diff --git a/Makefile b/Makefile
index feab5f5a507c..d5a2ab9b3291 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 56
+SUBLEVEL = 57
 EXTRAVERSION =
 NAME = Roaring Lionus
 
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index e9385bcd9723..9ade60ca08e0 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -2386,7 +2386,6 @@ static int fpu_emu(struct pt_regs *xcp, struct 
mips_fpu_struct *ctx,
                                        break;
                                default:
                                        /* Reserved R6 ops */
-                                       pr_err("Reserved MIPS R6 CMP.condn.S 
operation\n");
                                        return SIGILL;
                                }
                        }
@@ -2460,7 +2459,6 @@ static int fpu_emu(struct pt_regs *xcp, struct 
mips_fpu_struct *ctx,
                                        break;
                                default:
                                        /* Reserved R6 ops */
-                                       pr_err("Reserved MIPS R6 CMP.condn.D 
operation\n");
                                        return SIGILL;
                                }
                        }
diff --git a/arch/x86/include/asm/alternative-asm.h 
b/arch/x86/include/asm/alternative-asm.h
index e7636bac7372..6c98821fef5e 100644
--- a/arch/x86/include/asm/alternative-asm.h
+++ b/arch/x86/include/asm/alternative-asm.h
@@ -62,8 +62,10 @@
 #define new_len2               145f-144f
 
 /*
- * max without conditionals. Idea adapted from:
+ * gas compatible max based on the idea from:
  * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
+ *
+ * The additional "-" is needed because gas uses a "true" value of -1.
  */
 #define alt_max_short(a, b)    ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
 
diff --git a/arch/x86/include/asm/alternative.h 
b/arch/x86/include/asm/alternative.h
index 1b020381ab38..d4aea31eec03 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -103,12 +103,12 @@ static inline int alternatives_text_reserved(void *start, 
void *end)
        alt_end_marker ":\n"
 
 /*
- * max without conditionals. Idea adapted from:
+ * gas compatible max based on the idea from:
  * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
  *
- * The additional "-" is needed because gas works with s32s.
+ * The additional "-" is needed because gas uses a "true" value of -1.
  */
-#define alt_max_short(a, b)    "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") 
- (" b ")))))"
+#define alt_max_short(a, b)    "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") 
< (" b ")))))"
 
 /*
  * Pad the second replacement alternative with additional NOPs if it is
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 5f2412704b81..d29c745f10ad 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3648,13 +3648,6 @@ static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 
*sptep, gfn_t gfn,
 static inline bool is_last_gpte(struct kvm_mmu *mmu,
                                unsigned level, unsigned gpte)
 {
-       /*
-        * PT_PAGE_TABLE_LEVEL always terminates.  The RHS has bit 7 set
-        * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means
-        * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then.
-        */
-       gpte |= level - PT_PAGE_TABLE_LEVEL - 1;
-
        /*
         * The RHS has bit 7 set iff level < mmu->last_nonleaf_level.
         * If it is clear, there are no large pages at this level, so clear
@@ -3662,6 +3655,13 @@ static inline bool is_last_gpte(struct kvm_mmu *mmu,
         */
        gpte &= level - mmu->last_nonleaf_level;
 
+       /*
+        * PT_PAGE_TABLE_LEVEL always terminates.  The RHS has bit 7 set
+        * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means
+        * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then.
+        */
+       gpte |= level - PT_PAGE_TABLE_LEVEL - 1;
+
        return gpte & PT_PAGE_SIZE_MASK;
 }
 
@@ -4169,6 +4169,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool 
execonly)
 
        update_permission_bitmask(vcpu, context, true);
        update_pkru_bitmask(vcpu, context, true);
