From 2fc2cbaaaf0dcebdeffa6e87bbc9ad843a5470dd Mon Sep 17 00:00:00 2001 From: hmz007 Date: Sat, 11 Jan 2020 19:35:03 +0800 Subject: [PATCH] soc: friendlyelec: Add board info driver Change-Id: I122adb4f99c816b5c177f16392fb2df9c10a47be Signed-off-by: hmz007 --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/friendlyelec/Kconfig | 11 ++ drivers/soc/friendlyelec/Makefile | 1 + drivers/soc/friendlyelec/board.c | 143 ++++++++++++++++++ 8 files changed, 161 insertions(+) create mode 100644 drivers/soc/friendlyelec/Kconfig create mode 100644 drivers/soc/friendlyelec/Makefile create mode 100644 drivers/soc/friendlyelec/board.c diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 833e04a7835c..9ddbd976395d 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -21,5 +21,6 @@ source "drivers/soc/ux500/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" source "drivers/soc/xilinx/Kconfig" +source "drivers/soc/friendlyelec/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index f678e4d9e..cfc815a7e 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -29,3 +29,4 @@ obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ obj-y += xilinx/ +obj-$(CONFIG_VENDOR_FRIENDLYELEC) += friendlyelec/ diff --git a/drivers/soc/friendlyelec/Kconfig b/drivers/soc/friendlyelec/Kconfig new file mode 100644 index 000000000000..9e21c663e6c8 --- /dev/null +++ b/drivers/soc/friendlyelec/Kconfig @@ -0,0 +1,11 @@ +# +# Machine drivers +# + +if ARCH_ROCKCHIP + +config VENDOR_FRIENDLYELEC + bool "FriendlyElec board based on RK33XX SoCs" + default n + +endif diff --git a/drivers/soc/friendlyelec/Makefile b/drivers/soc/friendlyelec/Makefile new file mode 100644 index 000000000000..870542f05177 --- /dev/null +++ b/drivers/soc/friendlyelec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VENDOR_FRIENDLYELEC) += board.o diff --git a/drivers/soc/friendlyelec/board.c b/drivers/soc/friendlyelec/board.c new file mode 100644 index 000000000000..886a8e1f7dc0 --- /dev/null +++ b/drivers/soc/friendlyelec/board.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd. + * (http://www.friendlyarm.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can access it online at + * http://www.gnu.org/licenses/gpl-2.0.html. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOARD_MANF "FriendlyELEC Computer Tech. Co., Ltd." + +static const char *board_mach; +static const char *board_name; +static u32 board_rev; +static u32 board_serial_high, board_serial_low; + +static ssize_t board_sys_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + char *s = buf; + + s += sprintf(s, "Hardware\t: %s\n", board_mach); + s += sprintf(s, "Revision\t: %04x\n", board_rev); + s += sprintf(s, "Serial\t\t: %08x%08x\n", + board_serial_high, board_serial_low); + s += sprintf(s, "\nModel\t\t: %s\n", board_name); + s += sprintf(s, "Manufacturer\t: %s\n", BOARD_MANF); + + return (s - buf); +} + +static struct device_attribute board_attr_info = + __ATTR(info, S_IRUGO, board_sys_info_show, NULL); + +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)); + 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); + + board_serial_low = crc32(0, buf, 8); + board_serial_high = crc32(board_serial_low, buf + 8, 8); + + dev_info(dev, "Serial\t\t: %08x%08x\n", + board_serial_high, board_serial_low); + + return 0; +} + +static int board_sys_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *root; + + root = of_find_node_by_path("/"); + + of_property_read_u32(np, "hwrev", &board_rev); + + if (of_property_read_string(np, "machine", &board_mach)) + of_property_read_string(root, "compatible", &board_mach); + + if (of_property_read_string(np, "model", &board_name)) + of_property_read_string(root, "model", &board_name); + + of_node_put(root); + + rockchip_cpuinfo_probe(pdev); + + device_create_file(&pdev->dev, &board_attr_info); + + return 0; +} + +static const struct of_device_id board_sys_of_match[] = { + { .compatible = "friendlyelec,board" }, + {} +}; +MODULE_DEVICE_TABLE(of, board_sys_of_match); + +static struct platform_driver board_sys_driver = { + .probe = board_sys_probe, + .driver = { + .name = "friendlyelec-board", + .of_match_table = board_sys_of_match, + }, +}; + +static int __init board_sys_init(void) +{ + return platform_driver_register(&board_sys_driver); +} +late_initcall(board_sys_init); + +MODULE_AUTHOR("support@friendlyarm.com"); +MODULE_DESCRIPTION("FriendlyElec NanoPi Series Machine Driver"); +MODULE_LICENSE("GPL v2");