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 47B11C636D6 for ; Mon, 6 Feb 2023 10:30:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229946AbjBFK36 (ORCPT ); Mon, 6 Feb 2023 05:29:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230408AbjBFK3Y (ORCPT ); Mon, 6 Feb 2023 05:29:24 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E8E021A36 for ; Mon, 6 Feb 2023 02:28:43 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id o36so8301023wms.1 for ; Mon, 06 Feb 2023 02:28:42 -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=VPzogrq9+w7q2CusTGpCio2ntl2twjUvKsQGqbhgMApQ8pIRb902eGRRIXXHwUbgGI 1vRwXZH5kils82X8+HfnFjXCiALqpENCMsY/ceWqkkV+640u3GhC4fmtWk+SbhIfKD6N ReKAvMLAHI5T7JqWTrU9QEgM9FA6AiJ3YnWh0UHmBpV/ZfsRX80bCk3966Of3Omuy+LV 9PB1mYdiqHa21fh6EBfgvIY++DD+2WYG839dCBZH9qa4AhH6I7LPhHdAHIfe6jvPnH9E HBaNMBBAHlEniH/Nw0XJPN7oQUHLqNZj166cYiggDhxVguiSEAZZXxEAJH8BJngcM4PP 7gmw== 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=gdKsYuQ9XSIWL/cvuVOUkQgjL17wOpagF4otewiJ+M+P4RhAvARUDUHIgzyn6Kwr2M yJ+Iv9O5mvM9SLOTXjw/jqqOWIKUnCSIPPaUx84/WGYn4LuObQyCC7m2YGoG72CKOYED yMgVILszjhoQvCUT3/2SFpHMDbiZ/AUp21AyEwG9TnvshhjzsQ3rmYogBxxsSgWyc/AV SWbVdWG3qhQHgcKYhQfX4KaQc9Yf5icC59cmnIbMpempscFA23BpVj4ri2DwNz+HIv5E SNgPzNe3xHl8NXX6bOcRd6B6MR4LLDYqKsoZxU3vmjoBZmXi6S38EzfrhqW6ilM3r5ER ghkg== X-Gm-Message-State: AO0yUKUwfyrUFaFVeXqkC7mSFZP+M0tm7V681ak6tld3BcEnxs7jyznl vbTOh0dK0iIyKvB9jneuKt5Arg== X-Google-Smtp-Source: AK7set+qnnpD/32ZmOpfeVntU8PPttuK2DhYuxb4vY8t5ty/R/gT3aSnqboAWAg7szGlAPVye+YgXA== X-Received: by 2002:a05:600c:3ba3:b0:3dc:58a2:3900 with SMTP id n35-20020a05600c3ba300b003dc58a23900mr18736987wms.29.1675679322619; Mon, 06 Feb 2023 02:28:42 -0800 (PST) Received: from localhost.localdomain ([5.133.47.210]) by smtp.gmail.com with ESMTPSA id g10-20020a05600c310a00b003de77597f16sm11002446wmo.21.2023.02.06.02.28.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Feb 2023 02:28:42 -0800 (PST) From: Srinivas Kandagatla To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Michael Walle , Srinivas Kandagatla Subject: [RESEND PATCH 23/37] nvmem: layouts: add sl28vpd layout Date: Mon, 6 Feb 2023 10:27:45 +0000 Message-Id: <20230206102759.669838-24-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230206102759.669838-1-srinivas.kandagatla@linaro.org> References: <20230206102759.669838-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