GNU Linux-libre 4.9.337-gnu1
[releases.git] / net / bluetooth / hci_sysfs.c
1 /* Bluetooth HCI driver model support. */
2
3 #include <linux/module.h>
4
5 #include <net/bluetooth/bluetooth.h>
6 #include <net/bluetooth/hci_core.h>
7
8 static struct class *bt_class;
9
10 static void bt_link_release(struct device *dev)
11 {
12         struct hci_conn *conn = to_hci_conn(dev);
13         kfree(conn);
14 }
15
16 static struct device_type bt_link = {
17         .name    = "link",
18         .release = bt_link_release,
19 };
20
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  */
26 static int __match_tty(struct device *dev, void *data)
27 {
28         return !strncmp(dev_name(dev), "rfcomm", 6);
29 }
30
31 void 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
44 void hci_conn_add_sysfs(struct hci_conn *conn)
45 {
46         struct hci_dev *hdev = conn->hdev;
47
48         BT_DBG("conn %p", conn);
49
50         if (device_is_registered(&conn->dev))
51                 return;
52
53         dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
54
55         if (device_add(&conn->dev) < 0) {
56                 BT_ERR("Failed to register connection device");
57                 return;
58         }
59
60         hci_dev_hold(hdev);
61 }
62
63 void hci_conn_del_sysfs(struct hci_conn *conn)
64 {
65         struct hci_dev *hdev = conn->hdev;
66
67         if (!device_is_registered(&conn->dev))
68                 return;
69
70         while (1) {
71                 struct device *dev;
72
73                 dev = device_find_child(&conn->dev, NULL, __match_tty);
74                 if (!dev)
75                         break;
76                 device_move(dev, NULL, DPM_ORDER_DEV_LAST);
77                 put_device(dev);
78         }
79
80         device_del(&conn->dev);
81
82         hci_dev_put(hdev);
83 }
84
85 static void bt_host_release(struct device *dev)
86 {
87         struct hci_dev *hdev = to_hci_dev(dev);
88
89         if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
90                 hci_cleanup_dev(hdev);
91         kfree(hdev);
92         module_put(THIS_MODULE);
93 }
94
95 static struct device_type bt_host = {
96         .name    = "host",
97         .release = bt_host_release,
98 };
99
100 void hci_init_sysfs(struct hci_dev *hdev)
101 {
102         struct device *dev = &hdev->dev;
103
104         dev->type = &bt_host;
105         dev->class = bt_class;
106
107         __module_get(THIS_MODULE);
108         device_initialize(dev);
109 }
110
111 int __init bt_sysfs_init(void)
112 {
113         bt_class = class_create(THIS_MODULE, "bluetooth");
114
115         return PTR_ERR_OR_ZERO(bt_class);
116 }
117
118 void bt_sysfs_cleanup(void)
119 {
120         class_destroy(bt_class);
121 }