at master 2.7 kB view raw
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 9static const struct class bt_class = { 10 .name = "bluetooth", 11}; 12 13static void bt_link_release(struct device *dev) 14{ 15 struct hci_conn *conn = to_hci_conn(dev); 16 kfree(conn); 17} 18 19static const struct device_type bt_link = { 20 .name = "link", 21 .release = bt_link_release, 22}; 23 24void 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 37void 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 52void 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 82static 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 93static ssize_t reset_store(struct device *dev, struct device_attribute *attr, 94 const char *buf, size_t count) 95{ 96 struct hci_dev *hdev = to_hci_dev(dev); 97 98 if (hdev->reset) 99 hdev->reset(hdev); 100 101 return count; 102} 103static DEVICE_ATTR_WO(reset); 104 105static struct attribute *bt_host_attrs[] = { 106 &dev_attr_reset.attr, 107 NULL, 108}; 109ATTRIBUTE_GROUPS(bt_host); 110 111static const struct device_type bt_host = { 112 .name = "host", 113 .release = bt_host_release, 114 .groups = bt_host_groups, 115}; 116 117void hci_init_sysfs(struct hci_dev *hdev) 118{ 119 struct device *dev = &hdev->dev; 120 121 dev->type = &bt_host; 122 dev->class = &bt_class; 123 124 __module_get(THIS_MODULE); 125 device_initialize(dev); 126} 127 128int __init bt_sysfs_init(void) 129{ 130 return class_register(&bt_class); 131} 132 133void bt_sysfs_cleanup(void) 134{ 135 class_unregister(&bt_class); 136}