Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

Conflicts:
	net/nfc/netlink.c

Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 4bbb70e..c1b5285 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -761,31 +761,63 @@
 	},
 };
 
+
+struct urelease_work {
+	struct	work_struct w;
+	int	portid;
+};
+
+static void nfc_urelease_event_work(struct work_struct *work)
+{
+	struct urelease_work *w = container_of(work, struct urelease_work, w);
+	struct class_dev_iter iter;
+	struct nfc_dev *dev;
+
+	pr_debug("portid %d\n", w->portid);
+
+	mutex_lock(&nfc_devlist_mutex);
+
+	nfc_device_iter_init(&iter);
+	dev = nfc_device_iter_next(&iter);
+
+	while (dev) {
+		mutex_lock(&dev->genl_data.genl_data_mutex);
+
+		if (dev->genl_data.poll_req_portid == w->portid) {
+			nfc_stop_poll(dev);
+			dev->genl_data.poll_req_portid = 0;
+		}
+
+		mutex_unlock(&dev->genl_data.genl_data_mutex);
+
+		dev = nfc_device_iter_next(&iter);
+	}
+
+	nfc_device_iter_exit(&iter);
+
+	mutex_unlock(&nfc_devlist_mutex);
+
+	kfree(w);
+}
+
 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
 				 unsigned long event, void *ptr)
 {
 	struct netlink_notify *n = ptr;
-	struct class_dev_iter iter;
-	struct nfc_dev *dev;
+	struct urelease_work *w;
 
 	if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
 		goto out;
 
 	pr_debug("NETLINK_URELEASE event from id %d\n", n->portid);
 
-	nfc_device_iter_init(&iter);
-	dev = nfc_device_iter_next(&iter);
-
-	while (dev) {
-		if (dev->genl_data.poll_req_portid == n->portid) {
-			nfc_stop_poll(dev);
-			dev->genl_data.poll_req_portid = 0;
-		}
-		dev = nfc_device_iter_next(&iter);
+	w = kmalloc(sizeof(*w), GFP_ATOMIC);
+	if (w) {
+		INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
+		w->portid = n->portid;
+		schedule_work((struct work_struct *) w);
 	}
 
-	nfc_device_iter_exit(&iter);
-
 out:
 	return NOTIFY_DONE;
 }