diff mbox series

[4/8] cxl/core: Refactor CXL register lookup for bridge reuse

Message ID 161662144627.1723715.7776509014834832493.stgit@dwillia2-desk3.amr.corp.intel.com
State New
Headers show
Series CXL Port Enumeration | expand

Commit Message

Dan Williams March 24, 2021, 9:30 p.m. UTC
While CXL Memory Device endpoints locate the CXL MMIO registers in a PCI
BAR, CXL root bridges have their MMIO base address described by platform
firmware. Refactor the existing register lookup into a generic facility
for endpoints and bridges to share.

Reviewed-by: Ben Widawsky <ben.widawsky@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/cxl/core.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/cxl/cxl.h  |    3 +++
 drivers/cxl/mem.c  |   50 +++++-----------------------------------------
 3 files changed, 65 insertions(+), 45 deletions(-)

Comments

kernel test robot March 26, 2021, 1:11 a.m. UTC | #1
Hi Dan,

I love your patch! Yet something to improve:

[auto build test ERROR on a38fd8748464831584a19438cbb3082b5a2dab15]

url:    https://github.com/0day-ci/linux/commits/Dan-Williams/CXL-Port-Enumeration/20210325-053311
base:   a38fd8748464831584a19438cbb3082b5a2dab15
config: arc-randconfig-r014-20210325 (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/efa27967ffcd67a6109c23987e76b9ed2e97ae27
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dan-Williams/CXL-Port-Enumeration/20210325-053311
        git checkout efa27967ffcd67a6109c23987e76b9ed2e97ae27
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/cxl/core.c: In function 'cxl_setup_device_regs':
>> drivers/cxl/core.c:27:14: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
      27 |  cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET);
         |              ^~~~~
         |              readb
   cc1: some warnings being treated as errors


vim +27 drivers/cxl/core.c

     6	
     7	/**
     8	 * DOC: cxl core
     9	 *
    10	 * The CXL core provides a sysfs hierarchy for control devices and a rendezvous
    11	 * point for cross-device interleave coordination through cxl ports.
    12	 */
    13	
    14	/*
    15	 * cxl_setup_device_regs() - Detect CXL Device register blocks
    16	 * @dev: Host device of the @base mapping
    17	 * @base: mapping of CXL 2.0 8.2.8 CXL Device Register Interface
    18	 */
    19	void cxl_setup_device_regs(struct device *dev, void __iomem *base,
    20				   struct cxl_device_regs *regs)
    21	{
    22		int cap, cap_count;
    23		u64 cap_array;
    24	
    25		*regs = (struct cxl_device_regs) { 0 };
    26	
  > 27		cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET);
    28		if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) !=
    29		    CXLDEV_CAP_ARRAY_CAP_ID)
    30			return;
    31	
    32		cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array);
    33	
    34		for (cap = 1; cap <= cap_count; cap++) {
    35			void __iomem *register_block;
    36			u32 offset;
    37			u16 cap_id;
    38	
    39			cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK,
    40					   readl(base + cap * 0x10));
    41			offset = readl(base + cap * 0x10 + 0x4);
    42			register_block = base + offset;
    43	
    44			switch (cap_id) {
    45			case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
    46				dev_dbg(dev, "found Status capability (0x%x)\n", offset);
    47				regs->status = register_block;
    48				break;
    49			case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
    50				dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
    51				regs->mbox = register_block;
    52				break;
    53			case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
    54				dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
    55				break;
    56			case CXLDEV_CAP_CAP_ID_MEMDEV:
    57				dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
    58				regs->memdev = register_block;
    59				break;
    60			default:
    61				dev_dbg(dev, "Unknown cap ID: %d (0x%x)\n", cap_id, offset);
    62				break;
    63			}
    64		}
    65	}
    66	EXPORT_SYMBOL_GPL(cxl_setup_device_regs);
    67	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/cxl/core.c b/drivers/cxl/core.c
index 7f8d2034038a..2ab467ef9909 100644
--- a/drivers/cxl/core.c
+++ b/drivers/cxl/core.c
@@ -1,7 +1,8 @@ 
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+/* Copyright(c) 2020-2021 Intel Corporation. All rights reserved. */
 #include <linux/device.h>
 #include <linux/module.h>
