From patchwork Wed Mar 16 04:13:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4E6B9C433EF for ; Wed, 16 Mar 2022 04:13:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346056AbiCPEPG (ORCPT ); Wed, 16 Mar 2022 00:15:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbiCPEPF (ORCPT ); Wed, 16 Mar 2022 00:15:05 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 434EF33E08; Tue, 15 Mar 2022 21:13:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404032; x=1678940032; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZSLItZAXJIG/eKpF4GSFE8mJ7y09/lI4y0O6QSK69Tg=; b=kmf6EyAh6k60nQmKzrzweu8oDwF+eMcFgH3TPHOuplKTV7GYW2X9/j6S 7NXXqFng6t0gNt1V9mBcGikoh3SLeM9wDqFTfEjaw9q145oJt5R1MeQPh MzcW06VyjkjSavOY0VyurHbCSsehz4ucAoJHLQcVNvGTCNuuf18XL1/3y Av6WZuAvVCzHTRos3ntRgcgEqFQpNk+LcZ29FuBXtjMfUzeI49vvkBD3z jFkjpUC8t/eUu9QhqFHSr20thR6TKw2YrsGJYV2ztwGeBeMO0cx9mLMRP +WymQPeBM1LqvMDCPjn0cMUqRnnGhrC51q0/ji5tQ4KfUReJNMlnT/gDj g==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="255318968" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="255318968" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:47 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="580767820" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:47 -0700 Subject: [PATCH 1/8] cxl/pci: Cleanup repeated code in cxl_probe_regs() helpers From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:13:47 -0700 Message-ID: <164740402774.3912056.671750814250190348.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Rather then duplicating the setting of valid, length, and offset for each type, just convey a pointer to the register map to common code. Yes, the equivalent change in cxl_probe_component_regs() does not save any lines of code, but it is preparation for adding another component register type to map (RAS Capability Strucutre). Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/core/regs.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index 39a129c57d40..bd6ae14b679e 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -59,36 +59,41 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, for (cap = 1; cap <= cap_count; cap++) { void __iomem *register_block; - u32 hdr; - int decoder_cnt; + struct cxl_reg_map *rmap; u16 cap_id, offset; - u32 length; + u32 length, hdr; hdr = readl(base + cap * 0x4); cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr); offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr); register_block = base + offset; + hdr = readl(register_block); + rmap = NULL; switch (cap_id) { - case CXL_CM_CAP_CAP_ID_HDM: + case CXL_CM_CAP_CAP_ID_HDM: { + int decoder_cnt; + dev_dbg(dev, "found HDM decoder capability (0x%x)\n", offset); - hdr = readl(register_block); - decoder_cnt = cxl_hdm_decoder_count(hdr); length = 0x20 * decoder_cnt + 0x10; - - map->hdm_decoder.valid = true; - map->hdm_decoder.offset = CXL_CM_OFFSET + offset; - map->hdm_decoder.size = length; + rmap = &map->hdm_decoder; break; + } default: dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, offset); break; } + + if (!rmap) + continue; + rmap->valid = true; + rmap->offset = CXL_CM_OFFSET + offset; + rmap->size = length; } } EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL); @@ -117,6 +122,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array); for (cap = 1; cap <= cap_count; cap++) { + struct cxl_reg_map *rmap; u32 offset, length; u16 cap_id; @@ -125,28 +131,22 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, offset = readl(base + cap * 0x10 + 0x4); length = readl(base + cap * 0x10 + 0x8); + rmap = NULL; switch (cap_id) { case CXLDEV_CAP_CAP_ID_DEVICE_STATUS: dev_dbg(dev, "found Status capability (0x%x)\n", offset); - - map->status.valid = true; - map->status.offset = offset; - map->status.size = length; + rmap = &map->status; break; case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX: dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset); - map->mbox.valid = true; - map->mbox.offset = offset; - map->mbox.size = length; + rmap = &map->mbox; break; case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX: dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset); break; case CXLDEV_CAP_CAP_ID_MEMDEV: dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); - map->memdev.valid = true; - map->memdev.offset = offset; - map->memdev.size = length; + rmap = &map->memdev; break; default: if (cap_id >= 0x8000) @@ -155,6 +155,12 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset); break; } + + if (!rmap) + continue; + rmap->valid = true; + rmap->offset = offset; + rmap->size = length; } } EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, CXL); From patchwork Wed Mar 16 04:13:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782204 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0AA6C433F5 for ; Wed, 16 Mar 2022 04:13:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229437AbiCPEPI (ORCPT ); Wed, 16 Mar 2022 00:15:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347719AbiCPEPG (ORCPT ); Wed, 16 Mar 2022 00:15:06 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 60B32340C7; Tue, 15 Mar 2022 21:13:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404033; x=1678940033; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=53vzMOHjErR4dbS2Kgy3GzvXTkOvQUidDmgDE3n4p1k=; b=HuAShqTxWyqHtXyZXH7WbLSoBoXWwQVAkEQl9acELMHLf9FsjGr28r0P zfAmzcf2mcnYP6BAhdEEeDvjMBCgcvkSKCo/UEiVMc5L4S6g10nr/PVa0 wfibZpkOrzbDrLWarRxM7YGPs389aO6YguQKXiTzOtSmu6uL6tJ9pqoCB YPhbqxqubuLrRywZcr8OCcjSYygRtGBrvS9CUK47iVRNatdYT+91s1HcK Rn1ogkK/gzBd5U/vFDgiQ3qxuNTFpgcIJI7Gs9Wf9SdY0ZYNSmVnxqD63 kvXg4/IuPwB3IKooX4KQKrPOKxtQ+huyaM/EsFrh+kj9qYfGduu5hJPph Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="238655216" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="238655216" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:52 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="516166395" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:52 -0700 Subject: [PATCH 2/8] cxl/pci: Cleanup cxl_map_device_regs() From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:13:52 -0700 Message-ID: <164740403286.3912056.2514975283929305856.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Use a loop to reduce the duplicated code in cxl_map_device_regs(). This is in preparation for deleting cxl_map_regs(). Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/core/regs.c | 51 ++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index bd6ae14b679e..bd766e461f7d 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -211,42 +211,31 @@ int cxl_map_device_regs(struct pci_dev *pdev, struct cxl_device_regs *regs, struct cxl_register_map *map) { + resource_size_t phys_addr = + pci_resource_start(pdev, map->barno) + map->block_offset; struct device *dev = &pdev->dev; - resource_size_t phys_addr; - - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - - if (map->device_map.status.valid) { - resource_size_t addr; + struct mapinfo { + struct cxl_reg_map *rmap; + void __iomem **addr; + } mapinfo[] = { + { .rmap = &map->device_map.status, ®s->status, }, + { .rmap = &map->device_map.mbox, ®s->mbox, }, + { .rmap = &map->device_map.memdev, ®s->memdev, }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(mapinfo); i++) { + struct mapinfo *mi = &mapinfo[i]; resource_size_t length; - - addr = phys_addr + map->device_map.status.offset; - length = map->device_map.status.size; - regs->status = devm_cxl_iomap_block(dev, addr, length); - if (!regs->status) - return -ENOMEM; - } - - if (map->device_map.mbox.valid) { resource_size_t addr; - resource_size_t length; - addr = phys_addr + map->device_map.mbox.offset; - length = map->device_map.mbox.size; - regs->mbox = devm_cxl_iomap_block(dev, addr, length); - if (!regs->mbox) - return -ENOMEM; - } - - if (map->device_map.memdev.valid) { - resource_size_t addr; - resource_size_t length; + if (!mi->rmap->valid) + continue; - addr = phys_addr + map->device_map.memdev.offset; - length = map->device_map.memdev.size; - regs->memdev = devm_cxl_iomap_block(dev, addr, length); - if (!regs->memdev) + addr = phys_addr + mi->rmap->offset; + length = mi->rmap->size; + *(mi->addr) = devm_cxl_iomap_block(dev, addr, length); + if (!*(mi->addr)) return -ENOMEM; } From patchwork Wed Mar 16 04:13:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D77DC433F5 for ; Wed, 16 Mar 2022 04:14:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347719AbiCPEPN (ORCPT ); Wed, 16 Mar 2022 00:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350184AbiCPEPL (ORCPT ); Wed, 16 Mar 2022 00:15:11 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B14B734662; Tue, 15 Mar 2022 21:13:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404038; x=1678940038; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=S6z3Dqt2+Gnw13+ORdVS1nQd9F97flyxW1Nnt/toTGE=; b=adtfe+3DHW0a8f7EfYTkUk7TMMrVylwUHPmbqgj2Y42hPSLu5jApVs1p po/nnn++TFlL9qEX9KlU5QdGXdsL7yQf5ftu5PvKPuB4tH3drGlHsieWf 9CwTE8a8yR665w9Foluq+qV8aFrj2Bucn6NwMnmEkMbOfdFDCC5maYhEd tc3kttxBnLjN7P9QykDfhhGQiNRvpYllEJUZ/vTuZYNLKiXbbKn9j2uhb BdMLgG0hZ+peAFT2uJmmScm6c76aMUoldGSCk40ObW+E7U/JgCFQrDoVg Ng7pCB/dY1xNmu32YW2aYlrrr17yMlHAOfoNOHHhaQwIzX/W0H9ncHdsZ Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="281265839" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="281265839" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:58 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="644514748" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:13:58 -0700 Subject: [PATCH 3/8] cxl/pci: Kill cxl_map_regs() From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:13:58 -0700 Message-ID: <164740403796.3912056.13648238900454640514.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org The component registers are currently unused by the cxl_pci driver. Only the physical address base of the component registers is conveyed to the cxl_mem driver. Just call cxl_map_device_registers() directly. Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/pci.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 994c79bf6afd..0efbb356cce0 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -346,27 +346,6 @@ static int cxl_probe_regs(struct pci_dev *pdev, struct cxl_register_map *map) return 0; } -static int cxl_map_regs(struct cxl_dev_state *cxlds, struct cxl_register_map *map) -{ - struct device *dev = cxlds->dev; - struct pci_dev *pdev = to_pci_dev(dev); - - switch (map->reg_type) { - case CXL_REGLOC_RBI_COMPONENT: - cxl_map_component_regs(pdev, &cxlds->regs.component, map); - dev_dbg(dev, "Mapping component registers...\n"); - break; - case CXL_REGLOC_RBI_MEMDEV: - cxl_map_device_regs(pdev, &cxlds->regs.device_regs, map); - dev_dbg(dev, "Probing device registers...\n"); - break; - default: - break; - } - - return 0; -} - static int cxl_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, struct cxl_register_map *map) { @@ -599,7 +578,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; - rc = cxl_map_regs(cxlds, &map); + rc = cxl_map_device_regs(pdev, &cxlds->regs.device_regs, &map); if (rc) return rc; From patchwork Wed Mar 16 04:14:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782206 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7321AC433EF for ; Wed, 16 Mar 2022 04:14:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353087AbiCPEPT (ORCPT ); Wed, 16 Mar 2022 00:15:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41738 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351002AbiCPEPR (ORCPT ); Wed, 16 Mar 2022 00:15:17 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA9F7377D3; Tue, 15 Mar 2022 21:14:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404043; x=1678940043; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Sns9k7wMRPSY7JIEE8x0RCbNWk+l17I1Ts8Q2U1zk+8=; b=DYqso2jAycB53MITGEvzw+lOvo4+HrYH6kAR9Dzh7pECCAf/mbKhHxxa 8SlnW+rF176Scg652ATrljqNtH2osRsI9vMU7siQyWhh7RSJL6LlIvkO1 RKNkmUF20wF6MRqr+T1v8e1JAOzUFkkRWlnNb79pFizuPDRLD1EDs1sCK eyNrOnzmPQJDHVQBMcIxQpEYVkQq2KSwQXpJrAdrdfVOfXOsNeO2p2Hyi ytfj0MBW/JeOn3NznH+iynyXFKCvP2xuvKoyNXm2+/EDpira99IU0hmol /PWfKg7eqr35/4ulLpZFGKjEhI0MvejPKy0wPvV1FwT+uM9R/BzE7H87I w==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="281265847" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="281265847" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:03 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="580767870" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:03 -0700 Subject: [PATCH 4/8] cxl/core/regs: Make cxl_map_{component, device}_regs() device generic From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:14:03 -0700 Message-ID: <164740404348.3912056.9598057996803947688.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org There is no need to carry the barno and the block offset through the stack, just convert them to a resource base immediately. Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/core/pci.c | 3 +-- drivers/cxl/core/port.c | 2 +- drivers/cxl/core/regs.c | 40 +++++++++++++++++++++++----------------- drivers/cxl/cxl.h | 12 ++++++------ drivers/cxl/cxlpci.h | 9 --------- drivers/cxl/pci.c | 25 ++++++------------------- 6 files changed, 37 insertions(+), 54 deletions(-) diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index c9a494d6976a..6e9ad9933dd4 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -46,8 +46,7 @@ static int match_add_dports(struct pci_dev *pdev, void *data) dev_dbg(&port->dev, "failed to find component registers\n"); port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); - dport = devm_cxl_add_dport(port, &pdev->dev, port_num, - cxl_regmap_to_base(pdev, &map)); + dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource); if (IS_ERR(dport)) { ctx->error = PTR_ERR(dport); return PTR_ERR(dport); diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index c1681248f322..2cf27e71d8af 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -972,7 +972,7 @@ static resource_size_t find_component_registers(struct device *dev) pdev = to_pci_dev(dev); cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); - return cxl_regmap_to_base(pdev, &map); + return map.resource; } static int add_port_attach_ep(struct cxl_memdev *cxlmd, diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index bd766e461f7d..219c7d0e43e2 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -186,17 +186,13 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, return ret_val; } -int cxl_map_component_regs(struct pci_dev *pdev, - struct cxl_component_regs *regs, +int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, struct cxl_register_map *map) { - struct device *dev = &pdev->dev; resource_size_t phys_addr; resource_size_t length; - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - + phys_addr = map->resource; phys_addr += map->component_map.hdm_decoder.offset; length = map->component_map.hdm_decoder.size; regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); @@ -207,13 +203,11 @@ int cxl_map_component_regs(struct pci_dev *pdev, } EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL); -int cxl_map_device_regs(struct pci_dev *pdev, +int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs, struct cxl_register_map *map) { - resource_size_t phys_addr = - pci_resource_start(pdev, map->barno) + map->block_offset; - struct device *dev = &pdev->dev; + resource_size_t phys_addr = map->resource; struct mapinfo { struct cxl_reg_map *rmap; void __iomem **addr; @@ -243,13 +237,24 @@ int cxl_map_device_regs(struct pci_dev *pdev, } EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL); -static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi, +static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi, struct cxl_register_map *map) { - map->block_offset = ((u64)reg_hi << 32) | - (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK); - map->barno = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo); + int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo); + u64 offset = ((u64)reg_hi << 32) | + (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK); + + if (offset > pci_resource_len(pdev, bar)) { + dev_warn(&pdev->dev, + "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar, + &pdev->resource[bar], &offset, map->reg_type); + return false; + } + map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo); + map->resource = pci_resource_start(pdev, bar) + offset; + map->max_size = pci_resource_len(pdev, bar) - offset; + return true; } /** @@ -269,7 +274,7 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, u32 regloc_size, regblocks; int regloc, i; - map->block_offset = U64_MAX; + map->resource = CXL_RESOURCE_NONE; regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL, CXL_DVSEC_REG_LOCATOR); if (!regloc) @@ -287,13 +292,14 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, pci_read_config_dword(pdev, regloc, ®_lo); pci_read_config_dword(pdev, regloc + 4, ®_hi); - cxl_decode_regblock(reg_lo, reg_hi, map); + if (!cxl_decode_regblock(pdev, reg_lo, reg_hi, map)) + continue; if (map->reg_type == type) return 0; } - map->block_offset = U64_MAX; + map->resource = CXL_RESOURCE_NONE; return -ENODEV; } EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 990b6670222e..2080a75c61fe 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -132,17 +132,17 @@ struct cxl_device_reg_map { /** * struct cxl_register_map - DVSEC harvested register block mapping parameters * @base: virtual base of the register-block-BAR + @block_offset - * @block_offset: offset to start of register block in @barno + * @resource: physical resource base of the register block + * @max_size: maximum mapping size to perform register search * @reg_type: see enum cxl_regloc_type - * @barno: PCI BAR number containing the register block * @component_map: cxl_reg_map for component registers * @device_map: cxl_reg_maps for device registers */ struct cxl_register_map { void __iomem *base; - u64 block_offset; + resource_size_t resource; + resource_size_t max_size; u8 reg_type; - u8 barno; union { struct cxl_component_reg_map component_map; struct cxl_device_reg_map device_map; @@ -153,10 +153,10 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, struct cxl_component_reg_map *map); void cxl_probe_device_regs(struct device *dev, void __iomem *base, struct cxl_device_reg_map *map); -int cxl_map_component_regs(struct pci_dev *pdev, +int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, struct cxl_register_map *map); -int cxl_map_device_regs(struct pci_dev *pdev, +int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs, struct cxl_register_map *map); diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h index 329e7ea3f36a..3c5be664ab22 100644 --- a/drivers/cxl/cxlpci.h +++ b/drivers/cxl/cxlpci.h @@ -62,14 +62,5 @@ enum cxl_regloc_type { CXL_REGLOC_RBI_TYPES }; -static inline resource_size_t cxl_regmap_to_base(struct pci_dev *pdev, - struct cxl_register_map *map) -{ - if (map->block_offset == U64_MAX) - return CXL_RESOURCE_NONE; - - return pci_resource_start(pdev, map->barno) + map->block_offset; -} - int devm_cxl_port_enumerate_dports(struct cxl_port *port); #endif /* __CXL_PCI_H__ */ diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 0efbb356cce0..d8361331a013 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -275,35 +275,22 @@ static int cxl_pci_setup_mailbox(struct cxl_dev_state *cxlds) static int cxl_map_regblock(struct pci_dev *pdev, struct cxl_register_map *map) { - void __iomem *addr; - int bar = map->barno; struct device *dev = &pdev->dev; - resource_size_t offset = map->block_offset; - /* Basic sanity check that BAR is big enough */ - if (pci_resource_len(pdev, bar) < offset) { - dev_err(dev, "BAR%d: %pr: too small (offset: %pa)\n", bar, - &pdev->resource[bar], &offset); - return -ENXIO; - } - - addr = pci_iomap(pdev, bar, 0); - if (!addr) { + map->base = ioremap(map->resource, map->max_size); + if (!map->base) { dev_err(dev, "failed to map registers\n"); return -ENOMEM; } - dev_dbg(dev, "Mapped CXL Memory Device resource bar %u @ %pa\n", - bar, &offset); - - map->base = addr + map->block_offset; + dev_dbg(dev, "Mapped CXL Memory Device resource %pa\n", &map->resource); return 0; } static void cxl_unmap_regblock(struct pci_dev *pdev, struct cxl_register_map *map) { - pci_iounmap(pdev, map->base - map->block_offset); + iounmap(map->base); map->base = NULL; } @@ -578,7 +565,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; - rc = cxl_map_device_regs(pdev, &cxlds->regs.device_regs, &map); + rc = cxl_map_device_regs(&pdev->dev, &cxlds->regs.device_regs, &map); if (rc) return rc; @@ -591,7 +578,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) dev_warn(&pdev->dev, "No component registers (%d)\n", rc); - cxlds->component_reg_phys = cxl_regmap_to_base(pdev, &map); + cxlds->component_reg_phys = map.resource; rc = cxl_pci_setup_mailbox(cxlds); if (rc) From patchwork Wed Mar 16 04:14:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3723C433FE for ; Wed, 16 Mar 2022 04:14:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349427AbiCPEP0 (ORCPT ); Wed, 16 Mar 2022 00:15:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350184AbiCPEPY (ORCPT ); Wed, 16 Mar 2022 00:15:24 -0400 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89F18381A9; Tue, 15 Mar 2022 21:14:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404049; x=1678940049; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=imNb4z4rg9GqdaDPmtK5BMT2j1lOS6RZnBaSZaxPfCU=; b=RIqewtxlFJN7qdTU5lRQ4lXWYW04/bkvCeJWh66WTXcYSnbtKlcOzgoB ByeaMEbcnNXcw+SvP2rvesBeCHG8+yltDqi164VRgeW8sHw3cWWPP6RHB 1q9ISFyfX+1PVdDhqwF3/vE8h/+WGAS1rrgKSfkDX4okzUPSLywTwdlsn GxFoIXB6SaIdrECA7U4pSWo5QKW4VnFy3hJ+L/r8w3zZV+HUyoTj4pYeR W38qQ/fbIeJNlvAgnbNQ/GT/Jn0D9AcdufBjUrZ1E9XMzCCYAdO8FdWjs +Pya4Bfyb7SNAgfFkI8FYSQQ9NvJNnSzg0uF9fXv4qqnl4yPR2B+m1hoo Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="317210081" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="317210081" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:09 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="598559918" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:08 -0700 Subject: [PATCH 5/8] cxl/port: Limit the port driver to just the HDM Decoder Capability From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:14:08 -0700 Message-ID: <164740404858.3912056.13421993054614655037.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Update the port driver to use cxl_map_component_registers() so that the component register block can be shared between the cxl_pci driver and the cxl_port driver. I.e. stop the port driver from reserving the entire component register block for itself via request_region() when it only needs the HDM Decoder Capability subset. Signed-off-by: Dan Williams --- drivers/cxl/core/hdm.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index 0e89a7a932d4..09221afca309 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -77,18 +77,22 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm) cxlhdm->interleave_mask |= GENMASK(14, 12); } -static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, - void __iomem *crb) +static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, + struct cxl_component_regs *regs) { - struct cxl_component_reg_map map; + struct cxl_register_map map = { + .resource = port->component_reg_phys, + .base = crb, + .max_size = CXL_COMPONENT_REG_BLOCK_SIZE, + }; - cxl_probe_component_regs(&port->dev, crb, &map); - if (!map.hdm_decoder.valid) { + cxl_probe_component_regs(&port->dev, crb, &map.component_map); + if (!map.component_map.hdm_decoder.valid) { dev_err(&port->dev, "HDM decoder registers invalid\n"); - return IOMEM_ERR_PTR(-ENXIO); + return -ENXIO; } - return crb + map.hdm_decoder.offset; + return cxl_map_component_regs(&port->dev, regs, &map); } /** @@ -98,25 +102,25 @@ static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) { struct device *dev = &port->dev; - void __iomem *crb, *hdm; struct cxl_hdm *cxlhdm; + void __iomem *crb; + int rc; cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL); if (!cxlhdm) return ERR_PTR(-ENOMEM); cxlhdm->port = port; - crb = devm_cxl_iomap_block(dev, port->component_reg_phys, - CXL_COMPONENT_REG_BLOCK_SIZE); + crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE); if (!crb) { dev_err(dev, "No component registers mapped\n"); return ERR_PTR(-ENXIO); } - hdm = map_hdm_decoder_regs(port, crb); - if (IS_ERR(hdm)) - return ERR_CAST(hdm); - cxlhdm->regs.hdm_decoder = hdm; + rc = map_hdm_decoder_regs(port, crb, &cxlhdm->regs); + iounmap(crb); + if (rc) + return ERR_PTR(rc); parse_hdm_decoder_caps(cxlhdm); if (cxlhdm->decoder_count == 0) { From patchwork Wed Mar 16 04:14:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782212 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E65A8C433EF for ; Wed, 16 Mar 2022 04:14:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351002AbiCPEP3 (ORCPT ); Wed, 16 Mar 2022 00:15:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350184AbiCPEP2 (ORCPT ); Wed, 16 Mar 2022 00:15:28 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95D55381BC; Tue, 15 Mar 2022 21:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404054; x=1678940054; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Qe7YZzcyp/5v/goFi6W6IFF5j3H8Us8oUewaVXaJVLQ=; b=U8aqQqc+Bvny+KYK+cvB808ZE3rOOzBCHsNGJYNHteeeM0tU0FJN97sr Q/li/zbP6kYPG3gfE8YfgPqG1a8KXbMq8FsLK6woVb8R2uLcR+tIpJPpP o5rIdXmSMV9CKZBtq+pPrjra4fQFCQAmxT0vkP2C3EKxXoA/fRiKHFaRi PJoPa9zMV7aIHy7ikpJ4Yc3T/h1qDumOuBkNc/dVhKZYx1eH5Q2vU/pvI AB/RSjV1Df4t2osGLoQ2htfCKdysc8TsuIx2O4sIZ9BvuTBEjrkOhx5wP 4UnM3Ds7ymCgGE6Wxor0fC88JjLaWieeCGNhCPhq1v3bg8Ku9BZFm4pxf A==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="256678743" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="256678743" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:14 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="540739843" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:14 -0700 Subject: [PATCH 6/8] cxl/pci: Prepare for mapping RAS Capability Structure From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:14:14 -0700 Message-ID: <164740405408.3912056.16337643017370667205.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org The RAS Capabilitiy Structure is a CXL Component register capability block. Unlike the HDM Decoder Capability, it will be referenced by the cxl_pci driver in response to PCIe AER events. Due to this it is no longer the case that cxl_map_component_regs() can assume that it should map all component registers. Plumb a bitmask of capability ids to map through cxl_map_component_regs(). For symmetry cxl_probe_device_regs() is updated to populate @id in 'struct cxl_reg_map' even though cxl_map_device_regs() does not have a need to map a subset of the device registers per caller. Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/core/hdm.c | 3 ++- drivers/cxl/core/regs.c | 36 ++++++++++++++++++++++++++---------- drivers/cxl/cxl.h | 7 ++++--- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index 09221afca309..b348217ab704 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -92,7 +92,8 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, return -ENXIO; } - return cxl_map_component_regs(&port->dev, regs, &map); + return cxl_map_component_regs(&port->dev, regs, &map, + BIT(CXL_CM_CAP_CAP_ID_HDM)); } /** diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index 219c7d0e43e2..c022c8937dfc 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -92,6 +92,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, if (!rmap) continue; rmap->valid = true; + rmap->id = cap_id; rmap->offset = CXL_CM_OFFSET + offset; rmap->size = length; } @@ -159,6 +160,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, if (!rmap) continue; rmap->valid = true; + rmap->id = cap_id; rmap->offset = offset; rmap->size = length; } @@ -187,17 +189,31 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, } int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, - struct cxl_register_map *map) + struct cxl_register_map *map, unsigned long map_mask) { - resource_size_t phys_addr; - resource_size_t length; - - phys_addr = map->resource; - phys_addr += map->component_map.hdm_decoder.offset; - length = map->component_map.hdm_decoder.size; - regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); - if (!regs->hdm_decoder) - return -ENOMEM; + struct mapinfo { + struct cxl_reg_map *rmap; + void __iomem **addr; + } mapinfo[] = { + { .rmap = &map->component_map.hdm_decoder, ®s->hdm_decoder }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(mapinfo); i++) { + struct mapinfo *mi = &mapinfo[i]; + resource_size_t phys_addr; + resource_size_t length; + + if (!mi->rmap->valid) + continue; + if (!test_bit(mi->rmap->id, &map_mask)) + continue; + phys_addr = map->resource + mi->rmap->offset; + length = mi->rmap->size; + *(mi->addr) = devm_cxl_iomap_block(dev, phys_addr, length); + if (!*(mi->addr)) + return -ENOMEM; + } return 0; } diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 2080a75c61fe..52bd77d8e22a 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -115,6 +115,7 @@ struct cxl_regs { struct cxl_reg_map { bool valid; + int id; unsigned long offset; unsigned long size; }; @@ -153,9 +154,9 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, struct cxl_component_reg_map *map); void cxl_probe_device_regs(struct device *dev, void __iomem *base, struct cxl_device_reg_map *map); -int cxl_map_component_regs(struct device *dev, - struct cxl_component_regs *regs, - struct cxl_register_map *map); +int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, + struct cxl_register_map *map, + unsigned long map_mask); int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs, struct cxl_register_map *map); From patchwork Wed Mar 16 04:14:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FDD4C433F5 for ; Wed, 16 Mar 2022 04:14:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350184AbiCPEPg (ORCPT ); Wed, 16 Mar 2022 00:15:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353477AbiCPEPe (ORCPT ); Wed, 16 Mar 2022 00:15:34 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15C1C47045; Tue, 15 Mar 2022 21:14:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404060; x=1678940060; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RgvwNLJ5RGE63N7kLq/0oqLCZvNK+5TbxTMBDlodL0Y=; b=GZjZ7DQYGjcSNS8VKSp+YdNjL3QZZKHGIFPm6/DgRBNLWXwNYDJa1/7p 3ccFJHdjvgUKRoMqGk4pNVU6dvswocmxow4264aLQ+ybA7j4tWfxtHK7V q9Dn6X017w+Pg3pehsQBogG2XPHN1ddIt50nCDKcKtAIt33noY3BmB5An eeutrVWh0q4FJxvaR5qQecIcU9dLXeTLtGpYvLrhlDgpbwcAFh5Or8GiQ 7XWe/+5fBoq3NBCmapevnyIiL3lw85/l2zqJxVNZCd2cXWCtx/v9ErGGj fwwNX9TFY8TAzrf7mnfjOQk2yusn1s4e0hNjn6UNddV3aXMEJmWpT6Jv2 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="342918431" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="342918431" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:19 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="549842148" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:19 -0700 Subject: [PATCH 7/8] cxl/pci: Find and map the RAS Capability Structure From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:14:19 -0700 Message-ID: <164740405921.3912056.7575762163944798747.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org The RAS Capability Structure has some ancillary information that may be relevant with respect to AER events, link and protcol error status registers. Map the RAS Capability Registers in support of defining a 'struct pci_error_handlers' instance for the cxl_pci driver. Signed-off-by: Dan Williams Reviewed-by: Jonathan Cameron --- drivers/cxl/core/regs.c | 7 +++++++ drivers/cxl/cxl.h | 19 +++++++++++++++++++ drivers/cxl/pci.c | 8 ++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index c022c8937dfc..53aac68b9ce4 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -83,6 +83,12 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, rmap = &map->hdm_decoder; break; } + case CXL_CM_CAP_CAP_ID_RAS: + dev_dbg(dev, "found RAS capability (0x%x)\n", + offset); + length = CXL_RAS_CAPABILITY_LENGTH; + rmap = &map->ras; + break; default: dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, offset); @@ -196,6 +202,7 @@ int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs, void __iomem **addr; } mapinfo[] = { { .rmap = &map->component_map.hdm_decoder, ®s->hdm_decoder }, + { .rmap = &map->component_map.ras, ®s->ras }, }; int i; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 52bd77d8e22a..cf3d8d0aaf22 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -32,6 +32,7 @@ #define CXL_CM_CAP_HDR_ARRAY_SIZE_MASK GENMASK(31, 24) #define CXL_CM_CAP_PTR_MASK GENMASK(31, 20) +#define CXL_CM_CAP_CAP_ID_RAS 0x2 #define CXL_CM_CAP_CAP_ID_HDM 0x5 #define CXL_CM_CAP_CAP_HDM_VERSION 1 @@ -64,6 +65,21 @@ static inline int cxl_hdm_decoder_count(u32 cap_hdr) return val ? val * 2 : 1; } +/* RAS Registers CXL 2.0 8.2.5.9 CXL RAS Capability Structure */ +#define CXL_RAS_UNCORRECTABLE_STATUS_OFFSET 0x0 +#define CXL_RAS_UNCORRECTABLE_STATUS_MASK (GENMASK(16, 14) | GENMASK(11, 0)) +#define CXL_RAS_UNCORRECTABLE_MASK_OFFSET 0x4 +#define CXL_RAS_UNCORRECTABLE_MASK_MASK (GENMASK(16, 14) | GENMASK(11, 0)) +#define CXL_RAS_UNCORRECTABLE_SEVERITY_OFFSET 0x8 +#define CXL_RAS_UNCORRECTABLE_SEVERITY_MASK (GENMASK(16, 14) | GENMASK(11, 0)) +#define CXL_RAS_CORRECTABLE_STATUS_OFFSET 0xC +#define CXL_RAS_CORRECTABLE_STATUS_MASK GENMASK(6, 0) +#define CXL_RAS_CORRECTABLE_MASK_OFFSET 0x10 +#define CXL_RAS_CORRECTABLE_MASK_MASK GENMASK(6, 0) +#define CXL_RAS_CAP_CONTROL_OFFSET 0x14 +#define CXL_RAS_HEADER_LOG_OFFSET 0x18 +#define CXL_RAS_CAPABILITY_LENGTH 0x58 + /* CXL 2.0 8.2.8.1 Device Capabilities Array Register */ #define CXLDEV_CAP_ARRAY_OFFSET 0x0 #define CXLDEV_CAP_ARRAY_CAP_ID 0 @@ -98,9 +114,11 @@ struct cxl_regs { /* * Common set of CXL Component register block base pointers * @hdm_decoder: CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure + * @ras: CXL 2.0 8.2.5.9 CXL RAS Capability Structure */ struct_group_tagged(cxl_component_regs, component, void __iomem *hdm_decoder; + void __iomem *ras; ); /* * Common set of CXL Device register block base pointers @@ -122,6 +140,7 @@ struct cxl_reg_map { struct cxl_component_reg_map { struct cxl_reg_map hdm_decoder; + struct cxl_reg_map ras; }; struct cxl_device_reg_map { diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index d8361331a013..bde8929450f0 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -310,6 +310,9 @@ static int cxl_probe_regs(struct pci_dev *pdev, struct cxl_register_map *map) return -ENXIO; } + if (!comp_map->ras.valid) + dev_dbg(dev, "RAS registers not found\n"); + dev_dbg(dev, "Set up component registers\n"); break; case CXL_REGLOC_RBI_MEMDEV: @@ -580,6 +583,11 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) cxlds->component_reg_phys = map.resource; + rc = cxl_map_component_regs(&pdev->dev, &cxlds->regs.component, + &map, BIT(CXL_CM_CAP_CAP_ID_RAS)); + if (rc) + dev_dbg(&pdev->dev, "Failed to map RAS capability.\n"); + rc = cxl_pci_setup_mailbox(cxlds); if (rc) return rc; From patchwork Wed Mar 16 04:14:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12782214 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72154C433EF for ; Wed, 16 Mar 2022 04:14:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353509AbiCPEPk (ORCPT ); Wed, 16 Mar 2022 00:15:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353508AbiCPEPj (ORCPT ); Wed, 16 Mar 2022 00:15:39 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A35BB4B1D5; Tue, 15 Mar 2022 21:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647404065; x=1678940065; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XFiGcPS1f/T7+aDldvpmz0ApwwO2zws4MBb9vsb4Vi0=; b=cuqReaVvVMd1KCZLBxdCTUGW7ZgTySYn72pqcA9cem4/ENTa+ViqPBF8 xTtOMR8wRO43UxAfznndVub4rbedjRTlwRXPOCDV4HMFshmDDcz03Be06 b+glgDUsQPUw+bTzrfSF40kZyFa0Yntgp1sVuYAqBFgDpdIMw+Zq6Avcd n6N5u30hRGVuFad0WFADtlrUudhAQQlMwsG4Lzf5wXyzULVAn/EpKPyn/ Rv05l0Ks06CiuqAM86psJWGxWZY2UncE1S/OAq4V3xBoaM+oyBE84l7Tq eh4uDF4W53EbNvHmxmiQbD+LwENwINwNAiiPr1RMQiQN6EJbbwHLyHbcW Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="256678782" X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="256678782" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:25 -0700 X-IronPort-AV: E=Sophos;i="5.90,185,1643702400"; d="scan'208";a="540739866" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 21:14:24 -0700 Subject: [PATCH 8/8] cxl/pci: Add (hopeful) error handling support From: Dan Williams To: linux-cxl@vger.kernel.org Cc: ben.widawsky@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, Jonathan.Cameron@huawei.com, ira.weiny@intel.com, linux-pci@vger.kernel.org Date: Tue, 15 Mar 2022 21:14:24 -0700 Message-ID: <164740406489.3912056.8334546166826246693.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Add nominal error handling that tears down CXL.mem in response to error notifications that imply a device reset. Given some CXL.mem may be operating as System RAM, there is a high likelihood that these error events are fatal. However, if the system survives the notification the expectation is that the driver behavior is equivalent to a hot-unplug and re-plug of an endpoint. Note that this does not change the mask values from the default. That awaits CXL _OSC support to determine whether platform firmware is in control of the mask registers. Signed-off-by: Dan Williams --- drivers/cxl/core/memdev.c | 1 drivers/cxl/cxlmem.h | 2 + drivers/cxl/pci.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 1f76b28f9826..223d512790e1 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -341,6 +341,7 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) * needed as this is ordered with cdev_add() publishing the device. */ cxlmd->cxlds = cxlds; + cxlds->cxlmd = cxlmd; cdev = &cxlmd->cdev; rc = cdev_device_add(cdev, dev); diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 5d33ce24fe09..f58e16951414 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -117,6 +117,7 @@ struct cxl_endpoint_dvsec_info { * Currently only memory devices are represented. * * @dev: The device associated with this CXL state + * @cxlmd: The device representing the CXL.mem capabilities of @dev * @regs: Parsed register blocks * @cxl_dvsec: Offset to the PCIe device DVSEC * @payload_size: Size of space for payload @@ -148,6 +149,7 @@ struct cxl_endpoint_dvsec_info { */ struct cxl_dev_state { struct device *dev; + struct cxl_memdev *cxlmd; struct cxl_regs regs; int cxl_dvsec; diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index bde8929450f0..823cbfa093fa 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "cxlmem.h" #include "cxlpci.h" @@ -533,6 +534,11 @@ static void cxl_dvsec_ranges(struct cxl_dev_state *cxlds) info->ranges = __cxl_dvsec_ranges(cxlds, info); } +static void disable_aer(void *pdev) +{ + pci_disable_pcie_error_reporting(pdev); +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct cxl_register_map map; @@ -554,6 +560,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) cxlds = cxl_dev_state_create(&pdev->dev); if (IS_ERR(cxlds)) return PTR_ERR(cxlds); + pci_set_drvdata(pdev, cxlds); cxlds->serial = pci_get_dsn(pdev); cxlds->cxl_dvsec = pci_find_dvsec_capability( @@ -610,6 +617,14 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); + if (cxlds->regs.ras) { + pci_enable_pcie_error_reporting(pdev); + rc = devm_add_action_or_reset(&pdev->dev, disable_aer, pdev); + if (rc) + return rc; + } + pci_save_state(pdev); + if (range_len(&cxlds->pmem_range) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(&pdev->dev, cxlmd); @@ -623,10 +638,104 @@ static const struct pci_device_id cxl_mem_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cxl_mem_pci_tbl); +/* + * Log the state of the RAS status registers and prepare them to log the + * next error status. + */ +static void cxl_report_and_clear(struct cxl_dev_state *cxlds) +{ + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *dev = &cxlmd->dev; + void __iomem *addr; + u32 status; + + if (!cxlds->regs.ras) + return; + + addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_STATUS_OFFSET; + status = readl(addr); + if (status & CXL_RAS_UNCORRECTABLE_STATUS_MASK) { + dev_warn(cxlds->dev, "%s: uncorrectable status: %#08x\n", + dev_name(dev), status); + writel(status & CXL_RAS_UNCORRECTABLE_STATUS_MASK, addr); + } + + addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_STATUS_OFFSET; + status = readl(addr); + if (status & CXL_RAS_CORRECTABLE_STATUS_MASK) { + dev_warn(cxlds->dev, "%s: correctable status: %#08x\n", + dev_name(dev), status); + writel(status & CXL_RAS_CORRECTABLE_STATUS_MASK, addr); + } +} + +static pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *dev = &cxlmd->dev; + + /* + * A frozen channel indicates an impending reset which is fatal to + * CXL.mem operation, and will likely crash the system. On the off + * chance the situation is recoverable dump the status of the RAS + * capability registers and bounce the active state of the memdev. + */ + cxl_report_and_clear(cxlds); + + switch (state) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; + case pci_channel_io_frozen: + dev_warn(&pdev->dev, + "%s: frozen state error detected, disable CXL.mem\n", + dev_name(dev)); + device_release_driver(dev); + return PCI_ERS_RESULT_NEED_RESET; + case pci_channel_io_perm_failure: + dev_warn(&pdev->dev, + "failure state error detected, request disconnect\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t cxl_slot_reset(struct pci_dev *pdev) +{ + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *dev = &cxlmd->dev; + + dev_info(&pdev->dev, "%s: restart CXL.mem after slot reset\n", + dev_name(dev)); + pci_restore_state(pdev); + if (device_attach(dev) <= 0) + return PCI_ERS_RESULT_DISCONNECT; + return PCI_ERS_RESULT_RECOVERED; +} + +static void cxl_error_resume(struct pci_dev *pdev) +{ + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *dev = &cxlmd->dev; + + dev_info(&pdev->dev, "%s: error resume %s\n", dev_name(dev), + dev->driver ? "successful" : "failed"); +} + +static const struct pci_error_handlers cxl_error_handlers = { + .error_detected = cxl_error_detected, + .slot_reset = cxl_slot_reset, + .resume = cxl_error_resume, +}; + static struct pci_driver cxl_pci_driver = { .name = KBUILD_MODNAME, .id_table = cxl_mem_pci_tbl, .probe = cxl_pci_probe, + .err_handler = &cxl_error_handlers, .driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, },