diff --git a/Makefile b/Makefile
index ba34e4e77d96..375cfa8a374e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 18
-SUBLEVEL = 105
+SUBLEVEL = 106
 EXTRAVERSION =
 NAME = Diseased Newt
 
diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi 
b/arch/arm/boot/dts/at91sam9g25.dtsi
index 17b879990914..d69cfb540a07 100644
--- a/arch/arm/boot/dts/at91sam9g25.dtsi
+++ b/arch/arm/boot/dts/at91sam9g25.dtsi
@@ -20,7 +20,7 @@
                                atmel,mux-mask = <
                                      /*    A         B          C     */
                                       0xffffffff 0xffe0399f 0xc000001c  /* 
pioA */
-                                      0x0007ffff 0x8000fe3f 0x00000000  /* 
pioB */
+                                      0x0007ffff 0x00047e3f 0x00000000  /* 
pioB */
                                       0x80000000 0x07c0ffff 0xb83fffff  /* 
pioC */
                                       0x003fffff 0x003f8000 0x00000000  /* 
pioD */
                                      >;
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 7b0e5462ca51..1e178c4ae06f 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -178,7 +178,7 @@
 1:     PTR_ADDIU       a0, 1                   /* fill bytewise */
        R10KCBARRIER(0(ra))
        bne             t1, a0, 1b
-       sb              a1, -1(a0)
+        EX(sb, a1, -1(a0), .Lsmall_fixup\@)
 
 2:     jr              ra                      /* done */
        move            a2, zero
@@ -204,13 +204,18 @@
        PTR_L           t0, TI_TASK($28)
        andi            a2, STORMASK
        LONG_L          t0, THREAD_BUADDR(t0)
-       LONG_ADDU       a2, t1
+       LONG_ADDU       a2, a0
        jr              ra
        LONG_SUBU       a2, t0
 
 .Llast_fixup\@:
        jr              ra
-       andi            v1, a2, STORMASK
+        nop
+
+.Lsmall_fixup\@:
+       PTR_SUBU        a2, t1, a0
+       jr              ra
+        PTR_ADDIU      a2, 1
 
        .endm
 
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index dba508fe1683..4f7060ec6875 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -648,6 +648,10 @@ static int match_pci_device(struct device *dev, int index,
                                        (modpath->mod == PCI_FUNC(devfn)));
        }
 
+       /* index might be out of bounds for bc[] */
+       if (index >= 6)
+               return 0;
+
        id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
        return (modpath->bc[index] == id);
 }
diff --git a/arch/powerpc/include/asm/barrier.h 
b/arch/powerpc/include/asm/barrier.h
index bab79a110c7b..7c63ec5d4fa9 100644
--- a/arch/powerpc/include/asm/barrier.h
+++ b/arch/powerpc/include/asm/barrier.h
@@ -39,7 +39,8 @@
 
 #ifdef CONFIG_SMP
 
-#ifdef __SUBARCH_HAS_LWSYNC
+/* The sub-arch has lwsync */
+#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
 #    define SMPWMB      LWSYNC
 #else
 #    define SMPWMB      eieio
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9124b0ede1fc..e6bc95da0e13 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -801,6 +801,9 @@ typedef struct oppanel_line {
        uint64_t        line_len;
 } oppanel_line_t;
 
+/* Default time to sleep or delay between OPAL_BUSY/OPAL_BUSY_EVENT loops */
+#define OPAL_BUSY_DELAY_MS     10
+
 /* /sys/firmware/opal */
 extern struct kobject *opal_kobj;
 
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
index e682a7143edb..e344d98239a7 100644
--- a/arch/powerpc/include/asm/synch.h
+++ b/arch/powerpc/include/asm/synch.h
@@ -5,10 +5,6 @@
 #include <linux/stringify.h>
 #include <asm/feature-fixups.h>
 
-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
-#define __SUBARCH_HAS_LWSYNC
-#endif
-
 #ifndef __ASSEMBLY__
 extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
 extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
diff --git a/arch/powerpc/lib/feature-fixups.c 
b/arch/powerpc/lib/feature-fixups.c
index 7ce3870d7ddd..cd0b7bc34cef 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -52,7 +52,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned 
int *dest,
                unsigned int *target = (unsigned int *)branch_target(src);
 
                /* Branch within the section doesn't need translating */
-               if (target < alt_start || target >= alt_end) {
+               if (target < alt_start || target > alt_end) {
                        instr = translate_branch(dest, src);
                        if (!instr)
                                return 1;
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c 
b/arch/powerpc/platforms/powernv/opal-nvram.c
index f9896fd5d04a..f3b2f6f29716 100644
--- a/arch/powerpc/platforms/powernv/opal-nvram.c
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -11,6 +11,7 @@
 
 #define DEBUG
 
+#include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/of.h>
@@ -55,9 +56,17 @@ static ssize_t opal_nvram_write(char *buf, size_t count, 
loff_t *index)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_write_nvram(__pa(buf), count, off);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               }
        }
+
+       if (rc)
+               return -EIO;
+
        *index += count;
        return count;
 }
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index c952b981e4f2..f7ace92bb1f6 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -326,7 +326,7 @@ static void hypfs_kill_super(struct super_block *sb)
 
        if (sb->s_root)
                hypfs_delete_tree(sb->s_root);
