hci_sysfs.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Bluetooth HCI driver model support. */
  3. #include <linux/module.h>
  4. #include <net/bluetooth/bluetooth.h>
  5. #include <net/bluetooth/hci_core.h>
  6. static struct class *bt_class;
  7. static void bt_link_release(struct device *dev)
  8. {
  9. struct hci_conn *conn = to_hci_conn(dev);
  10. kfree(conn);
  11. }
  12. static const struct device_type bt_link = {
  13. .name = "link",
  14. .release = bt_link_release,
  15. };
  16. /*
  17. * The rfcomm tty device will possibly retain even when conn
  18. * is down, and sysfs doesn't support move zombie device,
  19. * so we should move the device before conn device is destroyed.
  20. */
  21. static int __match_tty(struct device *dev, void *data)
  22. {
  23. return !strncmp(dev_name(dev), "rfcomm", 6);
  24. }
  25. void hci_conn_init_sysfs(struct hci_conn *conn)
  26. {
  27. struct hci_dev *hdev = conn->hdev;
  28. BT_DBG("conn %p", conn);
  29. conn->dev.type = &bt_link;
  30. conn->dev.class = bt_class;
  31. conn->dev.parent = &hdev->dev;
  32. device_initialize(&conn->dev);
  33. }
  34. void hci_conn_add_sysfs(struct hci_conn *conn)
  35. {
  36. struct hci_dev *hdev = conn->hdev;
  37. BT_DBG("conn %p", conn);
  38. dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
  39. if (device_add(&conn->dev) < 0) {
  40. bt_dev_err(hdev, "failed to register connection device");
  41. return;
  42. }
  43. hci_dev_hold(hdev);
  44. }
  45. void hci_conn_del_sysfs(struct hci_conn *conn)
  46. {
  47. struct hci_dev *hdev = conn->hdev;
  48. if (!device_is_registered(&conn->dev))
  49. return;
  50. while (1) {
  51. struct device *dev;
  52. dev = device_find_child(&conn->dev, NULL, __match_tty);
  53. if (!dev)
  54. break;
  55. device_move(dev, NULL, DPM_ORDER_DEV_LAST);
  56. put_device(dev);
  57. }
  58. device_del(&conn->dev);
  59. hci_dev_put(hdev);
  60. }
  61. static void bt_host_release(struct device *dev)
  62. {
  63. struct hci_dev *hdev = to_hci_dev(dev);
  64. if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
  65. hci_cleanup_dev(hdev);
  66. kfree(hdev);
  67. module_put(THIS_MODULE);
  68. }
  69. static const struct device_type bt_host = {
  70. .name = "host",
  71. .release = bt_host_release,
  72. };
  73. void hci_init_sysfs(struct hci_dev *hdev)
  74. {
  75. struct device *dev = &hdev->dev;
  76. dev->type = &bt_host;
  77. dev->class = bt_class;
  78. __module_get(THIS_MODULE);
  79. device_initialize(dev);
  80. }
  81. int __init bt_sysfs_init(void)
  82. {
  83. bt_class = class_create(THIS_MODULE, "bluetooth");
  84. return PTR_ERR_OR_ZERO(bt_class);
  85. }
  86. void bt_sysfs_cleanup(void)
  87. {
  88. class_destroy(bt_class);
  89. }