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.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index b7c51082ddeb..4cc3624bd22d 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -9,7 +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 *bluetooth; 12static struct workqueue_struct *bt_workq;
13 13
14static inline char *link_typetostr(int type) 14static inline char *link_typetostr(int type)
15{ 15{
@@ -88,35 +88,19 @@ static struct device_type bt_link = {
88static void add_conn(struct work_struct *work) 88static void add_conn(struct work_struct *work)
89{ 89{
90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add); 90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
91 struct hci_dev *hdev = conn->hdev;
92
93 /* ensure previous del is complete */
94 flush_work(&conn->work_del);
91 95
92 /* ensure previous add/del is complete */ 96 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
93 flush_workqueue(bluetooth);
94 97
95 if (device_add(&conn->dev) < 0) { 98 if (device_add(&conn->dev) < 0) {
96 BT_ERR("Failed to register connection device"); 99 BT_ERR("Failed to register connection device");
97 return; 100 return;
98 } 101 }
99}
100 102
101void hci_conn_add_sysfs(struct hci_conn *conn) 103 hci_dev_hold(hdev);
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
111 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
112
113 dev_set_drvdata(&conn->dev, conn);
114
115 device_initialize(&conn->dev);
116
117 INIT_WORK(&conn->work_add, add_conn);
118
119 queue_work(bluetooth, &conn->work_add);
120} 104}
121 105
122/* 106/*
@@ -134,8 +118,11 @@ static void del_conn(struct work_struct *work)
134 struct hci_conn *conn = container_of(work, struct hci_conn, work_del); 118 struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
135 struct hci_dev *hdev = conn->hdev; 119 struct hci_dev *hdev = conn->hdev;
136 120
137 /* ensure previous add/del is complete */ 121 /* ensure previous add is complete */
138 flush_workqueue(bluetooth); 122 flush_work(&conn->work_add);
123
124 if (!device_is_registered(&conn->dev))
125 return;
139 126
140 while (1) { 127 while (1) {
141 struct device *dev; 128 struct device *dev;
@@ -149,19 +136,40 @@ static void del_conn(struct work_struct *work)
149 136
150 device_del(&conn->dev); 137 device_del(&conn->dev);
151 put_device(&conn->dev); 138 put_device(&conn->dev);
139
152 hci_dev_put(hdev); 140 hci_dev_put(hdev);
153} 141}
154 142
155void hci_conn_del_sysfs(struct hci_conn *conn) 143void hci_conn_init_sysfs(struct hci_conn *conn)
156{ 144{
145 struct hci_dev *hdev = conn->hdev;
146
157 BT_DBG("conn %p", conn); 147 BT_DBG("conn %p", conn);
158 148
159 if (!device_is_registered(&conn->dev)) 149 conn->dev.type = &bt_link;
160 return; 150 conn->dev.class = bt_class;
151 conn->dev.parent = &hdev->dev;
152
153 dev_set_drvdata(&conn->dev, conn);
154
155 device_initialize(&conn->dev);
161 156
157 INIT_WORK(&conn->work_add, add_conn);
162 INIT_WORK(&conn->work_del, del_conn); 158 INIT_WORK(&conn->work_del, del_conn);
159}
160
161void hci_conn_add_sysfs(struct hci_conn *conn)
162{
163 BT_DBG("conn %p", conn);
164
165 queue_work(bt_workq, &conn->work_add);
166}
167
168void hci_conn_del_sysfs(struct hci_conn *conn)
169{
170 BT_DBG("conn %p", conn);
163 171
164 queue_work(bluetooth, &conn->work_del); 172 queue_work(bt_workq, &conn->work_del);
165} 173}
166 174
167static inline char *host_typetostr(int type) 175static inline char *host_typetostr(int type)
@@ -438,13 +446,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
438 446
439int __init bt_sysfs_init(void) 447int __init bt_sysfs_init(void)
440{ 448{
441 bluetooth = create_singlethread_workqueue("bluetooth"); 449 bt_workq = create_singlethread_workqueue("bluetooth");
442 if (!bluetooth) 450 if (!bt_workq)
443 return -ENOMEM; 451 return -ENOMEM;
444 452
445 bt_class = class_create(THIS_MODULE, "bluetooth"); 453 bt_class = class_create(THIS_MODULE, "bluetooth");
446 if (IS_ERR(bt_class)) { 454 if (IS_ERR(bt_class)) {
447 destroy_workqueue(bluetooth); 455 destroy_workqueue(bt_workq);
448 return PTR_ERR(bt_class); 456 return PTR_ERR(bt_class);
449 } 457 }
450 458
@@ -453,7 +461,7 @@ int __init bt_sysfs_init(void)
453 461
454void bt_sysfs_cleanup(void) 462void bt_sysfs_cleanup(void)
455{ 463{
456 destroy_workqueue(bluetooth); 464 destroy_workqueue(bt_workq);
457 465
458 class_destroy(bt_class); 466 class_destroy(bt_class);
459} 467}