-       if (sb_info->update_file)
+       if (sb_info && sb_info->update_file)
                hypfs_remove(sb_info->update_file);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index f5ec05984364..ee2ca1bcfdba 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -808,6 +808,7 @@ static ssize_t reipl_generic_loadparm_store(struct 
ipl_parameter_block *ipb,
        /* copy and convert to ebcdic */
        memcpy(ipb->hdr.loadparm, buf, lp_len);
        ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
+       ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID;
        return len;
 }
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6fa0efa48cc5..4ba5c7e4e254 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -704,7 +704,7 @@ retry:
 
 static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
 {
-       const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
+       const int nbits_max = r->poolinfo->poolwords * 32;
 
        /* Cap the value to avoid overflows */
        nbits = min(nbits,  nbits_max);
diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
index 8bccf4ecdab6..9ff4ea63932d 100644
--- a/drivers/clk/mvebu/armada-38x.c
+++ b/drivers/clk/mvebu/armada-38x.c
@@ -46,10 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem 
*sar)
 }
 
 static const u32 armada_38x_cpu_frequencies[] __initconst = {
-       0, 0, 0, 0,
-       1066 * 1000 * 1000, 0, 0, 0,
+       666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
+       1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
        1332 * 1000 * 1000, 0, 0, 0,
-       1600 * 1000 * 1000,
+       1600 * 1000 * 1000, 0, 0, 0,
+       1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -75,11 +76,11 @@ static const struct coreclk_ratio 
armada_38x_coreclk_ratios[] __initconst = {
 };
 
 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
-       {0, 1}, {0, 1}, {0, 1}, {0, 1},
-       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {1, 2}, {0, 1},
+       {1, 2}, {0, 1}, {1, 2}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
-       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {1, 2},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst 
= {
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
-       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {7, 15},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 2113869e8678..c8509c9992f1 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -5894,9 +5894,9 @@ static void si_set_pcie_lane_width_in_smc(struct 
radeon_device *rdev,
 {
        u32 lane_width;
        u32 new_lane_width =
-               (radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> 
ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+               ((radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> 
ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
        u32 current_lane_width =
-               (radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) 
>> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+               ((radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) 
>> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
 
        if (new_lane_width != current_lane_width) {
                radeon_set_pcie_lanes(rdev, new_lane_width);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 9c2d7c23f296..c0c4df198725 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -197,6 +197,11 @@ static ssize_t hidraw_get_report(struct file *file, char 
__user *buffer, size_t
        int ret = 0, len;
        unsigned char report_number;
 
+       if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+               ret = -ENODEV;
+               goto out;
+       }
+
        dev = hidraw_table[minor]->hid;
 
        if (!dev->ll_driver->raw_request) {
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 462b0a383353..7f2c1c35cf55 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -136,10 +136,10 @@ struct i2c_hid {
                                                   * register of the HID
                                                   * descriptor. */
        unsigned int            bufsize;        /* i2c buffer size */
-       char                    *inbuf;         /* Input buffer */
-       char                    *rawbuf;        /* Raw Input buffer */
-       char                    *cmdbuf;        /* Command buffer */
-       char                    *argsbuf;       /* Command arguments buffer */
+       u8                      *inbuf;         /* Input buffer */
+       u8                      *rawbuf;        /* Raw Input buffer */
+       u8                      *cmdbuf;        /* Command buffer */
+       u8                      *argsbuf;       /* Command arguments buffer */
 
        unsigned long           flags;          /* device flags */
 
@@ -373,7 +373,8 @@ static int i2c_hid_hwreset(struct i2c_client *client)
 
 static void i2c_hid_get_input(struct i2c_hid *ihid)
 {
-       int ret, ret_size;
+       int ret;
+       u32 ret_size;
        int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
 
        if (size > ihid->bufsize)
@@ -398,7 +399,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
                return;
        }
 
-       if (ret_size > size) {
+       if ((ret_size > size) || (ret_size <= 2)) {
                dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
                        __func__, size, ret_size);
                return;
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index ca0a43ad4ec8..089391b2d0a1 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -101,7 +101,7 @@ static int get_v4l2_window32(struct v4l2_window __user *kp,
 static int put_v4l2_window32(struct v4l2_window __user *kp,
                             struct v4l2_window32 __user *up)
 {
-       struct v4l2_clip __user *kclips = kp->clips;
+       struct v4l2_clip __user *kclips;
        struct v4l2_clip32 __user *uclips;
        compat_caddr_t p;
        u32 clipcount;
@@ -116,6 +116,8 @@ static int put_v4l2_window32(struct v4l2_window __user *kp,
        if (!clipcount)
                return 0;
 
+       if (get_user(kclips, &kp->clips))
+               return -EFAULT;
        if (get_user(p, &up->clips))
                return -EFAULT;
        uclips = compat_ptr(p);
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 76e8bce6f46e..ad572a0f2124 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -368,9 +368,9 @@ static void jz4740_mmc_set_irq_enabled(struct 
jz4740_mmc_host *host,
                host->irq_mask &= ~irq;
        else
                host->irq_mask |= irq;
-       spin_unlock_irqrestore(&host->lock, flags);
 
        writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
+       spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 8876c7d3d712..06482fa3eee3 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -322,7 +322,7 @@ static int ubiblock_open(struct block_device *bdev, fmode_t 
mode)
         * in any case.
         */
        if (mode & FMODE_WRITE) {
-               ret = -EPERM;
+               ret = -EROFS;
                goto out_unlock;
        }
 
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index c3db383a9000..7bbd11e25f23 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -905,6 +905,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
                return -EINVAL;
        }
 
+       /*
+        * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes.
+        * MLC NAND is different and needs special care, otherwise UBI or UBIFS
+        * will die soon and you will lose all your data.
+        */
+       if (mtd->type == MTD_MLCNANDFLASH) {
+               pr_err("ubi: refuse attaching mtd%d - MLC NAND is not 
supported\n",
+                       mtd->index);
+               return -EINVAL;
+       }
+
        if (ubi_num == UBI_DEV_NUM_AUTO) {
                /* Search for an empty slot in the @ubi_devices array */
                for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
index 27ed25252aac..cfd81eb1b532 100644
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp, unsigned char 
*icp, int isize)
                if(x < 0 || x > comp->rslot_limit)
                        goto bad;
 
+               /* Check if the cstate is initialized */
+               if (!comp->rstate[x].initialized)
+                       goto bad;
+
                comp->flags &=~ SLF_TOSS;
                comp->recv_current = x;
        } else {
@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, 
int isize)
        if (cs->cs_tcp.doff > 5)
          memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), 
(cs->cs_tcp.doff - 5) * 4);
        cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
+       cs->initialized = true;
        /* Put headers back on packet
         * Neither header checksum is recalculated
         */
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 824ae807ea80..9967733a397e 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -2067,7 +2067,10 @@ static void netback_changed(struct xenbus_device *dev,
        case XenbusStateInitialised:
        case XenbusStateReconfiguring:
        case XenbusStateReconfigured:
+               break;
+
        case XenbusStateUnknown:
+               wake_up_all(&module_unload_q);
                break;
 
        case XenbusStateInitWait:
@@ -2314,7 +2317,9 @@ static int xennet_remove(struct xenbus_device *dev)
                xenbus_switch_state(dev, XenbusStateClosing);
                wait_event(module_unload_q,
                           xenbus_read_driver_state(dev->otherend) ==
-                          XenbusStateClosing);
+                          XenbusStateClosing ||
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateUnknown);
 
                xenbus_switch_state(dev, XenbusStateClosed);
                wait_event(module_unload_q,
diff --git a/drivers/pci/hotplug/acpiphp_glue.c 
b/drivers/pci/hotplug/acpiphp_glue.c
index b60309ee80ed..031f64da6151 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -587,6 +587,7 @@ static unsigned int get_slot_status(struct acpiphp_slot 
*slot)
 {
        unsigned long long sta = 0;
        struct acpiphp_func *func;
+       u32 dvid;
 
        list_for_each_entry(func, &slot->funcs, sibling) {
                if (func->flags & FUNC_HAS_STA) {
@@ -597,19 +598,27 @@ static unsigned int get_slot_status(struct acpiphp_slot 
*slot)
                        if (ACPI_SUCCESS(status) && sta)
                                break;
                } else {
-                       u32 dvid;
-
-                       pci_bus_read_config_dword(slot->bus,
-                                                 PCI_DEVFN(slot->device,
-                                                           func->function),
-                                                 PCI_VENDOR_ID, &dvid);
-                       if (dvid != 0xffffffff) {
+                       if (pci_bus_read_dev_vendor_id(slot->bus,
+                                       PCI_DEVFN(slot->device, func->function),
+                                       &dvid, 0)) {
                                sta = ACPI_STA_ALL;
                                break;
                        }
                }
        }
 
+       if (!sta) {
+               /*
+                * Check for the slot itself since it may be that the
+                * ACPI slot is a device below PCIe upstream port so in
+                * that case it may not even be reachable yet.
+                */
+               if (pci_bus_read_dev_vendor_id(slot->bus,
+                               PCI_DEVFN(slot->device, 0), &dvid, 0)) {
+                       sta = ACPI_STA_ALL;
+               }
+       }
+
        return (unsigned int)sta;
 }
 
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 848e3b64ea6e..fb7298920c8c 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -126,7 +126,7 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned 
int ccq)
 static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
                        int start, int count, int auto_ack)
 {
-       int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
+       int rc, tmp_count = count, tmp_start = start, nr = q->nr;
        unsigned int ccq = 0;
 
        qperf_inc(q, eqbs);
@@ -149,14 +149,7 @@ again:
                qperf_inc(q, eqbs_partial);
                DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
                        tmp_count);
-               /*
-                * Retry once, if that fails bail out and process the
-                * extracted buffers before trying again.
-                */
-               if (!retried++)
-                       goto again;
-               else
-                       return count - tmp_count;
+               return count - tmp_count;
        }
 
        DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
@@ -212,7 +205,10 @@ again:
        return 0;
 }
 
-/* returns number of examined buffers and their common state in *state */
+/*
+ * Returns number of examined buffers and their common state in *state.
+ * Requested number of buffers-to-examine must be > 0.
+ */
 static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
                                 unsigned char *state, unsigned int count,
                                 int auto_ack, int merge_pending)
@@ -223,17 +219,23 @@ static inline int get_buf_states(struct qdio_q *q, 
unsigned int bufnr,
        if (is_qebsm(q))
                return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
 
-       for (i = 0; i < count; i++) {
-               if (!__state) {
-                       __state = q->slsb.val[bufnr];
-                       if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
-                               __state = SLSB_P_OUTPUT_EMPTY;
-               } else if (merge_pending) {
-                       if ((q->slsb.val[bufnr] & __state) != __state)
-                               break;
-               } else if (q->slsb.val[bufnr] != __state)
-                       break;
+       /* get initial state: */
+       __state = q->slsb.val[bufnr];
+       if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
+               __state = SLSB_P_OUTPUT_EMPTY;
+
+       for (i = 1; i < count; i++) {
                bufnr = next_buf(bufnr);
+
+               /* merge PENDING into EMPTY: */
+               if (merge_pending &&
+                   q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING &&
+                   __state == SLSB_P_OUTPUT_EMPTY)
+                       continue;
+
+               /* stop if next state differs from initial state: */
+               if (q->slsb.val[bufnr] != __state)
+                       break;
        }
        *state = __state;
        return i;
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 5a1f1070b702..5a0e4a8ada40 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -493,6 +493,9 @@ static int imx_thermal_probe(struct platform_device *pdev)
        if (data->irq < 0)
                return data->irq;
 
+       data->irq_enabled = true;
+       data->mode = THERMAL_DEVICE_ENABLED;
+
        ret = devm_request_threaded_irq(&pdev->dev, data->irq,
                        imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
                        0, "imx_thermal", data);
@@ -576,9 +579,6 @@ static int imx_thermal_probe(struct platform_device *pdev)
        regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
        regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
 
-       data->irq_enabled = true;
-       data->mode = THERMAL_DEVICE_ENABLED;
-
        return 0;
 }
 
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index c68fe1222c16..5f3c4f45ab65 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -627,6 +627,7 @@ static const struct dev_pm_ops nhi_pm_ops = {
                                            * we just disable hotplug, the
                                            * pci-tunnels stay alive.
                                            */
+       .thaw_noirq = nhi_resume_noirq,
        .restore_noirq = nhi_resume_noirq,
 };
 
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 358ca8dd784f..a5240b4d7ab9 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -208,8 +208,13 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
        if (!udev->parent)
                rc = hcd_bus_suspend(udev, msg);
 
-       /* Non-root devices don't need to do anything for FREEZE or PRETHAW */
-       else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+       /*
+        * Non-root USB2 devices don't need to do anything for FREEZE
+        * or PRETHAW. USB3 devices don't support global suspend and
+        * needs to be selectively suspended.
+        */
+       else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+                && (udev->speed < USB_SPEED_SUPER))
                rc = 0;
        else
                rc = usb_port_suspend(udev, msg);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index a36cf66302fb..489e1c0dba29 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -143,7 +143,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
        ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
        if (ret) {
                dev_err(dev, "couldn't add resources to dwc3 device\n");
-               return ret;
+               goto err3;
        }
 
        pci_set_drvdata(pci, glue);
diff --git a/drivers/usb/musb/musb_gadget_ep0.c 
b/drivers/usb/musb/musb_gadget_ep0.c
index 2af45a0c8930..a4b991992595 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -114,15 +114,19 @@ static int service_tx_status_request(
                }
 
                is_in = epnum & USB_DIR_IN;
-               if (is_in) {
-                       epnum &= 0x0f;
+               epnum &= 0x0f;
+               if (epnum >= MUSB_C_NUM_EPS) {
+                       handled = -EINVAL;
+                       break;
+               }
+
+               if (is_in)
                        ep = &musb->endpoints[epnum].ep_in;
-               } else {
+               else
                        ep = &musb->endpoints[epnum].ep_out;
-               }
                regs = musb->endpoints[epnum].regs;
 
-               if (epnum >= MUSB_C_NUM_EPS || !ep->desc) {
+               if (!ep->desc) {
                        handled = -EINVAL;
                        break;
                }
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 016bd9355190..aa93df5833dc 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -450,7 +450,7 @@ static bool watchdog_is_running(void)
 
        is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
                && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF)
-                       & F71808FG_FLAG_WD_EN);
+                       & BIT(F71808FG_FLAG_WD_EN));
 
        superio_exit(watchdog.sioaddr);
 
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 21b5bb13af65..9ec171821f3c 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -753,7 +753,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct 
dentry *dentry, umode_t m
 
        autofs4_del_active(dentry);
 
-       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555);
+       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode);
        if (!inode)
                return -ENOMEM;
        d_add(dentry, inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c2434d72681e..859af265ae1b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3975,6 +3975,12 @@ struct inode *ext4_iget(struct super_block *sb, unsigned 
long ino)
                goto bad_inode;
        raw_inode = ext4_raw_inode(&iloc);
 
+       if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
+               EXT4_ERROR_INODE(inode, "root inode unallocated");
+               ret = -EUCLEAN;
+               goto bad_inode;
+       }
+
        if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
                ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
                if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index cc0a2298099d..deaf31a7a758 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2093,6 +2093,8 @@ static int ext4_check_descriptors(struct super_block *sb,
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
                                 "Block bitmap for group %u overlaps "
                                 "superblock", i);
+                       if (!(sb->s_flags & MS_RDONLY))
+                               return 0;
                }
                if (block_bitmap < first_block || block_bitmap > last_block) {
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2105,6 +2107,8 @@ static int ext4_check_descriptors(struct super_block *sb,
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
                                 "Inode bitmap for group %u overlaps "
                                 "superblock", i);
+                       if (!(sb->s_flags & MS_RDONLY))
+                               return 0;
                }
                if (inode_bitmap < first_block || inode_bitmap > last_block) {
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -2117,6 +2121,8 @@ static int ext4_check_descriptors(struct super_block *sb,
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
                                 "Inode table for group %u overlaps "
                                 "superblock", i);
+                       if (!(sb->s_flags & MS_RDONLY))
+                               return 0;
                }
                if (inode_table < first_block ||
                    inode_table + sbi->s_itb_per_group - 1 > last_block) {
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 985e95b9b4ef..2dc76fe6cd10 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -923,7 +923,7 @@ out:
 }
 
 /*
- * This is a variaon of __jbd2_update_log_tail which checks for validity of
+ * This is a variation of __jbd2_update_log_tail which checks for validity of
  * provided log tail and locks j_checkpoint_mutex. So it is safe against races
  * with other threads updating log tail.
  */
@@ -1399,6 +1399,9 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, 
tid_t tail_tid,
        journal_superblock_t *sb = journal->j_superblock;
        int ret;
 
+       if (is_journal_aborted(journal))
+               return -EIO;
+
        BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
        jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n",
                  tail_block, tail_tid);
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 0918f0e2e266..10902f70883d 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -345,7 +345,7 @@ static void jffs2_put_super (struct super_block *sb)
 static void jffs2_kill_sb(struct super_block *sb)
 {
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-       if (!(sb->s_flags & MS_RDONLY))
+       if (c && !(sb->s_flags & MS_RDONLY))
                jffs2_stop_garbage_collect_thread(c);
        kill_mtd_super(sb);
        kfree(c);
diff --git a/fs/namespace.c b/fs/namespace.c
index d0cd3f4012ec..ded3f1edd7f7 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -944,7 +944,8 @@ static struct mount *clone_mnt(struct mount *old, struct 
dentry *root,
                        goto out_free;
        }
 
-       mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED);
+       mnt->mnt.mnt_flags = old->mnt.mnt_flags;
+       mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
        /* Don't allow unprivileged users to change mount flags */
        if (flag & CL_UNPRIVILEGED) {
                mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f6298b974316..62959ac5a5b5 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(struct fsnotify_mark 
*inode_mark,
                                       u32 event_mask,
                                       void *data, int data_type)
 {
-       __u32 marks_mask, marks_ignored_mask;
+       __u32 marks_mask = 0, marks_ignored_mask = 0;
        struct path *path = data;
 
        pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(struct 
fsnotify_mark *inode_mark,
            !S_ISDIR(path->dentry->d_inode->i_mode))
                return false;
 
-       if (inode_mark && vfsmnt_mark) {
-               marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
-               marks_ignored_mask = (vfsmnt_mark->ignored_mask | 
inode_mark->ignored_mask);
-       } else if (inode_mark) {
-               /*
-                * if the event is for a child and this inode doesn't care about
-                * events on the child, don't send it!
-                */
-               if ((event_mask & FS_EVENT_ON_CHILD) &&
-                   !(inode_mark->mask & FS_EVENT_ON_CHILD))
-                       return false;
-               marks_mask = inode_mark->mask;
-               marks_ignored_mask = inode_mark->ignored_mask;
-       } else if (vfsmnt_mark) {
-               marks_mask = vfsmnt_mark->mask;
-               marks_ignored_mask = vfsmnt_mark->ignored_mask;
-       } else {
-               BUG();
+       /*
+        * if the event is for a child and this inode doesn't care about
+        * events on the child, don't send it!
+        */
+       if (inode_mark &&
+           (!(event_mask & FS_EVENT_ON_CHILD) ||
+            (inode_mark->mask & FS_EVENT_ON_CHILD))) {
+               marks_mask |= inode_mark->mask;
+               marks_ignored_mask |= inode_mark->ignored_mask;
+       }
+
+       if (vfsmnt_mark) {
+               marks_mask |= vfsmnt_mark->mask;
+               marks_ignored_mask |= vfsmnt_mark->ignored_mask;
        }
 
        if (S_ISDIR(path->dentry->d_inode->i_mode) &&
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index e503effd284d..135f4138f80d 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2643,7 +2643,7 @@ static int journal_init_dev(struct super_block *super,
        if (IS_ERR(journal->j_dev_bd)) {
                result = PTR_ERR(journal->j_dev_bd);
                journal->j_dev_bd = NULL;
-               reiserfs_warning(super,
+               reiserfs_warning(super, "sh-457",
                                 "journal_init_dev: Cannot open '%s': %i",
                                 jdev_name, result);
                return result;
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 106bf20629ce..2f7a74e73b7d 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1726,8 +1726,11 @@ static void ubifs_remount_ro(struct ubifs_info *c)
 
        dbg_save_space_info(c);
 
-       for (i = 0; i < c->jhead_cnt; i++)
-               ubifs_wbuf_sync(&c->jheads[i].wbuf);
+       for (i = 0; i < c->jhead_cnt; i++) {
+               err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+               if (err)
+                       ubifs_ro_mode(c, err);
+       }
 
        c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
        c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
@@ -1794,8 +1797,11 @@ static void ubifs_put_super(struct super_block *sb)
                        int err;
 
                        /* Synchronize write-buffers */
-                       for (i = 0; i < c->jhead_cnt; i++)
-                               ubifs_wbuf_sync(&c->jheads[i].wbuf);
+                       for (i = 0; i < c->jhead_cnt; i++) {
+                               err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+                               if (err)
+                                       ubifs_ro_mode(c, err);
+                       }
 
                        /*
                         * We are being cleanly unmounted which means the
diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h
index 8716d5942b65..8fcf8908a694 100644
--- a/include/net/slhc_vj.h
+++ b/include/net/slhc_vj.h
@@ -127,6 +127,7 @@ typedef __u32 int32;
  */
 struct cstate {
        byte_t  cs_this;        /* connection id number (xmit) */
+       bool    initialized;    /* true if initialized */
        struct cstate *next;    /* next in ring (xmit) */
        struct iphdr cs_ip;     /* ip/tcp hdr from most recent packet */
        struct tcphdr cs_tcp;
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 760c969d885d..12bbf8c81112 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime {
        char *buffer;                           /* vmallocated period */
        size_t buffer_used;                     /* used length from period 
buffer */
        struct mutex params_lock;
+       atomic_t rw_ref;                /* concurrent read/write accesses */
 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
        struct snd_pcm_plugin *plugin_first;
        struct snd_pcm_plugin *plugin_last;
diff --git a/kernel/resource.c b/kernel/resource.c
index e3011e1a5c8d..d9c7d5d77c8a 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -590,7 +590,8 @@ static int __find_resource(struct resource *root, struct 
resource *old,
                        alloc.start = 
constraint->alignf(constraint->alignf_data, &avail,
                                        size, constraint->align);
                        alloc.end = alloc.start + size - 1;
-                       if (resource_contains(&avail, &alloc)) {
+                       if (alloc.start <= alloc.end &&
+                           resource_contains(&avail, &alloc)) {
                                new->start = alloc.start;
                                new->end = alloc.end;
                                return 0;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 2d12b76b5a64..d8cfd7048721 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry *pipe_dentry)
        struct dentry *clnt_dir = pipe_dentry->d_parent;
        struct dentry *gssd_dir = clnt_dir->d_parent;
 
+       dget(pipe_dentry);
        __rpc_rmpipe(clnt_dir->d_inode, pipe_dentry);
        __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1);
        __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 520c6bed5d2b..e3c5fee7f838 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -833,8 +833,25 @@ static int choose_rate(struct snd_pcm_substream *substream,
        return snd_pcm_hw_param_near(substream, params, 
SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
 }
 
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
-                                    bool trylock)
+/* parameter locking: returns immediately if tried during streaming */
+static int lock_params(struct snd_pcm_runtime *runtime)
+{
+       if (mutex_lock_interruptible(&runtime->oss.params_lock))
+               return -ERESTARTSYS;
+       if (atomic_read(&runtime->oss.rw_ref)) {
+               mutex_unlock(&runtime->oss.params_lock);
+               return -EBUSY;
+       }
+       return 0;
+}
+
+static void unlock_params(struct snd_pcm_runtime *runtime)
+{
+       mutex_unlock(&runtime->oss.params_lock);
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream 
*substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_pcm_hw_params *params, *sparams;
@@ -848,12 +865,9 @@ static int snd_pcm_oss_change_params(struct 
snd_pcm_substream *substream,
        struct snd_mask sformat_mask;
        struct snd_mask mask;
 
-       if (trylock) {
-               if (!(mutex_trylock(&runtime->oss.params_lock)))
-                       return -EAGAIN;
-       } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
-               return -EINTR;
-       sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
+       if (!runtime->oss.params)
+               return 0;
+       sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
        params = kmalloc(sizeof(*params), GFP_KERNEL);
        sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
        if (!sw_params || !params || !sparams) {
@@ -992,7 +1006,6 @@ static int snd_pcm_oss_change_params(struct 
snd_pcm_substream *substream,
                goto failure;
        }
 
-       memset(sw_params, 0, sizeof(*sw_params));
        if (runtime->oss.trigger) {
                sw_params->start_threshold = 1;
        } else {
@@ -1080,6 +1093,23 @@ failure:
        kfree(sw_params);
        kfree(params);
        kfree(sparams);
+       return err;
+}
+
+/* this one takes the lock by itself */
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
+                                    bool trylock)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       int err;
+
+       if (trylock) {
+               if (!(mutex_trylock(&runtime->oss.params_lock)))
+                       return -EAGAIN;
+       } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
+               return -ERESTARTSYS;
+
+       err = snd_pcm_oss_change_params_locked(substream);
        mutex_unlock(&runtime->oss.params_lock);
        return err;
 }
@@ -1108,6 +1138,10 @@ static int snd_pcm_oss_get_active_substream(struct 
snd_pcm_oss_file *pcm_oss_fil
        return 0;
 }
 
+/* call with params_lock held */
+/* NOTE: this always call PREPARE unconditionally no matter whether
+ * runtime->oss.prepare is set or not
+ */
 static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
 {
        int err;
@@ -1132,14 +1166,35 @@ static int snd_pcm_oss_make_ready(struct 
snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime;
        int err;
 
-       if (substream == NULL)
-               return 0;
        runtime = substream->runtime;
        if (runtime->oss.params) {
                err = snd_pcm_oss_change_params(substream, false);
                if (err < 0)
                        return err;
        }
+       if (runtime->oss.prepare) {
+               if (mutex_lock_interruptible(&runtime->oss.params_lock))
+                       return -ERESTARTSYS;
+               err = snd_pcm_oss_prepare(substream);
+               mutex_unlock(&runtime->oss.params_lock);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+/* call with params_lock held */
+static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime;
+       int err;
+
+       runtime = substream->runtime;
+       if (runtime->oss.params) {
+               err = snd_pcm_oss_change_params_locked(substream);
+               if (err < 0)
+                       return err;
+       }
        if (runtime->oss.prepare) {
                err = snd_pcm_oss_prepare(substream);
                if (err < 0)
@@ -1368,13 +1423,15 @@ static ssize_t snd_pcm_oss_write1(struct 
snd_pcm_substream *substream, const cha
        if (atomic_read(&substream->mmap_count))
                return -ENXIO;
 
-       if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-               return tmp;
+       atomic_inc(&runtime->oss.rw_ref);
        while (bytes > 0) {
                if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
                        tmp = -ERESTARTSYS;
                        break;
                }
+               tmp = snd_pcm_oss_make_ready_locked(substream);
+               if (tmp < 0)
+                       goto err;
                if (bytes < runtime->oss.period_bytes || 
runtime->oss.buffer_used > 0) {
                        tmp = bytes;
                        if (tmp + runtime->oss.buffer_used > 
runtime->oss.period_bytes)
@@ -1430,6 +1487,7 @@ static ssize_t snd_pcm_oss_write1(struct 
snd_pcm_substream *substream, const cha
                }
                tmp = 0;
        }
+       atomic_dec(&runtime->oss.rw_ref);
        return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1475,13 +1533,15 @@ static ssize_t snd_pcm_oss_read1(struct 
snd_pcm_substream *substream, char __use
        if (atomic_read(&substream->mmap_count))
                return -ENXIO;
 
-       if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
-               return tmp;
+       atomic_inc(&runtime->oss.rw_ref);
        while (bytes > 0) {
                if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
                        tmp = -ERESTARTSYS;
                        break;
                }
+               tmp = snd_pcm_oss_make_ready_locked(substream);
+               if (tmp < 0)
+                       goto err;
                if (bytes < runtime->oss.period_bytes || 
runtime->oss.buffer_used > 0) {
                        if (runtime->oss.buffer_used == 0) {
                                tmp = snd_pcm_oss_read2(substream, 
runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1522,6 +1582,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream 
*substream, char __use
                }
                tmp = 0;
        }
+       atomic_dec(&runtime->oss.rw_ref);
        return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
@@ -1537,10 +1598,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file 
*pcm_oss_file)
                        continue;
                runtime = substream->runtime;
                snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
+               mutex_lock(&runtime->oss.params_lock);
                runtime->oss.prepare = 1;
                runtime->oss.buffer_used = 0;
                runtime->oss.prev_hw_ptr_period = 0;
                runtime->oss.period_ptr = 0;
+               mutex_unlock(&runtime->oss.params_lock);
        }
        return 0;
 }
@@ -1626,9 +1689,13 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                        goto __direct;
                if ((err = snd_pcm_oss_make_ready(substream)) < 0)
                        return err;
+               atomic_inc(&runtime->oss.rw_ref);
+               if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+                       atomic_dec(&runtime->oss.rw_ref);
+                       return -ERESTARTSYS;
+               }
                format = snd_pcm_oss_format_from(runtime->oss.format);
                width = snd_pcm_format_physical_width(format);
-               mutex_lock(&runtime->oss.params_lock);
                if (runtime->oss.buffer_used > 0) {
 #ifdef OSS_DEBUG
                        pcm_dbg(substream->pcm, "sync: buffer_used\n");
@@ -1638,10 +1705,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                                                   runtime->oss.buffer + 
runtime->oss.buffer_used,
                                                   size);
                        err = snd_pcm_oss_sync1(substream, 
runtime->oss.period_bytes);
-                       if (err < 0) {
-                               mutex_unlock(&runtime->oss.params_lock);
-                               return err;
-                       }
+                       if (err < 0)
+                               goto unlock;
                } else if (runtime->oss.period_ptr > 0) {
 #ifdef OSS_DEBUG
                        pcm_dbg(substream->pcm, "sync: period_ptr\n");
@@ -1651,10 +1716,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                                                   runtime->oss.buffer,
                                                   size * 8 / width);
                        err = snd_pcm_oss_sync1(substream, size);
-                       if (err < 0) {
-                               mutex_unlock(&runtime->oss.params_lock);
-                               return err;
-                       }
+                       if (err < 0)
+                               goto unlock;
                }
                /*
                 * The ALSA's period might be a bit large than OSS one.
@@ -1685,7 +1748,11 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                                snd_pcm_lib_writev(substream, buffers, size);
                        }
                }
+unlock:
                mutex_unlock(&runtime->oss.params_lock);
+               atomic_dec(&runtime->oss.rw_ref);
+               if (err < 0)
+                       return err;
                /*
                 * finish sync: drain the buffer
                 */
@@ -1696,7 +1763,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                substream->f_flags = saved_f_flags;
                if (err < 0)
                        return err;
+               mutex_lock(&runtime->oss.params_lock);
                runtime->oss.prepare = 1;
+               mutex_unlock(&runtime->oss.params_lock);
        }
 
        substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -1707,8 +1776,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file 
*pcm_oss_file)
                err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, 
NULL);
                if (err < 0)
                        return err;
+               mutex_lock(&runtime->oss.params_lock);
                runtime->oss.buffer_used = 0;
                runtime->oss.prepare = 1;
+               mutex_unlock(&runtime->oss.params_lock);
        }
        return 0;
 }
@@ -1720,6 +1791,8 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file 
*pcm_oss_file, int rate)
        for (idx = 1; idx >= 0; --idx) {
                struct snd_pcm_substream *substream = 
pcm_oss_file->streams[idx];
                struct snd_pcm_runtime *runtime;
+               int err;
+
                if (substream == NULL)
                        continue;
                runtime = substream->runtime;
@@ -1727,10 +1800,14 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file 
*pcm_oss_file, int rate)
                        rate = 1000;
                else if (rate > 192000)
                        rate = 192000;
+               err = lock_params(runtime);
+               if (err < 0)
+                       return err;
                if (runtime->oss.rate != rate) {
                        runtime->oss.params = 1;
                        runtime->oss.rate = rate;
                }
+               unlock_params(runtime);
        }
        return snd_pcm_oss_get_rate(pcm_oss_file);
 }
@@ -1755,13 +1832,19 @@ static int snd_pcm_oss_set_channels(struct 
snd_pcm_oss_file *pcm_oss_file, unsig
        for (idx = 1; idx >= 0; --idx) {
                struct snd_pcm_substream *substream = 
pcm_oss_file->streams[idx];
                struct snd_pcm_runtime *runtime;
+               int err;
+
                if (substream == NULL)
                        continue;
                runtime = substream->runtime;
+               err = lock_params(runtime);
+               if (err < 0)
+                       return err;
                if (runtime->oss.channels != channels) {
                        runtime->oss.params = 1;
                        runtime->oss.channels = channels;
                }
+               unlock_params(runtime);
        }
        return snd_pcm_oss_get_channels(pcm_oss_file);
 }
@@ -1834,6 +1917,7 @@ static int snd_pcm_oss_get_formats(struct 
snd_pcm_oss_file *pcm_oss_file)
 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int 
format)
 {
        int formats, idx;
+       int err;
        
        if (format != AFMT_QUERY) {
                formats = snd_pcm_oss_get_formats(pcm_oss_file);
@@ -1847,10 +1931,14 @@ static int snd_pcm_oss_set_format(struct 
snd_pcm_oss_file *pcm_oss_file, int for
                        if (substream == NULL)
                                continue;
                        runtime = substream->runtime;
+                       err = lock_params(runtime);
+                       if (err < 0)
+                               return err;
                        if (runtime->oss.format != format) {
                                runtime->oss.params = 1;
                                runtime->oss.format = format;
                        }
+                       unlock_params(runtime);
                }
        }
        return snd_pcm_oss_get_format(pcm_oss_file);
@@ -1870,8 +1958,6 @@ static int snd_pcm_oss_set_subdivide1(struct 
snd_pcm_substream *substream, int s
 {
        struct snd_pcm_runtime *runtime;
 
-       if (substream == NULL)
-               return 0;
        runtime = substream->runtime;
        if (subdivide == 0) {
                subdivide = runtime->oss.subdivision;
@@ -1895,9 +1981,17 @@ static int snd_pcm_oss_set_subdivide(struct 
snd_pcm_oss_file *pcm_oss_file, int
 
        for (idx = 1; idx >= 0; --idx) {
                struct snd_pcm_substream *substream = 
pcm_oss_file->streams[idx];
+               struct snd_pcm_runtime *runtime;
+
                if (substream == NULL)
                        continue;
-               if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 
0)
+               runtime = substream->runtime;
+               err = lock_params(runtime);
+               if (err < 0)
+                       return err;
+               err = snd_pcm_oss_set_subdivide1(substream, subdivide);
+               unlock_params(runtime);
+               if (err < 0)
                        return err;
        }
        return err;
@@ -1907,8 +2001,6 @@ static int snd_pcm_oss_set_fragment1(struct 
snd_pcm_substream *substream, unsign
 {
        struct snd_pcm_runtime *runtime;
 
-       if (substream == NULL)
-               return 0;
        runtime = substream->runtime;
        if (runtime->oss.subdivision || runtime->oss.fragshift)
                return -EINVAL;
@@ -1928,9 +2020,17 @@ static int snd_pcm_oss_set_fragment(struct 
snd_pcm_oss_file *pcm_oss_file, unsig
 
        for (idx = 1; idx >= 0; --idx) {
                struct snd_pcm_substream *substream = 
pcm_oss_file->streams[idx];
+               struct snd_pcm_runtime *runtime;
+
                if (substream == NULL)
                        continue;
-               if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
+               runtime = substream->runtime;
+               err = lock_params(runtime);
+               if (err < 0)
+                       return err;
+               err = snd_pcm_oss_set_fragment1(substream, val);
+               unlock_params(runtime);
+               if (err < 0)
                        return err;
        }
        return err;
@@ -2014,6 +2114,9 @@ static int snd_pcm_oss_set_trigger(struct 
snd_pcm_oss_file *pcm_oss_file, int tr
        }
        if (psubstream) {
                runtime = psubstream->runtime;
+               cmd = 0;
+               if (mutex_lock_interruptible(&runtime->oss.params_lock))
+                       return -ERESTARTSYS;
                if (trigger & PCM_ENABLE_OUTPUT) {
                        if (runtime->oss.trigger)
                                goto _skip1;
@@ -2031,13 +2134,19 @@ static int snd_pcm_oss_set_trigger(struct 
snd_pcm_oss_file *pcm_oss_file, int tr
                        cmd = SNDRV_PCM_IOCTL_DROP;
                        runtime->oss.prepare = 1;
                }
-               err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
-               if (err < 0)
-                       return err;
-       }
  _skip1:
+               mutex_unlock(&runtime->oss.params_lock);
+               if (cmd) {
+                       err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
+                       if (err < 0)
+                               return err;
+               }
+       }
        if (csubstream) {
                runtime = csubstream->runtime;
+               cmd = 0;
+               if (mutex_lock_interruptible(&runtime->oss.params_lock))
+                       return -ERESTARTSYS;
                if (trigger & PCM_ENABLE_INPUT) {
                        if (runtime->oss.trigger)
                                goto _skip2;
@@ -2052,11 +2161,14 @@ static int snd_pcm_oss_set_trigger(struct 
snd_pcm_oss_file *pcm_oss_file, int tr
                        cmd = SNDRV_PCM_IOCTL_DROP;
                        runtime->oss.prepare = 1;
                }
-               err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
-               if (err < 0)
-                       return err;
-       }
  _skip2:
+               mutex_unlock(&runtime->oss.params_lock);
+               if (cmd) {
+                       err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
+                       if (err < 0)
+                               return err;
+               }
+       }
        return 0;
 }
 
@@ -2308,6 +2420,7 @@ static void snd_pcm_oss_init_substream(struct 
snd_pcm_substream *substream,
        runtime->oss.maxfrags = 0;
        runtime->oss.subdivision = 0;
        substream->pcm_release = snd_pcm_oss_release_substream;
+       atomic_set(&runtime->oss.rw_ref, 0);
 }
 
 static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
index 09a89094dcf7..4e304a24924a 100644
--- a/sound/core/rawmidi_compat.c
+++ b/sound/core/rawmidi_compat.c
@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_compat(struct 
snd_rawmidi_file *rfile,
        struct snd_rawmidi_params params;
        unsigned int val;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(params.stream, &src->stream) ||
            get_user(params.buffer_size, &src->buffer_size) ||
            get_user(params.avail_min, &src->avail_min) ||
@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_compat(struct 
snd_rawmidi_file *rfile,
        params.no_active_sensing = val;
        switch (params.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                return snd_rawmidi_output_params(rfile->output, &params);
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                return snd_rawmidi_input_params(rfile->input, &params);
        }
        return -EINVAL;
@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_compat(struct 
snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
@@ -113,16 +117,18 @@ static int snd_rawmidi_ioctl_status_x32(struct 
snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 314eaece1b7d..ddf67da394de 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -54,10 +54,17 @@ struct ssm2602_priv {
  * using 2 wire for device control, so we cache them instead.
  * There is no point in caching the reset register
  */
-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
-       0x0097, 0x0097, 0x0079, 0x0079,
-       0x000a, 0x0008, 0x009f, 0x000a,
-       0x0000, 0x0000
+static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = {
+       { .reg = 0x00, .def = 0x0097 },
+       { .reg = 0x01, .def = 0x0097 },
+       { .reg = 0x02, .def = 0x0079 },
+       { .reg = 0x03, .def = 0x0079 },
+       { .reg = 0x04, .def = 0x000a },
+       { .reg = 0x05, .def = 0x0008 },
+       { .reg = 0x06, .def = 0x009f },
+       { .reg = 0x07, .def = 0x000a },
+       { .reg = 0x08, .def = 0x0000 },
+       { .reg = 0x09, .def = 0x0000 }
 };
 
 
@@ -620,8 +627,8 @@ const struct regmap_config ssm2602_regmap_config = {
        .volatile_reg = ssm2602_register_volatile,
 
        .cache_type = REGCACHE_RBTREE,
-       .reg_defaults_raw = ssm2602_reg,
-       .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg),
+       .reg_defaults = ssm2602_reg,
+       .num_reg_defaults = ARRAY_SIZE(ssm2602_reg),
 };
 EXPORT_SYMBOL_GPL(ssm2602_regmap_config);
 

Reply via email to