mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
Char / Misc and documentation fixes for 7.2-rc7
Here are some small char/misc and nvmem and documentation fixes for
7.2-rc7 to resolve some reported issues. Included in here are:
- updates to the documentation for the kernel threat model and
security bugs to get the LLMs to actually follow what we have been
asking them to do (i.e. not claim security issues for things we do
not consider security issues.)
- nvmem driver fixes which required a tiny "layout" driver to be
added.
- fastrpc driver fixes
- mei driver fix
- counter driver fix
- binder driver fix
All of these have been in linux-next this week with no reported
problems.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCandLdw8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+yldzACZAVaM2/I0hIeTnoBqRFIZBcroUQYAoNk5zQSW
qYG0DWUf4LJwj9WPQWIS
=e+LJ
-----END PGP SIGNATURE-----
Merge tag 'char-misc-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc and documentation fixes from Greg KH:
"Here are some small char/misc and nvmem and documentation fixes for
7.2-rc7 to resolve some reported issues. Included in here are:
- updates to the documentation for the kernel threat model and
security bugs to get the LLMs to actually follow what we have been
asking them to do (i.e. not claim security issues for things we do
not consider security issues.)
- nvmem driver fixes which required a tiny "layout" driver to be
added.
- fastrpc driver fixes
- mei driver fix
- counter driver fix
- binder driver fix
All of these have been in linux-next this week with no reported
problems"
* tag 'char-misc-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
docs: security-bugs: clarify some mandatory steps for AI reports
docs: coding-assistant: explain important steps when looking for bugs
docs: security-bugs: clarify what counts as a valid version
docs: threat-model: move fake devices out of "non production use"
docs: threat-model: clarify "security bug" vs "vulnerability"
counter: microchip-tcb-capture: Fix DT channel validation
mei: pull kvfree out of spinlock
rust_binder: do not query current thread for all ioctls
nvmem: layouts: Add fixed-layout driver
nvmem: apple-spmi-nvmem: wrap regmap calls to satisfy CFI
misc: fastrpc: fix memory leak in fastrpc_channel_ctx_free
misc: fastrpc: fix channel ctx ref leak when session alloc fails
misc: fastrpc: take fl->lock when moving mmaps on interrupted invoke
misc: fastrpc: Remove buffer from list prior to unmap operation
misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
This commit is contained in:
commit
5668ba2304
|
|
@ -57,3 +57,40 @@ Basic development tools (git, gcc, make, editors) should not be listed.
|
|||
Example::
|
||||
|
||||
Assisted-by: Claude:claude-3-opus coccinelle sparse
|
||||
|
||||
Procedure for finding and fixing bugs
|
||||
=====================================
|
||||
|
||||
When an AI assistant is used to find and fix bugs, it **MUST** follow at least
|
||||
these steps:
|
||||
|
||||
1. Before starting, read the whole process documentation listed above, as well
|
||||
as any other document mentioned in the request. Do not rely on isolated
|
||||
parts found by keyword search.
|
||||
2. Note the commit ID and Locate a bug as instructed.
|
||||
3. For any bug found that is not trivial, verify that it looks real by
|
||||
attempting to create a reproducer to demonstrate it. Lacking it may cause
|
||||
the report to be ignored, as many unverified bug reports sent to maintainers
|
||||
happen to be invalid. Stop here if it finally looks wrong.
|
||||
4. Write a fix for the bug. This part is not optional: except in a few very
|
||||
rare cases, an AI assistant able to find a bug is able to fix it. Note that
|
||||
fixes written in the same session as used to find the bug will generally
|
||||
lead to better and more accurate fixes as the LLM's reasoning context
|
||||
remains present.
|
||||
5. Build and verify that the fix works either using the reproducer or by
|
||||
re-running a complete analysis; drop any fix that doesn't work and try
|
||||
another one. The fix must not add build warnings and must pass the
|
||||
checkpatch.pl checks (see submitting-patches.rst).
|
||||
6. Commit the working fix with a detailed message describing the problem, the
|
||||
solution and a Fixes tag. Do not add a Signed-off-by tag, and add an
|
||||
Assisted-by tag, as described above.
|
||||
7. Identify the maintainers and lists using scripts/get_maintainer.pl.
|
||||
Documentation/process/security-bugs.rst shows how to do that.
|
||||
8. Indicate what could not be done. If the fix could not be built or tested, or
|
||||
if no reproducer could be produced, say so explicitly: maintainers currently
|
||||
waste too much time analyzing unverified reports and untested fixes.
|
||||
9. Read Documentation/process/threat-model.rst to determine whether the bug is
|
||||
a vulnerability or a regular bug, and leave the result to the reporter for
|
||||
review (the assistant must never send anything itself). Regular bugs are
|
||||
submitted as described in Documentation/process/submitting-patches.rst,
|
||||
vulnerabilities as described in Documentation/process/security-bugs.rst.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ information is helpful. The following information are absolutely necessary in
|
|||
**any** security bug report:
|
||||
|
||||
* **affected kernel version range**: with no version indication, your report
|
||||
will not be processed. Note that a time-dependent version such as "latest
|
||||
mainline" is not acceptable. A stable identifier such as a commit ID or an
|
||||
exact version is required. Versions designating kernels not coming from
|
||||
kernel.org (such as distro kernels) are meaningless to maintainers and
|
||||
will not be processed. A significant part of reports are for bugs that
|
||||
have already been fixed, so it is extremely important that vulnerabilities
|
||||
are verified on recent versions (development tree or latest stable
|
||||
|
|
@ -225,6 +229,28 @@ there is no need to consume a maintainer's time with an unimportant report. If
|
|||
the issue is clearly trivial and publicly discoverable, you should report it
|
||||
directly to the public mailing lists.
|
||||
|
||||
At the very least, when using an AI assistant to find and report bugs, make the
|
||||
assistant read this file and threat-model.rst before proceeding, and have it
|
||||
follow the procedure described in coding-assistants.rst: work on an up-to-date
|
||||
mainline tree and note the commit ID, verify the bug is real, write a fix,
|
||||
build it warning-free and checkpatch-clean, commit it with a Fixes tag, and
|
||||
identify the maintainers with get_maintainer.pl.
|
||||
|
||||
On top of that procedure, the AI assistant **MUST**:
|
||||
|
||||
1. Prepare a plain-text report explaining the problem. It must contain the
|
||||
four items listed at the top of this file as absolutely necessary: the
|
||||
affected version or commit ID noted while following the procedure above,
|
||||
the description of the problem, the reproducer or its status, and the
|
||||
triggering conditions.
|
||||
2. Start the report with a temporary section listing the recipients' addresses
|
||||
(maintainers+list for the patch, maintainers only for the report and
|
||||
reproducer), and with instructions reminding the reporter to check that
|
||||
their email client is properly setup (see email-clients.rst), and leave it
|
||||
to the reporter to remove that temporary section.
|
||||
|
||||
A more detailed process is covered at https://github.com/masoncl/kres.git.
|
||||
|
||||
Sending the report
|
||||
------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ measures whose purpose is to avoid crossing a security boundary when certain
|
|||
classes of bugs are found, but a failure of these extra protections do not
|
||||
constitute a vulnerability alone.
|
||||
|
||||
What does not constitute a security bug
|
||||
---------------------------------------
|
||||
What classes of problems are not considered vulnerabilities
|
||||
-----------------------------------------------------------
|
||||
|
||||
In the Linux kernel's threat model, the following classes of problems are
|
||||
**NOT** considered as Linux Kernel security bugs. However, when it is believed
|
||||
**NOT** considered Linux Kernel vulnerabilities. However, when it is believed
|
||||
that the kernel could do better, they should be reported, so that they can be
|
||||
reviewed and fixed where reasonably possible, but they will be handled as any
|
||||
regular bug:
|
||||
|
|
@ -111,8 +111,8 @@ regular bug:
|
|||
|
||||
* outdated kernels and particularly end-of-life branches are out of the scope
|
||||
of the kernel's threat model: administrators are responsible for keeping
|
||||
their system up to date. For a bug to qualify as a security bug, it must be
|
||||
demonstrated that it affects actively maintained versions.
|
||||
their system up to date. For a bug to qualify as a vulnerability, it must
|
||||
be demonstrated that it affects actively maintained versions.
|
||||
|
||||
* build-level: changes to the kernel configuration that are explicitly
|
||||
documented as lowering the security level (e.g. ``CONFIG_NOMMU``), or
|
||||
|
|
@ -178,9 +178,6 @@ regular bug:
|
|||
involving tens of millions of threads, tens of thousands of CPUs,
|
||||
unrealistic CPU frequencies, RAM sizes or disk capacities, network speeds).
|
||||
|
||||
* issues whose reproduction requires hardware modification or emulation,
|
||||
including fake USB devices that pretend to be another one.
|
||||
|
||||
* as well as issues that can be triggered at a cost that is orders of
|
||||
magnitude higher than the expected benefits (e.g. fully functional keyboard
|
||||
emulator only to retrieve 7 uninitialized bytes in a structure, or
|
||||
|
|
@ -208,19 +205,27 @@ regular bug:
|
|||
messages.
|
||||
|
||||
* Leaks of kernel memory addresses/pointers do not constitute an immediately
|
||||
exploitable vector and are not security bugs, though they must be reported
|
||||
and fixed.
|
||||
exploitable vector and are not vulnerabilities, though they must be
|
||||
reported and fixed.
|
||||
|
||||
* **Crafted file system images**:
|
||||
* **Non-conforming devices and media**:
|
||||
|
||||
Drivers are implemented against a specification. When a device or a storage
|
||||
medium violates the specification its driver was written against, the
|
||||
resulting misbehaviour is a regular bug to be fixed, not a vulnerability,
|
||||
unless the driver is specifically documented as being hardened against
|
||||
hostile inputs. The following are therefore not considered vulnerabilities:
|
||||
|
||||
* bugs triggered by mounting a corrupted or maliciously crafted file system
|
||||
image are generally not security bugs, as the kernel assumes the underlying
|
||||
storage media is under the administrator's control, unless the filesystem
|
||||
driver is specifically documented as being hardened against untrusted media.
|
||||
|
||||
* issues that are resolved, mitigated, or detected by running a filesystem
|
||||
image: mounting a block device is a privileged operation (see above), and
|
||||
the administrator is responsible for the media they mount. This includes
|
||||
issues that are resolved, mitigated, or detected by running a filesystem
|
||||
consistency check (fsck) on the image prior to mounting.
|
||||
|
||||
* bugs whose reproduction requires hardware modification or emulation,
|
||||
including fake USB devices that pretend to be another one, or devices
|
||||
reporting values outside their documented ranges.
|
||||
|
||||
* **Physical access**:
|
||||
|
||||
Issues that require physical access to the machine, hardware modification, or
|
||||
|
|
@ -232,4 +237,4 @@ regular bug:
|
|||
* **Functional and performance regressions**:
|
||||
|
||||
Any issue that can be mitigated by setting proper permissions and limits
|
||||
doesn't qualify as a security bug.
|
||||
doesn't qualify as a vulnerability.
|
||||
|
|
|
|||
|
|
@ -10125,6 +10125,11 @@ F: drivers/base/firmware_loader/
|
|||
F: rust/kernel/firmware.rs
|
||||
F: include/linux/firmware.h
|
||||
|
||||
FIXED-LAYOUT NVMEM LAYOUT DRIVER
|
||||
M: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
|
||||
S: Maintained
|
||||
F: drivers/nvmem/layouts/fixed-layout.c
|
||||
|
||||
FLEXTIMER FTM-QUADDEC DRIVER
|
||||
M: Patrick Havelange <patrick.havelange@essensium.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
|
|
|||
|
|
@ -1586,6 +1586,10 @@ fn ioctl_write_only(
|
|||
cmd: u32,
|
||||
reader: &mut UserSliceReader,
|
||||
) -> Result {
|
||||
if cmd == uapi::BINDER_FREEZE {
|
||||
return ioctl_freeze(reader);
|
||||
}
|
||||
|
||||
let thread = this.get_current_thread()?;
|
||||
match cmd {
|
||||
uapi::BINDER_SET_MAX_THREADS => this.set_max_threads(reader.read()?),
|
||||
|
|
@ -1597,7 +1601,6 @@ fn ioctl_write_only(
|
|||
uapi::BINDER_ENABLE_ONEWAY_SPAM_DETECTION => {
|
||||
this.set_oneway_spam_detection_enabled(reader.read()?)
|
||||
}
|
||||
uapi::BINDER_FREEZE => ioctl_freeze(reader)?,
|
||||
_ => return Err(EINVAL),
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -1612,15 +1615,16 @@ fn ioctl_write_read(
|
|||
cmd: u32,
|
||||
data: UserSlice,
|
||||
) -> Result {
|
||||
let thread = this.get_current_thread()?;
|
||||
let blocking = (file.flags() & file::flags::O_NONBLOCK) == 0;
|
||||
match cmd {
|
||||
uapi::BINDER_WRITE_READ => thread.write_read(data, blocking)?,
|
||||
uapi::BINDER_WRITE_READ => this.get_current_thread()?.write_read(data, blocking)?,
|
||||
uapi::BINDER_GET_NODE_DEBUG_INFO => this.get_node_debug_info(data)?,
|
||||
uapi::BINDER_GET_NODE_INFO_FOR_REF => this.get_node_info_from_ref(data)?,
|
||||
uapi::BINDER_VERSION => this.version(data)?,
|
||||
uapi::BINDER_GET_FROZEN_INFO => get_frozen_status(data)?,
|
||||
uapi::BINDER_GET_EXTENDED_ERROR => thread.get_extended_error(data)?,
|
||||
uapi::BINDER_GET_EXTENDED_ERROR => {
|
||||
this.get_current_thread()?.get_extended_error(data)?
|
||||
}
|
||||
_ => return Err(EINVAL),
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ static int mchp_tc_probe(struct platform_device *pdev)
|
|||
char clk_name[7];
|
||||
struct regmap *regmap;
|
||||
struct clk *clk[3];
|
||||
int channel;
|
||||
u32 channel;
|
||||
int ret, i;
|
||||
|
||||
counter = devm_counter_alloc(&pdev->dev, sizeof(*priv));
|
||||
|
|
@ -517,7 +517,7 @@ static int mchp_tc_probe(struct platform_device *pdev)
|
|||
|
||||
priv->channel[i] = channel;
|
||||
|
||||
snprintf(clk_name, sizeof(clk_name), "t%d_clk", channel);
|
||||
snprintf(clk_name, sizeof(clk_name), "t%u_clk", channel);
|
||||
|
||||
clk[i] = of_clk_get_by_name(np->parent, clk_name);
|
||||
if (IS_ERR(clk[i])) {
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ static void fastrpc_channel_ctx_free(struct kref *ref)
|
|||
|
||||
cctx = container_of(ref, struct fastrpc_channel_ctx, refcount);
|
||||
|
||||
idr_destroy(&cctx->ctx_idr);
|
||||
kfree(cctx);
|
||||
}
|
||||
|
||||
|
|
@ -1305,10 +1306,12 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
|
|||
}
|
||||
|
||||
if (err == -ERESTARTSYS) {
|
||||
spin_lock(&fl->lock);
|
||||
list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
|
||||
list_del(&buf->node);
|
||||
list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps);
|
||||
}
|
||||
spin_unlock(&fl->lock);
|
||||
}
|
||||
|
||||
if (err)
|
||||
|
|
@ -1370,7 +1373,9 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
|
|||
err = PTR_ERR(name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
inbuf.client_id = fl->client_id;
|
||||
inbuf.namelen = init.namelen;
|
||||
inbuf.pageslen = 0;
|
||||
if (!fl->cctx->remote_heap) {
|
||||
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
|
||||
&fl->cctx->remote_heap);
|
||||
|
|
@ -1393,12 +1398,10 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
|
|||
goto err_map;
|
||||
}
|
||||
scm_done = true;
|
||||
inbuf.pageslen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inbuf.client_id = fl->client_id;
|
||||
inbuf.namelen = init.namelen;
|
||||
inbuf.pageslen = 0;
|
||||
fl->pd = USER_PD;
|
||||
|
||||
args[0].ptr = (u64)(uintptr_t)&inbuf;
|
||||
|
|
@ -1673,7 +1676,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
|
|||
dev_err(&cctx->rpdev->dev, "No session available\n");
|
||||
mutex_destroy(&fl->mutex);
|
||||
kfree(fl);
|
||||
|
||||
fastrpc_channel_ctx_put(cctx);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -1889,9 +1892,6 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
|
|||
&args[0]);
|
||||
if (!err) {
|
||||
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
|
||||
spin_lock(&fl->lock);
|
||||
list_del(&buf->node);
|
||||
spin_unlock(&fl->lock);
|
||||
fastrpc_buf_free(buf);
|
||||
} else {
|
||||
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
|
||||
|
|
@ -1905,6 +1905,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
|
|||
struct fastrpc_buf *buf = NULL, *iter, *b;
|
||||
struct fastrpc_req_munmap req;
|
||||
struct device *dev = fl->sctx->dev;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&req, argp, sizeof(req)))
|
||||
return -EFAULT;
|
||||
|
|
@ -1912,6 +1913,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
|
|||
spin_lock(&fl->lock);
|
||||
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
|
||||
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
|
||||
list_del(&iter->node);
|
||||
buf = iter;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1924,7 +1926,14 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return fastrpc_req_munmap_impl(fl, buf);
|
||||
err = fastrpc_req_munmap_impl(fl, buf);
|
||||
if (err) {
|
||||
spin_lock(&fl->lock);
|
||||
list_add_tail(&buf->node, &fl->mmaps);
|
||||
spin_unlock(&fl->lock);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
|
||||
|
|
|
|||
|
|
@ -425,18 +425,24 @@ static void mei_io_tx_list_free_cl(struct list_head *head,
|
|||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_free_fp - free cb from a list that matches file pointer
|
||||
* mei_io_rd_list_free_fp - free cb from a rd_completed list that matches file pointer
|
||||
*
|
||||
* @head: io list
|
||||
* @cl: host client
|
||||
* @fp: file pointer (matching cb file object), may be NULL
|
||||
*/
|
||||
static void mei_io_list_free_fp(struct list_head *head, const struct file *fp)
|
||||
static void mei_io_rd_list_free_fp(struct mei_cl *cl, const struct file *fp)
|
||||
{
|
||||
struct mei_cl_cb *cb, *next;
|
||||
LIST_HEAD(cmpl_list);
|
||||
|
||||
list_for_each_entry_safe(cb, next, head, list)
|
||||
spin_lock(&cl->rd_completed_lock);
|
||||
list_for_each_entry_safe(cb, next, &cl->rd_completed, list)
|
||||
if (!fp || fp == cb->fp)
|
||||
mei_io_cb_free(cb);
|
||||
list_move(&cb->list, &cmpl_list);
|
||||
spin_unlock(&cl->rd_completed_lock);
|
||||
|
||||
list_for_each_entry_safe(cb, next, &cmpl_list, list)
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -565,9 +571,7 @@ int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp)
|
|||
mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl);
|
||||
mei_cl_free_pending(cl);
|
||||
}
|
||||
spin_lock(&cl->rd_completed_lock);
|
||||
mei_io_list_free_fp(&cl->rd_completed, fp);
|
||||
spin_unlock(&cl->rd_completed_lock);
|
||||
mei_io_rd_list_free_fp(cl, fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1401,7 +1405,7 @@ void mei_cl_add_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb)
|
|||
}
|
||||
|
||||
/**
|
||||
* mei_cl_del_rd_completed - free read completed callback with lock
|
||||
* mei_cl_del_rd_completed - unlink read completed callback with lock and free it
|
||||
*
|
||||
* @cl: host client
|
||||
* @cb: callback block
|
||||
|
|
@ -1410,8 +1414,9 @@ void mei_cl_add_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb)
|
|||
void mei_cl_del_rd_completed(struct mei_cl *cl, struct mei_cl_cb *cb)
|
||||
{
|
||||
spin_lock(&cl->rd_completed_lock);
|
||||
mei_io_cb_free(cb);
|
||||
list_del_init(&cb->list);
|
||||
spin_unlock(&cl->rd_completed_lock);
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,22 @@ static const struct regmap_config apple_spmi_regmap_config = {
|
|||
.max_register = 0xffff,
|
||||
};
|
||||
|
||||
static int apple_spmi_nvmem_read(void *priv, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
struct regmap *map = priv;
|
||||
|
||||
return regmap_bulk_read(map, offset, val, bytes);
|
||||
}
|
||||
|
||||
static int apple_spmi_nvmem_write(void *priv, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
struct regmap *map = priv;
|
||||
|
||||
return regmap_bulk_write(map, offset, val, bytes);
|
||||
}
|
||||
|
||||
static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
|
@ -28,8 +44,8 @@ static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
|
|||
.word_size = 1,
|
||||
.stride = 1,
|
||||
.size = 0xffff,
|
||||
.reg_read = (void *)regmap_bulk_read,
|
||||
.reg_write = (void *)regmap_bulk_write,
|
||||
.reg_read = apple_spmi_nvmem_read,
|
||||
.reg_write = apple_spmi_nvmem_write,
|
||||
};
|
||||
|
||||
regmap = devm_regmap_init_spmi_ext(sdev, &apple_spmi_regmap_config);
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
|
||||
int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
|
||||
{
|
||||
struct device *dev = &nvmem->dev;
|
||||
const __be32 *addr;
|
||||
|
|
@ -834,29 +834,13 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvmem_add_cells_from_dt);
|
||||
|
||||
static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
|
||||
{
|
||||
return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
|
||||
}
|
||||
|
||||
static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem)
|
||||
{
|
||||
struct device_node *layout_np;
|
||||
int err = 0;
|
||||
|
||||
layout_np = of_nvmem_layout_get_container(nvmem);
|
||||
if (!layout_np)
|
||||
return 0;
|
||||
|
||||
if (of_device_is_compatible(layout_np, "fixed-layout"))
|
||||
err = nvmem_add_cells_from_dt(nvmem, layout_np);
|
||||
|
||||
of_node_put(layout_np);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int nvmem_layout_register(struct nvmem_layout *layout)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1005,10 +989,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
|
|||
goto err_remove_cells;
|
||||
}
|
||||
|
||||
rval = nvmem_add_cells_from_fixed_layout(nvmem);
|
||||
if (rval)
|
||||
goto err_remove_cells;
|
||||
|
||||
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
|
||||
|
||||
rval = device_add(&nvmem->dev);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ struct nvmem_device {
|
|||
bool sysfs_cells_populated;
|
||||
};
|
||||
|
||||
int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np);
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
int nvmem_layout_bus_register(void);
|
||||
void nvmem_layout_bus_unregister(void);
|
||||
|
|
|
|||
|
|
@ -125,11 +125,6 @@ static int nvmem_layout_create_device(struct nvmem_device *nvmem,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_nvmem_layout_skip_table[] = {
|
||||
{ .compatible = "fixed-layout", },
|
||||
{}
|
||||
};
|
||||
|
||||
static int nvmem_layout_bus_populate(struct nvmem_device *nvmem,
|
||||
struct device_node *layout_dn)
|
||||
{
|
||||
|
|
@ -142,12 +137,6 @@ static int nvmem_layout_bus_populate(struct nvmem_device *nvmem,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Fixed layouts are parsed manually somewhere else for now */
|
||||
if (of_match_node(of_nvmem_layout_skip_table, layout_dn)) {
|
||||
pr_debug("%s() - skipping %pOF node\n", __func__, layout_dn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (of_node_check_flag(layout_dn, OF_POPULATED_BUS)) {
|
||||
pr_debug("%s() - skipping %pOF, already populated\n",
|
||||
__func__, layout_dn);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# Makefile for nvmem layouts.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_NVMEM_LAYOUTS) += fixed-layout.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
|
||||
|
|
|
|||
58
drivers/nvmem/layouts/fixed-layout.c
Normal file
58
drivers/nvmem/layouts/fixed-layout.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2026 Bootlin
|
||||
*
|
||||
* Authors: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
|
||||
*/
|
||||
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "../internals.h"
|
||||
|
||||
static int fixed_layout_add_cells(struct nvmem_layout *layout)
|
||||
{
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
np = of_nvmem_layout_get_container(layout->nvmem);
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
|
||||
ret = nvmem_add_cells_from_dt(layout->nvmem, np);
|
||||
of_node_put(np);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fixed_layout_probe(struct nvmem_layout *layout)
|
||||
{
|
||||
layout->add_cells = fixed_layout_add_cells;
|
||||
|
||||
return nvmem_layout_register(layout);
|
||||
}
|
||||
|
||||
static void fixed_layout_remove(struct nvmem_layout *layout)
|
||||
{
|
||||
nvmem_layout_unregister(layout);
|
||||
}
|
||||
|
||||
static const struct of_device_id fixed_layout_of_match_table[] = {
|
||||
{ .compatible = "fixed-layout", },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct nvmem_layout_driver fixed_layout_layout = {
|
||||
.driver = {
|
||||
.name = "fixed-layout",
|
||||
.of_match_table = fixed_layout_of_match_table,
|
||||
},
|
||||
.probe = fixed_layout_probe,
|
||||
.remove = fixed_layout_remove,
|
||||
};
|
||||
module_nvmem_layout_driver(fixed_layout_layout);
|
||||
|
||||
MODULE_AUTHOR("Mathieu Dubois-Briand");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(of, fixed_layout_of_match_table);
|
||||
MODULE_DESCRIPTION("NVMEM fixed-layout driver");
|
||||
|
|
@ -214,6 +214,12 @@ static inline int nvmem_layout_register(struct nvmem_layout *layout)
|
|||
|
||||
static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
|
||||
|
||||
static inline int nvmem_add_cells_from_dt(struct nvmem_device *nvmem,
|
||||
struct device_node *np)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NVMEM */
|
||||
|
||||
#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user