ARM64: DTS: Add rk3399-firefly uart4 device, node as /dev/ttyS1
[firefly-linux-kernel-4.4.55.git] / drivers / soc / rockchip / rockchip-cpuinfo.c
1 /*
2  * Copyright (C) 2017 Rockchip Electronics Co. Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details.
12  */
13
14 #include <linux/crc32.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/nvmem-consumer.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #include <asm/system_info.h>
21
22 static int rockchip_cpuinfo_probe(struct platform_device *pdev)
23 {
24         struct device *dev = &pdev->dev;
25         struct nvmem_cell *cell;
26         unsigned char *efuse_buf, buf[16];
27         size_t len;
28         int i;
29
30         cell = nvmem_cell_get(dev, "id");
31         if (IS_ERR(cell)) {
32                 dev_err(dev, "failed to get id cell: %ld\n", PTR_ERR(cell));
33                 if (PTR_ERR(cell) == -EPROBE_DEFER)
34                         return PTR_ERR(cell);
35                 return PTR_ERR(cell);
36         }
37         efuse_buf = nvmem_cell_read(cell, &len);
38         nvmem_cell_put(cell);
39
40         if (len != 16) {
41                 kfree(efuse_buf);
42                 dev_err(dev, "invalid id len: %zu\n", len);
43                 return -EINVAL;
44         }
45
46         for (i = 0; i < 8; i++) {
47                 buf[i] = efuse_buf[1 + (i << 1)];
48                 buf[i + 8] = efuse_buf[i << 1];
49         }
50
51         kfree(efuse_buf);
52
53         system_serial_low = crc32(0, buf, 8);
54         system_serial_high = crc32(system_serial_low, buf + 8, 8);
55
56         dev_info(dev, "Serial\t\t: %08x%08x\n",
57                  system_serial_high, system_serial_low);
58
59         return 0;
60 }
61
62 static const struct of_device_id rockchip_cpuinfo_of_match[] = {
63         { .compatible = "rockchip,cpuinfo", },
64         { },
65 };
66 MODULE_DEVICE_TABLE(of, rockchip_cpuinfo_of_match);
67
68 static struct platform_driver rockchip_cpuinfo_driver = {
69         .probe = rockchip_cpuinfo_probe,
70         .driver = {
71                 .name = "rockchip-cpuinfo",
72                 .of_match_table = rockchip_cpuinfo_of_match,
73         },
74 };
75 module_platform_driver(rockchip_cpuinfo_driver);