From patchwork Tue Apr 16 10:29:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Hunter X-Patchwork-Id: 1086194 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.b="ei7VkqPg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44k1nq2fDwz9s00 for ; Tue, 16 Apr 2019 20:29:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728147AbfDPK3d (ORCPT ); Tue, 16 Apr 2019 06:29:33 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:18357 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726682AbfDPK3d (ORCPT ); Tue, 16 Apr 2019 06:29:33 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 16 Apr 2019 03:29:37 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 16 Apr 2019 03:29:32 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 16 Apr 2019 03:29:32 -0700 Received: from HQMAIL110.nvidia.com (172.18.146.15) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:29 +0000 Received: from HQMAIL101.nvidia.com (172.20.187.10) by hqmail110.nvidia.com (172.18.146.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:28 +0000 Received: from hqnvemgw02.nvidia.com (172.16.227.111) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 16 Apr 2019 10:29:28 +0000 Received: from moonraker.nvidia.com (Not Verified[10.21.132.148]) by hqnvemgw02.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Tue, 16 Apr 2019 03:29:28 -0700 From: Jon Hunter To: Thierry Reding CC: Sandipan Patra , , "Jon Hunter" Subject: [PATCH 1/3] soc/tegra: pmc: Fix definition of reset sources and levels Date: Tue, 16 Apr 2019 11:29:02 +0100 Message-ID: <1555410544-14889-1-git-send-email-jonathanh@nvidia.com> X-Mailer: git-send-email 2.7.4 X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1555410578; bh=5vJZTcb4FEc0eBKDod/hwzDWE3x9mkm4K8hVkZYcmCc=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: X-NVConfidentiality:MIME-Version:Content-Type; b=ei7VkqPgcKsD4RwaXN+U5RCcVRvYaaiJv6ZniGNIJWluoy5SjVuiCKUwLgI5oQmY2 UjkmxYZBTgo4KmDHj/ZTwNmv0lkfBKuWsHpGDVFH4dsLM2iD47wJb1V/HtE3+KzdPd Un5GkoMWTAphp3DAGduWhUWZgqfWvcSfoU3z5dUlqGXYJQgyzKQOIjEcvt3IRcbJL0 OcU/kXpVJFNtwFNSYYOHiDnDECVLIu817sntcoV/yvILlMUIu5AhS5hPNgvRYGmF8C ifBZyv+qH+xj7kSATXJFT3Y0Hpk4FB2dvoj8gusolzLN5nndVi/uW6xAni8ooixaEv NI4MUkWN+R0wA== Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Commit 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info") added support for reading the Tegra reset source and level from sysfs. However, there are a few issues with this commit which are ... 1. The number of reset sources for Tegra210 is defined as 5 but it should be 6. 2. The number of reset sources for Tegra186 is defined as 13 but it should be 15. 3. The SoC data variables num_reset_sources and num_reset_levels are defined but never used. Fix the above by ... 1. Removing the reset source 'AOTAG' from the tegra30_reset_sources because this is only applicable for Tegra210. 2. Adding a new tegra210_reset_sources structure for Tegra210 reset sources. 3. Padding the reset sources structures with 'UNKNOWN' for any bit field values that are not valid. Although it should not really be necessary as these values should never be returned, it avoids having to check the value read from the register. 4. Removing the unused SoC data variables num_reset_sources and num_reset_levels. Fixes: 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info") Signed-off-by: Jon Hunter --- drivers/soc/tegra/pmc.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 0c5f79528e5f..61c61994f17d 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -237,9 +237,7 @@ struct tegra_pmc_soc { bool invert); const char * const *reset_sources; - unsigned int num_reset_sources; const char * const *reset_levels; - unsigned int num_reset_levels; const struct tegra_wake_event *wake_events; unsigned int num_wake_events; @@ -260,7 +258,8 @@ static const char * const tegra186_reset_sources[] = { "SWREST", "SC7", "HSM", - "CORESIGHT" + "CORESIGHT", + "UNKNOWN" }; static const char * const tegra186_reset_levels[] = { @@ -273,7 +272,18 @@ static const char * const tegra30_reset_sources[] = { "SENSOR", "SW_MAIN", "LP0", - "AOTAG" + "UNKNOWN", + "UNKNOWN" +}; + +static const char * const tegra210_reset_sources[] = { + "POWER_ON_RESET", + "WATCHDOG", + "SENSOR", + "SW_MAIN", + "LP0", + "AOTAG", + "UNKNOWN" }; /** @@ -2165,9 +2175,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .reset_sources = NULL, - .num_reset_sources = 0, .reset_levels = NULL, - .num_reset_levels = 0, }; static const char * const tegra30_powergates[] = { @@ -2212,9 +2220,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .reset_sources = tegra30_reset_sources, - .num_reset_sources = 5, .reset_levels = NULL, - .num_reset_levels = 0, }; static const char * const tegra114_powergates[] = { @@ -2263,9 +2269,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .reset_sources = tegra30_reset_sources, - .num_reset_sources = 5, .reset_levels = NULL, - .num_reset_levels = 0, }; static const char * const tegra124_powergates[] = { @@ -2374,9 +2378,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .reset_sources = tegra30_reset_sources, - .num_reset_sources = 5, .reset_levels = NULL, - .num_reset_levels = 0, }; static const char * const tegra210_powergates[] = { @@ -2479,10 +2481,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, - .reset_sources = tegra30_reset_sources, - .num_reset_sources = 5, + .reset_sources = tegra210_reset_sources, .reset_levels = NULL, - .num_reset_levels = 0, }; #define TEGRA186_IO_PAD_TABLE(_pad) \ @@ -2605,9 +2605,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { .init = NULL, .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, .reset_sources = tegra186_reset_sources, - .num_reset_sources = 14, .reset_levels = tegra186_reset_levels, - .num_reset_levels = 3, .num_wake_events = ARRAY_SIZE(tegra186_wake_events), .wake_events = tegra186_wake_events, }; From patchwork Tue Apr 16 10:29:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Hunter X-Patchwork-Id: 1086195 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.b="sRoFFZRb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44k1nq5jb5z9s3q for ; Tue, 16 Apr 2019 20:29:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728508AbfDPK3f (ORCPT ); Tue, 16 Apr 2019 06:29:35 -0400 Received: from hqemgate16.nvidia.com ([216.228.121.65]:5903 "EHLO hqemgate16.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727783AbfDPK3f (ORCPT ); Tue, 16 Apr 2019 06:29:35 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate16.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 16 Apr 2019 03:29:30 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 16 Apr 2019 03:29:33 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 16 Apr 2019 03:29:33 -0700 Received: from HQMAIL102.nvidia.com (172.18.146.10) by HQMAIL108.nvidia.com (172.18.146.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:33 +0000 Received: from HQMAIL105.nvidia.com (172.20.187.12) by HQMAIL102.nvidia.com (172.18.146.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:32 +0000 Received: from hqnvemgw02.nvidia.com (172.16.227.111) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 16 Apr 2019 10:29:32 +0000 Received: from moonraker.nvidia.com (Not Verified[10.21.132.148]) by hqnvemgw02.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Tue, 16 Apr 2019 03:29:32 -0700 From: Jon Hunter To: Thierry Reding CC: Sandipan Patra , , "Jon Hunter" Subject: [PATCH 2/3] soc/tegra: pmc: Remove reset sysfs entries on error Date: Tue, 16 Apr 2019 11:29:03 +0100 Message-ID: <1555410544-14889-2-git-send-email-jonathanh@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1555410544-14889-1-git-send-email-jonathanh@nvidia.com> References: <1555410544-14889-1-git-send-email-jonathanh@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1555410570; bh=QA4ZKBTSM+vt/i1e/S+M7YcKxGMWBKOKRUxyZfOm/BM=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=sRoFFZRb6mLtvpqUJQCgvaYABcvKOYJzJTSRdbvfeUSiY518Ws/wBC4xWrJWy8u4n tmEksla7WavyQBELenp99AbrtdWpjC2vU8kCn8dSJhQhKKPqwZ8N1D4YPykinoF75s U+tPuCPrhWcSNpn2suUF4Ct8SWBU0PEtQDSzvQbFoIXShvvUvFO7RsLnCw+qVwIvwL hsSvM7b6Z88a75Qv64HVD6oJFGwZQ5NQsGU7Ec+jL2xy/eLrM2bE40tXAd2LwEn9JA 5gVlvd0PBA1tcFxzUtMqTLfObHdBv4ia1C3UzXffjLzcOEWY2S2p0N34Om6ButbLrc bAFHz9nE4yJyw== Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Commit 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info") added sysfs entries for Tegra reset source and level. However, these sysfs are not removed on error and so if the registering of PMC device is probe deferred, then the next time we attempt to probe the PMC device warnings such as the following will be displayed on boot ... sysfs: cannot create duplicate filename '/devices/platform/7000e400.pmc/reset_reason' Fix this by ... 1. Splitting the function tegra_pmc_reset_sysfs_init() into two separate functions for initialising the reset reason sysfs entry and the reset level sysfs entry. Given that not all devices support both this simplifies the cleanup in the error path. 2. If either of the sysfs entries fail to be created, then instead of just printing a warning message, print an error message and return the error to prevent the probe from succeeding and cleanup as necessary. Previously the intention was to avoid the failure of creating the sysfs entries to causing the PMC probe to fail, this should never happen and so it is better to just return the error. Fixes: 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info") Signed-off-by: Jon Hunter --- drivers/soc/tegra/pmc.c | 68 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 61c61994f17d..8d769e3ba668 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1771,26 +1771,48 @@ static ssize_t reset_level_show(struct device *dev, static DEVICE_ATTR_RO(reset_level); -static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc) +static int tegra_pmc_reset_reason_init(struct tegra_pmc *pmc) { struct device *dev = pmc->dev; - int err = 0; + int err; - if (pmc->soc->reset_sources) { - err = device_create_file(dev, &dev_attr_reset_reason); - if (err < 0) - dev_warn(dev, - "failed to create attr \"reset_reason\": %d\n", - err); - } + if (!pmc->soc->reset_sources) + return 0; - if (pmc->soc->reset_levels) { - err = device_create_file(dev, &dev_attr_reset_level); - if (err < 0) - dev_warn(dev, - "failed to create attr \"reset_level\": %d\n", - err); - } + err = device_create_file(dev, &dev_attr_reset_reason); + if (err < 0) + dev_err(dev, "failed to create attr \"reset_reason\": %d\n", + err); + + return err; +} + +static void tegra_pmc_reset_reason_remove(struct tegra_pmc *pmc) +{ + if (pmc->soc->reset_sources) + device_remove_file(pmc->dev, &dev_attr_reset_reason); +} + +static int tegra_pmc_reset_level_init(struct tegra_pmc *pmc) +{ + struct device *dev = pmc->dev; + int err; + + if (!pmc->soc->reset_levels) + return 0; + + err = device_create_file(dev, &dev_attr_reset_level); + if (err < 0) + dev_err(dev, "failed to create attr \"reset_level\": %d\n", + err); + + return err; +} + +static void tegra_pmc_reset_level_remove(struct tegra_pmc *pmc) +{ + if (pmc->soc->reset_levels) + device_remove_file(pmc->dev, &dev_attr_reset_level); } static int tegra_pmc_irq_translate(struct irq_domain *domain, @@ -2031,12 +2053,18 @@ static int tegra_pmc_probe(struct platform_device *pdev) tegra_pmc_init_tsense_reset(pmc); - tegra_pmc_reset_sysfs_init(pmc); + err = tegra_pmc_reset_reason_init(pmc); + if (err < 0) + return err; + + err = tegra_pmc_reset_level_init(pmc); + if (err < 0) + goto cleanup_reset_reason; if (IS_ENABLED(CONFIG_DEBUG_FS)) { err = tegra_powergate_debugfs_init(); if (err < 0) - return err; + goto cleanup_reset_level; } err = register_restart_handler(&tegra_pmc_restart_handler); @@ -2067,6 +2095,10 @@ static int tegra_pmc_probe(struct platform_device *pdev) unregister_restart_handler(&tegra_pmc_restart_handler); cleanup_debugfs: debugfs_remove(pmc->debugfs); +cleanup_reset_level: + tegra_pmc_reset_level_remove(pmc); +cleanup_reset_reason: + tegra_pmc_reset_reason_remove(pmc); return err; } From patchwork Tue Apr 16 10:29:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Hunter X-Patchwork-Id: 1086196 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nvidia.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=nvidia.com header.i=@nvidia.com header.b="AUUCNTAm"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44k1ns022gz9s00 for ; Tue, 16 Apr 2019 20:29:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727783AbfDPK3g (ORCPT ); Tue, 16 Apr 2019 06:29:36 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:18361 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726682AbfDPK3g (ORCPT ); Tue, 16 Apr 2019 06:29:36 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 16 Apr 2019 03:29:39 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 16 Apr 2019 03:29:34 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 16 Apr 2019 03:29:34 -0700 Received: from HQMAIL102.nvidia.com (172.18.146.10) by HQMAIL106.nvidia.com (172.18.146.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:34 +0000 Received: from HQMAIL106.nvidia.com (172.18.146.12) by HQMAIL102.nvidia.com (172.18.146.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:29:33 +0000 Received: from hqnvemgw02.nvidia.com (172.16.227.111) by HQMAIL106.nvidia.com (172.18.146.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 16 Apr 2019 10:29:33 +0000 Received: from moonraker.nvidia.com (Not Verified[10.21.132.148]) by hqnvemgw02.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Tue, 16 Apr 2019 03:29:33 -0700 From: Jon Hunter To: Thierry Reding CC: Sandipan Patra , , "Jon Hunter" Subject: [PATCH 3/3] soc/tegra: pmc: Move powergate initialisation to probe Date: Tue, 16 Apr 2019 11:29:04 +0100 Message-ID: <1555410544-14889-3-git-send-email-jonathanh@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1555410544-14889-1-git-send-email-jonathanh@nvidia.com> References: <1555410544-14889-1-git-send-email-jonathanh@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1555410579; bh=aQrlROr0rZqnWWQglxXky0qwherI+jLFXKaWR0cXoCM=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=AUUCNTAmVwymdZ7ZD0NLH9P+KTUYD51vQakgxaUKlPqagzM1E9ZUtrP1RM/qs956X 98xSjHaoriAoy9Ue6MGQj0rOdPT8joj0WYe/Mw24KNK5kSGGfzN0I+sA3uPou5X8gX AaDYiPrlDXY6J3dhprUwfw/KD8F9/EH11SHkWkocMiMihL02IOaEQ+jbw5tPI2Ejyc gcm+eGCIvzMyY7vqyi8ogLFoEL1j6S/g02R5iDHBCBdMca7MOZps719AgEQ5e9DEin 8scgY97WVuKsZWxV4LxFE7VXFYgdtzw6S12n4XzWY3z+CFKUXyxHxL0vyT1lg6pxOf FoTm+6fA0yFvw== Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Commit 8df127456f29 ("soc/tegra: pmc: Enable XUSB partitions on boot") was added as a workaround to ensure that the XUSB powergates or domains were turned on early during boot because as this time the Tegra XHCI driver did not handle the power domains at all. Now that the Tegra XHCI driver has been updated to properly managed the power domains, the workaround to enable the XUSB power domain early has been removed. This also means that we can now move the initialisation of the powergates into the PMC driver probe. Therefore, move the powergate initialisation into the PMC driver probe and return any errors detected. To handle any errors, functions to cleanup and remove any power-domains registered with the generic power-domain framework have been added. Finally the initialisation of the 'powergates_available' bitmask is kept in the PMC early init function to allow the legacy PMC powergate APIs to be called during early boot for enabling secondary CPUs on 32-bit Tegra devices. Signed-off-by: Jon Hunter --- drivers/soc/tegra/pmc.c | 83 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 8d769e3ba668..268840449ff2 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -992,20 +992,21 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, return err; } -static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) +static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) { struct device *dev = pmc->dev; struct tegra_powergate *pg; - int id, err; + int id, err = 0; bool off; pg = kzalloc(sizeof(*pg), GFP_KERNEL); if (!pg) - return; + return -ENOMEM; id = tegra_powergate_lookup(pmc, np->name); if (id < 0) { dev_err(dev, "powergate lookup failed for %pOFn: %d\n", np, id); + err = -ENODEV; goto free_mem; } @@ -1058,7 +1059,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) dev_dbg(dev, "added PM domain %s\n", pg->genpd.name); - return; + return 0; remove_genpd: pm_genpd_remove(&pg->genpd); @@ -1077,25 +1078,67 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) free_mem: kfree(pg); + + return err; } -static void tegra_powergate_init(struct tegra_pmc *pmc, - struct device_node *parent) +static int tegra_powergate_init(struct tegra_pmc *pmc, + struct device_node *parent) { struct device_node *np, *child; - unsigned int i; + int err = 0; + + np = of_get_child_by_name(parent, "powergates"); + if (!np) + return 0; - /* Create a bitmap of the available and valid partitions */ - for (i = 0; i < pmc->soc->num_powergates; i++) - if (pmc->soc->powergates[i]) - set_bit(i, pmc->powergates_available); + for_each_child_of_node(np, child) { + err = tegra_powergate_add(pmc, child); + if (err < 0) { + of_node_put(child); + break; + } + } + + of_node_put(np); + + return err; +} + +static void tegra_powergate_remove(struct generic_pm_domain *genpd) +{ + struct tegra_powergate *pg = to_powergate(genpd); + + reset_control_put(pg->reset); + + while (pg->num_clks--) + clk_put(pg->clks[pg->num_clks]); + + kfree(pg->clks); + + set_bit(pg->id, pmc->powergates_available); + + kfree(pg); +} + +static void tegra_powergate_remove_all(struct device_node *parent) +{ + struct generic_pm_domain *genpd; + struct device_node *np, *child; np = of_get_child_by_name(parent, "powergates"); if (!np) return; - for_each_child_of_node(np, child) - tegra_powergate_add(pmc, child); + for_each_child_of_node(np, child) { + of_genpd_del_provider(child); + + genpd = of_genpd_remove_last(child); + if (IS_ERR(genpd)) + continue; + + tegra_powergate_remove(genpd); + } of_node_put(np); } @@ -2078,9 +2121,13 @@ static int tegra_pmc_probe(struct platform_device *pdev) if (err) goto cleanup_restart_handler; + err = tegra_powergate_init(pmc, pdev->dev.of_node); + if (err < 0) + goto cleanup_powergates; + err = tegra_pmc_irq_init(pmc); if (err < 0) - goto cleanup_restart_handler; + goto cleanup_powergates; mutex_lock(&pmc->powergates_lock); iounmap(pmc->base); @@ -2091,6 +2138,8 @@ static int tegra_pmc_probe(struct platform_device *pdev) return 0; +cleanup_powergates: + tegra_powergate_remove_all(pdev->dev.of_node); cleanup_restart_handler: unregister_restart_handler(&tegra_pmc_restart_handler); cleanup_debugfs: @@ -2776,6 +2825,7 @@ static int __init tegra_pmc_early_init(void) const struct of_device_id *match; struct device_node *np; struct resource regs; + unsigned int i; bool invert; mutex_init(&pmc->powergates_lock); @@ -2832,7 +2882,10 @@ static int __init tegra_pmc_early_init(void) if (pmc->soc->maybe_tz_only) pmc->tz_only = tegra_pmc_detect_tz_only(pmc); - tegra_powergate_init(pmc, np); + /* Create a bitmap of the available and valid partitions */ + for (i = 0; i < pmc->soc->num_powergates; i++) + if (pmc->soc->powergates[i]) + set_bit(i, pmc->powergates_available); /* * Invert the interrupt polarity if a PMC device tree node