nios2: convert altera sysid to driver model

Convert altera sysid to driver model with misc uclass.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Acked-by: Chin Liang See <clsee@altera.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 031b4d8..101a619 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -13,6 +13,13 @@
 	  set of generic read, write and ioctl methods may be used to
 	  access the device.
 
+config ALTERA_SYSID
+	bool "Altera Sysid support"
+	depends on MISC
+	help
+	  Select this to enable a sysid for Altera devices. Please find
+	  details on the "Embedded Peripherals IP User Guide" of Altera.
+
 config CMD_CROS_EC
 	bool "Enable crosec command"
 	depends on CROS_EC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7e76b12..aa137f5 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_MISC) += misc-uclass.o
 obj-$(CONFIG_ALI152X) += ali512x.o
+obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
 obj-$(CONFIG_DS4510)  += ds4510.o
 obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
 obj-$(CONFIG_CROS_EC) += cros_ec.o
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
new file mode 100644
index 0000000..249b273
--- /dev/null
+++ b/drivers/misc/altera_sysid.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <errno.h>
+#include <misc.h>
+#include <linux/time.h>
+#include <asm/io.h>
+
+struct altera_sysid_regs {
+	u32	id;		/* The system build id */
+	u32	timestamp;	/* Timestamp */
+};
+
+struct altera_sysid_platdata {
+	struct altera_sysid_regs *regs;
+};
+
+void display_sysid(void)
+{
+	struct udevice *dev;
+	u32 sysid[2];
+	struct tm t;
+	char asc[32];
+	time_t stamp;
+	int ret;
+
+	/* the first misc device will be used */
+	ret = uclass_first_device(UCLASS_MISC, &dev);
+	if (ret)
+		return;
+	if (!dev)
+		return;
+	ret = misc_read(dev, 0, &sysid, sizeof(sysid));
+	if (ret)
+		return;
+
+	stamp = sysid[1];
+	localtime_r(&stamp, &t);
+	asctime_r(&t, asc);
+	printf("SYSID: %08x, %s", sysid[0], asc);
+}
+
+int do_sysid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	display_sysid();
+	return 0;
+}
+
+U_BOOT_CMD(
+	sysid,	1,	1,	do_sysid,
+	"display Nios-II system id",
+	""
+);
+
+static int altera_sysid_read(struct udevice *dev,
+			     int offset, void *buf, int size)
+{
+	struct altera_sysid_platdata *plat = dev->platdata;
+	struct altera_sysid_regs *const regs = plat->regs;
+	u32 *sysid = buf;
+
+	sysid[0] = readl(&regs->id);
+	sysid[1] = readl(&regs->timestamp);
+
+	return 0;
+}
+
+static int altera_sysid_ofdata_to_platdata(struct udevice *dev)
+{
+	struct altera_sysid_platdata *plat = dev_get_platdata(dev);
+
+	plat->regs = ioremap(dev_get_addr(dev),
+		sizeof(struct altera_sysid_regs));
+
+	return 0;
+}
+
+static const struct misc_ops altera_sysid_ops = {
+	.read = altera_sysid_read,
+};
+
+static const struct udevice_id altera_sysid_ids[] = {
+	{ .compatible = "altr,sysid-1.0", },
+	{ }
+};
+
+U_BOOT_DRIVER(altera_sysid) = {
+	.name	= "altera_sysid",
+	.id	= UCLASS_MISC,
+	.of_match = altera_sysid_ids,
+	.ofdata_to_platdata = altera_sysid_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct altera_sysid_platdata),
+	.ops	= &altera_sysid_ops,
+};