From patchwork Fri Feb 13 04:43:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 5822921 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 012E8BF440 for ; Fri, 13 Feb 2015 04:46:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 091712025B for ; Fri, 13 Feb 2015 04:46:19 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id CA86E200F0 for ; Fri, 13 Feb 2015 04:46:17 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id D667626546F; Fri, 13 Feb 2015 05:46:16 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id BA1352654EB; Fri, 13 Feb 2015 05:44:59 +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 344DA2654EB; Fri, 13 Feb 2015 05:44:58 +0100 (CET) Received: from relmlie1.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by alsa0.perex.cz (Postfix) with ESMTP id 5417F265367 for ; Fri, 13 Feb 2015 05:43:57 +0100 (CET) Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie1.idc.renesas.com with ESMTP; 13 Feb 2015 13:43:55 +0900 Received: from relmlac4.idc.renesas.com (relmlac4.idc.renesas.com [10.200.69.24]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id CA1CE51F9D; Fri, 13 Feb 2015 13:43:55 +0900 (JST) Received: by relmlac4.idc.renesas.com (Postfix, from userid 0) id B2881480A3; Fri, 13 Feb 2015 13:43:55 +0900 (JST) Received: from relmlac4.idc.renesas.com (localhost [127.0.0.1]) by relmlac4.idc.renesas.com (Postfix) with ESMTP id AE03D48014; Fri, 13 Feb 2015 13:43:55 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac4.idc.renesas.com with ESMTP id PAX30187; Fri, 13 Feb 2015 13:43:55 +0900 X-IronPort-AV: E=Sophos;i="5.09,568,1418050800"; d="scan'208";a="179773288" Received: from mail-hk1lp0123.outbound.protection.outlook.com (HELO APAC01-HK1-obe.outbound.protection.outlook.com) ([207.46.51.123]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 13 Feb 2015 13:43:55 +0900 Received: from remon.renesas.com (211.11.155.132) by SIXPR06MB173.apcprd06.prod.outlook.com (10.242.151.12) with Microsoft SMTP Server (TLS) id 15.1.81.19; Fri, 13 Feb 2015 04:43:53 +0000 Message-ID: <87y4o24dyq.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto User-Agent: Wanderlust/2.14.0 Emacs/23.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") To: Mark Brown In-Reply-To: <874mqq5slj.wl%kuninori.morimoto.gx@renesas.com> References: <874mqq5slj.wl%kuninori.morimoto.gx@renesas.com> Date: Fri, 13 Feb 2015 04:43:53 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: SIXPR06CA0023.apcprd06.prod.outlook.com (25.160.171.141) To SIXPR06MB173.apcprd06.prod.outlook.com (10.242.151.12) Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none; X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:SIXPR06MB173; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004); SRVR:SIXPR06MB173; X-Forefront-PRVS: 0486A0CB86 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6009001)(62966003)(42186005)(2950100001)(77096005)(23726002)(86362001)(92566002)(66066001)(36756003)(77156002)(46406003)(83506001)(47776003)(50466002)(19580395003)(54356999)(33646002)(19580405001)(76176999)(40100003)(46102003)(122386002)(110136001)(50986999)(53416004)(229853001); DIR:OUT; SFP:1102; SCL:1; SRVR:SIXPR06MB173; H:remon.renesas.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:;SRVR:SIXPR06MB173; X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Feb 2015 04:43:53.1356 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SIXPR06MB173 Cc: Linux-ALSA , Simon , Liam Girdwood Subject: [alsa-devel] [PATCH 4/5 v4] ASoC: soc-core: call snd_soc_remove_card() when component del 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 ASoC devices are organized as CPU-CARD-CODEC. Then, CPU/CODEC are based on component structure. Now, each CARD device knows connected components. But CARD doesn't notice if connected component was removed when user used rmmod or unbind in current implementation. Thus, CARD which lost some components still exist in system. And then, ALSA sound card will have some problem if user used this CARD in such timing. This patch temporarily removes CARD from system if connected component was removed, and re-add it if some component was added. Reported-by: Nguyen Viet Dung Reported-by: Bui Duc Phuc Reported-by: Cao Minh Hiep Signed-off-by: Kuninori Morimoto --- v3 -> v4 - initialize unbinded_list - used mutex_lock in snd_soc_unregister_card() - check component->probed in snd_soc_component_del_unlocked() include/sound/soc.h | 1 + sound/soc/soc-core.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index ac8b333..a9272a4 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1084,6 +1084,7 @@ struct snd_soc_card { struct list_head paths; struct list_head dapm_list; struct list_head dapm_dirty; + struct list_head unbinded_list; /* Generic DAPM context for the card */ struct snd_soc_dapm_context dapm; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5d85b5b..f04e97d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -56,6 +56,7 @@ static DEFINE_MUTEX(client_mutex); static LIST_HEAD(platform_list); static LIST_HEAD(codec_list); static LIST_HEAD(component_list); +static LIST_HEAD(unbinded_card_list); /* * This is a timeout to do a DAPM powerdown after a stream is closed(). @@ -2379,6 +2380,7 @@ int snd_soc_register_card(struct snd_soc_card *card) card->rtd_aux[i].card = card; INIT_LIST_HEAD(&card->dapm_dirty); + INIT_LIST_HEAD(&card->unbinded_list); card->instantiated = 0; mutex_init(&card->mutex); mutex_init(&card->dapm_mutex); @@ -2406,6 +2408,10 @@ int snd_soc_unregister_card(struct snd_soc_card *card) dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); } + mutex_lock(&client_mutex); + list_del_init(&card->unbinded_list); + mutex_unlock(&client_mutex); + return 0; } EXPORT_SYMBOL_GPL(snd_soc_unregister_card); @@ -2669,6 +2675,9 @@ EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap); static void snd_soc_component_add_unlocked(struct snd_soc_component *component) { + struct snd_soc_card *card, *_card; + int ret; + if (!component->write && !component->read) { if (!component->regmap) component->regmap = dev_get_regmap(component->dev, NULL); @@ -2677,6 +2686,16 @@ static void snd_soc_component_add_unlocked(struct snd_soc_component *component) } list_add(&component->list, &component_list); + + /* re-add temporarily removed card if exist */ + list_for_each_entry_safe(card, _card, &unbinded_card_list, + unbinded_list) { + ret = snd_soc_instantiate_card(card); + if (ret < 0) + continue; + + list_del_init(&card->unbinded_list); + } } static void snd_soc_component_add(struct snd_soc_component *component) @@ -2694,7 +2713,15 @@ static void snd_soc_component_cleanup(struct snd_soc_component *component) static void snd_soc_component_del_unlocked(struct snd_soc_component *component) { + struct snd_soc_card *card = component->card; + list_del(&component->list); + + /* card is removed temporarily */ + if (component->probed && card->instantiated) { + list_add(&card->unbinded_list, &unbinded_card_list); + snd_soc_remove_card(card); + } } static void snd_soc_component_del(struct snd_soc_component *component)