[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220227115743.69059-2-sven@svenpeter.dev>
Date: Sun, 27 Feb 2022 12:57:43 +0100
From: Sven Peter <sven@...npeter.dev>
To: Srinivas Kandagatla <srinivas.kandagatla@...aro.org>,
Rob Herring <robh+dt@...nel.org>
Cc: Sven Peter <sven@...npeter.dev>, Hector Martin <marcan@...can.st>,
Alyssa Rosenzweig <alyssa@...enzweig.io>,
Mark Kettenis <kettenis@...nbsd.org>,
linux-arm-kernel@...ts.infradead.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 2/2] nvmem: Add Apple eFuse driver
Apple SoCs contain eFuses used to store factory-programmed data such
as calibration values for the PCIe or the Type-C PHY. They are organized
as 32bit values exposed as MMIO.
Signed-off-by: Sven Peter <sven@...npeter.dev>
---
MAINTAINERS | 1 +
drivers/nvmem/Kconfig | 12 +++++++
drivers/nvmem/Makefile | 2 ++
drivers/nvmem/apple-efuses.c | 67 ++++++++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+)
create mode 100644 drivers/nvmem/apple-efuses.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 1bc57af09c80..031198aec108 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1781,6 +1781,7 @@ F: drivers/i2c/busses/i2c-pasemi-core.c
F: drivers/i2c/busses/i2c-pasemi-platform.c
F: drivers/irqchip/irq-apple-aic.c
F: drivers/mailbox/apple-mailbox.c
+F: drivers/nvmem/apple-efuses.c
F: drivers/pinctrl/pinctrl-apple-gpio.c
F: drivers/soc/apple/*
F: drivers/watchdog/apple_wdt.c
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index da414617a54d..ef6a13c8a4d6 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -300,4 +300,16 @@ config NVMEM_BRCM_NVRAM
This driver provides support for Broadcom's NVRAM that can be accessed
using I/O mapping.
+config NVMEM_APPLE_EFUSES
+ tristate "Apple eFuse support"
+ depends on ARCH_APPLE || COMPILE_TEST
+ default ARCH_APPLE
+ help
+ Say y here to enabled support for reading eFuses on Apple SoCs
+ such as the M1. These are e.g. used to store factory programmed
+ calibration data required for the PCIe or the USB-C PHY.
+
+ This driver can also be built as a module. If so, the module will
+ be called nvmem-apple-efuses.
+
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index dcbbde35b6a8..1a8e54691d3e 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
nvmem-rmem-y := rmem.o
obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
nvmem_brcm_nvram-y := brcm_nvram.o
+obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
+nvmem-apple-efuses-y := apple-efuses.o
diff --git a/drivers/nvmem/apple-efuses.c b/drivers/nvmem/apple-efuses.c
new file mode 100644
index 000000000000..925fc0033b83
--- /dev/null
+++ b/drivers/nvmem/apple-efuses.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple SoC eFuse driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ */
+
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+
+static int apple_efuses_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+{
+ void __iomem *fuses = context;
+ u32 *dst = val;
+
+ while (bytes >= sizeof(u32)) {
+ *dst++ = readl_relaxed(fuses + offset);
+ bytes -= sizeof(u32);
+ offset += sizeof(u32);
+ }
+
+ return 0;
+}
+
+static int apple_efuses_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct nvmem_config config = {
+ .dev = &pdev->dev,
+ .read_only = true,
+ .reg_read = apple_efuses_read,
+ .stride = sizeof(u32),
+ .word_size = sizeof(u32),
+ .name = "apple_efuses_nvmem",
+ .id = NVMEM_DEVID_AUTO,
+ };
+
+ config.priv = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(config.priv))
+ return PTR_ERR(config.priv);
+
+ config.size = resource_size(res);
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config));
+}
+
+static const struct of_device_id apple_efuses_of_match[] = {
+ { .compatible = "apple,efuses", },
+ {}
+};
+
+static struct platform_driver apple_efuses_driver = {
+ .driver = {
+ .name = "apple_efuses",
+ .of_match_table = apple_efuses_of_match,
+ },
+ .probe = apple_efuses_probe,
+};
+
+module_platform_driver(apple_efuses_driver);
+
+MODULE_AUTHOR("Sven Peter <sven@...npeter.dev>");
+MODULE_LICENSE("GPL");
--
2.25.1
Powered by blists - more mailing lists