|
@@ -12,6 +12,8 @@
|
|
|
#undef BT_DBG
|
|
|
#define BT_DBG(D...)
|
|
|
#endif
|
|
|
+static struct workqueue_struct *btaddconn;
|
|
|
+static struct workqueue_struct *btdelconn;
|
|
|
|
|
|
static inline char *typetostr(int type)
|
|
|
{
|
|
@@ -279,6 +281,7 @@ static void add_conn(struct work_struct *work)
|
|
|
struct hci_conn *conn = container_of(work, struct hci_conn, work);
|
|
|
int i;
|
|
|
|
|
|
+ flush_workqueue(btdelconn);
|
|
|
if (device_add(&conn->dev) < 0) {
|
|
|
BT_ERR("Failed to register connection device");
|
|
|
return;
|
|
@@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
|
|
|
|
|
|
INIT_WORK(&conn->work, add_conn);
|
|
|
|
|
|
+ queue_work(btaddconn, &conn->work);
|
|
|
schedule_work(&conn->work);
|
|
|
}
|
|
|
|
|
@@ -349,6 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
|
|
|
|
|
|
INIT_WORK(&conn->work, del_conn);
|
|
|
|
|
|
+ queue_work(btdelconn, &conn->work);
|
|
|
schedule_work(&conn->work);
|
|
|
}
|
|
|
|
|
@@ -398,31 +403,52 @@ int __init bt_sysfs_init(void)
|
|
|
{
|
|
|
int err;
|
|
|
|
|
|
+ btaddconn = create_singlethread_workqueue("btaddconn");
|
|
|
+ if (!btaddconn) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ btdelconn = create_singlethread_workqueue("btdelconn");
|
|
|
+ if (!btdelconn) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto out_del;
|
|
|
+ }
|
|
|
+
|
|
|
bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
|
|
|
- if (IS_ERR(bt_platform))
|
|
|
- return PTR_ERR(bt_platform);
|
|
|
+ if (IS_ERR(bt_platform)) {
|
|
|
+ err = PTR_ERR(bt_platform);
|
|
|
+ goto out_platform;
|
|
|
+ }
|
|
|
|
|
|
err = bus_register(&bt_bus);
|
|
|
- if (err < 0) {
|
|
|
- platform_device_unregister(bt_platform);
|
|
|
- return err;
|
|
|
- }
|
|
|
+ if (err < 0)
|
|
|
+ goto out_bus;
|
|
|
|
|
|
bt_class = class_create(THIS_MODULE, "bluetooth");
|
|
|
if (IS_ERR(bt_class)) {
|
|
|
- bus_unregister(&bt_bus);
|
|
|
- platform_device_unregister(bt_platform);
|
|
|
- return PTR_ERR(bt_class);
|
|
|
+ err = PTR_ERR(bt_class);
|
|
|
+ goto out_class;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
+
|
|
|
+out_class:
|
|
|
+ bus_unregister(&bt_bus);
|
|
|
+out_bus:
|
|
|
+ platform_device_unregister(bt_platform);
|
|
|
+out_platform:
|
|
|
+ destroy_workqueue(btdelconn);
|
|
|
+out_del:
|
|
|
+ destroy_workqueue(btaddconn);
|
|
|
+out:
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
void bt_sysfs_cleanup(void)
|
|
|
{
|
|
|
+ destroy_workqueue(btaddconn);
|
|
|
+ destroy_workqueue(btdelconn);
|
|
|
class_destroy(bt_class);
|
|
|
-
|
|
|
bus_unregister(&bt_bus);
|
|
|
-
|
|
|
platform_device_unregister(bt_platform);
|
|
|
}
|