Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite2a5402

Browse files
Srinivas-Kandagatlagregkh
authored andcommitted
nvmem: Add nvmem_device based consumer apis.
This patch adds read/write apis which are based on nvmem_device. It iscommon that the drivers like omap cape manager or qcom cpr driver toaccess bytes directly at particular offset in the eeprom and not fromnvmem cell info in DT. These driver would need to get access to the nvmemdirectly, which is what these new APIS provide.These wrapper apis would help such users to avoid code duplication inthere drivers and also avoid them reading a big eeprom blob and parsingit internally in there driver.Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>Tested-by: Stefan Wahren <stefan.wahren@i2se.com>Tested-by: Philipp Zabel <p.zabel@pengutronix.de>Tested-by: Rajendra Nayak <rnayak@codeaurora.org>Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent69aba79 commite2a5402

File tree

2 files changed

+331
-0
lines changed

2 files changed

+331
-0
lines changed

‎drivers/nvmem/core.c‎

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,148 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
445445
mutex_unlock(&nvmem_mutex);
446446
}
447447

448+
staticintnvmem_match(structdevice*dev,void*data)
449+
{
450+
return !strcmp(dev_name(dev),data);
451+
}
452+
453+
staticstructnvmem_device*nvmem_find(constchar*name)
454+
{
455+
structdevice*d;
456+
457+
d=bus_find_device(&nvmem_bus_type,NULL, (void*)name,nvmem_match);
458+
459+
if (!d)
460+
returnNULL;
461+
462+
returnto_nvmem_device(d);
463+
}
464+
465+
#ifIS_ENABLED(CONFIG_NVMEM)&&IS_ENABLED(CONFIG_OF)
466+
/**
467+
* of_nvmem_device_get() - Get nvmem device from a given id
468+
*
469+
* @dev node: Device tree node that uses the nvmem device
470+
* @id: nvmem name from nvmem-names property.
471+
*
472+
* Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
473+
* on success.
474+
*/
475+
structnvmem_device*of_nvmem_device_get(structdevice_node*np,constchar*id)
476+
{
477+
478+
structdevice_node*nvmem_np;
479+
intindex;
480+
481+
index=of_property_match_string(np,"nvmem-names",id);
482+
483+
nvmem_np=of_parse_phandle(np,"nvmem",index);
484+
if (!nvmem_np)
485+
returnERR_PTR(-EINVAL);
486+
487+
return__nvmem_device_get(nvmem_np,NULL,NULL);
488+
}
489+
EXPORT_SYMBOL_GPL(of_nvmem_device_get);
490+
#endif
491+
492+
/**
493+
* nvmem_device_get() - Get nvmem device from a given id
494+
*
495+
* @dev : Device that uses the nvmem device
496+
* @id: nvmem name from nvmem-names property.
497+
*
498+
* Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
499+
* on success.
500+
*/
501+
structnvmem_device*nvmem_device_get(structdevice*dev,constchar*dev_name)
502+
{
503+
if (dev->of_node) {/* try dt first */
504+
structnvmem_device*nvmem;
505+
506+
nvmem=of_nvmem_device_get(dev->of_node,dev_name);
507+
508+
if (!IS_ERR(nvmem)||PTR_ERR(nvmem)==-EPROBE_DEFER)
509+
returnnvmem;
510+
511+
}
512+
513+
returnnvmem_find(dev_name);
514+
}
515+
EXPORT_SYMBOL_GPL(nvmem_device_get);
516+
517+
staticintdevm_nvmem_device_match(structdevice*dev,void*res,void*data)
518+
{
519+
structnvmem_device**nvmem=res;
520+
521+
if (WARN_ON(!nvmem|| !*nvmem))
522+
return0;
523+
524+
return*nvmem==data;
525+
}
526+
527+
staticvoiddevm_nvmem_device_release(structdevice*dev,void*res)
528+
{
529+
nvmem_device_put(*(structnvmem_device**)res);
530+
}
531+
532+
/**
533+
* devm_nvmem_device_put() - put alredy got nvmem device
534+
*
535+
* @nvmem: pointer to nvmem device allocated by devm_nvmem_cell_get(),
536+
* that needs to be released.
537+
*/
538+
voiddevm_nvmem_device_put(structdevice*dev,structnvmem_device*nvmem)
539+
{
540+
intret;
541+
542+
ret=devres_release(dev,devm_nvmem_device_release,
543+
devm_nvmem_device_match,nvmem);
544+
545+
WARN_ON(ret);
546+
}
547+
EXPORT_SYMBOL_GPL(devm_nvmem_device_put);
548+
549+
/**
550+
* nvmem_device_put() - put alredy got nvmem device
551+
*
552+
* @nvmem: pointer to nvmem device that needs to be released.
553+
*/
554+
voidnvmem_device_put(structnvmem_device*nvmem)
555+
{
556+
__nvmem_device_put(nvmem);
557+
}
558+
EXPORT_SYMBOL_GPL(nvmem_device_put);
559+
560+
/**
561+
* devm_nvmem_device_get() - Get nvmem cell of device form a given id
562+
*
563+
* @dev node: Device tree node that uses the nvmem cell
564+
* @id: nvmem name in nvmems property.
565+
*
566+
* Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell
567+
* on success. The nvmem_cell will be freed by the automatically once the
568+
* device is freed.
569+
*/
570+
structnvmem_device*devm_nvmem_device_get(structdevice*dev,constchar*id)
571+
{
572+
structnvmem_device**ptr,*nvmem;
573+
574+
ptr=devres_alloc(devm_nvmem_device_release,sizeof(*ptr),GFP_KERNEL);
575+
if (!ptr)
576+
returnERR_PTR(-ENOMEM);
577+
578+
nvmem=nvmem_device_get(dev,id);
579+
if (!IS_ERR(nvmem)) {
580+
*ptr=nvmem;
581+
devres_add(dev,ptr);
582+
}else {
583+
devres_free(ptr);
584+
}
585+
586+
returnnvmem;
587+
}
588+
EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
589+
448590
staticstructnvmem_cell*nvmem_cell_get_from_list(constchar*cell_id)
449591
{
450592
structnvmem_cell*cell=NULL;
@@ -806,6 +948,122 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
806948
}
807949
EXPORT_SYMBOL_GPL(nvmem_cell_write);
808950

