unsigned long   acl_last_tx;
        unsigned long   sco_last_tx;
 
+       struct workqueue_struct *workqueue;
+
        struct tasklet_struct   cmd_task;
        struct tasklet_struct   rx_task;
        struct tasklet_struct   tx_task;
 
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/rfkill.h>
 
        write_unlock_bh(&hci_dev_list_lock);
 
+       hdev->workqueue = create_singlethread_workqueue(hdev->name);
+       if (!hdev->workqueue)
+               goto nomem;
+
        hci_register_sysfs(hdev);
 
        hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
        hci_notify(hdev, HCI_DEV_REG);
 
        return id;
+
+nomem:
+       write_lock_bh(&hci_dev_list_lock);
+       list_del(&hdev->list);
+       write_unlock_bh(&hci_dev_list_lock);
+
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(hci_register_dev);
 
 
        hci_unregister_sysfs(hdev);
 
+       destroy_workqueue(hdev->workqueue);
+
        __hci_dev_put(hdev);
 
        return 0;
 
 struct dentry *bt_debugfs = NULL;
 EXPORT_SYMBOL_GPL(bt_debugfs);
 
-static struct workqueue_struct *bt_workq;
-
 static inline char *link_typetostr(int type)
 {
        switch (type) {
 {
        BT_DBG("conn %p", conn);
 
-       queue_work(bt_workq, &conn->work_add);
+       queue_work(conn->hdev->workqueue, &conn->work_add);
 }
 
 void hci_conn_del_sysfs(struct hci_conn *conn)
 {
        BT_DBG("conn %p", conn);
 
-       queue_work(bt_workq, &conn->work_del);
+       queue_work(conn->hdev->workqueue, &conn->work_del);
 }
 
 static inline char *host_bustostr(int bus)
 
 int __init bt_sysfs_init(void)
 {
-       bt_workq = create_singlethread_workqueue("bluetooth");
-       if (!bt_workq)
-               return -ENOMEM;
-
        bt_debugfs = debugfs_create_dir("bluetooth", NULL);
 
        bt_class = class_create(THIS_MODULE, "bluetooth");
-       if (IS_ERR(bt_class)) {
-               destroy_workqueue(bt_workq);
+       if (IS_ERR(bt_class))
                return PTR_ERR(bt_class);
-       }
 
        return 0;
 }
        class_destroy(bt_class);
 
        debugfs_remove_recursive(bt_debugfs);
-
-       destroy_workqueue(bt_workq);
 }