diff --git a/Makefile b/Makefile
index 900cd7c3a9ee..2f7a386b1751 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 59
+SUBLEVEL = 60
 EXTRAVERSION =
 NAME = Roaring Lionus
 
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 70963c845e96..fc0df0f6fe88 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -601,8 +601,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                break;
 #endif
        case KVM_CAP_PPC_HTM:
-               r = cpu_has_feature(CPU_FTR_TM_COMP) &&
-                   is_kvmppc_hv_enabled(kvm);
+               r = cpu_has_feature(CPU_FTR_TM_COMP) && hv_enabled;
                break;
        default:
                r = 0;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 08cd0bd3ebe5..3907439417e7 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -825,7 +825,7 @@ uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr)
 {
        uint32_t reference_clock, tmp;
        struct cgs_display_info info = {0};
-       struct cgs_mode_info mode_info;
+       struct cgs_mode_info mode_info = {0};
 
        info.mode_info = &mode_info;
 
@@ -3718,10 +3718,9 @@ int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
        uint32_t ref_clock;
        uint32_t refresh_rate = 0;
        struct cgs_display_info info = {0};
-       struct cgs_mode_info mode_info;
+       struct cgs_mode_info mode_info = {0};
 
        info.mode_info = &mode_info;
-
        cgs_get_active_displays_info(hwmgr->device, &info);
        num_active_displays = info.display_count;
 
@@ -3737,6 +3736,7 @@ int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
        frame_time_in_us = 1000000 / refresh_rate;
 
        pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
+
        data->frame_time_x2 = frame_time_in_us * 2 / 100;
 
        display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
diff --git a/drivers/input/mouse/elan_i2c_core.c 
b/drivers/input/mouse/elan_i2c_core.c
index 681dce15fbc8..b8c50d883b2c 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -1240,6 +1240,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
        { "ELAN0605", 0 },
        { "ELAN0609", 0 },
        { "ELAN060B", 0 },
+       { "ELAN0611", 0 },
        { "ELAN1000", 0 },
        { }
 };
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index abf09ac42ce4..339a0e2d2f86 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -230,13 +230,17 @@ static void parse_hid_report_descriptor(struct gtco 
*device, char * report,
 
        /* Walk  this report and pull out the info we need */
        while (i < length) {
-               prefix = report[i];
-
-               /* Skip over prefix */
-               i++;
+               prefix = report[i++];
 
                /* Determine data size and save the data in the proper variable 
*/
-               size = PREF_SIZE(prefix);
+               size = (1U << PREF_SIZE(prefix)) >> 1;
+               if (i + size > length) {
+                       dev_err(ddev,
+                               "Not enough data (need %d, have %d)\n",
+                               i + size, length);
+                       break;
+               }
+
                switch (size) {
                case 1:
                        data = report[i];
@@ -244,8 +248,7 @@ static void parse_hid_report_descriptor(struct gtco 
*device, char * report,
                case 2:
                        data16 = get_unaligned_le16(&report[i]);
                        break;
-               case 3:
-                       size = 4;
+               case 4:
                        data32 = get_unaligned_le32(&report[i]);
                        break;
                }
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 68ef0a4cd821..b0c80859f746 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -342,7 +342,7 @@ static int sun4i_can_start(struct net_device *dev)
 
        /* enter the selected mode */
        mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
-       if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK)
+       if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
                mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE;
        else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
                mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE;
@@ -811,7 +811,6 @@ static int sun4ican_probe(struct platform_device *pdev)
        priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
                                       CAN_CTRLMODE_LISTENONLY |
                                       CAN_CTRLMODE_LOOPBACK |
-                                      CAN_CTRLMODE_PRESUME_ACK |
                                       CAN_CTRLMODE_3_SAMPLES;
        priv->base = addr;
        priv->clk = clk;
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index d51e0c401b48..4224e066cb16 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -137,6 +137,7 @@ static inline bool kvaser_is_usbcan(const struct 
usb_device_id *id)
 #define CMD_RESET_ERROR_COUNTER                49
 #define CMD_TX_ACKNOWLEDGE             50
 #define CMD_CAN_ERROR_EVENT            51
+#define CMD_FLUSH_QUEUE_REPLY          68
 
 #define CMD_LEAF_USB_THROTTLE          77
 #define CMD_LEAF_LOG_MESSAGE           106
@@ -1301,6 +1302,11 @@ static void kvaser_usb_handle_message(const struct 
kvaser_usb *dev,
                        goto warn;
                break;
 
+       case CMD_FLUSH_QUEUE_REPLY:
+               if (dev->family != KVASER_LEAF)
+                       goto warn;
+               break;
+
        default:
 warn:          dev_warn(dev->udev->dev.parent,
                         "Unhandled message (%d)\n", msg->id);
@@ -1609,7 +1615,8 @@ static int kvaser_usb_close(struct net_device *netdev)
        if (err)
                netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
 
-       if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel))
+       err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel);
+       if (err)
                netdev_warn(netdev, "Cannot reset card, error %d\n", err);
 
        err = kvaser_usb_stop_chip(priv);
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index d7da81a875cf..c9af065feb28 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -476,7 +476,10 @@ static const struct i2c_device_id fan53555_id[] = {
                .name = "fan53555",
                .driver_data = FAN53555_VENDOR_FAIRCHILD
        }, {
-               .name = "syr82x",
+               .name = "syr827",
+               .driver_data = FAN53555_VENDOR_SILERGY
+       }, {
+               .name = "syr828",
                .driver_data = FAN53555_VENDOR_SILERGY
        },
        { },
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index bcc8f3dfd4c4..b3f9243cfed5 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -358,6 +358,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device 
*ccw_device)
 
        adapter->next_port_scan = jiffies;
 
