diff options
Diffstat (limited to '1009_linux-4.13.10.patch')
-rw-r--r-- | 1009_linux-4.13.10.patch | 3818 |
1 files changed, 3818 insertions, 0 deletions
diff --git a/1009_linux-4.13.10.patch b/1009_linux-4.13.10.patch new file mode 100644 index 00000000..56c56ee7 --- /dev/null +++ b/1009_linux-4.13.10.patch @@ -0,0 +1,3818 @@ +diff --git a/Makefile b/Makefile +index aa0267950444..0e30a0d282e8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 13 +-SUBLEVEL = 9 ++SUBLEVEL = 10 + EXTRAVERSION = + NAME = Fearless Coyote + +diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi +index aebc3f9dc7b6..fa1bbdca1710 100644 +--- a/arch/arm/boot/dts/sun6i-a31.dtsi ++++ b/arch/arm/boot/dts/sun6i-a31.dtsi +@@ -311,8 +311,8 @@ + #size-cells = <0>; + reg = <0>; + +- tcon1_in_drc1: endpoint@0 { +- reg = <0>; ++ tcon1_in_drc1: endpoint@1 { ++ reg = <1>; + remote-endpoint = <&drc1_out_tcon1>; + }; + }; +@@ -1012,8 +1012,8 @@ + #size-cells = <0>; + reg = <1>; + +- be1_out_drc1: endpoint@0 { +- reg = <0>; ++ be1_out_drc1: endpoint@1 { ++ reg = <1>; + remote-endpoint = <&drc1_in_be1>; + }; + }; +@@ -1042,8 +1042,8 @@ + #size-cells = <0>; + reg = <0>; + +- drc1_in_be1: endpoint@0 { +- reg = <0>; ++ drc1_in_be1: endpoint@1 { ++ reg = <1>; + remote-endpoint = <&be1_out_drc1>; + }; + }; +@@ -1053,8 +1053,8 @@ + #size-cells = <0>; + reg = <1>; + +- drc1_out_tcon1: endpoint@0 { +- reg = <0>; ++ drc1_out_tcon1: endpoint@1 { ++ reg = <1>; + remote-endpoint = <&tcon1_in_drc1>; + }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index ba1d9810ad1e..c27242a7d5e7 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -370,10 +370,10 @@ + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <3300000>; ++ regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; +- regulator-suspend-microvolt = <3300000>; ++ regulator-suspend-microvolt = <3000000>; + }; + }; + +diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S +index 23de307c3052..41e60a9c7db2 100644 +--- a/arch/parisc/kernel/syscall.S ++++ b/arch/parisc/kernel/syscall.S +@@ -742,7 +742,7 @@ lws_compare_and_swap_2: + 10: ldd 0(%r25), %r25 + 11: ldd 0(%r24), %r24 + #else +- /* Load new value into r22/r23 - high/low */ ++ /* Load old value into r22/r23 - high/low */ + 10: ldw 0(%r25), %r22 + 11: ldw 4(%r25), %r23 + /* Load new value into fr4 for atomic store later */ +@@ -834,11 +834,11 @@ cas2_action: + copy %r0, %r28 + #else + /* Compare first word */ +-19: ldw,ma 0(%r26), %r29 ++19: ldw 0(%r26), %r29 + sub,= %r29, %r22, %r0 + b,n cas2_end + /* Compare second word */ +-20: ldw,ma 4(%r26), %r29 ++20: ldw 4(%r26), %r29 + sub,= %r29, %r23, %r0 + b,n cas2_end + /* Perform the store */ +diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c +index 2d956aa0a38a..8c0105a49839 100644 +--- a/arch/parisc/kernel/time.c ++++ b/arch/parisc/kernel/time.c +@@ -253,7 +253,10 @@ static int __init init_cr16_clocksource(void) + cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; + + for_each_online_cpu(cpu) { +- if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc) ++ if (cpu == 0) ++ continue; ++ if ((cpu0_loc != 0) && ++ (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) + continue; + + clocksource_cr16.name = "cr16_unstable"; +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 1020a11a24e5..03895b6db719 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -293,7 +293,10 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) + lc->lpp = LPP_MAGIC; + lc->current_pid = tsk->pid; + lc->user_timer = tsk->thread.user_timer; ++ lc->guest_timer = tsk->thread.guest_timer; + lc->system_timer = tsk->thread.system_timer; ++ lc->hardirq_timer = tsk->thread.hardirq_timer; ++ lc->softirq_timer = tsk->thread.softirq_timer; + lc->steal_timer = 0; + } + +diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c +index 59edbe9d4ccb..636a5fcfdeb7 100644 +--- a/arch/x86/kernel/cpu/microcode/intel.c ++++ b/arch/x86/kernel/cpu/microcode/intel.c +@@ -34,6 +34,7 @@ + #include <linux/mm.h> + + #include <asm/microcode_intel.h> ++#include <asm/intel-family.h> + #include <asm/processor.h> + #include <asm/tlbflush.h> + #include <asm/setup.h> +@@ -917,6 +918,18 @@ static int get_ucode_fw(void *to, const void *from, size_t n) + return 0; + } + ++static bool is_blacklisted(unsigned int cpu) ++{ ++ struct cpuinfo_x86 *c = &cpu_data(cpu); ++ ++ if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) { ++ pr_err_once("late loading on model 79 is disabled.\n"); ++ return true; ++ } ++ ++ return false; ++} ++ + static enum ucode_state request_microcode_fw(int cpu, struct device *device, + bool refresh_fw) + { +@@ -925,6 +938,9 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device, + const struct firmware *firmware; + enum ucode_state ret; + ++ if (is_blacklisted(cpu)) ++ return UCODE_NFOUND; ++ + sprintf(name, "intel-ucode/%02x-%02x-%02x", + c->x86, c->x86_model, c->x86_mask); + +@@ -949,6 +965,9 @@ static int get_ucode_user(void *to, const void *from, size_t n) + static enum ucode_state + request_microcode_user(int cpu, const void __user *buf, size_t size) + { ++ if (is_blacklisted(cpu)) ++ return UCODE_NFOUND; ++ + return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); + } + +diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c +index af4cd8649117..d140d8bb2c96 100644 +--- a/crypto/asymmetric_keys/pkcs7_parser.c ++++ b/crypto/asymmetric_keys/pkcs7_parser.c +@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) + bool want = false; + + sinfo = msg->signed_infos; ++ if (!sinfo) ++ goto inconsistent; ++ + if (sinfo->authattrs) { + want = true; + msg->have_authattrs = true; +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 5bdf923294a5..da7043893249 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -243,7 +243,6 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, + struct nbd_config *config = nbd->config; + config->blksize = blocksize; + config->bytesize = blocksize * nr_blocks; +- nbd_size_update(nbd); + } + + static void nbd_complete_rq(struct request *req) +@@ -1090,6 +1089,7 @@ static int nbd_start_device(struct nbd_device *nbd) + args->index = i; + queue_work(recv_workqueue, &args->work); + } ++ nbd_size_update(nbd); + return error; + } + +diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c +index c7f396903184..70db4d5638a6 100644 +--- a/drivers/bus/mvebu-mbus.c ++++ b/drivers/bus/mvebu-mbus.c +@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) + if (mbus->hw_io_coherency) + w->mbus_attr |= ATTR_HW_COHERENCY; + w->base = base & DDR_BASE_CS_LOW_MASK; +- w->size = (size | ~DDR_SIZE_MASK) + 1; ++ w->size = (u64)(size | ~DDR_SIZE_MASK) + 1; + } + } + mvebu_mbus_dram_info.num_cs = cs; +diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c +index a1df588343f2..1de8cac99a0e 100644 +--- a/drivers/clocksource/cs5535-clockevt.c ++++ b/drivers/clocksource/cs5535-clockevt.c +@@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) + /* Turn off the clock (and clear the event) */ + disable_timer(cs5535_event_clock); + +- if (clockevent_state_shutdown(&cs5535_clockevent)) ++ if (clockevent_state_detached(&cs5535_clockevent) || ++ clockevent_state_shutdown(&cs5535_clockevent)) + return IRQ_HANDLED; + + /* Clear the counter */ +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index d3b3252a8742..384bf4695e99 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, + int *n_entries) + { + if (IS_BROADWELL(dev_priv)) { +- *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); +- return hsw_ddi_translations_fdi; ++ *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi); ++ return bdw_ddi_translations_fdi; + } else if (IS_HASWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); + return hsw_ddi_translations_fdi; +diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c +index 3d35ea3e95db..92ff3e4ca013 100644 +--- a/drivers/gpu/drm/nouveau/nv50_display.c ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -3281,11 +3281,14 @@ nv50_mstm = { + void + nv50_mstm_service(struct nv50_mstm *mstm) + { +- struct drm_dp_aux *aux = mstm->mgr.aux; ++ struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL; + bool handled = true; + int ret; + u8 esi[8] = {}; + ++ if (!aux) ++ return; ++ + while (handled) { + ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8); + if (ret != 8) { +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +index 8e2e24a74774..44e116f7880d 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +@@ -39,5 +39,5 @@ int + g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) + { + return nvkm_xtensa_new_(&g84_bsp, device, index, +- true, 0x103000, pengine); ++ device->chipset != 0x92, 0x103000, pengine); + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +index d06ad2c372bf..455da298227f 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +@@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) + mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem); + } + ++ mmu->func->flush(vm); ++ + nvkm_memory_del(&pgt); + } + } +diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c +index 22ffcb73c185..b51adffa4841 100644 +--- a/drivers/i2c/busses/i2c-ismt.c ++++ b/drivers/i2c/busses/i2c-ismt.c +@@ -340,12 +340,15 @@ static int ismt_process_desc(const struct ismt_desc *desc, + data->word = dma_buffer[0] | (dma_buffer[1] << 8); + break; + case I2C_SMBUS_BLOCK_DATA: +- case I2C_SMBUS_I2C_BLOCK_DATA: + if (desc->rxbytes != dma_buffer[0] + 1) + return -EMSGSIZE; + + memcpy(data->block, dma_buffer, desc->rxbytes); + break; ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ memcpy(&data->block[1], dma_buffer, desc->rxbytes); ++ data->block[0] = desc->rxbytes; ++ break; + } + return 0; + } +diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c +index 0ecdb47a23ab..01f767ee4546 100644 +--- a/drivers/i2c/busses/i2c-piix4.c ++++ b/drivers/i2c/busses/i2c-piix4.c +@@ -94,6 +94,12 @@ + #define SB800_PIIX4_PORT_IDX_ALT 0x2e + #define SB800_PIIX4_PORT_IDX_SEL 0x2f + #define SB800_PIIX4_PORT_IDX_MASK 0x06 ++#define SB800_PIIX4_PORT_IDX_SHIFT 1 ++ ++/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ ++#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02 ++#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18 ++#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3 + + /* insmod parameters */ + +@@ -149,6 +155,8 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { + */ + static DEFINE_MUTEX(piix4_mutex_sb800); + static u8 piix4_port_sel_sb800; ++static u8 piix4_port_mask_sb800; ++static u8 piix4_port_shift_sb800; + static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = { + " port 0", " port 2", " port 3", " port 4" + }; +@@ -347,7 +355,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, + + /* Find which register is used for port selection */ + if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) { +- piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; ++ switch (PIIX4_dev->device) { ++ case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS: ++ piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ; ++ piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ; ++ piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ; ++ break; ++ case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS: ++ default: ++ piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; ++ piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; ++ piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; ++ break; ++ } + } else { + mutex_lock(&piix4_mutex_sb800); + outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX); +@@ -355,6 +375,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, + piix4_port_sel_sb800 = (port_sel & 0x01) ? + SB800_PIIX4_PORT_IDX_ALT : + SB800_PIIX4_PORT_IDX; ++ piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; ++ piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; + mutex_unlock(&piix4_mutex_sb800); + } + +@@ -616,8 +638,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + + port = adapdata->port; +- if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != port) +- outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | port, ++ if ((smba_en_lo & piix4_port_mask_sb800) != port) ++ outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port, + SB800_PIIX4_SMB_IDX + 1); + + retval = piix4_access(adap, addr, flags, read_write, +@@ -706,7 +728,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, + + adapdata->smba = smba; + adapdata->sb800_main = sb800_main; +- adapdata->port = port << 1; ++ adapdata->port = port << piix4_port_shift_sb800; + + /* set up the sysfs linkage to our parent device */ + adap->dev.parent = &dev->dev; +diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c +index ed63ffd849f8..7ec2a0bb0807 100644 +--- a/drivers/iio/dummy/iio_simple_dummy_events.c ++++ b/drivers/iio/dummy/iio_simple_dummy_events.c +@@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, + st->event_en = state; + else + return -EINVAL; ++ break; + default: + return -EINVAL; + } +diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c +index 157fdb4bb2e8..8c6c6178ec12 100644 +--- a/drivers/input/touchscreen/stmfts.c ++++ b/drivers/input/touchscreen/stmfts.c +@@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client, + sdata->input->open = stmfts_input_open; + sdata->input->close = stmfts_input_close; + ++ input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X); ++ input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y); + touchscreen_parse_properties(sdata->input, true, &sdata->prop); + +- input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0, +- sdata->prop.max_x, 0, 0); +- input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0, +- sdata->prop.max_y, 0, 0); + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); + input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0); +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index d596b601ff42..8cfc5e84a129 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -1726,12 +1726,19 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + */ + switch (msg->msg[1]) { + case CEC_MSG_GET_CEC_VERSION: +- case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + case CEC_MSG_ABORT: + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: +- case CEC_MSG_GIVE_PHYSICAL_ADDR: + case CEC_MSG_GIVE_OSD_NAME: ++ /* ++ * These messages reply with a directed message, so ignore if ++ * the initiator is Unregistered. ++ */ ++ if (!adap->passthrough && from_unregistered) ++ return 0; ++ /* Fall through */ ++ case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + case CEC_MSG_GIVE_FEATURES: ++ case CEC_MSG_GIVE_PHYSICAL_ADDR: + /* + * Skip processing these messages if the passthrough mode + * is on. +@@ -1739,7 +1746,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + if (adap->passthrough) + goto skip_processing; + /* Ignore if addressing is wrong */ +- if (is_broadcast || from_unregistered) ++ if (is_broadcast) + return 0; + break; + +diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c +index 224283fe100a..4d086a7248e9 100644 +--- a/drivers/media/dvb-frontends/dib3000mc.c ++++ b/drivers/media/dvb-frontends/dib3000mc.c +@@ -55,29 +55,57 @@ struct dib3000mc_state { + + static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) + { +- u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; +- u8 rb[2]; + struct i2c_msg msg[2] = { +- { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, +- { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, ++ { .addr = state->i2c_addr >> 1, .flags = 0, .len = 2 }, ++ { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 }, + }; ++ u16 word; ++ u8 *b; ++ ++ b = kmalloc(4, GFP_KERNEL); ++ if (!b) ++ return 0; ++ ++ b[0] = (reg >> 8) | 0x80; ++ b[1] = reg; ++ b[2] = 0; ++ b[3] = 0; ++ ++ msg[0].buf = b; ++ msg[1].buf = b + 2; + + if (i2c_transfer(state->i2c_adap, msg, 2) != 2) + dprintk("i2c read error on %d\n",reg); + +- return (rb[0] << 8) | rb[1]; ++ word = (b[2] << 8) | b[3]; ++ kfree(b); ++ ++ return word; + } + + static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) + { +- u8 b[4] = { +- (reg >> 8) & 0xff, reg & 0xff, +- (val >> 8) & 0xff, val & 0xff, +- }; + struct i2c_msg msg = { +- .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 ++ .addr = state->i2c_addr >> 1, .flags = 0, .len = 4 + }; +- return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; ++ int rc; ++ u8 *b; ++ ++ b = kmalloc(4, GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ ++ b[0] = reg >> 8; ++ b[1] = reg; ++ b[2] = val >> 8; ++ b[3] = val; ++ ++ msg.buf = b; ++ ++ rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; ++ kfree(b); ++ ++ return rc; + } + + static int dib3000mc_identify(struct dib3000mc_state *state) +diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c +index 7bec3e028bee..5553b89b804e 100644 +--- a/drivers/media/dvb-frontends/dvb-pll.c ++++ b/drivers/media/dvb-frontends/dvb-pll.c +@@ -753,13 +753,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, + struct i2c_adapter *i2c, + unsigned int pll_desc_id) + { +- u8 b1 [] = { 0 }; +- struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, +- .buf = b1, .len = 1 }; ++ u8 *b1; ++ struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 }; + struct dvb_pll_priv *priv = NULL; + int ret; + const struct dvb_pll_desc *desc; + ++ b1 = kmalloc(1, GFP_KERNEL); ++ if (!b1) ++ return NULL; ++ ++ b1[0] = 0; ++ msg.buf = b1; ++ + if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && + (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) + pll_desc_id = id[dvb_pll_devcount]; +@@ -773,15 +779,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = i2c_transfer (i2c, &msg, 1); +- if (ret != 1) ++ if (ret != 1) { ++ kfree(b1); + return NULL; ++ } + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); +- if (priv == NULL) ++ if (!priv) { ++ kfree(b1); + return NULL; ++ } + + priv->pll_i2c_address = pll_addr; + priv->i2c = i2c; +@@ -811,6 +821,8 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, + "insmod option" : "autodetected"); + } + ++ kfree(b1); ++ + return fe; + } + EXPORT_SYMBOL(dvb_pll_attach); +diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c +index 1edf667d562a..146ae6f25cdb 100644 +--- a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c ++++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c +@@ -172,7 +172,8 @@ u32 s5p_cec_get_status(struct s5p_cec_dev *cec) + { + u32 status = 0; + +- status = readb(cec->reg + S5P_CEC_STATUS_0); ++ status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf; ++ status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4; + status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8; + status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16; + status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24; +diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c +index 8e06071a7977..7d8d67e5448f 100644 +--- a/drivers/media/platform/s5p-cec/s5p_cec.c ++++ b/drivers/media/platform/s5p-cec/s5p_cec.c +@@ -92,7 +92,10 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv) + dev_dbg(cec->dev, "irq received\n"); + + if (status & CEC_STATUS_TX_DONE) { +- if (status & CEC_STATUS_TX_ERROR) { ++ if (status & CEC_STATUS_TX_NACK) { ++ dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n"); ++ cec->tx = STATE_NACK; ++ } else if (status & CEC_STATUS_TX_ERROR) { + dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n"); + cec->tx = STATE_ERROR; + } else { +@@ -135,6 +138,12 @@ static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv) + cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); + cec->tx = STATE_IDLE; + break; ++ case STATE_NACK: ++ cec_transmit_done(cec->adap, ++ CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK, ++ 0, 1, 0, 0); ++ cec->tx = STATE_IDLE; ++ break; + case STATE_ERROR: + cec_transmit_done(cec->adap, + CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR, +diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h +index 8bcd8dc1aeb9..86ded522ef27 100644 +--- a/drivers/media/platform/s5p-cec/s5p_cec.h ++++ b/drivers/media/platform/s5p-cec/s5p_cec.h +@@ -35,6 +35,7 @@ + #define CEC_STATUS_TX_TRANSFERRING (1 << 1) + #define CEC_STATUS_TX_DONE (1 << 2) + #define CEC_STATUS_TX_ERROR (1 << 3) ++#define CEC_STATUS_TX_NACK (1 << 4) + #define CEC_STATUS_TX_BYTES (0xFF << 8) + #define CEC_STATUS_RX_RUNNING (1 << 16) + #define CEC_STATUS_RX_RECEIVING (1 << 17) +@@ -55,6 +56,7 @@ enum cec_state { + STATE_IDLE, + STATE_BUSY, + STATE_DONE, ++ STATE_NACK, + STATE_ERROR + }; + +diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c +index 2e487f9a2cc3..4983eeb39f36 100644 +--- a/drivers/media/tuners/mt2060.c ++++ b/drivers/media/tuners/mt2060.c +@@ -38,41 +38,74 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val) + { + struct i2c_msg msg[2] = { +- { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, +- { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, ++ { .addr = priv->cfg->i2c_address, .flags = 0, .len = 1 }, ++ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .len = 1 }, + }; ++ int rc = 0; ++ u8 *b; ++ ++ b = kmalloc(2, GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ ++ b[0] = reg; ++ b[1] = 0; ++ ++ msg[0].buf = b; ++ msg[1].buf = b + 1; + + if (i2c_transfer(priv->i2c, msg, 2) != 2) { + printk(KERN_WARNING "mt2060 I2C read failed\n"); +- return -EREMOTEIO; ++ rc = -EREMOTEIO; + } +- return 0; ++ *val = b[1]; ++ kfree(b); ++ ++ return rc; + } + + // Writes a single register + static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val) + { +- u8 buf[2] = { reg, val }; + struct i2c_msg msg = { +- .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 ++ .addr = priv->cfg->i2c_address, .flags = 0, .len = 2 + }; ++ u8 *buf; ++ int rc = 0; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ buf[0] = reg; ++ buf[1] = val; ++ ++ msg.buf = buf; + + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "mt2060 I2C write failed\n"); +- return -EREMOTEIO; ++ rc = -EREMOTEIO; + } +- return 0; ++ kfree(buf); ++ return rc; + } + + // Writes a set of consecutive registers + static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len) + { + int rem, val_len; +- u8 xfer_buf[16]; ++ u8 *xfer_buf; ++ int rc = 0; + struct i2c_msg msg = { +- .addr = priv->cfg->i2c_address, .flags = 0, .buf = xfer_buf ++ .addr = priv->cfg->i2c_address, .flags = 0 + }; + ++ xfer_buf = kmalloc(16, GFP_KERNEL); ++ if (!xfer_buf) ++ return -ENOMEM; ++ ++ msg.buf = xfer_buf; ++ + for (rem = len - 1; rem > 0; rem -= priv->i2c_max_regs) { + val_len = min_t(int, rem, priv->i2c_max_regs); + msg.len = 1 + val_len; +@@ -81,11 +114,13 @@ static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len) + + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n", val_len); +- return -EREMOTEIO; ++ rc = -EREMOTEIO; ++ break; + } + } + +- return 0; ++ kfree(xfer_buf); ++ return rc; + } + + // Initialisation sequences +diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c +index ba8a0f58fe08..b2d0ee0be8c3 100644 +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -449,6 +449,8 @@ static void intel_dsm_init(struct intel_host *intel_host, struct device *dev, + int err; + u32 val; + ++ intel_host->d3_retune = true; ++ + err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns); + if (err) { + pr_debug("%s: DSM not supported, error %d\n", +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index 13f0f219d8aa..a13a4896a8bd 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -182,22 +182,23 @@ + /* FLEXCAN hardware feature flags + * + * Below is some version info we got: +- * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err RTR re- +- * Filter? connected? detection ception in MB +- * MX25 FlexCAN2 03.00.00.00 no no no no +- * MX28 FlexCAN2 03.00.04.00 yes yes no no +- * MX35 FlexCAN2 03.00.00.00 no no no no +- * MX53 FlexCAN2 03.00.00.00 yes no no no +- * MX6s FlexCAN3 10.00.12.00 yes yes no yes +- * VF610 FlexCAN3 ? no yes yes yes? ++ * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- ++ * Filter? connected? Passive detection ception in MB ++ * MX25 FlexCAN2 03.00.00.00 no no ? no no ++ * MX28 FlexCAN2 03.00.04.00 yes yes no no no ++ * MX35 FlexCAN2 03.00.00.00 no no ? no no ++ * MX53 FlexCAN2 03.00.00.00 yes no no no no ++ * MX6s FlexCAN3 10.00.12.00 yes yes no no yes ++ * VF610 FlexCAN3 ? no yes ? yes yes? + * + * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. + */ +-#define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */ ++#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ + #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ + #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ + #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ + #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ ++#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ + + /* Structure of the message buffer */ + struct flexcan_mb { +@@ -281,14 +282,17 @@ struct flexcan_priv { + }; + + static const struct flexcan_devtype_data fsl_p1010_devtype_data = { +- .quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE, ++ .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | ++ FLEXCAN_QUIRK_BROKEN_PERR_STATE, + }; + +-static const struct flexcan_devtype_data fsl_imx28_devtype_data; ++static const struct flexcan_devtype_data fsl_imx28_devtype_data = { ++ .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, ++}; + + static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { + .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | +- FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, ++ FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, + }; + + static const struct flexcan_devtype_data fsl_vf610_devtype_data = { +@@ -335,6 +339,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr) + } + #endif + ++static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) ++{ ++ struct flexcan_regs __iomem *regs = priv->regs; ++ u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); ++ ++ flexcan_write(reg_ctrl, ®s->ctrl); ++} ++ ++static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) ++{ ++ struct flexcan_regs __iomem *regs = priv->regs; ++ u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); ++ ++ flexcan_write(reg_ctrl, ®s->ctrl); ++} ++ + static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) + { + if (!priv->reg_xceiver) +@@ -713,6 +733,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) + struct flexcan_regs __iomem *regs = priv->regs; + irqreturn_t handled = IRQ_NONE; + u32 reg_iflag1, reg_esr; ++ enum can_state last_state = priv->can.state; + + reg_iflag1 = flexcan_read(®s->iflag1); + +@@ -765,8 +786,10 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) + flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); + } + +- /* state change interrupt */ +- if (reg_esr & FLEXCAN_ESR_ERR_STATE) ++ /* state change interrupt or broken error state quirk fix is enabled */ ++ if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || ++ (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | ++ FLEXCAN_QUIRK_BROKEN_PERR_STATE))) + flexcan_irq_state(dev, reg_esr); + + /* bus error IRQ - handle if bus error reporting is activated */ +@@ -774,6 +797,44 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) + (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + flexcan_irq_bus_err(dev, reg_esr); + ++ /* availability of error interrupt among state transitions in case ++ * bus error reporting is de-activated and ++ * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled: ++ * +--------------------------------------------------------------+ ++ * | +----------------------------------------------+ [stopped / | ++ * | | | sleeping] -+ ++ * +-+-> active <-> warning <-> passive -> bus off -+ ++ * ___________^^^^^^^^^^^^_______________________________ ++ * disabled(1) enabled disabled ++ * ++ * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled ++ */ ++ if ((last_state != priv->can.state) && ++ (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && ++ !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { ++ switch (priv->can.state) { ++ case CAN_STATE_ERROR_ACTIVE: ++ if (priv->devtype_data->quirks & ++ FLEXCAN_QUIRK_BROKEN_WERR_STATE) ++ flexcan_error_irq_enable(priv); ++ else ++ flexcan_error_irq_disable(priv); ++ break; ++ ++ case CAN_STATE_ERROR_WARNING: ++ flexcan_error_irq_enable(priv); ++ break; ++ ++ case CAN_STATE_ERROR_PASSIVE: ++ case CAN_STATE_BUS_OFF: ++ flexcan_error_irq_disable(priv); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ + return handled; + } + +@@ -887,7 +948,7 @@ static int flexcan_chip_start(struct net_device *dev) + * on most Flexcan cores, too. Otherwise we don't get + * any error warning or passive interrupts. + */ +- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE || ++ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || + priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) + reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; + else +diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c +index be928ce62d32..9fdb0f0bfa06 100644 +--- a/drivers/net/can/usb/esd_usb2.c ++++ b/drivers/net/can/usb/esd_usb2.c +@@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, + } + + cf->can_id = id & ESD_IDMASK; +- cf->can_dlc = get_can_dlc(msg->msg.rx.dlc); ++ cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR); + + if (id & ESD_EXTID) + cf->can_id |= CAN_EFF_FLAG; +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index afcc1312dbaf..68ac3e88a8ce 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + + gs_free_tx_context(txc); + ++ atomic_dec(&dev->active_tx_urbs); ++ + netif_wake_queue(netdev); + } + +@@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct urb *urb) + urb->transfer_buffer_length, + urb->transfer_buffer, + urb->transfer_dma); +- +- atomic_dec(&dev->active_tx_urbs); +- +- if (!netif_device_present(netdev)) +- return; +- +- if (netif_queue_stopped(netdev)) +- netif_wake_queue(netdev); + } + + static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +index 4eb1e1ce9ace..ef72baf6dd96 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -429,7 +429,8 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, + if (code != BRCMF_E_IF && !fweh->evt_handler[code]) + return; + +- if (datalen > BRCMF_DCMD_MAXLEN) ++ if (datalen > BRCMF_DCMD_MAXLEN || ++ datalen + sizeof(*event_packet) > packet_len) + return; + + if (in_interrupt()) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +index b3aab2fe96eb..ef685465f80a 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +@@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) + } + + static void +-wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, +- u8 len) ++wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events, ++ const u8 *dlys, u8 len) + { + u32 t1_offset, t2_offset; + u8 ctr; +@@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) + static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + { + u16 currband; +- s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; +- s8 *lna1_gain_db = NULL; +- s8 *lna1_gain_db_2 = NULL; +- s8 *lna2_gain_db = NULL; +- s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; +- s8 *tia_gain_db; +- s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; +- s8 *tia_gainbits; +- u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; +- u16 *rfseq_init_gain; ++ static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; ++ const s8 *lna1_gain_db = NULL; ++ const s8 *lna1_gain_db_2 = NULL; ++ const s8 *lna2_gain_db = NULL; ++ static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; ++ const s8 *tia_gain_db; ++ static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; ++ const s8 *tia_gainbits; ++ static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; ++ const u16 *rfseq_init_gain; + u16 init_gaincode; + u16 clip1hi_gaincode; + u16 clip1md_gaincode = 0; +@@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + + if ((freq <= 5080) || (freq == 5825)) { + +- s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 11, 17, 22, 25}; +- s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; ++ static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25}; ++ static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x3e; + lna1_gain_db = lna1A_gain_db_rev7; +@@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + lna2_gain_db = lna2A_gain_db_rev7; + } else if ((freq >= 5500) && (freq <= 5700)) { + +- s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 12, 18, 22, 26}; +- s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; ++ static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; ++ static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; + + crsminu_th = 0x45; + clip1md_gaincode_B = 0x14; +@@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + lna2_gain_db = lna2A_gain_db_rev7; + } else { + +- s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 12, 18, 22, 26}; +- s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; ++ static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; ++ static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x41; + lna1_gain_db = lna1A_gain_db_rev7; +@@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_RFSEQ_CMD_SET_HPF_BW + }; +- u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; +- s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; +- s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; +- s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; +- s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; +- s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; +- s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; +- s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; +- s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; +- s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; +- s8 *lna1_gain_db = NULL; +- s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; +- s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; +- s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; +- s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; +- s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; +- s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; +- s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; +- s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; +- s8 *lna2_gain_db = NULL; +- s8 tiaG_gain_db[] = { ++ static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; ++ static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; ++ static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; ++ static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; ++ static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; ++ static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; ++ static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; ++ static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; ++ static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; ++ static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; ++ const s8 *lna1_gain_db = NULL; ++ static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; ++ static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; ++ static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; ++ static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; ++ static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; ++ static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; ++ static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; ++ static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; ++ const s8 *lna2_gain_db = NULL; ++ static const s8 tiaG_gain_db[] = { + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; +- s8 tiaA_gain_db[] = { ++ static const s8 tiaA_gain_db[] = { + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; +- s8 tiaA_gain_db_rev4[] = { ++ static const s8 tiaA_gain_db_rev4[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 tiaA_gain_db_rev5[] = { ++ static const s8 tiaA_gain_db_rev5[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 tiaA_gain_db_rev6[] = { ++ static const s8 tiaA_gain_db_rev6[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 *tia_gain_db; +- s8 tiaG_gainbits[] = { ++ const s8 *tia_gain_db; ++ static const s8 tiaG_gainbits[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; +- s8 tiaA_gainbits[] = { ++ static const s8 tiaA_gainbits[] = { + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; +- s8 tiaA_gainbits_rev4[] = { ++ static const s8 tiaA_gainbits_rev4[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 tiaA_gainbits_rev5[] = { ++ static const s8 tiaA_gainbits_rev5[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 tiaA_gainbits_rev6[] = { ++ static const s8 tiaA_gainbits_rev6[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 *tia_gainbits; +- s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; +- s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; +- u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; +- u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; +- u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; +- u16 rfseqG_init_gain_rev5_elna[] = { ++ const s8 *tia_gainbits; ++ static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; ++ static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; ++ static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; ++ static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; ++ static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; ++ static const u16 rfseqG_init_gain_rev5_elna[] = { + 0x013f, 0x013f, 0x013f, 0x013f }; +- u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; +- u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; +- u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; +- u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; +- u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; +- u16 rfseqA_init_gain_rev4_elna[] = { ++ static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; ++ static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; ++ static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; ++ static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; ++ static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; ++ static const u16 rfseqA_init_gain_rev4_elna[] = { + 0x314f, 0x314f, 0x314f, 0x314f }; +- u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; +- u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; +- u16 *rfseq_init_gain; ++ static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; ++ static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; ++ const u16 *rfseq_init_gain; + u16 initG_gaincode = 0x627e; + u16 initG_gaincode_rev4 = 0x527e; + u16 initG_gaincode_rev5 = 0x427e; +@@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + u16 clip1mdA_gaincode_rev6 = 0x2084; + u16 clip1md_gaincode = 0; + u16 clip1loG_gaincode = 0x0074; +- u16 clip1loG_gaincode_rev5[] = { ++ static const u16 clip1loG_gaincode_rev5[] = { + 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c + }; +- u16 clip1loG_gaincode_rev6[] = { ++ static const u16 clip1loG_gaincode_rev6[] = { + 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e + }; + u16 clip1loG_gaincode_rev6_224B0 = 0x1074; +@@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + + static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + { +- u8 rfseq_rx2tx_events[] = { ++ static const u8 rfseq_rx2tx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_TR_SWITCH, +@@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_EXT_PA + }; + u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; +- u8 rfseq_tx2rx_events[] = { ++ static const u8 rfseq_tx2rx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_EXT_PA, + NPHY_RFSEQ_CMD_TX_GAIN, +@@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS + }; +- u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; +- u8 rfseq_tx2rx_events_rev3[] = { ++ static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; ++ static const u8 rfseq_tx2rx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_EXT_PA, + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_TX_GAIN, +@@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_REV3_RFSEQ_CMD_END + }; +- u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; ++ static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; + u8 rfseq_rx2tx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, +@@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + }; + u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; + +- u8 rfseq_rx2tx_events_rev3_ipa[] = { ++ static const u8 rfseq_rx2tx_events_rev3_ipa[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, + NPHY_REV3_RFSEQ_CMD_TR_SWITCH, +@@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_END + }; +- u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; +- u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; ++ static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; ++ static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; + + s16 alpha0, alpha1, alpha2; + s16 beta0, beta1, beta2; + u32 leg_data_weights, ht_data_weights, nss1_data_weights, + stbc_data_weights; + u8 chan_freq_range = 0; +- u16 dac_control = 0x0002; ++ static const u16 dac_control = 0x0002; + u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; + u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; + u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; +@@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 *aux_adc_gain; +- u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; +- u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; ++ static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; ++ static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; + s32 min_nvar_val = 0x18d; + s32 min_nvar_offset_6mbps = 20; + u8 pdetrange; +@@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; +- u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; +- u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; +- u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; ++ static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; ++ static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; ++ static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + u16 ipalvlshift_3p3_war_en = 0; + u16 rccal_bcap_val, rccal_scap_val; + u16 rccal_tx20_11b_bcap = 0; +@@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) + u16 bbmult; + u16 tblentry; + +- struct nphy_txiqcal_ladder ladder_lo[] = { ++ static const struct nphy_txiqcal_ladder ladder_lo[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, + {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} + }; + +- struct nphy_txiqcal_ladder ladder_iq[] = { ++ static const struct nphy_txiqcal_ladder ladder_iq[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, + {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} +@@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, + u16 cal_gain[2]; + struct nphy_iqcal_params cal_params[2]; + u32 tbl_len; +- void *tbl_ptr; ++ const void *tbl_ptr; + bool ladder_updated[2]; + u8 mphase_cal_lastphase = 0; + int bcmerror = 0; + bool phyhang_avoid_state = false; + +- u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { ++ static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { + 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, + 0x1902, + 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, + 0x6407 + }; + +- u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { ++ static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { + 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, + 0x3200, + 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, + 0x6407 + }; + +- u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { ++ static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { + 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, + 0x1202, + 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, + 0x4707 + }; + +- u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { ++ static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { + 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, + 0x2300, + 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, + 0x4707 + }; + +- u16 tbl_tx_iqlo_cal_startcoefs[] = { ++ static const u16 tbl_tx_iqlo_cal_startcoefs[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + +- u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { + 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, + 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 + }; + +- u16 tbl_tx_iqlo_cal_cmds_recal[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_recal[] = { + 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, + 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 + }; + +- u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + +- u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, + 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 + }; + +- u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { + 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, + 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 + }; +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +index 2bc6bace069c..b4302f41493c 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +@@ -1122,7 +1122,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr) + } + if (0 == tmp) { + read_addr = REG_DBI_RDATA + addr % 4; +- ret = rtl_read_byte(rtlpriv, read_addr); ++ ret = rtl_read_word(rtlpriv, read_addr); + } + return ret; + } +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index df57655779ed..5da006d81900 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -3165,6 +3165,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) + host->can_queue, base_vha->req, + base_vha->mgmt_svr_loop_id, host->sg_tablesize); + ++ INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); ++ + if (ha->mqenable) { + bool mq = false; + bool startit = false; +@@ -3213,7 +3215,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) + */ + qla2xxx_wake_dpc(base_vha); + +- INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); + INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error); + + if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) { +diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +index 5f3d8f2339e3..4be864dbd41c 100644 +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream + __func__, instance); + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; +- ret = 0; // xxx todo -1; +- goto err_free_mem; ++ return 0; + } + + /* Initialize and create a VCHI connection */ +@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream + LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + +- ret = -EIO; +- goto err_free_mem; ++ return -EIO; + } + ret = vchi_connect(NULL, 0, vchi_instance); + if (ret) { + LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + +- ret = -EIO; +- goto err_free_mem; ++ kfree(vchi_instance); ++ return -EIO; + } + initted = 1; + } +@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream + if (IS_ERR(instance)) { + LOG_ERR("%s: failed to initialize audio service\n", __func__); + +- ret = PTR_ERR(instance); +- goto err_free_mem; ++ /* vchi_instance is retained for use the next time. */ ++ return PTR_ERR(instance); + } + + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + + LOG_DBG(" success !\n"); +- ret = 0; +-err_free_mem: +- kfree(vchi_instance); + +- return ret; ++ return 0; + } + + int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 5e056064259c..18c923a4c16e 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1832,6 +1832,9 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */ + .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ + }, ++ { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ ++ .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ ++ }, + + { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ + .driver_info = CLEAR_HALT_CONDITIONS, +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 68b54bd88d1e..883549ee946c 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -960,10 +960,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) + for (i = 0; i < num; i++) { + buffer += length; + cap = (struct usb_dev_cap_header *)buffer; +- length = cap->bLength; + +- if (total_len < length) ++ if (total_len < sizeof(*cap) || total_len < cap->bLength) { ++ dev->bos->desc->bNumDeviceCaps = i; + break; ++ } ++ length = cap->bLength; + total_len -= length; + + if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 1d4dfdeb61c1..066b58cb6c98 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1576,11 +1576,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + totlen += isopkt[u].length; + } + u *= sizeof(struct usb_iso_packet_descriptor); +- if (totlen <= uurb->buffer_length) +- uurb->buffer_length = totlen; +- else +- WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", +- totlen, uurb->buffer_length); ++ uurb->buffer_length = totlen; + break; + + default: +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 78c2aca5b0fc..3f44341259d8 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2710,13 +2710,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, + if (!(portstatus & USB_PORT_STAT_CONNECTION)) + return -ENOTCONN; + +- /* bomb out completely if the connection bounced. A USB 3.0 +- * connection may bounce if multiple warm resets were issued, ++ /* Retry if connect change is set but status is still connected. ++ * A USB 3.0 connection may bounce if multiple warm resets were issued, + * but the device may have successfully re-connected. Ignore it. + */ + if (!hub_is_superspeed(hub->hdev) && +- (portchange & USB_PORT_STAT_C_CONNECTION)) +- return -ENOTCONN; ++ (portchange & USB_PORT_STAT_C_CONNECTION)) { ++ usb_clear_port_feature(hub->hdev, port1, ++ USB_PORT_FEAT_C_CONNECTION); ++ return -EAGAIN; ++ } + + if (!(portstatus & USB_PORT_STAT_ENABLE)) + return -EBUSY; +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 82806e311202..a6aaf2f193a4 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -221,6 +221,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Corsair Strafe RGB */ + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + ++ /* MIDI keyboard WORLDE MINI */ ++ { USB_DEVICE(0x1c75, 0x0204), .driver_info = ++ USB_QUIRK_CONFIG_INTF_STRINGS }, ++ + /* Acer C120 LED Projector */ + { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 950dee33bfcc..ad4c697cf30e 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -420,14 +420,25 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) + GFP_NOWAIT); + if (!command) { + spin_unlock_irqrestore(&xhci->lock, flags); +- xhci_free_command(xhci, cmd); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto cmd_cleanup; ++ } ++ ++ ret = xhci_queue_stop_endpoint(xhci, command, slot_id, ++ i, suspend); ++ if (ret) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_free_command(xhci, command); ++ goto cmd_cleanup; + } +- xhci_queue_stop_endpoint(xhci, command, slot_id, i, +- suspend); + } + } +- xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); ++ ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); ++ if (ret) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ goto cmd_cleanup; ++ } ++ + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + +@@ -439,6 +450,8 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) + xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n"); + ret = -ETIME; + } ++ ++cmd_cleanup: + xhci_free_command(xhci, cmd); + return ret; + } +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index cc368ad2b51e..b0f42e1b91ee 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1309,6 +1309,7 @@ static void xhci_complete_del_and_free_cmd(struct xhci_command *cmd, u32 status) + void xhci_cleanup_command_queue(struct xhci_hcd *xhci) + { + struct xhci_command *cur_cmd, *tmp_cmd; ++ xhci->current_cmd = NULL; + list_for_each_entry_safe(cur_cmd, tmp_cmd, &xhci->cmd_list, cmd_list) + xhci_complete_del_and_free_cmd(cur_cmd, COMP_COMMAND_ABORTED); + } +@@ -2577,15 +2578,21 @@ static int handle_tx_event(struct xhci_hcd *xhci, + (struct xhci_generic_trb *) ep_trb); + + /* +- * No-op TRB should not trigger interrupts. +- * If ep_trb is a no-op TRB, it means the +- * corresponding TD has been cancelled. Just ignore +- * the TD. ++ * No-op TRB could trigger interrupts in a case where ++ * a URB was killed and a STALL_ERROR happens right ++ * after the endpoint ring stopped. Reset the halted ++ * endpoint. Otherwise, the endpoint remains stalled ++ * indefinitely. + */ + if (trb_is_noop(ep_trb)) { +- xhci_dbg(xhci, +- "ep_trb is a no-op TRB. Skip it for slot %u ep %u\n", +- slot_id, ep_index); ++ if (trb_comp_code == COMP_STALL_ERROR || ++ xhci_requires_manual_halt_cleanup(xhci, ep_ctx, ++ trb_comp_code)) ++ xhci_cleanup_halted_endpoint(xhci, slot_id, ++ ep_index, ++ ep_ring->stream_id, ++ td, ep_trb, ++ EP_HARD_RESET); + goto cleanup; + } + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index ee198ea47f49..51535ba2bcd4 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4805,7 +4805,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) + */ + hcd->has_tt = 1; + } else { +- if (xhci->sbrn == 0x31) { ++ /* Some 3.1 hosts return sbrn 0x30, can't rely on sbrn alone */ ++ if (xhci->sbrn == 0x31 || xhci->usb3_rhub.min_rev >= 1) { + xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n"); + hcd->speed = HCD_USB31; + hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index b67692857daf..458957e97fee 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -906,7 +906,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, + */ + if (int_usb & MUSB_INTR_RESET) { + handled = IRQ_HANDLED; +- if (devctl & MUSB_DEVCTL_HM) { ++ if (is_host_active(musb)) { + /* + * When BABBLE happens what we can depends on which + * platform MUSB is running, because some platforms +@@ -916,9 +916,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, + * drop the session. + */ + dev_err(musb->controller, "Babble\n"); +- +- if (is_host_active(musb)) +- musb_recover_from_babble(musb); ++ musb_recover_from_babble(musb); + } else { + musb_dbg(musb, "BUS RESET as %s", + usb_otg_state_string(musb->xceiv->otg->state)); +@@ -1861,22 +1859,22 @@ static void musb_pm_runtime_check_session(struct musb *musb) + MUSB_DEVCTL_HR; + switch (devctl & ~s) { + case MUSB_QUIRK_B_INVALID_VBUS_91: +- if (musb->quirk_retries--) { ++ if (musb->quirk_retries && !musb->flush_irq_work) { + musb_dbg(musb, + "Poll devctl on invalid vbus, assume no session"); + schedule_delayed_work(&musb->irq_work, + msecs_to_jiffies(1000)); +- ++ musb->quirk_retries--; + return; + } + /* fall through */ + case MUSB_QUIRK_A_DISCONNECT_19: +- if (musb->quirk_retries--) { ++ if (musb->quirk_retries && !musb->flush_irq_work) { + musb_dbg(musb, + "Poll devctl on possible host mode disconnect"); + schedule_delayed_work(&musb->irq_work, + msecs_to_jiffies(1000)); +- ++ musb->quirk_retries--; + return; + } + if (!musb->session) +@@ -2681,8 +2679,15 @@ static int musb_suspend(struct device *dev) + + musb_platform_disable(musb); + musb_disable_interrupts(musb); ++ ++ musb->flush_irq_work = true; ++ while (flush_delayed_work(&musb->irq_work)) ++ ; ++ musb->flush_irq_work = false; ++ + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); ++ + WARN_ON(!list_empty(&musb->pending_list)); + + spin_lock_irqsave(&musb->lock, flags); +diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h +index 9f22c5b8ce37..1830a571d025 100644 +--- a/drivers/usb/musb/musb_core.h ++++ b/drivers/usb/musb/musb_core.h +@@ -428,6 +428,8 @@ struct musb { + unsigned test_mode:1; + unsigned softconnect:1; + ++ unsigned flush_irq_work:1; ++ + u8 address; + u8 test_mode_nr; + u16 ackpend; /* ep0 */ +diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c +index ba255280a624..1ec0a4947b6b 100644 +--- a/drivers/usb/musb/musb_cppi41.c ++++ b/drivers/usb/musb/musb_cppi41.c +@@ -26,15 +26,28 @@ + + #define MUSB_DMA_NUM_CHANNELS 15 + ++#define DA8XX_USB_MODE 0x10 ++#define DA8XX_USB_AUTOREQ 0x14 ++#define DA8XX_USB_TEARDOWN 0x1c ++ ++#define DA8XX_DMA_NUM_CHANNELS 4 ++ + struct cppi41_dma_controller { + struct dma_controller controller; +- struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; +- struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; ++ struct cppi41_dma_channel *rx_channel; ++ struct cppi41_dma_channel *tx_channel; + struct hrtimer early_tx; + struct list_head early_tx_list; + u32 rx_mode; + u32 tx_mode; + u32 auto_req; ++ ++ u32 tdown_reg; ++ u32 autoreq_reg; ++ ++ void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel, ++ unsigned int mode); ++ u8 num_channels; + }; + + static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) +@@ -349,6 +362,32 @@ static void cppi41_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, + } + } + ++static void da8xx_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, ++ unsigned int mode) ++{ ++ struct cppi41_dma_controller *controller = cppi41_channel->controller; ++ struct musb *musb = controller->controller.musb; ++ unsigned int shift; ++ u32 port; ++ u32 new_mode; ++ u32 old_mode; ++ ++ old_mode = controller->tx_mode; ++ port = cppi41_channel->port_num; ++ ++ shift = (port - 1) * 4; ++ if (!cppi41_channel->is_tx) ++ shift += 16; ++ new_mode = old_mode & ~(3 << shift); ++ new_mode |= mode << shift; ++ ++ if (new_mode == old_mode) ++ return; ++ controller->tx_mode = new_mode; ++ musb_writel(musb->ctrl_base, DA8XX_USB_MODE, new_mode); ++} ++ ++ + static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, + unsigned mode) + { +@@ -364,8 +403,8 @@ static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, + if (new_mode == old_mode) + return; + controller->auto_req = new_mode; +- musb_writel(controller->controller.musb->ctrl_base, USB_CTRL_AUTOREQ, +- new_mode); ++ musb_writel(controller->controller.musb->ctrl_base, ++ controller->autoreq_reg, new_mode); + } + + static bool cppi41_configure_channel(struct dma_channel *channel, +@@ -373,6 +412,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, + dma_addr_t dma_addr, u32 len) + { + struct cppi41_dma_channel *cppi41_channel = channel->private_data; ++ struct cppi41_dma_controller *controller = cppi41_channel->controller; + struct dma_chan *dc = cppi41_channel->dc; + struct dma_async_tx_descriptor *dma_desc; + enum dma_transfer_direction direction; +@@ -398,7 +438,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, + musb_writel(musb->ctrl_base, + RNDIS_REG(cppi41_channel->port_num), len); + /* gen rndis */ +- cppi41_set_dma_mode(cppi41_channel, ++ controller->set_dma_mode(cppi41_channel, + EP_MODE_DMA_GEN_RNDIS); + + /* auto req */ +@@ -407,14 +447,15 @@ static bool cppi41_configure_channel(struct dma_channel *channel, + } else { + musb_writel(musb->ctrl_base, + RNDIS_REG(cppi41_channel->port_num), 0); +- cppi41_set_dma_mode(cppi41_channel, ++ controller->set_dma_mode(cppi41_channel, + EP_MODE_DMA_TRANSPARENT); + cppi41_set_autoreq_mode(cppi41_channel, + EP_MODE_AUTOREQ_NONE); + } + } else { + /* fallback mode */ +- cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); ++ controller->set_dma_mode(cppi41_channel, ++ EP_MODE_DMA_TRANSPARENT); + cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); + len = min_t(u32, packet_sz, len); + } +@@ -445,7 +486,7 @@ static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c, + struct cppi41_dma_channel *cppi41_channel = NULL; + u8 ch_num = hw_ep->epnum - 1; + +- if (ch_num >= MUSB_DMA_NUM_CHANNELS) ++ if (ch_num >= controller->num_channels) + return NULL; + + if (is_tx) +@@ -581,12 +622,13 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) + + do { + if (is_tx) +- musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); ++ musb_writel(musb->ctrl_base, controller->tdown_reg, ++ tdbit); + ret = dmaengine_terminate_all(cppi41_channel->dc); + } while (ret == -EAGAIN); + + if (is_tx) { +- musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); ++ musb_writel(musb->ctrl_base, controller->tdown_reg, tdbit); + + csr = musb_readw(epio, MUSB_TXCSR); + if (csr & MUSB_TXCSR_TXPKTRDY) { +@@ -604,7 +646,7 @@ static void cppi41_release_all_dma_chans(struct cppi41_dma_controller *ctrl) + struct dma_chan *dc; + int i; + +- for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) { ++ for (i = 0; i < ctrl->num_channels; i++) { + dc = ctrl->tx_channel[i].dc; + if (dc) + dma_release_channel(dc); +@@ -656,7 +698,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) + goto err; + + ret = -EINVAL; +- if (port > MUSB_DMA_NUM_CHANNELS || !port) ++ if (port > controller->num_channels || !port) + goto err; + if (is_tx) + cppi41_channel = &controller->tx_channel[port - 1]; +@@ -697,6 +739,8 @@ void cppi41_dma_controller_destroy(struct dma_controller *c) + + hrtimer_cancel(&controller->early_tx); + cppi41_dma_controller_stop(controller); ++ kfree(controller->rx_channel); ++ kfree(controller->tx_channel); + kfree(controller); + } + EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy); +@@ -705,6 +749,7 @@ struct dma_controller * + cppi41_dma_controller_create(struct musb *musb, void __iomem *base) + { + struct cppi41_dma_controller *controller; ++ int channel_size; + int ret = 0; + + if (!musb->controller->parent->of_node) { +@@ -727,12 +772,37 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) + controller->controller.is_compatible = cppi41_is_compatible; + controller->controller.musb = musb; + ++ if (musb->io.quirks & MUSB_DA8XX) { ++ controller->tdown_reg = DA8XX_USB_TEARDOWN; ++ controller->autoreq_reg = DA8XX_USB_AUTOREQ; ++ controller->set_dma_mode = da8xx_set_dma_mode; ++ controller->num_channels = DA8XX_DMA_NUM_CHANNELS; ++ } else { ++ controller->tdown_reg = USB_TDOWN; ++ controller->autoreq_reg = USB_CTRL_AUTOREQ; ++ controller->set_dma_mode = cppi41_set_dma_mode; ++ controller->num_channels = MUSB_DMA_NUM_CHANNELS; ++ } ++ ++ channel_size = controller->num_channels * ++ sizeof(struct cppi41_dma_channel); ++ controller->rx_channel = kzalloc(channel_size, GFP_KERNEL); ++ if (!controller->rx_channel) ++ goto rx_channel_alloc_fail; ++ controller->tx_channel = kzalloc(channel_size, GFP_KERNEL); ++ if (!controller->tx_channel) ++ goto tx_channel_alloc_fail; ++ + ret = cppi41_dma_controller_start(controller); + if (ret) + goto plat_get_fail; + return &controller->controller; + + plat_get_fail: ++ kfree(controller->tx_channel); ++tx_channel_alloc_fail: ++ kfree(controller->rx_channel); ++rx_channel_alloc_fail: + kfree(controller); + kzalloc_fail: + if (ret == -EPROBE_DEFER) +diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c +index c9a09b5bb6e5..dc353e24d53c 100644 +--- a/drivers/usb/musb/sunxi.c ++++ b/drivers/usb/musb/sunxi.c +@@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *musb) + if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) + sunxi_sram_release(musb->controller->parent); + ++ devm_usb_put_phy(glue->dev, glue->xceiv); ++ + return 0; + } + +diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c +index cc84da8dbb84..14511d6a7d44 100644 +--- a/drivers/usb/serial/metro-usb.c ++++ b/drivers/usb/serial/metro-usb.c +@@ -45,6 +45,7 @@ struct metrousb_private { + static const struct usb_device_id id_table[] = { + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) }, /* MS7820 */ + { }, /* Terminating entry. */ + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c +index 018c588c7ac3..8e704d12a1cf 100644 +--- a/fs/crypto/keyinfo.c ++++ b/fs/crypto/keyinfo.c +@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info, + goto out; + } + ukp = user_key_payload_locked(keyring_key); ++ if (!ukp) { ++ /* key was revoked before we acquired its semaphore */ ++ res = -EKEYREVOKED; ++ goto out; ++ } + if (ukp->datalen != sizeof(struct fscrypt_key)) { + res = -EINVAL; + goto out; +diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h +index 9c351bf757b2..3fbc0ff79699 100644 +--- a/fs/ecryptfs/ecryptfs_kernel.h ++++ b/fs/ecryptfs/ecryptfs_kernel.h +@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context { + static inline struct ecryptfs_auth_tok * + ecryptfs_get_encrypted_key_payload_data(struct key *key) + { +- if (key->type == &key_type_encrypted) +- return (struct ecryptfs_auth_tok *) +- (&((struct encrypted_key_payload *)key->payload.data[0])->payload_data); +- else ++ struct encrypted_key_payload *payload; ++ ++ if (key->type != &key_type_encrypted) + return NULL; ++ ++ payload = key->payload.data[0]; ++ if (!payload) ++ return ERR_PTR(-EKEYREVOKED); ++ ++ return (struct ecryptfs_auth_tok *)payload->payload_data; + } + + static inline struct key *ecryptfs_get_encrypted_key(char *sig) +@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok * + ecryptfs_get_key_payload_data(struct key *key) + { + struct ecryptfs_auth_tok *auth_tok; ++ struct user_key_payload *ukp; + + auth_tok = ecryptfs_get_encrypted_key_payload_data(key); +- if (!auth_tok) +- return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data; +- else ++ if (auth_tok) + return auth_tok; ++ ++ ukp = user_key_payload_locked(key); ++ if (!ukp) ++ return ERR_PTR(-EKEYREVOKED); ++ ++ return (struct ecryptfs_auth_tok *)ukp->data; + } + + #define ECRYPTFS_MAX_KEYSET_SIZE 1024 +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index 3cf1546dca82..fa218cd64f74 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version) + * @auth_tok_key: key containing the authentication token + * @auth_tok: authentication token + * +- * Returns zero on valid auth tok; -EINVAL otherwise ++ * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or ++ * -EKEYREVOKED if the key was revoked before we acquired its semaphore. + */ + static int + ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, +@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, + int rc = 0; + + (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); ++ if (IS_ERR(*auth_tok)) { ++ rc = PTR_ERR(*auth_tok); ++ *auth_tok = NULL; ++ goto out; ++ } ++ + if (ecryptfs_verify_version((*auth_tok)->version)) { + printk(KERN_ERR "Data structure version mismatch. Userspace " + "tools must match eCryptfs kernel module with major " +diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c +index 67f940892ef8..5eb2e24ce790 100644 +--- a/fs/fscache/object-list.c ++++ b/fs/fscache/object-list.c +@@ -330,6 +330,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data) + rcu_read_lock(); + + confkey = user_key_payload_rcu(key); ++ if (!confkey) { ++ /* key was revoked */ ++ rcu_read_unlock(); ++ key_put(key); ++ goto no_config; ++ } ++ + buf = confkey->data; + + for (len = confkey->datalen - 1; len >= 0; len--) { +diff --git a/fs/iomap.c b/fs/iomap.c +index 59cc98ad7577..b8a91064abc6 100644 +--- a/fs/iomap.c ++++ b/fs/iomap.c +@@ -993,6 +993,13 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + WARN_ON_ONCE(ret); + ret = 0; + ++ if (iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) && ++ !inode->i_sb->s_dio_done_wq) { ++ ret = sb_init_dio_done_wq(inode->i_sb); ++ if (ret < 0) ++ goto out_free_dio; ++ } ++ + inode_dio_begin(inode); + + blk_start_plug(&plug); +@@ -1015,13 +1022,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + if (ret < 0) + iomap_dio_set_error(dio, ret); + +- if (ret >= 0 && iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) && +- !inode->i_sb->s_dio_done_wq) { +- ret = sb_init_dio_done_wq(inode->i_sb); +- if (ret < 0) +- iomap_dio_set_error(dio, ret); +- } +- + if (!atomic_dec_and_test(&dio->ref)) { + if (!is_sync_kiocb(iocb)) + return -EIOCBQUEUED; +diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c +index b008ff3250eb..df3e600835e8 100644 +--- a/fs/xfs/libxfs/xfs_ag_resv.c ++++ b/fs/xfs/libxfs/xfs_ag_resv.c +@@ -156,7 +156,8 @@ __xfs_ag_resv_free( + trace_xfs_ag_resv_free(pag, type, 0); + + resv = xfs_perag_resv(pag, type); +- pag->pag_mount->m_ag_max_usable += resv->ar_asked; ++ if (pag->pag_agno == 0) ++ pag->pag_mount->m_ag_max_usable += resv->ar_asked; + /* + * AGFL blocks are always considered "free", so whatever + * was reserved at mount time must be given back at umount. +@@ -216,7 +217,14 @@ __xfs_ag_resv_init( + return error; + } + +- mp->m_ag_max_usable -= ask; ++ /* ++ * Reduce the maximum per-AG allocation length by however much we're ++ * trying to reserve for an AG. Since this is a filesystem-wide ++ * counter, we only make the adjustment for AG 0. This assumes that ++ * there aren't any AGs hungrier for per-AG reservation than AG 0. ++ */ ++ if (pag->pag_agno == 0) ++ mp->m_ag_max_usable -= ask; + + resv = xfs_perag_resv(pag, type); + resv->ar_asked = ask; +diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c +index 744dcaec34cc..f965ce832bc0 100644 +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -1584,6 +1584,10 @@ xfs_alloc_ag_vextent_small( + + bp = xfs_btree_get_bufs(args->mp, args->tp, + args->agno, fbno, 0); ++ if (!bp) { ++ error = -EFSCORRUPTED; ++ goto error0; ++ } + xfs_trans_binval(args->tp, bp); + } + args->len = 1; +@@ -2141,6 +2145,10 @@ xfs_alloc_fix_freelist( + if (error) + goto out_agbp_relse; + bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); ++ if (!bp) { ++ error = -EFSCORRUPTED; ++ goto out_agbp_relse; ++ } + xfs_trans_binval(tp, bp); + } + +diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c +index 6f2a5baded76..5c6eb19664f2 100644 +--- a/fs/xfs/libxfs/xfs_bmap.c ++++ b/fs/xfs/libxfs/xfs_bmap.c +@@ -3860,6 +3860,17 @@ xfs_trim_extent( + } + } + ++/* trim extent to within eof */ ++void ++xfs_trim_extent_eof( ++ struct xfs_bmbt_irec *irec, ++ struct xfs_inode *ip) ++ ++{ ++ xfs_trim_extent(irec, 0, XFS_B_TO_FSB(ip->i_mount, ++ i_size_read(VFS_I(ip)))); ++} ++ + /* + * Trim the returned map to the required bounds + */ +diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h +index 851982a5dfbc..502e0d8fb4ff 100644 +--- a/fs/xfs/libxfs/xfs_bmap.h ++++ b/fs/xfs/libxfs/xfs_bmap.h +@@ -208,6 +208,7 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, + + void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, + xfs_filblks_t len); ++void xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *); + int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); + void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); + void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops, +diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h +index 8372e9bcd7b6..71de185735e0 100644 +--- a/fs/xfs/libxfs/xfs_log_format.h ++++ b/fs/xfs/libxfs/xfs_log_format.h +@@ -270,6 +270,7 @@ typedef struct xfs_inode_log_format { + uint32_t ilf_fields; /* flags for fields logged */ + uint16_t ilf_asize; /* size of attr d/ext/root */ + uint16_t ilf_dsize; /* size of data/ext/root */ ++ uint32_t ilf_pad; /* pad for 64 bit boundary */ + uint64_t ilf_ino; /* inode number */ + union { + uint32_t ilfu_rdev; /* rdev value for dev inode*/ +@@ -280,29 +281,17 @@ typedef struct xfs_inode_log_format { + int32_t ilf_boffset; /* off of inode in buffer */ + } xfs_inode_log_format_t; + +-typedef struct xfs_inode_log_format_32 { +- uint16_t ilf_type; /* inode log item type */ +- uint16_t ilf_size; /* size of this item */ +- uint32_t ilf_fields; /* flags for fields logged */ +- uint16_t ilf_asize; /* size of attr d/ext/root */ +- uint16_t ilf_dsize; /* size of data/ext/root */ +- uint64_t ilf_ino; /* inode number */ +- union { +- uint32_t ilfu_rdev; /* rdev value for dev inode*/ +- uuid_t ilfu_uuid; /* mount point value */ +- } ilf_u; +- int64_t ilf_blkno; /* blkno of inode buffer */ +- int32_t ilf_len; /* len of inode buffer */ +- int32_t ilf_boffset; /* off of inode in buffer */ +-} __attribute__((packed)) xfs_inode_log_format_32_t; +- +-typedef struct xfs_inode_log_format_64 { ++/* ++ * Old 32 bit systems will log in this format without the 64 bit ++ * alignment padding. Recovery will detect this and convert it to the ++ * correct format. ++ */ ++struct xfs_inode_log_format_32 { + uint16_t ilf_type; /* inode log item type */ + uint16_t ilf_size; /* size of this item */ + uint32_t ilf_fields; /* flags for fields logged */ + uint16_t ilf_asize; /* size of attr d/ext/root */ + uint16_t ilf_dsize; /* size of data/ext/root */ +- uint32_t ilf_pad; /* pad for 64 bit boundary */ + uint64_t ilf_ino; /* inode number */ + union { + uint32_t ilfu_rdev; /* rdev value for dev inode*/ +@@ -311,7 +300,7 @@ typedef struct xfs_inode_log_format_64 { + int64_t ilf_blkno; /* blkno of inode buffer */ + int32_t ilf_len; /* len of inode buffer */ + int32_t ilf_boffset; /* off of inode in buffer */ +-} xfs_inode_log_format_64_t; ++} __attribute__((packed)); + + + /* +diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c +index 7034e17535de..3354140de07e 100644 +--- a/fs/xfs/xfs_acl.c ++++ b/fs/xfs/xfs_acl.c +@@ -247,6 +247,8 @@ xfs_set_mode(struct inode *inode, umode_t mode) + int + xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + { ++ umode_t mode; ++ bool set_mode = false; + int error = 0; + + if (!acl) +@@ -257,16 +259,24 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + return error; + + if (type == ACL_TYPE_ACCESS) { +- umode_t mode; +- + error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; +- error = xfs_set_mode(inode, mode); +- if (error) +- return error; ++ set_mode = true; + } + + set_acl: +- return __xfs_set_acl(inode, acl, type); ++ error = __xfs_set_acl(inode, acl, type); ++ if (error) ++ return error; ++ ++ /* ++ * We set the mode after successfully updating the ACL xattr because the ++ * xattr update can fail at ENOSPC and we don't want to change the mode ++ * if the ACL update hasn't been applied. ++ */ ++ if (set_mode) ++ error = xfs_set_mode(inode, mode); ++ ++ return error; + } +diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c +index f9efd67f6fa1..41b767ecfe50 100644 +--- a/fs/xfs/xfs_aops.c ++++ b/fs/xfs/xfs_aops.c +@@ -330,7 +330,8 @@ xfs_end_io( + error = xfs_reflink_end_cow(ip, offset, size); + break; + case XFS_IO_UNWRITTEN: +- error = xfs_iomap_write_unwritten(ip, offset, size); ++ /* writeback should never update isize */ ++ error = xfs_iomap_write_unwritten(ip, offset, size, false); + break; + default: + ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans); +@@ -432,6 +433,19 @@ xfs_imap_valid( + { + offset >>= inode->i_blkbits; + ++ /* ++ * We have to make sure the cached mapping is within EOF to protect ++ * against eofblocks trimming on file release leaving us with a stale ++ * mapping. Otherwise, a page for a subsequent file extending buffered ++ * write could get picked up by this writeback cycle and written to the ++ * wrong blocks. ++ * ++ * Note that what we really want here is a generic mapping invalidation ++ * mechanism to protect us from arbitrary extent modifying contexts, not ++ * just eofblocks. ++ */ ++ xfs_trim_extent_eof(imap, XFS_I(inode)); ++ + return offset >= imap->br_startoff && + offset < imap->br_startoff + imap->br_blockcount; + } +@@ -721,6 +735,14 @@ xfs_vm_invalidatepage( + { + trace_xfs_invalidatepage(page->mapping->host, page, offset, + length); ++ ++ /* ++ * If we are invalidating the entire page, clear the dirty state from it ++ * so that we can check for attempts to release dirty cached pages in ++ * xfs_vm_releasepage(). ++ */ ++ if (offset == 0 && length >= PAGE_SIZE) ++ cancel_dirty_page(page); + block_invalidatepage(page, offset, length); + } + +@@ -1176,25 +1198,27 @@ xfs_vm_releasepage( + * mm accommodates an old ext3 case where clean pages might not have had + * the dirty bit cleared. Thus, it can send actual dirty pages to + * ->releasepage() via shrink_active_list(). Conversely, +- * block_invalidatepage() can send pages that are still marked dirty +- * but otherwise have invalidated buffers. ++ * block_invalidatepage() can send pages that are still marked dirty but ++ * otherwise have invalidated buffers. + * + * We want to release the latter to avoid unnecessary buildup of the +- * LRU, skip the former and warn if we've left any lingering +- * delalloc/unwritten buffers on clean pages. Skip pages with delalloc +- * or unwritten buffers and warn if the page is not dirty. Otherwise +- * try to release the buffers. ++ * LRU, so xfs_vm_invalidatepage() clears the page dirty flag on pages ++ * that are entirely invalidated and need to be released. Hence the ++ * only time we should get dirty pages here is through ++ * shrink_active_list() and so we can simply skip those now. ++ * ++ * warn if we've left any lingering delalloc/unwritten buffers on clean ++ * or invalidated pages we are about to release. + */ ++ if (PageDirty(page)) ++ return 0; ++ + xfs_count_page_state(page, &delalloc, &unwritten); + +- if (delalloc) { +- WARN_ON_ONCE(!PageDirty(page)); ++ if (WARN_ON_ONCE(delalloc)) + return 0; +- } +- if (unwritten) { +- WARN_ON_ONCE(!PageDirty(page)); ++ if (WARN_ON_ONCE(unwritten)) + return 0; +- } + + return try_to_free_buffers(page); + } +diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c +index be0b79d8900f..c6643004e583 100644 +--- a/fs/xfs/xfs_attr_inactive.c ++++ b/fs/xfs/xfs_attr_inactive.c +@@ -302,6 +302,8 @@ xfs_attr3_node_inactive( + &bp, XFS_ATTR_FORK); + if (error) + return error; ++ node = bp->b_addr; ++ btree = dp->d_ops->node_tree_p(node); + child_fsb = be32_to_cpu(btree[i + 1].before); + xfs_trans_brelse(*trans, bp); + } +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index 3e9b7a4fb8fd..799c69a72f2c 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -84,6 +84,7 @@ xfs_zero_extent( + GFP_NOFS, 0); + } + ++#ifdef CONFIG_XFS_RT + int + xfs_bmap_rtalloc( + struct xfs_bmalloca *ap) /* bmap alloc argument struct */ +@@ -190,6 +191,7 @@ xfs_bmap_rtalloc( + } + return 0; + } ++#endif /* CONFIG_XFS_RT */ + + /* + * Check if the endoff is outside the last extent. If so the caller will grow +@@ -1459,7 +1461,19 @@ xfs_shift_file_space( + return error; + + /* +- * The extent shiting code works on extent granularity. So, if ++ * Clean out anything hanging around in the cow fork now that ++ * we've flushed all the dirty data out to disk to avoid having ++ * CoW extents at the wrong offsets. ++ */ ++ if (xfs_is_reflink_inode(ip)) { ++ error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF, ++ true); ++ if (error) ++ return error; ++ } ++ ++ /* ++ * The extent shifting code works on extent granularity. So, if + * stop_fsb is not the starting block of extent, we need to split + * the extent at stop_fsb. + */ +@@ -2109,11 +2123,31 @@ xfs_swap_extents( + ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; + tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK; ++ } ++ ++ /* Swap the cow forks. */ ++ if (xfs_sb_version_hasreflink(&mp->m_sb)) { ++ xfs_extnum_t extnum; ++ ++ ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); ++ ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); ++ ++ extnum = ip->i_cnextents; ++ ip->i_cnextents = tip->i_cnextents; ++ tip->i_cnextents = extnum; ++ + cowfp = ip->i_cowfp; + ip->i_cowfp = tip->i_cowfp; + tip->i_cowfp = cowfp; +- xfs_inode_set_cowblocks_tag(ip); +- xfs_inode_set_cowblocks_tag(tip); ++ ++ if (ip->i_cowfp && ip->i_cnextents) ++ xfs_inode_set_cowblocks_tag(ip); ++ else ++ xfs_inode_clear_cowblocks_tag(ip); ++ if (tip->i_cowfp && tip->i_cnextents) ++ xfs_inode_set_cowblocks_tag(tip); ++ else ++ xfs_inode_clear_cowblocks_tag(tip); + } + + xfs_trans_log_inode(tp, ip, src_log_flags); +diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h +index 0cede1043571..fb8d0c7d1db8 100644 +--- a/fs/xfs/xfs_bmap_util.h ++++ b/fs/xfs/xfs_bmap_util.h +@@ -28,7 +28,20 @@ struct xfs_mount; + struct xfs_trans; + struct xfs_bmalloca; + ++#ifdef CONFIG_XFS_RT + int xfs_bmap_rtalloc(struct xfs_bmalloca *ap); ++#else /* !CONFIG_XFS_RT */ ++/* ++ * Attempts to allocate RT extents when RT is disable indicates corruption and ++ * should trigger a shutdown. ++ */ ++static inline int ++xfs_bmap_rtalloc(struct xfs_bmalloca *ap) ++{ ++ return -EFSCORRUPTED; ++} ++#endif /* CONFIG_XFS_RT */ ++ + int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff, + int whichfork, int *eof); + int xfs_bmap_punch_delalloc_range(struct xfs_inode *ip, +diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c +index 2f4feb959bfb..028e50a36f95 100644 +--- a/fs/xfs/xfs_error.c ++++ b/fs/xfs/xfs_error.c +@@ -344,7 +344,7 @@ xfs_verifier_error( + { + struct xfs_mount *mp = bp->b_target->bt_mount; + +- xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", ++ xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx", + bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", + __return_address, bp->b_ops->name, bp->b_bn); + +diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c +index c4893e226fd8..ad5100ce8c44 100644 +--- a/fs/xfs/xfs_file.c ++++ b/fs/xfs/xfs_file.c +@@ -58,7 +58,7 @@ xfs_zero_range( + xfs_off_t count, + bool *did_zero) + { +- return iomap_zero_range(VFS_I(ip), pos, count, NULL, &xfs_iomap_ops); ++ return iomap_zero_range(VFS_I(ip), pos, count, did_zero, &xfs_iomap_ops); + } + + int +@@ -432,7 +432,6 @@ xfs_dio_write_end_io( + struct inode *inode = file_inode(iocb->ki_filp); + struct xfs_inode *ip = XFS_I(inode); + loff_t offset = iocb->ki_pos; +- bool update_size = false; + int error = 0; + + trace_xfs_end_io_direct_write(ip, offset, size); +@@ -443,6 +442,21 @@ xfs_dio_write_end_io( + if (size <= 0) + return size; + ++ if (flags & IOMAP_DIO_COW) { ++ error = xfs_reflink_end_cow(ip, offset, size); ++ if (error) ++ return error; ++ } ++ ++ /* ++ * Unwritten conversion updates the in-core isize after extent ++ * conversion but before updating the on-disk size. Updating isize any ++ * earlier allows a racing dio read to find unwritten extents before ++ * they are converted. ++ */ ++ if (flags & IOMAP_DIO_UNWRITTEN) ++ return xfs_iomap_write_unwritten(ip, offset, size, true); ++ + /* + * We need to update the in-core inode size here so that we don't end up + * with the on-disk inode size being outside the in-core inode size. We +@@ -457,20 +471,11 @@ xfs_dio_write_end_io( + spin_lock(&ip->i_flags_lock); + if (offset + size > i_size_read(inode)) { + i_size_write(inode, offset + size); +- update_size = true; +- } +- spin_unlock(&ip->i_flags_lock); +- +- if (flags & IOMAP_DIO_COW) { +- error = xfs_reflink_end_cow(ip, offset, size); +- if (error) +- return error; +- } +- +- if (flags & IOMAP_DIO_UNWRITTEN) +- error = xfs_iomap_write_unwritten(ip, offset, size); +- else if (update_size) ++ spin_unlock(&ip->i_flags_lock); + error = xfs_setfilesize(ip, offset, size); ++ } else { ++ spin_unlock(&ip->i_flags_lock); ++ } + + return error; + } +diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c +index 814ed729881d..43cfc07996a4 100644 +--- a/fs/xfs/xfs_fsmap.c ++++ b/fs/xfs/xfs_fsmap.c +@@ -367,29 +367,6 @@ xfs_getfsmap_datadev_helper( + return xfs_getfsmap_helper(cur->bc_tp, info, rec, rec_daddr); + } + +-/* Transform a rtbitmap "record" into a fsmap */ +-STATIC int +-xfs_getfsmap_rtdev_rtbitmap_helper( +- struct xfs_trans *tp, +- struct xfs_rtalloc_rec *rec, +- void *priv) +-{ +- struct xfs_mount *mp = tp->t_mountp; +- struct xfs_getfsmap_info *info = priv; +- struct xfs_rmap_irec irec; +- xfs_daddr_t rec_daddr; +- +- rec_daddr = XFS_FSB_TO_BB(mp, rec->ar_startblock); +- +- irec.rm_startblock = rec->ar_startblock; +- irec.rm_blockcount = rec->ar_blockcount; +- irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ +- irec.rm_offset = 0; +- irec.rm_flags = 0; +- +- return xfs_getfsmap_helper(tp, info, &irec, rec_daddr); +-} +- + /* Transform a bnobt irec into a fsmap */ + STATIC int + xfs_getfsmap_datadev_bnobt_helper( +@@ -475,6 +452,30 @@ xfs_getfsmap_logdev( + return xfs_getfsmap_helper(tp, info, &rmap, 0); + } + ++#ifdef CONFIG_XFS_RT ++/* Transform a rtbitmap "record" into a fsmap */ ++STATIC int ++xfs_getfsmap_rtdev_rtbitmap_helper( ++ struct xfs_trans *tp, ++ struct xfs_rtalloc_rec *rec, ++ void *priv) ++{ ++ struct xfs_mount *mp = tp->t_mountp; ++ struct xfs_getfsmap_info *info = priv; ++ struct xfs_rmap_irec irec; ++ xfs_daddr_t rec_daddr; ++ ++ rec_daddr = XFS_FSB_TO_BB(mp, rec->ar_startblock); ++ ++ irec.rm_startblock = rec->ar_startblock; ++ irec.rm_blockcount = rec->ar_blockcount; ++ irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ ++ irec.rm_offset = 0; ++ irec.rm_flags = 0; ++ ++ return xfs_getfsmap_helper(tp, info, &irec, rec_daddr); ++} ++ + /* Execute a getfsmap query against the realtime device. */ + STATIC int + __xfs_getfsmap_rtdev( +@@ -561,6 +562,7 @@ xfs_getfsmap_rtdev_rtbitmap( + return __xfs_getfsmap_rtdev(tp, keys, xfs_getfsmap_rtdev_rtbitmap_query, + info); + } ++#endif /* CONFIG_XFS_RT */ + + /* Execute a getfsmap query against the regular data device. */ + STATIC int +@@ -795,7 +797,15 @@ xfs_getfsmap_check_keys( + return false; + } + ++/* ++ * There are only two devices if we didn't configure RT devices at build time. ++ */ ++#ifdef CONFIG_XFS_RT + #define XFS_GETFSMAP_DEVS 3 ++#else ++#define XFS_GETFSMAP_DEVS 2 ++#endif /* CONFIG_XFS_RT */ ++ + /* + * Get filesystem's extents as described in head, and format for + * output. Calls formatter to fill the user's buffer until all +@@ -853,10 +863,12 @@ xfs_getfsmap( + handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev); + handlers[1].fn = xfs_getfsmap_logdev; + } ++#ifdef CONFIG_XFS_RT + if (mp->m_rtdev_targp) { + handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev); + handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap; + } ++#endif /* CONFIG_XFS_RT */ + + xfs_sort(handlers, XFS_GETFSMAP_DEVS, sizeof(struct xfs_getfsmap_dev), + xfs_getfsmap_dev_compare); +diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c +index 97045e8dfed5..cd2e5b122b01 100644 +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -1623,10 +1623,12 @@ xfs_itruncate_extents( + goto out; + + /* +- * Clear the reflink flag if we truncated everything. ++ * Clear the reflink flag if there are no data fork blocks and ++ * there are no extents staged in the cow fork. + */ +- if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) { +- ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; ++ if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) { ++ if (ip->i_d.di_nblocks == 0) ++ ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + xfs_inode_clear_cowblocks_tag(ip); + } + +diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c +index 6d0f74ec31e8..9bbc2d7cc8cb 100644 +--- a/fs/xfs/xfs_inode_item.c ++++ b/fs/xfs/xfs_inode_item.c +@@ -364,6 +364,9 @@ xfs_inode_to_log_dinode( + to->di_dmstate = from->di_dmstate; + to->di_flags = from->di_flags; + ++ /* log a dummy value to ensure log structure is fully initialised */ ++ to->di_next_unlinked = NULLAGINO; ++ + if (from->di_version == 3) { + to->di_changecount = inode->i_version; + to->di_crtime.t_sec = from->di_crtime.t_sec; +@@ -404,6 +407,11 @@ xfs_inode_item_format_core( + * the second with the on-disk inode structure, and a possible third and/or + * fourth with the inode data/extents/b-tree root and inode attributes + * data/extents/b-tree root. ++ * ++ * Note: Always use the 64 bit inode log format structure so we don't ++ * leave an uninitialised hole in the format item on 64 bit systems. Log ++ * recovery on 32 bit systems handles this just fine, so there's no reason ++ * for not using an initialising the properly padded structure all the time. + */ + STATIC void + xfs_inode_item_format( +@@ -412,8 +420,8 @@ xfs_inode_item_format( + { + struct xfs_inode_log_item *iip = INODE_ITEM(lip); + struct xfs_inode *ip = iip->ili_inode; +- struct xfs_inode_log_format *ilf; + struct xfs_log_iovec *vecp = NULL; ++ struct xfs_inode_log_format *ilf; + + ASSERT(ip->i_d.di_version > 1); + +@@ -425,7 +433,17 @@ xfs_inode_item_format( + ilf->ilf_boffset = ip->i_imap.im_boffset; + ilf->ilf_fields = XFS_ILOG_CORE; + ilf->ilf_size = 2; /* format + core */ +- xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); ++ ++ /* ++ * make sure we don't leak uninitialised data into the log in the case ++ * when we don't log every field in the inode. ++ */ ++ ilf->ilf_dsize = 0; ++ ilf->ilf_asize = 0; ++ ilf->ilf_pad = 0; ++ uuid_copy(&ilf->ilf_u.ilfu_uuid, &uuid_null); ++ ++ xlog_finish_iovec(lv, vecp, sizeof(*ilf)); + + xfs_inode_item_format_core(ip, lv, &vecp); + xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); +@@ -745,7 +763,7 @@ xfs_iflush_done( + */ + iip = INODE_ITEM(blip); + if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) || +- lip->li_flags & XFS_LI_FAILED) ++ (blip->li_flags & XFS_LI_FAILED)) + need_ail++; + + blip = next; +@@ -855,44 +873,29 @@ xfs_istale_done( + } + + /* +- * convert an xfs_inode_log_format struct from either 32 or 64 bit versions +- * (which can have different field alignments) to the native version ++ * convert an xfs_inode_log_format struct from the old 32 bit version ++ * (which can have different field alignments) to the native 64 bit version + */ + int + xfs_inode_item_format_convert( +- xfs_log_iovec_t *buf, +- xfs_inode_log_format_t *in_f) ++ struct xfs_log_iovec *buf, ++ struct xfs_inode_log_format *in_f) + { +- if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) { +- xfs_inode_log_format_32_t *in_f32 = buf->i_addr; +- +- in_f->ilf_type = in_f32->ilf_type; +- in_f->ilf_size = in_f32->ilf_size; +- in_f->ilf_fields = in_f32->ilf_fields; +- in_f->ilf_asize = in_f32->ilf_asize; +- in_f->ilf_dsize = in_f32->ilf_dsize; +- in_f->ilf_ino = in_f32->ilf_ino; +- /* copy biggest field of ilf_u */ +- uuid_copy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid); +- in_f->ilf_blkno = in_f32->ilf_blkno; +- in_f->ilf_len = in_f32->ilf_len; +- in_f->ilf_boffset = in_f32->ilf_boffset; +- return 0; +- } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){ +- xfs_inode_log_format_64_t *in_f64 = buf->i_addr; +- +- in_f->ilf_type = in_f64->ilf_type; +- in_f->ilf_size = in_f64->ilf_size; +- in_f->ilf_fields = in_f64->ilf_fields; +- in_f->ilf_asize = in_f64->ilf_asize; +- in_f->ilf_dsize = in_f64->ilf_dsize; +- in_f->ilf_ino = in_f64->ilf_ino; +- /* copy biggest field of ilf_u */ +- uuid_copy(&in_f->ilf_u.ilfu_uuid, &in_f64->ilf_u.ilfu_uuid); +- in_f->ilf_blkno = in_f64->ilf_blkno; +- in_f->ilf_len = in_f64->ilf_len; +- in_f->ilf_boffset = in_f64->ilf_boffset; +- return 0; +- } +- return -EFSCORRUPTED; ++ struct xfs_inode_log_format_32 *in_f32 = buf->i_addr; ++ ++ if (buf->i_len != sizeof(*in_f32)) ++ return -EFSCORRUPTED; ++ ++ in_f->ilf_type = in_f32->ilf_type; ++ in_f->ilf_size = in_f32->ilf_size; ++ in_f->ilf_fields = in_f32->ilf_fields; ++ in_f->ilf_asize = in_f32->ilf_asize; ++ in_f->ilf_dsize = in_f32->ilf_dsize; ++ in_f->ilf_ino = in_f32->ilf_ino; ++ /* copy biggest field of ilf_u */ ++ uuid_copy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid); ++ in_f->ilf_blkno = in_f32->ilf_blkno; ++ in_f->ilf_len = in_f32->ilf_len; ++ in_f->ilf_boffset = in_f32->ilf_boffset; ++ return 0; + } +diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c +index 813394c62849..2cef389d8955 100644 +--- a/fs/xfs/xfs_iomap.c ++++ b/fs/xfs/xfs_iomap.c +@@ -829,7 +829,8 @@ int + xfs_iomap_write_unwritten( + xfs_inode_t *ip, + xfs_off_t offset, +- xfs_off_t count) ++ xfs_off_t count, ++ bool update_isize) + { + xfs_mount_t *mp = ip->i_mount; + xfs_fileoff_t offset_fsb; +@@ -840,6 +841,7 @@ xfs_iomap_write_unwritten( + xfs_trans_t *tp; + xfs_bmbt_irec_t imap; + struct xfs_defer_ops dfops; ++ struct inode *inode = VFS_I(ip); + xfs_fsize_t i_size; + uint resblks; + int error; +@@ -899,7 +901,8 @@ xfs_iomap_write_unwritten( + i_size = XFS_FSB_TO_B(mp, offset_fsb + count_fsb); + if (i_size > offset + count) + i_size = offset + count; +- ++ if (update_isize && i_size > i_size_read(inode)) ++ i_size_write(inode, i_size); + i_size = xfs_new_eof(ip, i_size); + if (i_size) { + ip->i_d.di_size = i_size; +diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h +index 00db3ecea084..ee535065c5d0 100644 +--- a/fs/xfs/xfs_iomap.h ++++ b/fs/xfs/xfs_iomap.h +@@ -27,7 +27,7 @@ int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, + struct xfs_bmbt_irec *, int); + int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t, + struct xfs_bmbt_irec *); +-int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t); ++int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); + + void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, + struct xfs_bmbt_irec *); +diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h +index 0c381d71b242..0492436a053f 100644 +--- a/fs/xfs/xfs_ondisk.h ++++ b/fs/xfs/xfs_ondisk.h +@@ -134,7 +134,7 @@ xfs_check_ondisk_structs(void) + XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log, 28); + XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32, 52); +- XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64, 56); ++ XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format, 56); + XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat, 20); + XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header, 16); + } +diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c +index 2f2dc3c09ad0..4246876df7b7 100644 +--- a/fs/xfs/xfs_pnfs.c ++++ b/fs/xfs/xfs_pnfs.c +@@ -274,7 +274,7 @@ xfs_fs_commit_blocks( + (end - 1) >> PAGE_SHIFT); + WARN_ON_ONCE(error); + +- error = xfs_iomap_write_unwritten(ip, start, length); ++ error = xfs_iomap_write_unwritten(ip, start, length, false); + if (error) + goto out_drop_iolock; + } +diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c +index f45fbf0db9bb..8c8390a7f121 100644 +--- a/fs/xfs/xfs_reflink.c ++++ b/fs/xfs/xfs_reflink.c +@@ -735,7 +735,13 @@ xfs_reflink_end_cow( + /* If there is a hole at end_fsb - 1 go to the previous extent */ + if (!xfs_iext_lookup_extent(ip, ifp, end_fsb - 1, &idx, &got) || + got.br_startoff > end_fsb) { +- ASSERT(idx > 0); ++ /* ++ * In case of racing, overlapping AIO writes no COW extents ++ * might be left by the time I/O completes for the loser of ++ * the race. In that case we are done. ++ */ ++ if (idx <= 0) ++ goto out_cancel; + xfs_iext_get_extent(ifp, --idx, &got); + } + +@@ -807,6 +813,7 @@ xfs_reflink_end_cow( + + out_defer: + xfs_defer_cancel(&dfops); ++out_cancel: + xfs_trans_cancel(tp); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + out: +diff --git a/include/linux/key.h b/include/linux/key.h +index e315e16b6ff8..8a15cabe928d 100644 +--- a/include/linux/key.h ++++ b/include/linux/key.h +@@ -138,6 +138,11 @@ struct key_restriction { + struct key_type *keytype; + }; + ++enum key_state { ++ KEY_IS_UNINSTANTIATED, ++ KEY_IS_POSITIVE, /* Positively instantiated */ ++}; ++ + /*****************************************************************************/ + /* + * authentication token / access credential / keyring +@@ -169,6 +174,7 @@ struct key { + * - may not match RCU dereferenced payload + * - payload should contain own length + */ ++ short state; /* Key state (+) or rejection error (-) */ + + #ifdef KEY_DEBUGGING + unsigned magic; +@@ -176,18 +182,16 @@ struct key { + #endif + + unsigned long flags; /* status flags (change with bitops) */ +-#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */ +-#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */ +-#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */ +-#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ +-#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ +-#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ +-#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ +-#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ +-#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ +-#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ +-#define KEY_FLAG_KEEP 10 /* set if key should not be removed */ +-#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */ ++#define KEY_FLAG_DEAD 0 /* set if key type has been deleted */ ++#define KEY_FLAG_REVOKED 1 /* set if key had been revoked */ ++#define KEY_FLAG_IN_QUOTA 2 /* set if key consumes quota */ ++#define KEY_FLAG_USER_CONSTRUCT 3 /* set if key is being constructed in userspace */ ++#define KEY_FLAG_ROOT_CAN_CLEAR 4 /* set if key can be cleared by root without permission */ ++#define KEY_FLAG_INVALIDATED 5 /* set if key has been invalidated */ ++#define KEY_FLAG_BUILTIN 6 /* set if key is built in to the kernel */ ++#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */ ++#define KEY_FLAG_KEEP 8 /* set if key should not be removed */ ++#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */ + + /* the key type and key description string + * - the desc is used to match a key against search criteria +@@ -213,7 +217,6 @@ struct key { + struct list_head name_link; + struct assoc_array keys; + }; +- int reject_error; + }; + + /* This is set on a keyring to restrict the addition of a link to a key +@@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *, unsigned); + #define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */ + #define KEY_NEED_ALL 0x3f /* All the above permissions */ + ++static inline short key_read_state(const struct key *key) ++{ ++ /* Barrier versus mark_key_instantiated(). */ ++ return smp_load_acquire(&key->state); ++} ++ + /** +- * key_is_instantiated - Determine if a key has been positively instantiated ++ * key_is_positive - Determine if a key has been positively instantiated + * @key: The key to check. + * + * Return true if the specified key has been positively instantiated, false + * otherwise. + */ +-static inline bool key_is_instantiated(const struct key *key) ++static inline bool key_is_positive(const struct key *key) ++{ ++ return key_read_state(key) == KEY_IS_POSITIVE; ++} ++ ++static inline bool key_is_negative(const struct key *key) + { +- return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && +- !test_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ return key_read_state(key) < 0; + } + + #define dereference_key_rcu(KEY) \ +diff --git a/include/linux/mbus.h b/include/linux/mbus.h +index 0d3f14fd2621..4773145246ed 100644 +--- a/include/linux/mbus.h ++++ b/include/linux/mbus.h +@@ -31,8 +31,8 @@ struct mbus_dram_target_info + struct mbus_dram_window { + u8 cs_index; + u8 mbus_attr; +- u32 base; +- u32 size; ++ u64 base; ++ u64 size; + } cs[4]; + }; + +diff --git a/include/sound/control.h b/include/sound/control.h +index bd7246de58e7..a1f1152bc687 100644 +--- a/include/sound/control.h ++++ b/include/sound/control.h +@@ -248,6 +248,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl, + void *private_data); + void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); + #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true) ++int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, ++ int (*func)(struct snd_kcontrol *, void *), ++ void *arg); + + /* + * Helper functions for jack-detection controls +diff --git a/lib/digsig.c b/lib/digsig.c +index 03d7c63837ae..6ba6fcd92dd1 100644 +--- a/lib/digsig.c ++++ b/lib/digsig.c +@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key, + down_read(&key->sem); + ukp = user_key_payload_locked(key); + ++ if (!ukp) { ++ /* key was revoked before we acquired its semaphore */ ++ err = -EKEYREVOKED; ++ goto err1; ++ } ++ + if (ukp->datalen < sizeof(*pkh)) + goto err1; + +diff --git a/net/can/af_can.c b/net/can/af_can.c +index 88edac0f3e36..df186cdcc2b4 100644 +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -875,9 +875,14 @@ static int can_pernet_init(struct net *net) + spin_lock_init(&net->can.can_rcvlists_lock); + net->can.can_rx_alldev_list = + kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); +- ++ if (!net->can.can_rx_alldev_list) ++ goto out; + net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); ++ if (!net->can.can_stats) ++ goto out_free_alldev_list; + net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); ++ if (!net->can.can_pstats) ++ goto out_free_can_stats; + + if (IS_ENABLED(CONFIG_PROC_FS)) { + /* the statistics are updated every second (timer triggered) */ +@@ -892,6 +897,13 @@ static int can_pernet_init(struct net *net) + } + + return 0; ++ ++ out_free_can_stats: ++ kfree(net->can.can_stats); ++ out_free_alldev_list: ++ kfree(net->can.can_rx_alldev_list); ++ out: ++ return -ENOMEM; + } + + static void can_pernet_exit(struct net *net) +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index 8737412c7b27..e1d4d898a007 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data) + static void dns_resolver_describe(const struct key *key, struct seq_file *m) + { + seq_puts(m, key->description); +- if (key_is_instantiated(key)) { ++ if (key_is_positive(key)) { + int err = PTR_ERR(key->payload.data[dns_key_error]); + + if (err) +diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c +index bc7fcf010a5b..446beb7ac48d 100644 +--- a/samples/trace_events/trace-events-sample.c ++++ b/samples/trace_events/trace-events-sample.c +@@ -78,29 +78,37 @@ static int simple_thread_fn(void *arg) + } + + static DEFINE_MUTEX(thread_mutex); ++static bool simple_thread_cnt; + + int foo_bar_reg(void) + { ++ mutex_lock(&thread_mutex); ++ if (simple_thread_cnt++) ++ goto out; ++ + pr_info("Starting thread for foo_bar_fn\n"); + /* + * We shouldn't be able to start a trace when the module is + * unloading (there's other locks to prevent that). But + * for consistency sake, we still take the thread_mutex. + */ +- mutex_lock(&thread_mutex); + simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn"); ++ out: + mutex_unlock(&thread_mutex); + return 0; + } + + void foo_bar_unreg(void) + { +- pr_info("Killing thread for foo_bar_fn\n"); +- /* protect against module unloading */ + mutex_lock(&thread_mutex); ++ if (--simple_thread_cnt) ++ goto out; ++ ++ pr_info("Killing thread for foo_bar_fn\n"); + if (simple_tsk_fn) + kthread_stop(simple_tsk_fn); + simple_tsk_fn = NULL; ++ out: + mutex_unlock(&thread_mutex); + } + +diff --git a/security/keys/big_key.c b/security/keys/big_key.c +index 9c3b16ee1768..ad39a0bdf846 100644 +--- a/security/keys/big_key.c ++++ b/security/keys/big_key.c +@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key) + + /* clear the quota */ + key_payload_reserve(key, 0); +- if (key_is_instantiated(key) && ++ if (key_is_positive(key) && + (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) + vfs_truncate(path, 0); + } +@@ -279,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m) + + seq_puts(m, key->description); + +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, ": %zu [%s]", + datalen, + datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 69855ba0d3b3..d92cbf9687c3 100644 +--- a/security/keys/encrypted-keys/encrypted.c ++++ b/security/keys/encrypted-keys/encrypted.c +@@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k + + down_read(&ukey->sem); + upayload = user_key_payload_locked(ukey); ++ if (!upayload) { ++ /* key was revoked before we acquired its semaphore */ ++ up_read(&ukey->sem); ++ key_put(ukey); ++ ukey = ERR_PTR(-EKEYREVOKED); ++ goto error; ++ } + *master_key = upayload->data; + *master_keylen = upayload->datalen; + error: +@@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) + size_t datalen = prep->datalen; + int ret = 0; + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_negative(key)) + return -ENOKEY; + if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; +diff --git a/security/keys/gc.c b/security/keys/gc.c +index 87cb260e4890..f01d48cb3de1 100644 +--- a/security/keys/gc.c ++++ b/security/keys/gc.c +@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) + while (!list_empty(keys)) { + struct key *key = + list_entry(keys->next, struct key, graveyard_link); ++ short state = key->state; ++ + list_del(&key->graveyard_link); + + kdebug("- %u", key->serial); + key_check(key); + + /* Throw away the key data if the key is instantiated */ +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && +- !test_bit(KEY_FLAG_NEGATIVE, &key->flags) && +- key->type->destroy) ++ if (state == KEY_IS_POSITIVE && key->type->destroy) + key->type->destroy(key); + + security_key_free(key); +@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys) + } + + atomic_dec(&key->user->nkeys); +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) ++ if (state != KEY_IS_UNINSTANTIATED) + atomic_dec(&key->user->nikeys); + + key_user_put(key->user); +diff --git a/security/keys/key.c b/security/keys/key.c +index e5c0896c3a8f..3186c769f300 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -401,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen) + } + EXPORT_SYMBOL(key_payload_reserve); + ++/* ++ * Change the key state to being instantiated. ++ */ ++static void mark_key_instantiated(struct key *key, int reject_error) ++{ ++ /* Commit the payload before setting the state; barrier versus ++ * key_read_state(). ++ */ ++ smp_store_release(&key->state, ++ (reject_error < 0) ? reject_error : KEY_IS_POSITIVE); ++} ++ + /* + * Instantiate a key and link it into the target keyring atomically. Must be + * called with the target keyring's semaphore writelocked. The target key's +@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key, + mutex_lock(&key_construction_mutex); + + /* can't instantiate twice */ +- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state == KEY_IS_UNINSTANTIATED) { + /* instantiate the key */ + ret = key->type->instantiate(key, prep); + + if (ret == 0) { + /* mark the key as being instantiated */ + atomic_inc(&key->user->nikeys); +- set_bit(KEY_FLAG_INSTANTIATED, &key->flags); ++ mark_key_instantiated(key, 0); + + if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) + awaken = 1; +@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key, + mutex_lock(&key_construction_mutex); + + /* can't instantiate twice */ +- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state == KEY_IS_UNINSTANTIATED) { + /* mark the key as being negatively instantiated */ + atomic_inc(&key->user->nikeys); +- key->reject_error = -error; +- smp_wmb(); +- set_bit(KEY_FLAG_NEGATIVE, &key->flags); +- set_bit(KEY_FLAG_INSTANTIATED, &key->flags); ++ mark_key_instantiated(key, -error); + now = current_kernel_time(); + key->expiry = now.tv_sec + timeout; + key_schedule_gc(key->expiry + key_gc_delay); +@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, + + ret = key->type->update(key, prep); + if (ret == 0) +- /* updating a negative key instantiates it */ +- clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ /* Updating a negative key positively instantiates it */ ++ mark_key_instantiated(key, 0); + + up_write(&key->sem); + +@@ -936,6 +945,16 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + */ + __key_link_end(keyring, &index_key, edit); + ++ key = key_ref_to_ptr(key_ref); ++ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) { ++ ret = wait_for_key_construction(key, true); ++ if (ret < 0) { ++ key_ref_put(key_ref); ++ key_ref = ERR_PTR(ret); ++ goto error_free_prep; ++ } ++ } ++ + key_ref = __key_update(key_ref, &prep); + goto error_free_prep; + } +@@ -986,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) + + ret = key->type->update(key, &prep); + if (ret == 0) +- /* updating a negative key instantiates it */ +- clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ /* Updating a negative key positively instantiates it */ ++ mark_key_instantiated(key, 0); + + up_write(&key->sem); + +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index 6a82090c7fc1..2eb624c0aefc 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) + + key = key_ref_to_ptr(key_ref); + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { +- ret = -ENOKEY; +- goto error2; +- } ++ ret = key_read_state(key); ++ if (ret < 0) ++ goto error2; /* Negatively instantiated */ + + /* see if we can read it directly */ + ret = key_permission(key_ref, KEY_NEED_READ); +@@ -901,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) + atomic_dec(&key->user->nkeys); + atomic_inc(&newowner->nkeys); + +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state != KEY_IS_UNINSTANTIATED) { + atomic_dec(&key->user->nikeys); + atomic_inc(&newowner->nikeys); + } +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index 4fa82a8a9c0e..06173b091a74 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) + else + seq_puts(m, "[anon]"); + +- if (key_is_instantiated(keyring)) { ++ if (key_is_positive(keyring)) { + if (keyring->keys.nr_leaves_on_tree != 0) + seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree); + else +@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) + { + struct keyring_search_context *ctx = iterator_data; + const struct key *key = keyring_ptr_to_key(object); +- unsigned long kflags = key->flags; ++ unsigned long kflags = READ_ONCE(key->flags); ++ short state = READ_ONCE(key->state); + + kenter("{%d}", key->serial); + +@@ -597,9 +598,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) + + if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { + /* we set a different error code if we pass a negative key */ +- if (kflags & (1 << KEY_FLAG_NEGATIVE)) { +- smp_rmb(); +- ctx->result = ERR_PTR(key->reject_error); ++ if (state < 0) { ++ ctx->result = ERR_PTR(state); + kleave(" = %d [neg]", ctx->skipped_ret); + goto skipped; + } +diff --git a/security/keys/proc.c b/security/keys/proc.c +index bf08d02b6646..e6aa1b257578 100644 +--- a/security/keys/proc.c ++++ b/security/keys/proc.c +@@ -182,6 +182,7 @@ static int proc_keys_show(struct seq_file *m, void *v) + unsigned long timo; + key_ref_t key_ref, skey_ref; + char xbuf[16]; ++ short state; + int rc; + + struct keyring_search_context ctx = { +@@ -240,17 +241,19 @@ static int proc_keys_show(struct seq_file *m, void *v) + sprintf(xbuf, "%luw", timo / (60*60*24*7)); + } + ++ state = key_read_state(key); ++ + #define showflag(KEY, LETTER, FLAG) \ + (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') + + seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", + key->serial, +- showflag(key, 'I', KEY_FLAG_INSTANTIATED), ++ state != KEY_IS_UNINSTANTIATED ? 'I' : '-', + showflag(key, 'R', KEY_FLAG_REVOKED), + showflag(key, 'D', KEY_FLAG_DEAD), + showflag(key, 'Q', KEY_FLAG_IN_QUOTA), + showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), +- showflag(key, 'N', KEY_FLAG_NEGATIVE), ++ state < 0 ? 'N' : '-', + showflag(key, 'i', KEY_FLAG_INVALIDATED), + refcount_read(&key->usage), + xbuf, +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 293d3598153b..740affd65ee9 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -730,7 +730,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, + + ret = -EIO; + if (!(lflags & KEY_LOOKUP_PARTIAL) && +- !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) ++ key_read_state(key) == KEY_IS_UNINSTANTIATED) + goto invalid_key; + + /* check the permissions */ +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index 63e63a42db3c..e8036cd0ad54 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr) + intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); + if (ret) + return -ERESTARTSYS; +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { +- smp_rmb(); +- return key->reject_error; +- } ++ ret = key_read_state(key); ++ if (ret < 0) ++ return ret; + return key_validate(key); + } + EXPORT_SYMBOL(wait_for_key_construction); +diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c +index afe9d22ab361..4a740e50322b 100644 +--- a/security/keys/request_key_auth.c ++++ b/security/keys/request_key_auth.c +@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key, + + seq_puts(m, "key:"); + seq_puts(m, key->description); +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); + } + +diff --git a/security/keys/trusted.c b/security/keys/trusted.c +index ddfaebf60fc8..bd85315cbfeb 100644 +--- a/security/keys/trusted.c ++++ b/security/keys/trusted.c +@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) + char *datablob; + int ret = 0; + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_negative(key)) + return -ENOKEY; + p = key->payload.data[0]; + if (!p->migratable) +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index 3d8c68eba516..9f558bedba23 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) + + /* attach the new data, displacing the old */ + key->expiry = prep->expiry; +- if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_positive(key)) + zap = dereference_key_locked(key); + rcu_assign_keypointer(key, prep->payload.data[0]); + prep->payload.data[0] = NULL; +@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy); + void user_describe(const struct key *key, struct seq_file *m) + { + seq_puts(m, key->description); +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, ": %u", key->datalen); + } + +diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c +index 0ff7926a5a69..cda64b489e42 100644 +--- a/sound/core/seq/seq_lock.c ++++ b/sound/core/seq/seq_lock.c +@@ -23,8 +23,6 @@ + #include <sound/core.h> + #include "seq_lock.h" + +-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) +- + /* wait until all locks are released */ + void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + { +@@ -41,5 +39,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + } + } + EXPORT_SYMBOL(snd_use_lock_sync_helper); +- +-#endif +diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h +index 54044bc2c9ef..ac38031c370e 100644 +--- a/sound/core/seq/seq_lock.h ++++ b/sound/core/seq/seq_lock.h +@@ -3,8 +3,6 @@ + + #include <linux/sched.h> + +-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) +- + typedef atomic_t snd_use_lock_t; + + /* initialize lock */ +@@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t; + void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line); + #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__) + +-#else /* SMP || CONFIG_SND_DEBUG */ +- +-typedef spinlock_t snd_use_lock_t; /* dummy */ +-#define snd_use_lock_init(lockp) /**/ +-#define snd_use_lock_use(lockp) /**/ +-#define snd_use_lock_free(lockp) /**/ +-#define snd_use_lock_sync(lockp) /**/ +- +-#endif /* SMP || CONFIG_SND_DEBUG */ +- + #endif /* __SND_SEQ_LOCK_H */ +diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c +index 6c58e6f73a01..e43af18d4383 100644 +--- a/sound/core/vmaster.c ++++ b/sound/core/vmaster.c +@@ -484,3 +484,34 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only) + master->hook(master->hook_private_data, master->val); + } + EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); ++ ++/** ++ * snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave ++ * @kctl: vmaster kctl element ++ * @func: function to apply ++ * @arg: optional function argument ++ * ++ * Apply the function @func to each slave kctl of the given vmaster kctl. ++ * Returns 0 if successful, or a negative error code. ++ */ ++int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, ++ int (*func)(struct snd_kcontrol *, void *), ++ void *arg) ++{ ++ struct link_master *master; ++ struct link_slave *slave; ++ int err; ++ ++ master = snd_kcontrol_chip(kctl); ++ err = master_init(master); ++ if (err < 0) ++ return err; ++ list_for_each_entry(slave, &master->slaves, list) { ++ err = func(&slave->slave, arg); ++ if (err < 0) ++ return err; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves); +diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c +index 978dc1801b3a..f6d2985b2520 100644 +--- a/sound/hda/hdac_controller.c ++++ b/sound/hda/hdac_controller.c +@@ -284,6 +284,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus) + dev_dbg(bus->dev, "HDA capability ID: 0x%x\n", + (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF); + ++ if (cur_cap == -1) { ++ dev_dbg(bus->dev, "Invalid capability reg read\n"); ++ break; ++ } ++ + switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) { + case AZX_ML_CAP_ID: + dev_dbg(bus->dev, "Found ML capability\n"); +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index 821aad374a06..0bb46966d2d4 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -1803,36 +1803,6 @@ static int check_slave_present(struct hda_codec *codec, + return 1; + } + +-/* guess the value corresponding to 0dB */ +-static int get_kctl_0dB_offset(struct hda_codec *codec, +- struct snd_kcontrol *kctl, int *step_to_check) +-{ +- int _tlv[4]; +- const int *tlv = NULL; +- int val = -1; +- +- if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && +- kctl->tlv.c == snd_hda_mixer_amp_tlv) { +- get_ctl_amp_tlv(kctl, _tlv); +- tlv = _tlv; +- } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) +- tlv = kctl->tlv.p; +- if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { +- int step = tlv[3]; +- step &= ~TLV_DB_SCALE_MUTE; +- if (!step) +- return -1; +- if (*step_to_check && *step_to_check != step) { +- codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n", +-- *step_to_check, step); +- return -1; +- } +- *step_to_check = step; +- val = -tlv[2] / step; +- } +- return val; +-} +- + /* call kctl->put with the given value(s) */ + static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) + { +@@ -1847,19 +1817,58 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) + return 0; + } + +-/* initialize the slave volume with 0dB */ +-static int init_slave_0dB(struct hda_codec *codec, +- void *data, struct snd_kcontrol *slave) ++struct slave_init_arg { ++ struct hda_codec *codec; ++ int step; ++}; ++ ++/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ ++static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) + { +- int offset = get_kctl_0dB_offset(codec, slave, data); +- if (offset > 0) +- put_kctl_with_value(slave, offset); ++ struct slave_init_arg *arg = _arg; ++ int _tlv[4]; ++ const int *tlv = NULL; ++ int step; ++ int val; ++ ++ if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { ++ if (kctl->tlv.c != snd_hda_mixer_amp_tlv) { ++ codec_err(arg->codec, ++ "Unexpected TLV callback for slave %s:%d\n", ++ kctl->id.name, kctl->id.index); ++ return 0; /* ignore */ ++ } ++ get_ctl_amp_tlv(kctl, _tlv); ++ tlv = _tlv; ++ } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) ++ tlv = kctl->tlv.p; ++ ++ if (!tlv || tlv[0] != SNDRV_CTL_TLVT_DB_SCALE) ++ return 0; ++ ++ step = tlv[3]; ++ step &= ~TLV_DB_SCALE_MUTE; ++ if (!step) ++ return 0; ++ if (arg->step && arg->step != step) { ++ codec_err(arg->codec, ++ "Mismatching dB step for vmaster slave (%d!=%d)\n", ++ arg->step, step); ++ return 0; ++ } ++ ++ arg->step = step; ++ val = -tlv[2] / step; ++ if (val > 0) { ++ put_kctl_with_value(kctl, val); ++ return val; ++ } ++ + return 0; + } + +-/* unmute the slave */ +-static int init_slave_unmute(struct hda_codec *codec, +- void *data, struct snd_kcontrol *slave) ++/* unmute the slave via snd_ctl_apply_vmaster_slaves() */ ++static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg) + { + return put_kctl_with_value(slave, 1); + } +@@ -1919,9 +1928,13 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, + /* init with master mute & zero volume */ + put_kctl_with_value(kctl, 0); + if (init_slave_vol) { +- int step = 0; +- map_slaves(codec, slaves, suffix, +- tlv ? init_slave_0dB : init_slave_unmute, &step); ++ struct slave_init_arg arg = { ++ .codec = codec, ++ .step = 0, ++ }; ++ snd_ctl_apply_vmaster_slaves(kctl, ++ tlv ? init_slave_0dB : init_slave_unmute, ++ &arg); + } + + if (ctl_ret) +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 5d2a63248b1d..0e54fe490458 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1352,6 +1352,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, + case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ + case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ + case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ ++ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ + if (fp->altsetting == 2) + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + break; +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 0dafba2c1e7d..bd9c6b31a504 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -92,7 +92,6 @@ unsigned int do_ring_perf_limit_reasons; + unsigned int crystal_hz; + unsigned long long tsc_hz; + int base_cpu; +-int do_migrate; + double discover_bclk(unsigned int family, unsigned int model); + unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ + /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ +@@ -303,9 +302,6 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg + + int cpu_migrate(int cpu) + { +- if (!do_migrate) +- return 0; +- + CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); + CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); + if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) +@@ -5007,7 +5003,6 @@ void cmdline(int argc, char **argv) + {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help + {"Joules", no_argument, 0, 'J'}, + {"list", no_argument, 0, 'l'}, +- {"migrate", no_argument, 0, 'm'}, + {"out", required_argument, 0, 'o'}, + {"quiet", no_argument, 0, 'q'}, + {"show", required_argument, 0, 's'}, +@@ -5019,7 +5014,7 @@ void cmdline(int argc, char **argv) + + progname = argv[0]; + +- while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:Jmo:qST:v", ++ while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v", + long_options, &option_index)) != -1) { + switch (opt) { + case 'a': +@@ -5062,9 +5057,6 @@ void cmdline(int argc, char **argv) + list_header_only++; + quiet++; + break; +- case 'm': +- do_migrate = 1; +- break; + case 'o': + outf = fopen_or_die(optarg, "w"); + break; |