diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index dfd4c1deefb..6c15ca61851 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -141,7 +141,7 @@ int lll_init(void) /* Initialize Clocks */ err = lll_clock_init(); - if (err) { + if (err < 0) { return err; } @@ -486,7 +486,7 @@ void lll_isr_cleanup(void *param) radio_tmr_stop(); err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(NULL); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c index 9a20445081f..295afcc3d51 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c @@ -109,7 +109,7 @@ void lll_adv_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, p); LL_ASSERT(!err || err == -EINPROGRESS); @@ -139,7 +139,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param) int err; err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(NULL); @@ -274,7 +274,7 @@ static int is_abort_cb(void *next, int prio, void *curr, /* Retain HF clk */ err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); return -EAGAIN; #endif /* CONFIG_BT_PERIPHERAL */ @@ -312,7 +312,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c index f9152f4ac34..f3cf692743e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c @@ -69,7 +69,7 @@ void lll_adv_aux_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); err = lll_prepare(lll_is_abort_cb, abort_cb, prepare_cb, 0, p); LL_ASSERT(!err || err == -EINPROGRESS); @@ -236,7 +236,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c index 897f94c9b6a..688531295af 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c @@ -72,7 +72,7 @@ void lll_adv_sync_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); /* Instants elapsed */ elapsed = p->lazy + 1; @@ -239,7 +239,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c index 2a51592593f..1fdf964081d 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c @@ -19,106 +19,97 @@ #define LFCLOCK_TIMEOUT_MS 500 #define HFCLOCK_TIMEOUT_MS 2 -static void clock_ready(struct device *dev, clock_control_subsys_t subsys, - void *user_data); +struct lll_clock_state { + struct onoff_client cli; + struct k_sem sem; +}; -static struct device *dev; +static struct onoff_client lf_cli; +static atomic_val_t hf_refcnt; + +static void clock_ready(struct onoff_manager *mgr, struct onoff_client *cli, + uint32_t state, int res) +{ + struct lll_clock_state *clk_state = + CONTAINER_OF(cli, struct lll_clock_state, cli); + + k_sem_give(&clk_state->sem); +} + +static int blocking_on(struct onoff_manager *mgr, uint32_t timeout) +{ + + struct lll_clock_state state; + int err; + + k_sem_init(&state.sem, 0, 1); + sys_notify_init_callback(&state.cli.notify, clock_ready); + err = onoff_request(mgr, &state.cli); + if (err < 0) { + return err; + } + + return k_sem_take(&state.sem, K_MSEC(timeout)); +} int lll_clock_init(void) { - int err; + struct onoff_manager *mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); - dev = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock))); - if (!dev) { - return -ENODEV; - } + sys_notify_init_spinwait(&lf_cli.notify); - err = clock_control_on(dev, CLOCK_CONTROL_NRF_SUBSYS_LF); - - return err; + return onoff_request(mgr, &lf_cli); } int lll_clock_wait(void) { - static bool done; + struct onoff_manager *mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); - if (done) { - return 0; - } - done = true; - - struct k_sem sem_clock_wait; - struct clock_control_async_data async_data = { - .cb = clock_ready, - .user_data = &sem_clock_wait, - }; - int err; - - k_sem_init(&sem_clock_wait, 0, 1); - - err = clock_control_async_on(dev, CLOCK_CONTROL_NRF_SUBSYS_LF, - &async_data); - if (err) { - return err; - } - - err = k_sem_take(&sem_clock_wait, K_MSEC(LFCLOCK_TIMEOUT_MS)); - - return err; + return blocking_on(mgr, LFCLOCK_TIMEOUT_MS); } int lll_hfclock_on(void) { - int err; - - /* turn on radio clock in non-blocking mode. */ - err = clock_control_on(dev, CLOCK_CONTROL_NRF_SUBSYS_HF); - if (!err || err == -EINPROGRESS) { - DEBUG_RADIO_XTAL(1); + if (atomic_inc(&hf_refcnt) > 0) { + return 0; } - return err; + z_nrf_clock_bt_ctlr_hf_request(); + DEBUG_RADIO_XTAL(1); + + return 0; } int lll_hfclock_on_wait(void) { - struct k_sem sem_clock_wait; - struct clock_control_async_data async_data = { - .cb = clock_ready, - .user_data = &sem_clock_wait, - }; + struct onoff_manager *mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); int err; - k_sem_init(&sem_clock_wait, 0, 1); + atomic_inc(&hf_refcnt); - err = clock_control_async_on(dev, CLOCK_CONTROL_NRF_SUBSYS_HF, - &async_data); - LL_ASSERT(!err); - - err = k_sem_take(&sem_clock_wait, K_MSEC(HFCLOCK_TIMEOUT_MS)); - - DEBUG_RADIO_XTAL(1); + err = blocking_on(mgr, HFCLOCK_TIMEOUT_MS); + if (err >= 0) { + DEBUG_RADIO_XTAL(1); + } return err; } int lll_hfclock_off(void) { - int err; - - /* turn off radio clock in non-blocking mode. */ - err = clock_control_off(dev, CLOCK_CONTROL_NRF_SUBSYS_HF); - if (!err) { - DEBUG_RADIO_XTAL(0); - } else if (err == -EBUSY) { - DEBUG_RADIO_XTAL(1); + if (hf_refcnt < 1) { + return -EALREADY; } - return err; -} + if (atomic_dec(&hf_refcnt) > 1) { + return 0; + } -static void clock_ready(struct device *dev, clock_control_subsys_t subsys, - void *user_data) -{ - k_sem_give(user_data); + z_nrf_clock_bt_ctlr_hf_release(); + DEBUG_RADIO_XTAL(0); + + return 0; } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index 3dc4b2e53ff..20780254b2f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -119,7 +119,7 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c index 47ebfd856b5..e2beed9977b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c @@ -69,7 +69,7 @@ void lll_master_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); /* Instants elapsed */ elapsed = p->lazy + 1; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index 24fc1ed5d5a..a120a92b446 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -106,7 +106,7 @@ void lll_scan_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, p); LL_ASSERT(!err || err == -EINPROGRESS); @@ -136,7 +136,7 @@ static int prepare_cb(struct lll_prepare_param *p) int err; err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(NULL); @@ -317,7 +317,7 @@ static int is_abort_cb(void *next, int prio, void *curr, /* Retain HF clock */ err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); return -EAGAIN; } @@ -359,7 +359,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index 5d1ebaa41ed..016bbcba466 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -72,7 +72,7 @@ void lll_scan_aux_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); err = lll_prepare(lll_is_abort_cb, abort_cb, prepare_cb, 0, p); LL_ASSERT(!err || err == -EINPROGRESS); @@ -223,7 +223,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) * currently in preparation pipeline. */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); lll_done(param); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c index b5a907d7aa5..4843748561f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c @@ -69,7 +69,7 @@ void lll_slave_prepare(void *param) int err; err = lll_hfclock_on(); - LL_ASSERT(!err || err == -EINPROGRESS); + LL_ASSERT(err >= 0); /* Instants elapsed */ elapsed = p->lazy + 1; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_test.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_test.c index 20ba0275a69..2fefd2f6dd3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_test.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_test.c @@ -336,7 +336,7 @@ uint32_t ll_test_end(uint16_t *num_rx) /* Release resources acquired for Radio */ err = lll_hfclock_off(); - LL_ASSERT(!err || err == -EBUSY); + LL_ASSERT(err >= 0); /* Stop coarse timer */ cntr_stop();