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

Reply via email to