arm64: cpufeature: Schedule enable() calls instead of calling them via IPI
[linux-2.6-block.git] / net / bluetooth / hci_sysfs.c
CommitLineData
1da177e4
LT
1/* Bluetooth HCI driver model support. */
2
3a9a231d 3#include <linux/module.h>
1da177e4
LT
4
5#include <net/bluetooth/bluetooth.h>
6#include <net/bluetooth/hci_core.h>
7
aef7d97c 8static struct class *bt_class;
90855d7b 9
90855d7b
MH
10static void bt_link_release(struct device *dev)
11{
2dd10688
DH
12 struct hci_conn *conn = to_hci_conn(dev);
13 kfree(conn);
90855d7b
MH
14}
15
16static struct device_type bt_link = {
17 .name = "link",
90855d7b
MH
18 .release = bt_link_release,
19};
20
6d438e33
GP
21/*
22 * The rfcomm tty device will possibly retain even when conn
23 * is down, and sysfs doesn't support move zombie device,
24 * so we should move the device before conn device is destroyed.
25 */
26static int __match_tty(struct device *dev, void *data)
27{
28 return !strncmp(dev_name(dev), "rfcomm", 6);
29}
30
31void hci_conn_init_sysfs(struct hci_conn *conn)
32{
33 struct hci_dev *hdev = conn->hdev;
34
35 BT_DBG("conn %p", conn);
36
37 conn->dev.type = &bt_link;
38 conn->dev.class = bt_class;
39 conn->dev.parent = &hdev->dev;
40
41 device_initialize(&conn->dev);
42}
43
44void hci_conn_add_sysfs(struct hci_conn *conn)
90855d7b 45{
457ca7bb 46 struct hci_dev *hdev = conn->hdev;
90855d7b 47
6d438e33
GP
48 BT_DBG("conn %p", conn);
49
457ca7bb
MH
50 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
51
90855d7b
MH
52 if (device_add(&conn->dev) < 0) {
53 BT_ERR("Failed to register connection device");
54 return;
55 }
384943ec
MH
56
57 hci_dev_hold(hdev);
90855d7b
MH
58}
59
6d438e33 60void hci_conn_del_sysfs(struct hci_conn *conn)
90855d7b 61{
90855d7b
MH
62 struct hci_dev *hdev = conn->hdev;
63
a67e899c
MH
64 if (!device_is_registered(&conn->dev))
65 return;
f3784d83 66
90855d7b
MH
67 while (1) {
68 struct device *dev;
69
70 dev = device_find_child(&conn->dev, NULL, __match_tty);
71 if (!dev)
72 break;
ffa6a705 73 device_move(dev, NULL, DPM_ORDER_DEV_LAST);
90855d7b
MH
74 put_device(dev);
75 }
76
77 device_del(&conn->dev);
384943ec 78
90855d7b
MH
79 hci_dev_put(hdev);
80}
81
90855d7b 82static void bt_host_release(struct device *dev)
a91f2e39 83{
2dd10688
DH
84 struct hci_dev *hdev = to_hci_dev(dev);
85 kfree(hdev);
46e06531 86 module_put(THIS_MODULE);
b219e3ac
MH
87}
88
90855d7b
MH
89static struct device_type bt_host = {
90 .name = "host",
90855d7b
MH
91 .release = bt_host_release,
92};
a91f2e39 93
0ac7e700
DH
94void hci_init_sysfs(struct hci_dev *hdev)
95{
96 struct device *dev = &hdev->dev;
97
98 dev->type = &bt_host;
99 dev->class = bt_class;
100
46e06531 101 __module_get(THIS_MODULE);
0ac7e700
DH
102 device_initialize(dev);
103}
104
1da177e4
LT
105int __init bt_sysfs_init(void)
106{
a91f2e39 107 bt_class = class_create(THIS_MODULE, "bluetooth");
27d35284 108
8c6ffba0 109 return PTR_ERR_OR_ZERO(bt_class);
1da177e4
LT
110}
111
860e13b5 112void bt_sysfs_cleanup(void)
1da177e4 113{
a91f2e39 114 class_destroy(bt_class);
1da177e4 115}