summaryrefslogtreecommitdiff
path: root/drivers/nvmem
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-29 11:58:27 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-29 11:58:27 -0800
commit2eff01ee2881becc9daaa0d53477ec202136b1f4 (patch)
treed90cf5527266962e3a249a1f96e10e4afe29d246 /drivers/nvmem
parent55cb93fd243bad2c6e15f9151a32f575d2f5371f (diff)
parent5a6c35258d10a4966f45ee48ae24a7d4dad303ce (diff)
Merge tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc/IIO/whatever driver subsystem updates from Greg KH: "Here is the 'big and hairy' char/misc/iio and other small driver subsystem updates for 6.13-rc1. Loads of things in here, and even a fun merge conflict! - rust misc driver bindings and other rust changes to make misc drivers actually possible. I think this is the tipping point, expect to see way more rust drivers going forward now that these bindings are present. Next merge window hopefully we will have pci and platform drivers working, which will fully enable almost all driver subsystems to start accepting (or at least getting) rust drivers. This is the end result of a lot of work from a lot of people, congrats to all of them for getting this far, you've proved many of us wrong in the best way possible, working code :) - IIO driver updates, too many to list individually, that subsystem keeps growing and growing... - Interconnect driver updates - nvmem driver updates - pwm driver updates - platform_driver::remove() fixups, loads of them - counter driver updates - misc driver updates (keba?) - binder driver updates and fixes - loads of other small char/misc/etc driver updates and additions, full details in the shortlog. All of these have been in linux-next for a while, with no other reported issues other than that merge conflict" * tag 'char-misc-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (401 commits) mei: vsc: Fix typo "maintstepping" -> "mainstepping" firmware: Switch back to struct platform_driver::remove() misc: isl29020: Fix the wrong format specifier scripts/tags.sh: Don't tag usages of DEFINE_MUTEX fpga: Switch back to struct platform_driver::remove() mei: vsc: Improve error logging in vsc_identify_silicon() mei: vsc: Do not re-enable interrupt from vsc_tp_reset() dt-bindings: spmi: qcom,x1e80100-spmi-pmic-arb: Add SAR2130P compatible dt-bindings: spmi: spmi-mtk-pmif: Add compatible for MT8188 spmi: pmic-arb: fix return path in for_each_available_child_of_node() iio: Move __private marking before struct element priv in struct iio_dev docs: iio: ad7380: add adaq4370-4 and adaq4380-4 iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 iio: adc: ad7380: use local dev variable to shorten long lines iio: adc: ad7380: fix oversampling formula dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts bus: mhi: host: pci_generic: Use pcim_iomap_region() to request and map MHI BAR bus: mhi: host: Switch trace_mhi_gen_tre fields to native endian misc: atmel-ssc: Use of_property_present() for non-boolean properties misc: keba: Add hardware dependency ...
Diffstat (limited to 'drivers/nvmem')
-rw-r--r--drivers/nvmem/Kconfig11
-rw-r--r--drivers/nvmem/Makefile2
-rw-r--r--drivers/nvmem/brcm_nvram.c2
-rw-r--r--drivers/nvmem/core.c6
-rw-r--r--drivers/nvmem/imx-iim.c10
-rw-r--r--drivers/nvmem/lpc18xx_otp.c2
-rw-r--r--drivers/nvmem/microchip-otpc.c2
-rw-r--r--drivers/nvmem/rcar-efuse.c142
8 files changed, 166 insertions, 11 deletions
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index d2c384f58028..8671b7c974b9 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -246,6 +246,17 @@ config NVMEM_RAVE_SP_EEPROM
help
Say y here to enable Rave SP EEPROM support.
+config NVMEM_RCAR_EFUSE
+ tristate "Renesas R-Car Gen4 E-FUSE support"
+ depends on (ARCH_RENESAS && ARM64) || COMPILE_TEST
+ depends on NVMEM
+ help
+ Enable support for reading the fuses in the E-FUSE or OTP
+ non-volatile memory block on Renesas R-Car Gen4 SoCs.
+
+ This driver can also be built as a module. If so, the module
+ will be called nvmem-rcar-efuse.
+
config NVMEM_RMEM
tristate "Reserved Memory Based Driver Support"
depends on HAS_IOMEM
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index cdd01fbf1313..5b77bbb6488b 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -52,6 +52,8 @@ obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o
nvmem_sec_qfprom-y := sec-qfprom.o
obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o
nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o
+obj-$(CONFIG_NVMEM_RCAR_EFUSE) += nvmem-rcar-efuse.o
+nvmem-rcar-efuse-y := rcar-efuse.o
obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
nvmem-rmem-y := rmem.o
obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o
diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
index 3d8c87835f4d..b810df727b44 100644
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -22,7 +22,7 @@
*
* @dev: NVMEM device pointer
* @nvmem_size: Size of the whole space available for NVRAM
- * @data: NVRAM data copy stored to avoid poking underlaying flash controller
+ * @data: NVRAM data copy stored to avoid poking underlying flash controller
* @data_len: NVRAM data size
* @padding_byte: Padding value used to fill remaining space
* @cells: Array of discovered NVMEM cells
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 73e44d724f90..d6494dfc20a7 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -267,7 +267,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
count = round_down(count, nvmem->word_size);
- if (!nvmem->reg_write)
+ if (!nvmem->reg_write || nvmem->read_only)
return -EPERM;
rc = nvmem_reg_write(nvmem, pos, buf, count);
@@ -1257,7 +1257,7 @@ static void devm_nvmem_device_release(struct device *dev, void *res)
}
/**
- * devm_nvmem_device_put() - put alredy got nvmem device
+ * devm_nvmem_device_put() - put already got nvmem device
*
* @dev: Device that uses the nvmem device.
* @nvmem: pointer to nvmem device allocated by devm_nvmem_cell_get(),
@@ -1275,7 +1275,7 @@ void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem)
EXPORT_SYMBOL_GPL(devm_nvmem_device_put);
/**
- * nvmem_device_put() - put alredy got nvmem device
+ * nvmem_device_put() - put already got nvmem device
*
* @nvmem: pointer to nvmem device that needs to be released.
*/
diff --git a/drivers/nvmem/imx-iim.c b/drivers/nvmem/imx-iim.c
index f13bbd164086..8cfbe55a56cb 100644
--- a/drivers/nvmem/imx-iim.c
+++ b/drivers/nvmem/imx-iim.c
@@ -115,11 +115,11 @@ static int imx_iim_probe(struct platform_device *pdev)
if (IS_ERR(iim->clk))
return PTR_ERR(iim->clk);
- cfg.name = "imx-iim",
- cfg.read_only = true,
- cfg.word_size = 1,
- cfg.stride = 1,
- cfg.reg_read = imx_iim_read,
+ cfg.name = "imx-iim";
+ cfg.read_only = true;
+ cfg.word_size = 1;
+ cfg.stride = 1;
+ cfg.reg_read = imx_iim_read;
cfg.dev = dev;
cfg.size = drvdata->nregs;
cfg.priv = iim;
diff --git a/drivers/nvmem/lpc18xx_otp.c b/drivers/nvmem/lpc18xx_otp.c
index adc9948e7b2e..c41a0c58bec7 100644
--- a/drivers/nvmem/lpc18xx_otp.c
+++ b/drivers/nvmem/lpc18xx_otp.c
@@ -21,7 +21,7 @@
* LPC18xx OTP memory contains 4 banks with 4 32-bit words. Bank 0 starts
* at offset 0 from the base.
*
- * Bank 0 contains the part ID for Flashless devices and is reseverd for
+ * Bank 0 contains the part ID for Flashless devices and is reserved for
* devices with Flash.
* Bank 1/2 is generale purpose or AES key storage for secure devices.
* Bank 3 contains control data, USB ID and generale purpose words.
diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c
index 7cf81738a3e0..df979e8549fd 100644
--- a/drivers/nvmem/microchip-otpc.c
+++ b/drivers/nvmem/microchip-otpc.c
@@ -156,7 +156,7 @@ static int mchp_otpc_read(void *priv, unsigned int off, void *val,
/*
* We reach this point with off being multiple of stride = 4 to
* be able to cross the subsystem. Inside the driver we use continuous
- * unsigned integer numbers for packet id, thus devide off by 4
+ * unsigned integer numbers for packet id, thus divide off by 4
* before passing it to mchp_otpc_id_to_packet().
*/
packet = mchp_otpc_id_to_packet(otpc, off / 4);
diff --git a/drivers/nvmem/rcar-efuse.c b/drivers/nvmem/rcar-efuse.c
new file mode 100644
index 000000000000..f24bdb9cb5a7
--- /dev/null
+++ b/drivers/nvmem/rcar-efuse.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Renesas R-Car E-FUSE/OTP Driver
+ *
+ * Copyright (C) 2024 Glider bv
+ */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+
+struct rcar_fuse {
+ struct nvmem_keepout keepouts[2];
+ struct nvmem_device *nvmem;
+ struct device *dev;
+ void __iomem *base;
+};
+
+struct rcar_fuse_data {
+ unsigned int bank; /* 0: PFC + E-FUSE, 1: OPT_MEM + E-FUSE */
+ unsigned int start; /* inclusive */
+ unsigned int end; /* exclusive */
+};
+
+static int rcar_fuse_reg_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct rcar_fuse *fuse = priv;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(fuse->dev);
+ if (ret < 0)
+ return ret;
+
+ __ioread32_copy(val, fuse->base + offset, bytes / 4);
+
+ pm_runtime_put(fuse->dev);
+
+ return 0;
+}
+
+static int rcar_fuse_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct rcar_fuse_data *data = device_get_match_data(dev);
+ struct nvmem_config config = {
+ .dev = dev,
+ .name = "rcar-fuse",
+ .id = NVMEM_DEVID_NONE,
+ .owner = THIS_MODULE,
+ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+ .root_only = true,
+ .reg_read = rcar_fuse_reg_read,
+ .word_size = 4,
+ .stride = 4,
+ };
+ struct rcar_fuse *fuse;
+ struct resource *res;
+ int ret;
+
+ ret = devm_pm_runtime_enable(dev);
+ if (ret < 0)
+ return ret;
+
+ fuse = devm_kzalloc(dev, sizeof(*fuse), GFP_KERNEL);
+ if (!fuse)
+ return -ENOMEM;
+
+ fuse->base = devm_platform_get_and_ioremap_resource(pdev, data->bank,
+ &res);
+ if (IS_ERR(fuse->base))
+ return PTR_ERR(fuse->base);
+
+ fuse->dev = dev;
+ fuse->keepouts[0].start = 0;
+ fuse->keepouts[0].end = data->start;
+ fuse->keepouts[1].start = data->end;
+ fuse->keepouts[1].end = resource_size(res);
+
+ config.keepout = fuse->keepouts;
+ config.nkeepout = ARRAY_SIZE(fuse->keepouts);
+ config.size = resource_size(res);
+ config.priv = fuse;
+
+ fuse->nvmem = devm_nvmem_register(dev, &config);
+ if (IS_ERR(fuse->nvmem))
+ return dev_err_probe(dev, PTR_ERR(fuse->nvmem),
+ "Failed to register NVMEM device\n");
+
+ return 0;
+}
+
+static const struct rcar_fuse_data rcar_fuse_v3u = {
+ .bank = 0,
+ .start = 0x0c0,
+ .end = 0x0e8,
+};
+
+static const struct rcar_fuse_data rcar_fuse_s4 = {
+ .bank = 0,
+ .start = 0x0c0,
+ .end = 0x14c,
+};
+
+static const struct rcar_fuse_data rcar_fuse_v4h = {
+ .bank = 1,
+ .start = 0x100,
+ .end = 0x1a0,
+};
+
+static const struct rcar_fuse_data rcar_fuse_v4m = {
+ .bank = 1,
+ .start = 0x100,
+ .end = 0x110,
+};
+
+static const struct of_device_id rcar_fuse_match[] = {
+ { .compatible = "renesas,r8a779a0-efuse", .data = &rcar_fuse_v3u },
+ { .compatible = "renesas,r8a779f0-efuse", .data = &rcar_fuse_s4 },
+ { .compatible = "renesas,r8a779g0-otp", .data = &rcar_fuse_v4h },
+ { .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m },
+ { /* sentinel */ }
+};
+
+static struct platform_driver rcar_fuse_driver = {
+ .probe = rcar_fuse_probe,
+ .driver = {
+ .name = "rcar_fuse",
+ .of_match_table = rcar_fuse_match,
+ },
+};
+module_platform_driver(rcar_fuse_driver);
+
+MODULE_DESCRIPTION("Renesas R-Car E-FUSE/OTP driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Geert Uytterhoeven");