nvmem(9)

nvmem9

Usage

options FDT device nvmem

#include <sys/extres/nvmem/nvmem.h>

int

nvmem_get_cell_len(phandle_t node, const char *name);

int

nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen);

int

nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen);

int

nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen);

int

nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen);

Overview

On some embedded boards, the manufacturer stored some data on a NVMEM (Non-Volatile Memory), this is generally stored in some eeprom or fuses.

The nvmem API consist of helpers functions for consumer and device methods for providers.

Functions

nvmem_get_cell_len(phandle_t node, const char *name)

Get the size of the cell base on the reg property on the node. Return the size or ENOENT if the cell name wasn't found

nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)

Get the cell content based on the name. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)

Get the cell content based on the id. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)

Write the cell content based on the name. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)

Write the cell content based on the id. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

Device methods

nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)

Provider device method to read a cell content.

nvmem_write(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)

Provider device method to write a cell content.

Examples

Consider this DTS

/* Provider */
eeprom: eeprom@20000 {
	board_id: id@0 {
		reg = <0x0 0x4>;
	};
};
/* Consumer */
device@30000 {
	...
	nvmem-cells = <&board_id>
	nvmem-cell-names = "boardid";
};

The device driver for eeprom@20000 needs to expose itself as a provider

#include "nvmem_if.h"
int
foo_nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)
{
	/* Read the data */
}
int
foo_attach(device_t dev)
{
	phandle_t node;
	node = ofw_bus_get_node(dev);
	...
	/* Registering the device so the consumers can find us */
	OF_device_register_xref(OF_xref_from_node(node), dev);
	...
}
static device_method_t foo_methods[] = {
	...
	/* nvmem interface */
	DEVMETHOD(nvmem_read, foo_nvmem_read),
	/* Terminate method list */
	DEVMETHOD_END
};

The consumer device driver for device@30000 can now read the nvmem data

int
bar_attach(device_t dev)
{
	phandle_t node;
	uint32_t boardid;
	...
	node = ofw_bus_get_node(dev);
	nvmem_read_cell_by_name(node, "boardid", (void *)&boardid, sizeof(boardid));
	...
}

Releases

9 releases since FreeBSD 14.0-RELEASE; the text changed 3 times.

  1. 14.0–14.3
  2. 14.4–14.5
  3. 15.0
  4. 15.1–16.0

History

The nvmem related function first appear in FreeBSD 12.0. The nvmem interface and manual page was written by Emmanuel Vadot ⟨[email protected]⟩.

From base 16.0-CURRENT-20261027-61c70dc16a79 in FreeBSD 16.0-CURRENT (2026-10-27). Parsed by carta from the page's mdoc source.