Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <daniel.baluta@nxp.com>
Reviewed-by: Paul Olaru <paul.olaru@nxp.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>

authored by

Daniel Baluta and committed by
Shawn Guo
23d89aa0 04632698

+35
+25
drivers/firmware/imx/imx-dsp.c
··· 60 60 } 61 61 } 62 62 63 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *dsp_ipc, int idx) 64 + { 65 + struct imx_dsp_chan *dsp_chan; 66 + 67 + if (idx >= DSP_MU_CHAN_NUM) 68 + return ERR_PTR(-EINVAL); 69 + 70 + dsp_chan = &dsp_ipc->chans[idx]; 71 + dsp_chan->ch = mbox_request_channel_byname(&dsp_chan->cl, dsp_chan->name); 72 + return dsp_chan->ch; 73 + } 74 + EXPORT_SYMBOL(imx_dsp_request_channel); 75 + 76 + void imx_dsp_free_channel(struct imx_dsp_ipc *dsp_ipc, int idx) 77 + { 78 + struct imx_dsp_chan *dsp_chan; 79 + 80 + if (idx >= DSP_MU_CHAN_NUM) 81 + return; 82 + 83 + dsp_chan = &dsp_ipc->chans[idx]; 84 + mbox_free_channel(dsp_chan->ch); 85 + } 86 + EXPORT_SYMBOL(imx_dsp_free_channel); 87 + 63 88 static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) 64 89 { 65 90 struct device *dev = dsp_ipc->dev;
+10
include/linux/firmware/imx/dsp.h
··· 55 55 56 56 int imx_dsp_ring_doorbell(struct imx_dsp_ipc *dsp, unsigned int chan_idx); 57 57 58 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx); 59 + void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx); 60 + 58 61 #else 59 62 60 63 static inline int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc, ··· 65 62 { 66 63 return -ENOTSUPP; 67 64 } 65 + 66 + struct mbox_chan *imx_dsp_request_channel(struct imx_dsp_ipc *ipc, int idx) 67 + { 68 + return ERR_PTR(-EOPNOTSUPP); 69 + } 70 + 71 + void imx_dsp_free_channel(struct imx_dsp_ipc *ipc, int idx) { } 68 72 69 73 #endif 70 74 #endif /* _IMX_DSP_IPC_H */