+#include "cxl.h"
 
 /**
  * DOC: cxl core
@@ -10,6 +11,60 @@ 
  * point for cross-device interleave coordination through cxl ports.
  */
 
+/*
+ * cxl_setup_device_regs() - Detect CXL Device register blocks
+ * @dev: Host device of the @base mapping
+ * @base: mapping of CXL 2.0 8.2.8 CXL Device Register Interface
+ */
+void cxl_setup_device_regs(struct device *dev, void __iomem *base,
+			   struct cxl_device_regs *regs)
+{
+	int cap, cap_count;
+	u64 cap_array;
+
+	*regs = (struct cxl_device_regs) { 0 };
+
+	cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET);
+	if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) !=
+	    CXLDEV_CAP_ARRAY_CAP_ID)
+		return;
+
+	cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array);
+
+	for (cap = 1; cap <= cap_count; cap++) {
+		void __iomem *register_block;
+		u32 offset;
+		u16 cap_id;
+
+		cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK,
+				   readl(base + cap * 0x10));
+		offset = readl(base + cap * 0x10 + 0x4);
+		register_block = base + offset;
+
+		switch (cap_id) {
+		case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
+			dev_dbg(dev, "found Status capability (0x%x)\n", offset);
+			regs->status = register_block;
+			break;
+		case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
+			dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
+			regs->mbox = register_block;
+			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);
+			regs->memdev = register_block;
+			break;
+		default:
+			dev_dbg(dev, "Unknown cap ID: %d (0x%x)\n", cap_id, offset);
+			break;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(cxl_setup_device_regs);
+
 struct bus_type cxl_bus_type = {
 	.name = "cxl",
 };
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 37325e504fb7..cbd29650c4e2 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -67,5 +67,8 @@  struct cxl_regs {
 	};
 };
 
+void cxl_setup_device_regs(struct device *dev, void __iomem *base,
+			   struct cxl_device_regs *regs);
+
 extern struct bus_type cxl_bus_type;
 #endif /* __CXL_H__ */
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 6951243d128e..ee55abfa147e 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -865,53 +865,15 @@  static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode,
 static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
 {
 	struct device *dev = &cxlm->pdev->dev;
-	int cap, cap_count;
-	u64 cap_array;
+	struct cxl_regs *regs = &cxlm->regs;
 
-	cap_array = readq(cxlm->base + CXLDEV_CAP_ARRAY_OFFSET);
-	if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) !=
-	    CXLDEV_CAP_ARRAY_CAP_ID)
-		return -ENODEV;
-
-	cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array);
-
-	for (cap = 1; cap <= cap_count; cap++) {
-		void __iomem *register_block;
-		u32 offset;
-		u16 cap_id;
-
-		cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK,
-				   readl(cxlm->base + cap * 0x10));
-		offset = readl(cxlm->base + cap * 0x10 + 0x4);
-		register_block = cxlm->base + offset;
-
-		switch (cap_id) {
-		case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
-			dev_dbg(dev, "found Status capability (0x%x)\n", offset);
-			cxlm->regs.status = register_block;
-			break;
-		case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
-			dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
-			cxlm->regs.mbox = register_block;
-			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);
-			cxlm->regs.memdev = register_block;
-			break;
-		default:
-			dev_dbg(dev, "Unknown cap ID: %d (0x%x)\n", cap_id, offset);
-			break;
-		}
-	}
+	cxl_setup_device_regs(dev, cxlm->base, &regs->device_regs);
 
-	if (!cxlm->regs.status || !cxlm->regs.mbox || !cxlm->regs.memdev) {
+	if (!regs->status || !regs->mbox || !regs->memdev) {
 		dev_err(dev, "registers not found: %s%s%s\n",
-			!cxlm->regs.status ? "status " : "",
-			!cxlm->regs.mbox ? "mbox " : "",
-			!cxlm->regs.memdev ? "memdev" : "");
+			!regs->status ? "status " : "",
+			!regs->mbox ? "mbox " : "",
+			!regs->memdev ? "memdev" : "");
 		return -ENXIO;
 	}