Skip to content

Commit

Permalink
drivers: bluetooth: hci: added h4_close() support
Browse files Browse the repository at this point in the history
- added h4_close() support in h4 driver to de-init hci driver
  instance to allow bluetooth stack de-init when calling
  bt_disable() function.
- added flag in nxp setup driver to perform HCI controller firmware-
  load and configuration only once. This avoid loading/setting-up
  controller firmware on successive h4_open() after h4_close().
- added HCI command to send HCI_RESET in bt_disable() func, and
  remove its call from the driver close() call.

Signed-off-by: Nirav Agrawal <[email protected]>
  • Loading branch information
nirav-agrawal committed Mar 5, 2025
1 parent 14f382b commit c221ccf
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 29 deletions.
25 changes: 23 additions & 2 deletions drivers/bluetooth/hci/h4.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright 2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -256,8 +257,10 @@ static void rx_thread(void *p1, void *p2, void *p3)
do {
uart_irq_rx_enable(cfg->uart);

LOG_DBG("Calling bt_recv(%p)", buf);
h4->recv(dev, buf);
if (h4->recv != NULL) {
LOG_DBG("Calling bt_recv(%p)", buf);
h4->recv(dev, buf);
}

/* Give other threads a chance to run if the ISR
* is receiving data so fast that rx.fifo never
Expand Down Expand Up @@ -545,6 +548,23 @@ static int h4_open(const struct device *dev, bt_hci_recv_t recv)
return 0;
}

static int h4_close(const struct device *dev)
{
struct h4_data *h4 = dev->data;
const struct h4_config *cfg = dev->config;
int ret = 0;

LOG_DBG("");

uart_irq_rx_disable(cfg->uart);
uart_irq_tx_disable(cfg->uart);

h4->recv = NULL;
k_thread_abort((k_tid_t)cfg->rx_thread);

return ret;
}

#if defined(CONFIG_BT_HCI_SETUP)
static int h4_setup(const struct device *dev, const struct bt_hci_setup_params *params)
{
Expand All @@ -567,6 +587,7 @@ static int h4_setup(const struct device *dev, const struct bt_hci_setup_params *
static DEVICE_API(bt_hci, h4_driver_api) = {
.open = h4_open,
.send = h4_send,
.close = h4_close,
#if defined(CONFIG_BT_HCI_SETUP)
.setup = h4_setup,
#endif
Expand Down
19 changes: 7 additions & 12 deletions drivers/bluetooth/hci/hci_nxp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 NXP
* Copyright 2023-2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -507,19 +507,14 @@ static int bt_nxp_close(const struct device *dev)
{
struct bt_nxp_data *hci = dev->data;
int ret = 0;
/* Reset the Controller */
if (IS_ENABLED(CONFIG_BT_HCI_HOST)) {
ret = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL);
if (ret) {
LOG_ERR("Failed to reset BLE controller");
}
k_sleep(K_SECONDS(1));

ret = PLATFORM_TerminateBle();
if (ret < 0) {
LOG_ERR("Failed to shutdown BLE controller");
}
k_sleep(K_SECONDS(1));

ret = PLATFORM_TerminateBle();
if (ret < 0) {
LOG_ERR("Failed to shutdown BLE controller");
}

hci->recv = NULL;

return ret;
Expand Down
23 changes: 16 additions & 7 deletions drivers/bluetooth/hci/hci_nxp_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ struct nxp_ctlr_fw_upload_state {
bool is_error_case;
bool is_cmd7_req;
bool is_entry_point_req;
bool is_setup_done;

uint8_t last_5bytes_buffer[6];
};
Expand Down Expand Up @@ -1171,11 +1172,15 @@ static int bt_nxp_ctlr_init(void)

int bt_hci_transport_setup(const struct device *dev)
{
int ret = 0;
if (dev != uart_dev) {
return -EINVAL;
}

return bt_nxp_ctlr_init();
if (!fw_upload.is_setup_done) {
ret = bt_nxp_ctlr_init();
}
return ret;
}

#define BT_HCI_VSC_BAUDRATE_UPDATE_LENGTH 4
Expand Down Expand Up @@ -1228,19 +1233,23 @@ int bt_h4_vnd_setup(const struct device *dev)
return 0;
}

err = bt_hci_baudrate_update(dev, operation_speed);
if (err) {
return err;
}
if (!fw_upload.is_setup_done) {
err = bt_hci_baudrate_update(dev, operation_speed);
if (err) {
return err;
}

/* BT waiting time after controller bandrate updated */
(void)k_msleep(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_BAUDRATE_UPDATE);
/* BT waiting time after controller bandrate updated */
(void)k_msleep(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_BAUDRATE_UPDATE);
}

err = fw_upload_uart_reconfig(operation_speed, flowcontrol_of_hci);
if (err) {
LOG_ERR("Fail to update uart bandrate");
return err;
}

fw_upload.is_setup_done = true;

return 0;
}
9 changes: 1 addition & 8 deletions drivers/bluetooth/hci/ipc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
* Copyright 2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -351,14 +352,6 @@ static int bt_ipc_close(const struct device *dev)
struct ipc_data *ipc = dev->data;
int err;

if (IS_ENABLED(CONFIG_BT_HCI_HOST)) {
err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL);
if (err) {
LOG_ERR("Sending reset command failed with: %d", err);
return err;
}
}

err = ipc_service_deregister_endpoint(&ipc->hci_ept);
if (err) {
LOG_ERR("Deregistering HCI endpoint failed with: %d", err);
Expand Down
13 changes: 13 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/*
* Copyright (c) 2017-2021 Nordic Semiconductor ASA
* Copyright (c) 2015-2016 Intel Corporation
* Copyright 2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -4382,6 +4383,18 @@ int bt_disable(void)
disconnected_handles_reset();
#endif /* CONFIG_BT_CONN */

/* Reset the Controller */
if (!drv_quirk_no_reset()) {
struct net_buf *rsp;
err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp);
if (err) {
LOG_ERR("Failed to reset BLE controller");
return err;
}
hci_reset_complete(rsp);
net_buf_unref(rsp);
}

err = bt_hci_close(bt_dev.hci);
if (err == -ENOSYS) {
atomic_clear_bit(bt_dev.flags, BT_DEV_DISABLE);
Expand Down

0 comments on commit c221ccf

Please sign in to comment.