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 void hci_conn_init_sysfs(struct hci_conn *conn) 25 { 26 struct hci_dev *hdev = conn->hdev; 27 28 bt_dev_dbg(hdev, "conn %p", conn); 29 30 conn->dev.type = &bt_link; 31 conn->dev.class = &bt_class; 32 conn->dev.parent = &hdev->dev; 33 34 device_initialize(&conn->dev); 35 } 36 37 void hci_conn_add_sysfs(struct hci_conn *conn) 38 { 39 struct hci_dev *hdev = conn->hdev; 40 41 bt_dev_dbg(hdev, "conn %p", conn); 42 43 if (device_is_registered(&conn->dev)) 44 return; 45 46 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); 47 48 if (device_add(&conn->dev) < 0) 49 bt_dev_err(hdev, "failed to register connection device"); 50 } 51 52 void hci_conn_del_sysfs(struct hci_conn *conn) 53 { 54 struct hci_dev *hdev = conn->hdev; 55 56 bt_dev_dbg(hdev, "conn %p", conn); 57 58 if (!device_is_registered(&conn->dev)) { 59 /* If device_add() has *not* succeeded, use *only* put_device() 60 * to drop the reference count. 61 */ 62 put_device(&conn->dev); 63 return; 64 } 65 66 /* If there are devices using the connection as parent reset it to NULL 67 * before unregistering the device. 68 */ 69 while (1) { 70 struct device *dev; 71 72 dev = device_find_any_child(&conn->dev); 73 if (!dev) 74 break; 75 device_move(dev, NULL, DPM_ORDER_DEV_LAST); 76 put_device(dev); 77 } 78 79 device_unregister(&conn->dev); 80 } 81 82 static void bt_host_release(struct device *dev) 83 { 84 struct hci_dev *hdev = to_hci_dev(dev); 85 86 if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) 87 hci_release_dev(hdev); 88 else 89 kfree(hdev); 90 module_put(THIS_MODULE); 91 } 92 93 static const struct device_type bt_host = { 94 .name = "host", 95 .release = bt_host_release, 96 }; 97 98 void hci_init_sysfs(struct hci_dev *hdev) 99 { 100 struct device *dev = &hdev->dev; 101 102 dev->type = &bt_host; 103 dev->class = &bt_class; 104 105 __module_get(THIS_MODULE); 106 device_initialize(dev); 107 } 108 109 int __init bt_sysfs_init(void) 110 { 111 return class_register(&bt_class); 112 } 113 114 void bt_sysfs_cleanup(void) 115 { 116 class_unregister(&bt_class); 117 } 118