1818
1919struct devres_node ;
2020typedef void (* dr_node_release_t )(struct device * dev , struct devres_node * node );
21+ typedef void (* dr_node_free_t )(struct devres_node * node );
2122
2223struct devres_node {
2324 struct list_head entry ;
2425 dr_node_release_t release ;
26+ dr_node_free_t free_node ;
2527 const char * name ;
2628 size_t size ;
2729};
@@ -46,10 +48,18 @@ struct devres_group {
4648 /* -- 8 pointers */
4749};
4850
49- static void devres_node_init (struct devres_node * node , dr_node_release_t release )
51+ static void devres_node_init (struct devres_node * node ,
52+ dr_node_release_t release ,
53+ dr_node_free_t free_node )
5054{
5155 INIT_LIST_HEAD (& node -> entry );
5256 node -> release = release ;
57+ node -> free_node = free_node ;
58+ }
59+
60+ static inline void free_node (struct devres_node * node )
61+ {
62+ node -> free_node (node );
5363}
5464
5565static void set_node_dbginfo (struct devres_node * node , const char * name ,
@@ -124,6 +134,13 @@ static void dr_node_release(struct device *dev, struct devres_node *node)
124134 dr -> release (dev , dr -> data );
125135}
126136
137+ static void dr_node_free (struct devres_node * node )
138+ {
139+ struct devres * dr = container_of (node , struct devres , node );
140+
141+ kfree (dr );
142+ }
143+
127144static __always_inline struct devres * alloc_dr (dr_release_t release ,
128145 size_t size , gfp_t gfp , int nid )
129146{
@@ -141,7 +158,7 @@ static __always_inline struct devres *alloc_dr(dr_release_t release,
141158 if (!(gfp & __GFP_ZERO ))
142159 memset (dr , 0 , offsetof(struct devres , data ));
143160
144- devres_node_init (& dr -> node , dr_node_release );
161+ devres_node_init (& dr -> node , dr_node_release , dr_node_free );
145162 dr -> release = release ;
146163 return dr ;
147164}
@@ -233,6 +250,11 @@ void devres_for_each_res(struct device *dev, dr_release_t release,
233250}
234251EXPORT_SYMBOL_GPL (devres_for_each_res );
235252
253+ static inline void free_dr (struct devres * dr )
254+ {
255+ free_node (& dr -> node );
256+ }
257+
236258/**
237259 * devres_free - Free device resource data
238260 * @res: Pointer to devres data to free
@@ -245,7 +267,7 @@ void devres_free(void *res)
245267 struct devres * dr = container_of (res , struct devres , data );
246268
247269 BUG_ON (!list_empty (& dr -> node .entry ));
248- kfree (dr );
270+ free_dr (dr );
249271 }
250272}
251273EXPORT_SYMBOL_GPL (devres_free );
@@ -522,13 +544,10 @@ static void release_nodes(struct device *dev, struct list_head *todo)
522544{
523545 struct devres_node * node , * tmp ;
524546
525- /* Release. Note that devres, devres_action and devres_group are
526- * handled as devres_node in the following loop. This is safe.
527- */
528547 list_for_each_entry_safe_reverse (node , tmp , todo , entry ) {
529548 devres_log (dev , node , "REL" );
530549 node -> release (dev , node );
531- kfree (node );
550+ free_node (node );
532551 }
533552}
534553
@@ -561,6 +580,13 @@ int devres_release_all(struct device *dev)
561580 return cnt ;
562581}
563582
583+ static void devres_group_free (struct devres_node * node )
584+ {
585+ struct devres_group * grp = container_of (node , struct devres_group , node [0 ]);
586+
587+ kfree (grp );
588+ }
589+
564590/**
565591 * devres_open_group - Open a new devres group
566592 * @dev: Device to open devres group for
@@ -582,8 +608,8 @@ void *devres_open_group(struct device *dev, void *id, gfp_t gfp)
582608 if (unlikely (!grp ))
583609 return NULL ;
584610
585- devres_node_init (& grp -> node [0 ], & group_open_release );
586- devres_node_init (& grp -> node [1 ], & group_close_release );
611+ devres_node_init (& grp -> node [0 ], & group_open_release , devres_group_free );
612+ devres_node_init (& grp -> node [1 ], & group_close_release , NULL );
587613 set_node_dbginfo (& grp -> node [0 ], "grp<" , 0 );
588614 set_node_dbginfo (& grp -> node [1 ], "grp>" , 0 );
589615 grp -> id = grp ;
@@ -754,6 +780,13 @@ static void devm_action_release(struct device *dev, struct devres_node *node)
754780 devres -> action .action (devres -> action .data );
755781}
756782
783+ static void devm_action_free (struct devres_node * node )
784+ {
785+ struct devres_action * action = container_of (node , struct devres_action , node );
786+
787+ kfree (action );
788+ }
789+
757790/**
758791 * __devm_add_action() - add a custom action to list of managed resources
759792 * @dev: Device that owns the action
@@ -772,7 +805,7 @@ int __devm_add_action(struct device *dev, void (*action)(void *), void *data, co
772805 if (!devres )
773806 return - ENOMEM ;
774807
775- devres_node_init (& devres -> node , devm_action_release );
808+ devres_node_init (& devres -> node , devm_action_release , devm_action_free );
776809 set_node_dbginfo (& devres -> node , name , sizeof (* devres ));
777810
778811 devres -> action .data = data ;
@@ -1015,7 +1048,7 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp)
10151048 old_dr = find_dr (dev , devm_kmalloc_release , devm_kmalloc_match , ptr );
10161049 if (!old_dr ) {
10171050 spin_unlock_irqrestore (& dev -> devres_lock , flags );
1018- kfree (new_dr );
1051+ free_dr (new_dr );
10191052 WARN (1 , "Memory chunk not managed or managed by a different device." );
10201053 return NULL ;
10211054 }
@@ -1035,7 +1068,7 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp)
10351068 * list. This is also the reason why we must not use devm_kfree() - the
10361069 * links are no longer valid.
10371070 */
1038- kfree (old_dr );
1071+ free_dr (old_dr );
10391072
10401073 return new_dr -> data ;
10411074}
0 commit comments