summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cxl/core/hdm.c2
-rw-r--r--drivers/cxl/cxl.h11
-rw-r--r--drivers/cxl/cxlmem.h2
3 files changed, 12 insertions, 3 deletions
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index c222e98ae736..3930e130d6b6 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -177,7 +177,7 @@ static struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
}
parse_hdm_decoder_caps(cxlhdm);
- if (cxlhdm->decoder_count == 0) {
+ if (cxlhdm->decoder_count < 0) {
dev_err(dev, "Spec violation. Caps invalid\n");
return ERR_PTR(-ENXIO);
}
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index d09c84bcc015..4e7923811f94 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -77,7 +77,16 @@ static inline int cxl_hdm_decoder_count(u32 cap_hdr)
{
int val = FIELD_GET(CXL_HDM_DECODER_COUNT_MASK, cap_hdr);
- return val ? val * 2 : 1;
+ switch (val) {
+ case 0:
+ return 1;
+ case 1 ... 8:
+ return val * 2;
+ case 9 ... 12:
+ return (val - 4) * 4;
+ default:
+ return -ENXIO;
+ }
}
/* Encode defined in CXL 2.0 8.2.5.12.7 HDM Decoder Control Register */
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index e21d744d639b..399b150b404c 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -923,7 +923,7 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd);
*/
struct cxl_hdm {
struct cxl_component_regs regs;
- unsigned int decoder_count;
+ int decoder_count;
unsigned int target_count;
unsigned int interleave_mask;
unsigned long iw_cap_mask;