Skip to content

Commit ca899f4

Browse files
committed
Merge branch 'for-6.3/cxl-autodetect-fixes' into for-6.4/cxl
Pick up late v6.3 fixes for v6.4.
2 parents 856ef55 + c841ecd commit ca899f4

4 files changed

Lines changed: 53 additions & 19 deletions

File tree

drivers/cxl/core/hdm.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
3-
#include <linux/io-64-nonatomic-hi-lo.h>
43
#include <linux/seq_file.h>
54
#include <linux/device.h>
65
#include <linux/delay.h>
@@ -93,8 +92,9 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
9392

9493
cxl_probe_component_regs(&port->dev, crb, &map.component_map);
9594
if (!map.component_map.hdm_decoder.valid) {
96-
dev_err(&port->dev, "HDM decoder registers invalid\n");
97-
return -ENXIO;
95+
dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
96+
/* unique error code to indicate no HDM decoder capability */
97+
return -ENODEV;
9898
}
9999

100100
return cxl_map_component_regs(&port->dev, regs, &map,
@@ -130,6 +130,14 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
130130
*/
131131
for (i = 0; i < cxlhdm->decoder_count; i++) {
132132
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
133+
dev_dbg(&info->port->dev,
134+
"decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n",
135+
info->port->id, i,
136+
FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl),
137+
readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)),
138+
readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)),
139+
readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)),
140+
readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i)));
133141
if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
134142
return false;
135143
}
@@ -269,8 +277,11 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
269277

270278
lockdep_assert_held_write(&cxl_dpa_rwsem);
271279

272-
if (!len)
273-
goto success;
280+
if (!len) {
281+
dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
282+
port->id, cxled->cxld.id);
283+
return -EINVAL;
284+
}
274285

275286
if (cxled->dpa_res) {
276287
dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
@@ -323,7 +334,6 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
323334
cxled->mode = CXL_DECODER_MIXED;
324335
}
325336

326-
success:
327337
port->hdm_end++;
328338
get_device(&cxled->cxld.dev);
329339
return 0;
@@ -783,8 +793,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
783793
int *target_map, void __iomem *hdm, int which,
784794
u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
785795
{
796+
u64 size, base, skip, dpa_size, lo, hi;
786797
struct cxl_endpoint_decoder *cxled;
787-
u64 size, base, skip, dpa_size;
788798
bool committed;
789799
u32 remainder;
790800
int i, rc;
@@ -799,8 +809,12 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
799809
which, info);
800810

801811
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
802-
base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
803-
size = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
812+
lo = readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
813+
hi = readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(which));
814+
base = (hi << 32) + lo;
815+
lo = readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
816+
hi = readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(which));
817+
size = (hi << 32) + lo;
804818
committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED);
805819
cxld->commit = cxl_decoder_commit;
806820
cxld->reset = cxl_decoder_reset;
@@ -833,6 +847,13 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
833847
port->id, cxld->id);
834848
return -ENXIO;
835849
}
850+
851+
if (size == 0) {
852+
dev_warn(&port->dev,
853+
"decoder%d.%d: Committed with zero size\n",
854+
port->id, cxld->id);
855+
return -ENXIO;
856+
}
836857
port->commit_end = cxld->id;
837858
} else {
838859
/* unless / until type-2 drivers arrive, assume type-3 */
@@ -855,9 +876,14 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
855876
if (rc)
856877
return rc;
857878

879+
dev_dbg(&port->dev, "decoder%d.%d: range: %#llx-%#llx iw: %d ig: %d\n",
880+
port->id, cxld->id, cxld->hpa_range.start, cxld->hpa_range.end,
881+
cxld->interleave_ways, cxld->interleave_granularity);
882+
858883
if (!info) {
859-
target_list.value =
860-
ioread64_hi_lo(hdm + CXL_HDM_DECODER0_TL_LOW(which));
884+
lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which));
885+
hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
886+
target_list.value = (hi << 32) + lo;
861887
for (i = 0; i < cxld->interleave_ways; i++)
862888
target_map[i] = target_list.target_id[i];
863889

@@ -874,7 +900,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
874900
port->id, cxld->id, size, cxld->interleave_ways);
875901
return -ENXIO;
876902
}
877-
skip = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
903+
lo = readl(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
904+
hi = readl(hdm + CXL_HDM_DECODER0_SKIP_HIGH(which));
905+
skip = (hi << 32) + lo;
878906
cxled = to_cxl_endpoint_decoder(&cxld->dev);
879907
rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip);
880908
if (rc) {

drivers/cxl/core/mbox.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3-
#include <linux/io-64-nonatomic-lo-hi.h>
43
#include <linux/security.h>
54
#include <linux/debugfs.h>
65
#include <linux/ktime.h>

drivers/cxl/core/port.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3-
#include <linux/io-64-nonatomic-lo-hi.h>
43
#include <linux/memregion.h>
54
#include <linux/workqueue.h>
65
#include <linux/debugfs.h>

drivers/cxl/port.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,22 @@ static int cxl_switch_port_probe(struct cxl_port *port)
6666
if (rc < 0)
6767
return rc;
6868

69-
if (rc == 1)
70-
return devm_cxl_add_passthrough_decoder(port);
71-
7269
cxlhdm = devm_cxl_setup_hdm(port, NULL);
73-
if (IS_ERR(cxlhdm))
70+
if (!IS_ERR(cxlhdm))
71+
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
72+
73+
if (PTR_ERR(cxlhdm) != -ENODEV) {
74+
dev_err(&port->dev, "Failed to map HDM decoder capability\n");
7475
return PTR_ERR(cxlhdm);
76+
}
77+
78+
if (rc == 1) {
79+
dev_dbg(&port->dev, "Fallback to passthrough decoder\n");
80+
return devm_cxl_add_passthrough_decoder(port);
81+
}
7582

76-
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
83+
dev_err(&port->dev, "HDM decoder capability not found\n");
84+
return -ENXIO;
7785
}
7886

7987
static int cxl_endpoint_port_probe(struct cxl_port *port)

0 commit comments

Comments
 (0)