diff options
Diffstat (limited to 'drivers/bus/fsl-mc/dprc-driver.c')
-rw-r--r-- | drivers/bus/fsl-mc/dprc-driver.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index 68488a7ad0d6..fc684615a135 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -603,6 +603,7 @@ int dprc_setup(struct fsl_mc_device *mc_dev) struct irq_domain *mc_msi_domain; bool mc_io_created = false; bool msi_domain_set = false; + bool root_dprc = false; u16 major_ver, minor_ver; size_t region_size; int error; @@ -635,6 +636,11 @@ int dprc_setup(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); @@ -646,11 +652,19 @@ int dprc_setup(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, @@ -683,6 +697,10 @@ int dprc_setup(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); @@ -763,6 +781,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev) int dprc_cleanup(struct fsl_mc_device *mc_dev) { + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); int error; /* this function should be called only for DPRCs, it @@ -793,6 +812,8 @@ int dprc_cleanup(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); } return 0; |