Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp7752701rwb; Wed, 23 Nov 2022 10:15:01 -0800 (PST) X-Google-Smtp-Source: AA0mqf47XPCMaPbuBUFtTtFlT7WVhF/DHIxYRdaHTZLg6YAylbrnukI8oSpi8IEOUQVo2P6afGLD X-Received: by 2002:a17:902:ec82:b0:176:be21:409c with SMTP id x2-20020a170902ec8200b00176be21409cmr10384184plg.14.1669227301565; Wed, 23 Nov 2022 10:15:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669227301; cv=none; d=google.com; s=arc-20160816; b=TtyYH3sPSHI4eAJu7TSYxaY1qmhIynE7waGEOuXHSQryB5ODbSbZM2mNyNrpX0HQfQ adRDHyhp13d6f3hsDwnOPuNj2GApP5pThzreUeOF+jHVHtTeP9ED+zEOtntTGwxDuzz6 wBDAzVipxUUE1pdDC3WSQGpteZPEzd3XCVymJ3+VVFZ7uKbvcfoEZuxsventtu5kaHZ7 Z+O4zKHvbGhBa1edSYXSfslu/PpsPWfpjAApjh8xfXX3Gcdh78gc+zXQOqd7VyCx0BFp lQtCWZxE5kaT31vSq8ndibcPif6gFcomkJiTBmjSE9DThUHOwk+s5AYhVCNsanBvXVZp W+lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gx58Y1T19qV8Bq9PgxKKY6gnXxp8UlcL8mKnK8kjD4w=; b=WO5uyZBtzsaKP2n8H4YyvdMfr8SnNXXdORjnrx54KZGbswJY9cA38bIoNTkDcOBpiK 92LoRhOI3KhXyF9C9nI0r1taOxQGEMuS5D1heOdsZH+BZC8sev9C0t5pzajLp5ppQLoI dd/geUzYuqVBuQpJ3ktHLihyhWDqM/GtMbh7t7bAK1DaC0zuVLf4MPiupzBgC2qVASBL COiNBBCkZuhwiwkg6aSQw0+6N7nw+4CPrEYSWZMiCEbplwIk5Q4CCX4ZZEQBrJKzpSSG W7HphW7mx3A1X1qO19omVqi5305+Zia+hG2UXIuEtToBYqdK4py3MKf+SulY6XeVg12f +gBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2022082101 header.b=dRQajWbU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=walle.cc Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x2-20020a170902820200b00186f2ef80bbsi15783751pln.308.2022.11.23.10.14.46; Wed, 23 Nov 2022 10:15:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2022082101 header.b=dRQajWbU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=walle.cc Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239630AbiKWSFR (ORCPT + 88 others); Wed, 23 Nov 2022 13:05:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239489AbiKWSDK (ORCPT ); Wed, 23 Nov 2022 13:03:10 -0500 Received: from mail.3ffe.de (0001.3ffe.de [IPv6:2a01:4f8:c0c:9d57::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8280A5F6B; Wed, 23 Nov 2022 10:02:27 -0800 (PST) Received: from mwalle01.kontron.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.3ffe.de (Postfix) with ESMTPSA id C5B3D27B2; Wed, 23 Nov 2022 19:02:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2022082101; t=1669226545; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gx58Y1T19qV8Bq9PgxKKY6gnXxp8UlcL8mKnK8kjD4w=; b=dRQajWbUb2FkbeedIH/kXXPtAGgDJr31JVvVvqLGyx+wZGtexa2v84wx7N3cJdZ6XlRrH9 o+BAzEdw9ANJnwWolU+SUnNgJsttxNRBMNzY9ob6kLQKT/O4pCZ4BhGt6dNJMRDcs/6rg9 3CrSo6QVVAPbrkKT3FS3BHgKgasLwk9RmC++wd92i4NmsIZJaffCaCbz7ZYvPjeLzM45OI Ret59ELFrKyaZ03D36sC+aklPCBI+OUOMCgE8ljiSmd85VM/v+Zwwb2i3LKSxFAywObM0Z Oh7dyZ6Vl8IQP7YeHnDpCLMOMVYR+QRAq6ZRlI0Jo+FZHvQlqBvE37BuDiZFJA== From: Michael Walle To: Jonathan Corbet , Srinivas Kandagatla , Miquel Raynal , Rob Herring , Frank Rowand , Sascha Hauer Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, Michael Walle Subject: [PATCH v4 17/20] nvmem: layouts: add sl28vpd layout Date: Wed, 23 Nov 2022 19:01:48 +0100 Message-Id: <20221123180151.2160033-18-michael@walle.cc> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221123180151.2160033-1-michael@walle.cc> References: <20221123180151.2160033-1-michael@walle.cc> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam: Yes X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This layout applies to the VPD of the Kontron sl28 boards. The VPD only contains a base MAC address. Therefore, we have to add an individual offset to it. This is done by taking the second argument of the nvmem phandle into account. Also this let us checking the VPD version and the checksum. Signed-off-by: Michael Walle --- changes since v3: - none changes since v2: - use of_nvmem_layout_get_container() changes since v1: - none drivers/nvmem/layouts/Kconfig | 9 ++ drivers/nvmem/layouts/Makefile | 2 + drivers/nvmem/layouts/sl28vpd.c | 153 ++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 drivers/nvmem/layouts/sl28vpd.c diff --git a/drivers/nvmem/layouts/Kconfig b/drivers/nvmem/layouts/Kconfig index 9ad3911d1605..75082f6b471d 100644 --- a/drivers/nvmem/layouts/Kconfig +++ b/drivers/nvmem/layouts/Kconfig @@ -2,4 +2,13 @@ menu "Layout Types" +config NVMEM_LAYOUT_SL28_VPD + bool "Kontron sl28 VPD layout support" + select CRC8 + help + Say Y here if you want to support the VPD layout of the Kontron + SMARC-sAL28 boards. + + If unsure, say N. + endmenu diff --git a/drivers/nvmem/layouts/Makefile b/drivers/nvmem/layouts/Makefile index 6fdb3c60a4fa..fc617b9e87d0 100644 --- a/drivers/nvmem/layouts/Makefile +++ b/drivers/nvmem/layouts/Makefile @@ -2,3 +2,5 @@ # # Makefile for nvmem layouts. # + +obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c new file mode 100644 index 000000000000..a36800f201a3 --- /dev/null +++ b/drivers/nvmem/layouts/sl28vpd.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include + +#define SL28VPD_MAGIC 'V' + +struct sl28vpd_header { + u8 magic; + u8 version; +} __packed; + +struct sl28vpd_v1 { + struct sl28vpd_header header; + char serial_number[15]; + u8 base_mac_address[ETH_ALEN]; + u8 crc8; +} __packed; + +static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, + unsigned int offset, void *buf, + size_t bytes) +{ + if (bytes != ETH_ALEN) + return -EINVAL; + + if (index < 0) + return -EINVAL; + + if (!is_valid_ether_addr(buf)) + return -EINVAL; + + eth_addr_add(buf, index); + + return 0; +} + +static const struct nvmem_cell_info sl28vpd_v1_entries[] = { + { + .name = "serial-number", + .offset = offsetof(struct sl28vpd_v1, serial_number), + .bytes = sizeof_field(struct sl28vpd_v1, serial_number), + }, + { + .name = "base-mac-address", + .offset = offsetof(struct sl28vpd_v1, base_mac_address), + .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), + .read_post_process = sl28vpd_mac_address_pp, + }, +}; + +static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) +{ + struct sl28vpd_v1 data_v1; + u8 table[CRC8_TABLE_SIZE]; + int ret; + u8 crc; + + crc8_populate_msb(table, 0x07); + + ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); + if (ret < 0) + return ret; + else if (ret != sizeof(data_v1)) + return -EIO; + + crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); + + if (crc != data_v1.crc8) { + dev_err(dev, + "Checksum is invalid (got %02x, expected %02x).\n", + crc, data_v1.crc8); + return -EINVAL; + } + + return 0; +} + +static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, + struct nvmem_layout *layout) +{ + const struct nvmem_cell_info *pinfo; + struct nvmem_cell_info info = {0}; + struct device_node *layout_np; + struct sl28vpd_header hdr; + int ret, i; + + /* check header */ + ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); + if (ret < 0) + return ret; + else if (ret != sizeof(hdr)) + return -EIO; + + if (hdr.magic != SL28VPD_MAGIC) { + dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); + return -EINVAL; + } + + if (hdr.version != 1) { + dev_err(dev, "Version %d is unsupported.\n", hdr.version); + return -EINVAL; + } + + ret = sl28vpd_v1_check_crc(dev, nvmem); + if (ret) + return ret; + + layout_np = of_nvmem_layout_get_container(nvmem); + if (!layout_np) + return -ENOENT; + + for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { + pinfo = &sl28vpd_v1_entries[i]; + + info.name = pinfo->name; + info.offset = pinfo->offset; + info.bytes = pinfo->bytes; + info.read_post_process = pinfo->read_post_process; + info.np = of_get_child_by_name(layout_np, pinfo->name); + + ret = nvmem_add_one_cell(nvmem, &info); + if (ret) { + of_node_put(layout_np); + return ret; + } + } + + of_node_put(layout_np); + + return 0; +} + +static const struct of_device_id sl28vpd_of_match_table[] = { + { .compatible = "kontron,sl28-vpd" }, + {}, +}; + +struct nvmem_layout sl28vpd_layout = { + .name = "sl28-vpd", + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, +}; + +static int __init sl28vpd_init(void) +{ + return nvmem_layout_register(&sl28vpd_layout); +} +subsys_initcall(sl28vpd_init); -- 2.30.2