951+
/**
952+
* nvmem_device_cell_read() - Read a given nvmem device and cell
953+
*
954+
* @nvmem: nvmem device to read from.
955+
* @info: nvmem cell info to be read.
956+
* @buf: buffer pointer which will be populated on successful read.
957+
*
958+
* Return: length of successful bytes read on success and negative
959+
* error code on error.
960+
*/
961+
ssize_tnvmem_device_cell_read(structnvmem_device*nvmem,
962+
structnvmem_cell_info*info,void*buf)
963+
{
964+
structnvmem_cellcell;
965+
intrc;
966+
ssize_tlen;
967+
968+
if (!nvmem|| !nvmem->regmap)
969+
return-EINVAL;
970+
971+
rc=nvmem_cell_info_to_nvmem_cell(nvmem,info,&cell);
972+
if (IS_ERR_VALUE(rc))
973+
returnrc;
974+
975+
rc=__nvmem_cell_read(nvmem,&cell,buf,&len);
976+
if (IS_ERR_VALUE(rc))
977+
returnrc;
978+
979+
returnlen;
980+
}
981+
EXPORT_SYMBOL_GPL(nvmem_device_cell_read);
982+
983+
/**
984+
* nvmem_device_cell_write() - Write cell to a given nvmem device
985+
*
986+
* @nvmem: nvmem device to be written to.
987+
* @info: nvmem cell info to be written
988+
* @buf: buffer to be written to cell.
989+
*
990+
* Return: length of bytes written or negative error code on failure.
991+
* */
992+
intnvmem_device_cell_write(structnvmem_device*nvmem,
993+
structnvmem_cell_info*info,void*buf)
994+
{
995+
structnvmem_cellcell;
996+
intrc;
997+
998+
if (!nvmem|| !nvmem->regmap)
999+
return-EINVAL;
1000+
1001+
rc=nvmem_cell_info_to_nvmem_cell(nvmem,info,&cell);
1002+
if (IS_ERR_VALUE(rc))
1003+
returnrc;
1004+
1005+
returnnvmem_cell_write(&cell,buf,cell.bytes);
1006+
}
1007+
EXPORT_SYMBOL_GPL(nvmem_device_cell_write);
1008+
1009+
/**
1010+
* nvmem_device_read() - Read from a given nvmem device
1011+
*
1012+
* @nvmem: nvmem device to read from.
1013+
* @offset: offset in nvmem device.
1014+
* @bytes: number of bytes to read.
1015+
* @buf: buffer pointer which will be populated on successful read.
1016+
*
1017+
* Return: length of successful bytes read on success and negative
1018+
* error code on error.
1019+
*/
1020+
intnvmem_device_read(structnvmem_device*nvmem,
1021+
unsignedintoffset,
1022+
size_tbytes,void*buf)
1023+
{
1024+
intrc;
1025+
1026+
if (!nvmem|| !nvmem->regmap)
1027+
return-EINVAL;
1028+
1029+
rc=regmap_raw_read(nvmem->regmap,offset,buf,bytes);
1030+
1031+
if (IS_ERR_VALUE(rc))
1032+
returnrc;
1033+
1034+
returnbytes;
1035+
}
1036+
EXPORT_SYMBOL_GPL(nvmem_device_read);
1037+
1038+
/**
1039+
* nvmem_device_write() - Write cell to a given nvmem device
1040+
*
1041+
* @nvmem: nvmem device to be written to.
1042+
* @offset: offset in nvmem device.
1043+
* @bytes: number of bytes to write.
1044+
* @buf: buffer to be written.
1045+
*
1046+
* Return: length of bytes written or negative error code on failure.
1047+
* */
1048+
intnvmem_device_write(structnvmem_device*nvmem,
1049+
unsignedintoffset,
1050+
size_tbytes,void*buf)
1051+
{
1052+
intrc;
1053+
1054+
if (!nvmem|| !nvmem->regmap)
1055+
return-EINVAL;
1056+
1057+
rc=regmap_raw_write(nvmem->regmap,offset,buf,bytes);
1058+
1059+
if (IS_ERR_VALUE(rc))
1060+
returnrc;
1061+
1062+
1063+
returnbytes;
1064+
}
1065+
EXPORT_SYMBOL_GPL(nvmem_device_write);
1066+
8091067
staticint__initnvmem_init(void)
8101068
{
8111069
returnbus_register(&nvmem_bus_type);

‎include/linux/nvmem-consumer.h‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct device;
1616
structdevice_node;
1717
/* consumer cookie */
1818
structnvmem_cell;
19+
structnvmem_device;
1920

2021
structnvmem_cell_info {
2122
constchar*name;
@@ -35,6 +36,21 @@ void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
3536
void*nvmem_cell_read(structnvmem_cell*cell,size_t*len);
3637
intnvmem_cell_write(structnvmem_cell*cell,void*buf,size_tlen);
3738

39+
/* direct nvmem device read/write interface */
40+
structnvmem_device*nvmem_device_get(structdevice*dev,constchar*name);
41+
structnvmem_device*devm_nvmem_device_get(structdevice*dev,
42+
constchar*name);
43+
voidnvmem_device_put(structnvmem_device*nvmem);
44+
voiddevm_nvmem_device_put(structdevice*dev,structnvmem_device*nvmem);
45+
intnvmem_device_read(structnvmem_device*nvmem,unsignedintoffset,
46+
size_tbytes,void*buf);
47+
intnvmem_device_write(structnvmem_device*nvmem,unsignedintoffset,
48+
size_tbytes,void*buf);
49+
ssize_tnvmem_device_cell_read(structnvmem_device*nvmem,
50+
structnvmem_cell_info*info,void*buf);
51+
intnvmem_device_cell_write(structnvmem_device*nvmem,
52+
structnvmem_cell_info*info,void*buf);
53+
3854
#else
3955

4056
staticinlinestructnvmem_cell*nvmem_cell_get(structdevice*dev,
@@ -68,17 +84,74 @@ static inline int nvmem_cell_write(struct nvmem_cell *cell,
6884
{
6985
return-ENOSYS;
7086
}
87+
88+
staticinlinestructnvmem_device*nvmem_device_get(structdevice*dev,
89+
constchar*name)
90+
{
91+
returnERR_PTR(-ENOSYS);
92+
}
93+
94+
staticinlinestructnvmem_device*devm_nvmem_device_get(structdevice*dev,
95+
constchar*name)
96+
{
97+
returnERR_PTR(-ENOSYS);
98+
}
99+
100+
staticinlinevoidnvmem_device_put(structnvmem_device*nvmem)
101+
{
102+
}
103+
104+
staticinlinevoiddevm_nvmem_device_put(structdevice*dev,
105+
structnvmem_device*nvmem)
106+
{
107+
}
108+
109+
staticinlinessize_tnvmem_device_cell_read(structnvmem_device*nvmem,
110+
structnvmem_cell_info*info,
111+
void*buf)
112+
{
113+
return-ENOSYS;
114+
}
115+
116+
staticinlineintnvmem_device_cell_write(structnvmem_device*nvmem,
117+
structnvmem_cell_info*info,
118+
void*buf)
119+
{
120+
return-ENOSYS;
121+
}
122+
123+
staticinlineintnvmem_device_read(structnvmem_device*nvmem,
124+
unsignedintoffset,size_tbytes,
125+
void*buf)
126+
{
127+
return-ENOSYS;
128+
}
129+
130+
staticinlineintnvmem_device_write(structnvmem_device*nvmem,
131+
unsignedintoffset,size_tbytes,
132+
void*buf)
133+
{
134+
return-ENOSYS;
135+
}
71136
#endif/* CONFIG_NVMEM */
72137

73138
#ifIS_ENABLED(CONFIG_NVMEM)&&IS_ENABLED(CONFIG_OF)
74139
structnvmem_cell*of_nvmem_cell_get(structdevice_node*np,
75140
constchar*name);
141+
structnvmem_device*of_nvmem_device_get(structdevice_node*np,
142+
constchar*name);
76143
#else
77144
staticinlinestructnvmem_cell*of_nvmem_cell_get(structdevice_node*np,
78145
constchar*name)
79146
{
80147
returnERR_PTR(-ENOSYS);
81148
}
149+
150+
staticinlinestructnvmem_device*of_nvmem_device_get(structdevice_node*np,
151+
constchar*name)
152+
{
153+
returnERR_PTR(-ENOSYS);
154+
}
82155
#endif/* CONFIG_NVMEM && CONFIG_OF */
83156

84157
#endif/* ifndef _LINUX_NVMEM_CONSUMER_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp