void hci_adv_monitors_clear(struct hci_dev *hdev);
 void hci_free_adv_monitor(struct adv_monitor *monitor);
 int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
+int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 
        return 0;
 }
 
+static int free_adv_monitor(int id, void *ptr, void *data)
+{
+       struct hci_dev *hdev = data;
+       struct adv_monitor *monitor = ptr;
+
+       idr_remove(&hdev->adv_monitors_idr, monitor->handle);
+       hci_free_adv_monitor(monitor);
+
+       return 0;
+}
+
+/* This function requires the caller holds hdev->lock */
+int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle)
+{
+       struct adv_monitor *monitor;
+
+       if (handle) {
+               monitor = idr_find(&hdev->adv_monitors_idr, handle);
+               if (!monitor)
+                       return -ENOENT;
+
+               idr_remove(&hdev->adv_monitors_idr, monitor->handle);
+               hci_free_adv_monitor(monitor);
+       } else {
+               /* Remove all monitors if handle is 0. */
+               idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev);
+       }
+
+       return 0;
+}
+
 struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
                                         bdaddr_t *bdaddr, u8 type)
 {
 
        MGMT_OP_SET_DEVICE_FLAGS,
        MGMT_OP_READ_ADV_MONITOR_FEATURES,
        MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+       MGMT_OP_REMOVE_ADV_MONITOR,
 };
 
 static const u16 mgmt_events[] = {
        return err;
 }
 
+static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
+                             void *data, u16 len)
+{
+       struct mgmt_cp_remove_adv_monitor *cp = data;
+       struct mgmt_rp_remove_adv_monitor rp;
+       u16 handle;
+       int err;
+
+       BT_DBG("request for %s", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       handle = __le16_to_cpu(cp->monitor_handle);
+
+       err = hci_remove_adv_monitor(hdev, handle);
+       if (err == -ENOENT) {
+               err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
+                                     MGMT_STATUS_INVALID_INDEX);
+               goto unlock;
+       }
+
+       hci_dev_unlock(hdev);
+
+       rp.monitor_handle = cp->monitor_handle;
+
+       return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
+                                MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
+
+unlock:
+       hci_dev_unlock(hdev);
+       return err;
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
                                         u16 opcode, struct sk_buff *skb)
 {
        { read_adv_mon_features,   MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
        { add_adv_patterns_monitor,MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE,
                                                HCI_MGMT_VAR_LEN },
+       { remove_adv_monitor,      MGMT_REMOVE_ADV_MONITOR_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)