Skip to content

Commit afa2bdb

Browse files
djbwdavejiang
authored andcommitted
cxl/port: Cleanup dport removal with a devres group
In preparation for adding more setup actions like RAS register mapping, introduce a devres group to collect all the dport creation / registration actions. This replaces the maintenance tedium of open coding several devm_release_action() calls in del_dport(). Tested-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Link: https://patch.msgid.link/20260131000403.2135324-4-dan.j.williams@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 83ccbaf commit afa2bdb

1 file changed

Lines changed: 61 additions & 10 deletions

File tree

drivers/cxl/core/port.c

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,57 @@ static void cxl_dport_unlink(void *data)
11181118
sysfs_remove_link(&port->dev.kobj, link_name);
11191119
}
11201120

1121+
static struct device *dport_to_host(struct cxl_dport *dport)
1122+
{
1123+
struct cxl_port *port = dport->port;
1124+
1125+
if (is_cxl_root(port))
1126+
return port->uport_dev;
1127+
return &port->dev;
1128+
}
1129+
1130+
static void free_dport(void *dport)
1131+
{
1132+
kfree(dport);
1133+
}
1134+
1135+
/*
1136+
* Upon return either a group is established with one action (free_dport()), or
1137+
* no group established and @dport is freed.
1138+
*/
1139+
static void *cxl_dport_open_dr_group_or_free(struct cxl_dport *dport)
1140+
{
1141+
int rc;
1142+
struct device *host = dport_to_host(dport);
1143+
void *group = devres_open_group(host, dport, GFP_KERNEL);
1144+
1145+
if (!group) {
1146+
kfree(dport);
1147+
return NULL;
1148+
}
1149+
1150+
rc = devm_add_action_or_reset(host, free_dport, dport);
1151+
if (rc) {
1152+
devres_release_group(host, group);
1153+
return NULL;
1154+
}
1155+
1156+
return group;
1157+
}
1158+
1159+
static void cxl_dport_close_dr_group(struct cxl_dport *dport, void *group)
1160+
{
1161+
devres_close_group(dport_to_host(dport), group);
1162+
}
1163+
1164+
static void del_dport(struct cxl_dport *dport)
1165+
{
1166+
devres_release_group(dport_to_host(dport), dport);
1167+
}
1168+
1169+
/* The dport group id is the dport */
1170+
DEFINE_FREE(cxl_dport_release_dr_group, void *, if (_T) del_dport(_T))
1171+
11211172
static struct cxl_dport *
11221173
__devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
11231174
int port_id, resource_size_t component_reg_phys,
@@ -1143,14 +1194,20 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
11431194
CXL_TARGET_STRLEN)
11441195
return ERR_PTR(-EINVAL);
11451196

1146-
dport = devm_kzalloc(host, sizeof(*dport), GFP_KERNEL);
1197+
dport = kzalloc(sizeof(*dport), GFP_KERNEL);
11471198
if (!dport)
11481199
return ERR_PTR(-ENOMEM);
11491200

1201+
/* Just enough init to manage the devres group */
11501202
dport->dport_dev = dport_dev;
11511203
dport->port_id = port_id;
11521204
dport->port = port;
11531205

1206+
void *dport_dr_group __free(cxl_dport_release_dr_group) =
1207+
cxl_dport_open_dr_group_or_free(dport);
1208+
if (!dport_dr_group)
1209+
return ERR_PTR(-ENOMEM);
1210+
11541211
if (rcrb == CXL_RESOURCE_NONE) {
11551212
rc = cxl_dport_setup_regs(&port->dev, dport,
11561213
component_reg_phys);
@@ -1203,6 +1260,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
12031260

12041261
cxl_debugfs_create_dport_dir(dport);
12051262

1263+
/* keep the group, and mark the end of devm actions */
1264+
cxl_dport_close_dr_group(dport, no_free_ptr(dport_dr_group));
1265+
12061266
return dport;
12071267
}
12081268

@@ -1429,15 +1489,6 @@ static void delete_switch_port(struct cxl_port *port)
14291489
devm_release_action(port->dev.parent, unregister_port, port);
14301490
}
14311491

1432-
static void del_dport(struct cxl_dport *dport)
1433-
{
1434-
struct cxl_port *port = dport->port;
1435-
1436-
devm_release_action(&port->dev, cxl_dport_unlink, dport);
1437-
devm_release_action(&port->dev, cxl_dport_remove, dport);
1438-
devm_kfree(&port->dev, dport);
1439-
}
1440-
14411492
static void del_dports(struct cxl_port *port)
14421493
{
14431494
struct cxl_dport *dport;

0 commit comments

Comments
 (0)