+       adapter->erp_action.adapter = adapter;
+
        if (zfcp_qdio_setup(adapter))
                goto failed;
 
@@ -514,6 +516,9 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter 
*adapter, u64 wwpn,
        port->dev.groups = zfcp_port_attr_groups;
        port->dev.release = zfcp_port_release;
 
+       port->erp_action.adapter = adapter;
+       port->erp_action.port = port;
+
        if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
                kfree(port);
                goto err_out;
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 7ccfce559034..3b23d6754598 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -193,9 +193,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, 
u32 act_status,
                atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE,
                                &zfcp_sdev->status);
                erp_action = &zfcp_sdev->erp_action;
-               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
-               erp_action->port = port;
-               erp_action->sdev = sdev;
+               WARN_ON_ONCE(erp_action->port != port);
+               WARN_ON_ONCE(erp_action->sdev != sdev);
                if (!(atomic_read(&zfcp_sdev->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -208,8 +207,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, 
u32 act_status,
                zfcp_erp_action_dismiss_port(port);
                atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
                erp_action = &port->erp_action;
-               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
-               erp_action->port = port;
+               WARN_ON_ONCE(erp_action->port != port);
+               WARN_ON_ONCE(erp_action->sdev != NULL);
                if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
                break;
@@ -219,7 +218,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, 
u32 act_status,
                zfcp_erp_action_dismiss_adapter(adapter);
                atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
                erp_action = &adapter->erp_action;
-               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               WARN_ON_ONCE(erp_action->port != NULL);
+               WARN_ON_ONCE(erp_action->sdev != NULL);
                if (!(atomic_read(&adapter->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -229,7 +229,11 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int 
need, u32 act_status,
                return NULL;
        }
 
-       erp_action->adapter = adapter;
+       WARN_ON_ONCE(erp_action->adapter != adapter);
+       memset(&erp_action->list, 0, sizeof(erp_action->list));
+       memset(&erp_action->timer, 0, sizeof(erp_action->timer));
+       erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED;
+       erp_action->fsf_req_id = 0;
        erp_action->action = need;
        erp_action->status = act_status;
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 9bd9b9a29dfc..a9b8104b982e 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -115,10 +115,15 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
        struct zfcp_unit *unit;
        int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE;
 
+       zfcp_sdev->erp_action.adapter = adapter;
+       zfcp_sdev->erp_action.sdev = sdev;
+
        port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
        if (!port)
                return -ENXIO;
 
+       zfcp_sdev->erp_action.port = port;
+
        unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
        if (unit)
                put_device(&unit->dev);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 02dfbc1373e3..184c7db1e0ca 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -837,7 +837,7 @@ sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo)
 
        val = 0;
        list_for_each_entry(srp, &sfp->rq_list, entry) {
-               if (val > SG_MAX_QUEUE)
+               if (val >= SG_MAX_QUEUE)
                        break;
                rinfo[val].req_state = srp->done + 1;
                rinfo[val].problem =
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index 14f9dea3173f..7d629b4e1ecc 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -1215,7 +1215,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
                        goto qspi_probe_err;
                }
        } else {
-               goto qspi_probe_err;
+               goto qspi_resource_err;
        }
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
@@ -1237,7 +1237,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
                qspi->base[CHIP_SELECT]  = devm_ioremap_resource(dev, res);
                if (IS_ERR(qspi->base[CHIP_SELECT])) {
                        ret = PTR_ERR(qspi->base[CHIP_SELECT]);
-                       goto qspi_probe_err;
+                       goto qspi_resource_err;
                }
        }
 
@@ -1245,7 +1245,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
                                GFP_KERNEL);
        if (!qspi->dev_ids) {
                ret = -ENOMEM;
-               goto qspi_probe_err;
+               goto qspi_resource_err;
        }
 
        for (val = 0; val < num_irqs; val++) {
@@ -1334,8 +1334,9 @@ int bcm_qspi_probe(struct platform_device *pdev,
        bcm_qspi_hw_uninit(qspi);
        clk_disable_unprepare(qspi->clk);
 qspi_probe_err:
-       spi_master_put(master);
        kfree(qspi->dev_ids);
+qspi_resource_err:
+       spi_master_put(master);
        return ret;
 }
 /* probe function to be called by SoC specific platform driver probe */
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 4a02c5c7df0d..0722f75f1d6a 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -412,15 +412,25 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int 
slot_id, int suspend)
                                                     GFP_NOWAIT);
                        if (!command) {
                                spin_unlock_irqrestore(&xhci->lock, flags);
-                               xhci_free_command(xhci, cmd);
-                               return -ENOMEM;
+                               ret = -ENOMEM;
+                               goto cmd_cleanup;
+                       }
 
