device: supported devices visitor API
Adds an API to query and visit supported devices. Follows the example set by the required devices API. Implements #37793. Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
parent
0c6588ff47
commit
b01e41ccdd
2 changed files with 103 additions and 7 deletions
|
@ -487,6 +487,47 @@ device_required_handles_get(const struct device *dev,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the set of handles that this device supports.
|
||||
*
|
||||
* The set of supported devices is inferred from devicetree, and does not
|
||||
* include any software constructs that may depend on the device.
|
||||
*
|
||||
* @param dev the device for which supports are desired.
|
||||
*
|
||||
* @param count pointer to a place to store the number of devices provided at
|
||||
* the returned pointer. The value is not set if the call returns a null
|
||||
* pointer. The value may be set to zero.
|
||||
*
|
||||
* @return a pointer to a sequence of @p *count device handles, or a null
|
||||
* pointer if @p dh does not provide dependency information.
|
||||
*/
|
||||
static inline const device_handle_t *
|
||||
device_supported_handles_get(const struct device *dev,
|
||||
size_t *count)
|
||||
{
|
||||
const device_handle_t *rv = dev->handles;
|
||||
size_t region = 0;
|
||||
size_t i = 0;
|
||||
|
||||
if (rv != NULL) {
|
||||
/* Fast forward to supporting devices */
|
||||
while (region != 2) {
|
||||
if (*rv == DEVICE_HANDLE_SEP) {
|
||||
region++;
|
||||
}
|
||||
rv++;
|
||||
}
|
||||
/* Count supporting devices */
|
||||
while (rv[i] != DEVICE_HANDLE_ENDS) {
|
||||
++i;
|
||||
}
|
||||
*count = i;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Visit every device that @p dev directly requires.
|
||||
*
|
||||
|
@ -524,6 +565,42 @@ int device_required_foreach(const struct device *dev,
|
|||
device_visitor_callback_t visitor_cb,
|
||||
void *context);
|
||||
|
||||
/**
|
||||
* @brief Visit every device that @p dev directly supports.
|
||||
*
|
||||
* Zephyr maintains information about which devices are directly supported by
|
||||
* another device; for example an I2C controller will support an I2C-based
|
||||
* sensor driver. Supported devices can derive from statically-defined
|
||||
* devicetree relationships.
|
||||
*
|
||||
* This API supports operating on the set of supported devices. Example uses
|
||||
* include iterating over the devices connected to a regulator when it is
|
||||
* powered on.
|
||||
*
|
||||
* There is no guarantee on the order in which required devices are visited.
|
||||
*
|
||||
* If the @p visitor function returns a negative value iteration is halted,
|
||||
* and the returned value from the visitor is returned from this function.
|
||||
*
|
||||
* @note This API is not available to unprivileged threads.
|
||||
*
|
||||
* @param dev a device of interest. The devices that this device supports
|
||||
* will be used as the set of devices to visit. This parameter must not be
|
||||
* null.
|
||||
*
|
||||
* @param visitor_cb the function that should be invoked on each device in the
|
||||
* support set. This parameter must not be null.
|
||||
*
|
||||
* @param context state that is passed through to the visitor function. This
|
||||
* parameter may be null if @p visitor tolerates a null @p context.
|
||||
*
|
||||
* @return The number of devices that were visited if all visits succeed, or
|
||||
* the negative value returned from the first visit that did not succeed.
|
||||
*/
|
||||
int device_supported_foreach(const struct device *dev,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
void *context);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the device structure for a driver by name
|
||||
*
|
||||
|
|
|
@ -176,14 +176,11 @@ bool z_device_ready(const struct device *dev)
|
|||
return dev->state->initialized && (dev->state->init_res == 0U);
|
||||
}
|
||||
|
||||
int device_required_foreach(const struct device *dev,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
void *context)
|
||||
static int device_visitor(const device_handle_t *handles,
|
||||
size_t handle_count,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
void *context)
|
||||
{
|
||||
size_t handle_count = 0;
|
||||
const device_handle_t *handles =
|
||||
device_required_handles_get(dev, &handle_count);
|
||||
|
||||
/* Iterate over fixed devices */
|
||||
for (size_t i = 0; i < handle_count; ++i) {
|
||||
device_handle_t dh = handles[i];
|
||||
|
@ -197,3 +194,25 @@ int device_required_foreach(const struct device *dev,
|
|||
|
||||
return handle_count;
|
||||
}
|
||||
|
||||
int device_required_foreach(const struct device *dev,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
void *context)
|
||||
{
|
||||
size_t handle_count = 0;
|
||||
const device_handle_t *handles =
|
||||
device_required_handles_get(dev, &handle_count);
|
||||
|
||||
return device_visitor(handles, handle_count, visitor_cb, context);
|
||||
}
|
||||
|
||||
int device_supported_foreach(const struct device *dev,
|
||||
device_visitor_callback_t visitor_cb,
|
||||
void *context)
|
||||
{
|
||||
size_t handle_count = 0;
|
||||
const device_handle_t *handles =
|
||||
device_supported_handles_get(dev, &handle_count);
|
||||
|
||||
return device_visitor(handles, handle_count, visitor_cb, context);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue