Skip to content

Commit 68d5d97

Browse files
committed
cxl/test: Refactor decoder setup to reduce cxl_test burden
Group the decoder setup code in switch and endpoint port probe into a single function for each to reduce the number of functions to be mocked in cxl_test. Introduce devm_cxl_switch_port_decoders_setup() and devm_cxl_endpoint_decoders_setup(). These two functions will be mocked instead with some functions optimized out since the mock version does not do anything. Remove devm_cxl_setup_hdm(), devm_cxl_add_passthrough_decoder(), and devm_cxl_enumerate_decoders() in cxl_test mock code. In turn, mock_cxl_add_passthrough_decoder() can be removed since cxl_test does not setup passthrough decoders. __wrap_cxl_hdm_decode_init() and __wrap_cxl_dvsec_rr_decode() can be removed as well since they only return 0 when called. [dj: drop 'struct cxl_port' forward declaration (Robert)] Suggested-by: Robert Richter <rrichter@amd.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Robert Richter <rrichter@amd.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 02edab6 commit 68d5d97

10 files changed

Lines changed: 169 additions & 133 deletions

File tree

drivers/cxl/core/core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ int cxl_ras_init(void);
147147
void cxl_ras_exit(void);
148148
int cxl_gpf_port_setup(struct cxl_dport *dport);
149149

150+
struct cxl_hdm;
151+
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
152+
struct cxl_endpoint_dvsec_info *info);
153+
int cxl_port_get_possible_dports(struct cxl_port *port);
154+
150155
#ifdef CONFIG_CXL_FEATURES
151156
struct cxl_feat_entry *
152157
cxl_feature_info(struct cxl_features_state *cxlfs, const uuid_t *uuid);

drivers/cxl/core/hdm.c

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld)
4949
* are claimed and passed to the single dport. Disable the range until the first
5050
* CXL region is enumerated / activated.
5151
*/
52-
int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
52+
static int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
5353
{
5454
struct cxl_switch_decoder *cxlsd;
5555
struct cxl_dport *dport = NULL;
@@ -75,7 +75,6 @@ int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
7575

7676
return add_hdm_decoder(port, &cxlsd->cxld);
7777
}
78-
EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, "CXL");
7978

8079
static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
8180
{
@@ -145,8 +144,8 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
145144
* @port: cxl_port to map
146145
* @info: cached DVSEC range register info
147146
*/
148-
struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
149-
struct cxl_endpoint_dvsec_info *info)
147+
static struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
148+
struct cxl_endpoint_dvsec_info *info)
150149
{
151150
struct cxl_register_map *reg_map = &port->reg_map;
152151
struct device *dev = &port->dev;
@@ -201,7 +200,6 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
201200

202201
return cxlhdm;
203202
}
204-
EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, "CXL");
205203

206204
static void __cxl_dpa_debug(struct seq_file *file, struct resource *r, int depth)
207205
{
@@ -1166,8 +1164,8 @@ static void cxl_settle_decoders(struct cxl_hdm *cxlhdm)
11661164
* @cxlhdm: Structure to populate with HDM capabilities
11671165
* @info: cached DVSEC range register info
11681166
*/
1169-
int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
1170-
struct cxl_endpoint_dvsec_info *info)
1167+
static int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
1168+
struct cxl_endpoint_dvsec_info *info)
11711169
{
11721170
void __iomem *hdm = cxlhdm->regs.hdm_decoder;
11731171
struct cxl_port *port = cxlhdm->port;
@@ -1222,4 +1220,71 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
12221220

12231221
return 0;
12241222
}
1225-
EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_decoders, "CXL");
1223+
1224+
/**
1225+
* devm_cxl_switch_port_decoders_setup - allocate and setup switch decoders
1226+
* @port: CXL port context
1227+
*
1228+
* Return 0 or -errno on error
1229+
*/
1230+
int devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
1231+
{
1232+
struct cxl_hdm *cxlhdm;
1233+
1234+
if (is_cxl_root(port) || is_cxl_endpoint(port))
1235+
return -EOPNOTSUPP;
1236+
1237+
cxlhdm = devm_cxl_setup_hdm(port, NULL);
1238+
if (!IS_ERR(cxlhdm))
1239+
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
1240+
1241+
if (PTR_ERR(cxlhdm) != -ENODEV) {
1242+
dev_err(&port->dev, "Failed to map HDM decoder capability\n");
1243+
return PTR_ERR(cxlhdm);
1244+
}
1245+
1246+
if (cxl_port_get_possible_dports(port) == 1) {
1247+
dev_dbg(&port->dev, "Fallback to passthrough decoder\n");
1248+
return devm_cxl_add_passthrough_decoder(port);
1249+
}
1250+
1251+
dev_err(&port->dev, "HDM decoder capability not found\n");
1252+
return -ENXIO;
1253+
}
1254+
EXPORT_SYMBOL_NS_GPL(devm_cxl_switch_port_decoders_setup, "CXL");
1255+
1256+
/**
1257+
* devm_cxl_endpoint_decoders_setup - allocate and setup endpoint decoders
1258+
* @port: CXL port context
1259+
*
1260+
* Return 0 or -errno on error
1261+
*/
1262+
int devm_cxl_endpoint_decoders_setup(struct cxl_port *port)
1263+
{
1264+
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
1265+
struct cxl_endpoint_dvsec_info info = { .port = port };
1266+
struct cxl_dev_state *cxlds = cxlmd->cxlds;
1267+
struct cxl_hdm *cxlhdm;
1268+
int rc;
1269+
1270+
if (!is_cxl_endpoint(port))
1271+
return -EOPNOTSUPP;
1272+
1273+
rc = cxl_dvsec_rr_decode(cxlds, &info);
1274+
if (rc < 0)
1275+
return rc;
1276+
1277+
cxlhdm = devm_cxl_setup_hdm(port, &info);
1278+
if (IS_ERR(cxlhdm)) {
1279+
if (PTR_ERR(cxlhdm) == -ENODEV)
1280+
dev_err(&port->dev, "HDM decoder registers not found\n");
1281+
return PTR_ERR(cxlhdm);
1282+
}
1283+
1284+
rc = cxl_hdm_decode_init(cxlds, cxlhdm, &info);
1285+
if (rc)
1286+
return rc;
1287+
1288+
return devm_cxl_enumerate_decoders(cxlhdm, &info);
1289+
}
1290+
EXPORT_SYMBOL_NS_GPL(devm_cxl_endpoint_decoders_setup, "CXL");

drivers/cxl/core/pci.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,3 +1169,45 @@ int cxl_gpf_port_setup(struct cxl_dport *dport)
11691169

11701170
return 0;
11711171
}
1172+
1173+
static int count_dports(struct pci_dev *pdev, void *data)
1174+
{
1175+
struct cxl_walk_context *ctx = data;
1176+
int type = pci_pcie_type(pdev);
1177+
1178+
if (pdev->bus != ctx->bus)
1179+
return 0;
1180+
if (!pci_is_pcie(pdev))
1181+
return 0;
1182+
if (type != ctx->type)
1183+
return 0;
1184+
1185+
ctx->count++;
1186+
return 0;
1187+
}
1188+
1189+
int cxl_port_get_possible_dports(struct cxl_port *port)
1190+
{
1191+
struct pci_bus *bus = cxl_port_to_pci_bus(port);
1192+
struct cxl_walk_context ctx;
1193+
int type;
1194+
1195+
if (!bus) {
1196+
dev_err(&port->dev, "No PCI bus found for port %s\n",
1197+
dev_name(&port->dev));
1198+
return -ENXIO;
1199+
}
1200+
1201+
if (pci_is_root_bus(bus))
1202+
type = PCI_EXP_TYPE_ROOT_PORT;
1203+
else
1204+
type = PCI_EXP_TYPE_DOWNSTREAM;
1205+
1206+
ctx = (struct cxl_walk_context) {
1207+
.bus = bus,
1208+
.type = type,
1209+
};
1210+
pci_walk_bus(bus, count_dports, &ctx);
1211+
1212+
return ctx.count;
1213+
}

drivers/cxl/cxl.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -810,12 +810,9 @@ struct cxl_endpoint_dvsec_info {
810810
struct range dvsec_range[2];
811811
};
812812

813-
struct cxl_hdm;
814-
struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
815-
struct cxl_endpoint_dvsec_info *info);
816-
int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
817-
struct cxl_endpoint_dvsec_info *info);
818-
int devm_cxl_add_passthrough_decoder(struct cxl_port *port);
813+
int devm_cxl_switch_port_decoders_setup(struct cxl_port *port);
814+
int devm_cxl_endpoint_decoders_setup(struct cxl_port *port);
815+
819816
struct cxl_dev_state;
820817
int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
821818
struct cxl_endpoint_dvsec_info *info);

drivers/cxl/cxlpci.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ static inline bool cxl_pci_flit_256(struct pci_dev *pdev)
129129

130130
int devm_cxl_port_enumerate_dports(struct cxl_port *port);
131131
struct cxl_dev_state;
132-
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
133-
struct cxl_endpoint_dvsec_info *info);
134132
void read_cdat_data(struct cxl_port *port);
135133
void cxl_cor_error_detected(struct pci_dev *pdev);
136134
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,

drivers/cxl/port.c

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ static int discover_region(struct device *dev, void *unused)
5959

6060
static int cxl_switch_port_probe(struct cxl_port *port)
6161
{
62-
struct cxl_hdm *cxlhdm;
6362
int rc;
6463

6564
/* Cache the data early to ensure is_visible() works */
@@ -71,43 +70,14 @@ static int cxl_switch_port_probe(struct cxl_port *port)
7170

7271
cxl_switch_parse_cdat(port);
7372

74-
cxlhdm = devm_cxl_setup_hdm(port, NULL);
75-
if (!IS_ERR(cxlhdm))
76-
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
77-
78-
if (PTR_ERR(cxlhdm) != -ENODEV) {
79-
dev_err(&port->dev, "Failed to map HDM decoder capability\n");
80-
return PTR_ERR(cxlhdm);
81-
}
82-
83-
if (rc == 1) {
84-
dev_dbg(&port->dev, "Fallback to passthrough decoder\n");
85-
return devm_cxl_add_passthrough_decoder(port);
86-
}
87-
88-
dev_err(&port->dev, "HDM decoder capability not found\n");
89-
return -ENXIO;
73+
return devm_cxl_switch_port_decoders_setup(port);
9074
}
9175