+                       ret = xhci_queue_stop_endpoint(xhci, command, slot_id,
+                                                      i, suspend);
+                       if (ret) {
+                               spin_unlock_irqrestore(&xhci->lock, flags);
+                               xhci_free_command(xhci, command);
+                               goto cmd_cleanup;
                        }
-                       xhci_queue_stop_endpoint(xhci, command, slot_id, i,
-                                                suspend);
                }
        }
-       xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+       ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+       if (ret) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               goto cmd_cleanup;
+       }
+
        xhci_ring_cmd_db(xhci);
        spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -431,6 +441,8 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int 
slot_id, int suspend)
                xhci_warn(xhci, "Timeout while waiting for stop endpoint 
command\n");
                ret = -ETIME;
        }
+
+cmd_cleanup:
        xhci_free_command(xhci, cmd);
        return ret;
 }
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 2ef2b61b69df..79b8ab4c6663 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -1030,6 +1030,7 @@ static int gntdev_mmap(struct file *flip, struct 
vm_area_struct *vma)
        mutex_unlock(&priv->lock);
 
        if (use_ptemod) {
+               map->pages_vm_start = vma->vm_start;
                err = apply_to_page_range(vma->vm_mm, vma->vm_start,
                                          vma->vm_end - vma->vm_start,
                                          find_grant_ptes, map);
@@ -1067,7 +1068,6 @@ static int gntdev_mmap(struct file *flip, struct 
vm_area_struct *vma)
                                            set_grant_ptes_as_special, NULL);
                }
 #endif
-               map->pages_vm_start = vma->vm_start;
        }
 
        return 0;
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 03951f90ecf7..3e1c136aadb7 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1900,6 +1900,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
 retry:
        spin_lock(&ci->i_ceph_lock);
        if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+               spin_unlock(&ci->i_ceph_lock);
                dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
                goto out;
        }
