[PATCH 09/19] dm: add tag support

Heinrich Schuchardt xypron.glpk at gmx.de
Sat Feb 5 10:34:56 CET 2022


On 2/2/22 02:08, AKASHI Takahiro wrote:
> With dm-tag feature, any U-Boot subsystem is allowed to associate
> arbitrary number of data with a particular udevice. This can been
> see as expanding "struct udevice" without modifying the definition.
>
> As a first user, UEFI subsystem makes use of tags to associate
> an efi_disk object with a block device.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
>   drivers/core/Makefile             |   2 +-
>   drivers/core/root.c               |   2 +
>   drivers/core/tag.c                | 139 ++++++++++++++++++++++++++++++
>   include/asm-generic/global_data.h |   1 +
>   include/dm/tag.h                  | 110 +++++++++++++++++++++++
>   5 files changed, 253 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/core/tag.c
>   create mode 100644 include/dm/tag.h
>
> diff --git a/drivers/core/Makefile b/drivers/core/Makefile
> index 5edd4e413576..3742e7574525 100644
> --- a/drivers/core/Makefile
> +++ b/drivers/core/Makefile
> @@ -2,7 +2,7 @@
>   #
>   # Copyright (c) 2013 Google, Inc
>
> -obj-y	+= device.o fdtaddr.o lists.o root.o uclass.o util.o
> +obj-y	+= device.o fdtaddr.o lists.o root.o uclass.o util.o tag.o
>   obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o
>   obj-$(CONFIG_DEVRES) += devres.o
>   obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE)	+= device-remove.o
> diff --git a/drivers/core/root.c b/drivers/core/root.c
> index e3f87956d866..1aa4819ceb6c 100644
> --- a/drivers/core/root.c
> +++ b/drivers/core/root.c
> @@ -199,6 +199,8 @@ int dm_init(bool of_live)
>   			return ret;
>   	}
>
> +	INIT_LIST_HEAD((struct list_head *)&gd->dmtag_list);
> +
>   	return 0;
>   }
>
> diff --git a/drivers/core/tag.c b/drivers/core/tag.c
> new file mode 100644
> index 000000000000..6829bcd8806c
> --- /dev/null
> +++ b/drivers/core/tag.c
> @@ -0,0 +1,139 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2021 Linaro Limited
> + *			Author: AKASHI Takahiro
> + */
> +
> +#include <malloc.h>
> +#include <asm/global_data.h>
> +#include <dm/tag.h>
> +#include <linux/err.h>
> +#include <linux/list.h>
> +#include <linux/types.h>
> +
> +struct udevice;
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr)
> +{
> +	struct dmtag_node *node;
> +
> +	if (!dev || tag >= DM_TAG_COUNT)
> +		return -EINVAL;
> +
> +	list_for_each_entry(node, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev && node->tag == tag)
> +			return -EEXIST;
> +	}
> +
> +	node = calloc(sizeof(*node), 1);
> +	if (!node)
> +		return -ENOSPC;
> +
> +	node->dev = dev;
> +	node->tag = tag;
> +	node->ptr = ptr;
> +	list_add_tail(&node->sibling, (struct list_head *)&gd->dmtag_list);
> +
> +	return 0;
> +}
> +
> +int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val)
> +{
> +	struct dmtag_node *node;
> +
> +	if (!dev || tag >= DM_TAG_COUNT)
> +		return -EINVAL;
> +
> +	list_for_each_entry(node, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev && node->tag == tag)
> +			return -EEXIST;
> +	}
> +
> +	node = calloc(sizeof(*node), 1);
> +	if (!node)
> +		return -ENOSPC;
> +
> +	node->dev = dev;
> +	node->tag = tag;
> +	node->val = val;
> +	list_add_tail(&node->sibling, (struct list_head *)&gd->dmtag_list);
> +
> +	return 0;
> +}
> +
> +int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp)
> +{
> +	struct dmtag_node *node;
> +
> +	if (!dev || tag >= DM_TAG_COUNT)
> +		return -EINVAL;
> +
> +	list_for_each_entry(node, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev && node->tag == tag) {
> +			*ptrp = node->ptr;
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp)
> +{
> +	struct dmtag_node *node;
> +
> +	if (!dev || tag >= DM_TAG_COUNT)
> +		return -EINVAL;
> +
> +	list_for_each_entry(node, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev && node->tag == tag) {
> +			*valp = node->val;
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +int dev_tag_del(struct udevice *dev, enum dm_tag_t tag)
> +{
> +	struct dmtag_node *node, *tmp;
> +
> +	if (!dev || tag >= DM_TAG_COUNT)
> +		return -EINVAL;
> +
> +	list_for_each_entry_safe(node, tmp, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev && node->tag == tag) {
> +			list_del(&node->sibling);
> +			free(node);
> +
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +int dev_tag_del_all(struct udevice *dev)
> +{
> +	struct dmtag_node *node, *tmp;
> +	bool found = false;
> +
> +	if (!dev)
> +		return -EINVAL;
> +
> +	list_for_each_entry_safe(node, tmp, &gd->dmtag_list, sibling) {
> +		if (node->dev == dev) {
> +			list_del(&node->sibling);
> +			free(node);
> +			found = true;
> +		}
> +	}
> +
> +	if (found)
> +		return 0;
> +
> +	return -ENOENT;
> +}
> diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
> index 9f4598f09ee5..b887bef6deef 100644
> --- a/include/asm-generic/global_data.h
> +++ b/include/asm-generic/global_data.h
> @@ -470,6 +470,7 @@ struct global_data {
>   #if CONFIG_IS_ENABLED(EVENT)
>   	struct event_state *event_state;
>   #endif
> +	struct list_head dmtag_list;

This breaks 'make htmldocs'. You have to describe the new element.

Best regards

Heinrich

>   };
>   #ifndef DO_DEPS_ONLY
>   static_assert(sizeof(struct global_data) == GD_SIZE);
> diff --git a/include/dm/tag.h b/include/dm/tag.h
> new file mode 100644
> index 000000000000..54fc31eb1539
> --- /dev/null
> +++ b/include/dm/tag.h
> @@ -0,0 +1,110 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2021 Linaro Limited
> + *			Author: AKASHI Takahiro
> + */
> +
> +#ifndef _DM_TAG_H
> +#define _DM_TAG_H
> +
> +#include <linux/list.h>
> +#include <linux/types.h>
> +
> +struct udevice;
> +
> +enum dm_tag_t {
> +	/* EFI_LOADER */
> +	DM_TAG_EFI = 0,
> +
> +	DM_TAG_COUNT,
> +};
> +
> +/**
> + * dmtag_node
> + *
> + * @sibling: List of dm-tag nodes
> + * @dev:     Associated udevice
> + * @tag:     Tag type
> + * @ptr:     Pointer as a value
> + * @val:     Value
> + */
> +struct dmtag_node {
> +	struct list_head sibling;
> +	struct  udevice *dev;
> +	enum dm_tag_t tag;
> +	union {
> +		void *ptr;
> +		ulong val;
> +	};
> +};
> +
> +/**
> + * dev_tag_set_ptr() - set a tag's value as a pointer
> + * @dev: Device to operate
> + * @tag: Tag type
> + * @ptr: Pointer to set
> + *
> + * Set the value, @ptr, as of @tag associated with the device, @dev
> + *
> + * Return: 0 on success, -ve on error
> + */
> +int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr);
> +
> +/**
> + * dev_tag_set_val() set a tag's value as an integer
> + * @dev: Device to operate
> + * @tag: Tag type
> + * @val: Value to set
> + *
> + * Set the value, @val, as of @tag associated with the device, @dev
> + *
> + * Return: on success, -ve on error
> + */
> +int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val);
> +
> +/**
> + * dev_tag_get_ptr() - get a tag's value as a pointer
> + * @dev: Device to operate
> + * @tag: Tag type
> + * @ptrp: Pointer to tag's value (pointer)
> + *
> + * Get a tag's value as a pointer
> + *
> + * Return: on success, -ve on error
> + */
> +int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp);
> +
> +/**
> + * dev_tag_get_val() - get a tag's value as an integer
> + * @dev: Device to operate
> + * @tag: Tag type
> + * @valp: Pointer to tag's value (ulong)
> + *
> + * Get a tag's value as an integer
> + *
> + * Return: 0 on success, -ve on error
> + */
> +int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp);
> +
> +/**
> + * dev_tag_del() - delete a tag
> + * @dev: Device to operate
> + * @tag: Tag type
> + *
> + * Delete a tag of @tag associated with the device, @dev
> + *
> + * Return: 0 on success, -ve on error
> + */
> +int dev_tag_del(struct udevice *dev, enum dm_tag_t tag);
> +
> +/**
> + * dev_tag_del_all() - delete all tags
> + * @dev: Device to operate
> + *
> + * Delete all the tags associated with the device, @dev
> + *
> + * Return: 0 on success, -ve on error
> + */
> +int dev_tag_del_all(struct udevice *dev);
> +
> +#endif /* _DM_TAG_H */



More information about the U-Boot mailing list