summaryrefslogtreecommitdiff
path: root/drivers/firmware/imx/imx-scu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/imx/imx-scu.c')
-rw-r--r--drivers/firmware/imx/imx-scu.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index 67b267a7408a..203aac421252 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -82,6 +82,17 @@ static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = {
static struct imx_sc_ipc *imx_sc_ipc_handle;
+static void imx_scu_free_mbox_chan(void *data)
+{
+ mbox_free_channel(data);
+}
+
+static void imx_scu_clear_handle(void *data)
+{
+ if (imx_sc_ipc_handle == data)
+ imx_sc_ipc_handle = NULL;
+}
+
static inline int imx_sc_to_linux_errno(int errno)
{
if (errno >= IMX_SC_ERR_NONE && errno < IMX_SC_ERR_LAST)
@@ -321,6 +332,11 @@ static int imx_scu_probe(struct platform_device *pdev)
dev_dbg(dev, "request mbox chan %s\n", chan_name);
/* chan_name is not used anymore by framework */
kfree(chan_name);
+
+ ret = devm_add_action_or_reset(dev, imx_scu_free_mbox_chan,
+ sc_chan->ch);
+ if (ret)
+ return ret;
}
sc_ipc->dev = dev;
@@ -330,6 +346,9 @@ static int imx_scu_probe(struct platform_device *pdev)
init_completion(&sc_ipc->done);
imx_sc_ipc_handle = sc_ipc;
+ ret = devm_add_action_or_reset(dev, imx_scu_clear_handle, sc_ipc);
+ if (ret)
+ return ret;
ret = imx_scu_soc_init(dev);
if (ret)
@@ -342,7 +361,11 @@ static int imx_scu_probe(struct platform_device *pdev)
dev_info(dev, "NXP i.MX SCU Initialized\n");
- return devm_of_platform_populate(dev);
+ ret = devm_of_platform_populate(dev);
+ if (ret)
+ of_platform_depopulate(dev);
+
+ return ret;
}
static const struct of_device_id imx_scu_match[] = {