diff options
Diffstat (limited to 'drivers/bus/fsl-mc/mc-io.c')
| -rw-r--r-- | drivers/bus/fsl-mc/mc-io.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c index 7226cfc49b6f..cd8754763f40 100644 --- a/drivers/bus/fsl-mc/mc-io.c +++ b/drivers/bus/fsl-mc/mc-io.c @@ -50,12 +50,12 @@ static void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io) } /** - * Creates an MC I/O object + * fsl_create_mc_io() - Creates an MC I/O object * * @dev: device to be associated with the MC I/O object * @mc_portal_phys_addr: physical address of the MC portal to use * @mc_portal_size: size in bytes of the MC portal - * @dpmcp-dev: Pointer to the DPMCP object associated with this MC I/O + * @dpmcp_dev: Pointer to the DPMCP object associated with this MC I/O * object or NULL if none. * @flags: flags for the new MC I/O object * @new_mc_io: Area to return pointer to newly created MC I/O object @@ -82,7 +82,7 @@ int __must_check fsl_create_mc_io(struct device *dev, mc_io->portal_phys_addr = mc_portal_phys_addr; mc_io->portal_size = mc_portal_size; if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) - spin_lock_init(&mc_io->spinlock); + raw_spin_lock_init(&mc_io->spinlock); else mutex_init(&mc_io->mutex); @@ -97,12 +97,12 @@ int __must_check fsl_create_mc_io(struct device *dev, return -EBUSY; } - mc_portal_virt_addr = devm_ioremap_nocache(dev, + mc_portal_virt_addr = devm_ioremap(dev, mc_portal_phys_addr, mc_portal_size); if (!mc_portal_virt_addr) { dev_err(dev, - "devm_ioremap_nocache failed for MC portal %pa\n", + "devm_ioremap failed for MC portal %pa\n", &mc_portal_phys_addr); return -ENXIO; } @@ -123,13 +123,18 @@ error_destroy_mc_io: } /** - * Destroys an MC I/O object + * fsl_destroy_mc_io() - Destroys an MC I/O object * * @mc_io: MC I/O object to destroy */ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) { - struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; + struct fsl_mc_device *dpmcp_dev; + + if (!mc_io) + return; + + dpmcp_dev = mc_io->dpmcp_dev; if (dpmcp_dev) fsl_mc_io_unset_dpmcp(mc_io); @@ -209,9 +214,26 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, if (error < 0) goto error_cleanup_resource; + /* If the DPRC device itself tries to allocate a portal (usually for + * UAPI interaction), don't add a device link between them since the + * DPMCP device is an actual child device of the DPRC and a reverse + * dependency is not allowed. + */ + if (mc_dev != mc_bus_dev) { + dpmcp_dev->consumer_link = device_link_add(&mc_dev->dev, + &dpmcp_dev->dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!dpmcp_dev->consumer_link) { + error = -EINVAL; + goto error_cleanup_mc_io; + } + } + *new_mc_io = mc_io; return 0; +error_cleanup_mc_io: + fsl_destroy_mc_io(mc_io); error_cleanup_resource: fsl_mc_resource_free(resource); return error; @@ -244,25 +266,7 @@ void fsl_mc_portal_free(struct fsl_mc_io *mc_io) fsl_destroy_mc_io(mc_io); fsl_mc_resource_free(resource); -} -EXPORT_SYMBOL_GPL(fsl_mc_portal_free); -/** - * fsl_mc_portal_reset - Resets the dpmcp object for a given fsl_mc_io object - * - * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free - */ -int fsl_mc_portal_reset(struct fsl_mc_io *mc_io) -{ - int error; - struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; - - error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle); - if (error < 0) { - dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error); - return error; - } - - return 0; + dpmcp_dev->consumer_link = NULL; } -EXPORT_SYMBOL_GPL(fsl_mc_portal_reset); +EXPORT_SYMBOL_GPL(fsl_mc_portal_free); |
