mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
device property: Fix usecount for of_graph_get_port_parent()
Fix inconsistent use of of_graph_get_port_parent() where asoc_simple_card_parse_graph_dai() does of_node_get() before calling it while other callers do not. We can fix this by not trashing the node passed to of_graph_get_port_parent(). Let's also make sure the callers have correct refcounts and remove related incorrect of_node_put() calls for of_for_each_phandle as that's done by of_phandle_iterator_next() except when we break out of the loop early. Let's fix both issues with a single patch to avoid kobject refcounts getting messed up more if two patches are merged separately. Otherwise strange issues can happen caused by memory corruption caused by too many kobject_del() calls such as: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747 ... (___might_sleep) (__mutex_lock) (mutex_lock_nested) (kernfs_remove) (kobject_del) (kobject_put) (of_get_next_parent) (of_graph_get_port_parent) (asoc_simple_card_parse_graph_dai [snd_soc_simple_card_utils]) (asoc_graph_card_probe [snd_soc_audio_graph_card]) Fixes:0ef472a973("of_graph: add of_graph_get_port_parent()") Fixes:2692c1c63c("ASoC: add audio-graph-card support") Fixes:1689333f83("ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()") Signed-off-by: Tony Lindgren <[email protected]> Reviewed-by: Rob Herring <[email protected]> Tested-by: Antonio Borneo <[email protected]> Tested-by: Kuninori Morimoto <[email protected]> Signed-off-by: Mark Brown <[email protected]>
This commit is contained in:
parent
5771a8c088
commit
c0a480d1ac
5 changed files with 34 additions and 18 deletions
|
|
@ -708,6 +708,15 @@ struct device_node *of_graph_get_port_parent(struct device_node *node)
|
|||
{
|
||||
unsigned int depth;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Preserve usecount for passed in node as of_get_next_parent()
|
||||
* will do of_node_put() on it.
|
||||
*/
|
||||
of_node_get(node);
|
||||
|
||||
/* Walk 3 levels up only if there is 'ports' node. */
|
||||
for (depth = 3; depth && node; depth--) {
|
||||
node = of_get_next_parent(node);
|
||||
|
|
@ -728,12 +737,16 @@ EXPORT_SYMBOL(of_graph_get_port_parent);
|
|||
struct device_node *of_graph_get_remote_port_parent(
|
||||
const struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device_node *np, *pp;
|
||||
|
||||
/* Get remote endpoint node. */
|
||||
np = of_graph_get_remote_endpoint(node);
|
||||
|
||||
return of_graph_get_port_parent(np);
|
||||
pp = of_graph_get_port_parent(np);
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(of_graph_get_remote_port_parent);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue