aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r--net/bluetooth/hci_sysfs.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ed82796d4a0f..95f7a7a544b4 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -9,8 +9,7 @@
9struct class *bt_class = NULL; 9struct class *bt_class = NULL;
10EXPORT_SYMBOL_GPL(bt_class); 10EXPORT_SYMBOL_GPL(bt_class);
11 11
12static struct workqueue_struct *btaddconn; 12static struct workqueue_struct *bt_workq;
13static struct workqueue_struct *btdelconn;
14 13
15static inline char *link_typetostr(int type) 14static inline char *link_typetostr(int type)
16{ 15{
@@ -88,35 +87,17 @@ static struct device_type bt_link = {
88 87
89static void add_conn(struct work_struct *work) 88static void add_conn(struct work_struct *work)
90{ 89{
91 struct hci_conn *conn = container_of(work, struct hci_conn, work); 90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
91 struct hci_dev *hdev = conn->hdev;
92 92
93 flush_workqueue(btdelconn); 93 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
94 94
95 if (device_add(&conn->dev) < 0) { 95 if (device_add(&conn->dev) < 0) {
96 BT_ERR("Failed to register connection device"); 96 BT_ERR("Failed to register connection device");
97 return; 97 return;
98 } 98 }
99}
100
101void hci_conn_add_sysfs(struct hci_conn *conn)
102{
103 struct hci_dev *hdev = conn->hdev;
104
105 BT_DBG("conn %p", conn);
106
107 conn->dev.type = &bt_link;
108 conn->dev.class = bt_class;
109 conn->dev.parent = &hdev->dev;
110 99
111 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); 100 hci_dev_hold(hdev);
112
113 dev_set_drvdata(&conn->dev, conn);
114
115 device_initialize(&conn->dev);
116
117 INIT_WORK(&conn->work, add_conn);
118
119 queue_work(btaddconn, &conn->work);
120} 101}
121 102
122/* 103/*
@@ -131,9 +112,12 @@ static int __match_tty(struct device *dev, void *data)
131 112
132static void del_conn(struct work_struct *work) 113static void del_conn(struct work_struct *work)
133{ 114{
134 struct hci_conn *conn = container_of(work, struct hci_conn, work); 115 struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
135 struct hci_dev *hdev = conn->hdev; 116 struct hci_dev *hdev = conn->hdev;
136 117
118 if (!device_is_registered(&conn->dev))
119 return;
120
137 while (1) { 121 while (1) {
138 struct device *dev; 122 struct device *dev;
139 123
@@ -146,19 +130,40 @@ static void del_conn(struct work_struct *work)
146 130
147 device_del(&conn->dev); 131 device_del(&conn->dev);
148 put_device(&conn->dev); 132 put_device(&conn->dev);
133
149 hci_dev_put(hdev); 134 hci_dev_put(hdev);
150} 135}
151 136
152void hci_conn_del_sysfs(struct hci_conn *conn) 137void hci_conn_init_sysfs(struct hci_conn *conn)
153{ 138{
139 struct hci_dev *hdev = conn->hdev;
140
154 BT_DBG("conn %p", conn); 141 BT_DBG("conn %p", conn);
155 142
156 if (!device_is_registered(&conn->dev)) 143 conn->dev.type = &bt_link;
157 return; 144 conn->dev.class = bt_class;
145 conn->dev.parent = &hdev->dev;
158 146
159 INIT_WORK(&conn->work, del_conn); 147 dev_set_drvdata(&conn->dev, conn);
148
149 device_initialize(&conn->dev);
160 150
161 queue_work(btdelconn, &conn->work); 151 INIT_WORK(&conn->work_add, add_conn);
152 INIT_WORK(&conn->work_del, del_conn);
153}
154
155void hci_conn_add_sysfs(struct hci_conn *conn)
156{
157 BT_DBG("conn %p", conn);
158
159 queue_work(bt_workq, &conn->work_add);
160}
161
162void hci_conn_del_sysfs(struct hci_conn *conn)
163{
164 BT_DBG("conn %p", conn);
165
166 queue_work(bt_workq, &conn->work_del);
162} 167}
163 168
164static inline char *host_typetostr(int type) 169static inline char *host_typetostr(int type)
@@ -435,20 +440,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
435 440
436int __init bt_sysfs_init(void) 441int __init bt_sysfs_init(void)
437{ 442{
438 btaddconn = create_singlethread_workqueue("btaddconn"); 443 bt_workq = create_singlethread_workqueue("bluetooth");
439 if (!btaddconn) 444 if (!bt_workq)
440 return -ENOMEM; 445 return -ENOMEM;
441 446
442 btdelconn = create_singlethread_workqueue("btdelconn");
443 if (!btdelconn) {
444 destroy_workqueue(btaddconn);
445 return -ENOMEM;
446 }
447
448 bt_class = class_create(THIS_MODULE, "bluetooth"); 447 bt_class = class_create(THIS_MODULE, "bluetooth");
449 if (IS_ERR(bt_class)) { 448 if (IS_ERR(bt_class)) {
450 destroy_workqueue(btdelconn); 449 destroy_workqueue(bt_workq);
451 destroy_workqueue(btaddconn);
452 return PTR_ERR(bt_class); 450 return PTR_ERR(bt_class);
453 } 451 }
454 452
@@ -457,8 +455,7 @@ int __init bt_sysfs_init(void)
457 455
458void bt_sysfs_cleanup(void) 456void bt_sysfs_cleanup(void)
459{ 457{
460 destroy_workqueue(btaddconn); 458 destroy_workqueue(bt_workq);
461 destroy_workqueue(btdelconn);
462 459
463 class_destroy(bt_class); 460 class_destroy(bt_class);
464} 461}