forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/mailbox/mailbox.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Mailbox: Common code for Mailbox controllers and users
34 *
45 * Copyright (C) 2013-2014 Linaro Ltd.
56 * Author: Jassi Brar <jassisinghbrar@gmail.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
107 */
118
129 #include <linux/interrupt.h>
....@@ -53,7 +50,7 @@
5350 return idx;
5451 }
5552
56
-static int __msg_submit(struct mbox_chan *chan)
53
+static void msg_submit(struct mbox_chan *chan)
5754 {
5855 unsigned count, idx;
5956 unsigned long flags;
....@@ -84,24 +81,6 @@
8481 }
8582 exit:
8683 spin_unlock_irqrestore(&chan->lock, flags);
87
-
88
- return err;
89
-}
90
-
91
-static void msg_submit(struct mbox_chan *chan)
92
-{
93
- int err = 0;
94
-
95
- /*
96
- * If the controller returns -EAGAIN, then it means, our spinlock
97
- * here is preventing the controller from receiving its interrupt,
98
- * that would help clear the controller channels that are currently
99
- * blocked waiting on the interrupt response.
100
- * Retry again.
101
- */
102
- do {
103
- err = __msg_submit(chan);
104
- } while (err == -EAGAIN);
10584
10685 /* kick start the timer immediately to avoid delays */
10786 if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
....@@ -304,6 +283,35 @@
304283 EXPORT_SYMBOL_GPL(mbox_send_message);
305284
306285 /**
286
+ * mbox_flush - flush a mailbox channel
287
+ * @chan: mailbox channel to flush
288
+ * @timeout: time, in milliseconds, to allow the flush operation to succeed
289
+ *
290
+ * Mailbox controllers that need to work in atomic context can implement the
291
+ * ->flush() callback to busy loop until a transmission has been completed.
292
+ * The implementation must call mbox_chan_txdone() upon success. Clients can
293
+ * call the mbox_flush() function at any time after mbox_send_message() to
294
+ * flush the transmission. After the function returns success, the mailbox
295
+ * transmission is guaranteed to have completed.
296
+ *
297
+ * Returns: 0 on success or a negative error code on failure.
298
+ */
299
+int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
300
+{
301
+ int ret;
302
+
303
+ if (!chan->mbox->ops->flush)
304
+ return -ENOTSUPP;
305
+
306
+ ret = chan->mbox->ops->flush(chan, timeout);
307
+ if (ret < 0)
308
+ tx_tick(chan, ret);
309
+
310
+ return ret;
311
+}
312
+EXPORT_SYMBOL_GPL(mbox_flush);
313
+
314
+/**
307315 * mbox_request_channel - Request a mailbox channel.
308316 * @cl: Identity of the client requesting the channel.
309317 * @index: Index of mailbox specifier in 'mboxes' property.
....@@ -347,7 +355,8 @@
347355 list_for_each_entry(mbox, &mbox_cons, node)
348356 if (mbox->dev->of_node == spec.np) {
349357 chan = mbox->of_xlate(mbox, &spec);
350
- break;
358
+ if (!IS_ERR(chan))
359
+ break;
351360 }
352361
353362 of_node_put(spec.np);
....@@ -537,3 +546,73 @@
537546 mutex_unlock(&con_mutex);
538547 }
539548 EXPORT_SYMBOL_GPL(mbox_controller_unregister);
549
+
550
+static void __devm_mbox_controller_unregister(struct device *dev, void *res)
551
+{
552
+ struct mbox_controller **mbox = res;
553
+
554
+ mbox_controller_unregister(*mbox);
555
+}
556
+
557
+static int devm_mbox_controller_match(struct device *dev, void *res, void *data)
558
+{
559
+ struct mbox_controller **mbox = res;
560
+
561
+ if (WARN_ON(!mbox || !*mbox))
562
+ return 0;
563
+
564
+ return *mbox == data;
565
+}
566
+
567
+/**
568
+ * devm_mbox_controller_register() - managed mbox_controller_register()
569
+ * @dev: device owning the mailbox controller being registered
570
+ * @mbox: mailbox controller being registered
571
+ *
572
+ * This function adds a device-managed resource that will make sure that the
573
+ * mailbox controller, which is registered using mbox_controller_register()
574
+ * as part of this function, will be unregistered along with the rest of
575
+ * device-managed resources upon driver probe failure or driver removal.
576
+ *
577
+ * Returns 0 on success or a negative error code on failure.
578
+ */
579
+int devm_mbox_controller_register(struct device *dev,
580
+ struct mbox_controller *mbox)
581
+{
582
+ struct mbox_controller **ptr;
583
+ int err;
584
+
585
+ ptr = devres_alloc(__devm_mbox_controller_unregister, sizeof(*ptr),
586
+ GFP_KERNEL);
587
+ if (!ptr)
588
+ return -ENOMEM;
589
+
590
+ err = mbox_controller_register(mbox);
591
+ if (err < 0) {
592
+ devres_free(ptr);
593
+ return err;
594
+ }
595
+
596
+ devres_add(dev, ptr);
597
+ *ptr = mbox;
598
+
599
+ return 0;
600
+}
601
+EXPORT_SYMBOL_GPL(devm_mbox_controller_register);
602
+
603
+/**
604
+ * devm_mbox_controller_unregister() - managed mbox_controller_unregister()
605
+ * @dev: device owning the mailbox controller being unregistered
606
+ * @mbox: mailbox controller being unregistered
607
+ *
608
+ * This function unregisters the mailbox controller and removes the device-
609
+ * managed resource that was set up to automatically unregister the mailbox
610
+ * controller on driver probe failure or driver removal. It's typically not
611
+ * necessary to call this function.
612
+ */
613
+void devm_mbox_controller_unregister(struct device *dev, struct mbox_controller *mbox)
614
+{
615
+ WARN_ON(devres_release(dev, __devm_mbox_controller_unregister,
616
+ devm_mbox_controller_match, mbox));
617
+}
618
+EXPORT_SYMBOL_GPL(devm_mbox_controller_unregister);