NVMEM SUBSYSTEM
Srinivas Kandagatla srinivas.kandagatla@linaro.org
文章目录
- 1. Introduction
- 2. Registering/Unregistering the NVMEM provider
- 3. NVMEM cell based consumer APIs
- 4. Direct NVMEM device based consumer APIs
- 5. Releasing a reference to the NVMEM
- 6. Userspace binary interface
- 7. DeviceTree Binding
本文档介绍了NVMEM框架以及提供的API以及如何使用它。
1. Introduction
NVMEM是非易失性存储器层的缩写。它用于从非易失性存储器(如eeprom,efuses等)中检索SOC或设备特定数据的配置。
在此框架存在之前,像eeprom这样的NVMEM驱动程序存储在drivers / misc中,它们都必须复制几乎相同的代码来注册sysfs文件,允许内核内用户访问他们正在驱动的设备的内容,等等。
就其他内核用户而言,这也是一个问题,因为使用的解决方案从一个驱动程序到另一个驱动程序几乎不同,存在相当大的抽象泄漏。
该框架旨在解决这些问题。它还为消费类设备引入了DT表示,以便从NVMEM获取所需的数据(MAC地址,SoC /版本ID,部件号等)。该框架基于regmap,因此regmap中可用的大部分抽象都可以在多种类型的总线上重复使用。
NVMEM Providers
+++++++++++++++
NVMEM provider是指实现初始化,读取和写入非易失性存储器的方法的实体。
2. Registering/Unregistering the NVMEM provider
可以通过NVMEM core向nvmem_register()提供相关的nvmem配置来注册NVMEM provider,成功时core将返回有效的nvmem_device指针。
nvmem_unregister(nvmem)用于取消以前注册的provider。
For example, a simple qfprom case:static struct nvmem_config econfig = {.name = "qfprom",.owner = THIS_MODULE,
};static int qfprom_probe(struct platform_device *pdev)
{...econfig.dev = &pdev->dev;nvmem = nvmem_register(&econfig);...
}
NVMEM provider 必须具有与其结构设备关联的regmap。 如果不这样做,将从nvmem_register()返回错误代码。
板文件的用户可以使用。来定义和注册nvmem单元nvmem_cell_table结构:
static struct nvmem_cell_info foo_nvmem_cells[] = {{.name = "macaddr",.offset = 0x7f00,.bytes = ETH_ALEN,}
};static struct nvmem_cell_table foo_nvmem_cell_table = {.nvmem_name = "i2c-eeprom",.cells = foo_nvmem_cells,.ncells = ARRAY_SIZE(foo_nvmem_cells),
};nvmem_add_cell_table(&foo_nvmem_cell_table);
此外,还可以创建nvmem单元查找条目,并使用机器代码中的nvmem框架注册它们,如下例所示:
static struct nvmem_cell_lookup foo_nvmem_lookup = {.nvmem_name = "i2c-eeprom",.cell_name = "macaddr",.dev_id = "foo_mac.0",.con_id = "mac-address",
};nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
NVMEM Consumers
+++++++++++++++
NVMEM consumers是利用NVMEM provider 读取和写入NVMEM的实体。 a
3. NVMEM cell based consumer APIs
NVMEM cell是NVMEM中的数据条目/字段。
NVMEM框架提供3个API来读/写NVMEM单元。
struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);void nvmem_cell_put(struct nvmem_cell *cell);
void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);*nvmem_cell_get() apis will get a reference to nvmem cell for a given id,
and nvmem_cell_read/write() can then read or write to the cell.
一旦完成单元的使用,consumer 应调用nvmem_cell_put()以释放分配给cell的所有内存。
4. Direct NVMEM device based consumer APIs
在某些情况下,有必要直接读/写NVMEM。 为了方便这样的consumers ,NVMEM框架提供了以下API。
struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
struct nvmem_device *devm_nvmem_device_get(struct device *dev,const char *name);
void nvmem_device_put(struct nvmem_device *nvmem);
int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,size_t bytes, void *buf);
int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,size_t bytes, void *buf);
int nvmem_device_cell_read(struct nvmem_device *nvmem,struct nvmem_cell_info *info, void *buf);
int nvmem_device_cell_write(struct nvmem_device *nvmem,struct nvmem_cell_info *info, void *buf);
在consumers 可以直接读/写NVMEM之前,应该* nvmem_device_get()api中获取nvmem_controller。
The difference between these apis and cell based apis is that these apis always
take nvmem_device as parameter.
5. Releasing a reference to the NVMEM
当consumer 不再需要NVMEM时,它必须释放对使用上一节中提到的API获得的NVMEM的引用。
NVMEM框架提供2个API以释放对NVMEM的引用。
void nvmem_cell_put(struct nvmem_cell *cell);
void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
void nvmem_device_put(struct nvmem_device *nvmem);
void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
这两个API都用于释放对NVMEM的引用,devm_nvmem_cell_put和devm_nvmem_device_put销毁与此NVMEM关联的devres。
Userspace
+++++++++
6. Userspace binary interface
用户空间可以读取/写入位于/sys/bus/nvmem/devices/*/nvmem的原始NVMEM文件
ex:hexdump /sys/bus/nvmem/devices/qfprom0/nvmem0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
0000000 0000 0000 0000 0000 0000 0000 0000 0000
...
*
0001000
7. DeviceTree Binding
参考Documentation/devicetree/bindings/nvmem/nvmem.txt
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
