From patchwork Thu Mar 11 17:42:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 397583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B750AC433DB for ; Thu, 11 Mar 2021 17:44:17 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id F25F764E77 for ; Thu, 11 Mar 2021 17:44:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F25F764E77 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 58C1A1726; Thu, 11 Mar 2021 18:43:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 58C1A1726 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1615484655; bh=4Do8m4M0qAJ0NYIgTW+FYixwJg7MaUOrw2wPRgVG6Bs=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=mfz0yPQuvQHW63d6JYdGox04AFH90Hcd9nIqdex+5ANrqJmsvYsghLYPg82pbrj9y 3SSBffHHqCBDFnUQtnAdRB9LOaLcTChYPG8dme/fPYvk1bxth6rEXYiKSh1B57FJUB nPV3UzYp1DMG8zrSUKWqxYAE5n+y7HRfqX9HNYZo= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4A8EAF8025A; Thu, 11 Mar 2021 18:43:24 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9F1ADF80275; Thu, 11 Mar 2021 18:43:22 +0100 (CET) Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BDBCAF800BF for ; Thu, 11 Mar 2021 18:43:13 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BDBCAF800BF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Oo8FyoG7" Received: by mail-lf1-x12e.google.com with SMTP id u4so41202854lfs.0 for ; Thu, 11 Mar 2021 09:43:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eHJDWKwpMM6cb9JU11x1wUIhvtQqgROewecwtgVy2N0=; b=Oo8FyoG74UY6khXJw001bnNsUEzVJmthtgVa72zwl0B21I4U4yuSfHEpVh1Tg90cxb hhh4GZEsSJa/UcyukKDTVCHjQcxrkpUjh48wA3bJ6uLc33ryaufMWAfjD2crcn6RpuCZ F1DxY50VpQByZuszT/Kjlw4Ehig+N7MZn4zDzZ3+EXaZDoCGEFR4qfHJolxNCPZTKVkN hP5wh4M2Nn/B3u6a16IYjBpId/j/ep3+HAd1/NgxudGHSXcUlgudG0LBrz7kzvPszAMh zdFDu+4pgmTgak6ZwEb2YWO5o9bJXeuAAAFw8WDPyxP4ouTjNffZyex3rxZtRO0kKuEc 4B2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eHJDWKwpMM6cb9JU11x1wUIhvtQqgROewecwtgVy2N0=; b=a/CbwT7OypPwQVVO1IDuiFmYk+TGZSusNFfoVrOM3e6AHDHILzhMMtUXSPp3sSgqmo lwDXXsmfFGkfh+D+5MZfHWe2GctGMUh5i0PV/a6RPU9uZ0gM0k7fmVE2524lxVfJ88sk 9/MLc8jV/1aYks/drKsbm/RDhudztB8y9evcZiA4XsvSB2KZD0KN4MhTUddPBDqkM8wH +YXiTl7JEN2trH7sdgeN9MaXjXoRAr2rTUjwGKqvK83WZYIS6hd4mFNApXHTQYQqcWkD bXs+/sM1H6U+ayuxS4HQPW0bh5X9egXty0qx6OIK2sl5gXmWJxcoiEDUFsNGCfsSasyw Eqtg== X-Gm-Message-State: AOAM531/8wvmH1EuLU+A0s2kGeQQhofMx6jHNctbKRosTB19nS9udJFu ngLfbZ5qQpR8gn75422qP3k= X-Google-Smtp-Source: ABdhPJwjr3vVXZN9uXoOC8Wd43GEhHXuWl10o49dbqFbet8fNjmYUTrDD7/t8JGP6cIp6uIB7HI0vA== X-Received: by 2002:a05:6512:ad4:: with SMTP id n20mr3022328lfu.507.1615484592811; Thu, 11 Mar 2021 09:43:12 -0800 (PST) Received: from localhost.localdomain (109-252-193-52.dynamic.spd-mgts.ru. [109.252.193.52]) by smtp.gmail.com with ESMTPSA id g10sm1021245lfe.90.2021.03.11.09.43.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Mar 2021 09:43:12 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Mark Brown , Takashi Iwai , Jaroslav Kysela , Philipp Zabel , Paul Fertser Subject: [PATCH v3 1/5] ASoC: tegra20: ac97: Add reset control Date: Thu, 11 Mar 2021 20:42:58 +0300 Message-Id: <20210311174302.15430-2-digetx@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210311174302.15430-1-digetx@gmail.com> References: <20210311174302.15430-1-digetx@gmail.com> MIME-Version: 1.0 Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Tegra20 AC97 driver doesn't manage the AC97 controller reset, relying on implicit deassertion of the reset by tegra-clk driver, which needs to be fixed since this behaviour is unacceptable by other Tegra drivers. Add explicit reset control to the Tegra20 AC97 driver. Note that AC97 reset was always specified in Tegra20 device-tree, hence DTB ABI changes aren't required. Signed-off-by: Dmitry Osipenko --- sound/soc/tegra/tegra20_ac97.c | 21 +++++++++++++++++++++ sound/soc/tegra/tegra20_ac97.h | 1 + 2 files changed, 22 insertions(+) diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 06c728ae17ed..c454a34c15c4 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -313,6 +314,12 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, ac97); + ac97->reset = devm_reset_control_get_exclusive(&pdev->dev, "ac97"); + if (IS_ERR(ac97->reset)) { + dev_err(&pdev->dev, "Can't retrieve ac97 reset\n"); + return PTR_ERR(ac97->reset); + } + ac97->clk_ac97 = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ac97->clk_ac97)) { dev_err(&pdev->dev, "Can't retrieve ac97 clock\n"); @@ -364,12 +371,26 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->playback_dma_data.maxburst = 4; + ret = reset_control_assert(ac97->reset); + if (ret) { + dev_err(&pdev->dev, "Failed to assert AC'97 reset: %d\n", ret); + goto err_clk_put; + } + ret = clk_prepare_enable(ac97->clk_ac97); if (ret) { dev_err(&pdev->dev, "clk_enable failed: %d\n", ret); goto err_clk_put; } + usleep_range(10, 100); + + ret = reset_control_deassert(ac97->reset); + if (ret) { + dev_err(&pdev->dev, "Failed to deassert AC'97 reset: %d\n", ret); + goto err_clk_disable_unprepare; + } + ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops); if (ret) { dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h index e467cd1ff2ca..870ea09ff301 100644 --- a/sound/soc/tegra/tegra20_ac97.h +++ b/sound/soc/tegra/tegra20_ac97.h @@ -78,6 +78,7 @@ struct tegra20_ac97 { struct clk *clk_ac97; struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; + struct reset_control *reset; struct regmap *regmap; int reset_gpio; int sync_gpio; From patchwork Thu Mar 11 17:42:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 398743 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A78CC433DB for ; Thu, 11 Mar 2021 17:46:42 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id AB6C264E77 for ; Thu, 11 Mar 2021 17:46:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AB6C264E77 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 0B95B1750; Thu, 11 Mar 2021 18:45:50 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0B95B1750 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1615484800; bh=j4aUPdKiYoXEoNs6zvEijyuS4laHxmQHyZetALal37k=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=WGgwRLc71zRBh/S1j6sJ3nZl1Q5Nx+gFXESX/Vk5iCrF8xQySsw0A9Bx2p5G8Wntx r8QNiu4/YPzuH48oEgk2gF1R/KS52SXVb/p+wVze8d2YejUXH5nlDvhxx/0lkwa+Ke z2ABgB/2MZPuHVqLKkDfB6zyAmmeZPwT1pt77ZRg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D6711F804AD; Thu, 11 Mar 2021 18:43:40 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9B75CF804AA; Thu, 11 Mar 2021 18:43:36 +0100 (CET) Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 461D6F802D2 for ; Thu, 11 Mar 2021 18:43:14 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 461D6F802D2 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ncmLWICc" Received: by mail-lf1-x132.google.com with SMTP id x4so34455895lfu.7 for ; Thu, 11 Mar 2021 09:43:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yx3Rm9jzGKCPBq80QBACsTq0WbETqkrvY2ZCaXbwiog=; b=ncmLWICcV/ueLUTt4miizhqzcPLhFPWMuCwm6Wvnn4Fuexvsjv5PGhi7fuNQodHWzZ Kr42xSGHaL71hOg8vnUVxEEWOPyVxDyyLb8PDgPISlDn5Fgar9f5L4HGpq8/1umKz4nJ i5ajGHqRdqrv2Ghkje7/Egwj1Exbtvu09v9bqqDXlbP1gRHe0kdzca0+hPtZiT98j6My lyjzc743VrhggXuNxuOoEuP9GsKo7+DEqJMxnIHtk4cMK1pMI2SoOF2jnc9OL0kuR6mZ PyovLu9WEPa4OvU3sSyrrZca1aqNU6j2mhhD6sSOkqI0MeIOUpjKeeTHEovZyjEFSAC2 c6Og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yx3Rm9jzGKCPBq80QBACsTq0WbETqkrvY2ZCaXbwiog=; b=BeKUmJNOsTMpZ15O4L7ykWh5tcwkR995vM6sTfvr7t4KIy3f39VjIdwF/MYocFpb3S QyAUl+6EWkg+IQ/oQiz0ljXm/P54g8eY2vtubAKcPPT4VCwTsBN3DM6PRbdAa2LJh5TE non+LwUvCuNWVy5MczlaXbMk/pdWJFYpymHL8Re1I8b0vZwWo3iWEtFEVRCvEaL7W3EP HqbIeeITCgeUYjcJLIl9vHYa8HrS3MrJGcDVYA4QZ8kK7oNO+Tcvo1z48gQ6aBneDkJA DMfb1ATo782aR2A4OBT/YweyoAWzg1dflwfmdmRAEGhkxcKOxcUmhXUA8lKpbEQGlIzb QDGg== X-Gm-Message-State: AOAM533Mz9m3PnMC0FzTRM+e9DomUBd/wZ51f8BvZrIc3ZFNLx8V41Hw fqJZytPfv9hVOF/3n5v4VcvkgL91IzY= X-Google-Smtp-Source: ABdhPJx77qEmgld5IVk3yUglYrcFPBmRtlD+rxMWWSZzDCIAzCF7Voj0tGD0X0Jo2Nk0/zMo+G3X/Q== X-Received: by 2002:ac2:4896:: with SMTP id x22mr2936884lfc.565.1615484593543; Thu, 11 Mar 2021 09:43:13 -0800 (PST) Received: from localhost.localdomain (109-252-193-52.dynamic.spd-mgts.ru. [109.252.193.52]) by smtp.gmail.com with ESMTPSA id g10sm1021245lfe.90.2021.03.11.09.43.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Mar 2021 09:43:13 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Mark Brown , Takashi Iwai , Jaroslav Kysela , Philipp Zabel , Paul Fertser Subject: [PATCH v3 2/5] ASoC: tegra20: i2s: Add reset control Date: Thu, 11 Mar 2021 20:42:59 +0300 Message-Id: <20210311174302.15430-3-digetx@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210311174302.15430-1-digetx@gmail.com> References: <20210311174302.15430-1-digetx@gmail.com> MIME-Version: 1.0 Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The I2S reset may be asserted at a boot time, in particular this is the case on Tegra20 AC100 netbook. Tegra20 I2S driver doesn't manage the reset control and currently it happens to work because reset is implicitly deasserted by the tegra-clk driver when I2S clock is enabled. The I2S permanently stays in a reset once tegra-clk is fixed to not touch the resets, which it shouldn't be doing. Add reset control to the Tegra20 I2S driver. Note that I2S reset was always specified in Tegra20 device-tree, hence DTB ABI changes aren't required. Tested-by: Paul Fertser # T20 AC100 Reported-by: Paul Fertser Signed-off-by: Dmitry Osipenko --- sound/soc/tegra/tegra20_i2s.c | 31 +++++++++++++++++++++++++++++++ sound/soc/tegra/tegra20_i2s.h | 1 + 2 files changed, 32 insertions(+) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index d7a3d046c8f8..c0af5352b483 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ static int tegra20_i2s_runtime_suspend(struct device *dev) { struct tegra20_i2s *i2s = dev_get_drvdata(dev); + regcache_cache_only(i2s->regmap, true); + clk_disable_unprepare(i2s->clk_i2s); return 0; @@ -47,13 +50,35 @@ static int tegra20_i2s_runtime_resume(struct device *dev) struct tegra20_i2s *i2s = dev_get_drvdata(dev); int ret; + ret = reset_control_assert(i2s->reset); + if (ret) + return ret; + ret = clk_prepare_enable(i2s->clk_i2s); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; } + usleep_range(10, 100); + + ret = reset_control_deassert(i2s->reset); + if (ret) + goto disable_clocks; + + regcache_cache_only(i2s->regmap, false); + regcache_mark_dirty(i2s->regmap); + + ret = regcache_sync(i2s->regmap); + if (ret) + goto disable_clocks; + return 0; + +disable_clocks: + clk_disable_unprepare(i2s->clk_i2s); + + return ret; } static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, @@ -339,6 +364,12 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) i2s->dai = tegra20_i2s_dai_template; i2s->dai.name = dev_name(&pdev->dev); + i2s->reset = devm_reset_control_get_exclusive(&pdev->dev, "i2s"); + if (IS_ERR(i2s->reset)) { + dev_err(&pdev->dev, "Can't retrieve i2s reset\n"); + return PTR_ERR(i2s->reset); + } + i2s->clk_i2s = clk_get(&pdev->dev, NULL); if (IS_ERR(i2s->clk_i2s)) { dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index 628d3ca09f42..8233e5fa2eff 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h @@ -144,6 +144,7 @@ struct tegra20_i2s { struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; struct regmap *regmap; + struct reset_control *reset; }; #endif From patchwork Thu Mar 11 17:43:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 398745 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A1C8C433DB for ; Thu, 11 Mar 2021 17:45:09 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 4F8DF64F3B for ; Thu, 11 Mar 2021 17:45:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4F8DF64F3B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id A87F51750; Thu, 11 Mar 2021 18:44:16 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz A87F51750 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1615484706; bh=lM8GOOCpvUTwlOOR+j55s0PnLGsgvCRMd2ds1GLpIqo=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=TlPT03mHxLJAzSIlNAyoL/hIFI6ENNaJS0m2l+wuAo2QjNqdjZhCQj2ZiZUgxYh9F hEwYkus5I7juA6AfI6q7ljwlTTyw7zulPrh/t7Aef6gtEv88ymA8ggD++M4cqLZ2VE 2er5afJuM/xjri+pDZka41SoQbLuUeHaJdounbRU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7C8A1F8010D; Thu, 11 Mar 2021 18:43:29 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 10B07F802E7; Thu, 11 Mar 2021 18:43:27 +0100 (CET) Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 04322F8019B for ; Thu, 11 Mar 2021 18:43:14 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 04322F8019B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nPMDAfRV" Received: by mail-lf1-x12d.google.com with SMTP id p21so41094681lfu.11 for ; Thu, 11 Mar 2021 09:43:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2SMSIMvYxaxu4F53i5qtc3hVUmETiEH2Ssz4CshQdOI=; b=nPMDAfRVDDoZs0rrhyF8XsG0pQQNjBacimeiag9hlGeuKQ5Lu0pHbeoRz3avqMOcvx 7GobZrCvZLlROufJ1ApX0WI4zMA5ISknv2y9vbZTmJWJupOKBPJfE84fPWSCA5842JTu 7VAKq5BDxktUVfz0SrBjcmEyVeAAt1qr7Rrj8841PcWrZTg+TLxRroxejVfo34v0An45 rm/bAEN3Ob6X2eI2P/C9TyY7nIaVu4zmVTaCBRwYzsAJdSyoTvfKTCIop+Yh+i+l1QJc yyGFRC2pKSIh9rQOQ+qUi78TNZ1DFBc5qTBo02g1oWlT6sgMpCQDbVtHlyEQ86EAdQhf 5P+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2SMSIMvYxaxu4F53i5qtc3hVUmETiEH2Ssz4CshQdOI=; b=r/4srL2Pu7buu6EiZ3r7JTqOVeGjbGMFREeULNBgag5LKJ3BqafQvTXX+d8FPP2VYY QNtONZho8tFSPzgtd3Ht7SNlm/mWrDd9Ab2pBduDM/LUMx4gdZwWo1MvwFpbwkP2yKqu otHtoxaqbVxyklRHKYu6I+RZSHQMS4Twiwqt3qSJk3v2hJWCr8CekOalCqlm3qnepqI6 T7z4uZCoQW/snIJat4dsc+Hw2/28VzJTxVtzJ5zWqXg636kyytLagTt/ttigYxEsrDTE aoLFPXY+6IHm1AujqB8sDDKgV9KyveWQtzsDPmtm5ao+gYap3Bcpms3dx71Ba79wbO6I W/DA== X-Gm-Message-State: AOAM530nmgvFwbHX2GEEzYf6OYUHLf0b9DfjXgcNYJQ4Fe+SKWHRt3Os d9wI9kIUCDXLpoMEV+HHUTWCwgMLcIE= X-Google-Smtp-Source: ABdhPJx7am9gJOeVJtdyhP6kXrjDmeN/fJJmTlBjiUylapuIR/ADwJzfnKrRqmdAVcxiJ1d2hV5Szg== X-Received: by 2002:a19:4850:: with SMTP id v77mr2979755lfa.6.1615484594239; Thu, 11 Mar 2021 09:43:14 -0800 (PST) Received: from localhost.localdomain (109-252-193-52.dynamic.spd-mgts.ru. [109.252.193.52]) by smtp.gmail.com with ESMTPSA id g10sm1021245lfe.90.2021.03.11.09.43.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Mar 2021 09:43:14 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Mark Brown , Takashi Iwai , Jaroslav Kysela , Philipp Zabel , Paul Fertser Subject: [PATCH v3 3/5] ASoC: tegra30: i2s: Restore hardware state on runtime PM resume Date: Thu, 11 Mar 2021 20:43:00 +0300 Message-Id: <20210311174302.15430-4-digetx@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210311174302.15430-1-digetx@gmail.com> References: <20210311174302.15430-1-digetx@gmail.com> MIME-Version: 1.0 Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Tegra30 I2S driver syncs regmap cache only on resume from system suspend, but hardware is reset across the runtime suspend because RPM of the parent AHUB driver resets the I2S hardware, hence h/w state is lost after each RPM resume. The problem isn't visible because hardware happens to be fully reprogrammed after each RPM resume. Move hardware syncing to RPM resume in order to restore h/w state properly. Fixes: ed9ce1ed2239 ("ASoC: tegra: ahub: Reset hardware properly") Signed-off-by: Dmitry Osipenko --- sound/soc/tegra/tegra30_i2s.c | 40 +++++++++++------------------------ 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 6740df541508..3d22c1be6f3d 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -58,8 +58,18 @@ static int tegra30_i2s_runtime_resume(struct device *dev) } regcache_cache_only(i2s->regmap, false); + regcache_mark_dirty(i2s->regmap); + + ret = regcache_sync(i2s->regmap); + if (ret) + goto disable_clocks; return 0; + +disable_clocks: + clk_disable_unprepare(i2s->clk_i2s); + + return ret; } static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, @@ -551,37 +561,11 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int tegra30_i2s_suspend(struct device *dev) -{ - struct tegra30_i2s *i2s = dev_get_drvdata(dev); - - regcache_mark_dirty(i2s->regmap); - - return 0; -} - -static int tegra30_i2s_resume(struct device *dev) -{ - struct tegra30_i2s *i2s = dev_get_drvdata(dev); - int ret; - - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put(dev); - return ret; - } - ret = regcache_sync(i2s->regmap); - pm_runtime_put(dev); - - return ret; -} -#endif - static const struct dev_pm_ops tegra30_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, tegra30_i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(tegra30_i2s_suspend, tegra30_i2s_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) }; static struct platform_driver tegra30_i2s_driver = { From patchwork Thu Mar 11 17:43:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 397581 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 098B5C433DB for ; Thu, 11 Mar 2021 17:46:24 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1CEC364E77 for ; Thu, 11 Mar 2021 17:46:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1CEC364E77 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 64E481754; Thu, 11 Mar 2021 18:45:31 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 64E481754 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1615484781; bh=EhlL56XR7JX03LW6kac6wFTAOjYkP8fYlAUPW+ZGQlE=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Q8aCh4vXa2DFeM0g2r2bxxH/NuutFMFW+dM3nwuN0TRelr0xWy/yIaOK7DpaM9fyp GeqR9qrkuK0/9P1PUnbaxZbyK444DHtSIv8+pA7XtsDjVKHwTLg90g8QmR4RqLvdyH 9YWsVg69dNaXbxI56vKthe5MucbQdjc8Q68py4Go= Received: from vmi242170.contaboserver.net (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 45CB9F804A9; Thu, 11 Mar 2021 18:43:40 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 08F0EF8032B; Thu, 11 Mar 2021 18:43:31 +0100 (CET) Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5C3FDF80227 for ; Thu, 11 Mar 2021 18:43:15 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5C3FDF80227 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sMbW3iAa" Received: by mail-lf1-x130.google.com with SMTP id r3so32973045lfc.13 for ; Thu, 11 Mar 2021 09:43:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lauIwrt96uAPmpkrgU4FkhkQ/MY42MuzLH07yJAIu60=; b=sMbW3iAares8fpIlDuMmc9YI74PfSXvdcJIvyXpnEOcIR4/3hvj8GpTS/RfVyTjrO1 H9Ix8PjdZ1rGW+L77V/6Hc5zYwJx5CnY9O53HJv0Jnjd0EZOR76AGP2+zCBP3DTTEXSq mTFRs6mb6LgT+1QNRaoy+13EYTh1xMDLg4XNJ9E0Lw3fPQ4TMCfuw++a/Ehl4NxZq8fY 4s++VB8f80cKYKx7TfrHjn+ZiUIab/F213Cfphr9X5zcSTbg6sikkUkfmfgsE0auED8I oVrYHUIEzGAa28kD4Mrr+vY8QcUl04WXfRL+u3ylQjROHlCDYIrOf7oqRTySxxYGU3bE 7xtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lauIwrt96uAPmpkrgU4FkhkQ/MY42MuzLH07yJAIu60=; b=eB/b2759LQGyIsOvQw9v0deAbn6XIdKkP+UlrbZEKkT8NXm+/GMf4QZaYjV0xZukZ3 G1qOgUwNzh98DpOzv4n7TPdKiwxm0guLQyh1n0c80RFdO1corZFm0yJmr8Xy4qijP9lI Gr13Zx/YLYb/bZWGX8i0L1nwbnUJquc+tC/GHncwDkab154hOh1tgpSEsnWKQriwTU+l fbsmI7aQYmfO0KN9DQRtxp18A63SxUa9YVURTJESYl3evqt2ppF/3LafFWUVwYLCEit2 1Ggc+FIT63slG4KSvGsnf9E1qVbe7tbLqPG6qS61qdtHz2StFPLb33Puqm6j4OvKa74F d8aw== X-Gm-Message-State: AOAM530NEKcJ6bFzLK79kO25D1BPDkPwAZGMVWFffKY2sdOIssf3Dsta TyyFoCB4iqe8PZJi+I0P6TL4tOmdYmQ= X-Google-Smtp-Source: ABdhPJwIIkynBE0lnQlCVlI1gW0xq8XCAS4IoguTr8qyqLBTSVgd1olLBmUQt8E7z0Qmiqfsy+uy4w== X-Received: by 2002:a19:22cb:: with SMTP id i194mr2851771lfi.191.1615484595022; Thu, 11 Mar 2021 09:43:15 -0800 (PST) Received: from localhost.localdomain (109-252-193-52.dynamic.spd-mgts.ru. [109.252.193.52]) by smtp.gmail.com with ESMTPSA id g10sm1021245lfe.90.2021.03.11.09.43.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Mar 2021 09:43:14 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Mark Brown , Takashi Iwai , Jaroslav Kysela , Philipp Zabel , Paul Fertser Subject: [PATCH v3 4/5] reset: Add reset_control_bulk API Date: Thu, 11 Mar 2021 20:43:01 +0300 Message-Id: <20210311174302.15430-5-digetx@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210311174302.15430-1-digetx@gmail.com> References: <20210311174302.15430-1-digetx@gmail.com> MIME-Version: 1.0 Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Philipp Zabel Follow the clock and regulator subsystems' lead and add a bulk API for reset controls. Signed-off-by: Philipp Zabel Tested-by: Dmitry Osipenko Signed-off-by: Dmitry Osipenko --- drivers/reset/core.c | 215 +++++++++++++++++++++++++++++ include/linux/reset.h | 308 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 523 insertions(+) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index dbf881b586d9..71c1c8264b2d 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -358,6 +358,30 @@ int reset_control_reset(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_reset); +/** + * reset_control_bulk_reset - reset the controlled devices in order + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + * + * Issue a reset on all provided reset controls, in order. + * + * See also: reset_control_reset() + */ +int reset_control_bulk_reset(int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + int ret, i; + + for (i = 0; i < num_rstcs; i++) { + ret = reset_control_reset(rstcs[i].rstc); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(reset_control_bulk_reset); + /** * reset_control_rearm - allow shared reset line to be re-triggered" * @rstc: reset controller @@ -461,6 +485,36 @@ int reset_control_assert(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_assert); +/** + * reset_control_bulk_assert - asserts the reset lines in order + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + * + * Assert the reset lines for all provided reset controls, in order. + * If an assertion fails, already asserted resets are deasserted again. + * + * See also: reset_control_assert() + */ +int reset_control_bulk_assert(int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + int ret, i; + + for (i = 0; i < num_rstcs; i++) { + ret = reset_control_assert(rstcs[i].rstc); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + reset_control_deassert(rstcs[i].rstc); + return ret; +} +EXPORT_SYMBOL_GPL(reset_control_bulk_assert); + /** * reset_control_deassert - deasserts the reset line * @rstc: reset controller @@ -511,6 +565,36 @@ int reset_control_deassert(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_deassert); +/** + * reset_control_bulk_deassert - deasserts the reset lines in reverse order + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + * + * Deassert the reset lines for all provided reset controls, in reverse order. + * If a deassertion fails, already deasserted resets are asserted again. + * + * See also: reset_control_deassert() + */ +int reset_control_bulk_deassert(int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + int ret, i; + + for (i = num_rstcs - 1; i >= 0; i--) { + ret = reset_control_deassert(rstcs[i].rstc); + if (ret) + goto err; + } + + return 0; + +err: + while (i < num_rstcs) + reset_control_assert(rstcs[i++].rstc); + return ret; +} +EXPORT_SYMBOL_GPL(reset_control_bulk_deassert); + /** * reset_control_status - returns a negative errno if not supported, a * positive value if the reset line is asserted, or zero if the reset @@ -588,6 +672,36 @@ int reset_control_acquire(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_acquire); +/** + * reset_control_bulk_acquire - acquires reset controls for exclusive use + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + * + * This is used to explicitly acquire reset controls requested with + * reset_control_bulk_get_exclusive_release() for temporary exclusive use. + * + * See also: reset_control_acquire(), reset_control_bulk_release() + */ +int reset_control_bulk_acquire(int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + int ret, i; + + for (i = 0; i < num_rstcs; i++) { + ret = reset_control_acquire(rstcs[i].rstc); + if (ret) + goto err; + } + + return 0; + +err: + while (i--) + reset_control_release(rstcs[i].rstc); + return ret; +} +EXPORT_SYMBOL_GPL(reset_control_bulk_acquire); + /** * reset_control_release() - releases exclusive access to a reset control * @rstc: reset control @@ -610,6 +724,26 @@ void reset_control_release(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_release); +/** + * reset_control_bulk_release() - releases exclusive access to reset controls + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + * + * Releases exclusive access right to reset controls previously obtained by a + * call to reset_control_bulk_acquire(). + * + * See also: reset_control_release(), reset_control_bulk_acquire() + */ +void reset_control_bulk_release(int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + int i; + + for (i = 0; i < num_rstcs; i++) + reset_control_release(rstcs[i].rstc); +} +EXPORT_SYMBOL_GPL(reset_control_bulk_release); + static struct reset_control *__reset_control_get_internal( struct reset_controller_dev *rcdev, unsigned int index, bool shared, bool acquired) @@ -814,6 +948,32 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id, } EXPORT_SYMBOL_GPL(__reset_control_get); +int __reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired) +{ + int ret, i; + + for (i = 0; i < num_rstcs; i++) { + rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0, + shared, optional, acquired); + if (IS_ERR(rstcs[i].rstc)) { + ret = PTR_ERR(rstcs[i].rstc); + goto err; + } + } + + return 0; + +err: + mutex_lock(&reset_list_mutex); + while (i--) + __reset_control_put_internal(rstcs[i].rstc); + mutex_unlock(&reset_list_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(__reset_control_bulk_get); + static void reset_control_array_put(struct reset_control_array *resets) { int i; @@ -845,6 +1005,23 @@ void reset_control_put(struct reset_control *rstc) } EXPORT_SYMBOL_GPL(reset_control_put); +/** + * reset_control_bulk_put - free the reset controllers + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset controls set + */ +void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ + mutex_lock(&reset_list_mutex); + while (num_rstcs--) { + if (IS_ERR_OR_NULL(rstcs[num_rstcs].rstc)) + continue; + __reset_control_put_internal(rstcs[num_rstcs].rstc); + } + mutex_unlock(&reset_list_mutex); +} +EXPORT_SYMBOL_GPL(reset_control_bulk_put); + static void devm_reset_control_release(struct device *dev, void *res) { reset_control_put(*(struct reset_control **)res); @@ -874,6 +1051,44 @@ struct reset_control *__devm_reset_control_get(struct device *dev, } EXPORT_SYMBOL_GPL(__devm_reset_control_get); +struct reset_control_bulk_devres { + int num_rstcs; + struct reset_control_bulk_data *rstcs; +}; + +static void devm_reset_control_bulk_release(struct device *dev, void *res) +{ + struct reset_control_bulk_devres *devres = res; + + reset_control_bulk_put(devres->num_rstcs, devres->rstcs); +} + +int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired) +{ + struct reset_control_bulk_devres *ptr; + int ret; + + ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired); + if (ret < 0) { + devres_free(ptr); + return ret; + } + + ptr->num_rstcs = num_rstcs; + ptr->rstcs = rstcs; + devres_add(dev, ptr); + + return 0; +} +EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get); + /** * __device_reset - find reset controller associated with the device * and perform reset diff --git a/include/linux/reset.h b/include/linux/reset.h index b9109efa2a5c..6a12c666e499 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -10,6 +10,21 @@ struct device; struct device_node; struct reset_control; +/** + * struct reset_control_bulk_data - Data used for bulk reset control operations. + * + * @id: reset control consumer ID + * @rstc: struct reset_control * to store the associated reset control + * + * The reset APIs provide a series of reset_control_bulk_*() API calls as + * a convenience to consumers which require multiple reset controls. + * This structure is used to manage data for these calls. + */ +struct reset_control_bulk_data { + const char *id; + struct reset_control *rstc; +}; + #ifdef CONFIG_RESET_CONTROLLER int reset_control_reset(struct reset_control *rstc); @@ -20,17 +35,29 @@ int reset_control_status(struct reset_control *rstc); int reset_control_acquire(struct reset_control *rstc); void reset_control_release(struct reset_control *rstc); +int reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs); +int reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs); +int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs); +int reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs); +void reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs); + struct reset_control *__of_reset_control_get(struct device_node *node, const char *id, int index, bool shared, bool optional, bool acquired); struct reset_control *__reset_control_get(struct device *dev, const char *id, int index, bool shared, bool optional, bool acquired); +int __reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired); void reset_control_put(struct reset_control *rstc); int __device_reset(struct device *dev, bool optional); struct reset_control *__devm_reset_control_get(struct device *dev, const char *id, int index, bool shared, bool optional, bool acquired); +int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired); struct reset_control *devm_reset_control_array_get(struct device *dev, bool shared, bool optional); @@ -71,6 +98,35 @@ static inline void reset_control_release(struct reset_control *rstc) { } +static inline int +reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ + return 0; +} + +static inline int +reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ + return 0; +} + +static inline int +reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ + return 0; +} + +static inline int +reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ + return 0; +} + +static inline void +reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs) +{ +} + static inline void reset_control_put(struct reset_control *rstc) { } @@ -96,6 +152,14 @@ static inline struct reset_control *__reset_control_get( return optional ? NULL : ERR_PTR(-ENOTSUPP); } +static inline int +__reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired) +{ + return optional ? 0 : -EOPNOTSUPP; +} + static inline struct reset_control *__devm_reset_control_get( struct device *dev, const char *id, int index, bool shared, bool optional, @@ -104,6 +168,14 @@ static inline struct reset_control *__devm_reset_control_get( return optional ? NULL : ERR_PTR(-ENOTSUPP); } +static inline int +__devm_reset_control_bulk_get(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs, + bool shared, bool optional, bool acquired) +{ + return optional ? 0 : -EOPNOTSUPP; +} + static inline struct reset_control * devm_reset_control_array_get(struct device *dev, bool shared, bool optional) { @@ -155,6 +227,23 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) return __reset_control_get(dev, id, 0, false, false, true); } +/** + * reset_control_bulk_get_exclusive - Lookup and obtain exclusive references to + * multiple reset controllers. + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Fills the rstcs array with pointers to exclusive reset controls and + * returns 0, or an IS_ERR() condition containing errno. + */ +static inline int __must_check +reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true); +} + /** * reset_control_get_exclusive_released - Lookup and obtain a temoprarily * exclusive reference to a reset @@ -176,6 +265,48 @@ __must_check reset_control_get_exclusive_released(struct device *dev, return __reset_control_get(dev, id, 0, false, false, false); } +/** + * reset_control_bulk_get_exclusive_released - Lookup and obtain temporarily + * exclusive references to multiple reset + * controllers. + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Fills the rstcs array with pointers to exclusive reset controls and + * returns 0, or an IS_ERR() condition containing errno. + * reset-controls returned by this function must be acquired via + * reset_control_bulk_acquire() before they can be used and should be released + * via reset_control_bulk_release() afterwards. + */ +static inline int __must_check +reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false); +} + +/** + * reset_control_bulk_get_optional_exclusive_released - Lookup and obtain optional + * temporarily exclusive references to multiple + * reset controllers. + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Optional variant of reset_control_bulk_get_exclusive_released(). If the + * requested reset is not specified in the device tree, this function returns 0 + * instead of an error and missing rtsc is set to NULL. + * + * See reset_control_bulk_get_exclusive_released() for more information. + */ +static inline int __must_check +reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false); +} + /** * reset_control_get_shared - Lookup and obtain a shared reference to a * reset controller. @@ -204,6 +335,23 @@ static inline struct reset_control *reset_control_get_shared( return __reset_control_get(dev, id, 0, true, false, false); } +/** + * reset_control_bulk_get_shared - Lookup and obtain shared references to + * multiple reset controllers. + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Fills the rstcs array with pointers to shared reset controls and + * returns 0, or an IS_ERR() condition containing errno. + */ +static inline int __must_check +reset_control_bulk_get_shared(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false); +} + /** * reset_control_get_optional_exclusive - optional reset_control_get_exclusive() * @dev: device to be reset by the controller @@ -221,6 +369,26 @@ static inline struct reset_control *reset_control_get_optional_exclusive( return __reset_control_get(dev, id, 0, false, true, true); } +/** + * reset_control_bulk_get_optional_exclusive - optional + * reset_control_bulk_get_exclusive() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Optional variant of reset_control_bulk_get_exclusive(). If any of the + * requested resets are not specified in the device tree, this function sets + * them to NULL instead of returning an error. + * + * See reset_control_bulk_get_exclusive() for more information. + */ +static inline int __must_check +reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true); +} + /** * reset_control_get_optional_shared - optional reset_control_get_shared() * @dev: device to be reset by the controller @@ -238,6 +406,26 @@ static inline struct reset_control *reset_control_get_optional_shared( return __reset_control_get(dev, id, 0, true, true, false); } +/** + * reset_control_bulk_get_optional_shared - optional + * reset_control_bulk_get_shared() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Optional variant of reset_control_bulk_get_shared(). If the requested resets + * are not specified in the device tree, this function sets them to NULL + * instead of returning an error. + * + * See reset_control_bulk_get_shared() for more information. + */ +static inline int __must_check +reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false); +} + /** * of_reset_control_get_exclusive - Lookup and obtain an exclusive reference * to a reset controller. @@ -343,6 +531,26 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, return __devm_reset_control_get(dev, id, 0, false, false, true); } +/** + * devm_reset_control_bulk_get_exclusive - resource managed + * reset_control_bulk_get_exclusive() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_get_exclusive(). For reset controllers returned + * from this function, reset_control_put() is called automatically on driver + * detach. + * + * See reset_control_bulk_get_exclusive() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true); +} + /** * devm_reset_control_get_exclusive_released - resource managed * reset_control_get_exclusive_released() @@ -362,6 +570,26 @@ __must_check devm_reset_control_get_exclusive_released(struct device *dev, return __devm_reset_control_get(dev, id, 0, false, false, false); } +/** + * devm_reset_control_bulk_get_exclusive_released - resource managed + * reset_control_bulk_get_exclusive_released() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_get_exclusive_released(). For reset controllers + * returned from this function, reset_control_put() is called automatically on + * driver detach. + * + * See reset_control_bulk_get_exclusive_released() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false); +} + /** * devm_reset_control_get_optional_exclusive_released - resource managed * reset_control_get_optional_exclusive_released() @@ -381,6 +609,26 @@ __must_check devm_reset_control_get_optional_exclusive_released(struct device *d return __devm_reset_control_get(dev, id, 0, false, true, false); } +/** + * devm_reset_control_bulk_get_optional_exclusive_released - resource managed + * reset_control_bulk_optional_get_exclusive_released() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_optional_get_exclusive_released(). For reset + * controllers returned from this function, reset_control_put() is called + * automatically on driver detach. + * + * See reset_control_bulk_optional_get_exclusive_released() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false); +} + /** * devm_reset_control_get_shared - resource managed reset_control_get_shared() * @dev: device to be reset by the controller @@ -396,6 +644,26 @@ static inline struct reset_control *devm_reset_control_get_shared( return __devm_reset_control_get(dev, id, 0, true, false, false); } +/** + * devm_reset_control_bulk_get_shared - resource managed + * reset_control_bulk_get_shared() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_get_shared(). For reset controllers returned + * from this function, reset_control_put() is called automatically on driver + * detach. + * + * See reset_control_bulk_get_shared() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false); +} + /** * devm_reset_control_get_optional_exclusive - resource managed * reset_control_get_optional_exclusive() @@ -414,6 +682,26 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive( return __devm_reset_control_get(dev, id, 0, false, true, true); } +/** + * devm_reset_control_bulk_get_optional_exclusive - resource managed + * reset_control_bulk_get_optional_exclusive() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_get_optional_exclusive(). For reset controllers + * returned from this function, reset_control_put() is called automatically on + * driver detach. + * + * See reset_control_bulk_get_optional_exclusive() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, true); +} + /** * devm_reset_control_get_optional_shared - resource managed * reset_control_get_optional_shared() @@ -432,6 +720,26 @@ static inline struct reset_control *devm_reset_control_get_optional_shared( return __devm_reset_control_get(dev, id, 0, true, true, false); } +/** + * devm_reset_control_bulk_get_optional_shared - resource managed + * reset_control_bulk_get_optional_shared() + * @dev: device to be reset by the controller + * @num_rstcs: number of entries in rstcs array + * @rstcs: array of struct reset_control_bulk_data with reset line names set + * + * Managed reset_control_bulk_get_optional_shared(). For reset controllers + * returned from this function, reset_control_put() is called automatically on + * driver detach. + * + * See reset_control_bulk_get_optional_shared() for more information. + */ +static inline int __must_check +devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs, + struct reset_control_bulk_data *rstcs) +{ + return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false); +} + /** * devm_reset_control_get_exclusive_by_index - resource managed * reset_control_get_exclusive() From patchwork Thu Mar 11 17:43:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 398744 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B8FEC433DB for ; Thu, 11 Mar 2021 17:45:53 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 5023764F97 for ; Thu, 11 Mar 2021 17:45:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5023764F97 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 92F4B1729; Thu, 11 Mar 2021 18:45:00 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 92F4B1729 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1615484750; bh=XRJyqw/pXkIasdZQxg8O0t/Aew+OI2IcWd5DSpLusp4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ux1iZ5ujUyJN54C7PHCKWvN8Bkny7m2ikCeEbxxr/pMBWpzuDi4x0ODCuT9I8W+2H ZWpoNgZUzER28OohEfIU6Qno3GbfRUIzA55JpTg4nycgvD5UVh0AD0nSEC1J4ZRoYb PhpLCuTgGQy2I8PSOXyPg/2MLQ35ueT2Ll9S7lVA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D256DF8032C; Thu, 11 Mar 2021 18:43:32 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6EB1CF800BF; Thu, 11 Mar 2021 18:43:29 +0100 (CET) Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D9835F800BF for ; Thu, 11 Mar 2021 18:43:16 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D9835F800BF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JYIOXxWQ" Received: by mail-lf1-x134.google.com with SMTP id n16so41191077lfb.4 for ; Thu, 11 Mar 2021 09:43:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KFH1WQ55n2o2H6XVeSwGtTqtJ0JVSPd2X/kO35Iu2VI=; b=JYIOXxWQ0tCq5tpE5vlFkgbMyZR4z0PZzmUho8YJJBzdNyHjvAoAriWB8Kk47Irn7Y /RVSAvvbV4KA/9nBbU9SxdJLs+SxbSQ9kCdyNI5ScmtMiwghBTiyl/IJoQcmCE6mGmR/ cSCKXUi4XsDQmwwRe/qYgh9thvxXimW9jRf17yktbfGQaa92Z+O6mA4JSB7eDrH0X7Gj 8N4VN3/cgY8/IEHMXQGa75Xh4YS0U8IzO1SPuLtNcEl1XHZ0G+sVOIaCqBFXkkZSojWf hw4wu9sWfmR4RCsm+Ef83k9BBw2N9dEWCBDUU19o2DFqS8FucBrgWoB3b2DiZelAaYqO 7tBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KFH1WQ55n2o2H6XVeSwGtTqtJ0JVSPd2X/kO35Iu2VI=; b=tlz2tAcL8S4MD9/Ovif/RNRleACsyomyZcyd80dBVBQco0N30UoXAd7+Q65JGMyUs+ mHMY4LCudGF3mePw/B6PiDEcj/TnDdFcp9w9BdmTdJ+HS7Ig9K7s4qjn+9RfSybvsaI6 58VOyw0hLktJtpgjz5Om0tf/NKUTJbuvvyixQjI4Vbf5+Yj/q8iC5Bv7LD8zMq532YEV 0p1xaBMjucERAnZ7t/Yo07Fqxn9xKtJbN/ev/w7LA8HjunWn2tPYP2sbqFUoAk8C1nVg ocxkrdp7R0j7S8Xq+rUOSlAy1UQTIL+n7JXPvqz3YbiwQa1plV3PSj2lEC7MSNBUn3h/ Y83Q== X-Gm-Message-State: AOAM530fGo6x4/2bkFkGU62o9ux7nym3Y0Ukcohfr4GITo2ekBtoe0rZ YQeyRCeOQTt91ePTMgYw5zo= X-Google-Smtp-Source: ABdhPJx+umdPXW4BrOcDOBr5X/nTi6J68GJ4UmbG0xK+Rc+6qqHb//k3tPQCAP+QpJuCr8CJdtfkYA== X-Received: by 2002:a19:6b10:: with SMTP id d16mr2764909lfa.540.1615484595668; Thu, 11 Mar 2021 09:43:15 -0800 (PST) Received: from localhost.localdomain (109-252-193-52.dynamic.spd-mgts.ru. [109.252.193.52]) by smtp.gmail.com with ESMTPSA id g10sm1021245lfe.90.2021.03.11.09.43.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Mar 2021 09:43:15 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Mark Brown , Takashi Iwai , Jaroslav Kysela , Philipp Zabel , Paul Fertser Subject: [PATCH v3 5/5] ASoC: tegra: ahub: Switch to use reset-bulk API Date: Thu, 11 Mar 2021 20:43:02 +0300 Message-Id: <20210311174302.15430-6-digetx@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210311174302.15430-1-digetx@gmail.com> References: <20210311174302.15430-1-digetx@gmail.com> MIME-Version: 1.0 Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Switch to use reset-bulk API in order to make code cleaner. Signed-off-by: Dmitry Osipenko --- sound/soc/tegra/tegra30_ahub.c | 104 ++++++++++++--------------------- sound/soc/tegra/tegra30_ahub.h | 5 +- sound/soc/tegra/tegra30_i2s.c | 1 + 3 files changed, 40 insertions(+), 70 deletions(-) diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 9ef05ca4f6c4..d24c26f4960d 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -65,7 +65,7 @@ static int tegra30_ahub_runtime_resume(struct device *dev) { int ret; - ret = reset_control_assert(ahub->reset); + ret = reset_control_bulk_assert(ahub->nresets, ahub->resets); if (ret) return ret; @@ -75,7 +75,7 @@ static int tegra30_ahub_runtime_resume(struct device *dev) usleep_range(10, 100); - ret = reset_control_deassert(ahub->reset); + ret = reset_control_bulk_deassert(ahub->nresets, ahub->resets); if (ret) goto disable_clocks; @@ -339,41 +339,28 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) } EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); -#define MOD_LIST_MASK_TEGRA30 BIT(0) -#define MOD_LIST_MASK_TEGRA114 BIT(1) -#define MOD_LIST_MASK_TEGRA124 BIT(2) - -#define MOD_LIST_MASK_TEGRA30_OR_LATER \ - (MOD_LIST_MASK_TEGRA30 | MOD_LIST_MASK_TEGRA114 | \ - MOD_LIST_MASK_TEGRA124) -#define MOD_LIST_MASK_TEGRA114_OR_LATER \ - (MOD_LIST_MASK_TEGRA114 | MOD_LIST_MASK_TEGRA124) - -static const struct { - const char *rst_name; - u32 mod_list_mask; -} configlink_mods[] = { - { "d_audio", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "apbif", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER }, - { "amx", MOD_LIST_MASK_TEGRA114_OR_LATER }, - { "adx", MOD_LIST_MASK_TEGRA114_OR_LATER }, - { "amx1", MOD_LIST_MASK_TEGRA124 }, - { "adx1", MOD_LIST_MASK_TEGRA124 }, - { "afc0", MOD_LIST_MASK_TEGRA124 }, - { "afc1", MOD_LIST_MASK_TEGRA124 }, - { "afc2", MOD_LIST_MASK_TEGRA124 }, - { "afc3", MOD_LIST_MASK_TEGRA124 }, - { "afc4", MOD_LIST_MASK_TEGRA124 }, - { "afc5", MOD_LIST_MASK_TEGRA124 }, +static const struct reset_control_bulk_data tegra30_ahub_resets_data[] = { + { "d_audio" }, + { "apbif" }, + { "i2s0" }, + { "i2s1" }, + { "i2s2" }, + { "i2s3" }, + { "i2s4" }, + { "dam0" }, + { "dam1" }, + { "dam2" }, + { "spdif" }, + { "amx" }, /* Tegra114+ */ + { "adx" }, /* Tegra114+ */ + { "amx1" }, /* Tegra124 */ + { "adx1" }, /* Tegra124 */ + { "afc0" }, /* Tegra124 */ + { "afc1" }, /* Tegra124 */ + { "afc2" }, /* Tegra124 */ + { "afc3" }, /* Tegra124 */ + { "afc4" }, /* Tegra124 */ + { "afc5" }, /* Tegra124 */ }; #define LAST_REG(name) \ @@ -502,17 +489,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { }; static struct tegra30_ahub_soc_data soc_data_tegra30 = { - .mod_list_mask = MOD_LIST_MASK_TEGRA30, + .num_resets = 11, .set_audio_cif = tegra30_ahub_set_cif, }; static struct tegra30_ahub_soc_data soc_data_tegra114 = { - .mod_list_mask = MOD_LIST_MASK_TEGRA114, + .num_resets = 13, .set_audio_cif = tegra30_ahub_set_cif, }; static struct tegra30_ahub_soc_data soc_data_tegra124 = { - .mod_list_mask = MOD_LIST_MASK_TEGRA124, + .num_resets = 21, .set_audio_cif = tegra124_ahub_set_cif, }; @@ -527,8 +514,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct tegra30_ahub_soc_data *soc_data; - struct reset_control *rst; - int i; struct resource *res0; void __iomem *regs_apbif, *regs_ahub; int ret = 0; @@ -541,34 +526,16 @@ static int tegra30_ahub_probe(struct platform_device *pdev) return -EINVAL; soc_data = match->data; - /* - * The AHUB hosts a register bus: the "configlink". For this to - * operate correctly, all devices on this bus must be out of reset. - */ - for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) { - if (!(configlink_mods[i].mod_list_mask & - soc_data->mod_list_mask)) - continue; - - rst = reset_control_get_exclusive(&pdev->dev, - configlink_mods[i].rst_name); - if (IS_ERR(rst)) { - dev_err(&pdev->dev, "Can't get reset %s\n", - configlink_mods[i].rst_name); - ret = PTR_ERR(rst); - return ret; - } - - /* just check presence of the reset control in DT */ - reset_control_put(rst); - } - ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), GFP_KERNEL); if (!ahub) return -ENOMEM; dev_set_drvdata(&pdev->dev, ahub); + BUILD_BUG_ON(sizeof(ahub->resets) != sizeof(tegra30_ahub_resets_data)); + memcpy(ahub->resets, tegra30_ahub_resets_data, sizeof(ahub->resets)); + + ahub->nresets = soc_data->num_resets; ahub->soc_data = soc_data; ahub->dev = &pdev->dev; @@ -579,10 +546,11 @@ static int tegra30_ahub_probe(struct platform_device *pdev) if (ret) return ret; - ahub->reset = devm_reset_control_array_get_exclusive(&pdev->dev); - if (IS_ERR(ahub->reset)) { - dev_err(&pdev->dev, "Can't get resets: %pe\n", ahub->reset); - return PTR_ERR(ahub->reset); + ret = devm_reset_control_bulk_get_exclusive(&pdev->dev, ahub->nresets, + ahub->resets); + if (ret) { + dev_err(&pdev->dev, "Can't get resets: %d\n", ret); + return ret; } res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index 3b85244f87f1..c9eaf4ec8f6e 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -491,7 +491,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg, struct tegra30_ahub_cif_conf *conf); struct tegra30_ahub_soc_data { - u32 mod_list_mask; + unsigned int num_resets; void (*set_audio_cif)(struct regmap *regmap, unsigned int reg, struct tegra30_ahub_cif_conf *conf); @@ -511,7 +511,8 @@ struct tegra30_ahub_soc_data { struct tegra30_ahub { const struct tegra30_ahub_soc_data *soc_data; struct device *dev; - struct reset_control *reset; + struct reset_control_bulk_data resets[21]; + unsigned int nresets; struct clk_bulk_data clocks[2]; unsigned int nclocks; resource_size_t apbif_addr; diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 3d22c1be6f3d..614b67be1dd9 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include