+       update_last_nonleaf_level(vcpu, context);
        reset_rsvds_bits_mask_ept(vcpu, context, execonly);
        reset_ept_shadow_zero_bits_mask(vcpu, context, execonly);
 }
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index a01105485315..37363900297d 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -324,10 +324,11 @@ static int FNAME(walk_addr_generic)(struct guest_walker 
*walker,
                --walker->level;
 
                index = PT_INDEX(addr, walker->level);
-
                table_gfn = gpte_to_gfn(pte);
                offset    = index * sizeof(pt_element_t);
                pte_gpa   = gfn_to_gpa(table_gfn) + offset;
+
+               BUG_ON(walker->level < 1);
                walker->table_gfn[walker->level - 1] = table_gfn;
                walker->pte_gpa[walker->level - 1] = pte_gpa;
 
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index fb49212d25df..a8ae57acb6f6 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -10690,7 +10690,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu 
*vcpu,
         * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask();
         */
        vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
-       kvm_set_cr4(vcpu, vmcs12->host_cr4);
+       vmx_set_cr4(vcpu, vmcs12->host_cr4);
 
        nested_ept_uninit_mmu_context(vcpu);
 
diff --git a/block/bio.c b/block/bio.c
index 655c9016052a..07f287b14cff 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1171,8 +1171,8 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
         */
        bmd->is_our_pages = map_data ? 0 : 1;
        memcpy(bmd->iov, iter->iov, sizeof(struct iovec) * iter->nr_segs);
-       iov_iter_init(&bmd->iter, iter->type, bmd->iov,
-                       iter->nr_segs, iter->count);
+       bmd->iter = *iter;
+       bmd->iter.iov = bmd->iov;
 
        ret = -ENOMEM;
        bio = bio_kmalloc(gfp_mask, nr_pages);
@@ -1266,6 +1266,7 @@ struct bio *bio_map_user_iov(struct request_queue *q,
        int ret, offset;
        struct iov_iter i;
        struct iovec iov;
+       struct bio_vec *bvec;
 
        iov_for_each(iov, i, *iter) {
                unsigned long uaddr = (unsigned long) iov.iov_base;
@@ -1310,7 +1311,12 @@ struct bio *bio_map_user_iov(struct request_queue *q,
                ret = get_user_pages_fast(uaddr, local_nr_pages,
                                (iter->type & WRITE) != WRITE,
                                &pages[cur_page]);
-               if (ret < local_nr_pages) {
+               if (unlikely(ret < local_nr_pages)) {
+                       for (j = cur_page; j < page_limit; j++) {
+                               if (!pages[j])
+                                       break;
+                               put_page(pages[j]);
+                       }
                        ret = -EFAULT;
                        goto out_unmap;
                }
@@ -1318,6 +1324,7 @@ struct bio *bio_map_user_iov(struct request_queue *q,
                offset = offset_in_page(uaddr);
                for (j = cur_page; j < page_limit; j++) {
                        unsigned int bytes = PAGE_SIZE - offset;
+                       unsigned short prev_bi_vcnt = bio->bi_vcnt;
 
                        if (len <= 0)
                                break;
@@ -1332,6 +1339,13 @@ struct bio *bio_map_user_iov(struct request_queue *q,
                                            bytes)
                                break;
 
+                       /*
+                        * check if vector was merged with previous
+                        * drop page reference if needed
+                        */
+                       if (bio->bi_vcnt == prev_bi_vcnt)
+                               put_page(pages[j]);
+
                        len -= bytes;
                        offset = 0;
                }
@@ -1364,10 +1378,8 @@ struct bio *bio_map_user_iov(struct request_queue *q,
        return bio;
 
  out_unmap:
-       for (j = 0; j < nr_pages; j++) {
-               if (!pages[j])
-                       break;
-               put_page(pages[j]);
+       bio_for_each_segment_all(bvec, bio, j) {
+               put_page(bvec->bv_page);
        }
  out:
        kfree(pages);
diff --git a/crypto/shash.c b/crypto/shash.c
index a051541a4a17..4d8a671d1614 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -274,12 +274,14 @@ static int shash_async_finup(struct ahash_request *req)
 
 int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
 {
-       struct scatterlist *sg = req->src;
-       unsigned int offset = sg->offset;
        unsigned int nbytes = req->nbytes;
+       struct scatterlist *sg;
+       unsigned int offset;
        int err;
 
-       if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
+       if (nbytes &&
+           (sg = req->src, offset = sg->offset,
+            nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) {
                void *data;
 
                data = kmap_atomic(sg_page(sg));
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 06f66687fe0b..7b313b567f4c 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -20,6 +20,7 @@
 #include <linux/phy.h>
 
 struct property_set {
+       struct device *dev;
        struct fwnode_handle fwnode;
        struct property_entry *properties;
 };
@@ -817,6 +818,7 @@ static struct property_set *pset_copy_set(const struct 
property_set *pset)
 void device_remove_properties(struct device *dev)
 {
        struct fwnode_handle *fwnode;
+       struct property_set *pset;
 
        fwnode = dev_fwnode(dev);
        if (!fwnode)
@@ -826,16 +828,16 @@ void device_remove_properties(struct device *dev)
         * the pset. If there is no real firmware node (ACPI/DT) primary
         * will hold the pset.
         */
-       if (is_pset_node(fwnode)) {
+       pset = to_pset_node(fwnode);
+       if (pset) {
                set_primary_fwnode(dev, NULL);
-               pset_free_set(to_pset_node(fwnode));
        } else {
-               fwnode = fwnode->secondary;
-               if (!IS_ERR(fwnode) && is_pset_node(fwnode)) {
+               pset = to_pset_node(fwnode->secondary);
+               if (pset && dev == pset->dev)
                        set_secondary_fwnode(dev, NULL);
-                       pset_free_set(to_pset_node(fwnode));
-               }
        }
+       if (pset && dev == pset->dev)
+               pset_free_set(pset);
 }
 EXPORT_SYMBOL_GPL(device_remove_properties);
 
@@ -863,6 +865,7 @@ int device_add_properties(struct device *dev, struct 
property_entry *properties)
 
        p->fwnode.type = FWNODE_PDATA;
        set_secondary_fwnode(dev, &p->fwnode);
+       p->dev = dev;
        return 0;
 }
 EXPORT_SYMBOL_GPL(device_add_properties);
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 77242b37ef87..57962bff7532 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -1143,11 +1143,24 @@ static struct dma_async_tx_descriptor 
*edma_prep_dma_memcpy(
        struct edma_desc *edesc;
        struct device *dev = chan->device->dev;
        struct edma_chan *echan = to_edma_chan(chan);
-       unsigned int width, pset_len;
+       unsigned int width, pset_len, array_size;
 
        if (unlikely(!echan || !len))
                return NULL;
 
+       /* Align the array size (acnt block) with the transfer properties */
+       switch (__ffs((src | dest | len))) {
+       case 0:
+               array_size = SZ_32K - 1;
+               break;
+       case 1:
+               array_size = SZ_32K - 2;
+               break;
+       default:
+               array_size = SZ_32K - 4;
+               break;
+       }
+
        if (len < SZ_64K) {
                /*
                 * Transfer size less than 64K can be handled with one paRAM
@@ -1169,7 +1182,7 @@ static struct dma_async_tx_descriptor 
*edma_prep_dma_memcpy(
                 * When the full_length is multibple of 32767 one slot can be
                 * used to complete the transfer.
                 */
-               width = SZ_32K - 1;
+               width = array_size;
                pset_len = rounddown(len, width);
                /* One slot is enough for lengths multiple of (SZ_32K -1) */
                if (unlikely(pset_len == len))
@@ -1217,7 +1230,7 @@ static struct dma_async_tx_descriptor 
*edma_prep_dma_memcpy(
                }
                dest += pset_len;
                src += pset_len;
-               pset_len = width = len % (SZ_32K - 1);
+               pset_len = width = len % array_size;
 
                ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1,
                                       width, pset_len, DMA_MEM_TO_MEM);
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
index 2403475a37cf..88a00d06def6 100644
--- a/drivers/dma/ti-dma-crossbar.c
+++ b/drivers/dma/ti-dma-crossbar.c
@@ -262,13 +262,14 @@ static void *ti_dra7_xbar_route_allocate(struct 
of_phandle_args *dma_spec,
        mutex_lock(&xbar->mutex);
        map->xbar_out = find_first_zero_bit(xbar->dma_inuse,
                                            xbar->dma_requests);
-       mutex_unlock(&xbar->mutex);
        if (map->xbar_out == xbar->dma_requests) {
+               mutex_unlock(&xbar->mutex);
                dev_err(&pdev->dev, "Run out of free DMA requests\n");
                kfree(map);
                return ERR_PTR(-ENOMEM);
        }
        set_bit(map->xbar_out, xbar->dma_inuse);
+       mutex_unlock(&xbar->mutex);
 
        map->xbar_in = (u16)dma_spec->args[0];
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 8aeb7f8ee59c..80c5cc5640c1 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1219,7 +1219,7 @@ static void parse_ddi_ports(struct drm_i915_private 
*dev_priv,
 {
        enum port port;
 
-       if (!HAS_DDI(dev_priv))
+       if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv))
                return;
 
        if (!dev_priv->vbt.child_dev_num)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index f8efd20e4a90..ce32303b3013 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11471,13 +11471,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct 
drm_device *dev,
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+       enum transcoder cpu_transcoder;
        struct drm_display_mode *mode;
        struct intel_crtc_state *pipe_config;
-       int htot = I915_READ(HTOTAL(cpu_transcoder));
-       int hsync = I915_READ(HSYNC(cpu_transcoder));
-       int vtot = I915_READ(VTOTAL(cpu_transcoder));
-       int vsync = I915_READ(VSYNC(cpu_transcoder));
+       u32 htot, hsync, vtot, vsync;
        enum pipe pipe = intel_crtc->pipe;
 
        mode = kzalloc(sizeof(*mode), GFP_KERNEL);
@@ -11505,6 +11502,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct 
drm_device *dev,
        i9xx_crtc_clock_get(intel_crtc, pipe_config);
 
        mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
+
+       cpu_transcoder = pipe_config->cpu_transcoder;
+       htot = I915_READ(HTOTAL(cpu_transcoder));
+       hsync = I915_READ(HSYNC(cpu_transcoder));
+       vtot = I915_READ(VTOTAL(cpu_transcoder));
+       vsync = I915_READ(VSYNC(cpu_transcoder));
+
        mode->hdisplay = (htot & 0xffff) + 1;
        mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
        mode->hsync_start = (hsync & 0xffff) + 1;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7b06280b23aa..afa3d010c650 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2193,8 +2193,8 @@ static void edp_panel_off(struct intel_dp *intel_dp)
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
 
-       intel_dp->panel_power_off_time = ktime_get_boottime();
        wait_panel_off(intel_dp);
+       intel_dp->panel_power_off_time = ktime_get_boottime();
 
        /* We got a reference when we enabled the VDD. */
        power_domain = intel_display_port_aux_power_domain(intel_encoder);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ae83af649a60..7838343eb37c 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -971,6 +971,8 @@ static int usbhid_parse(struct hid_device *hid)
        unsigned int rsize = 0;
        char *rdesc;
        int ret, n;
+       int num_descriptors;
+       size_t offset = offsetof(struct hid_descriptor, desc);
 
        quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
                        le16_to_cpu(dev->descriptor.idProduct));
@@ -993,10 +995,18 @@ static int usbhid_parse(struct hid_device *hid)
                return -ENODEV;
        }
 
+       if (hdesc->bLength < sizeof(struct hid_descriptor)) {
+               dbg_hid("hid descriptor is too short\n");
+               return -EINVAL;
+       }
+
        hid->version = le16_to_cpu(hdesc->bcdHID);
        hid->country = hdesc->bCountryCode;
 
-       for (n = 0; n < hdesc->bNumDescriptors; n++)
+       num_descriptors = min_t(int, hdesc->bNumDescriptors,
+              (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
+
+       for (n = 0; n < num_descriptors; n++)
                if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
                        rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
 
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index c380b7e8f1c6..1a0b110f12c0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3120,6 +3120,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, 
unsigned long iova,
        mutex_unlock(&domain->api_lock);
 
        domain_flush_tlb_pde(domain);
+       domain_flush_complete(domain);
 
        return unmap_size;
 }
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0e75d94972ba..671610c989b6 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -82,6 +82,7 @@ config PINCTRL_AMD
        tristate "AMD GPIO pin control"
        depends on GPIOLIB
        select GPIOLIB_IRQCHIP
+       select PINMUX
        select PINCONF
        select GENERIC_PINCONF
        help
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index baa7cdcc0ebc..325bf21ba13b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -2018,6 +2018,8 @@ static DEVICE_ATTR_RO(suspended);
 static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
 {
        struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_gadget_strings       *gstr = cdev->driver->strings[0];
+       struct usb_string               *dev_str = gstr->strings;
 
        /* composite_disconnect() must already have been called
         * by the underlying peripheral controller driver!
@@ -2037,6 +2039,9 @@ static void __composite_unbind(struct usb_gadget *gadget, 
bool unbind_driver)
 
        composite_dev_cleanup(cdev);
 
+       if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
+               dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
+
        kfree(cdev->def_manufacturer);
        kfree(cdev);
        set_gadget_data(gadget, NULL);
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 3984787f8e97..502a096fc380 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -1140,11 +1140,12 @@ static struct configfs_attribute *interf_grp_attrs[] = {
        NULL
 };
 
-int usb_os_desc_prepare_interf_dir(struct config_group *parent,
-                                  int n_interf,
-                                  struct usb_os_desc **desc,
-                                  char **names,
-                                  struct module *owner)
+struct config_group *usb_os_desc_prepare_interf_dir(
+               struct config_group *parent,
+               int n_interf,
+               struct usb_os_desc **desc,
+               char **names,
+               struct module *owner)
 {
        struct config_group *os_desc_group;
        struct config_item_type *os_desc_type, *interface_type;
@@ -1156,7 +1157,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group 
*parent,
 
        char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
        if (!vlabuf)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
        os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
@@ -1181,7 +1182,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group 
*parent,
                configfs_add_default_group(&d->group, os_desc_group);
        }
 
-       return 0;
+       return os_desc_group;
 }
 EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
 
diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h
index 36c468c4f5e9..540d5e92ed22 100644
--- a/drivers/usb/gadget/configfs.h
+++ b/drivers/usb/gadget/configfs.h
@@ -5,11 +5,12 @@
 
 void unregister_gadget_item(struct config_item *item);
 
-int usb_os_desc_prepare_interf_dir(struct config_group *parent,
-                                  int n_interf,
-                                  struct usb_os_desc **desc,
-                                  char **names,
-                                  struct module *owner);
+struct config_group *usb_os_desc_prepare_interf_dir(
+               struct config_group *parent,
+               int n_interf,
+               struct usb_os_desc **desc,
+               char **names,
+               struct module *owner);
 
 static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
 {
diff --git a/drivers/usb/gadget/function/f_rndis.c 
b/drivers/usb/gadget/function/f_rndis.c
index 16562e461121..ba00cdb809d6 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -892,6 +892,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
                        free_netdev(opts->net);
        }
 
+       kfree(opts->rndis_interf_group);        /* single VLA chunk */
        kfree(opts);
 }
 
@@ -900,6 +901,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
        struct f_rndis_opts *opts;
        struct usb_os_desc *descs[1];
        char *names[1];
+       struct config_group *rndis_interf_group;
 
        opts = kzalloc(sizeof(*opts), GFP_KERNEL);
        if (!opts)
@@ -920,8 +922,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
        names[0] = "rndis";
        config_group_init_type_name(&opts->func_inst.group, "",
                                    &rndis_func_type);
-       usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
-                                      names, THIS_MODULE);
+       rndis_interf_group =
+               usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
+                                              names, THIS_MODULE);
+       if (IS_ERR(rndis_interf_group)) {
+               rndis_free_inst(&opts->func_inst);
+               return ERR_CAST(rndis_interf_group);
+       }
+       opts->rndis_interf_group = rndis_interf_group;
 
        return &opts->func_inst;
 }
diff --git a/drivers/usb/gadget/function/u_rndis.h 
b/drivers/usb/gadget/function/u_rndis.h
index 4eafd5050545..4e2ad04fe8d6 100644
--- a/drivers/usb/gadget/function/u_rndis.h
+++ b/drivers/usb/gadget/function/u_rndis.h
@@ -26,6 +26,7 @@ struct f_rndis_opts {
        bool                            bound;
        bool                            borrowed_net;
 
+       struct config_group             *rndis_interf_group;
        struct usb_os_desc              rndis_os_desc;
        char                            rndis_ext_compat_id[16];
 
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c 
b/drivers/usb/gadget/udc/dummy_hcd.c
index fb17fb23fa9a..b62a3de65075 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -420,6 +420,7 @@ static void set_link_state_by_speed(struct dummy_hcd 
*dum_hcd)
 static void set_link_state(struct dummy_hcd *dum_hcd)
 {
        struct dummy *dum = dum_hcd->dum;
+       unsigned int power_bit;
 
        dum_hcd->active = 0;
        if (dum->pullup)
@@ -430,17 +431,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
                        return;
 
        set_link_state_by_speed(dum_hcd);
+       power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
+                       USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
 
        if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
             dum_hcd->active)
                dum_hcd->resuming = 0;
 
        /* Currently !connected or in reset */
-       if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
+       if ((dum_hcd->port_status & power_bit) == 0 ||
                        (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
-               unsigned disconnect = USB_PORT_STAT_CONNECTION &
+               unsigned int disconnect = power_bit &
                                dum_hcd->old_status & (~dum_hcd->port_status);
-               unsigned reset = USB_PORT_STAT_RESET &
+               unsigned int reset = USB_PORT_STAT_RESET &
                                (~dum_hcd->old_status) & dum_hcd->port_status;
 
                /* Report reset and disconnect events to the driver */
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 8897195396b2..6c6a3a8df07a 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -860,9 +860,9 @@ static void xfer_work(struct work_struct *work)
                fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
 
        usbhs_pipe_running(pipe, 1);
-       usbhsf_dma_start(pipe, fifo);
        usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
        dma_async_issue_pending(chan);
+       usbhsf_dma_start(pipe, fifo);
        usbhs_pipe_enable(pipe);
 
 xfer_work_end:
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index b6f1adefb758..76062ce2d459 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char 
*options)
        tty_kref_put(tty);
  reset_open_count:
        port->port.count = 0;
+       info->port = NULL;
        usb_autopm_put_interface(serial->interface);
  error_get_interface:
        usb_serial_put(serial);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 470b17b0c11b..11ee55e080e5 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -171,6 +171,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
        { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
        { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+       { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */
        { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
        { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
        { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 19394963f675..3249f42b4b93 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
        { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
+       { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
        { }                                     /* Terminating entry */
 };
 
diff --git a/drivers/usb/serial/ftdi_sio_ids.h 
b/drivers/usb/serial/ftdi_sio_ids.h
index 4fcf1cecb6d7..f9d15bd62785 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -609,6 +609,13 @@
 #define ADI_GNICE_PID          0xF000
 #define ADI_GNICEPLUS_PID      0xF001
 
+/*
+ * Cypress WICED USB UART
+ */
+#define CYPRESS_VID                    0x04B4
+#define CYPRESS_WICED_BT_USB_PID       0x009B
+#define CYPRESS_WICED_WL_USB_PID       0xF900
+
 /*
  * Microchip Technology, Inc.
  *
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 2a9944326210..db3d34c2c82e 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb);
 
 /* TP-LINK Incorporated products */
 #define TPLINK_VENDOR_ID                       0x2357
+#define TPLINK_PRODUCT_LTE                     0x000D
 #define TPLINK_PRODUCT_MA180                   0x0201
 
 /* Changhong products */
@@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
        { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) },
        { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
+       { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 
0xff, 0x00, 0x00) },      /* TP-Link LTE Module */
        { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000),                                 
/* TP-Link MA260 */
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 652b4334b26d..e1c1e329c877 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_SWI(0x413c, 0x81b3)},   /* Dell Wireless 5809e Gobi(TM) 4G LTE 
Mobile Broadband Card (rev3) */
        {DEVICE_SWI(0x413c, 0x81b5)},   /* Dell Wireless 5811e QDL */
        {DEVICE_SWI(0x413c, 0x81b6)},   /* Dell Wireless 5811e QDL */
+       {DEVICE_SWI(0x413c, 0x81cf)},   /* Dell Wireless 5819 */
+       {DEVICE_SWI(0x413c, 0x81d0)},   /* Dell Wireless 5819 */
+       {DEVICE_SWI(0x413c, 0x81d1)},   /* Dell Wireless 5818 */
+       {DEVICE_SWI(0x413c, 0x81d2)},   /* Dell Wireless 5818 */
 
        /* Huawei devices */
        {DEVICE_HWI(0x03f0, 0x581d)},   /* HP lt4112 LTE/HSPA+ Gobi 4G Modem 
(Huawei me906e) */
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 07e46b786500..cb936c90ae82 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -450,10 +450,12 @@ int bdev_write_page(struct block_device *bdev, sector_t 
sector,
 
        set_page_writeback(page);
        result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, true);
-       if (result)
+       if (result) {
                end_page_writeback(page);
-       else
+       } else {
+               clean_page_buffers(page);
                unlock_page(page);
+       }
        blk_queue_exit(bdev->bd_queue);
        return result;
 }
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 48ef401c3c61..7b496a4e650e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -365,6 +365,8 @@ struct smb_version_operations {
        unsigned int (*calc_smb_size)(void *);
        /* check for STATUS_PENDING and process it in a positive case */
        bool (*is_status_pending)(char *, struct TCP_Server_Info *, int);
+       /* check for STATUS_NETWORK_SESSION_EXPIRED */
+       bool (*is_session_expired)(char *);
        /* send oplock break response */
        int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *,
                               struct cifsInodeInfo *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 1f91c9dadd5b..cc420d6b71f7 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1457,6 +1457,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, 
struct mid_q_entry *mid)
                return length;
        server->total_read += length;
 
+       if (server->ops->is_session_expired &&
+           server->ops->is_session_expired(buf)) {
+               cifs_reconnect(server);
+               wake_up(&server->response_q);
+               return -1;
+       }
+
        if (server->ops->is_status_pending &&
            server->ops->is_status_pending(buf, server, 0)) {
                discard_remaining_data(server);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f6712b6128d8..580b3a4ca53a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -796,6 +796,13 @@ standard_receive3(struct TCP_Server_Info *server, struct 
mid_q_entry *mid)
                cifs_dump_mem("Bad SMB: ", buf,
                        min_t(unsigned int, server->total_read, 48));
 
+       if (server->ops->is_session_expired &&
+           server->ops->is_session_expired(buf)) {
+               cifs_reconnect(server);
+               wake_up(&server->response_q);
+               return -1;
+       }
+
        if (server->ops->is_status_pending &&
            server->ops->is_status_pending(buf, server, length))
                return -1;
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index b6968241c26f..812e4884c392 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1018,6 +1018,18 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info 
*server, int length)
        return true;
 }
 
+static bool
+smb2_is_session_expired(char *buf)
+{
+       struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+
+       if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED)
+               return false;
+
+       cifs_dbg(FYI, "Session expired\n");
+       return true;
+}
+
 static int
 smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
                     struct cifsInodeInfo *cinode)
@@ -1609,6 +1621,7 @@ struct smb_version_operations smb20_operations = {
        .close_dir = smb2_close_dir,
        .calc_smb_size = smb2_calc_size,
        .is_status_pending = smb2_is_status_pending,
+       .is_session_expired = smb2_is_session_expired,
        .oplock_response = smb2_oplock_response,
        .queryfs = smb2_queryfs,
        .mand_lock = smb2_mand_lock,
@@ -1690,6 +1703,7 @@ struct smb_version_operations smb21_operations = {
        .close_dir = smb2_close_dir,
        .calc_smb_size = smb2_calc_size,
        .is_status_pending = smb2_is_status_pending,
+       .is_session_expired = smb2_is_session_expired,
        .oplock_response = smb2_oplock_response,
        .queryfs = smb2_queryfs,
        .mand_lock = smb2_mand_lock,
@@ -1773,6 +1787,7 @@ struct smb_version_operations smb30_operations = {
        .close_dir = smb2_close_dir,
        .calc_smb_size = smb2_calc_size,
        .is_status_pending = smb2_is_status_pending,
+       .is_session_expired = smb2_is_session_expired,
        .oplock_response = smb2_oplock_response,
        .queryfs = smb2_queryfs,
        .mand_lock = smb2_mand_lock,
@@ -1862,6 +1877,7 @@ struct smb_version_operations smb311_operations = {
        .close_dir = smb2_close_dir,
        .calc_smb_size = smb2_calc_size,
        .is_status_pending = smb2_is_status_pending,
+       .is_session_expired = smb2_is_session_expired,
        .oplock_response = smb2_oplock_response,
        .queryfs = smb2_queryfs,
        .mand_lock = smb2_mand_lock,
diff --git a/fs/direct-io.c b/fs/direct-io.c
index c60756e89833..c6220a2daefd 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -835,7 +835,8 @@ submit_page_section(struct dio *dio, struct dio_submit 
*sdio, struct page *page,
         */
        if (sdio->boundary) {
                ret = dio_send_cur_page(dio, sdio, map_bh);
-               dio_bio_submit(dio, sdio);
+               if (sdio->bio)
+                       dio_bio_submit(dio, sdio);
                put_page(sdio->cur_page);
                sdio->cur_page = NULL;
        }
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index d17d12ed6f73..510e66422f04 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -527,7 +527,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t 
offset, loff_t maxsize)
        inode_lock(inode);
 
        isize = i_size_read(inode);
-       if (offset >= isize) {
+       if (offset < 0 || offset >= isize) {
                inode_unlock(inode);
                return -ENXIO;
        }
@@ -590,7 +590,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t 
offset, loff_t maxsize)
        inode_lock(inode);
 
        isize = i_size_read(inode);
-       if (offset >= isize) {
+       if (offset < 0 || offset >= isize) {
                inode_unlock(inode);
                return -ENXIO;
        }
diff --git a/fs/mpage.c b/fs/mpage.c
index d2fcb149720d..e2ea442bb9e1 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -466,6 +466,16 @@ static void clean_buffers(struct page *page, unsigned 
first_unmapped)
                try_to_free_buffers(page);
 }
 
+/*
+ * For situations where we want to clean all buffers attached to a page.
+ * We don't need to calculate how many buffers are attached to the page,
+ * we just need to specify a number larger than the maximum number of buffers.
+ */
+void clean_page_buffers(struct page *page)
+{
+       clean_buffers(page, ~0U);
+}
+
 static int __mpage_writepage(struct page *page, struct writeback_control *wbc,
                      void *data)
 {
@@ -604,10 +614,8 @@ static int __mpage_writepage(struct page *page, struct 
writeback_control *wbc,
        if (bio == NULL) {
                if (first_unmapped == blocks_per_page) {
                        if (!bdev_write_page(bdev, blocks[0] << (blkbits - 9),
-                                                               page, wbc)) {
-                               clean_buffers(page, first_unmapped);
+                                                               page, wbc))
                                goto out;
-                       }
                }
                bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
                                BIO_MAX_PAGES, GFP_NOFS|__GFP_HIGH);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index ebbacd14d450..447a915db25d 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -226,6 +226,7 @@ int generic_write_end(struct file *, struct address_space *,
                                loff_t, unsigned, unsigned,
                                struct page *, void *);
 void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
+void clean_page_buffers(struct page *page);
 int cont_write_begin(struct file *, struct address_space *, loff_t,
                        unsigned, unsigned, struct page **, void **,
                        get_block_t *, loff_t *);
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
index a03acd0d398a..695257ae64ac 100644
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -60,6 +60,7 @@ struct snd_virmidi_dev {
        int port;                       /* created/attached port */
        unsigned int flags;             /* SNDRV_VIRMIDI_* */
        rwlock_t filelist_lock;
+       struct rw_semaphore filelist_sem;
        struct list_head filelist;
 };
 
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 10f62c6f48e7..d1a02877a42c 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -792,8 +792,13 @@ void rcu_irq_exit(void)
        long long oldval;
        struct rcu_dynticks *rdtp;
 
-       RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs 
enabled!!!");
        rdtp = this_cpu_ptr(&rcu_dynticks);
+
+       /* Page faults can happen in NMI handlers, so check... */
+       if (READ_ONCE(rdtp->dynticks_nmi_nesting))
+               return;
+
+       RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs 
enabled!!!");
        oldval = rdtp->dynticks_nesting;
        rdtp->dynticks_nesting--;
        WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
@@ -930,8 +935,13 @@ void rcu_irq_enter(void)
        struct rcu_dynticks *rdtp;
        long long oldval;
 
-       RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs 
enabled!!!");
        rdtp = this_cpu_ptr(&rcu_dynticks);
+
+       /* Page faults can happen in NMI handlers, so check... */
+       if (READ_ONCE(rdtp->dynticks_nmi_nesting))
+               return;
+
+       RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs 
enabled!!!");
        oldval = rdtp->dynticks_nesting;
        rdtp->dynticks_nesting++;
        WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ece0fbc08607..c626f679e1c8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -541,6 +541,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
        [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
 };
 
+/* policy for packet pattern attributes */
+static const struct nla_policy
+nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
+       [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
+       [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
+       [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
+};
+
 static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
                                     struct netlink_callback *cb,
                                     struct cfg80211_registered_device **rdev,
@@ -10009,7 +10017,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, 
struct genl_info *info)
                        u8 *mask_pat;
 
                        nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
-                                 nla_len(pat), NULL);
+                                 nla_len(pat), nl80211_packet_pattern_policy);
                        err = -EINVAL;
                        if (!pat_tb[NL80211_PKTPAT_MASK] ||
                            !pat_tb[NL80211_PKTPAT_PATTERN])
@@ -10259,7 +10267,7 @@ static int nl80211_parse_coalesce_rule(struct 
cfg80211_registered_device *rdev,
                u8 *mask_pat;
 
                nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
-                         nla_len(pat), NULL);
+                         nla_len(pat), nl80211_packet_pattern_policy);
                if (!pat_tb[NL80211_PKTPAT_MASK] ||
                    !pat_tb[NL80211_PKTPAT_PATTERN])
                        return -EINVAL;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 67c4c68ce041..c41148353e19 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1259,6 +1259,7 @@ static int snd_seq_ioctl_create_port(struct 
snd_seq_client *client, void *arg)
        struct snd_seq_port_info *info = arg;
        struct snd_seq_client_port *port;
        struct snd_seq_port_callback *callback;
+       int port_idx;
 
        /* it is not allowed to create the port for an another client */
        if (info->addr.client != client->number)
@@ -1269,7 +1270,9 @@ static int snd_seq_ioctl_create_port(struct 
snd_seq_client *client, void *arg)
                return -ENOMEM;
 
        if (client->type == USER_CLIENT && info->kernel) {
-               snd_seq_delete_port(client, port->addr.port);
+               port_idx = port->addr.port;
+               snd_seq_port_unlock(port);
+               snd_seq_delete_port(client, port_idx);
                return -EINVAL;
        }
        if (client->type == KERNEL_CLIENT) {
@@ -1290,6 +1293,7 @@ static int snd_seq_ioctl_create_port(struct 
snd_seq_client *client, void *arg)
 
        snd_seq_set_port_info(port, info);
        snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
+       snd_seq_port_unlock(port);
 
        return 0;
 }
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index fe686ee41c6d..f04714d70bf7 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -122,7 +122,9 @@ static void port_subs_info_init(struct 
snd_seq_port_subs_info *grp)
 }
 
 
-/* create a port, port number is returned (-1 on failure) */
+/* create a port, port number is returned (-1 on failure);
+ * the caller needs to unref the port via snd_seq_port_unlock() appropriately
+ */
 struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
                                                int port)
 {
@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct 
snd_seq_client *client,
        snd_use_lock_init(&new_port->use_lock);
        port_subs_info_init(&new_port->c_src);
        port_subs_info_init(&new_port->c_dest);
+       snd_use_lock_use(&new_port->use_lock);
 
        num = port >= 0 ? port : 0;
        mutex_lock(&client->ports_mutex);
@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct 
snd_seq_client *client,
        list_add_tail(&new_port->list, &p->list);
        client->num_ports++;
        new_port->addr.port = num;      /* store the port number in the port */
+       sprintf(new_port->name, "port-%d", num);
        write_unlock_irqrestore(&client->ports_lock, flags);
        mutex_unlock(&client->ports_mutex);
-       sprintf(new_port->name, "port-%d", num);
 
        return new_port;
 }
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index c82ed3e70506..200764948ed1 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi 
*vmidi,
  * decode input event and put to read buffer of each opened file
  */
 static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
-                                        struct snd_seq_event *ev)
+                                        struct snd_seq_event *ev,
+                                        bool atomic)
 {
        struct snd_virmidi *vmidi;
        unsigned char msg[4];
        int len;
 
-       read_lock(&rdev->filelist_lock);
+       if (atomic)
+               read_lock(&rdev->filelist_lock);
+       else
+               down_read(&rdev->filelist_sem);
        list_for_each_entry(vmidi, &rdev->filelist, list) {
                if (!vmidi->trigger)
                        continue;
@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct 
snd_virmidi_dev *rdev,
                                snd_rawmidi_receive(vmidi->substream, msg, len);
                }
        }
-       read_unlock(&rdev->filelist_lock);
+       if (atomic)
+               read_unlock(&rdev->filelist_lock);
+       else
+               up_read(&rdev->filelist_sem);
 
        return 0;
 }
@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct 
snd_seq_event *ev)
        struct snd_virmidi_dev *rdev;
 
        rdev = rmidi->private_data;
-       return snd_virmidi_dev_receive_event(rdev, ev);
+       return snd_virmidi_dev_receive_event(rdev, ev, true);
 }
 #endif  /*  0  */
 
@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event 
*ev, int direct,
        rdev = private_data;
        if (!(rdev->flags & SNDRV_VIRMIDI_USE))
                return 0; /* ignored */
-       return snd_virmidi_dev_receive_event(rdev, ev);
+       return snd_virmidi_dev_receive_event(rdev, ev, atomic);
 }
 
 /*
@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct 
snd_rawmidi_substream *substream)
        struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
        struct snd_rawmidi_runtime *runtime = substream->runtime;
        struct snd_virmidi *vmidi;
-       unsigned long flags;
 
        vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
        if (vmidi == NULL)
@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct 
snd_rawmidi_substream *substream)
        vmidi->client = rdev->client;
        vmidi->port = rdev->port;       
        runtime->private_data = vmidi;
-       write_lock_irqsave(&rdev->filelist_lock, flags);
+       down_write(&rdev->filelist_sem);
+       write_lock_irq(&rdev->filelist_lock);
        list_add_tail(&vmidi->list, &rdev->filelist);
-       write_unlock_irqrestore(&rdev->filelist_lock, flags);
+       write_unlock_irq(&rdev->filelist_lock);
+       up_write(&rdev->filelist_sem);
        vmidi->rdev = rdev;
        return 0;
 }
@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct 
snd_rawmidi_substream *substream)
        struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
        struct snd_virmidi *vmidi = substream->runtime->private_data;
 
+       down_write(&rdev->filelist_sem);
        write_lock_irq(&rdev->filelist_lock);
        list_del(&vmidi->list);
        write_unlock_irq(&rdev->filelist_lock);
+       up_write(&rdev->filelist_sem);
        snd_midi_event_free(vmidi->parser);
        substream->runtime->private_data = NULL;
        kfree(vmidi);
@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, 
struct snd_rawmidi **rrmi
        rdev->rmidi = rmidi;
        rdev->device = device;
        rdev->client = -1;
+       init_rwsem(&rdev->filelist_sem);
        rwlock_init(&rdev->filelist_lock);
        INIT_LIST_HEAD(&rdev->filelist);
        rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index b871ba407e4e..4458190149d1 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
 
        err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 
0);
        if (err)
-               return err;
+               goto err_kill_urb;
 
-       if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ))
-               return -ENODEV;
+       if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) 
{
+               err = -ENODEV;
+               goto err_kill_urb;
+       }
 
        usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
                   cdev->vendor_name, CAIAQ_USB_STR_LEN);
@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
 
        setup_card(cdev);
        return 0;
+
+ err_kill_urb:
+       usb_kill_urb(&cdev->ep1_in_urb);
+       return err;
 }
 
 static int snd_probe(struct usb_interface *intf,
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index ab3c280a23d1..58d624938a9f 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -775,9 +775,10 @@ int line6_probe(struct usb_interface *interface,
        return 0;
 
  error:
-       if (line6->disconnect)
-               line6->disconnect(line6);
-       snd_card_free(card);
+       /* we can call disconnect callback here because no close-sync is
+        * needed yet at this point
+        */
+       line6_disconnect(interface);
        return ret;
 }
 EXPORT_SYMBOL_GPL(line6_probe);
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 49cd4a65e390..5ab9e0c89211 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -307,6 +307,9 @@ static int podhd_init(struct usb_line6 *line6,
 
        line6->disconnect = podhd_disconnect;
 
+       init_timer(&pod->startup_timer);
+       INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
+
        if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
                /* create sysfs entries: */
                err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
@@ -330,8 +333,6 @@ static int podhd_init(struct usb_line6 *line6,
        }
 
        /* init device and delay registering */
-       init_timer(&pod->startup_timer);
-       INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
        podhd_startup(pod);
        return 0;
 }
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index d09c28c1deaf..d82e3c81c258 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2228,6 +2228,9 @@ static int parse_audio_unit(struct mixer_build *state, 
int unitid)
 
 static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
 {
+       /* kill pending URBs */
+       snd_usb_mixer_disconnect(mixer);
+
        kfree(mixer->id_elems);
        if (mixer->urb) {
                kfree(mixer->urb->transfer_buffer);
@@ -2578,8 +2581,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int 
ctrlif,
 
 void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer)
 {
-       usb_kill_urb(mixer->urb);
-       usb_kill_urb(mixer->rc_urb);
+       if (mixer->disconnected)
+               return;
+       if (mixer->urb)
+               usb_kill_urb(mixer->urb);
+       if (mixer->rc_urb)
+               usb_kill_urb(mixer->rc_urb);
+       mixer->disconnected = true;
 }
 
 #ifdef CONFIG_PM
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 2b4b067646ab..545d99b09706 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -22,6 +22,8 @@ struct usb_mixer_interface {
        struct urb *rc_urb;
        struct usb_ctrlrequest *rc_setup_packet;
        u8 rc_buffer[6];
+
+       bool disconnected;
 };
 
 #define MAX_CHANNELS   16      /* max logical channels */

Reply via email to