summaryrefslogtreecommitdiff
path: root/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch')
-rw-r--r--target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch267
1 files changed, 0 insertions, 267 deletions
diff --git a/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch b/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch
deleted file mode 100644
index a0f8c4715e..0000000000
--- a/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-From fd3bb8f54a88107570334c156efb0c724a261003 Mon Sep 17 00:00:00 2001
-From: Evan Green <evgreen@chromium.org>
-Date: Fri, 27 Nov 2020 10:28:34 +0000
-Subject: [PATCH] nvmem: core: Add support for keepout regions
-
-Introduce support into the nvmem core for arrays of register ranges
-that should not result in actual device access. For these regions a
-constant byte (repeated) is returned instead on read, and writes are
-quietly ignored and returned as successful.
-
-This is useful for instance if certain efuse regions are protected
-from access by Linux because they contain secret info to another part
-of the system (like an integrated modem).
-
-Signed-off-by: Evan Green <evgreen@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20201127102837.19366-3-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c | 153 ++++++++++++++++++++++++++++++++-
- include/linux/nvmem-provider.h | 17 ++++
- 2 files changed, 166 insertions(+), 4 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -34,6 +34,8 @@ struct nvmem_device {
- struct bin_attribute eeprom;
- struct device *base_dev;
- struct list_head cells;
-+ const struct nvmem_keepout *keepout;
-+ unsigned int nkeepout;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
- struct gpio_desc *wp_gpio;
-@@ -66,8 +68,8 @@ static LIST_HEAD(nvmem_lookup_list);
-
- static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
-
--static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
-- void *val, size_t bytes)
-+static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
-+ void *val, size_t bytes)
- {
- if (nvmem->reg_read)
- return nvmem->reg_read(nvmem->priv, offset, val, bytes);
-@@ -75,8 +77,8 @@ static int nvmem_reg_read(struct nvmem_d
- return -EINVAL;
- }
-
--static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
-- void *val, size_t bytes)
-+static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
-+ void *val, size_t bytes)
- {
- int ret;
-
-@@ -90,6 +92,88 @@ static int nvmem_reg_write(struct nvmem_
- return -EINVAL;
- }
-
-+static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
-+ unsigned int offset, void *val,
-+ size_t bytes, int write)
-+{
-+
-+ unsigned int end = offset + bytes;
-+ unsigned int kend, ksize;
-+ const struct nvmem_keepout *keepout = nvmem->keepout;
-+ const struct nvmem_keepout *keepoutend = keepout + nvmem->nkeepout;
-+ int rc;
-+
-+ /*
-+ * Skip all keepouts before the range being accessed.
-+ * Keepouts are sorted.
-+ */
-+ while ((keepout < keepoutend) && (keepout->end <= offset))
-+ keepout++;
-+
-+ while ((offset < end) && (keepout < keepoutend)) {
-+ /* Access the valid portion before the keepout. */
-+ if (offset < keepout->start) {
-+ kend = min(end, keepout->start);
-+ ksize = kend - offset;
-+ if (write)
-+ rc = __nvmem_reg_write(nvmem, offset, val, ksize);
-+ else
-+ rc = __nvmem_reg_read(nvmem, offset, val, ksize);
-+
-+ if (rc)
-+ return rc;
-+
-+ offset += ksize;
-+ val += ksize;
-+ }
-+
-+ /*
-+ * Now we're aligned to the start of this keepout zone. Go
-+ * through it.
-+ */
-+ kend = min(end, keepout->end);
-+ ksize = kend - offset;
-+ if (!write)
-+ memset(val, keepout->value, ksize);
-+
-+ val += ksize;
-+ offset += ksize;
-+ keepout++;
-+ }
-+
-+ /*
-+ * If we ran out of keepouts but there's still stuff to do, send it
-+ * down directly
-+ */
-+ if (offset < end) {
-+ ksize = end - offset;
-+ if (write)
-+ return __nvmem_reg_write(nvmem, offset, val, ksize);
-+ else
-+ return __nvmem_reg_read(nvmem, offset, val, ksize);
-+ }
-+
-+ return 0;
-+}
-+
-+static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ if (!nvmem->nkeepout)
-+ return __nvmem_reg_read(nvmem, offset, val, bytes);
-+
-+ return nvmem_access_with_keepouts(nvmem, offset, val, bytes, false);
-+}
-+
-+static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
-+ void *val, size_t bytes)
-+{
-+ if (!nvmem->nkeepout)
-+ return __nvmem_reg_write(nvmem, offset, val, bytes);
-+
-+ return nvmem_access_with_keepouts(nvmem, offset, val, bytes, true);
-+}
-+
- #ifdef CONFIG_NVMEM_SYSFS
- static const char * const nvmem_type_str[] = {
- [NVMEM_TYPE_UNKNOWN] = "Unknown",
-@@ -535,6 +619,59 @@ nvmem_find_cell_by_name(struct nvmem_dev
- return cell;
- }
-
-+static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
-+{
-+ unsigned int cur = 0;
-+ const struct nvmem_keepout *keepout = nvmem->keepout;
-+ const struct nvmem_keepout *keepoutend = keepout + nvmem->nkeepout;
-+
-+ while (keepout < keepoutend) {
-+ /* Ensure keepouts are sorted and don't overlap. */
-+ if (keepout->start < cur) {
-+ dev_err(&nvmem->dev,
-+ "Keepout regions aren't sorted or overlap.\n");
-+
-+ return -ERANGE;
-+ }
-+
-+ if (keepout->end < keepout->start) {
-+ dev_err(&nvmem->dev,
-+ "Invalid keepout region.\n");
-+
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ * Validate keepouts (and holes between) don't violate
-+ * word_size constraints.
-+ */
-+ if ((keepout->end - keepout->start < nvmem->word_size) ||
-+ ((keepout->start != cur) &&
-+ (keepout->start - cur < nvmem->word_size))) {
-+
-+ dev_err(&nvmem->dev,
-+ "Keepout regions violate word_size constraints.\n");
-+
-+ return -ERANGE;
-+ }
-+
-+ /* Validate keepouts don't violate stride (alignment). */
-+ if (!IS_ALIGNED(keepout->start, nvmem->stride) ||
-+ !IS_ALIGNED(keepout->end, nvmem->stride)) {
-+
-+ dev_err(&nvmem->dev,
-+ "Keepout regions violate stride.\n");
-+
-+ return -EINVAL;
-+ }
-+
-+ cur = keepout->end;
-+ keepout++;
-+ }
-+
-+ return 0;
-+}
-+
- static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
- {
- struct device_node *parent, *child;
-@@ -656,6 +793,8 @@ struct nvmem_device *nvmem_register(cons
- nvmem->type = config->type;
- nvmem->reg_read = config->reg_read;
- nvmem->reg_write = config->reg_write;
-+ nvmem->keepout = config->keepout;
-+ nvmem->nkeepout = config->nkeepout;
- if (!config->no_of_node)
- nvmem->dev.of_node = config->dev->of_node;
-
-@@ -703,6 +842,12 @@ struct nvmem_device *nvmem_register(cons
- if (rval)
- goto err_remove_cells;
-
-+ if (nvmem->nkeepout) {
-+ rval = nvmem_validate_keepouts(nvmem);
-+ if (rval)
-+ goto err_put_device;
-+ }
-+
- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-
- rval = device_add(&nvmem->dev);
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -31,6 +31,19 @@ enum nvmem_type {
- #define NVMEM_DEVID_AUTO (-2)
-
- /**
-+ * struct nvmem_keepout - NVMEM register keepout range.
-+ *
-+ * @start: The first byte offset to avoid.
-+ * @end: One beyond the last byte offset to avoid.
-+ * @value: The byte to fill reads with for this region.
-+ */
-+struct nvmem_keepout {
-+ unsigned int start;
-+ unsigned int end;
-+ unsigned char value;
-+};
-+
-+/**
- * struct nvmem_config - NVMEM device configuration
- *
- * @dev: Parent device.
-@@ -39,6 +52,8 @@ enum nvmem_type {
- * @owner: Pointer to exporter module. Used for refcounting.
- * @cells: Optional array of pre-defined NVMEM cells.
- * @ncells: Number of elements in cells.
-+ * @keepout: Optional array of keepout ranges (sorted ascending by start).
-+ * @nkeepout: Number of elements in the keepout array.
- * @type: Type of the nvmem storage
- * @read_only: Device is read-only.
- * @root_only: Device is accessibly to root only.
-@@ -65,6 +80,8 @@ struct nvmem_config {
- struct module *owner;
- const struct nvmem_cell_info *cells;
- int ncells;
-+ const struct nvmem_keepout *keepout;
-+ unsigned int nkeepout;
- enum nvmem_type type;
- bool read_only;
- bool root_only;