Merge tag 'pm-6.6-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[platform/kernel/linux-starfive.git] / drivers / mailbox / pcc.c
index 105d46c..a44d4b3 100644 (file)
@@ -282,8 +282,7 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
 {
        struct pcc_chan_info *pchan;
        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);
@@ -294,32 +293,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
                pr_err("Channel not found for idx: %d\n", subspace_id);
                return ERR_PTR(-EBUSY);
        }
-       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);
-
-       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)) {
-                       dev_err(dev, "failed to register PCC interrupt %d\n",
-                               pchan->plat_irq);
-                       pcc_mbox_free_channel(&pchan->chan);
-                       return ERR_PTR(rc);
-               }
-       }
+       rc = mbox_bind_client(chan, cl);
+       if (rc)
+               return ERR_PTR(rc);
 
        return &pchan->chan;
 }
@@ -333,23 +310,12 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
  */
 void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
 {
-       struct pcc_chan_info *pchan_info = to_pcc_chan_info(pchan);
        struct mbox_chan *chan = pchan->mchan;
-       unsigned long flags;
 
        if (!chan || !chan->cl)
                return;
 
-       if (pchan_info->plat_irq > 0)
-               devm_free_irq(chan->mbox->dev, pchan_info->plat_irq, chan);
-
-       spin_lock_irqsave(&chan->lock, flags);
-       chan->cl = NULL;
-       chan->active_req = NULL;
-       if (chan->txdone_method == TXDONE_BY_ACK)
-               chan->txdone_method = TXDONE_BY_POLL;
-
-       spin_unlock_irqrestore(&chan->lock, flags);
+       mbox_free_channel(chan);
 }
 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
 
@@ -377,8 +343,48 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
        return pcc_chan_reg_read_modify_write(&pchan->db);
 }
 
+/**
+ * pcc_startup - Called from Mailbox Controller code. Used here
+ *             to request the interrupt.
+ * @chan: Pointer to Mailbox channel to startup.
+ *
+ * Return: Err if something failed else 0 for success.
+ */
+static int pcc_startup(struct mbox_chan *chan)
+{
+       struct pcc_chan_info *pchan = chan->con_priv;
+       int rc;
+
+       if (pchan->plat_irq > 0) {
+               rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
+                                     MBOX_IRQ_NAME, chan);
+               if (unlikely(rc)) {
+                       dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
+                               pchan->plat_irq);
+                       return rc;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * pcc_shutdown - Called from Mailbox Controller code. Used here
+ *             to free the interrupt.
+ * @chan: Pointer to Mailbox channel to shutdown.
+ */
+static void pcc_shutdown(struct mbox_chan *chan)
+{
+       struct pcc_chan_info *pchan = chan->con_priv;
+
+       if (pchan->plat_irq > 0)
+               devm_free_irq(chan->mbox->dev, pchan->plat_irq, chan);
+}
+
 static const struct mbox_chan_ops pcc_chan_ops = {
        .send_data = pcc_send_data,
+       .startup = pcc_startup,
+       .shutdown = pcc_shutdown,
 };
 
 /**