[v7,07/20] mailbox: Allow direct registration to a channel

Message ID 20221121140009.2353512-8-quic_eberman@quicinc.com
State New
Headers
Series Drivers for gunyah hypervisor |

Commit Message

Elliot Berman Nov. 21, 2022, 1:59 p.m. UTC
  Support virtual mailbox controllers and clients which are not platform
devices or come from the devicetree by allowing them to match client to
channel via some other mechanism.

Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/mailbox/mailbox.c      | 96 ++++++++++++++++++++++++----------
 drivers/mailbox/omap-mailbox.c | 18 ++-----
 drivers/mailbox/pcc.c          | 17 ++----
 include/linux/mailbox_client.h |  1 +
 4 files changed, 76 insertions(+), 56 deletions(-)
  

Comments

kernel test robot Nov. 22, 2022, 4:34 a.m. UTC | #1
Hi Elliot,

I love your patch! Perhaps something to improve:

[auto build test WARNING on 094226ad94f471a9f19e8f8e7140a09c2625abaa]

url:    https://github.com/intel-lab-lkp/linux/commits/Elliot-Berman/Drivers-for-gunyah-hypervisor/20221121-220942
base:   094226ad94f471a9f19e8f8e7140a09c2625abaa
patch link:    https://lore.kernel.org/r/20221121140009.2353512-8-quic_eberman%40quicinc.com
patch subject: [PATCH v7 07/20] mailbox: Allow direct registration to a channel
config: x86_64-allyesconfig
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/5b7d4244a3896cfa8c098f01bee924c3ea869884
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Elliot-Berman/Drivers-for-gunyah-hypervisor/20221121-220942
        git checkout 5b7d4244a3896cfa8c098f01bee924c3ea869884
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/mailbox/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/mailbox/pcc.c: In function 'pcc_mbox_request_channel':
>> drivers/mailbox/pcc.c:286:23: warning: unused variable 'flags' [-Wunused-variable]
     286 |         unsigned long flags;
         |                       ^~~~~


vim +/flags +286 drivers/mailbox/pcc.c

aca314efb177274 hotran          2016-08-15  267  
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  268  /**
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  269   * pcc_mbox_request_channel - PCC clients call this function to
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  270   *		request a pointer to their PCC subspace, from which they
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  271   *		can get the details of communicating with the remote.
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  272   * @cl: Pointer to Mailbox client, so we know where to bind the
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  273   *		Channel.
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  274   * @subspace_id: The PCC Subspace index as parsed in the PCC client
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  275   *		ACPI package. This is used to lookup the array of PCC
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  276   *		subspaces as parsed by the PCC Mailbox controller.
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  277   *
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  278   * Return: Pointer to the PCC Mailbox Channel if successful or ERR_PTR.
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  279   */
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  280  struct pcc_mbox_chan *
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  281  pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  282  {
80b2bdde002c521 Sudeep Holla    2021-09-17  283  	struct pcc_chan_info *pchan;
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  284  	struct mbox_chan *chan;
ce028702ddbc697 Sudeep Holla    2021-09-17  285  	struct device *dev;
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12 @286  	unsigned long flags;
5b7d4244a3896cf Elliot Berman   2022-11-21  287  	int rc;
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  288  
ce028702ddbc697 Sudeep Holla    2021-09-17  289  	if (subspace_id < 0 || subspace_id >= pcc_chan_count)
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  290  		return ERR_PTR(-ENOENT);
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  291  
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  292  	pchan = chan_info + subspace_id;
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  293  	chan = pchan->chan.mchan;
d311a28a5853857 Sudip Mukherjee 2015-09-16  294  	if (IS_ERR(chan) || chan->cl) {
960c4056aadcf61 Sudeep Holla    2021-12-09  295  		pr_err("Channel not found for idx: %d\n", subspace_id);
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  296  		return ERR_PTR(-EBUSY);
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  297  	}
ce028702ddbc697 Sudeep Holla    2021-09-17  298  	dev = chan->mbox->dev;
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  299  
5b7d4244a3896cf Elliot Berman   2022-11-21  300  	rc = mbox_bind_client(chan, cl);
5b7d4244a3896cf Elliot Berman   2022-11-21  301  	if (rc)
5b7d4244a3896cf Elliot Berman   2022-11-21  302  		return ERR_PTR(rc);
6ca595a70bc46e1 Hoan Tran       2016-11-14  303  
f92ae90e52bb09d Sudeep Holla    2021-09-17  304  	if (pchan->plat_irq > 0) {
f92ae90e52bb09d Sudeep Holla    2021-09-17  305  		rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
80b2bdde002c521 Sudeep Holla    2021-09-17  306  				      MBOX_IRQ_NAME, chan);
aca314efb177274 hotran          2016-08-15  307  		if (unlikely(rc)) {
aca314efb177274 hotran          2016-08-15  308  			dev_err(dev, "failed to register PCC interrupt %d\n",
f92ae90e52bb09d Sudeep Holla    2021-09-17  309  				pchan->plat_irq);
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  310  			pcc_mbox_free_channel(&pchan->chan);
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  311  			return ERR_PTR(rc);
aca314efb177274 hotran          2016-08-15  312  		}
aca314efb177274 hotran          2016-08-15  313  	}
aca314efb177274 hotran          2016-08-15  314  
7b6da7fe7bba1cd Sudeep Holla    2021-09-17  315  	return &pchan->chan;
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  316  }
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  317  EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
86c22f8c9a3b71d Ashwin Chaugule 2014-11-12  318
  

Patch

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 4229b9b5da98..adf36c05fa43 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -317,6 +317,71 @@  int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 }
 EXPORT_SYMBOL_GPL(mbox_flush);
 
