diff options
author | Ronald Cron <ronald.cron@arm.com> | 2018-06-05 09:31:39 +0200 |
---|---|---|
committer | Ronald Cron <ronald.cron@arm.com> | 2018-06-08 11:46:47 +0200 |
commit | b151958dbb2f37383f4d9a1f7802c36008d9fef2 (patch) | |
tree | fe20ebfb8c10facbfd028edefe601462ae3ee64c /module/psu | |
parent | fd3027b6fd17a4a33a685adb73f2acfcae9a2ced (diff) |
Add support for SGM-775
Co-authored-by: Filipe Rinaldi <filipe.rinaldi@arm.com>
Co-authored-by: Paul Beesley <paul.beesley@arm.com>
Co-authored-by: Chris Kay <chris.kay@arm.com>
Co-authored-by: Elieva Pignat <elieva.pignat@arm.com>
Co-authored-by: Pedro Custodio <pedro.krewinkelcustodio@arm.com>
Change-Id: Ic7524ad58a7c15d5b055e88a9719b2feee437f1d
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Diffstat (limited to 'module/psu')
-rw-r--r-- | module/psu/include/mod_psu.h | 257 | ||||
-rw-r--r-- | module/psu/src/Makefile | 14 | ||||
-rw-r--r-- | module/psu/src/mod_psu_device_api.c | 224 | ||||
-rw-r--r-- | module/psu/src/mod_psu_device_api_private.h | 16 | ||||
-rw-r--r-- | module/psu/src/mod_psu_event.c | 98 | ||||
-rw-r--r-- | module/psu/src/mod_psu_event_private.h | 29 | ||||
-rw-r--r-- | module/psu/src/mod_psu_module.c | 128 | ||||
-rw-r--r-- | module/psu/src/mod_psu_module_private.h | 28 | ||||
-rw-r--r-- | module/psu/src/mod_psu_private.h | 16 |
9 files changed, 810 insertions, 0 deletions
diff --git a/module/psu/include/mod_psu.h b/module/psu/include/mod_psu.h new file mode 100644 index 00000000..026a2221 --- /dev/null +++ b/module/psu/include/mod_psu.h @@ -0,0 +1,257 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PSU_H +#define MOD_PSU_H + +#include <stdbool.h> +#include <stdint.h> +#include <fwk_id.h> +#include <fwk_module_idx.h> + +/*! + * \ingroup GroupModules + * \defgroup GroupPsu PSU HAL + * \{ + */ + +/*! + * \defgroup GroupPsuApis APIs + * \{ + */ + +/*! + * \brief Device API. + */ +struct mod_psu_device_api { + /*! + * \brief Get the enabled state of a device. + * + * \param device_id Identifier of the device to get the state of. + * \param [out] enabled \c true if the device is enabled, or \c if it is + * disabled. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_HANDLER An error occurred in the device driver. + */ + int (*get_enabled)(fwk_id_t device_id, bool *enabled); + + /*! + * \brief Set the enabled state of a device. + * + * \param device_id Identifier of the device to set the state of. + * \param enable \c true to enable the device, or \c false to disable it. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_HANDLER An error occurred in the device driver. + */ + int (*set_enabled)(fwk_id_t device_id, bool enable); + + /*! + * \brief Set the enabled state of a device. + * + * \param device_id Identifier of the device to set the state of. + * \param enable \c true to enable the device, or \c false to disable it. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_NOMEM The event queue is full. + * \retval FWK_E_PANIC An error in the framework occurred. + */ + int (*set_enabled_async)(fwk_id_t device_id, bool enable); + + /*! + * \brief Get the voltage of a device. + * + * \param device_id Identifier of the device to get the voltage of. + * \param [out] voltage Voltage in mV. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_HANDLER An error occurred in the device driver. + */ + int (*get_voltage)(fwk_id_t device_id, uintmax_t *voltage); + + /*! + * \brief Set the voltage of a device. + * + * \param device_id Identifier of the device to set the voltage of. + * \param voltage New voltage in mV. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_HANDLER An error occurred in the device driver. + */ + int (*set_voltage)(fwk_id_t device_id, uintmax_t voltage); + + /*! + * \brief Set the voltage of a device. + * + * \param device_id Identifier of the device to set the voltage of. + * \param voltage New voltage in mV. + * + * \retval FWK_SUCCESS The operation succeeded. + * \retval FWK_E_PARAM One or more parameters were invalid. + * \retval FWK_E_STATE The element cannot accept the request. + * \retval FWK_E_NOMEM The event queue is full. + * \retval FWK_E_PANIC An error in the framework occurred. + */ + int (*set_voltage_async)(fwk_id_t device_id, uintmax_t voltage); +}; + +/*! + * \brief Driver API. + */ +struct mod_psu_driver_api { + /*! + * \brief Set the enabled state of a device. + * + * \param id Identifier of the device to set the state of. + * \param enable \c true to enable the device, or \c false to disable it. + * + * \retval FWK_SUCCESS The operation succeeded. + * \return One of the other driver-defined error codes. + */ + int (*set_enabled)(fwk_id_t id, bool enable); + + /*! + * \brief Get the enabled state of a device. + * + * \param id Identifier of the device to get the state of. + * \param [out] enabled \c true if the device is enabled, or \c if it is + * disabled. + * + * \retval FWK_SUCCESS The operation succeeded. + * \return One of the other driver-defined error codes. + */ + int (*get_enabled)(fwk_id_t id, bool *enabled); + + /*! + * \brief Set the voltage of a device. + * + * \param id Identifier of the device to set the voltage of. + * \param voltage New voltage in millivolts (mV). + * + * \retval FWK_SUCCESS The operation succeeded. + * \return One of the other driver-defined error codes. + */ + int (*set_voltage)(fwk_id_t id, uintmax_t voltage); + + /*! + * \brief Get the voltage of a device. + * + * \param id Identifier of the device to get the voltage of. + * \param [out] voltage Voltage in millivolts (mV). + * + * \retval FWK_SUCCESS The operation succeeded. + * \return One of the other driver-defined error codes. + */ + int (*get_voltage)(fwk_id_t id, uintmax_t *voltage); +}; + +/*! + * \} + */ + +/*! + * \defgroup GroupPsuConfig Configuration + * \{ + */ + +/*! + * \brief Device configuration. + */ +struct mod_psu_device_config { + fwk_id_t driver_id; /*!< Driver identifier */ + fwk_id_t driver_api_id; /*!< Driver API identifier */ +}; + +/*! + * \} + */ + +/*! + * \defgroup GroupPsuEvents Events + * \{ + */ + +/*! + * \brief <tt>Set enabled</tt> event response parameters. + */ +struct mod_psu_event_params_set_enabled_response { + int status; /*!< Status of the request */ +}; + +/*! + * \brief <tt>Set voltage</tt> event response parameters. + */ +struct mod_psu_event_params_set_voltage_response { + int status; /*!< Status of the request */ +}; + +/*! + * \} + */ + +/*! + * \defgroup GroupPsuIds Identifiers + * \{ + */ + +/*! + * \brief API indices. + */ +enum mod_psu_api_idx { + /*! API index for mod_psu_api_id_psu_device */ + MOD_PSU_API_IDX_PSU_DEVICE, + + /*! Number of defined APIs */ + MOD_PSU_API_IDX_COUNT +}; + +/*! Device API identifier */ +static const fwk_id_t mod_psu_api_id_psu_device = + FWK_ID_API_INIT(FWK_MODULE_IDX_PSU, MOD_PSU_API_IDX_PSU_DEVICE); + +/*! + * \brief Event indices. + */ +enum mod_psu_event_idx { + /*! Event index for mod_psu_event_id_set_enabled */ + MOD_PSU_EVENT_IDX_SET_ENABLED, + + /*! Event index for mod_psu_event_id_set_voltage */ + MOD_PSU_EVENT_IDX_SET_VOLTAGE, + + /*! Number of defined events */ + MOD_PSU_EVENT_IDX_COUNT +}; + +/*! <tt>Set enabled</tt> event identifier */ +static const fwk_id_t mod_psu_event_id_set_enabled = + FWK_ID_EVENT_INIT(FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_SET_ENABLED); + +/*! <tt>Set voltage</tt> event identifier */ +static const fwk_id_t mod_psu_event_id_set_voltage = + FWK_ID_EVENT_INIT(FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_SET_VOLTAGE); + +/*! + * \} + */ + +/*! + * \} + */ + +#endif /* MOD_PSU_H */ diff --git a/module/psu/src/Makefile b/module/psu/src/Makefile new file mode 100644 index 00000000..da070113 --- /dev/null +++ b/module/psu/src/Makefile @@ -0,0 +1,14 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := psu +BS_LIB_SOURCES := \ + mod_psu_device_api.c \ + mod_psu_event.c \ + mod_psu_module.c + +include $(BS_DIR)/lib.mk diff --git a/module/psu/src/mod_psu_device_api.c b/module/psu/src/mod_psu_device_api.c new file mode 100644 index 00000000..f3500d7a --- /dev/null +++ b/module/psu/src/mod_psu_device_api.c @@ -0,0 +1,224 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <fwk_mm.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <fwk_thread.h> +#include <mod_psu_private.h> + +static int api_get_enabled(fwk_id_t device_id, bool *enabled) +{ + int status; + const struct mod_psu_device_ctx *ctx; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to a valid element */ + if (!fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + ctx = __mod_psu_get_valid_device_ctx(device_id); + if (ctx == NULL) + return FWK_E_PARAM; + + /* Get the enabled state from the driver */ + status = ctx->apis.driver->get_enabled(ctx->config->driver_id, enabled); + if (status != FWK_SUCCESS) + return FWK_E_HANDLER; + + return FWK_SUCCESS; +} + +static int api_set_enabled(fwk_id_t device_id, bool enable) +{ + int status; + const struct mod_psu_device_ctx *ctx; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to a valid element */ + if (!fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + ctx = __mod_psu_get_valid_device_ctx(device_id); + if (ctx == NULL) + return FWK_E_PARAM; + + /* Set the enabled state through the driver */ + status = ctx->apis.driver->set_enabled(ctx->config->driver_id, enable); + if (status != FWK_SUCCESS) + return FWK_E_HANDLER; + + return FWK_SUCCESS; +} + +static int api_set_enabled_async(fwk_id_t device_id, bool enable) +{ + int status; + struct fwk_event event; + struct mod_psu_event_params_set_enabled *params; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to an existing element */ + if (fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + /* Build and submit the event */ + event = (struct fwk_event) { + .id = mod_psu_event_id_set_enabled, + .target_id = device_id, + .response_requested = true, + }; + + params = (void *)&event.params; + *params = (struct mod_psu_event_params_set_enabled) { + .enable = enable, + }; + + /* Submit the event for processing */ + status = fwk_thread_put_event(&event); + if (status == FWK_E_NOMEM) + return FWK_E_NOMEM; + else if (status != FWK_SUCCESS) + return FWK_E_PANIC; + + return FWK_SUCCESS; +} + +static int api_get_voltage(fwk_id_t device_id, uintmax_t *voltage) +{ + int status; + const struct mod_psu_device_ctx *ctx; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to a valid element */ + if (!fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + ctx = __mod_psu_get_valid_device_ctx(device_id); + if (ctx == NULL) + return FWK_E_PARAM; + + /* Get the voltage from the driver */ + status = ctx->apis.driver->get_voltage(ctx->config->driver_id, voltage); + if (status != FWK_SUCCESS) + return FWK_E_HANDLER; + + return FWK_SUCCESS; +} + +static int api_set_voltage(fwk_id_t device_id, uintmax_t voltage) +{ + int status; + const struct mod_psu_device_ctx *ctx; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to a valid element */ + if (!fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + ctx = __mod_psu_get_valid_device_ctx(device_id); + if (ctx == NULL) + return FWK_E_PARAM; + + /* Set the voltage state through the driver */ + status = ctx->apis.driver->set_voltage(ctx->config->driver_id, voltage); + if (status != FWK_SUCCESS) + return FWK_E_HANDLER; + + return FWK_SUCCESS; +} + +static int api_set_voltage_async(fwk_id_t device_id, uintmax_t voltage) +{ + int status; + struct fwk_event event; + struct mod_psu_event_params_set_voltage *params; + + /* This API call cannot target another module */ + if (fwk_id_get_module_idx(device_id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the identifier refers to an existing element */ + if (fwk_module_is_valid_element_id(device_id)) + return FWK_E_PARAM; + + /* Validate the API call */ + status = fwk_module_check_call(device_id); + if (status != FWK_SUCCESS) + return FWK_E_STATE; + + /* Build and submit the event */ + event = (struct fwk_event) { + .id = mod_psu_event_id_set_enabled, + .target_id = device_id, + .response_requested = true, + }; + + params = (void *)&event.params; + *params = (struct mod_psu_event_params_set_voltage) { + .voltage = voltage, + }; + + status = fwk_thread_put_event(&event); + if (status == FWK_E_NOMEM) + return FWK_E_NOMEM; + else if (status != FWK_SUCCESS) + return FWK_E_PANIC; + + return FWK_SUCCESS; +} + +/* Module API implementation */ +const struct mod_psu_device_api __mod_psu_device_api = { + .get_enabled = api_get_enabled, + .set_enabled = api_set_enabled, + .set_enabled_async = api_set_enabled_async, + .get_voltage = api_get_voltage, + .set_voltage = api_set_voltage, + .set_voltage_async = api_set_voltage_async, +}; diff --git a/module/psu/src/mod_psu_device_api_private.h b/module/psu/src/mod_psu_device_api_private.h new file mode 100644 index 00000000..6959f594 --- /dev/null +++ b/module/psu/src/mod_psu_device_api_private.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PSU_DEVICE_API_PRIVATE_H +#define MOD_PSU_DEVICE_API_PRIVATE_H + +#include <mod_psu.h> + +/* Module API implementation */ +extern const struct mod_psu_device_api __mod_psu_device_api; + +#endif /* MOD_PSU_DEVICE_API_PRIVATE_H */ diff --git a/module/psu/src/mod_psu_event.c b/module/psu/src/mod_psu_event.c new file mode 100644 index 00000000..104045a6 --- /dev/null +++ b/module/psu/src/mod_psu_event.c @@ -0,0 +1,98 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <fwk_macros.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <mod_psu_private.h> + +int mod_psu_event_set_enabled( + const struct fwk_event *event, + struct fwk_event *response) +{ + const struct mod_psu_device_ctx *ctx; + const struct mod_psu_event_params_set_enabled *params; + struct mod_psu_event_params_set_enabled_response *response_params; + + /* These conditions were checked when we submitted the event */ + assert(fwk_id_get_module_idx(event->target_id) == FWK_MODULE_IDX_PSU); + assert(fwk_module_is_valid_element_id(event->target_id)); + + /* Explicitly cast to our parameter types */ + params = (void *)&event->params; + response_params = (void *)&response->params; + + ctx = __mod_psu_get_device_ctx(event->target_id); + + /* Set the enabled state through the driver */ + response_params->status = ctx->apis.driver->set_enabled( + ctx->config->driver_id, + params->enable); + + return FWK_SUCCESS; +} + +int mod_psu_event_set_voltage( + const struct fwk_event *event, + struct fwk_event *response) +{ + const struct mod_psu_device_ctx *ctx; + const struct mod_psu_event_params_set_voltage *params; + struct mod_psu_event_params_set_voltage_response *response_params; + + /* These conditions were checked when we submitted the event */ + assert(fwk_id_get_module_idx(event->target_id) == FWK_MODULE_IDX_PSU); + assert(fwk_module_is_valid_element_id(event->target_id)); + + /* Explicitly cast to our parameter types */ + params = (void *)&event->params; + response_params = (void *)&response->params; + + ctx = __mod_psu_get_device_ctx(event->target_id); + + /* Set the voltage through the driver */ + response_params->status = ctx->apis.driver->set_voltage( + ctx->config->driver_id, + params->voltage); + + return FWK_SUCCESS; +} + +int __mod_psu_process_event( + const struct fwk_event *event, + struct fwk_event *response) +{ + typedef int (*handler_t)( + const struct fwk_event *event, + struct fwk_event *response); + + static const handler_t handlers[] = { + [MOD_PSU_EVENT_IDX_SET_ENABLED] = mod_psu_event_set_enabled, + [MOD_PSU_EVENT_IDX_SET_VOLTAGE] = mod_psu_event_set_voltage, + }; + + unsigned int event_idx; + handler_t handler; + + /* We only handle the events defined by us */ + if (fwk_id_get_module_idx(event->id) != FWK_MODULE_IDX_PSU) + return FWK_E_PARAM; + + /* Ensure the event index is within bounds we can handle */ + event_idx = fwk_id_get_event_idx(event->id); + if (event_idx >= FWK_ARRAY_SIZE(handlers)) + return FWK_E_PARAM; + + /* Ensure we have an implemented handler for this event */ + handler = handlers[event_idx]; + if (handler == NULL) + return FWK_E_PARAM; + + /* Delegate event handling to the relevant handler */ + return handler(event, response); +} diff --git a/module/psu/src/mod_psu_event_private.h b/module/psu/src/mod_psu_event_private.h new file mode 100644 index 00000000..e451c8ac --- /dev/null +++ b/module/psu/src/mod_psu_event_private.h @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PSU_EVENT_PRIVATE_H +#define MOD_PSU_EVENT_PRIVATE_H + +#include <fwk_event.h> +#include <fwk_id.h> + +/* "Set enabled" event */ +struct mod_psu_event_params_set_enabled { + bool enable; +}; + +/* "Set voltage" event */ +struct mod_psu_event_params_set_voltage { + uintmax_t voltage; +}; + +/* Event handler */ +int __mod_psu_process_event( + const struct fwk_event *event, + struct fwk_event *response); + +#endif /* MOD_PSU_EVENT_PRIVATE_H */ diff --git a/module/psu/src/mod_psu_module.c b/module/psu/src/mod_psu_module.c new file mode 100644 index 00000000..9eab2f1d --- /dev/null +++ b/module/psu/src/mod_psu_module.c @@ -0,0 +1,128 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <fwk_macros.h> +#include <fwk_mm.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <mod_psu_private.h> + +/* Device context table */ +static struct mod_psu_device_ctx (*device_ctx)[]; + +static int psu_init( + fwk_id_t module_id, + unsigned int element_count, + const void *data) +{ + device_ctx = fwk_mm_calloc( + element_count, + sizeof((*device_ctx)[0])); + if (device_ctx == NULL) + return FWK_E_NOMEM; + + return FWK_SUCCESS; +} + +static int psu_element_init( + fwk_id_t device_id, + unsigned int sub_element_count, + const void *data) +{ + assert(sub_element_count == 0); + + __mod_psu_get_device_ctx(device_id)->config = data; + + return FWK_SUCCESS; +} + +static int psu_bind_element(fwk_id_t device_id, unsigned int round) +{ + int status; + const struct mod_psu_device_ctx *ctx; + + /* Only handle the first round */ + if (round > 0) + return FWK_SUCCESS; + + ctx = __mod_psu_get_device_ctx(device_id); + + /* Bind to the driver */ + status = fwk_module_bind( + ctx->config->driver_id, + ctx->config->driver_api_id, + &ctx->apis.driver); + if (status != FWK_SUCCESS) { + assert(false); + + return FWK_E_PANIC; + } + + assert(ctx->apis.driver->set_enabled != NULL); + assert(ctx->apis.driver->get_enabled != NULL); + assert(ctx->apis.driver->set_voltage != NULL); + assert(ctx->apis.driver->get_voltage != NULL); + + return FWK_SUCCESS; +} + +static int psu_bind(fwk_id_t id, unsigned int round) +{ + /* We only need to handle element binding */ + if (fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) + return psu_bind_element(id, round); + + return FWK_SUCCESS; +} + +static int psu_process_bind_request( + fwk_id_t source_id, + fwk_id_t target_id, + fwk_id_t api_id, + const void **api) +{ + /* Only accept binds to the elements */ + if (!fwk_id_is_type(target_id, FWK_ID_TYPE_ELEMENT)) + return FWK_E_PARAM; + + /* Only expose the device API */ + if (!fwk_id_is_equal(api_id, mod_psu_api_id_psu_device)) + return FWK_E_PARAM; + + *api = &__mod_psu_device_api; + + return FWK_SUCCESS; +} + +struct mod_psu_device_ctx *__mod_psu_get_device_ctx(fwk_id_t device_id) +{ + unsigned int element_idx = fwk_id_get_element_idx(device_id); + + return &(*device_ctx)[element_idx]; +} + +struct mod_psu_device_ctx *__mod_psu_get_valid_device_ctx(fwk_id_t device_id) +{ + if (fwk_module_check_call(device_id) != FWK_SUCCESS) + return NULL; + + return __mod_psu_get_device_ctx(device_id); +} + +/* Module description */ +const struct fwk_module module_psu = { + .name = "PSU", + .type = FWK_MODULE_TYPE_HAL, + .init = psu_init, + .element_init = psu_element_init, + .bind = psu_bind, + .process_bind_request = psu_process_bind_request, + .process_event = __mod_psu_process_event, + .api_count = MOD_PSU_API_IDX_COUNT, + .event_count = MOD_PSU_EVENT_IDX_COUNT, +}; diff --git a/module/psu/src/mod_psu_module_private.h b/module/psu/src/mod_psu_module_private.h new file mode 100644 index 00000000..adf01784 --- /dev/null +++ b/module/psu/src/mod_psu_module_private.h @@ -0,0 +1,28 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PSU_DEVICE_CTX_PRIVATE_H +#define MOD_PSU_DEVICE_CTX_PRIVATE_H + +#include <fwk_id.h> +#include <mod_psu.h> + +/* Device context */ +struct mod_psu_device_ctx { + /* Device configuration */ + const struct mod_psu_device_config *config; + + struct { + /* Driver API */ + const struct mod_psu_driver_api *driver; + } apis; +}; + +struct mod_psu_device_ctx *__mod_psu_get_device_ctx(fwk_id_t device_id); +struct mod_psu_device_ctx *__mod_psu_get_valid_device_ctx(fwk_id_t device_id); + +#endif /* MOD_PSU_DEVICE_CTX_PRIVATE_H */ diff --git a/module/psu/src/mod_psu_private.h b/module/psu/src/mod_psu_private.h new file mode 100644 index 00000000..446e9f63 --- /dev/null +++ b/module/psu/src/mod_psu_private.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PSU_PRIVATE_H +#define MOD_PSU_PRIVATE_H + +#include <fwk_id.h> +#include <mod_psu_device_api_private.h> +#include <mod_psu_event_private.h> +#include <mod_psu_module_private.h> + +#endif /* MOD_PSU_PRIVATE_H */ |