l2cap_chan_hold(chan);
 
-       hci_conn_hold(conn->hcon);
+       /* Only keep a reference for fixed channels if they requested it */
+       if (chan->chan_type != L2CAP_CHAN_FIXED ||
+           test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
+               hci_conn_hold(conn->hcon);
 
        list_add(&chan->list, &conn->chan_l);
 }
 
                chan->conn = NULL;
 
-               if (chan->scid != L2CAP_CID_A2MP)
+               /* Reference was only held for non-fixed channels or
+                * fixed channels that explicitly requested it using the
+                * FLAG_HOLD_HCI_CONN flag.
+                */
+               if (chan->chan_type != L2CAP_CHAN_FIXED ||
+                   test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
                        hci_conn_drop(conn->hcon);
 
                if (mgr && mgr->bredr_chan == chan)
 
        case L2CAP_CHAN_RAW:
                chan->sec_level = BT_SECURITY_SDP;
                break;
+       case L2CAP_CHAN_FIXED:
+               /* Fixed channels default to the L2CAP core not holding a
+                * hci_conn reference for them. For fixed channels mapping to
+                * L2CAP sockets we do want to hold a reference so set the
+                * appropriate flag to request it.
+                */
+               set_bit(FLAG_HOLD_HCI_CONN, &chan->flags);
+               break;
        }
 
        bacpy(&chan->src, &la.l2_bdaddr);