firmware: imx-dsp: Export functions to request/free channels
authorDaniel Baluta <daniel.baluta@nxp.com>
Wed, 11 Nov 2020 11:11:18 +0000 (13:11 +0200)
committerShawn Guo <shawnguo@kernel.org>
Mon, 16 Nov 2020 08:33:48 +0000 (16:33 +0800)
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>
drivers/firmware/imx/imx-dsp.c
include/linux/firmware/imx/dsp.h

index b6e95d6d34c0b3e5042ebe37e02a0d43eadfdf40..a6c06d7476c328ef7e166ac809fd304ce2faa059 100644 (file)
@@ -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;
index 7562099c9e4644189ecf8e67c87c92a19bfeefb6..4f7895a3b73c70485ea6709739f373f736d22662 100644 (file)
@@ -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 */