9276
static int cxl_endpoint_port_probe(struct cxl_port *port)
9377
{
94-
struct cxl_endpoint_dvsec_info info = { .port = port };
9578
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
96-
struct cxl_dev_state *cxlds = cxlmd->cxlds;
97-
struct cxl_hdm *cxlhdm;
9879
int rc;
9980

100-
rc = cxl_dvsec_rr_decode(cxlds, &info);
101-
if (rc < 0)
102-
return rc;
103-
104-
cxlhdm = devm_cxl_setup_hdm(port, &info);
105-
if (IS_ERR(cxlhdm)) {
106-
if (PTR_ERR(cxlhdm) == -ENODEV)
107-
dev_err(&port->dev, "HDM decoder registers not found\n");
108-
return PTR_ERR(cxlhdm);
109-
}
110-
11181
/* Cache the data early to ensure is_visible() works */
11282
read_cdat_data(port);
11383
cxl_endpoint_parse_cdat(port);
@@ -117,11 +87,7 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
11787
if (rc)
11888
return rc;
11989

120-
rc = cxl_hdm_decode_init(cxlds, cxlhdm, &info);
121-
if (rc)
122-
return rc;
123-
124-
rc = devm_cxl_enumerate_decoders(cxlhdm, &info);
90+
rc = devm_cxl_endpoint_decoders_setup(port);
12591
if (rc)
12692
return rc;
12793

tools/testing/cxl/Kbuild

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@ ldflags-y += --wrap=acpi_evaluate_integer
55
ldflags-y += --wrap=acpi_pci_find_root
66
ldflags-y += --wrap=nvdimm_bus_register
77
ldflags-y += --wrap=devm_cxl_port_enumerate_dports
8-
ldflags-y += --wrap=devm_cxl_setup_hdm
9-
ldflags-y += --wrap=devm_cxl_add_passthrough_decoder
10-
ldflags-y += --wrap=devm_cxl_enumerate_decoders
118
ldflags-y += --wrap=cxl_await_media_ready
12-
ldflags-y += --wrap=cxl_hdm_decode_init
13-
ldflags-y += --wrap=cxl_dvsec_rr_decode
149
ldflags-y += --wrap=devm_cxl_add_rch_dport
1510
ldflags-y += --wrap=cxl_rcd_component_reg_phys
1611
ldflags-y += --wrap=cxl_endpoint_parse_cdat
1712
ldflags-y += --wrap=cxl_dport_init_ras_reporting
13+
ldflags-y += --wrap=devm_cxl_switch_port_decoders_setup
14+
ldflags-y += --wrap=devm_cxl_endpoint_decoders_setup
1815

1916
DRIVERS := ../../../drivers
2017
CXL_SRC := $(DRIVERS)/cxl

tools/testing/cxl/test/cxl.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -643,13 +643,6 @@ static struct cxl_hdm *mock_cxl_setup_hdm(struct cxl_port *port,
643643
return cxlhdm;
644644
}
645645

646-
static int mock_cxl_add_passthrough_decoder(struct cxl_port *port)
647-
{
648-
dev_err(&port->dev, "unexpected passthrough decoder for cxl_test\n");
649-
return -EOPNOTSUPP;
650-
}
651-
652-
653646
struct target_map_ctx {
654647
u32 *target_map;
655648
int index;
@@ -921,6 +914,36 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
921914
return 0;
922915
}
923916

917+
static int __mock_cxl_decoders_setup(struct cxl_port *port)
918+
{
919+
struct cxl_hdm *cxlhdm;
920+
921+
cxlhdm = mock_cxl_setup_hdm(port, NULL);
922+
if (IS_ERR(cxlhdm)) {
923+
if (PTR_ERR(cxlhdm) != -ENODEV)
924+
dev_err(&port->dev, "Failed to map HDM decoder capability\n");
925+
return PTR_ERR(cxlhdm);
926+
}
927+
928+
return mock_cxl_enumerate_decoders(cxlhdm, NULL);
929+
}
930+
931+
static int mock_cxl_switch_port_decoders_setup(struct cxl_port *port)
932+
{
933+
if (is_cxl_root(port) || is_cxl_endpoint(port))
934+
return -EOPNOTSUPP;
935+
936+
return __mock_cxl_decoders_setup(port);
937+
}
938+
939+
static int mock_cxl_endpoint_decoders_setup(struct cxl_port *port)
940+
{
941+
if (!is_cxl_endpoint(port))
942+
return -EOPNOTSUPP;
943+
944+
return __mock_cxl_decoders_setup(port);
945+
}
946+
924947
static int mock_cxl_port_enumerate_dports(struct cxl_port *port)
925948
{
926949
struct platform_device **array;
@@ -1035,10 +1058,9 @@ static struct cxl_mock_ops cxl_mock_ops = {
10351058
.acpi_table_parse_cedt = mock_acpi_table_parse_cedt,
10361059
.acpi_evaluate_integer = mock_acpi_evaluate_integer,
10371060
.acpi_pci_find_root = mock_acpi_pci_find_root,
1061+
.devm_cxl_switch_port_decoders_setup = mock_cxl_switch_port_decoders_setup,
1062+
.devm_cxl_endpoint_decoders_setup = mock_cxl_endpoint_decoders_setup,
10381063
.devm_cxl_port_enumerate_dports = mock_cxl_port_enumerate_dports,
1039-
.devm_cxl_setup_hdm = mock_cxl_setup_hdm,
1040-
.devm_cxl_add_passthrough_decoder = mock_cxl_add_passthrough_decoder,
1041-
.devm_cxl_enumerate_decoders = mock_cxl_enumerate_decoders,
10421064
.cxl_endpoint_parse_cdat = mock_cxl_endpoint_parse_cdat,
10431065
.list = LIST_HEAD_INIT(cxl_mock_ops.list),
10441066
};

0 commit comments

Comments
 (0)