in hci_serdev.c [294:381]
int hci_uart_register_device(struct hci_uart *hu,
const struct hci_uart_proto *p)
{
int err;
struct hci_dev *hdev;
BT_DBG("");
serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops);
err = serdev_device_open(hu->serdev);
if (err)
return err;
err = p->open(hu);
if (err)
goto err_open;
hu->proto = p;
set_bit(HCI_UART_PROTO_READY, &hu->flags);
/* Initialize and register HCI device */
hdev = hci_alloc_dev();
if (!hdev) {
BT_ERR("Can't allocate HCI device");
err = -ENOMEM;
goto err_alloc;
}
hu->hdev = hdev;
hdev->bus = HCI_UART;
hci_set_drvdata(hdev, hu);
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);
percpu_init_rwsem(&hu->proto_lock);
/* Only when vendor specific setup callback is provided, consider
* the manufacturer information valid. This avoids filling in the
* value for Ericsson when nothing is specified.
*/
if (hu->proto->setup)
hdev->manufacturer = hu->proto->manufacturer;
hdev->open = hci_uart_open;
hdev->close = hci_uart_close;
hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame;
hdev->setup = hci_uart_setup;
SET_HCIDEV_DEV(hdev, &hu->serdev->dev);
if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags))
set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
hdev->dev_type = HCI_AMP;
else
hdev->dev_type = HCI_PRIMARY;
if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
return 0;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
err = -ENODEV;
goto err_register;
}
set_bit(HCI_UART_REGISTERED, &hu->flags);
return 0;
err_register:
hci_free_dev(hdev);
err_alloc:
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
p->close(hu);
err_open:
serdev_device_close(hu->serdev);
return err;
}