diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index d5e00d0dd1a0..030d402cc9bd 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -163,6 +163,24 @@ static struct iso_conn *iso_conn_add(struct hci_conn *hcon)
 	return conn;
 }
 
+static void iso_conn_drop(struct iso_conn *conn)
+{
+	if (!conn || !conn->hcon)
+		return;
+
+	BT_DBG("conn %p hcon %p", conn, conn->hcon);
+
+	hci_conn_drop(conn->hcon);
+
+	iso_conn_lock(conn);
+	conn->hcon->iso_data = NULL;
+	conn->hcon = NULL;
+	iso_conn_unlock(conn);
+
+	/* Ensure no more work items will run since hci_conn has been dropped */
+	disable_delayed_work_sync(&conn->timeout_work);
+}
+
 /* Delete channel. Must be called on the locked socket. */
 static void iso_chan_del(struct sock *sk, int err)
 {
@@ -179,8 +197,7 @@ static void iso_chan_del(struct sock *sk, int err)
 		iso_pi(sk)->conn = NULL;
 		iso_conn_unlock(conn);
 
-		if (conn->hcon)
-			hci_conn_drop(conn->hcon);
+		iso_conn_drop(conn);
 	}
 
 	sk->sk_state = BT_CLOSED;
@@ -197,6 +214,21 @@ static void iso_chan_del(struct sock *sk, int err)
 	sock_set_flag(sk, SOCK_ZAPPED);
 }
 
+static void iso_conn_destruct(struct iso_conn *conn)
+{
+	if (!conn)
+		return;
+
+	BT_DBG("conn %p", conn);
+
+	if (conn->sk)
+		iso_pi(conn->sk)->conn = NULL;
+
+	iso_conn_drop(conn);
+
+	kfree(conn);
+}
+
 static void iso_conn_del(struct hci_conn *hcon, int err)
 {
 	struct iso_conn *conn = hcon->iso_data;
@@ -214,19 +246,16 @@ static void iso_conn_del(struct hci_conn *hcon, int err)
 		sock_hold(sk);
 	iso_conn_unlock(conn);
 
-	if (sk) {
-		lock_sock(sk);
-		iso_sock_clear_timer(sk);
-		iso_chan_del(sk, err);
-		release_sock(sk);
-		sock_put(sk);
+	if (!sk) {
+		iso_conn_destruct(conn);
+		return;
 	}
 
-	/* Ensure no more work items will run before freeing conn. */
-	cancel_delayed_work_sync(&conn->timeout_work);
-
-	hcon->iso_data = NULL;
-	kfree(conn);
+	lock_sock(sk);
+	iso_sock_clear_timer(sk);
+	iso_chan_del(sk, err);
+	release_sock(sk);
+	sock_put(sk);
 }
 
 static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
@@ -646,6 +675,8 @@ static void iso_sock_destruct(struct sock *sk)
 {
 	BT_DBG("sk %p", sk);
 
+	iso_conn_destruct(iso_pi(sk)->conn);
+
 	skb_queue_purge(&sk->sk_receive_queue);
 	skb_queue_purge(&sk->sk_write_queue);
 }
@@ -714,7 +745,6 @@ static void iso_sock_disconn(struct sock *sk)
 	}
 
 	sk->sk_state = BT_DISCONN;
-	iso_sock_set_timer(sk, ISO_DISCONN_TIMEOUT);
 	iso_conn_lock(iso_pi(sk)->conn);
 	hci_conn_drop(iso_pi(sk)->conn->hcon);
 	iso_pi(sk)->conn->hcon = NULL;