From patchwork Tue Mar 24 05:04:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 6077181 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 A6CFB9F2A9 for ; Tue, 24 Mar 2015 05:06:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9697520260 for ; Tue, 24 Mar 2015 05:06:17 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id E4ECE201FA for ; Tue, 24 Mar 2015 05:06:15 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 24584264F28; Tue, 24 Mar 2015 06:06:13 +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 58D402625FF; Tue, 24 Mar 2015 06:05:47 +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 CD244264F39; Tue, 24 Mar 2015 06:05:46 +0100 (CET) Received: from relmlie3.idc.renesas.com (relmlor4.renesas.com [210.160.252.174]) by alsa0.perex.cz (Postfix) with ESMTP id 94116261B21 for ; Tue, 24 Mar 2015 06:05:00 +0100 (CET) Received: from unknown (HELO relmlir1.idc.renesas.com) ([10.200.68.151]) by relmlie3.idc.renesas.com with ESMTP; 24 Mar 2015 14:04:59 +0900 Received: from relmlac3.idc.renesas.com (relmlac3.idc.renesas.com [10.200.69.23]) by relmlir1.idc.renesas.com (Postfix) with ESMTP id 33446538D5; Tue, 24 Mar 2015 14:04:59 +0900 (JST) Received: by relmlac3.idc.renesas.com (Postfix, from userid 0) id 34D2D1806F; Tue, 24 Mar 2015 14:04:59 +0900 (JST) Received: from relmlac3.idc.renesas.com (localhost [127.0.0.1]) by relmlac3.idc.renesas.com (Postfix) with ESMTP id 1C3BA18077; Tue, 24 Mar 2015 14:04:59 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac3.idc.renesas.com with ESMTP id QAX31032; Tue, 24 Mar 2015 14:04:59 +0900 X-IronPort-AV: E=Sophos;i="5.11,456,1422889200"; d="scan'208";a="182614022" Received: from mail-hk1lp0126.outbound.protection.outlook.com (HELO APAC01-HK1-obe.outbound.protection.outlook.com) ([207.46.51.126]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 24 Mar 2015 14:04:58 +0900 Received: from morimoto-PC.renesas.com (211.11.155.132) by HKNPR06MB308.apcprd06.prod.outlook.com (10.141.37.28) with Microsoft SMTP Server (TLS) id 15.1.118.21; Tue, 24 Mar 2015 05:04:56 +0000 Message-ID: <874mpb3s14.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 To: Mark Brown In-Reply-To: <878uen3s5m.wl%kuninori.morimoto.gx@renesas.com> References: <878uen3s5m.wl%kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Tue, 24 Mar 2015 05:04:56 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: TY1PR0201CA0018.apcprd02.prod.outlook.com (25.164.90.156) To HKNPR06MB308.apcprd06.prod.outlook.com (10.141.37.28) Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HKNPR06MB308; X-Microsoft-Antispam-PRVS: X-Forefront-Antispam-Report: BMV:1; SFV:NSPM; SFS:(10019020)(6009001)(53416004)(92566002)(46102003)(2950100001)(229853001)(47776003)(87976001)(19580395003)(77096005)(110136001)(50466002)(19580405001)(83506001)(23726002)(50986999)(76176999)(33646002)(54356999)(46406003)(40100003)(86362001)(62966003)(66066001)(36756003)(77156002)(122386002)(42186005); DIR:OUT; SFP:1102; SCL:1; SRVR:HKNPR06MB308; 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:HKNPR06MB308; BCL:0; PCL:0; RULEID:; SRVR:HKNPR06MB308; X-Forefront-PRVS: 0525BB0ADF X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Mar 2015 05:04:56.5943 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HKNPR06MB308 Cc: Linux-DT , Linux-ALSA , Simon , Liam Girdwood , Das Biju Subject: [alsa-devel] [PATCH 3/5] ASoC: rsnd: call clk_prepare_enable/unprepare() from 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/unprepare() uses mutex inside, and it uses __schedule(). Then, raw_spin_lock/unlock_irq() is called, and it breaks Renesas sound driver's spin lock irq. This patch moves clk_prepare_enable/unprepare to probe/remove function. Special thanks to Das Biju. Reported-by: Das Biju Signed-off-by: Kuninori Morimoto --- - it should goes to linus/master too sound/soc/sh/rcar/core.c | 14 ++++++++++++++ sound/soc/sh/rcar/dvc.c | 20 +++++++------------- sound/soc/sh/rcar/rsnd.h | 4 ++-- sound/soc/sh/rcar/src.c | 18 ++++++++++++------ sound/soc/sh/rcar/ssi.c | 25 ++++++++++++++++--------- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8d67042..398eb8f 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -157,6 +157,20 @@ void rsnd_mod_init(struct rsnd_mod *mod, mod->clk = clk; } +int rsnd_mod_probe(struct rsnd_mod *mod, + struct rsnd_priv *priv) +{ + return clk_prepare_enable(mod->clk); +} + +int rsnd_mod_remove(struct rsnd_mod *mod, + struct rsnd_priv *priv) +{ + clk_disable_unprepare(mod->clk); + + return 0; +} + /* * settting function */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index aeeef13..8f7558c 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -123,11 +123,16 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); + int ret; + + ret = rsnd_mod_probe(mod, priv); + if (ret) + return ret; dev_dbg(dev, "%s[%d] (Gen2) is probed\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - return 0; + return ret; } static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, @@ -141,7 +146,7 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, rsnd_kctrl_remove(dvc->rup); rsnd_kctrl_remove(dvc->rdown); - return 0; + return rsnd_mod_remove(mod, priv); } static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, @@ -166,8 +171,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, return -EINVAL; } - rsnd_mod_hw_start(dvc_mod); - /* * fixme * it doesn't support CTU/MIX @@ -191,14 +194,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, return 0; } -static int rsnd_dvc_quit(struct rsnd_mod *mod, - struct rsnd_priv *priv) -{ - rsnd_mod_hw_stop(mod); - - return 0; -} - static int rsnd_dvc_start(struct rsnd_mod *mod, struct rsnd_priv *priv) { @@ -286,7 +281,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = { .probe = rsnd_dvc_probe_gen2, .remove = rsnd_dvc_remove_gen2, .init = rsnd_dvc_init, - .quit = rsnd_dvc_quit, .start = rsnd_dvc_start, .stop = rsnd_dvc_stop, .pcm_new = rsnd_dvc_pcm_new, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5f35af7..49ea11b 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -285,9 +285,9 @@ 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) +int rsnd_mod_probe(struct rsnd_mod *mod, struct rsnd_priv *priv); +int rsnd_mod_remove(struct rsnd_mod *mod, struct rsnd_priv *priv); void rsnd_mod_init(struct rsnd_mod *mod, struct rsnd_mod_ops *ops, struct clk *clk, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index cc93f32..327771a 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -292,8 +292,6 @@ static int rsnd_src_init(struct rsnd_mod *mod) { struct rsnd_src *src = rsnd_mod_to_src(mod); - rsnd_mod_hw_start(mod); - src->err = 0; /* @@ -311,8 +309,6 @@ static int rsnd_src_quit(struct rsnd_mod *mod, struct rsnd_src *src = rsnd_mod_to_src(mod); struct device *dev = rsnd_priv_to_dev(priv); - rsnd_mod_hw_stop(mod); - if (src->err) dev_warn(dev, "%s[%d] under/over flow err = %d\n", rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); @@ -464,11 +460,16 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); + int ret; + + ret = rsnd_mod_probe(mod, priv); + if (ret) + return ret; dev_dbg(dev, "%s[%d] (Gen1) is probed\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - return 0; + return ret; } static int rsnd_src_init_gen1(struct rsnd_mod *mod, @@ -519,6 +520,7 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { .name = SRC_NAME, .dma_req = rsnd_src_dma_req, .probe = rsnd_src_probe_gen1, + .remove = rsnd_mod_remove, .init = rsnd_src_init_gen1, .quit = rsnd_src_quit, .start = rsnd_src_start_gen1, @@ -734,6 +736,10 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, if (ret) goto rsnd_src_probe_gen2_fail; + ret = rsnd_mod_probe(mod, priv); + if (ret) + goto rsnd_src_probe_gen2_fail; + dev_dbg(dev, "%s[%d] (Gen2) is probed\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); @@ -751,7 +757,7 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, { rsnd_dma_quit(rsnd_mod_to_dma(mod)); - return 0; + return rsnd_mod_remove(mod, priv); } static int rsnd_src_init_gen2(struct rsnd_mod *mod, diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 060d3d2..dd49559 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -186,8 +186,6 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, u32 cr; if (0 == ssi->usrcnt) { - rsnd_mod_hw_start(&ssi->mod); - if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_ssi_clk_from_parent(ssi)) rsnd_ssi_hw_start(ssi->parent, io); @@ -258,8 +256,6 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) else rsnd_ssi_master_clk_stop(ssi); } - - rsnd_mod_hw_stop(&ssi->mod); } dev_dbg(dev, "%s[%d] hw stopped\n", @@ -445,12 +441,18 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, rsnd_ssi_interrupt, IRQF_SHARED, dev_name(dev), ssi); - if (ret) + if (ret) { dev_err(dev, "%s[%d] (PIO) request interrupt failed\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - else - dev_dbg(dev, "%s[%d] (PIO) is probed\n", - rsnd_mod_name(mod), rsnd_mod_id(mod)); + return ret; + } + + ret = rsnd_mod_probe(mod, priv); + if (ret) + return ret; + + dev_dbg(dev, "%s[%d] (PIO) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } @@ -458,6 +460,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .name = SSI_NAME, .probe = rsnd_ssi_pio_probe, + .remove = rsnd_mod_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -485,6 +488,10 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, if (ret) goto rsnd_ssi_dma_probe_fail; + ret = rsnd_mod_probe(mod, priv); + if (ret) + goto rsnd_ssi_dma_probe_fail; + dev_dbg(dev, "%s[%d] (DMA) is probed\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); @@ -509,7 +516,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, /* PIO will request IRQ again */ devm_free_irq(dev, irq, ssi); - return 0; + return rsnd_mod_remove(mod, priv); } static int rsnd_ssi_fallback(struct rsnd_mod *mod,