mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 22:54:01 +00:00
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
2 changed files with 52 additions and 18 deletions
|
@ -727,6 +727,55 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
|
||||||
fsl_mc_free_irqs(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
|
* 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)
|
static int dprc_remove(struct fsl_mc_device *mc_dev)
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
|
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
|
||||||
|
|
||||||
if (!is_fsl_mc_bus_dprc(mc_dev))
|
if (!is_fsl_mc_bus_dprc(mc_dev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!mc_dev->mc_io)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!mc_bus->irq_resources)
|
if (!mc_bus->irq_resources)
|
||||||
return -EINVAL;
|
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);
|
device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
|
||||||
|
|
||||||
if (dev_get_msi_domain(&mc_dev->dev)) {
|
dprc_cleanup(mc_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
|
dev_info(&mc_dev->dev, "DPRC device unbound from driver");
|
||||||
return 0;
|
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,
|
struct fsl_mc_obj_desc *obj_desc_array,
|
||||||
int num_child_objects_in_mc);
|
int num_child_objects_in_mc);
|
||||||
|
|
||||||
|
int dprc_cleanup(struct fsl_mc_device *mc_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data Path Buffer Pool (DPBP) API
|
* Data Path Buffer Pool (DPBP) API
|
||||||
* Contains initialization APIs and runtime control APIs for DPBP
|
* Contains initialization APIs and runtime control APIs for DPBP
|
||||||
|
|
Loading…
Reference in a new issue