Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4E78C38142 for ; Fri, 27 Jan 2023 11:19:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233097AbjA0LTT (ORCPT ); Fri, 27 Jan 2023 06:19:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233023AbjA0LSf (ORCPT ); Fri, 27 Jan 2023 06:18:35 -0500 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9AF1374A75 for ; Fri, 27 Jan 2023 03:18:12 -0800 (PST) Received: by mail-wm1-x32e.google.com with SMTP id c10-20020a05600c0a4a00b003db0636ff84so3218949wmq.0 for ; Fri, 27 Jan 2023 03:18:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nqPT9IiPlOeT+18a7EVyxb18GhOwuqWu5IcugbyndEU=; b=jrFHF32Roorg7EjKovLUCXNESHz+/pjZIfyhtkhj8RUMyutnVZEUS0NhwUDSIZvjdY HtcWgWKddAr+UEbb7b4NrrVa3lj41OUsy+Pc/2oEJcz9hAnYFCV0aeUm3FSVnESSeQ1b CqPrz5giQWSVOe0mHo5BDON+K8mBBFNQdqyMvB88+ssg4TVReKzlf2hzrFY/wbP6I7tc tFYMfeBTwi8BGRRsj3yOYWOodvaxSgUvSxsVJNVOqZ4/lqX5JwWKJcrAGzjd5PYeZfZf iEXb7Y/eT2TpT50ACCJQO6sAjHpT0QIx64gvzbJ2TV1Ko+VODRceBGNslbnuJODf6km7 cCSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nqPT9IiPlOeT+18a7EVyxb18GhOwuqWu5IcugbyndEU=; b=0huNm7vH6y+LOTCxgmRZPClKUGFgpacVCdPqy2T100ueFppMXxE33SLn7RqvA0kVE8 kHZtrmOsV5VpRV2k4E42aM81v+f8/hVsj7bNhvLxfMVknM1t2FhoKCZ2uuLsTQYGe0sv rW2k53pd/eaI8t96+N1UhQFycZyq4JaeE1iH81FcnAkWYR2PcixYYGzbp53c4ULMJPdm RvyMOZx4avS45Sfs0nRmmhtSXamAs9OIdpNfSZu4ofj2mvmdddiBKDplVYvacW6tcw9N p7Rhjx3QAFaEMw9VBZywgDikU8fQg+9F7inIyuht6NkBYwsY9cAwpUYQmCFIqcifkDW5 OqFg== X-Gm-Message-State: AFqh2kryrZYm/NHCMF0aJmTDiH6Hk55jzXwiCrYrMa/Ww+kCN6gFljwf z+eUJeAJkzlO9hecVmiygXl+tLWIJGVyVNoN X-Google-Smtp-Source: AMrXdXu5xGopDbmm0/TutphPqfsg1HT/KuPkS3ft60VZQpM+kDDLiJ63eswCkcXvnLym/akPJE+ceg== X-Received: by 2002:a05:600c:54d0:b0:3d9:7847:96e2 with SMTP id iw16-20020a05600c54d000b003d9784796e2mr38589128wmb.2.1674818290830; Fri, 27 Jan 2023 03:18:10 -0800 (PST) Received: from localhost.localdomain ([5.133.47.210]) by smtp.gmail.com with ESMTPSA id c13-20020adffb0d000000b002bfd190fd60sm1843314wrr.108.2023.01.27.03.18.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 03:18:10 -0800 (PST) From: Srinivas Kandagatla To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Michael Walle , Srinivas Kandagatla Subject: [PATCH 23/37] nvmem: layouts: add sl28vpd layout Date: Fri, 27 Jan 2023 11:15:51 +0000 Message-Id: <20230127111605.25958-24-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230127111605.25958-1-srinivas.kandagatla@linaro.org> References: <20230127111605.25958-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Michael Walle 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 Signed-off-by: Srinivas Kandagatla --- 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.25.1