209 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3===============4NVMEM Subsystem5===============6 7 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>8 9This document explains the NVMEM Framework along with the APIs provided,10and how to use it.11 121. Introduction13===============14*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to15retrieve configuration of SOC or Device specific data from non volatile16memories like eeprom, efuses and so on.17 18Before this framework existed, NVMEM drivers like eeprom were stored in19drivers/misc, where they all had to duplicate pretty much the same code to20register a sysfs file, allow in-kernel users to access the content of the21devices they were driving, etc.22 23This was also a problem as far as other in-kernel users were involved, since24the solutions used were pretty much different from one driver to another, there25was a rather big abstraction leak.26 27This framework aims at solve these problems. It also introduces DT28representation for consumer devices to go get the data they require (MAC29Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs.30 31NVMEM Providers32+++++++++++++++33 34NVMEM provider refers to an entity that implements methods to initialize, read35and write the non-volatile memory.36 372. Registering/Unregistering the NVMEM provider38===============================================39 40A NVMEM provider can register with NVMEM core by supplying relevant41nvmem configuration to nvmem_register(), on success core would return a valid42nvmem_device pointer.43 44nvmem_unregister() is used to unregister a previously registered provider.45 46For example, a simple nvram case::47 48 static int brcm_nvram_probe(struct platform_device *pdev)49 {50 struct nvmem_config config = {51 .name = "brcm-nvram",52 .reg_read = brcm_nvram_read,53 };54 ...55 config.dev = &pdev->dev;56 config.priv = priv;57 config.size = resource_size(res);58 59 devm_nvmem_register(&config);60 }61 62Users of board files can define and register nvmem cells using the63nvmem_cell_table struct::64 65 static struct nvmem_cell_info foo_nvmem_cells[] = {66 {67 .name = "macaddr",68 .offset = 0x7f00,69 .bytes = ETH_ALEN,70 }71 };72 73 static struct nvmem_cell_table foo_nvmem_cell_table = {74 .nvmem_name = "i2c-eeprom",75 .cells = foo_nvmem_cells,76 .ncells = ARRAY_SIZE(foo_nvmem_cells),77 };78 79 nvmem_add_cell_table(&foo_nvmem_cell_table);80 81Additionally it is possible to create nvmem cell lookup entries and register82them with the nvmem framework from machine code as shown in the example below::83 84 static struct nvmem_cell_lookup foo_nvmem_lookup = {85 .nvmem_name = "i2c-eeprom",86 .cell_name = "macaddr",87 .dev_id = "foo_mac.0",88 .con_id = "mac-address",89 };90 91 nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);92 93NVMEM Consumers94+++++++++++++++95 96NVMEM consumers are the entities which make use of the NVMEM provider to97read from and to NVMEM.98 993. NVMEM cell based consumer APIs100=================================101 102NVMEM cells are the data entries/fields in the NVMEM.103The NVMEM framework provides 3 APIs to read/write NVMEM cells::104 105 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);106 struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);107 108 void nvmem_cell_put(struct nvmem_cell *cell);109 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);110 111 void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);112 int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);113 114`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,115and nvmem_cell_read/write() can then read or write to the cell.116Once the usage of the cell is finished the consumer should call117`*nvmem_cell_put()` to free all the allocation memory for the cell.118 1194. Direct NVMEM device based consumer APIs120==========================================121 122In some instances it is necessary to directly read/write the NVMEM.123To facilitate such consumers NVMEM framework provides below apis::124 125 struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);126 struct nvmem_device *devm_nvmem_device_get(struct device *dev,127 const char *name);128 struct nvmem_device *nvmem_device_find(void *data,129 int (*match)(struct device *dev, const void *data));130 void nvmem_device_put(struct nvmem_device *nvmem);131 int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,132 size_t bytes, void *buf);133 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,134 size_t bytes, void *buf);135 int nvmem_device_cell_read(struct nvmem_device *nvmem,136 struct nvmem_cell_info *info, void *buf);137 int nvmem_device_cell_write(struct nvmem_device *nvmem,138 struct nvmem_cell_info *info, void *buf);139 140Before the consumers can read/write NVMEM directly, it should get hold141of nvmem_controller from one of the `*nvmem_device_get()` api.142 143The difference between these apis and cell based apis is that these apis always144take nvmem_device as parameter.145 1465. Releasing a reference to the NVMEM147=====================================148 149When a consumer no longer needs the NVMEM, it has to release the reference150to the NVMEM it has obtained using the APIs mentioned in the above section.151The NVMEM framework provides 2 APIs to release a reference to the NVMEM::152 153 void nvmem_cell_put(struct nvmem_cell *cell);154 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);155 void nvmem_device_put(struct nvmem_device *nvmem);156 void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);157 158Both these APIs are used to release a reference to the NVMEM and159devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated160with this NVMEM.161 162Userspace163+++++++++164 1656. Userspace binary interface166==============================167 168Userspace can read/write the raw NVMEM file located at::169 170 /sys/bus/nvmem/devices/*/nvmem171 172ex::173 174 hexdump /sys/bus/nvmem/devices/qfprom0/nvmem175 176 0000000 0000 0000 0000 0000 0000 0000 0000 0000177 *178 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00179 0000000 0000 0000 0000 0000 0000 0000 0000 0000180 ...181 *182 0001000183 1847. DeviceTree Binding185=====================186 187See Documentation/devicetree/bindings/nvmem/nvmem.txt188 1898. NVMEM layouts190================191 192NVMEM layouts are yet another mechanism to create cells. With the device193tree binding it is possible to specify simple cells by using an offset194and a length. Sometimes, the cells doesn't have a static offset, but195the content is still well defined, e.g. tag-length-values. In this case,196the NVMEM device content has to be first parsed and the cells need to197be added accordingly. Layouts let you read the content of the NVMEM device198and let you add cells dynamically.199 200Another use case for layouts is the post processing of cells. With layouts,201it is possible to associate a custom post processing hook to a cell. It202even possible to add this hook to cells not created by the layout itself.203 2049. Internal kernel API205======================206 207.. kernel-doc:: drivers/nvmem/core.c208 :export:209