[PATCH 06/14] misc: Add support for nvmem cells

Simon Glass sjg at chromium.org
Tue Mar 1 15:58:31 CET 2022


Hi Sean,

On Mon, 28 Feb 2022 at 09:43, Sean Anderson <sean.anderson at seco.com> wrote:
>
>
>
> On 2/26/22 1:36 PM, Simon Glass wrote:
> > Hi Sean,
> >
> > On Mon, 7 Feb 2022 at 16:42, Sean Anderson <sean.anderson at seco.com> wrote:
> >>
> >> This adds support for "nvmem cells" as seen in Linux. The nvmem device
> >> class in Linux is used for various assorted ROMs and EEPROMs. In this
> >> sense, it is similar to UCLASS_MISC, but also includes
> >> UCLASS_I2C_EEPROM, UCLASS_RTC, and UCLASS_MTD. While nvmem devices can
> >> be accessed directly, they are most often used by reading/writing
> >> contiguous values called "cells". Cells typically hold information like
> >> calibration, versions, or configuration (such as mac addresses).
> >>
> >> nvmem devices can specify "cells" in their device tree:
> >>
> >>         qfprom: eeprom at 700000 {
> >>                 #address-cells = <1>;
> >>                 #size-cells = <1>;
> >>                 reg = <0x00700000 0x100000>;
> >>
> >>                 /* ... */
> >>
> >>                 tsens_calibration: calib at 404 {
> >>                         reg = <0x404 0x10>;
> >>                 };
> >>         };
> >>
> >> which can then be referenced like:
> >>
> >>         tsens {
> >>                 /* ... */
> >>                 nvmem-cells = <&tsens_calibration>;
> >>                 nvmem-cell-names = "calibration";
> >>         };
> >>
> >> The tsens driver could then read the calibration value like:
> >>
> >>         struct nvmem_cell cal_cell;
> >>         u8 cal[16];
> >>         nvmem_cell_get_by_name(dev, "calibration", &cal_cell);
> >>         nvmem_cell_read(&cal_cell, cal, sizeof(cal));
> >>
> >> Because nvmem devices are not all of the same uclass, supported uclasses
> >> must register a nvmem_interface struct. This allows CONFIG_NVMEM to be
> >> enabled without depending on specific uclasses. At the moment,
> >> nvmem_interface is very bare-bones, and assumes that no initialization
> >> is necessary. However, this could be amended in the future.
> >>
> >> Although I2C_EEPROM and MISC are quite similar (and could likely be
> >> unified), they present different read/write function signatures. To
> >> abstract over this, NVMEM uses the same read/write signature as Linux.
> >> In particular, short read/writes are not allowed, which is allowed by
> >> MISC.
> >>
> >> The functionality implemented by nvmem cells is very similar to that
> >> provided by i2c_eeprom_partition. "fixed-partition"s for eeproms does
> >> not seem to have made its way into Linux or into any device tree other
> >> than sandbox. It is possible that with the introduction of this API it
> >> would be possible to remove it.
> >>
> >> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> >> ---
> >>
> >>  MAINTAINERS           |   7 ++
> >>  doc/api/index.rst     |   1 +
> >>  doc/api/nvmem.rst     |   7 ++
> >>  drivers/misc/Kconfig  |  16 ++++
> >>  drivers/misc/Makefile |   1 +
> >>  drivers/misc/nvmem.c  | 109 +++++++++++++++++++++++++
> >>  include/nvmem.h       | 185 ++++++++++++++++++++++++++++++++++++++++++
> >>  7 files changed, 326 insertions(+)
> >>  create mode 100644 doc/api/nvmem.rst
> >>  create mode 100644 drivers/misc/nvmem.c
> >>  create mode 100644 include/nvmem.h
> >
> > Here I think it would be better to add a new uclass so that drivers
> > which support it can add a child device in that uclass. This is done
> > in lots of places in U-Boot.
>
> I'm not sure exactly what you have in mind. The issue is that there are at
> least 6 uclasses which I would like to support:
>
> - UCLASS_MISC
> - UCLASS_I2C_EEPROM
> - UCLASS_RTC
> - UCLASS_MTD
> - UCLASS_FUSE (doesn't exist yet, but probably should)
> - Possibly UCLASS_PMIC
>
> Most of these uclasses have existing interfaces which expose an NVMEM-like API,
> in addition to other uclass-specific functionality. Instead of having an
> additional API which drivers must implement, I would like to leverage these
> existing APIs to make adding NVMEM support as painless as possible. NVMEM is
> more of a "meta-uclass" which allows us to leverage existing read/write
> functions in uclasses. If any additional devices are to be created, they need
> to be created by the nvmem subsystem, or by the supported uclasses, rather than
> in drivers.

I may be missing something as I have not looked in detail at your API changes.

But the way to have a consistent API is to use a uclass. We do this
with BLK. When a PMIC have GPIOs, RTC and regulators, we add them as
child devices. We also have it with bootstd, where a bootdev is
created as a child device of a storage device. We can put the required
stuff in a helper function. We can even avoid any new code in the
drivers by using the pending event system.

Can you first help me understand what is wrong with using a new uclass?

>
> Now, there are some instances where creating a new child device might be the
> best approach. For example, you might have some OTP memory in an unrelated
> device. In that case, creating a child device (of UCLASS_MISC, or UCLASS_FUSE
> if that gets created) is the right course of action.

Regards,
SImon


More information about the U-Boot mailing list