From patchwork Thu Mar 26 04:02:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 6096421 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9DF669F399 for ; Thu, 26 Mar 2015 04:04:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7BAEC202EB for ; Thu, 26 Mar 2015 04:04:01 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 15C5E201BB for ; Thu, 26 Mar 2015 04:04:00 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 29DE82654ED; Thu, 26 Mar 2015 05:03:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id F23D12654F1; Thu, 26 Mar 2015 05:03:04 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3B8692654F1; Thu, 26 Mar 2015 05:03:04 +0100 (CET) Received: from relmlie2.idc.renesas.com (relmlor3.renesas.com [210.160.252.173]) by alsa0.perex.cz (Postfix) with ESMTP id 349352654ED for ; Thu, 26 Mar 2015 05:02:12 +0100 (CET) Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie2.idc.renesas.com with ESMTP; 26 Mar 2015 13:02:11 +0900 Received: from relmlac3.idc.renesas.com (relmlac3.idc.renesas.com [10.200.69.23]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id BF4DE4B51F; Thu, 26 Mar 2015 13:02:11 +0900 (JST) Received: by relmlac3.idc.renesas.com (Postfix, from userid 0) id A94CF18070; Thu, 26 Mar 2015 13:02:11 +0900 (JST) Received: from relmlac3.idc.renesas.com (localhost [127.0.0.1]) by relmlac3.idc.renesas.com (Postfix) with ESMTP id A4D841806F; Thu, 26 Mar 2015 13:02:11 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac3.idc.renesas.com with ESMTP id PAL11793; Thu, 26 Mar 2015 13:02:11 +0900 X-IronPort-AV: E=Sophos;i="5.11,469,1422889200"; d="scan'208";a="182778399" Received: from mail-hk1lp0119.outbound.protection.outlook.com (HELO APAC01-HK1-obe.outbound.protection.outlook.com) ([207.46.51.119]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 26 Mar 2015 13:02:11 +0900 Received: from morimoto-PC.renesas.com (211.11.155.132) by HKXPR06MB310.apcprd06.prod.outlook.com (10.141.135.152) with Microsoft SMTP Server (TLS) id 15.1.118.21; Thu, 26 Mar 2015 04:02:09 +0000 Message-ID: <87d23w5rvo.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") To: Mark Brown In-Reply-To: <87h9t85ry1.wl%kuninori.morimoto.gx@renesas.com> References: <87h9t85ry1.wl%kuninori.morimoto.gx@renesas.com> Date: Thu, 26 Mar 2015 04:02:09 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: OS1PR01CA0015.jpnprd01.prod.outlook.com (25.161.225.153) To HKXPR06MB310.apcprd06.prod.outlook.com (10.141.135.152) Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HKXPR06MB310; X-Microsoft-Antispam-PRVS: X-Forefront-Antispam-Report: BMV:1; SFV:NSPM; SFS:(10019020)(6009001)(19580395003)(23726002)(19580405001)(66066001)(77096005)(36756003)(87976001)(575784001)(40100003)(50466002)(47776003)(2950100001)(83506001)(76176999)(122386002)(54356999)(92566002)(62966003)(77156002)(50986999)(53416004)(42186005)(229853001)(33646002)(46102003)(86362001)(46406003)(110136001); DIR:OUT; SFP:1102; SCL:1; SRVR:HKXPR06MB310; H:morimoto-PC.renesas.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(5002010); SRVR:HKXPR06MB310; BCL:0; PCL:0; RULEID:; SRVR:HKXPR06MB310; X-Forefront-PRVS: 0527DFA348 X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Mar 2015 04:02:09.4964 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HKXPR06MB310 Cc: Linux-DT , Linux-ALSA , Simon , Liam Girdwood , Das Biju Subject: [alsa-devel] [PATCH 3/5 v2] ASoC: rsnd: call clk_prepare/unprepare() in probe/remove X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto clk_prepare_enable()/clk_disable_unprepare() uses mutex inside, in concretely clk_prepare()/clk_unprepare().And it uses __schedule(). Then, raw_spin_lock/unlock_irq() is called, and it breaks Renesas sound driver's spin lock irq. This patch separates thesse into clk_prepare()/clk_unprepare() and clk_enable/clk_disable. And call clk_prepare()/clk_unprepare() from probe/remove function. Special thanks to Das Biju. Reported-by: Das Biju Signed-off-by: Kuninori Morimoto --- v1 -> v2 - separate clk_prepare_enable()/clk_disable_unprepare() into clk_prepare()/clk_unprepare() and clk_enable()/clk_disable() sound/soc/sh/rcar/core.c | 24 +++++++++++++++++++++++- sound/soc/sh/rcar/dvc.c | 17 +++++++++++++++-- sound/soc/sh/rcar/rsnd.h | 11 ++++++++--- sound/soc/sh/rcar/src.c | 17 +++++++++++++++-- sound/soc/sh/rcar/ssi.c | 17 +++++++++++++++-- 5 files changed, 76 insertions(+), 10 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8d67042..b20e5bd 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -145,16 +145,29 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod) return mod->ops->dma_req(mod); } -void rsnd_mod_init(struct rsnd_mod *mod, +int rsnd_mod_init(struct rsnd_mod *mod, struct rsnd_mod_ops *ops, struct clk *clk, enum rsnd_mod_type type, int id) { + int ret = clk_prepare(clk); + + if (ret) + return ret; + mod->id = id; mod->ops = ops; mod->type = type; mod->clk = clk; + + return ret; +} + +void rsnd_mod_quit(struct rsnd_mod *mod) +{ + if (mod->clk) + clk_unprepare(mod->clk); } /* @@ -1073,6 +1086,12 @@ static int rsnd_remove(struct platform_device *pdev) { struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); struct rsnd_dai *rdai; + void (*remove_func[])(struct platform_device *pdev, + struct rsnd_priv *priv) = { + rsnd_ssi_remove, + rsnd_src_remove, + rsnd_dvc_remove, + }; int ret = 0, i; pm_runtime_disable(&pdev->dev); @@ -1082,6 +1101,9 @@ static int rsnd_remove(struct platform_device *pdev) ret |= rsnd_dai_call(remove, &rdai->capture, priv); } + for (i = 0; i < ARRAY_SIZE(remove_func); i++) + remove_func[i](pdev, priv); + snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index aeeef13..d8a0837 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -345,7 +345,7 @@ int rsnd_dvc_probe(struct platform_device *pdev, struct rsnd_dvc *dvc; struct clk *clk; char name[RSND_DVC_NAME_SIZE]; - int i, nr; + int i, nr, ret; rsnd_of_parse_dvc(pdev, of_data, priv); @@ -378,11 +378,24 @@ int rsnd_dvc_probe(struct platform_device *pdev, dvc->info = &info->dvc_info[i]; - rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, + ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, clk, RSND_MOD_DVC, i); + if (ret) + return ret; dev_dbg(dev, "CMD%d probed\n", i); } return 0; } + +void rsnd_dvc_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_dvc *dvc; + int i; + + for_each_rsnd_dvc(dvc, priv, i) { + rsnd_mod_quit(&dvc->mod); + } +} diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5f35af7..f7af0be 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -285,14 +285,15 @@ struct rsnd_mod { #define rsnd_mod_to_dma(mod) (&(mod)->dma) #define rsnd_mod_to_io(mod) ((mod)->io) #define rsnd_mod_id(mod) ((mod)->id) -#define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) -#define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk) +#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) +#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) -void rsnd_mod_init(struct rsnd_mod *mod, +int rsnd_mod_init(struct rsnd_mod *mod, struct rsnd_mod_ops *ops, struct clk *clk, enum rsnd_mod_type type, int id); +void rsnd_mod_quit(struct rsnd_mod *mod); char *rsnd_mod_name(struct rsnd_mod *mod); struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); @@ -496,6 +497,8 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, int rsnd_src_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); +void rsnd_src_remove(struct platform_device *pdev, + struct rsnd_priv *priv); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, @@ -514,6 +517,8 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); int rsnd_ssi_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); +void rsnd_ssi_remove(struct platform_device *pdev, + struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index cc93f32..6099a8e 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -867,7 +867,7 @@ int rsnd_src_probe(struct platform_device *pdev, struct rsnd_mod_ops *ops; struct clk *clk; char name[RSND_SRC_NAME_SIZE]; - int i, nr; + int i, nr, ret; ops = NULL; if (rsnd_is_gen1(priv)) @@ -907,10 +907,23 @@ int rsnd_src_probe(struct platform_device *pdev, src->info = &info->src_info[i]; - rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); + ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); + if (ret) + return ret; dev_dbg(dev, "SRC%d probed\n", i); } return 0; } + +void rsnd_src_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_src *src; + int i; + + for_each_rsnd_src(src, priv, i) { + rsnd_mod_quit(&src->mod); + } +} diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 060d3d2..79dc7a3 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -710,7 +710,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, struct clk *clk; struct rsnd_ssi *ssi; char name[RSND_SSI_NAME_SIZE]; - int i, nr; + int i, nr, ret; rsnd_of_parse_ssi(pdev, of_data, priv); @@ -745,10 +745,23 @@ int rsnd_ssi_probe(struct platform_device *pdev, else if (rsnd_ssi_pio_available(ssi)) ops = &rsnd_ssi_pio_ops; - rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); + ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); + if (ret) + return ret; rsnd_ssi_parent_clk_setup(priv, ssi); } return 0; } + +void rsnd_ssi_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_ssi *ssi; + int i; + + for_each_rsnd_ssi(ssi, priv, i) { + rsnd_mod_quit(&ssi->mod); + } +}