--- /dev/null
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/crc32.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/system_info.h>
+
+static int rockchip_cpuinfo_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct nvmem_cell *cell;
+ unsigned char *efuse_buf, buf[16];
+ size_t len;
+ int i;
+
+ cell = nvmem_cell_get(dev, "id");
+ if (IS_ERR(cell)) {
+ dev_err(dev, "failed to get id cell: %ld\n", PTR_ERR(cell));
+ if (PTR_ERR(cell) == -EPROBE_DEFER)
+ return PTR_ERR(cell);
+ return PTR_ERR(cell);
+ }
+ efuse_buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+
+ if (len != 16) {
+ kfree(efuse_buf);
+ dev_err(dev, "invalid id len: %zu\n", len);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 8; i++) {
+ buf[i] = efuse_buf[1 + (i << 1)];
+ buf[i + 8] = efuse_buf[i << 1];
+ }
+
+ kfree(efuse_buf);
+
+ system_serial_low = crc32(0, buf, 8);
+ system_serial_high = crc32(system_serial_low, buf + 8, 8);
+
+ dev_info(dev, "Serial\t\t: %08x%08x\n",
+ system_serial_high, system_serial_low);
+
+ return 0;
+}
+
+static const struct of_device_id rockchip_cpuinfo_of_match[] = {
+ { .compatible = "rockchip,cpuinfo", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rockchip_cpuinfo_of_match);
+
+static struct platform_driver rockchip_cpuinfo_driver = {
+ .probe = rockchip_cpuinfo_probe,
+ .driver = {
+ .name = "rockchip-cpuinfo",
+ .of_match_table = rockchip_cpuinfo_of_match,
+ },
+};
+module_platform_driver(rockchip_cpuinfo_driver);