OSDN Git Service

firmware: meson_sm: Add serial number sysfs entry
authorNeil Armstrong <narmstrong@baylibre.com>
Thu, 26 Jul 2018 13:59:16 +0000 (15:59 +0200)
committerKevin Hilman <khilman@baylibre.com>
Thu, 13 Sep 2018 03:54:07 +0000 (20:54 -0700)
The Amlogic Meson SoC Secure Monitor implements a call to retrieve an unique
SoC ID starting from the GX Family and all new families.

The serial number is simply exposed as a sysfs entry under the firmware
sysfs directory.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
drivers/firmware/meson/meson_sm.c
include/linux/firmware/meson/meson_sm.h

index 0ec2ca8..29fbc81 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/printk.h>
 #include <linux/types.h>
 #include <linux/sizes.h>
+ #include <linux/slab.h>
 
 #include <linux/firmware/meson/meson_sm.h>
 
@@ -48,6 +49,7 @@ struct meson_sm_chip gxbb_chip = {
                CMD(SM_EFUSE_READ,      0x82000030),
                CMD(SM_EFUSE_WRITE,     0x82000031),
                CMD(SM_EFUSE_USER_MAX,  0x82000033),
+               CMD(SM_GET_CHIP_ID,     0x82000044),
                { /* sentinel */ },
        },
 };
@@ -214,6 +216,57 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
 }
 EXPORT_SYMBOL(meson_sm_call_write);
 
+#define SM_CHIP_ID_LENGTH      119
+#define SM_CHIP_ID_OFFSET      4
+#define SM_CHIP_ID_SIZE                12
+
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       uint8_t *id_buf;
+       int ret;
+
+       id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
+       if (!id_buf)
+               return -ENOMEM;
+
+       ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
+                                0, 0, 0, 0, 0);
+       if (ret < 0) {
+               kfree(id_buf);
+               return ret;
+       }
+
+       ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                       id_buf[SM_CHIP_ID_OFFSET + 0],
+                       id_buf[SM_CHIP_ID_OFFSET + 1],
+                       id_buf[SM_CHIP_ID_OFFSET + 2],
+                       id_buf[SM_CHIP_ID_OFFSET + 3],
+                       id_buf[SM_CHIP_ID_OFFSET + 4],
+                       id_buf[SM_CHIP_ID_OFFSET + 5],
+                       id_buf[SM_CHIP_ID_OFFSET + 6],
+                       id_buf[SM_CHIP_ID_OFFSET + 7],
+                       id_buf[SM_CHIP_ID_OFFSET + 8],
+                       id_buf[SM_CHIP_ID_OFFSET + 9],
+                       id_buf[SM_CHIP_ID_OFFSET + 10],
+                       id_buf[SM_CHIP_ID_OFFSET + 11]);
+
+       kfree(id_buf);
+
+       return ret;
+}
+
+static DEVICE_ATTR_RO(serial);
+
+static struct attribute *meson_sm_sysfs_attributes[] = {
+       &dev_attr_serial.attr,
+       NULL,
+};
+
+static const struct attribute_group meson_sm_sysfs_attr_group = {
+       .attrs = meson_sm_sysfs_attributes,
+};
+
 static const struct of_device_id meson_sm_ids[] = {
        { .compatible = "amlogic,meson-gxbb-sm", .data = &gxbb_chip },
        { /* sentinel */ },
@@ -242,6 +295,9 @@ static int __init meson_sm_probe(struct platform_device *pdev)
        fw.chip = chip;
        pr_info("secure-monitor enabled\n");
 
+       if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
+               goto out_in_base;
+
        return 0;
 
 out_in_base:
index 37a5eae..f98c20d 100644 (file)
@@ -17,6 +17,7 @@ enum {
        SM_EFUSE_READ,
        SM_EFUSE_WRITE,
        SM_EFUSE_USER_MAX,
+       SM_GET_CHIP_ID,
 };
 
 struct meson_sm_firmware;