diff options
Diffstat (limited to 'drivers/bus/fsl-mc/dprc-driver.c')
-rw-r--r-- | drivers/bus/fsl-mc/dprc-driver.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index 2a473c09bc33..affd9b3ee545 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -614,6 +614,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); bool mc_io_created = false; bool msi_domain_set = false; + bool root_dprc = false; u16 major_ver, minor_ver; struct irq_domain *mc_msi_domain; @@ -645,6 +646,11 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) return error; mc_io_created = true; + } else { + if (dev_is_fsl_mc(parent_dev)) + return -EINVAL; + + root_dprc = true; } mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev); @@ -656,11 +662,19 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) msi_domain_set = true; } + if (root_dprc) { + error = fsl_mc_uapi_create_device_file(mc_bus); + if (error < 0) { + error = -EPROBE_DEFER; + goto error_cleanup_msi_domain; + } + } + error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, &mc_dev->mc_handle); if (error < 0) { dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error); - goto error_cleanup_msi_domain; + goto error_cleanup_uapi; } error = dprc_get_attributes(mc_dev->mc_io, 0, mc_dev->mc_handle, @@ -712,6 +726,10 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) error_cleanup_open: (void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); +error_cleanup_uapi: + if (fsl_mc_is_root_dprc(&mc_dev->dev)) + fsl_mc_uapi_remove_device_file(mc_bus); + error_cleanup_msi_domain: if (msi_domain_set) dev_set_msi_domain(&mc_dev->dev, NULL); @@ -780,6 +798,8 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { fsl_destroy_mc_io(mc_dev->mc_io); mc_dev->mc_io = NULL; + } else { + fsl_mc_uapi_remove_device_file(mc_bus); } dev_info(&mc_dev->dev, "DPRC device unbound from driver"); |