Commit 0789724f authored by Neil Armstrong's avatar Neil Armstrong Committed by Kevin Hilman
Browse files

firmware: meson_sm: Add serial number sysfs entry



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: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarKevin Hilman <khilman@baylibre.com>
parent 5b394b2d
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ enum {
	SM_EFUSE_READ,
	SM_EFUSE_WRITE,
	SM_EFUSE_USER_MAX,
	SM_GET_CHIP_ID,
};

struct meson_sm_firmware;