mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
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>
This commit is contained in:
parent
83ccbaf1a1
commit
afa2bdba1e
|
|
@ -1118,6 +1118,57 @@ static void cxl_dport_unlink(void *data)
|
|||
sysfs_remove_link(&port->dev.kobj, link_name);
|
||||
}
|
||||
|
||||
static struct device *dport_to_host(struct cxl_dport *dport)
|
||||
{
|
||||
struct cxl_port *port = dport->port;
|
||||
|
||||
if (is_cxl_root(port))
|
||||
return port->uport_dev;
|
||||
return &port->dev;
|
||||
}
|
||||
|
||||
static void free_dport(void *dport)
|
||||
{
|
||||
kfree(dport);
|
||||
}
|
||||
|
||||
/*
|
||||
* Upon return either a group is established with one action (free_dport()), or
|
||||
* no group established and @dport is freed.
|
||||
*/
|
||||
static void *cxl_dport_open_dr_group_or_free(struct cxl_dport *dport)
|
||||
{
|
||||
int rc;
|
||||
struct device *host = dport_to_host(dport);
|
||||
void *group = devres_open_group(host, dport, GFP_KERNEL);
|
||||
|
||||
if (!group) {
|
||||
kfree(dport);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = devm_add_action_or_reset(host, free_dport, dport);
|
||||
if (rc) {
|
||||
devres_release_group(host, group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static void cxl_dport_close_dr_group(struct cxl_dport *dport, void *group)
|
||||
{
|
||||
devres_close_group(dport_to_host(dport), group);
|
||||
}
|
||||
|
||||
static void del_dport(struct cxl_dport *dport)
|
||||
{
|
||||
devres_release_group(dport_to_host(dport), dport);
|
||||
}
|
||||
|
||||
/* The dport group id is the dport */
|
||||
DEFINE_FREE(cxl_dport_release_dr_group, void *, if (_T) del_dport(_T))
|
||||
|
||||
static struct cxl_dport *
|
||||
__devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
|
||||
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,
|
|||
CXL_TARGET_STRLEN)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
dport = devm_kzalloc(host, sizeof(*dport), GFP_KERNEL);
|
||||
dport = kzalloc(sizeof(*dport), GFP_KERNEL);
|
||||
if (!dport)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Just enough init to manage the devres group */
|
||||
dport->dport_dev = dport_dev;
|
||||
dport->port_id = port_id;
|
||||
dport->port = port;
|
||||
|
||||
void *dport_dr_group __free(cxl_dport_release_dr_group) =
|
||||
cxl_dport_open_dr_group_or_free(dport);
|
||||
if (!dport_dr_group)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (rcrb == CXL_RESOURCE_NONE) {
|
||||
rc = cxl_dport_setup_regs(&port->dev, dport,
|
||||
component_reg_phys);
|
||||
|
|
@ -1203,6 +1260,9 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
|
|||
|
||||
cxl_debugfs_create_dport_dir(dport);
|
||||
|
||||
/* keep the group, and mark the end of devm actions */
|
||||
cxl_dport_close_dr_group(dport, no_free_ptr(dport_dr_group));
|
||||
|
||||
return dport;
|
||||
}
|
||||
|
||||
|
|
@ -1429,15 +1489,6 @@ static void delete_switch_port(struct cxl_port *port)
|
|||
devm_release_action(port->dev.parent, unregister_port, port);
|
||||
}
|
||||
|
||||
static void del_dport(struct cxl_dport *dport)
|
||||
{
|
||||
struct cxl_port *port = dport->port;
|
||||
|
||||
devm_release_action(&port->dev, cxl_dport_unlink, dport);
|
||||
devm_release_action(&port->dev, cxl_dport_remove, dport);
|
||||
devm_kfree(&port->dev, dport);
|
||||
}
|
||||
|
||||
static void del_dports(struct cxl_port *port)
|
||||
{
|
||||
struct cxl_dport *dport;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user