[U-Boot] [PATCH v2 1/3] drivers: Add board uclass

Dr. Philipp Tomsich philipp.tomsich at theobroma-systems.com
Fri Apr 27 13:02:57 UTC 2018


> On 27 Apr 2018, at 14:51, Mario Six <mario.six at gdsys.cc> wrote:
> 
> Since there is no canonical "board device" that can be used in board
> files, it is difficult to use DM function for board initialization in
> these cases.
> 
> Hence, add a uclass that implements a simple "board device", which can
> hold devices not suitable anywhere else in the device tree, and is also
> able to read encoded information, e.g. hard-wired GPIOs on a GPIO
> expander, read-only memory ICs, etc. that carry information about the
> hardware.

A board-uclass should model a board (i.e. provide implementations for
the same key abstractions that we have in place today: e.g., board_init).

This seems more like a specialised form of a misc-device.

> The devices of this uclass expose methods to read generic data types
> (integers, strings, booleans) to encode the information provided by the
> hardware.

Again, this is what a misc-device is intended for… and extending the
misc-device APIs (or having a convenience layer on top of its ioctl
interface?) might be more appropriate.

After reviewing the below, the similarities to the misc-device are even
more apparent: if you need typed access to a key-value pair, this can
be easily implemented through a common ioctl with semantic sugar
at the misc-uclass level.

> Signed-off-by: Mario Six <mario.six at gdsys.cc>
> ---
> 
> v1 -> v2:
> * Corrected description of dev parameter of devinfo_detect
> * Added size parameter to devinfo_get_str
> * Expanded uclass documentation
> * Added function to get devinfo instance
> * Renamed the uclass from devinfo to board
> 
> ---
> drivers/Kconfig              |   2 +
> drivers/Makefile             |   1 +
> drivers/board/Kconfig        |  17 +++++++
> drivers/board/Makefile       |   9 ++++
> drivers/board/board-uclass.c |  61 +++++++++++++++++++++++
> include/board.h              | 115 +++++++++++++++++++++++++++++++++++++++++++
> include/dm/uclass-id.h       |   1 +
> 7 files changed, 206 insertions(+)
> create mode 100644 drivers/board/Kconfig
> create mode 100644 drivers/board/Makefile
> create mode 100644 drivers/board/board-uclass.c
> create mode 100644 include/board.h
> 
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index c2e813f5ad..19c7c448c0 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -22,6 +22,8 @@ source "drivers/ddr/Kconfig"
> 
> source "drivers/demo/Kconfig"
> 
> +source "drivers/board/Kconfig"
> +
> source "drivers/ddr/fsl/Kconfig"
> 
> source "drivers/dfu/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 6846d181aa..fecf64021c 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -72,6 +72,7 @@ obj-y += block/
> obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
> obj-$(CONFIG_CPU) += cpu/
> obj-y += crypto/
> +obj-y += board/
> obj-y += firmware/
> obj-$(CONFIG_FPGA) += fpga/
> obj-y += misc/
> diff --git a/drivers/board/Kconfig b/drivers/board/Kconfig
> new file mode 100644
> index 0000000000..cc1cf27205
> --- /dev/null
> +++ b/drivers/board/Kconfig
> @@ -0,0 +1,17 @@
> +menuconfig BOARD
> +	bool "Device Information"
> +	help
> +	  Support methods to query hardware configurations from internal
> +	  mechanisms (e.g. reading GPIO values, determining the presence of
> +	  devices on busses, etc.). This enables the usage of U-Boot with
> +	  modular board architectures.
> +
> +if BOARD
> +
> +
> +config BOARD_GAZERBEAM
> +	bool "Enable device information for the Gazerbeam board"
> +	help
> +	  Support querying device information for the gdsys Gazerbeam board.
> +
> +endif
> diff --git a/drivers/board/Makefile b/drivers/board/Makefile
> new file mode 100644
> index 0000000000..397706245a
> --- /dev/null
> +++ b/drivers/board/Makefile
> @@ -0,0 +1,9 @@
> +#
> +# (C) Copyright 2017
> +# Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> +#
> +# SPDX-License-Identifier:	GPL-2.0+
> +#
> +
> +obj-$(CONFIG_BOARD) += board-uclass.o
> +obj-$(CONFIG_BOARD_GAZERBEAM) += gazerbeam.o
> diff --git a/drivers/board/board-uclass.c b/drivers/board/board-uclass.c
> new file mode 100644
> index 0000000000..3137437245
> --- /dev/null
> +++ b/drivers/board/board-uclass.c
> @@ -0,0 +1,61 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <board.h>
> +
> +int get_board(struct udevice **devp)
> +{
> +	return uclass_first_device_err(UCLASS_BOARD, devp);
> +}
> +
> +int board_detect(struct udevice *dev)
> +{
> +	struct board_ops *ops = board_get_ops(dev);
> +
> +	if (!ops->detect)
> +		return -ENOSYS;
> +
> +	return ops->detect(dev);
> +}
> +
> +int board_get_bool(struct udevice *dev, int id, bool *val)
> +{
> +	struct board_ops *ops = board_get_ops(dev);
> +
> +	if (!ops->get_bool)
> +		return -ENOSYS;
> +
> +	return ops->get_bool(dev, id, val);
> +}
> +
> +int board_get_int(struct udevice *dev, int id, int *val)
> +{
> +	struct board_ops *ops = board_get_ops(dev);
> +
> +	if (!ops->get_int)
> +		return -ENOSYS;
> +
> +	return ops->get_int(dev, id, val);
> +}
> +
> +int board_get_str(struct udevice *dev, int id, size_t size, char *val)
> +{
> +	struct board_ops *ops = board_get_ops(dev);
> +
> +	if (!ops->get_str)
> +		return -ENOSYS;
> +
> +	return ops->get_str(dev, id, size, val);
> +}
> +
> +UCLASS_DRIVER(board) = {
> +	.id		= UCLASS_BOARD,
> +	.name		= "board",
> +	.post_bind	= dm_scan_fdt_dev,
> +};
> diff --git a/include/board.h b/include/board.h
> new file mode 100644
> index 0000000000..0e64a3dfce
> --- /dev/null
> +++ b/include/board.h
> @@ -0,0 +1,115 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +/**
> + * This uclass encapsulates hardware methods to gather information about a
> + * board or a specific device such as hard-wired GPIOs on GPIO expanders,
> + * read-only data in flash ICs, or similar.
> + *
> + * The interface offers functions to read the usual standard data types (bool,
> + * int, string) from the device, each of which is identified by a static
> + * numeric ID (which will usually be defined as a enum in a header file).
> + *
> + * If for example dev was a board device representing a read-only serial
> + * number flash IC, we could call
> + *
> + * board_detect(dev);
> + * board_get_int(dev, ID_SERIAL_NUMBER, &serial);
> + *
> + * to read the serial number from the device.
> + */
> +
> +struct board_ops {
> +	/**
> +	 * detect() - Run the hardware info detection procedure for this
> +	 *	      device.
> +	 *
> +	 * @dev:      The device containing the information
> +	 * @return 0 if OK, -ve on error.
> +	 */
> +	int (*detect)(struct udevice *dev);

This doesn’t make any sense, as the probe entry-point is intended to
probe for a device.

> +
> +	/**
> +	 * get_bool() - Read a specific bool data value that describes the
> +	 *		hardware setup.
> +	 *
> +	 * @dev:	The board instance to gather the data.
> +	 * @id: 	A unique identifier for the bool value to be read.
> +	 * @val:	Pointer to a buffer that receives the value read.
> +	 * @return 0 if OK, -ve on error.
> +	 */
> +	int (*get_bool)(struct udevice *dev, int id, bool *val);
> +
> +	/**
> +	 * get_int() - Read a specific int data value that describes the
> +	 *	       hardware setup.
> +	 *
> +	 * @dev:       The board instance to gather the data.
> +	 * @id:        A unique identifier for the int value to be read.
> +	 * @val:       Pointer to a buffer that receives the value read.
> +	 * @return 0 if OK, -ve on error.
> +	 */
> +	int (*get_int)(struct udevice *dev, int id, int *val);
> +
> +	/**
> +	 * get_str() - Read a specific string data value that describes the
> +	 *	       hardware setup.
> +	 *
> +	 * @dev:	The board instance to gather the data.
> +	 * @id: 	A unique identifier for the string value to be read.
> +	 * @size:	The size of the buffer to receive the string data.
> +	 * @val:	Pointer to a buffer that receives the value read.
> +	 * @return 0 if OK, -ve on error.
> +	 */
> +	int (*get_str)(struct udevice *dev, int id, size_t size, char *val);

These could all be handled as ioctl()-calls to a misc-device by
defining a common protocol and convenience layer.

> +};
> +
> +#define board_get_ops(dev)	((struct board_ops *)(dev)->driver->ops)
> +
> +/**
> + * board_detect() - Run the hardware info detection procedure for this device.
> + *
> + * @dev:	The device containing the information
> + * @return 0 if OK, -ve on error.
> + */
> +int board_detect(struct udevice *dev);
> +
> +/**
> + * board_get_bool() - Read a specific bool data value that describes the
> + * 		      hardware setup.
> + *
> + * @dev:	The board instance to gather the data.
> + * @id: 	A unique identifier for the bool value to be read.
> + * @val:	Pointer to a buffer that receives the value read.
> + * @return 0 if OK, -ve on error.
> + */
> +int board_get_bool(struct udevice *dev, int id, bool *val);
> +
> +/**
> + * board_get_int() - Read a specific int data value that describes the
> + * 		     hardware setup.
> + *
> + * @dev:	The board instance to gather the data.
> + * @id: 	A unique identifier for the int value to be read.
> + * @val:	Pointer to a buffer that receives the value read.
> + * @return 0 if OK, -ve on error.
> + */
> +int board_get_int(struct udevice *dev, int id, int *val);
> +
> +/**
> + * board_get_str() - Read a specific string data value that describes the
> + * 		     hardware setup.
> + *
> + * @dev:	The board instance to gather the data.
> + * @id: 	A unique identifier for the string value to be read.
> + * @size:	The size of the buffer to receive the string data.
> + * @val:	Pointer to a buffer that receives the value read.
> + * @return 0 if OK, -ve on error.
> + */
> +int board_get_str(struct udevice *dev, int id, size_t size, char *val);
> +
> +int get_board(struct udevice **devp);
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index d28fb3e23f..97327194b4 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -30,6 +30,7 @@ enum uclass_id {
> 	UCLASS_ADC,		/* Analog-to-digital converter */
> 	UCLASS_AHCI,		/* SATA disk controller */
> 	UCLASS_BLK,		/* Block device */
> +	UCLASS_BOARD, 		/* Device information from hardware */
> 	UCLASS_CLK,		/* Clock source, e.g. used by peripherals */
> 	UCLASS_CPU,		/* CPU, typically part of an SoC */
> 	UCLASS_CROS_EC,		/* Chrome OS EC */
> -- 
> 2.16.1
> 



More information about the U-Boot mailing list