Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp300394pxb; Tue, 31 Aug 2021 22:17:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxiy5ViHXPPUNlSXduCTglQYGPpKiKwPfzpYKwNSqpdY6FnQeUw010vRuV05OWma2fsPXJo X-Received: by 2002:a92:6711:: with SMTP id b17mr23751324ilc.122.1630473478398; Tue, 31 Aug 2021 22:17:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630473478; cv=none; d=google.com; s=arc-20160816; b=nYaeUSya5Y1LiaQLY1Qn8FYxNwyJhBZR9bi+8g8gbHMkgMgdEWCJyKP8VPyPXgaZYN bfoYDga1opz9+7TpCH9OQxUXtXrbtcNJlGHLtlv/sipf6uwv/MSV5n+oBLCLtmFxy8qT d91iMHUL9Y8AvknxYcu0CIjFXLIyDRsszJbSt+s/HHbO2PIpOncx3Lha2ijssWphE1uT 6rJ3gzY1PlorZN7NV1Y4iMD9MIC1XG8k24LewJNsrXL8ecUIu78rzE9W7qwaaM+AFPdy X3aY3qoT2KrjEjTdD0lH90rYlPkKj1jj6d/V0opNkWoW5wNArEbsa2lbUDgjgy89XDpa pZzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=YmGLSlTYRSYfdd+vbizS6t86QzjfKEn2uwZjV/AHO6E=; b=agl7OYJJXNzZMESww9tvjIOnOs7keMgBMjwNT314KjHquiSicV2lvBrwVnWJpR6/I+ Xv0c63xlUwf2+n9YyfwOLOd/C0bVNcfRRhWJPiclfvtSgZdswnGIDUGtjN5f9MwRmToX kW5xPV6RAft+LtP04eQYUOlC1h0fNNWdj/MoQnjUpLeZAin5FMfvDqjgAnjOSXblJ+t9 xJuAVwfUbpZ0H1aKPVsRfjhguXu8dT5+UZXHLtBvyWIvDMoYSwlsfH1mXK4pJAxn9c++ dMAESLV0lWlqyaV/haMsiMevX+Tjta0o6CHRexj9yHqigRUeA7aXBoq8Qyro7lNwRgAF Iv4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h14si19135444ile.129.2021.08.31.22.17.47; Tue, 31 Aug 2021 22:17:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241974AbhIAFRO (ORCPT + 99 others); Wed, 1 Sep 2021 01:17:14 -0400 Received: from mx.socionext.com ([202.248.49.38]:39598 "EHLO mx.socionext.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241949AbhIAFRJ (ORCPT ); Wed, 1 Sep 2021 01:17:09 -0400 Received: from unknown (HELO iyokan2-ex.css.socionext.com) ([172.31.9.54]) by mx.socionext.com with ESMTP; 01 Sep 2021 14:16:12 +0900 Received: from mail.mfilter.local (m-filter-1 [10.213.24.61]) by iyokan2-ex.css.socionext.com (Postfix) with ESMTP id C74A22022042; Wed, 1 Sep 2021 14:16:12 +0900 (JST) Received: from 172.31.9.51 (172.31.9.51) by m-FILTER with ESMTP; Wed, 1 Sep 2021 14:16:12 +0900 Received: from plum.e01.socionext.com (unknown [10.212.243.119]) by kinkan2.css.socionext.com (Postfix) with ESMTP id 2C317B62B7; Wed, 1 Sep 2021 14:16:12 +0900 (JST) From: Kunihiko Hayashi To: Jingoo Han , Gustavo Pimentel , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Bjorn Helgaas , Kishon Vijay Abraham I Cc: Xiaowei Bao , Om Prakash Singh , Vidya Sagar , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Kunihiko Hayashi Subject: [PATCH v2 2/2] PCI: designware-ep: Fix the access to DBI/iATU registers before enabling controller Date: Wed, 1 Sep 2021 14:16:01 +0900 Message-Id: <1630473361-27198-3-git-send-email-hayashi.kunihiko@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1630473361-27198-1-git-send-email-hayashi.kunihiko@socionext.com> References: <1630473361-27198-1-git-send-email-hayashi.kunihiko@socionext.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The driver using core_init_notifier, e.g. pcie-tegra194.c, runs according to the following sequence: probe() dw_pcie_ep_init() bind() dw_pcie_ep_start() enable_irq() (interrupt occurred) handler() [enable controller] dw_pcie_ep_init_complete() dw_pcie_ep_init_notify() After receiving an interrupt from RC, the handler enables the controller and the controller registers can be accessed. So accessing the registers should do in dw_pcie_ep_init_complete(). Currently dw_pcie_ep_init() has functions dw_iatu_detect() and dw_pcie_ep_find_capability() that include accesses to DWC registers. As a result, accessing the registers before enabling the controller, the access will fail. The function dw_pcie_ep_init() shouldn't have any access to DWC registers if the controller is enabled after calling bind(). This moves access codes to DBI/iATU registers and depending variables from dw_pcie_ep_init() to dw_pcie_ep_init_complete(). Cc: Xiaowei Bao Cc: Vidya Sagar Fixes: 6bfc9c3a2c70 ("PCI: designware-ep: Move the function of getting MSI capability forward") Signed-off-by: Kunihiko Hayashi Acked-by: Om Prakash Singh Reviewed-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-designware-ep.c | 81 +++++++++++++------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 998b698..00ce83c 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -636,16 +636,56 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + struct dw_pcie_ep_func *ep_func; + struct device *dev = pci->dev; unsigned int offset; unsigned int nbars; u8 hdr_type; + u8 func_no; + void *addr; u32 reg; int i; + dw_pcie_iatu_detect(pci); + + ep->ib_window_map = devm_kcalloc(dev, + BITS_TO_LONGS(pci->num_ib_windows), + sizeof(long), + GFP_KERNEL); + if (!ep->ib_window_map) + return -ENOMEM; + + ep->ob_window_map = devm_kcalloc(dev, + BITS_TO_LONGS(pci->num_ob_windows), + sizeof(long), + GFP_KERNEL); + if (!ep->ob_window_map) + return -ENOMEM; + + addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), + GFP_KERNEL); + if (!addr) + return -ENOMEM; + ep->outbound_addr = addr; + + for (func_no = 0; func_no < ep->epc->max_functions; func_no++) { + ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); + if (!ep_func) + return -ENOMEM; + + ep_func->func_no = func_no; + ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, + PCI_CAP_ID_MSI); + ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, + PCI_CAP_ID_MSIX); + + list_add_tail(&ep_func->list, &ep->func_list); + } + hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & PCI_HEADER_TYPE_MASK; if (hdr_type != PCI_HEADER_TYPE_NORMAL) { - dev_err(pci->dev, + dev_err(dev, "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n", hdr_type); return -EIO; @@ -674,8 +714,6 @@ EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete); int dw_pcie_ep_init(struct dw_pcie_ep *ep) { int ret; - void *addr; - u8 func_no; struct resource *res; struct pci_epc *epc; struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -683,7 +721,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) struct platform_device *pdev = to_platform_device(dev); struct device_node *np = dev->of_node; const struct pci_epc_features *epc_features; - struct dw_pcie_ep_func *ep_func; INIT_LIST_HEAD(&ep->func_list); @@ -705,8 +742,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) } } - dw_pcie_iatu_detect(pci); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); if (!res) return -EINVAL; @@ -714,26 +749,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) ep->phys_base = res->start; ep->addr_size = resource_size(res); - ep->ib_window_map = devm_kcalloc(dev, - BITS_TO_LONGS(pci->num_ib_windows), - sizeof(long), - GFP_KERNEL); - if (!ep->ib_window_map) - return -ENOMEM; - - ep->ob_window_map = devm_kcalloc(dev, - BITS_TO_LONGS(pci->num_ob_windows), - sizeof(long), - GFP_KERNEL); - if (!ep->ob_window_map) - return -ENOMEM; - - addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), - GFP_KERNEL); - if (!addr) - return -ENOMEM; - ep->outbound_addr = addr; - if (pci->link_gen < 1) pci->link_gen = of_pci_get_max_link_speed(np); @@ -750,20 +765,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) if (ret < 0) epc->max_functions = 1; - for (func_no = 0; func_no < epc->max_functions; func_no++) { - ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); - if (!ep_func) - return -ENOMEM; - - ep_func->func_no = func_no; - ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, - PCI_CAP_ID_MSI); - ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, - PCI_CAP_ID_MSIX); - - list_add_tail(&ep_func->list, &ep->func_list); - } - if (ep->ops->ep_init) ep->ops->ep_init(ep); -- 2.7.4