From 23d89aa0c2192f2d4582198b381d8805492c7925 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 11 Nov 2020 13:11:18 +0200 Subject: [PATCH] firmware: imx-dsp: Export functions to request/free channels In order to save power, we only need to request a channel when the communication with the DSP active. For this we export the following functions: - imx_dsp_request_channel, gets a channel with a given index - imx_dsp_free_channel, frees a channel with a given index Notice that we still request channels at probe to support devices that do not have PM callbacks implemented. More explanations about why requesting a channel has an effect on power savings: - requesting an mailbox channel will call mailbox's startup function. - startup function calls pm_runtime_get_sync which increments device usage count and will keep the device active. Specifically, mailbox clock will be always ON when a mailbox channel is requested. Signed-off-by: Daniel Baluta Reviewed-by: Paul Olaru Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-dsp.c | 25 +++++++++++++++++++++++++ include/linux/firmware/imx/dsp.h | 10 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c index b6e95d6..a6c06d7 100644 --- a/drivers/firmware/imx/imx-dsp.c +++ b/drivers/firmware/imx/imx-dsp.c @@ -60,6 +60,31 @@ static void imx_dsp_handle_rx(struct mbox_client *c, void *msg) } } +struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *dsp_ipc, int idx) +{ + struct imx_dsp_chan *dsp_chan; + + if (idx >= DSP_MU_CHAN_NUM) + return ERR_PTR(-EINVAL); + + dsp_chan = &dsp_ipc->chans[idx]; + dsp_chan->ch = mbox_request_channel_byname(&dsp_chan->cl, dsp_chan->name); + return dsp_chan->ch; +} +EXPORT_SYMBOL(imx_dsp_request_channel); + +void imx_dsp_free_channel(struct imx_dsp_ipc *dsp_ipc, int idx) +{ + struct imx_dsp_chan *dsp_chan; + + if (idx >= DSP_MU_CHAN_NUM) + return; + + dsp_chan = &dsp_ipc->chans[idx]; + mbox_free_channel(dsp_chan->ch); +} +EXPORT_SYMBOL(imx_dsp_free_channel); + static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) { struct device *dev = dsp_ipc->dev; diff --git a/include/linux/firmware/imx/dsp.h b/include/linux/firmware/imx/dsp.h index 7562099..4f7895a 100644 --- a/include/linux/firmware/imx/dsp.h +++ b/include/linux/firmware/imx/dsp.h @@ -55,6 +55,9 @@ static inline void *imx_dsp_get_data(struct imx_dsp_ipc *ipc) int imx_dsp_ring_doorbell(struct imx_dsp_ipc *dsp, unsigned int chan_idx); +struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx); +void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx); + #else static inline int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc, @@ -63,5 +66,12 @@ static inline int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc, return -ENOTSUPP; } +struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx) { } + #endif #endif /* _IMX_DSP_IPC_H */ -- 2.7.4