From patchwork Fri Jan 27 12:00:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 648000 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65F1AC38142 for ; Fri, 27 Jan 2023 12:02:21 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 14AA7EBB; Fri, 27 Jan 2023 13:01:29 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 14AA7EBB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820939; bh=ErXZt99budl/AwAVcBjT9ltQP+XTzjusuCPQ2fqpFNE=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=B6uDy10cTwPizeO5Hxfurntz7q4QR6ctIhRZdQ9v23QqzxI/odBpMiFy2tCkzPEmC fFNPjOYIetQ5L7wDXZQxvi728JEAMIVswy7AaMtB17DhVPyryur/JOX9cBqsk94QBf JrAIJ/dwwC1Cs4xDbjJy12JlFBcK140N0+Oj7VdQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 711A9F8053D; Fri, 27 Jan 2023 13:00:39 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 401A9F804A9; Fri, 27 Jan 2023 13:00:36 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B2DDFF80154 for ; Fri, 27 Jan 2023 13:00:30 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B2DDFF80154 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=DjATl/ZV DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820832; x=1706356832; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ErXZt99budl/AwAVcBjT9ltQP+XTzjusuCPQ2fqpFNE=; b=DjATl/ZV4qVBgEhiNXvn9ksD8xTwP+qfVXkTh9LvdbttLSjWK+B+uGm9 kFYF5aVoUNiRBKLhmQaR+klQtFsEWt0yQeiatTraN1lQEmIzim/+uPDIC 5UeuIRIZSb/cin2n/AO4l7Mf9jAa2v/WHR/8MNg8r4FZwu4/KpQ3SRXdp q0EScNdhQjnAW6cxOA3+9XhsTiywt/IboT/wtqtzqDAKseQzF9BpUjCFJ B3SSZuQ2v/EpHnouJxvpS0LK7f4YAiSTROT1o6ABatfFO6HHUTguT/dOb 4ZfXVvtMqM8oWC3uNa5FLQwMRGV0KaX7tkqp0mvF1uedrb4fO/Ggri49A Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091783" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091783" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:28 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782076" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782076" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:26 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 01/18] ASoC: SOF: ipc4-topology: No need to unbind routes within a pipeline Date: Fri, 27 Jan 2023 14:00:14 +0200 Message-Id: <20230127120031.10709-2-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan The FW currently ignores unbinding routes if the source and sink widgets belong to the same pipeline. So no need to send the IPC at all in the first place. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Rander Wang Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc4-topology.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index ba99114e86a9..ae8ec98bb4eb 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1805,12 +1805,19 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; struct sof_ipc4_msg msg = {{ 0 }}; u32 header, extension; - int ret; + int ret = 0; dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", src_widget->widget->name, sroute->src_queue_id, sink_widget->widget->name, sroute->dst_queue_id); + /* + * routes belonging to the same pipeline will be disconnected by the FW when the pipeline + * is freed. So avoid sending this IPC which will be ignored by the FW anyway. + */ + if (src_widget->pipe_widget == sink_widget->pipe_widget) + goto out; + header = src_fw_module->man4_module_entry.id; header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_UNBIND); @@ -1829,7 +1836,7 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s if (ret < 0) dev_err(sdev->dev, "failed to unbind modules %s -> %s\n", src_widget->widget->name, sink_widget->widget->name); - +out: sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK); sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE); From patchwork Fri Jan 27 12:00:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2083BC38142 for ; Fri, 27 Jan 2023 12:01:57 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 29ACBE97; Fri, 27 Jan 2023 13:01:05 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 29ACBE97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820915; bh=5yvFZt+LuISUfxj7udrcr3X4NtTxM9Mzz/F7j8/WCdE=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=XIdqXNGC+lmXusGOrpAP6GcYV1lAL0t9DCwW2GlSWsNWuunpTIy9os1z13BHrDENb WrzA5x0lVUF2J32BnNeS1VeQmmVLPZH1oa5/QLMm2KX+jewkYb7q8SXrsWu+ISjaJa OVAYvwZJNgW8laAV5klOD1GMnVQnEH3WJjy8i4Ek= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F2997F804FC; Fri, 27 Jan 2023 13:00:37 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4A739F80424; Fri, 27 Jan 2023 13:00:35 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F33AFF80424 for ; Fri, 27 Jan 2023 13:00:31 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F33AFF80424 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=L1WDBqMq DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820833; x=1706356833; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5yvFZt+LuISUfxj7udrcr3X4NtTxM9Mzz/F7j8/WCdE=; b=L1WDBqMqTWwaoVFrhMLV/ZDfBFxLqI6TZTWBYipSTLkG36zQE4ea+u1b M7BQkhxjfjN4bmH1EC3q4EjOmPSFFAExbgRueEeZCCws6+9pK3qbr0zwX mlFAPhndG+z0q2vTD5prJM5HDhTZxqzwra60o22wV5LPHqLL1+kJyAn1k dAGFWSVfX29Nd6mpdiuxEQt9xZz62AaKZnJxecFBnzYmFNAWLuxi7U3+Q tesrklaOTSuTToSCrLmpcC2gEK9MysY4h5A6vKIVtMxeLRUilX/JZCAVh DzYA8E1MPZD14GC2Spr+FEX3mcqnKiXBnNqdA35sS/QEIPlVtV3+lL/hK A==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091796" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091796" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:31 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782094" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782094" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:29 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 02/18] ASoC: soc-pcm: Export widget_in_list() Date: Fri, 27 Jan 2023 14:00:15 +0200 Message-Id: <20230127120031.10709-3-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Export the widget_in_list() function to be used by other modules. Signed-off-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- include/sound/soc-dpcm.h | 2 ++ sound/soc/soc-pcm.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index 2864aed72998..1e7d09556fe3 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -162,6 +162,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream); int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event); bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir); +int widget_in_list(struct snd_soc_dapm_widget_list *list, + struct snd_soc_dapm_widget *widget); #define dpcm_be_dai_startup_rollback(fe, stream, last) \ dpcm_be_dai_stop(fe, stream, 0, last) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 579a44d81d9a..f6caa55ef322 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1337,7 +1337,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, return NULL; } -static int widget_in_list(struct snd_soc_dapm_widget_list *list, +int widget_in_list(struct snd_soc_dapm_widget_list *list, struct snd_soc_dapm_widget *widget) { struct snd_soc_dapm_widget *w; @@ -1349,6 +1349,7 @@ static int widget_in_list(struct snd_soc_dapm_widget_list *list, return 0; } +EXPORT_SYMBOL_GPL(widget_in_list); bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir) { From patchwork Fri Jan 27 12:00:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9F059C38142 for ; Fri, 27 Jan 2023 12:02:29 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id ED2E7DF1; Fri, 27 Jan 2023 13:01:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz ED2E7DF1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820947; bh=SYxl5ORHfYu3n4ZTLyDzRfOA6FhujfLMgVg1CCrCmkI=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=Nk7bRVEZDtM253+Azr0LPFHQathR1FWykLU8RiGOlG10RaSQxV/imQQIgIRR+04Gd iZQRdX8Ui0zKLyAtNPjdBVAJI/bex6us5djvREol0gkyMKqZthGC4ta05c/79rxV06 6nl6hgepF5xOGsb00LCCcxSlBHOZORtDbIi1FM5w= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 8768FF804F3; Fri, 27 Jan 2023 13:00:46 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 089D9F802E8; Fri, 27 Jan 2023 13:00:37 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 7F055F802E8 for ; Fri, 27 Jan 2023 13:00:34 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7F055F802E8 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=eokhHcSn DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820835; x=1706356835; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SYxl5ORHfYu3n4ZTLyDzRfOA6FhujfLMgVg1CCrCmkI=; b=eokhHcSnXi/bXRcEKTA4XgCeDUUtbVdCMD/xzGTZWZ4SUou1Lafei9UY 9ckY7+irrPjfkGkNK9Ht+VdJUeBY+YiaUdJTTFqOHcHL5uCTYUlMD7T4X oLEV9+wRQiVi/ft5mS5ashAliIiZ8xemkR65LTnHBE7FqSJ2pylEvlmOb wW9OJX5y8eiJy1Bv4P+MYbbaHKZFFS+jcw8BOL2qcNxgtHM3oDbIMeTiS sPT4Fl51VnDHs37y1RtJlIMWag8UsGDAcHbP1lMgP/gsuGXXYzHlzRO1u GAQft2gMYDYwtGJtTIO8Lbhn4Seor172Xy93Lvn0y+muBqjZEwCQkSKli Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091807" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091807" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:34 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782110" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782110" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:31 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 03/18] ASoC: SOF: sof-audio: Set up/free DAI/AIF widgets only once Date: Fri, 27 Jan 2023 14:00:16 +0200 Message-Id: <20230127120031.10709-4-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Calling the sof_widget_setup/free() for the DAI/AIF widgets inside the snd_soc_dapm_widget_for_each_sink_path() loop will end up setting up or freeing the widget multiple times if there are multiple paths leaving the widget. Fix this by moving the widget setup/free for the starting widget in each path outside the loop. Signed-off-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/sof-audio.c | 48 +++++++++++++++------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 2dff3ae25d27..572ac6a0c9ac 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -358,19 +358,16 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap int err; int ret = 0; - /* free all widgets even in case of error to keep use counts balanced */ + if (widget->dobj.private) { + err = sof_widget_free(sdev, widget->dobj.private); + if (err < 0) + ret = err; + } + + /* free all widgets in the sink paths even in case of error to keep use counts balanced */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { - if (!p->walking && p->sink->dobj.private && widget->dobj.private) { + if (!p->walking) { p->walking = true; - if (WIDGET_IS_AIF_OR_DAI(widget->id)) { - err = sof_widget_free(sdev, widget->dobj.private); - if (err < 0) - ret = err; - } - - err = sof_widget_free(sdev, p->sink->dobj.private); - if (err < 0) - ret = err; err = sof_free_widgets_in_path(sdev, p->sink, dir); if (err < 0) @@ -393,32 +390,23 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d struct snd_soc_dapm_path *p; int ret; + if (widget->dobj.private) { + ret = sof_widget_setup(sdev, widget->dobj.private); + if (ret < 0) + return ret; + } + snd_soc_dapm_widget_for_each_sink_path(widget, p) { - if (!p->walking && p->sink->dobj.private && widget->dobj.private) { + if (!p->walking) { p->walking = true; - if (WIDGET_IS_AIF_OR_DAI(widget->id)) { - ret = sof_widget_setup(sdev, widget->dobj.private); - if (ret < 0) - goto out; - } - - ret = sof_widget_setup(sdev, p->sink->dobj.private); - if (ret < 0) { - if (WIDGET_IS_AIF_OR_DAI(widget->id)) - sof_widget_free(sdev, widget->dobj.private); - goto out; - } ret = sof_set_up_widgets_in_path(sdev, p->sink, dir); + p->walking = false; if (ret < 0) { - if (WIDGET_IS_AIF_OR_DAI(widget->id)) + if (widget->dobj.private) sof_widget_free(sdev, widget->dobj.private); - sof_widget_free(sdev, p->sink->dobj.private); - } -out: - p->walking = false; - if (ret < 0) return ret; + } } } From patchwork Fri Jan 27 12:00:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647999 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 90025C54EAA for ; Fri, 27 Jan 2023 12:02:40 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 982D6ECE; Fri, 27 Jan 2023 13:01:48 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 982D6ECE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820958; bh=gIMwkMidUhA4Ii5fiqwjJHw3CbGLAGaZpvsrfz91oBE=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=cCiDyv1qOGZrz0fJnxEvA20R7onWGGGnnaXYEe8B9TCYexDd45YxmzwP17W2UUmhY 7XNtN82fmwbm9da/3QfBl78P/UAokqQoG4TPHoC81Qb5I+FQnaZf1AvW/ooGH73eIu 4oDP12lnB+pXebuREk3xGHVMg2vvG5INrlrLCVDU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7CA10F80557; Fri, 27 Jan 2023 13:00:47 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B1B55F80549; Fri, 27 Jan 2023 13:00:41 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id E2AD1F804F3 for ; Fri, 27 Jan 2023 13:00:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E2AD1F804F3 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=jmWQgsub DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820838; x=1706356838; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gIMwkMidUhA4Ii5fiqwjJHw3CbGLAGaZpvsrfz91oBE=; b=jmWQgsub8axtekOFMFueI0rW5nYbOuj48zVYnjLg1D7UxkI7cNRv3vNy xIo1+4hTOKe+el68SILM+hM4UKGfXQwg/XcJOSlMfW8Rj/hFnZiTQTSxD 4NB6AKN21XmxOwMa234dUpTIrJkrzwtATaybKwScDuo8cAP1Z3zAJTgCc 0xGxyjoXAQFqkL3O5F3UvJHoWbbytD07hWcWfWosv9ZnaLvd6UnrmiqFG j558wWk8MGCSxeN0CSkaQxwEiEoIs8FEMwu/FUYTgYGw2Ts8HI3yYoFvy 1ZQ9XHrM99N7N9OmszliOSJqLcM2PRMDf8YxiS3zF+bRxxc8+pVev0vWb w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091819" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091819" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:36 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782124" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782124" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:34 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 04/18] ASoC: SOF: sof-audio: Only process widgets in the connected widget list Date: Fri, 27 Jan 2023 14:00:17 +0200 Message-Id: <20230127120031.10709-5-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan When walking the list of the widgets from the source to the sink, we accidentally also end up preparing/setting up the widgets that are not in the list of connected DAPM widgets associated with the PCM. Avoid this by checking if a widget is part of the connected DAPM widget list during widget prepare, unprepare, setup or free. Signed-off-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/sof-audio.c | 51 +++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 572ac6a0c9ac..b127b304298c 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -241,24 +241,32 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev, if (!widget->dobj.private) continue; - snd_soc_dapm_widget_for_each_sink_path(widget, p) + snd_soc_dapm_widget_for_each_sink_path(widget, p) { + if (!widget_in_list(list, p->sink)) + continue; + if (p->sink->dobj.private) { ret = sof_route_setup(sdev, widget, p->sink); if (ret < 0) return ret; } + } } } else { for_each_dapm_widgets(list, i, widget) { if (!widget->dobj.private) continue; - snd_soc_dapm_widget_for_each_source_path(widget, p) + snd_soc_dapm_widget_for_each_source_path(widget, p) { + if (!widget_in_list(list, p->source)) + continue; + if (p->source->dobj.private) { ret = sof_route_setup(sdev, p->source, widget); if (ret < 0) return ret; } + } } } @@ -266,7 +274,8 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev, } static void -sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget) +sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, + struct snd_soc_dapm_widget_list *list) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); struct snd_sof_widget *swidget = widget->dobj.private; @@ -287,9 +296,11 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg sink_unprepare: /* unprepare all widgets in the sink paths */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { + if (!widget_in_list(list, p->sink)) + continue; if (!p->walking && p->sink->dobj.private) { p->walking = true; - sof_unprepare_widgets_in_path(sdev, p->sink); + sof_unprepare_widgets_in_path(sdev, p->sink, list); p->walking = false; } } @@ -299,7 +310,8 @@ static int sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, struct snd_pcm_hw_params *fe_params, struct snd_sof_platform_stream_params *platform_params, - struct snd_pcm_hw_params *pipeline_params, int dir) + struct snd_pcm_hw_params *pipeline_params, int dir, + struct snd_soc_dapm_widget_list *list) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); struct snd_sof_widget *swidget = widget->dobj.private; @@ -327,10 +339,13 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget sink_prepare: /* prepare all widgets in the sink paths */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { + if (!widget_in_list(list, p->sink)) + continue; if (!p->walking && p->sink->dobj.private) { p->walking = true; ret = sof_prepare_widgets_in_path(sdev, p->sink, fe_params, - platform_params, pipeline_params, dir); + platform_params, pipeline_params, dir, + list); p->walking = false; if (ret < 0) { /* unprepare the source widget */ @@ -352,7 +367,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget * (DAI type for capture, AIF type for playback) */ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, - int dir) + int dir, struct snd_soc_dapm_widget_list *list) { struct snd_soc_dapm_path *p; int err; @@ -367,9 +382,12 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap /* free all widgets in the sink paths even in case of error to keep use counts balanced */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking) { + if (!widget_in_list(list, p->sink)) + continue; + p->walking = true; - err = sof_free_widgets_in_path(sdev, p->sink, dir); + err = sof_free_widgets_in_path(sdev, p->sink, dir, list); if (err < 0) ret = err; p->walking = false; @@ -385,7 +403,7 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap * The error path in this function ensures that all successfully set up widgets getting freed. */ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, - int dir) + int dir, struct snd_soc_dapm_widget_list *list) { struct snd_soc_dapm_path *p; int ret; @@ -398,9 +416,12 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking) { + if (!widget_in_list(list, p->sink)) + continue; + p->walking = true; - ret = sof_set_up_widgets_in_path(sdev, p->sink, dir); + ret = sof_set_up_widgets_in_path(sdev, p->sink, dir, list); p->walking = false; if (ret < 0) { if (widget->dobj.private) @@ -435,11 +456,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l switch (op) { case SOF_WIDGET_SETUP: - ret = sof_set_up_widgets_in_path(sdev, widget, dir); + ret = sof_set_up_widgets_in_path(sdev, widget, dir, list); str = "set up"; break; case SOF_WIDGET_FREE: - ret = sof_free_widgets_in_path(sdev, widget, dir); + ret = sof_free_widgets_in_path(sdev, widget, dir, list); str = "free"; break; case SOF_WIDGET_PREPARE: @@ -455,12 +476,12 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l */ memcpy(&pipeline_params, fe_params, sizeof(*fe_params)); - ret = sof_prepare_widgets_in_path(sdev, widget, fe_params, - platform_params, &pipeline_params, dir); + ret = sof_prepare_widgets_in_path(sdev, widget, fe_params, platform_params, + &pipeline_params, dir, list); break; } case SOF_WIDGET_UNPREPARE: - sof_unprepare_widgets_in_path(sdev, widget); + sof_unprepare_widgets_in_path(sdev, widget, list); break; default: dev_err(sdev->dev, "Invalid widget op %d\n", op); From patchwork Fri Jan 27 12:00:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647562 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C3215C54EAA for ; Fri, 27 Jan 2023 12:03:07 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B04C0EC1; Fri, 27 Jan 2023 13:02:15 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B04C0EC1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820985; bh=2SerIkFyJLI9Kvb9oAS46V2qXRic/jO3U+kVf4WmVAY=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=e2dIkfQ6G+4SmTpZy9v6+yGTzus+rFik5PqZ90/1GS9QuTgOnN2qp8JU5hobg0s1x 2yODaSD5JVsrsmPgEh3gmc3PTRJzkQ11zx0W/67WeHHZHQ3J8/tB+7n0j+Cz66RXKx fqoSk91Q4/+1Elf2wEsLb0EduWxcYSNF41BmyRHI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id E47B5F8055C; Fri, 27 Jan 2023 13:01:00 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C82F0F80549; Fri, 27 Jan 2023 13:00:44 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 6B416F80543 for ; Fri, 27 Jan 2023 13:00:39 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6B416F80543 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=hqmHXQVV DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820840; x=1706356840; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2SerIkFyJLI9Kvb9oAS46V2qXRic/jO3U+kVf4WmVAY=; b=hqmHXQVVGKIx1bFFQoo5wqc2Ht/bJdLIV0is1qa1ucJx30hvvjn05Ihf nCltE7ft0lI3TORNYkU7BZXax1a+he8S0u8+mVnYug7X4Ms+QJNQrgGPH Ip5WQYmFJ5AW+k1HHj4f9npNs2b+SZkHswInOkXXMwCBe0aXyHpeLfkjq 1DoSi3IBi+jR7kDcd/oucubmxKZsYbnxTZKgl9UblzVU19t3YaviqbDOr 0PKtG83VlKQwIE6kI0LF/dnJHM5RQ84MLzrIQmbeQKUxDYnNWC/xsOBgH jtv6LEMsWr5bcJA9o6Ojou1nivzgkX6X6wHv1FIYy6tBlRfukF7JGVSnh w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091828" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091828" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:38 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782137" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782137" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:36 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 05/18] ASoC: SOF: pcm: do not free widgets during suspend trigger Date: Fri, 27 Jan 2023 14:00:18 +0200 Message-Id: <20230127120031.10709-6-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan IPC3 and IPC4 have different requirements for the order in which the FE CPU and BE CPU DAI trigger callbacks must be invoked. With a regular PCM start/stop, pipeline widgets are set up during hw_params and freed during hw_free. But when the system is suspended when a PCM is running, pipeline widgets are freed during the SUSPEND trigger callback for the FE CPU DAI. In order to avoid freeing the pipeline widgets before the BE CPU DAI trigger is executed, the trigger order was modified in previous contributions in the PCM dai_link_fixup callback to make sure that the BE CPU DAI trigger stop/suspend is always invoked before the FE CPU DAI trigger. But this contradicts the firmware requirement for IPC4 w.r.t. ordering of pipeline triggers. So, remove the freeing of pipeline widgets during FE CPU DAI suspend trigger and handle it during system suspend when the tear_down_all_pipelines() IPC op is invoked. This will be followed up with a patch to fix the trigger order for IPC4. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc3-topology.c | 2 +- sound/soc/sof/ipc4-pcm.c | 12 ------------ sound/soc/sof/ipc4-topology.c | 2 +- sound/soc/sof/pcm.c | 5 +---- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 989395999d6e..72ac1725af0d 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2264,7 +2264,7 @@ static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev) for_each_pcm_streams(dir) { struct snd_pcm_substream *substream = spcm->stream[dir].substream; - if (!substream || !substream->runtime) + if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) continue; if (spcm->stream[dir].list) { diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 96941bebc1f1..23de58d7d06b 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -183,7 +183,6 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct sof_ipc4_copier *ipc4_copier; - struct snd_soc_dpcm *dpcm; if (!dai) { dev_err(component->dev, "%s: No DAI found with name %s\n", __func__, @@ -205,17 +204,6 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = ipc4_copier->available_fmt.base_config->audio_fmt.sampling_frequency; rate->max = rate->min; - /* - * Set trigger order for capture to SND_SOC_DPCM_TRIGGER_PRE. This is required - * to ensure that the BE DAI pipeline gets stopped/suspended before the FE DAI - * pipeline gets triggered and the pipeline widgets are freed. - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) { - struct snd_soc_pcm_runtime *fe = dpcm->fe; - - fe->dai_link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; - } - switch (ipc4_copier->dai_type) { case SOF_DAI_INTEL_SSP: ipc4_ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params); diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index ae8ec98bb4eb..3938ff2d998b 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -2025,7 +2025,7 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif for_each_pcm_streams(dir) { struct snd_pcm_substream *substream = spcm->stream[dir].substream; - if (!substream || !substream->runtime) + if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) continue; if (spcm->stream[dir].list) { diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 952fc698a586..34d40c5c629a 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -282,7 +282,6 @@ static int sof_pcm_trigger(struct snd_soc_component *component, const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); struct snd_sof_pcm *spcm; bool reset_hw_params = false; - bool free_widget_list = false; bool ipc_first = false; int ret = 0; @@ -326,7 +325,6 @@ static int sof_pcm_trigger(struct snd_soc_component *component, spcm->stream[substream->stream].suspend_ignored = true; return 0; } - free_widget_list = true; fallthrough; case SNDRV_PCM_TRIGGER_STOP: ipc_first = true; @@ -353,8 +351,7 @@ static int sof_pcm_trigger(struct snd_soc_component *component, /* free PCM if reset_hw_params is set and the STOP IPC is successful */ if (!ret && reset_hw_params) - ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, - free_widget_list); + ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, false); return ret; } From patchwork Fri Jan 27 12:00:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647998 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C1581C54EAA for ; Fri, 27 Jan 2023 12:03:16 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8F837ED2; Fri, 27 Jan 2023 13:02:24 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8F837ED2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674820994; bh=H3MuiZXEd2x/7QMkMjwGfQ6eGimV78IlHXWNjuFSlN0=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=vpTvEr9MTWkHsiDnrg/vSUKlJguPnWCvdofeY237CTwnm8d3CS3UNeBD6aTVUoBfX 5baYqETM3mgrl7TbpFrgnH7TJ+9oTeeJxNOMw+R7xGTP1PVYxyV3B72Sfjx4zpNtiK BFIVut/01MMZ1BJtx7KyfeS5ENi1B14C0uo3bJOc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 11D13F80579; Fri, 27 Jan 2023 13:01:02 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id AFFA4F8055B; Fri, 27 Jan 2023 13:00:47 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CA7AAF80544 for ; Fri, 27 Jan 2023 13:00:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CA7AAF80544 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=WYmr3OcI DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820843; x=1706356843; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=H3MuiZXEd2x/7QMkMjwGfQ6eGimV78IlHXWNjuFSlN0=; b=WYmr3OcIbuJbeut6OC1ETP149Ye4RYdxhtuBbUj41U8QguSa4qvVMcHn 9Wp+16Xhcsr/Rs6rp498iysxYliMNx44Pi10C39XwkGzApf2tXHpxvmzF lWICawG7cd1Af6N5OeEmERkyMNJianmXaqls+WqkSellnLyyxnyyCSK8e CvkF0tG+IZbHnQHyAKHmfx3l1/YcUEABf/zKEfHm8hoYW228LeWfsz4qW TIW0H0aeOIAga8no/yhhp+OLnLUwfHjYuealvtDdsEwe9nUJ0TNT9x8tz HqgOJB7MvC9Cty7KjmzgAsdrrtGBu41lKFm5QGUe0xXLeI+LWkRJpv7HI A==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091839" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091839" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:41 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782150" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782150" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:39 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 06/18] ASoC: SOF: topology: Set IPC-specific trigger order for DAI links Date: Fri, 27 Jan 2023 14:00:19 +0200 Message-Id: <20230127120031.10709-7-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Add a new topology IPC op to set up DAI links and set the link trigger order to match the expectation based on the IPC type. Note that the link_setup op implementations for IPC3 and IPC4 are not identical and have contrasting trigger orders for playback and capture. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc3-topology.c | 19 +++++++++++++++++++ sound/soc/sof/ipc4-topology.c | 19 +++++++++++++++++++ sound/soc/sof/sof-audio.h | 2 ++ sound/soc/sof/topology.c | 25 +++++++------------------ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 72ac1725af0d..3f52dfb19e01 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2426,6 +2426,24 @@ static int sof_ipc3_parse_manifest(struct snd_soc_component *scomp, int index, return 0; } +static int sof_ipc3_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) +{ + if (link->no_pcm) + return 0; + + /* + * set default trigger order for all links. Exceptions to + * the rule will be handled in sof_pcm_dai_link_fixup() + * For playback, the sequence is the following: start FE, + * start BE, stop BE, stop FE; for Capture the sequence is + * inverted start BE, start FE, stop FE, stop BE + */ + link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_PRE; + link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_POST; + + return 0; +} + /* token list for each topology object */ static enum sof_tokens host_token_list[] = { SOF_CORE_TOKENS, @@ -2537,4 +2555,5 @@ const struct sof_ipc_tplg_ops ipc3_tplg_ops = { .set_up_all_pipelines = sof_ipc3_set_up_all_pipelines, .tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines, .parse_manifest = sof_ipc3_parse_manifest, + .link_setup = sof_ipc3_link_setup, }; diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 3938ff2d998b..b07a405516b1 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -2038,6 +2038,24 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif return 0; } +static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) +{ + if (link->no_pcm) + return 0; + + /* + * set default trigger order for all links. Exceptions to + * the rule will be handled in sof_pcm_dai_link_fixup() + * For playback, the sequence is the following: start BE, + * start FE, stop FE, stop BE; for Capture the sequence is + * inverted start FE, start BE, stop BE, stop FE + */ + link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; + link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; + + return 0; +} + static enum sof_tokens common_copier_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -2144,4 +2162,5 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .parse_manifest = sof_ipc4_parse_manifest, .dai_get_clk = sof_ipc4_dai_get_clk, .tear_down_all_pipelines = sof_ipc4_tear_down_all_pipelines, + .link_setup = sof_ipc4_link_setup, }; diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 8e4abb1f5f73..28062a0c3a43 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -180,6 +180,7 @@ struct sof_ipc_tplg_widget_ops { * @set_up_all_pipelines: Function pointer for setting up all topology pipelines * @tear_down_all_pipelines: Function pointer for tearing down all topology pipelines * @parse_manifest: Function pointer for ipc4 specific parsing of topology manifest + * @link_setup: Function pointer for IPC-specific DAI link set up * * Note: function pointers (ops) are optional */ @@ -201,6 +202,7 @@ struct sof_ipc_tplg_ops { int (*tear_down_all_pipelines)(struct snd_sof_dev *sdev, bool verify); int (*parse_manifest)(struct snd_soc_component *scomp, int index, struct snd_soc_tplg_manifest *man); + int (*link_setup)(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link); }; /** struct snd_sof_tuple - Tuple info diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 560771ba8fb9..f67c39c47930 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1813,26 +1813,15 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ } link->platforms->name = dev_name(scomp->dev); - /* - * Set nonatomic property for FE dai links as their trigger action - * involves IPC's. - */ + if (tplg_ops && tplg_ops->link_setup) { + ret = tplg_ops->link_setup(sdev, link); + if (ret < 0) + return ret; + } + + /* Set nonatomic property for FE dai links as their trigger action involves IPC's */ if (!link->no_pcm) { link->nonatomic = true; - - /* - * set default trigger order for all links. Exceptions to - * the rule will be handled in sof_pcm_dai_link_fixup() - * For playback, the sequence is the following: start FE, - * start BE, stop BE, stop FE; for Capture the sequence is - * inverted start BE, start FE, stop FE, stop BE - */ - link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = - SND_SOC_DPCM_TRIGGER_PRE; - link->trigger[SNDRV_PCM_STREAM_CAPTURE] = - SND_SOC_DPCM_TRIGGER_POST; - - /* nothing more to do for FE dai links */ return 0; } From patchwork Fri Jan 27 12:00:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 86191C54EAA for ; Fri, 27 Jan 2023 12:03:31 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 662E9DEE; Fri, 27 Jan 2023 13:02:39 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 662E9DEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821009; bh=o7PqVOj4UA9kzrLik5m1/juhbWoX6yinf+DXgI5qQQg=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=hx/ZW0KEXIWnUykPxDG9ETatDnpCkBL4SN74D5Nwlk50CXNfFO2V0bVcGr0QYGr5q xsgrPWCZe/1BDqFo56PnYxafWYojQdvwAP+KrPyQEmyzcc2ZycfrUVVZaJfccMp4Sg J1magcLKC/vfra8qcWOmmtIlDpysCJEmJHlQ5TjI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 477F9F8057C; Fri, 27 Jan 2023 13:01:03 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8978FF8055C; Fri, 27 Jan 2023 13:00:49 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 9BAFCF80548 for ; Fri, 27 Jan 2023 13:00:44 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9BAFCF80548 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gKX9MDq6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820845; x=1706356845; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=o7PqVOj4UA9kzrLik5m1/juhbWoX6yinf+DXgI5qQQg=; b=gKX9MDq6s2282ivWagHl364ULZ0mYgjmY6yGkY4ZLmgVl9z8coFr7Bt8 Kv7iRWRVNl8lKApSNpG8i82pbt9fK6Mjbq60fVCIU6voS5T19NcK1IQJ6 Vbs7gz7ADkRellaBKoNzWUyIpP6sdLY1+8S8f+sdqsLvRews7trb0Wv2R byEbcup5Yyi1KQuWXlCUXqBj09jJmCzGAjnVVoDuQ5S+qdm/Nwg7eWLPt ppkb7SjM2XrmyGA8NheBWeZh7xlop74cWNEqWdk1EHzumo+sAW8SCjRac J10wXp7jSIEWjt7tqYuGMmV7khYb012vkicpe/Ui0nLtZ8NBxY8VjhC9f g==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091847" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091847" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:43 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782164" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782164" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:41 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 07/18] ASoC: SOF: Introduce PCM setup/free PCM IPC ops Date: Fri, 27 Jan 2023 14:00:20 +0200 Message-Id: <20230127120031.10709-8-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan These will be used to perform IPC-specific PCM setup/free. Signed-off-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/sof-audio.h | 7 +++++++ sound/soc/sof/topology.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 28062a0c3a43..bcde2ebaf022 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -85,6 +85,7 @@ struct snd_sof_widget; struct snd_sof_route; struct snd_sof_control; struct snd_sof_dai; +struct snd_sof_pcm; struct snd_sof_dai_config_data { int dai_index; @@ -97,6 +98,10 @@ struct snd_sof_dai_config_data { * @hw_free: Function pointer for hw_free * @trigger: Function pointer for trigger * @dai_link_fixup: Function pointer for DAI link fixup + * @pcm_setup: Function pointer for IPC-specific PCM set up that can be used for allocating + * additional memory in the SOF PCM stream structure + * @pcm_free: Function pointer for PCM free that can be used for freeing any + * additional memory in the SOF PCM stream structure */ struct sof_ipc_pcm_ops { int (*hw_params)(struct snd_soc_component *component, struct snd_pcm_substream *substream, @@ -106,6 +111,8 @@ struct sof_ipc_pcm_ops { int (*trigger)(struct snd_soc_component *component, struct snd_pcm_substream *substream, int cmd); int (*dai_link_fixup)(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); + int (*pcm_setup)(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm); + void (*pcm_free)(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm); }; /** diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index f67c39c47930..51f6fed45ae7 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1669,6 +1669,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm); struct snd_soc_tplg_stream_caps *caps; struct snd_soc_tplg_private *private = &pcm->priv; struct snd_sof_pcm *spcm; @@ -1696,6 +1697,13 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, spcm->pcm = *pcm; dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name); + /* perform pcm set op */ + if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) { + ret = ipc_pcm_ops->pcm_setup(sdev, spcm); + if (ret < 0) + return ret; + } + dai_drv->dobj.private = spcm; list_add(&spcm->list, &sdev->pcm_list); @@ -1773,6 +1781,8 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, static int sof_dai_unload(struct snd_soc_component *scomp, struct snd_soc_dobj *dobj) { + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm); struct snd_sof_pcm *spcm = dobj->private; /* free PCM DMA pages */ @@ -1782,6 +1792,10 @@ static int sof_dai_unload(struct snd_soc_component *scomp, if (spcm->pcm.capture) snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table); + /* perform pcm free op */ + if (ipc_pcm_ops && ipc_pcm_ops->pcm_free) + ipc_pcm_ops->pcm_free(sdev, spcm); + /* remove from list and free spcm */ list_del(&spcm->list); kfree(spcm); From patchwork Fri Jan 27 12:00:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 921FFC38142 for ; Fri, 27 Jan 2023 12:03:46 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 5D71AE78; Fri, 27 Jan 2023 13:02:54 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 5D71AE78 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821024; bh=oMeC3yQQdvlNQlgHeuJq/tVyXvOBb7zZyx9xiHIQCw4=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=nYc6zntSCvwUiEVkhT0Z+FS+rUihGN5fSO2jRy6FvggKVXvuyKPzbUDenYHHQ5txo 0F30frCpR3zSe+Owzq14Y8+dNMuu5JoCIFKD8o1B5YV4zb3bUiKUYXZCQG0ast4xAG iyyh9tbcwPPznYjKLt5w20uMxx2js61hF0UQGzeQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 720CCF80571; Fri, 27 Jan 2023 13:01:04 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CDC6EF8055B; Fri, 27 Jan 2023 13:00:50 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D5A73F80544 for ; Fri, 27 Jan 2023 13:00:46 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D5A73F80544 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=ADz0xo11 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820848; x=1706356848; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oMeC3yQQdvlNQlgHeuJq/tVyXvOBb7zZyx9xiHIQCw4=; b=ADz0xo11M54brME+uE21B38stO6Y4SDJMRDekxKLMQmRvZBsdTV/sAHA m1cNAUY85LS+/zSw4NgqNPfkZAP0IIs4wD5FPLvyDp2yw57TYAVa/NOrr xy1dvFF1coC1qCa/kR7p/I7TVEvav3BAiFWDb3WvpC8YM82fJLJxGKYK2 Cfr3rVQuKdGv4lt3bE9JmwHwyJh6WrwGy5NYgzYoo4E1K7zDO5KOgLR5g YjL0cFIVUnrAhFkOpsr/XDLG3CyBI6lHyiEBJ3qKv80Ln6jgS19WAO0CG eUqZ6sws1SodlCDvvSowgJQSmFSbNqJPQ/E0Yi5hZIJ/g0n+o6E70aSAK g==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091864" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091864" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:46 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782183" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782183" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:43 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 08/18] ASoC: SOF: ipc4-pcm: Define pcm_setup/free ops Date: Fri, 27 Jan 2023 14:00:21 +0200 Message-Id: <20230127120031.10709-9-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Define the pcm_setup/pcm_free ops for IPC4. Define a new struct snd_sof_pcm_stream_trigger_info and add a new field trigger_info of this type to struct snd_sof_pcm_stream. This will be used to save the list of pipelines that need to be triggered. Signed-off-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc4-pcm.c | 36 ++++++++++++++++++++++++++++++++++++ sound/soc/sof/sof-audio.h | 11 +++++++++++ 2 files changed, 47 insertions(+) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 23de58d7d06b..05515e8e6f57 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -215,8 +215,44 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static void sof_ipc4_pcm_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm) +{ + struct snd_sof_pcm_stream_pipeline_list *pipeline_list; + int stream; + + for_each_pcm_streams(stream) { + pipeline_list = &spcm->stream[stream].pipeline_list; + kfree(pipeline_list->pipe_widgets); + pipeline_list->pipe_widgets = NULL; + } +} + +static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm) +{ + struct snd_sof_pcm_stream_pipeline_list *pipeline_list; + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + int stream; + + for_each_pcm_streams(stream) { + pipeline_list = &spcm->stream[stream].pipeline_list; + + /* allocate memory for max number of pipeline IDs */ + pipeline_list->pipe_widgets = kcalloc(ipc4_data->max_num_pipelines, + sizeof(struct snd_sof_widget *), + GFP_KERNEL); + if (!pipeline_list->pipe_widgets) { + sof_ipc4_pcm_free(sdev, spcm); + return -ENOMEM; + } + } + + return 0; +} + const struct sof_ipc_pcm_ops ipc4_pcm_ops = { .trigger = sof_ipc4_pcm_trigger, .hw_free = sof_ipc4_pcm_hw_free, .dai_link_fixup = sof_ipc4_pcm_dai_link_fixup, + .pcm_setup = sof_ipc4_pcm_setup, + .pcm_free = sof_ipc4_pcm_free, }; diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index bcde2ebaf022..bb5c61dd9b1e 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -285,6 +285,16 @@ struct sof_token_info { int count; }; +/** + * struct snd_sof_pcm_stream_pipeline_list - List of pipelines associated with a PCM stream + * @count: number of pipeline widgets in the @pipe_widgets array + * @pipe_widgets: array of pipeline widgets + */ +struct snd_sof_pcm_stream_pipeline_list { + u32 count; + struct snd_sof_widget **pipe_widgets; +}; + /* PCM stream, mapped to FW component */ struct snd_sof_pcm_stream { u32 comp_id; @@ -300,6 +310,7 @@ struct snd_sof_pcm_stream { * active or not while suspending the stream */ bool suspend_ignored; + struct snd_sof_pcm_stream_pipeline_list pipeline_list; }; /* ALSA SOF PCM device */ From patchwork Fri Jan 27 12:00:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647560 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 986FDC54EAA for ; Fri, 27 Jan 2023 12:04:03 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 6E1EAED4; Fri, 27 Jan 2023 13:03:11 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6E1EAED4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821041; bh=kGFffIQ+TZLB+Io2ley2iXEMkqrlz19ht5/2zQw9TqQ=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=jeLSvgxc/74054SfrpX9NxaqWEp+wpSDedTV02BEjtGWXlAFvmfrGljonUX3p8Z3S u25GSqfGI7nwNcX5+QpLuwyHw0Rp4MkpoFV2WAM/Mle6jjEUurgDEPeyq20xKg0Ync K5QAe0WH0ksiPwdG3lmNIWgg59PEuAwIy4zG/hFU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1B4A3F8058C; Fri, 27 Jan 2023 13:01:06 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EF478F8056F; Fri, 27 Jan 2023 13:00:54 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D19A7F80548 for ; Fri, 27 Jan 2023 13:00:50 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D19A7F80548 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=DKiGmqF5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820852; x=1706356852; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kGFffIQ+TZLB+Io2ley2iXEMkqrlz19ht5/2zQw9TqQ=; b=DKiGmqF5xuupJ+A8vOn9kbbuaFHQBhZILoVj1C375s2OsgDsVOuSx5sL /cprIDBRYzYx377X+yEZacJTx0cXJ09sSvo9B/0rLBWGNxw1N51jd8VYx H74C4rW+2pzjBOPumRgwIJg8qpOdqi9Ms6zY9tj26uGyH3tM1jfolNgBz DRKcr1pqfNV0BDE9lucbkJHWhfR+3jJeSj8sqyIKtnc6pB6vkkmKKCS+Y N+4jW/L6X9pBazkF0tNpIxE+qJCm2qm/dUEB+M2AAuEJlM+7FOkykfuad qt1ply+2X2lZvXyRnf3VF2WaHSmh3HS8WVR9bO5EPRoDOHQfM145rzGuo Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091875" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091875" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:48 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782200" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782200" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:46 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 09/18] ASoC: SOF: ipc4: Add flag to skip triggering pipelines during FE DAI trigger Date: Fri, 27 Jan 2023 14:00:22 +0200 Message-Id: <20230127120031.10709-10-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Add a new flag, skip_during_fe_trigger, to struct sof_ipc4_pipeline to skip triggering pipelines in the FE DAI trigger. Set this flag for the HDA DAI BE pipelines so that their BE pipeline will not be triggered in the FE DAI trigger. Also, move the trigger handling for all commands include START/PAUSE_RELEASE for the HDA DAI's to the backend DAI trigger ops. For the SSP/DMIC/SDW cases, remove the BE DAI trigger as they involve no DMA operations and can be triggered in the FE DAI trigger. This is in preparation to perform batch triggering of all pipelines for the non-HDA case. Signed-off-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/intel/hda-dai.c | 92 +++++++---------------------------- sound/soc/sof/ipc4-pcm.c | 17 +------ sound/soc/sof/ipc4-topology.c | 1 + sound/soc/sof/ipc4-topology.h | 2 + 4 files changed, 21 insertions(+), 91 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 1c3d4887aa30..98eebb4b07e6 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -450,6 +450,8 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, { struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(dai, substream); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + struct snd_sof_widget *pipe_widget; + struct sof_ipc4_pipeline *pipeline; struct snd_soc_pcm_runtime *rtd; struct snd_sof_widget *swidget; struct snd_soc_dapm_widget *w; @@ -466,18 +468,30 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, w = snd_soc_dai_get_widget(dai, substream->stream); swidget = w->dobj.private; + pipe_widget = swidget->pipe_widget; + pipeline = pipe_widget->private; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: snd_hdac_ext_stream_start(hext_stream); + if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { + ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) + return ret; + pipeline->state = SOF_IPC4_PIPE_PAUSED; + } + + ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, + SOF_IPC4_PIPE_RUNNING); + if (ret < 0) + return ret; + pipeline->state = SOF_IPC4_PIPE_RUNNING; break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: { - struct snd_sof_widget *pipe_widget = swidget->pipe_widget; - struct sof_ipc4_pipeline *pipeline = pipe_widget->private; - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, SOF_IPC4_PIPE_PAUSED); if (ret < 0) @@ -503,9 +517,6 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, } case SNDRV_PCM_TRIGGER_PAUSE_PUSH: { - struct snd_sof_widget *pipe_widget = swidget->pipe_widget; - struct sof_ipc4_pipeline *pipeline = pipe_widget->private; - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, SOF_IPC4_PIPE_PAUSED); if (ret < 0) @@ -703,64 +714,6 @@ static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { .shutdown = ssp_dai_shutdown, }; -static int ipc4_be_dai_common_trigger(struct snd_soc_dai *dai, int cmd, int stream) -{ - struct snd_sof_widget *pipe_widget; - struct sof_ipc4_pipeline *pipeline; - struct snd_sof_widget *swidget; - struct snd_soc_dapm_widget *w; - struct snd_sof_dev *sdev; - int ret; - - w = snd_soc_dai_get_widget(dai, stream); - swidget = w->dobj.private; - pipe_widget = swidget->pipe_widget; - pipeline = pipe_widget->private; - sdev = snd_soc_component_get_drvdata(swidget->scomp); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, - SOF_IPC4_PIPE_PAUSED); - if (ret < 0) - return ret; - pipeline->state = SOF_IPC4_PIPE_PAUSED; - - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, - SOF_IPC4_PIPE_RESET); - if (ret < 0) - return ret; - pipeline->state = SOF_IPC4_PIPE_RESET; - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, - SOF_IPC4_PIPE_PAUSED); - if (ret < 0) - return ret; - pipeline->state = SOF_IPC4_PIPE_PAUSED; - break; - default: - break; - } - - return 0; -} - -static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - return ipc4_be_dai_common_trigger(dai, cmd, substream->stream); -} - -static const struct snd_soc_dai_ops ipc4_dmic_dai_ops = { - .trigger = ipc4_be_dai_trigger, -}; - -static const struct snd_soc_dai_ops ipc4_ssp_dai_ops = { - .trigger = ipc4_be_dai_trigger, -}; - void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) { int i; @@ -785,14 +738,6 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) struct sof_ipc4_fw_data *ipc4_data = sdev->private; for (i = 0; i < ops->num_drv; i++) { - if (strstr(ops->drv[i].name, "DMIC")) { - ops->drv[i].ops = &ipc4_dmic_dai_ops; - continue; - } - if (strstr(ops->drv[i].name, "SSP")) { - ops->drv[i].ops = &ipc4_ssp_dai_ops; - continue; - } #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) if (strstr(ops->drv[i].name, "iDisp") || strstr(ops->drv[i].name, "Analog") || @@ -804,9 +749,6 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) if (!hda_use_tplg_nhlt) ipc4_data->nhlt = intel_nhlt_init(sdev->dev); - if (IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)) - sdw_callback.trigger = ipc4_be_dai_common_trigger; - break; } default: diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 05515e8e6f57..db9d0adb2717 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -58,25 +58,10 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, if (!swidget) continue; - /* - * set pipeline state for both FE and BE pipelines for RUNNING state. - * For PAUSE/RESET, set the pipeline state only for the FE pipeline. - */ - switch (state) { - case SOF_IPC4_PIPE_PAUSED: - case SOF_IPC4_PIPE_RESET: - if (!WIDGET_IS_AIF(swidget->id)) - continue; - break; - default: - break; - } - - /* find pipeline widget for the pipeline that this widget belongs to */ pipeline_widget = swidget->pipe_widget; pipeline = (struct sof_ipc4_pipeline *)pipeline_widget->private; - if (pipeline->state == state) + if (pipeline->state == state || pipeline->skip_during_fe_trigger) continue; /* first set the pipeline to PAUSED state */ diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index b07a405516b1..f3b1a7f81216 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1869,6 +1869,7 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * case SOF_DAI_INTEL_HDA: gtw_attr = ipc4_copier->gtw_attr; gtw_attr->lp_buffer_alloc = pipeline->lp_mode; + pipeline->skip_during_fe_trigger = true; fallthrough; case SOF_DAI_INTEL_ALH: copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 8dbbf69b0eb7..028b5d91b9db 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -73,6 +73,7 @@ * @mem_usage: Memory usage * @state: Pipeline state * @msg: message structure for pipeline + * @skip_during_fe_trigger: skip triggering this pipeline during the FE DAI trigger */ struct sof_ipc4_pipeline { uint32_t priority; @@ -80,6 +81,7 @@ struct sof_ipc4_pipeline { uint32_t mem_usage; int state; struct sof_ipc4_msg msg; + bool skip_during_fe_trigger; }; /** From patchwork Fri Jan 27 12:00:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B2F63C38142 for ; Fri, 27 Jan 2023 12:04:17 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8A5D2EDD; Fri, 27 Jan 2023 13:03:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8A5D2EDD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821055; bh=w9n5zT80vCbdVvQ5MJ7or2NBoNtNjWK0nKVW2cFHFYE=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=lCkugLdmY4zRhjMuLw2qV8+PwrNx/iaDxPqjJ1HsTeddq8H9slRzAeqMboLdNR468 3/9J50WaDPQ31SzVFZRy8nOcKAOp6QbTw9OhULOxlpfx35JLYvJdMc9GwvTOkhEZ48 ysU3/LveK1FRd3kOcU/zwu16HbXKJatZP8s8lf8U= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id CC39EF805A9; Fri, 27 Jan 2023 13:01:07 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 90B84F8056F; Fri, 27 Jan 2023 13:00:56 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id DA081F80563 for ; Fri, 27 Jan 2023 13:00:52 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DA081F80563 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=BXP40Fn0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820854; x=1706356854; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=w9n5zT80vCbdVvQ5MJ7or2NBoNtNjWK0nKVW2cFHFYE=; b=BXP40Fn0GF3QnIeaBQ6x5ktBbTKRNmmBhYVN8WhAdEZ/agw3DiY2+Z1J 6HqJxKYyxcwVYkv28CqO1hOSoUN2MbBT81J9R7KyWKdsFgdObHkRVVLkK esQT08I5RI31O8vEg2VyJc/xpTWoTypoiQHk7dJjZQFzdiT49sXklk6ar DvH/k7peuDJMy73hlIvri8dNMIK7449YM4GIGC1nwuio45pnTQtjlq466 vKXkyFvjaG4yYhIyvzOwgYqKqaypM0twqVcd01Jc3hWgETiNBmU2335vv 1QUUO37Z0RFrjRRgTxVtW8s/Sdps/uhMs3X/e/dp6d6wfJzntD3kA2edE g==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091883" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091883" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:51 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782215" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782215" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:49 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 10/18] ASoC: SOF: sof-audio: Populate the PCM stream pipeline_info Date: Fri, 27 Jan 2023 14:00:23 +0200 Message-Id: <20230127120031.10709-11-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Populate the pipeline_info for the PCM stream with the list of pipeline widgets that need to be handled during the PCM trigger. This will be used in the IPC-specific PCM trigger op to trigger the pipelines. Signed-off-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/sof-audio.c | 69 +++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index b127b304298c..e6796c59e04b 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -367,8 +367,9 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget * (DAI type for capture, AIF type for playback) */ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, - int dir, struct snd_soc_dapm_widget_list *list) + int dir, struct snd_sof_pcm *spcm) { + struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; struct snd_soc_dapm_path *p; int err; int ret = 0; @@ -387,7 +388,7 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap p->walking = true; - err = sof_free_widgets_in_path(sdev, p->sink, dir, list); + err = sof_free_widgets_in_path(sdev, p->sink, dir, spcm); if (err < 0) ret = err; p->walking = false; @@ -403,17 +404,44 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap * The error path in this function ensures that all successfully set up widgets getting freed. */ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, - int dir, struct snd_soc_dapm_widget_list *list) + int dir, struct snd_sof_pcm *spcm) { + struct snd_sof_pcm_stream_pipeline_list *pipeline_list = &spcm->stream[dir].pipeline_list; + struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; + struct snd_sof_widget *swidget = widget->dobj.private; + struct snd_sof_widget *pipe_widget; struct snd_soc_dapm_path *p; int ret; - if (widget->dobj.private) { + if (swidget) { + int i; + ret = sof_widget_setup(sdev, widget->dobj.private); if (ret < 0) return ret; + + /* skip populating the pipe_widgets array if it is NULL */ + if (!pipeline_list->pipe_widgets) + goto sink_setup; + + /* + * Add the widget's pipe_widget to the list of pipelines to be triggered if not + * already in the list. This will result in the pipelines getting added in the + * order source to sink. + */ + for (i = 0; i < pipeline_list->count; i++) { + pipe_widget = pipeline_list->pipe_widgets[i]; + if (pipe_widget == swidget->pipe_widget) + break; + } + + if (i == pipeline_list->count) { + pipeline_list->count++; + pipeline_list->pipe_widgets[i] = swidget->pipe_widget; + } } +sink_setup: snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking) { if (!widget_in_list(list, p->sink)) @@ -421,11 +449,11 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d p->walking = true; - ret = sof_set_up_widgets_in_path(sdev, p->sink, dir, list); + ret = sof_set_up_widgets_in_path(sdev, p->sink, dir, spcm); p->walking = false; if (ret < 0) { - if (widget->dobj.private) - sof_widget_free(sdev, widget->dobj.private); + if (swidget) + sof_widget_free(sdev, swidget); return ret; } } @@ -435,16 +463,20 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d } static int -sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_list *list, +sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, struct snd_pcm_hw_params *fe_params, struct snd_sof_platform_stream_params *platform_params, int dir, enum sof_widget_op op) { + struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; struct snd_soc_dapm_widget *widget; char *str; int ret = 0; int i; + if (!list) + return 0; + for_each_dapm_widgets(list, i, widget) { /* starting widget for playback is AIF type */ if (dir == SNDRV_PCM_STREAM_PLAYBACK && widget->id != snd_soc_dapm_aif_in) @@ -456,11 +488,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l switch (op) { case SOF_WIDGET_SETUP: - ret = sof_set_up_widgets_in_path(sdev, widget, dir, list); + ret = sof_set_up_widgets_in_path(sdev, widget, dir, spcm); str = "set up"; break; case SOF_WIDGET_FREE: - ret = sof_free_widgets_in_path(sdev, widget, dir, list); + ret = sof_free_widgets_in_path(sdev, widget, dir, spcm); str = "free"; break; case SOF_WIDGET_PREPARE: @@ -514,16 +546,16 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, * Prepare widgets for set up. The prepare step is used to allocate memory, assign * instance ID and pick the widget configuration based on the runtime PCM params. */ - ret = sof_walk_widgets_in_order(sdev, list, fe_params, platform_params, + ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, dir, SOF_WIDGET_PREPARE); if (ret < 0) return ret; /* Set up is used to send the IPC to the DSP to create the widget */ - ret = sof_walk_widgets_in_order(sdev, list, fe_params, platform_params, + ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, dir, SOF_WIDGET_SETUP); if (ret < 0) { - ret = sof_walk_widgets_in_order(sdev, list, fe_params, platform_params, + ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, dir, SOF_WIDGET_UNPREPARE); return ret; } @@ -567,15 +599,16 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, return 0; widget_free: - sof_walk_widgets_in_order(sdev, list, fe_params, platform_params, dir, + sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, dir, SOF_WIDGET_FREE); - sof_walk_widgets_in_order(sdev, list, NULL, NULL, dir, SOF_WIDGET_UNPREPARE); + sof_walk_widgets_in_order(sdev, spcm, NULL, NULL, dir, SOF_WIDGET_UNPREPARE); return ret; } int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir) { + struct snd_sof_pcm_stream_pipeline_list *pipeline_list = &spcm->stream[dir].pipeline_list; struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; int ret; @@ -584,14 +617,16 @@ int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int return 0; /* send IPC to free widget in the DSP */ - ret = sof_walk_widgets_in_order(sdev, list, NULL, NULL, dir, SOF_WIDGET_FREE); + ret = sof_walk_widgets_in_order(sdev, spcm, NULL, NULL, dir, SOF_WIDGET_FREE); /* unprepare the widget */ - sof_walk_widgets_in_order(sdev, list, NULL, NULL, dir, SOF_WIDGET_UNPREPARE); + sof_walk_widgets_in_order(sdev, spcm, NULL, NULL, dir, SOF_WIDGET_UNPREPARE); snd_soc_dapm_dai_free_widgets(&list); spcm->stream[dir].list = NULL; + pipeline_list->count = 0; + return ret; } From patchwork Fri Jan 27 12:00:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647559 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 90022C54EAA for ; Fri, 27 Jan 2023 12:04:32 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 375CAEDF; Fri, 27 Jan 2023 13:03:40 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 375CAEDF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821070; bh=+kymWazXPBD0SKozUzfVf3F8zIOViQsRVsyzwhHuWas=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=V1ce2Ty0aaG4xUCC3/O5AvBaluglc5cynKX49s3OHt7D3Fb/e3ah1AQ+kepPBy2WR PeatNeXn6z6ffq/Eqt34Ezw87M46duPuv1Ie3lAbX8csJbdx/Ke+hiQz6+iyXdvqlp GfZePs+sEcdwxhpNdxmtlR/q5j22jgpaaQDpbg/c= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 8BE2BF805AB; Fri, 27 Jan 2023 13:01:09 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 44C16F80568; Fri, 27 Jan 2023 13:00:58 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 57131F80548 for ; Fri, 27 Jan 2023 13:00:54 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 57131F80548 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=UFsWS556 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820855; x=1706356855; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+kymWazXPBD0SKozUzfVf3F8zIOViQsRVsyzwhHuWas=; b=UFsWS556v4Vwj52HJtEVddd+3ANTgu+8uujwjFkkhzMd9Xz8AZG5xXHU PQtfdnoOyhwtcMNnEGEi+Kvz+qeBP+B9B3vh48w2LtMV4XfsoldKqdJAQ tsgPcopG0lrD3RsfRpouy+EDfGcMpn0bbC5q+uTSHdbeyt4hIluKF4DI7 RSTye0u899qCKsnxBMKUwQX7WSZnZKsztaclNtMWeNZz1NnL9/JfvoP6x BKv9PjGSL/QVExcCZZYbIKz1nyod7IRUpeMrogrUnNsgtiTYIoXQWH4bJ 4APciuuokEJgT5mwcc25XBRWWGl+H1cOhtb2ySpiLvLaMDtj2ehIdZyOr A==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091900" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091900" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:53 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782231" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782231" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:51 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 11/18] ASoC: SOF: ipc4-pcm: Use the PCM stream's pipeline_info during trigger Date: Fri, 27 Jan 2023 14:00:24 +0200 Message-Id: <20230127120031.10709-12-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Use the list of pipelines in the PCM stream's pipeline info to trigger the pipelines in the right order. Add a helper for triggering pipelines in batch mode that will be used to trigger multiple pipelines at the same time. Signed-off-by: Ranjani Sridharan Reviewed-by: Libin Yang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- include/sound/sof/ipc4/header.h | 3 + sound/soc/sof/ipc4-pcm.c | 137 ++++++++++++++++++++++++-------- sound/soc/sof/ipc4-topology.h | 10 +++ 3 files changed, 115 insertions(+), 35 deletions(-) diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index 622193be7ac4..d31349bf011d 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -185,6 +185,9 @@ enum sof_ipc4_pipeline_state { #define SOF_IPC4_GLB_PIPE_STATE_MASK GENMASK(15, 0) #define SOF_IPC4_GLB_PIPE_STATE(x) ((x) << SOF_IPC4_GLB_PIPE_STATE_SHIFT) +/* pipeline set state IPC msg extension */ +#define SOF_IPC4_GLB_PIPE_STATE_EXT_MULTI BIT(0) + /* load library ipc msg */ #define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16 #define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index db9d0adb2717..a5482185cd6c 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -13,6 +13,33 @@ #include "ipc4-priv.h" #include "ipc4-topology.h" +static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state, + struct ipc4_pipeline_set_state_data *data) +{ + struct sof_ipc4_msg msg = {{ 0 }}; + u32 primary, ipc_size; + + /* trigger a single pipeline */ + if (data->count == 1) + return sof_ipc4_set_pipeline_state(sdev, data->pipeline_ids[0], state); + + primary = state; + primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_SET_PIPELINE_STATE); + primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); + msg.primary = primary; + + /* trigger multiple pipelines with a single IPC */ + msg.extension = SOF_IPC4_GLB_PIPE_STATE_EXT_MULTI; + + /* ipc_size includes the count and the pipeline IDs for the number of pipelines */ + ipc_size = sizeof(u32) * (data->count + 1); + msg.data_size = ipc_size; + msg.data_ptr = data; + + return sof_ipc_tx_message(sdev->ipc, &msg, ipc_size, NULL, 0); +} + int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state) { struct sof_ipc4_msg msg = {{ 0 }}; @@ -37,60 +64,100 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_sof_widget *pipeline_widget; - struct snd_soc_dapm_widget_list *list; - struct snd_soc_dapm_widget *widget; + struct snd_sof_pcm_stream_pipeline_list *pipeline_list; + struct ipc4_pipeline_set_state_data *data; + struct snd_sof_widget *pipe_widget; struct sof_ipc4_pipeline *pipeline; - struct snd_sof_widget *swidget; struct snd_sof_pcm *spcm; - int ret = 0; - int num_widgets; + int ret; + int i, j; spcm = snd_sof_find_spcm_dai(component, rtd); if (!spcm) return -EINVAL; - list = spcm->stream[substream->stream].list; - - for_each_dapm_widgets(list, num_widgets, widget) { - swidget = widget->dobj.private; + pipeline_list = &spcm->stream[substream->stream].pipeline_list; + + /* nothing to trigger if the list is empty */ + if (!pipeline_list->pipe_widgets) + return 0; + + /* allocate memory for the pipeline data */ + data = kzalloc(struct_size(data, pipeline_ids, pipeline_list->count), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* + * IPC4 requires pipelines to be triggered in order starting at the sink and + * walking all the way to the source. So traverse the pipeline_list in the reverse order. + * Skip the pipelines that have their skip_during_fe_trigger flag set or if they're already + * in the requested state. If there is a fork in the pipeline, the order of triggering + * between the left/right paths will be indeterministic. But the sink->source trigger order + * sink->source would still be guaranteed for each fork independently. + */ + for (i = pipeline_list->count - 1; i >= 0; i--) { + pipe_widget = pipeline_list->pipe_widgets[i]; + pipeline = pipe_widget->private; + if (pipeline->state != state && !pipeline->skip_during_fe_trigger) + data->pipeline_ids[data->count++] = pipe_widget->instance_id; + } - if (!swidget) - continue; + /* return if all pipelines are in the requested state already */ + if (!data->count) { + kfree(data); + return 0; + } - pipeline_widget = swidget->pipe_widget; - pipeline = (struct sof_ipc4_pipeline *)pipeline_widget->private; + /* + * Pause all pipelines. This could result in an extra IPC to pause all pipelines even if + * they are already paused. But it helps keep the logic simpler and the firmware handles + * the repeated pause gracefully. This can be optimized in the future if needed. + */ + ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, data); + if (ret < 0) { + dev_err(sdev->dev, "failed to pause all pipelines\n"); + goto free; + } - if (pipeline->state == state || pipeline->skip_during_fe_trigger) - continue; + /* update PAUSED state for all pipelines that were just triggered */ + for (i = 0; i < data->count; i++) { + for (j = 0; j < pipeline_list->count; j++) { + pipe_widget = pipeline_list->pipe_widgets[j]; + pipeline = pipe_widget->private; - /* first set the pipeline to PAUSED state */ - if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { - ret = sof_ipc4_set_pipeline_state(sdev, pipeline_widget->instance_id, - SOF_IPC4_PIPE_PAUSED); - if (ret < 0) { - dev_err(sdev->dev, "failed to pause pipeline %d\n", - swidget->pipeline_id); - return ret; + if (data->pipeline_ids[i] == pipe_widget->instance_id) { + pipeline->state = SOF_IPC4_PIPE_PAUSED; + break; } } + } - pipeline->state = SOF_IPC4_PIPE_PAUSED; + /* return if this is the final state */ + if (state == SOF_IPC4_PIPE_PAUSED) + goto free; - if (pipeline->state == state) - continue; + /* else set the final state in the DSP */ + ret = sof_ipc4_set_multi_pipeline_state(sdev, state, data); + if (ret < 0) { + dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); + goto free; + } - /* then set the final state */ - ret = sof_ipc4_set_pipeline_state(sdev, pipeline_widget->instance_id, state); - if (ret < 0) { - dev_err(sdev->dev, "failed to set state %d for pipeline %d\n", - state, swidget->pipeline_id); - break; - } + /* update final state for all pipelines that were just triggered */ + for (i = 0; i < data->count; i++) { + for (j = 0; j < pipeline_list->count; j++) { + pipe_widget = pipeline_list->pipe_widgets[j]; + pipeline = pipe_widget->private; - pipeline->state = state; + if (data->pipeline_ids[i] == pipe_widget->instance_id) { + pipeline->state = state; + break; + } + } } +free: + kfree(data); return ret; } diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 028b5d91b9db..ee5d31e68a77 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -84,6 +84,16 @@ struct sof_ipc4_pipeline { bool skip_during_fe_trigger; }; +/** + * struct sof_ipc4_multi_pipeline_data - multi pipeline trigger IPC data + * @count: Number of pipelines to be triggered + * @pipeline_ids: Flexible array of IDs of the pipelines to be triggered + */ +struct ipc4_pipeline_set_state_data { + u32 count; + DECLARE_FLEX_ARRAY(u32, pipeline_ids); +} __packed; + /** * struct sof_ipc4_available_audio_format - Available audio formats * @base_config: Available base config From patchwork Fri Jan 27 12:00:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647558 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 32B0CC54EAA for ; Fri, 27 Jan 2023 12:05:06 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 3C357EBE; Fri, 27 Jan 2023 13:04:14 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3C357EBE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821104; bh=2rKTX750cV41OCkc76ovb9epH0NKmhnhadfJ14nQrNg=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=FtPRPj/tGKIz/SrCyTN7ZhTy3RlQSxK68J7WR5jbYmqxGV8Uv7BFUB7j3KpVp2GTB oPRAN6JTf1kQWkrhmgYMyg4czEaE40fvV3cHwF9ifmdwo4TcMVnSb4F6H/TddofKGR DLVjue/iQ9hDbMGR0qohwreVWKDZUvREWqEeuwD8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id ADE74F805B1; Fri, 27 Jan 2023 13:01:21 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1DC8BF805AB; Fri, 27 Jan 2023 13:01:08 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 909ACF80548 for ; Fri, 27 Jan 2023 13:00:58 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 909ACF80548 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=VicwOTma DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820860; x=1706356860; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2rKTX750cV41OCkc76ovb9epH0NKmhnhadfJ14nQrNg=; b=VicwOTmaqC7mY8EqenlMN0/d32+4dDcJ9NDXwPk9BRe5apZ1g82aZnrU zpAK8bfN7xhgA6ven13qpp5F2+bK5CmBuPCkJQZDsgwXUdDfuFs56W3k8 VztF+s+WETMYThHz+rmwlmdB6KZY0DNhlDIh7fgJ3dbWdYf7MWrbpRURA GbWpxDd/2NEvGceRNlQo0RECO65elmqMH9hQgDIDIRxBd8kubfHa5vTdO yoJ88lJXZesOp7SNDyFRg4sjFbYD05hLw1RMY4lSbr2NoNJQZpZRxE7/t RWQeF/eizZo9ck+sCc1UeBpEa45ruAK9P0Htm/7YzN4dPRxASlGGAunca w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091913" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091913" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:56 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782252" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782252" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:53 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 12/18] ASoC: SOF: Introduce struct snd_sof_pipeline Date: Fri, 27 Jan 2023 14:00:25 +0200 Message-Id: <20230127120031.10709-13-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Introduce struct snd_sof_pipeline to save the information about pipelines including the pipeline widget, their status wrt how many PCM's are using them and whether they are complete or not. In struct snd_sof_widget, replace pipe_widget with spipe and remove complete. In struct snd_sof_pcm_stream_pipeline_list, replace pipe_widgets with pipelines. Update all users accordingly. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/core.c | 1 + sound/soc/sof/intel/hda-dai.c | 2 +- sound/soc/sof/ipc3-topology.c | 9 +++-- sound/soc/sof/ipc4-pcm.c | 23 ++++++----- sound/soc/sof/ipc4-topology.c | 12 +++--- sound/soc/sof/sof-audio.c | 48 +++++++++++++++-------- sound/soc/sof/sof-audio.h | 27 +++++++++---- sound/soc/sof/sof-priv.h | 1 + sound/soc/sof/topology.c | 73 +++++++++++++++++++++++------------ 9 files changed, 126 insertions(+), 70 deletions(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 26a3f7c8c914..7de8673a01ce 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -390,6 +390,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) INIT_LIST_HEAD(&sdev->pcm_list); INIT_LIST_HEAD(&sdev->kcontrol_list); INIT_LIST_HEAD(&sdev->widget_list); + INIT_LIST_HEAD(&sdev->pipeline_list); INIT_LIST_HEAD(&sdev->dai_list); INIT_LIST_HEAD(&sdev->dai_link_list); INIT_LIST_HEAD(&sdev->route_list); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 98eebb4b07e6..193b3e74820a 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -468,7 +468,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, w = snd_soc_dai_get_widget(dai, substream->stream); swidget = w->dobj.private; - pipe_widget = swidget->pipe_widget; + pipe_widget = swidget->spipe->pipe_widget; pipeline = pipe_widget->private; switch (cmd) { diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 3f52dfb19e01..88b9b9507231 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2233,9 +2233,9 @@ static int sof_ipc3_set_up_all_pipelines(struct snd_sof_dev *sdev, bool verify) return ret; } - swidget->complete = sof_ipc3_complete_pipeline(sdev, swidget); - if (swidget->complete < 0) - return swidget->complete; + swidget->spipe->complete = sof_ipc3_complete_pipeline(sdev, swidget); + if (swidget->spipe->complete < 0) + return swidget->spipe->complete; break; default: break; @@ -2317,7 +2317,8 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif if (!verify && !swidget->dynamic_pipeline_widget && SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) { swidget->use_count = 0; - swidget->complete = 0; + if (swidget->spipe) + swidget->spipe->complete = 0; continue; } diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index a5482185cd6c..17a116e8c47c 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -68,6 +68,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, struct ipc4_pipeline_set_state_data *data; struct snd_sof_widget *pipe_widget; struct sof_ipc4_pipeline *pipeline; + struct snd_sof_pipeline *spipe; struct snd_sof_pcm *spcm; int ret; int i, j; @@ -79,7 +80,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, pipeline_list = &spcm->stream[substream->stream].pipeline_list; /* nothing to trigger if the list is empty */ - if (!pipeline_list->pipe_widgets) + if (!pipeline_list->pipelines) return 0; /* allocate memory for the pipeline data */ @@ -96,7 +97,8 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, * sink->source would still be guaranteed for each fork independently. */ for (i = pipeline_list->count - 1; i >= 0; i--) { - pipe_widget = pipeline_list->pipe_widgets[i]; + spipe = pipeline_list->pipelines[i]; + pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; if (pipeline->state != state && !pipeline->skip_during_fe_trigger) data->pipeline_ids[data->count++] = pipe_widget->instance_id; @@ -122,7 +124,8 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, /* update PAUSED state for all pipelines that were just triggered */ for (i = 0; i < data->count; i++) { for (j = 0; j < pipeline_list->count; j++) { - pipe_widget = pipeline_list->pipe_widgets[j]; + spipe = pipeline_list->pipelines[j]; + pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; if (data->pipeline_ids[i] == pipe_widget->instance_id) { @@ -146,7 +149,8 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, /* update final state for all pipelines that were just triggered */ for (i = 0; i < data->count; i++) { for (j = 0; j < pipeline_list->count; j++) { - pipe_widget = pipeline_list->pipe_widgets[j]; + spipe = pipeline_list->pipelines[j]; + pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; if (data->pipeline_ids[i] == pipe_widget->instance_id) { @@ -274,8 +278,8 @@ static void sof_ipc4_pcm_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm for_each_pcm_streams(stream) { pipeline_list = &spcm->stream[stream].pipeline_list; - kfree(pipeline_list->pipe_widgets); - pipeline_list->pipe_widgets = NULL; + kfree(pipeline_list->pipelines); + pipeline_list->pipelines = NULL; } } @@ -289,10 +293,9 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm pipeline_list = &spcm->stream[stream].pipeline_list; /* allocate memory for max number of pipeline IDs */ - pipeline_list->pipe_widgets = kcalloc(ipc4_data->max_num_pipelines, - sizeof(struct snd_sof_widget *), - GFP_KERNEL); - if (!pipeline_list->pipe_widgets) { + pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines, + sizeof(struct snd_sof_widget *), GFP_KERNEL); + if (!pipeline_list->pipelines) { sof_ipc4_pcm_free(sdev, spcm); return -ENOMEM; } diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index f3b1a7f81216..2f82b5e02a27 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -855,7 +855,7 @@ sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widg total = SOF_IPC4_FW_PAGE(task_mem + queue_mem); - pipe_widget = swidget->pipe_widget; + pipe_widget = swidget->spipe->pipe_widget; pipeline = pipe_widget->private; pipeline->mem_usage += total; } @@ -969,7 +969,7 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) struct sof_ipc4_pipeline *pipeline; /* reset pipeline memory usage */ - pipe_widget = swidget->pipe_widget; + pipe_widget = swidget->spipe->pipe_widget; pipeline = pipe_widget->private; pipeline->mem_usage = 0; @@ -1136,7 +1136,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct snd_sof_widget *pipe_widget; struct sof_ipc4_pipeline *pipeline; - pipe_widget = swidget->pipe_widget; + pipe_widget = swidget->spipe->pipe_widget; pipeline = pipe_widget->private; ipc4_copier = (struct sof_ipc4_copier *)swidget->private; gtw_attr = ipc4_copier->gtw_attr; @@ -1495,7 +1495,7 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) { - struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; struct sof_ipc4_fw_data *ipc4_data = sdev->private; struct sof_ipc4_pipeline *pipeline; struct sof_ipc4_msg *msg; @@ -1815,7 +1815,7 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s * routes belonging to the same pipeline will be disconnected by the FW when the pipeline * is freed. So avoid sending this IPC which will be ignored by the FW anyway. */ - if (src_widget->pipe_widget == sink_widget->pipe_widget) + if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) goto out; header = src_fw_module->man4_module_entry.id; @@ -1846,7 +1846,7 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, unsigned int flags, struct snd_sof_dai_config_data *data) { - struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; struct sof_ipc4_pipeline *pipeline = pipe_widget->private; struct snd_sof_dai *dai = swidget->private; struct sof_ipc4_gtw_attributes *gtw_attr; diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index e6796c59e04b..158f7b03fbc2 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -31,6 +31,7 @@ static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_so int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); + struct snd_sof_widget *pipe_widget; int err = 0; int ret; @@ -43,6 +44,8 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) if (--swidget->use_count) return 0; + pipe_widget = swidget->spipe->pipe_widget; + /* reset route setup status for all routes that contain this widget */ sof_reset_route_setup_status(sdev, swidget); @@ -67,12 +70,15 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) * skip for static pipelines */ if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) { - ret = sof_widget_free(sdev, swidget->pipe_widget); + ret = sof_widget_free(sdev, pipe_widget); if (ret < 0 && !err) err = ret; - swidget->pipe_widget->complete = 0; } + /* clear pipeline complete */ + if (swidget->id == snd_soc_dapm_scheduler) + swidget->spipe->complete = 0; + if (!err) dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name); @@ -103,14 +109,13 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) * widget in the pipeline is freed. Skip setting up scheduler widget for static pipelines. */ if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) { - if (!swidget->pipe_widget) { - dev_err(sdev->dev, "No scheduler widget set for %s\n", - swidget->widget->name); + if (!swidget->spipe || !swidget->spipe->pipe_widget) { + dev_err(sdev->dev, "No pipeline set for %s\n", swidget->widget->name); ret = -EINVAL; goto use_count_dec; } - ret = sof_widget_setup(sdev, swidget->pipe_widget); + ret = sof_widget_setup(sdev, swidget->spipe->pipe_widget); if (ret < 0) goto use_count_dec; } @@ -159,7 +164,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) snd_sof_dsp_core_put(sdev, swidget->core); pipe_widget_free: if (swidget->id != snd_soc_dapm_scheduler) - sof_widget_free(sdev, swidget->pipe_widget); + sof_widget_free(sdev, swidget->spipe->pipe_widget); use_count_dec: swidget->use_count--; return ret; @@ -409,7 +414,7 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d struct snd_sof_pcm_stream_pipeline_list *pipeline_list = &spcm->stream[dir].pipeline_list; struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; struct snd_sof_widget *swidget = widget->dobj.private; - struct snd_sof_widget *pipe_widget; + struct snd_sof_pipeline *spipe; struct snd_soc_dapm_path *p; int ret; @@ -421,7 +426,7 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d return ret; /* skip populating the pipe_widgets array if it is NULL */ - if (!pipeline_list->pipe_widgets) + if (!pipeline_list->pipelines) goto sink_setup; /* @@ -430,14 +435,14 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d * order source to sink. */ for (i = 0; i < pipeline_list->count; i++) { - pipe_widget = pipeline_list->pipe_widgets[i]; - if (pipe_widget == swidget->pipe_widget) + spipe = pipeline_list->pipelines[i]; + if (spipe == swidget->spipe) break; } if (i == pipeline_list->count) { pipeline_list->count++; - pipeline_list->pipe_widgets[i] = swidget->pipe_widget; + pipeline_list->pipelines[i] = swidget->spipe; } } @@ -572,11 +577,20 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, for_each_dapm_widgets(list, i, widget) { struct snd_sof_widget *swidget = widget->dobj.private; struct snd_sof_widget *pipe_widget; + struct snd_sof_pipeline *spipe; if (!swidget) continue; - pipe_widget = swidget->pipe_widget; + spipe = swidget->spipe; + if (!spipe) { + dev_err(sdev->dev, "no pipeline found for %s\n", + swidget->widget->name); + ret = -EINVAL; + goto widget_free; + } + + pipe_widget = spipe->pipe_widget; if (!pipe_widget) { dev_err(sdev->dev, "error: no pipeline widget found for %s\n", swidget->widget->name); @@ -584,13 +598,13 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, goto widget_free; } - if (pipe_widget->complete) + if (spipe->complete) continue; if (tplg_ops && tplg_ops->pipeline_complete) { - pipe_widget->complete = tplg_ops->pipeline_complete(sdev, pipe_widget); - if (pipe_widget->complete < 0) { - ret = pipe_widget->complete; + spipe->complete = tplg_ops->pipeline_complete(sdev, pipe_widget); + if (spipe->complete < 0) { + ret = spipe->complete; goto widget_free; } } diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index bb5c61dd9b1e..f1bbd1adc8b6 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -288,11 +288,11 @@ struct sof_token_info { /** * struct snd_sof_pcm_stream_pipeline_list - List of pipelines associated with a PCM stream * @count: number of pipeline widgets in the @pipe_widgets array - * @pipe_widgets: array of pipeline widgets + * @pipelines: array of pipelines */ struct snd_sof_pcm_stream_pipeline_list { u32 count; - struct snd_sof_widget **pipe_widgets; + struct snd_sof_pipeline **pipelines; }; /* PCM stream, mapped to FW component */ @@ -382,11 +382,6 @@ struct snd_sof_widget { struct snd_soc_component *scomp; int comp_id; int pipeline_id; - /* - * complete flag is used to indicate that pipeline set up is complete for scheduler type - * widgets. It is unused for all other widget types. - */ - int complete; /* * the prepared flag is used to indicate that a widget has been prepared for getting set * up in the DSP. @@ -413,7 +408,7 @@ struct snd_sof_widget { struct snd_soc_dapm_widget *widget; struct list_head list; /* list in sdev widget list */ - struct snd_sof_widget *pipe_widget; + struct snd_sof_pipeline *spipe; void *module_info; const guid_t uuid; @@ -451,6 +446,22 @@ struct snd_sof_widget { void *private; /* core does not touch this */ }; +/** struct snd_sof_pipeline - ASoC SOF pipeline + * @pipe_widget: Pointer to the pipeline widget + * @started_count: Count of number of PCM's that have started this pipeline + * @paused_count: Count of number of PCM's that have started and have currently paused this + pipeline + * @complete: flag used to indicate that pipeline set up is complete. + * @list: List item in sdev pipeline_list + */ +struct snd_sof_pipeline { + struct snd_sof_widget *pipe_widget; + int started_count; + int paused_count; + int complete; + struct list_head list; +}; + /* ASoC SOF DAPM route */ struct snd_sof_route { struct snd_soc_component *scomp; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 86fc5c6a9c39..208a30ff3db9 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -578,6 +578,7 @@ struct snd_sof_dev { struct list_head pcm_list; struct list_head kcontrol_list; struct list_head widget_list; + struct list_head pipeline_list; struct list_head dai_list; struct list_head dai_link_list; struct list_head route_list; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 51f6fed45ae7..33ca3067262b 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1402,7 +1402,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, swidget->scomp = scomp; swidget->widget = w; swidget->comp_id = sdev->next_comp_id++; - swidget->complete = 0; swidget->id = w->id; swidget->pipeline_id = index; swidget->private = NULL; @@ -1553,6 +1552,23 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, } } + /* create and add pipeline for scheduler type widgets */ + if (w->id == snd_soc_dapm_scheduler) { + struct snd_sof_pipeline *spipe; + + spipe = kzalloc(sizeof(*spipe), GFP_KERNEL); + if (!spipe) { + kfree(swidget->private); + kfree(swidget->tuples); + kfree(swidget); + return -ENOMEM; + } + + spipe->pipe_widget = swidget; + swidget->spipe = spipe; + list_add(&spipe->list, &sdev->pipeline_list); + } + w->dobj.private = swidget; list_add(&swidget->list, &sdev->widget_list); return ret; @@ -1608,6 +1624,15 @@ static int sof_widget_unload(struct snd_soc_component *scomp, sof_disconnect_dai_widget(scomp, widget); break; + case snd_soc_dapm_scheduler: + { + struct snd_sof_pipeline *spipe = swidget->spipe; + + list_del(&spipe->list); + kfree(spipe); + swidget->spipe = NULL; + break; + } default: break; } @@ -2082,18 +2107,19 @@ static int sof_route_load(struct snd_soc_component *scomp, int index, } /** - * sof_set_pipe_widget - Set pipe_widget for a component + * sof_set_widget_pipeline - Set pipeline for a component * @sdev: pointer to struct snd_sof_dev - * @pipe_widget: pointer to struct snd_sof_widget of type snd_soc_dapm_scheduler + * @spipe: pointer to struct snd_sof_pipeline * @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget * * Return: 0 if successful, -EINVAL on error. * The function checks if @swidget is associated with any volatile controls. If so, setting * the dynamic_pipeline_widget is disallowed. */ -static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *pipe_widget, - struct snd_sof_widget *swidget) +static int sof_set_widget_pipeline(struct snd_sof_dev *sdev, struct snd_sof_pipeline *spipe, + struct snd_sof_widget *swidget) { + struct snd_sof_widget *pipe_widget = spipe->pipe_widget; struct snd_sof_control *scontrol; if (pipe_widget->dynamic_pipeline_widget) { @@ -2108,8 +2134,8 @@ static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget * } } - /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */ - swidget->pipe_widget = pipe_widget; + /* set the pipeline and apply the dynamic_pipeline_widget_flag */ + swidget->spipe = spipe; swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget; return 0; @@ -2123,6 +2149,7 @@ static int sof_complete(struct snd_soc_component *scomp) struct snd_sof_widget *swidget, *comp_swidget; const struct sof_ipc_tplg_widget_ops *widget_ops; struct snd_sof_control *scontrol; + struct snd_sof_pipeline *spipe; int ret; widget_ops = tplg_ops ? tplg_ops->widget : NULL; @@ -2155,23 +2182,21 @@ static int sof_complete(struct snd_soc_component *scomp) } /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */ - list_for_each_entry(swidget, &sdev->widget_list, list) { - switch (swidget->id) { - case snd_soc_dapm_scheduler: - /* - * Apply the dynamic_pipeline_widget flag and set the pipe_widget field - * for all widgets that have the same pipeline ID as the scheduler widget - */ - list_for_each_entry(comp_swidget, &sdev->widget_list, list) - if (comp_swidget->pipeline_id == swidget->pipeline_id) { - ret = sof_set_pipe_widget(sdev, swidget, comp_swidget); - if (ret < 0) - return ret; - } - break; - default: - break; - } + list_for_each_entry(spipe, &sdev->pipeline_list, list) { + struct snd_sof_widget *pipe_widget = spipe->pipe_widget; + + /* + * Apply the dynamic_pipeline_widget flag and set the pipe_widget field + * for all widgets that have the same pipeline ID as the scheduler widget. + * Skip the scheduler widgets as they have their pipeline set during widget_ready + */ + list_for_each_entry(comp_swidget, &sdev->widget_list, list) + if (comp_swidget->widget->id != snd_soc_dapm_scheduler && + comp_swidget->pipeline_id == pipe_widget->pipeline_id) { + ret = sof_set_widget_pipeline(sdev, spipe, comp_swidget); + if (ret < 0) + return ret; + } } /* verify topology components loading including dynamic pipelines */ From patchwork Fri Jan 27 12:00:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3B29BC54EAA for ; Fri, 27 Jan 2023 12:04:51 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EF754EE0; Fri, 27 Jan 2023 13:03:58 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EF754EE0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821089; bh=PPo0KwcTlNQHFN82YqyJJd1QX7wbrdoJBDXbFwxNjTk=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=owOIRiHkzxR0FPM2lP6T4GY5JqGO8wKnlusaBUEdmIf79pUfPG6GNSi+XA2cs5INE x97cSKasOGPCQg3lidsrqGm5/a7pTXbn1DZXqDcgHWJBREjNYWafOH3QYSR+8OCeBs cA7RztwPv1bE66FVYg+5M4ZNXa7iai+wXJX7IWzU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 58BDCF805B0; Fri, 27 Jan 2023 13:01:11 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 5E2CFF80589; Fri, 27 Jan 2023 13:01:04 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id ECD88F80571 for ; Fri, 27 Jan 2023 13:01:00 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz ECD88F80571 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=DRw22snM DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820862; x=1706356862; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PPo0KwcTlNQHFN82YqyJJd1QX7wbrdoJBDXbFwxNjTk=; b=DRw22snMa5XBCgi5tvpLEY1MEmKqm/g3fxWbEhvJSr7oJyPEOcD0aXt1 nUHA1DTsQbOLKfgol2oFiVTkwGrfC08R34MlOOgZVvO66YkUWG1UUMPKg 29d3tZHzKby0nTbPbgF+HRhg3TYbTj0K0Zam6zB3CcE9KwNNSZbDahgXG SLBLRePU3H5feXOPQHkacZyTotH07aXzTYON3qpYENkHGtK4nooDNBsS+ nBtVan+r/qD9zZudcLWhbM818zj3pKroC4ayBTY4PH6Woko6AHtUSpWBD UG/0DuBBeG/VlHmGPNRNObxymsnVync/S7ycphvZ1F9zuLrM1ddCyu5Kt A==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091924" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091924" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:58 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782275" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782275" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:56 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 13/18] ASoC: SOF: ipc4-pcm: Rename 'data' variable to trigger_list Date: Fri, 27 Jan 2023 14:00:26 +0200 Message-Id: <20230127120031.10709-14-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan For more clarity, rename the struct ipc4_pipeline_set_state_data variable to trigger_list instead of data. No functionality change. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc4-pcm.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 17a116e8c47c..284e402709be 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -14,14 +14,14 @@ #include "ipc4-topology.h" static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state, - struct ipc4_pipeline_set_state_data *data) + struct ipc4_pipeline_set_state_data *trigger_list) { struct sof_ipc4_msg msg = {{ 0 }}; u32 primary, ipc_size; /* trigger a single pipeline */ - if (data->count == 1) - return sof_ipc4_set_pipeline_state(sdev, data->pipeline_ids[0], state); + if (trigger_list->count == 1) + return sof_ipc4_set_pipeline_state(sdev, trigger_list->pipeline_ids[0], state); primary = state; primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_SET_PIPELINE_STATE); @@ -33,9 +33,9 @@ static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state msg.extension = SOF_IPC4_GLB_PIPE_STATE_EXT_MULTI; /* ipc_size includes the count and the pipeline IDs for the number of pipelines */ - ipc_size = sizeof(u32) * (data->count + 1); + ipc_size = sizeof(u32) * (trigger_list->count + 1); msg.data_size = ipc_size; - msg.data_ptr = data; + msg.data_ptr = trigger_list; return sof_ipc_tx_message(sdev->ipc, &msg, ipc_size, NULL, 0); } @@ -65,7 +65,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_sof_pcm_stream_pipeline_list *pipeline_list; - struct ipc4_pipeline_set_state_data *data; + struct ipc4_pipeline_set_state_data *trigger_list; struct snd_sof_widget *pipe_widget; struct sof_ipc4_pipeline *pipeline; struct snd_sof_pipeline *spipe; @@ -84,8 +84,9 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, return 0; /* allocate memory for the pipeline data */ - data = kzalloc(struct_size(data, pipeline_ids, pipeline_list->count), GFP_KERNEL); - if (!data) + trigger_list = kzalloc(struct_size(trigger_list, pipeline_ids, pipeline_list->count), + GFP_KERNEL); + if (!trigger_list) return -ENOMEM; /* @@ -101,12 +102,13 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; if (pipeline->state != state && !pipeline->skip_during_fe_trigger) - data->pipeline_ids[data->count++] = pipe_widget->instance_id; + trigger_list->pipeline_ids[trigger_list->count++] = + pipe_widget->instance_id; } /* return if all pipelines are in the requested state already */ - if (!data->count) { - kfree(data); + if (!trigger_list->count) { + kfree(trigger_list); return 0; } @@ -115,20 +117,20 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, * they are already paused. But it helps keep the logic simpler and the firmware handles * the repeated pause gracefully. This can be optimized in the future if needed. */ - ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, data); + ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list); if (ret < 0) { dev_err(sdev->dev, "failed to pause all pipelines\n"); goto free; } /* update PAUSED state for all pipelines that were just triggered */ - for (i = 0; i < data->count; i++) { + for (i = 0; i < trigger_list->count; i++) { for (j = 0; j < pipeline_list->count; j++) { spipe = pipeline_list->pipelines[j]; pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; - if (data->pipeline_ids[i] == pipe_widget->instance_id) { + if (trigger_list->pipeline_ids[i] == pipe_widget->instance_id) { pipeline->state = SOF_IPC4_PIPE_PAUSED; break; } @@ -140,20 +142,20 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, goto free; /* else set the final state in the DSP */ - ret = sof_ipc4_set_multi_pipeline_state(sdev, state, data); + ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list); if (ret < 0) { dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); goto free; } /* update final state for all pipelines that were just triggered */ - for (i = 0; i < data->count; i++) { + for (i = 0; i < trigger_list->count; i++) { for (j = 0; j < pipeline_list->count; j++) { spipe = pipeline_list->pipelines[j]; pipe_widget = spipe->pipe_widget; pipeline = pipe_widget->private; - if (data->pipeline_ids[i] == pipe_widget->instance_id) { + if (trigger_list->pipeline_ids[i] == pipe_widget->instance_id) { pipeline->state = state; break; } @@ -161,7 +163,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, } free: - kfree(data); + kfree(trigger_list); return ret; } From patchwork Fri Jan 27 12:00:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647994 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 00B5CC636CB for ; Fri, 27 Jan 2023 12:05:20 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 77CE0EE5; Fri, 27 Jan 2023 13:04:28 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 77CE0EE5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821119; bh=YnmSLJaFnFtOzmsH3VkHh5gTAVhICMT69MYMah7BKLA=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=q6GYBoSVVtNrHPLAEsTK+jPG2Rt3emYsfuv0bZ/ckAHUy3lTM1X33cwNWKc6oDrbC Xx2HmbjptathABJDRtsmreQ7LNeOOfofqvzNNGrUVdxBXrklRQQeVhIaV8Tqc0n6Kq Z+olIfweCIPcN8RzuV+7JYXzNw3wHs1lsETd6Ws0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 56F7CF805B6; Fri, 27 Jan 2023 13:01:22 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id ADE43F8057A; Fri, 27 Jan 2023 13:01:09 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 03DCAF8057A for ; Fri, 27 Jan 2023 13:01:01 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 03DCAF8057A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=W2xJjXmy DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820863; x=1706356863; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YnmSLJaFnFtOzmsH3VkHh5gTAVhICMT69MYMah7BKLA=; b=W2xJjXmyhM4X1ZQ6UPIq4ysaqyVQTn+ym3G97rLzk+5O4o+5R5bgd7zG o2XUwCj4Kqm6Wv/jUNXOyt+AZfzn97xecbUF9RiFzFtnNiRexpaDl0cPy oBN4sGzepql5saJtGCREblARF448WH9AhAAE8qyPj/lv+j1MH8Wgdpsn2 YX9POsMA4l/fRz+isZKfj2pgoDtfIFp3pqD+vmTzQ7ZGusgiIFAeQ7GYY X1vHdlv5ejeyO0F7BDKFzr5rZmzm0qXnWuZi++3W5uYSiP2nApkfCzs4c VdZhnvDlTH7eiyRWtnGiopK09dhkB2faMGoBxID8DdbibsTt358nKTg39 w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091936" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091936" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:01 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782295" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782295" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:00:59 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 14/18] ASoC: SOF: ipc4-pcm: Implement pipeline trigger reference counting Date: Fri, 27 Jan 2023 14:00:27 +0200 Message-Id: <20230127120031.10709-15-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan Use the started_count and paused_count to implement reference counting when making decisions to start/stop/pause pipelines during the FE DAI trigger. This is necessary to trigger the shared pipelines in the FE DAI trigger properly. With IPC4, the FE trigger will issue multiple pipeline state changes, and the triggers are propagated downstream to connected pipelines by the SOF driver - not the firmware. This creates a window for race conditions where an FE trigger preempts another one, which results in inconsistent pipeline states and refcounts. This patch introduces a mutex lock for the pcm trigger that guarantees that IPC4 state and resources are accessed in a serialized manner. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc4-pcm.c | 228 +++++++++++++++++++++++++++++--------- sound/soc/sof/ipc4-priv.h | 2 + sound/soc/sof/ipc4.c | 2 + 3 files changed, 182 insertions(+), 50 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 284e402709be..ababa29d6eac 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -59,19 +59,152 @@ int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state) } EXPORT_SYMBOL(sof_ipc4_set_pipeline_state); +static void +sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state, + struct snd_sof_pipeline *spipe, + struct ipc4_pipeline_set_state_data *trigger_list) +{ + struct snd_sof_widget *pipe_widget = spipe->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + + if (pipeline->skip_during_fe_trigger) + return; + + switch (state) { + case SOF_IPC4_PIPE_RUNNING: + /* + * Trigger pipeline if all PCMs containing it are paused or if it is RUNNING + * for the first time + */ + if (spipe->started_count == spipe->paused_count) + trigger_list->pipeline_ids[trigger_list->count++] = + pipe_widget->instance_id; + break; + case SOF_IPC4_PIPE_RESET: + /* RESET if the pipeline is neither running nor paused */ + if (!spipe->started_count && !spipe->paused_count) + trigger_list->pipeline_ids[trigger_list->count++] = + pipe_widget->instance_id; + break; + case SOF_IPC4_PIPE_PAUSED: + /* Pause the pipeline only when its started_count is 1 more than paused_count */ + if (spipe->paused_count == (spipe->started_count - 1)) + trigger_list->pipeline_ids[trigger_list->count++] = + pipe_widget->instance_id; + break; + default: + break; + } +} + +static void +sof_ipc4_update_pipeline_state(struct snd_sof_dev *sdev, int state, int cmd, + struct snd_sof_pipeline *spipe, + struct ipc4_pipeline_set_state_data *trigger_list) +{ + struct snd_sof_widget *pipe_widget = spipe->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + int i; + + if (pipeline->skip_during_fe_trigger) + return; + + /* set state for pipeline if it was just triggered */ + for (i = 0; i < trigger_list->count; i++) { + if (trigger_list->pipeline_ids[i] == pipe_widget->instance_id) { + pipeline->state = state; + break; + } + } + + switch (state) { + case SOF_IPC4_PIPE_PAUSED: + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + /* + * increment paused_count if the PAUSED is the final state during + * the PAUSE trigger + */ + spipe->paused_count++; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + /* + * decrement started_count if PAUSED is the final state during the + * STOP trigger + */ + spipe->started_count--; + break; + default: + break; + } + break; + case SOF_IPC4_PIPE_RUNNING: + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* decrement paused_count for RELEASE */ + spipe->paused_count--; + break; + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* increment started_count for START/RESUME */ + spipe->started_count++; + break; + default: + break; + } + break; + default: + break; + } +} + +/* + * The picture below represents the pipeline state machine wrt PCM actions corresponding to the + * triggers and ioctls + * +---------------+ + * | | + * | INIT | + * | | + * +-------+-------+ + * | + * | + * | START + * | + * | + * +----------------+ +------v-------+ +-------------+ + * | | START | | HW_FREE | | + * | RUNNING <-------------+ PAUSED +--------------> + RESET | + * | | PAUSE | | | | + * +------+---------+ RELEASE +---------+----+ +-------------+ + * | ^ + * | | + * | | + * | | + * | PAUSE | + * +---------------------------------+ + * STOP/SUSPEND + * + * Note that during system suspend, the suspend trigger is followed by a hw_free in + * sof_pcm_trigger(). So, the final state during suspend would be RESET. + * Also, since the SOF driver doesn't support full resume, streams would be restarted with the + * prepare ioctl before the START trigger. + */ + static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, - struct snd_pcm_substream *substream, int state) + struct snd_pcm_substream *substream, int state, int cmd) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_sof_pcm_stream_pipeline_list *pipeline_list; + struct sof_ipc4_fw_data *ipc4_data = sdev->private; struct ipc4_pipeline_set_state_data *trigger_list; - struct snd_sof_widget *pipe_widget; - struct sof_ipc4_pipeline *pipeline; struct snd_sof_pipeline *spipe; struct snd_sof_pcm *spcm; int ret; - int i, j; + int i; + + dev_dbg(sdev->dev, "trigger cmd: %d state: %d\n", cmd, state); spcm = snd_sof_find_spcm_dai(component, rtd); if (!spcm) @@ -89,33 +222,41 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, if (!trigger_list) return -ENOMEM; + mutex_lock(&ipc4_data->trigger_mutex); + /* * IPC4 requires pipelines to be triggered in order starting at the sink and - * walking all the way to the source. So traverse the pipeline_list in the reverse order. - * Skip the pipelines that have their skip_during_fe_trigger flag set or if they're already - * in the requested state. If there is a fork in the pipeline, the order of triggering - * between the left/right paths will be indeterministic. But the sink->source trigger order - * sink->source would still be guaranteed for each fork independently. + * walking all the way to the source. So traverse the pipeline_list in the order + * sink->source when starting PCM's and in the reverse order to pause/stop PCM's. + * Skip the pipelines that have their skip_during_fe_trigger flag set. If there is a fork + * in the pipeline, the order of triggering between the left/right paths will be + * indeterministic. But the sink->source trigger order sink->source would still be + * guaranteed for each fork independently. */ - for (i = pipeline_list->count - 1; i >= 0; i--) { - spipe = pipeline_list->pipelines[i]; - pipe_widget = spipe->pipe_widget; - pipeline = pipe_widget->private; - if (pipeline->state != state && !pipeline->skip_during_fe_trigger) - trigger_list->pipeline_ids[trigger_list->count++] = - pipe_widget->instance_id; - } + if (state == SOF_IPC4_PIPE_RUNNING || state == SOF_IPC4_PIPE_RESET) + for (i = pipeline_list->count - 1; i >= 0; i--) { + spipe = pipeline_list->pipelines[i]; + sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); + } + else + for (i = 0; i < pipeline_list->count; i++) { + spipe = pipeline_list->pipelines[i]; + sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); + } /* return if all pipelines are in the requested state already */ if (!trigger_list->count) { - kfree(trigger_list); - return 0; + ret = 0; + goto free; } + /* no need to pause before reset or before pause release */ + if (state == SOF_IPC4_PIPE_RESET || cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) + goto skip_pause_transition; + /* - * Pause all pipelines. This could result in an extra IPC to pause all pipelines even if - * they are already paused. But it helps keep the logic simpler and the firmware handles - * the repeated pause gracefully. This can be optimized in the future if needed. + * set paused state for pipelines if the final state is PAUSED or when the pipeline + * is set to RUNNING for the first time after the PCM is started. */ ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list); if (ret < 0) { @@ -123,46 +264,32 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, goto free; } - /* update PAUSED state for all pipelines that were just triggered */ - for (i = 0; i < trigger_list->count; i++) { - for (j = 0; j < pipeline_list->count; j++) { - spipe = pipeline_list->pipelines[j]; - pipe_widget = spipe->pipe_widget; - pipeline = pipe_widget->private; - - if (trigger_list->pipeline_ids[i] == pipe_widget->instance_id) { - pipeline->state = SOF_IPC4_PIPE_PAUSED; - break; - } - } + /* update PAUSED state for all pipelines just triggered */ + for (i = 0; i < pipeline_list->count ; i++) { + spipe = pipeline_list->pipelines[i]; + sof_ipc4_update_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, cmd, spipe, + trigger_list); } /* return if this is the final state */ if (state == SOF_IPC4_PIPE_PAUSED) goto free; - - /* else set the final state in the DSP */ +skip_pause_transition: + /* else set the RUNNING/RESET state in the DSP */ ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list); if (ret < 0) { dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); goto free; } - /* update final state for all pipelines that were just triggered */ - for (i = 0; i < trigger_list->count; i++) { - for (j = 0; j < pipeline_list->count; j++) { - spipe = pipeline_list->pipelines[j]; - pipe_widget = spipe->pipe_widget; - pipeline = pipe_widget->private; - - if (trigger_list->pipeline_ids[i] == pipe_widget->instance_id) { - pipeline->state = state; - break; - } - } + /* update RUNNING/RESET state for all pipelines that were just triggered */ + for (i = 0; i < pipeline_list->count; i++) { + spipe = pipeline_list->pipelines[i]; + sof_ipc4_update_pipeline_state(sdev, state, cmd, spipe, trigger_list); } free: + mutex_unlock(&ipc4_data->trigger_mutex); kfree(trigger_list); return ret; } @@ -192,13 +319,14 @@ static int sof_ipc4_pcm_trigger(struct snd_soc_component *component, } /* set the pipeline state */ - return sof_ipc4_trigger_pipelines(component, substream, state); + return sof_ipc4_trigger_pipelines(component, substream, state, cmd); } static int sof_ipc4_pcm_hw_free(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET); + /* command is not relevant with RESET, so just pass 0 */ + return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET, 0); } static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name, diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index fc9efdce67e0..0c0d48376045 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -70,6 +70,7 @@ struct sof_ipc4_fw_library { * base firmware * * @load_library: Callback function for platform dependent library loading + * @trigger_mutex: Mutex to protect pipeline triggers, ref counts and states */ struct sof_ipc4_fw_data { u32 manifest_fw_hdr_offset; @@ -82,6 +83,7 @@ struct sof_ipc4_fw_data { int (*load_library)(struct snd_sof_dev *sdev, struct sof_ipc4_fw_library *fw_lib, bool reload); + struct mutex trigger_mutex; /* protect pipeline triggers, ref counts and states */ }; extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 74cd7e956019..fb4760ae593f 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -662,6 +662,8 @@ static int sof_ipc4_init(struct snd_sof_dev *sdev) { struct sof_ipc4_fw_data *ipc4_data = sdev->private; + mutex_init(&ipc4_data->trigger_mutex); + xa_init_flags(&ipc4_data->fw_lib_xa, XA_FLAGS_ALLOC); return 0; From patchwork Fri Jan 27 12:00:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647556 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 95BFBC38142 for ; Fri, 27 Jan 2023 12:06:08 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 55598ECF; Fri, 27 Jan 2023 13:05:16 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 55598ECF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821166; bh=5Va798cQXhbO862MbOkfolstSdalrkBTuJu5kXBJ9co=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=t8zGICvq3D5VERi8hIDApQTpbKwD8UMS2aSMS5rIO01tK69zT3D3r/zJ3p67B3r7w BfP1o5gEEqjhTA3ef6YRI93AoU1r0x7e203SV5P+z4Z2zO416zS4fXmSFBpGSK1ACI BbeQ9QJ5BLLPsM1lnCi6k7pCKg7G1CNb1UcEx39Y= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4B50FF805C6; Fri, 27 Jan 2023 13:01:27 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EE026F805B4; Fri, 27 Jan 2023 13:01:16 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CBE5FF805A0 for ; Fri, 27 Jan 2023 13:01:05 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CBE5FF805A0 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=k0Ba5aeN DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820867; x=1706356867; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5Va798cQXhbO862MbOkfolstSdalrkBTuJu5kXBJ9co=; b=k0Ba5aeNuWJoJvz6zt1AT75AIZa+d/JDkCKRJrjqJV9WtBHueTzoAPIH 45yiZrtwKSC+ula6P5s8X+z0/VvMXYR2sMx3vm49k8u/C0F86FwNILf/8 kdBskQEwQjKLA3J61MY4/0oj3E3jGcp850xM5oyO4nqxfg17xbANEvUOL wUy6Ivc9iFnyj7XuZ5U5oZmqBmAJJaSJ8TPtxH9k6//YtxdPvZEqHEOwX yiva4IEa2f2uReuY/HYSqmxOyOPDfE9Cav2G0EcMOCAx7uFXaEVc34WDK GWlnzRXzaxlBE/rGMbukRTJY2VCDtZL/g4abcOqVIg4s4g3iwF0y4U+ZP w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091959" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091959" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:03 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782320" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782320" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:01 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 15/18] ASoC: SOF: ipc4-topology: Protect pipeline free with mutex Date: Fri, 27 Jan 2023 14:00:28 +0200 Message-Id: <20230127120031.10709-16-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Ranjani Sridharan When starting/stopping multiple streams in parallel, pipeline triggers and pipeline frees can get interleaved. So use the same mutex used for pipeline trigger to protect the pipeline frees as well. Rename the trigger_mutex to pipeline_state_mutex for more clarity. Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc4-pcm.c | 4 ++-- sound/soc/sof/ipc4-priv.h | 4 ++-- sound/soc/sof/ipc4-topology.c | 5 +++++ sound/soc/sof/ipc4.c | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index ababa29d6eac..2d89d3708ed0 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -222,7 +222,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, if (!trigger_list) return -ENOMEM; - mutex_lock(&ipc4_data->trigger_mutex); + mutex_lock(&ipc4_data->pipeline_state_mutex); /* * IPC4 requires pipelines to be triggered in order starting at the sink and @@ -289,7 +289,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, } free: - mutex_unlock(&ipc4_data->trigger_mutex); + mutex_unlock(&ipc4_data->pipeline_state_mutex); kfree(trigger_list); return ret; } diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index 0c0d48376045..38bb3d7df42e 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -70,7 +70,7 @@ struct sof_ipc4_fw_library { * base firmware * * @load_library: Callback function for platform dependent library loading - * @trigger_mutex: Mutex to protect pipeline triggers, ref counts and states + * @pipeline_state_mutex: Mutex to protect pipeline triggers, ref counts, states and deletion */ struct sof_ipc4_fw_data { u32 manifest_fw_hdr_offset; @@ -83,7 +83,7 @@ struct sof_ipc4_fw_data { int (*load_library)(struct snd_sof_dev *sdev, struct sof_ipc4_fw_library *fw_lib, bool reload); - struct mutex trigger_mutex; /* protect pipeline triggers, ref counts and states */ + struct mutex pipeline_state_mutex; /* protect pipeline triggers, ref counts and states */ }; extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 2f82b5e02a27..43340c8917b7 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1625,8 +1625,11 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) { struct sof_ipc4_fw_module *fw_module = swidget->module_info; + struct sof_ipc4_fw_data *ipc4_data = sdev->private; int ret = 0; + mutex_lock(&ipc4_data->pipeline_state_mutex); + /* freeing a pipeline frees all the widgets associated with it */ if (swidget->id == snd_soc_dapm_scheduler) { struct sof_ipc4_pipeline *pipeline = swidget->private; @@ -1652,6 +1655,8 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget ida_free(&fw_module->m_ida, swidget->instance_id); } + mutex_unlock(&ipc4_data->pipeline_state_mutex); + return ret; } diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index fb4760ae593f..35c9f3913d9a 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -662,7 +662,7 @@ static int sof_ipc4_init(struct snd_sof_dev *sdev) { struct sof_ipc4_fw_data *ipc4_data = sdev->private; - mutex_init(&ipc4_data->trigger_mutex); + mutex_init(&ipc4_data->pipeline_state_mutex); xa_init_flags(&ipc4_data->fw_lib_xa, XA_FLAGS_ALLOC); From patchwork Fri Jan 27 12:00:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647557 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AC9F3C54EAA for ; Fri, 27 Jan 2023 12:05:38 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 82A09ED0; Fri, 27 Jan 2023 13:04:46 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 82A09ED0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821136; bh=/zQedUmqQ05hRyXZMI9pSi2x6aVDsMgYOBr4faBAQkg=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=qH+5yFuPvDS8ZhjFYHVEBWiyQYBMaEXfPdsZcHXyhcPG76rMgBSWFq1p/MTh+wVio sjhS0BgMKVUy7tw3C6swGxSXyjCpAgoXQ55JfTDz4/10FRdMFyB1qQqkH4S68lqobv h3NeRG5ecPaQu6lm7gBPGmtHu37U1gCkYKimewsk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F2FCEF805BE; Fri, 27 Jan 2023 13:01:22 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id DA93FF805B1; Fri, 27 Jan 2023 13:01:10 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 0365EF80154 for ; Fri, 27 Jan 2023 13:01:07 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 0365EF80154 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=G5HqE8Yv DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820869; x=1706356869; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/zQedUmqQ05hRyXZMI9pSi2x6aVDsMgYOBr4faBAQkg=; b=G5HqE8YvMbUYD6u0jwmJKSP8DhBnPdUaDyJtI30bnL5Ls4tjPPrdFO/i C0KNW6gycOyR4a0+EeKVaRWyWycoeEf33TNdnMhk3k0iwb/oQRkuVg+P9 LM83ICiNLVyKVyjFtA9EZpcKZpVsvVF7OKvzr5V7cEnAIcbomBo/ETqOU kTBGCZkTJEfYqUXVg9zehiFFeOyx5cuDB/HGinFMJxRP6g+HXCKH7knR/ tkniulhS+9z9S6O4VE0Tf2Y654Qbpoec9QSZnPDTgKy2p+Cl8i9eJxE0v 33bncYbd1atqbWZUOQwZOMuSGjHbVg5fa6RqdQDV9IBdpnJVbi9Td2aic Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091973" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091973" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:06 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782343" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782343" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:04 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 16/18] ASoC: SOF: Avoid double decrementing use_count in sof_widget_setup on error Date: Fri, 27 Jan 2023 14:00:29 +0200 Message-Id: <20230127120031.10709-17-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The sof_widget_free() on the error path will decrement the use count and if we jump to widget_free: then the use_count will be decremented by two, which is not correct as we only incremented once with 1. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan --- sound/soc/sof/sof-audio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 158f7b03fbc2..14b4b949d081 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -89,6 +89,7 @@ EXPORT_SYMBOL(sof_widget_free); int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); + bool use_count_decremented = false; int ret; /* skip if there is no private data */ @@ -160,13 +161,16 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) widget_free: /* widget use_count and core ref_count will both be decremented by sof_widget_free() */ sof_widget_free(sdev, swidget); + use_count_decremented = true; core_put: snd_sof_dsp_core_put(sdev, swidget->core); pipe_widget_free: if (swidget->id != snd_soc_dapm_scheduler) sof_widget_free(sdev, swidget->spipe->pipe_widget); use_count_dec: - swidget->use_count--; + if (!use_count_decremented) + swidget->use_count--; + return ret; } EXPORT_SYMBOL(sof_widget_setup); From patchwork Fri Jan 27 12:00:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4000AC54EAA for ; Fri, 27 Jan 2023 12:05:51 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 10849EEA; Fri, 27 Jan 2023 13:04:59 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 10849EEA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821149; bh=JlP7tSdET7YNPyTP/iqqIcvig2UOEilz8efwoMaz1CQ=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=gsJie1oHMlm49Kc+7X7OYNg8y4RRToM3O9oY1oVApaRE8ukIQj8bSZezxsgfeIvDU Wtae8tzwet2GXgcP9llz5RaiMoj+NmQLA2fGyBFa22gfkijrD68r9vYBaP8NE9r4x4 MA8/ziHh6LpeSOjeX9DDE7MWHvJSCplTHLGM0h4U= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9FBDDF805C2; Fri, 27 Jan 2023 13:01:23 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 896D0F805B5; Fri, 27 Jan 2023 13:01:15 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 91F93F8057A for ; Fri, 27 Jan 2023 13:01:09 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 91F93F8057A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=dnXwZnL0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820870; x=1706356870; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JlP7tSdET7YNPyTP/iqqIcvig2UOEilz8efwoMaz1CQ=; b=dnXwZnL0uqsX170kcR0n58AfuLsLD3DKx8o986933bWr5u04KknwtoFO eXR5CysYzDy0b7B7iiZK7jW5sIS3J0YKQnCMdn0U6laWIigECjRKASTkf uA2UlIEQO6JnYokLZJK1U7NFPJBJayNVrqSeQJvYvna2RK0EyQYpvjbnU Vz6J1SW6Q9na3oxYbSrKbB+RAEFj+nPqBovR0zXLA5YxcsDrPbFaZUZaX aOe75jsxcSRPVQCTx8g6J1udoV3yd0RzYIhTOLK3DTgskFl2uDPvfz8lq IvAAA+D5aedgVREohdKse2xYS3iYIoFtVJn91RYh/4Ykb8H38QsfMcSpl g==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091982" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091982" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:09 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782364" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782364" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:06 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 17/18] ASoC: SOF: Protect swidget->use_count with mutex for kcontrol access race Date: Fri, 27 Jan 2023 14:00:30 +0200 Message-Id: <20230127120031.10709-18-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The use_count of the swidget is protect by ALSA core PCM locking with the exception when an associated kcontrol is changed. It has been observed that a rightly timed kcontrol access during stream stop can result of an attempt to send a control update to a widget which has been freed up between the check of the use_count and the message sending. We need to protect the entire sof_widget_setup() and sof_widget_free() execution to make it safe to rely on the use_count. Move the code under an _unlocked() function and use a mutex to protect the execution of the functions for concurrency. On the control path we need to use the lock only for the kcontrol access, the widget_kcontrol_setup() op is called with the lock already held. Reported-by: Guennadi Liakhovetski Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan --- sound/soc/sof/ipc3-control.c | 46 +++++++++++++++++++++++------------ sound/soc/sof/ipc3-topology.c | 2 ++ sound/soc/sof/ipc4-control.c | 33 +++++++++++++++++-------- sound/soc/sof/sof-audio.c | 36 ++++++++++++++++++++++----- sound/soc/sof/sof-audio.h | 11 ++++++++- sound/soc/sof/topology.c | 2 ++ 6 files changed, 97 insertions(+), 33 deletions(-) diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index 3fdc0d854e65..217ac5501a98 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -12,7 +12,8 @@ #include "ipc3-priv.h" /* IPC set()/get() for kcontrols. */ -static int sof_ipc3_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool set) +static int sof_ipc3_set_get_kcontrol_data(struct snd_sof_control *scontrol, + bool set, bool lock) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scontrol->scomp); struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; @@ -21,6 +22,7 @@ static int sof_ipc3_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool struct snd_sof_widget *swidget; bool widget_found = false; u32 ipc_cmd, msg_bytes; + int ret = 0; list_for_each_entry(swidget, &sdev->widget_list, list) { if (swidget->comp_id == scontrol->comp_id) { @@ -35,13 +37,18 @@ static int sof_ipc3_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool return -EINVAL; } + if (lock) + mutex_lock(&swidget->setup_mutex); + else + lockdep_assert_held(&swidget->setup_mutex); + /* - * Volatile controls should always be part of static pipelines and the widget use_count - * would always be > 0 in this case. For the others, just return the cached value if the - * widget is not set up. + * Volatile controls should always be part of static pipelines and the + * widget use_count would always be > 0 in this case. For the others, + * just return the cached value if the widget is not set up. */ if (!swidget->use_count) - return 0; + goto unlock; /* * Select the IPC cmd and the ctrl_type based on the ctrl_cmd and the @@ -81,13 +88,20 @@ static int sof_ipc3_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool sizeof(struct sof_abi_hdr); break; default: - return -EINVAL; + ret = -EINVAL; + goto unlock; } cdata->rhdr.hdr.size = msg_bytes; cdata->elems_remaining = 0; - return iops->set_get_data(sdev, cdata, cdata->rhdr.hdr.size, set); + ret = iops->set_get_data(sdev, cdata, cdata->rhdr.hdr.size, set); + +unlock: + if (lock) + mutex_unlock(&swidget->setup_mutex); + + return ret; } static void snd_sof_refresh_control(struct snd_sof_control *scontrol) @@ -108,7 +122,7 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol) /* refresh the component data from DSP */ scontrol->comp_data_dirty = false; - ret = sof_ipc3_set_get_kcontrol_data(scontrol, false); + ret = sof_ipc3_set_get_kcontrol_data(scontrol, false, true); if (ret < 0) { dev_err(scomp->dev, "Failed to get control data: %d\n", ret); @@ -156,7 +170,7 @@ static bool sof_ipc3_volume_put(struct snd_sof_control *scontrol, /* notify DSP of mixer updates */ if (pm_runtime_active(scomp->dev)) { - int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true); + int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true, true); if (ret < 0) { dev_err(scomp->dev, "Failed to set mixer updates for %s\n", @@ -204,7 +218,7 @@ static bool sof_ipc3_switch_put(struct snd_sof_control *scontrol, /* notify DSP of mixer updates */ if (pm_runtime_active(scomp->dev)) { - int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true); + int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true, true); if (ret < 0) { dev_err(scomp->dev, "Failed to set mixer updates for %s\n", @@ -252,7 +266,7 @@ static bool sof_ipc3_enum_put(struct snd_sof_control *scontrol, /* notify DSP of enum updates */ if (pm_runtime_active(scomp->dev)) { - int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true); + int ret = sof_ipc3_set_get_kcontrol_data(scontrol, true, true); if (ret < 0) { dev_err(scomp->dev, "Failed to set enum updates for %s\n", @@ -324,7 +338,7 @@ static int sof_ipc3_bytes_put(struct snd_sof_control *scontrol, /* notify DSP of byte control updates */ if (pm_runtime_active(scomp->dev)) - return sof_ipc3_set_get_kcontrol_data(scontrol, true); + return sof_ipc3_set_get_kcontrol_data(scontrol, true, true); return 0; } @@ -438,7 +452,7 @@ static int sof_ipc3_bytes_ext_put(struct snd_sof_control *scontrol, /* notify DSP of byte control updates */ if (pm_runtime_active(scomp->dev)) - return sof_ipc3_set_get_kcontrol_data(scontrol, true); + return sof_ipc3_set_get_kcontrol_data(scontrol, true, true); return 0; } @@ -468,7 +482,7 @@ static int sof_ipc3_bytes_ext_volatile_get(struct snd_sof_control *scontrol, cdata->data->abi = SOF_ABI_VERSION; /* get all the component data from DSP */ - ret = sof_ipc3_set_get_kcontrol_data(scontrol, false); + ret = sof_ipc3_set_get_kcontrol_data(scontrol, false, true); if (ret < 0) return ret; @@ -647,7 +661,7 @@ static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev, list_for_each_entry(scontrol, &sdev->kcontrol_list, list) if (scontrol->comp_id == swidget->comp_id) { /* set kcontrol data in DSP */ - ret = sof_ipc3_set_get_kcontrol_data(scontrol, true); + ret = sof_ipc3_set_get_kcontrol_data(scontrol, true, false); if (ret < 0) { dev_err(sdev->dev, "kcontrol %d set up failed for widget %s\n", @@ -664,7 +678,7 @@ static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev, if (swidget->dynamic_pipeline_widget) continue; - ret = sof_ipc3_set_get_kcontrol_data(scontrol, false); + ret = sof_ipc3_set_get_kcontrol_data(scontrol, false, false); if (ret < 0) dev_warn(sdev->dev, "kcontrol %d read failed for widget %s\n", diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 88b9b9507231..dceb78bfe17c 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2316,7 +2316,9 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif /* Do not free widgets for static pipelines with FW older than SOF2.2 */ if (!verify && !swidget->dynamic_pipeline_widget && SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) { + mutex_lock(&swidget->setup_mutex); swidget->use_count = 0; + mutex_unlock(&swidget->setup_mutex); if (swidget->spipe) swidget->spipe->complete = 0; continue; diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c index 0d5a578c3496..67bd2233fd9a 100644 --- a/sound/soc/sof/ipc4-control.c +++ b/sound/soc/sof/ipc4-control.c @@ -12,7 +12,8 @@ #include "ipc4-priv.h" #include "ipc4-topology.h" -static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool set) +static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, + bool set, bool lock) { struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; struct snd_soc_component *scomp = scontrol->scomp; @@ -21,6 +22,7 @@ static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool struct sof_ipc4_msg *msg = &cdata->msg; struct snd_sof_widget *swidget; bool widget_found = false; + int ret = 0; /* find widget associated with the control */ list_for_each_entry(swidget, &sdev->widget_list, list) { @@ -35,23 +37,34 @@ static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool return -ENOENT; } + if (lock) + mutex_lock(&swidget->setup_mutex); + else + lockdep_assert_held(&swidget->setup_mutex); + /* - * Volatile controls should always be part of static pipelines and the widget use_count - * would always be > 0 in this case. For the others, just return the cached value if the - * widget is not set up. + * Volatile controls should always be part of static pipelines and the + * widget use_count would always be > 0 in this case. For the others, + * just return the cached value if the widget is not set up. */ if (!swidget->use_count) - return 0; + goto unlock; msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); - return iops->set_get_data(sdev, msg, msg->data_size, set); + ret = iops->set_get_data(sdev, msg, msg->data_size, set); + +unlock: + if (lock) + mutex_unlock(&swidget->setup_mutex); + + return ret; } static int sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, - struct snd_sof_control *scontrol) + struct snd_sof_control *scontrol, bool lock) { struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; struct sof_ipc4_gain *gain = swidget->private; @@ -90,7 +103,7 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge msg->data_ptr = &data; msg->data_size = sizeof(data); - ret = sof_ipc4_set_get_kcontrol_data(scontrol, true); + ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock); msg->data_ptr = NULL; msg->data_size = 0; if (ret < 0) { @@ -145,7 +158,7 @@ static bool sof_ipc4_volume_put(struct snd_sof_control *scontrol, return false; } - ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol); + ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol, true); if (ret < 0) return false; @@ -175,7 +188,7 @@ static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_s list_for_each_entry(scontrol, &sdev->kcontrol_list, list) if (scontrol->comp_id == swidget->comp_id) { - ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol); + ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol, false); if (ret < 0) { dev_err(sdev->dev, "%s: kcontrol %d set up failed for widget %s\n", __func__, scontrol->comp_id, swidget->widget->name); diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 14b4b949d081..760621bfc802 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -28,7 +28,8 @@ static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_so } } -int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +static int sof_widget_free_unlocked(struct snd_sof_dev *sdev, + struct snd_sof_widget *swidget) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); struct snd_sof_widget *pipe_widget; @@ -70,7 +71,7 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) * skip for static pipelines */ if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) { - ret = sof_widget_free(sdev, pipe_widget); + ret = sof_widget_free_unlocked(sdev, pipe_widget); if (ret < 0 && !err) err = ret; } @@ -84,9 +85,21 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) return err; } + +int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +{ + int ret; + + mutex_lock(&swidget->setup_mutex); + ret = sof_widget_free_unlocked(sdev, swidget); + mutex_unlock(&swidget->setup_mutex); + + return ret; +} EXPORT_SYMBOL(sof_widget_free); -int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev, + struct snd_sof_widget *swidget) { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); bool use_count_decremented = false; @@ -116,7 +129,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) goto use_count_dec; } - ret = sof_widget_setup(sdev, swidget->spipe->pipe_widget); + ret = sof_widget_setup_unlocked(sdev, swidget->spipe->pipe_widget); if (ret < 0) goto use_count_dec; } @@ -160,19 +173,30 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) widget_free: /* widget use_count and core ref_count will both be decremented by sof_widget_free() */ - sof_widget_free(sdev, swidget); + sof_widget_free_unlocked(sdev, swidget); use_count_decremented = true; core_put: snd_sof_dsp_core_put(sdev, swidget->core); pipe_widget_free: if (swidget->id != snd_soc_dapm_scheduler) - sof_widget_free(sdev, swidget->spipe->pipe_widget); + sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget); use_count_dec: if (!use_count_decremented) swidget->use_count--; return ret; } + +int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +{ + int ret; + + mutex_lock(&swidget->setup_mutex); + ret = sof_widget_setup_unlocked(sdev, swidget); + mutex_unlock(&swidget->setup_mutex); + + return ret; +} EXPORT_SYMBOL(sof_widget_setup); int sof_route_setup(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *wsource, diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index f1bbd1adc8b6..b0593b46d477 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -387,7 +387,16 @@ struct snd_sof_widget { * up in the DSP. */ bool prepared; - int use_count; /* use_count will be protected by the PCM mutex held by the core */ + + struct mutex setup_mutex; /* to protect the swidget setup and free operations */ + + /* + * use_count is protected by the PCM mutex held by the core and the + * setup_mutex against non stream domain races (kcontrol access for + * example) + */ + int use_count; + int core; int id; /* id is the DAPM widget type */ /* diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 33ca3067262b..e2f8cd9e278e 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1405,6 +1405,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, swidget->id = w->id; swidget->pipeline_id = index; swidget->private = NULL; + mutex_init(&swidget->setup_mutex); + ida_init(&swidget->src_queue_ida); ida_init(&swidget->sink_queue_ida); From patchwork Fri Jan 27 12:00:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ujfalusi X-Patchwork-Id: 647992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 74701C38142 for ; Fri, 27 Jan 2023 12:06:22 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 14C6EEE8; Fri, 27 Jan 2023 13:05:30 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 14C6EEE8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1674821180; bh=g2HxaHZv6nAGmwGq/ZGWCFp+VKkPfC+vYOfDP21maiQ=; h=From:To:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=qi78OsaL2KfXmsZNzo1RMZCRvx4WCdnbtQz7vg/I3wUfibVK1OSbFICNyZKbaAQN7 3z9jSZN80csiD9fK9Vvo/xicZqqWtld9usD8/H/5Rtasox4e4c+navjuBrGz0mRkES tE+h5IwEJdTzBq9/qbITyJMtth+qb5VgbFLusU9c= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B0933F80424; Fri, 27 Jan 2023 13:01:28 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3E826F805B3; Fri, 27 Jan 2023 13:01:18 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 11113F805B1 for ; Fri, 27 Jan 2023 13:01:11 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 11113F805B1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=Xb50swOy DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674820873; x=1706356873; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=g2HxaHZv6nAGmwGq/ZGWCFp+VKkPfC+vYOfDP21maiQ=; b=Xb50swOyiEJPc31zw8fNafo72PtZvfnU8pnQCClw0rVJcwHw/7q1+sj+ 1tuZQ2A54SRoktgZlFmOylZSJbydlXilfULogJrErcHsTlOA+vOuPaiBL ZZvTBqAaDazpbvIV8a5zeZ/V9ju28/P3RtsSYPCuwNKVc5sabjl4TGTa8 qitaDaWSQpzRUZAu0Bt51kyT+77CTfIvGeQ2HCHrQ8SQTVtjSTQbY/hhW Z9puMaIQsYizC4qXzjFUZpi4I4YPLE+abvAqMJAJxnTaDCRfAHLl2FhIw 8dz0OG1U9TXKxdQw+iiGF/rDo9qno7w94ZU5TmSSPt1sEHnbAG9P8HYfV w==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="327091992" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="327091992" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:11 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="805782380" X-IronPort-AV: E=Sophos;i="5.97,250,1669104000"; d="scan'208";a="805782380" Received: from aaralsto-mobl.amr.corp.intel.com (HELO pujfalus-desk.ger.corp.intel.com) ([10.252.30.130]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2023 04:01:09 -0800 From: Peter Ujfalusi To: lgirdwood@gmail.com, broonie@kernel.org Subject: [PATCH 18/18] ASoC: SOF: ipc4-pcm: Do not run the trigger pipelines if no spipe is stored Date: Fri, 27 Jan 2023 14:00:31 +0200 Message-Id: <20230127120031.10709-19-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> References: <20230127120031.10709-1-peter.ujfalusi@linux.intel.com> MIME-Version: 1.0 X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.29 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: , Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com, pierre-louis.bossart@linux.intel.com, rander.wang@intel.com, ranjani.sridharan@linux.intel.com, yung-chuan.liao@linux.intel.com Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" If the pipeline setup fails at the first widget/pipeline then we will have no spipe stored under the pipeline_list->pipelines, the pipeline_list->count is 0. If this is the case we would have a NULL pointer dereference if the execution is allowed to proceed. Check for this condition along with the pipeline_list->pipelines check Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan --- sound/soc/sof/ipc4-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 2d89d3708ed0..521090d4498d 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -213,7 +213,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, pipeline_list = &spcm->stream[substream->stream].pipeline_list; /* nothing to trigger if the list is empty */ - if (!pipeline_list->pipelines) + if (!pipeline_list->pipelines || !pipeline_list->count) return 0; /* allocate memory for the pipeline data */