6282 lines
205 KiB
Diff
6282 lines
205 KiB
Diff
diff --git a/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt b/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt
|
|
deleted file mode 100644
|
|
index 7175dc3740ac..000000000000
|
|
--- a/Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt
|
|
+++ /dev/null
|
|
@@ -1,30 +0,0 @@
|
|
-Toppoly TD028TTEC1 Panel
|
|
-========================
|
|
-
|
|
-Required properties:
|
|
-- compatible: "toppoly,td028ttec1"
|
|
-
|
|
-Optional properties:
|
|
-- label: a symbolic name for the panel
|
|
-
|
|
-Required nodes:
|
|
-- Video port for DPI input
|
|
-
|
|
-Example
|
|
--------
|
|
-
|
|
-lcd-panel: td028ttec1@0 {
|
|
- compatible = "toppoly,td028ttec1";
|
|
- reg = <0>;
|
|
- spi-max-frequency = <100000>;
|
|
- spi-cpol;
|
|
- spi-cpha;
|
|
-
|
|
- label = "lcd";
|
|
- port {
|
|
- lcd_in: endpoint {
|
|
- remote-endpoint = <&dpi_out>;
|
|
- };
|
|
- };
|
|
-};
|
|
-
|
|
diff --git a/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt b/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
|
|
new file mode 100644
|
|
index 000000000000..ed34253d9fb1
|
|
--- /dev/null
|
|
+++ b/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
|
|
@@ -0,0 +1,30 @@
|
|
+Toppoly TD028TTEC1 Panel
|
|
+========================
|
|
+
|
|
+Required properties:
|
|
+- compatible: "tpo,td028ttec1"
|
|
+
|
|
+Optional properties:
|
|
+- label: a symbolic name for the panel
|
|
+
|
|
+Required nodes:
|
|
+- Video port for DPI input
|
|
+
|
|
+Example
|
|
+-------
|
|
+
|
|
+lcd-panel: td028ttec1@0 {
|
|
+ compatible = "tpo,td028ttec1";
|
|
+ reg = <0>;
|
|
+ spi-max-frequency = <100000>;
|
|
+ spi-cpol;
|
|
+ spi-cpha;
|
|
+
|
|
+ label = "lcd";
|
|
+ port {
|
|
+ lcd_in: endpoint {
|
|
+ remote-endpoint = <&dpi_out>;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
|
|
index 8f3ad9ab4637..b41d2601c6ba 100644
|
|
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
|
|
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
|
|
@@ -28,6 +28,9 @@ Optional properties:
|
|
regulator to drive the OTG VBus, rather then as an input pin
|
|
which signals whether the board is driving OTG VBus or not.
|
|
|
|
+- x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is
|
|
+ wired for master mode. The default is slave mode.
|
|
+
|
|
- <input>-supply: a phandle to the regulator supply node. May be omitted if
|
|
inputs are unregulated, such as using the IPSOUT output
|
|
from the PMIC.
|
|
diff --git a/Makefile b/Makefile
|
|
index 16dca98900e7..df3b20af0fdb 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 9
|
|
-SUBLEVEL = 89
|
|
+SUBLEVEL = 90
|
|
EXTRAVERSION =
|
|
NAME = Roaring Lionus
|
|
|
|
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
|
|
index 6a61deed4a85..ab228ed45945 100644
|
|
--- a/arch/alpha/kernel/console.c
|
|
+++ b/arch/alpha/kernel/console.c
|
|
@@ -20,6 +20,7 @@
|
|
struct pci_controller *pci_vga_hose;
|
|
static struct resource alpha_vga = {
|
|
.name = "alpha-vga+",
|
|
+ .flags = IORESOURCE_IO,
|
|
.start = 0x3C0,
|
|
.end = 0x3DF
|
|
};
|
|
diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
|
|
index 1b7a5ff0e533..d7774d35e466 100644
|
|
--- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts
|
|
+++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
|
|
@@ -15,7 +15,7 @@
|
|
bootargs = "console=ttyS4,115200 earlyprintk";
|
|
};
|
|
|
|
- memory {
|
|
+ memory@80000000 {
|
|
reg = <0x80000000 0x20000000>;
|
|
};
|
|
};
|
|
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
|
|
index 3f1759411d51..414e60ed0257 100644
|
|
--- a/arch/arm/kernel/ftrace.c
|
|
+++ b/arch/arm/kernel/ftrace.c
|
|
@@ -29,11 +29,6 @@
|
|
#endif
|
|
|
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
|
-#ifdef CONFIG_OLD_MCOUNT
|
|
-#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
|
|
-#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
|
|
-
|
|
-#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
|
|
|
|
static int __ftrace_modify_code(void *data)
|
|
{
|
|
@@ -51,6 +46,12 @@ void arch_ftrace_update_code(int command)
|
|
stop_machine(__ftrace_modify_code, &command, NULL);
|
|
}
|
|
|
|
+#ifdef CONFIG_OLD_MCOUNT
|
|
+#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
|
|
+#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
|
|
+
|
|
+#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
|
|
+
|
|
static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
|
|
{
|
|
return rec->arch.old_mcount ? OLD_NOP : NOP;
|
|
diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c
|
|
index ef9ed36e8a61..e3416b40e82b 100644
|
|
--- a/arch/arm/mach-omap2/clockdomains7xx_data.c
|
|
+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
|
|
@@ -524,7 +524,7 @@ static struct clockdomain pcie_7xx_clkdm = {
|
|
.dep_bit = DRA7XX_PCIE_STATDEP_SHIFT,
|
|
.wkdep_srcs = pcie_wkup_sleep_deps,
|
|
.sleepdep_srcs = pcie_wkup_sleep_deps,
|
|
- .flags = CLKDM_CAN_HWSUP_SWSUP,
|
|
+ .flags = CLKDM_CAN_SWSUP,
|
|
};
|
|
|
|
static struct clockdomain atl_7xx_clkdm = {
|
|
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
|
|
index 6ab0ae7d6535..d1d945c6bd05 100644
|
|
--- a/arch/ia64/kernel/module.c
|
|
+++ b/arch/ia64/kernel/module.c
|
|
@@ -153,7 +153,7 @@ slot (const struct insn *insn)
|
|
static int
|
|
apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
|
|
{
|
|
- if (slot(insn) != 2) {
|
|
+ if (slot(insn) != 1 && slot(insn) != 2) {
|
|
printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
|
|
mod->name, slot(insn));
|
|
return 0;
|
|
@@ -165,7 +165,7 @@ apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
|
|
static int
|
|
apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
|
|
{
|
|
- if (slot(insn) != 2) {
|
|
+ if (slot(insn) != 1 && slot(insn) != 2) {
|
|
printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
|
|
mod->name, slot(insn));
|
|
return 0;
|
|
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
|
|
index ab68d0ee7725..4e54282c29b4 100644
|
|
--- a/arch/powerpc/include/asm/cputable.h
|
|
+++ b/arch/powerpc/include/asm/cputable.h
|
|
@@ -474,7 +474,8 @@ enum {
|
|
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
|
|
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
|
|
CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
|
|
-#define CPU_FTRS_POWER9_DD1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1)
|
|
+#define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
|
|
+ (~CPU_FTR_SAO))
|
|
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
|
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
|
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
|
|
index a587e8f4fd26..4b4e927c4822 100644
|
|
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
|
|
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
|
|
@@ -177,12 +177,15 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
|
|
ret = mmu_hash_ops.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
|
|
hpsize, hpsize, MMU_SEGSIZE_256M);
|
|
|
|
- if (ret < 0) {
|
|
+ if (ret == -1) {
|
|
/* If we couldn't map a primary PTE, try a secondary */
|
|
hash = ~hash;
|
|
vflags ^= HPTE_V_SECONDARY;
|
|
attempt++;
|
|
goto map_again;
|
|
+ } else if (ret < 0) {
|
|
+ r = -EIO;
|
|
+ goto out_unlock;
|
|
} else {
|
|
trace_kvm_book3s_64_mmu_map(rflags, hpteg,
|
|
vpn, hpaddr, orig_pte);
|
|
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
|
|
index 826c541a12af..e0d88d0890aa 100644
|
|
--- a/arch/powerpc/kvm/book3s_pr.c
|
|
+++ b/arch/powerpc/kvm/book3s_pr.c
|
|
@@ -627,7 +627,11 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
|
kvmppc_mmu_unmap_page(vcpu, &pte);
|
|
}
|
|
/* The guest's PTE is not mapped yet. Map on the host */
|
|
- kvmppc_mmu_map_page(vcpu, &pte, iswrite);
|
|
+ if (kvmppc_mmu_map_page(vcpu, &pte, iswrite) == -EIO) {
|
|
+ /* Exit KVM if mapping failed */
|
|
+ run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
+ return RESUME_HOST;
|
|
+ }
|
|
if (data)
|
|
vcpu->stat.sp_storage++;
|
|
else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
|
|
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
|
|
index 6de58f1bd7ec..eb5ff66b4d7a 100644
|
|
--- a/arch/x86/boot/compressed/kaslr.c
|
|
+++ b/arch/x86/boot/compressed/kaslr.c
|
|
@@ -460,10 +460,17 @@ void choose_random_location(unsigned long input,
|
|
add_identity_map(random_addr, output_size);
|
|
*output = random_addr;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * This loads the identity mapping page table.
|
|
+ * This should only be done if a new physical address
|
|
+ * is found for the kernel, otherwise we should keep
|
|
+ * the old page table to make it be like the "nokaslr"
|
|
+ * case.
|
|
+ */
|
|
+ finalize_identity_maps();
|
|
}
|
|
|
|
- /* This actually loads the identity pagetable on x86_64. */
|
|
- finalize_identity_maps();
|
|
|
|
/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
|
|
if (IS_ENABLED(CONFIG_X86_64))
|
|
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
|
|
index be22f5a2192e..4e3b8a587c88 100644
|
|
--- a/arch/x86/kernel/i8259.c
|
|
+++ b/arch/x86/kernel/i8259.c
|
|
@@ -418,6 +418,7 @@ struct legacy_pic default_legacy_pic = {
|
|
};
|
|
|
|
struct legacy_pic *legacy_pic = &default_legacy_pic;
|
|
+EXPORT_SYMBOL(legacy_pic);
|
|
|
|
static int __init i8259A_init_ops(void)
|
|
{
|
|
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
|
|
index ca699677e288..ea217caa731c 100644
|
|
--- a/arch/x86/kernel/smp.c
|
|
+++ b/arch/x86/kernel/smp.c
|
|
@@ -33,6 +33,7 @@
|
|
#include <asm/mce.h>
|
|
#include <asm/trace/irq_vectors.h>
|
|
#include <asm/kexec.h>
|
|
+#include <asm/virtext.h>
|
|
|
|
/*
|
|
* Some notes on x86 processor bugs affecting SMP operation:
|
|
@@ -162,6 +163,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
|
|
if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
|
|
return NMI_HANDLED;
|
|
|
|
+ cpu_emergency_vmxoff();
|
|
stop_this_cpu(NULL);
|
|
|
|
return NMI_HANDLED;
|
|
@@ -174,6 +176,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
|
|
asmlinkage __visible void smp_reboot_interrupt(void)
|
|
{
|
|
ipi_entering_ack_irq();
|
|
+ cpu_emergency_vmxoff();
|
|
stop_this_cpu(NULL);
|
|
irq_exit();
|
|
}
|
|
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
|
|
index 137afbbd0590..a11540e51f62 100644
|
|
--- a/arch/x86/xen/smp.c
|
|
+++ b/arch/x86/xen/smp.c
|
|
@@ -299,35 +299,46 @@ static void __init xen_filter_cpu_maps(void)
|
|
|
|
}
|
|
|
|
-static void __init xen_smp_prepare_boot_cpu(void)
|
|
+static void __init xen_pv_smp_prepare_boot_cpu(void)
|
|
{
|
|
BUG_ON(smp_processor_id() != 0);
|
|
native_smp_prepare_boot_cpu();
|
|
|
|
- if (xen_pv_domain()) {
|
|
- if (!xen_feature(XENFEAT_writable_page_tables))
|
|
- /* We've switched to the "real" per-cpu gdt, so make
|
|
- * sure the old memory can be recycled. */
|
|
- make_lowmem_page_readwrite(xen_initial_gdt);
|
|
+ if (!xen_feature(XENFEAT_writable_page_tables))
|
|
+ /* We've switched to the "real" per-cpu gdt, so make
|
|
+ * sure the old memory can be recycled. */
|
|
+ make_lowmem_page_readwrite(xen_initial_gdt);
|
|
|
|
#ifdef CONFIG_X86_32
|
|
- /*
|
|
- * Xen starts us with XEN_FLAT_RING1_DS, but linux code
|
|
- * expects __USER_DS
|
|
- */
|
|
- loadsegment(ds, __USER_DS);
|
|
- loadsegment(es, __USER_DS);
|
|
+ /*
|
|
+ * Xen starts us with XEN_FLAT_RING1_DS, but linux code
|
|
+ * expects __USER_DS
|
|
+ */
|
|
+ loadsegment(ds, __USER_DS);
|
|
+ loadsegment(es, __USER_DS);
|
|
#endif
|
|
|
|
- xen_filter_cpu_maps();
|
|
- xen_setup_vcpu_info_placement();
|
|
- }
|
|
+ xen_filter_cpu_maps();
|
|
+ xen_setup_vcpu_info_placement();
|
|
+
|
|
+ /*
|
|
+ * The alternative logic (which patches the unlock/lock) runs before
|
|
+ * the smp bootup up code is activated. Hence we need to set this up
|
|
+ * the core kernel is being patched. Otherwise we will have only
|
|
+ * modules patched but not core code.
|
|
+ */
|
|
+ xen_init_spinlocks();
|
|
+}
|
|
+
|
|
+static void __init xen_hvm_smp_prepare_boot_cpu(void)
|
|
+{
|
|
+ BUG_ON(smp_processor_id() != 0);
|
|
+ native_smp_prepare_boot_cpu();
|
|
|
|
/*
|
|
* Setup vcpu_info for boot CPU.
|
|
*/
|
|
- if (xen_hvm_domain())
|
|
- xen_vcpu_setup(0);
|
|
+ xen_vcpu_setup(0);
|
|
|
|
/*
|
|
* The alternative logic (which patches the unlock/lock) runs before
|
|
@@ -733,7 +744,7 @@ static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id)
|
|
}
|
|
|
|
static const struct smp_ops xen_smp_ops __initconst = {
|
|
- .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
|
|
+ .smp_prepare_boot_cpu = xen_pv_smp_prepare_boot_cpu,
|
|
.smp_prepare_cpus = xen_smp_prepare_cpus,
|
|
.smp_cpus_done = xen_smp_cpus_done,
|
|
|
|
@@ -772,5 +783,5 @@ void __init xen_hvm_smp_init(void)
|
|
smp_ops.cpu_die = xen_cpu_die;
|
|
smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
|
|
smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
|
|
- smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu;
|
|
+ smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu;
|
|
}
|
|
diff --git a/block/blk-mq.c b/block/blk-mq.c
|
|
index 10f8f94b7f20..c6572ffc1e87 100644
|
|
--- a/block/blk-mq.c
|
|
+++ b/block/blk-mq.c
|
|
@@ -2014,15 +2014,15 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
|
|
|
|
blk_mq_init_cpu_queues(q, set->nr_hw_queues);
|
|
|
|
- get_online_cpus();
|
|
mutex_lock(&all_q_mutex);
|
|
+ get_online_cpus();
|
|
|
|
list_add_tail(&q->all_q_node, &all_q_list);
|
|
blk_mq_add_queue_tag_set(set, q);
|
|
blk_mq_map_swqueue(q, cpu_online_mask);
|
|
|
|
- mutex_unlock(&all_q_mutex);
|
|
put_online_cpus();
|
|
+ mutex_unlock(&all_q_mutex);
|
|
|
|
return q;
|
|
|
|
diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c
|
|
index e6e991ac20f3..0c6874e6a9b6 100644
|
|
--- a/drivers/acpi/pmic/intel_pmic_xpower.c
|
|
+++ b/drivers/acpi/pmic/intel_pmic_xpower.c
|
|
@@ -28,97 +28,97 @@ static struct pmic_table power_table[] = {
|
|
.address = 0x00,
|
|
.reg = 0x13,
|
|
.bit = 0x05,
|
|
- },
|
|
+ }, /* ALD1 */
|
|
{
|
|
.address = 0x04,
|
|
.reg = 0x13,
|
|
.bit = 0x06,
|
|
- },
|
|
+ }, /* ALD2 */
|
|
{
|
|
.address = 0x08,
|
|
.reg = 0x13,
|
|
.bit = 0x07,
|
|
- },
|
|
+ }, /* ALD3 */
|
|
{
|
|
.address = 0x0c,
|
|
.reg = 0x12,
|
|
.bit = 0x03,
|
|
- },
|
|
+ }, /* DLD1 */
|
|
{
|
|
.address = 0x10,
|
|
.reg = 0x12,
|
|
.bit = 0x04,
|
|
- },
|
|
+ }, /* DLD2 */
|
|
{
|
|
.address = 0x14,
|
|
.reg = 0x12,
|
|
.bit = 0x05,
|
|
- },
|
|
+ }, /* DLD3 */
|
|
{
|
|
.address = 0x18,
|
|
.reg = 0x12,
|
|
.bit = 0x06,
|
|
- },
|
|
+ }, /* DLD4 */
|
|
{
|
|
.address = 0x1c,
|
|
.reg = 0x12,
|
|
.bit = 0x00,
|
|
- },
|
|
+ }, /* ELD1 */
|
|
{
|
|
.address = 0x20,
|
|
.reg = 0x12,
|
|
.bit = 0x01,
|
|
- },
|
|
+ }, /* ELD2 */
|
|
{
|
|
.address = 0x24,
|
|
.reg = 0x12,
|
|
.bit = 0x02,
|
|
- },
|
|
+ }, /* ELD3 */
|
|
{
|
|
.address = 0x28,
|
|
.reg = 0x13,
|
|
.bit = 0x02,
|
|
- },
|
|
+ }, /* FLD1 */
|
|
{
|
|
.address = 0x2c,
|
|
.reg = 0x13,
|
|
.bit = 0x03,
|
|
- },
|
|
+ }, /* FLD2 */
|
|
{
|
|
.address = 0x30,
|
|
.reg = 0x13,
|
|
.bit = 0x04,
|
|
- },
|
|
+ }, /* FLD3 */
|
|
{
|
|
- .address = 0x38,
|
|
+ .address = 0x34,
|
|
.reg = 0x10,
|
|
.bit = 0x03,
|
|
- },
|
|
+ }, /* BUC1 */
|
|
{
|
|
- .address = 0x3c,
|
|
+ .address = 0x38,
|
|
.reg = 0x10,
|
|
.bit = 0x06,
|
|
- },
|
|
+ }, /* BUC2 */
|
|
{
|
|
- .address = 0x40,
|
|
+ .address = 0x3c,
|
|
.reg = 0x10,
|
|
.bit = 0x05,
|
|
- },
|
|
+ }, /* BUC3 */
|
|
{
|
|
- .address = 0x44,
|
|
+ .address = 0x40,
|
|
.reg = 0x10,
|
|
.bit = 0x04,
|
|
- },
|
|
+ }, /* BUC4 */
|
|
{
|
|
- .address = 0x48,
|
|
+ .address = 0x44,
|
|
.reg = 0x10,
|
|
.bit = 0x01,
|
|
- },
|
|
+ }, /* BUC5 */
|
|
{
|
|
- .address = 0x4c,
|
|
+ .address = 0x48,
|
|
.reg = 0x10,
|
|
.bit = 0x00
|
|
- },
|
|
+ }, /* BUC6 */
|
|
};
|
|
|
|
/* TMP0 - TMP5 are the same, all from GPADC */
|
|
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
|
|
index 1c2b846c5776..3a6c9b741b23 100644
|
|
--- a/drivers/acpi/power.c
|
|
+++ b/drivers/acpi/power.c
|
|
@@ -864,6 +864,16 @@ void acpi_resume_power_resources(void)
|
|
|
|
mutex_unlock(&resource->resource_lock);
|
|
}
|
|
+
|
|
+ mutex_unlock(&power_resource_list_lock);
|
|
+}
|
|
+
|
|
+void acpi_turn_off_unused_power_resources(void)
|
|
+{
|
|
+ struct acpi_power_resource *resource;
|
|
+
|
|
+ mutex_lock(&power_resource_list_lock);
|
|
+
|
|
list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
|
|
int result, state;
|
|
|
|
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
|
|
index 9d5f0c7ed3f7..8697a82bd465 100644
|
|
--- a/drivers/acpi/processor_driver.c
|
|
+++ b/drivers/acpi/processor_driver.c
|
|
@@ -251,6 +251,9 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|
if (ACPI_SUCCESS(status))
|
|
return 0;
|
|
|
|
+ result = -ENODEV;
|
|
+ acpi_pss_perf_exit(pr, device);
|
|
+
|
|
err_power_exit:
|
|
acpi_processor_power_exit(pr);
|
|
return result;
|
|
@@ -259,11 +262,16 @@ static int __acpi_processor_start(struct acpi_device *device)
|
|
static int acpi_processor_start(struct device *dev)
|
|
{
|
|
struct acpi_device *device = ACPI_COMPANION(dev);
|
|
+ int ret;
|
|
|
|
if (!device)
|
|
return -ENODEV;
|
|
|
|
- return __acpi_processor_start(device);
|
|
+ /* Protect against concurrent CPU hotplug operations */
|
|
+ get_online_cpus();
|
|
+ ret = __acpi_processor_start(device);
|
|
+ put_online_cpus();
|
|
+ return ret;
|
|
}
|
|
|
|
static int acpi_processor_stop(struct device *dev)
|
|
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
|
|
index d51ca1c05619..207e9bbb9490 100644
|
|
--- a/drivers/acpi/processor_throttling.c
|
|
+++ b/drivers/acpi/processor_throttling.c
|
|
@@ -62,8 +62,8 @@ struct acpi_processor_throttling_arg {
|
|
#define THROTTLING_POSTCHANGE (2)
|
|
|
|
static int acpi_processor_get_throttling(struct acpi_processor *pr);
|
|
-int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
- int state, bool force);
|
|
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
+ int state, bool force, bool direct);
|
|
|
|
static int acpi_processor_update_tsd_coord(void)
|
|
{
|
|
@@ -891,7 +891,8 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
"Invalid throttling state, reset\n"));
|
|
state = 0;
|
|
- ret = acpi_processor_set_throttling(pr, state, true);
|
|
+ ret = __acpi_processor_set_throttling(pr, state, true,
|
|
+ true);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
@@ -901,36 +902,31 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
|
|
return 0;
|
|
}
|
|
|
|
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
|
|
+static long __acpi_processor_get_throttling(void *data)
|
|
{
|
|
- cpumask_var_t saved_mask;
|
|
- int ret;
|
|
+ struct acpi_processor *pr = data;
|
|
+
|
|
+ return pr->throttling.acpi_processor_get_throttling(pr);
|
|
+}
|
|
|
|
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
|
|
+{
|
|
if (!pr)
|
|
return -EINVAL;
|
|
|
|
if (!pr->flags.throttling)
|
|
return -ENODEV;
|
|
|
|
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
|
|
- return -ENOMEM;
|
|
-
|
|
/*
|
|
- * Migrate task to the cpu pointed by pr.
|
|
+ * This is either called from the CPU hotplug callback of
|
|
+ * processor_driver or via the ACPI probe function. In the latter
|
|
+ * case the CPU is not guaranteed to be online. Both call sites are
|
|
+ * protected against CPU hotplug.
|
|
*/
|
|
- cpumask_copy(saved_mask, ¤t->cpus_allowed);
|
|
- /* FIXME: use work_on_cpu() */
|
|
- if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
|
|
- /* Can't migrate to the target pr->id CPU. Exit */
|
|
- free_cpumask_var(saved_mask);
|
|
+ if (!cpu_online(pr->id))
|
|
return -ENODEV;
|
|
- }
|
|
- ret = pr->throttling.acpi_processor_get_throttling(pr);
|
|
- /* restore the previous state */
|
|
- set_cpus_allowed_ptr(current, saved_mask);
|
|
- free_cpumask_var(saved_mask);
|
|
|
|
- return ret;
|
|
+ return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr);
|
|
}
|
|
|
|
static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
|
|
@@ -1080,8 +1076,15 @@ static long acpi_processor_throttling_fn(void *data)
|
|
arg->target_state, arg->force);
|
|
}
|
|
|
|
-int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
- int state, bool force)
|
|
+static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct)
|
|
+{
|
|
+ if (direct)
|
|
+ return fn(arg);
|
|
+ return work_on_cpu(cpu, fn, arg);
|
|
+}
|
|
+
|
|
+static int __acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
+ int state, bool force, bool direct)
|
|
{
|
|
int ret = 0;
|
|
unsigned int i;
|
|
@@ -1130,7 +1133,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
arg.pr = pr;
|
|
arg.target_state = state;
|
|
arg.force = force;
|
|
- ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg);
|
|
+ ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, &arg,
|
|
+ direct);
|
|
} else {
|
|
/*
|
|
* When the T-state coordination is SW_ALL or HW_ALL,
|
|
@@ -1163,8 +1167,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
arg.pr = match_pr;
|
|
arg.target_state = state;
|
|
arg.force = force;
|
|
- ret = work_on_cpu(pr->id, acpi_processor_throttling_fn,
|
|
- &arg);
|
|
+ ret = call_on_cpu(pr->id, acpi_processor_throttling_fn,
|
|
+ &arg, direct);
|
|
}
|
|
}
|
|
/*
|
|
@@ -1182,6 +1186,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|
return ret;
|
|
}
|
|
|
|
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state,
|
|
+ bool force)
|
|
+{
|
|
+ return __acpi_processor_set_throttling(pr, state, force, false);
|
|
+}
|
|
+
|
|
int acpi_processor_get_throttling_info(struct acpi_processor *pr)
|
|
{
|
|
int result = 0;
|
|
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
|
|
index a4327af676fe..097d630ab886 100644
|
|
--- a/drivers/acpi/sleep.c
|
|
+++ b/drivers/acpi/sleep.c
|
|
@@ -474,6 +474,7 @@ static void acpi_pm_start(u32 acpi_state)
|
|
*/
|
|
static void acpi_pm_end(void)
|
|
{
|
|
+ acpi_turn_off_unused_power_resources();
|
|
acpi_scan_lock_release();
|
|
/*
|
|
* This is necessary in case acpi_pm_finish() is not called during a
|
|
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
|
|
index a9cc34e663f9..a82ff74faf7a 100644
|
|
--- a/drivers/acpi/sleep.h
|
|
+++ b/drivers/acpi/sleep.h
|
|
@@ -6,6 +6,7 @@ extern struct list_head acpi_wakeup_device_list;
|
|
extern struct mutex acpi_device_lock;
|
|
|
|
extern void acpi_resume_power_resources(void);
|
|
+extern void acpi_turn_off_unused_power_resources(void);
|
|
|
|
static inline acpi_status acpi_set_waking_vector(u32 wakeup_address)
|
|
{
|
|
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
|
|
index 3cfd879267b2..b86273fdf48e 100644
|
|
--- a/drivers/block/mtip32xx/mtip32xx.c
|
|
+++ b/drivers/block/mtip32xx/mtip32xx.c
|
|
@@ -169,6 +169,25 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev)
|
|
return false; /* device present */
|
|
}
|
|
|
|
+/* we have to use runtime tag to setup command header */
|
|
+static void mtip_init_cmd_header(struct request *rq)
|
|
+{
|
|
+ struct driver_data *dd = rq->q->queuedata;
|
|
+ struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
|
+ u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
|
|
+
|
|
+ /* Point the command headers at the command tables. */
|
|
+ cmd->command_header = dd->port->command_list +
|
|
+ (sizeof(struct mtip_cmd_hdr) * rq->tag);
|
|
+ cmd->command_header_dma = dd->port->command_list_dma +
|
|
+ (sizeof(struct mtip_cmd_hdr) * rq->tag);
|
|
+
|
|
+ if (host_cap_64)
|
|
+ cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
|
|
+
|
|
+ cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
|
|
+}
|
|
+
|
|
static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
|
|
{
|
|
struct request *rq;
|
|
@@ -180,6 +199,9 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
|
|
if (IS_ERR(rq))
|
|
return NULL;
|
|
|
|
+ /* Internal cmd isn't submitted via .queue_rq */
|
|
+ mtip_init_cmd_header(rq);
|
|
+
|
|
return blk_mq_rq_to_pdu(rq);
|
|
}
|
|
|
|
@@ -3811,6 +3833,8 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|
struct request *rq = bd->rq;
|
|
int ret;
|
|
|
|
+ mtip_init_cmd_header(rq);
|
|
+
|
|
if (unlikely(mtip_check_unal_depth(hctx, rq)))
|
|
return BLK_MQ_RQ_QUEUE_BUSY;
|
|
|
|
@@ -3842,7 +3866,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx,
|
|
{
|
|
struct driver_data *dd = data;
|
|
struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
|
|
- u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
|
|
|
|
/*
|
|
* For flush requests, request_idx starts at the end of the
|
|
@@ -3859,17 +3882,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx,
|
|
|
|
memset(cmd->command, 0, CMD_DMA_ALLOC_SZ);
|
|
|
|
- /* Point the command headers at the command tables. */
|
|
- cmd->command_header = dd->port->command_list +
|
|
- (sizeof(struct mtip_cmd_hdr) * request_idx);
|
|
- cmd->command_header_dma = dd->port->command_list_dma +
|
|
- (sizeof(struct mtip_cmd_hdr) * request_idx);
|
|
-
|
|
- if (host_cap_64)
|
|
- cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
|
|
-
|
|
- cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
|
|
-
|
|
sg_init_table(cmd->sg, MTIP_MAX_SG);
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
|
|
index 08c2c93887c1..3aac78a5091b 100644
|
|
--- a/drivers/bluetooth/btqcomsmd.c
|
|
+++ b/drivers/bluetooth/btqcomsmd.c
|
|
@@ -85,7 +85,8 @@ static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb)
|
|
break;
|
|
}
|
|
|
|
- kfree_skb(skb);
|
|
+ if (!ret)
|
|
+ kfree_skb(skb);
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
|
|
index 9497c469efd2..2230f9368c21 100644
|
|
--- a/drivers/bluetooth/hci_ldisc.c
|
|
+++ b/drivers/bluetooth/hci_ldisc.c
|
|
@@ -113,16 +113,21 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
|
|
{
|
|
struct sk_buff *skb = hu->tx_skb;
|
|
|
|
- if (!skb)
|
|
- skb = hu->proto->dequeue(hu);
|
|
- else
|
|
+ if (!skb) {
|
|
+ if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
|
|
+ skb = hu->proto->dequeue(hu);
|
|
+ } else {
|
|
hu->tx_skb = NULL;
|
|
+ }
|
|
|
|
return skb;
|
|
}
|
|
|
|
int hci_uart_tx_wakeup(struct hci_uart *hu)
|
|
{
|
|
+ if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
|
|
+ return 0;
|
|
+
|
|
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
|
|
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
|
|
return 0;
|
|
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
|
|
index 6c867fbc56a7..74b2f4a14643 100644
|
|
--- a/drivers/bluetooth/hci_qca.c
|
|
+++ b/drivers/bluetooth/hci_qca.c
|
|
@@ -936,6 +936,9 @@ static int qca_setup(struct hci_uart *hu)
|
|
if (!ret) {
|
|
set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);
|
|
qca_debugfs_init(hdev);
|
|
+ } else if (ret == -ENOENT) {
|
|
+ /* No patch/nvm-config found, run with original fw/config */
|
|
+ ret = 0;
|
|
}
|
|
|
|
/* Setup bdaddr */
|
|
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
|
|
index 909311016108..055d2ce378a7 100644
|
|
--- a/drivers/char/ipmi/ipmi_watchdog.c
|
|
+++ b/drivers/char/ipmi/ipmi_watchdog.c
|
|
@@ -515,7 +515,7 @@ static void panic_halt_ipmi_heartbeat(void)
|
|
msg.cmd = IPMI_WDOG_RESET_TIMER;
|
|
msg.data = NULL;
|
|
msg.data_len = 0;
|
|
- atomic_add(2, &panic_done_count);
|
|
+ atomic_add(1, &panic_done_count);
|
|
rv = ipmi_request_supply_msgs(watchdog_user,
|
|
(struct ipmi_addr *) &addr,
|
|
0,
|
|
@@ -525,7 +525,7 @@ static void panic_halt_ipmi_heartbeat(void)
|
|
&panic_halt_heartbeat_recv_msg,
|
|
1);
|
|
if (rv)
|
|
- atomic_sub(2, &panic_done_count);
|
|
+ atomic_sub(1, &panic_done_count);
|
|
}
|
|
|
|
static struct ipmi_smi_msg panic_halt_smi_msg = {
|
|
@@ -549,12 +549,12 @@ static void panic_halt_ipmi_set_timeout(void)
|
|
/* Wait for the messages to be free. */
|
|
while (atomic_read(&panic_done_count) != 0)
|
|
ipmi_poll_interface(watchdog_user);
|
|
- atomic_add(2, &panic_done_count);
|
|
+ atomic_add(1, &panic_done_count);
|
|
rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
|
|
&panic_halt_recv_msg,
|
|
&send_heartbeat_now);
|
|
if (rv) {
|
|
- atomic_sub(2, &panic_done_count);
|
|
+ atomic_sub(1, &panic_done_count);
|
|
printk(KERN_WARNING PFX
|
|
"Unable to extend the watchdog timeout.");
|
|
} else {
|
|
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
|
|
index d0ac2d56520f..830d7e30e508 100644
|
|
--- a/drivers/char/tpm/tpm-interface.c
|
|
+++ b/drivers/char/tpm/tpm-interface.c
|
|
@@ -1078,6 +1078,11 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
|
|
break;
|
|
|
|
recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
|
|
+ if (recd > num_bytes) {
|
|
+ total = -EFAULT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
|
|
|
|
dest += recd;
|
|
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
|
|
index 17896d654033..a5780ebe15ef 100644
|
|
--- a/drivers/char/tpm/tpm2-cmd.c
|
|
+++ b/drivers/char/tpm/tpm2-cmd.c
|
|
@@ -668,6 +668,11 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
|
if (!rc) {
|
|
data_len = be16_to_cpup(
|
|
(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
|
|
+ if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) {
|
|
+ rc = -EFAULT;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
data = &buf.data[TPM_HEADER_SIZE + 6];
|
|
|
|
memcpy(payload->key, data, data_len - 1);
|
|
@@ -675,6 +680,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
|
payload->migratable = data[data_len - 1];
|
|
}
|
|
|
|
+out:
|
|
tpm_buf_destroy(&buf);
|
|
return rc;
|
|
}
|
|
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c
|
|
index a564e9248814..adc14145861a 100644
|
|
--- a/drivers/clk/bcm/clk-ns2.c
|
|
+++ b/drivers/clk/bcm/clk-ns2.c
|
|
@@ -103,7 +103,7 @@ CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr",
|
|
|
|
static const struct iproc_pll_ctrl genpll_sw = {
|
|
.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
|
|
- .aon = AON_VAL(0x0, 2, 9, 8),
|
|
+ .aon = AON_VAL(0x0, 1, 11, 10),
|
|
.reset = RESET_VAL(0x4, 2, 1),
|
|
.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
|
|
.ndiv_int = REG_VAL(0x8, 4, 10),
|
|
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
|
|
index 5e918e7afaba..95a6e9834392 100644
|
|
--- a/drivers/clk/clk-axi-clkgen.c
|
|
+++ b/drivers/clk/clk-axi-clkgen.c
|
|
@@ -40,6 +40,10 @@
|
|
#define MMCM_REG_FILTER1 0x4e
|
|
#define MMCM_REG_FILTER2 0x4f
|
|
|
|
+#define MMCM_CLKOUT_NOCOUNT BIT(6)
|
|
+
|
|
+#define MMCM_CLK_DIV_NOCOUNT BIT(12)
|
|
+
|
|
struct axi_clkgen {
|
|
void __iomem *base;
|
|
struct clk_hw clk_hw;
|
|
@@ -315,12 +319,27 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
|
|
unsigned int reg;
|
|
unsigned long long tmp;
|
|
|
|
- axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®);
|
|
- dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, ®);
|
|
+ if (reg & MMCM_CLKOUT_NOCOUNT) {
|
|
+ dout = 1;
|
|
+ } else {
|
|
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®);
|
|
+ dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
+ }
|
|
+
|
|
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, ®);
|
|
- d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
- axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®);
|
|
- m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
+ if (reg & MMCM_CLK_DIV_NOCOUNT)
|
|
+ d = 1;
|
|
+ else
|
|
+ d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
+
|
|
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, ®);
|
|
+ if (reg & MMCM_CLKOUT_NOCOUNT) {
|
|
+ m = 1;
|
|
+ } else {
|
|
+ axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®);
|
|
+ m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
|
+ }
|
|
|
|
if (d == 0 || dout == 0)
|
|
return 0;
|
|
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
|
|
index b051db43fae1..136a86094c53 100644
|
|
--- a/drivers/clk/clk-si5351.c
|
|
+++ b/drivers/clk/clk-si5351.c
|
|
@@ -72,7 +72,7 @@ static const char * const si5351_input_names[] = {
|
|
"xtal", "clkin"
|
|
};
|
|
static const char * const si5351_pll_names[] = {
|
|
- "plla", "pllb", "vxco"
|
|
+ "si5351_plla", "si5351_pllb", "si5351_vxco"
|
|
};
|
|
static const char * const si5351_msynth_names[] = {
|
|
"ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
|
|
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
|
|
index 0fb39fe217d1..0cdb8550729d 100644
|
|
--- a/drivers/clk/clk.c
|
|
+++ b/drivers/clk/clk.c
|
|
@@ -2437,6 +2437,21 @@ static int __clk_core_init(struct clk_core *core)
|
|
rate = 0;
|
|
core->rate = core->req_rate = rate;
|
|
|
|
+ /*
|
|
+ * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
|
|
+ * don't get accidentally disabled when walking the orphan tree and
|
|
+ * reparenting clocks
|
|
+ */
|
|
+ if (core->flags & CLK_IS_CRITICAL) {
|
|
+ unsigned long flags;
|
|
+
|
|
+ clk_core_prepare(core);
|
|
+
|
|
+ flags = clk_enable_lock();
|
|
+ clk_core_enable(core);
|
|
+ clk_enable_unlock(flags);
|
|
+ }
|
|
+
|
|
/*
|
|
* walk the list of orphan clocks and reparent any that newly finds a
|
|
* parent.
|
|
@@ -2445,10 +2460,13 @@ static int __clk_core_init(struct clk_core *core)
|
|
struct clk_core *parent = __clk_init_parent(orphan);
|
|
|
|
/*
|
|
- * we could call __clk_set_parent, but that would result in a
|
|
- * redundant call to the .set_rate op, if it exists
|
|
+ * We need to use __clk_set_parent_before() and _after() to
|
|
+ * to properly migrate any prepare/enable count of the orphan
|
|
+ * clock. This is important for CLK_IS_CRITICAL clocks, which
|
|
+ * are enabled during init but might not have a parent yet.
|
|
*/
|
|
if (parent) {
|
|
+ /* update the clk tree topology */
|
|
__clk_set_parent_before(orphan, parent);
|
|
__clk_set_parent_after(orphan, parent, NULL);
|
|
__clk_recalc_accuracies(orphan);
|
|
@@ -2467,16 +2485,6 @@ static int __clk_core_init(struct clk_core *core)
|
|
if (core->ops->init)
|
|
core->ops->init(core->hw);
|
|
|
|
- if (core->flags & CLK_IS_CRITICAL) {
|
|
- unsigned long flags;
|
|
-
|
|
- clk_core_prepare(core);
|
|
-
|
|
- flags = clk_enable_lock();
|
|
- clk_core_enable(core);
|
|
- clk_enable_unlock(flags);
|
|
- }
|
|
-
|
|
kref_init(&core->ref);
|
|
out:
|
|
clk_prepare_unlock();
|
|
diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c
|
|
index 86628e22b2a3..719c3d9f07fb 100644
|
|
--- a/drivers/cpufreq/sh-cpufreq.c
|
|
+++ b/drivers/cpufreq/sh-cpufreq.c
|
|
@@ -30,54 +30,63 @@
|
|
|
|
static DEFINE_PER_CPU(struct clk, sh_cpuclk);
|
|
|
|
+struct cpufreq_target {
|
|
+ struct cpufreq_policy *policy;
|
|
+ unsigned int freq;
|
|
+};
|
|
+
|
|
static unsigned int sh_cpufreq_get(unsigned int cpu)
|
|
{
|
|
return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000;
|
|
}
|
|
|
|
-/*
|
|
- * Here we notify other drivers of the proposed change and the final change.
|
|
- */
|
|
-static int sh_cpufreq_target(struct cpufreq_policy *policy,
|
|
- unsigned int target_freq,
|
|
- unsigned int relation)
|
|
+static long __sh_cpufreq_target(void *arg)
|
|
{
|
|
- unsigned int cpu = policy->cpu;
|
|
+ struct cpufreq_target *target = arg;
|
|
+ struct cpufreq_policy *policy = target->policy;
|
|
+ int cpu = policy->cpu;
|
|
struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu);
|
|
- cpumask_t cpus_allowed;
|
|
struct cpufreq_freqs freqs;
|
|
struct device *dev;
|
|
long freq;
|
|
|
|
- cpus_allowed = current->cpus_allowed;
|
|
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
|
|
-
|
|
- BUG_ON(smp_processor_id() != cpu);
|
|
+ if (smp_processor_id() != cpu)
|
|
+ return -ENODEV;
|
|
|
|
dev = get_cpu_device(cpu);
|
|
|
|
/* Convert target_freq from kHz to Hz */
|
|
- freq = clk_round_rate(cpuclk, target_freq * 1000);
|
|
+ freq = clk_round_rate(cpuclk, target->freq * 1000);
|
|
|
|
if (freq < (policy->min * 1000) || freq > (policy->max * 1000))
|
|
return -EINVAL;
|
|
|
|
- dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000);
|
|
+ dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000);
|
|
|
|
freqs.old = sh_cpufreq_get(cpu);
|
|
freqs.new = (freq + 500) / 1000;
|
|
freqs.flags = 0;
|
|
|
|
- cpufreq_freq_transition_begin(policy, &freqs);
|
|
- set_cpus_allowed_ptr(current, &cpus_allowed);
|
|
+ cpufreq_freq_transition_begin(target->policy, &freqs);
|
|
clk_set_rate(cpuclk, freq);
|
|
- cpufreq_freq_transition_end(policy, &freqs, 0);
|
|
+ cpufreq_freq_transition_end(target->policy, &freqs, 0);
|
|
|
|
dev_dbg(dev, "set frequency %lu Hz\n", freq);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
+/*
|
|
+ * Here we notify other drivers of the proposed change and the final change.
|
|
+ */
|
|
+static int sh_cpufreq_target(struct cpufreq_policy *policy,
|
|
+ unsigned int target_freq,
|
|
+ unsigned int relation)
|
|
+{
|
|
+ struct cpufreq_target data = { .policy = policy, .freq = target_freq };
|
|
+
|
|
+ return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data);
|
|
+}
|
|
+
|
|
static int sh_cpufreq_verify(struct cpufreq_policy *policy)
|
|
{
|
|
struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu);
|
|
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
|
|
index 43e88d85129e..8c3c588834d2 100644
|
|
--- a/drivers/dma/ti-dma-crossbar.c
|
|
+++ b/drivers/dma/ti-dma-crossbar.c
|
|
@@ -54,7 +54,15 @@ struct ti_am335x_xbar_map {
|
|
|
|
static inline void ti_am335x_xbar_write(void __iomem *iomem, int event, u8 val)
|
|
{
|
|
- writeb_relaxed(val, iomem + event);
|
|
+ /*
|
|
+ * TPCC_EVT_MUX_60_63 register layout is different than the
|
|
+ * rest, in the sense, that event 63 is mapped to lowest byte
|
|
+ * and event 60 is mapped to highest, handle it separately.
|
|
+ */
|
|
+ if (event >= 60 && event <= 63)
|
|
+ writeb_relaxed(val, iomem + (63 - event % 4));
|
|
+ else
|
|
+ writeb_relaxed(val, iomem + event);
|
|
}
|
|
|
|
static void ti_am335x_xbar_free(struct device *dev, void *route_data)
|
|
diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
|
|
index 6d221e5c72ee..22658057fe27 100644
|
|
--- a/drivers/dma/xilinx/zynqmp_dma.c
|
|
+++ b/drivers/dma/xilinx/zynqmp_dma.c
|
|
@@ -933,7 +933,8 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan)
|
|
if (!chan)
|
|
return;
|
|
|
|
- devm_free_irq(chan->zdev->dev, chan->irq, chan);
|
|
+ if (chan->irq)
|
|
+ devm_free_irq(chan->zdev->dev, chan->irq, chan);
|
|
tasklet_kill(&chan->tasklet);
|
|
list_del(&chan->common.device_node);
|
|
clk_disable_unprepare(chan->clk_apb);
|
|
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
|
|
index d0ddba7a9d08..5ef4980f3f14 100644
|
|
--- a/drivers/gpio/gpio-wcove.c
|
|
+++ b/drivers/gpio/gpio-wcove.c
|
|
@@ -51,6 +51,8 @@
|
|
#define GROUP1_NR_IRQS 6
|
|
#define IRQ_MASK_BASE 0x4e19
|
|
#define IRQ_STATUS_BASE 0x4e0b
|
|
+#define GPIO_IRQ0_MASK GENMASK(6, 0)
|
|
+#define GPIO_IRQ1_MASK GENMASK(5, 0)
|
|
#define UPDATE_IRQ_TYPE BIT(0)
|
|
#define UPDATE_IRQ_MASK BIT(1)
|
|
|
|
@@ -310,7 +312,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
|
|
return IRQ_NONE;
|
|
}
|
|
|
|
- pending = p[0] | (p[1] << 8);
|
|
+ pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
|
|
if (!pending)
|
|
return IRQ_NONE;
|
|
|
|
@@ -318,7 +320,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
|
|
while (pending) {
|
|
/* One iteration is for all pending bits */
|
|
for_each_set_bit(gpio, (const unsigned long *)&pending,
|
|
- GROUP0_NR_IRQS) {
|
|
+ WCOVE_GPIO_NUM) {
|
|
offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0;
|
|
mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) :
|
|
BIT(gpio);
|
|
@@ -334,7 +336,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
|
|
break;
|
|
}
|
|
|
|
- pending = p[0] | (p[1] << 8);
|
|
+ pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
|
|
}
|
|
|
|
return IRQ_HANDLED;
|
|
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
index 50f18f666d67..d0c3e56ece74 100644
|
|
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
@@ -2237,7 +2237,7 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
|
struct amdgpu_ring *ring = adev->rings[i];
|
|
|
|
- if (!ring)
|
|
+ if (!ring || !ring->sched.thread)
|
|
continue;
|
|
kthread_park(ring->sched.thread);
|
|
amd_sched_hw_job_reset(&ring->sched);
|
|
@@ -2326,7 +2326,8 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|
}
|
|
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
|
struct amdgpu_ring *ring = adev->rings[i];
|
|
- if (!ring)
|
|
+
|
|
+ if (!ring || !ring->sched.thread)
|
|
continue;
|
|
|
|
amd_sched_job_recovery(&ring->sched);
|
|
@@ -2335,7 +2336,7 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|
} else {
|
|
dev_err(adev->dev, "asic resume failed (%d).\n", r);
|
|
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
|
- if (adev->rings[i]) {
|
|
+ if (adev->rings[i] && adev->rings[i]->sched.thread) {
|
|
kthread_unpark(adev->rings[i]->sched.thread);
|
|
}
|
|
}
|
|
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
|
|
index b6ac27e31929..797d1f8340b9 100644
|
|
--- a/drivers/gpu/drm/msm/msm_gem.c
|
|
+++ b/drivers/gpu/drm/msm/msm_gem.c
|
|
@@ -91,14 +91,17 @@ static struct page **get_pages(struct drm_gem_object *obj)
|
|
return p;
|
|
}
|
|
|
|
+ msm_obj->pages = p;
|
|
+
|
|
msm_obj->sgt = drm_prime_pages_to_sg(p, npages);
|
|
if (IS_ERR(msm_obj->sgt)) {
|
|
+ void *ptr = ERR_CAST(msm_obj->sgt);
|
|
+
|
|
dev_err(dev->dev, "failed to allocate sgt\n");
|
|
- return ERR_CAST(msm_obj->sgt);
|
|
+ msm_obj->sgt = NULL;
|
|
+ return ptr;
|
|
}
|
|
|
|
- msm_obj->pages = p;
|
|
-
|
|
/* For non-cached buffers, ensure the new pages are clean
|
|
* because display controller, GPU, etc. are not coherent:
|
|
*/
|
|
@@ -121,7 +124,10 @@ static void put_pages(struct drm_gem_object *obj)
|
|
if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
|
|
dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
|
|
msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
|
|
- sg_free_table(msm_obj->sgt);
|
|
+
|
|
+ if (msm_obj->sgt)
|
|
+ sg_free_table(msm_obj->sgt);
|
|
+
|
|
kfree(msm_obj->sgt);
|
|
|
|
if (use_pages(obj))
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
|
|
index 2c2b86d68129..6526a3366087 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
|
|
@@ -106,7 +106,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
|
|
};
|
|
struct nouveau_display *disp = nouveau_display(crtc->dev);
|
|
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
|
|
- int ret, retry = 1;
|
|
+ int ret, retry = 20;
|
|
|
|
do {
|
|
ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
|
|
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
|
|
index e859b3f893f7..6112c32b994f 100644
|
|
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
|
|
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
|
|
@@ -456,6 +456,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
|
|
}
|
|
|
|
static const struct of_device_id td028ttec1_of_match[] = {
|
|
+ { .compatible = "omapdss,tpo,td028ttec1", },
|
|
+ /* keep to not break older DTB */
|
|
{ .compatible = "omapdss,toppoly,td028ttec1", },
|
|
{},
|
|
};
|
|
@@ -475,6 +477,7 @@ static struct spi_driver td028ttec1_spi_driver = {
|
|
|
|
module_spi_driver(td028ttec1_spi_driver);
|
|
|
|
+MODULE_ALIAS("spi:tpo,td028ttec1");
|
|
MODULE_ALIAS("spi:toppoly,td028ttec1");
|
|
MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
|
|
MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
|
|
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
|
|
index 4b83e9eeab06..7def04049498 100644
|
|
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
|
|
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
|
|
@@ -298,7 +298,12 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
|
|
msecs_to_jiffies(100))) {
|
|
dev_err(dmm->dev, "timed out waiting for done\n");
|
|
ret = -ETIMEDOUT;
|
|
+ goto cleanup;
|
|
}
|
|
+
|
|
+ /* Check the engine status before continue */
|
|
+ ret = wait_status(engine, DMM_PATSTATUS_READY |
|
|
+ DMM_PATSTATUS_VALID | DMM_PATSTATUS_DONE);
|
|
}
|
|
|
|
cleanup:
|
|
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
|
|
index f57c0d62c76a..19d8dc3cdd40 100644
|
|
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
|
|
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
|
|
@@ -124,7 +124,7 @@ static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
|
|
struct tilcdc_drm_private *priv = dev->dev_private;
|
|
volatile void __iomem *addr = priv->mmio + reg;
|
|
|
|
-#ifdef iowrite64
|
|
+#if defined(iowrite64) && !defined(iowrite64_is_nonatomic)
|
|
iowrite64(data, addr);
|
|
#else
|
|
__iowmb();
|
|
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
|
|
index 6031cd146556..802afc98e8bd 100644
|
|
--- a/drivers/hsi/clients/ssi_protocol.c
|
|
+++ b/drivers/hsi/clients/ssi_protocol.c
|
|
@@ -989,7 +989,7 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
goto drop;
|
|
/* Pad to 32-bits - FIXME: Revisit*/
|
|
if ((skb->len & 3) && skb_pad(skb, 4 - (skb->len & 3)))
|
|
- goto drop;
|
|
+ goto inc_dropped;
|
|
|
|
/*
|
|
* Modem sends Phonet messages over SSI with its own endianess...
|
|
@@ -1041,8 +1041,9 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
drop2:
|
|
hsi_free_msg(msg);
|
|
drop:
|
|
- dev->stats.tx_dropped++;
|
|
dev_kfree_skb(skb);
|
|
+inc_dropped:
|
|
+ dev->stats.tx_dropped++;
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
|
|
index 0673baf0f2f5..ff579a7c6d00 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
|
|
@@ -46,8 +46,11 @@
|
|
#define TPIU_ITATBCTR0 0xef8
|
|
|
|
/** register definition **/
|
|
+/* FFSR - 0x300 */
|
|
+#define FFSR_FT_STOPPED BIT(1)
|
|
/* FFCR - 0x304 */
|
|
#define FFCR_FON_MAN BIT(6)
|
|
+#define FFCR_STOP_FI BIT(12)
|
|
|
|
/**
|
|
* @base: memory mapped base address for this component.
|
|
@@ -85,10 +88,14 @@ static void tpiu_disable_hw(struct tpiu_drvdata *drvdata)
|
|
{
|
|
CS_UNLOCK(drvdata->base);
|
|
|
|
- /* Clear formatter controle reg. */
|
|
- writel_relaxed(0x0, drvdata->base + TPIU_FFCR);
|
|
+ /* Clear formatter and stop on flush */
|
|
+ writel_relaxed(FFCR_STOP_FI, drvdata->base + TPIU_FFCR);
|
|
/* Generate manual flush */
|
|
- writel_relaxed(FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
|
|
+ writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR);
|
|
+ /* Wait for flush to complete */
|
|
+ coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN, 0);
|
|
+ /* Wait for formatter to stop */
|
|
+ coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED, 1);
|
|
|
|
CS_LOCK(drvdata->base);
|
|
}
|
|
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
|
|
index dfc98df7b1b6..7aa7b9cb6203 100644
|
|
--- a/drivers/i2c/busses/i2c-scmi.c
|
|
+++ b/drivers/i2c/busses/i2c-scmi.c
|
|
@@ -18,6 +18,9 @@
|
|
#define ACPI_SMBUS_HC_CLASS "smbus"
|
|
#define ACPI_SMBUS_HC_DEVICE_NAME "cmi"
|
|
|
|
+/* SMBUS HID definition as supported by Microsoft Windows */
|
|
+#define ACPI_SMBUS_MS_HID "SMB0001"
|
|
+
|
|
ACPI_MODULE_NAME("smbus_cmi");
|
|
|
|
struct smbus_methods_t {
|
|
@@ -51,6 +54,7 @@ static const struct smbus_methods_t ibm_smbus_methods = {
|
|
static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
|
|
{"SMBUS01", (kernel_ulong_t)&smbus_methods},
|
|
{ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
|
|
+ {ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods},
|
|
{"", 0}
|
|
};
|
|
MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
|
|
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
|
|
index 3a557e3181ea..fe94415a0bc7 100644
|
|
--- a/drivers/iio/accel/st_accel_core.c
|
|
+++ b/drivers/iio/accel/st_accel_core.c
|
|
@@ -827,6 +827,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
|
|
int st_accel_common_probe(struct iio_dev *indio_dev)
|
|
{
|
|
struct st_sensor_data *adata = iio_priv(indio_dev);
|
|
+ struct st_sensors_platform_data *pdata =
|
|
+ (struct st_sensors_platform_data *)adata->dev->platform_data;
|
|
int irq = adata->get_irq_data_ready(indio_dev);
|
|
int err;
|
|
|
|
@@ -853,9 +855,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
|
|
&adata->sensor_settings->fs.fs_avl[0];
|
|
adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
|
|
|
|
- if (!adata->dev->platform_data)
|
|
- adata->dev->platform_data =
|
|
- (struct st_sensors_platform_data *)&default_accel_pdata;
|
|
+ if (!pdata)
|
|
+ pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
|
|
|
|
err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
|
|
if (err < 0)
|
|
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
|
|
index ab646a90e3da..af85db50412e 100644
|
|
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
|
|
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
|
|
@@ -215,7 +215,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
|
|
ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id,
|
|
st->poll.index, sizeof(value), &value);
|
|
if (ret < 0 || value < 0)
|
|
- ret = -EINVAL;
|
|
+ return -EINVAL;
|
|
|
|
ret = sensor_hub_get_feature(st->hsdev,
|
|
st->poll.report_id,
|
|
@@ -265,7 +265,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
|
|
st->sensitivity.index, sizeof(value),
|
|
&value);
|
|
if (ret < 0 || value < 0)
|
|
- ret = -EINVAL;
|
|
+ return -EINVAL;
|
|
|
|
ret = sensor_hub_get_feature(st->hsdev,
|
|
st->sensitivity.report_id,
|
|
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
|
|
index 44e46c159a7e..bec60299b6ec 100644
|
|
--- a/drivers/iio/pressure/st_pressure_core.c
|
|
+++ b/drivers/iio/pressure/st_pressure_core.c
|
|
@@ -638,6 +638,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
|
|
int st_press_common_probe(struct iio_dev *indio_dev)
|
|
{
|
|
struct st_sensor_data *press_data = iio_priv(indio_dev);
|
|
+ struct st_sensors_platform_data *pdata =
|
|
+ (struct st_sensors_platform_data *)press_data->dev->platform_data;
|
|
int irq = press_data->get_irq_data_ready(indio_dev);
|
|
int err;
|
|
|
|
@@ -673,10 +675,8 @@ int st_press_common_probe(struct iio_dev *indio_dev)
|
|
press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
|
|
|
|
/* Some devices don't support a data ready pin. */
|
|
- if (!press_data->dev->platform_data &&
|
|
- press_data->sensor_settings->drdy_irq.addr)
|
|
- press_data->dev->platform_data =
|
|
- (struct st_sensors_platform_data *)&default_press_pdata;
|
|
+ if (!pdata && press_data->sensor_settings->drdy_irq.addr)
|
|
+ pdata = (struct st_sensors_platform_data *)&default_press_pdata;
|
|
|
|
err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
|
|
if (err < 0)
|
|
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
|
|
index 30f01613b518..cbe5324c4331 100644
|
|
--- a/drivers/infiniband/core/cma.c
|
|
+++ b/drivers/infiniband/core/cma.c
|
|
@@ -4039,6 +4039,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
|
|
struct cma_multicast *mc;
|
|
int ret;
|
|
|
|
+ if (!id->device)
|
|
+ return -EINVAL;
|
|
+
|
|
id_priv = container_of(id, struct rdma_id_private, id);
|
|
if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
|
|
!cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
|
|
@@ -4336,7 +4339,7 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb)
|
|
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR))
|
|
goto out;
|
|
if (ibnl_put_attr(skb, nlh,
|
|
- rdma_addr_size(cma_src_addr(id_priv)),
|
|
+ rdma_addr_size(cma_dst_addr(id_priv)),
|
|
cma_dst_addr(id_priv),
|
|
RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
|
|
goto out;
|
|
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c
|
|
index ade71e7f0131..2fe4c2c921de 100644
|
|
--- a/drivers/infiniband/core/iwpm_util.c
|
|
+++ b/drivers/infiniband/core/iwpm_util.c
|
|
@@ -664,6 +664,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid)
|
|
}
|
|
skb_num++;
|
|
spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
|
|
+ ret = -EINVAL;
|
|
for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
|
|
hlist_for_each_entry(map_info, &iwpm_hash_bucket[i],
|
|
hlist_node) {
|
|
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
|
|
index 6840d3c5cd64..017a09ceba3f 100644
|
|
--- a/drivers/infiniband/core/ucma.c
|
|
+++ b/drivers/infiniband/core/ucma.c
|
|
@@ -1330,7 +1330,7 @@ static ssize_t ucma_process_join(struct ucma_file *file,
|
|
return -ENOSPC;
|
|
|
|
addr = (struct sockaddr *) &cmd->addr;
|
|
- if (!cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
|
|
+ if (cmd->addr_size != rdma_addr_size(addr))
|
|
return -EINVAL;
|
|
|
|
if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER)
|
|
@@ -1398,6 +1398,9 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
|
|
join_cmd.uid = cmd.uid;
|
|
join_cmd.id = cmd.id;
|
|
join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
|
|
+ if (!join_cmd.addr_size)
|
|
+ return -EINVAL;
|
|
+
|
|
join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER;
|
|
memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
|
|
|
|
@@ -1413,6 +1416,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
|
|
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
|
|
return -EFAULT;
|
|
|
|
+ if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
|
|
+ return -EINVAL;
|
|
+
|
|
return ucma_process_join(file, &cmd, out_len);
|
|
}
|
|
|
|
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
|
|
index 8e973a2993a6..e74aa1d60fdb 100644
|
|
--- a/drivers/infiniband/core/umem.c
|
|
+++ b/drivers/infiniband/core/umem.c
|
|
@@ -357,7 +357,7 @@ int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length,
|
|
+ ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->npages, dst, length,
|
|
offset + ib_umem_offset(umem));
|
|
|
|
if (ret < 0)
|
|
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
|
|
index d118ffe0bfb6..4b717cf50d27 100644
|
|
--- a/drivers/infiniband/core/uverbs_cmd.c
|
|
+++ b/drivers/infiniband/core/uverbs_cmd.c
|
|
@@ -2491,9 +2491,13 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
|
|
|
|
static void *alloc_wr(size_t wr_size, __u32 num_sge)
|
|
{
|
|
+ if (num_sge >= (U32_MAX - ALIGN(wr_size, sizeof (struct ib_sge))) /
|
|
+ sizeof (struct ib_sge))
|
|
+ return NULL;
|
|
+
|
|
return kmalloc(ALIGN(wr_size, sizeof (struct ib_sge)) +
|
|
num_sge * sizeof (struct ib_sge), GFP_KERNEL);
|
|
-};
|
|
+}
|
|
|
|
ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
|
|
struct ib_device *ib_dev,
|
|
@@ -2720,6 +2724,13 @@ static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
|
|
goto err;
|
|
}
|
|
|
|
+ if (user_wr->num_sge >=
|
|
+ (U32_MAX - ALIGN(sizeof *next, sizeof (struct ib_sge))) /
|
|
+ sizeof (struct ib_sge)) {
|
|
+ ret = -EINVAL;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
|
|
user_wr->num_sge * sizeof (struct ib_sge),
|
|
GFP_KERNEL);
|
|
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
|
|
index 3be62ef154d1..7853b0caad32 100644
|
|
--- a/drivers/infiniband/hw/hfi1/chip.c
|
|
+++ b/drivers/infiniband/hw/hfi1/chip.c
|
|
@@ -6379,18 +6379,17 @@ static void lcb_shutdown(struct hfi1_devdata *dd, int abort)
|
|
*
|
|
* The expectation is that the caller of this routine would have taken
|
|
* care of properly transitioning the link into the correct state.
|
|
+ * NOTE: the caller needs to acquire the dd->dc8051_lock lock
|
|
+ * before calling this function.
|
|
*/
|
|
-static void dc_shutdown(struct hfi1_devdata *dd)
|
|
+static void _dc_shutdown(struct hfi1_devdata *dd)
|
|
{
|
|
- unsigned long flags;
|
|
+ lockdep_assert_held(&dd->dc8051_lock);
|
|
|
|
- spin_lock_irqsave(&dd->dc8051_lock, flags);
|
|
- if (dd->dc_shutdown) {
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
+ if (dd->dc_shutdown)
|
|
return;
|
|
- }
|
|
+
|
|
dd->dc_shutdown = 1;
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
/* Shutdown the LCB */
|
|
lcb_shutdown(dd, 1);
|
|
/*
|
|
@@ -6401,35 +6400,45 @@ static void dc_shutdown(struct hfi1_devdata *dd)
|
|
write_csr(dd, DC_DC8051_CFG_RST, 0x1);
|
|
}
|
|
|
|
+static void dc_shutdown(struct hfi1_devdata *dd)
|
|
+{
|
|
+ mutex_lock(&dd->dc8051_lock);
|
|
+ _dc_shutdown(dd);
|
|
+ mutex_unlock(&dd->dc8051_lock);
|
|
+}
|
|
+
|
|
/*
|
|
* Calling this after the DC has been brought out of reset should not
|
|
* do any damage.
|
|
+ * NOTE: the caller needs to acquire the dd->dc8051_lock lock
|
|
+ * before calling this function.
|
|
*/
|
|
-static void dc_start(struct hfi1_devdata *dd)
|
|
+static void _dc_start(struct hfi1_devdata *dd)
|
|
{
|
|
- unsigned long flags;
|
|
- int ret;
|
|
+ lockdep_assert_held(&dd->dc8051_lock);
|
|
|
|
- spin_lock_irqsave(&dd->dc8051_lock, flags);
|
|
if (!dd->dc_shutdown)
|
|
- goto done;
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
+ return;
|
|
+
|
|
/* Take the 8051 out of reset */
|
|
write_csr(dd, DC_DC8051_CFG_RST, 0ull);
|
|
/* Wait until 8051 is ready */
|
|
- ret = wait_fm_ready(dd, TIMEOUT_8051_START);
|
|
- if (ret) {
|
|
+ if (wait_fm_ready(dd, TIMEOUT_8051_START))
|
|
dd_dev_err(dd, "%s: timeout starting 8051 firmware\n",
|
|
__func__);
|
|
- }
|
|
+
|
|
/* Take away reset for LCB and RX FPE (set in lcb_shutdown). */
|
|
write_csr(dd, DCC_CFG_RESET, 0x10);
|
|
/* lcb_shutdown() with abort=1 does not restore these */
|
|
write_csr(dd, DC_LCB_ERR_EN, dd->lcb_err_en);
|
|
- spin_lock_irqsave(&dd->dc8051_lock, flags);
|
|
dd->dc_shutdown = 0;
|
|
-done:
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
+}
|
|
+
|
|
+static void dc_start(struct hfi1_devdata *dd)
|
|
+{
|
|
+ mutex_lock(&dd->dc8051_lock);
|
|
+ _dc_start(dd);
|
|
+ mutex_unlock(&dd->dc8051_lock);
|
|
}
|
|
|
|
/*
|
|
@@ -8418,16 +8427,11 @@ static int do_8051_command(
|
|
{
|
|
u64 reg, completed;
|
|
int return_code;
|
|
- unsigned long flags;
|
|
unsigned long timeout;
|
|
|
|
hfi1_cdbg(DC8051, "type %d, data 0x%012llx", type, in_data);
|
|
|
|
- /*
|
|
- * Alternative to holding the lock for a long time:
|
|
- * - keep busy wait - have other users bounce off
|
|
- */
|
|
- spin_lock_irqsave(&dd->dc8051_lock, flags);
|
|
+ mutex_lock(&dd->dc8051_lock);
|
|
|
|
/* We can't send any commands to the 8051 if it's in reset */
|
|
if (dd->dc_shutdown) {
|
|
@@ -8453,10 +8457,8 @@ static int do_8051_command(
|
|
return_code = -ENXIO;
|
|
goto fail;
|
|
}
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
- dc_shutdown(dd);
|
|
- dc_start(dd);
|
|
- spin_lock_irqsave(&dd->dc8051_lock, flags);
|
|
+ _dc_shutdown(dd);
|
|
+ _dc_start(dd);
|
|
}
|
|
|
|
/*
|
|
@@ -8534,8 +8536,7 @@ static int do_8051_command(
|
|
write_csr(dd, DC_DC8051_CFG_HOST_CMD_0, 0);
|
|
|
|
fail:
|
|
- spin_unlock_irqrestore(&dd->dc8051_lock, flags);
|
|
-
|
|
+ mutex_unlock(&dd->dc8051_lock);
|
|
return return_code;
|
|
}
|
|
|
|
@@ -11849,6 +11850,10 @@ static void free_cntrs(struct hfi1_devdata *dd)
|
|
dd->scntrs = NULL;
|
|
kfree(dd->cntrnames);
|
|
dd->cntrnames = NULL;
|
|
+ if (dd->update_cntr_wq) {
|
|
+ destroy_workqueue(dd->update_cntr_wq);
|
|
+ dd->update_cntr_wq = NULL;
|
|
+ }
|
|
}
|
|
|
|
static u64 read_dev_port_cntr(struct hfi1_devdata *dd, struct cntr_entry *entry,
|
|
@@ -12004,7 +12009,7 @@ u64 write_port_cntr(struct hfi1_pportdata *ppd, int index, int vl, u64 data)
|
|
return write_dev_port_cntr(ppd->dd, entry, sval, ppd, vl, data);
|
|
}
|
|
|
|
-static void update_synth_timer(unsigned long opaque)
|
|
+static void do_update_synth_timer(struct work_struct *work)
|
|
{
|
|
u64 cur_tx;
|
|
u64 cur_rx;
|
|
@@ -12013,8 +12018,8 @@ static void update_synth_timer(unsigned long opaque)
|
|
int i, j, vl;
|
|
struct hfi1_pportdata *ppd;
|
|
struct cntr_entry *entry;
|
|
-
|
|
- struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque;
|
|
+ struct hfi1_devdata *dd = container_of(work, struct hfi1_devdata,
|
|
+ update_cntr_work);
|
|
|
|
/*
|
|
* Rather than keep beating on the CSRs pick a minimal set that we can
|
|
@@ -12097,7 +12102,13 @@ static void update_synth_timer(unsigned long opaque)
|
|
} else {
|
|
hfi1_cdbg(CNTR, "[%d] No update necessary", dd->unit);
|
|
}
|
|
+}
|
|
+
|
|
+static void update_synth_timer(unsigned long opaque)
|
|
+{
|
|
+ struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque;
|
|
|
|
+ queue_work(dd->update_cntr_wq, &dd->update_cntr_work);
|
|
mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME);
|
|
}
|
|
|
|
@@ -12333,6 +12344,13 @@ static int init_cntrs(struct hfi1_devdata *dd)
|
|
if (init_cpu_counters(dd))
|
|
goto bail;
|
|
|
|
+ dd->update_cntr_wq = alloc_ordered_workqueue("hfi1_update_cntr_%d",
|
|
+ WQ_MEM_RECLAIM, dd->unit);
|
|
+ if (!dd->update_cntr_wq)
|
|
+ goto bail;
|
|
+
|
|
+ INIT_WORK(&dd->update_cntr_work, do_update_synth_timer);
|
|
+
|
|
mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME);
|
|
return 0;
|
|
bail:
|
|
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
|
|
index cc87fd4e534b..a3279f3d2578 100644
|
|
--- a/drivers/infiniband/hw/hfi1/hfi.h
|
|
+++ b/drivers/infiniband/hw/hfi1/hfi.h
|
|
@@ -475,7 +475,7 @@ struct rvt_sge_state;
|
|
#define HFI1_PART_ENFORCE_OUT 0x2
|
|
|
|
/* how often we check for synthetic counter wrap around */
|
|
-#define SYNTH_CNT_TIME 2
|
|
+#define SYNTH_CNT_TIME 3
|
|
|
|
/* Counter flags */
|
|
#define CNTR_NORMAL 0x0 /* Normal counters, just read register */
|
|
@@ -929,8 +929,9 @@ struct hfi1_devdata {
|
|
spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */
|
|
/* around rcd and (user ctxts) ctxt_cnt use (intr vs free) */
|
|
spinlock_t uctxt_lock; /* rcd and user context changes */
|
|
- /* exclusive access to 8051 */
|
|
- spinlock_t dc8051_lock;
|
|
+ struct mutex dc8051_lock; /* exclusive access to 8051 */
|
|
+ struct workqueue_struct *update_cntr_wq;
|
|
+ struct work_struct update_cntr_work;
|
|
/* exclusive access to 8051 memory */
|
|
spinlock_t dc8051_memlock;
|
|
int dc8051_timed_out; /* remember if the 8051 timed out */
|
|
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
|
|
index a3dd27b1305d..84a97f3f9299 100644
|
|
--- a/drivers/infiniband/hw/hfi1/init.c
|
|
+++ b/drivers/infiniband/hw/hfi1/init.c
|
|
@@ -1078,11 +1078,11 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra)
|
|
spin_lock_init(&dd->uctxt_lock);
|
|
spin_lock_init(&dd->hfi1_diag_trans_lock);
|
|
spin_lock_init(&dd->sc_init_lock);
|
|
- spin_lock_init(&dd->dc8051_lock);
|
|
spin_lock_init(&dd->dc8051_memlock);
|
|
seqlock_init(&dd->sc2vl_lock);
|
|
spin_lock_init(&dd->sde_map_lock);
|
|
spin_lock_init(&dd->pio_map_lock);
|
|
+ mutex_init(&dd->dc8051_lock);
|
|
init_waitqueue_head(&dd->event_queue);
|
|
|
|
dd->int_counter = alloc_percpu(u64);
|
|
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
|
|
index c41c8d0a4ac0..19bc1c2186ff 100644
|
|
--- a/drivers/infiniband/hw/mlx4/main.c
|
|
+++ b/drivers/infiniband/hw/mlx4/main.c
|
|
@@ -1168,7 +1168,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
|
/* need to protect from a race on closing the vma as part of
|
|
* mlx4_ib_vma_close().
|
|
*/
|
|
- down_read(&owning_mm->mmap_sem);
|
|
+ down_write(&owning_mm->mmap_sem);
|
|
for (i = 0; i < HW_BAR_COUNT; i++) {
|
|
vma = context->hw_bar_info[i].vma;
|
|
if (!vma)
|
|
@@ -1182,11 +1182,13 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
|
BUG_ON(1);
|
|
}
|
|
|
|
+ context->hw_bar_info[i].vma->vm_flags &=
|
|
+ ~(VM_SHARED | VM_MAYSHARE);
|
|
/* context going to be destroyed, should not access ops any more */
|
|
context->hw_bar_info[i].vma->vm_ops = NULL;
|
|
}
|
|
|
|
- up_read(&owning_mm->mmap_sem);
|
|
+ up_write(&owning_mm->mmap_sem);
|
|
mmput(owning_mm);
|
|
put_task_struct(owning_process);
|
|
}
|
|
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
|
|
index 9cdcff77b9a8..fc62a7ded734 100644
|
|
--- a/drivers/infiniband/hw/mlx5/cq.c
|
|
+++ b/drivers/infiniband/hw/mlx5/cq.c
|
|
@@ -172,6 +172,8 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
|
|
struct mlx5_ib_srq *srq;
|
|
struct mlx5_ib_wq *wq;
|
|
u16 wqe_ctr;
|
|
+ u8 roce_packet_type;
|
|
+ bool vlan_present;
|
|
u8 g;
|
|
|
|
if (qp->ibqp.srq || qp->ibqp.xrcd) {
|
|
@@ -223,7 +225,6 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
|
|
break;
|
|
}
|
|
wc->slid = be16_to_cpu(cqe->slid);
|
|
- wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
|
|
wc->src_qp = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
|
|
wc->dlid_path_bits = cqe->ml_path;
|
|
g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
|
|
@@ -237,10 +238,22 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
|
|
wc->pkey_index = 0;
|
|
}
|
|
|
|
- if (ll != IB_LINK_LAYER_ETHERNET)
|
|
+ if (ll != IB_LINK_LAYER_ETHERNET) {
|
|
+ wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
|
|
return;
|
|
+ }
|
|
+
|
|
+ vlan_present = cqe->l4_l3_hdr_type & 0x1;
|
|
+ roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
|
|
+ if (vlan_present) {
|
|
+ wc->vlan_id = (be16_to_cpu(cqe->vlan_info)) & 0xfff;
|
|
+ wc->sl = (be16_to_cpu(cqe->vlan_info) >> 13) & 0x7;
|
|
+ wc->wc_flags |= IB_WC_WITH_VLAN;
|
|
+ } else {
|
|
+ wc->sl = 0;
|
|
+ }
|
|
|
|
- switch (wc->sl & 0x3) {
|
|
+ switch (roce_packet_type) {
|
|
case MLX5_CQE_ROCE_L3_HEADER_TYPE_GRH:
|
|
wc->network_hdr_type = RDMA_NETWORK_IB;
|
|
break;
|
|
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
|
|
index 5e29fbd3a5a0..d7da1dca765f 100644
|
|
--- a/drivers/infiniband/hw/mlx5/main.c
|
|
+++ b/drivers/infiniband/hw/mlx5/main.c
|
|
@@ -1313,7 +1313,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
|
/* need to protect from a race on closing the vma as part of
|
|
* mlx5_ib_vma_close.
|
|
*/
|
|
- down_read(&owning_mm->mmap_sem);
|
|
+ down_write(&owning_mm->mmap_sem);
|
|
list_for_each_entry_safe(vma_private, n, &context->vma_private_list,
|
|
list) {
|
|
vma = vma_private->vma;
|
|
@@ -1323,11 +1323,12 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
|
/* context going to be destroyed, should
|
|
* not access ops any more.
|
|
*/
|
|
+ vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
|
|
vma->vm_ops = NULL;
|
|
list_del(&vma_private->list);
|
|
kfree(vma_private);
|
|
}
|
|
- up_read(&owning_mm->mmap_sem);
|
|
+ up_write(&owning_mm->mmap_sem);
|
|
mmput(owning_mm);
|
|
put_task_struct(owning_process);
|
|
}
|
|
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
|
|
index fdd156101a72..403df3591d29 100644
|
|
--- a/drivers/infiniband/hw/mlx5/qp.c
|
|
+++ b/drivers/infiniband/hw/mlx5/qp.c
|
|
@@ -1130,7 +1130,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
|
|
ib_umem_release(sq->ubuffer.umem);
|
|
}
|
|
|
|
-static int get_rq_pas_size(void *qpc)
|
|
+static size_t get_rq_pas_size(void *qpc)
|
|
{
|
|
u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
|
|
u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
|
|
@@ -1146,7 +1146,8 @@ static int get_rq_pas_size(void *qpc)
|
|
}
|
|
|
|
static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
|
|
- struct mlx5_ib_rq *rq, void *qpin)
|
|
+ struct mlx5_ib_rq *rq, void *qpin,
|
|
+ size_t qpinlen)
|
|
{
|
|
struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
|
|
__be64 *pas;
|
|
@@ -1155,9 +1156,12 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
|
|
void *rqc;
|
|
void *wq;
|
|
void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
|
|
- int inlen;
|
|
+ size_t rq_pas_size = get_rq_pas_size(qpc);
|
|
+ size_t inlen;
|
|
int err;
|
|
- u32 rq_pas_size = get_rq_pas_size(qpc);
|
|
+
|
|
+ if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas))
|
|
+ return -EINVAL;
|
|
|
|
inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
|
|
in = mlx5_vzalloc(inlen);
|
|
@@ -1235,7 +1239,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
|
|
}
|
|
|
|
static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
|
- u32 *in,
|
|
+ u32 *in, size_t inlen,
|
|
struct ib_pd *pd)
|
|
{
|
|
struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
|
|
@@ -1262,7 +1266,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
|
if (qp->rq.wqe_cnt) {
|
|
rq->base.container_mibqp = qp;
|
|
|
|
- err = create_raw_packet_qp_rq(dev, rq, in);
|
|
+ err = create_raw_packet_qp_rq(dev, rq, in, inlen);
|
|
if (err)
|
|
goto err_destroy_sq;
|
|
|
|
@@ -1753,10 +1757,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|
qp->flags |= MLX5_IB_QP_LSO;
|
|
}
|
|
|
|
+ if (inlen < 0) {
|
|
+ err = -EINVAL;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
|
|
qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
|
|
raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
|
|
- err = create_raw_packet_qp(dev, qp, in, pd);
|
|
+ err = create_raw_packet_qp(dev, qp, in, inlen, pd);
|
|
} else {
|
|
err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
|
|
}
|
|
@@ -1796,6 +1805,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|
else if (qp->create_type == MLX5_QP_KERNEL)
|
|
destroy_qp_kernel(dev, qp);
|
|
|
|
+err:
|
|
kvfree(in);
|
|
return err;
|
|
}
|
|
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
|
|
index d61fd2c727c0..5c1dbe2f8757 100644
|
|
--- a/drivers/infiniband/hw/mlx5/srq.c
|
|
+++ b/drivers/infiniband/hw/mlx5/srq.c
|
|
@@ -243,8 +243,8 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
|
|
{
|
|
struct mlx5_ib_dev *dev = to_mdev(pd->device);
|
|
struct mlx5_ib_srq *srq;
|
|
- int desc_size;
|
|
- int buf_size;
|
|
+ size_t desc_size;
|
|
+ size_t buf_size;
|
|
int err;
|
|
struct mlx5_srq_attr in = {0};
|
|
__u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
|
|
@@ -268,15 +268,18 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
|
|
|
|
desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
|
|
srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
|
|
+ if (desc_size == 0 || srq->msrq.max_gs > desc_size)
|
|
+ return ERR_PTR(-EINVAL);
|
|
desc_size = roundup_pow_of_two(desc_size);
|
|
- desc_size = max_t(int, 32, desc_size);
|
|
+ desc_size = max_t(size_t, 32, desc_size);
|
|
+ if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg))
|
|
+ return ERR_PTR(-EINVAL);
|
|
srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
|
|
sizeof(struct mlx5_wqe_data_seg);
|
|
srq->msrq.wqe_shift = ilog2(desc_size);
|
|
buf_size = srq->msrq.max * desc_size;
|
|
- mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n",
|
|
- desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
|
|
- srq->msrq.max_avail_gather);
|
|
+ if (buf_size < desc_size)
|
|
+ return ERR_PTR(-EINVAL);
|
|
in.type = init_attr->srq_type;
|
|
|
|
if (pd->uobject)
|
|
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
|
|
index 8bef09a8c49f..265943069b35 100644
|
|
--- a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
|
|
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
|
|
@@ -836,7 +836,7 @@ void ocrdma_add_port_stats(struct ocrdma_dev *dev)
|
|
|
|
dev->reset_stats.type = OCRDMA_RESET_STATS;
|
|
dev->reset_stats.dev = dev;
|
|
- if (!debugfs_create_file("reset_stats", S_IRUSR, dev->dir,
|
|
+ if (!debugfs_create_file("reset_stats", 0200, dev->dir,
|
|
&dev->reset_stats, &ocrdma_dbg_ops))
|
|
goto err;
|
|
|
|
diff --git a/drivers/infiniband/sw/rdmavt/ah.c b/drivers/infiniband/sw/rdmavt/ah.c
|
|
index 16c446142c2a..b0f09fb45c72 100644
|
|
--- a/drivers/infiniband/sw/rdmavt/ah.c
|
|
+++ b/drivers/infiniband/sw/rdmavt/ah.c
|
|
@@ -119,7 +119,7 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
|
|
|
|
spin_lock_irqsave(&dev->n_ahs_lock, flags);
|
|
if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
|
|
- spin_unlock(&dev->n_ahs_lock);
|
|
+ spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
|
|
kfree(ah);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
index 8c0ddd7165ae..0d25dc84d294 100644
|
|
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
|
|
@@ -471,8 +471,6 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
|
|
state = RESPST_ERR_LENGTH;
|
|
goto err;
|
|
}
|
|
-
|
|
- qp->resp.resid = mtu;
|
|
} else {
|
|
if (pktlen != resid) {
|
|
state = RESPST_ERR_LENGTH;
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
|
|
index 335bd2c9e16e..34122c96522b 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
|
|
@@ -974,6 +974,19 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv)
|
|
*/
|
|
priv->dev->broadcast[8] = priv->pkey >> 8;
|
|
priv->dev->broadcast[9] = priv->pkey & 0xff;
|
|
+
|
|
+ /*
|
|
+ * Update the broadcast address in the priv->broadcast object,
|
|
+ * in case it already exists, otherwise no one will do that.
|
|
+ */
|
|
+ if (priv->broadcast) {
|
|
+ spin_lock_irq(&priv->lock);
|
|
+ memcpy(priv->broadcast->mcmember.mgid.raw,
|
|
+ priv->dev->broadcast + 4,
|
|
+ sizeof(union ib_gid));
|
|
+ spin_unlock_irq(&priv->lock);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
index e37e918cb935..0df7d4504c06 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
@@ -799,6 +799,22 @@ static void path_rec_completion(int status,
|
|
spin_lock_irqsave(&priv->lock, flags);
|
|
|
|
if (!IS_ERR_OR_NULL(ah)) {
|
|
+ /*
|
|
+ * pathrec.dgid is used as the database key from the LLADDR,
|
|
+ * it must remain unchanged even if the SA returns a different
|
|
+ * GID to use in the AH.
|
|
+ */
|
|
+ if (memcmp(pathrec->dgid.raw, path->pathrec.dgid.raw,
|
|
+ sizeof(union ib_gid))) {
|
|
+ ipoib_dbg(
|
|
+ priv,
|
|
+ "%s got PathRec for gid %pI6 while asked for %pI6\n",
|
|
+ dev->name, pathrec->dgid.raw,
|
|
+ path->pathrec.dgid.raw);
|
|
+ memcpy(pathrec->dgid.raw, path->pathrec.dgid.raw,
|
|
+ sizeof(union ib_gid));
|
|
+ }
|
|
+
|
|
path->pathrec = *pathrec;
|
|
|
|
old_ah = path->ah;
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
|
|
index 6b6826f3e446..8f79caedf905 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
|
|
@@ -487,6 +487,9 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast)
|
|
!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
|
|
return -EINVAL;
|
|
|
|
+ init_completion(&mcast->done);
|
|
+ set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
|
|
+
|
|
ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw);
|
|
|
|
rec.mgid = mcast->mcmember.mgid;
|
|
@@ -645,8 +648,6 @@ void ipoib_mcast_join_task(struct work_struct *work)
|
|
if (mcast->backoff == 1 ||
|
|
time_after_eq(jiffies, mcast->delay_until)) {
|
|
/* Found the next unjoined group */
|
|
- init_completion(&mcast->done);
|
|
- set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
|
|
if (ipoib_mcast_join(dev, mcast)) {
|
|
spin_unlock_irq(&priv->lock);
|
|
return;
|
|
@@ -666,11 +667,9 @@ void ipoib_mcast_join_task(struct work_struct *work)
|
|
queue_delayed_work(priv->wq, &priv->mcast_task,
|
|
delay_until - jiffies);
|
|
}
|
|
- if (mcast) {
|
|
- init_completion(&mcast->done);
|
|
- set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
|
|
+ if (mcast)
|
|
ipoib_mcast_join(dev, mcast);
|
|
- }
|
|
+
|
|
spin_unlock_irq(&priv->lock);
|
|
}
|
|
|
|
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
|
|
index 0983470929bd..b879d21b7548 100644
|
|
--- a/drivers/infiniband/ulp/isert/ib_isert.c
|
|
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
|
|
@@ -2098,6 +2098,9 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn,
|
|
u32 rkey, offset;
|
|
int ret;
|
|
|
|
+ if (cmd->ctx_init_done)
|
|
+ goto rdma_ctx_post;
|
|
+
|
|
if (dir == DMA_FROM_DEVICE) {
|
|
addr = cmd->write_va;
|
|
rkey = cmd->write_stag;
|
|
@@ -2125,11 +2128,15 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn,
|
|
se_cmd->t_data_sg, se_cmd->t_data_nents,
|
|
offset, addr, rkey, dir);
|
|
}
|
|
+
|
|
if (ret < 0) {
|
|
isert_err("Cmd: %p failed to prepare RDMA res\n", cmd);
|
|
return ret;
|
|
}
|
|
|
|
+ cmd->ctx_init_done = true;
|
|
+
|
|
+rdma_ctx_post:
|
|
ret = rdma_rw_ctx_post(&cmd->rw, conn->qp, port_num, cqe, chain_wr);
|
|
if (ret < 0)
|
|
isert_err("Cmd: %p failed to post RDMA res\n", cmd);
|
|
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
|
|
index c02ada57d7f5..85bd19753d55 100644
|
|
--- a/drivers/infiniband/ulp/isert/ib_isert.h
|
|
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
|
|
@@ -124,6 +124,7 @@ struct isert_cmd {
|
|
struct rdma_rw_ctx rw;
|
|
struct work_struct comp_work;
|
|
struct scatterlist sg;
|
|
+ bool ctx_init_done;
|
|
};
|
|
|
|
static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc)
|
|
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c
|
|
index 603fc2fadf05..12b20840fb74 100644
|
|
--- a/drivers/input/misc/twl4030-pwrbutton.c
|
|
+++ b/drivers/input/misc/twl4030-pwrbutton.c
|
|
@@ -70,7 +70,7 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev)
|
|
pwr->phys = "twl4030_pwrbutton/input0";
|
|
pwr->dev.parent = &pdev->dev;
|
|
|
|
- err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq,
|
|
+ err = devm_request_threaded_irq(&pdev->dev, irq, NULL, powerbutton_irq,
|
|
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
|
|
IRQF_ONESHOT,
|
|
"twl4030_pwrbutton", pwr);
|
|
diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c
|
|
index 71b5a634cf6d..e7bb155911d0 100644
|
|
--- a/drivers/input/touchscreen/ar1021_i2c.c
|
|
+++ b/drivers/input/touchscreen/ar1021_i2c.c
|
|
@@ -152,7 +152,7 @@ static int __maybe_unused ar1021_i2c_resume(struct device *dev)
|
|
static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume);
|
|
|
|
static const struct i2c_device_id ar1021_i2c_id[] = {
|
|
- { "MICROCHIP_AR1021_I2C", 0 },
|
|
+ { "ar1021", 0 },
|
|
{ },
|
|
};
|
|
MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
|
|
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
|
|
index cb72e0011310..3a1c40684213 100644
|
|
--- a/drivers/iommu/intel-svm.c
|
|
+++ b/drivers/iommu/intel-svm.c
|
|
@@ -127,6 +127,7 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)
|
|
pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n",
|
|
iommu->name);
|
|
dmar_free_hwirq(irq);
|
|
+ iommu->pr_irq = 0;
|
|
goto err;
|
|
}
|
|
dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
|
|
@@ -142,9 +143,11 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
|
|
dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
|
|
dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
|
|
|
|
- free_irq(iommu->pr_irq, iommu);
|
|
- dmar_free_hwirq(iommu->pr_irq);
|
|
- iommu->pr_irq = 0;
|
|
+ if (iommu->pr_irq) {
|
|
+ free_irq(iommu->pr_irq, iommu);
|
|
+ dmar_free_hwirq(iommu->pr_irq);
|
|
+ iommu->pr_irq = 0;
|
|
+ }
|
|
|
|
free_pages((unsigned long)iommu->prq, PRQ_ORDER);
|
|
iommu->prq = NULL;
|
|
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
|
|
index e2583cce2cc1..54556713c8d1 100644
|
|
--- a/drivers/iommu/omap-iommu.c
|
|
+++ b/drivers/iommu/omap-iommu.c
|
|
@@ -1299,6 +1299,7 @@ static int __init omap_iommu_init(void)
|
|
const unsigned long flags = SLAB_HWCACHE_ALIGN;
|
|
size_t align = 1 << 10; /* L2 pagetable alignement */
|
|
struct device_node *np;
|
|
+ int ret;
|
|
|
|
np = of_find_matching_node(NULL, omap_iommu_of_match);
|
|
if (!np)
|
|
@@ -1312,11 +1313,25 @@ static int __init omap_iommu_init(void)
|
|
return -ENOMEM;
|
|
iopte_cachep = p;
|
|
|
|
- bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
|
|
-
|
|
omap_iommu_debugfs_init();
|
|
|
|
- return platform_driver_register(&omap_iommu_driver);
|
|
+ ret = platform_driver_register(&omap_iommu_driver);
|
|
+ if (ret) {
|
|
+ pr_err("%s: failed to register driver\n", __func__);
|
|
+ goto fail_driver;
|
|
+ }
|
|
+
|
|
+ ret = bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
|
|
+ if (ret)
|
|
+ goto fail_bus;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+fail_bus:
|
|
+ platform_driver_unregister(&omap_iommu_driver);
|
|
+fail_driver:
|
|
+ kmem_cache_destroy(iopte_cachep);
|
|
+ return ret;
|
|
}
|
|
subsys_initcall(omap_iommu_init);
|
|
/* must be ready before omap3isp is probed */
|
|
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
|
|
index d74374f25392..abf696b49dd7 100644
|
|
--- a/drivers/irqchip/irq-mips-gic.c
|
|
+++ b/drivers/irqchip/irq-mips-gic.c
|
|
@@ -55,6 +55,7 @@ static unsigned int gic_cpu_pin;
|
|
static unsigned int timer_cpu_pin;
|
|
static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
|
|
DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
|
|
+DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
|
|
|
|
static void __gic_irq_dispatch(void);
|
|
|
|
@@ -746,17 +747,17 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
|
return gic_setup_dev_chip(d, virq, spec->hwirq);
|
|
} else {
|
|
- base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs);
|
|
+ base_hwirq = find_first_bit(ipi_available, gic_shared_intrs);
|
|
if (base_hwirq == gic_shared_intrs) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
/* check that we have enough space */
|
|
for (i = base_hwirq; i < nr_irqs; i++) {
|
|
- if (!test_bit(i, ipi_resrv))
|
|
+ if (!test_bit(i, ipi_available))
|
|
return -EBUSY;
|
|
}
|
|
- bitmap_clear(ipi_resrv, base_hwirq, nr_irqs);
|
|
+ bitmap_clear(ipi_available, base_hwirq, nr_irqs);
|
|
|
|
/* map the hwirq for each cpu consecutively */
|
|
i = 0;
|
|
@@ -787,7 +788,7 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
|
return 0;
|
|
error:
|
|
- bitmap_set(ipi_resrv, base_hwirq, nr_irqs);
|
|
+ bitmap_set(ipi_available, base_hwirq, nr_irqs);
|
|
return ret;
|
|
}
|
|
|
|
@@ -802,7 +803,7 @@ void gic_irq_domain_free(struct irq_domain *d, unsigned int virq,
|
|
return;
|
|
|
|
base_hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(data));
|
|
- bitmap_set(ipi_resrv, base_hwirq, nr_irqs);
|
|
+ bitmap_set(ipi_available, base_hwirq, nr_irqs);
|
|
}
|
|
|
|
int gic_irq_domain_match(struct irq_domain *d, struct device_node *node,
|
|
@@ -1066,6 +1067,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
|
|
2 * gic_vpes);
|
|
}
|
|
|
|
+ bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
|
|
gic_basic_init();
|
|
}
|
|
|
|
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
|
|
index d70d4a5273b8..454ed4dc6ec1 100644
|
|
--- a/drivers/leds/led-core.c
|
|
+++ b/drivers/leds/led-core.c
|
|
@@ -186,8 +186,9 @@ void led_blink_set(struct led_classdev *led_cdev,
|
|
unsigned long *delay_on,
|
|
unsigned long *delay_off)
|
|
{
|
|
- led_stop_software_blink(led_cdev);
|
|
+ del_timer_sync(&led_cdev->blink_timer);
|
|
|
|
+ led_cdev->flags &= ~LED_BLINK_SW;
|
|
led_cdev->flags &= ~LED_BLINK_ONESHOT;
|
|
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
|
|
|
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
|
|
index b19b551bb34b..18a4271bf569 100644
|
|
--- a/drivers/md/raid10.c
|
|
+++ b/drivers/md/raid10.c
|
|
@@ -2704,6 +2704,11 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
|
|
list_add(&r10_bio->retry_list, &conf->bio_end_io_list);
|
|
conf->nr_queued++;
|
|
spin_unlock_irq(&conf->device_lock);
|
|
+ /*
|
|
+ * In case freeze_array() is waiting for condition
|
|
+ * nr_pending == nr_queued + extra to be true.
|
|
+ */
|
|
+ wake_up(&conf->wait_barrier);
|
|
md_wakeup_thread(conf->mddev->thread);
|
|
} else {
|
|
if (test_bit(R10BIO_WriteError,
|
|
@@ -4084,6 +4089,7 @@ static int raid10_start_reshape(struct mddev *mddev)
|
|
diff = 0;
|
|
if (first || diff < min_offset_diff)
|
|
min_offset_diff = diff;
|
|
+ first = 0;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
|
|
index b5b5b195ea7f..42ce88ceac66 100644
|
|
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
|
|
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
|
|
@@ -779,6 +779,29 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
|
|
goto exit;
|
|
}
|
|
|
|
+ /*
|
|
+ * It may need some time for the CAM to settle down, or there might
|
|
+ * be a race condition between the CAM, writing HC and our last
|
|
+ * check for DA. This happens, if the CAM asserts DA, just after
|
|
+ * checking DA before we are setting HC. In this case it might be
|
|
+ * a bug in the CAM to keep the FR bit, the lower layer/HW
|
|
+ * communication requires a longer timeout or the CAM needs more
|
|
+ * time internally. But this happens in reality!
|
|
+ * We need to read the status from the HW again and do the same
|
|
+ * we did for the previous check for DA
|
|
+ */
|
|
+ status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
|
|
+ if (status < 0)
|
|
+ goto exit;
|
|
+
|
|
+ if (status & (STATUSREG_DA | STATUSREG_RE)) {
|
|
+ if (status & STATUSREG_DA)
|
|
+ dvb_ca_en50221_thread_wakeup(ca);
|
|
+
|
|
+ status = -EAGAIN;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
/* send the amount of data */
|
|
if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
|
|
goto exit;
|
|
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
|
|
index 20b4a659e2e4..0fe69f79a24d 100644
|
|
--- a/drivers/media/dvb-frontends/si2168.c
|
|
+++ b/drivers/media/dvb-frontends/si2168.c
|
|
@@ -14,6 +14,8 @@
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
+#include <linux/delay.h>
|
|
+
|
|
#include "si2168_priv.h"
|
|
|
|
static const struct dvb_frontend_ops si2168_ops;
|
|
@@ -378,6 +380,7 @@ static int si2168_init(struct dvb_frontend *fe)
|
|
if (ret)
|
|
goto err;
|
|
|
|
+ udelay(100);
|
|
memcpy(cmd.args, "\x85", 1);
|
|
cmd.wlen = 1;
|
|
cmd.rlen = 1;
|
|
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
|
|
index 8aa726651630..90fcccc05b56 100644
|
|
--- a/drivers/media/pci/bt8xx/bt878.c
|
|
+++ b/drivers/media/pci/bt8xx/bt878.c
|
|
@@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
|
|
bt878_num);
|
|
if (bt878_num >= BT878_MAX) {
|
|
printk(KERN_ERR "bt878: Too many devices inserted\n");
|
|
- result = -ENOMEM;
|
|
- goto fail0;
|
|
+ return -ENOMEM;
|
|
}
|
|
if (pci_enable_device(dev))
|
|
return -EIO;
|
|
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
|
|
index 30c148b9d65e..06e2cfd09855 100644
|
|
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
|
|
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
|
|
@@ -83,7 +83,7 @@ static void c8sectpfe_timer_interrupt(unsigned long ac8sectpfei)
|
|
static void channel_swdemux_tsklet(unsigned long data)
|
|
{
|
|
struct channel_info *channel = (struct channel_info *)data;
|
|
- struct c8sectpfei *fei = channel->fei;
|
|
+ struct c8sectpfei *fei;
|
|
unsigned long wp, rp;
|
|
int pos, num_packets, n, size;
|
|
u8 *buf;
|
|
@@ -91,6 +91,8 @@ static void channel_swdemux_tsklet(unsigned long data)
|
|
if (unlikely(!channel || !channel->irec))
|
|
return;
|
|
|
|
+ fei = channel->fei;
|
|
+
|
|
wp = readl(channel->irec + DMA_PRDS_BUSWP_TP(0));
|
|
rp = readl(channel->irec + DMA_PRDS_BUSRP_TP(0));
|
|
|
|
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
|
|
index 8f8bacb67a15..a6b5259ffbdd 100644
|
|
--- a/drivers/mfd/palmas.c
|
|
+++ b/drivers/mfd/palmas.c
|
|
@@ -430,6 +430,20 @@ static void palmas_power_off(void)
|
|
{
|
|
unsigned int addr;
|
|
int ret, slave;
|
|
+ struct device_node *np = palmas_dev->dev->of_node;
|
|
+
|
|
+ if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
|
|
+ addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
|
|
+ PALMAS_PRIMARY_SECONDARY_PAD2);
|
|
+ slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
|
|
+
|
|
+ ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
|
|
+ PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0);
|
|
+ if (ret)
|
|
+ dev_err(palmas_dev->dev,
|
|
+ "Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
|
|
+ ret);
|
|
+ }
|
|
|
|
if (!palmas_dev)
|
|
return;
|
|
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
|
|
index 2553d903a82b..cff5829790c9 100644
|
|
--- a/drivers/mmc/core/core.c
|
|
+++ b/drivers/mmc/core/core.c
|
|
@@ -2974,6 +2974,14 @@ static int mmc_pm_notify(struct notifier_block *notify_block,
|
|
if (!err)
|
|
break;
|
|
|
|
+ if (!mmc_card_is_removable(host)) {
|
|
+ dev_warn(mmc_dev(host),
|
|
+ "pre_suspend failed for non-removable host: "
|
|
+ "%d\n", err);
|
|
+ /* Avoid removing non-removable hosts */
|
|
+ break;
|
|
+ }
|
|
+
|
|
/* Calling bus_ops->remove() with a claimed host can deadlock */
|
|
host->bus_ops->remove(host);
|
|
mmc_claim_host(host);
|
|
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
|
|
index 5f2f24a7360d..a082aa330f47 100644
|
|
--- a/drivers/mmc/host/omap_hsmmc.c
|
|
+++ b/drivers/mmc/host/omap_hsmmc.c
|
|
@@ -1762,8 +1762,8 @@ static int omap_hsmmc_configure_wake_irq(struct omap_hsmmc_host *host)
|
|
*/
|
|
if (host->pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) {
|
|
struct pinctrl *p = devm_pinctrl_get(host->dev);
|
|
- if (!p) {
|
|
- ret = -ENODEV;
|
|
+ if (IS_ERR(p)) {
|
|
+ ret = PTR_ERR(p);
|
|
goto err_free_irq;
|
|
}
|
|
if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_DEFAULT))) {
|
|
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
|
|
index 3c27401cf7fe..a51d636c2312 100644
|
|
--- a/drivers/mmc/host/sdhci-of-esdhc.c
|
|
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
|
|
@@ -432,6 +432,20 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
|
|
if (esdhc->vendor_ver < VENDOR_V_23)
|
|
pre_div = 2;
|
|
|
|
+ /*
|
|
+ * Limit SD clock to 167MHz for ls1046a according to its datasheet
|
|
+ */
|
|
+ if (clock > 167000000 &&
|
|
+ of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
|
|
+ clock = 167000000;
|
|
+
|
|
+ /*
|
|
+ * Limit SD clock to 125MHz for ls1012a according to its datasheet
|
|
+ */
|
|
+ if (clock > 125000000 &&
|
|
+ of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
|
|
+ clock = 125000000;
|
|
+
|
|
/* Workaround to reduce the clock frequency for p1010 esdhc */
|
|
if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
|
|
if (clock > 20000000)
|
|
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
index c3f3096b24ae..4907c9b57565 100644
|
|
--- a/drivers/net/bonding/bond_main.c
|
|
+++ b/drivers/net/bonding/bond_main.c
|
|
@@ -2067,6 +2067,7 @@ static int bond_miimon_inspect(struct bonding *bond)
|
|
(bond->params.downdelay - slave->delay) *
|
|
bond->params.miimon,
|
|
slave->dev->name);
|
|
+ commit++;
|
|
continue;
|
|
}
|
|
|
|
@@ -2104,7 +2105,7 @@ static int bond_miimon_inspect(struct bonding *bond)
|
|
(bond->params.updelay - slave->delay) *
|
|
bond->params.miimon,
|
|
slave->dev->name);
|
|
-
|
|
+ commit++;
|
|
continue;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
index 596f88b693ef..ca6c4718000f 100644
|
|
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
|
|
@@ -2026,6 +2026,7 @@ static void bnx2x_set_rx_buf_size(struct bnx2x *bp)
|
|
ETH_OVREHEAD +
|
|
mtu +
|
|
BNX2X_FW_RX_ALIGN_END;
|
|
+ fp->rx_buf_size = SKB_DATA_ALIGN(fp->rx_buf_size);
|
|
/* Note : rx_buf_size doesn't take into account NET_SKB_PAD */
|
|
if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
|
|
fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
|
|
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
|
|
index f76d33279454..ef9bc26ebc1a 100644
|
|
--- a/drivers/net/ethernet/freescale/ucc_geth.c
|
|
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
|
|
@@ -2594,11 +2594,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
|
|
} else if (ugeth->ug_info->uf_info.bd_mem_part ==
|
|
MEM_PART_MURAM) {
|
|
out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
|
|
- (u32) immrbar_virt_to_phys(ugeth->
|
|
- p_tx_bd_ring[i]));
|
|
+ (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i]));
|
|
out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
|
|
last_bd_completed_address,
|
|
- (u32) immrbar_virt_to_phys(endOfRing));
|
|
+ (u32)qe_muram_dma(endOfRing));
|
|
}
|
|
}
|
|
|
|
@@ -2844,8 +2843,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
|
|
} else if (ugeth->ug_info->uf_info.bd_mem_part ==
|
|
MEM_PART_MURAM) {
|
|
out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
|
|
- (u32) immrbar_virt_to_phys(ugeth->
|
|
- p_rx_bd_ring[i]));
|
|
+ (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i]));
|
|
}
|
|
/* rest of fields handled by QE */
|
|
}
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
|
|
index 02a03bccde7b..34b5e699a1d5 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
|
|
@@ -671,7 +671,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data)
|
|
|
|
static int hns_gmac_get_sset_count(int stringset)
|
|
{
|
|
- if (stringset == ETH_SS_STATS)
|
|
+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
|
|
return ARRAY_SIZE(g_gmac_stats_string);
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
|
|
index 6ea872287307..4ecb809785f9 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
|
|
@@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb)
|
|
|
|
int hns_ppe_get_sset_count(int stringset)
|
|
{
|
|
- if (stringset == ETH_SS_STATS)
|
|
+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
|
|
return ETH_PPE_STATIC_NUM;
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
|
|
index f3be9ac47bfb..fbbbbffd58dc 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
|
|
@@ -798,7 +798,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data)
|
|
*/
|
|
int hns_rcb_get_ring_sset_count(int stringset)
|
|
{
|
|
- if (stringset == ETH_SS_STATS)
|
|
+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
|
|
return HNS_RING_STATIC_REG_NUM;
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
|
|
index 8f4f0e8da984..d1c868c800f9 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
|
|
@@ -776,7 +776,7 @@ static void hns_xgmac_get_strings(u32 stringset, u8 *data)
|
|
*/
|
|
static int hns_xgmac_get_sset_count(int stringset)
|
|
{
|
|
- if (stringset == ETH_SS_STATS)
|
|
+ if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
|
|
return ARRAY_SIZE(g_xgmac_stats_string);
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
|
|
index 7c6c1468628b..49094c965697 100644
|
|
--- a/drivers/net/ethernet/ibm/ibmvnic.c
|
|
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
|
|
@@ -511,6 +511,23 @@ static int ibmvnic_open(struct net_device *netdev)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
+static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (adapter->tx_scrq) {
|
|
+ for (i = 0; i < adapter->req_tx_queues; i++)
|
|
+ if (adapter->tx_scrq[i])
|
|
+ disable_irq(adapter->tx_scrq[i]->irq);
|
|
+ }
|
|
+
|
|
+ if (adapter->rx_scrq) {
|
|
+ for (i = 0; i < adapter->req_rx_queues; i++)
|
|
+ if (adapter->rx_scrq[i])
|
|
+ disable_irq(adapter->rx_scrq[i]->irq);
|
|
+ }
|
|
+}
|
|
+
|
|
static int ibmvnic_close(struct net_device *netdev)
|
|
{
|
|
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
|
|
@@ -519,6 +536,7 @@ static int ibmvnic_close(struct net_device *netdev)
|
|
int i;
|
|
|
|
adapter->closing = true;
|
|
+ disable_sub_crqs(adapter);
|
|
|
|
for (i = 0; i < adapter->req_rx_queues; i++)
|
|
napi_disable(&adapter->napi[i]);
|
|
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
index 0feddf3393f9..528a926dd979 100644
|
|
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
|
|
@@ -3528,6 +3528,12 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
|
|
|
|
switch (hw->mac.type) {
|
|
case e1000_pch2lan:
|
|
+ /* Stable 96MHz frequency */
|
|
+ incperiod = INCPERIOD_96MHz;
|
|
+ incvalue = INCVALUE_96MHz;
|
|
+ shift = INCVALUE_SHIFT_96MHz;
|
|
+ adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
|
|
+ break;
|
|
case e1000_pch_lpt:
|
|
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
|
|
/* Stable 96MHz frequency */
|
|
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
|
|
index 508e72c5f1c2..d665de8849a2 100644
|
|
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
|
|
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
|
|
@@ -80,7 +80,7 @@ static struct ixgbe_stats ixgbevf_gstrings_stats[] = {
|
|
#define IXGBEVF_QUEUE_STATS_LEN ( \
|
|
(((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \
|
|
((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \
|
|
- (sizeof(struct ixgbe_stats) / sizeof(u64)))
|
|
+ (sizeof(struct ixgbevf_stats) / sizeof(u64)))
|
|
#define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats)
|
|
|
|
#define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN)
|
|
diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c
|
|
index abf5bf11f865..0645124a887b 100644
|
|
--- a/drivers/net/ethernet/qlogic/qed/qed_vf.c
|
|
+++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c
|
|
@@ -204,7 +204,7 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
|
|
/* send acquire request */
|
|
rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
|
|
if (rc)
|
|
- return rc;
|
|
+ goto exit;
|
|
|
|
/* copy acquire response from buffer to p_hwfn */
|
|
memcpy(&p_iov->acquire_resp, resp, sizeof(p_iov->acquire_resp));
|
|
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
|
|
index d7107055ec60..2f656f395f39 100644
|
|
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
|
|
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
|
|
@@ -128,6 +128,8 @@ static int qlcnic_sriov_virtid_fn(struct qlcnic_adapter *adapter, int vf_id)
|
|
return 0;
|
|
|
|
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
|
|
+ if (!pos)
|
|
+ return 0;
|
|
pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
|
|
pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
|
|
|
|
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
|
|
index c2ac39a940f7..14f58b60d1b5 100644
|
|
--- a/drivers/net/hyperv/netvsc.c
|
|
+++ b/drivers/net/hyperv/netvsc.c
|
|
@@ -151,6 +151,13 @@ static void netvsc_destroy_buf(struct hv_device *device)
|
|
sizeof(struct nvsp_message),
|
|
(unsigned long)revoke_packet,
|
|
VM_PKT_DATA_INBAND, 0);
|
|
+ /* If the failure is because the channel is rescinded;
|
|
+ * ignore the failure since we cannot send on a rescinded
|
|
+ * channel. This would allow us to properly cleanup
|
|
+ * even when the channel is rescinded.
|
|
+ */
|
|
+ if (device->channel->rescind)
|
|
+ ret = 0;
|
|
/*
|
|
* If we failed here, we might as well return and
|
|
* have a leak rather than continue and a bugchk
|
|
@@ -211,6 +218,15 @@ static void netvsc_destroy_buf(struct hv_device *device)
|
|
sizeof(struct nvsp_message),
|
|
(unsigned long)revoke_packet,
|
|
VM_PKT_DATA_INBAND, 0);
|
|
+
|
|
+ /* If the failure is because the channel is rescinded;
|
|
+ * ignore the failure since we cannot send on a rescinded
|
|
+ * channel. This would allow us to properly cleanup
|
|
+ * even when the channel is rescinded.
|
|
+ */
|
|
+ if (device->channel->rescind)
|
|
+ ret = 0;
|
|
+
|
|
/* If we failed here, we might as well return and
|
|
* have a leak rather than continue and a bugchk
|
|
*/
|
|
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
|
index a30d6a6dbd95..973e90fb4a24 100644
|
|
--- a/drivers/net/usb/qmi_wwan.c
|
|
+++ b/drivers/net/usb/qmi_wwan.c
|
|
@@ -531,7 +531,7 @@ static int qmi_wwan_resume(struct usb_interface *intf)
|
|
|
|
static const struct driver_info qmi_wwan_info = {
|
|
.description = "WWAN/QMI device",
|
|
- .flags = FLAG_WWAN,
|
|
+ .flags = FLAG_WWAN | FLAG_SEND_ZLP,
|
|
.bind = qmi_wwan_bind,
|
|
.unbind = qmi_wwan_unbind,
|
|
.manage_power = qmi_wwan_manage_power,
|
|
@@ -540,7 +540,7 @@ static const struct driver_info qmi_wwan_info = {
|
|
|
|
static const struct driver_info qmi_wwan_info_quirk_dtr = {
|
|
.description = "WWAN/QMI device",
|
|
- .flags = FLAG_WWAN,
|
|
+ .flags = FLAG_WWAN | FLAG_SEND_ZLP,
|
|
.bind = qmi_wwan_bind,
|
|
.unbind = qmi_wwan_unbind,
|
|
.manage_power = qmi_wwan_manage_power,
|
|
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
|
|
index 50570d779b01..0f5dfb8a545d 100644
|
|
--- a/drivers/net/vxlan.c
|
|
+++ b/drivers/net/vxlan.c
|
|
@@ -2816,17 +2816,21 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
|
|
|
|
static int vxlan_sock_add(struct vxlan_dev *vxlan)
|
|
{
|
|
- bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
|
|
bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA;
|
|
+ bool ipv6 = vxlan->flags & VXLAN_F_IPV6 || metadata;
|
|
+ bool ipv4 = !ipv6 || metadata;
|
|
int ret = 0;
|
|
|
|
RCU_INIT_POINTER(vxlan->vn4_sock, NULL);
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
RCU_INIT_POINTER(vxlan->vn6_sock, NULL);
|
|
- if (ipv6 || metadata)
|
|
+ if (ipv6) {
|
|
ret = __vxlan_sock_add(vxlan, true);
|
|
+ if (ret < 0 && ret != -EAFNOSUPPORT)
|
|
+ ipv4 = false;
|
|
+ }
|
|
#endif
|
|
- if (!ret && (!ipv6 || metadata))
|
|
+ if (ipv4)
|
|
ret = __vxlan_sock_add(vxlan, false);
|
|
if (ret < 0)
|
|
vxlan_sock_release(vxlan);
|
|
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
|
|
index db363856e0b5..2b064998915f 100644
|
|
--- a/drivers/net/wan/pc300too.c
|
|
+++ b/drivers/net/wan/pc300too.c
|
|
@@ -347,6 +347,7 @@ static int pc300_pci_init_one(struct pci_dev *pdev,
|
|
card->rambase == NULL) {
|
|
pr_err("ioremap() failed\n");
|
|
pc300_pci_remove_one(pdev);
|
|
+ return -ENOMEM;
|
|
}
|
|
|
|
/* PLX PCI 9050 workaround for local configuration register read bug */
|
|
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
|
|
index 6aa2b93497dd..0dadc6044dba 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/debug.c
|
|
@@ -624,17 +624,21 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
struct ath10k *ar = file->private_data;
|
|
- char buf[32];
|
|
+ char buf[32] = {0};
|
|
+ ssize_t rc;
|
|
int ret;
|
|
|
|
- simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
|
+ /* filter partial writes and invalid commands */
|
|
+ if (*ppos != 0 || count >= sizeof(buf) || count == 0)
|
|
+ return -EINVAL;
|
|
|
|
- /* make sure that buf is null terminated */
|
|
- buf[sizeof(buf) - 1] = 0;
|
|
+ rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
|
+ if (rc < 0)
|
|
+ return rc;
|
|
|
|
/* drop the possible '\n' from the end */
|
|
- if (buf[count - 1] == '\n')
|
|
- buf[count - 1] = 0;
|
|
+ if (buf[*ppos - 1] == '\n')
|
|
+ buf[*ppos - 1] = '\0';
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
|
|
index 1e6e63dbd61c..a497bf31953d 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
|
@@ -2505,7 +2505,7 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
|
}
|
|
break;
|
|
case WMI_VDEV_TYPE_STA:
|
|
- if (vif->bss_conf.qos)
|
|
+ if (sta->wme)
|
|
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
|
break;
|
|
case WMI_VDEV_TYPE_IBSS:
|
|
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
|
|
index f8506037736f..404fc306cb2a 100644
|
|
--- a/drivers/net/wireless/ath/regd.c
|
|
+++ b/drivers/net/wireless/ath/regd.c
|
|
@@ -254,8 +254,12 @@ bool ath_is_49ghz_allowed(u16 regdomain)
|
|
EXPORT_SYMBOL(ath_is_49ghz_allowed);
|
|
|
|
/* Frequency is one where radar detection is required */
|
|
-static bool ath_is_radar_freq(u16 center_freq)
|
|
+static bool ath_is_radar_freq(u16 center_freq,
|
|
+ struct ath_regulatory *reg)
|
|
+
|
|
{
|
|
+ if (reg->country_code == CTRY_INDIA)
|
|
+ return (center_freq >= 5500 && center_freq <= 5700);
|
|
return (center_freq >= 5260 && center_freq <= 5700);
|
|
}
|
|
|
|
@@ -306,7 +310,7 @@ __ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
|
enum nl80211_reg_initiator initiator,
|
|
struct ieee80211_channel *ch)
|
|
{
|
|
- if (ath_is_radar_freq(ch->center_freq) ||
|
|
+ if (ath_is_radar_freq(ch->center_freq, reg) ||
|
|
(ch->flags & IEEE80211_CHAN_RADAR))
|
|
return;
|
|
|
|
@@ -395,8 +399,9 @@ ath_reg_apply_ir_flags(struct wiphy *wiphy,
|
|
}
|
|
}
|
|
|
|
-/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
|
|
-static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
|
|
+/* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */
|
|
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
|
|
+ struct ath_regulatory *reg)
|
|
{
|
|
struct ieee80211_supported_band *sband;
|
|
struct ieee80211_channel *ch;
|
|
@@ -409,7 +414,7 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
|
|
|
|
for (i = 0; i < sband->n_channels; i++) {
|
|
ch = &sband->channels[i];
|
|
- if (!ath_is_radar_freq(ch->center_freq))
|
|
+ if (!ath_is_radar_freq(ch->center_freq, reg))
|
|
continue;
|
|
/* We always enable radar detection/DFS on this
|
|
* frequency range. Additionally we also apply on
|
|
@@ -505,7 +510,7 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
|
|
struct ath_common *common = container_of(reg, struct ath_common,
|
|
regulatory);
|
|
/* We always apply this */
|
|
- ath_reg_apply_radar_flags(wiphy);
|
|
+ ath_reg_apply_radar_flags(wiphy, reg);
|
|
|
|
/*
|
|
* This would happen when we have sent a custom regulatory request
|
|
@@ -653,7 +658,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
|
|
}
|
|
|
|
wiphy_apply_custom_regulatory(wiphy, regd);
|
|
- ath_reg_apply_radar_flags(wiphy);
|
|
+ ath_reg_apply_radar_flags(wiphy, reg);
|
|
ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
|
|
index ea1618525878..e267377edbe7 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
|
|
@@ -65,12 +65,12 @@
|
|
#define IWL_A000_TX_POWER_VERSION 0xffff /* meaningless */
|
|
|
|
/* Memory offsets and lengths */
|
|
-#define IWL_A000_DCCM_OFFSET 0x800000
|
|
-#define IWL_A000_DCCM_LEN 0x18000
|
|
+#define IWL_A000_DCCM_OFFSET 0x800000 /* LMAC1 */
|
|
+#define IWL_A000_DCCM_LEN 0x10000 /* LMAC1 */
|
|
#define IWL_A000_DCCM2_OFFSET 0x880000
|
|
#define IWL_A000_DCCM2_LEN 0x8000
|
|
#define IWL_A000_SMEM_OFFSET 0x400000
|
|
-#define IWL_A000_SMEM_LEN 0x68000
|
|
+#define IWL_A000_SMEM_LEN 0xD0000
|
|
|
|
#define IWL_A000_FW_PRE "iwlwifi-Qu-a0-jf-b0-"
|
|
#define IWL_A000_MODULE_FIRMWARE(api) \
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c
|
|
index 88f260db3744..68412ff2112e 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c
|
|
@@ -76,8 +76,8 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait)
|
|
}
|
|
IWL_EXPORT_SYMBOL(iwl_notification_wait_init);
|
|
|
|
-void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
|
|
- struct iwl_rx_packet *pkt)
|
|
+bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,
|
|
+ struct iwl_rx_packet *pkt)
|
|
{
|
|
bool triggered = false;
|
|
|
|
@@ -118,13 +118,11 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
|
|
}
|
|
}
|
|
spin_unlock(¬if_wait->notif_wait_lock);
|
|
-
|
|
}
|
|
|
|
- if (triggered)
|
|
- wake_up_all(¬if_wait->notif_waitq);
|
|
+ return triggered;
|
|
}
|
|
-IWL_EXPORT_SYMBOL(iwl_notification_wait_notify);
|
|
+IWL_EXPORT_SYMBOL(iwl_notification_wait);
|
|
|
|
void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
|
|
{
|
|
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h
|
|
index 0f9995ed71cd..368884be4e7c 100644
|
|
--- a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h
|
|
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h
|
|
@@ -6,7 +6,7 @@
|
|
* GPL LICENSE SUMMARY
|
|
*
|
|
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
|
- * Copyright(c) 2015 Intel Deutschland GmbH
|
|
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of version 2 of the GNU General Public License as
|
|
@@ -32,6 +32,7 @@
|
|
* BSD LICENSE
|
|
*
|
|
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
|
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -89,10 +90,10 @@ struct iwl_notif_wait_data {
|
|
*
|
|
* This structure is not used directly, to wait for a
|
|
* notification declare it on the stack, and call
|
|
- * iwlagn_init_notification_wait() with appropriate
|
|
+ * iwl_init_notification_wait() with appropriate
|
|
* parameters. Then do whatever will cause the ucode
|
|
* to notify the driver, and to wait for that then
|
|
- * call iwlagn_wait_notification().
|
|
+ * call iwl_wait_notification().
|
|
*
|
|
* Each notification is one-shot. If at some point we
|
|
* need to support multi-shot notifications (which
|
|
@@ -114,10 +115,24 @@ struct iwl_notification_wait {
|
|
|
|
/* caller functions */
|
|
void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
|
|
-void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
|
|
- struct iwl_rx_packet *pkt);
|
|
+bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data,
|
|
+ struct iwl_rx_packet *pkt);
|
|
void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
|
|
|
|
+static inline void
|
|
+iwl_notification_notify(struct iwl_notif_wait_data *notif_data)
|
|
+{
|
|
+ wake_up_all(¬if_data->notif_waitq);
|
|
+}
|
|
+
|
|
+static inline void
|
|
+iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
|
|
+ struct iwl_rx_packet *pkt)
|
|
+{
|
|
+ if (iwl_notification_wait(notif_data, pkt))
|
|
+ iwl_notification_notify(notif_data);
|
|
+}
|
|
+
|
|
/* user functions */
|
|
void __acquires(wait_entry)
|
|
iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
|
|
diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
|
|
index c3a53cd6988e..7b4955cc38db 100644
|
|
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
|
|
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
|
|
@@ -1181,6 +1181,10 @@ static int if_spi_probe(struct spi_device *spi)
|
|
|
|
/* Initialize interrupt handling stuff. */
|
|
card->workqueue = alloc_workqueue("libertas_spi", WQ_MEM_RECLAIM, 0);
|
|
+ if (!card->workqueue) {
|
|
+ err = -ENOMEM;
|
|
+ goto remove_card;
|
|
+ }
|
|
INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
|
|
INIT_WORK(&card->resume_work, if_spi_resume_worker);
|
|
|
|
@@ -1209,6 +1213,7 @@ static int if_spi_probe(struct spi_device *spi)
|
|
free_irq(spi->irq, card);
|
|
terminate_workqueue:
|
|
destroy_workqueue(card->workqueue);
|
|
+remove_card:
|
|
lbs_remove_card(priv); /* will call free_netdev */
|
|
free_card:
|
|
free_if_spi_card(card);
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
|
|
index 2478ccd6f2d9..1e36f11831a9 100644
|
|
--- a/drivers/net/wireless/marvell/mwifiex/main.c
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
|
|
@@ -146,7 +146,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
|
|
|
|
kfree(adapter->regd);
|
|
|
|
- vfree(adapter->chan_stats);
|
|
kfree(adapter);
|
|
return 0;
|
|
}
|
|
@@ -636,6 +635,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
|
|
goto done;
|
|
|
|
err_add_intf:
|
|
+ vfree(adapter->chan_stats);
|
|
wiphy_unregister(adapter->wiphy);
|
|
wiphy_free(adapter->wiphy);
|
|
err_init_fw:
|
|
@@ -1429,6 +1429,7 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter, struct semaphore *sem)
|
|
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
|
|
rtnl_unlock();
|
|
}
|
|
+ vfree(adapter->chan_stats);
|
|
|
|
up(sem);
|
|
exit_sem_err:
|
|
@@ -1729,6 +1730,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
|
|
mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
|
|
rtnl_unlock();
|
|
}
|
|
+ vfree(adapter->chan_stats);
|
|
|
|
wiphy_unregister(adapter->wiphy);
|
|
wiphy_free(adapter->wiphy);
|
|
diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.c b/drivers/net/wireless/mediatek/mt7601u/mcu.c
|
|
index dbdfb3f5c507..a9f5f398b2f8 100644
|
|
--- a/drivers/net/wireless/mediatek/mt7601u/mcu.c
|
|
+++ b/drivers/net/wireless/mediatek/mt7601u/mcu.c
|
|
@@ -66,8 +66,10 @@ mt7601u_mcu_msg_alloc(struct mt7601u_dev *dev, const void *data, int len)
|
|
WARN_ON(len % 4); /* if length is not divisible by 4 we need to pad */
|
|
|
|
skb = alloc_skb(len + MT_DMA_HDR_LEN + 4, GFP_KERNEL);
|
|
- skb_reserve(skb, MT_DMA_HDR_LEN);
|
|
- memcpy(skb_put(skb, len), data, len);
|
|
+ if (skb) {
|
|
+ skb_reserve(skb, MT_DMA_HDR_LEN);
|
|
+ memcpy(skb_put(skb, len), data, len);
|
|
+ }
|
|
|
|
return skb;
|
|
}
|
|
@@ -170,6 +172,8 @@ static int mt7601u_mcu_function_select(struct mt7601u_dev *dev,
|
|
};
|
|
|
|
skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg));
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
return mt7601u_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5);
|
|
}
|
|
|
|
@@ -205,6 +209,8 @@ mt7601u_mcu_calibrate(struct mt7601u_dev *dev, enum mcu_calibrate cal, u32 val)
|
|
};
|
|
|
|
skb = mt7601u_mcu_msg_alloc(dev, &msg, sizeof(msg));
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
return mt7601u_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true);
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
|
|
index 75ffeaa54ed8..e15b462d096b 100644
|
|
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
|
|
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
|
|
@@ -1572,7 +1572,14 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
|
|
dev_kfree_skb_irq(skb);
|
|
ring->idx = (ring->idx + 1) % ring->entries;
|
|
}
|
|
+
|
|
+ if (rtlpriv->use_new_trx_flow) {
|
|
+ rtlpci->tx_ring[i].cur_tx_rp = 0;
|
|
+ rtlpci->tx_ring[i].cur_tx_wp = 0;
|
|
+ }
|
|
+
|
|
ring->idx = 0;
|
|
+ ring->entries = rtlpci->txringcount[i];
|
|
}
|
|
}
|
|
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
|
|
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
|
|
index 603c90470225..15b2350d9f45 100644
|
|
--- a/drivers/net/wireless/rndis_wlan.c
|
|
+++ b/drivers/net/wireless/rndis_wlan.c
|
|
@@ -3427,6 +3427,10 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
|
|
|
|
/* because rndis_command() sleeps we need to use workqueue */
|
|
priv->workqueue = create_singlethread_workqueue("rndis_wlan");
|
|
+ if (!priv->workqueue) {
|
|
+ wiphy_free(wiphy);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
INIT_WORK(&priv->work, rndis_wlan_worker);
|
|
INIT_DELAYED_WORK(&priv->dev_poller_work, rndis_device_poller);
|
|
INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
|
|
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
|
|
index fb38e208f32d..735d8f7f9d71 100644
|
|
--- a/drivers/pinctrl/core.c
|
|
+++ b/drivers/pinctrl/core.c
|
|
@@ -992,19 +992,16 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p,
|
|
EXPORT_SYMBOL_GPL(pinctrl_lookup_state);
|
|
|
|
/**
|
|
- * pinctrl_select_state() - select/activate/program a pinctrl state to HW
|
|
+ * pinctrl_commit_state() - select/activate/program a pinctrl state to HW
|
|
* @p: the pinctrl handle for the device that requests configuration
|
|
* @state: the state handle to select/activate/program
|
|
*/
|
|
-int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
|
+static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
|
|
{
|
|
struct pinctrl_setting *setting, *setting2;
|
|
struct pinctrl_state *old_state = p->state;
|
|
int ret;
|
|
|
|
- if (p->state == state)
|
|
- return 0;
|
|
-
|
|
if (p->state) {
|
|
/*
|
|
* For each pinmux setting in the old state, forget SW's record
|
|
@@ -1068,6 +1065,19 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
|
|
|
return ret;
|
|
}
|
|
+
|
|
+/**
|
|
+ * pinctrl_select_state() - select/activate/program a pinctrl state to HW
|
|
+ * @p: the pinctrl handle for the device that requests configuration
|
|
+ * @state: the state handle to select/activate/program
|
|
+ */
|
|
+int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
|
+{
|
|
+ if (p->state == state)
|
|
+ return 0;
|
|
+
|
|
+ return pinctrl_commit_state(p, state);
|
|
+}
|
|
EXPORT_SYMBOL_GPL(pinctrl_select_state);
|
|
|
|
static void devm_pinctrl_release(struct device *dev, void *res)
|
|
@@ -1236,7 +1246,7 @@ void pinctrl_unregister_map(struct pinctrl_map const *map)
|
|
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
|
|
{
|
|
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
|
|
- return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
|
|
+ return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
|
|
@@ -1248,7 +1258,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
|
|
int pinctrl_force_default(struct pinctrl_dev *pctldev)
|
|
{
|
|
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
|
|
- return pinctrl_select_state(pctldev->p, pctldev->hog_default);
|
|
+ return pinctrl_commit_state(pctldev->p, pctldev->hog_default);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(pinctrl_force_default);
|
|
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
|
|
index 49bf7dcb7ed8..f826793e972c 100644
|
|
--- a/drivers/pinctrl/pinctrl-rockchip.c
|
|
+++ b/drivers/pinctrl/pinctrl-rockchip.c
|
|
@@ -1278,8 +1278,16 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
|
{
|
|
struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
|
|
u32 data;
|
|
+ int ret;
|
|
|
|
+ ret = clk_enable(bank->clk);
|
|
+ if (ret < 0) {
|
|
+ dev_err(bank->drvdata->dev,
|
|
+ "failed to enable clock for bank %s\n", bank->name);
|
|
+ return ret;
|
|
+ }
|
|
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
|
|
+ clk_disable(bank->clk);
|
|
|
|
return !(data & BIT(offset));
|
|
}
|
|
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
|
|
index 04053fe1e980..cfa3e850c49f 100644
|
|
--- a/drivers/platform/chrome/cros_ec_proto.c
|
|
+++ b/drivers/platform/chrome/cros_ec_proto.c
|
|
@@ -60,12 +60,14 @@ static int send_command(struct cros_ec_device *ec_dev,
|
|
struct cros_ec_command *msg)
|
|
{
|
|
int ret;
|
|
+ int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
|
|
|
|
if (ec_dev->proto_version > 2)
|
|
- ret = ec_dev->pkt_xfer(ec_dev, msg);
|
|
+ xfer_fxn = ec_dev->pkt_xfer;
|
|
else
|
|
- ret = ec_dev->cmd_xfer(ec_dev, msg);
|
|
+ xfer_fxn = ec_dev->cmd_xfer;
|
|
|
|
+ ret = (*xfer_fxn)(ec_dev, msg);
|
|
if (msg->result == EC_RES_IN_PROGRESS) {
|
|
int i;
|
|
struct cros_ec_command *status_msg;
|
|
@@ -88,7 +90,7 @@ static int send_command(struct cros_ec_device *ec_dev,
|
|
for (i = 0; i < EC_COMMAND_RETRIES; i++) {
|
|
usleep_range(10000, 11000);
|
|
|
|
- ret = ec_dev->cmd_xfer(ec_dev, status_msg);
|
|
+ ret = (*xfer_fxn)(ec_dev, status_msg);
|
|
if (ret < 0)
|
|
break;
|
|
|
|
diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c
|
|
index f3baf9973989..24f1630a8b3f 100644
|
|
--- a/drivers/platform/chrome/cros_ec_sysfs.c
|
|
+++ b/drivers/platform/chrome/cros_ec_sysfs.c
|
|
@@ -187,7 +187,7 @@ static ssize_t show_ec_version(struct device *dev,
|
|
count += scnprintf(buf + count, PAGE_SIZE - count,
|
|
"Build info: EC error %d\n", msg->result);
|
|
else {
|
|
- msg->data[sizeof(msg->data) - 1] = '\0';
|
|
+ msg->data[EC_HOST_PARAM_SIZE - 1] = '\0';
|
|
count += scnprintf(buf + count, PAGE_SIZE - count,
|
|
"Build info: %s\n", msg->data);
|
|
}
|
|
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
|
|
index 6eb2837f6b89..687cc5b922ee 100644
|
|
--- a/drivers/platform/x86/asus-nb-wmi.c
|
|
+++ b/drivers/platform/x86/asus-nb-wmi.c
|
|
@@ -120,6 +120,10 @@ static struct quirk_entry quirk_asus_x550lb = {
|
|
.xusb2pr = 0x01D9,
|
|
};
|
|
|
|
+static struct quirk_entry quirk_asus_ux330uak = {
|
|
+ .wmi_force_als_set = true,
|
|
+};
|
|
+
|
|
static int dmi_matched(const struct dmi_system_id *dmi)
|
|
{
|
|
quirks = dmi->driver_data;
|
|
@@ -150,6 +154,15 @@ static const struct dmi_system_id asus_quirks[] = {
|
|
*/
|
|
.driver_data = &quirk_asus_wapf4,
|
|
},
|
|
+ {
|
|
+ .callback = dmi_matched,
|
|
+ .ident = "ASUSTeK COMPUTER INC. X302UA",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"),
|
|
+ },
|
|
+ .driver_data = &quirk_asus_wapf4,
|
|
+ },
|
|
{
|
|
.callback = dmi_matched,
|
|
.ident = "ASUSTeK COMPUTER INC. X401U",
|
|
@@ -411,6 +424,15 @@ static const struct dmi_system_id asus_quirks[] = {
|
|
},
|
|
.driver_data = &quirk_asus_ux303ub,
|
|
},
|
|
+ {
|
|
+ .callback = dmi_matched,
|
|
+ .ident = "ASUSTeK COMPUTER INC. UX330UAK",
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"),
|
|
+ },
|
|
+ .driver_data = &quirk_asus_ux330uak,
|
|
+ },
|
|
{
|
|
.callback = dmi_matched,
|
|
.ident = "ASUSTeK COMPUTER INC. X550LB",
|
|
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
|
|
index 8499d3ae4257..8a1bfd489c26 100644
|
|
--- a/drivers/platform/x86/asus-wmi.c
|
|
+++ b/drivers/platform/x86/asus-wmi.c
|
|
@@ -1108,6 +1108,15 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
|
|
orig_ports_available, ports_available);
|
|
}
|
|
|
|
+/*
|
|
+ * Some devices dont support or have borcken get_als method
|
|
+ * but still support set method.
|
|
+ */
|
|
+static void asus_wmi_set_als(void)
|
|
+{
|
|
+ asus_wmi_set_devstate(ASUS_WMI_DEVID_ALS_ENABLE, 1, NULL);
|
|
+}
|
|
+
|
|
/*
|
|
* Hwmon device
|
|
*/
|
|
@@ -2120,6 +2129,9 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|
goto fail_rfkill;
|
|
}
|
|
|
|
+ if (asus->driver->quirks->wmi_force_als_set)
|
|
+ asus_wmi_set_als();
|
|
+
|
|
/* Some Asus desktop boards export an acpi-video backlight interface,
|
|
stop this from showing up */
|
|
chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
|
|
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
|
|
index fdff626c3b51..5db052d1de1e 100644
|
|
--- a/drivers/platform/x86/asus-wmi.h
|
|
+++ b/drivers/platform/x86/asus-wmi.h
|
|
@@ -45,6 +45,7 @@ struct quirk_entry {
|
|
bool store_backlight_power;
|
|
bool wmi_backlight_power;
|
|
bool wmi_backlight_native;
|
|
+ bool wmi_force_als_set;
|
|
int wapf;
|
|
/*
|
|
* For machines with AMD graphic chips, it will send out WMI event
|
|
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
|
|
index 78080763df51..a74340dff530 100644
|
|
--- a/drivers/platform/x86/intel-vbtn.c
|
|
+++ b/drivers/platform/x86/intel-vbtn.c
|
|
@@ -37,6 +37,10 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
|
|
static const struct key_entry intel_vbtn_keymap[] = {
|
|
{ KE_IGNORE, 0xC0, { KEY_POWER } }, /* power key press */
|
|
{ KE_KEY, 0xC1, { KEY_POWER } }, /* power key release */
|
|
+ { KE_KEY, 0xC4, { KEY_VOLUMEUP } }, /* volume-up key press */
|
|
+ { KE_IGNORE, 0xC5, { KEY_VOLUMEUP } }, /* volume-up key release */
|
|
+ { KE_KEY, 0xC6, { KEY_VOLUMEDOWN } }, /* volume-down key press */
|
|
+ { KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } }, /* volume-down key release */
|
|
{ KE_END },
|
|
};
|
|
|
|
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
|
|
index 50171fd3cc6d..8ed2782d1bb1 100644
|
|
--- a/drivers/power/supply/bq24190_charger.c
|
|
+++ b/drivers/power/supply/bq24190_charger.c
|
|
@@ -506,6 +506,9 @@ static int bq24190_register_reset(struct bq24190_dev_info *bdi)
|
|
int ret, limit = 100;
|
|
u8 v;
|
|
|
|
+ if (device_property_read_bool(bdi->dev, "disable-reset"))
|
|
+ return 0;
|
|
+
|
|
/* Reset the registers */
|
|
ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
|
|
BQ24190_REG_POC_RESET_MASK,
|
|
@@ -1184,8 +1187,13 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
|
|
}
|
|
} while (f_reg && ++i < 2);
|
|
|
|
+ /* ignore over/under voltage fault after disconnect */
|
|
+ if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
|
|
+ !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
|
|
+ f_reg = 0;
|
|
+
|
|
if (f_reg != bdi->f_reg) {
|
|
- dev_info(bdi->dev,
|
|
+ dev_warn(bdi->dev,
|
|
"Fault: boost %d, charge %d, battery %d, ntc %d\n",
|
|
!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
|
|
!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
|
|
diff --git a/drivers/power/supply/isp1704_charger.c b/drivers/power/supply/isp1704_charger.c
|
|
index 4cd6899b961e..95af5f305838 100644
|
|
--- a/drivers/power/supply/isp1704_charger.c
|
|
+++ b/drivers/power/supply/isp1704_charger.c
|
|
@@ -418,6 +418,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
|
|
|
|
pdata = devm_kzalloc(&pdev->dev,
|
|
sizeof(struct isp1704_charger_data), GFP_KERNEL);
|
|
+ if (!pdata) {
|
|
+ ret = -ENOMEM;
|
|
+ goto fail0;
|
|
+ }
|
|
pdata->enable_gpio = gpio;
|
|
|
|
dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio);
|
|
diff --git a/drivers/power/supply/pda_power.c b/drivers/power/supply/pda_power.c
|
|
index dfe1ee89f7c7..922a86787c5c 100644
|
|
--- a/drivers/power/supply/pda_power.c
|
|
+++ b/drivers/power/supply/pda_power.c
|
|
@@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags(struct resource *res)
|
|
static struct device *dev;
|
|
static struct pda_power_pdata *pdata;
|
|
static struct resource *ac_irq, *usb_irq;
|
|
-static struct timer_list charger_timer;
|
|
-static struct timer_list supply_timer;
|
|
-static struct timer_list polling_timer;
|
|
+static struct delayed_work charger_work;
|
|
+static struct delayed_work polling_work;
|
|
+static struct delayed_work supply_work;
|
|
static int polling;
|
|
static struct power_supply *pda_psy_ac, *pda_psy_usb;
|
|
|
|
@@ -140,7 +140,7 @@ static void update_charger(void)
|
|
}
|
|
}
|
|
|
|
-static void supply_timer_func(unsigned long unused)
|
|
+static void supply_work_func(struct work_struct *work)
|
|
{
|
|
if (ac_status == PDA_PSY_TO_CHANGE) {
|
|
ac_status = new_ac_status;
|
|
@@ -161,11 +161,12 @@ static void psy_changed(void)
|
|
* Okay, charger set. Now wait a bit before notifying supplicants,
|
|
* charge power should stabilize.
|
|
*/
|
|
- mod_timer(&supply_timer,
|
|
- jiffies + msecs_to_jiffies(pdata->wait_for_charger));
|
|
+ cancel_delayed_work(&supply_work);
|
|
+ schedule_delayed_work(&supply_work,
|
|
+ msecs_to_jiffies(pdata->wait_for_charger));
|
|
}
|
|
|
|
-static void charger_timer_func(unsigned long unused)
|
|
+static void charger_work_func(struct work_struct *work)
|
|
{
|
|
update_status();
|
|
psy_changed();
|
|
@@ -184,13 +185,14 @@ static irqreturn_t power_changed_isr(int irq, void *power_supply)
|
|
* Wait a bit before reading ac/usb line status and setting charger,
|
|
* because ac/usb status readings may lag from irq.
|
|
*/
|
|
- mod_timer(&charger_timer,
|
|
- jiffies + msecs_to_jiffies(pdata->wait_for_status));
|
|
+ cancel_delayed_work(&charger_work);
|
|
+ schedule_delayed_work(&charger_work,
|
|
+ msecs_to_jiffies(pdata->wait_for_status));
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
-static void polling_timer_func(unsigned long unused)
|
|
+static void polling_work_func(struct work_struct *work)
|
|
{
|
|
int changed = 0;
|
|
|
|
@@ -211,8 +213,9 @@ static void polling_timer_func(unsigned long unused)
|
|
if (changed)
|
|
psy_changed();
|
|
|
|
- mod_timer(&polling_timer,
|
|
- jiffies + msecs_to_jiffies(pdata->polling_interval));
|
|
+ cancel_delayed_work(&polling_work);
|
|
+ schedule_delayed_work(&polling_work,
|
|
+ msecs_to_jiffies(pdata->polling_interval));
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_USB_PHY)
|
|
@@ -250,8 +253,9 @@ static int otg_handle_notification(struct notifier_block *nb,
|
|
* Wait a bit before reading ac/usb line status and setting charger,
|
|
* because ac/usb status readings may lag from irq.
|
|
*/
|
|
- mod_timer(&charger_timer,
|
|
- jiffies + msecs_to_jiffies(pdata->wait_for_status));
|
|
+ cancel_delayed_work(&charger_work);
|
|
+ schedule_delayed_work(&charger_work,
|
|
+ msecs_to_jiffies(pdata->wait_for_status));
|
|
|
|
return NOTIFY_OK;
|
|
}
|
|
@@ -300,8 +304,8 @@ static int pda_power_probe(struct platform_device *pdev)
|
|
if (!pdata->ac_max_uA)
|
|
pdata->ac_max_uA = 500000;
|
|
|
|
- setup_timer(&charger_timer, charger_timer_func, 0);
|
|
- setup_timer(&supply_timer, supply_timer_func, 0);
|
|
+ INIT_DELAYED_WORK(&charger_work, charger_work_func);
|
|
+ INIT_DELAYED_WORK(&supply_work, supply_work_func);
|
|
|
|
ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
|
|
usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
|
|
@@ -385,9 +389,10 @@ static int pda_power_probe(struct platform_device *pdev)
|
|
|
|
if (polling) {
|
|
dev_dbg(dev, "will poll for status\n");
|
|
- setup_timer(&polling_timer, polling_timer_func, 0);
|
|
- mod_timer(&polling_timer,
|
|
- jiffies + msecs_to_jiffies(pdata->polling_interval));
|
|
+ INIT_DELAYED_WORK(&polling_work, polling_work_func);
|
|
+ cancel_delayed_work(&polling_work);
|
|
+ schedule_delayed_work(&polling_work,
|
|
+ msecs_to_jiffies(pdata->polling_interval));
|
|
}
|
|
|
|
if (ac_irq || usb_irq)
|
|
@@ -433,9 +438,9 @@ static int pda_power_remove(struct platform_device *pdev)
|
|
free_irq(ac_irq->start, pda_psy_ac);
|
|
|
|
if (polling)
|
|
- del_timer_sync(&polling_timer);
|
|
- del_timer_sync(&charger_timer);
|
|
- del_timer_sync(&supply_timer);
|
|
+ cancel_delayed_work_sync(&polling_work);
|
|
+ cancel_delayed_work_sync(&charger_work);
|
|
+ cancel_delayed_work_sync(&supply_work);
|
|
|
|
if (pdata->is_usb_online)
|
|
power_supply_unregister(pda_psy_usb);
|
|
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
|
|
index 86280b7e41f3..2aa5b37cc6d2 100644
|
|
--- a/drivers/ptp/ptp_clock.c
|
|
+++ b/drivers/ptp/ptp_clock.c
|
|
@@ -97,30 +97,26 @@ static s32 scaled_ppm_to_ppb(long ppm)
|
|
|
|
/* posix clock implementation */
|
|
|
|
-static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp)
|
|
+static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
|
|
{
|
|
tp->tv_sec = 0;
|
|
tp->tv_nsec = 1;
|
|
return 0;
|
|
}
|
|
|
|
-static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp)
|
|
+static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp)
|
|
{
|
|
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
|
|
- struct timespec64 ts = timespec_to_timespec64(*tp);
|
|
|
|
- return ptp->info->settime64(ptp->info, &ts);
|
|
+ return ptp->info->settime64(ptp->info, tp);
|
|
}
|
|
|
|
-static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp)
|
|
+static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp)
|
|
{
|
|
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
|
|
- struct timespec64 ts;
|
|
int err;
|
|
|
|
- err = ptp->info->gettime64(ptp->info, &ts);
|
|
- if (!err)
|
|
- *tp = timespec64_to_timespec(ts);
|
|
+ err = ptp->info->gettime64(ptp->info, tp);
|
|
return err;
|
|
}
|
|
|
|
@@ -133,7 +129,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
|
|
ops = ptp->info;
|
|
|
|
if (tx->modes & ADJ_SETOFFSET) {
|
|
- struct timespec ts;
|
|
+ struct timespec64 ts;
|
|
ktime_t kt;
|
|
s64 delta;
|
|
|
|
@@ -146,7 +142,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
|
|
if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
|
|
return -EINVAL;
|
|
|
|
- kt = timespec_to_ktime(ts);
|
|
+ kt = timespec64_to_ktime(ts);
|
|
delta = ktime_to_ns(kt);
|
|
err = ops->adjtime(ops, delta);
|
|
} else if (tx->modes & ADJ_FREQUENCY) {
|
|
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
|
|
index 3a6d0290c54c..c5e272ea4372 100644
|
|
--- a/drivers/regulator/anatop-regulator.c
|
|
+++ b/drivers/regulator/anatop-regulator.c
|
|
@@ -296,6 +296,11 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
|
if (!sreg->sel && !strcmp(sreg->name, "vddpu"))
|
|
sreg->sel = 22;
|
|
|
|
+ /* set the default voltage of the pcie phy to be 1.100v */
|
|
+ if (!sreg->sel && rdesc->name &&
|
|
+ !strcmp(rdesc->name, "vddpcie"))
|
|
+ sreg->sel = 0x10;
|
|
+
|
|
if (!sreg->bypass && !sreg->sel) {
|
|
dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
|
|
return -EINVAL;
|
|
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
|
|
index 7030d7cd3861..c554e529fc4e 100644
|
|
--- a/drivers/rtc/rtc-cmos.c
|
|
+++ b/drivers/rtc/rtc-cmos.c
|
|
@@ -41,6 +41,9 @@
|
|
#include <linux/pm.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_platform.h>
|
|
+#ifdef CONFIG_X86
|
|
+#include <asm/i8259.h>
|
|
+#endif
|
|
|
|
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
|
|
#include <linux/mc146818rtc.h>
|
|
@@ -1117,17 +1120,23 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
|
{
|
|
cmos_wake_setup(&pnp->dev);
|
|
|
|
- if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0))
|
|
+ if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
|
|
+ unsigned int irq = 0;
|
|
+#ifdef CONFIG_X86
|
|
/* Some machines contain a PNP entry for the RTC, but
|
|
* don't define the IRQ. It should always be safe to
|
|
- * hardcode it in these cases
|
|
+ * hardcode it on systems with a legacy PIC.
|
|
*/
|
|
+ if (nr_legacy_irqs())
|
|
+ irq = 8;
|
|
+#endif
|
|
return cmos_do_probe(&pnp->dev,
|
|
- pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
|
|
- else
|
|
+ pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
|
|
+ } else {
|
|
return cmos_do_probe(&pnp->dev,
|
|
pnp_get_resource(pnp, IORESOURCE_IO, 0),
|
|
pnp_irq(pnp, 0));
|
|
+ }
|
|
}
|
|
|
|
static void cmos_pnp_remove(struct pnp_dev *pnp)
|
|
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
|
|
index 3b3049c8c9e0..c0eb113588ff 100644
|
|
--- a/drivers/rtc/rtc-ds1374.c
|
|
+++ b/drivers/rtc/rtc-ds1374.c
|
|
@@ -527,6 +527,10 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd,
|
|
if (get_user(new_margin, (int __user *)arg))
|
|
return -EFAULT;
|
|
|
|
+ /* the hardware's tick rate is 4096 Hz, so
|
|
+ * the counter value needs to be scaled accordingly
|
|
+ */
|
|
+ new_margin <<= 12;
|
|
if (new_margin < 1 || new_margin > 16777216)
|
|
return -EINVAL;
|
|
|
|
@@ -535,7 +539,8 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd,
|
|
ds1374_wdt_ping();
|
|
/* fallthrough */
|
|
case WDIOC_GETTIMEOUT:
|
|
- return put_user(wdt_margin, (int __user *)arg);
|
|
+ /* when returning ... inverse is true */
|
|
+ return put_user((wdt_margin >> 12), (int __user *)arg);
|
|
case WDIOC_SETOPTIONS:
|
|
if (copy_from_user(&options, (int __user *)arg, sizeof(int)))
|
|
return -EFAULT;
|
|
@@ -543,14 +548,15 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd,
|
|
if (options & WDIOS_DISABLECARD) {
|
|
pr_info("disable watchdog\n");
|
|
ds1374_wdt_disable();
|
|
+ return 0;
|
|
}
|
|
|
|
if (options & WDIOS_ENABLECARD) {
|
|
pr_info("enable watchdog\n");
|
|
ds1374_wdt_settimeout(wdt_margin);
|
|
ds1374_wdt_ping();
|
|
+ return 0;
|
|
}
|
|
-
|
|
return -EINVAL;
|
|
}
|
|
return -ENOTTY;
|
|
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
|
index f7e3f27bb5c5..e9ea8f4ea2c9 100644
|
|
--- a/drivers/scsi/lpfc/lpfc_init.c
|
|
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
|
@@ -11312,6 +11312,7 @@ int
|
|
lpfc_fof_queue_create(struct lpfc_hba *phba)
|
|
{
|
|
struct lpfc_queue *qdesc;
|
|
+ uint32_t wqesize;
|
|
|
|
/* Create FOF EQ */
|
|
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize,
|
|
@@ -11332,8 +11333,11 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
|
|
phba->sli4_hba.oas_cq = qdesc;
|
|
|
|
/* Create OAS WQ */
|
|
- qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
|
|
+ wqesize = (phba->fcp_embed_io) ?
|
|
+ LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
|
|
+ qdesc = lpfc_sli4_queue_alloc(phba, wqesize,
|
|
phba->sli4_hba.wq_ecount);
|
|
+
|
|
if (!qdesc)
|
|
goto out_error;
|
|
|
|
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
|
index 8f1df76a77b6..0902ed204ba8 100644
|
|
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
|
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
|
@@ -13696,6 +13696,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
|
|
case LPFC_Q_CREATE_VERSION_1:
|
|
bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1,
|
|
wq->entry_count);
|
|
+ bf_set(lpfc_mbox_hdr_version, &shdr->request,
|
|
+ LPFC_Q_CREATE_VERSION_1);
|
|
+
|
|
switch (wq->entry_size) {
|
|
default:
|
|
case 64:
|
|
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
|
|
index 14c0334f41e4..26c67c42985c 100644
|
|
--- a/drivers/scsi/mac_esp.c
|
|
+++ b/drivers/scsi/mac_esp.c
|
|
@@ -55,6 +55,7 @@ struct mac_esp_priv {
|
|
int error;
|
|
};
|
|
static struct esp *esp_chips[2];
|
|
+static DEFINE_SPINLOCK(esp_chips_lock);
|
|
|
|
#define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \
|
|
platform_get_drvdata((struct platform_device *) \
|
|
@@ -562,15 +563,18 @@ static int esp_mac_probe(struct platform_device *dev)
|
|
}
|
|
|
|
host->irq = IRQ_MAC_SCSI;
|
|
- esp_chips[dev->id] = esp;
|
|
- mb();
|
|
- if (esp_chips[!dev->id] == NULL) {
|
|
- err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
|
|
- if (err < 0) {
|
|
- esp_chips[dev->id] = NULL;
|
|
- goto fail_free_priv;
|
|
- }
|
|
+
|
|
+ /* The request_irq() call is intended to succeed for the first device
|
|
+ * and fail for the second device.
|
|
+ */
|
|
+ err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
|
|
+ spin_lock(&esp_chips_lock);
|
|
+ if (err < 0 && esp_chips[!dev->id] == NULL) {
|
|
+ spin_unlock(&esp_chips_lock);
|
|
+ goto fail_free_priv;
|
|
}
|
|
+ esp_chips[dev->id] = esp;
|
|
+ spin_unlock(&esp_chips_lock);
|
|
|
|
err = scsi_esp_register(esp, &dev->dev);
|
|
if (err)
|
|
@@ -579,8 +583,13 @@ static int esp_mac_probe(struct platform_device *dev)
|
|
return 0;
|
|
|
|
fail_free_irq:
|
|
- if (esp_chips[!dev->id] == NULL)
|
|
+ spin_lock(&esp_chips_lock);
|
|
+ esp_chips[dev->id] = NULL;
|
|
+ if (esp_chips[!dev->id] == NULL) {
|
|
+ spin_unlock(&esp_chips_lock);
|
|
free_irq(host->irq, esp);
|
|
+ } else
|
|
+ spin_unlock(&esp_chips_lock);
|
|
fail_free_priv:
|
|
kfree(mep);
|
|
fail_free_command_block:
|
|
@@ -599,9 +608,13 @@ static int esp_mac_remove(struct platform_device *dev)
|
|
|
|
scsi_esp_unregister(esp);
|
|
|
|
+ spin_lock(&esp_chips_lock);
|
|
esp_chips[dev->id] = NULL;
|
|
- if (!(esp_chips[0] || esp_chips[1]))
|
|
+ if (esp_chips[!dev->id] == NULL) {
|
|
+ spin_unlock(&esp_chips_lock);
|
|
free_irq(irq, NULL);
|
|
+ } else
|
|
+ spin_unlock(&esp_chips_lock);
|
|
|
|
kfree(mep);
|
|
|
|
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
|
|
index c680d7641311..8f4adc1d9588 100644
|
|
--- a/drivers/scsi/virtio_scsi.c
|
|
+++ b/drivers/scsi/virtio_scsi.c
|
|
@@ -28,6 +28,7 @@
|
|
#include <scsi/scsi_device.h>
|
|
#include <scsi/scsi_cmnd.h>
|
|
#include <scsi/scsi_tcq.h>
|
|
+#include <scsi/scsi_devinfo.h>
|
|
#include <linux/seqlock.h>
|
|
|
|
#define VIRTIO_SCSI_MEMPOOL_SZ 64
|
|
@@ -705,6 +706,28 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc)
|
|
return virtscsi_tmf(vscsi, cmd);
|
|
}
|
|
|
|
+static int virtscsi_device_alloc(struct scsi_device *sdevice)
|
|
+{
|
|
+ /*
|
|
+ * Passed through SCSI targets (e.g. with qemu's 'scsi-block')
|
|
+ * may have transfer limits which come from the host SCSI
|
|
+ * controller or something on the host side other than the
|
|
+ * target itself.
|
|
+ *
|
|
+ * To make this work properly, the hypervisor can adjust the
|
|
+ * target's VPD information to advertise these limits. But
|
|
+ * for that to work, the guest has to look at the VPD pages,
|
|
+ * which we won't do by default if it is an SPC-2 device, even
|
|
+ * if it does actually support it.
|
|
+ *
|
|
+ * So, set the blist to always try to read the VPD pages.
|
|
+ */
|
|
+ sdevice->sdev_bflags = BLIST_TRY_VPD_PAGES;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
/**
|
|
* virtscsi_change_queue_depth() - Change a virtscsi target's queue depth
|
|
* @sdev: Virtscsi target whose queue depth to change
|
|
@@ -776,6 +799,7 @@ static struct scsi_host_template virtscsi_host_template_single = {
|
|
.change_queue_depth = virtscsi_change_queue_depth,
|
|
.eh_abort_handler = virtscsi_abort,
|
|
.eh_device_reset_handler = virtscsi_device_reset,
|
|
+ .slave_alloc = virtscsi_device_alloc,
|
|
|
|
.can_queue = 1024,
|
|
.dma_boundary = UINT_MAX,
|
|
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
|
|
index 2707a827261b..5482302d3d9e 100644
|
|
--- a/drivers/soc/fsl/qe/qe.c
|
|
+++ b/drivers/soc/fsl/qe/qe.c
|
|
@@ -163,11 +163,15 @@ EXPORT_SYMBOL(qe_issue_cmd);
|
|
*/
|
|
static unsigned int brg_clk = 0;
|
|
|
|
+#define CLK_GRAN (1000)
|
|
+#define CLK_GRAN_LIMIT (5)
|
|
+
|
|
unsigned int qe_get_brg_clk(void)
|
|
{
|
|
struct device_node *qe;
|
|
int size;
|
|
const u32 *prop;
|
|
+ unsigned int mod;
|
|
|
|
if (brg_clk)
|
|
return brg_clk;
|
|
@@ -185,6 +189,15 @@ unsigned int qe_get_brg_clk(void)
|
|
|
|
of_node_put(qe);
|
|
|
|
+ /* round this if near to a multiple of CLK_GRAN */
|
|
+ mod = brg_clk % CLK_GRAN;
|
|
+ if (mod) {
|
|
+ if (mod < CLK_GRAN_LIMIT)
|
|
+ brg_clk -= mod;
|
|
+ else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT))
|
|
+ brg_clk += CLK_GRAN - mod;
|
|
+ }
|
|
+
|
|
return brg_clk;
|
|
}
|
|
EXPORT_SYMBOL(qe_get_brg_clk);
|
|
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
|
|
index 447497e9124c..d25cc4037e23 100644
|
|
--- a/drivers/spi/spi-dw-mmio.c
|
|
+++ b/drivers/spi/spi-dw-mmio.c
|
|
@@ -115,8 +115,8 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
|
|
{
|
|
struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
|
|
|
|
- clk_disable_unprepare(dwsmmio->clk);
|
|
dw_spi_remove_host(&dwsmmio->dws);
|
|
+ clk_disable_unprepare(dwsmmio->clk);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
|
|
index db100154f85c..6d690e5fa9bb 100644
|
|
--- a/drivers/staging/android/ashmem.c
|
|
+++ b/drivers/staging/android/ashmem.c
|
|
@@ -718,16 +718,14 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
|
|
size_t pgstart, pgend;
|
|
int ret = -EINVAL;
|
|
|
|
+ if (unlikely(copy_from_user(&pin, p, sizeof(pin))))
|
|
+ return -EFAULT;
|
|
+
|
|
mutex_lock(&ashmem_mutex);
|
|
|
|
if (unlikely(!asma->file))
|
|
goto out_unlock;
|
|
|
|
- if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) {
|
|
- ret = -EFAULT;
|
|
- goto out_unlock;
|
|
- }
|
|
-
|
|
/* per custom, you can pass zero for len to mean "everything onward" */
|
|
if (!pin.len)
|
|
pin.len = PAGE_ALIGN(asma->size) - pin.offset;
|
|
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
|
|
index 5a7a87efed27..28b5392153a8 100644
|
|
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
|
|
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
|
|
@@ -842,7 +842,7 @@ static void
|
|
do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
|
|
{
|
|
struct scsi_device *scsidev;
|
|
- unsigned char buf[36];
|
|
+ unsigned char *buf;
|
|
struct scatterlist *sg;
|
|
unsigned int i;
|
|
char *this_page;
|
|
@@ -857,6 +857,10 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
|
|
if (cmdrsp->scsi.no_disk_result == 0)
|
|
return;
|
|
|
|
+ buf = kzalloc(sizeof(char) * 36, GFP_KERNEL);
|
|
+ if (!buf)
|
|
+ return;
|
|
+
|
|
/* Linux scsi code wants a device at Lun 0
|
|
* to issue report luns, but we don't want
|
|
* a disk there so we'll present a processor
|
|
@@ -868,6 +872,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
|
|
if (scsi_sg_count(scsicmd) == 0) {
|
|
memcpy(scsi_sglist(scsicmd), buf,
|
|
cmdrsp->scsi.bufflen);
|
|
+ kfree(buf);
|
|
return;
|
|
}
|
|
|
|
@@ -879,6 +884,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
|
|
memcpy(this_page, buf + bufind, sg[i].length);
|
|
kunmap_atomic(this_page_orig);
|
|
}
|
|
+ kfree(buf);
|
|
} else {
|
|
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
|
|
for_each_vdisk_match(vdisk, devdata, scsidev) {
|
|
diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c
|
|
index 242f82f4d24f..d8ab4cb11289 100644
|
|
--- a/drivers/staging/wilc1000/linux_mon.c
|
|
+++ b/drivers/staging/wilc1000/linux_mon.c
|
|
@@ -197,6 +197,8 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
|
|
|
|
if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) {
|
|
skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr));
|
|
+ if (!skb2)
|
|
+ return -ENOMEM;
|
|
|
|
memcpy(skb_put(skb2, skb->len), skb->data, skb->len);
|
|
|
|
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
|
|
index 97928b42ad62..57a3d3936364 100644
|
|
--- a/drivers/target/target_core_file.c
|
|
+++ b/drivers/target/target_core_file.c
|
|
@@ -276,12 +276,11 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,
|
|
else
|
|
ret = vfs_iter_read(fd, &iter, &pos);
|
|
|
|
- kfree(bvec);
|
|
-
|
|
if (is_write) {
|
|
if (ret < 0 || ret != data_length) {
|
|
pr_err("%s() write returned %d\n", __func__, ret);
|
|
- return (ret < 0 ? ret : -EINVAL);
|
|
+ if (ret >= 0)
|
|
+ ret = -EINVAL;
|
|
}
|
|
} else {
|
|
/*
|
|
@@ -294,17 +293,29 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,
|
|
pr_err("%s() returned %d, expecting %u for "
|
|
"S_ISBLK\n", __func__, ret,
|
|
data_length);
|
|
- return (ret < 0 ? ret : -EINVAL);
|
|
+ if (ret >= 0)
|
|
+ ret = -EINVAL;
|
|
}
|
|
} else {
|
|
if (ret < 0) {
|
|
pr_err("%s() returned %d for non S_ISBLK\n",
|
|
__func__, ret);
|
|
- return ret;
|
|
+ } else if (ret != data_length) {
|
|
+ /*
|
|
+ * Short read case:
|
|
+ * Probably some one truncate file under us.
|
|
+ * We must explicitly zero sg-pages to prevent
|
|
+ * expose uninizialized pages to userspace.
|
|
+ */
|
|
+ if (ret < data_length)
|
|
+ ret += iov_iter_zero(data_length - ret, &iter);
|
|
+ else
|
|
+ ret = -EINVAL;
|
|
}
|
|
}
|
|
}
|
|
- return 1;
|
|
+ kfree(bvec);
|
|
+ return ret;
|
|
}
|
|
|
|
static sense_reason_t
|
|
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
|
|
index 459d726f9d59..3eb01a719d22 100644
|
|
--- a/drivers/tty/serial/8250/8250_dw.c
|
|
+++ b/drivers/tty/serial/8250/8250_dw.c
|
|
@@ -464,7 +464,8 @@ static int dw8250_probe(struct platform_device *pdev)
|
|
/* If no clock rate is defined, fail. */
|
|
if (!p->uartclk) {
|
|
dev_err(dev, "clock rate not defined\n");
|
|
- return -EINVAL;
|
|
+ err = -EINVAL;
|
|
+ goto err_clk;
|
|
}
|
|
|
|
data->pclk = devm_clk_get(dev, "apb_pclk");
|
|
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
|
|
index 8d9f9a803b42..fb9bada5f1d5 100644
|
|
--- a/drivers/tty/tty_io.c
|
|
+++ b/drivers/tty/tty_io.c
|
|
@@ -1702,6 +1702,8 @@ static void release_tty(struct tty_struct *tty, int idx)
|
|
if (tty->link)
|
|
tty->link->port->itty = NULL;
|
|
tty_buffer_cancel_work(tty->port);
|
|
+ if (tty->link)
|
|
+ tty_buffer_cancel_work(tty->link->port);
|
|
|
|
tty_kref_put(tty->link);
|
|
tty_kref_put(tty);
|
|
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
|
|
index b6d4b484c51a..5815120c0402 100644
|
|
--- a/drivers/usb/gadget/function/f_hid.c
|
|
+++ b/drivers/usb/gadget/function/f_hid.c
|
|
@@ -284,6 +284,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
|
size_t count, loff_t *offp)
|
|
{
|
|
struct f_hidg *hidg = file->private_data;
|
|
+ struct usb_request *req;
|
|
unsigned long flags;
|
|
ssize_t status = -ENOMEM;
|
|
|
|
@@ -293,7 +294,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
|
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
|
|
|
#define WRITE_COND (!hidg->write_pending)
|
|
-
|
|
+try_again:
|
|
/* write queue */
|
|
while (!WRITE_COND) {
|
|
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
@@ -308,6 +309,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
|
}
|
|
|
|
hidg->write_pending = 1;
|
|
+ req = hidg->req;
|
|
count = min_t(unsigned, count, hidg->report_length);
|
|
|
|
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
@@ -320,24 +322,38 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
|
goto release_write_pending;
|
|
}
|
|
|
|
- hidg->req->status = 0;
|
|
- hidg->req->zero = 0;
|
|
- hidg->req->length = count;
|
|
- hidg->req->complete = f_hidg_req_complete;
|
|
- hidg->req->context = hidg;
|
|
+ spin_lock_irqsave(&hidg->write_spinlock, flags);
|
|
+
|
|
+ /* we our function has been disabled by host */
|
|
+ if (!hidg->req) {
|
|
+ free_ep_req(hidg->in_ep, hidg->req);
|
|
+ /*
|
|
+ * TODO
|
|
+ * Should we fail with error here?
|
|
+ */
|
|
+ goto try_again;
|
|
+ }
|
|
+
|
|
+ req->status = 0;
|
|
+ req->zero = 0;
|
|
+ req->length = count;
|
|
+ req->complete = f_hidg_req_complete;
|
|
+ req->context = hidg;
|
|
|
|
status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
|
|
if (status < 0) {
|
|
ERROR(hidg->func.config->cdev,
|
|
"usb_ep_queue error on int endpoint %zd\n", status);
|
|
- goto release_write_pending;
|
|
+ goto release_write_pending_unlocked;
|
|
} else {
|
|
status = count;
|
|
}
|
|
+ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
|
|
return status;
|
|
release_write_pending:
|
|
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
|
+release_write_pending_unlocked:
|
|
hidg->write_pending = 0;
|
|
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
|
|
@@ -541,12 +557,23 @@ static void hidg_disable(struct usb_function *f)
|
|
kfree(list);
|
|
}
|
|
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
|
+
|
|
+ spin_lock_irqsave(&hidg->write_spinlock, flags);
|
|
+ if (!hidg->write_pending) {
|
|
+ free_ep_req(hidg->in_ep, hidg->req);
|
|
+ hidg->write_pending = 1;
|
|
+ }
|
|
+
|
|
+ hidg->req = NULL;
|
|
+ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
}
|
|
|
|
static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|
{
|
|
struct usb_composite_dev *cdev = f->config->cdev;
|
|
struct f_hidg *hidg = func_to_hidg(f);
|
|
+ struct usb_request *req_in = NULL;
|
|
+ unsigned long flags;
|
|
int i, status = 0;
|
|
|
|
VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
|
|
@@ -567,6 +594,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|
goto fail;
|
|
}
|
|
hidg->in_ep->driver_data = hidg;
|
|
+
|
|
+ req_in = hidg_alloc_ep_req(hidg->in_ep, hidg->report_length);
|
|
+ if (!req_in) {
|
|
+ status = -ENOMEM;
|
|
+ goto disable_ep_in;
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -578,12 +611,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|
hidg->out_ep);
|
|
if (status) {
|
|
ERROR(cdev, "config_ep_by_speed FAILED!\n");
|
|
- goto fail;
|
|
+ goto free_req_in;
|
|
}
|
|
status = usb_ep_enable(hidg->out_ep);
|
|
if (status < 0) {
|
|
ERROR(cdev, "Enable OUT endpoint FAILED!\n");
|
|
- goto fail;
|
|
+ goto free_req_in;
|
|
}
|
|
hidg->out_ep->driver_data = hidg;
|
|
|
|
@@ -599,17 +632,37 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|
req->context = hidg;
|
|
status = usb_ep_queue(hidg->out_ep, req,
|
|
GFP_ATOMIC);
|
|
- if (status)
|
|
+ if (status) {
|
|
ERROR(cdev, "%s queue req --> %d\n",
|
|
hidg->out_ep->name, status);
|
|
+ free_ep_req(hidg->out_ep, req);
|
|
+ }
|
|
} else {
|
|
- usb_ep_disable(hidg->out_ep);
|
|
status = -ENOMEM;
|
|
- goto fail;
|
|
+ goto disable_out_ep;
|
|
}
|
|
}
|
|
}
|
|
|
|
+ if (hidg->in_ep != NULL) {
|
|
+ spin_lock_irqsave(&hidg->write_spinlock, flags);
|
|
+ hidg->req = req_in;
|
|
+ hidg->write_pending = 0;
|
|
+ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
|
+
|
|
+ wake_up(&hidg->write_queue);
|
|
+ }
|
|
+ return 0;
|
|
+disable_out_ep:
|
|
+ usb_ep_disable(hidg->out_ep);
|
|
+free_req_in:
|
|
+ if (req_in)
|
|
+ free_ep_req(hidg->in_ep, req_in);
|
|
+
|
|
+disable_ep_in:
|
|
+ if (hidg->in_ep)
|
|
+ usb_ep_disable(hidg->in_ep);
|
|
+
|
|
fail:
|
|
return status;
|
|
}
|
|
@@ -658,12 +711,6 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|
goto fail;
|
|
hidg->out_ep = ep;
|
|
|
|
- /* preallocate request and buffer */
|
|
- status = -ENOMEM;
|
|
- hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length);
|
|
- if (!hidg->req)
|
|
- goto fail;
|
|
-
|
|
/* set descriptor dynamic values */
|
|
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
|
|
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
|
|
@@ -690,6 +737,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|
goto fail;
|
|
|
|
spin_lock_init(&hidg->write_spinlock);
|
|
+ hidg->write_pending = 1;
|
|
+ hidg->req = NULL;
|
|
spin_lock_init(&hidg->read_spinlock);
|
|
init_waitqueue_head(&hidg->write_queue);
|
|
init_waitqueue_head(&hidg->read_queue);
|
|
@@ -954,10 +1003,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
|
|
device_destroy(hidg_class, MKDEV(major, hidg->minor));
|
|
cdev_del(&hidg->cdev);
|
|
|
|
- /* disable/free request and end point */
|
|
- usb_ep_disable(hidg->in_ep);
|
|
- free_ep_req(hidg->in_ep, hidg->req);
|
|
-
|
|
usb_free_all_descriptors(f);
|
|
}
|
|
|
|
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
|
|
index 11576611a974..dda1c4b3a229 100644
|
|
--- a/drivers/video/console/vgacon.c
|
|
+++ b/drivers/video/console/vgacon.c
|
|
@@ -405,7 +405,10 @@ static const char *vgacon_startup(void)
|
|
vga_video_port_val = VGA_CRT_DM;
|
|
if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
|
|
static struct resource ega_console_resource =
|
|
- { .name = "ega", .start = 0x3B0, .end = 0x3BF };
|
|
+ { .name = "ega",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3B0,
|
|
+ .end = 0x3BF };
|
|
vga_video_type = VIDEO_TYPE_EGAM;
|
|
vga_vram_size = 0x8000;
|
|
display_desc = "EGA+";
|
|
@@ -413,9 +416,15 @@ static const char *vgacon_startup(void)
|
|
&ega_console_resource);
|
|
} else {
|
|
static struct resource mda1_console_resource =
|
|
- { .name = "mda", .start = 0x3B0, .end = 0x3BB };
|
|
+ { .name = "mda",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3B0,
|
|
+ .end = 0x3BB };
|
|
static struct resource mda2_console_resource =
|
|
- { .name = "mda", .start = 0x3BF, .end = 0x3BF };
|
|
+ { .name = "mda",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3BF,
|
|
+ .end = 0x3BF };
|
|
vga_video_type = VIDEO_TYPE_MDA;
|
|
vga_vram_size = 0x2000;
|
|
display_desc = "*MDA";
|
|
@@ -437,15 +446,21 @@ static const char *vgacon_startup(void)
|
|
vga_vram_size = 0x8000;
|
|
|
|
if (!screen_info.orig_video_isVGA) {
|
|
- static struct resource ega_console_resource
|
|
- = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
|
|
+ static struct resource ega_console_resource =
|
|
+ { .name = "ega",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3C0,
|
|
+ .end = 0x3DF };
|
|
vga_video_type = VIDEO_TYPE_EGAC;
|
|
display_desc = "EGA";
|
|
request_resource(&ioport_resource,
|
|
&ega_console_resource);
|
|
} else {
|
|
- static struct resource vga_console_resource
|
|
- = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
|
|
+ static struct resource vga_console_resource =
|
|
+ { .name = "vga+",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3C0,
|
|
+ .end = 0x3DF };
|
|
vga_video_type = VIDEO_TYPE_VGAC;
|
|
display_desc = "VGA+";
|
|
request_resource(&ioport_resource,
|
|
@@ -489,7 +504,10 @@ static const char *vgacon_startup(void)
|
|
}
|
|
} else {
|
|
static struct resource cga_console_resource =
|
|
- { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
|
|
+ { .name = "cga",
|
|
+ .flags = IORESOURCE_IO,
|
|
+ .start = 0x3D4,
|
|
+ .end = 0x3D5 };
|
|
vga_video_type = VIDEO_TYPE_CGA;
|
|
vga_vram_size = 0x2000;
|
|
display_desc = "*CGA";
|
|
diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c
|
|
index b529a8c2b652..3984716096aa 100644
|
|
--- a/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c
|
|
+++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c
|
|
@@ -455,6 +455,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
|
|
}
|
|
|
|
static const struct of_device_id td028ttec1_of_match[] = {
|
|
+ { .compatible = "omapdss,tpo,td028ttec1", },
|
|
+ /* keep to not break older DTB */
|
|
{ .compatible = "omapdss,toppoly,td028ttec1", },
|
|
{},
|
|
};
|
|
@@ -474,6 +476,7 @@ static struct spi_driver td028ttec1_spi_driver = {
|
|
|
|
module_spi_driver(td028ttec1_spi_driver);
|
|
|
|
+MODULE_ALIAS("spi:tpo,td028ttec1");
|
|
MODULE_ALIAS("spi:toppoly,td028ttec1");
|
|
MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
|
|
MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
|
|
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
|
|
index d0a4e2f79a57..d215faacce04 100644
|
|
--- a/drivers/video/fbdev/sm501fb.c
|
|
+++ b/drivers/video/fbdev/sm501fb.c
|
|
@@ -1600,6 +1600,7 @@ static int sm501fb_start(struct sm501fb_info *info,
|
|
info->fbmem = ioremap(res->start, resource_size(res));
|
|
if (info->fbmem == NULL) {
|
|
dev_err(dev, "cannot remap framebuffer\n");
|
|
+ ret = -ENXIO;
|
|
goto err_mem_res;
|
|
}
|
|
|
|
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
|
|
index 53326badfb61..2add8def83be 100644
|
|
--- a/drivers/video/fbdev/udlfb.c
|
|
+++ b/drivers/video/fbdev/udlfb.c
|
|
@@ -1487,15 +1487,25 @@ static struct device_attribute fb_device_attrs[] = {
|
|
static int dlfb_select_std_channel(struct dlfb_data *dev)
|
|
{
|
|
int ret;
|
|
- u8 set_def_chn[] = { 0x57, 0xCD, 0xDC, 0xA7,
|
|
+ void *buf;
|
|
+ static const u8 set_def_chn[] = {
|
|
+ 0x57, 0xCD, 0xDC, 0xA7,
|
|
0x1C, 0x88, 0x5E, 0x15,
|
|
0x60, 0xFE, 0xC6, 0x97,
|
|
0x16, 0x3D, 0x47, 0xF2 };
|
|
|
|
+ buf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL);
|
|
+
|
|
+ if (!buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
|
|
NR_USB_REQUEST_CHANNEL,
|
|
(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
|
|
- set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
|
|
+ buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
|
|
+
|
|
+ kfree(buf);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
|
|
index 32930a073a12..977fe74e5abe 100644
|
|
--- a/drivers/watchdog/watchdog_dev.c
|
|
+++ b/drivers/watchdog/watchdog_dev.c
|
|
@@ -760,6 +760,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
|
|
{
|
|
struct watchdog_core_data *wd_data;
|
|
struct watchdog_device *wdd;
|
|
+ bool hw_running;
|
|
int err;
|
|
|
|
/* Get the corresponding watchdog device */
|
|
@@ -779,7 +780,8 @@ static int watchdog_open(struct inode *inode, struct file *file)
|
|
* If the /dev/watchdog device is open, we don't want the module
|
|
* to be unloaded.
|
|
*/
|
|
- if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) {
|
|
+ hw_running = watchdog_hw_running(wdd);
|
|
+ if (!hw_running && !try_module_get(wdd->ops->owner)) {
|
|
err = -EBUSY;
|
|
goto out_clear;
|
|
}
|
|
@@ -790,7 +792,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
|
|
|
|
file->private_data = wd_data;
|
|
|
|
- if (!watchdog_hw_running(wdd))
|
|
+ if (!hw_running)
|
|
kref_get(&wd_data->kref);
|
|
|
|
/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
|
|
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
|
|
index 3286a6e47ff0..c95ff096cd24 100644
|
|
--- a/fs/btrfs/file.c
|
|
+++ b/fs/btrfs/file.c
|
|
@@ -2817,8 +2817,10 @@ static long btrfs_fallocate(struct file *file, int mode,
|
|
}
|
|
ret = btrfs_qgroup_reserve_data(inode, cur_offset,
|
|
last_byte - cur_offset);
|
|
- if (ret < 0)
|
|
+ if (ret < 0) {
|
|
+ free_extent_map(em);
|
|
break;
|
|
+ }
|
|
} else {
|
|
/*
|
|
* Do not need to reserve unwritten extent for this
|
|
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
|
index d196ce4be31c..ffd5831ca15c 100644
|
|
--- a/fs/btrfs/inode.c
|
|
+++ b/fs/btrfs/inode.c
|
|
@@ -567,8 +567,10 @@ static noinline void compress_file_range(struct inode *inode,
|
|
PAGE_SET_WRITEBACK |
|
|
page_error_op |
|
|
PAGE_END_WRITEBACK);
|
|
- btrfs_free_reserved_data_space_noquota(inode, start,
|
|
- end - start + 1);
|
|
+ if (ret == 0)
|
|
+ btrfs_free_reserved_data_space_noquota(inode,
|
|
+ start,
|
|
+ end - start + 1);
|
|
goto free_pages_out;
|
|
}
|
|
}
|
|
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
|
|
index 9a47b5598df7..d040afc966fe 100644
|
|
--- a/fs/btrfs/send.c
|
|
+++ b/fs/btrfs/send.c
|
|
@@ -5156,13 +5156,19 @@ static int is_extent_unchanged(struct send_ctx *sctx,
|
|
while (key.offset < ekey->offset + left_len) {
|
|
ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
|
|
right_type = btrfs_file_extent_type(eb, ei);
|
|
- if (right_type != BTRFS_FILE_EXTENT_REG) {
|
|
+ if (right_type != BTRFS_FILE_EXTENT_REG &&
|
|
+ right_type != BTRFS_FILE_EXTENT_INLINE) {
|
|
ret = 0;
|
|
goto out;
|
|
}
|
|
|
|
right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
|
|
- right_len = btrfs_file_extent_num_bytes(eb, ei);
|
|
+ if (right_type == BTRFS_FILE_EXTENT_INLINE) {
|
|
+ right_len = btrfs_file_extent_inline_len(eb, slot, ei);
|
|
+ right_len = PAGE_ALIGN(right_len);
|
|
+ } else {
|
|
+ right_len = btrfs_file_extent_num_bytes(eb, ei);
|
|
+ }
|
|
right_offset = btrfs_file_extent_offset(eb, ei);
|
|
right_gen = btrfs_file_extent_generation(eb, ei);
|
|
|
|
@@ -5176,6 +5182,19 @@ static int is_extent_unchanged(struct send_ctx *sctx,
|
|
goto out;
|
|
}
|
|
|
|
+ /*
|
|
+ * We just wanted to see if when we have an inline extent, what
|
|
+ * follows it is a regular extent (wanted to check the above
|
|
+ * condition for inline extents too). This should normally not
|
|
+ * happen but it's possible for example when we have an inline
|
|
+ * compressed extent representing data with a size matching
|
|
+ * the page size (currently the same as sector size).
|
|
+ */
|
|
+ if (right_type == BTRFS_FILE_EXTENT_INLINE) {
|
|
+ ret = 0;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
left_offset_fixed = left_offset;
|
|
if (key.offset < ekey->offset) {
|
|
/* Fix the right offset for 2a and 7. */
|
|
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
|
|
index 5900508ca6ed..4730ba2cc049 100644
|
|
--- a/fs/btrfs/volumes.c
|
|
+++ b/fs/btrfs/volumes.c
|
|
@@ -3765,6 +3765,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
|
|
struct btrfs_ioctl_balance_args *bargs)
|
|
{
|
|
struct btrfs_fs_info *fs_info = bctl->fs_info;
|
|
+ u64 meta_target, data_target;
|
|
u64 allowed;
|
|
int mixed = 0;
|
|
int ret;
|
|
@@ -3861,11 +3862,16 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
|
|
}
|
|
} while (read_seqretry(&fs_info->profiles_lock, seq));
|
|
|
|
- if (btrfs_get_num_tolerated_disk_barrier_failures(bctl->meta.target) <
|
|
- btrfs_get_num_tolerated_disk_barrier_failures(bctl->data.target)) {
|
|
+ /* if we're not converting, the target field is uninitialized */
|
|
+ meta_target = (bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) ?
|
|
+ bctl->meta.target : fs_info->avail_metadata_alloc_bits;
|
|
+ data_target = (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) ?
|
|
+ bctl->data.target : fs_info->avail_data_alloc_bits;
|
|
+ if (btrfs_get_num_tolerated_disk_barrier_failures(meta_target) <
|
|
+ btrfs_get_num_tolerated_disk_barrier_failures(data_target)) {
|
|
btrfs_warn(fs_info,
|
|
"metadata profile 0x%llx has lower redundancy than data profile 0x%llx",
|
|
- bctl->meta.target, bctl->data.target);
|
|
+ meta_target, data_target);
|
|
}
|
|
|
|
if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
|
|
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
|
|
index abae6dd2c6b9..cc88f4f0325e 100644
|
|
--- a/fs/cifs/netmisc.c
|
|
+++ b/fs/cifs/netmisc.c
|
|
@@ -980,10 +980,10 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
|
cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
|
|
days = sd->Day;
|
|
month = sd->Month;
|
|
- if ((days > 31) || (month > 12)) {
|
|
+ if (days < 1 || days > 31 || month < 1 || month > 12) {
|
|
cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days);
|
|
- if (month > 12)
|
|
- month = 12;
|
|
+ days = clamp(days, 1, 31);
|
|
+ month = clamp(month, 1, 12);
|
|
}
|
|
month -= 1;
|
|
days += total_days_of_prev_months[month];
|
|
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
|
|
index 538d9b55699a..c3db2a882aee 100644
|
|
--- a/fs/cifs/sess.c
|
|
+++ b/fs/cifs/sess.c
|
|
@@ -344,13 +344,12 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
|
/* BB is NTLMV2 session security format easier to use here? */
|
|
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
|
|
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
|
|
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
|
- if (ses->server->sign) {
|
|
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
|
|
+ NTLMSSP_NEGOTIATE_SEAL;
|
|
+ if (ses->server->sign)
|
|
flags |= NTLMSSP_NEGOTIATE_SIGN;
|
|
- if (!ses->server->session_estab ||
|
|
- ses->ntlmssp->sesskey_per_smbsess)
|
|
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
|
- }
|
|
+ if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
|
|
+ flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
|
|
|
sec_blob->NegotiateFlags = cpu_to_le32(flags);
|
|
|
|
@@ -407,13 +406,12 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
|
|
flags = NTLMSSP_NEGOTIATE_56 |
|
|
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
|
|
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
|
|
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
|
- if (ses->server->sign) {
|
|
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
|
|
+ NTLMSSP_NEGOTIATE_SEAL;
|
|
+ if (ses->server->sign)
|
|
flags |= NTLMSSP_NEGOTIATE_SIGN;
|
|
- if (!ses->server->session_estab ||
|
|
- ses->ntlmssp->sesskey_per_smbsess)
|
|
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
|
- }
|
|
+ if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
|
|
+ flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
|
|
|
tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
|
sec_blob->NegotiateFlags = cpu_to_le32(flags);
|
|
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
|
|
index 94c4c1901222..7c26286a525d 100644
|
|
--- a/fs/cifs/smb2pdu.c
|
|
+++ b/fs/cifs/smb2pdu.c
|
|
@@ -707,15 +707,13 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
|
|
struct cifs_ses *ses = sess_data->ses;
|
|
|
|
mutex_lock(&ses->server->srv_mutex);
|
|
- if (ses->server->sign && ses->server->ops->generate_signingkey) {
|
|
+ if (ses->server->ops->generate_signingkey) {
|
|
rc = ses->server->ops->generate_signingkey(ses);
|
|
- kfree(ses->auth_key.response);
|
|
- ses->auth_key.response = NULL;
|
|
if (rc) {
|
|
cifs_dbg(FYI,
|
|
"SMB3 session key generation failed\n");
|
|
mutex_unlock(&ses->server->srv_mutex);
|
|
- goto keygen_exit;
|
|
+ return rc;
|
|
}
|
|
}
|
|
if (!ses->server->session_estab) {
|
|
@@ -729,12 +727,6 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
|
|
ses->status = CifsGood;
|
|
ses->need_reconnect = false;
|
|
spin_unlock(&GlobalMid_Lock);
|
|
-
|
|
-keygen_exit:
|
|
- if (!ses->server->sign) {
|
|
- kfree(ses->auth_key.response);
|
|
- ses->auth_key.response = NULL;
|
|
- }
|
|
return rc;
|
|
}
|
|
|
|
@@ -1712,6 +1704,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
} else
|
|
iov[0].iov_len = get_rfc1002_length(req) + 4;
|
|
|
|
+ /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
|
|
+ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
|
|
+ req->hdr.Flags |= SMB2_FLAGS_SIGNED;
|
|
|
|
rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
|
|
rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
|
|
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
|
|
index 7d4b557f1962..047c8ef620fe 100644
|
|
--- a/fs/jbd2/journal.c
|
|
+++ b/fs/jbd2/journal.c
|
|
@@ -691,8 +691,21 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
|
|
{
|
|
int err = 0;
|
|
|
|
- jbd2_might_wait_for_commit(journal);
|
|
read_lock(&journal->j_state_lock);
|
|
+#ifdef CONFIG_PROVE_LOCKING
|
|
+ /*
|
|
+ * Some callers make sure transaction is already committing and in that
|
|
+ * case we cannot block on open handles anymore. So don't warn in that
|
|
+ * case.
|
|
+ */
|
|
+ if (tid_gt(tid, journal->j_commit_sequence) &&
|
|
+ (!journal->j_committing_transaction ||
|
|
+ journal->j_committing_transaction->t_tid != tid)) {
|
|
+ read_unlock(&journal->j_state_lock);
|
|
+ jbd2_might_wait_for_commit(journal);
|
|
+ read_lock(&journal->j_state_lock);
|
|
+ }
|
|
+#endif
|
|
#ifdef CONFIG_JBD2_DEBUG
|
|
if (!tid_geq(journal->j_commit_request, tid)) {
|
|
printk(KERN_ERR
|
|
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
|
|
index 3d17fc82b9fe..892c88542ebd 100644
|
|
--- a/fs/nfs/pagelist.c
|
|
+++ b/fs/nfs/pagelist.c
|
|
@@ -1262,8 +1262,10 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
|
|
mirror = &desc->pg_mirrors[midx];
|
|
if (!list_empty(&mirror->pg_list)) {
|
|
prev = nfs_list_entry(mirror->pg_list.prev);
|
|
- if (index != prev->wb_index + 1)
|
|
- nfs_pageio_complete_mirror(desc, midx);
|
|
+ if (index != prev->wb_index + 1) {
|
|
+ nfs_pageio_complete(desc);
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
|
|
index b8e44746f761..0e008db16b16 100644
|
|
--- a/fs/nfs/pnfs.c
|
|
+++ b/fs/nfs/pnfs.c
|
|
@@ -1953,8 +1953,6 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
|
|
|
|
spin_lock(&inode->i_lock);
|
|
pnfs_set_plh_return_info(lo, range.iomode, 0);
|
|
- /* Block LAYOUTGET */
|
|
- set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
|
|
/*
|
|
* mark all matching lsegs so that we are sure to have no live
|
|
* segments at hand when sending layoutreturn. See pnfs_put_lseg()
|
|
@@ -2308,10 +2306,20 @@ pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr)
|
|
enum pnfs_try_status trypnfs;
|
|
|
|
trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
|
|
- if (trypnfs == PNFS_TRY_AGAIN)
|
|
- pnfs_read_resend_pnfs(hdr);
|
|
- if (trypnfs == PNFS_NOT_ATTEMPTED || hdr->task.tk_status)
|
|
+ switch (trypnfs) {
|
|
+ case PNFS_NOT_ATTEMPTED:
|
|
pnfs_read_through_mds(desc, hdr);
|
|
+ case PNFS_ATTEMPTED:
|
|
+ break;
|
|
+ case PNFS_TRY_AGAIN:
|
|
+ /* cleanup hdr and prepare to redo pnfs */
|
|
+ if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
|
|
+ struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
|
|
+ list_splice_init(&hdr->pages, &mirror->pg_list);
|
|
+ mirror->pg_recoalesce = 1;
|
|
+ }
|
|
+ hdr->mds_ops->rpc_release(hdr);
|
|
+ }
|
|
}
|
|
|
|
static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
|
|
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
|
|
index 022d95886d66..eef0caf6e67d 100644
|
|
--- a/fs/nfsd/nfs4proc.c
|
|
+++ b/fs/nfsd/nfs4proc.c
|
|
@@ -1338,14 +1338,14 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
|
|
const struct nfsd4_layout_ops *ops;
|
|
struct nfs4_layout_stateid *ls;
|
|
__be32 nfserr;
|
|
- int accmode;
|
|
+ int accmode = NFSD_MAY_READ_IF_EXEC;
|
|
|
|
switch (lgp->lg_seg.iomode) {
|
|
case IOMODE_READ:
|
|
- accmode = NFSD_MAY_READ;
|
|
+ accmode |= NFSD_MAY_READ;
|
|
break;
|
|
case IOMODE_RW:
|
|
- accmode = NFSD_MAY_READ | NFSD_MAY_WRITE;
|
|
+ accmode |= NFSD_MAY_READ | NFSD_MAY_WRITE;
|
|
break;
|
|
default:
|
|
dprintk("%s: invalid iomode %d\n",
|
|
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
|
|
index b829cc9a9b39..8f0b19a3ca81 100644
|
|
--- a/fs/nfsd/vfs.c
|
|
+++ b/fs/nfsd/vfs.c
|
|
@@ -94,6 +94,12 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
|
|
err = follow_down(&path);
|
|
if (err < 0)
|
|
goto out;
|
|
+ if (path.mnt == exp->ex_path.mnt && path.dentry == dentry &&
|
|
+ nfsd_mountpoint(dentry, exp) == 2) {
|
|
+ /* This is only a mountpoint in some other namespace */
|
|
+ path_put(&path);
|
|
+ goto out;
|
|
+ }
|
|
|
|
exp2 = rqst_exp_get_by_name(rqstp, &path);
|
|
if (IS_ERR(exp2)) {
|
|
@@ -167,16 +173,26 @@ static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, st
|
|
/*
|
|
* For nfsd purposes, we treat V4ROOT exports as though there was an
|
|
* export at *every* directory.
|
|
+ * We return:
|
|
+ * '1' if this dentry *must* be an export point,
|
|
+ * '2' if it might be, if there is really a mount here, and
|
|
+ * '0' if there is no chance of an export point here.
|
|
*/
|
|
int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
|
|
{
|
|
- if (d_mountpoint(dentry))
|
|
+ if (!d_inode(dentry))
|
|
+ return 0;
|
|
+ if (exp->ex_flags & NFSEXP_V4ROOT)
|
|
return 1;
|
|
if (nfsd4_is_junction(dentry))
|
|
return 1;
|
|
- if (!(exp->ex_flags & NFSEXP_V4ROOT))
|
|
- return 0;
|
|
- return d_inode(dentry) != NULL;
|
|
+ if (d_mountpoint(dentry))
|
|
+ /*
|
|
+ * Might only be a mountpoint in a different namespace,
|
|
+ * but we need to check.
|
|
+ */
|
|
+ return 2;
|
|
+ return 0;
|
|
}
|
|
|
|
__be32
|
|
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c
|
|
index f61b00887481..cbca58ba008a 100644
|
|
--- a/fs/orangefs/waitqueue.c
|
|
+++ b/fs/orangefs/waitqueue.c
|
|
@@ -124,7 +124,14 @@ int service_operation(struct orangefs_kernel_op_s *op,
|
|
gossip_debug(GOSSIP_WAIT_DEBUG,
|
|
"%s:client core is NOT in service.\n",
|
|
__func__);
|
|
- timeout = op_timeout_secs * HZ;
|
|
+ /*
|
|
+ * Don't wait for the userspace component to return if
|
|
+ * the filesystem is being umounted anyway.
|
|
+ */
|
|
+ if (op->upcall.type == ORANGEFS_VFS_OP_FS_UMOUNT)
|
|
+ timeout = 0;
|
|
+ else
|
|
+ timeout = op_timeout_secs * HZ;
|
|
}
|
|
spin_unlock(&orangefs_request_list_lock);
|
|
|
|
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
|
|
index c93dbadfc71d..db7d15b6a580 100644
|
|
--- a/include/acpi/actbl2.h
|
|
+++ b/include/acpi/actbl2.h
|
|
@@ -783,6 +783,15 @@ struct acpi_iort_smmu {
|
|
#define ACPI_IORT_SMMU_DVM_SUPPORTED (1)
|
|
#define ACPI_IORT_SMMU_COHERENT_WALK (1<<1)
|
|
|
|
+/* Global interrupt format */
|
|
+
|
|
+struct acpi_iort_smmu_gsi {
|
|
+ u32 nsg_irpt;
|
|
+ u32 nsg_irpt_flags;
|
|
+ u32 nsg_cfg_irpt;
|
|
+ u32 nsg_cfg_irpt_flags;
|
|
+};
|
|
+
|
|
struct acpi_iort_smmu_v3 {
|
|
u64 base_address; /* SMMUv3 base address */
|
|
u32 flags;
|
|
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
|
|
index 6a620e01b040..7751d72a6a40 100644
|
|
--- a/include/linux/mlx5/driver.h
|
|
+++ b/include/linux/mlx5/driver.h
|
|
@@ -380,8 +380,8 @@ struct mlx5_core_srq {
|
|
struct mlx5_core_rsc_common common; /* must be first */
|
|
u32 srqn;
|
|
int max;
|
|
- int max_gs;
|
|
- int max_avail_gather;
|
|
+ size_t max_gs;
|
|
+ size_t max_avail_gather;
|
|
int wqe_shift;
|
|
void (*event) (struct mlx5_core_srq *, enum mlx5_event);
|
|
|
|
diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
|
|
index 34c4498b800f..83b22ae9ae12 100644
|
|
--- a/include/linux/posix-clock.h
|
|
+++ b/include/linux/posix-clock.h
|
|
@@ -59,23 +59,23 @@ struct posix_clock_operations {
|
|
|
|
int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
|
|
|
|
- int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts);
|
|
+ int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
|
|
|
|
- int (*clock_getres) (struct posix_clock *pc, struct timespec *ts);
|
|
+ int (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts);
|
|
|
|
int (*clock_settime)(struct posix_clock *pc,
|
|
- const struct timespec *ts);
|
|
+ const struct timespec64 *ts);
|
|
|
|
int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
|
|
|
|
int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
|
|
|
|
void (*timer_gettime)(struct posix_clock *pc,
|
|
- struct k_itimer *kit, struct itimerspec *tsp);
|
|
+ struct k_itimer *kit, struct itimerspec64 *tsp);
|
|
|
|
int (*timer_settime)(struct posix_clock *pc,
|
|
struct k_itimer *kit, int flags,
|
|
- struct itimerspec *tsp, struct itimerspec *old);
|
|
+ struct itimerspec64 *tsp, struct itimerspec64 *old);
|
|
/*
|
|
* Optional character device methods:
|
|
*/
|
|
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
|
|
index 70339d7958c0..0cd4c11479b1 100644
|
|
--- a/include/soc/fsl/qe/qe.h
|
|
+++ b/include/soc/fsl/qe/qe.h
|
|
@@ -243,6 +243,7 @@ static inline int qe_alive_during_sleep(void)
|
|
#define qe_muram_free cpm_muram_free
|
|
#define qe_muram_addr cpm_muram_addr
|
|
#define qe_muram_offset cpm_muram_offset
|
|
+#define qe_muram_dma cpm_muram_dma
|
|
|
|
#define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
|
|
#define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
|
|
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
|
|
index ea41820ab12e..ed18aa4dceab 100644
|
|
--- a/kernel/irq/manage.c
|
|
+++ b/kernel/irq/manage.c
|
|
@@ -1210,8 +1210,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
|
|
* set the trigger type must match. Also all must
|
|
* agree on ONESHOT.
|
|
*/
|
|
+ unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
|
|
+
|
|
if (!((old->flags & new->flags) & IRQF_SHARED) ||
|
|
- ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
|
|
+ (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
|
|
((old->flags ^ new->flags) & IRQF_ONESHOT))
|
|
goto mismatch;
|
|
|
|
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
|
|
index 9cff0ab82b63..e24008c098c6 100644
|
|
--- a/kernel/time/posix-clock.c
|
|
+++ b/kernel/time/posix-clock.c
|
|
@@ -300,14 +300,17 @@ static int pc_clock_adjtime(clockid_t id, struct timex *tx)
|
|
static int pc_clock_gettime(clockid_t id, struct timespec *ts)
|
|
{
|
|
struct posix_clock_desc cd;
|
|
+ struct timespec64 ts64;
|
|
int err;
|
|
|
|
err = get_clock_desc(id, &cd);
|
|
if (err)
|
|
return err;
|
|
|
|
- if (cd.clk->ops.clock_gettime)
|
|
- err = cd.clk->ops.clock_gettime(cd.clk, ts);
|
|
+ if (cd.clk->ops.clock_gettime) {
|
|
+ err = cd.clk->ops.clock_gettime(cd.clk, &ts64);
|
|
+ *ts = timespec64_to_timespec(ts64);
|
|
+ }
|
|
else
|
|
err = -EOPNOTSUPP;
|
|
|
|
@@ -319,14 +322,17 @@ static int pc_clock_gettime(clockid_t id, struct timespec *ts)
|
|
static int pc_clock_getres(clockid_t id, struct timespec *ts)
|
|
{
|
|
struct posix_clock_desc cd;
|
|
+ struct timespec64 ts64;
|
|
int err;
|
|
|
|
err = get_clock_desc(id, &cd);
|
|
if (err)
|
|
return err;
|
|
|
|
- if (cd.clk->ops.clock_getres)
|
|
- err = cd.clk->ops.clock_getres(cd.clk, ts);
|
|
+ if (cd.clk->ops.clock_getres) {
|
|
+ err = cd.clk->ops.clock_getres(cd.clk, &ts64);
|
|
+ *ts = timespec64_to_timespec(ts64);
|
|
+ }
|
|
else
|
|
err = -EOPNOTSUPP;
|
|
|
|
@@ -337,6 +343,7 @@ static int pc_clock_getres(clockid_t id, struct timespec *ts)
|
|
|
|
static int pc_clock_settime(clockid_t id, const struct timespec *ts)
|
|
{
|
|
+ struct timespec64 ts64 = timespec_to_timespec64(*ts);
|
|
struct posix_clock_desc cd;
|
|
int err;
|
|
|
|
@@ -350,7 +357,7 @@ static int pc_clock_settime(clockid_t id, const struct timespec *ts)
|
|
}
|
|
|
|
if (cd.clk->ops.clock_settime)
|
|
- err = cd.clk->ops.clock_settime(cd.clk, ts);
|
|
+ err = cd.clk->ops.clock_settime(cd.clk, &ts64);
|
|
else
|
|
err = -EOPNOTSUPP;
|
|
out:
|
|
@@ -403,29 +410,36 @@ static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec *ts)
|
|
{
|
|
clockid_t id = kit->it_clock;
|
|
struct posix_clock_desc cd;
|
|
+ struct itimerspec64 ts64;
|
|
|
|
if (get_clock_desc(id, &cd))
|
|
return;
|
|
|
|
- if (cd.clk->ops.timer_gettime)
|
|
- cd.clk->ops.timer_gettime(cd.clk, kit, ts);
|
|
-
|
|
+ if (cd.clk->ops.timer_gettime) {
|
|
+ cd.clk->ops.timer_gettime(cd.clk, kit, &ts64);
|
|
+ *ts = itimerspec64_to_itimerspec(&ts64);
|
|
+ }
|
|
put_clock_desc(&cd);
|
|
}
|
|
|
|
static int pc_timer_settime(struct k_itimer *kit, int flags,
|
|
struct itimerspec *ts, struct itimerspec *old)
|
|
{
|
|
+ struct itimerspec64 ts64 = itimerspec_to_itimerspec64(ts);
|
|
clockid_t id = kit->it_clock;
|
|
struct posix_clock_desc cd;
|
|
+ struct itimerspec64 old64;
|
|
int err;
|
|
|
|
err = get_clock_desc(id, &cd);
|
|
if (err)
|
|
return err;
|
|
|
|
- if (cd.clk->ops.timer_settime)
|
|
- err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old);
|
|
+ if (cd.clk->ops.timer_settime) {
|
|
+ err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, &old64);
|
|
+ if (old)
|
|
+ *old = itimerspec64_to_itimerspec(&old64);
|
|
+ }
|
|
else
|
|
err = -EOPNOTSUPP;
|
|
|
|
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
|
|
index 5aa71a82ca73..851efb004857 100644
|
|
--- a/mm/memory-failure.c
|
|
+++ b/mm/memory-failure.c
|
|
@@ -921,6 +921,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
|
|
int ret;
|
|
int kill = 1, forcekill;
|
|
struct page *hpage = *hpagep;
|
|
+ bool mlocked = PageMlocked(hpage);
|
|
|
|
/*
|
|
* Here we are interested only in user-mapped pages, so skip any
|
|
@@ -984,6 +985,13 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
|
|
pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n",
|
|
pfn, page_mapcount(hpage));
|
|
|
|
+ /*
|
|
+ * try_to_unmap() might put mlocked page in lru cache, so call
|
|
+ * shake_page() again to ensure that it's flushed.
|
|
+ */
|
|
+ if (mlocked)
|
|
+ shake_page(hpage, 0);
|
|
+
|
|
/*
|
|
* Now that the dirty bit has been propagated to the
|
|
* struct page and all unmaps done we can decide if
|
|
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
|
index 4365de74bdb0..cdd5c3b5c357 100644
|
|
--- a/mm/vmscan.c
|
|
+++ b/mm/vmscan.c
|
|
@@ -2841,8 +2841,10 @@ static bool allow_direct_reclaim(pg_data_t *pgdat)
|
|
|
|
for (i = 0; i <= ZONE_NORMAL; i++) {
|
|
zone = &pgdat->node_zones[i];
|
|
- if (!managed_zone(zone) ||
|
|
- pgdat_reclaimable_pages(pgdat) == 0)
|
|
+ if (!managed_zone(zone))
|
|
+ continue;
|
|
+
|
|
+ if (!zone_reclaimable_pages(zone))
|
|
continue;
|
|
|
|
pfmemalloc_reserve += min_wmark_pages(zone);
|
|
diff --git a/mm/vmstat.c b/mm/vmstat.c
|
|
index 3863b5d6d598..68b3193e4493 100644
|
|
--- a/mm/vmstat.c
|
|
+++ b/mm/vmstat.c
|
|
@@ -1387,18 +1387,24 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
|
|
zone->present_pages,
|
|
zone->managed_pages);
|
|
|
|
- for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
|
|
- seq_printf(m, "\n %-12s %lu", vmstat_text[i],
|
|
- zone_page_state(zone, i));
|
|
-
|
|
seq_printf(m,
|
|
"\n protection: (%ld",
|
|
zone->lowmem_reserve[0]);
|
|
for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
|
|
seq_printf(m, ", %ld", zone->lowmem_reserve[i]);
|
|
- seq_printf(m,
|
|
- ")"
|
|
- "\n pagesets");
|
|
+ seq_putc(m, ')');
|
|
+
|
|
+ /* If unpopulated, no other information is useful */
|
|
+ if (!populated_zone(zone)) {
|
|
+ seq_putc(m, '\n');
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
|
|
+ seq_printf(m, "\n %-12s %lu", vmstat_text[i],
|
|
+ zone_page_state(zone, i));
|
|
+
|
|
+ seq_printf(m, "\n pagesets");
|
|
for_each_online_cpu(i) {
|
|
struct per_cpu_pageset *pageset;
|
|
|
|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
|
|
index 2f107e46355c..b5f264ae3bff 100644
|
|
--- a/net/ipv4/tcp_input.c
|
|
+++ b/net/ipv4/tcp_input.c
|
|
@@ -5606,10 +5606,6 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
|
|
else
|
|
tp->pred_flags = 0;
|
|
|
|
- if (!sock_flag(sk, SOCK_DEAD)) {
|
|
- sk->sk_state_change(sk);
|
|
- sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
|
|
- }
|
|
}
|
|
|
|
static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
|
|
@@ -5678,6 +5674,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
struct tcp_fastopen_cookie foc = { .len = -1 };
|
|
int saved_clamp = tp->rx_opt.mss_clamp;
|
|
+ bool fastopen_fail;
|
|
|
|
tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
|
|
if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
|
|
@@ -5781,10 +5778,15 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
|
|
|
|
tcp_finish_connect(sk, skb);
|
|
|
|
- if ((tp->syn_fastopen || tp->syn_data) &&
|
|
- tcp_rcv_fastopen_synack(sk, skb, &foc))
|
|
- return -1;
|
|
+ fastopen_fail = (tp->syn_fastopen || tp->syn_data) &&
|
|
+ tcp_rcv_fastopen_synack(sk, skb, &foc);
|
|
|
|
+ if (!sock_flag(sk, SOCK_DEAD)) {
|
|
+ sk->sk_state_change(sk);
|
|
+ sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
|
|
+ }
|
|
+ if (fastopen_fail)
|
|
+ return -1;
|
|
if (sk->sk_write_pending ||
|
|
icsk->icsk_accept_queue.rskq_defer_accept ||
|
|
icsk->icsk_ack.pingpong) {
|
|
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
|
|
index 912333586de6..345efeb887ef 100644
|
|
--- a/net/ipv6/ip6_vti.c
|
|
+++ b/net/ipv6/ip6_vti.c
|
|
@@ -625,6 +625,7 @@ static void vti6_link_config(struct ip6_tnl *t)
|
|
{
|
|
struct net_device *dev = t->dev;
|
|
struct __ip6_tnl_parm *p = &t->parms;
|
|
+ struct net_device *tdev = NULL;
|
|
|
|
memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
|
|
memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
|
|
@@ -637,6 +638,25 @@ static void vti6_link_config(struct ip6_tnl *t)
|
|
dev->flags |= IFF_POINTOPOINT;
|
|
else
|
|
dev->flags &= ~IFF_POINTOPOINT;
|
|
+
|
|
+ if (p->flags & IP6_TNL_F_CAP_XMIT) {
|
|
+ int strict = (ipv6_addr_type(&p->raddr) &
|
|
+ (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
|
|
+ struct rt6_info *rt = rt6_lookup(t->net,
|
|
+ &p->raddr, &p->laddr,
|
|
+ p->link, strict);
|
|
+
|
|
+ if (rt)
|
|
+ tdev = rt->dst.dev;
|
|
+ ip6_rt_put(rt);
|
|
+ }
|
|
+
|
|
+ if (!tdev && p->link)
|
|
+ tdev = __dev_get_by_index(t->net, p->link);
|
|
+
|
|
+ if (tdev)
|
|
+ dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
|
|
+ IPV6_MIN_MTU);
|
|
}
|
|
|
|
/**
|
|
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
|
|
index d8e671457d10..41c22cb33424 100644
|
|
--- a/net/ipv6/ndisc.c
|
|
+++ b/net/ipv6/ndisc.c
|
|
@@ -1723,6 +1723,8 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
|
|
case NETDEV_CHANGEADDR:
|
|
neigh_changeaddr(&nd_tbl, dev);
|
|
fib6_run_gc(0, net, false);
|
|
+ /* fallthrough */
|
|
+ case NETDEV_UP:
|
|
idev = in6_dev_get(dev);
|
|
if (!idev)
|
|
break;
|
|
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
|
|
index dee60428c78c..efa2a2fcae72 100644
|
|
--- a/net/mac80211/cfg.c
|
|
+++ b/net/mac80211/cfg.c
|
|
@@ -620,10 +620,11 @@ void sta_set_rate_info_tx(struct sta_info *sta,
|
|
int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
|
|
u16 brate;
|
|
|
|
- sband = sta->local->hw.wiphy->bands[
|
|
- ieee80211_get_sdata_band(sta->sdata)];
|
|
- brate = sband->bitrates[rate->idx].bitrate;
|
|
- rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
|
|
+ sband = ieee80211_get_sband(sta->sdata);
|
|
+ if (sband) {
|
|
+ brate = sband->bitrates[rate->idx].bitrate;
|
|
+ rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
|
|
+ }
|
|
}
|
|
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
|
rinfo->bw = RATE_INFO_BW_40;
|
|
@@ -1218,10 +1219,11 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|
int ret = 0;
|
|
struct ieee80211_supported_band *sband;
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
u32 mask, set;
|
|
|
|
- sband = local->hw.wiphy->bands[band];
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return -EINVAL;
|
|
|
|
mask = params->sta_flags_mask;
|
|
set = params->sta_flags_set;
|
|
@@ -1354,7 +1356,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
|
sband, params->supported_rates,
|
|
params->supported_rates_len,
|
|
- &sta->sta.supp_rates[band]);
|
|
+ &sta->sta.supp_rates[sband->band]);
|
|
}
|
|
|
|
if (params->ht_capa)
|
|
@@ -1370,8 +1372,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|
/* returned value is only needed for rc update, but the
|
|
* rc isn't initialized here yet, so ignore it
|
|
*/
|
|
- __ieee80211_vht_handle_opmode(sdata, sta,
|
|
- params->opmode_notif, band);
|
|
+ __ieee80211_vht_handle_opmode(sdata, sta, params->opmode_notif,
|
|
+ sband->band);
|
|
}
|
|
|
|
if (params->support_p2p_ps >= 0)
|
|
@@ -2017,13 +2019,15 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
|
struct bss_parameters *params)
|
|
{
|
|
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
- enum nl80211_band band;
|
|
+ struct ieee80211_supported_band *sband;
|
|
u32 changed = 0;
|
|
|
|
if (!sdata_dereference(sdata->u.ap.beacon, sdata))
|
|
return -ENOENT;
|
|
|
|
- band = ieee80211_get_sdata_band(sdata);
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return -EINVAL;
|
|
|
|
if (params->use_cts_prot >= 0) {
|
|
sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
|
|
@@ -2036,7 +2040,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
|
}
|
|
|
|
if (!sdata->vif.bss_conf.use_short_slot &&
|
|
- band == NL80211_BAND_5GHZ) {
|
|
+ sband->band == NL80211_BAND_5GHZ) {
|
|
sdata->vif.bss_conf.use_short_slot = true;
|
|
changed |= BSS_CHANGED_ERP_SLOT;
|
|
}
|
|
@@ -2049,7 +2053,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
|
|
|
if (params->basic_rates) {
|
|
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
|
- wiphy->bands[band],
|
|
+ wiphy->bands[sband->band],
|
|
params->basic_rates,
|
|
params->basic_rates_len,
|
|
&sdata->vif.bss_conf.basic_rates);
|
|
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
|
|
index 62d13eabe17f..d31818e7d10c 100644
|
|
--- a/net/mac80211/ibss.c
|
|
+++ b/net/mac80211/ibss.c
|
|
@@ -994,7 +994,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
|
enum nl80211_band band = rx_status->band;
|
|
enum nl80211_bss_scan_width scan_width;
|
|
struct ieee80211_local *local = sdata->local;
|
|
- struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
|
+ struct ieee80211_supported_band *sband;
|
|
bool rates_updated = false;
|
|
u32 supp_rates = 0;
|
|
|
|
@@ -1004,6 +1004,10 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
|
if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
|
|
return;
|
|
|
|
+ sband = local->hw.wiphy->bands[band];
|
|
+ if (WARN_ON(!sband))
|
|
+ return;
|
|
+
|
|
rcu_read_lock();
|
|
sta = sta_info_get(sdata, mgmt->sa);
|
|
|
|
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
|
|
index 03dbc6bd8598..7fd544d970d9 100644
|
|
--- a/net/mac80211/ieee80211_i.h
|
|
+++ b/net/mac80211/ieee80211_i.h
|
|
@@ -991,21 +991,6 @@ sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
|
|
lockdep_assert_held(&sdata->wdev.mtx);
|
|
}
|
|
|
|
-static inline enum nl80211_band
|
|
-ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
|
|
-{
|
|
- enum nl80211_band band = NL80211_BAND_2GHZ;
|
|
- struct ieee80211_chanctx_conf *chanctx_conf;
|
|
-
|
|
- rcu_read_lock();
|
|
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
|
- if (!WARN_ON(!chanctx_conf))
|
|
- band = chanctx_conf->def.chan->band;
|
|
- rcu_read_unlock();
|
|
-
|
|
- return band;
|
|
-}
|
|
-
|
|
static inline int
|
|
ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
|
|
{
|
|
@@ -1410,6 +1395,27 @@ IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev)
|
|
return container_of(wdev, struct ieee80211_sub_if_data, wdev);
|
|
}
|
|
|
|
+static inline struct ieee80211_supported_band *
|
|
+ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)
|
|
+{
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
|
+ enum nl80211_band band;
|
|
+
|
|
+ rcu_read_lock();
|
|
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
|
+
|
|
+ if (WARN_ON(!chanctx_conf)) {
|
|
+ rcu_read_unlock();
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ band = chanctx_conf->def.chan->band;
|
|
+ rcu_read_unlock();
|
|
+
|
|
+ return local->hw.wiphy->bands[band];
|
|
+}
|
|
+
|
|
/* this struct represents 802.11n's RA/TID combination */
|
|
struct ieee80211_ra_tid {
|
|
u8 ra[ETH_ALEN];
|
|
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
|
|
index b4b3fe078868..b2a27263d6ff 100644
|
|
--- a/net/mac80211/mesh.c
|
|
+++ b/net/mac80211/mesh.c
|
|
@@ -63,6 +63,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
|
u32 basic_rates = 0;
|
|
struct cfg80211_chan_def sta_chan_def;
|
|
+ struct ieee80211_supported_band *sband;
|
|
|
|
/*
|
|
* As support for each feature is added, check for matching
|
|
@@ -83,7 +84,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
|
(ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
|
|
return false;
|
|
|
|
- ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return false;
|
|
+
|
|
+ ieee80211_sta_get_rates(sdata, ie, sband->band,
|
|
&basic_rates);
|
|
|
|
if (sdata->vif.bss_conf.basic_rates != basic_rates)
|
|
@@ -399,12 +404,13 @@ static int mesh_add_ds_params_ie(struct ieee80211_sub_if_data *sdata,
|
|
int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
|
struct sk_buff *skb)
|
|
{
|
|
- struct ieee80211_local *local = sdata->local;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
struct ieee80211_supported_band *sband;
|
|
u8 *pos;
|
|
|
|
- sband = local->hw.wiphy->bands[band];
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return -EINVAL;
|
|
+
|
|
if (!sband->ht_cap.ht_supported ||
|
|
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
|
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
|
@@ -462,12 +468,13 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
|
|
int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
|
struct sk_buff *skb)
|
|
{
|
|
- struct ieee80211_local *local = sdata->local;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
struct ieee80211_supported_band *sband;
|
|
u8 *pos;
|
|
|
|
- sband = local->hw.wiphy->bands[band];
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return -EINVAL;
|
|
+
|
|
if (!sband->vht_cap.vht_supported ||
|
|
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
|
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
|
@@ -916,12 +923,16 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
|
struct cfg80211_csa_settings params;
|
|
struct ieee80211_csa_ie csa_ie;
|
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
+ struct ieee80211_supported_band *sband;
|
|
int err;
|
|
u32 sta_flags;
|
|
|
|
sdata_assert_lock(sdata);
|
|
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return false;
|
|
+
|
|
sta_flags = IEEE80211_STA_DISABLE_VHT;
|
|
switch (sdata->vif.bss_conf.chandef.width) {
|
|
case NL80211_CHAN_WIDTH_20_NOHT:
|
|
@@ -935,7 +946,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
|
memset(¶ms, 0, sizeof(params));
|
|
memset(&csa_ie, 0, sizeof(csa_ie));
|
|
- err = ieee80211_parse_ch_switch_ie(sdata, elems, band,
|
|
+ err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band,
|
|
sta_flags, sdata->vif.addr,
|
|
&csa_ie);
|
|
if (err < 0)
|
|
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
|
|
index fcba70e57073..2d3c4695e75b 100644
|
|
--- a/net/mac80211/mesh_plink.c
|
|
+++ b/net/mac80211/mesh_plink.c
|
|
@@ -93,19 +93,23 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
|
|
static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
|
|
{
|
|
struct ieee80211_local *local = sdata->local;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
- struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
|
+ struct ieee80211_supported_band *sband;
|
|
struct sta_info *sta;
|
|
u32 erp_rates = 0, changed = 0;
|
|
int i;
|
|
bool short_slot = false;
|
|
|
|
- if (band == NL80211_BAND_5GHZ) {
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return changed;
|
|
+
|
|
+ if (sband->band == NL80211_BAND_5GHZ) {
|
|
/* (IEEE 802.11-2012 19.4.5) */
|
|
short_slot = true;
|
|
goto out;
|
|
- } else if (band != NL80211_BAND_2GHZ)
|
|
+ } else if (sband->band != NL80211_BAND_2GHZ) {
|
|
goto out;
|
|
+ }
|
|
|
|
for (i = 0; i < sband->n_bitrates; i++)
|
|
if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
|
|
@@ -121,7 +125,7 @@ static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
|
|
continue;
|
|
|
|
short_slot = false;
|
|
- if (erp_rates & sta->sta.supp_rates[band])
|
|
+ if (erp_rates & sta->sta.supp_rates[sband->band])
|
|
short_slot = true;
|
|
else
|
|
break;
|
|
@@ -247,7 +251,15 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
|
|
mgmt->u.action.u.self_prot.action_code = action;
|
|
|
|
if (action != WLAN_SP_MESH_PEERING_CLOSE) {
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
+ struct ieee80211_supported_band *sband;
|
|
+ enum nl80211_band band;
|
|
+
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband) {
|
|
+ err = -EINVAL;
|
|
+ goto free;
|
|
+ }
|
|
+ band = sband->band;
|
|
|
|
/* capability info */
|
|
pos = skb_put(skb, 2);
|
|
@@ -393,13 +405,16 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
|
struct ieee802_11_elems *elems, bool insert)
|
|
{
|
|
struct ieee80211_local *local = sdata->local;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
struct ieee80211_supported_band *sband;
|
|
u32 rates, basic_rates = 0, changed = 0;
|
|
enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;
|
|
|
|
- sband = local->hw.wiphy->bands[band];
|
|
- rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return;
|
|
+
|
|
+ rates = ieee80211_sta_get_rates(sdata, elems, sband->band,
|
|
+ &basic_rates);
|
|
|
|
spin_lock_bh(&sta->mesh->plink_lock);
|
|
sta->rx_stats.last_rx = jiffies;
|
|
@@ -410,9 +425,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
|
goto out;
|
|
sta->mesh->processed_beacon = true;
|
|
|
|
- if (sta->sta.supp_rates[band] != rates)
|
|
+ if (sta->sta.supp_rates[sband->band] != rates)
|
|
changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
|
|
- sta->sta.supp_rates[band] = rates;
|
|
+ sta->sta.supp_rates[sband->band] = rates;
|
|
|
|
if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
|
elems->ht_cap_elem, sta))
|
|
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
|
|
index 1118c61f835d..fdab4f1390d2 100644
|
|
--- a/net/mac80211/mlme.c
|
|
+++ b/net/mac80211/mlme.c
|
|
@@ -1851,11 +1851,16 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
|
|
u16 capab, bool erp_valid, u8 erp)
|
|
{
|
|
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
|
+ struct ieee80211_supported_band *sband;
|
|
u32 changed = 0;
|
|
bool use_protection;
|
|
bool use_short_preamble;
|
|
bool use_short_slot;
|
|
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return changed;
|
|
+
|
|
if (erp_valid) {
|
|
use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
|
|
use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
|
|
@@ -1865,7 +1870,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
|
|
}
|
|
|
|
use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
|
|
- if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_5GHZ)
|
|
+ if (sband->band == NL80211_BAND_5GHZ)
|
|
use_short_slot = true;
|
|
|
|
if (use_protection != bss_conf->use_cts_prot) {
|
|
@@ -2994,7 +2999,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|
goto out;
|
|
}
|
|
|
|
- sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband) {
|
|
+ mutex_unlock(&sdata->local->sta_mtx);
|
|
+ ret = false;
|
|
+ goto out;
|
|
+ }
|
|
|
|
/* Set up internal HT/VHT capabilities */
|
|
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
|
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
|
|
index 206698bc93f4..dbceb42c2a8e 100644
|
|
--- a/net/mac80211/rate.c
|
|
+++ b/net/mac80211/rate.c
|
|
@@ -875,7 +875,9 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
|
|
struct ieee80211_sta_rates *old;
|
|
struct ieee80211_supported_band *sband;
|
|
|
|
- sband = hw->wiphy->bands[ieee80211_get_sdata_band(sta->sdata)];
|
|
+ sband = ieee80211_get_sband(sta->sdata);
|
|
+ if (!sband)
|
|
+ return -EINVAL;
|
|
rate_control_apply_mask_ratetbl(sta, sband, rates);
|
|
/*
|
|
* mac80211 guarantees that this function will not be called
|
|
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
|
|
index 348700b424ea..1ecf3d07d1f5 100644
|
|
--- a/net/mac80211/sta_info.c
|
|
+++ b/net/mac80211/sta_info.c
|
|
@@ -395,10 +395,15 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
|
|
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
|
- struct ieee80211_supported_band *sband =
|
|
- hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
|
|
- u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
|
|
- IEEE80211_HT_CAP_SM_PS_SHIFT;
|
|
+ struct ieee80211_supported_band *sband;
|
|
+ u8 smps;
|
|
+
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ goto free_txq;
|
|
+
|
|
+ smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
|
|
+ IEEE80211_HT_CAP_SM_PS_SHIFT;
|
|
/*
|
|
* Assume that hostapd advertises our caps in the beacon and
|
|
* this is the known_smps_mode for a station that just assciated
|
|
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
|
|
index ad37b4e58c2f..72fe9bc7a1f9 100644
|
|
--- a/net/mac80211/status.c
|
|
+++ b/net/mac80211/status.c
|
|
@@ -200,6 +200,7 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
|
|
}
|
|
|
|
if (ieee80211_is_action(mgmt->frame_control) &&
|
|
+ !ieee80211_has_protected(mgmt->frame_control) &&
|
|
mgmt->u.action.category == WLAN_CATEGORY_HT &&
|
|
mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS &&
|
|
ieee80211_sdata_running(sdata)) {
|
|
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
|
|
index afca7d103684..f20dcf1b1830 100644
|
|
--- a/net/mac80211/tdls.c
|
|
+++ b/net/mac80211/tdls.c
|
|
@@ -47,8 +47,7 @@ static void ieee80211_tdls_add_ext_capab(struct ieee80211_sub_if_data *sdata,
|
|
NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
|
|
bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
|
|
!ifmgd->tdls_wider_bw_prohibited;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
- struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
|
+ struct ieee80211_supported_band *sband = ieee80211_get_sband(sdata);
|
|
bool vht = sband && sband->vht_cap.vht_supported;
|
|
u8 *pos = (void *)skb_put(skb, 10);
|
|
|
|
@@ -180,11 +179,14 @@ static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb)
|
|
static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
|
|
u16 status_code)
|
|
{
|
|
+ struct ieee80211_supported_band *sband;
|
|
+
|
|
/* The capability will be 0 when sending a failure code */
|
|
if (status_code != 0)
|
|
return 0;
|
|
|
|
- if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_2GHZ) {
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (sband && sband->band == NL80211_BAND_2GHZ) {
|
|
return WLAN_CAPABILITY_SHORT_SLOT_TIME |
|
|
WLAN_CAPABILITY_SHORT_PREAMBLE;
|
|
}
|
|
@@ -358,17 +360,20 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
|
|
u8 action_code, bool initiator,
|
|
const u8 *extra_ies, size_t extra_ies_len)
|
|
{
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
- struct ieee80211_local *local = sdata->local;
|
|
struct ieee80211_supported_band *sband;
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
struct ieee80211_sta_ht_cap ht_cap;
|
|
struct ieee80211_sta_vht_cap vht_cap;
|
|
struct sta_info *sta = NULL;
|
|
size_t offset = 0, noffset;
|
|
u8 *pos;
|
|
|
|
- ieee80211_add_srates_ie(sdata, skb, false, band);
|
|
- ieee80211_add_ext_srates_ie(sdata, skb, false, band);
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return;
|
|
+
|
|
+ ieee80211_add_srates_ie(sdata, skb, false, sband->band);
|
|
+ ieee80211_add_ext_srates_ie(sdata, skb, false, sband->band);
|
|
ieee80211_tdls_add_supp_channels(sdata, skb);
|
|
|
|
/* add any custom IEs that go before Extended Capabilities */
|
|
@@ -439,7 +444,6 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
|
|
* the same on all bands. The specification limits the setup to a
|
|
* single HT-cap, so use the current band for now.
|
|
*/
|
|
- sband = local->hw.wiphy->bands[band];
|
|
memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
|
|
|
|
if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
|
|
@@ -545,9 +549,13 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
size_t offset = 0, noffset;
|
|
struct sta_info *sta, *ap_sta;
|
|
- enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
|
+ struct ieee80211_supported_band *sband;
|
|
u8 *pos;
|
|
|
|
+ sband = ieee80211_get_sband(sdata);
|
|
+ if (!sband)
|
|
+ return;
|
|
+
|
|
mutex_lock(&local->sta_mtx);
|
|
|
|
sta = sta_info_get(sdata, peer);
|
|
@@ -612,7 +620,8 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
|
|
ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
|
|
|
|
/* only include VHT-operation if not on the 2.4GHz band */
|
|
- if (band != NL80211_BAND_2GHZ && sta->sta.vht_cap.vht_supported) {
|
|
+ if (sband->band != NL80211_BAND_2GHZ &&
|
|
+ sta->sta.vht_cap.vht_supported) {
|
|
/*
|
|
* if both peers support WIDER_BW, we can expand the chandef to
|
|
* a wider compatible one, up to 80MHz
|
|
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
|
index 1ffd1e145c13..84582998f65f 100644
|
|
--- a/net/mac80211/tx.c
|
|
+++ b/net/mac80211/tx.c
|
|
@@ -4182,7 +4182,10 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
|
return bcn;
|
|
|
|
shift = ieee80211_vif_get_shift(vif);
|
|
- sband = hw->wiphy->bands[ieee80211_get_sdata_band(vif_to_sdata(vif))];
|
|
+ sband = ieee80211_get_sband(vif_to_sdata(vif));
|
|
+ if (!sband)
|
|
+ return bcn;
|
|
+
|
|
ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
|
|
|
|
return bcn;
|
|
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
|
|
index 545c79a42a77..a2756096b94a 100644
|
|
--- a/net/mac80211/util.c
|
|
+++ b/net/mac80211/util.c
|
|
@@ -1590,14 +1590,14 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
|
|
size_t num_rates;
|
|
u32 supp_rates, rate_flags;
|
|
int i, j, shift;
|
|
+
|
|
sband = sdata->local->hw.wiphy->bands[band];
|
|
+ if (WARN_ON(!sband))
|
|
+ return 1;
|
|
|
|
rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
|
|
shift = ieee80211_vif_get_shift(&sdata->vif);
|
|
|
|
- if (WARN_ON(!sband))
|
|
- return 1;
|
|
-
|
|
num_rates = sband->n_bitrates;
|
|
supp_rates = 0;
|
|
for (i = 0; i < elems->supp_rates_len +
|
|
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
|
|
index 2155c2498aed..74d119512d96 100644
|
|
--- a/net/netfilter/ipvs/ip_vs_ctl.c
|
|
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
|
|
@@ -3092,6 +3092,17 @@ static int ip_vs_genl_dump_services(struct sk_buff *skb,
|
|
return skb->len;
|
|
}
|
|
|
|
+static bool ip_vs_is_af_valid(int af)
|
|
+{
|
|
+ if (af == AF_INET)
|
|
+ return true;
|
|
+#ifdef CONFIG_IP_VS_IPV6
|
|
+ if (af == AF_INET6 && ipv6_mod_enabled())
|
|
+ return true;
|
|
+#endif
|
|
+ return false;
|
|
+}
|
|
+
|
|
static int ip_vs_genl_parse_service(struct netns_ipvs *ipvs,
|
|
struct ip_vs_service_user_kern *usvc,
|
|
struct nlattr *nla, int full_entry,
|
|
@@ -3118,11 +3129,7 @@ static int ip_vs_genl_parse_service(struct netns_ipvs *ipvs,
|
|
memset(usvc, 0, sizeof(*usvc));
|
|
|
|
usvc->af = nla_get_u16(nla_af);
|
|
-#ifdef CONFIG_IP_VS_IPV6
|
|
- if (usvc->af != AF_INET && usvc->af != AF_INET6)
|
|
-#else
|
|
- if (usvc->af != AF_INET)
|
|
-#endif
|
|
+ if (!ip_vs_is_af_valid(usvc->af))
|
|
return -EAFNOSUPPORT;
|
|
|
|
if (nla_fwmark) {
|
|
@@ -3624,6 +3631,11 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
|
|
if (udest.af == 0)
|
|
udest.af = svc->af;
|
|
|
|
+ if (!ip_vs_is_af_valid(udest.af)) {
|
|
+ ret = -EAFNOSUPPORT;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
if (udest.af != svc->af && cmd != IPVS_CMD_DEL_DEST) {
|
|
/* The synchronization protocol is incompatible
|
|
* with mixed family services
|
|
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
|
|
index 6dc44d9b4190..92e69af41656 100644
|
|
--- a/net/netfilter/nf_conntrack_helper.c
|
|
+++ b/net/netfilter/nf_conntrack_helper.c
|
|
@@ -379,17 +379,33 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
|
|
struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
|
|
unsigned int h = helper_hash(&me->tuple);
|
|
struct nf_conntrack_helper *cur;
|
|
- int ret = 0;
|
|
+ int ret = 0, i;
|
|
|
|
BUG_ON(me->expect_policy == NULL);
|
|
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
|
|
BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
|
|
|
|
mutex_lock(&nf_ct_helper_mutex);
|
|
- hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
|
|
- if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) {
|
|
- ret = -EEXIST;
|
|
- goto out;
|
|
+ for (i = 0; i < nf_ct_helper_hsize; i++) {
|
|
+ hlist_for_each_entry(cur, &nf_ct_helper_hash[i], hnode) {
|
|
+ if (!strcmp(cur->name, me->name) &&
|
|
+ (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
|
|
+ cur->tuple.src.l3num == me->tuple.src.l3num) &&
|
|
+ cur->tuple.dst.protonum == me->tuple.dst.protonum) {
|
|
+ ret = -EEXIST;
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* avoid unpredictable behaviour for auto_assign_helper */
|
|
+ if (!(me->flags & NF_CT_HELPER_F_USERSPACE)) {
|
|
+ hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
|
|
+ if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple,
|
|
+ &mask)) {
|
|
+ ret = -EEXIST;
|
|
+ goto out;
|
|
+ }
|
|
}
|
|
}
|
|
hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
|
|
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
|
|
index 31ca94793aa9..b9dd4e960426 100644
|
|
--- a/net/netfilter/nft_dynset.c
|
|
+++ b/net/netfilter/nft_dynset.c
|
|
@@ -82,8 +82,7 @@ static void nft_dynset_eval(const struct nft_expr *expr,
|
|
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
|
|
timeout = priv->timeout ? : set->timeout;
|
|
*nft_set_ext_expiration(ext) = jiffies + timeout;
|
|
- } else if (sexpr == NULL)
|
|
- goto out;
|
|
+ }
|
|
|
|
if (sexpr != NULL)
|
|
sexpr->ops->eval(sexpr, regs, pkt);
|
|
@@ -92,7 +91,7 @@ static void nft_dynset_eval(const struct nft_expr *expr,
|
|
regs->verdict.code = NFT_BREAK;
|
|
return;
|
|
}
|
|
-out:
|
|
+
|
|
if (!priv->invert)
|
|
regs->verdict.code = NFT_BREAK;
|
|
}
|
|
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
|
|
index ac26b71d900e..7ad1a863587a 100644
|
|
--- a/net/netfilter/x_tables.c
|
|
+++ b/net/netfilter/x_tables.c
|
|
@@ -1006,8 +1006,10 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
|
|
list_for_each_entry(t, &init_net.xt.tables[af], list) {
|
|
if (strcmp(t->name, name))
|
|
continue;
|
|
- if (!try_module_get(t->me))
|
|
+ if (!try_module_get(t->me)) {
|
|
+ mutex_unlock(&xt[af].mutex);
|
|
return NULL;
|
|
+ }
|
|
|
|
mutex_unlock(&xt[af].mutex);
|
|
if (t->table_init(net) != 0) {
|
|
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
|
|
index 6669e68d589e..00ef8243d48d 100644
|
|
--- a/net/netfilter/xt_CT.c
|
|
+++ b/net/netfilter/xt_CT.c
|
|
@@ -168,8 +168,10 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
|
|
goto err_put_timeout;
|
|
}
|
|
timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
|
|
- if (timeout_ext == NULL)
|
|
+ if (!timeout_ext) {
|
|
ret = -ENOMEM;
|
|
+ goto err_put_timeout;
|
|
+ }
|
|
|
|
rcu_read_unlock();
|
|
return ret;
|
|
@@ -201,6 +203,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
|
struct xt_ct_target_info_v1 *info)
|
|
{
|
|
struct nf_conntrack_zone zone;
|
|
+ struct nf_conn_help *help;
|
|
struct nf_conn *ct;
|
|
int ret = -EOPNOTSUPP;
|
|
|
|
@@ -249,7 +252,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
|
if (info->timeout[0]) {
|
|
ret = xt_ct_set_timeout(ct, par, info->timeout);
|
|
if (ret < 0)
|
|
- goto err3;
|
|
+ goto err4;
|
|
}
|
|
__set_bit(IPS_CONFIRMED_BIT, &ct->status);
|
|
nf_conntrack_get(&ct->ct_general);
|
|
@@ -257,6 +260,10 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
|
info->ct = ct;
|
|
return 0;
|
|
|
|
+err4:
|
|
+ help = nfct_help(ct);
|
|
+ if (help)
|
|
+ module_put(help->helper->me);
|
|
err3:
|
|
nf_ct_tmpl_free(ct);
|
|
err2:
|
|
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
|
|
index b28e45b691de..466393936db9 100644
|
|
--- a/net/openvswitch/conntrack.c
|
|
+++ b/net/openvswitch/conntrack.c
|
|
@@ -396,10 +396,38 @@ ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone,
|
|
u16 proto, const struct sk_buff *skb)
|
|
{
|
|
struct nf_conntrack_tuple tuple;
|
|
+ struct nf_conntrack_expect *exp;
|
|
|
|
if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, net, &tuple))
|
|
return NULL;
|
|
- return __nf_ct_expect_find(net, zone, &tuple);
|
|
+
|
|
+ exp = __nf_ct_expect_find(net, zone, &tuple);
|
|
+ if (exp) {
|
|
+ struct nf_conntrack_tuple_hash *h;
|
|
+
|
|
+ /* Delete existing conntrack entry, if it clashes with the
|
|
+ * expectation. This can happen since conntrack ALGs do not
|
|
+ * check for clashes between (new) expectations and existing
|
|
+ * conntrack entries. nf_conntrack_in() will check the
|
|
+ * expectations only if a conntrack entry can not be found,
|
|
+ * which can lead to OVS finding the expectation (here) in the
|
|
+ * init direction, but which will not be removed by the
|
|
+ * nf_conntrack_in() call, if a matching conntrack entry is
|
|
+ * found instead. In this case all init direction packets
|
|
+ * would be reported as new related packets, while reply
|
|
+ * direction packets would be reported as un-related
|
|
+ * established packets.
|
|
+ */
|
|
+ h = nf_conntrack_find_get(net, zone, &tuple);
|
|
+ if (h) {
|
|
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
|
|
+
|
|
+ nf_ct_delete(ct, 0, 0);
|
|
+ nf_conntrack_put(&ct->ct_general);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return exp;
|
|
}
|
|
|
|
/* This replicates logic from nf_conntrack_core.c that is not exported. */
|
|
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
|
|
index 69502fa68a3c..1a2b1f61ed26 100644
|
|
--- a/net/sunrpc/xprtrdma/verbs.c
|
|
+++ b/net/sunrpc/xprtrdma/verbs.c
|
|
@@ -1054,6 +1054,7 @@ void
|
|
rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
|
|
{
|
|
cancel_delayed_work_sync(&buf->rb_recovery_worker);
|
|
+ cancel_delayed_work_sync(&buf->rb_refresh_worker);
|
|
|
|
while (!list_empty(&buf->rb_recv_bufs)) {
|
|
struct rpcrdma_rep *rep;
|
|
diff --git a/net/tipc/node.c b/net/tipc/node.c
|
|
index 5b3e1ea37b6d..db8fbc076e1a 100644
|
|
--- a/net/tipc/node.c
|
|
+++ b/net/tipc/node.c
|
|
@@ -2094,6 +2094,8 @@ int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info)
|
|
int err;
|
|
|
|
msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
|
|
+ if (!msg.skb)
|
|
+ return -ENOMEM;
|
|
msg.portid = info->snd_portid;
|
|
msg.seq = info->snd_seq;
|
|
|
|
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
|
index cd427ea8861d..dae0021f39c3 100644
|
|
--- a/sound/pci/hda/patch_realtek.c
|
|
+++ b/sound/pci/hda/patch_realtek.c
|
|
@@ -6780,6 +6780,7 @@ enum {
|
|
ALC668_FIXUP_DELL_DISABLE_AAMIX,
|
|
ALC668_FIXUP_DELL_XPS13,
|
|
ALC662_FIXUP_ASUS_Nx50,
|
|
+ ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
|
|
ALC668_FIXUP_ASUS_Nx51,
|
|
ALC891_FIXUP_HEADSET_MODE,
|
|
ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
|
|
@@ -7031,14 +7032,21 @@ static const struct hda_fixup alc662_fixups[] = {
|
|
.chained = true,
|
|
.chain_id = ALC662_FIXUP_BASS_1A
|
|
},
|
|
+ [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
|
|
+ .type = HDA_FIXUP_FUNC,
|
|
+ .v.func = alc_fixup_headset_mode_alc668,
|
|
+ .chain_id = ALC662_FIXUP_BASS_CHMAP
|
|
+ },
|
|
[ALC668_FIXUP_ASUS_Nx51] = {
|
|
.type = HDA_FIXUP_PINS,
|
|
.v.pins = (const struct hda_pintbl[]) {
|
|
- {0x1a, 0x90170151}, /* bass speaker */
|
|
+ { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
|
|
+ { 0x1a, 0x90170151 }, /* bass speaker */
|
|
+ { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
|
|
{}
|
|
},
|
|
.chained = true,
|
|
- .chain_id = ALC662_FIXUP_BASS_CHMAP,
|
|
+ .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
|
|
},
|
|
[ALC891_FIXUP_HEADSET_MODE] = {
|
|
.type = HDA_FIXUP_FUNC,
|
|
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
|
|
index 0bfa68862460..cd16b431d1bd 100644
|
|
--- a/sound/soc/intel/atom/sst/sst_acpi.c
|
|
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
|
|
@@ -420,7 +420,21 @@ static const struct dmi_system_id byt_table[] = {
|
|
.callback = byt_thinkpad10_quirk_cb,
|
|
.matches = {
|
|
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
- DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"),
|
|
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .callback = byt_thinkpad10_quirk_cb,
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .callback = byt_thinkpad10_quirk_cb,
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
|
|
},
|
|
},
|
|
{ }
|
|
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
|
|
index 06fa5e85dd0e..3e526fbd267e 100644
|
|
--- a/sound/soc/intel/skylake/skl.c
|
|
+++ b/sound/soc/intel/skylake/skl.c
|
|
@@ -457,7 +457,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
|
|
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
|
unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
|
|
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
|
|
- unsigned int res;
|
|
+ unsigned int res = -1;
|
|
|
|
mutex_lock(&bus->cmd_mutex);
|
|
snd_hdac_bus_send_cmd(bus, cmd);
|
|
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
|
|
index 7d92a24b7cfa..98835e9d1d7d 100644
|
|
--- a/sound/soc/sh/rcar/cmd.c
|
|
+++ b/sound/soc/sh/rcar/cmd.c
|
|
@@ -82,6 +82,9 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
|
|
[9] = 0x2,
|
|
};
|
|
|
|
+ if (unlikely(!src))
|
|
+ return -EIO;
|
|
+
|
|
data = path[rsnd_mod_id(src)] |
|
|
cmd_case[rsnd_mod_id(src)] << 16;
|
|
}
|
|
diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c
|
|
index 76f41f249944..6cd9e5107f77 100644
|
|
--- a/tools/perf/tests/kmod-path.c
|
|
+++ b/tools/perf/tests/kmod-path.c
|
|
@@ -61,6 +61,7 @@ int test__kmod_path__parse(int subtest __maybe_unused)
|
|
M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_KERNEL, true);
|
|
M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_USER, false);
|
|
|
|
+#ifdef HAVE_ZLIB_SUPPORT
|
|
/* path alloc_name alloc_ext kmod comp name ext */
|
|
T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz");
|
|
T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz");
|
|
@@ -96,6 +97,7 @@ int test__kmod_path__parse(int subtest __maybe_unused)
|
|
M("x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
|
|
M("x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
|
|
M("x.ko.gz", PERF_RECORD_MISC_USER, false);
|
|
+#endif
|
|
|
|
/* path alloc_name alloc_ext kmod comp name ext */
|
|
T("[test_module]", true , true , true, false, "[test_module]", NULL);
|
|
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
|
|
index 71620fa95953..d025eafc09c2 100644
|
|
--- a/tools/testing/nvdimm/test/nfit.c
|
|
+++ b/tools/testing/nvdimm/test/nfit.c
|
|
@@ -1908,6 +1908,7 @@ static __init int nfit_test_init(void)
|
|
put_device(&pdev->dev);
|
|
goto err_register;
|
|
}
|
|
+ get_device(&pdev->dev);
|
|
|
|
rc = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
|
if (rc)
|
|
@@ -1926,6 +1927,10 @@ static __init int nfit_test_init(void)
|
|
if (instances[i])
|
|
platform_device_unregister(&instances[i]->pdev);
|
|
nfit_test_teardown();
|
|
+ for (i = 0; i < NUM_NFITS; i++)
|
|
+ if (instances[i])
|
|
+ put_device(&instances[i]->pdev.dev);
|
|
+
|
|
return rc;
|
|
}
|
|
|
|
@@ -1933,10 +1938,13 @@ static __exit void nfit_test_exit(void)
|
|
{
|
|
int i;
|
|
|
|
- platform_driver_unregister(&nfit_test_driver);
|
|
for (i = 0; i < NUM_NFITS; i++)
|
|
platform_device_unregister(&instances[i]->pdev);
|
|
+ platform_driver_unregister(&nfit_test_driver);
|
|
nfit_test_teardown();
|
|
+
|
|
+ for (i = 0; i < NUM_NFITS; i++)
|
|
+ put_device(&instances[i]->pdev.dev);
|
|
class_destroy(nfit_test_dimm);
|
|
}
|
|
|