+static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl)
+{
+	struct device *dev = cl->dev;
+	unsigned long flags;
+	int ret;
+
+	if (chan->cl || !try_module_get(chan->mbox->dev->driver->owner)) {
+		dev_dbg(dev, "%s: mailbox not free\n", __func__);
+		return -EBUSY;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+	chan->msg_free = 0;
+	chan->msg_count = 0;
+	chan->active_req = NULL;
+	chan->cl = cl;
+	init_completion(&chan->tx_complete);
+
+	if (chan->txdone_method	== TXDONE_BY_POLL && cl->knows_txdone)
+		chan->txdone_method = TXDONE_BY_ACK;
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	if (chan->mbox->ops->startup) {
+		ret = chan->mbox->ops->startup(chan);
+
+		if (ret) {
+			dev_err(dev, "Unable to startup the chan (%d)\n", ret);
+			mbox_free_channel(chan);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * mbox_bind_client - Request a mailbox channel.
+ * @chan: The mailbox channel to bind the client to.
+ * @cl: Identity of the client requesting the channel.
+ *
+ * The Client specifies its requirements and capabilities while asking for
+ * a mailbox channel. It can't be called from atomic context.
+ * The channel is exclusively allocated and can't be used by another
+ * client before the owner calls mbox_free_channel.
+ * After assignment, any packet received on this channel will be
+ * handed over to the client via the 'rx_callback'.
+ * The framework holds reference to the client, so the mbox_client
+ * structure shouldn't be modified until the mbox_free_channel returns.
+ *
+ * Return: 0 if the channel was assigned to the client successfully.
+ *         <0 for request failure.
+ */
+int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl)
+{
+	int ret;
+
+	mutex_lock(&con_mutex);
+	ret = __mbox_bind_client(chan, cl);
+	mutex_unlock(&con_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mbox_bind_client);
+
 /**
  * mbox_request_channel - Request a mailbox channel.
  * @cl: Identity of the client requesting the channel.
@@ -340,7 +405,6 @@  struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
 	struct mbox_controller *mbox;
 	struct of_phandle_args spec;
 	struct mbox_chan *chan;
-	unsigned long flags;
 	int ret;
 
 	if (!dev || !dev->of_node) {
@@ -372,33 +436,9 @@  struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
 		return chan;
 	}
 
-	if (chan->cl || !try_module_get(mbox->dev->driver->owner)) {
-		dev_dbg(dev, "%s: mailbox not free\n", __func__);
-		mutex_unlock(&con_mutex);
-		return ERR_PTR(-EBUSY);
-	}
-
-	spin_lock_irqsave(&chan->lock, flags);
-	chan->msg_free = 0;
-	chan->msg_count = 0;
-	chan->active_req = NULL;
-	chan->cl = cl;
-	init_completion(&chan->tx_complete);
-
-	if (chan->txdone_method	== TXDONE_BY_POLL && cl->knows_txdone)
-		chan->txdone_method = TXDONE_BY_ACK;
-
-	spin_unlock_irqrestore(&chan->lock, flags);
-
-	if (chan->mbox->ops->startup) {
-		ret = chan->mbox->ops->startup(chan);
-
-		if (ret) {
-			dev_err(dev, "Unable to startup the chan (%d)\n", ret);
-			mbox_free_channel(chan);
-			chan = ERR_PTR(ret);
-		}
-	}
+	ret = __mbox_bind_client(chan, cl);
+	if (ret)
+		chan = ERR_PTR(ret);
 
 	mutex_unlock(&con_mutex);
 	return chan;
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 098c82d87137..711a56ec8592 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -441,21 +441,9 @@  struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
 	if (!mbox || !mbox->chan)
 		return ERR_PTR(-ENOENT);
 
-	chan = mbox->chan;
-	spin_lock_irqsave(&chan->lock, flags);
-	chan->msg_free = 0;
-	chan->msg_count = 0;
-	chan->active_req = NULL;
-	chan->cl = cl;
-	init_completion(&chan->tx_complete);
-	spin_unlock_irqrestore(&chan->lock, flags);
-
-	ret = chan->mbox->ops->startup(chan);
-	if (ret) {
-		pr_err("Unable to startup the chan (%d)\n", ret);
-		mbox_free_channel(chan);
-		chan = ERR_PTR(ret);
-	}
+	ret = mbox_bind_client(mbox->chan, cl);
+	if (ret)
+		return ERR_PTR(ret);
 
 	return chan;
 }
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 3c2bc0ca454c..b93fd95559c0 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -284,6 +284,7 @@  pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
 	struct mbox_chan *chan;
 	struct device *dev;
 	unsigned long flags;
+	int rc;
 
 	if (subspace_id < 0 || subspace_id >= pcc_chan_count)
 		return ERR_PTR(-ENOENT);
@@ -296,21 +297,11 @@  pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
 	}
 	dev = chan->mbox->dev;
 
-	spin_lock_irqsave(&chan->lock, flags);
-	chan->msg_free = 0;
-	chan->msg_count = 0;
-	chan->active_req = NULL;
-	chan->cl = cl;
-	init_completion(&chan->tx_complete);
-
-	if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
-		chan->txdone_method = TXDONE_BY_ACK;
-
-	spin_unlock_irqrestore(&chan->lock, flags);
+	rc = mbox_bind_client(chan, cl);
+	if (rc)
+		return ERR_PTR(rc);
 
 	if (pchan->plat_irq > 0) {
-		int rc;
-
 		rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
 				      MBOX_IRQ_NAME, chan);
 		if (unlikely(rc)) {
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 65229a45590f..734694912ef7 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -37,6 +37,7 @@  struct mbox_client {
 	void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
 };
 
+int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
 struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 					      const char *name);
 struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);