libplatsupportports: Look for BPMP interface This commit changes the TX2 reset and clock drivers to try to look for a BPMP interface instance in the interface registration service before initialising the interface itself. This is mostly for streamlining the process of being able to share the BPMP interface between drivers which require access to the BPMP interface.
diff --git a/libplatsupportports/src/plat/tx2/clock.c b/libplatsupportports/src/plat/tx2/clock.c index 30e5b22..db2f883 100644 --- a/libplatsupportports/src/plat/tx2/clock.c +++ b/libplatsupportports/src/plat/tx2/clock.c
@@ -181,6 +181,14 @@ return NULL; } +static int interface_search_handler(void *handler_data, void *interface_instance, char **properties) +{ + /* Select the first one that is registered */ + tx2_clk_t *clk = handler_data; + clk->bpmp = (struct tx2_bpmp *) interface_instance; + return PS_INTERFACE_FOUND_MATCH; +} + int clock_sys_init(ps_io_ops_t *io_ops, clock_sys_t *clock_sys) { if (!io_ops || !clock_sys) { @@ -196,7 +204,7 @@ } int error = 0; - bool bpmp_initialised = false; + tx2_clk_t *clk = NULL; error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(tx2_clk_t), (void **) &clock_sys->priv); if (error) { @@ -205,7 +213,7 @@ goto fail; } - tx2_clk_t *clk = clock_sys->priv; + clk = clock_sys->priv; void *car_vaddr = NULL; car_vaddr = ps_io_map(&io_ops->io_mapper, TX2_CLKCAR_PADDR, TX2_CLKCAR_SIZE, 0, PS_MEM_NORMAL); @@ -217,12 +225,23 @@ clk->car_vaddr = car_vaddr; - error = tx2_bpmp_init(io_ops, &clk->bpmp); + /* See if there's a registered interface for the BPMP, if not, create one + * ourselves */ + error = ps_interface_find(&io_ops->interface_registration_ops, TX2_BPMP_INTERFACE, + interface_search_handler, clk); if (error) { - goto fail; - } + error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(struct tx2_bpmp), (void **) &clk->bpmp); + if (error) { + ZF_LOGE("Failed to allocate memory for the BPMP structure"); + goto fail; + } - bpmp_initialised = true; + error = tx2_bpmp_init(io_ops, clk->bpmp); + if (error) { + ZF_LOGE("Failed to initialise BPMP interface"); + goto fail; + } + } clk->io_ops = io_ops; @@ -238,12 +257,12 @@ } if (clock_sys->priv) { - ps_free(&io_ops->malloc_ops, sizeof(tx2_clk_t), (void *) clock_sys->priv); - } - - if (bpmp_initialised) { - ZF_LOGF_IF(tx2_bpmp_destroy(io_ops, clk->bpmp), - "Failed to cleanup after a failed clock system initialisation"); + if (clk->bpmp) { + ZF_LOGF_IF(ps_free(&io_ops->malloc_ops, sizeof(struct tx2_bpmp), (void *) clk->bpmp), + "Failed to free the BPMP structure after failing to initialise"); + } + ZF_LOGF_IF(ps_free(&io_ops->malloc_ops, sizeof(tx2_clk_t), (void *) clock_sys->priv), + "Failed to free the clock private structure after failing to initialise"); } return error;
diff --git a/libplatsupportports/src/plat/tx2/reset.c b/libplatsupportports/src/plat/tx2/reset.c index ecfaf9a..75fb8f1 100644 --- a/libplatsupportports/src/plat/tx2/reset.c +++ b/libplatsupportports/src/plat/tx2/reset.c
@@ -62,7 +62,15 @@ return tx2_reset_common(data, id, false); } -int reset_sys_init(ps_io_ops_t *io_ops, void *dependecies, reset_sys_t *reset_sys) +static int interface_search_handler(void *handler_data, void *interface_instance, char **properties) +{ + /* Select the first one that is registered */ + tx2_reset_t *reset = handler_data; + reset->bpmp = (struct tx2_bpmp *) interface_instance; + return PS_INTERFACE_FOUND_MATCH; +} + +int reset_sys_init(ps_io_ops_t *io_ops, void *dependencies, reset_sys_t *reset_sys) { if (!io_ops || !reset_sys) { if (!io_ops) { @@ -77,7 +85,8 @@ } int error = 0; - bool bpmp_initialised = false; + bool bpmp_allocated = false; + tx2_reset_t *reset = NULL; error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(tx2_reset_t), (void **) &reset_sys->data); if (error) { ZF_LOGE("Failed to allocate memory for reset sys internal structure"); @@ -85,15 +94,30 @@ goto fail; } - tx2_reset_t *reset = reset_sys->data; + reset = reset_sys->data; - error = tx2_bpmp_init(io_ops, &reset->bpmp); - if (error) { - goto fail; + if (dependencies) { + reset->bpmp = (struct tx2_bpmp *) dependencies; + } else { + /* See if there's a registered interface for the BPMP, if not, then we + * initialise one ourselves. */ + error = ps_interface_find(&io_ops->interface_registration_ops, TX2_BPMP_INTERFACE, + interface_search_handler, reset); + if (error) { + error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(struct tx2_bpmp), (void **) &reset->bpmp); + if (error) { + ZF_LOGE("Failed to allocate memory for the BPMP structure to be initialised"); + goto fail; + } + + error = tx2_bpmp_init(io_ops, reset->bpmp); + if (error) { + ZF_LOGE("Failed to initialise the BPMP"); + goto fail; + } + } } - bpmp_initialised = true; - reset_sys->reset_assert = &tx2_reset_assert; reset_sys->reset_deassert = &tx2_reset_deassert; @@ -101,13 +125,13 @@ fail: - if (bpmp_initialised) { - ZF_LOGF_IF(tx2_bpmp_destroy(io_ops, reset->bpmp), - "Failed to cleanup the BPMP after a failed reset system initialisation"); - } - if (reset_sys->data) { - ps_free(&io_ops->malloc_ops, sizeof(tx2_reset_t), (void *) reset_sys->data); + if (reset->bpmp) { + ZF_LOGF_IF(ps_free(&io_ops->malloc_ops, sizeof(struct tx2_bpmp), (void *) reset->bpmp), + "Failed to free the BPMP structure after a failed reset subsystem initialisation"); + } + ZF_LOGF_IF(ps_free(&io_ops->malloc_ops, sizeof(tx2_reset_t), (void *) reset_sys->data), + "Failed to free the reset private data after a failed reset subsystem initialisation"); } return error;