@@ -456,6 +456,73 @@ static int nvmem_add_cells_from_table(struct nvmem_device *nvmem)
456
456
return rval ;
457
457
}
458
458
459
+ static struct nvmem_cell *
460
+ nvmem_find_cell_by_index (struct nvmem_device * nvmem , int index )
461
+ {
462
+ struct nvmem_cell * cell = NULL ;
463
+ int i = 0 ;
464
+
465
+ mutex_lock (& nvmem_mutex );
466
+ list_for_each_entry (cell , & nvmem -> cells , node ) {
467
+ if (index == i ++ )
468
+ break ;
469
+ }
470
+ mutex_unlock (& nvmem_mutex );
471
+
472
+ return cell ;
473
+ }
474
+
475
+ static int nvmem_add_cells_from_of (struct nvmem_device * nvmem )
476
+ {
477
+ struct device_node * parent , * child ;
478
+ struct device * dev = & nvmem -> dev ;
479
+ struct nvmem_cell * cell ;
480
+ const __be32 * addr ;
481
+ int len ;
482
+
483
+ parent = dev -> of_node ;
484
+
485
+ for_each_child_of_node (parent , child ) {
486
+ addr = of_get_property (child , "reg" , & len );
487
+ if (!addr || (len < 2 * sizeof (u32 ))) {
488
+ dev_err (dev , "nvmem: invalid reg on %pOF\n" , child );
489
+ return - EINVAL ;
490
+ }
491
+
492
+ cell = kzalloc (sizeof (* cell ), GFP_KERNEL );
493
+ if (!cell )
494
+ return - ENOMEM ;
495
+
496
+ cell -> nvmem = nvmem ;
497
+ cell -> offset = be32_to_cpup (addr ++ );
498
+ cell -> bytes = be32_to_cpup (addr );
499
+ cell -> name = child -> name ;
500
+
501
+ addr = of_get_property (child , "bits" , & len );
502
+ if (addr && len == (2 * sizeof (u32 ))) {
503
+ cell -> bit_offset = be32_to_cpup (addr ++ );
504
+ cell -> nbits = be32_to_cpup (addr );
505
+ }
506
+
507
+ if (cell -> nbits )
508
+ cell -> bytes = DIV_ROUND_UP (
509
+ cell -> nbits + cell -> bit_offset ,
510
+ BITS_PER_BYTE );
511
+
512
+ if (!IS_ALIGNED (cell -> offset , nvmem -> stride )) {
513
+ dev_err (dev , "cell %s unaligned to nvmem stride %d\n" ,
514
+ cell -> name , nvmem -> stride );
515
+ /* Cells already added will be freed later. */
516
+ kfree (cell );
517
+ return - EINVAL ;
518
+ }
519
+
520
+ nvmem_cell_add (cell );
521
+ }
522
+
523
+ return 0 ;
524
+ }
525
+
459
526
/**
460
527
* nvmem_register() - Register a nvmem device for given nvmem_config.
461
528
* Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -546,6 +613,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
546
613
if (rval )
547
614
goto err_remove_cells ;
548
615
616
+ rval = nvmem_add_cells_from_of (nvmem );
617
+ if (rval )
618
+ goto err_remove_cells ;
619
+
549
620
return nvmem ;
550
621
551
622
err_remove_cells :
@@ -848,10 +919,8 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
848
919
const char * name )
849
920
{
850
921
struct device_node * cell_np , * nvmem_np ;
851
- struct nvmem_cell * cell ;
852
922
struct nvmem_device * nvmem ;
853
- const __be32 * addr ;
854
- int rval , len ;
923
+ struct nvmem_cell * cell ;
855
924
int index = 0 ;
856
925
857
926
/* if cell name exists, find index to the name */
@@ -871,54 +940,13 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
871
940
if (IS_ERR (nvmem ))
872
941
return ERR_CAST (nvmem );
873
942
874
- addr = of_get_property (cell_np , "reg" , & len );
875
- if (!addr || (len < 2 * sizeof (u32 ))) {
876
- dev_err (& nvmem -> dev , "nvmem: invalid reg on %pOF\n" ,
877
- cell_np );
878
- rval = - EINVAL ;
879
- goto err_mem ;
880
- }
881
-
882
- cell = kzalloc (sizeof (* cell ), GFP_KERNEL );
943
+ cell = nvmem_find_cell_by_index (nvmem , index );
883
944
if (!cell ) {
884
- rval = - ENOMEM ;
885
- goto err_mem ;
886
- }
887
-
888
- cell -> nvmem = nvmem ;
889
- cell -> offset = be32_to_cpup (addr ++ );
890
- cell -> bytes = be32_to_cpup (addr );
891
- cell -> name = cell_np -> name ;
892
-
893
- addr = of_get_property (cell_np , "bits" , & len );
894
- if (addr && len == (2 * sizeof (u32 ))) {
895
- cell -> bit_offset = be32_to_cpup (addr ++ );
896
- cell -> nbits = be32_to_cpup (addr );
897
- }
898
-
899
- if (cell -> nbits )
900
- cell -> bytes = DIV_ROUND_UP (cell -> nbits + cell -> bit_offset ,
901
- BITS_PER_BYTE );
902
-
903
- if (!IS_ALIGNED (cell -> offset , nvmem -> stride )) {
904
- dev_err (& nvmem -> dev ,
905
- "cell %s unaligned to nvmem stride %d\n" ,
906
- cell -> name , nvmem -> stride );
907
- rval = - EINVAL ;
908
- goto err_sanity ;
945
+ __nvmem_device_put (nvmem );
946
+ return ERR_PTR (- ENOENT );
909
947
}
910
948
911
- nvmem_cell_add (cell );
912
-
913
949
return cell ;
914
-
915
- err_sanity :
916
- kfree (cell );
917
-
918
- err_mem :
919
- __nvmem_device_put (nvmem );
920
-
921
- return ERR_PTR (rval );
922
950
}
923
951
EXPORT_SYMBOL_GPL (of_nvmem_cell_get );
924
952
#endif
@@ -1024,7 +1052,6 @@ void nvmem_cell_put(struct nvmem_cell *cell)
1024
1052
struct nvmem_device * nvmem = cell -> nvmem ;
1025
1053
1026
1054
__nvmem_device_put (nvmem );
1027
- nvmem_cell_drop (cell );
1028
1055
}
1029
1056
EXPORT_SYMBOL_GPL (nvmem_cell_put );
1030
1057
0 commit comments