Mainline kernel uses the "soc_id" attribute to identify the SoC for some of the h/w platforms. Adding this attribute in u-boot will make SoC identification similar to the mainline kernel, so that it can be easily maintained.
Add a new attribute named "soc_id" to SOC uclass, in order to allow device drivers for identifying the SoC using SoC identification string and also for matching this attribute for selecting SoC specific data. Signed-off-by: Biju Das <biju.das...@bp.renesas.com> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com> Reviewed-by: Simon Glass <s...@chromium.org> --- v3->v4: * Updated patch description * Added Simon's Rb tag. v2->v3: * split the comments patch seperate. Ref:https://patchwork.ozlabs.org/project/uboot/patch/20201102150959.4793-3-biju.das...@bp.renesas.com/ v1->v2: Changed the comments from "a SoC" to "an SoC" Ref: https://patchwork.ozlabs.org/project/uboot/patch/20201030140724.12773-1-biju.das...@bp.renesas.com/ --- drivers/soc/soc-uclass.c | 19 ++++++++++++++++++- drivers/soc/soc_sandbox.c | 8 ++++++++ include/soc.h | 27 +++++++++++++++++++++++++++ test/dm/soc.c | 8 ++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/soc/soc-uclass.c b/drivers/soc/soc-uclass.c index c32d647864..a3f8be841b 100644 --- a/drivers/soc/soc-uclass.c +++ b/drivers/soc/soc-uclass.c @@ -46,6 +46,16 @@ int soc_get_revision(struct udevice *dev, char *buf, int size) return ops->get_revision(dev, buf, size); } +int soc_get_soc_id(struct udevice *dev, char *buf, int size) +{ + struct soc_ops *ops = soc_get_ops(dev); + + if (!ops->get_soc_id) + return -ENOSYS; + + return ops->get_soc_id(dev, buf, size); +} + const struct soc_attr * soc_device_match(const struct soc_attr *matches) { @@ -61,7 +71,7 @@ soc_device_match(const struct soc_attr *matches) while (1) { if (!(matches->machine || matches->family || - matches->revision)) + matches->revision || matches->soc_id)) break; match = true; @@ -87,6 +97,13 @@ soc_device_match(const struct soc_attr *matches) } } + if (matches->soc_id) { + if (!soc_get_soc_id(soc, str, SOC_MAX_STR_SIZE)) { + if (strcmp(matches->soc_id, str)) + match = false; + } + } + if (match) return matches; diff --git a/drivers/soc/soc_sandbox.c b/drivers/soc/soc_sandbox.c index 5c82ad84fc..1a81d3562a 100644 --- a/drivers/soc/soc_sandbox.c +++ b/drivers/soc/soc_sandbox.c @@ -31,10 +31,18 @@ int soc_sandbox_get_revision(struct udevice *dev, char *buf, int size) return 0; } +int soc_sandbox_get_soc_id(struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "r8a774a1"); + + return 0; +} + static const struct soc_ops soc_sandbox_ops = { .get_family = soc_sandbox_get_family, .get_revision = soc_sandbox_get_revision, .get_machine = soc_sandbox_get_machine, + .get_soc_id = soc_sandbox_get_soc_id, }; int soc_sandbox_probe(struct udevice *dev) diff --git a/include/soc.h b/include/soc.h index 05058f9331..db0e8880d1 100644 --- a/include/soc.h +++ b/include/soc.h @@ -20,12 +20,14 @@ * variants. Example: am33 * @machine - Name of a specific SoC. Example: am3352 * @revision - Name of a specific SoC revision. Example: SR1.1 + * @soc_id - SoC identification string. Example: r8a774a1 * @data - A pointer to user data for the SoC variant */ struct soc_attr { const char *family; const char *machine; const char *revision; + const char *soc_id; const void *data; }; @@ -59,6 +61,16 @@ struct soc_ops { * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error */ int (*get_family)(struct udevice *dev, char *buf, int size); + + /** + * get_soc_id() - Get SoC identification name of an SoC + * + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ + int (*get_soc_id)(struct udevice *dev, char *buf, int size); }; #define soc_get_ops(dev) ((struct soc_ops *)(dev)->driver->ops) @@ -105,6 +117,16 @@ int soc_get_revision(struct udevice *dev, char *buf, int size); */ int soc_get_family(struct udevice *dev, char *buf, int size); +/** + * soc_get_soc_id() - Get SoC identification name of an SoC + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * + * Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int soc_get_soc_id(struct udevice *dev, char *buf, int size); + /** * soc_device_match() - Return match from an array of soc_attr * @matches: Array with any combination of family, revision or machine set @@ -136,6 +158,11 @@ static inline int soc_get_family(struct udevice *dev, char *buf, int size) return -ENOSYS; } +static inline int soc_get_soc_id(struct udevice *dev, char *buf, int size) +{ + return -ENOSYS; +} + static inline const struct soc_attr * soc_device_match(const struct soc_attr *matches) { diff --git a/test/dm/soc.c b/test/dm/soc.c index 17e1b5ba01..82cd53ff29 100644 --- a/test/dm/soc.c +++ b/test/dm/soc.c @@ -32,24 +32,28 @@ static int dm_test_soc(struct unit_test_state *uts) .family = "SANDBOX0xx", .machine = "SANDBOX012", .revision = "1.0", + .soc_id = "r8a774a1", .data = NULL, }, { .family = "SANDBOX1xx", .machine = "SANDBOX107", .revision = "1.0", + .soc_id = "r8a774a1", .data = NULL, }, { .family = "SANDBOX1xx", .machine = "SANDBOX123", .revision = "1.0", + .soc_id = "r8a774a1", .data = &soc_sandbox123_data, }, { .family = "SANDBOX1xx", .machine = "SANDBOX131", .revision = "2.0", + .soc_id = "r8a774a1", .data = NULL, }, { /* sentinel */ } @@ -78,6 +82,7 @@ static int dm_test_soc(struct unit_test_state *uts) { .family = "SANDBOX0xx", .revision = "1.0", + .soc_id = "r8a774b1", .data = NULL, }, { @@ -99,6 +104,9 @@ static int dm_test_soc(struct unit_test_state *uts) ut_assertok(soc_get_revision(dev, text, sizeof(text))); ut_asserteq_str(text, "1.0"); + ut_assertok(soc_get_soc_id(dev, text, sizeof(text))); + ut_asserteq_str(text, "r8a774a1"); + soc_data = soc_device_match(sb_soc_devices_full); ut_assert(soc_data); -- 2.17.1