Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[deliverable/linux.git] / drivers / bluetooth / hci_ldisc.c
index b6d1f200401a4f04d0a449706e8b955c75c5fdf5..74e0966b3ead0bbcf3678ebea52ea6886a65baee 100644 (file)
@@ -156,6 +156,35 @@ restart:
        return 0;
 }
 
+static void hci_uart_init_work(struct work_struct *work)
+{
+       struct hci_uart *hu = container_of(work, struct hci_uart, init_ready);
+       int err;
+
+       if (!test_and_clear_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
+               return;
+
+       err = hci_register_dev(hu->hdev);
+       if (err < 0) {
+               BT_ERR("Can't register HCI device");
+               hci_free_dev(hu->hdev);
+               hu->hdev = NULL;
+               hu->proto->close(hu);
+       }
+
+       set_bit(HCI_UART_REGISTERED, &hu->flags);
+}
+
+int hci_uart_init_ready(struct hci_uart *hu)
+{
+       if (!test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
+               return -EALREADY;
+
+       schedule_work(&hu->init_ready);
+
+       return 0;
+}
+
 /* ------- Interface to HCI layer ------ */
 /* Initialize device */
 static int hci_uart_open(struct hci_dev *hdev)
@@ -264,6 +293,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
        hu->tty = tty;
        tty->receive_room = 65536;
 
+       INIT_WORK(&hu->init_ready, hci_uart_init_work);
+
        spin_lock_init(&hu->rx_lock);
 
        /* Flush any pending characters in the driver and line discipline. */
@@ -302,7 +333,8 @@ static void hci_uart_tty_close(struct tty_struct *tty)
 
        if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
                if (hdev) {
-                       hci_unregister_dev(hdev);
+                       if (test_bit(HCI_UART_REGISTERED, &hu->flags))
+                               hci_unregister_dev(hdev);
                        hci_free_dev(hdev);
                }
                hu->proto->close(hu);
@@ -402,12 +434,17 @@ static int hci_uart_register_dev(struct hci_uart *hu)
        else
                hdev->dev_type = HCI_BREDR;
 
+       if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
+               return 0;
+
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
                hci_free_dev(hdev);
                return -ENODEV;
        }
 
+       set_bit(HCI_UART_REGISTERED, &hu->flags);
+
        return 0;
 }
 
This page took 0.025102 seconds and 5 git commands to generate.