@@ -1917,8 +1918,10 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
                        mutex_lock(&session->s_mutex);
                        goto retry;
                }
-               if (cap->session->s_state < CEPH_MDS_SESSION_OPEN)
+               if (cap->session->s_state < CEPH_MDS_SESSION_OPEN) {
+                       spin_unlock(&ci->i_ceph_lock);
                        goto out;
+               }
 
                flushing = __mark_caps_flushing(inode, session, true,
                                                &flush_tid, &oldest_flush_tid);
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 599a29237cfe..a896e46671ea 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
 static inline struct ecryptfs_auth_tok *
 ecryptfs_get_encrypted_key_payload_data(struct key *key)
 {
-       if (key->type == &key_type_encrypted)
-               return (struct ecryptfs_auth_tok *)
-                       (&((struct encrypted_key_payload 
*)key->payload.data[0])->payload_data);
-       else
+       struct encrypted_key_payload *payload;
+
+       if (key->type != &key_type_encrypted)
                return NULL;
+
+       payload = key->payload.data[0];
+       if (!payload)
+               return ERR_PTR(-EKEYREVOKED);
+
+       return (struct ecryptfs_auth_tok *)payload->payload_data;
 }
 
 static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
 ecryptfs_get_key_payload_data(struct key *key)
 {
        struct ecryptfs_auth_tok *auth_tok;
+       const struct user_key_payload *ukp;
 
        auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
-       if (!auth_tok)
-               return (struct ecryptfs_auth_tok *)user_key_payload(key)->data;
-       else
+       if (auth_tok)
                return auth_tok;
+
+       ukp = user_key_payload(key);
+       if (!ukp)
+               return ERR_PTR(-EKEYREVOKED);
+
+       return (struct ecryptfs_auth_tok *)ukp->data;
 }
 
 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 3cf1546dca82..fa218cd64f74 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version)
  * @auth_tok_key: key containing the authentication token
  * @auth_tok: authentication token
  *
