1 // SPDX-License-Identifier: GPL-2.0
2 /* Bluetooth HCI driver model support. */
4 #include <linux/module.h>
6 #include <net/bluetooth/bluetooth.h>
7 #include <net/bluetooth/hci_core.h>
9 static struct class *bt_class
;
11 static void bt_link_release(struct device
*dev
)
13 struct hci_conn
*conn
= to_hci_conn(dev
);
17 static const struct device_type bt_link
= {
19 .release
= bt_link_release
,
23 * The rfcomm tty device will possibly retain even when conn
24 * is down, and sysfs doesn't support move zombie device,
25 * so we should move the device before conn device is destroyed.
27 static int __match_tty(struct device
*dev
, void *data
)
29 return !strncmp(dev_name(dev
), "rfcomm", 6);
32 void hci_conn_init_sysfs(struct hci_conn
*conn
)
34 struct hci_dev
*hdev
= conn
->hdev
;
36 BT_DBG("conn %p", conn
);
38 conn
->dev
.type
= &bt_link
;
39 conn
->dev
.class = bt_class
;
40 conn
->dev
.parent
= &hdev
->dev
;
42 device_initialize(&conn
->dev
);
45 void hci_conn_add_sysfs(struct hci_conn
*conn
)
47 struct hci_dev
*hdev
= conn
->hdev
;
49 BT_DBG("conn %p", conn
);
51 dev_set_name(&conn
->dev
, "%s:%d", hdev
->name
, conn
->handle
);
53 if (device_add(&conn
->dev
) < 0) {
54 bt_dev_err(hdev
, "failed to register connection device");
61 void hci_conn_del_sysfs(struct hci_conn
*conn
)
63 struct hci_dev
*hdev
= conn
->hdev
;
65 if (!device_is_registered(&conn
->dev
))
71 dev
= device_find_child(&conn
->dev
, NULL
, __match_tty
);
74 device_move(dev
, NULL
, DPM_ORDER_DEV_LAST
);
78 device_del(&conn
->dev
);
83 static void bt_host_release(struct device
*dev
)
85 struct hci_dev
*hdev
= to_hci_dev(dev
);
87 module_put(THIS_MODULE
);
90 static const struct device_type bt_host
= {
92 .release
= bt_host_release
,
95 void hci_init_sysfs(struct hci_dev
*hdev
)
97 struct device
*dev
= &hdev
->dev
;
100 dev
->class = bt_class
;
102 __module_get(THIS_MODULE
);
103 device_initialize(dev
);
106 int __init
bt_sysfs_init(void)
108 bt_class
= class_create(THIS_MODULE
, "bluetooth");
110 return PTR_ERR_OR_ZERO(bt_class
);
113 void bt_sysfs_cleanup(void)
115 class_destroy(bt_class
);