@@ -164,6 +164,22 @@ void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
}
EXPORT_SYMBOL_GPL(mbox_chan_received_data);
+/**
+ * mbox_chan_received_data_bh - A way for controller driver to push data
+ * received from remote to the upper layer.
+ * @chan: Pointer to the mailbox channel on which RX happened.
+ * @mssg: Client specific message typecasted as void *
+ *
+ * For the operations which is not atomic can be called from
+ * mbox_chan_received_data_bh().
+ */
+void mbox_chan_received_data_bh(struct mbox_chan *chan, void *mssg)
+{
+ if (chan->cl->rx_callback_bh)
+ chan->cl->rx_callback_bh(chan->cl, mssg);
+}
+EXPORT_SYMBOL_GPL(mbox_chan_received_data_bh);
+
/**
* mbox_chan_txdone - A way for controller driver to notify the
* framework that the last TX has completed.
@@ -22,6 +22,7 @@ struct mbox_chan;
* if the client receives some ACK packet for transmission.
* Unused if the controller already has TX_Done/RTR IRQ.
* @rx_callback: Atomic callback to provide client the data received
+ * @rx_callback_bh: Non-atomic callback to provide client the data received
* @tx_prepare: Atomic callback to ask client to prepare the payload
* before initiating the transmission if required.
* @tx_done: Atomic callback to tell client of data transmission
@@ -33,6 +34,7 @@ struct mbox_client {
bool knows_txdone;
void (*rx_callback)(struct mbox_client *cl, void *mssg);
+ void (*rx_callback_bh)(struct mbox_client *cl, void *mssg);
void (*tx_prepare)(struct mbox_client *cl, void *mssg);
void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
};
@@ -130,6 +130,7 @@ struct mbox_chan {
int mbox_controller_register(struct mbox_controller *mbox); /* can sleep */
void mbox_controller_unregister(struct mbox_controller *mbox); /* can sleep */
void mbox_chan_received_data(struct mbox_chan *chan, void *data); /* atomic */
+void mbox_chan_received_data_bh(struct mbox_chan *chan, void *data); /* can sleep */
void mbox_chan_txdone(struct mbox_chan *chan, int r); /* atomic */
int devm_mbox_controller_register(struct device *dev,