Re: [PATCH v10 01/12] cxl: Move HDM decoder programming helpers

From: Li Ming

Date: Mon Aug 24 2026 - 03:21:22 EST


On 8/24/2026 3:11 PM, Li Ming wrote:
> On 8/5/2026 3:29 AM, Srirangan Madhavan wrote:
>> Move the low-level HDM decoder programming helpers from hdm.c into
>> resource.c so they can be shared by later reset restore code.
>>
>> Keep the existing decoder commit flow and register programming sequence
>> unchanged. This patch is intended to be a mechanical move. Follow-on
>> patches update the helper interface for reset restore.
>>
>> Signed-off-by: Srirangan Madhavan <smadhavan@xxxxxxxxxx>
>> ---
>> drivers/cxl/Kconfig | 4 ++
>> drivers/cxl/core/Makefile | 1 +
>> drivers/cxl/core/core.h | 2 +
>> drivers/cxl/core/hdm.c | 124 +-------------------------------
>> drivers/cxl/core/resource.c | 138 ++++++++++++++++++++++++++++++++++++
>> drivers/cxl/cxl.h | 41 -----------
>> include/cxl/cxl.h | 45 +++++++++++-
>> tools/testing/cxl/Kbuild | 1 +
>> 8 files changed, 191 insertions(+), 165 deletions(-)
>> create mode 100644 drivers/cxl/core/resource.c
>>
>> diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
>> index 80aeb0d556bd..87d719ea1e14 100644
>> --- a/drivers/cxl/Kconfig
>> +++ b/drivers/cxl/Kconfig
>> @@ -6,6 +6,7 @@ menuconfig CXL_BUS
>> select FW_UPLOAD
>> select PCI_DOE
>> select FIRMWARE_TABLE
>> + select CXL_HDM
>> select NUMA_KEEP_MEMINFO if NUMA_MEMBLKS
>> select FWCTL if CXL_FEATURES
>> help
>> @@ -243,4 +244,7 @@ config CXL_ATL
>> depends on CXL_REGION
>> depends on ACPI_PRMT && AMD_NB
>>
>> +config CXL_HDM
>> + bool
>> +
>> endif
>> diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
>> index ce7213818d3c..0df4178bbbaa 100644
>> --- a/drivers/cxl/core/Makefile
>> +++ b/drivers/cxl/core/Makefile
>> @@ -1,5 +1,6 @@
>> # SPDX-License-Identifier: GPL-2.0
>> obj-$(CONFIG_CXL_BUS) += cxl_core.o
>> +obj-$(CONFIG_CXL_HDM) += resource.o
>> obj-$(CONFIG_CXL_SUSPEND) += suspend.o
>>
>> ccflags-y += -I$(srctree)/drivers/cxl
>> diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
>> index 07555ae63859..cb6853a92a93 100644
>> --- a/drivers/cxl/core/core.h
>> +++ b/drivers/cxl/core/core.h
>> @@ -213,6 +213,8 @@ int cxl_gpf_port_setup(struct cxl_dport *dport);
>> struct cxl_hdm;
>> int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
>> struct cxl_endpoint_dvsec_info *info);
>> +void cxl_setup_hw_decoder(struct cxl_decoder *cxld, void __iomem *hdm);
>> +int cxld_await_commit(void __iomem *hdm, int id);
>> int cxl_port_get_possible_dports(struct cxl_port *port);
>>
>> #ifdef CONFIG_CXL_FEATURES
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index 0c80b76a5f9b..6ae0b9f46ac0 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -16,10 +16,6 @@
>> * for enumerating these registers and capabilities.
>> */
>>
>> -struct cxl_rwsem cxl_rwsem = {
>> - .region = __RWSEM_INITIALIZER(cxl_rwsem.region),
>> - .dpa = __RWSEM_INITIALIZER(cxl_rwsem.dpa),
>> -};
>>
>> static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld)
>> {
>> @@ -679,124 +675,6 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
>> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
>> }
>>
>> -static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
>> -{
>> - u16 eig;
>> - u8 eiw;
>> -
>> - /*
>> - * Input validation ensures these warns never fire, but otherwise
>> - * suppress unititalized variable usage warnings.
>> - */
>> - if (WARN_ONCE(ways_to_eiw(cxld->interleave_ways, &eiw),
>> - "invalid interleave_ways: %d\n", cxld->interleave_ways))
>> - return;
>> - if (WARN_ONCE(granularity_to_eig(cxld->interleave_granularity, &eig),
>> - "invalid interleave_granularity: %d\n",
>> - cxld->interleave_granularity))
>> - return;
>> -
>> - u32p_replace_bits(ctrl, eig, CXL_HDM_DECODER0_CTRL_IG_MASK);
>> - u32p_replace_bits(ctrl, eiw, CXL_HDM_DECODER0_CTRL_IW_MASK);
>> - *ctrl |= CXL_HDM_DECODER0_CTRL_COMMIT;
>> -}
>> -
>> -static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl)
>> -{
>> - u32p_replace_bits(ctrl,
>> - !!(cxld->target_type == CXL_DECODER_HOSTONLYMEM),
>> - CXL_HDM_DECODER0_CTRL_HOSTONLY);
>> -}
>> -
>> -static void cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
>> -{
>> - struct cxl_dport **t = &cxlsd->target[0];
>> - int ways = cxlsd->cxld.interleave_ways;
>> -
>> - *tgt = FIELD_PREP(GENMASK(7, 0), t[0]->port_id);
>> - if (ways > 1)
>> - *tgt |= FIELD_PREP(GENMASK(15, 8), t[1]->port_id);
>> - if (ways > 2)
>> - *tgt |= FIELD_PREP(GENMASK(23, 16), t[2]->port_id);
>> - if (ways > 3)
>> - *tgt |= FIELD_PREP(GENMASK(31, 24), t[3]->port_id);
>> - if (ways > 4)
>> - *tgt |= FIELD_PREP(GENMASK_ULL(39, 32), t[4]->port_id);
>> - if (ways > 5)
>> - *tgt |= FIELD_PREP(GENMASK_ULL(47, 40), t[5]->port_id);
>> - if (ways > 6)
>> - *tgt |= FIELD_PREP(GENMASK_ULL(55, 48), t[6]->port_id);
>> - if (ways > 7)
>> - *tgt |= FIELD_PREP(GENMASK_ULL(63, 56), t[7]->port_id);
>> -}
>> -
>> -/*
>> - * Per CXL 2.0 8.2.5.12.20 Committing Decoder Programming, hardware must set
>> - * committed or error within 10ms, but just be generous with 20ms to account for
>> - * clock skew and other marginal behavior
>> - */
>> -#define COMMIT_TIMEOUT_MS 20
>> -static int cxld_await_commit(void __iomem *hdm, int id)
>> -{
>> - u32 ctrl;
>> - int i;
>> -
>> - for (i = 0; i < COMMIT_TIMEOUT_MS; i++) {
>> - ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMIT_ERROR, ctrl)) {
>> - ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
>> - writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> - return -EIO;
>> - }
>> - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
>> - return 0;
>> - fsleep(1000);
>> - }
>> -
>> - return -ETIMEDOUT;
>> -}
>> -
>> -static void setup_hw_decoder(struct cxl_decoder *cxld, void __iomem *hdm)
>> -{
>> - int id = cxld->id;
>> - u64 base, size;
>> - u32 ctrl;
>> -
>> - /* common decoder settings */
>> - ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
>> - cxld_set_interleave(cxld, &ctrl);
>> - cxld_set_type(cxld, &ctrl);
>> - base = cxld->hpa_range.start;
>> - size = range_len(&cxld->hpa_range);
>> -
>> - writel(upper_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id));
>> - writel(lower_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
>> - writel(upper_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(id));
>> - writel(lower_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(id));
>> -
>> - if (is_switch_decoder(&cxld->dev)) {
>> - struct cxl_switch_decoder *cxlsd =
>> - to_cxl_switch_decoder(&cxld->dev);
>> - void __iomem *tl_hi = hdm + CXL_HDM_DECODER0_TL_HIGH(id);
>> - void __iomem *tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW(id);
>> - u64 targets;
>> -
>> - cxlsd_set_targets(cxlsd, &targets);
>> - writel(upper_32_bits(targets), tl_hi);
>> - writel(lower_32_bits(targets), tl_lo);
>> - } else {
>> - struct cxl_endpoint_decoder *cxled =
>> - to_cxl_endpoint_decoder(&cxld->dev);
>> - void __iomem *sk_hi = hdm + CXL_HDM_DECODER0_SKIP_HIGH(id);
>> - void __iomem *sk_lo = hdm + CXL_HDM_DECODER0_SKIP_LOW(id);
>> -
>> - writel(upper_32_bits(cxled->skip), sk_hi);
>> - writel(lower_32_bits(cxled->skip), sk_lo);
>> - }
>> -
>> - writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> -}
>> -
>> static int cxl_decoder_commit(struct cxl_decoder *cxld)
>> {
>> struct cxl_port *port = to_cxl_port(cxld->dev.parent);
>> @@ -835,7 +713,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
>> }
>>
>> scoped_guard(rwsem_read, &cxl_rwsem.dpa)
>> - setup_hw_decoder(cxld, hdm);
>> + cxl_setup_hw_decoder(cxld, hdm);
>>
>> rc = cxld_await_commit(hdm, cxld->id);
>> if (rc) {
>> diff --git a/drivers/cxl/core/resource.c b/drivers/cxl/core/resource.c
>> new file mode 100644
>> index 000000000000..dd8bed3d3ff0
>> --- /dev/null
>> +++ b/drivers/cxl/core/resource.c
>> @@ -0,0 +1,138 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/* Copyright (c) 2026 NVIDIA Corporation & Affiliates */
>> +#include <linux/delay.h>
>> +#include <linux/bug.h>
>> +#include <linux/errno.h>
>> +#include <linux/export.h>
>> +#include <linux/kernel.h>
>> +
>> +#include "cxl.h"
>> +#include "core.h"
>> +
>> +struct cxl_rwsem cxl_rwsem = {
>> + .region = __RWSEM_INITIALIZER(cxl_rwsem.region),
>> + .dpa = __RWSEM_INITIALIZER(cxl_rwsem.dpa),
>> +};
>> +EXPORT_SYMBOL_FOR_MODULES(cxl_rwsem, "cxl_core");
>> +
>> +static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
>> +{
>> + u16 eig;
>> + u8 eiw;
>> +
>> + /*
>> + * Input validation ensures these warns never fire, but otherwise
>> + * suppress unititalized variable usage warnings.
>> + */
>> + if (WARN_ONCE(ways_to_eiw(cxld->interleave_ways, &eiw),
>> + "invalid interleave_ways: %d\n", cxld->interleave_ways))
>> + return;
>> + if (WARN_ONCE(granularity_to_eig(cxld->interleave_granularity, &eig),
>> + "invalid interleave_granularity: %d\n",
>> + cxld->interleave_granularity))
>> + return;
>> +
>> + u32p_replace_bits(ctrl, eig, CXL_HDM_DECODER0_CTRL_IG_MASK);
>> + u32p_replace_bits(ctrl, eiw, CXL_HDM_DECODER0_CTRL_IW_MASK);
>> + *ctrl |= CXL_HDM_DECODER0_CTRL_COMMIT;
>> +}
>> +
>> +static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl)
>> +{
>> + u32p_replace_bits(ctrl,
>> + !!(cxld->target_type == CXL_DECODER_HOSTONLYMEM),
>> + CXL_HDM_DECODER0_CTRL_HOSTONLY);
>> +}
>> +
>> +static void cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
>> +{
>> + struct cxl_dport **t = &cxlsd->target[0];
>> + int ways = cxlsd->cxld.interleave_ways;
>> +
>> + *tgt = FIELD_PREP(GENMASK(7, 0), t[0]->port_id);
>> + if (ways > 1)
>> + *tgt |= FIELD_PREP(GENMASK(15, 8), t[1]->port_id);
>> + if (ways > 2)
>> + *tgt |= FIELD_PREP(GENMASK(23, 16), t[2]->port_id);
>> + if (ways > 3)
>> + *tgt |= FIELD_PREP(GENMASK(31, 24), t[3]->port_id);
>> + if (ways > 4)
>> + *tgt |= FIELD_PREP(GENMASK_ULL(39, 32), t[4]->port_id);
>> + if (ways > 5)
>> + *tgt |= FIELD_PREP(GENMASK_ULL(47, 40), t[5]->port_id);
>> + if (ways > 6)
>> + *tgt |= FIELD_PREP(GENMASK_ULL(55, 48), t[6]->port_id);
>> + if (ways > 7)
>> + *tgt |= FIELD_PREP(GENMASK_ULL(63, 56), t[7]->port_id);
>> +}
>> +
>> +/*
>> + * Per CXL 2.0 8.2.5.12.20 Committing Decoder Programming, hardware must set
>> + * committed or error within 10ms, but just be generous with 20ms to account for
>> + * clock skew and other marginal behavior
>> + */
>> +#define COMMIT_TIMEOUT_MS 20
>> +int cxld_await_commit(void __iomem *hdm, int id)
>> +{
>> + u32 ctrl;
>> + int i;
>> +
>> + for (i = 0; i < COMMIT_TIMEOUT_MS; i++) {
>> + ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> + if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMIT_ERROR, ctrl)) {
>> + ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
>> + writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> + return -EIO;
>> + }
>> + if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
>> + return 0;
>> + fsleep(1000);
>> + }
>> +
>> + return -ETIMEDOUT;
>> +}
>> +
>> +EXPORT_SYMBOL_FOR_MODULES(cxld_await_commit, "cxl_core");
> Redundant blank line between function implementation and EXPORT_SYMBOL_FOR_MODULES().
Oh, sorry, I saw you deleting this EXPORT_SYMBOL_FOR_MODULES() in PATCH #2.
>> +
>> +void cxl_setup_hw_decoder(struct cxl_decoder *cxld, void __iomem *hdm)
>> +{
>> + int id = cxld->id;
>> + u64 base, size;
>> + u32 ctrl;
>> +
>> + /* common decoder settings */
>> + ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
>> + cxld_set_interleave(cxld, &ctrl);
>> + cxld_set_type(cxld, &ctrl);
>> + base = cxld->hpa_range.start;
>> + size = range_len(&cxld->hpa_range);
>> +
>> + writel(upper_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id));
>> + writel(lower_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
>> + writel(upper_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(id));
>> + writel(lower_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(id));
>> +
>> + if (is_switch_decoder(&cxld->dev)) {
>> + struct cxl_switch_decoder *cxlsd =
>> + to_cxl_switch_decoder(&cxld->dev);
>> + void __iomem *tl_hi = hdm + CXL_HDM_DECODER0_TL_HIGH(id);
>> + void __iomem *tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW(id);
>> + u64 targets;
>> +
>> + cxlsd_set_targets(cxlsd, &targets);
>> + writel(upper_32_bits(targets), tl_hi);
>> + writel(lower_32_bits(targets), tl_lo);
>> + } else {
>> + struct cxl_endpoint_decoder *cxled =
>> + to_cxl_endpoint_decoder(&cxld->dev);
>> + void __iomem *sk_hi = hdm + CXL_HDM_DECODER0_SKIP_HIGH(id);
>> + void __iomem *sk_lo = hdm + CXL_HDM_DECODER0_SKIP_LOW(id);
>> +
>> + writel(upper_32_bits(cxled->skip), sk_hi);
>> + writel(lower_32_bits(cxled->skip), sk_lo);
>> + }
>> +
>> + writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
>> +}
>> +
>> +EXPORT_SYMBOL_FOR_MODULES(cxl_setup_hw_decoder, "cxl_core");
> Same as above
>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
>> index c0e5308e4d1b..c795cce0fcbc 100644
>> --- a/drivers/cxl/cxl.h
>> +++ b/drivers/cxl/cxl.h
>> @@ -264,49 +264,8 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
>> #define CXL_DECODER_F_NORMALIZED_ADDRESSING BIT(6)
>> #define CXL_DECODER_F_RESET_MASK (CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK)
>>
>> -enum cxl_decoder_type {
>> - CXL_DECODER_DEVMEM = 2,
>> - CXL_DECODER_HOSTONLYMEM = 3,
>> -};
>> -
>> -/*
>> - * Current specification goes up to 8, double that seems a reasonable
>> - * software max for the foreseeable future
>> - */
>> -#define CXL_DECODER_MAX_INTERLEAVE 16
>> -
>> #define CXL_QOS_CLASS_INVALID -1
>>
>> -/**
>> - * struct cxl_decoder - Common CXL HDM Decoder Attributes
>> - * @dev: this decoder's device
>> - * @id: kernel device name id
>> - * @hpa_range: Host physical address range mapped by this decoder
>> - * @interleave_ways: number of cxl_dports in this decode
>> - * @interleave_granularity: data stride per dport
>> - * @target_type: accelerator vs expander (type2 vs type3) selector
>> - * @region: currently assigned region for this decoder
>> - * @flags: memory type capabilities and locking
>> - * @target_map: cached copy of hardware port-id list, available at init
>> - * before all @dport objects have been instantiated. While
>> - * dport id is 8bit, CFMWS interleave targets are 32bits.
>> - * @commit: device/decoder-type specific callback to commit settings to hw
>> - * @reset: device/decoder-type specific callback to reset hw settings
>> -*/
>> -struct cxl_decoder {
>> - struct device dev;
>> - int id;
>> - struct range hpa_range;
>> - int interleave_ways;
>> - int interleave_granularity;
>> - enum cxl_decoder_type target_type;
>> - struct cxl_region *region;
>> - unsigned long flags;
>> - u32 target_map[CXL_DECODER_MAX_INTERLEAVE];
>> - int (*commit)(struct cxl_decoder *cxld);
>> - void (*reset)(struct cxl_decoder *cxld);
>> -};
>> -
>> /*
>> * Track whether this decoder is free for userspace provisioning, reserved for
>> * region autodiscovery, whether it is started connecting (awaiting other
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 016c74fb747c..05a8bc32138c 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -5,8 +5,10 @@
>> #ifndef __CXL_CXL_H__
>> #define __CXL_CXL_H__
>>
>> +#include <linux/device.h>
>> #include <linux/node.h>
>> #include <linux/ioport.h>
>> +#include <linux/range.h>
>> #include <cxl/mailbox.h>
>>
>> /**
>> @@ -23,7 +25,48 @@ enum cxl_devtype {
>> CXL_DEVTYPE_CLASSMEM,
>> };
>>
>> -struct device;
>> +struct cxl_region;
>> +
>> +enum cxl_decoder_type {
>> + CXL_DECODER_DEVMEM = 2,
>> + CXL_DECODER_HOSTONLYMEM = 3,
>> +};
>> +
>> +/*
>> + * Current specification goes up to 8, double that seems a reasonable
>> + * software max for the foreseeable future
>> + */
>> +#define CXL_DECODER_MAX_INTERLEAVE 16
>> +
>> +/**
>> + * struct cxl_decoder - Common CXL HDM Decoder Attributes
>> + * @dev: this decoder's device
>> + * @id: kernel device name id
>> + * @hpa_range: Host physical address range mapped by this decoder
>> + * @interleave_ways: number of cxl_dports in this decode
>> + * @interleave_granularity: data stride per dport
>> + * @target_type: accelerator vs expander (type2 vs type3) selector
>> + * @flags: memory type capabilities and locking
>> + * @region: currently assigned region for this decoder
>> + * @target_map: cached copy of hardware port-id list, available at init
>> + * before all @dport objects have been instantiated. While
>> + * dport id is 8bit, CFMWS interleave targets are 32bits.
>> + * @commit: device/decoder-type specific callback to commit settings to hw
>> + * @reset: device/decoder-type specific callback to reset hw settings
>> + */
>> +struct cxl_decoder {
>> + struct device dev;
>> + int id;
>> + struct range hpa_range;
>> + int interleave_ways;
>> + int interleave_granularity;
>> + enum cxl_decoder_type target_type;
>> + unsigned long flags;
>> + struct cxl_region *region;
>> + u32 target_map[CXL_DECODER_MAX_INTERLEAVE];
>> + int (*commit)(struct cxl_decoder *cxld);
>> + void (*reset)(struct cxl_decoder *cxld);
>> +};
>>
>> /*
>> * Using struct_group() allows for per register-block-type helper routines,
>> diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild
>> index 2be1df80fcc9..6c09932587ce 100644
>> --- a/tools/testing/cxl/Kbuild
>> +++ b/tools/testing/cxl/Kbuild
>> @@ -60,6 +60,7 @@ cxl_core-y += $(CXL_CORE_SRC)/memdev.o
>> cxl_core-y += $(CXL_CORE_SRC)/mbox.o
>> cxl_core-y += $(CXL_CORE_SRC)/pci.o
>> cxl_core-y += $(CXL_CORE_SRC)/hdm.o
>> +cxl_core-y += $(CXL_CORE_SRC)/resource.o
>> cxl_core-y += $(CXL_CORE_SRC)/pmu.o
>> cxl_core-y += $(CXL_CORE_SRC)/cdat.o
>> cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
>