1 // SPDX-License-Identifier: GPL-2.0 2 /* Bluetooth HCI driver model support. */ 3 4 #include <linux/module.h> 5 6 #include <net/bluetooth/bluetooth.h> 7 #include <net/bluetooth/hci_core.h> 8 9 static const struct class bt_class = { 10 .name = "bluetooth", 11 }; 12 13 static void bt_link_release(struct device *dev) 14 { 15 struct hci_conn *conn = to_hci_conn(dev); 16 kfree(conn); 17 } 18 19 static const struct device_type bt_link = { 20 .name = "link", 21 .release = bt_link_release, 22 }; 23 24 /* 25 * The rfcomm tty device will possibly retain even when conn 26 * is down, and sysfs doesn't support move zombie device, 27 * so we should move the device before conn device is destroyed. 28 */ 29 static int __match_tty(struct device *dev, void *data) 30 { 31 return !strncmp(dev_name(dev), "rfcomm", 6); 32 } 33 34 void hci_conn_init_sysfs(struct hci_conn *conn) 35 { 36 struct hci_dev *hdev = conn->hdev; 37 38 bt_dev_dbg(hdev, "conn %p", conn); 39 40 conn->dev.type = &bt_link; 41 conn->dev.class = &bt_class; 42 conn->dev.parent = &hdev->dev; 43 44 device_initialize(&conn->dev); 45 } 46 47 void hci_conn_add_sysfs(struct hci_conn *conn) 48 { 49 struct hci_dev *hdev = conn->hdev; 50 51 bt_dev_dbg(hdev, "conn %p", conn); 52 53 if (device_is_registered(&conn->dev)) 54 return; 55 56 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); 57 58 if (device_add(&conn->dev) < 0) 59 bt_dev_err(hdev, "failed to register connection device"); 60 } 61 62 void hci_conn_del_sysfs(struct hci_conn *conn) 63 { 64 struct hci_dev *hdev = conn->hdev; 65 66 bt_dev_dbg(hdev, "conn %p", conn); 67 68 if (!device_is_registered(&conn->dev)) { 69 /* If device_add() has *not* succeeded, use *only* put_device() 70 * to drop the reference count. 71 */ 72 put_device(&conn->dev); 73 return; 74 } 75 76 while (1) { 77 struct device *dev; 78 79 dev = device_find_child(&conn->dev, NULL, __match_tty); 80 if (!dev) 81 break; 82 device_move(dev, NULL, DPM_ORDER_DEV_LAST); 83 put_device(dev); 84 } 85 86 device_unregister(&conn->dev); 87 } 88 89 static void bt_host_release(struct device *dev) 90 { 91 struct hci_dev *hdev = to_hci_dev(dev); 92 93 if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) 94 hci_release_dev(hdev); 95 else 96 kfree(hdev); 97 module_put(THIS_MODULE); 98 } 99 100 static const struct device_type bt_host = { 101 .name = "host", 102 .release = bt_host_release, 103 }; 104 105 void hci_init_sysfs(struct hci_dev *hdev) 106 { 107 struct device *dev = &hdev->dev; 108 109 dev->type = &bt_host; 110 dev->class = &bt_class; 111 112 __module_get(THIS_MODULE); 113 device_initialize(dev); 114 } 115 116 int __init bt_sysfs_init(void) 117 { 118 return class_register(&bt_class); 119 } 120 121 void bt_sysfs_cleanup(void) 122 { 123 class_unregister(&bt_class); 124 } 125
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.