From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932103AbcGOFS0 (ORCPT ); Fri, 15 Jul 2016 01:18:26 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:45409 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751503AbcGOFSX (ORCPT ); Fri, 15 Jul 2016 01:18:23 -0400 X-AuditID: cbfee68e-f79266d000001428-e8-5788721c9efd Message-id: <5788721B.7010602@samsung.com> Date: Fri, 15 Jul 2016 14:18:19 +0900 From: Chanwoo Choi User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-version: 1.0 To: Sylwester Nawrocki , broonie@kernel.org Cc: robh@kernel.org, alsa-devel@alsa-project.org, devicetree@vger.kernel.org, ideal.song@samsung.com, inki.dae@samsung.com, b.zolnierkie@samsung.com, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Krzysztof Kozlowski Subject: Re: [PATCH v4 4/4] ASoC: samsung: Add machine driver for Exynos5433 based TM2 board References: <1467738877-31555-1-git-send-email-s.nawrocki@samsung.com> In-reply-to: <1467738877-31555-1-git-send-email-s.nawrocki@samsung.com> Content-type: text/plain; charset=windows-1252 Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrPIsWRmVeSWpSXmKPExsWyRsSkUFemqCPcoKtRxuLKxUNMFhtnrGe1 mPrwCZvF/CPnWC12/b3PaDHp/gQWi9cvDC0u75rDZjHj/D4mi/97drBbHH7TzurA7bHhcxOb x6ZVnWwefVtWMXp83iQXwBLFZZOSmpNZllqkb5fAlfHkVSN7wWXVikmPt7A3MG6T62Lk4JAQ MJFYdCeki5ETyBSTuHBvPVsXIxeHkMAKRom+OztZIBImEn8n/WOHSMxilJg+7w0ThPOAUWLj sbmMIFW8AloSl04sYQWxWQRUJU4duskEYrMBxfe/uMEGsk1UIEKi+0QlRLmgxI/J91hAwiIC zhL3V7OAjGQW6GKSaNq6nhmkRlggTuLero9Qi+cwSqw4sQhsPqeAO5B9nxWkmVlAT+L+RS2Q MLOAvMTmNW+ZQeolBF6yS7QvaWKDuEdA4tvkQywQH8tKbDrADPGYpMTBFTdYJjCKzUJy0iyE qbOQTF3AyLyKUTS1ILmgOCm9yEivODG3uDQvXS85P3cTIzAeT/971reD8eYB60OMAhyMSjy8 Akfbw4VYE8uKK3MPMZoCHTGRWUo0OR8Y9Xkl8YbGZkYWpiamxkbmlmZK4rwJUj+DhQTSE0tS s1NTC1KL4otKc1KLDzEycXBKNTByZS8y+de96PA33oJnp1snXaxLDDZ47xD6R78ymH39IjY9 n4BTT7tVn3bI7qpNm/Nh47Qfv60lxWKbP+S1XG3wSZOWsU9JjtwzvUuKuXDrdO5FJS32tZG+ sdIv2G/PM95mLKD/9/Vh4fWmH0SWnAh02pV16kpG8x7FPNlFMms5sz8J+sZ/l1FiKc5INNRi LipOBAAJM97IwgIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrLIsWRmVeSWpSXmKPExsVy+t9jQV3poo5wg74nVhZXLh5istg4Yz2r xdSHT9gs5h85x2qx6+99RotJ9yewWLx+YWhxedccNosZ5/cxWfzfs4Pd4vCbdlYHbo8Nn5vY PDat6mTz6NuyitHj8ya5AJaoBkabjNTElNQihdS85PyUzLx0WyXv4HjneFMzA0NdQ0sLcyWF vMTcVFslF58AXbfMHKCrlBTKEnNKgUIBicXFSvp2mCaEhrjpWsA0Ruj6hgTB9RgZoIGENYwZ T141shdcVq2Y9HgLewPjNrkuRk4OCQETib+T/rFD2GISF+6tZ+ti5OIQEpjFKDF93hsmCOcB o8TGY3MZQap4BbQkLp1YwgpiswioSpw6dJMJxGYDiu9/cQOom4NDVCBCovtEJUS5oMSPyfdY QMIiAs4S91ezgIxkFuhikmjaup4ZpEZYIE7i3q6P7BC75jBKrDixCGw+p4A7kH2fFaSZWUBP 4v5FLZAws4C8xOY1b5knMAJdibBiFkLVLCRVCxiZVzFKpBYkFxQnpeca5aWW6xUn5haX5qXr JefnbmIER/0z6R2Mh3e5H2IU4GBU4uFl8O0IF2JNLCuuzD3EKMHBrCTCy18AFOJNSaysSi3K jy8qzUktPsRoCgyCicxSosn5wISUVxJvaGxiZmRpZG5oYWRsriTO+/j/ujAhgfTEktTs1NSC 1CKYPiYOTqkGxuUZopoX0mwCt6rk7Nu1bZdU3om+uiPz5rfxNl3+VXCoyCyjNWzJZsVjnwWP STaLGG3Vu/VKwraKQ+ExsyTLWlaB242id/fW3/NSYvfk+zPb9QvPi/i3AQmFKy8K79Nu/+gt bK1htkGk7FSlmc3xJ8qv4pVUL3/c+qqp4sjBqfvXzrnRWpm/QImlOCPRUIu5qDgRAB9bllAQ AwAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Sylwester, [snip] > +static int tm2_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct snd_soc_card *card = &tm2_card; > + struct tm2_machine_priv *priv; > + struct device_node *cpu_dai_node, *codec_dai_node; > + int ret, i; > + > + if (!dev->of_node) { > + dev_err(dev, "DT node is missing\n"); > + return -ENODEV; > + } > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + snd_soc_card_set_drvdata(card, priv); > + card->dev = dev; > + > + priv->gpio_mic_bias = devm_gpiod_get(dev, "mic-bias", > + GPIOF_OUT_INIT_LOW); > + if (IS_ERR(priv->gpio_mic_bias)) { > + dev_err(dev, "Failed to get mic bias gpio\n"); > + return PTR_ERR(priv->gpio_mic_bias); > + } > + > + ret = snd_soc_of_parse_card_name(card, "model"); > + if (ret < 0) { > + dev_err(dev, "Card name is not specified\n"); > + return ret; > + } > + > + ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing"); > + if (ret < 0) { > + dev_err(dev, "Audio routing is not specified or invalid\n"); > + return ret; > + } > + > + card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node, > + "audio-amplifier", 0); > + if (!card->aux_dev[0].codec_of_node) { > + dev_err(dev, "audio-amplifier property invalid or missing\n"); > + return -EINVAL; > + } > + > + cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0); > + if (!cpu_dai_node) { > + dev_err(dev, "i2s-controllers property invalid or missing\n"); > + ret = -EINVAL; > + goto err_put_amp; > + } > + > + codec_dai_node = of_parse_phandle(dev->of_node, "audio-codec", 0); > + if (!codec_dai_node) { > + dev_err(dev, "audio-codec property invalid or missing\n"); > + ret = -EINVAL; > + goto err_put_cpu_dai; > + } > + > + for (i = 0; i < card->num_links; i++) { > + card->dai_link[i].cpu_dai_name = NULL; > + card->dai_link[i].cpu_name = NULL; > + card->dai_link[i].platform_name = NULL; > + card->dai_link[i].codec_of_node = codec_dai_node; > + card->dai_link[i].cpu_of_node = cpu_dai_node; > + card->dai_link[i].platform_of_node = cpu_dai_node; > + } > + > + priv->codec_mclk1 = of_clk_get_by_name(codec_dai_node, "mclk1"); > + if (IS_ERR(priv->codec_mclk1)) { > + dev_err(dev, "Failed to get mclk1 clock\n"); > + ret = PTR_ERR(priv->codec_mclk1); > + goto err_put_codec_dai; > + } I think that you better to use the devm_clk_get() instead of of_clk_get_by_name() because you don't need to handle the clk_put() when error happen and remove the this driver. priv->codec_mclk1 = devm_clk_get(dev, "mclk1"); > + > + /* mclk2 is optional */ > + priv->codec_mclk2 = of_clk_get_by_name(codec_dai_node, "mclk2"); > + if (IS_ERR(priv->codec_mclk2)) > + dev_info(dev, "Not using mclk2 clock\n"); priv->codec_mclk2 = devm_clk_get(dev, "mclk2"); > + > + ret = devm_snd_soc_register_component(dev, &tm2_component, > + tm2_ext_dai, ARRAY_SIZE(tm2_ext_dai)); > + if (ret < 0) { > + dev_err(dev, "Failed to register component: %d\n", ret); > + goto err_put_mclk; > + } > + > + ret = devm_snd_soc_register_card(dev, card); > + if (ret < 0) { > + dev_err(dev, "Failed to register card: %d\n", ret); > + goto err_put_mclk; > + } > + > + return 0; > + > +err_put_mclk: > + clk_put(priv->codec_mclk1); > + if (!IS_ERR(priv->codec_mclk2)) > + clk_put(priv->codec_mclk2); If using the devm_clk_get(), clk_put() is not needed > +err_put_codec_dai: > + of_node_put(codec_dai_node); > +err_put_cpu_dai: > + of_node_put(cpu_dai_node); > +err_put_amp: > + of_node_put(card->aux_dev[0].codec_of_node); > + return ret; > +} > + > +static int tm2_remove(struct platform_device *pdev) > +{ > + struct snd_soc_card *card = &tm2_card; > + struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); > + > + clk_put(priv->codec_mclk1); > + if (!IS_ERR(priv->codec_mclk2)) > + clk_put(priv->codec_mclk2); ditto. > + > + of_node_put(card->dai_link[0].codec_of_node); > + of_node_put(card->dai_link[0].cpu_of_node); > + of_node_put(card->aux_dev[0].codec_of_node); > + > + return 0; > +} > + > +static const struct of_device_id tm2_of_match[] = { > + { .compatible = "samsung,tm2-audio" }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, tm2_of_match); > + > +static struct platform_driver tm2_driver = { > + .driver = { > + .name = "tm2-audio", > + .pm = &snd_soc_pm_ops, > + .of_match_table = tm2_of_match, > + }, > + .probe = tm2_probe, > + .remove = tm2_remove, > +}; > + > +module_platform_driver(tm2_driver); > + > +MODULE_AUTHOR("Inha Song "); > +MODULE_DESCRIPTION("ALSA SoC Exynos TM2 Audio Support"); > +MODULE_LICENSE("GPL v2"); > Thanks, Chanwoo Choi