We need to ensure DMA engine could be stopped in order for kexec to start the next kernel. So add the shutdown operation support. Signed-off-by: Peng Ma <peng.ma@xxxxxxx> --- drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c | 17 +++++++++++++++++ drivers/dma/fsl-dpaa2-qdma/dpdmai.c | 21 +++++++++++++++++++++ drivers/dma/fsl-dpaa2-qdma/dpdmai.h | 2 ++ 3 files changed, 40 insertions(+) diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c index c70a7965f140..fabbbb90b2c7 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -790,6 +790,22 @@ static int dpaa2_qdma_remove(struct fsl_mc_device *ls_dev) return 0; } +static void dpaa2_qdma_shutdown(struct fsl_mc_device *ls_dev) +{ + struct dpaa2_qdma_engine *dpaa2_qdma; + struct dpaa2_qdma_priv *priv; + struct device *dev; + + dev = &ls_dev->dev; + priv = dev_get_drvdata(dev); + dpaa2_qdma = priv->dpaa2_qdma; + + dpdmai_disable(priv->mc_io, 0, ls_dev->mc_handle); + dpaa2_dpdmai_dpio_unbind(priv); + dpdmai_close(priv->mc_io, 0, ls_dev->mc_handle); + dpdmai_destroy(priv->mc_io, 0, ls_dev->mc_handle); +} + static const struct fsl_mc_device_id dpaa2_qdma_id_table[] = { { .vendor = FSL_MC_VENDOR_FREESCALE, @@ -805,6 +821,7 @@ static struct fsl_mc_driver dpaa2_qdma_driver = { }, .probe = dpaa2_qdma_probe, .remove = dpaa2_qdma_remove, + .shutdown = dpaa2_qdma_shutdown, .match_id_table = dpaa2_qdma_id_table }; diff --git a/drivers/dma/fsl-dpaa2-qdma/dpdmai.c b/drivers/dma/fsl-dpaa2-qdma/dpdmai.c index f8d22115154a..878662aaa1c2 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpdmai.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpdmai.c @@ -159,6 +159,27 @@ int dpdmai_create(struct fsl_mc_io *mc_io, u32 cmd_flags, return 0; } +/** + * dpdmai_destroy() - Destroy the DPDMAI object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPDMAI object + * + * Return: '0' on Success; error code otherwise. + */ +int dpdmai_destroy(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) +{ + struct fsl_mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY, + cmd_flags, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL_GPL(dpdmai_destroy); + /** * dpdmai_enable() - Enable the DPDMAI, allow sending and receiving frames. * @mc_io: Pointer to MC portal's I/O object diff --git a/drivers/dma/fsl-dpaa2-qdma/dpdmai.h b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h index 6d785093da8e..b13b9bf0c003 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpdmai.h +++ b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h @@ -18,6 +18,7 @@ #define DPDMAI_CMDID_CLOSE DPDMAI_CMDID_FORMAT(0x800) #define DPDMAI_CMDID_OPEN DPDMAI_CMDID_FORMAT(0x80E) #define DPDMAI_CMDID_CREATE DPDMAI_CMDID_FORMAT(0x90E) +#define DPDMAI_CMDID_DESTROY DPDMAI_CMDID_FORMAT(0x900) #define DPDMAI_CMDID_ENABLE DPDMAI_CMDID_FORMAT(0x002) #define DPDMAI_CMDID_DISABLE DPDMAI_CMDID_FORMAT(0x003) @@ -160,6 +161,7 @@ struct dpdmai_rx_queue_attr { int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpdmai_id, u16 *token); int dpdmai_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); +int dpdmai_destroy(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); int dpdmai_create(struct fsl_mc_io *mc_io, u32 cmd_flags, const struct dpdmai_cfg *cfg, u16 *token); int dpdmai_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -- 2.17.1