[v8,03/10] PCI: dwc: ep: Introduce dw_pcie_ep_cleanup() API for drivers supporting PERST#
Message ID | 20240224-pci-dbi-rework-v8-3-64c7fd0cfe64@linaro.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1020642dyb; Fri, 23 Feb 2024 22:55:40 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUOFUyOli/qgEZvtRFfinlhwF4ciu8rXs8J/KFbbXCsBoEbwgm+qWXhcNKqTOSSc78NDgIS2/3VqlFb5K1qdN2POKuPpg== X-Google-Smtp-Source: AGHT+IHQQYY6xF1GFKUzGBuEX+ZyOSIl1zLiRpjTSTvMQah7h5Eiua5shnFL0298sBR6s8jgsvQP X-Received: by 2002:a0c:e1d1:0:b0:68f:2d49:27f1 with SMTP id v17-20020a0ce1d1000000b0068f2d4927f1mr2032261qvl.59.1708757740398; Fri, 23 Feb 2024 22:55:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708757740; cv=pass; d=google.com; s=arc-20160816; b=qzIWIGLt9Sw4y9yfk6IZHaOfqNDR99LklnGU3yJb329h4Njbuxp1oECA3dOAAJB/Wf uae6aqIHH3ZRh4KsX3tQCpJ9eywTPf3PPtoNiSIOdLgZbrBIyW7lOxU3olgaP0WEksE8 HLT6obEHihdqkoqNBgcDp9vkyvl4o1EX9/t3Qsc7FDecXB27Ch4Dn5RL4lRQPEarcBnh uxwKfRriJjUCmgF0HH8vunj3OXW3kw4+ZnRI4FTH4nlA5GpLlxnblVsYvcBYfl8IW1zZ l2fgYnqpgEuLa6sTQfr3fTooOcwBmIqWRdEJ6LEHECPu8PutF7BfARFZjenvQxi+0/59 HBfg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=Gm7BOWCebEzto6pQtqllLk3GIjiAQNALfrviMiZ/ywU=; fh=An+CmN5fvtgCJlel39XOGQMASGlqfnVavlf9by9w8F8=; b=Nmvk4l5TP/mbmKINjT4z2A+ouG6GSFDAStHMQ4UAErLnnskJV8fkSdGg1krjYBHwPS o6Y7/CnsUjyzX2/Avn0BoTIU+ExhLGcERtB4Z2VO63zIf15jPOL5WDWChZr1HBdkxuCz ych+o+WOYdPW0tdz60mA6YWXouYQWsDNbezn+UHR6QE8633qcZDnEEovoqPgp9jaT3Ok aqPGqhkpVOQfyLt2TsfD/+EoweravZolgVdNiSgdqw41GiIkGgcVjT/vqX/6c4dwXhHs bulERLQZgHBSgK2NxNrWAox9klFf+vrFCYTFmRQ1+R4VqcuQDBVWh6erS/aNi9tFiF7k LOOA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZgaSv86P; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id g8-20020a0562140ac800b0068f5c7d73absi554609qvi.161.2024.02.23.22.55.40 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Feb 2024 22:55:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZgaSv86P; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79487-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 122B21C21B99 for <ouuuleilei@gmail.com>; Sat, 24 Feb 2024 06:55:40 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8641E1B7EF; Sat, 24 Feb 2024 06:54:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="ZgaSv86P" Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4919524C for <linux-kernel@vger.kernel.org>; Sat, 24 Feb 2024 06:54:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708757693; cv=none; b=r4hAUQw2ESwUvAC2S0HM2bgm/hHOyxy9GEomPhJmSX/pIiF0yZ4upY1UrOsnlRiNarFA5cRyi9AW3xDdDcmeitFV+u1z9DNTFBuJ3P7ldSQa724+JaQY5CpvvBsKzEF4el7EfYcbtuHWvSU6xbQb3wW1Q/pL9LJFf9CyPhKagKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708757693; c=relaxed/simple; bh=AMzVel+mzNPZDu5rNOshxFrNbNGmTb5cvr1qXK6YD5c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hmcj0d4yDbOoZX0zZoN3/DrSBBCinX3xhgYyNdRIC1zRnrU4QUsOvyLCwFfkR/MQIYKRfBelZQXYaHYjYbMwqFt6wcEOVkDCyKrFu18gtHVkKhNRfPX6zGIJEtiPcP67AUHcx1cjw4vymzP+VavcpDjsHKlwOsz0eKvXnQK6I9o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=ZgaSv86P; arc=none smtp.client-ip=209.85.215.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-pg1-f177.google.com with SMTP id 41be03b00d2f7-5ce9555d42eso1324424a12.2 for <linux-kernel@vger.kernel.org>; Fri, 23 Feb 2024 22:54:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1708757691; x=1709362491; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Gm7BOWCebEzto6pQtqllLk3GIjiAQNALfrviMiZ/ywU=; b=ZgaSv86PWk6aIyq7gfcgteSTipIx3I9ArIokDljZZIfRe5HEYmCgPJONdOcmZL5TGv ys58ShzKhoQH6bQrsUbLdBAlyTTnL8zcsKUhfIXry7+H8WSTkYcTw0loi8n3YLNvSshf mqx+Kzj1h45QomKIF7QrG3hJFI3wPKmbs5RjFXjBE5Y50+mdSLNaOQFosKJIvzFnnhOB 19UP7LO3NYA+lxhzKovY1LUbENjqOCu/Io18f1wiTzXZ4/W7wKKHfvy+//QoaG7O8Qpk n8YnVih7bso+h5F3Jev1qAhdkDfsWCZkD7bDZsoSM1wUjWrT4Luzqs1T6LesxkL7o46J tC1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708757691; x=1709362491; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Gm7BOWCebEzto6pQtqllLk3GIjiAQNALfrviMiZ/ywU=; b=P5X66rtdjNNtUBBaKtXfozLS3pRKly903odkFv+ZoudAuZ47nahngsQCj/F0bjwRQG jlDQ+Kj6yqAWgWhXGl/ikikYWqkpSuWyzduda9secYJejn/X6AQBRRitDC57mH7NMM/l RBp+m+uZzva3nSyZocSp0k6x8Kv9S8eHz4y2jtmannHmftkjYJwDeowbl5ko3idA6FIK 1oKnAaxtPiYVz+SWkh8qqtn0nACCtJ75/GmGQSAOzaxEXwYt/IjGIlzncatREYMmbQcA BtmwXberuX8BxpOX9ld/iahnRIhBjG/JJ/ZRk1mVwOhqyQxKIG28BbYiPcvmaz2sFzTE u+Fg== X-Forwarded-Encrypted: i=1; AJvYcCVUkinzoOVdxc/LQYcTkPULPW32ADAeKnurWc9moP2hhlOBT2VBOw6SR0DuUZBwNcMIpkHjWSDUztw7ccZWCnVhsrwaOACtj3iDXXq8 X-Gm-Message-State: AOJu0Ywz4P6lAA1vcgNF9iaqoc2oO3+/qyjcvai5w+6PFXdEMgKZHcK6 64pDQmy8EU2ALlnqVtsi2SG4QJ0I7ntUSpFp6x6ztGfoKNlvuinN6IpvVTZ0ew== X-Received: by 2002:a05:6a20:c995:b0:1a0:d04a:8485 with SMTP id gy21-20020a056a20c99500b001a0d04a8485mr2121214pzb.22.1708757691194; Fri, 23 Feb 2024 22:54:51 -0800 (PST) Received: from [127.0.1.1] ([120.138.12.46]) by smtp.gmail.com with ESMTPSA id r5-20020aa78b85000000b006e4cb7f4393sm502932pfd.165.2024.02.23.22.54.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Feb 2024 22:54:50 -0800 (PST) From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Date: Sat, 24 Feb 2024 12:24:09 +0530 Subject: [PATCH v8 03/10] PCI: dwc: ep: Introduce dw_pcie_ep_cleanup() API for drivers supporting PERST# Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20240224-pci-dbi-rework-v8-3-64c7fd0cfe64@linaro.org> References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org> In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org> To: Jingoo Han <jingoohan1@gmail.com>, Gustavo Pimentel <gustavo.pimentel@synopsys.com>, Lorenzo Pieralisi <lpieralisi@kernel.org>, =?utf-8?q?Krzysztof_Wilczy=C5=84?= =?utf-8?q?ski?= <kw@linux.com>, Rob Herring <robh@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, Marek Vasut <marek.vasut+renesas@gmail.com>, Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>, Thierry Reding <thierry.reding@gmail.com>, Jonathan Hunter <jonathanh@nvidia.com>, Kishon Vijay Abraham I <kishon@ti.com>, Vidya Sagar <vidyas@nvidia.com>, Vignesh Raghavendra <vigneshr@ti.com>, Richard Zhu <hongxing.zhu@nxp.com>, Lucas Stach <l.stach@pengutronix.de>, Shawn Guo <shawnguo@kernel.org>, Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix Kernel Team <kernel@pengutronix.de>, Fabio Estevam <festevam@gmail.com>, NXP Linux Team <linux-imx@nxp.com>, Minghuan Lian <minghuan.Lian@nxp.com>, Mingkai Hu <mingkai.hu@nxp.com>, Roy Zang <roy.zang@nxp.com>, Kunihiko Hayashi <hayashi.kunihiko@socionext.com>, Masami Hiramatsu <mhiramat@kernel.org>, Kishon Vijay Abraham I <kishon@kernel.org> Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-tegra@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linuxppc-dev@lists.ozlabs.org, Niklas Cassel <cassel@kernel.org>, Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=3640; i=manivannan.sadhasivam@linaro.org; h=from:subject:message-id; bh=AMzVel+mzNPZDu5rNOshxFrNbNGmTb5cvr1qXK6YD5c=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBl2ZKWN5s7yp9FVQGAuReNe7g8yseCdV9BNHSCP Zrav+1vZ/2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCZdmSlgAKCRBVnxHm/pHO 9UFMB/9QN232kQi2reuocmy2tE//cMRFTozpfDoIA92osFCOoy0Cer23LiZEAcJeSGrpC5C49sC mgA1ZnNS7iSCH4PCISxuQiI86G73z/enEIpqSklDziO4mv0OyumLih98yNqum7HVp67XWtw3Vm9 fGzA5s/htyFJnXZvvsTAIRUlBSyCkENUFLZZjR9X9iDCUeUWzWxKXHC+0E066ZOGDZdEuohlxNg TB5ZqF4hSHZaz18Uai4MAw0p+JFaIfZIfAcZwz67LBb5w4MFCIagUxuZfhWlQJ9M5tV6rpAzERJ tdNfrJDsEPY/efpFhDlwrXfYiKuRtY+jzlQqn6wXjmIuQe5/ X-Developer-Key: i=manivannan.sadhasivam@linaro.org; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791762356131604436 X-GMAIL-MSGID: 1791762356131604436 |
Series |
PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host
|
|
Commit Message
Manivannan Sadhasivam
Feb. 24, 2024, 6:54 a.m. UTC
For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some
of the DWC resources like eDMA should be cleaned up during the PERST#
assert time.
So let's introduce a dw_pcie_ep_cleanup() API that could be called by these
drivers to cleanup the DWC specific resources. Currently, it just removes
eDMA.
Reported-by: Niklas Cassel <cassel@kernel.org>
Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES@x1-carbon
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +++++++++--
drivers/pci/controller/dwc/pcie-designware.h | 5 +++++
drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 +
drivers/pci/controller/dwc/pcie-tegra194.c | 2 ++
4 files changed, 17 insertions(+), 2 deletions(-)
Comments
On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote: > For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some > of the DWC resources like eDMA should be cleaned up during the PERST# > assert time. > > So let's introduce a dw_pcie_ep_cleanup() API that could be called by these > drivers to cleanup the DWC specific resources. Currently, it just removes > eDMA. > > Reported-by: Niklas Cassel <cassel@kernel.org> > Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES@x1-carbon > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> > --- > drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +++++++++-- > drivers/pci/controller/dwc/pcie-designware.h | 5 +++++ > drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + > drivers/pci/controller/dwc/pcie-tegra194.c | 2 ++ > 4 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > index 2b11290aab4c..1205bfba8310 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > @@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, > return 0; > } > > -void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) > { > struct dw_pcie *pci = to_dw_pcie_from_ep(ep); > - struct pci_epc *epc = ep->epc; > > dw_pcie_edma_remove(pci); > +} > +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup); > + > +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > +{ > + struct pci_epc *epc = ep->epc; > + > + dw_pcie_ep_cleanup(ep); > > pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, > epc->mem->window.page_size); > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h > index 61465203bb60..351d2fe3ea4d 100644 > --- a/drivers/pci/controller/dwc/pcie-designware.h > +++ b/drivers/pci/controller/dwc/pcie-designware.h > @@ -672,6 +672,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep); > int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); > void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); > void dw_pcie_ep_deinit(struct dw_pcie_ep *ep); > +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep); > int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no); > int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, > u8 interrupt_num); > @@ -705,6 +706,10 @@ static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > { > } > > +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) > +{ > +} > + > static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) > { > return 0; > diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c > index 36e5e80cd22f..59b1c0110288 100644 > --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c > +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c > @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci) > return; > } > > + dw_pcie_ep_cleanup(&pci->ep); > qcom_pcie_disable_resources(pcie_ep); > pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; > } > diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c > index 7afa9e9aabe2..68bfeed3429b 100644 > --- a/drivers/pci/controller/dwc/pcie-tegra194.c > +++ b/drivers/pci/controller/dwc/pcie-tegra194.c > @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) > if (ret) > dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); > > + dw_pcie_ep_cleanup(&pcie->pci.ep); > + > reset_control_assert(pcie->core_rst); > > tegra_pcie_disable_phy(pcie); > > -- > 2.25.1 >
On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote: > For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some > of the DWC resources like eDMA should be cleaned up during the PERST# > assert time. > > So let's introduce a dw_pcie_ep_cleanup() API that could be called by these > drivers to cleanup the DWC specific resources. Currently, it just removes > eDMA. > > Reported-by: Niklas Cassel <cassel@kernel.org> > Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES@x1-carbon > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > --- > drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +++++++++-- > drivers/pci/controller/dwc/pcie-designware.h | 5 +++++ > drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + > drivers/pci/controller/dwc/pcie-tegra194.c | 2 ++ > 4 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > index 2b11290aab4c..1205bfba8310 100644 > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > @@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, > return 0; > } > > -void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) > { > struct dw_pcie *pci = to_dw_pcie_from_ep(ep); > - struct pci_epc *epc = ep->epc; > > dw_pcie_edma_remove(pci); Hello Mani, In this message: https://lore.kernel.org/linux-pci/20240130062938.GB32821@thinkpad/ You mentioned that you were going to clean up the BARs. (Like I wrote in that thread, I really think that we should merge a fix for the broken "do we have a saved value from find_first_zero_bit() in the array", by using a "if (!saved_value[bar])", when find_first_zero_bit() returns zero.) However, regardless of that, I do not see that this series (neither dw_pcie_ep_cleanup(), nor dw_pcie_ep_linkdown()), calls any function which will clean up the BARs. Since e.g. qcom-ep.c does a reset_control_assert() during perst assert/deassert, which should clear sticky registers, I think that you should let dw_pcie_ep_cleanup() clean up the BARs using dw_pcie_ep_clear_bar(). Kind regards, Niklas > +} > +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup); > + > +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > +{ > + struct pci_epc *epc = ep->epc; > + > + dw_pcie_ep_cleanup(ep); > > pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, > epc->mem->window.page_size); > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h > index 61465203bb60..351d2fe3ea4d 100644 > --- a/drivers/pci/controller/dwc/pcie-designware.h > +++ b/drivers/pci/controller/dwc/pcie-designware.h > @@ -672,6 +672,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep); > int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); > void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); > void dw_pcie_ep_deinit(struct dw_pcie_ep *ep); > +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep); > int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no); > int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, > u8 interrupt_num); > @@ -705,6 +706,10 @@ static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > { > } > > +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) > +{ > +} > + > static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) > { > return 0; > diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c > index 36e5e80cd22f..59b1c0110288 100644 > --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c > +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c > @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci) > return; > } > > + dw_pcie_ep_cleanup(&pci->ep); > qcom_pcie_disable_resources(pcie_ep); > pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; > } > diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c > index 7afa9e9aabe2..68bfeed3429b 100644 > --- a/drivers/pci/controller/dwc/pcie-tegra194.c > +++ b/drivers/pci/controller/dwc/pcie-tegra194.c > @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) > if (ret) > dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); > > + dw_pcie_ep_cleanup(&pcie->pci.ep); > + > reset_control_assert(pcie->core_rst); > > tegra_pcie_disable_phy(pcie); > > -- > 2.25.1 >
On Thu, Feb 29, 2024 at 01:40:29PM +0100, Niklas Cassel wrote: > On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote: > > For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some > > of the DWC resources like eDMA should be cleaned up during the PERST# > > assert time. > > > > So let's introduce a dw_pcie_ep_cleanup() API that could be called by these > > drivers to cleanup the DWC specific resources. Currently, it just removes > > eDMA. > > > > Reported-by: Niklas Cassel <cassel@kernel.org> > > Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES@x1-carbon > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > --- > > drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +++++++++-- > > drivers/pci/controller/dwc/pcie-designware.h | 5 +++++ > > drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + > > drivers/pci/controller/dwc/pcie-tegra194.c | 2 ++ > > 4 files changed, 17 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c > > index 2b11290aab4c..1205bfba8310 100644 > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c > > @@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, > > return 0; > > } > > > > -void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) > > +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) > > { > > struct dw_pcie *pci = to_dw_pcie_from_ep(ep); > > - struct pci_epc *epc = ep->epc; > > > > dw_pcie_edma_remove(pci); > > Hello Mani, > > In this message: > https://lore.kernel.org/linux-pci/20240130062938.GB32821@thinkpad/ > > You mentioned that you were going to clean up the BARs. Yes, I did and it is still in my queue. > (Like I wrote in that thread, I really think that we should merge a fix for > the broken "do we have a saved value from find_first_zero_bit() in the array", > by using a "if (!saved_value[bar])", when find_first_zero_bit() returns zero.) > Hmm, yeah that logic is flawed. Let me take another look. > However, regardless of that, I do not see that this series (neither > dw_pcie_ep_cleanup(), nor dw_pcie_ep_linkdown()), calls any function which > will clean up the BARs. > > Since e.g. qcom-ep.c does a reset_control_assert() during perst > assert/deassert, which should clear sticky registers, I think that > you should let dw_pcie_ep_cleanup() clean up the BARs using > dw_pcie_ep_clear_bar(). > As I mentioned earlier, it is the job of the EPF drivers to clear the BARs since they allocate them. I'm trying to reduce the implicit resetting wherever we could. The proper fix is to add the LINK_DOWN callback to EPF drivers and do cleanup. I'm planning to submit a series for that after this one. - Mani
On Mon, Mar 04, 2024 at 01:47:13PM +0530, Manivannan Sadhasivam wrote: > On Thu, Feb 29, 2024 at 01:40:29PM +0100, Niklas Cassel wrote: > > On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote: > > > > Since e.g. qcom-ep.c does a reset_control_assert() during perst > > assert/deassert, which should clear sticky registers, I think that > > you should let dw_pcie_ep_cleanup() clean up the BARs using > > dw_pcie_ep_clear_bar(). > > > > As I mentioned earlier, it is the job of the EPF drivers to clear the BARs since > they allocate them. I'm trying to reduce the implicit resetting wherever we > could. > > The proper fix is to add the LINK_DOWN callback to EPF drivers and do cleanup. > I'm planning to submit a series for that after this one. Currently, pci-epf-test allocates memory for the BARs in .bind(). Likewise it frees the memory for the BARs in .unbind(). AFAICT, most iATU registers, and most BAR registers are sticky registers, so they will not get reset on link down. (The currently selected BAR size, in case of Resizable BAR is an exception.) That means that even on link down, we do not need to free the memory, or change the iATU settings. (This applies to all drivers.) However, on PERST (for the drivers call dw_pcie_ep_cleanup()), they call reset_control_assert(), so they will clear sticky registers, which means that they need to at least re-write the iATU and BAR registers. (I guess they could free + allocate the memory for the BARs again, but I don't think that is strictly necessary.) That is why I suggested that you call dw_pcie_ep_clear_bar() from dw_pcie_ep_cleanup(). If you free the memory for the BARs in link_down() (this callback exists for many drivers, even drivers without a PERST handler), where are you supposted to alloc the memory for the BARs again? Allocating them at link_up() is too late (because as soon as the link is up, the host is allowed to enumerate the EP BARs.) The proper place is to allocate them when receiving PERST, but not all drivers have a PERST handler. (My understanding is that 1) PERST assert 2) PERST deassert 3) link is up.) unbind() undos what was done in bind(), so shouldn't link_down() undo what was done in link_up()? With that logic, if you move the alloc to .core_init(), should we perhaps have a .core_deinit() callback for EPF drivers? (I guess only drivers which perform a reset during PERST would call this.) But considering that free+alloc is not strictly needed, why not just keep the allocation + free in .bind()/.unbind() ? (To avoid the need to create a .core_deinit()), and let dw_pcie_ep_cleanup() call dw_pcie_ep_clear_bar() ? I guess my point is that it seems a bit pointless for drivers that do not clear sticky registers to free+alloc memory on link down, for no good reason. (Memory might get fragmented over time, so it might not be possible to perform a big allocation after the device has been running for a really long time.) So I'm thinking that we either 1) Keep the alloc/free in bind/unbind, and let dw_pcie_ep_cleanup() call dw_pcie_ep_clear_bar(), or 2) Introduce a .deinit_core() callback which will free the BARs. (Because I don't see how you will (re-)allocate memory for all drivers if you free the memory in link_down().) Kind regards, Niklas
On Mon, Mar 04, 2024 at 11:51:04AM +0100, Niklas Cassel wrote: > On Mon, Mar 04, 2024 at 01:47:13PM +0530, Manivannan Sadhasivam wrote: > > On Thu, Feb 29, 2024 at 01:40:29PM +0100, Niklas Cassel wrote: > > > On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote: > > > > > > Since e.g. qcom-ep.c does a reset_control_assert() during perst > > > assert/deassert, which should clear sticky registers, I think that > > > you should let dw_pcie_ep_cleanup() clean up the BARs using > > > dw_pcie_ep_clear_bar(). > > > > > > > As I mentioned earlier, it is the job of the EPF drivers to clear the BARs since > > they allocate them. I'm trying to reduce the implicit resetting wherever we > > could. > > > > The proper fix is to add the LINK_DOWN callback to EPF drivers and do cleanup. > > I'm planning to submit a series for that after this one. > > Currently, pci-epf-test allocates memory for the BARs in .bind(). > Likewise it frees the memory for the BARs in .unbind(). > > AFAICT, most iATU registers, and most BAR registers are sticky registers, > so they will not get reset on link down. > (The currently selected BAR size, in case of Resizable BAR is an exception.) > > That means that even on link down, we do not need to free the memory, > or change the iATU settings. (This applies to all drivers.) > > > > However, on PERST (for the drivers call dw_pcie_ep_cleanup()), they call > reset_control_assert(), so they will clear sticky registers, which means > that they need to at least re-write the iATU and BAR registers. > (I guess they could free + allocate the memory for the BARs again, > but I don't think that is strictly necessary.) > That is why I suggested that you call dw_pcie_ep_clear_bar() from > dw_pcie_ep_cleanup(). > Sorry, I keep assuming the flow w.r.t PERST# supported platforms :/ My bad! > > > If you free the memory for the BARs in link_down() (this callback exists > for many drivers, even drivers without a PERST handler), where are you > supposted to alloc the memory for the BARs again? > > Allocating them at link_up() is too late (because as soon as the link is > up, the host is allowed to enumerate the EP BARs.) The proper place is to > allocate them when receiving PERST, but not all drivers have a PERST handler. > > (My understanding is that 1) PERST assert 2) PERST deassert 3) link is up.) > > > > unbind() undos what was done in bind(), so shouldn't link_down() undo what was > done in link_up()? With that logic, if you move the alloc to .core_init(), > should we perhaps have a .core_deinit() callback for EPF drivers? > (I guess only drivers which perform a reset during PERST would call this.) > > But considering that free+alloc is not strictly needed, why not just keep > the allocation + free in .bind()/.unbind() ? > (To avoid the need to create a .core_deinit()), and let dw_pcie_ep_cleanup() > call dw_pcie_ep_clear_bar() ? > > I guess my point is that it seems a bit pointless for drivers that do not > clear sticky registers to free+alloc memory on link down, for no good > reason. (Memory might get fragmented over time, so it might not be possible > to perform a big allocation after the device has been running for a really > long time.) > > > > So I'm thinking that we either > 1) Keep the alloc/free in bind/unbind, and let dw_pcie_ep_cleanup() call > dw_pcie_ep_clear_bar(), > or > 2) Introduce a .deinit_core() callback which will free the BARs. > (Because I don't see how you will (re-)allocate memory for all drivers > if you free the memory in link_down().) > I think option 2 is the better solution. In my view, calling dw_pcie_ep_clear_bar() from EPC drivers is a layering violation since the allocation happens from EPF drivers. So clearing the BARs during the deinit() callback that gets called when PERST# assert happens is the way to go. - Mani
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 2b11290aab4c..1205bfba8310 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, return 0; } -void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); - struct pci_epc *epc = ep->epc; dw_pcie_edma_remove(pci); +} +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup); + +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +{ + struct pci_epc *epc = ep->epc; + + dw_pcie_ep_cleanup(ep); pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, epc->mem->window.page_size); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 61465203bb60..351d2fe3ea4d 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -672,6 +672,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep); int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); void dw_pcie_ep_deinit(struct dw_pcie_ep *ep); +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep); int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no); int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num); @@ -705,6 +706,10 @@ static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) { } +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) +{ +} + static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) { return 0; diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 36e5e80cd22f..59b1c0110288 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci) return; } + dw_pcie_ep_cleanup(&pci->ep); qcom_pcie_disable_resources(pcie_ep); pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; } diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 7afa9e9aabe2..68bfeed3429b 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) if (ret) dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); + dw_pcie_ep_cleanup(&pcie->pci.ep); + reset_control_assert(pcie->core_rst); tegra_pcie_disable_phy(pcie);