From patchwork Mon Dec 18 13:37:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 13497010 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C5F62C35274 for ; Mon, 18 Dec 2023 13:44:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=vAsmTHgzbpbzXBivvKEn3JlWg7JFIqtgy02hyofBhXQ=; b=Rv7CXt2FNoNVn5 LRH/kW+Amp/gBt+ic7shiUJCjNFlJB1f+IqYzLyeT1oIl3LTdbSGhz/4n8nyixztb78/UN0frF7tY 5rtnq6OSrJdipHcdm5ZM10Ks9KKZWJ0/xOj2Plg3pmxk2wOGyDfySaf7p17890f5vXy9iOscfv2La bnL0MzuMNgjv32IR+lk98O7wk1pcuzJGvnjvG2Mp9qSytwVzcBc1YUt0wumnNDgRWnRS0cuUGXMex Ifacj89xRIK+pPI6Okv6c1wkVkJ6quUwr3KeBchd8IOrStlNT1OpxmQUwk15QpuOq7/FWU24A4uY+ vdhQzq+6CDMPkI1Z1sBg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rFDuR-00AuIj-1v; Mon, 18 Dec 2023 13:43:51 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rFDuL-00AuHP-2l; Mon, 18 Dec 2023 13:43:47 +0000 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-40c60dfa5bfso36282705e9.0; Mon, 18 Dec 2023 05:43:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702907022; x=1703511822; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=74hbRXhVdXgSDAgGqkd3Z2N/WmcE11nXVnluNKZBVyg=; b=MymsCwcGaAGzU5RItC4vqDy6LEsANBpUbnMYzjdR4RHp0M44EbjxdI7ABdFhG4Btmz 9d04K0pqLwPyh2nfvpcpkYRaRxpSfTpV+rconqnYYuVr9kIAb/ljp6YwomRgPCVKOtS0 KC/m1JermDUV0aZ56jOxP5YA67ilzG1x8/cl8ODv5i5oRdePtV5TzRJ+hZrukk5Z0YMB InyAs+1u3kdLTqMUz3HD4ovNqKTZDYLEYlhH9d5/RlrLsJCu+nDLM1KEAWgSQ/sJYxkF zQVSwPwUxxPVsOCg+3qqeYblghjAa2TOn4KIqLEQc8ncqTDUkbnx04V9XWp3AjVGHn7R sOxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702907023; x=1703511823; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=74hbRXhVdXgSDAgGqkd3Z2N/WmcE11nXVnluNKZBVyg=; b=WiENoPnqyZPkcrh8+XSfLg6SRTOtX48Z7j8eBBguOOPmZeTeY6JGxOBiPryojNHWPT JAPhYW5G3OZiCMF0j8ny2xl5R6hC+7iCT6JW+v9Cp52M9aB8uRD1ToAPoCW63LYyV4kJ SFdb8SmfrMAcu/Q2nDKySvZilwbP/B1g0V9fV9v5pXcd/wcWWQjGdNtwNRU5WgxwrB3L g46nhLyRPmqwibDEUolhirOOebtsnIw5TMgioeA5XlSpRXm/ufNFesvaSYMi0c4PBbal 5wEqwhXqEvM4NL5rtzJe1D1BA6M7blTxCGoiWLZzXkRk1Xaa44YKEkauy1EoZ+v1cfGZ AlIg== X-Gm-Message-State: AOJu0YzB58L4+gviD845QcNXVaaVswnVdSZFqa9leA4che540F+aXBrr xtULMZrviC9+/MOmIRhdKzFHQu1OpUU= X-Google-Smtp-Source: AGHT+IHT+hNGJimAnfQ6BtcEMsMSLNWd6wLudFTGCwXIlKzIipmCiwiwJao7CLfyL16Ml1MTDiLl1w== X-Received: by 2002:a05:600c:3556:b0:40b:5e1e:cf9 with SMTP id i22-20020a05600c355600b0040b5e1e0cf9mr7839833wmq.52.1702906659774; Mon, 18 Dec 2023 05:37:39 -0800 (PST) Received: from localhost.lan (031011218106.poznan.vectranet.pl. [31.11.218.106]) by smtp.gmail.com with ESMTPSA id f20-20020a1709067f9400b00a234907311asm1891537ejr.55.2023.12.18.05.37.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 05:37:39 -0800 (PST) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: Srinivas Kandagatla , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Greg Kroah-Hartman , Michael Walle , Miquel Raynal , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, u-boot@lists.denx.de, =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= Subject: [PATCH 1/4] dt-bindings: nvmem: layouts: add U-Boot environment variables layout Date: Mon, 18 Dec 2023 14:37:19 +0100 Message-Id: <20231218133722.16150-1-zajec5@gmail.com> X-Mailer: git-send-email 2.35.3 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231218_054345_899053_0DA1209D X-CRM114-Status: GOOD ( 17.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Rafał Miłecki U-Boot env data is a way of storing firmware variables. It's a format that can be used of top of various storage devices. Its binding should be an NVMEM layout instead of a standalone device. This patch adds layout binding which allows using it on top of MTD NVMEM device as well as any other. At the same time it deprecates the old combined binding. Signed-off-by: Rafał Miłecki --- .../bindings/nvmem/layouts/u-boot,env.yaml | 55 +++++++++++++++++++ .../devicetree/bindings/nvmem/u-boot,env.yaml | 6 ++ 2 files changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml diff --git a/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml new file mode 100644 index 000000000000..3a7ec02b3535 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/layouts/u-boot,env.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVMEM layout of U-Boot environment variables + +maintainers: + - Rafał Miłecki + +description: + U-Boot uses environment variables to store device parameters and + configuration. They may be used for booting process, setup or keeping end user + info. + + Data is stored using U-Boot specific formats (variant specific header and NUL + separated key-value pairs). + +properties: + compatible: + oneOf: + - description: A standalone env data block + const: u-boot,env + - description: Two redundant blocks with active one flagged + const: u-boot,env-redundant-bool + - description: Two redundant blocks with active having higher counter + const: u-boot,env-redundant-count + - description: Broadcom's variant with custom header + const: brcm,env + +additionalProperties: false + +examples: + - | + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x40000>; + label = "u-boot"; + read-only; + }; + + partition@40000 { + reg = <0x40000 0x10000>; + label = "u-boot-env"; + + nvmem-layout { + compatible = "u-boot,env"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml index 68214b96f5c9..fd95e611322d 100644 --- a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml +++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml @@ -26,9 +26,15 @@ description: | Variables can be defined as NVMEM device subnodes. + Introduction of NVMEM layouts exposed a limitation of this binding design. + Description of NVMEM data content should be separated from NVMEM devices. + Since the introduction of U-Boot env data layout this binding is deprecated. + maintainers: - Rafał Miłecki +deprecated: true + properties: compatible: oneOf: From patchwork Mon Dec 18 13:37:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 13497007 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A4817C46CCD for ; Mon, 18 Dec 2023 13:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=NfO/RHEjgGUEi+dsbxgIwK/gzQmUvwTjsNm+MZamq/M=; b=LO91e2Jy6ze4xn rr/oJ/iCzxeRav7g1sUVjGmYP5EMn8inxx0/ARN8NWX6DDXbxqTqGrrEDiACAGnF8S/zFiXl7RCuU k7GPOAwsM3meNMoXhxJHkUszhQL+Mfzi+9tbUVKfact9LTba9yUDF+oGOVbDNfYDCETJFZJTpEGlU 7erqoVWiuk3X7oHgXefSStNUre2mAFccwe/eGVV2M5dBeqEHcA8uavZPa4IneqTtYfivFx3pz6+aE AanayNC2YqXS9jZu8CxvbWCfVh6/LF/+iUHjO1wpNB+HzGnP8egh45DbJtNcs8yl6Ug+ltbsDgFZf 8QQ1odn5qJvJKVpTRMvw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rFDod-00AtC8-0R; Mon, 18 Dec 2023 13:37:51 +0000 Received: from mail-ej1-x629.google.com ([2a00:1450:4864:20::629]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rFDoZ-00AtAE-1O; Mon, 18 Dec 2023 13:37:48 +0000 Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a22f59c6ae6so381867866b.1; Mon, 18 Dec 2023 05:37:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702906663; x=1703511463; darn=lists.infradead.org; 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=lNpHTEQT4LZHegIzvZ+kMOyv6eP7HeX0Sd04kR5jmCY=; b=jS+kNQn7NoqdE3GjXHPXf8bK2TlI6c/nXZn27d9GKWLfXMMhdaI5fg/0F3GGLndSxa NKcadWyBaOmu41zwwTPvotdUAYcVXg23eoRAEbP6q5EUshMiAiODiuZffU8YjVga51MA tRli10GvaoLYqdLKFrmpU1iIzA4q89MDPfSXoOLzEm8V6J4bnBa19LDTGYyJlTS4vCpl jDCpC8MZfZYm+VKEt1qM5+dWLY1P0FwMHKwyNXLSBWWf+RM9zFIgWwXz7drp1uFyyBO3 4Jjic/V+VhSG94xU0nnSSYrdQAlJ3b0uM7MZ6mky3x+aIaqPG/g8a0BW+npIUcP4ncj2 hx/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702906663; x=1703511463; 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=lNpHTEQT4LZHegIzvZ+kMOyv6eP7HeX0Sd04kR5jmCY=; b=nek1kDAFkP5tjHhAKyLYxw9XMQ2BaCZ5mGHVXzsZ0E4H+GYFsBlYk8Irfsht/qCWMh dS+PviP++lqI3RhzJlbeRzlcQSQGwxntlA6Q9jE/a1CaoEmc2bI0p/8/nZSiv2uyYEGO TPOw1fv6M1STbTd0i4gNTt73aZwhciaK9+m4nzRxPH3/hDcZkYSVJRYFPcyKFM2m8Br+ Zm/9ox172mTvb3c7PYzDyq0PtrUokVvgcgtM1Nn8vWrmjvi60lSHwy2W8YPDbYcsLiyM f3Vk6nVl/LGH7oVpdMEAReYVmwEM15quS8aeeRuE/xPlQQ8j+t1+rb9KOZI2orjRGiXV qS6A== X-Gm-Message-State: AOJu0Yx3vEuBl3Hz/j9wvYNXkMlSewxM1zd7rfI/U7YIUT/yTjiJger2 GS1oioNmuP592ypgpLZbOayY8gg37Po= X-Google-Smtp-Source: AGHT+IGtGbsdUUc3O88BnV6j6UsM+dxyCX5fJtxHEDFGyKvcLjEb50ze3OtdtgF9HqxDX13eg9axjw== X-Received: by 2002:a17:906:3f46:b0:a19:a1ba:bad8 with SMTP id f6-20020a1709063f4600b00a19a1babad8mr3339416ejj.126.1702906662688; Mon, 18 Dec 2023 05:37:42 -0800 (PST) Received: from localhost.lan (031011218106.poznan.vectranet.pl. [31.11.218.106]) by smtp.gmail.com with ESMTPSA id f20-20020a1709067f9400b00a234907311asm1891537ejr.55.2023.12.18.05.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 05:37:42 -0800 (PST) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: Srinivas Kandagatla , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Greg Kroah-Hartman , Michael Walle , Miquel Raynal , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, u-boot@lists.denx.de, =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= Subject: [PATCH 2/4] nvmem: core: add nvmem_dev_size() helper Date: Mon, 18 Dec 2023 14:37:20 +0100 Message-Id: <20231218133722.16150-2-zajec5@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20231218133722.16150-1-zajec5@gmail.com> References: <20231218133722.16150-1-zajec5@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231218_053747_471586_7ACEE34D X-CRM114-Status: GOOD ( 11.06 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Rafał Miłecki This is required by layouts that need to read whole NVMEM content. It's especially useful for NVMEM devices without hardcoded layout (like U-Boot environment data block). Signed-off-by: Rafał Miłecki Reviewed-by: Miquel Raynal --- drivers/nvmem/core.c | 13 +++++++++++++ include/linux/nvmem-consumer.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index ba559e81f77f..1b08bb072f86 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -2176,6 +2176,19 @@ const char *nvmem_dev_name(struct nvmem_device *nvmem) } EXPORT_SYMBOL_GPL(nvmem_dev_name); +/** + * nvmem_dev_size() - Get the size of a given nvmem device. + * + * @nvmem: nvmem device. + * + * Return: size of the nvmem device. + */ +size_t nvmem_dev_size(struct nvmem_device *nvmem) +{ + return nvmem->size; +} +EXPORT_SYMBOL_GPL(nvmem_dev_size); + static int __init nvmem_init(void) { int ret; diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index 2d306fa13b1a..34c0e58dfa26 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem, struct nvmem_cell_info *info, void *buf); const char *nvmem_dev_name(struct nvmem_device *nvmem); +size_t nvmem_dev_size(struct nvmem_device *nvmem); void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); From patchwork Mon Dec 18 13:37:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 13497012 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C5F93C46CCD for ; Mon, 18 Dec 2023 13:46:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kTfJpEddafiKCHJguydDWTF30rL08a8lQOPphYiyVfs=; b=v3vWtKR0bkAG8a NMsdcOUOEIJJPjSQ8dXWACxSdQXM5HEZ2XHXDGswg/oiFzeEhnWw9I3OP9HzWOsYEfHvqm1xNgDON rgOfqPEX5r1aUiJoaDyqpzCupuIb9ey+GHZyPbk/C/emaqqF4K7OTtpEthtRdrgpYK3wp7gtfaNFP sVqbDLp/YK5JgpZej0hHPNWyMvt/YtwzKipFUzKiVxez3U593xKdco9mwz8mgHjaGDo98c5dkdIsG bjetJITrcx2Q+SMCYejvkI4tc5VIWDEqDg/t7EtU/YgGgruuLApNbT3+yZEoWgGL6yJDuuYSObGpM g7Onjj8xhpWOcXhV+3yg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rFDwg-00Aurr-2c; Mon, 18 Dec 2023 13:46:10 +0000 Received: from mail-ed1-x52b.google.com ([2a00:1450:4864:20::52b]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rFDwd-00Aup0-1U; Mon, 18 Dec 2023 13:46:09 +0000 Received: by mail-ed1-x52b.google.com with SMTP id 4fb4d7f45d1cf-54ba86ae133so2685248a12.2; Mon, 18 Dec 2023 05:46:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702907164; x=1703511964; darn=lists.infradead.org; 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=cWStvqK6KrlPpDCxoD+LXp2BPwdp0DZEpw1OHP4LGGI=; b=a+IdPjTijvOxz4jLJoCAi8a9vQtIeIkPPn2+DT1NCt3xLsLTXWWfTv77Ox91yh7rWC 0oJ+AI0ZzVaUROmQeooPqktodsxEHmGu5OlbkSaUvCA2IXAWQqZH0A3s44tmW3V7toKG 2O2HlO5kB1oFfr89JWlQz1AE0tesx12choYm6cWloIbzSdtD+fWeRzVdAc/fG9x3N1W/ eNmarDoU/vcUtLa3hsoPOaSdiy6/pmNL5l1oXPYVYj7j81ffFTahgejsnPGyIfIpvUMa G5tPXCtmvFIdTMkXK4ic46nBrGAv6k8hgsX943wiF/gjVyEld/2Jd+b+rDA4lh/FTsnA uHsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702907164; x=1703511964; 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=cWStvqK6KrlPpDCxoD+LXp2BPwdp0DZEpw1OHP4LGGI=; b=cvvfAlYm27CkY8Qg2yqVSKGfCztVoxKJhMudvh5CpNgEoFHijCihml/OGEb6qJuXTC DWiF1Rr8M3Lg+jWjfEG/omzNAanGKKh/4FTH8/mZU2g92rwoMIvbCTKwxyf1/nWMifIR I6Qr5vMg5T78YGbDg5j2+qwBAvDka1XADnY3N5QbOcGjwfOtjaw4Sj9UtwzWfiB/f3bn nW56HAXYETTYNUG6AdeFWwiztoQ9mVMIwJpq7fq97NaVNr2A8I0IV5fS9HUfwvhHFtPO 5VdURxDgxISqbFBzzCyEAKWABHKAcNBbSjj86ZnM9aSLV4ycX1V5s11QsyvKv3fEUqyi IT1w== X-Gm-Message-State: AOJu0YzZwqFuPcorKbpy6JZSfchZ8ra8W286RxPp2WYjtyxRUwpwefie jE06/NYLz+p7gQBA3qs/eK3AmFNAC5A= X-Google-Smtp-Source: AGHT+IHp95pnHBpGST+4vtRvNyTH5biaemOYZgB8XiiCBPCxXrTDcGLJjvu3bDnbMTy8rJsQqRJ+XQ== X-Received: by 2002:a05:6512:39cb:b0:50b:f03c:1ea2 with SMTP id k11-20020a05651239cb00b0050bf03c1ea2mr10860168lfu.84.1702906664468; Mon, 18 Dec 2023 05:37:44 -0800 (PST) Received: from localhost.lan (031011218106.poznan.vectranet.pl. [31.11.218.106]) by smtp.gmail.com with ESMTPSA id f20-20020a1709067f9400b00a234907311asm1891537ejr.55.2023.12.18.05.37.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 05:37:44 -0800 (PST) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: Srinivas Kandagatla , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Greg Kroah-Hartman , Michael Walle , Miquel Raynal , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, u-boot@lists.denx.de, =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= Subject: [PATCH 3/4] nvmem: u-boot-env: use more nvmem subsystem helpers Date: Mon, 18 Dec 2023 14:37:21 +0100 Message-Id: <20231218133722.16150-3-zajec5@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20231218133722.16150-1-zajec5@gmail.com> References: <20231218133722.16150-1-zajec5@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231218_054607_661730_48A6DFA8 X-CRM114-Status: GOOD ( 20.32 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Rafał Miłecki 1. Use nvmem_dev_size() and nvmem_device_read() to make this driver less mtd dependent 2. Use nvmem_add_one_cell() to simplify adding NVMEM cells Signed-off-by: Rafał Miłecki Reviewed-by: Miquel Raynal --- drivers/nvmem/u-boot-env.c | 79 +++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c index c4ae94af4af7..ab8c9bf63d99 100644 --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c @@ -23,13 +23,10 @@ enum u_boot_env_format { struct u_boot_env { struct device *dev; + struct nvmem_device *nvmem; enum u_boot_env_format format; struct mtd_info *mtd; - - /* Cells */ - struct nvmem_cell_info *cells; - int ncells; }; struct u_boot_env_image_single { @@ -94,72 +91,69 @@ static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, i static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, size_t data_offset, size_t data_len) { + struct nvmem_device *nvmem = priv->nvmem; struct device *dev = priv->dev; char *data = buf + data_offset; char *var, *value, *eq; - int idx; - - priv->ncells = 0; - for (var = data; var < data + data_len && *var; var += strlen(var) + 1) - priv->ncells++; - priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); - if (!priv->cells) - return -ENOMEM; - - for (var = data, idx = 0; + for (var = data; var < data + data_len && *var; - var = value + strlen(value) + 1, idx++) { + var = value + strlen(value) + 1) { + struct nvmem_cell_info info = {}; + eq = strchr(var, '='); if (!eq) break; *eq = '\0'; value = eq + 1; - priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); - if (!priv->cells[idx].name) + info.name = devm_kstrdup(dev, var, GFP_KERNEL); + if (!info.name) return -ENOMEM; - priv->cells[idx].offset = data_offset + value - data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); + info.offset = data_offset + value - data; + info.bytes = strlen(value); + info.np = of_get_child_by_name(dev->of_node, info.name); if (!strcmp(var, "ethaddr")) { - priv->cells[idx].raw_len = strlen(value); - priv->cells[idx].bytes = ETH_ALEN; - priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; + info.raw_len = strlen(value); + info.bytes = ETH_ALEN; + info.read_post_process = u_boot_env_read_post_process_ethaddr; } - } - if (WARN_ON(idx != priv->ncells)) - priv->ncells = idx; + nvmem_add_one_cell(nvmem, &info); + } return 0; } static int u_boot_env_parse(struct u_boot_env *priv) { + struct nvmem_device *nvmem = priv->nvmem; struct device *dev = priv->dev; size_t crc32_data_offset; size_t crc32_data_len; size_t crc32_offset; size_t data_offset; size_t data_len; + size_t dev_size; uint32_t crc32; uint32_t calc; - size_t bytes; uint8_t *buf; + int bytes; int err; - buf = kcalloc(1, priv->mtd->size, GFP_KERNEL); + dev_size = nvmem_dev_size(nvmem); + + buf = kcalloc(1, dev_size, GFP_KERNEL); if (!buf) { err = -ENOMEM; goto err_out; } - err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf); - if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) { - dev_err(dev, "Failed to read from mtd: %d\n", err); - goto err_kfree; - } + bytes = nvmem_device_read(nvmem, 0, dev_size, buf); + if (bytes < 0) + return bytes; + else if (bytes != dev_size) + return -EIO; switch (priv->format) { case U_BOOT_FORMAT_SINGLE: @@ -179,8 +173,8 @@ static int u_boot_env_parse(struct u_boot_env *priv) break; } crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); - crc32_data_len = priv->mtd->size - crc32_data_offset; - data_len = priv->mtd->size - data_offset; + crc32_data_len = dev_size - crc32_data_offset; + data_len = dev_size - data_offset; calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; if (calc != crc32) { @@ -189,7 +183,7 @@ static int u_boot_env_parse(struct u_boot_env *priv) goto err_kfree; } - buf[priv->mtd->size - 1] = '\0'; + buf[dev_size - 1] = '\0'; err = u_boot_env_add_cells(priv, buf, data_offset, data_len); if (err) dev_err(dev, "Failed to add cells: %d\n", err); @@ -209,7 +203,6 @@ static int u_boot_env_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct u_boot_env *priv; - int err; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -224,17 +217,15 @@ static int u_boot_env_probe(struct platform_device *pdev) return PTR_ERR(priv->mtd); } - err = u_boot_env_parse(priv); - if (err) - return err; - config.dev = dev; - config.cells = priv->cells; - config.ncells = priv->ncells; config.priv = priv; config.size = priv->mtd->size; - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); + priv->nvmem = devm_nvmem_register(dev, &config); + if (IS_ERR(priv->nvmem)) + return PTR_ERR(priv->nvmem); + + return u_boot_env_parse(priv); } static const struct of_device_id u_boot_env_of_match_table[] = { From patchwork Mon Dec 18 13:37:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 13497008 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 73197C35274 for ; Mon, 18 Dec 2023 13:38:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=wtPQKpYGpSqlraMIf6w2QVrLFTfDpl1VrbQX/ORqwtg=; b=4mXZq/T9xZSOgb nIS9xQ3q91IXo6wyhLYN/jM1nX1Su8/14d17RJYkwzD13wZ2cuawKWv4cPGXvsVQL3qIOSBDfSjk9 MhxNu7OZkgR+EBq1a76MkzfiOen2W7P0LuX9xQS5Jbunk+Mhnz5lEFWg4cyTVecA/gzsgQhv6v4Rp vr5EZowZsLcENN6BY963mO1tJc/7GqcAv30LpdZ5c2hMhtRwquSEiz719V9yNos9zWJrNw1DXlYjV 3IE5NzzNZMj5dxtZVRrMvnmu5SqBev9ONzB0pdZx3H+/pKzOnkFUQhFGu0N8Eigj6426JfB4R0PQZ 9UHXRzbNuqtsFfF0kNRw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rFDoj-00AtFQ-2y; Mon, 18 Dec 2023 13:37:57 +0000 Received: from mail-ej1-x630.google.com ([2a00:1450:4864:20::630]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rFDoa-00AtAn-0Q; Mon, 18 Dec 2023 13:37:50 +0000 Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-a1ca24776c3so774878766b.0; Mon, 18 Dec 2023 05:37:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702906666; x=1703511466; darn=lists.infradead.org; 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=5NnQuhRM2aKmxMX4UvGIlLC0dqge59QIibPSitP1r8c=; b=b1LGLE37dLXAhMtYnKho6j3Rkj3M9CkleeopsaczKgA3CkjPV0djAJIJqDS0jHnFE6 G1zg/0HnL3+cwwH5sfB5mc7gdRTRApaLvbUGwJdXlaFlaEAj+74PS9Ea8gADTP0kLFTX mu1Fo0HTpNpvxfH6/URbbsMB7Zjn7+S3svhmhSU4JpDovStR6RHzUJbPbmXf2BneE5Gh Cs/fJnuevRsWXQtaJdwX+4Yti8g4BOIXo+0hf0IMQe8qrXRaz+NxYYxdLjU1LP+V6eg7 bpQdDUBEK8YF0ok5XtZ5qWrEzQfZdHV2BLMeSzg6D9nP8eaTlSlb9azJ59khGIxVZctX 9s+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702906666; x=1703511466; 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=5NnQuhRM2aKmxMX4UvGIlLC0dqge59QIibPSitP1r8c=; b=cGtYihit9XBnrJCpsSRDwAicj3zR7nrx6oQJW6hAJzEy9B4+6ppbOXAEuI5IpfgT6l vDFC5r0uGXkgy0QjzHu66Np4Ofdwg2Y+fpYfhMmG+Bk6ErZqAhDFCOZ+r3WYKgkQOpaA s3M/w6D4Ts9smFimRt+C4p3p3Rs/JINBm+Fh0S66+2HgS9KGs3WF0J3Eze264xEom3ZR BprxOb98DS2+GgqiGsTo9LcoivmFoz1Lz6+YYdfTHkigOh6q/ip9SHECCvGoeKbNt4QH bAvDWL2UsZedJl5gXZKpQnHTmJMP8IudMPJGbh8v4y7mq/wwus01M/Ec29FNlnQQdnNd LRgg== X-Gm-Message-State: AOJu0YyUXnRfjHOkJ8FABODuSD9PuMXYYVaZLN8WtpIjbM47JRlnMrMO n6NudUStFoQ0yPdA3Wl8/xQ= X-Google-Smtp-Source: AGHT+IHfTv+BKJWGNsKj+Odg60M5z2SLEb0xSXLQVDZohpDTBi8IGg8TUepkJ6sZFipc+PIZqYgp3w== X-Received: by 2002:a17:906:5345:b0:a1c:b707:cbd1 with SMTP id j5-20020a170906534500b00a1cb707cbd1mr13446680ejo.24.1702906666210; Mon, 18 Dec 2023 05:37:46 -0800 (PST) Received: from localhost.lan (031011218106.poznan.vectranet.pl. [31.11.218.106]) by smtp.gmail.com with ESMTPSA id f20-20020a1709067f9400b00a234907311asm1891537ejr.55.2023.12.18.05.37.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 05:37:45 -0800 (PST) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: Srinivas Kandagatla , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Greg Kroah-Hartman , Michael Walle , Miquel Raynal , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, u-boot@lists.denx.de, =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= Subject: [PATCH 4/4] nvmem: layouts: add U-Boot env layout Date: Mon, 18 Dec 2023 14:37:22 +0100 Message-Id: <20231218133722.16150-4-zajec5@gmail.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20231218133722.16150-1-zajec5@gmail.com> References: <20231218133722.16150-1-zajec5@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231218_053748_173640_4C5B86F8 X-CRM114-Status: GOOD ( 29.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Rafał Miłecki This patch moves all generic (NVMEM devices independent) code from NVMEM device driver to NVMEM layout driver. Then it adds a simple NVMEM layout code on top of it. Thanks to proper layout it's possible to support U-Boot env data stored on any kind of NVMEM device. For backward compatibility with old DT bindings we need to keep old NVMEM device driver functional. To avoid code duplication a parsing function is exported and reused in it. Signed-off-by: Rafał Miłecki --- MAINTAINERS | 1 + drivers/nvmem/Kconfig | 3 +- drivers/nvmem/layouts/Kconfig | 11 ++ drivers/nvmem/layouts/Makefile | 1 + drivers/nvmem/layouts/u-boot-env.c | 212 +++++++++++++++++++++++++++++ drivers/nvmem/layouts/u-boot-env.h | 15 ++ drivers/nvmem/u-boot-env.c | 155 +-------------------- 7 files changed, 243 insertions(+), 155 deletions(-) create mode 100644 drivers/nvmem/layouts/u-boot-env.c create mode 100644 drivers/nvmem/layouts/u-boot-env.h diff --git a/MAINTAINERS b/MAINTAINERS index b589218605b4..1f7e6d74cd51 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22282,6 +22282,7 @@ U-BOOT ENVIRONMENT VARIABLES M: Rafał Miłecki S: Maintained F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml +F: drivers/nvmem/layouts/u-boot-env.c F: drivers/nvmem/u-boot-env.c UACCE ACCELERATOR FRAMEWORK diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 283134498fbc..d2c384f58028 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID config NVMEM_U_BOOT_ENV tristate "U-Boot environment variables support" depends on OF && MTD - select CRC32 - select GENERIC_NET_UTILS + select NVMEM_LAYOUT_U_BOOT_ENV help U-Boot stores its setup as environment variables. This driver adds support for verifying & exporting such data. It also exposes variables diff --git a/drivers/nvmem/layouts/Kconfig b/drivers/nvmem/layouts/Kconfig index 9c6e672fc350..5e586dfebe47 100644 --- a/drivers/nvmem/layouts/Kconfig +++ b/drivers/nvmem/layouts/Kconfig @@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV If unsure, say N. +config NVMEM_LAYOUT_U_BOOT_ENV + tristate "U-Boot environment variables layout" + select CRC32 + select GENERIC_NET_UTILS + help + U-Boot stores its setup as environment variables. This driver adds + support for verifying & exporting such data. It also exposes variables + as NVMEM cells so they can be referenced by other drivers. + + If unsure, say N. + endmenu endif diff --git a/drivers/nvmem/layouts/Makefile b/drivers/nvmem/layouts/Makefile index 2974bd7d33ed..4940c9db0665 100644 --- a/drivers/nvmem/layouts/Makefile +++ b/drivers/nvmem/layouts/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o +obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o diff --git a/drivers/nvmem/layouts/u-boot-env.c b/drivers/nvmem/layouts/u-boot-env.c new file mode 100644 index 000000000000..1787cfaf45f8 --- /dev/null +++ b/drivers/nvmem/layouts/u-boot-env.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 - 2023 Rafał Miłecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "u-boot-env.h" + +struct u_boot_env_image_single { + __le32 crc32; + uint8_t data[]; +} __packed; + +struct u_boot_env_image_redundant { + __le32 crc32; + u8 mark; + uint8_t data[]; +} __packed; + +struct u_boot_env_image_broadcom { + __le32 magic; + __le32 len; + __le32 crc32; + DECLARE_FLEX_ARRAY(uint8_t, data); +} __packed; + +static const struct of_device_id u_boot_env_of_match_table[] = { + { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, + { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, + { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, + { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, + {}, +}; + +static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, + unsigned int offset, void *buf, size_t bytes) +{ + u8 mac[ETH_ALEN]; + + if (bytes != 3 * ETH_ALEN - 1) + return -EINVAL; + + if (!mac_pton(buf, mac)) + return -EINVAL; + + if (index) + eth_addr_add(mac, index); + + ether_addr_copy(buf, mac); + + return 0; +} + +static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf, + size_t data_offset, size_t data_len) +{ + char *data = buf + data_offset; + char *var, *value, *eq; + + for (var = data; + var < data + data_len && *var; + var = value + strlen(value) + 1) { + struct nvmem_cell_info info = {}; + + eq = strchr(var, '='); + if (!eq) + break; + *eq = '\0'; + value = eq + 1; + + info.name = devm_kstrdup(dev, var, GFP_KERNEL); + if (!info.name) + return -ENOMEM; + info.offset = data_offset + value - data; + info.bytes = strlen(value); + info.np = of_get_child_by_name(dev->of_node, info.name); + if (!strcmp(var, "ethaddr")) { + info.raw_len = strlen(value); + info.bytes = ETH_ALEN; + info.read_post_process = u_boot_env_read_post_process_ethaddr; + } + + nvmem_add_one_cell(nvmem, &info); + } + + return 0; +} + +int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, + enum u_boot_env_format format) +{ + size_t crc32_data_offset; + size_t crc32_data_len; + size_t crc32_offset; + size_t data_offset; + size_t data_len; + size_t dev_size; + uint32_t crc32; + uint32_t calc; + uint8_t *buf; + int bytes; + int err; + + dev_size = nvmem_dev_size(nvmem); + + buf = kcalloc(1, dev_size, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto err_out; + } + + bytes = nvmem_device_read(nvmem, 0, dev_size, buf); + if (bytes < 0) + return bytes; + else if (bytes != dev_size) + return -EIO; + + switch (format) { + case U_BOOT_FORMAT_SINGLE: + crc32_offset = offsetof(struct u_boot_env_image_single, crc32); + crc32_data_offset = offsetof(struct u_boot_env_image_single, data); + data_offset = offsetof(struct u_boot_env_image_single, data); + break; + case U_BOOT_FORMAT_REDUNDANT: + crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); + crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); + data_offset = offsetof(struct u_boot_env_image_redundant, data); + break; + case U_BOOT_FORMAT_BROADCOM: + crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); + crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); + data_offset = offsetof(struct u_boot_env_image_broadcom, data); + break; + } + crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); + crc32_data_len = dev_size - crc32_data_offset; + data_len = dev_size - data_offset; + + calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; + if (calc != crc32) { + dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); + err = -EINVAL; + goto err_kfree; + } + + buf[dev_size - 1] = '\0'; + err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len); + if (err) + dev_err(dev, "Failed to add cells: %d\n", err); + +err_kfree: + kfree(buf); +err_out: + return err; +} +EXPORT_SYMBOL_GPL(u_boot_env_parse); + +static int u_boot_env_add_cells(struct device *dev, struct nvmem_device *nvmem) +{ + const struct of_device_id *match; + struct device_node *layout_np; + enum u_boot_env_format format; + + layout_np = of_nvmem_layout_get_container(nvmem); + if (!layout_np) + return -ENOENT; + + match = of_match_node(u_boot_env_of_match_table, layout_np); + if (!match) + return -ENOENT; + + format = (uintptr_t)match->data; + + of_node_put(layout_np); + + return u_boot_env_parse(dev, nvmem, format); +} + +static int u_boot_env_probe(struct nvmem_layout *layout) +{ + layout->add_cells = u_boot_env_add_cells; + + return nvmem_layout_register(layout); +} + +static void u_boot_env_remove(struct nvmem_layout *layout) +{ + nvmem_layout_unregister(layout); +} + +static struct nvmem_layout_driver u_boot_env_layout = { + .driver = { + .owner = THIS_MODULE, + .name = "u-boot-env-layout", + .of_match_table = u_boot_env_of_match_table, + }, + .probe = u_boot_env_probe, + .remove = u_boot_env_remove, +}; +module_nvmem_layout_driver(u_boot_env_layout); + +MODULE_AUTHOR("Rafał Miłecki"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); diff --git a/drivers/nvmem/layouts/u-boot-env.h b/drivers/nvmem/layouts/u-boot-env.h new file mode 100644 index 000000000000..dd5f280ac047 --- /dev/null +++ b/drivers/nvmem/layouts/u-boot-env.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H +#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H + +enum u_boot_env_format { + U_BOOT_FORMAT_SINGLE, + U_BOOT_FORMAT_REDUNDANT, + U_BOOT_FORMAT_BROADCOM, +}; + +int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, + enum u_boot_env_format format); + +#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */ diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c index ab8c9bf63d99..386b2b255c30 100644 --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c @@ -3,23 +3,15 @@ * Copyright (C) 2022 Rafał Miłecki */ -#include -#include -#include #include #include #include -#include #include #include #include #include -enum u_boot_env_format { - U_BOOT_FORMAT_SINGLE, - U_BOOT_FORMAT_REDUNDANT, - U_BOOT_FORMAT_BROADCOM, -}; +#include "layouts/u-boot-env.h" struct u_boot_env { struct device *dev; @@ -29,24 +21,6 @@ struct u_boot_env { struct mtd_info *mtd; }; -struct u_boot_env_image_single { - __le32 crc32; - uint8_t data[]; -} __packed; - -struct u_boot_env_image_redundant { - __le32 crc32; - u8 mark; - uint8_t data[]; -} __packed; - -struct u_boot_env_image_broadcom { - __le32 magic; - __le32 len; - __le32 crc32; - DECLARE_FLEX_ARRAY(uint8_t, data); -} __packed; - static int u_boot_env_read(void *context, unsigned int offset, void *val, size_t bytes) { @@ -69,131 +43,6 @@ static int u_boot_env_read(void *context, unsigned int offset, void *val, return 0; } -static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, - unsigned int offset, void *buf, size_t bytes) -{ - u8 mac[ETH_ALEN]; - - if (bytes != 3 * ETH_ALEN - 1) - return -EINVAL; - - if (!mac_pton(buf, mac)) - return -EINVAL; - - if (index) - eth_addr_add(mac, index); - - ether_addr_copy(buf, mac); - - return 0; -} - -static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, - size_t data_offset, size_t data_len) -{ - struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - char *data = buf + data_offset; - char *var, *value, *eq; - - for (var = data; - var < data + data_len && *var; - var = value + strlen(value) + 1) { - struct nvmem_cell_info info = {}; - - eq = strchr(var, '='); - if (!eq) - break; - *eq = '\0'; - value = eq + 1; - - info.name = devm_kstrdup(dev, var, GFP_KERNEL); - if (!info.name) - return -ENOMEM; - info.offset = data_offset + value - data; - info.bytes = strlen(value); - info.np = of_get_child_by_name(dev->of_node, info.name); - if (!strcmp(var, "ethaddr")) { - info.raw_len = strlen(value); - info.bytes = ETH_ALEN; - info.read_post_process = u_boot_env_read_post_process_ethaddr; - } - - nvmem_add_one_cell(nvmem, &info); - } - - return 0; -} - -static int u_boot_env_parse(struct u_boot_env *priv) -{ - struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - size_t crc32_data_offset; - size_t crc32_data_len; - size_t crc32_offset; - size_t data_offset; - size_t data_len; - size_t dev_size; - uint32_t crc32; - uint32_t calc; - uint8_t *buf; - int bytes; - int err; - - dev_size = nvmem_dev_size(nvmem); - - buf = kcalloc(1, dev_size, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; - } - - bytes = nvmem_device_read(nvmem, 0, dev_size, buf); - if (bytes < 0) - return bytes; - else if (bytes != dev_size) - return -EIO; - - switch (priv->format) { - case U_BOOT_FORMAT_SINGLE: - crc32_offset = offsetof(struct u_boot_env_image_single, crc32); - crc32_data_offset = offsetof(struct u_boot_env_image_single, data); - data_offset = offsetof(struct u_boot_env_image_single, data); - break; - case U_BOOT_FORMAT_REDUNDANT: - crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); - crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); - data_offset = offsetof(struct u_boot_env_image_redundant, data); - break; - case U_BOOT_FORMAT_BROADCOM: - crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); - crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); - data_offset = offsetof(struct u_boot_env_image_broadcom, data); - break; - } - crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); - crc32_data_len = dev_size - crc32_data_offset; - data_len = dev_size - data_offset; - - calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; - if (calc != crc32) { - dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); - err = -EINVAL; - goto err_kfree; - } - - buf[dev_size - 1] = '\0'; - err = u_boot_env_add_cells(priv, buf, data_offset, data_len); - if (err) - dev_err(dev, "Failed to add cells: %d\n", err); - -err_kfree: - kfree(buf); -err_out: - return err; -} - static int u_boot_env_probe(struct platform_device *pdev) { struct nvmem_config config = { @@ -225,7 +74,7 @@ static int u_boot_env_probe(struct platform_device *pdev) if (IS_ERR(priv->nvmem)) return PTR_ERR(priv->nvmem); - return u_boot_env_parse(priv); + return u_boot_env_parse(dev, priv->nvmem, priv->format); } static const struct of_device_id u_boot_env_of_match_table[] = {