summaryrefslogtreecommitdiff
path: root/drivers/bus/fsl-mc/dprc-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bus/fsl-mc/dprc-driver.c')
-rw-r--r--drivers/bus/fsl-mc/dprc-driver.c23
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;