- * Returns zero on valid auth tok; -EINVAL otherwise
+ * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
+ * -EKEYREVOKED if the key was revoked before we acquired its semaphore.
  */
 static int
 ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
        int rc = 0;
 
        (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
+       if (IS_ERR(*auth_tok)) {
+               rc = PTR_ERR(*auth_tok);
+               *auth_tok = NULL;
+               goto out;
+       }
+
        if (ecryptfs_verify_version((*auth_tok)->version)) {
                printk(KERN_ERR "Data structure version mismatch. Userspace "
                       "tools must match eCryptfs kernel module with major "
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 642c57b8de7b..4bbad745415a 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1312,7 +1312,8 @@ static int parse_dirplusfile(char *buf, size_t nbytes, 
struct file *file,
                        */
                        over = !dir_emit(ctx, dirent->name, dirent->namelen,
                                       dirent->ino, dirent->type);
-                       ctx->pos = dirent->off;
+                       if (!over)
+                               ctx->pos = dirent->off;
                }
 
                buf += reclen;
diff --git a/include/uapi/linux/spi/spidev.h b/include/uapi/linux/spi/spidev.h
index dd5f21e75805..856de39d0b89 100644
--- a/include/uapi/linux/spi/spidev.h
+++ b/include/uapi/linux/spi/spidev.h
@@ -23,6 +23,7 @@
 #define SPIDEV_H
 
 #include <linux/types.h>
+#include <linux/ioctl.h>
 
 /* User space versions of kernel symbols for SPI clocking modes,
  * matching <linux/spi/spi.h>
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 776dda02e751..296dcca77f33 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -68,6 +68,7 @@ enum {
         * attach_mutex to avoid changing binding state while
         * worker_attach_to_pool() is in progress.
         */
+       POOL_MANAGER_ACTIVE     = 1 << 0,       /* being managed */
        POOL_DISASSOCIATED      = 1 << 2,       /* cpu can't serve workers */
 
        /* worker flags */
@@ -165,7 +166,6 @@ struct worker_pool {
                                                /* L: hash of busy workers */
 
        /* see manage_workers() for details on the two manager mutexes */
-       struct mutex            manager_arb;    /* manager arbitration */
        struct worker           *manager;       /* L: purely informational */
        struct mutex            attach_mutex;   /* attach/detach exclusion */
        struct list_head        workers;        /* A: attached workers */
@@ -297,6 +297,7 @@ static struct workqueue_attrs 
*wq_update_unbound_numa_attrs_buf;
 
 static DEFINE_MUTEX(wq_pool_mutex);    /* protects pools and workqueues list */
 static DEFINE_SPINLOCK(wq_mayday_lock);        /* protects wq->maydays list */
+static DECLARE_WAIT_QUEUE_HEAD(wq_manager_wait); /* wait for manager to go 
away */
 
 static LIST_HEAD(workqueues);          /* PR: list of all workqueues */
 static bool workqueue_freezing;                /* PL: have wqs started 
freezing? */
@@ -799,7 +800,7 @@ static bool need_to_create_worker(struct worker_pool *pool)
 /* Do we have too many workers and should some go away? */
 static bool too_many_workers(struct worker_pool *pool)
 {
-       bool managing = mutex_is_locked(&pool->manager_arb);
+       bool managing = pool->flags & POOL_MANAGER_ACTIVE;
        int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
        int nr_busy = pool->nr_workers - nr_idle;
 
@@ -1979,24 +1980,17 @@ static bool manage_workers(struct worker *worker)
 {
        struct worker_pool *pool = worker->pool;
 
-       /*
-        * Anyone who successfully grabs manager_arb wins the arbitration
-        * and becomes the manager.  mutex_trylock() on pool->manager_arb
-        * failure while holding pool->lock reliably indicates that someone
-        * else is managing the pool and the worker which failed trylock
-        * can proceed to executing work items.  This means that anyone
-        * grabbing manager_arb is responsible for actually performing
-        * manager duties.  If manager_arb is grabbed and released without
-        * actual management, the pool may stall indefinitely.
-        */
-       if (!mutex_trylock(&pool->manager_arb))
+       if (pool->flags & POOL_MANAGER_ACTIVE)
                return false;
+
+       pool->flags |= POOL_MANAGER_ACTIVE;
        pool->manager = worker;
 
        maybe_create_worker(pool);
 
        pool->manager = NULL;
-       mutex_unlock(&pool->manager_arb);
+       pool->flags &= ~POOL_MANAGER_ACTIVE;
+       wake_up(&wq_manager_wait);
        return true;
 }
 
@@ -3203,7 +3197,6 @@ static int init_worker_pool(struct worker_pool *pool)
        setup_timer(&pool->mayday_timer, pool_mayday_timeout,
                    (unsigned long)pool);
 
-       mutex_init(&pool->manager_arb);
        mutex_init(&pool->attach_mutex);
        INIT_LIST_HEAD(&pool->workers);
 
@@ -3273,13 +3266,15 @@ static void put_unbound_pool(struct worker_pool *pool)
        hash_del(&pool->hash_node);
 
        /*
-        * Become the manager and destroy all workers.  Grabbing
-        * manager_arb prevents @pool's workers from blocking on
-        * attach_mutex.
+        * Become the manager and destroy all workers.  This prevents
+        * @pool's workers from blocking on attach_mutex.  We're the last
+        * manager and @pool gets freed with the flag set.
         */
-       mutex_lock(&pool->manager_arb);
-
        spin_lock_irq(&pool->lock);
+       wait_event_lock_irq(wq_manager_wait,
+                           !(pool->flags & POOL_MANAGER_ACTIVE), pool->lock);
+       pool->flags |= POOL_MANAGER_ACTIVE;
+
        while ((worker = first_idle_worker(pool)))
                destroy_worker(worker);
        WARN_ON(pool->nr_workers || pool->nr_idle);
@@ -3293,8 +3288,6 @@ static void put_unbound_pool(struct worker_pool *pool)
        if (pool->detach_completion)
                wait_for_completion(pool->detach_completion);
 
-       mutex_unlock(&pool->manager_arb);
-
        /* shut down the timers */
        del_timer_sync(&pool->idle_timer);
        del_timer_sync(&pool->mayday_timer);
diff --git a/lib/assoc_array.c b/lib/assoc_array.c
index 59fd7c0b119c..5cd093589c5a 100644
--- a/lib/assoc_array.c
+++ b/lib/assoc_array.c
@@ -598,21 +598,31 @@ static bool assoc_array_insert_into_terminal_node(struct 
assoc_array_edit *edit,
                if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0)
                        goto all_leaves_cluster_together;
 
-               /* Otherwise we can just insert a new node ahead of the old
-                * one.
+               /* Otherwise all the old leaves cluster in the same slot, but
+                * the new leaf wants to go into a different slot - so we
+                * create a new node (n0) to hold the new leaf and a pointer to
+                * a new node (n1) holding all the old leaves.
+                *
+                * This can be done by falling through to the node splitting
+                * path.
                 */
-               goto present_leaves_cluster_but_not_new_leaf;
+               pr_devel("present leaves cluster but not new leaf\n");
        }
 
 split_node:
        pr_devel("split node\n");
 
-       /* We need to split the current node; we know that the node doesn't
-        * simply contain a full set of leaves that cluster together (it
-        * contains meta pointers and/or non-clustering leaves).
+       /* We need to split the current node.  The node must contain anything
+        * from a single leaf (in the one leaf case, this leaf will cluster
+        * with the new leaf) and the rest meta-pointers, to all leaves, some
+        * of which may cluster.
+        *
+        * It won't contain the case in which all the current leaves plus the
+        * new leaves want to cluster in the same slot.
         *
         * We need to expel at least two leaves out of a set consisting of the
-        * leaves in the node and the new leaf.
+        * leaves in the node and the new leaf.  The current meta pointers can
+        * just be copied as they shouldn't cluster with any of the leaves.
         *
         * We need a new node (n0) to replace the current one and a new node to
         * take the expelled nodes (n1).
@@ -717,33 +727,6 @@ static bool assoc_array_insert_into_terminal_node(struct 
assoc_array_edit *edit,
        pr_devel("<--%s() = ok [split node]\n", __func__);
        return true;
 
-present_leaves_cluster_but_not_new_leaf:
-       /* All the old leaves cluster in the same slot, but the new leaf wants
-        * to go into a different slot, so we create a new node to hold the new
-        * leaf and a pointer to a new node holding all the old leaves.
-        */
-       pr_devel("present leaves cluster but not new leaf\n");
-
-       new_n0->back_pointer = node->back_pointer;
-       new_n0->parent_slot = node->parent_slot;
-       new_n0->nr_leaves_on_branch = node->nr_leaves_on_branch;
-       new_n1->back_pointer = assoc_array_node_to_ptr(new_n0);
-       new_n1->parent_slot = edit->segment_cache[0];
-       new_n1->nr_leaves_on_branch = node->nr_leaves_on_branch;
-       edit->adjust_count_on = new_n0;
-
-       for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++)
-               new_n1->slots[i] = node->slots[i];
-
-       new_n0->slots[edit->segment_cache[0]] = assoc_array_node_to_ptr(new_n0);
-       edit->leaf_p = &new_n0->slots[edit->segment_cache[ASSOC_ARRAY_FAN_OUT]];
-
-       edit->set[0].ptr = 
&assoc_array_ptr_to_node(node->back_pointer)->slots[node->parent_slot];
-       edit->set[0].to = assoc_array_node_to_ptr(new_n0);
-       edit->excised_meta[0] = assoc_array_node_to_ptr(node);
-       pr_devel("<--%s() = ok [insert node before]\n", __func__);
-       return true;
-
 all_leaves_cluster_together:
        /* All the leaves, new and old, want to cluster together in this node
         * in the same slot, so we have to replace this node with a shortcut to
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 35cc1de85dcc..6fd24f6435c3 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -505,11 +505,6 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
                return -EOPNOTSUPP;
 
        if (wdev->current_bss) {
-               if (!prev_bssid)
-                       return -EALREADY;
-               if (prev_bssid &&
-                   !ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid))
-                       return -ENOTCONN;
                cfg80211_unhold_bss(wdev->current_bss);
                cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
                wdev->current_bss = NULL;
@@ -1025,11 +1020,35 @@ int cfg80211_connect(struct cfg80211_registered_device 
*rdev,
 
        ASSERT_WDEV_LOCK(wdev);
 
-       if (WARN_ON(wdev->connect_keys)) {
-               kzfree(wdev->connect_keys);
-               wdev->connect_keys = NULL;
+       /*
+        * If we have an ssid_len, we're trying to connect or are
+        * already connected, so reject a new SSID unless it's the
+        * same (which is the case for re-association.)
+        */
+       if (wdev->ssid_len &&
+           (wdev->ssid_len != connect->ssid_len ||
+            memcmp(wdev->ssid, connect->ssid, wdev->ssid_len)))
+               return -EALREADY;
+
+       /*
+        * If connected, reject (re-)association unless prev_bssid
+        * matches the current BSSID.
+        */
+       if (wdev->current_bss) {
+               if (!prev_bssid)
+                       return -EALREADY;
+               if (!ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid))
+                       return -ENOTCONN;
        }
 
+       /*
+        * Reject if we're in the process of connecting with WEP,
+        * this case isn't very interesting and trying to handle
+        * it would make the code much more complex.
+        */
+       if (wdev->connect_keys)
+               return -EINPROGRESS;
+
        cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
                                  rdev->wiphy.ht_capa_mod_mask);
 
@@ -1080,7 +1099,12 @@ int cfg80211_connect(struct cfg80211_registered_device 
*rdev,
 
        if (err) {
                wdev->connect_keys = NULL;
-               wdev->ssid_len = 0;
+               /*
+                * This could be reassoc getting refused, don't clear
+                * ssid_len in that case.
+                */
+               if (!wdev->current_bss)
+                       wdev->ssid_len = 0;
                return err;
        }
 
@@ -1105,5 +1129,13 @@ int cfg80211_disconnect(struct 
cfg80211_registered_device *rdev,
        else if (wdev->current_bss)
                err = rdev_disconnect(rdev, dev, reason);
 
+       /*
+        * Clear ssid_len unless we actually were fully connected,
+        * in which case cfg80211_disconnected() will take care of
+        * this later.
+        */
+       if (!wdev->current_bss)
+               wdev->ssid_len = 0;
+
        return err;
 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index a7e27e1140dd..22934885bd3f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1656,32 +1656,34 @@ static int dump_one_policy(struct xfrm_policy *xp, int 
dir, int count, void *ptr
 
 static int xfrm_dump_policy_done(struct netlink_callback *cb)
 {
-       struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) 
&cb->args[1];
+       struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
        struct net *net = sock_net(cb->skb->sk);
 
        xfrm_policy_walk_done(walk, net);
        return 0;
 }
 
+static int xfrm_dump_policy_start(struct netlink_callback *cb)
+{
+       struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
+
+       BUILD_BUG_ON(sizeof(*walk) > sizeof(cb->args));
+
+       xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
+       return 0;
+}
+
 static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct net *net = sock_net(skb->sk);
-       struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) 
&cb->args[1];
+       struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
        struct xfrm_dump_info info;
 
-       BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
-                    sizeof(cb->args) - sizeof(cb->args[0]));
-
        info.in_skb = cb->skb;
        info.out_skb = skb;
        info.nlmsg_seq = cb->nlh->nlmsg_seq;
        info.nlmsg_flags = NLM_F_MULTI;
 
-       if (!cb->args[0]) {
-               cb->args[0] = 1;
-               xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
-       }
-
        (void) xfrm_policy_walk(net, walk, dump_one_policy, &info);
 
        return skb->len;
@@ -2415,6 +2417,7 @@ static const struct nla_policy 
xfrma_spd_policy[XFRMA_SPD_MAX+1] = {
 
 static const struct xfrm_link {
        int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
+       int (*start)(struct netlink_callback *);
        int (*dump)(struct sk_buff *, struct netlink_callback *);
        int (*done)(struct netlink_callback *);
        const struct nla_policy *nla_pol;
@@ -2428,6 +2431,7 @@ static const struct xfrm_link {
        [XFRM_MSG_NEWPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_add_policy    },
        [XFRM_MSG_DELPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy    },
        [XFRM_MSG_GETPOLICY   - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
+                                                  .start = 
xfrm_dump_policy_start,
                                                   .dump = xfrm_dump_policy,
                                                   .done = 
xfrm_dump_policy_done },
        [XFRM_MSG_ALLOCSPI    - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
@@ -2479,6 +2483,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
 
                {
                        struct netlink_dump_control c = {
+                               .start = link->start,
                                .dump = link->dump,
                                .done = link->done,
                        };
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6f337f00ba58..fe1d06d50392 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -329,6 +329,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
                break;
        case 0x10ec0225:
        case 0x10ec0233:
+       case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
        case 0x10ec0282:
@@ -909,6 +910,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = 
{
        { 0x10ec0275, 0x1028, 0, "ALC3260" },
        { 0x10ec0899, 0x1028, 0, "ALC3861" },
        { 0x10ec0298, 0x1028, 0, "ALC3266" },
+       { 0x10ec0236, 0x1028, 0, "ALC3204" },
        { 0x10ec0256, 0x1028, 0, "ALC3246" },
        { 0x10ec0225, 0x1028, 0, "ALC3253" },
        { 0x10ec0295, 0x1028, 0, "ALC3254" },
@@ -3694,6 +3696,7 @@ static void alc_headset_mode_unplugged(struct hda_codec 
*codec)
                alc_process_coef_fw(codec, coef0255_1);
                alc_process_coef_fw(codec, coef0255);
                break;
+       case 0x10ec0236:
        case 0x10ec0256:
                alc_process_coef_fw(codec, coef0256);
                alc_process_coef_fw(codec, coef0255);
@@ -3777,6 +3780,7 @@ static void alc_headset_mode_mic_in(struct hda_codec 
*codec, hda_nid_t hp_pin,
 
 
        switch (codec->core.vendor_id) {
+       case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
                alc_write_coef_idx(codec, 0x45, 0xc489);
@@ -3885,6 +3889,7 @@ static void alc_headset_mode_default(struct hda_codec 
*codec)
        case 0x10ec0295:
                alc_process_coef_fw(codec, coef0225);
                break;
+       case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
                alc_process_coef_fw(codec, coef0255);
@@ -3971,6 +3976,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
        case 0x10ec0255:
                alc_process_coef_fw(codec, coef0255);
                break;
+       case 0x10ec0236:
        case 0x10ec0256:
                alc_process_coef_fw(codec, coef0256);
                break;
@@ -4064,6 +4070,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
        case 0x10ec0255:
                alc_process_coef_fw(codec, coef0255);
                break;
+       case 0x10ec0236:
        case 0x10ec0256:
                alc_process_coef_fw(codec, coef0256);
                break;
@@ -4131,6 +4138,7 @@ static void alc_determine_headset_type(struct hda_codec 
*codec)
        };
 
        switch (codec->core.vendor_id) {
+       case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
                alc_process_coef_fw(codec, coef0255);
@@ -4335,6 +4343,7 @@ static void alc255_set_default_jack_type(struct hda_codec 
*codec)
        case 0x10ec0255:
                alc_process_coef_fw(codec, alc255fw);
                break;
+       case 0x10ec0236:
        case 0x10ec0256:
                alc_process_coef_fw(codec, alc256fw);
                break;
@@ -5852,6 +5861,14 @@ static const struct snd_hda_pin_quirk 
alc269_pin_fixup_tbl[] = {
                ALC225_STANDARD_PINS,
                {0x12, 0xb7a60130},
                {0x1b, 0x90170110}),
+       SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", 
ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60140},
+               {0x14, 0x90170110},
+               {0x21, 0x02211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", 
ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60140},
+               {0x14, 0x90170150},
+               {0x21, 0x02211020}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", 
ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
                {0x14, 0x90170110},
                {0x21, 0x02211020}),
@@ -6226,6 +6243,7 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0255:
                spec->codec_variant = ALC269_TYPE_ALC255;
                break;
+       case 0x10ec0236:
        case 0x10ec0256:
                spec->codec_variant = ALC269_TYPE_ALC256;
                spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback 
mixer path */
@@ -7205,6 +7223,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),

Reply via email to