mirror of
https://github.com/openwrt/openwrt.git
synced 2025-03-24 21:15:29 +00:00
kernel: 5.10: update nvmem subsystem to the 5.15 state
This allows cleanly backporting more recent stuff that's important for OpenWrt. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
2621ddb0be
commit
457cc59795
@ -0,0 +1,267 @@
|
||||
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;
|
||||
@@ -655,6 +792,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;
|
||||
|
||||
@@ -679,6 +818,12 @@ struct nvmem_device *nvmem_register(cons
|
||||
nvmem->dev.groups = nvmem_dev_groups;
|
||||
#endif
|
||||
|
||||
+ 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_register(&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.
|
||||
@@ -66,6 +81,8 @@ struct nvmem_config {
|
||||
struct gpio_desc *wp_gpio;
|
||||
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;
|
@ -0,0 +1,87 @@
|
||||
From 044ee8f85267599a9b0112911f5c16d4548b4289 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Green <evgreen@chromium.org>
|
||||
Date: Fri, 27 Nov 2020 10:28:36 +0000
|
||||
Subject: [PATCH] nvmem: qfprom: Don't touch certain fuses
|
||||
|
||||
Some fuse ranges are protected by the XPU such that the AP cannot
|
||||
access them. Attempting to do so causes an SError. Use the newly
|
||||
introduced per-soc compatible string, and the newly introduced
|
||||
nvmem keepout support to attach the set of regions
|
||||
we should not access.
|
||||
|
||||
Reviewed-by: Douglas Anderson <dianders@chromium.org>
|
||||
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-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qfprom.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/qfprom.c
|
||||
+++ b/drivers/nvmem/qfprom.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
/* Blow timer clock frequency in Mhz */
|
||||
@@ -89,6 +90,28 @@ struct qfprom_touched_values {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * struct qfprom_soc_compatible_data - Data matched against the SoC
|
||||
+ * compatible string.
|
||||
+ *
|
||||
+ * @keepout: Array of keepout regions for this SoC.
|
||||
+ * @nkeepout: Number of elements in the keepout array.
|
||||
+ */
|
||||
+struct qfprom_soc_compatible_data {
|
||||
+ const struct nvmem_keepout *keepout;
|
||||
+ unsigned int nkeepout;
|
||||
+};
|
||||
+
|
||||
+static const struct nvmem_keepout sc7180_qfprom_keepout[] = {
|
||||
+ {.start = 0x128, .end = 0x148},
|
||||
+ {.start = 0x220, .end = 0x228}
|
||||
+};
|
||||
+
|
||||
+static const struct qfprom_soc_compatible_data sc7180_qfprom = {
|
||||
+ .keepout = sc7180_qfprom_keepout,
|
||||
+ .nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
|
||||
* @priv: Our driver data.
|
||||
* @old: The data that was stashed from before fuse blowing.
|
||||
@@ -302,6 +325,7 @@ static int qfprom_probe(struct platform_
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct nvmem_device *nvmem;
|
||||
+ const struct qfprom_soc_compatible_data *soc_data;
|
||||
struct qfprom_priv *priv;
|
||||
int ret;
|
||||
|
||||
@@ -320,6 +344,11 @@ static int qfprom_probe(struct platform_
|
||||
econfig.priv = priv;
|
||||
|
||||
priv->dev = dev;
|
||||
+ soc_data = device_get_match_data(dev);
|
||||
+ if (soc_data) {
|
||||
+ econfig.keepout = soc_data->keepout;
|
||||
+ econfig.nkeepout = soc_data->nkeepout;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If more than one region is provided then the OS has the ability
|
||||
@@ -375,6 +404,7 @@ static int qfprom_probe(struct platform_
|
||||
|
||||
static const struct of_device_id qfprom_of_match[] = {
|
||||
{ .compatible = "qcom,qfprom",},
|
||||
+ { .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
|
||||
{/* sentinel */},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qfprom_of_match);
|
@ -0,0 +1,105 @@
|
||||
From 3311bf18467272388039922a5e29c4925b291f73 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Fan <peng.fan@nxp.com>
|
||||
Date: Fri, 27 Nov 2020 10:28:37 +0000
|
||||
Subject: [PATCH] nvmem: imx-ocotp: add support for the unaliged word count
|
||||
|
||||
When offset is not 4 bytes aligned, directly shift righty by 2 bits
|
||||
will cause reading out wrong data. Since imx ocotp only supports
|
||||
4 bytes reading once, we need handle offset is not 4 bytes aligned
|
||||
and enlarge the bytes to 4 bytes aligned. After reading finished,
|
||||
copy the needed data from buffer to caller and free buffer.
|
||||
|
||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20201127102837.19366-6-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/imx-ocotp.c | 30 ++++++++++++++++++++++++------
|
||||
1 file changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp.c
|
||||
+++ b/drivers/nvmem/imx-ocotp.c
|
||||
@@ -4,6 +4,8 @@
|
||||
*
|
||||
* Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
|
||||
*
|
||||
+ * Copyright 2019 NXP
|
||||
+ *
|
||||
* Based on the barebox ocotp driver,
|
||||
* Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
|
||||
* Orex Computed Radiography
|
||||
@@ -158,22 +160,30 @@ static int imx_ocotp_read(void *context,
|
||||
{
|
||||
struct ocotp_priv *priv = context;
|
||||
unsigned int count;
|
||||
- u32 *buf = val;
|
||||
+ u8 *buf, *p;
|
||||
int i, ret;
|
||||
- u32 index;
|
||||
+ u32 index, num_bytes;
|
||||
|
||||
index = offset >> 2;
|
||||
- count = bytes >> 2;
|
||||
+ num_bytes = round_up((offset % 4) + bytes, 4);
|
||||
+ count = num_bytes >> 2;
|
||||
|
||||
if (count > (priv->params->nregs - index))
|
||||
count = priv->params->nregs - index;
|
||||
|
||||
+ p = kzalloc(num_bytes, GFP_KERNEL);
|
||||
+ if (!p)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
mutex_lock(&ocotp_mutex);
|
||||
|
||||
+ buf = p;
|
||||
+
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&ocotp_mutex);
|
||||
dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
|
||||
+ kfree(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -184,7 +194,7 @@ static int imx_ocotp_read(void *context,
|
||||
}
|
||||
|
||||
for (i = index; i < (index + count); i++) {
|
||||
- *buf++ = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
|
||||
+ *(u32 *)buf = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
|
||||
i * IMX_OCOTP_OFFSET_PER_WORD);
|
||||
|
||||
/* 47.3.1.2
|
||||
@@ -193,13 +203,21 @@ static int imx_ocotp_read(void *context,
|
||||
* software before any new write, read or reload access can be
|
||||
* issued
|
||||
*/
|
||||
- if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL)
|
||||
+ if (*((u32 *)buf) == IMX_OCOTP_READ_LOCKED_VAL)
|
||||
imx_ocotp_clr_err_if_set(priv);
|
||||
+
|
||||
+ buf += 4;
|
||||
}
|
||||
|
||||
+ index = offset % 4;
|
||||
+ memcpy(val, &p[index], bytes);
|
||||
+
|
||||
read_end:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
mutex_unlock(&ocotp_mutex);
|
||||
+
|
||||
+ kfree(p);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -447,7 +465,7 @@ static struct nvmem_config imx_ocotp_nvm
|
||||
.name = "imx-ocotp",
|
||||
.read_only = false,
|
||||
.word_size = 4,
|
||||
- .stride = 4,
|
||||
+ .stride = 1,
|
||||
.reg_read = imx_ocotp_read,
|
||||
.reg_write = imx_ocotp_write,
|
||||
};
|
@ -0,0 +1,41 @@
|
||||
From 579db09c6106977c0496f2cca48606b289df4bdf Mon Sep 17 00:00:00 2001
|
||||
From: Fabio Estevam <festevam@gmail.com>
|
||||
Date: Fri, 29 Jan 2021 17:14:27 +0000
|
||||
Subject: [PATCH] nvmem: imx-iim: Use of_device_get_match_data()
|
||||
|
||||
The retrieval of driver data via of_device_get_match_data() can make
|
||||
the code simpler.
|
||||
|
||||
Use of_device_get_match_data() to simplify the code.
|
||||
|
||||
Signed-off-by: Fabio Estevam <festevam@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210129171430.11328-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/imx-iim.c | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/imx-iim.c
|
||||
+++ b/drivers/nvmem/imx-iim.c
|
||||
@@ -96,7 +96,6 @@ MODULE_DEVICE_TABLE(of, imx_iim_dt_ids);
|
||||
|
||||
static int imx_iim_probe(struct platform_device *pdev)
|
||||
{
|
||||
- const struct of_device_id *of_id;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct iim_priv *iim;
|
||||
struct nvmem_device *nvmem;
|
||||
@@ -111,11 +110,7 @@ static int imx_iim_probe(struct platform
|
||||
if (IS_ERR(iim->base))
|
||||
return PTR_ERR(iim->base);
|
||||
|
||||
- of_id = of_match_device(imx_iim_dt_ids, dev);
|
||||
- if (!of_id)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- drvdata = of_id->data;
|
||||
+ drvdata = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
iim->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(iim->clk))
|
@ -0,0 +1,160 @@
|
||||
From 5a3fa75a4d9cb6bcfc9081ef224a4cdcd4b3eafe Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
Date: Fri, 29 Jan 2021 17:14:29 +0000
|
||||
Subject: [PATCH] nvmem: Add driver to expose reserved memory as nvmem
|
||||
|
||||
Firmware/co-processors might use reserved memory areas in order to pass
|
||||
data stemming from an nvmem device otherwise non accessible to Linux.
|
||||
For example an EEPROM memory only physically accessible to firmware, or
|
||||
data only accessible early at boot time.
|
||||
|
||||
In order to expose this data to other drivers and user-space, the driver
|
||||
models the reserved memory area as an nvmem device.
|
||||
|
||||
Tested-by: Tim Gover <tim.gover@raspberrypi.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210129171430.11328-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 8 ++++
|
||||
drivers/nvmem/Makefile | 2 +
|
||||
drivers/nvmem/rmem.c | 97 ++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/of/platform.c | 1 +
|
||||
4 files changed, 108 insertions(+)
|
||||
create mode 100644 drivers/nvmem/rmem.c
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -270,4 +270,12 @@ config SPRD_EFUSE
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called nvmem-sprd-efuse.
|
||||
|
||||
+config NVMEM_RMEM
|
||||
+ tristate "Reserved Memory Based Driver Support"
|
||||
+ help
|
||||
+ This drivers maps reserved memory into an nvmem device. It might be
|
||||
+ useful to expose information left by firmware in memory.
|
||||
+
|
||||
+ This driver can also be built as a module. If so, the module
|
||||
+ will be called nvmem-rmem.
|
||||
endif
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -55,3 +55,5 @@ obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynq
|
||||
nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
|
||||
obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_efuse.o
|
||||
nvmem_sprd_efuse-y := sprd-efuse.o
|
||||
+obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
|
||||
+nvmem-rmem-y := rmem.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/rmem.c
|
||||
@@ -0,0 +1,97 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/nvmem-provider.h>
|
||||
+#include <linux/of_reserved_mem.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+struct rmem {
|
||||
+ struct device *dev;
|
||||
+ struct nvmem_device *nvmem;
|
||||
+ struct reserved_mem *mem;
|
||||
+
|
||||
+ phys_addr_t size;
|
||||
+};
|
||||
+
|
||||
+static int rmem_read(void *context, unsigned int offset,
|
||||
+ void *val, size_t bytes)
|
||||
+{
|
||||
+ struct rmem *priv = context;
|
||||
+ size_t available = priv->mem->size;
|
||||
+ loff_t off = offset;
|
||||
+ void *addr;
|
||||
+ int count;
|
||||
+
|
||||
+ /*
|
||||
+ * Only map the reserved memory at this point to avoid potential rogue
|
||||
+ * kernel threads inadvertently modifying it. Based on the current
|
||||
+ * uses-cases for this driver, the performance hit isn't a concern.
|
||||
+ * Nor is likely to be, given the nature of the subsystem. Most nvmem
|
||||
+ * devices operate over slow buses to begin with.
|
||||
+ *
|
||||
+ * An alternative would be setting the memory as RO, set_memory_ro(),
|
||||
+ * but as of Dec 2020 this isn't possible on arm64.
|
||||
+ */
|
||||
+ addr = memremap(priv->mem->base, available, MEMREMAP_WB);
|
||||
+ if (IS_ERR(addr)) {
|
||||
+ dev_err(priv->dev, "Failed to remap memory region\n");
|
||||
+ return PTR_ERR(addr);
|
||||
+ }
|
||||
+
|
||||
+ count = memory_read_from_buffer(val, bytes, &off, addr, available);
|
||||
+
|
||||
+ memunmap(addr);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static int rmem_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct nvmem_config config = { };
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct reserved_mem *mem;
|
||||
+ struct rmem *priv;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+ priv->dev = dev;
|
||||
+
|
||||
+ mem = of_reserved_mem_lookup(dev->of_node);
|
||||
+ if (!mem) {
|
||||
+ dev_err(dev, "Failed to lookup reserved memory\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ priv->mem = mem;
|
||||
+
|
||||
+ config.dev = dev;
|
||||
+ config.priv = priv;
|
||||
+ config.name = "rmem";
|
||||
+ config.size = mem->size;
|
||||
+ config.reg_read = rmem_read;
|
||||
+
|
||||
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id rmem_match[] = {
|
||||
+ { .compatible = "nvmem-rmem", },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rmem_match);
|
||||
+
|
||||
+static struct platform_driver rmem_driver = {
|
||||
+ .probe = rmem_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rmem",
|
||||
+ .of_match_table = rmem_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(rmem_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
|
||||
+MODULE_DESCRIPTION("Reserved Memory Based nvmem Driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/of/platform.c
|
||||
+++ b/drivers/of/platform.c
|
||||
@@ -511,6 +511,7 @@ static const struct of_device_id reserve
|
||||
{ .compatible = "qcom,rmtfs-mem" },
|
||||
{ .compatible = "qcom,cmd-db" },
|
||||
{ .compatible = "ramoops" },
|
||||
+ { .compatible = "nvmem-rmem" },
|
||||
{}
|
||||
};
|
||||
|
@ -0,0 +1,28 @@
|
||||
From b31f1eb41c140d7979f855df73064b3a3ae8055a Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
Date: Fri, 5 Feb 2021 10:08:52 +0000
|
||||
Subject: [PATCH] nvmem: Kconfig: Correct typo in NVMEM_RMEM
|
||||
|
||||
s/drivers/driver/ as the configuration selects a single driver.
|
||||
|
||||
Suggested-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Acked-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210205100853.32372-2-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -273,7 +273,7 @@ config SPRD_EFUSE
|
||||
config NVMEM_RMEM
|
||||
tristate "Reserved Memory Based Driver Support"
|
||||
help
|
||||
- This drivers maps reserved memory into an nvmem device. It might be
|
||||
+ This driver maps reserved memory into an nvmem device. It might be
|
||||
useful to expose information left by firmware in memory.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
@ -0,0 +1,39 @@
|
||||
From e050f160d4832ce5227fb6ca934969cec0fc48be Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Yongjun <zhengyongjun3@huawei.com>
|
||||
Date: Tue, 30 Mar 2021 12:12:33 +0100
|
||||
Subject: [PATCH] nvmem: convert comma to semicolon
|
||||
|
||||
Replace a comma between expression statements by a semicolon.
|
||||
|
||||
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qcom-spmi-sdam.c | 2 +-
|
||||
drivers/nvmem/snvs_lpgpr.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qcom-spmi-sdam.c
|
||||
+++ b/drivers/nvmem/qcom-spmi-sdam.c
|
||||
@@ -141,7 +141,7 @@ static int sdam_probe(struct platform_de
|
||||
sdam->sdam_config.dev = &pdev->dev;
|
||||
sdam->sdam_config.name = "spmi_sdam";
|
||||
sdam->sdam_config.id = NVMEM_DEVID_AUTO;
|
||||
- sdam->sdam_config.owner = THIS_MODULE,
|
||||
+ sdam->sdam_config.owner = THIS_MODULE;
|
||||
sdam->sdam_config.stride = 1;
|
||||
sdam->sdam_config.word_size = 1;
|
||||
sdam->sdam_config.reg_read = sdam_read;
|
||||
--- a/drivers/nvmem/snvs_lpgpr.c
|
||||
+++ b/drivers/nvmem/snvs_lpgpr.c
|
||||
@@ -123,7 +123,7 @@ static int snvs_lpgpr_probe(struct platf
|
||||
cfg->dev = dev;
|
||||
cfg->stride = 4;
|
||||
cfg->word_size = 4;
|
||||
- cfg->size = dcfg->size,
|
||||
+ cfg->size = dcfg->size;
|
||||
cfg->owner = THIS_MODULE;
|
||||
cfg->reg_read = snvs_lpgpr_read;
|
||||
cfg->reg_write = snvs_lpgpr_write;
|
@ -1,6 +1,6 @@
|
||||
From b152bbeb0282bfcf6f91d0d5befd7582c1c3fc23 Mon Sep 17 00:00:00 2001
|
||||
From 3fef9ed0627af30753a2404b8bd59d92cdb4c0ce Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 5 Mar 2021 19:32:36 +0100
|
||||
Date: Tue, 30 Mar 2021 12:12:36 +0100
|
||||
Subject: [PATCH] nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -10,6 +10,8 @@ This driver provides access to Broadcom's NVRAM.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-6-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 9 +++++
|
||||
drivers/nvmem/Makefile | 2 +
|
||||
@ -19,10 +21,10 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -283,4 +283,13 @@ config NVMEM_U_BOOT_ENV
|
||||
|
||||
If compiled as module it will be called nvmem_u-boot-env.
|
||||
@@ -278,4 +278,13 @@ config NVMEM_RMEM
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called nvmem-rmem.
|
||||
+
|
||||
+config NVMEM_BRCM_NVRAM
|
||||
+ tristate "Broadcom's NVRAM support"
|
||||
@ -37,8 +39,8 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -57,3 +57,5 @@ obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_e
|
||||
nvmem_sprd_efuse-y := sprd-efuse.o
|
||||
obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
|
||||
nvmem_u-boot-env-y := u-boot-env.o
|
||||
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
|
||||
--- /dev/null
|
@ -0,0 +1,174 @@
|
||||
From a28e824fb8270eda43fd0f65c2a5fdf33f55c5eb Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Anderson <dianders@chromium.org>
|
||||
Date: Tue, 30 Mar 2021 12:12:37 +0100
|
||||
Subject: [PATCH] nvmem: core: Add functions to make number reading easy
|
||||
|
||||
Sometimes the clients of nvmem just want to get a number out of
|
||||
nvmem. They don't want to think about exactly how many bytes the nvmem
|
||||
cell took up. They just want the number. Let's make it easy.
|
||||
|
||||
In general this concept is useful because nvmem space is precious and
|
||||
usually the fewest bits are allocated that will hold a given value on
|
||||
a given system. However, even though small numbers might be fine on
|
||||
one system that doesn't mean that logically the number couldn't be
|
||||
bigger. Imagine nvmem containing a max frequency for a component. On
|
||||
one system perhaps that fits in 16 bits. On another system it might
|
||||
fit in 32 bits. The code reading this number doesn't care--it just
|
||||
wants the number.
|
||||
|
||||
We'll provide two functions: nvmem_cell_read_variable_le_u32() and
|
||||
nvmem_cell_read_variable_le_u64().
|
||||
|
||||
Comparing these to the existing functions like nvmem_cell_read_u32():
|
||||
* These new functions have no problems if the value was stored in
|
||||
nvmem in fewer bytes. It's OK to use these function as long as the
|
||||
value stored will fit in 32-bits (or 64-bits).
|
||||
* These functions avoid problems that the earlier APIs had with bit
|
||||
offsets. For instance, you can't use nvmem_cell_read_u32() to read a
|
||||
value has nbits=32 and bit_offset=4 because the nvmem cell must be
|
||||
at least 5 bytes big to hold this value. The new API accounts for
|
||||
this and works fine.
|
||||
* These functions make it very explicit that they assume that the
|
||||
number was stored in little endian format. The old functions made
|
||||
this assumption whenever bit_offset was non-zero (see
|
||||
nvmem_shift_read_buffer_in_place()) but didn't whenever the
|
||||
bit_offset was zero.
|
||||
|
||||
NOTE: it's assumed that we don't need an 8-bit or 16-bit version of
|
||||
this function. The 32-bit version of the function can be used to read
|
||||
8-bit or 16-bit data.
|
||||
|
||||
At the moment, I'm only adding the "unsigned" versions of these
|
||||
functions, but if it ends up being useful someone could add a "signed"
|
||||
version that did 2's complement sign extension.
|
||||
|
||||
At the moment, I'm only adding the "little endian" versions of these
|
||||
functions. Adding the "big endian" version would require adding "big
|
||||
endian" support to nvmem_shift_read_buffer_in_place().
|
||||
|
||||
Signed-off-by: Douglas Anderson <dianders@chromium.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-7-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 95 ++++++++++++++++++++++++++++++++++
|
||||
include/linux/nvmem-consumer.h | 4 ++
|
||||
2 files changed, 99 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -1612,6 +1612,101 @@ int nvmem_cell_read_u64(struct device *d
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
|
||||
|
||||
+static void *nvmem_cell_read_variable_common(struct device *dev,
|
||||
+ const char *cell_id,
|
||||
+ size_t max_len, size_t *len)
|
||||
+{
|
||||
+ struct nvmem_cell *cell;
|
||||
+ int nbits;
|
||||
+ void *buf;
|
||||
+
|
||||
+ cell = nvmem_cell_get(dev, cell_id);
|
||||
+ if (IS_ERR(cell))
|
||||
+ return cell;
|
||||
+
|
||||
+ nbits = cell->nbits;
|
||||
+ buf = nvmem_cell_read(cell, len);
|
||||
+ nvmem_cell_put(cell);
|
||||
+ if (IS_ERR(buf))
|
||||
+ return buf;
|
||||
+
|
||||
+ /*
|
||||
+ * If nbits is set then nvmem_cell_read() can significantly exaggerate
|
||||
+ * the length of the real data. Throw away the extra junk.
|
||||
+ */
|
||||
+ if (nbits)
|
||||
+ *len = DIV_ROUND_UP(nbits, 8);
|
||||
+
|
||||
+ if (*len > max_len) {
|
||||
+ kfree(buf);
|
||||
+ return ERR_PTR(-ERANGE);
|
||||
+ }
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * nvmem_cell_read_variable_le_u32() - Read up to 32-bits of data as a little endian number.
|
||||
+ *
|
||||
+ * @dev: Device that requests the nvmem cell.
|
||||
+ * @cell_id: Name of nvmem cell to read.
|
||||
+ * @val: pointer to output value.
|
||||
+ *
|
||||
+ * Return: 0 on success or negative errno.
|
||||
+ */
|
||||
+int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
|
||||
+ u32 *val)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ u8 *buf;
|
||||
+ int i;
|
||||
+
|
||||
+ buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
|
||||
+ if (IS_ERR(buf))
|
||||
+ return PTR_ERR(buf);
|
||||
+
|
||||
+ /* Copy w/ implicit endian conversion */
|
||||
+ *val = 0;
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ *val |= buf[i] << (8 * i);
|
||||
+
|
||||
+ kfree(buf);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u32);
|
||||
+
|
||||
+/**
|
||||
+ * nvmem_cell_read_variable_le_u64() - Read up to 64-bits of data as a little endian number.
|
||||
+ *
|
||||
+ * @dev: Device that requests the nvmem cell.
|
||||
+ * @cell_id: Name of nvmem cell to read.
|
||||
+ * @val: pointer to output value.
|
||||
+ *
|
||||
+ * Return: 0 on success or negative errno.
|
||||
+ */
|
||||
+int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
|
||||
+ u64 *val)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ u8 *buf;
|
||||
+ int i;
|
||||
+
|
||||
+ buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
|
||||
+ if (IS_ERR(buf))
|
||||
+ return PTR_ERR(buf);
|
||||
+
|
||||
+ /* Copy w/ implicit endian conversion */
|
||||
+ *val = 0;
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ *val |= buf[i] << (8 * i);
|
||||
+
|
||||
+ kfree(buf);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u64);
|
||||
+
|
||||
/**
|
||||
* nvmem_device_cell_read() - Read a given nvmem device and cell
|
||||
*
|
||||
--- a/include/linux/nvmem-consumer.h
|
||||
+++ b/include/linux/nvmem-consumer.h
|
||||
@@ -65,6 +65,10 @@ int nvmem_cell_read_u8(struct device *de
|
||||
int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val);
|
||||
int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val);
|
||||
int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val);
|
||||
+int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
|
||||
+ u32 *val);
|
||||
+int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
|
||||
+ u64 *val);
|
||||
|
||||
/* direct nvmem device read/write interface */
|
||||
struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
|
@ -0,0 +1,34 @@
|
||||
From 55022fdeace8e432f008787ce03703bdcc9c3ca9 Mon Sep 17 00:00:00 2001
|
||||
From: Colin Ian King <colin.king@canonical.com>
|
||||
Date: Tue, 30 Mar 2021 12:12:38 +0100
|
||||
Subject: [PATCH] nvmem: core: Fix unintentional sign extension issue
|
||||
|
||||
The shifting of the u8 integer buf[3] by 24 bits to the left will
|
||||
be promoted to a 32 bit signed int and then sign-extended to a
|
||||
u64. In the event that the top bit of buf[3] is set then all
|
||||
then all the upper 32 bits of the u64 end up as also being set
|
||||
because of the sign-extension. Fix this by casting buf[i] to
|
||||
a u64 before the shift.
|
||||
|
||||
Fixes: a28e824fb827 ("nvmem: core: Add functions to make number reading easy")
|
||||
Reviewed-by: Douglas Anderson <dianders@chromium.org>
|
||||
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Addresses-Coverity: ("Unintended sign extension")
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -1699,7 +1699,7 @@ int nvmem_cell_read_variable_le_u64(stru
|
||||
/* Copy w/ implicit endian conversion */
|
||||
*val = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
- *val |= buf[i] << (8 * i);
|
||||
+ *val |= (uint64_t)buf[i] << (8 * i);
|
||||
|
||||
kfree(buf);
|
||||
|
@ -0,0 +1,29 @@
|
||||
From cc1bc56fdc76a55bb8fae9a145a2e60bf22fb129 Mon Sep 17 00:00:00 2001
|
||||
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Date: Tue, 30 Mar 2021 12:12:39 +0100
|
||||
Subject: [PATCH] nvmem: rmem: fix undefined reference to memremap
|
||||
|
||||
Fix below error reporte by kernel test robot
|
||||
rmem.c:(.text+0x14e): undefined reference to memremap
|
||||
s390x-linux-gnu-ld: rmem.c:(.text+0x1b6): undefined reference to memunmap
|
||||
|
||||
Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem")
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-9-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -272,6 +272,7 @@ config SPRD_EFUSE
|
||||
|
||||
config NVMEM_RMEM
|
||||
tristate "Reserved Memory Based Driver Support"
|
||||
+ depends on HAS_IOMEM
|
||||
help
|
||||
This driver maps reserved memory into an nvmem device. It might be
|
||||
useful to expose information left by firmware in memory.
|
@ -0,0 +1,102 @@
|
||||
From 5a1bea2a2572ce5eb4bdcf432a6929681ee381f2 Mon Sep 17 00:00:00 2001
|
||||
From: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Date: Tue, 30 Mar 2021 12:12:41 +0100
|
||||
Subject: [PATCH] nvmem: qfprom: Add support for fuse blowing on sc7280
|
||||
|
||||
Handle the differences across LDO voltage needed for blowing fuses,
|
||||
and the blow timer value, identified using a minor version of 15
|
||||
on sc7280.
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210330111241.19401-11-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qfprom.c | 27 +++++++++++++++++++++++++--
|
||||
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qfprom.c
|
||||
+++ b/drivers/nvmem/qfprom.c
|
||||
@@ -45,11 +45,13 @@ MODULE_PARM_DESC(read_raw_data, "Read ra
|
||||
* @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
|
||||
* @qfprom_blow_set_freq: The frequency required to set when we start the
|
||||
* fuse blowing.
|
||||
+ * @qfprom_blow_uV: LDO voltage to be set when doing efuse blow
|
||||
*/
|
||||
struct qfprom_soc_data {
|
||||
u32 accel_value;
|
||||
u32 qfprom_blow_timer_value;
|
||||
u32 qfprom_blow_set_freq;
|
||||
+ int qfprom_blow_uV;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -111,6 +113,15 @@ static const struct qfprom_soc_compatibl
|
||||
.nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
|
||||
};
|
||||
|
||||
+static const struct nvmem_keepout sc7280_qfprom_keepout[] = {
|
||||
+ {.start = 0x128, .end = 0x148},
|
||||
+ {.start = 0x238, .end = 0x248}
|
||||
+};
|
||||
+
|
||||
+static const struct qfprom_soc_compatible_data sc7280_qfprom = {
|
||||
+ .keepout = sc7280_qfprom_keepout,
|
||||
+ .nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
|
||||
+};
|
||||
/**
|
||||
* qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
|
||||
* @priv: Our driver data.
|
||||
@@ -168,6 +179,7 @@ static int qfprom_enable_fuse_blowing(co
|
||||
struct qfprom_touched_values *old)
|
||||
{
|
||||
int ret;
|
||||
+ int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV;
|
||||
|
||||
ret = clk_prepare_enable(priv->secclk);
|
||||
if (ret) {
|
||||
@@ -187,9 +199,9 @@ static int qfprom_enable_fuse_blowing(co
|
||||
* a rail shared do don't specify a max--regulator constraints
|
||||
* will handle.
|
||||
*/
|
||||
- ret = regulator_set_voltage(priv->vcc, 1800000, INT_MAX);
|
||||
+ ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
|
||||
if (ret) {
|
||||
- dev_err(priv->dev, "Failed to set 1.8 voltage\n");
|
||||
+ dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV);
|
||||
goto err_clk_rate_set;
|
||||
}
|
||||
|
||||
@@ -311,6 +323,14 @@ static const struct qfprom_soc_data qfpr
|
||||
.accel_value = 0xD10,
|
||||
.qfprom_blow_timer_value = 25,
|
||||
.qfprom_blow_set_freq = 4800000,
|
||||
+ .qfprom_blow_uV = 1800000,
|
||||
+};
|
||||
+
|
||||
+static const struct qfprom_soc_data qfprom_7_15_data = {
|
||||
+ .accel_value = 0xD08,
|
||||
+ .qfprom_blow_timer_value = 24,
|
||||
+ .qfprom_blow_set_freq = 4800000,
|
||||
+ .qfprom_blow_uV = 1900000,
|
||||
};
|
||||
|
||||
static int qfprom_probe(struct platform_device *pdev)
|
||||
@@ -379,6 +399,8 @@ static int qfprom_probe(struct platform_
|
||||
|
||||
if (major_version == 7 && minor_version == 8)
|
||||
priv->soc_data = &qfprom_7_8_data;
|
||||
+ if (major_version == 7 && minor_version == 15)
|
||||
+ priv->soc_data = &qfprom_7_15_data;
|
||||
|
||||
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
|
||||
if (IS_ERR(priv->vcc))
|
||||
@@ -405,6 +427,7 @@ static int qfprom_probe(struct platform_
|
||||
static const struct of_device_id qfprom_of_match[] = {
|
||||
{ .compatible = "qcom,qfprom",},
|
||||
{ .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
|
||||
+ { .compatible = "qcom,sc7280-qfprom", .data = &sc7280_qfprom},
|
||||
{/* sentinel */},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qfprom_of_match);
|
@ -0,0 +1,80 @@
|
||||
From 1333a6779501f4cc662ff5c8b36b0a22f3a7ddc6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Sat, 24 Apr 2021 13:06:04 +0200
|
||||
Subject: [PATCH] nvmem: core: allow specifying of_node
|
||||
|
||||
Until now, the of_node of the parent device is used. Some devices
|
||||
provide more than just the nvmem provider. To avoid name space clashes,
|
||||
add a way to allow specifying the nvmem cells in subnodes. Consider the
|
||||
following example:
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
reg = <0x000000 0x010000>;
|
||||
};
|
||||
};
|
||||
|
||||
otp {
|
||||
compatible = "user-otp";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
serial-number@0 {
|
||||
reg = <0x0 0x8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
There the nvmem provider might be the MTD partition or the OTP region of
|
||||
the flash.
|
||||
|
||||
Add a new config->of_node parameter, which if set, will be used instead
|
||||
of the parent's of_node.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20210424110608.15748-2-michael@walle.cc
|
||||
---
|
||||
drivers/nvmem/core.c | 4 +++-
|
||||
include/linux/nvmem-provider.h | 2 ++
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -794,7 +794,9 @@ struct nvmem_device *nvmem_register(cons
|
||||
nvmem->reg_write = config->reg_write;
|
||||
nvmem->keepout = config->keepout;
|
||||
nvmem->nkeepout = config->nkeepout;
|
||||
- if (!config->no_of_node)
|
||||
+ if (config->of_node)
|
||||
+ nvmem->dev.of_node = config->of_node;
|
||||
+ else if (!config->no_of_node)
|
||||
nvmem->dev.of_node = config->dev->of_node;
|
||||
|
||||
switch (config->id) {
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -57,6 +57,7 @@ struct nvmem_keepout {
|
||||
* @type: Type of the nvmem storage
|
||||
* @read_only: Device is read-only.
|
||||
* @root_only: Device is accessibly to root only.
|
||||
+ * @of_node: If given, this will be used instead of the parent's of_node.
|
||||
* @no_of_node: Device should not use the parent's of_node even if it's !NULL.
|
||||
* @reg_read: Callback to read data.
|
||||
* @reg_write: Callback to write data.
|
||||
@@ -86,6 +87,7 @@ struct nvmem_config {
|
||||
enum nvmem_type type;
|
||||
bool read_only;
|
||||
bool root_only;
|
||||
+ struct device_node *of_node;
|
||||
bool no_of_node;
|
||||
nvmem_reg_read_t reg_read;
|
||||
nvmem_reg_write_t reg_write;
|
@ -0,0 +1,30 @@
|
||||
From 20be064ec864086bca7a4eb62c772a397b44afb7 Mon Sep 17 00:00:00 2001
|
||||
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||||
Date: Fri, 7 May 2021 19:02:48 +0200
|
||||
Subject: [PATCH] nvmem: sprd: Fix an error message
|
||||
|
||||
'ret' is known to be 0 here.
|
||||
The expected error status is stored in 'status', so use it instead.
|
||||
|
||||
Also change %d in %u, because status is an u32, not a int.
|
||||
|
||||
Fixes: 096030e7f449 ("nvmem: sprd: Add Spreadtrum SoCs eFuse support")
|
||||
Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
|
||||
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||||
Link: https://lore.kernel.org/r/5bc44aace2fe7e1c91d8b35c8fe31e7134ceab2c.1620406852.git.christophe.jaillet@wanadoo.fr
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/sprd-efuse.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/sprd-efuse.c
|
||||
+++ b/drivers/nvmem/sprd-efuse.c
|
||||
@@ -234,7 +234,7 @@ static int sprd_efuse_raw_prog(struct sp
|
||||
status = readl(efuse->base + SPRD_EFUSE_ERR_FLAG);
|
||||
if (status) {
|
||||
dev_err(efuse->dev,
|
||||
- "write error status %d of block %d\n", ret, blk);
|
||||
+ "write error status %u of block %d\n", status, blk);
|
||||
|
||||
writel(SPRD_EFUSE_ERR_CLR_MASK,
|
||||
efuse->base + SPRD_EFUSE_ERR_CLR);
|
@ -0,0 +1,27 @@
|
||||
From 78a005a22d5608b266eafa011b093a33284c52ce Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Holland <samuel@sholland.org>
|
||||
Date: Fri, 11 Jun 2021 09:33:45 +0100
|
||||
Subject: [PATCH] nvmem: sunxi_sid: Set type to OTP
|
||||
|
||||
This device currently reports an "Unknown" type in sysfs.
|
||||
Since it is an eFuse hardware device, set its type to OTP.
|
||||
|
||||
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||||
Acked-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210611083348.20170-7-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/sunxi_sid.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/nvmem/sunxi_sid.c
|
||||
+++ b/drivers/nvmem/sunxi_sid.c
|
||||
@@ -142,6 +142,7 @@ static int sunxi_sid_probe(struct platfo
|
||||
|
||||
nvmem_cfg->dev = dev;
|
||||
nvmem_cfg->name = "sunxi-sid";
|
||||
+ nvmem_cfg->type = NVMEM_TYPE_OTP;
|
||||
nvmem_cfg->read_only = true;
|
||||
nvmem_cfg->size = cfg->size;
|
||||
nvmem_cfg->word_size = 1;
|
@ -0,0 +1,46 @@
|
||||
From c813bb37bd32cb967060a2c573fae4ea518d32eb Mon Sep 17 00:00:00 2001
|
||||
From: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Date: Fri, 11 Jun 2021 09:33:46 +0100
|
||||
Subject: [PATCH] nvmem: qfprom: minor nit fixes
|
||||
|
||||
Fix a missed newline, change an 'if' to 'else if' and update
|
||||
a comment which is stale after the merge of '5a1bea2a: nvmem:
|
||||
qfprom: Add support for fuseblowing on sc7280'
|
||||
|
||||
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Reviewed-by: Douglas Anderson <dianders@chromium.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210611083348.20170-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qfprom.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qfprom.c
|
||||
+++ b/drivers/nvmem/qfprom.c
|
||||
@@ -122,6 +122,7 @@ static const struct qfprom_soc_compatibl
|
||||
.keepout = sc7280_qfprom_keepout,
|
||||
.nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
|
||||
};
|
||||
+
|
||||
/**
|
||||
* qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
|
||||
* @priv: Our driver data.
|
||||
@@ -195,7 +196,7 @@ static int qfprom_enable_fuse_blowing(co
|
||||
}
|
||||
|
||||
/*
|
||||
- * Hardware requires 1.8V min for fuse blowing; this may be
|
||||
+ * Hardware requires a min voltage for fuse blowing; this may be
|
||||
* a rail shared do don't specify a max--regulator constraints
|
||||
* will handle.
|
||||
*/
|
||||
@@ -399,7 +400,7 @@ static int qfprom_probe(struct platform_
|
||||
|
||||
if (major_version == 7 && minor_version == 8)
|
||||
priv->soc_data = &qfprom_7_8_data;
|
||||
- if (major_version == 7 && minor_version == 15)
|
||||
+ else if (major_version == 7 && minor_version == 15)
|
||||
priv->soc_data = &qfprom_7_15_data;
|
||||
|
||||
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
|
@ -0,0 +1,52 @@
|
||||
From 1f7b4d87874624f4beb25253900a25306a193b8b Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Anderson <dianders@chromium.org>
|
||||
Date: Fri, 11 Jun 2021 09:33:47 +0100
|
||||
Subject: [PATCH] nvmem: core: constify nvmem_cell_read_variable_common()
|
||||
return value
|
||||
|
||||
The caller doesn't modify the memory pointed to by the pointer so it
|
||||
can be const.
|
||||
|
||||
Suggested-by: Stephen Boyd <swboyd@chromium.org>
|
||||
Signed-off-by: Douglas Anderson <dianders@chromium.org>
|
||||
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210611083348.20170-9-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -1614,9 +1614,9 @@ int nvmem_cell_read_u64(struct device *d
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
|
||||
|
||||
-static void *nvmem_cell_read_variable_common(struct device *dev,
|
||||
- const char *cell_id,
|
||||
- size_t max_len, size_t *len)
|
||||
+static const void *nvmem_cell_read_variable_common(struct device *dev,
|
||||
+ const char *cell_id,
|
||||
+ size_t max_len, size_t *len)
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
int nbits;
|
||||
@@ -1660,7 +1660,7 @@ int nvmem_cell_read_variable_le_u32(stru
|
||||
u32 *val)
|
||||
{
|
||||
size_t len;
|
||||
- u8 *buf;
|
||||
+ const u8 *buf;
|
||||
int i;
|
||||
|
||||
buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
|
||||
@@ -1691,7 +1691,7 @@ int nvmem_cell_read_variable_le_u64(stru
|
||||
u64 *val)
|
||||
{
|
||||
size_t len;
|
||||
- u8 *buf;
|
||||
+ const u8 *buf;
|
||||
int i;
|
||||
|
||||
buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
|
@ -0,0 +1,33 @@
|
||||
From 989f77e3fdee2e8f414dd1da9b6397d8763d414e Mon Sep 17 00:00:00 2001
|
||||
From: Douglas Anderson <dianders@chromium.org>
|
||||
Date: Fri, 11 Jun 2021 09:33:48 +0100
|
||||
Subject: [PATCH] nvmem: qfprom: Improve the comment about regulator setting
|
||||
|
||||
In review feedback Joe Perches found the existing comment
|
||||
confusing. Let's use something based on the wording proposed by Joe.
|
||||
|
||||
Suggested-by: Joe Perches <joe@perches.com>
|
||||
Signed-off-by: Douglas Anderson <dianders@chromium.org>
|
||||
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210611083348.20170-10-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qfprom.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qfprom.c
|
||||
+++ b/drivers/nvmem/qfprom.c
|
||||
@@ -196,9 +196,9 @@ static int qfprom_enable_fuse_blowing(co
|
||||
}
|
||||
|
||||
/*
|
||||
- * Hardware requires a min voltage for fuse blowing; this may be
|
||||
- * a rail shared do don't specify a max--regulator constraints
|
||||
- * will handle.
|
||||
+ * Hardware requires a minimum voltage for fuse blowing.
|
||||
+ * This may be a shared rail so don't specify a maximum.
|
||||
+ * Regulator constraints will cap to the actual maximum.
|
||||
*/
|
||||
ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
|
||||
if (ret) {
|
@ -0,0 +1,36 @@
|
||||
From: Rafał Miłecki <rafal@milecki.pl>
|
||||
Subject: [PATCH] nvmem: add NVMEM_TYPE_FRAM
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -180,6 +180,7 @@ static const char * const nvmem_type_str
|
||||
[NVMEM_TYPE_EEPROM] = "EEPROM",
|
||||
[NVMEM_TYPE_OTP] = "OTP",
|
||||
[NVMEM_TYPE_BATTERY_BACKED] = "Battery backed",
|
||||
+ [NVMEM_TYPE_FRAM] = "FRAM",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
@@ -361,6 +362,9 @@ static int nvmem_sysfs_setup_compat(stru
|
||||
if (!config->base_dev)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (config->type == NVMEM_TYPE_FRAM)
|
||||
+ bin_attr_nvmem_eeprom_compat.attr.name = "fram";
|
||||
+
|
||||
nvmem->eeprom = bin_attr_nvmem_eeprom_compat;
|
||||
nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem);
|
||||
nvmem->eeprom.size = nvmem->size;
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -25,6 +25,7 @@ enum nvmem_type {
|
||||
NVMEM_TYPE_EEPROM,
|
||||
NVMEM_TYPE_OTP,
|
||||
NVMEM_TYPE_BATTERY_BACKED,
|
||||
+ NVMEM_TYPE_FRAM,
|
||||
};
|
||||
|
||||
#define NVMEM_DEVID_NONE (-1)
|
@ -0,0 +1,89 @@
|
||||
From 7b808449f572d07bee840cd9da7e2fe6a1b8f4b5 Mon Sep 17 00:00:00 2001
|
||||
From: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Date: Fri, 6 Aug 2021 09:59:46 +0100
|
||||
Subject: [PATCH] nvmem: qfprom: sc7280: Handle the additional power-domains
|
||||
vote
|
||||
|
||||
On sc7280, to reliably blow fuses, we need an additional vote
|
||||
on max performance state of 'MX' power-domain.
|
||||
Add support for power-domain performance state voting in the
|
||||
driver.
|
||||
|
||||
Reviewed-by: Douglas Anderson <dianders@chromium.org>
|
||||
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210806085947.22682-4-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qfprom.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/qfprom.c
|
||||
+++ b/drivers/nvmem/qfprom.c
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
@@ -142,6 +144,9 @@ static void qfprom_disable_fuse_blowing(
|
||||
writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
|
||||
writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
|
||||
|
||||
+ dev_pm_genpd_set_performance_state(priv->dev, 0);
|
||||
+ pm_runtime_put(priv->dev);
|
||||
+
|
||||
/*
|
||||
* This may be a shared rail and may be able to run at a lower rate
|
||||
* when we're not blowing fuses. At the moment, the regulator framework
|
||||
@@ -212,6 +217,14 @@ static int qfprom_enable_fuse_blowing(co
|
||||
goto err_clk_rate_set;
|
||||
}
|
||||
|
||||
+ ret = pm_runtime_get_sync(priv->dev);
|
||||
+ if (ret < 0) {
|
||||
+ pm_runtime_put_noidle(priv->dev);
|
||||
+ dev_err(priv->dev, "Failed to enable power-domain\n");
|
||||
+ goto err_reg_enable;
|
||||
+ }
|
||||
+ dev_pm_genpd_set_performance_state(priv->dev, INT_MAX);
|
||||
+
|
||||
old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
|
||||
old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
|
||||
writel(priv->soc_data->qfprom_blow_timer_value,
|
||||
@@ -221,6 +234,8 @@ static int qfprom_enable_fuse_blowing(co
|
||||
|
||||
return 0;
|
||||
|
||||
+err_reg_enable:
|
||||
+ regulator_disable(priv->vcc);
|
||||
err_clk_rate_set:
|
||||
clk_set_rate(priv->secclk, old->clk_rate);
|
||||
err_clk_prepared:
|
||||
@@ -320,6 +335,11 @@ static int qfprom_reg_read(void *context
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void qfprom_runtime_disable(void *data)
|
||||
+{
|
||||
+ pm_runtime_disable(data);
|
||||
+}
|
||||
+
|
||||
static const struct qfprom_soc_data qfprom_7_8_data = {
|
||||
.accel_value = 0xD10,
|
||||
.qfprom_blow_timer_value = 25,
|
||||
@@ -420,6 +440,11 @@ static int qfprom_probe(struct platform_
|
||||
econfig.reg_write = qfprom_reg_write;
|
||||
}
|
||||
|
||||
+ pm_runtime_enable(dev);
|
||||
+ ret = devm_add_action_or_reset(dev, qfprom_runtime_disable, dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
||||
|
||||
return PTR_ERR_OR_ZERO(nvmem);
|
@ -0,0 +1,36 @@
|
||||
From de0534df93474f268486c486ea7e01b44a478026 Mon Sep 17 00:00:00 2001
|
||||
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Date: Fri, 6 Aug 2021 09:59:47 +0100
|
||||
Subject: [PATCH] nvmem: core: fix error handling while validating keepout
|
||||
regions
|
||||
|
||||
Current error path on failure of validating keepout regions is calling
|
||||
put_device, eventhough the device is not even registered at that point.
|
||||
|
||||
Fix this by adding proper error handling of freeing ida and nvmem.
|
||||
|
||||
Fixes: fd3bb8f54a88 ("nvmem: core: Add support for keepout regions")
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210806085947.22682-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -826,8 +826,11 @@ struct nvmem_device *nvmem_register(cons
|
||||
|
||||
if (nvmem->nkeepout) {
|
||||
rval = nvmem_validate_keepouts(nvmem);
|
||||
- if (rval)
|
||||
- goto err_put_device;
|
||||
+ if (rval) {
|
||||
+ ida_free(&nvmem_ida, nvmem->id);
|
||||
+ kfree(nvmem);
|
||||
+ return ERR_PTR(rval);
|
||||
+ }
|
||||
}
|
||||
|
||||
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
|
@ -0,0 +1,191 @@
|
||||
From 3683b761fe3a10ad18515acd5368dd601268cfe5 Mon Sep 17 00:00:00 2001
|
||||
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
Date: Tue, 10 Aug 2021 16:30:36 +0100
|
||||
Subject: [PATCH] nvmem: nintendo-otp: Add new driver for the Wii and Wii U OTP
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This OTP is read-only and contains various keys used by the console to
|
||||
decrypt, encrypt or verify various pieces of storage.
|
||||
|
||||
Its size depends on the console, it is 128 bytes on the Wii and
|
||||
1024 bytes on the Wii U (split into eight 128 bytes banks).
|
||||
|
||||
It can be used directly by writing into one register and reading from
|
||||
the other one, without any additional synchronisation.
|
||||
|
||||
This driver was written based on reversed documentation, see:
|
||||
https://wiiubrew.org/wiki/Hardware/OTP
|
||||
|
||||
Tested-by: Jonathan Neuschäfer <j.ne@posteo.net> # on Wii
|
||||
Tested-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> # on Wii U
|
||||
Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20210810153036.1494-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 11 ++++
|
||||
drivers/nvmem/Makefile | 2 +
|
||||
drivers/nvmem/nintendo-otp.c | 124 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 137 insertions(+)
|
||||
create mode 100644 drivers/nvmem/nintendo-otp.c
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -107,6 +107,17 @@ config MTK_EFUSE
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called efuse-mtk.
|
||||
|
||||
+config NVMEM_NINTENDO_OTP
|
||||
+ tristate "Nintendo Wii and Wii U OTP Support"
|
||||
+ help
|
||||
+ This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
|
||||
+
|
||||
+ This memory contains common and per-console keys, signatures and
|
||||
+ related data required to access peripherals.
|
||||
+
|
||||
+ This driver can also be built as a module. If so, the module
|
||||
+ will be called nvmem-nintendo-otp.
|
||||
+
|
||||
config QCOM_QFPROM
|
||||
tristate "QCOM QFPROM Support"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -23,6 +23,8 @@ obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem
|
||||
nvmem_lpc18xx_otp-y := lpc18xx_otp.o
|
||||
obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o
|
||||
nvmem-mxs-ocotp-y := mxs-ocotp.o
|
||||
+obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o
|
||||
+nvmem-nintendo-otp-y := nintendo-otp.o
|
||||
obj-$(CONFIG_MTK_EFUSE) += nvmem_mtk-efuse.o
|
||||
nvmem_mtk-efuse-y := mtk-efuse.o
|
||||
obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/nintendo-otp.c
|
||||
@@ -0,0 +1,124 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Nintendo Wii and Wii U OTP driver
|
||||
+ *
|
||||
+ * This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
|
||||
+ *
|
||||
+ * This memory contains common and per-console keys, signatures and
|
||||
+ * related data required to access peripherals.
|
||||
+ *
|
||||
+ * Based on reversed documentation from https://wiiubrew.org/wiki/Hardware/OTP
|
||||
+ *
|
||||
+ * Copyright (C) 2021 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/nvmem-provider.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#define HW_OTPCMD 0
|
||||
+#define HW_OTPDATA 4
|
||||
+#define OTP_READ 0x80000000
|
||||
+#define BANK_SIZE 128
|
||||
+#define WORD_SIZE 4
|
||||
+
|
||||
+struct nintendo_otp_priv {
|
||||
+ void __iomem *regs;
|
||||
+};
|
||||
+
|
||||
+struct nintendo_otp_devtype_data {
|
||||
+ const char *name;
|
||||
+ unsigned int num_banks;
|
||||
+};
|
||||
+
|
||||
+static const struct nintendo_otp_devtype_data hollywood_otp_data = {
|
||||
+ .name = "wii-otp",
|
||||
+ .num_banks = 1,
|
||||
+};
|
||||
+
|
||||
+static const struct nintendo_otp_devtype_data latte_otp_data = {
|
||||
+ .name = "wiiu-otp",
|
||||
+ .num_banks = 8,
|
||||
+};
|
||||
+
|
||||
+static int nintendo_otp_reg_read(void *context,
|
||||
+ unsigned int reg, void *_val, size_t bytes)
|
||||
+{
|
||||
+ struct nintendo_otp_priv *priv = context;
|
||||
+ u32 *val = _val;
|
||||
+ int words = bytes / WORD_SIZE;
|
||||
+ u32 bank, addr;
|
||||
+
|
||||
+ while (words--) {
|
||||
+ bank = (reg / BANK_SIZE) << 8;
|
||||
+ addr = (reg / WORD_SIZE) % (BANK_SIZE / WORD_SIZE);
|
||||
+ iowrite32be(OTP_READ | bank | addr, priv->regs + HW_OTPCMD);
|
||||
+ *val++ = ioread32be(priv->regs + HW_OTPDATA);
|
||||
+ reg += WORD_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id nintendo_otp_of_table[] = {
|
||||
+ { .compatible = "nintendo,hollywood-otp", .data = &hollywood_otp_data },
|
||||
+ { .compatible = "nintendo,latte-otp", .data = &latte_otp_data },
|
||||
+ {/* sentinel */},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, nintendo_otp_of_table);
|
||||
+
|
||||
+static int nintendo_otp_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ const struct of_device_id *of_id =
|
||||
+ of_match_device(nintendo_otp_of_table, dev);
|
||||
+ struct resource *res;
|
||||
+ struct nvmem_device *nvmem;
|
||||
+ struct nintendo_otp_priv *priv;
|
||||
+
|
||||
+ struct nvmem_config config = {
|
||||
+ .stride = WORD_SIZE,
|
||||
+ .word_size = WORD_SIZE,
|
||||
+ .reg_read = nintendo_otp_reg_read,
|
||||
+ .read_only = true,
|
||||
+ .root_only = true,
|
||||
+ };
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ priv->regs = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(priv->regs))
|
||||
+ return PTR_ERR(priv->regs);
|
||||
+
|
||||
+ if (of_id->data) {
|
||||
+ const struct nintendo_otp_devtype_data *data = of_id->data;
|
||||
+ config.name = data->name;
|
||||
+ config.size = data->num_banks * BANK_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ config.dev = dev;
|
||||
+ config.priv = priv;
|
||||
+
|
||||
+ nvmem = devm_nvmem_register(dev, &config);
|
||||
+
|
||||
+ return PTR_ERR_OR_ZERO(nvmem);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver nintendo_otp_driver = {
|
||||
+ .probe = nintendo_otp_probe,
|
||||
+ .driver = {
|
||||
+ .name = "nintendo-otp",
|
||||
+ .of_match_table = nintendo_otp_of_table,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(nintendo_otp_driver);
|
||||
+MODULE_AUTHOR("Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>");
|
||||
+MODULE_DESCRIPTION("Nintendo Wii and Wii U OTP driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,29 @@
|
||||
From 7af526c740bdbd5b4dcebba04ace5b3b0c07801f Mon Sep 17 00:00:00 2001
|
||||
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Date: Tue, 14 Sep 2021 11:29:49 +0200
|
||||
Subject: [PATCH] nvmem: NVMEM_NINTENDO_OTP should depend on WII
|
||||
|
||||
The Nintendo Wii and Wii U OTP is only present on Nintendo Wii and Wii U
|
||||
consoles. Hence add a dependency on WII, to prevent asking the user
|
||||
about this driver when configuring a kernel without Nintendo Wii and Wii
|
||||
U console support.
|
||||
|
||||
Fixes: 3683b761fe3a10ad ("nvmem: nintendo-otp: Add new driver for the Wii and Wii U OTP")
|
||||
Reviewed-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Link: https://lore.kernel.org/r/01318920709dddc4d85fe895e2083ca0eee234d8.1631611652.git.geert+renesas@glider.be
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -109,6 +109,7 @@ config MTK_EFUSE
|
||||
|
||||
config NVMEM_NINTENDO_OTP
|
||||
tristate "Nintendo Wii and Wii U OTP Support"
|
||||
+ depends on WII || COMPILE_TEST
|
||||
help
|
||||
This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
|
||||
|
@ -29,9 +29,9 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -270,4 +270,17 @@ config SPRD_EFUSE
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called nvmem-sprd-efuse.
|
||||
@@ -300,4 +300,17 @@ config NVMEM_BRCM_NVRAM
|
||||
This driver provides support for Broadcom's NVRAM that can be accessed
|
||||
using I/O mapping.
|
||||
|
||||
+config NVMEM_U_BOOT_ENV
|
||||
+ tristate "U-Boot environment variables support"
|
||||
@ -49,10 +49,10 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
endif
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -55,3 +55,5 @@ obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynq
|
||||
nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
|
||||
obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_efuse.o
|
||||
nvmem_sprd_efuse-y := sprd-efuse.o
|
||||
@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.
|
||||
nvmem-rmem-y := rmem.o
|
||||
obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
|
||||
nvmem_brcm_nvram-y := brcm_nvram.o
|
||||
+obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o
|
||||
+nvmem_u-boot-env-y := u-boot-env.o
|
||||
--- /dev/null
|
@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -374,6 +374,7 @@ static int nvmem_cell_info_to_nvmem_cell
|
||||
@@ -462,6 +462,7 @@ static int nvmem_cell_info_to_nvmem_cell
|
||||
|
||||
cell->bit_offset = info->bit_offset;
|
||||
cell->nbits = info->nbits;
|
@ -4244,6 +4244,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
|
||||
# CONFIG_NVMEM_BCM_OCOTP is not set
|
||||
# CONFIG_NVMEM_IMX_OCOTP is not set
|
||||
# CONFIG_NVMEM_REBOOT_MODE is not set
|
||||
# CONFIG_NVMEM_RMEM is not set
|
||||
# CONFIG_NVMEM_SYSFS is not set
|
||||
# CONFIG_NVMEM_U_BOOT_ENV is not set
|
||||
# CONFIG_NVME_FC is not set
|
||||
|
Loading…
x
Reference in New Issue
Block a user