diff options
Diffstat (limited to 'sound/soc/generic/simple-card.c')
-rw-r--r-- | sound/soc/generic/simple-card.c | 117 |
1 files changed, 52 insertions, 65 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 9c79ff6a568f..afe7e79ffdbd 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -5,6 +5,7 @@ // Copyright (C) 2012 Renesas Solutions Corp. // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +#include <linux/cleanup.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/module.h> @@ -119,32 +120,12 @@ static void simple_parse_convert(struct device *dev, struct simple_util_data *adata) { struct device_node *top = dev->of_node; - struct device_node *node = of_get_parent(np); + struct device_node *node __free(device_node) = of_get_parent(np); simple_util_parse_convert(top, PREFIX, adata); simple_util_parse_convert(node, PREFIX, adata); simple_util_parse_convert(node, NULL, adata); simple_util_parse_convert(np, NULL, adata); - - of_node_put(node); -} - -static void simple_parse_mclk_fs(struct device_node *top, - struct device_node *np, - struct simple_dai_props *props, - char *prefix) -{ - struct device_node *node = of_get_parent(np); - char prop[128]; - - snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); - of_property_read_u32(top, prop, &props->mclk_fs); - - snprintf(prop, sizeof(prop), "%smclk-fs", prefix); - of_property_read_u32(node, prop, &props->mclk_fs); - of_property_read_u32(np, prop, &props->mclk_fs); - - of_node_put(node); } static int simple_parse_node(struct simple_util_priv *priv, @@ -154,7 +135,6 @@ static int simple_parse_node(struct simple_util_priv *priv, int *cpu) { struct device *dev = simple_priv_to_dev(priv); - struct device_node *top = dev->of_node; struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); struct snd_soc_dai_link_component *dlc; @@ -169,8 +149,6 @@ static int simple_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, 0); } - simple_parse_mclk_fs(top, np, dai_props, prefix); - ret = simple_parse_dai(dev, np, dlc, cpu); if (ret) return ret; @@ -187,19 +165,50 @@ static int simple_parse_node(struct simple_util_priv *priv, } static int simple_link_init(struct simple_util_priv *priv, - struct device_node *node, + struct device_node *cpu, struct device_node *codec, struct link_info *li, char *prefix, char *name) { struct device *dev = simple_priv_to_dev(priv); + struct device_node *top = dev->of_node; struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); + struct device_node *node __free(device_node) = of_get_parent(cpu); + enum snd_soc_trigger_order trigger_start = SND_SOC_TRIGGER_ORDER_DEFAULT; + enum snd_soc_trigger_order trigger_stop = SND_SOC_TRIGGER_ORDER_DEFAULT; + bool playback_only = 0, capture_only = 0; int ret; ret = simple_util_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); if (ret < 0) - return 0; + return ret; + + graph_util_parse_link_direction(top, &playback_only, &capture_only); + graph_util_parse_link_direction(node, &playback_only, &capture_only); + graph_util_parse_link_direction(cpu, &playback_only, &capture_only); + graph_util_parse_link_direction(codec, &playback_only, &capture_only); + + of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec, PREFIX "mclk-fs", &dai_props->mclk_fs); + + graph_util_parse_trigger_order(priv, top, &trigger_start, &trigger_stop); + graph_util_parse_trigger_order(priv, node, &trigger_start, &trigger_stop); + graph_util_parse_trigger_order(priv, cpu, &trigger_start, &trigger_stop); + graph_util_parse_trigger_order(priv, codec, &trigger_start, &trigger_stop); + + dai_link->playback_only = playback_only; + dai_link->capture_only = capture_only; + + dai_link->trigger_start = trigger_start; + dai_link->trigger_stop = trigger_stop; dai_link->init = simple_util_dai_init; dai_link->ops = &simple_ops; @@ -217,7 +226,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); struct device_node *top = dev->of_node; - struct device_node *node = of_get_parent(np); + struct device_node *node __free(device_node) = of_get_parent(np); char *prefix = ""; char dai_name[64]; int ret; @@ -276,14 +285,11 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, simple_parse_convert(dev, np, &dai_props->adata); - snd_soc_dai_link_set_capabilities(dai_link); - - ret = simple_link_init(priv, node, codec, li, prefix, dai_name); + ret = simple_link_init(priv, np, codec, li, prefix, dai_name); out_put_node: li->link++; - of_node_put(node); return ret; } @@ -299,15 +305,13 @@ static int simple_dai_link_of(struct simple_util_priv *priv, struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, 0); struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, 0); struct device_node *cpu = NULL; - struct device_node *node = NULL; - struct device_node *plat = NULL; char dai_name[64]; char prop[128]; char *prefix = ""; int ret, single_cpu = 0; cpu = np; - node = of_get_parent(np); + struct device_node *node __free(device_node) = of_get_parent(np); dev_dbg(dev, "link_of (%pOF)\n", node); @@ -316,7 +320,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv, prefix = PREFIX; snprintf(prop, sizeof(prop), "%splat", prefix); - plat = of_get_child_by_name(node, prop); + struct device_node *plat __free(device_node) = of_get_child_by_name(node, prop); ret = simple_parse_node(priv, cpu, li, prefix, &single_cpu); if (ret < 0) @@ -336,12 +340,9 @@ static int simple_dai_link_of(struct simple_util_priv *priv, simple_util_canonicalize_cpu(cpus, single_cpu); simple_util_canonicalize_platform(platforms, cpus); - ret = simple_link_init(priv, node, codec, li, prefix, dai_name); + ret = simple_link_init(priv, cpu, codec, li, prefix, dai_name); dai_link_of_err: - of_node_put(plat); - of_node_put(node); - li->link++; return ret; @@ -361,7 +362,6 @@ static int __simple_for_each_link(struct simple_util_priv *priv, struct device *dev = simple_priv_to_dev(priv); struct device_node *top = dev->of_node; struct device_node *node; - struct device_node *add_devs; uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); bool is_top = 0; int ret = 0; @@ -373,14 +373,11 @@ static int __simple_for_each_link(struct simple_util_priv *priv, is_top = 1; } - add_devs = of_get_child_by_name(top, PREFIX "additional-devs"); + struct device_node *add_devs __free(device_node) = of_get_child_by_name(top, PREFIX "additional-devs"); /* loop for all dai-link */ do { struct simple_util_data adata; - struct device_node *codec; - struct device_node *plat; - struct device_node *np; int num = of_get_child_count(node); /* Skip additional-devs node */ @@ -390,26 +387,26 @@ static int __simple_for_each_link(struct simple_util_priv *priv, } /* get codec */ - codec = of_get_child_by_name(node, is_top ? - PREFIX "codec" : "codec"); + struct device_node *codec __free(device_node) = + of_get_child_by_name(node, is_top ? PREFIX "codec" : "codec"); if (!codec) { ret = -ENODEV; goto error; } /* get platform */ - plat = of_get_child_by_name(node, is_top ? - PREFIX "plat" : "plat"); + struct device_node *plat __free(device_node) = + of_get_child_by_name(node, is_top ? PREFIX "plat" : "plat"); /* get convert-xxx property */ memset(&adata, 0, sizeof(adata)); - for_each_child_of_node(node, np) { + for_each_child_of_node_scoped(node, np) { if (np == add_devs) continue; simple_parse_convert(dev, np, &adata); } /* loop for all CPU/Codec node */ - for_each_child_of_node(node, np) { + for_each_child_of_node_scoped(node, np) { if (plat == np || add_devs == np) continue; /* @@ -439,22 +436,16 @@ static int __simple_for_each_link(struct simple_util_priv *priv, ret = func_noml(priv, np, codec, li, is_top); } - if (ret < 0) { - of_node_put(codec); - of_node_put(plat); - of_node_put(np); + if (ret < 0) goto error; - } } - of_node_put(codec); - of_node_put(plat); node = of_get_next_child(top, node); } while (!is_top && node); error: - of_node_put(add_devs); of_node_put(node); + return ret; } @@ -501,15 +492,13 @@ static void simple_depopulate_aux(void *data) static int simple_populate_aux(struct simple_util_priv *priv) { struct device *dev = simple_priv_to_dev(priv); - struct device_node *node; + struct device_node *node __free(device_node) = of_get_child_by_name(dev->of_node, PREFIX "additional-devs"); int ret; - node = of_get_child_by_name(dev->of_node, PREFIX "additional-devs"); if (!node) return 0; ret = of_platform_populate(node, NULL, NULL, dev); - of_node_put(node); if (ret) return ret; @@ -713,7 +702,6 @@ static int simple_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct snd_soc_card *card; - struct link_info *li; int ret; /* Allocate the private data and the DAI link array */ @@ -727,7 +715,7 @@ static int simple_probe(struct platform_device *pdev) card->probe = simple_soc_probe; card->driver_name = "simple-card"; - li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); + struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); if (!li) return -ENOMEM; @@ -804,7 +792,6 @@ static int simple_probe(struct platform_device *pdev) if (ret < 0) goto err; - devm_kfree(dev, li); return 0; err: simple_util_clean_reference(card); @@ -827,7 +814,7 @@ static struct platform_driver simple_card = { .of_match_table = simple_of_match, }, .probe = simple_probe, - .remove_new = simple_util_remove, + .remove = simple_util_remove, }; module_platform_driver(simple_card); |