forked from Minki/linux
bus/fsl-mc: Export a cleanup function for DPRC
Create and export a cleanup function for DPRC. The function is used by the DPRC driver, but it will be used by the VFIO driver as well. Reviewed-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Acked-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com> Link: https://lore.kernel.org/r/20200929085441.17448-9-diana.craciun@oss.nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
5d781fabe6
commit
46f35b5fbb
@ -727,6 +727,55 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
|
||||
fsl_mc_free_irqs(mc_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* dprc_cleanup - function that cleanups a DPRC
|
||||
*
|
||||
* @mc_dev: Pointer to fsl-mc device representing the DPRC
|
||||
*
|
||||
* It closes the DPRC device in the MC.
|
||||
* It destroys the interrupt pool associated with this MC bus.
|
||||
*/
|
||||
|
||||
int dprc_cleanup(struct fsl_mc_device *mc_dev)
|
||||
{
|
||||
int error;
|
||||
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
|
||||
|
||||
|
||||
/* this function should be called only for DPRCs, it
|
||||
* is an error to call it for regular objects
|
||||
*/
|
||||
if (!is_fsl_mc_bus_dprc(mc_dev))
|
||||
return -EINVAL;
|
||||
|
||||
if (dev_get_msi_domain(&mc_dev->dev)) {
|
||||
fsl_mc_cleanup_irq_pool(mc_bus);
|
||||
dev_set_msi_domain(&mc_dev->dev, NULL);
|
||||
}
|
||||
|
||||
fsl_mc_cleanup_all_resource_pools(mc_dev);
|
||||
|
||||
/* if this step fails we cannot go further with cleanup as there is no way of
|
||||
* communicating with the firmware
|
||||
*/
|
||||
if (!mc_dev->mc_io) {
|
||||
dev_err(&mc_dev->dev, "mc_io is NULL, tear down cannot be performed in firmware\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
|
||||
if (error < 0)
|
||||
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
|
||||
|
||||
if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
|
||||
fsl_destroy_mc_io(mc_dev->mc_io);
|
||||
mc_dev->mc_io = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dprc_cleanup);
|
||||
|
||||
/**
|
||||
* dprc_remove - callback invoked when a DPRC is being unbound from this driver
|
||||
*
|
||||
@ -739,13 +788,10 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
|
||||
*/
|
||||
static int dprc_remove(struct fsl_mc_device *mc_dev)
|
||||
{
|
||||
int error;
|
||||
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
|
||||
|
||||
if (!is_fsl_mc_bus_dprc(mc_dev))
|
||||
return -EINVAL;
|
||||
if (!mc_dev->mc_io)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mc_bus->irq_resources)
|
||||
return -EINVAL;
|
||||
@ -755,21 +801,7 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
|
||||
|
||||
device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
|
||||
|
||||
if (dev_get_msi_domain(&mc_dev->dev)) {
|
||||
fsl_mc_cleanup_irq_pool(mc_bus);
|
||||
dev_set_msi_domain(&mc_dev->dev, NULL);
|
||||
}
|
||||
|
||||
fsl_mc_cleanup_all_resource_pools(mc_dev);
|
||||
|
||||
error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
|
||||
if (error < 0)
|
||||
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
|
||||
|
||||
if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
|
||||
fsl_destroy_mc_io(mc_dev->mc_io);
|
||||
mc_dev->mc_io = NULL;
|
||||
}
|
||||
dprc_cleanup(mc_dev);
|
||||
|
||||
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
|
||||
return 0;
|
||||
|
@ -538,6 +538,8 @@ void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev,
|
||||
struct fsl_mc_obj_desc *obj_desc_array,
|
||||
int num_child_objects_in_mc);
|
||||
|
||||
int dprc_cleanup(struct fsl_mc_device *mc_dev);
|
||||
|
||||
/*
|
||||
* Data Path Buffer Pool (DPBP) API
|
||||
* Contains initialization APIs and runtime control APIs for DPBP
|
||||
|
Loading…
Reference in New Issue
Block a user