From patchwork Thu Jun 1 05:27:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oza Pawandeep X-Patchwork-Id: 9758677 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0961A60360 for ; Thu, 1 Jun 2017 05:28:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1803284E4 for ; Thu, 1 Jun 2017 05:28:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5D63284F1; Thu, 1 Jun 2017 05:28:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 512DB284F9 for ; Thu, 1 Jun 2017 05:28:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751263AbdFAF2N (ORCPT ); Thu, 1 Jun 2017 01:28:13 -0400 Received: from mail-qt0-f175.google.com ([209.85.216.175]:34051 "EHLO mail-qt0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751168AbdFAF2M (ORCPT ); Thu, 1 Jun 2017 01:28:12 -0400 Received: by mail-qt0-f175.google.com with SMTP id c13so28499076qtc.1 for ; Wed, 31 May 2017 22:28:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=Alm3KX5cArecw+Q1pegw3awDklMnQmbriboK9fJfoPc=; b=MWiEHgY7wLIMAKXVuC+p4kb8KU9FbcaTN+a2CquTYzcksBJEiapbTbxndFl2olKrrQ wMym9X9tDoEbcTNgsToCTLLhZuTKOkcuKvjojR8sHV9ByWj6Ube96uusRGxIwkGWVDP0 93ej8GUZojo5woz2SWQAE4fyA3S5QTSN2ebjk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Alm3KX5cArecw+Q1pegw3awDklMnQmbriboK9fJfoPc=; b=ehr/B7Z6UmXY/ePDOlcLo/Hw2a8qz/+1nl8FH5BwADYbmDwRTQXaBd0Ml7k35uTeUx MWNmmR7QXzIVTV8vLxZlmAmhO16IXmrNFh1D9vV3BJ52MHu5kc/u93MwJE8lhHnL40nw W6BCb5Rb5OnLLsTJ6OxPwqvrDPiW7qDxlb+0KROtLkoMhmr2zKNoQXG4N249+Ke/gwfY JRtyEC4W9KbImWhtyi9LWwfO+b5kaHrNO50qj+9mD4Nk3pGUp/kY+mn3zB9ll1gK27yB 4Bv4Br0ZbUUDGWPKYQeYXDh5qRYMHQz/a03mmtoSbivxm54AgU9YAM5vS5NtCVjlcKrO UF0Q== X-Gm-Message-State: AODbwcCsYmb+a0VRv7SFn1BazC+LbUHW6by+h5AkwSm7pIYFcBvy2zLG 5/tX1FbPfaMDRE2F X-Received: by 10.237.39.37 with SMTP id n34mr35919614qtd.222.1496294891617; Wed, 31 May 2017 22:28:11 -0700 (PDT) Received: from anjanavk-OptiPlex-7010.dhcp.avagotech.net ([192.19.237.250]) by smtp.gmail.com with ESMTPSA id d34sm12307026qta.59.2017.05.31.22.28.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 31 May 2017 22:28:10 -0700 (PDT) From: Oza Pawandeep To: Bjorn Helgaas , Ray Jui , Scott Branden , Jon Mason , bcm-kernel-feedback-list@broadcom.com, Oza Pawandeep , Andy Gospodarek , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Oza Pawandeep Subject: [PATCH 2/2] PCI: iproc: add device shutdown for PCI RC Date: Thu, 1 Jun 2017 10:57:51 +0530 Message-Id: <1496294871-5836-3-git-send-email-oza.oza@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1496294871-5836-1-git-send-email-oza.oza@broadcom.com> References: <1496294871-5836-1-git-send-email-oza.oza@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP PERST# must be asserted around ~500ms before the reboot is applied. During soft reset (e.g., "reboot" from Linux) on some iProc based SoCs LCPLL clock and PERST both goes off simultaneously. This will cause certain Endpoints Intel NVMe not get detected, upon next boot sequence. This happens because; Endpoint is expecting the clock for some amount of time after PERST is asserted, which is not happening in our case (Compare to Intel X86 boards, will have clocks running). this cause NVMe to behave in undefined way. Essentially clock will remain alive for 500ms with PERST# = 0 before reboot. This patch adds platform shutdown where it should be called in device_shutdown while reboot command is issued. So in sequence first Endpoint Shutdown (e.g. nvme_shutdown) followed by RC shutdown is called, which issues safe PERST assertion. Signed-off-by: Oza Pawandeep Reviewed-by: Ray Jui Reviewed-by: Scott Branden diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index 90d2bdd..9512960 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c @@ -131,6 +131,13 @@ static int iproc_pcie_pltfm_remove(struct platform_device *pdev) return iproc_pcie_remove(pcie); } +static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev) +{ + struct iproc_pcie *pcie = platform_get_drvdata(pdev); + + iproc_pcie_shutdown(pcie); +} + static struct platform_driver iproc_pcie_pltfm_driver = { .driver = { .name = "iproc-pcie", @@ -138,6 +145,7 @@ static int iproc_pcie_pltfm_remove(struct platform_device *pdev) }, .probe = iproc_pcie_pltfm_probe, .remove = iproc_pcie_pltfm_remove, + .shutdown = iproc_pcie_pltfm_shutdown, }; module_platform_driver(iproc_pcie_pltfm_driver); diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 05a3647..e9afc63 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c @@ -608,31 +608,38 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, .write = iproc_pcie_config_write32, }; -static void iproc_pcie_reset(struct iproc_pcie *pcie) +static void iproc_pcie_perst_ctrl(struct iproc_pcie *pcie, bool assert) { u32 val; /* - * PAXC and the internal emulated endpoint device downstream should not - * be reset. If firmware has been loaded on the endpoint device at an - * earlier boot stage, reset here causes issues. + * The internal emulated endpoints (such as PAXC) device downstream + * should not be reset. If firmware has been loaded on the endpoint + * device at an earlier boot stage, reset here causes issues. */ if (pcie->ep_is_internal) return; - /* - * Select perst_b signal as reset source. Put the device into reset, - * and then bring it out of reset - */ - val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); - val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & - ~RC_PCIE_RST_OUTPUT; - iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); - udelay(250); - - val |= RC_PCIE_RST_OUTPUT; - iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); - msleep(100); + if (assert) { + val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); + val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & + ~RC_PCIE_RST_OUTPUT; + iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); + udelay(250); + } else { + val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); + val |= RC_PCIE_RST_OUTPUT; + iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); + msleep(100); + } +} + +int iproc_pcie_shutdown(struct iproc_pcie *pcie) +{ + iproc_pcie_perst_ctrl(pcie, true); + msleep(500); + + return 0; } static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) @@ -1310,7 +1317,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) goto err_exit_phy; } - iproc_pcie_reset(pcie); + iproc_pcie_perst_ctrl(pcie, true); + iproc_pcie_perst_ctrl(pcie, false); if (pcie->need_ob_cfg) { ret = iproc_pcie_map_ranges(pcie, res); diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h index 0bbe2ea..a6b55ce 100644 --- a/drivers/pci/host/pcie-iproc.h +++ b/drivers/pci/host/pcie-iproc.h @@ -110,6 +110,7 @@ struct iproc_pcie { int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res); int iproc_pcie_remove(struct iproc_pcie *pcie); +int iproc_pcie_shutdown(struct iproc_pcie *pcie); #ifdef CONFIG_PCIE_IPROC_MSI int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);