mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] mailbox: Documentation: remove the old documentation
@ 2024-10-19 19:55 anish kumar
  2024-10-19 19:55 ` [PATCH 2/2] mailbox: Documentation: add the latest documentation anish kumar
  0 siblings, 1 reply; 12+ messages in thread
From: anish kumar @ 2024-10-19 19:55 UTC (permalink / raw)
  To: jassisinghbrar, corbet; +Cc: linux-doc, linux-kernel, anish kumar

In preparation of better and latest documentation,
remove the current documentation.

Signed-off-by: anish kumar <yesanishhere@gmail.com>
---
 Documentation/driver-api/mailbox.rst | 129 ---------------------------
 1 file changed, 129 deletions(-)
 delete mode 100644 Documentation/driver-api/mailbox.rst

diff --git a/Documentation/driver-api/mailbox.rst b/Documentation/driver-api/mailbox.rst
deleted file mode 100644
index 0ed95009cc30..000000000000
--- a/Documentation/driver-api/mailbox.rst
+++ /dev/null
@@ -1,129 +0,0 @@
-============================
-The Common Mailbox Framework
-============================
-
-:Author: Jassi Brar <jaswinder.singh@linaro.org>
-
-This document aims to help developers write client and controller
-drivers for the API. But before we start, let us note that the
-client (especially) and controller drivers are likely going to be
-very platform specific because the remote firmware is likely to be
-proprietary and implement non-standard protocol. So even if two
-platforms employ, say, PL320 controller, the client drivers can't
-be shared across them. Even the PL320 driver might need to accommodate
-some platform specific quirks. So the API is meant mainly to avoid
-similar copies of code written for each platform. Having said that,
-nothing prevents the remote f/w to also be Linux based and use the
-same api there. However none of that helps us locally because we only
-ever deal at client's protocol level.
-
-Some of the choices made during implementation are the result of this
-peculiarity of this "common" framework.
-
-
-
-Controller Driver (See include/linux/mailbox_controller.h)
-==========================================================
-
-
-Allocate mbox_controller and the array of mbox_chan.
-Populate mbox_chan_ops, except peek_data() all are mandatory.
-The controller driver might know a message has been consumed
-by the remote by getting an IRQ or polling some hardware flag
-or it can never know (the client knows by way of the protocol).
-The method in order of preference is IRQ -> Poll -> None, which
-the controller driver should set via 'txdone_irq' or 'txdone_poll'
-or neither.
-
-
-Client Driver (See include/linux/mailbox_client.h)
-==================================================
-
-
-The client might want to operate in blocking mode (synchronously
-send a message through before returning) or non-blocking/async mode (submit
-a message and a callback function to the API and return immediately).
-
-::
-
-	struct demo_client {
-		struct mbox_client cl;
-		struct mbox_chan *mbox;
-		struct completion c;
-		bool async;
-		/* ... */
-	};
-
-	/*
-	* This is the handler for data received from remote. The behaviour is purely
-	* dependent upon the protocol. This is just an example.
-	*/
-	static void message_from_remote(struct mbox_client *cl, void *mssg)
-	{
-		struct demo_client *dc = container_of(cl, struct demo_client, cl);
-		if (dc->async) {
-			if (is_an_ack(mssg)) {
-				/* An ACK to our last sample sent */
-				return; /* Or do something else here */
-			} else { /* A new message from remote */
-				queue_req(mssg);
-			}
-		} else {
-			/* Remote f/w sends only ACK packets on this channel */
-			return;
-		}
-	}
-
-	static void sample_sent(struct mbox_client *cl, void *mssg, int r)
-	{
-		struct demo_client *dc = container_of(cl, struct demo_client, cl);
-		complete(&dc->c);
-	}
-
-	static void client_demo(struct platform_device *pdev)
-	{
-		struct demo_client *dc_sync, *dc_async;
-		/* The controller already knows async_pkt and sync_pkt */
-		struct async_pkt ap;
-		struct sync_pkt sp;
-
-		dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
-		dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
-
-		/* Populate non-blocking mode client */
-		dc_async->cl.dev = &pdev->dev;
-		dc_async->cl.rx_callback = message_from_remote;
-		dc_async->cl.tx_done = sample_sent;
-		dc_async->cl.tx_block = false;
-		dc_async->cl.tx_tout = 0; /* doesn't matter here */
-		dc_async->cl.knows_txdone = false; /* depending upon protocol */
-		dc_async->async = true;
-		init_completion(&dc_async->c);
-
-		/* Populate blocking mode client */
-		dc_sync->cl.dev = &pdev->dev;
-		dc_sync->cl.rx_callback = message_from_remote;
-		dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
-		dc_sync->cl.tx_block = true;
-		dc_sync->cl.tx_tout = 500; /* by half a second */
-		dc_sync->cl.knows_txdone = false; /* depending upon protocol */
-		dc_sync->async = false;
-
-		/* ASync mailbox is listed second in 'mboxes' property */
-		dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
-		/* Populate data packet */
-		/* ap.xxx = 123; etc */
-		/* Send async message to remote */
-		mbox_send_message(dc_async->mbox, &ap);
-
-		/* Sync mailbox is listed first in 'mboxes' property */
-		dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
-		/* Populate data packet */
-		/* sp.abc = 123; etc */
-		/* Send message to remote in blocking mode */
-		mbox_send_message(dc_sync->mbox, &sp);
-		/* At this point 'sp' has been sent */
-
-		/* Now wait for async chan to be done */
-		wait_for_completion(&dc_async->c);
-	}
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-19 19:55 [PATCH 1/2] mailbox: Documentation: remove the old documentation anish kumar
@ 2024-10-19 19:55 ` anish kumar
  2024-10-24 18:42   ` anish kumar
  2024-10-25  3:38   ` Bagas Sanjaya
  0 siblings, 2 replies; 12+ messages in thread
From: anish kumar @ 2024-10-19 19:55 UTC (permalink / raw)
  To: jassisinghbrar, corbet; +Cc: linux-doc, linux-kernel, anish kumar

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 23131 bytes --]

1. added client documentation
2. added controller documentation.
3. added framework documentation

Signed-off-by: anish kumar <yesanishhere@gmail.com>
---
 Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
 Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
 Documentation/driver-api/mailbox/index.rst    |  45 ++++
 .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
 4 files changed, 598 insertions(+)
 create mode 100644 Documentation/driver-api/mailbox/client.rst
 create mode 100644 Documentation/driver-api/mailbox/core.rst
 create mode 100644 Documentation/driver-api/mailbox/index.rst
 create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst

diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
new file mode 100644
index 000000000000..9088f8373423
--- /dev/null
+++ b/Documentation/driver-api/mailbox/client.rst
@@ -0,0 +1,192 @@
+Mailbox Client Documentation
+============================
+
+Overview
+--------
+The mailbox client driver is responsible for sending and receiving messages
+to and from a remote processor. It uses mailbox APIs provided by the
+mailbox framework.
+
+Mailbox Structure
+-----------------
+The mailbox structure is defined as follows:
+
+.. code-block:: c
+
+   struct mbox_client {
+       //device associated with the mailbox
+       struct device *dev;
+       // callback for transmission completion
+       void (*tx_done)(struct mbox_client *client);
+       // callback to prepare for sending a message
+       void (*tx_prepare)(struct mbox_client *client);
+       // callback for received messages
+       void (*rx_callback)(struct mbox_client *client, void *data);
+       // flag to indicate if transmission should block
+       bool tx_block;
+       // indicates if the client knows when transmission is done
+       bool knows_txdone;
+   };
+
+Key Functions
+-------------
+1. Requesting a Mailbox Channel
+   - **Function**: `mbox_request_channel(struct mbox_client *client,
+     unsigned int channel)`
+   - **Description**: Requests a mailbox channel for sending messages.
+   - **Parameters**:
+     - `client`: Pointer to the mailbox client structure.
+     - `channel`: The specific mailbox channel to request.
+   - **Returns**: A pointer to the mailbox channel on success, or an error
+     code on failure.
+
+2. Sending a Message
+   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
+   - **Description**: Sends a message through the mailbox channel.
+   - **Parameters**:
+     - `chan`: The mailbox channel used for communication.
+     - `msg`: Pointer to the message to be sent (usually NULL for dummy
+       messages).
+   - **Returns**: 0 on success, or a negative error code on failure.
+
+3. Transmitting Completion
+   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
+     msg_id)`
+   - **Description**: Notifies the mailbox framework that message
+     transmission is complete.
+   - **Parameters**:
+     - `chan`: The mailbox channel associated with the message.
+     - `msg_id`: The identifier of the message that was transmitted.
+
+Usage Example
+-------------
+In a typical mailbox client driver, the following steps are typically
+performed:
+
+1. Initialize the Mailbox Client:
+
+   .. code-block:: c
+
+      struct mbox_client my_mbox_client = {
+          .dev = &my_device,
+          .tx_done = my_tx_done_callback,
+          .rx_callback = my_rx_callback,
+          .tx_block = false,
+          .knows_txdone = true,
+      };
+
+2. Request a Mailbox Channel:
+
+   .. code-block:: c
+
+      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
+      if (IS_ERR(mbox_chan)) {
+          // Handle error
+      }
+
+3. Send a Message:
+
+   .. code-block:: c
+
+      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
+      if (ret < 0) {
+          // Handle error
+      }
+
+4. Complete Transmission:
+
+   .. code-block:: c
+
+      mbox_client_txdone(mbox_chan, 0);
+
+Interrupt Handling
+------------------
+The mailbox interface can trigger interrupts upon message receipt. Handlers
+should be implemented in the `rx_callback` function defined in the mailbox
+client structure to process incoming messages.
+
+Example Mailbox Client Driver
+-----------------------------
+.. code-block:: c
+
+   struct demo_client {
+       struct mbox_client cl;
+       struct mbox_chan *mbox;
+       struct completion c;
+       bool async;
+       /* ... */
+   };
+
+   /*
+   * This is the handler for data received from remote. The behaviour is purely
+   * dependent upon the protocol. This is just an example.
+   */
+   static void message_from_remote(struct mbox_client *cl, void *mssg)
+   {
+       struct demo_client *dc = container_of(cl, struct demo_client, cl);
+       if (dc->async) {
+           if (is_an_ack(mssg)) {
+               /* An ACK to our last sample sent */
+               return; /* Or do something else here */
+           } else { /* A new message from remote */
+               queue_req(mssg);
+           }
+       } else {
+           /* Remote f/w sends only ACK packets on this channel */
+           return;
+       }
+   }
+
+   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
+   {
+       struct demo_client *dc = container_of(cl, struct demo_client, cl);
+       complete(&dc->c);
+   }
+
+   static void client_demo(struct platform_device *pdev)
+   {
+       struct demo_client *dc_sync, *dc_async;
+       /* The controller already knows async_pkt and sync_pkt */
+       struct async_pkt ap;
+       struct sync_pkt sp;
+
+       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
+       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
+
+       /* Populate non-blocking mode client */
+       dc_async->cl.dev = &pdev->dev;
+       dc_async->cl.rx_callback = message_from_remote;
+       dc_async->cl.tx_done = sample_sent;
+       dc_async->cl.tx_block = false;
+       dc_async->cl.tx_tout = 0; /* doesn't matter here */
+       dc_async->cl.knows_txdone = false; /* depending upon protocol */
+       dc_async->async = true;
+       init_completion(&dc_async->c);
+
+       /* Populate blocking mode client */
+       dc_sync->cl.dev = &pdev->dev;
+       dc_sync->cl.rx_callback = message_from_remote;
+       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
+       dc_sync->cl.tx_block = true;
+       dc_sync->cl.tx_tout = 500; /* by half a second */
+       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
+       dc_sync->async = false;
+
+       /* ASync mailbox is listed second in 'mboxes' property */
+       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
+       /* Populate data packet */
+       /* ap.xxx = 123; etc */
+       /* Send async message to remote */
+       mbox_send_message(dc_async->mbox, &ap);
+
+       /* Sync mailbox is listed first in 'mboxes' property */
+       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
+       /* Populate data packet */
+       /* sp.abc = 123; etc */
+       /* Send message to remote in blocking mode */
+       mbox_send_message(dc_sync->mbox, &sp);
+       /* At this point 'sp' has been sent */
+
+       /* Now wait for async chan to be done */
+       wait_for_completion(&dc_async->c);
+   }
diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
new file mode 100644
index 000000000000..d1220086da67
--- /dev/null
+++ b/Documentation/driver-api/mailbox/core.rst
@@ -0,0 +1,182 @@
+=====================
+mailbox documentation
+=====================
+
+Hardware Introduction
+=====================
+
+Mailbox hardware is a specialized component found in multi-core
+processors and embedded systems that facilitates inter-processor
+communication (IPC) or communication between different hardware
+components. It provides a structured mechanism for sending and
+receiving messages, allowing various processors or devices to
+exchange data efficiently. Here's an overview of its key
+characteristics and functions:
+
+Key Characteristics of Mailbox Hardware
+Interrupt Handling: Many mailbox implementations support
+interrupt-driven communication. This allows a receiving processor
+to be alerted when a new message arrives, facilitating immediate
+processing without polling the mailbox constantly.
+
+Hardware Registers: Mailbox hardware often includes registers for
+configuration and status monitoring. These registers can be used
+to control the mailbox's behavior, check for available messages,
+or acknowledge message receipt.
+
+Support for Multiple Protocols: Mailboxes can support various
+communication protocols, enabling interoperability between different
+hardware components and simplifying the integration of diverse systems.
+
+Synchronous and Asynchronous Modes: Mailbox hardware can operate in
+both synchronous and asynchronous modes. In synchronous mode, the
+sender may wait for the receiver to acknowledge receipt before
+proceeding, while in asynchronous mode, the sender can continue
+executing other tasks immediately after sending the message.
+
+
+Mailbox framework design
+========================
+
+The mailbox facilitates interprocessor communication by allowing processors to
+exchange messages or signals. The mailbox framework consists of:
+
+Mailbox Controller: This is platform-specific and is responsible for configuring
+and managing interrupts from the remote processor. It offers a generic API for
+the mailbox client.
+
+Mailbox Client: This component handles the sending and receiving of messages.
+
+
+............................................................................
+:  client driver      client_a            client_b                         :
+............................................................................
+                            ^-------------------^
+                                    |
+                                    |
+............................................................................
+:  controller framework          mailbox                                   :
+....................................|.......................................
+                                    |
+                                    |
+............................................................................
+:  controller driver          device specific                              :
+....................................|.......................................
+                                    |
+                                    |
+kernel                              |
+............................................................................
+hardware                            |
+                                    |
+                                    |
+............................................................................
+:                             remote processor                             :
+............................................................................
+
+
+In the context of a mailbox framework, a channel refers to a dedicated
+communication pathway between two or more processors or components. By using
+channels, the framework abstracts the complexity of interprocessor communication.
+
+Data Structures
+================
+
+- **struct mbox_client**
+  This structure represents a client that communicates over a mailbox
+  channel. It holds information such as:
+  - A pointer to the device associated with the client (`dev`).
+  - Callback functions for handling message transmission events, including:
+    - `rx_callback`: Called when a message is received.
+    - `tx_done`: Called when a message transmission is acknowledged.
+  - Flags that specify the client’s configuration, such as whether it operates
+    in blocking mode.
+
+- **struct mbox_chan**
+  This structure represents an individual mailbox channel. It maintains the
+  state required for message queuing and transmission. Key members include:
+  - `msg_data`: Array of messages queued for transmission.
+  - `msg_count`: Number of messages currently queued.
+  - `msg_free`: Index of the next free slot in the message queue.
+  - `active_req`: Pointer to the currently active message being transmitted.
+  - Synchronization primitives to manage access from multiple contexts.
+
+- **struct mbox_controller**
+  This structure represents a mailbox controller that manages multiple
+  channels. It includes:
+  - A pointer to the device managing the mailbox.
+  - Operations for sending and receiving messages, as well as initializing
+    and shutting down the mailbox.
+  - A list of associated channels and the total number of channels available.
+
+controller framework APIs
+=========================
+
+``struct `mbox_controller` Initialization
+-----------------------------------------
+
+Just like any other kernel framework, the whole mailbox controller registration
+relies on the driver filling a structure and registering against the
+framework. In our case, that structure is mbox_controller.
+
+The first thing you need to do in your driver is to allocate this
+structure. Any of the usual memory allocators will do, but you'll also
+need to initialize a few fields in there:
+
+- ``dev``: should hold the pointer to the ``struct device`` associated
+  to your current driver instance.
+
+- ``ops``: Operators that work on each communication channel.
+
+- ``chans``: Array of channels.
+
+- ``num_chans``: Number of channels in the `chans` array.
+
+- ``txdone_irq``: Indicates if the controller can report to the API
+  when the last transmitted data was read by the
+                          remote (e.g., if it has a TX ACK interrupt).
+
+All the below fields are not mandatory.
+
+- ``txdone_poll``: Indicates if the controller can read but not report
+                          the TX done. For example, some register may show
+                          the TX status, but no interrupt is raised. This
+                          field is ignored if `txdone_irq` is set.
+
+- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
+                          the last TX status after this many milliseconds.
+
+- ``of_xlate``: Controller driver-specific mapping of channel via
+                          Device Tree (DT).
+
+
+Key Functions
+-------------
+
+- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
+  This function registers a mailbox controller with the kernel. It makes the
+  channels associated with the controller available for client requests. The
+  function performs sanity checks on the controller structure to ensure all
+  necessary fields are populated.
+
+- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
+  This function requests a mailbox channel for a specified client, identified
+  by an index. It searches for the appropriate mailbox channel, and if found,
+  it returns a pointer to the channel. If the request fails (e.g., if the
+  index is invalid), it returns an error pointer.
+
+- **void mbox_free_channel(struct mbox_chan *chan)**
+  This function releases a mailbox channel that was previously allocated for a
+  client. It ensures that the channel can be reused by other clients. If any
+  messages are still in the queue, they are aborted, and no callbacks are made.
+
+- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
+  This function is used by clients to send a message through the specified
+  mailbox channel. The function can operate in either blocking or non-blocking
+  mode, depending on the client’s configuration. It will queue the message for
+  transmission and notify the client once the message is acknowledged.
+
+- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
+  This function is called by the controller driver to notify the mailbox
+  framework that a message has been received on the specified channel. The
+  received message is then passed to the appropriate client's `rx_callback`
+  function for processing.
diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
new file mode 100644
index 000000000000..e254a8fdb66a
--- /dev/null
+++ b/Documentation/driver-api/mailbox/index.rst
@@ -0,0 +1,45 @@
+=======================
+Mailbox documentation
+=======================
+
+Mailbox documentation provides documents for various aspects of mailbox
+framework.
+
+Mailbox development documentation
+---------------------------------
+
+This book helps with mailbox internal APIs and guide for mailbox device
+driver writers.
+
+.. toctree::
+   :maxdepth: 1
+
+   core
+
+mailbox controller driver documentation
+------------------------------
+
+This book is a guide to device driver writers on how to register
+mailbox controller to the mailbox framework.
+
+.. toctree::
+   :maxdepth: 1
+
+   writing_mailbox_controller_drivers
+
+mailbox client driver documentation
+------------------------------
+
+This book is a guide to mailbox client driver writers.
+
+.. toctree::
+   :maxdepth: 1
+
+   client
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
new file mode 100644
index 000000000000..2a82645c1357
--- /dev/null
+++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
@@ -0,0 +1,179 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _writing_mailbox_controller_drivers:
+
+==================================
+Writing Mailbox Controller Drivers
+==================================
+
+Introduction
+============
+
+This document serves as a basic guideline for driver programmers that need
+to hack a new mailbox controller driver or understand the essentials of
+the existing ones.
+
+Driver Boilerplate
+==================
+
+As a bare minimum, a mailbox controller driver needs to call
+``mbox_controller_register`` function to register with the framework.
+
+A basic driver skeleton could look like this for a mailbox hardware that
+has the following characteristics:
+a. It supports only a single channel, i.e., only the remote processor can
+   send interrupts.
+b. Data transfer is over the registers associated with mailbox hardware.
+c. Mailbox hardware is configured to receive interrupts.
+d. When the remote processor is ready to send data, it triggers a mailbox
+   interrupt.
+e. As part of interrupt handling by Linux, it copies data from the registers.
+
+.. code-block:: c
+
+   #include <linux/device.h>
+   #include <linux/interrupt.h>
+   #include <linux/io.h>
+   #include <linux/kernel.h>
+   #include <linux/mailbox_controller.h>
+   #include <linux/module.h>
+   #include <linux/of.h>
+   #include <linux/platform_device.h>
+   #define DRIVER_NAME "dummy_controller"
+
+   struct dummy_mbox {
+       struct device *dev;
+       struct mbox_controller controller;
+       int irq;
+   };
+
+   static void dummy_mbox_receive(struct mbox_chan *chan)
+   {
+       struct dummy_mbox *mbox = chan->con_priv;
+       int val;
+
+       // Data copied from registers
+       val = read_register();
+       mbox_chan_received_data(chan, &val);
+   }
+
+   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
+   {
+       struct mbox_chan *chan = data;
+       struct dummy_mbox *mbox = chan->con_priv;
+       u32 reg;
+
+       // Read registers to see if data is received
+       dummy_mbox_receive(chan);
+       mbox_chan_txdone(chan, 0);
+       return reg ? IRQ_HANDLED : IRQ_NONE;
+   }
+
+   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
+   {
+       // Write data in registers to send it to the remote processor
+       return 0;
+   }
+
+   static int dummy_mbox_startup(struct mbox_chan *chan)
+   {
+       struct dummy_mbox *mbox = chan->con_priv;
+       u32 reg;
+       int ret;
+
+       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
+               DRIVER_NAME, chan);
+       if (ret < 0) {
+           dev_err(mbox->dev, "Cannot request irq\n");
+           return ret;
+       }
+
+       /* Register write to enable IRQ generation */
+
+       return 0;
+   }
+
+   static void dummy_mbox_shutdown(struct mbox_chan *chan)
+   {
+       struct dummy_mbox *mbox = chan->con_priv;
+
+       /* Disable interrupt generation */
+       devm_free_irq(mbox->dev, mbox->irq, chan);
+   }
+
+   static const struct mbox_chan_ops dummy_mbox_ops = {
+       .send_data = dummy_mbox_send_data,
+       .startup = dummy_mbox_startup,
+       .shutdown = dummy_mbox_shutdown,
+   };
+
+   static int dummy_mbox_probe(struct platform_device *pdev)
+   {
+       struct dummy_mbox *mbox;
+       struct mbox_chan *chans;
+       int ret;
+
+       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
+       if (!mbox)
+           return -ENOMEM;
+
+       /* Allocate one channel */
+       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
+       if (!chans)
+           return -ENOMEM;
+
+       mbox->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(mbox->base))
+           return PTR_ERR(mbox->base);
+
+       mbox->irq = platform_get_irq(pdev, 0);
+       if (mbox->irq < 0)
+           return mbox->irq;
+
+       mbox->dev = &pdev->dev;
+
+       /* Hardware supports only one channel. */
+       mbox->controller.dev = mbox->dev;
+       mbox->controller.num_chans = 1;
+       mbox->controller.chans = chans;
+       mbox->controller.ops = &dummy_mbox_ops;
+       mbox->controller.txdone_irq = true;
+
+       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
+       if (ret) {
+           dev_err(&pdev->dev, "Could not register mailbox controller\n");
+           return ret;
+       }
+
+       return ret;
+   }
+
+   static const struct of_device_id dummy_mbox_match[] = {
+       { .compatible = "dummy,dummy-mailbox" },
+       { },
+   };
+
+   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
+
+   static struct platform_driver dummy_mbox_driver = {
+       .probe = dummy_mbox_probe,
+       .driver = {
+           .name = DRIVER_NAME,
+           .of_match_table = dummy_mbox_match,
+       },
+   };
+
+   module_platform_driver(dummy_mbox_driver);
+   MODULE_LICENSE("GPL v2");
+   MODULE_DESCRIPTION("Dummy mailbox controller driver");
+
+In the above code, a couple of things are done:
+a. The controller is registered in the probe along with callbacks, which in
+   this case are the bare minimum: ``startup``, ``shutdown``, and
+   ``send_data``.
+b. IRQ is registered to get notifications from the remote processor.
+c. In the IRQ handler, registers are read to copy data, and
+   ``mbox_chan_received_data`` is called to hand over the data to the client.
+d. ``mbox_chan_txdone`` is called to let the framework know that this data
+   is the last data and no more data is to be expected for the current transfer.
+
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-19 19:55 ` [PATCH 2/2] mailbox: Documentation: add the latest documentation anish kumar
@ 2024-10-24 18:42   ` anish kumar
  2024-10-25  3:38   ` Bagas Sanjaya
  1 sibling, 0 replies; 12+ messages in thread
From: anish kumar @ 2024-10-24 18:42 UTC (permalink / raw)
  To: jassisinghbrar, corbet; +Cc: linux-doc, linux-kernel

Jassi,

Wondering if you have any comments. Thanks.

On Sat, Oct 19, 2024 at 12:55 PM anish kumar <yesanishhere@gmail.com> wrote:
>
> 1. added client documentation
> 2. added controller documentation.
> 3. added framework documentation
>
> Signed-off-by: anish kumar <yesanishhere@gmail.com>
> ---
>  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
>  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
>  Documentation/driver-api/mailbox/index.rst    |  45 ++++
>  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
>  4 files changed, 598 insertions(+)
>  create mode 100644 Documentation/driver-api/mailbox/client.rst
>  create mode 100644 Documentation/driver-api/mailbox/core.rst
>  create mode 100644 Documentation/driver-api/mailbox/index.rst
>  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
>
> diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> new file mode 100644
> index 000000000000..9088f8373423
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/client.rst
> @@ -0,0 +1,192 @@
> +Mailbox Client Documentation
> +============================
> +
> +Overview
> +--------
> +The mailbox client driver is responsible for sending and receiving messages
> +to and from a remote processor. It uses mailbox APIs provided by the
> +mailbox framework.
> +
> +Mailbox Structure
> +-----------------
> +The mailbox structure is defined as follows:
> +
> +.. code-block:: c
> +
> +   struct mbox_client {
> +       //device associated with the mailbox
> +       struct device *dev;
> +       // callback for transmission completion
> +       void (*tx_done)(struct mbox_client *client);
> +       // callback to prepare for sending a message
> +       void (*tx_prepare)(struct mbox_client *client);
> +       // callback for received messages
> +       void (*rx_callback)(struct mbox_client *client, void *data);
> +       // flag to indicate if transmission should block
> +       bool tx_block;
> +       // indicates if the client knows when transmission is done
> +       bool knows_txdone;
> +   };
> +
> +Key Functions
> +-------------
> +1. Requesting a Mailbox Channel
> +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> +     unsigned int channel)`
> +   - **Description**: Requests a mailbox channel for sending messages.
> +   - **Parameters**:
> +     - `client`: Pointer to the mailbox client structure.
> +     - `channel`: The specific mailbox channel to request.
> +   - **Returns**: A pointer to the mailbox channel on success, or an error
> +     code on failure.
> +
> +2. Sending a Message
> +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> +   - **Description**: Sends a message through the mailbox channel.
> +   - **Parameters**:
> +     - `chan`: The mailbox channel used for communication.
> +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> +       messages).
> +   - **Returns**: 0 on success, or a negative error code on failure.
> +
> +3. Transmitting Completion
> +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> +     msg_id)`
> +   - **Description**: Notifies the mailbox framework that message
> +     transmission is complete.
> +   - **Parameters**:
> +     - `chan`: The mailbox channel associated with the message.
> +     - `msg_id`: The identifier of the message that was transmitted.
> +
> +Usage Example
> +-------------
> +In a typical mailbox client driver, the following steps are typically
> +performed:
> +
> +1. Initialize the Mailbox Client:
> +
> +   .. code-block:: c
> +
> +      struct mbox_client my_mbox_client = {
> +          .dev = &my_device,
> +          .tx_done = my_tx_done_callback,
> +          .rx_callback = my_rx_callback,
> +          .tx_block = false,
> +          .knows_txdone = true,
> +      };
> +
> +2. Request a Mailbox Channel:
> +
> +   .. code-block:: c
> +
> +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> +      if (IS_ERR(mbox_chan)) {
> +          // Handle error
> +      }
> +
> +3. Send a Message:
> +
> +   .. code-block:: c
> +
> +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> +      if (ret < 0) {
> +          // Handle error
> +      }
> +
> +4. Complete Transmission:
> +
> +   .. code-block:: c
> +
> +      mbox_client_txdone(mbox_chan, 0);
> +
> +Interrupt Handling
> +------------------
> +The mailbox interface can trigger interrupts upon message receipt. Handlers
> +should be implemented in the `rx_callback` function defined in the mailbox
> +client structure to process incoming messages.
> +
> +Example Mailbox Client Driver
> +-----------------------------
> +.. code-block:: c
> +
> +   struct demo_client {
> +       struct mbox_client cl;
> +       struct mbox_chan *mbox;
> +       struct completion c;
> +       bool async;
> +       /* ... */
> +   };
> +
> +   /*
> +   * This is the handler for data received from remote. The behaviour is purely
> +   * dependent upon the protocol. This is just an example.
> +   */
> +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> +   {
> +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> +       if (dc->async) {
> +           if (is_an_ack(mssg)) {
> +               /* An ACK to our last sample sent */
> +               return; /* Or do something else here */
> +           } else { /* A new message from remote */
> +               queue_req(mssg);
> +           }
> +       } else {
> +           /* Remote f/w sends only ACK packets on this channel */
> +           return;
> +       }
> +   }
> +
> +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> +   {
> +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> +       complete(&dc->c);
> +   }
> +
> +   static void client_demo(struct platform_device *pdev)
> +   {
> +       struct demo_client *dc_sync, *dc_async;
> +       /* The controller already knows async_pkt and sync_pkt */
> +       struct async_pkt ap;
> +       struct sync_pkt sp;
> +
> +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> +
> +       /* Populate non-blocking mode client */
> +       dc_async->cl.dev = &pdev->dev;
> +       dc_async->cl.rx_callback = message_from_remote;
> +       dc_async->cl.tx_done = sample_sent;
> +       dc_async->cl.tx_block = false;
> +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> +       dc_async->async = true;
> +       init_completion(&dc_async->c);
> +
> +       /* Populate blocking mode client */
> +       dc_sync->cl.dev = &pdev->dev;
> +       dc_sync->cl.rx_callback = message_from_remote;
> +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> +       dc_sync->cl.tx_block = true;
> +       dc_sync->cl.tx_tout = 500; /* by half a second */
> +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> +       dc_sync->async = false;
> +
> +       /* ASync mailbox is listed second in 'mboxes' property */
> +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> +       /* Populate data packet */
> +       /* ap.xxx = 123; etc */
> +       /* Send async message to remote */
> +       mbox_send_message(dc_async->mbox, &ap);
> +
> +       /* Sync mailbox is listed first in 'mboxes' property */
> +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> +       /* Populate data packet */
> +       /* sp.abc = 123; etc */
> +       /* Send message to remote in blocking mode */
> +       mbox_send_message(dc_sync->mbox, &sp);
> +       /* At this point 'sp' has been sent */
> +
> +       /* Now wait for async chan to be done */
> +       wait_for_completion(&dc_async->c);
> +   }
> diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> new file mode 100644
> index 000000000000..d1220086da67
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/core.rst
> @@ -0,0 +1,182 @@
> +=====================
> +mailbox documentation
> +=====================
> +
> +Hardware Introduction
> +=====================
> +
> +Mailbox hardware is a specialized component found in multi-core
> +processors and embedded systems that facilitates inter-processor
> +communication (IPC) or communication between different hardware
> +components. It provides a structured mechanism for sending and
> +receiving messages, allowing various processors or devices to
> +exchange data efficiently. Here's an overview of its key
> +characteristics and functions:
> +
> +Key Characteristics of Mailbox Hardware
> +Interrupt Handling: Many mailbox implementations support
> +interrupt-driven communication. This allows a receiving processor
> +to be alerted when a new message arrives, facilitating immediate
> +processing without polling the mailbox constantly.
> +
> +Hardware Registers: Mailbox hardware often includes registers for
> +configuration and status monitoring. These registers can be used
> +to control the mailbox's behavior, check for available messages,
> +or acknowledge message receipt.
> +
> +Support for Multiple Protocols: Mailboxes can support various
> +communication protocols, enabling interoperability between different
> +hardware components and simplifying the integration of diverse systems.
> +
> +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> +both synchronous and asynchronous modes. In synchronous mode, the
> +sender may wait for the receiver to acknowledge receipt before
> +proceeding, while in asynchronous mode, the sender can continue
> +executing other tasks immediately after sending the message.
> +
> +
> +Mailbox framework design
> +========================
> +
> +The mailbox facilitates interprocessor communication by allowing processors to
> +exchange messages or signals. The mailbox framework consists of:
> +
> +Mailbox Controller: This is platform-specific and is responsible for configuring
> +and managing interrupts from the remote processor. It offers a generic API for
> +the mailbox client.
> +
> +Mailbox Client: This component handles the sending and receiving of messages.
> +
> +
> +............................................................................
> +:  client driver      client_a            client_b                         :
> +............................................................................
> +                            ^-------------------^
> +                                    |
> +                                    |
> +............................................................................
> +:  controller framework          mailbox                                   :
> +....................................|.......................................
> +                                    |
> +                                    |
> +............................................................................
> +:  controller driver          device specific                              :
> +....................................|.......................................
> +                                    |
> +                                    |
> +kernel                              |
> +............................................................................
> +hardware                            |
> +                                    |
> +                                    |
> +............................................................................
> +:                             remote processor                             :
> +............................................................................
> +
> +
> +In the context of a mailbox framework, a channel refers to a dedicated
> +communication pathway between two or more processors or components. By using
> +channels, the framework abstracts the complexity of interprocessor communication.
> +
> +Data Structures
> +================
> +
> +- **struct mbox_client**
> +  This structure represents a client that communicates over a mailbox
> +  channel. It holds information such as:
> +  - A pointer to the device associated with the client (`dev`).
> +  - Callback functions for handling message transmission events, including:
> +    - `rx_callback`: Called when a message is received.
> +    - `tx_done`: Called when a message transmission is acknowledged.
> +  - Flags that specify the client’s configuration, such as whether it operates
> +    in blocking mode.
> +
> +- **struct mbox_chan**
> +  This structure represents an individual mailbox channel. It maintains the
> +  state required for message queuing and transmission. Key members include:
> +  - `msg_data`: Array of messages queued for transmission.
> +  - `msg_count`: Number of messages currently queued.
> +  - `msg_free`: Index of the next free slot in the message queue.
> +  - `active_req`: Pointer to the currently active message being transmitted.
> +  - Synchronization primitives to manage access from multiple contexts.
> +
> +- **struct mbox_controller**
> +  This structure represents a mailbox controller that manages multiple
> +  channels. It includes:
> +  - A pointer to the device managing the mailbox.
> +  - Operations for sending and receiving messages, as well as initializing
> +    and shutting down the mailbox.
> +  - A list of associated channels and the total number of channels available.
> +
> +controller framework APIs
> +=========================
> +
> +``struct `mbox_controller` Initialization
> +-----------------------------------------
> +
> +Just like any other kernel framework, the whole mailbox controller registration
> +relies on the driver filling a structure and registering against the
> +framework. In our case, that structure is mbox_controller.
> +
> +The first thing you need to do in your driver is to allocate this
> +structure. Any of the usual memory allocators will do, but you'll also
> +need to initialize a few fields in there:
> +
> +- ``dev``: should hold the pointer to the ``struct device`` associated
> +  to your current driver instance.
> +
> +- ``ops``: Operators that work on each communication channel.
> +
> +- ``chans``: Array of channels.
> +
> +- ``num_chans``: Number of channels in the `chans` array.
> +
> +- ``txdone_irq``: Indicates if the controller can report to the API
> +  when the last transmitted data was read by the
> +                          remote (e.g., if it has a TX ACK interrupt).
> +
> +All the below fields are not mandatory.
> +
> +- ``txdone_poll``: Indicates if the controller can read but not report
> +                          the TX done. For example, some register may show
> +                          the TX status, but no interrupt is raised. This
> +                          field is ignored if `txdone_irq` is set.
> +
> +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> +                          the last TX status after this many milliseconds.
> +
> +- ``of_xlate``: Controller driver-specific mapping of channel via
> +                          Device Tree (DT).
> +
> +
> +Key Functions
> +-------------
> +
> +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> +  This function registers a mailbox controller with the kernel. It makes the
> +  channels associated with the controller available for client requests. The
> +  function performs sanity checks on the controller structure to ensure all
> +  necessary fields are populated.
> +
> +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> +  This function requests a mailbox channel for a specified client, identified
> +  by an index. It searches for the appropriate mailbox channel, and if found,
> +  it returns a pointer to the channel. If the request fails (e.g., if the
> +  index is invalid), it returns an error pointer.
> +
> +- **void mbox_free_channel(struct mbox_chan *chan)**
> +  This function releases a mailbox channel that was previously allocated for a
> +  client. It ensures that the channel can be reused by other clients. If any
> +  messages are still in the queue, they are aborted, and no callbacks are made.
> +
> +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> +  This function is used by clients to send a message through the specified
> +  mailbox channel. The function can operate in either blocking or non-blocking
> +  mode, depending on the client’s configuration. It will queue the message for
> +  transmission and notify the client once the message is acknowledged.
> +
> +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> +  This function is called by the controller driver to notify the mailbox
> +  framework that a message has been received on the specified channel. The
> +  received message is then passed to the appropriate client's `rx_callback`
> +  function for processing.
> diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> new file mode 100644
> index 000000000000..e254a8fdb66a
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/index.rst
> @@ -0,0 +1,45 @@
> +=======================
> +Mailbox documentation
> +=======================
> +
> +Mailbox documentation provides documents for various aspects of mailbox
> +framework.
> +
> +Mailbox development documentation
> +---------------------------------
> +
> +This book helps with mailbox internal APIs and guide for mailbox device
> +driver writers.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   core
> +
> +mailbox controller driver documentation
> +------------------------------
> +
> +This book is a guide to device driver writers on how to register
> +mailbox controller to the mailbox framework.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   writing_mailbox_controller_drivers
> +
> +mailbox client driver documentation
> +------------------------------
> +
> +This book is a guide to mailbox client driver writers.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   client
> +
> +.. only::  subproject and html
> +
> +   Indices
> +   =======
> +
> +   * :ref:`genindex`
> diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> new file mode 100644
> index 000000000000..2a82645c1357
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> @@ -0,0 +1,179 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. _writing_mailbox_controller_drivers:
> +
> +==================================
> +Writing Mailbox Controller Drivers
> +==================================
> +
> +Introduction
> +============
> +
> +This document serves as a basic guideline for driver programmers that need
> +to hack a new mailbox controller driver or understand the essentials of
> +the existing ones.
> +
> +Driver Boilerplate
> +==================
> +
> +As a bare minimum, a mailbox controller driver needs to call
> +``mbox_controller_register`` function to register with the framework.
> +
> +A basic driver skeleton could look like this for a mailbox hardware that
> +has the following characteristics:
> +a. It supports only a single channel, i.e., only the remote processor can
> +   send interrupts.
> +b. Data transfer is over the registers associated with mailbox hardware.
> +c. Mailbox hardware is configured to receive interrupts.
> +d. When the remote processor is ready to send data, it triggers a mailbox
> +   interrupt.
> +e. As part of interrupt handling by Linux, it copies data from the registers.
> +
> +.. code-block:: c
> +
> +   #include <linux/device.h>
> +   #include <linux/interrupt.h>
> +   #include <linux/io.h>
> +   #include <linux/kernel.h>
> +   #include <linux/mailbox_controller.h>
> +   #include <linux/module.h>
> +   #include <linux/of.h>
> +   #include <linux/platform_device.h>
> +   #define DRIVER_NAME "dummy_controller"
> +
> +   struct dummy_mbox {
> +       struct device *dev;
> +       struct mbox_controller controller;
> +       int irq;
> +   };
> +
> +   static void dummy_mbox_receive(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       int val;
> +
> +       // Data copied from registers
> +       val = read_register();
> +       mbox_chan_received_data(chan, &val);
> +   }
> +
> +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> +   {
> +       struct mbox_chan *chan = data;
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       u32 reg;
> +
> +       // Read registers to see if data is received
> +       dummy_mbox_receive(chan);
> +       mbox_chan_txdone(chan, 0);
> +       return reg ? IRQ_HANDLED : IRQ_NONE;
> +   }
> +
> +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> +   {
> +       // Write data in registers to send it to the remote processor
> +       return 0;
> +   }
> +
> +   static int dummy_mbox_startup(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       u32 reg;
> +       int ret;
> +
> +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> +               DRIVER_NAME, chan);
> +       if (ret < 0) {
> +           dev_err(mbox->dev, "Cannot request irq\n");
> +           return ret;
> +       }
> +
> +       /* Register write to enable IRQ generation */
> +
> +       return 0;
> +   }
> +
> +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +
> +       /* Disable interrupt generation */
> +       devm_free_irq(mbox->dev, mbox->irq, chan);
> +   }
> +
> +   static const struct mbox_chan_ops dummy_mbox_ops = {
> +       .send_data = dummy_mbox_send_data,
> +       .startup = dummy_mbox_startup,
> +       .shutdown = dummy_mbox_shutdown,
> +   };
> +
> +   static int dummy_mbox_probe(struct platform_device *pdev)
> +   {
> +       struct dummy_mbox *mbox;
> +       struct mbox_chan *chans;
> +       int ret;
> +
> +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> +       if (!mbox)
> +           return -ENOMEM;
> +
> +       /* Allocate one channel */
> +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> +       if (!chans)
> +           return -ENOMEM;
> +
> +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(mbox->base))
> +           return PTR_ERR(mbox->base);
> +
> +       mbox->irq = platform_get_irq(pdev, 0);
> +       if (mbox->irq < 0)
> +           return mbox->irq;
> +
> +       mbox->dev = &pdev->dev;
> +
> +       /* Hardware supports only one channel. */
> +       mbox->controller.dev = mbox->dev;
> +       mbox->controller.num_chans = 1;
> +       mbox->controller.chans = chans;
> +       mbox->controller.ops = &dummy_mbox_ops;
> +       mbox->controller.txdone_irq = true;
> +
> +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> +       if (ret) {
> +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> +           return ret;
> +       }
> +
> +       return ret;
> +   }
> +
> +   static const struct of_device_id dummy_mbox_match[] = {
> +       { .compatible = "dummy,dummy-mailbox" },
> +       { },
> +   };
> +
> +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> +
> +   static struct platform_driver dummy_mbox_driver = {
> +       .probe = dummy_mbox_probe,
> +       .driver = {
> +           .name = DRIVER_NAME,
> +           .of_match_table = dummy_mbox_match,
> +       },
> +   };
> +
> +   module_platform_driver(dummy_mbox_driver);
> +   MODULE_LICENSE("GPL v2");
> +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> +
> +In the above code, a couple of things are done:
> +a. The controller is registered in the probe along with callbacks, which in
> +   this case are the bare minimum: ``startup``, ``shutdown``, and
> +   ``send_data``.
> +b. IRQ is registered to get notifications from the remote processor.
> +c. In the IRQ handler, registers are read to copy data, and
> +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> +   is the last data and no more data is to be expected for the current transfer.
> +
> --
> 2.39.3 (Apple Git-146)
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-19 19:55 ` [PATCH 2/2] mailbox: Documentation: add the latest documentation anish kumar
  2024-10-24 18:42   ` anish kumar
@ 2024-10-25  3:38   ` Bagas Sanjaya
  2024-10-25 19:24     ` anish kumar
  1 sibling, 1 reply; 12+ messages in thread
From: Bagas Sanjaya @ 2024-10-25  3:38 UTC (permalink / raw)
  To: anish kumar, jassisinghbrar, corbet; +Cc: linux-doc, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 37328 bytes --]

On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> 1. added client documentation
> 2. added controller documentation.
> 3. added framework documentation

One doc topic on each patch, please.

> 
> Signed-off-by: anish kumar <yesanishhere@gmail.com>
> ---
>  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
>  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
>  Documentation/driver-api/mailbox/index.rst    |  45 ++++
>  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
>  4 files changed, 598 insertions(+)
>  create mode 100644 Documentation/driver-api/mailbox/client.rst
>  create mode 100644 Documentation/driver-api/mailbox/core.rst
>  create mode 100644 Documentation/driver-api/mailbox/index.rst
>  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> 
> diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> new file mode 100644
> index 000000000000..9088f8373423
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/client.rst
> @@ -0,0 +1,192 @@
> +Mailbox Client Documentation
> +============================
> +
> +Overview
> +--------
> +The mailbox client driver is responsible for sending and receiving messages
> +to and from a remote processor. It uses mailbox APIs provided by the
> +mailbox framework.
> +
> +Mailbox Structure
> +-----------------
> +The mailbox structure is defined as follows:
> +
> +.. code-block:: c
> +
> +   struct mbox_client {
> +       //device associated with the mailbox
> +       struct device *dev;
> +       // callback for transmission completion
> +       void (*tx_done)(struct mbox_client *client);
> +       // callback to prepare for sending a message
> +       void (*tx_prepare)(struct mbox_client *client);
> +       // callback for received messages
> +       void (*rx_callback)(struct mbox_client *client, void *data);
> +       // flag to indicate if transmission should block
> +       bool tx_block;
> +       // indicates if the client knows when transmission is done
> +       bool knows_txdone;
> +   };
> +
> +Key Functions
> +-------------
> +1. Requesting a Mailbox Channel
> +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> +     unsigned int channel)`
> +   - **Description**: Requests a mailbox channel for sending messages.
> +   - **Parameters**:
> +     - `client`: Pointer to the mailbox client structure.
> +     - `channel`: The specific mailbox channel to request.
> +   - **Returns**: A pointer to the mailbox channel on success, or an error
> +     code on failure.
> +
> +2. Sending a Message
> +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> +   - **Description**: Sends a message through the mailbox channel.
> +   - **Parameters**:
> +     - `chan`: The mailbox channel used for communication.
> +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> +       messages).
> +   - **Returns**: 0 on success, or a negative error code on failure.
> +
> +3. Transmitting Completion
> +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> +     msg_id)`
> +   - **Description**: Notifies the mailbox framework that message
> +     transmission is complete.
> +   - **Parameters**:
> +     - `chan`: The mailbox channel associated with the message.
> +     - `msg_id`: The identifier of the message that was transmitted.

These functions should've been documented as kernel-doc comments, though.

> +
> +Usage Example
> +-------------
> +In a typical mailbox client driver, the following steps are typically
> +performed:
> +
> +1. Initialize the Mailbox Client:
> +
> +   .. code-block:: c
> +
> +      struct mbox_client my_mbox_client = {
> +          .dev = &my_device,
> +          .tx_done = my_tx_done_callback,
> +          .rx_callback = my_rx_callback,
> +          .tx_block = false,
> +          .knows_txdone = true,
> +      };
> +
> +2. Request a Mailbox Channel:
> +
> +   .. code-block:: c
> +
> +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> +      if (IS_ERR(mbox_chan)) {
> +          // Handle error
> +      }
> +
> +3. Send a Message:
> +
> +   .. code-block:: c
> +
> +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> +      if (ret < 0) {
> +          // Handle error
> +      }
> +
> +4. Complete Transmission:
> +
> +   .. code-block:: c
> +
> +      mbox_client_txdone(mbox_chan, 0);
> +
> +Interrupt Handling
> +------------------
> +The mailbox interface can trigger interrupts upon message receipt. Handlers
> +should be implemented in the `rx_callback` function defined in the mailbox
> +client structure to process incoming messages.
> +
> +Example Mailbox Client Driver
> +-----------------------------
> +.. code-block:: c
> +
> +   struct demo_client {
> +       struct mbox_client cl;
> +       struct mbox_chan *mbox;
> +       struct completion c;
> +       bool async;
> +       /* ... */
> +   };
> +
> +   /*
> +   * This is the handler for data received from remote. The behaviour is purely
> +   * dependent upon the protocol. This is just an example.
> +   */
> +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> +   {
> +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> +       if (dc->async) {
> +           if (is_an_ack(mssg)) {
> +               /* An ACK to our last sample sent */
> +               return; /* Or do something else here */
> +           } else { /* A new message from remote */
> +               queue_req(mssg);
> +           }
> +       } else {
> +           /* Remote f/w sends only ACK packets on this channel */
> +           return;
> +       }
> +   }
> +
> +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> +   {
> +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> +       complete(&dc->c);
> +   }
> +
> +   static void client_demo(struct platform_device *pdev)
> +   {
> +       struct demo_client *dc_sync, *dc_async;
> +       /* The controller already knows async_pkt and sync_pkt */
> +       struct async_pkt ap;
> +       struct sync_pkt sp;
> +
> +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> +
> +       /* Populate non-blocking mode client */
> +       dc_async->cl.dev = &pdev->dev;
> +       dc_async->cl.rx_callback = message_from_remote;
> +       dc_async->cl.tx_done = sample_sent;
> +       dc_async->cl.tx_block = false;
> +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> +       dc_async->async = true;
> +       init_completion(&dc_async->c);
> +
> +       /* Populate blocking mode client */
> +       dc_sync->cl.dev = &pdev->dev;
> +       dc_sync->cl.rx_callback = message_from_remote;
> +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> +       dc_sync->cl.tx_block = true;
> +       dc_sync->cl.tx_tout = 500; /* by half a second */
> +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> +       dc_sync->async = false;
> +
> +       /* ASync mailbox is listed second in 'mboxes' property */
> +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> +       /* Populate data packet */
> +       /* ap.xxx = 123; etc */
> +       /* Send async message to remote */
> +       mbox_send_message(dc_async->mbox, &ap);
> +
> +       /* Sync mailbox is listed first in 'mboxes' property */
> +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> +       /* Populate data packet */
> +       /* sp.abc = 123; etc */
> +       /* Send message to remote in blocking mode */
> +       mbox_send_message(dc_sync->mbox, &sp);
> +       /* At this point 'sp' has been sent */
> +
> +       /* Now wait for async chan to be done */
> +       wait_for_completion(&dc_async->c);
> +   }
> diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> new file mode 100644
> index 000000000000..d1220086da67
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/core.rst
> @@ -0,0 +1,182 @@
> +=====================
> +mailbox documentation
> +=====================
> +
> +Hardware Introduction
> +=====================
> +
> +Mailbox hardware is a specialized component found in multi-core
> +processors and embedded systems that facilitates inter-processor
> +communication (IPC) or communication between different hardware
> +components. It provides a structured mechanism for sending and
> +receiving messages, allowing various processors or devices to
> +exchange data efficiently. Here's an overview of its key
> +characteristics and functions:
> +
> +Key Characteristics of Mailbox Hardware
> +Interrupt Handling: Many mailbox implementations support
> +interrupt-driven communication. This allows a receiving processor
> +to be alerted when a new message arrives, facilitating immediate
> +processing without polling the mailbox constantly.
> +
> +Hardware Registers: Mailbox hardware often includes registers for
> +configuration and status monitoring. These registers can be used
> +to control the mailbox's behavior, check for available messages,
> +or acknowledge message receipt.
> +
> +Support for Multiple Protocols: Mailboxes can support various
> +communication protocols, enabling interoperability between different
> +hardware components and simplifying the integration of diverse systems.
> +
> +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> +both synchronous and asynchronous modes. In synchronous mode, the
> +sender may wait for the receiver to acknowledge receipt before
> +proceeding, while in asynchronous mode, the sender can continue
> +executing other tasks immediately after sending the message.
> +
> +
> +Mailbox framework design
> +========================
> +
> +The mailbox facilitates interprocessor communication by allowing processors to
> +exchange messages or signals. The mailbox framework consists of:
> +
> +Mailbox Controller: This is platform-specific and is responsible for configuring
> +and managing interrupts from the remote processor. It offers a generic API for
> +the mailbox client.
> +
> +Mailbox Client: This component handles the sending and receiving of messages.
> +
> +
> +............................................................................
> +:  client driver      client_a            client_b                         :
> +............................................................................
> +                            ^-------------------^
> +                                    |
> +                                    |
> +............................................................................
> +:  controller framework          mailbox                                   :
> +....................................|.......................................
> +                                    |
> +                                    |
> +............................................................................
> +:  controller driver          device specific                              :
> +....................................|.......................................
> +                                    |
> +                                    |
> +kernel                              |
> +............................................................................
> +hardware                            |
> +                                    |
> +                                    |
> +............................................................................
> +:                             remote processor                             :
> +............................................................................

htmldocs build errors out:

Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.

............................................................................
:  controller framework          mailbox                                   :
....................................|.......................................

reST markup error:
Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.

............................................................................
:  controller framework          mailbox                                   :
....................................|.......................................

I have to fix up the design diagram and wrap it:

---- >8 ----
diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
index d1220086da679f..8d56d81007c11c 100644
--- a/Documentation/driver-api/mailbox/core.rst
+++ b/Documentation/driver-api/mailbox/core.rst
@@ -47,31 +47,32 @@ the mailbox client.
 
 Mailbox Client: This component handles the sending and receiving of messages.
 
+::
 
-............................................................................
-:  client driver      client_a            client_b                         :
-............................................................................
-                            ^-------------------^
-                                    |
-                                    |
-............................................................................
-:  controller framework          mailbox                                   :
-....................................|.......................................
-                                    |
-                                    |
-............................................................................
-:  controller driver          device specific                              :
-....................................|.......................................
-                                    |
-                                    |
-kernel                              |
-............................................................................
-hardware                            |
-                                    |
-                                    |
-............................................................................
-:                             remote processor                             :
-............................................................................
+  +---------------------------------------------------------------------------+
+  |  client driver      client_a            client_b                          |
+  +---------------------------------------------------------------------------+
+                              ^-------------------^
+                                      |
+                                      |
+  +--------------------------------------------------------------------------+
+  |  controller framework          mailbox                                   |
+  +-----------------------------------|--------------------------------------+
+                                      |
+                                      |
+  +--------------------------------------------------------------------------+
+  |  controller driver          device specific                              |
+  +-----------------------------------|--------------------------------------+
+                                      |
+                                      |
+  kernel                              |
+  ----------------------------------------------------------------------------
+  hardware                            |
+                                      |
+                                      |
+  +--------------------------------------------------------------------------+
+  |                             remote processor                             |
+  +--------------------------------------------------------------------------+
 
 
 In the context of a mailbox framework, a channel refers to a dedicated

> +
> +
> +In the context of a mailbox framework, a channel refers to a dedicated
> +communication pathway between two or more processors or components. By using
> +channels, the framework abstracts the complexity of interprocessor communication.
> +
> +Data Structures
> +================
> +
> +- **struct mbox_client**
> +  This structure represents a client that communicates over a mailbox
> +  channel. It holds information such as:
> +  - A pointer to the device associated with the client (`dev`).
> +  - Callback functions for handling message transmission events, including:
> +    - `rx_callback`: Called when a message is received.
> +    - `tx_done`: Called when a message transmission is acknowledged.
> +  - Flags that specify the client’s configuration, such as whether it operates
> +    in blocking mode.
> +
> +- **struct mbox_chan**
> +  This structure represents an individual mailbox channel. It maintains the
> +  state required for message queuing and transmission. Key members include:
> +  - `msg_data`: Array of messages queued for transmission.
> +  - `msg_count`: Number of messages currently queued.
> +  - `msg_free`: Index of the next free slot in the message queue.
> +  - `active_req`: Pointer to the currently active message being transmitted.
> +  - Synchronization primitives to manage access from multiple contexts.
> +
> +- **struct mbox_controller**
> +  This structure represents a mailbox controller that manages multiple
> +  channels. It includes:
> +  - A pointer to the device managing the mailbox.
> +  - Operations for sending and receiving messages, as well as initializing
> +    and shutting down the mailbox.
> +  - A list of associated channels and the total number of channels available.

Shouldn't these structs be documented as kernel-doc comments? tl;dr:
see Documentation/doc-guide/kernel-doc.html

> +
> +controller framework APIs
> +=========================
> +
> +``struct `mbox_controller` Initialization
> +-----------------------------------------

Properly double-backquote the struct name to format it as inline code:

---- >8 ----
diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
index 239538f497e41a..d83456164464aa 100644
--- a/Documentation/driver-api/mailbox/core.rst
+++ b/Documentation/driver-api/mailbox/core.rst
@@ -117,7 +117,7 @@ Data Structures
 controller framework APIs
 =========================
 
-``struct `mbox_controller` Initialization
+``struct mbox_controller`` Initialization
 -----------------------------------------
 
 Just like any other kernel framework, the whole mailbox controller registration

> +
> +Just like any other kernel framework, the whole mailbox controller registration
> +relies on the driver filling a structure and registering against the
> +framework. In our case, that structure is mbox_controller.
> +
> +The first thing you need to do in your driver is to allocate this
> +structure. Any of the usual memory allocators will do, but you'll also
> +need to initialize a few fields in there:
> +
> +- ``dev``: should hold the pointer to the ``struct device`` associated
> +  to your current driver instance.
> +
> +- ``ops``: Operators that work on each communication channel.
> +
> +- ``chans``: Array of channels.
> +
> +- ``num_chans``: Number of channels in the `chans` array.
> +
> +- ``txdone_irq``: Indicates if the controller can report to the API
> +  when the last transmitted data was read by the
> +                          remote (e.g., if it has a TX ACK interrupt).
> +
> +All the below fields are not mandatory.
> +
> +- ``txdone_poll``: Indicates if the controller can read but not report
> +                          the TX done. For example, some register may show
> +                          the TX status, but no interrupt is raised. This
> +                          field is ignored if `txdone_irq` is set.
> +
> +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> +                          the last TX status after this many milliseconds.
> +
> +- ``of_xlate``: Controller driver-specific mapping of channel via
> +                          Device Tree (DT).
> +
> +
> +Key Functions
> +-------------
> +
> +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> +  This function registers a mailbox controller with the kernel. It makes the
> +  channels associated with the controller available for client requests. The
> +  function performs sanity checks on the controller structure to ensure all
> +  necessary fields are populated.
> +
> +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> +  This function requests a mailbox channel for a specified client, identified
> +  by an index. It searches for the appropriate mailbox channel, and if found,
> +  it returns a pointer to the channel. If the request fails (e.g., if the
> +  index is invalid), it returns an error pointer.
> +
> +- **void mbox_free_channel(struct mbox_chan *chan)**
> +  This function releases a mailbox channel that was previously allocated for a
> +  client. It ensures that the channel can be reused by other clients. If any
> +  messages are still in the queue, they are aborted, and no callbacks are made.
> +
> +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> +  This function is used by clients to send a message through the specified
> +  mailbox channel. The function can operate in either blocking or non-blocking
> +  mode, depending on the client’s configuration. It will queue the message for
> +  transmission and notify the client once the message is acknowledged.
> +
> +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> +  This function is called by the controller driver to notify the mailbox
> +  framework that a message has been received on the specified channel. The
> +  received message is then passed to the appropriate client's `rx_callback`
> +  function for processing.

Shouldn't these functions also be documented as kernel-doc comments?

> diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> new file mode 100644
> index 000000000000..e254a8fdb66a
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/index.rst
> @@ -0,0 +1,45 @@
> +=======================
> +Mailbox documentation
> +=======================
> +
> +Mailbox documentation provides documents for various aspects of mailbox
> +framework.
> +
> +Mailbox development documentation
> +---------------------------------
> +
> +This book helps with mailbox internal APIs and guide for mailbox device
> +driver writers.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   core
> +
> +mailbox controller driver documentation
> +------------------------------
> +
> +This book is a guide to device driver writers on how to register
> +mailbox controller to the mailbox framework.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   writing_mailbox_controller_drivers
> +
> +mailbox client driver documentation
> +------------------------------

Match up section underline length by its title:

---- >8 ----
diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
index e254a8fdb66ac7..02d7d5e8660999 100644
--- a/Documentation/driver-api/mailbox/index.rst
+++ b/Documentation/driver-api/mailbox/index.rst
@@ -1,6 +1,6 @@
-=======================
+=====================
 Mailbox documentation
-=======================
+=====================
 
 Mailbox documentation provides documents for various aspects of mailbox
 framework.
@@ -17,7 +17,7 @@ driver writers.
    core
 
 mailbox controller driver documentation
-------------------------------
+---------------------------------------
 
 This book is a guide to device driver writers on how to register
 mailbox controller to the mailbox framework.
@@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
    writing_mailbox_controller_drivers
 
 mailbox client driver documentation
-------------------------------
+-----------------------------------
 
 This book is a guide to mailbox client driver writers.
 

> +
> +This book is a guide to mailbox client driver writers.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   client
> +
> +.. only::  subproject and html
> +
> +   Indices
> +   =======
> +
> +   * :ref:`genindex`

Fix up also the reference link on parent toctree:

---- >8 ----
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index 7f83e05769b4a4..b4d78b92fd921a 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -102,7 +102,7 @@ Subsystem-specific APIs
    ipmb
    ipmi
    libata
-   mailbox
+   mailbox/index
    md/index
    media/index
    mei/index

> diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> new file mode 100644
> index 000000000000..2a82645c1357
> --- /dev/null
> +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> @@ -0,0 +1,179 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. _writing_mailbox_controller_drivers:
> +
> +==================================
> +Writing Mailbox Controller Drivers
> +==================================
> +
> +Introduction
> +============
> +
> +This document serves as a basic guideline for driver programmers that need
> +to hack a new mailbox controller driver or understand the essentials of
> +the existing ones.
> +
> +Driver Boilerplate
> +==================
> +
> +As a bare minimum, a mailbox controller driver needs to call
> +``mbox_controller_register`` function to register with the framework.
> +
> +A basic driver skeleton could look like this for a mailbox hardware that
> +has the following characteristics:
> +a. It supports only a single channel, i.e., only the remote processor can
> +   send interrupts.
> +b. Data transfer is over the registers associated with mailbox hardware.
> +c. Mailbox hardware is configured to receive interrupts.
> +d. When the remote processor is ready to send data, it triggers a mailbox
> +   interrupt.
> +e. As part of interrupt handling by Linux, it copies data from the registers.
> +
> +.. code-block:: c
> +
> +   #include <linux/device.h>
> +   #include <linux/interrupt.h>
> +   #include <linux/io.h>
> +   #include <linux/kernel.h>
> +   #include <linux/mailbox_controller.h>
> +   #include <linux/module.h>
> +   #include <linux/of.h>
> +   #include <linux/platform_device.h>
> +   #define DRIVER_NAME "dummy_controller"
> +
> +   struct dummy_mbox {
> +       struct device *dev;
> +       struct mbox_controller controller;
> +       int irq;
> +   };
> +
> +   static void dummy_mbox_receive(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       int val;
> +
> +       // Data copied from registers
> +       val = read_register();
> +       mbox_chan_received_data(chan, &val);
> +   }
> +
> +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> +   {
> +       struct mbox_chan *chan = data;
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       u32 reg;
> +
> +       // Read registers to see if data is received
> +       dummy_mbox_receive(chan);
> +       mbox_chan_txdone(chan, 0);
> +       return reg ? IRQ_HANDLED : IRQ_NONE;
> +   }
> +
> +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> +   {
> +       // Write data in registers to send it to the remote processor
> +       return 0;
> +   }
> +
> +   static int dummy_mbox_startup(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +       u32 reg;
> +       int ret;
> +
> +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> +               DRIVER_NAME, chan);
> +       if (ret < 0) {
> +           dev_err(mbox->dev, "Cannot request irq\n");
> +           return ret;
> +       }
> +
> +       /* Register write to enable IRQ generation */
> +
> +       return 0;
> +   }
> +
> +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> +   {
> +       struct dummy_mbox *mbox = chan->con_priv;
> +
> +       /* Disable interrupt generation */
> +       devm_free_irq(mbox->dev, mbox->irq, chan);
> +   }
> +
> +   static const struct mbox_chan_ops dummy_mbox_ops = {
> +       .send_data = dummy_mbox_send_data,
> +       .startup = dummy_mbox_startup,
> +       .shutdown = dummy_mbox_shutdown,
> +   };
> +
> +   static int dummy_mbox_probe(struct platform_device *pdev)
> +   {
> +       struct dummy_mbox *mbox;
> +       struct mbox_chan *chans;
> +       int ret;
> +
> +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> +       if (!mbox)
> +           return -ENOMEM;
> +
> +       /* Allocate one channel */
> +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> +       if (!chans)
> +           return -ENOMEM;
> +
> +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(mbox->base))
> +           return PTR_ERR(mbox->base);
> +
> +       mbox->irq = platform_get_irq(pdev, 0);
> +       if (mbox->irq < 0)
> +           return mbox->irq;
> +
> +       mbox->dev = &pdev->dev;
> +
> +       /* Hardware supports only one channel. */
> +       mbox->controller.dev = mbox->dev;
> +       mbox->controller.num_chans = 1;
> +       mbox->controller.chans = chans;
> +       mbox->controller.ops = &dummy_mbox_ops;
> +       mbox->controller.txdone_irq = true;
> +
> +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> +       if (ret) {
> +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> +           return ret;
> +       }
> +
> +       return ret;
> +   }
> +
> +   static const struct of_device_id dummy_mbox_match[] = {
> +       { .compatible = "dummy,dummy-mailbox" },
> +       { },
> +   };
> +
> +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> +
> +   static struct platform_driver dummy_mbox_driver = {
> +       .probe = dummy_mbox_probe,
> +       .driver = {
> +           .name = DRIVER_NAME,
> +           .of_match_table = dummy_mbox_match,
> +       },
> +   };
> +
> +   module_platform_driver(dummy_mbox_driver);
> +   MODULE_LICENSE("GPL v2");
> +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> +
> +In the above code, a couple of things are done:
> +a. The controller is registered in the probe along with callbacks, which in
> +   this case are the bare minimum: ``startup``, ``shutdown``, and
> +   ``send_data``.
> +b. IRQ is registered to get notifications from the remote processor.
> +c. In the IRQ handler, registers are read to copy data, and
> +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> +   is the last data and no more data is to be expected for the current transfer.
> +

Sphinx warns out numerous indentation warnings on the lists, so I have to
fix them up:

---- >8 ----
diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
index 9088f83734230d..17dafaca056777 100644
--- a/Documentation/driver-api/mailbox/client.rst
+++ b/Documentation/driver-api/mailbox/client.rst
@@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
 Key Functions
 -------------
 1. Requesting a Mailbox Channel
+
    - **Function**: `mbox_request_channel(struct mbox_client *client,
      unsigned int channel)`
    - **Description**: Requests a mailbox channel for sending messages.
@@ -41,15 +42,19 @@ Key Functions
      code on failure.
 
 2. Sending a Message
+
    - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
    - **Description**: Sends a message through the mailbox channel.
    - **Parameters**:
+
      - `chan`: The mailbox channel used for communication.
      - `msg`: Pointer to the message to be sent (usually NULL for dummy
        messages).
+
    - **Returns**: 0 on success, or a negative error code on failure.
 
 3. Transmitting Completion
+
    - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
      msg_id)`
    - **Description**: Notifies the mailbox framework that message
diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
index 8d56d81007c11c..239538f497e41a 100644
--- a/Documentation/driver-api/mailbox/core.rst
+++ b/Documentation/driver-api/mailbox/core.rst
@@ -85,16 +85,20 @@ Data Structures
 - **struct mbox_client**
   This structure represents a client that communicates over a mailbox
   channel. It holds information such as:
+
   - A pointer to the device associated with the client (`dev`).
   - Callback functions for handling message transmission events, including:
+
     - `rx_callback`: Called when a message is received.
     - `tx_done`: Called when a message transmission is acknowledged.
+
   - Flags that specify the client’s configuration, such as whether it operates
     in blocking mode.
 
 - **struct mbox_chan**
   This structure represents an individual mailbox channel. It maintains the
   state required for message queuing and transmission. Key members include:
+
   - `msg_data`: Array of messages queued for transmission.
   - `msg_count`: Number of messages currently queued.
   - `msg_free`: Index of the next free slot in the message queue.
@@ -104,6 +108,7 @@ Data Structures
 - **struct mbox_controller**
   This structure represents a mailbox controller that manages multiple
   channels. It includes:
+
   - A pointer to the device managing the mailbox.
   - Operations for sending and receiving messages, as well as initializing
     and shutting down the mailbox.
@@ -133,21 +138,20 @@ need to initialize a few fields in there:
 - ``num_chans``: Number of channels in the `chans` array.
 
 - ``txdone_irq``: Indicates if the controller can report to the API
-  when the last transmitted data was read by the
-                          remote (e.g., if it has a TX ACK interrupt).
+  when the last transmitted data was read by the remote (e.g., if it has a
+  TX ACK interrupt).
 
 All the below fields are not mandatory.
 
 - ``txdone_poll``: Indicates if the controller can read but not report
-                          the TX done. For example, some register may show
-                          the TX status, but no interrupt is raised. This
-                          field is ignored if `txdone_irq` is set.
+  the TX done. For example, some register may show the TX status, but no
+  interrupt is raised. This field is ignored if `txdone_irq` is set.
 
 - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
-                          the last TX status after this many milliseconds.
+  the last TX status after this many milliseconds.
 
 - ``of_xlate``: Controller driver-specific mapping of channel via
-                          Device Tree (DT).
+  Device Tree (DT).
 
 
 Key Functions
diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
index 2a82645c13573e..853adf6918173d 100644
--- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
+++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
@@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
 
 A basic driver skeleton could look like this for a mailbox hardware that
 has the following characteristics:
+
 a. It supports only a single channel, i.e., only the remote processor can
    send interrupts.
 b. Data transfer is over the registers associated with mailbox hardware.
@@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
    MODULE_DESCRIPTION("Dummy mailbox controller driver");
 
 In the above code, a couple of things are done:
+
 a. The controller is registered in the probe along with callbacks, which in
    this case are the bare minimum: ``startup``, ``shutdown``, and
    ``send_data``.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-25  3:38   ` Bagas Sanjaya
@ 2024-10-25 19:24     ` anish kumar
  2024-10-29 18:06       ` anish kumar
  0 siblings, 1 reply; 12+ messages in thread
From: anish kumar @ 2024-10-25 19:24 UTC (permalink / raw)
  To: jassisinghbrar, Jonathan Corbet; +Cc: linux-doc, linux-kernel, Bagas Sanjaya

Hello Jassi,

I hope to get some more comments from you before
spinning up a new revision.

On Thu, Oct 24, 2024 at 8:38 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
>
> On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> > 1. added client documentation
> > 2. added controller documentation.
> > 3. added framework documentation
>
> One doc topic on each patch, please.
>
> >
> > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > ---
> >  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
> >  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
> >  Documentation/driver-api/mailbox/index.rst    |  45 ++++
> >  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
> >  4 files changed, 598 insertions(+)
> >  create mode 100644 Documentation/driver-api/mailbox/client.rst
> >  create mode 100644 Documentation/driver-api/mailbox/core.rst
> >  create mode 100644 Documentation/driver-api/mailbox/index.rst
> >  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> >
> > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > new file mode 100644
> > index 000000000000..9088f8373423
> > --- /dev/null
> > +++ b/Documentation/driver-api/mailbox/client.rst
> > @@ -0,0 +1,192 @@
> > +Mailbox Client Documentation
> > +============================
> > +
> > +Overview
> > +--------
> > +The mailbox client driver is responsible for sending and receiving messages
> > +to and from a remote processor. It uses mailbox APIs provided by the
> > +mailbox framework.
> > +
> > +Mailbox Structure
> > +-----------------
> > +The mailbox structure is defined as follows:
> > +
> > +.. code-block:: c
> > +
> > +   struct mbox_client {
> > +       //device associated with the mailbox
> > +       struct device *dev;
> > +       // callback for transmission completion
> > +       void (*tx_done)(struct mbox_client *client);
> > +       // callback to prepare for sending a message
> > +       void (*tx_prepare)(struct mbox_client *client);
> > +       // callback for received messages
> > +       void (*rx_callback)(struct mbox_client *client, void *data);
> > +       // flag to indicate if transmission should block
> > +       bool tx_block;
> > +       // indicates if the client knows when transmission is done
> > +       bool knows_txdone;
> > +   };
> > +
> > +Key Functions
> > +-------------
> > +1. Requesting a Mailbox Channel
> > +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> > +     unsigned int channel)`
> > +   - **Description**: Requests a mailbox channel for sending messages.
> > +   - **Parameters**:
> > +     - `client`: Pointer to the mailbox client structure.
> > +     - `channel`: The specific mailbox channel to request.
> > +   - **Returns**: A pointer to the mailbox channel on success, or an error
> > +     code on failure.
> > +
> > +2. Sending a Message
> > +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > +   - **Description**: Sends a message through the mailbox channel.
> > +   - **Parameters**:
> > +     - `chan`: The mailbox channel used for communication.
> > +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > +       messages).
> > +   - **Returns**: 0 on success, or a negative error code on failure.
> > +
> > +3. Transmitting Completion
> > +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > +     msg_id)`
> > +   - **Description**: Notifies the mailbox framework that message
> > +     transmission is complete.
> > +   - **Parameters**:
> > +     - `chan`: The mailbox channel associated with the message.
> > +     - `msg_id`: The identifier of the message that was transmitted.
>
> These functions should've been documented as kernel-doc comments, though.
>
> > +
> > +Usage Example
> > +-------------
> > +In a typical mailbox client driver, the following steps are typically
> > +performed:
> > +
> > +1. Initialize the Mailbox Client:
> > +
> > +   .. code-block:: c
> > +
> > +      struct mbox_client my_mbox_client = {
> > +          .dev = &my_device,
> > +          .tx_done = my_tx_done_callback,
> > +          .rx_callback = my_rx_callback,
> > +          .tx_block = false,
> > +          .knows_txdone = true,
> > +      };
> > +
> > +2. Request a Mailbox Channel:
> > +
> > +   .. code-block:: c
> > +
> > +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> > +      if (IS_ERR(mbox_chan)) {
> > +          // Handle error
> > +      }
> > +
> > +3. Send a Message:
> > +
> > +   .. code-block:: c
> > +
> > +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> > +      if (ret < 0) {
> > +          // Handle error
> > +      }
> > +
> > +4. Complete Transmission:
> > +
> > +   .. code-block:: c
> > +
> > +      mbox_client_txdone(mbox_chan, 0);
> > +
> > +Interrupt Handling
> > +------------------
> > +The mailbox interface can trigger interrupts upon message receipt. Handlers
> > +should be implemented in the `rx_callback` function defined in the mailbox
> > +client structure to process incoming messages.
> > +
> > +Example Mailbox Client Driver
> > +-----------------------------
> > +.. code-block:: c
> > +
> > +   struct demo_client {
> > +       struct mbox_client cl;
> > +       struct mbox_chan *mbox;
> > +       struct completion c;
> > +       bool async;
> > +       /* ... */
> > +   };
> > +
> > +   /*
> > +   * This is the handler for data received from remote. The behaviour is purely
> > +   * dependent upon the protocol. This is just an example.
> > +   */
> > +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> > +   {
> > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > +       if (dc->async) {
> > +           if (is_an_ack(mssg)) {
> > +               /* An ACK to our last sample sent */
> > +               return; /* Or do something else here */
> > +           } else { /* A new message from remote */
> > +               queue_req(mssg);
> > +           }
> > +       } else {
> > +           /* Remote f/w sends only ACK packets on this channel */
> > +           return;
> > +       }
> > +   }
> > +
> > +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> > +   {
> > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > +       complete(&dc->c);
> > +   }
> > +
> > +   static void client_demo(struct platform_device *pdev)
> > +   {
> > +       struct demo_client *dc_sync, *dc_async;
> > +       /* The controller already knows async_pkt and sync_pkt */
> > +       struct async_pkt ap;
> > +       struct sync_pkt sp;
> > +
> > +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> > +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> > +
> > +       /* Populate non-blocking mode client */
> > +       dc_async->cl.dev = &pdev->dev;
> > +       dc_async->cl.rx_callback = message_from_remote;
> > +       dc_async->cl.tx_done = sample_sent;
> > +       dc_async->cl.tx_block = false;
> > +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> > +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> > +       dc_async->async = true;
> > +       init_completion(&dc_async->c);
> > +
> > +       /* Populate blocking mode client */
> > +       dc_sync->cl.dev = &pdev->dev;
> > +       dc_sync->cl.rx_callback = message_from_remote;
> > +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> > +       dc_sync->cl.tx_block = true;
> > +       dc_sync->cl.tx_tout = 500; /* by half a second */
> > +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> > +       dc_sync->async = false;
> > +
> > +       /* ASync mailbox is listed second in 'mboxes' property */
> > +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> > +       /* Populate data packet */
> > +       /* ap.xxx = 123; etc */
> > +       /* Send async message to remote */
> > +       mbox_send_message(dc_async->mbox, &ap);
> > +
> > +       /* Sync mailbox is listed first in 'mboxes' property */
> > +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> > +       /* Populate data packet */
> > +       /* sp.abc = 123; etc */
> > +       /* Send message to remote in blocking mode */
> > +       mbox_send_message(dc_sync->mbox, &sp);
> > +       /* At this point 'sp' has been sent */
> > +
> > +       /* Now wait for async chan to be done */
> > +       wait_for_completion(&dc_async->c);
> > +   }
> > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > new file mode 100644
> > index 000000000000..d1220086da67
> > --- /dev/null
> > +++ b/Documentation/driver-api/mailbox/core.rst
> > @@ -0,0 +1,182 @@
> > +=====================
> > +mailbox documentation
> > +=====================
> > +
> > +Hardware Introduction
> > +=====================
> > +
> > +Mailbox hardware is a specialized component found in multi-core
> > +processors and embedded systems that facilitates inter-processor
> > +communication (IPC) or communication between different hardware
> > +components. It provides a structured mechanism for sending and
> > +receiving messages, allowing various processors or devices to
> > +exchange data efficiently. Here's an overview of its key
> > +characteristics and functions:
> > +
> > +Key Characteristics of Mailbox Hardware
> > +Interrupt Handling: Many mailbox implementations support
> > +interrupt-driven communication. This allows a receiving processor
> > +to be alerted when a new message arrives, facilitating immediate
> > +processing without polling the mailbox constantly.
> > +
> > +Hardware Registers: Mailbox hardware often includes registers for
> > +configuration and status monitoring. These registers can be used
> > +to control the mailbox's behavior, check for available messages,
> > +or acknowledge message receipt.
> > +
> > +Support for Multiple Protocols: Mailboxes can support various
> > +communication protocols, enabling interoperability between different
> > +hardware components and simplifying the integration of diverse systems.
> > +
> > +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> > +both synchronous and asynchronous modes. In synchronous mode, the
> > +sender may wait for the receiver to acknowledge receipt before
> > +proceeding, while in asynchronous mode, the sender can continue
> > +executing other tasks immediately after sending the message.
> > +
> > +
> > +Mailbox framework design
> > +========================
> > +
> > +The mailbox facilitates interprocessor communication by allowing processors to
> > +exchange messages or signals. The mailbox framework consists of:
> > +
> > +Mailbox Controller: This is platform-specific and is responsible for configuring
> > +and managing interrupts from the remote processor. It offers a generic API for
> > +the mailbox client.
> > +
> > +Mailbox Client: This component handles the sending and receiving of messages.
> > +
> > +
> > +............................................................................
> > +:  client driver      client_a            client_b                         :
> > +............................................................................
> > +                            ^-------------------^
> > +                                    |
> > +                                    |
> > +............................................................................
> > +:  controller framework          mailbox                                   :
> > +....................................|.......................................
> > +                                    |
> > +                                    |
> > +............................................................................
> > +:  controller driver          device specific                              :
> > +....................................|.......................................
> > +                                    |
> > +                                    |
> > +kernel                              |
> > +............................................................................
> > +hardware                            |
> > +                                    |
> > +                                    |
> > +............................................................................
> > +:                             remote processor                             :
> > +............................................................................
>
> htmldocs build errors out:
>
> Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
> Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.
>
> ............................................................................
> :  controller framework          mailbox                                   :
> ....................................|.......................................
>
> reST markup error:
> Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.
>
> ............................................................................
> :  controller framework          mailbox                                   :
> ....................................|.......................................
>
> I have to fix up the design diagram and wrap it:
>
> ---- >8 ----
> diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> index d1220086da679f..8d56d81007c11c 100644
> --- a/Documentation/driver-api/mailbox/core.rst
> +++ b/Documentation/driver-api/mailbox/core.rst
> @@ -47,31 +47,32 @@ the mailbox client.
>
>  Mailbox Client: This component handles the sending and receiving of messages.
>
> +::
>
> -............................................................................
> -:  client driver      client_a            client_b                         :
> -............................................................................
> -                            ^-------------------^
> -                                    |
> -                                    |
> -............................................................................
> -:  controller framework          mailbox                                   :
> -....................................|.......................................
> -                                    |
> -                                    |
> -............................................................................
> -:  controller driver          device specific                              :
> -....................................|.......................................
> -                                    |
> -                                    |
> -kernel                              |
> -............................................................................
> -hardware                            |
> -                                    |
> -                                    |
> -............................................................................
> -:                             remote processor                             :
> -............................................................................
> +  +---------------------------------------------------------------------------+
> +  |  client driver      client_a            client_b                          |
> +  +---------------------------------------------------------------------------+
> +                              ^-------------------^
> +                                      |
> +                                      |
> +  +--------------------------------------------------------------------------+
> +  |  controller framework          mailbox                                   |
> +  +-----------------------------------|--------------------------------------+
> +                                      |
> +                                      |
> +  +--------------------------------------------------------------------------+
> +  |  controller driver          device specific                              |
> +  +-----------------------------------|--------------------------------------+
> +                                      |
> +                                      |
> +  kernel                              |
> +  ----------------------------------------------------------------------------
> +  hardware                            |
> +                                      |
> +                                      |
> +  +--------------------------------------------------------------------------+
> +  |                             remote processor                             |
> +  +--------------------------------------------------------------------------+
>
>
>  In the context of a mailbox framework, a channel refers to a dedicated
>
> > +
> > +
> > +In the context of a mailbox framework, a channel refers to a dedicated
> > +communication pathway between two or more processors or components. By using
> > +channels, the framework abstracts the complexity of interprocessor communication.
> > +
> > +Data Structures
> > +================
> > +
> > +- **struct mbox_client**
> > +  This structure represents a client that communicates over a mailbox
> > +  channel. It holds information such as:
> > +  - A pointer to the device associated with the client (`dev`).
> > +  - Callback functions for handling message transmission events, including:
> > +    - `rx_callback`: Called when a message is received.
> > +    - `tx_done`: Called when a message transmission is acknowledged.
> > +  - Flags that specify the client’s configuration, such as whether it operates
> > +    in blocking mode.
> > +
> > +- **struct mbox_chan**
> > +  This structure represents an individual mailbox channel. It maintains the
> > +  state required for message queuing and transmission. Key members include:
> > +  - `msg_data`: Array of messages queued for transmission.
> > +  - `msg_count`: Number of messages currently queued.
> > +  - `msg_free`: Index of the next free slot in the message queue.
> > +  - `active_req`: Pointer to the currently active message being transmitted.
> > +  - Synchronization primitives to manage access from multiple contexts.
> > +
> > +- **struct mbox_controller**
> > +  This structure represents a mailbox controller that manages multiple
> > +  channels. It includes:
> > +  - A pointer to the device managing the mailbox.
> > +  - Operations for sending and receiving messages, as well as initializing
> > +    and shutting down the mailbox.
> > +  - A list of associated channels and the total number of channels available.
>
> Shouldn't these structs be documented as kernel-doc comments? tl;dr:
> see Documentation/doc-guide/kernel-doc.html
>
> > +
> > +controller framework APIs
> > +=========================
> > +
> > +``struct `mbox_controller` Initialization
> > +-----------------------------------------
>
> Properly double-backquote the struct name to format it as inline code:
>
> ---- >8 ----
> diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> index 239538f497e41a..d83456164464aa 100644
> --- a/Documentation/driver-api/mailbox/core.rst
> +++ b/Documentation/driver-api/mailbox/core.rst
> @@ -117,7 +117,7 @@ Data Structures
>  controller framework APIs
>  =========================
>
> -``struct `mbox_controller` Initialization
> +``struct mbox_controller`` Initialization
>  -----------------------------------------
>
>  Just like any other kernel framework, the whole mailbox controller registration
>
> > +
> > +Just like any other kernel framework, the whole mailbox controller registration
> > +relies on the driver filling a structure and registering against the
> > +framework. In our case, that structure is mbox_controller.
> > +
> > +The first thing you need to do in your driver is to allocate this
> > +structure. Any of the usual memory allocators will do, but you'll also
> > +need to initialize a few fields in there:
> > +
> > +- ``dev``: should hold the pointer to the ``struct device`` associated
> > +  to your current driver instance.
> > +
> > +- ``ops``: Operators that work on each communication channel.
> > +
> > +- ``chans``: Array of channels.
> > +
> > +- ``num_chans``: Number of channels in the `chans` array.
> > +
> > +- ``txdone_irq``: Indicates if the controller can report to the API
> > +  when the last transmitted data was read by the
> > +                          remote (e.g., if it has a TX ACK interrupt).
> > +
> > +All the below fields are not mandatory.
> > +
> > +- ``txdone_poll``: Indicates if the controller can read but not report
> > +                          the TX done. For example, some register may show
> > +                          the TX status, but no interrupt is raised. This
> > +                          field is ignored if `txdone_irq` is set.
> > +
> > +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > +                          the last TX status after this many milliseconds.
> > +
> > +- ``of_xlate``: Controller driver-specific mapping of channel via
> > +                          Device Tree (DT).
> > +
> > +
> > +Key Functions
> > +-------------
> > +
> > +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> > +  This function registers a mailbox controller with the kernel. It makes the
> > +  channels associated with the controller available for client requests. The
> > +  function performs sanity checks on the controller structure to ensure all
> > +  necessary fields are populated.
> > +
> > +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> > +  This function requests a mailbox channel for a specified client, identified
> > +  by an index. It searches for the appropriate mailbox channel, and if found,
> > +  it returns a pointer to the channel. If the request fails (e.g., if the
> > +  index is invalid), it returns an error pointer.
> > +
> > +- **void mbox_free_channel(struct mbox_chan *chan)**
> > +  This function releases a mailbox channel that was previously allocated for a
> > +  client. It ensures that the channel can be reused by other clients. If any
> > +  messages are still in the queue, they are aborted, and no callbacks are made.
> > +
> > +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> > +  This function is used by clients to send a message through the specified
> > +  mailbox channel. The function can operate in either blocking or non-blocking
> > +  mode, depending on the client’s configuration. It will queue the message for
> > +  transmission and notify the client once the message is acknowledged.
> > +
> > +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> > +  This function is called by the controller driver to notify the mailbox
> > +  framework that a message has been received on the specified channel. The
> > +  received message is then passed to the appropriate client's `rx_callback`
> > +  function for processing.
>
> Shouldn't these functions also be documented as kernel-doc comments?
>
> > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > new file mode 100644
> > index 000000000000..e254a8fdb66a
> > --- /dev/null
> > +++ b/Documentation/driver-api/mailbox/index.rst
> > @@ -0,0 +1,45 @@
> > +=======================
> > +Mailbox documentation
> > +=======================
> > +
> > +Mailbox documentation provides documents for various aspects of mailbox
> > +framework.
> > +
> > +Mailbox development documentation
> > +---------------------------------
> > +
> > +This book helps with mailbox internal APIs and guide for mailbox device
> > +driver writers.
> > +
> > +.. toctree::
> > +   :maxdepth: 1
> > +
> > +   core
> > +
> > +mailbox controller driver documentation
> > +------------------------------
> > +
> > +This book is a guide to device driver writers on how to register
> > +mailbox controller to the mailbox framework.
> > +
> > +.. toctree::
> > +   :maxdepth: 1
> > +
> > +   writing_mailbox_controller_drivers
> > +
> > +mailbox client driver documentation
> > +------------------------------
>
> Match up section underline length by its title:
>
> ---- >8 ----
> diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> index e254a8fdb66ac7..02d7d5e8660999 100644
> --- a/Documentation/driver-api/mailbox/index.rst
> +++ b/Documentation/driver-api/mailbox/index.rst
> @@ -1,6 +1,6 @@
> -=======================
> +=====================
>  Mailbox documentation
> -=======================
> +=====================
>
>  Mailbox documentation provides documents for various aspects of mailbox
>  framework.
> @@ -17,7 +17,7 @@ driver writers.
>     core
>
>  mailbox controller driver documentation
> -------------------------------
> +---------------------------------------
>
>  This book is a guide to device driver writers on how to register
>  mailbox controller to the mailbox framework.
> @@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
>     writing_mailbox_controller_drivers
>
>  mailbox client driver documentation
> -------------------------------
> +-----------------------------------
>
>  This book is a guide to mailbox client driver writers.
>
>
> > +
> > +This book is a guide to mailbox client driver writers.
> > +
> > +.. toctree::
> > +   :maxdepth: 1
> > +
> > +   client
> > +
> > +.. only::  subproject and html
> > +
> > +   Indices
> > +   =======
> > +
> > +   * :ref:`genindex`
>
> Fix up also the reference link on parent toctree:
>
> ---- >8 ----
> diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
> index 7f83e05769b4a4..b4d78b92fd921a 100644
> --- a/Documentation/driver-api/index.rst
> +++ b/Documentation/driver-api/index.rst
> @@ -102,7 +102,7 @@ Subsystem-specific APIs
>     ipmb
>     ipmi
>     libata
> -   mailbox
> +   mailbox/index
>     md/index
>     media/index
>     mei/index
>
> > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > new file mode 100644
> > index 000000000000..2a82645c1357
> > --- /dev/null
> > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > @@ -0,0 +1,179 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +.. _writing_mailbox_controller_drivers:
> > +
> > +==================================
> > +Writing Mailbox Controller Drivers
> > +==================================
> > +
> > +Introduction
> > +============
> > +
> > +This document serves as a basic guideline for driver programmers that need
> > +to hack a new mailbox controller driver or understand the essentials of
> > +the existing ones.
> > +
> > +Driver Boilerplate
> > +==================
> > +
> > +As a bare minimum, a mailbox controller driver needs to call
> > +``mbox_controller_register`` function to register with the framework.
> > +
> > +A basic driver skeleton could look like this for a mailbox hardware that
> > +has the following characteristics:
> > +a. It supports only a single channel, i.e., only the remote processor can
> > +   send interrupts.
> > +b. Data transfer is over the registers associated with mailbox hardware.
> > +c. Mailbox hardware is configured to receive interrupts.
> > +d. When the remote processor is ready to send data, it triggers a mailbox
> > +   interrupt.
> > +e. As part of interrupt handling by Linux, it copies data from the registers.
> > +
> > +.. code-block:: c
> > +
> > +   #include <linux/device.h>
> > +   #include <linux/interrupt.h>
> > +   #include <linux/io.h>
> > +   #include <linux/kernel.h>
> > +   #include <linux/mailbox_controller.h>
> > +   #include <linux/module.h>
> > +   #include <linux/of.h>
> > +   #include <linux/platform_device.h>
> > +   #define DRIVER_NAME "dummy_controller"
> > +
> > +   struct dummy_mbox {
> > +       struct device *dev;
> > +       struct mbox_controller controller;
> > +       int irq;
> > +   };
> > +
> > +   static void dummy_mbox_receive(struct mbox_chan *chan)
> > +   {
> > +       struct dummy_mbox *mbox = chan->con_priv;
> > +       int val;
> > +
> > +       // Data copied from registers
> > +       val = read_register();
> > +       mbox_chan_received_data(chan, &val);
> > +   }
> > +
> > +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> > +   {
> > +       struct mbox_chan *chan = data;
> > +       struct dummy_mbox *mbox = chan->con_priv;
> > +       u32 reg;
> > +
> > +       // Read registers to see if data is received
> > +       dummy_mbox_receive(chan);
> > +       mbox_chan_txdone(chan, 0);
> > +       return reg ? IRQ_HANDLED : IRQ_NONE;
> > +   }
> > +
> > +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> > +   {
> > +       // Write data in registers to send it to the remote processor
> > +       return 0;
> > +   }
> > +
> > +   static int dummy_mbox_startup(struct mbox_chan *chan)
> > +   {
> > +       struct dummy_mbox *mbox = chan->con_priv;
> > +       u32 reg;
> > +       int ret;
> > +
> > +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> > +               DRIVER_NAME, chan);
> > +       if (ret < 0) {
> > +           dev_err(mbox->dev, "Cannot request irq\n");
> > +           return ret;
> > +       }
> > +
> > +       /* Register write to enable IRQ generation */
> > +
> > +       return 0;
> > +   }
> > +
> > +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> > +   {
> > +       struct dummy_mbox *mbox = chan->con_priv;
> > +
> > +       /* Disable interrupt generation */
> > +       devm_free_irq(mbox->dev, mbox->irq, chan);
> > +   }
> > +
> > +   static const struct mbox_chan_ops dummy_mbox_ops = {
> > +       .send_data = dummy_mbox_send_data,
> > +       .startup = dummy_mbox_startup,
> > +       .shutdown = dummy_mbox_shutdown,
> > +   };
> > +
> > +   static int dummy_mbox_probe(struct platform_device *pdev)
> > +   {
> > +       struct dummy_mbox *mbox;
> > +       struct mbox_chan *chans;
> > +       int ret;
> > +
> > +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> > +       if (!mbox)
> > +           return -ENOMEM;
> > +
> > +       /* Allocate one channel */
> > +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> > +       if (!chans)
> > +           return -ENOMEM;
> > +
> > +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> > +       if (IS_ERR(mbox->base))
> > +           return PTR_ERR(mbox->base);
> > +
> > +       mbox->irq = platform_get_irq(pdev, 0);
> > +       if (mbox->irq < 0)
> > +           return mbox->irq;
> > +
> > +       mbox->dev = &pdev->dev;
> > +
> > +       /* Hardware supports only one channel. */
> > +       mbox->controller.dev = mbox->dev;
> > +       mbox->controller.num_chans = 1;
> > +       mbox->controller.chans = chans;
> > +       mbox->controller.ops = &dummy_mbox_ops;
> > +       mbox->controller.txdone_irq = true;
> > +
> > +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> > +       if (ret) {
> > +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> > +           return ret;
> > +       }
> > +
> > +       return ret;
> > +   }
> > +
> > +   static const struct of_device_id dummy_mbox_match[] = {
> > +       { .compatible = "dummy,dummy-mailbox" },
> > +       { },
> > +   };
> > +
> > +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> > +
> > +   static struct platform_driver dummy_mbox_driver = {
> > +       .probe = dummy_mbox_probe,
> > +       .driver = {
> > +           .name = DRIVER_NAME,
> > +           .of_match_table = dummy_mbox_match,
> > +       },
> > +   };
> > +
> > +   module_platform_driver(dummy_mbox_driver);
> > +   MODULE_LICENSE("GPL v2");
> > +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > +
> > +In the above code, a couple of things are done:
> > +a. The controller is registered in the probe along with callbacks, which in
> > +   this case are the bare minimum: ``startup``, ``shutdown``, and
> > +   ``send_data``.
> > +b. IRQ is registered to get notifications from the remote processor.
> > +c. In the IRQ handler, registers are read to copy data, and
> > +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> > +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> > +   is the last data and no more data is to be expected for the current transfer.
> > +
>
> Sphinx warns out numerous indentation warnings on the lists, so I have to
> fix them up:
>
> ---- >8 ----
> diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> index 9088f83734230d..17dafaca056777 100644
> --- a/Documentation/driver-api/mailbox/client.rst
> +++ b/Documentation/driver-api/mailbox/client.rst
> @@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
>  Key Functions
>  -------------
>  1. Requesting a Mailbox Channel
> +
>     - **Function**: `mbox_request_channel(struct mbox_client *client,
>       unsigned int channel)`
>     - **Description**: Requests a mailbox channel for sending messages.
> @@ -41,15 +42,19 @@ Key Functions
>       code on failure.
>
>  2. Sending a Message
> +
>     - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
>     - **Description**: Sends a message through the mailbox channel.
>     - **Parameters**:
> +
>       - `chan`: The mailbox channel used for communication.
>       - `msg`: Pointer to the message to be sent (usually NULL for dummy
>         messages).
> +
>     - **Returns**: 0 on success, or a negative error code on failure.
>
>  3. Transmitting Completion
> +
>     - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
>       msg_id)`
>     - **Description**: Notifies the mailbox framework that message
> diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> index 8d56d81007c11c..239538f497e41a 100644
> --- a/Documentation/driver-api/mailbox/core.rst
> +++ b/Documentation/driver-api/mailbox/core.rst
> @@ -85,16 +85,20 @@ Data Structures
>  - **struct mbox_client**
>    This structure represents a client that communicates over a mailbox
>    channel. It holds information such as:
> +
>    - A pointer to the device associated with the client (`dev`).
>    - Callback functions for handling message transmission events, including:
> +
>      - `rx_callback`: Called when a message is received.
>      - `tx_done`: Called when a message transmission is acknowledged.
> +
>    - Flags that specify the client’s configuration, such as whether it operates
>      in blocking mode.
>
>  - **struct mbox_chan**
>    This structure represents an individual mailbox channel. It maintains the
>    state required for message queuing and transmission. Key members include:
> +
>    - `msg_data`: Array of messages queued for transmission.
>    - `msg_count`: Number of messages currently queued.
>    - `msg_free`: Index of the next free slot in the message queue.
> @@ -104,6 +108,7 @@ Data Structures
>  - **struct mbox_controller**
>    This structure represents a mailbox controller that manages multiple
>    channels. It includes:
> +
>    - A pointer to the device managing the mailbox.
>    - Operations for sending and receiving messages, as well as initializing
>      and shutting down the mailbox.
> @@ -133,21 +138,20 @@ need to initialize a few fields in there:
>  - ``num_chans``: Number of channels in the `chans` array.
>
>  - ``txdone_irq``: Indicates if the controller can report to the API
> -  when the last transmitted data was read by the
> -                          remote (e.g., if it has a TX ACK interrupt).
> +  when the last transmitted data was read by the remote (e.g., if it has a
> +  TX ACK interrupt).
>
>  All the below fields are not mandatory.
>
>  - ``txdone_poll``: Indicates if the controller can read but not report
> -                          the TX done. For example, some register may show
> -                          the TX status, but no interrupt is raised. This
> -                          field is ignored if `txdone_irq` is set.
> +  the TX done. For example, some register may show the TX status, but no
> +  interrupt is raised. This field is ignored if `txdone_irq` is set.
>
>  - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> -                          the last TX status after this many milliseconds.
> +  the last TX status after this many milliseconds.
>
>  - ``of_xlate``: Controller driver-specific mapping of channel via
> -                          Device Tree (DT).
> +  Device Tree (DT).
>
>
>  Key Functions
> diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> index 2a82645c13573e..853adf6918173d 100644
> --- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> @@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
>
>  A basic driver skeleton could look like this for a mailbox hardware that
>  has the following characteristics:
> +
>  a. It supports only a single channel, i.e., only the remote processor can
>     send interrupts.
>  b. Data transfer is over the registers associated with mailbox hardware.
> @@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
>     MODULE_DESCRIPTION("Dummy mailbox controller driver");
>
>  In the above code, a couple of things are done:
> +
>  a. The controller is registered in the probe along with callbacks, which in
>     this case are the bare minimum: ``startup``, ``shutdown``, and
>     ``send_data``.
>
> Thanks.
>
> --
> An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-25 19:24     ` anish kumar
@ 2024-10-29 18:06       ` anish kumar
  2024-10-29 23:51         ` Bagas Sanjaya
  2024-10-30 17:41         ` Jassi Brar
  0 siblings, 2 replies; 12+ messages in thread
From: anish kumar @ 2024-10-29 18:06 UTC (permalink / raw)
  To: jassisinghbrar, Jonathan Corbet; +Cc: linux-doc, linux-kernel, Bagas Sanjaya

Hello Jassi,

Gentle reminder for the review.

On Fri, Oct 25, 2024 at 12:24 PM anish kumar <yesanishhere@gmail.com> wrote:
>
> Hello Jassi,
>
> I hope to get some more comments from you before
> spinning up a new revision.
>
> On Thu, Oct 24, 2024 at 8:38 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
> >
> > On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> > > 1. added client documentation
> > > 2. added controller documentation.
> > > 3. added framework documentation
> >
> > One doc topic on each patch, please.
> >
> > >
> > > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > > ---
> > >  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
> > >  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
> > >  Documentation/driver-api/mailbox/index.rst    |  45 ++++
> > >  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
> > >  4 files changed, 598 insertions(+)
> > >  create mode 100644 Documentation/driver-api/mailbox/client.rst
> > >  create mode 100644 Documentation/driver-api/mailbox/core.rst
> > >  create mode 100644 Documentation/driver-api/mailbox/index.rst
> > >  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > >
> > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > new file mode 100644
> > > index 000000000000..9088f8373423
> > > --- /dev/null
> > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > @@ -0,0 +1,192 @@
> > > +Mailbox Client Documentation
> > > +============================
> > > +
> > > +Overview
> > > +--------
> > > +The mailbox client driver is responsible for sending and receiving messages
> > > +to and from a remote processor. It uses mailbox APIs provided by the
> > > +mailbox framework.
> > > +
> > > +Mailbox Structure
> > > +-----------------
> > > +The mailbox structure is defined as follows:
> > > +
> > > +.. code-block:: c
> > > +
> > > +   struct mbox_client {
> > > +       //device associated with the mailbox
> > > +       struct device *dev;
> > > +       // callback for transmission completion
> > > +       void (*tx_done)(struct mbox_client *client);
> > > +       // callback to prepare for sending a message
> > > +       void (*tx_prepare)(struct mbox_client *client);
> > > +       // callback for received messages
> > > +       void (*rx_callback)(struct mbox_client *client, void *data);
> > > +       // flag to indicate if transmission should block
> > > +       bool tx_block;
> > > +       // indicates if the client knows when transmission is done
> > > +       bool knows_txdone;
> > > +   };
> > > +
> > > +Key Functions
> > > +-------------
> > > +1. Requesting a Mailbox Channel
> > > +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > +     unsigned int channel)`
> > > +   - **Description**: Requests a mailbox channel for sending messages.
> > > +   - **Parameters**:
> > > +     - `client`: Pointer to the mailbox client structure.
> > > +     - `channel`: The specific mailbox channel to request.
> > > +   - **Returns**: A pointer to the mailbox channel on success, or an error
> > > +     code on failure.
> > > +
> > > +2. Sending a Message
> > > +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > +   - **Description**: Sends a message through the mailbox channel.
> > > +   - **Parameters**:
> > > +     - `chan`: The mailbox channel used for communication.
> > > +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > +       messages).
> > > +   - **Returns**: 0 on success, or a negative error code on failure.
> > > +
> > > +3. Transmitting Completion
> > > +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > +     msg_id)`
> > > +   - **Description**: Notifies the mailbox framework that message
> > > +     transmission is complete.
> > > +   - **Parameters**:
> > > +     - `chan`: The mailbox channel associated with the message.
> > > +     - `msg_id`: The identifier of the message that was transmitted.
> >
> > These functions should've been documented as kernel-doc comments, though.
> >
> > > +
> > > +Usage Example
> > > +-------------
> > > +In a typical mailbox client driver, the following steps are typically
> > > +performed:
> > > +
> > > +1. Initialize the Mailbox Client:
> > > +
> > > +   .. code-block:: c
> > > +
> > > +      struct mbox_client my_mbox_client = {
> > > +          .dev = &my_device,
> > > +          .tx_done = my_tx_done_callback,
> > > +          .rx_callback = my_rx_callback,
> > > +          .tx_block = false,
> > > +          .knows_txdone = true,
> > > +      };
> > > +
> > > +2. Request a Mailbox Channel:
> > > +
> > > +   .. code-block:: c
> > > +
> > > +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> > > +      if (IS_ERR(mbox_chan)) {
> > > +          // Handle error
> > > +      }
> > > +
> > > +3. Send a Message:
> > > +
> > > +   .. code-block:: c
> > > +
> > > +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> > > +      if (ret < 0) {
> > > +          // Handle error
> > > +      }
> > > +
> > > +4. Complete Transmission:
> > > +
> > > +   .. code-block:: c
> > > +
> > > +      mbox_client_txdone(mbox_chan, 0);
> > > +
> > > +Interrupt Handling
> > > +------------------
> > > +The mailbox interface can trigger interrupts upon message receipt. Handlers
> > > +should be implemented in the `rx_callback` function defined in the mailbox
> > > +client structure to process incoming messages.
> > > +
> > > +Example Mailbox Client Driver
> > > +-----------------------------
> > > +.. code-block:: c
> > > +
> > > +   struct demo_client {
> > > +       struct mbox_client cl;
> > > +       struct mbox_chan *mbox;
> > > +       struct completion c;
> > > +       bool async;
> > > +       /* ... */
> > > +   };
> > > +
> > > +   /*
> > > +   * This is the handler for data received from remote. The behaviour is purely
> > > +   * dependent upon the protocol. This is just an example.
> > > +   */
> > > +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> > > +   {
> > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > +       if (dc->async) {
> > > +           if (is_an_ack(mssg)) {
> > > +               /* An ACK to our last sample sent */
> > > +               return; /* Or do something else here */
> > > +           } else { /* A new message from remote */
> > > +               queue_req(mssg);
> > > +           }
> > > +       } else {
> > > +           /* Remote f/w sends only ACK packets on this channel */
> > > +           return;
> > > +       }
> > > +   }
> > > +
> > > +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> > > +   {
> > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > +       complete(&dc->c);
> > > +   }
> > > +
> > > +   static void client_demo(struct platform_device *pdev)
> > > +   {
> > > +       struct demo_client *dc_sync, *dc_async;
> > > +       /* The controller already knows async_pkt and sync_pkt */
> > > +       struct async_pkt ap;
> > > +       struct sync_pkt sp;
> > > +
> > > +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> > > +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> > > +
> > > +       /* Populate non-blocking mode client */
> > > +       dc_async->cl.dev = &pdev->dev;
> > > +       dc_async->cl.rx_callback = message_from_remote;
> > > +       dc_async->cl.tx_done = sample_sent;
> > > +       dc_async->cl.tx_block = false;
> > > +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> > > +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> > > +       dc_async->async = true;
> > > +       init_completion(&dc_async->c);
> > > +
> > > +       /* Populate blocking mode client */
> > > +       dc_sync->cl.dev = &pdev->dev;
> > > +       dc_sync->cl.rx_callback = message_from_remote;
> > > +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> > > +       dc_sync->cl.tx_block = true;
> > > +       dc_sync->cl.tx_tout = 500; /* by half a second */
> > > +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> > > +       dc_sync->async = false;
> > > +
> > > +       /* ASync mailbox is listed second in 'mboxes' property */
> > > +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> > > +       /* Populate data packet */
> > > +       /* ap.xxx = 123; etc */
> > > +       /* Send async message to remote */
> > > +       mbox_send_message(dc_async->mbox, &ap);
> > > +
> > > +       /* Sync mailbox is listed first in 'mboxes' property */
> > > +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> > > +       /* Populate data packet */
> > > +       /* sp.abc = 123; etc */
> > > +       /* Send message to remote in blocking mode */
> > > +       mbox_send_message(dc_sync->mbox, &sp);
> > > +       /* At this point 'sp' has been sent */
> > > +
> > > +       /* Now wait for async chan to be done */
> > > +       wait_for_completion(&dc_async->c);
> > > +   }
> > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > new file mode 100644
> > > index 000000000000..d1220086da67
> > > --- /dev/null
> > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > @@ -0,0 +1,182 @@
> > > +=====================
> > > +mailbox documentation
> > > +=====================
> > > +
> > > +Hardware Introduction
> > > +=====================
> > > +
> > > +Mailbox hardware is a specialized component found in multi-core
> > > +processors and embedded systems that facilitates inter-processor
> > > +communication (IPC) or communication between different hardware
> > > +components. It provides a structured mechanism for sending and
> > > +receiving messages, allowing various processors or devices to
> > > +exchange data efficiently. Here's an overview of its key
> > > +characteristics and functions:
> > > +
> > > +Key Characteristics of Mailbox Hardware
> > > +Interrupt Handling: Many mailbox implementations support
> > > +interrupt-driven communication. This allows a receiving processor
> > > +to be alerted when a new message arrives, facilitating immediate
> > > +processing without polling the mailbox constantly.
> > > +
> > > +Hardware Registers: Mailbox hardware often includes registers for
> > > +configuration and status monitoring. These registers can be used
> > > +to control the mailbox's behavior, check for available messages,
> > > +or acknowledge message receipt.
> > > +
> > > +Support for Multiple Protocols: Mailboxes can support various
> > > +communication protocols, enabling interoperability between different
> > > +hardware components and simplifying the integration of diverse systems.
> > > +
> > > +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> > > +both synchronous and asynchronous modes. In synchronous mode, the
> > > +sender may wait for the receiver to acknowledge receipt before
> > > +proceeding, while in asynchronous mode, the sender can continue
> > > +executing other tasks immediately after sending the message.
> > > +
> > > +
> > > +Mailbox framework design
> > > +========================
> > > +
> > > +The mailbox facilitates interprocessor communication by allowing processors to
> > > +exchange messages or signals. The mailbox framework consists of:
> > > +
> > > +Mailbox Controller: This is platform-specific and is responsible for configuring
> > > +and managing interrupts from the remote processor. It offers a generic API for
> > > +the mailbox client.
> > > +
> > > +Mailbox Client: This component handles the sending and receiving of messages.
> > > +
> > > +
> > > +............................................................................
> > > +:  client driver      client_a            client_b                         :
> > > +............................................................................
> > > +                            ^-------------------^
> > > +                                    |
> > > +                                    |
> > > +............................................................................
> > > +:  controller framework          mailbox                                   :
> > > +....................................|.......................................
> > > +                                    |
> > > +                                    |
> > > +............................................................................
> > > +:  controller driver          device specific                              :
> > > +....................................|.......................................
> > > +                                    |
> > > +                                    |
> > > +kernel                              |
> > > +............................................................................
> > > +hardware                            |
> > > +                                    |
> > > +                                    |
> > > +............................................................................
> > > +:                             remote processor                             :
> > > +............................................................................
> >
> > htmldocs build errors out:
> >
> > Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
> > Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.
> >
> > ............................................................................
> > :  controller framework          mailbox                                   :
> > ....................................|.......................................
> >
> > reST markup error:
> > Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.
> >
> > ............................................................................
> > :  controller framework          mailbox                                   :
> > ....................................|.......................................
> >
> > I have to fix up the design diagram and wrap it:
> >
> > ---- >8 ----
> > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > index d1220086da679f..8d56d81007c11c 100644
> > --- a/Documentation/driver-api/mailbox/core.rst
> > +++ b/Documentation/driver-api/mailbox/core.rst
> > @@ -47,31 +47,32 @@ the mailbox client.
> >
> >  Mailbox Client: This component handles the sending and receiving of messages.
> >
> > +::
> >
> > -............................................................................
> > -:  client driver      client_a            client_b                         :
> > -............................................................................
> > -                            ^-------------------^
> > -                                    |
> > -                                    |
> > -............................................................................
> > -:  controller framework          mailbox                                   :
> > -....................................|.......................................
> > -                                    |
> > -                                    |
> > -............................................................................
> > -:  controller driver          device specific                              :
> > -....................................|.......................................
> > -                                    |
> > -                                    |
> > -kernel                              |
> > -............................................................................
> > -hardware                            |
> > -                                    |
> > -                                    |
> > -............................................................................
> > -:                             remote processor                             :
> > -............................................................................
> > +  +---------------------------------------------------------------------------+
> > +  |  client driver      client_a            client_b                          |
> > +  +---------------------------------------------------------------------------+
> > +                              ^-------------------^
> > +                                      |
> > +                                      |
> > +  +--------------------------------------------------------------------------+
> > +  |  controller framework          mailbox                                   |
> > +  +-----------------------------------|--------------------------------------+
> > +                                      |
> > +                                      |
> > +  +--------------------------------------------------------------------------+
> > +  |  controller driver          device specific                              |
> > +  +-----------------------------------|--------------------------------------+
> > +                                      |
> > +                                      |
> > +  kernel                              |
> > +  ----------------------------------------------------------------------------
> > +  hardware                            |
> > +                                      |
> > +                                      |
> > +  +--------------------------------------------------------------------------+
> > +  |                             remote processor                             |
> > +  +--------------------------------------------------------------------------+
> >
> >
> >  In the context of a mailbox framework, a channel refers to a dedicated
> >
> > > +
> > > +
> > > +In the context of a mailbox framework, a channel refers to a dedicated
> > > +communication pathway between two or more processors or components. By using
> > > +channels, the framework abstracts the complexity of interprocessor communication.
> > > +
> > > +Data Structures
> > > +================
> > > +
> > > +- **struct mbox_client**
> > > +  This structure represents a client that communicates over a mailbox
> > > +  channel. It holds information such as:
> > > +  - A pointer to the device associated with the client (`dev`).
> > > +  - Callback functions for handling message transmission events, including:
> > > +    - `rx_callback`: Called when a message is received.
> > > +    - `tx_done`: Called when a message transmission is acknowledged.
> > > +  - Flags that specify the client’s configuration, such as whether it operates
> > > +    in blocking mode.
> > > +
> > > +- **struct mbox_chan**
> > > +  This structure represents an individual mailbox channel. It maintains the
> > > +  state required for message queuing and transmission. Key members include:
> > > +  - `msg_data`: Array of messages queued for transmission.
> > > +  - `msg_count`: Number of messages currently queued.
> > > +  - `msg_free`: Index of the next free slot in the message queue.
> > > +  - `active_req`: Pointer to the currently active message being transmitted.
> > > +  - Synchronization primitives to manage access from multiple contexts.
> > > +
> > > +- **struct mbox_controller**
> > > +  This structure represents a mailbox controller that manages multiple
> > > +  channels. It includes:
> > > +  - A pointer to the device managing the mailbox.
> > > +  - Operations for sending and receiving messages, as well as initializing
> > > +    and shutting down the mailbox.
> > > +  - A list of associated channels and the total number of channels available.
> >
> > Shouldn't these structs be documented as kernel-doc comments? tl;dr:
> > see Documentation/doc-guide/kernel-doc.html
> >
> > > +
> > > +controller framework APIs
> > > +=========================
> > > +
> > > +``struct `mbox_controller` Initialization
> > > +-----------------------------------------
> >
> > Properly double-backquote the struct name to format it as inline code:
> >
> > ---- >8 ----
> > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > index 239538f497e41a..d83456164464aa 100644
> > --- a/Documentation/driver-api/mailbox/core.rst
> > +++ b/Documentation/driver-api/mailbox/core.rst
> > @@ -117,7 +117,7 @@ Data Structures
> >  controller framework APIs
> >  =========================
> >
> > -``struct `mbox_controller` Initialization
> > +``struct mbox_controller`` Initialization
> >  -----------------------------------------
> >
> >  Just like any other kernel framework, the whole mailbox controller registration
> >
> > > +
> > > +Just like any other kernel framework, the whole mailbox controller registration
> > > +relies on the driver filling a structure and registering against the
> > > +framework. In our case, that structure is mbox_controller.
> > > +
> > > +The first thing you need to do in your driver is to allocate this
> > > +structure. Any of the usual memory allocators will do, but you'll also
> > > +need to initialize a few fields in there:
> > > +
> > > +- ``dev``: should hold the pointer to the ``struct device`` associated
> > > +  to your current driver instance.
> > > +
> > > +- ``ops``: Operators that work on each communication channel.
> > > +
> > > +- ``chans``: Array of channels.
> > > +
> > > +- ``num_chans``: Number of channels in the `chans` array.
> > > +
> > > +- ``txdone_irq``: Indicates if the controller can report to the API
> > > +  when the last transmitted data was read by the
> > > +                          remote (e.g., if it has a TX ACK interrupt).
> > > +
> > > +All the below fields are not mandatory.
> > > +
> > > +- ``txdone_poll``: Indicates if the controller can read but not report
> > > +                          the TX done. For example, some register may show
> > > +                          the TX status, but no interrupt is raised. This
> > > +                          field is ignored if `txdone_irq` is set.
> > > +
> > > +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > +                          the last TX status after this many milliseconds.
> > > +
> > > +- ``of_xlate``: Controller driver-specific mapping of channel via
> > > +                          Device Tree (DT).
> > > +
> > > +
> > > +Key Functions
> > > +-------------
> > > +
> > > +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> > > +  This function registers a mailbox controller with the kernel. It makes the
> > > +  channels associated with the controller available for client requests. The
> > > +  function performs sanity checks on the controller structure to ensure all
> > > +  necessary fields are populated.
> > > +
> > > +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> > > +  This function requests a mailbox channel for a specified client, identified
> > > +  by an index. It searches for the appropriate mailbox channel, and if found,
> > > +  it returns a pointer to the channel. If the request fails (e.g., if the
> > > +  index is invalid), it returns an error pointer.
> > > +
> > > +- **void mbox_free_channel(struct mbox_chan *chan)**
> > > +  This function releases a mailbox channel that was previously allocated for a
> > > +  client. It ensures that the channel can be reused by other clients. If any
> > > +  messages are still in the queue, they are aborted, and no callbacks are made.
> > > +
> > > +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> > > +  This function is used by clients to send a message through the specified
> > > +  mailbox channel. The function can operate in either blocking or non-blocking
> > > +  mode, depending on the client’s configuration. It will queue the message for
> > > +  transmission and notify the client once the message is acknowledged.
> > > +
> > > +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> > > +  This function is called by the controller driver to notify the mailbox
> > > +  framework that a message has been received on the specified channel. The
> > > +  received message is then passed to the appropriate client's `rx_callback`
> > > +  function for processing.
> >
> > Shouldn't these functions also be documented as kernel-doc comments?
> >
> > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > new file mode 100644
> > > index 000000000000..e254a8fdb66a
> > > --- /dev/null
> > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > @@ -0,0 +1,45 @@
> > > +=======================
> > > +Mailbox documentation
> > > +=======================
> > > +
> > > +Mailbox documentation provides documents for various aspects of mailbox
> > > +framework.
> > > +
> > > +Mailbox development documentation
> > > +---------------------------------
> > > +
> > > +This book helps with mailbox internal APIs and guide for mailbox device
> > > +driver writers.
> > > +
> > > +.. toctree::
> > > +   :maxdepth: 1
> > > +
> > > +   core
> > > +
> > > +mailbox controller driver documentation
> > > +------------------------------
> > > +
> > > +This book is a guide to device driver writers on how to register
> > > +mailbox controller to the mailbox framework.
> > > +
> > > +.. toctree::
> > > +   :maxdepth: 1
> > > +
> > > +   writing_mailbox_controller_drivers
> > > +
> > > +mailbox client driver documentation
> > > +------------------------------
> >
> > Match up section underline length by its title:
> >
> > ---- >8 ----
> > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > index e254a8fdb66ac7..02d7d5e8660999 100644
> > --- a/Documentation/driver-api/mailbox/index.rst
> > +++ b/Documentation/driver-api/mailbox/index.rst
> > @@ -1,6 +1,6 @@
> > -=======================
> > +=====================
> >  Mailbox documentation
> > -=======================
> > +=====================
> >
> >  Mailbox documentation provides documents for various aspects of mailbox
> >  framework.
> > @@ -17,7 +17,7 @@ driver writers.
> >     core
> >
> >  mailbox controller driver documentation
> > -------------------------------
> > +---------------------------------------
> >
> >  This book is a guide to device driver writers on how to register
> >  mailbox controller to the mailbox framework.
> > @@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
> >     writing_mailbox_controller_drivers
> >
> >  mailbox client driver documentation
> > -------------------------------
> > +-----------------------------------
> >
> >  This book is a guide to mailbox client driver writers.
> >
> >
> > > +
> > > +This book is a guide to mailbox client driver writers.
> > > +
> > > +.. toctree::
> > > +   :maxdepth: 1
> > > +
> > > +   client
> > > +
> > > +.. only::  subproject and html
> > > +
> > > +   Indices
> > > +   =======
> > > +
> > > +   * :ref:`genindex`
> >
> > Fix up also the reference link on parent toctree:
> >
> > ---- >8 ----
> > diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
> > index 7f83e05769b4a4..b4d78b92fd921a 100644
> > --- a/Documentation/driver-api/index.rst
> > +++ b/Documentation/driver-api/index.rst
> > @@ -102,7 +102,7 @@ Subsystem-specific APIs
> >     ipmb
> >     ipmi
> >     libata
> > -   mailbox
> > +   mailbox/index
> >     md/index
> >     media/index
> >     mei/index
> >
> > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > new file mode 100644
> > > index 000000000000..2a82645c1357
> > > --- /dev/null
> > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > @@ -0,0 +1,179 @@
> > > +.. SPDX-License-Identifier: GPL-2.0
> > > +
> > > +.. _writing_mailbox_controller_drivers:
> > > +
> > > +==================================
> > > +Writing Mailbox Controller Drivers
> > > +==================================
> > > +
> > > +Introduction
> > > +============
> > > +
> > > +This document serves as a basic guideline for driver programmers that need
> > > +to hack a new mailbox controller driver or understand the essentials of
> > > +the existing ones.
> > > +
> > > +Driver Boilerplate
> > > +==================
> > > +
> > > +As a bare minimum, a mailbox controller driver needs to call
> > > +``mbox_controller_register`` function to register with the framework.
> > > +
> > > +A basic driver skeleton could look like this for a mailbox hardware that
> > > +has the following characteristics:
> > > +a. It supports only a single channel, i.e., only the remote processor can
> > > +   send interrupts.
> > > +b. Data transfer is over the registers associated with mailbox hardware.
> > > +c. Mailbox hardware is configured to receive interrupts.
> > > +d. When the remote processor is ready to send data, it triggers a mailbox
> > > +   interrupt.
> > > +e. As part of interrupt handling by Linux, it copies data from the registers.
> > > +
> > > +.. code-block:: c
> > > +
> > > +   #include <linux/device.h>
> > > +   #include <linux/interrupt.h>
> > > +   #include <linux/io.h>
> > > +   #include <linux/kernel.h>
> > > +   #include <linux/mailbox_controller.h>
> > > +   #include <linux/module.h>
> > > +   #include <linux/of.h>
> > > +   #include <linux/platform_device.h>
> > > +   #define DRIVER_NAME "dummy_controller"
> > > +
> > > +   struct dummy_mbox {
> > > +       struct device *dev;
> > > +       struct mbox_controller controller;
> > > +       int irq;
> > > +   };
> > > +
> > > +   static void dummy_mbox_receive(struct mbox_chan *chan)
> > > +   {
> > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > +       int val;
> > > +
> > > +       // Data copied from registers
> > > +       val = read_register();
> > > +       mbox_chan_received_data(chan, &val);
> > > +   }
> > > +
> > > +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> > > +   {
> > > +       struct mbox_chan *chan = data;
> > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > +       u32 reg;
> > > +
> > > +       // Read registers to see if data is received
> > > +       dummy_mbox_receive(chan);
> > > +       mbox_chan_txdone(chan, 0);
> > > +       return reg ? IRQ_HANDLED : IRQ_NONE;
> > > +   }
> > > +
> > > +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> > > +   {
> > > +       // Write data in registers to send it to the remote processor
> > > +       return 0;
> > > +   }
> > > +
> > > +   static int dummy_mbox_startup(struct mbox_chan *chan)
> > > +   {
> > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > +       u32 reg;
> > > +       int ret;
> > > +
> > > +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> > > +               DRIVER_NAME, chan);
> > > +       if (ret < 0) {
> > > +           dev_err(mbox->dev, "Cannot request irq\n");
> > > +           return ret;
> > > +       }
> > > +
> > > +       /* Register write to enable IRQ generation */
> > > +
> > > +       return 0;
> > > +   }
> > > +
> > > +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> > > +   {
> > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > +
> > > +       /* Disable interrupt generation */
> > > +       devm_free_irq(mbox->dev, mbox->irq, chan);
> > > +   }
> > > +
> > > +   static const struct mbox_chan_ops dummy_mbox_ops = {
> > > +       .send_data = dummy_mbox_send_data,
> > > +       .startup = dummy_mbox_startup,
> > > +       .shutdown = dummy_mbox_shutdown,
> > > +   };
> > > +
> > > +   static int dummy_mbox_probe(struct platform_device *pdev)
> > > +   {
> > > +       struct dummy_mbox *mbox;
> > > +       struct mbox_chan *chans;
> > > +       int ret;
> > > +
> > > +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> > > +       if (!mbox)
> > > +           return -ENOMEM;
> > > +
> > > +       /* Allocate one channel */
> > > +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> > > +       if (!chans)
> > > +           return -ENOMEM;
> > > +
> > > +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> > > +       if (IS_ERR(mbox->base))
> > > +           return PTR_ERR(mbox->base);
> > > +
> > > +       mbox->irq = platform_get_irq(pdev, 0);
> > > +       if (mbox->irq < 0)
> > > +           return mbox->irq;
> > > +
> > > +       mbox->dev = &pdev->dev;
> > > +
> > > +       /* Hardware supports only one channel. */
> > > +       mbox->controller.dev = mbox->dev;
> > > +       mbox->controller.num_chans = 1;
> > > +       mbox->controller.chans = chans;
> > > +       mbox->controller.ops = &dummy_mbox_ops;
> > > +       mbox->controller.txdone_irq = true;
> > > +
> > > +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> > > +       if (ret) {
> > > +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> > > +           return ret;
> > > +       }
> > > +
> > > +       return ret;
> > > +   }
> > > +
> > > +   static const struct of_device_id dummy_mbox_match[] = {
> > > +       { .compatible = "dummy,dummy-mailbox" },
> > > +       { },
> > > +   };
> > > +
> > > +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> > > +
> > > +   static struct platform_driver dummy_mbox_driver = {
> > > +       .probe = dummy_mbox_probe,
> > > +       .driver = {
> > > +           .name = DRIVER_NAME,
> > > +           .of_match_table = dummy_mbox_match,
> > > +       },
> > > +   };
> > > +
> > > +   module_platform_driver(dummy_mbox_driver);
> > > +   MODULE_LICENSE("GPL v2");
> > > +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > +
> > > +In the above code, a couple of things are done:
> > > +a. The controller is registered in the probe along with callbacks, which in
> > > +   this case are the bare minimum: ``startup``, ``shutdown``, and
> > > +   ``send_data``.
> > > +b. IRQ is registered to get notifications from the remote processor.
> > > +c. In the IRQ handler, registers are read to copy data, and
> > > +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> > > +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> > > +   is the last data and no more data is to be expected for the current transfer.
> > > +
> >
> > Sphinx warns out numerous indentation warnings on the lists, so I have to
> > fix them up:
> >
> > ---- >8 ----
> > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > index 9088f83734230d..17dafaca056777 100644
> > --- a/Documentation/driver-api/mailbox/client.rst
> > +++ b/Documentation/driver-api/mailbox/client.rst
> > @@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
> >  Key Functions
> >  -------------
> >  1. Requesting a Mailbox Channel
> > +
> >     - **Function**: `mbox_request_channel(struct mbox_client *client,
> >       unsigned int channel)`
> >     - **Description**: Requests a mailbox channel for sending messages.
> > @@ -41,15 +42,19 @@ Key Functions
> >       code on failure.
> >
> >  2. Sending a Message
> > +
> >     - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> >     - **Description**: Sends a message through the mailbox channel.
> >     - **Parameters**:
> > +
> >       - `chan`: The mailbox channel used for communication.
> >       - `msg`: Pointer to the message to be sent (usually NULL for dummy
> >         messages).
> > +
> >     - **Returns**: 0 on success, or a negative error code on failure.
> >
> >  3. Transmitting Completion
> > +
> >     - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> >       msg_id)`
> >     - **Description**: Notifies the mailbox framework that message
> > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > index 8d56d81007c11c..239538f497e41a 100644
> > --- a/Documentation/driver-api/mailbox/core.rst
> > +++ b/Documentation/driver-api/mailbox/core.rst
> > @@ -85,16 +85,20 @@ Data Structures
> >  - **struct mbox_client**
> >    This structure represents a client that communicates over a mailbox
> >    channel. It holds information such as:
> > +
> >    - A pointer to the device associated with the client (`dev`).
> >    - Callback functions for handling message transmission events, including:
> > +
> >      - `rx_callback`: Called when a message is received.
> >      - `tx_done`: Called when a message transmission is acknowledged.
> > +
> >    - Flags that specify the client’s configuration, such as whether it operates
> >      in blocking mode.
> >
> >  - **struct mbox_chan**
> >    This structure represents an individual mailbox channel. It maintains the
> >    state required for message queuing and transmission. Key members include:
> > +
> >    - `msg_data`: Array of messages queued for transmission.
> >    - `msg_count`: Number of messages currently queued.
> >    - `msg_free`: Index of the next free slot in the message queue.
> > @@ -104,6 +108,7 @@ Data Structures
> >  - **struct mbox_controller**
> >    This structure represents a mailbox controller that manages multiple
> >    channels. It includes:
> > +
> >    - A pointer to the device managing the mailbox.
> >    - Operations for sending and receiving messages, as well as initializing
> >      and shutting down the mailbox.
> > @@ -133,21 +138,20 @@ need to initialize a few fields in there:
> >  - ``num_chans``: Number of channels in the `chans` array.
> >
> >  - ``txdone_irq``: Indicates if the controller can report to the API
> > -  when the last transmitted data was read by the
> > -                          remote (e.g., if it has a TX ACK interrupt).
> > +  when the last transmitted data was read by the remote (e.g., if it has a
> > +  TX ACK interrupt).
> >
> >  All the below fields are not mandatory.
> >
> >  - ``txdone_poll``: Indicates if the controller can read but not report
> > -                          the TX done. For example, some register may show
> > -                          the TX status, but no interrupt is raised. This
> > -                          field is ignored if `txdone_irq` is set.
> > +  the TX done. For example, some register may show the TX status, but no
> > +  interrupt is raised. This field is ignored if `txdone_irq` is set.
> >
> >  - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > -                          the last TX status after this many milliseconds.
> > +  the last TX status after this many milliseconds.
> >
> >  - ``of_xlate``: Controller driver-specific mapping of channel via
> > -                          Device Tree (DT).
> > +  Device Tree (DT).
> >
> >
> >  Key Functions
> > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > index 2a82645c13573e..853adf6918173d 100644
> > --- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > @@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
> >
> >  A basic driver skeleton could look like this for a mailbox hardware that
> >  has the following characteristics:
> > +
> >  a. It supports only a single channel, i.e., only the remote processor can
> >     send interrupts.
> >  b. Data transfer is over the registers associated with mailbox hardware.
> > @@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
> >     MODULE_DESCRIPTION("Dummy mailbox controller driver");
> >
> >  In the above code, a couple of things are done:
> > +
> >  a. The controller is registered in the probe along with callbacks, which in
> >     this case are the bare minimum: ``startup``, ``shutdown``, and
> >     ``send_data``.
> >
> > Thanks.
> >
> > --
> > An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-29 18:06       ` anish kumar
@ 2024-10-29 23:51         ` Bagas Sanjaya
  2024-10-30  0:42           ` anish kumar
  2024-10-30 17:41         ` Jassi Brar
  1 sibling, 1 reply; 12+ messages in thread
From: Bagas Sanjaya @ 2024-10-29 23:51 UTC (permalink / raw)
  To: anish kumar, jassisinghbrar, Jonathan Corbet; +Cc: linux-doc, linux-kernel

On 10/30/24 01:06, anish kumar wrote:
> Hello Jassi,
> 
> Gentle reminder for the review.
> 

Reroll.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-29 23:51         ` Bagas Sanjaya
@ 2024-10-30  0:42           ` anish kumar
  2024-10-30  1:17             ` Bagas Sanjaya
  0 siblings, 1 reply; 12+ messages in thread
From: anish kumar @ 2024-10-30  0:42 UTC (permalink / raw)
  To: Bagas Sanjaya; +Cc: jassisinghbrar, Jonathan Corbet, linux-doc, linux-kernel

On Tue, Oct 29, 2024 at 4:51 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
>
> On 10/30/24 01:06, anish kumar wrote:
> > Hello Jassi,
> >
> > Gentle reminder for the review.
> >
>
> Reroll.

Waiting for him to provide any additional comments otherwise
I will have to upload a new rev after that.
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-30  0:42           ` anish kumar
@ 2024-10-30  1:17             ` Bagas Sanjaya
  0 siblings, 0 replies; 12+ messages in thread
From: Bagas Sanjaya @ 2024-10-30  1:17 UTC (permalink / raw)
  To: anish kumar; +Cc: jassisinghbrar, Jonathan Corbet, linux-doc, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 540 bytes --]

On Tue, Oct 29, 2024 at 05:42:32PM -0700, anish kumar wrote:
> On Tue, Oct 29, 2024 at 4:51 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
> >
> > On 10/30/24 01:06, anish kumar wrote:
> > > Hello Jassi,
> > >
> > > Gentle reminder for the review.
> > >
> >
> > Reroll.
> 
> Waiting for him to provide any additional comments otherwise
> I will have to upload a new rev after that.
> >

IMO you can reroll anyway with my review suggestions applied.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-29 18:06       ` anish kumar
  2024-10-29 23:51         ` Bagas Sanjaya
@ 2024-10-30 17:41         ` Jassi Brar
  2024-10-30 18:13           ` anish kumar
  1 sibling, 1 reply; 12+ messages in thread
From: Jassi Brar @ 2024-10-30 17:41 UTC (permalink / raw)
  To: anish kumar; +Cc: Jonathan Corbet, linux-doc, linux-kernel, Bagas Sanjaya

Hi Anish,
  It is the third ping within 10 days, please avoid. Documentation is
not a high priority, esp when it is mostly copying info from header
files.
I haven't looked closely and you haven't mentioned in the log what new
info are you adding or clearer?
From a quick look it seems just api explanation copied into doc
format. Will look closer later.

Thanks

On Tue, Oct 29, 2024 at 1:06 PM anish kumar <yesanishhere@gmail.com> wrote:
>
> Hello Jassi,
>
> Gentle reminder for the review.
>
> On Fri, Oct 25, 2024 at 12:24 PM anish kumar <yesanishhere@gmail.com> wrote:
> >
> > Hello Jassi,
> >
> > I hope to get some more comments from you before
> > spinning up a new revision.
> >
> > On Thu, Oct 24, 2024 at 8:38 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
> > >
> > > On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> > > > 1. added client documentation
> > > > 2. added controller documentation.
> > > > 3. added framework documentation
> > >
> > > One doc topic on each patch, please.
> > >
> > > >
> > > > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > > > ---
> > > >  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
> > > >  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
> > > >  Documentation/driver-api/mailbox/index.rst    |  45 ++++
> > > >  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
> > > >  4 files changed, 598 insertions(+)
> > > >  create mode 100644 Documentation/driver-api/mailbox/client.rst
> > > >  create mode 100644 Documentation/driver-api/mailbox/core.rst
> > > >  create mode 100644 Documentation/driver-api/mailbox/index.rst
> > > >  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > >
> > > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > > new file mode 100644
> > > > index 000000000000..9088f8373423
> > > > --- /dev/null
> > > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > > @@ -0,0 +1,192 @@
> > > > +Mailbox Client Documentation
> > > > +============================
> > > > +
> > > > +Overview
> > > > +--------
> > > > +The mailbox client driver is responsible for sending and receiving messages
> > > > +to and from a remote processor. It uses mailbox APIs provided by the
> > > > +mailbox framework.
> > > > +
> > > > +Mailbox Structure
> > > > +-----------------
> > > > +The mailbox structure is defined as follows:
> > > > +
> > > > +.. code-block:: c
> > > > +
> > > > +   struct mbox_client {
> > > > +       //device associated with the mailbox
> > > > +       struct device *dev;
> > > > +       // callback for transmission completion
> > > > +       void (*tx_done)(struct mbox_client *client);
> > > > +       // callback to prepare for sending a message
> > > > +       void (*tx_prepare)(struct mbox_client *client);
> > > > +       // callback for received messages
> > > > +       void (*rx_callback)(struct mbox_client *client, void *data);
> > > > +       // flag to indicate if transmission should block
> > > > +       bool tx_block;
> > > > +       // indicates if the client knows when transmission is done
> > > > +       bool knows_txdone;
> > > > +   };
> > > > +
> > > > +Key Functions
> > > > +-------------
> > > > +1. Requesting a Mailbox Channel
> > > > +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > > +     unsigned int channel)`
> > > > +   - **Description**: Requests a mailbox channel for sending messages.
> > > > +   - **Parameters**:
> > > > +     - `client`: Pointer to the mailbox client structure.
> > > > +     - `channel`: The specific mailbox channel to request.
> > > > +   - **Returns**: A pointer to the mailbox channel on success, or an error
> > > > +     code on failure.
> > > > +
> > > > +2. Sending a Message
> > > > +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > > +   - **Description**: Sends a message through the mailbox channel.
> > > > +   - **Parameters**:
> > > > +     - `chan`: The mailbox channel used for communication.
> > > > +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > > +       messages).
> > > > +   - **Returns**: 0 on success, or a negative error code on failure.
> > > > +
> > > > +3. Transmitting Completion
> > > > +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > > +     msg_id)`
> > > > +   - **Description**: Notifies the mailbox framework that message
> > > > +     transmission is complete.
> > > > +   - **Parameters**:
> > > > +     - `chan`: The mailbox channel associated with the message.
> > > > +     - `msg_id`: The identifier of the message that was transmitted.
> > >
> > > These functions should've been documented as kernel-doc comments, though.
> > >
> > > > +
> > > > +Usage Example
> > > > +-------------
> > > > +In a typical mailbox client driver, the following steps are typically
> > > > +performed:
> > > > +
> > > > +1. Initialize the Mailbox Client:
> > > > +
> > > > +   .. code-block:: c
> > > > +
> > > > +      struct mbox_client my_mbox_client = {
> > > > +          .dev = &my_device,
> > > > +          .tx_done = my_tx_done_callback,
> > > > +          .rx_callback = my_rx_callback,
> > > > +          .tx_block = false,
> > > > +          .knows_txdone = true,
> > > > +      };
> > > > +
> > > > +2. Request a Mailbox Channel:
> > > > +
> > > > +   .. code-block:: c
> > > > +
> > > > +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> > > > +      if (IS_ERR(mbox_chan)) {
> > > > +          // Handle error
> > > > +      }
> > > > +
> > > > +3. Send a Message:
> > > > +
> > > > +   .. code-block:: c
> > > > +
> > > > +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> > > > +      if (ret < 0) {
> > > > +          // Handle error
> > > > +      }
> > > > +
> > > > +4. Complete Transmission:
> > > > +
> > > > +   .. code-block:: c
> > > > +
> > > > +      mbox_client_txdone(mbox_chan, 0);
> > > > +
> > > > +Interrupt Handling
> > > > +------------------
> > > > +The mailbox interface can trigger interrupts upon message receipt. Handlers
> > > > +should be implemented in the `rx_callback` function defined in the mailbox
> > > > +client structure to process incoming messages.
> > > > +
> > > > +Example Mailbox Client Driver
> > > > +-----------------------------
> > > > +.. code-block:: c
> > > > +
> > > > +   struct demo_client {
> > > > +       struct mbox_client cl;
> > > > +       struct mbox_chan *mbox;
> > > > +       struct completion c;
> > > > +       bool async;
> > > > +       /* ... */
> > > > +   };
> > > > +
> > > > +   /*
> > > > +   * This is the handler for data received from remote. The behaviour is purely
> > > > +   * dependent upon the protocol. This is just an example.
> > > > +   */
> > > > +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> > > > +   {
> > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > +       if (dc->async) {
> > > > +           if (is_an_ack(mssg)) {
> > > > +               /* An ACK to our last sample sent */
> > > > +               return; /* Or do something else here */
> > > > +           } else { /* A new message from remote */
> > > > +               queue_req(mssg);
> > > > +           }
> > > > +       } else {
> > > > +           /* Remote f/w sends only ACK packets on this channel */
> > > > +           return;
> > > > +       }
> > > > +   }
> > > > +
> > > > +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> > > > +   {
> > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > +       complete(&dc->c);
> > > > +   }
> > > > +
> > > > +   static void client_demo(struct platform_device *pdev)
> > > > +   {
> > > > +       struct demo_client *dc_sync, *dc_async;
> > > > +       /* The controller already knows async_pkt and sync_pkt */
> > > > +       struct async_pkt ap;
> > > > +       struct sync_pkt sp;
> > > > +
> > > > +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> > > > +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> > > > +
> > > > +       /* Populate non-blocking mode client */
> > > > +       dc_async->cl.dev = &pdev->dev;
> > > > +       dc_async->cl.rx_callback = message_from_remote;
> > > > +       dc_async->cl.tx_done = sample_sent;
> > > > +       dc_async->cl.tx_block = false;
> > > > +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> > > > +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> > > > +       dc_async->async = true;
> > > > +       init_completion(&dc_async->c);
> > > > +
> > > > +       /* Populate blocking mode client */
> > > > +       dc_sync->cl.dev = &pdev->dev;
> > > > +       dc_sync->cl.rx_callback = message_from_remote;
> > > > +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> > > > +       dc_sync->cl.tx_block = true;
> > > > +       dc_sync->cl.tx_tout = 500; /* by half a second */
> > > > +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> > > > +       dc_sync->async = false;
> > > > +
> > > > +       /* ASync mailbox is listed second in 'mboxes' property */
> > > > +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> > > > +       /* Populate data packet */
> > > > +       /* ap.xxx = 123; etc */
> > > > +       /* Send async message to remote */
> > > > +       mbox_send_message(dc_async->mbox, &ap);
> > > > +
> > > > +       /* Sync mailbox is listed first in 'mboxes' property */
> > > > +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> > > > +       /* Populate data packet */
> > > > +       /* sp.abc = 123; etc */
> > > > +       /* Send message to remote in blocking mode */
> > > > +       mbox_send_message(dc_sync->mbox, &sp);
> > > > +       /* At this point 'sp' has been sent */
> > > > +
> > > > +       /* Now wait for async chan to be done */
> > > > +       wait_for_completion(&dc_async->c);
> > > > +   }
> > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > new file mode 100644
> > > > index 000000000000..d1220086da67
> > > > --- /dev/null
> > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > @@ -0,0 +1,182 @@
> > > > +=====================
> > > > +mailbox documentation
> > > > +=====================
> > > > +
> > > > +Hardware Introduction
> > > > +=====================
> > > > +
> > > > +Mailbox hardware is a specialized component found in multi-core
> > > > +processors and embedded systems that facilitates inter-processor
> > > > +communication (IPC) or communication between different hardware
> > > > +components. It provides a structured mechanism for sending and
> > > > +receiving messages, allowing various processors or devices to
> > > > +exchange data efficiently. Here's an overview of its key
> > > > +characteristics and functions:
> > > > +
> > > > +Key Characteristics of Mailbox Hardware
> > > > +Interrupt Handling: Many mailbox implementations support
> > > > +interrupt-driven communication. This allows a receiving processor
> > > > +to be alerted when a new message arrives, facilitating immediate
> > > > +processing without polling the mailbox constantly.
> > > > +
> > > > +Hardware Registers: Mailbox hardware often includes registers for
> > > > +configuration and status monitoring. These registers can be used
> > > > +to control the mailbox's behavior, check for available messages,
> > > > +or acknowledge message receipt.
> > > > +
> > > > +Support for Multiple Protocols: Mailboxes can support various
> > > > +communication protocols, enabling interoperability between different
> > > > +hardware components and simplifying the integration of diverse systems.
> > > > +
> > > > +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> > > > +both synchronous and asynchronous modes. In synchronous mode, the
> > > > +sender may wait for the receiver to acknowledge receipt before
> > > > +proceeding, while in asynchronous mode, the sender can continue
> > > > +executing other tasks immediately after sending the message.
> > > > +
> > > > +
> > > > +Mailbox framework design
> > > > +========================
> > > > +
> > > > +The mailbox facilitates interprocessor communication by allowing processors to
> > > > +exchange messages or signals. The mailbox framework consists of:
> > > > +
> > > > +Mailbox Controller: This is platform-specific and is responsible for configuring
> > > > +and managing interrupts from the remote processor. It offers a generic API for
> > > > +the mailbox client.
> > > > +
> > > > +Mailbox Client: This component handles the sending and receiving of messages.
> > > > +
> > > > +
> > > > +............................................................................
> > > > +:  client driver      client_a            client_b                         :
> > > > +............................................................................
> > > > +                            ^-------------------^
> > > > +                                    |
> > > > +                                    |
> > > > +............................................................................
> > > > +:  controller framework          mailbox                                   :
> > > > +....................................|.......................................
> > > > +                                    |
> > > > +                                    |
> > > > +............................................................................
> > > > +:  controller driver          device specific                              :
> > > > +....................................|.......................................
> > > > +                                    |
> > > > +                                    |
> > > > +kernel                              |
> > > > +............................................................................
> > > > +hardware                            |
> > > > +                                    |
> > > > +                                    |
> > > > +............................................................................
> > > > +:                             remote processor                             :
> > > > +............................................................................
> > >
> > > htmldocs build errors out:
> > >
> > > Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
> > > Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.
> > >
> > > ............................................................................
> > > :  controller framework          mailbox                                   :
> > > ....................................|.......................................
> > >
> > > reST markup error:
> > > Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.
> > >
> > > ............................................................................
> > > :  controller framework          mailbox                                   :
> > > ....................................|.......................................
> > >
> > > I have to fix up the design diagram and wrap it:
> > >
> > > ---- >8 ----
> > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > index d1220086da679f..8d56d81007c11c 100644
> > > --- a/Documentation/driver-api/mailbox/core.rst
> > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > @@ -47,31 +47,32 @@ the mailbox client.
> > >
> > >  Mailbox Client: This component handles the sending and receiving of messages.
> > >
> > > +::
> > >
> > > -............................................................................
> > > -:  client driver      client_a            client_b                         :
> > > -............................................................................
> > > -                            ^-------------------^
> > > -                                    |
> > > -                                    |
> > > -............................................................................
> > > -:  controller framework          mailbox                                   :
> > > -....................................|.......................................
> > > -                                    |
> > > -                                    |
> > > -............................................................................
> > > -:  controller driver          device specific                              :
> > > -....................................|.......................................
> > > -                                    |
> > > -                                    |
> > > -kernel                              |
> > > -............................................................................
> > > -hardware                            |
> > > -                                    |
> > > -                                    |
> > > -............................................................................
> > > -:                             remote processor                             :
> > > -............................................................................
> > > +  +---------------------------------------------------------------------------+
> > > +  |  client driver      client_a            client_b                          |
> > > +  +---------------------------------------------------------------------------+
> > > +                              ^-------------------^
> > > +                                      |
> > > +                                      |
> > > +  +--------------------------------------------------------------------------+
> > > +  |  controller framework          mailbox                                   |
> > > +  +-----------------------------------|--------------------------------------+
> > > +                                      |
> > > +                                      |
> > > +  +--------------------------------------------------------------------------+
> > > +  |  controller driver          device specific                              |
> > > +  +-----------------------------------|--------------------------------------+
> > > +                                      |
> > > +                                      |
> > > +  kernel                              |
> > > +  ----------------------------------------------------------------------------
> > > +  hardware                            |
> > > +                                      |
> > > +                                      |
> > > +  +--------------------------------------------------------------------------+
> > > +  |                             remote processor                             |
> > > +  +--------------------------------------------------------------------------+
> > >
> > >
> > >  In the context of a mailbox framework, a channel refers to a dedicated
> > >
> > > > +
> > > > +
> > > > +In the context of a mailbox framework, a channel refers to a dedicated
> > > > +communication pathway between two or more processors or components. By using
> > > > +channels, the framework abstracts the complexity of interprocessor communication.
> > > > +
> > > > +Data Structures
> > > > +================
> > > > +
> > > > +- **struct mbox_client**
> > > > +  This structure represents a client that communicates over a mailbox
> > > > +  channel. It holds information such as:
> > > > +  - A pointer to the device associated with the client (`dev`).
> > > > +  - Callback functions for handling message transmission events, including:
> > > > +    - `rx_callback`: Called when a message is received.
> > > > +    - `tx_done`: Called when a message transmission is acknowledged.
> > > > +  - Flags that specify the client’s configuration, such as whether it operates
> > > > +    in blocking mode.
> > > > +
> > > > +- **struct mbox_chan**
> > > > +  This structure represents an individual mailbox channel. It maintains the
> > > > +  state required for message queuing and transmission. Key members include:
> > > > +  - `msg_data`: Array of messages queued for transmission.
> > > > +  - `msg_count`: Number of messages currently queued.
> > > > +  - `msg_free`: Index of the next free slot in the message queue.
> > > > +  - `active_req`: Pointer to the currently active message being transmitted.
> > > > +  - Synchronization primitives to manage access from multiple contexts.
> > > > +
> > > > +- **struct mbox_controller**
> > > > +  This structure represents a mailbox controller that manages multiple
> > > > +  channels. It includes:
> > > > +  - A pointer to the device managing the mailbox.
> > > > +  - Operations for sending and receiving messages, as well as initializing
> > > > +    and shutting down the mailbox.
> > > > +  - A list of associated channels and the total number of channels available.
> > >
> > > Shouldn't these structs be documented as kernel-doc comments? tl;dr:
> > > see Documentation/doc-guide/kernel-doc.html
> > >
> > > > +
> > > > +controller framework APIs
> > > > +=========================
> > > > +
> > > > +``struct `mbox_controller` Initialization
> > > > +-----------------------------------------
> > >
> > > Properly double-backquote the struct name to format it as inline code:
> > >
> > > ---- >8 ----
> > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > index 239538f497e41a..d83456164464aa 100644
> > > --- a/Documentation/driver-api/mailbox/core.rst
> > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > @@ -117,7 +117,7 @@ Data Structures
> > >  controller framework APIs
> > >  =========================
> > >
> > > -``struct `mbox_controller` Initialization
> > > +``struct mbox_controller`` Initialization
> > >  -----------------------------------------
> > >
> > >  Just like any other kernel framework, the whole mailbox controller registration
> > >
> > > > +
> > > > +Just like any other kernel framework, the whole mailbox controller registration
> > > > +relies on the driver filling a structure and registering against the
> > > > +framework. In our case, that structure is mbox_controller.
> > > > +
> > > > +The first thing you need to do in your driver is to allocate this
> > > > +structure. Any of the usual memory allocators will do, but you'll also
> > > > +need to initialize a few fields in there:
> > > > +
> > > > +- ``dev``: should hold the pointer to the ``struct device`` associated
> > > > +  to your current driver instance.
> > > > +
> > > > +- ``ops``: Operators that work on each communication channel.
> > > > +
> > > > +- ``chans``: Array of channels.
> > > > +
> > > > +- ``num_chans``: Number of channels in the `chans` array.
> > > > +
> > > > +- ``txdone_irq``: Indicates if the controller can report to the API
> > > > +  when the last transmitted data was read by the
> > > > +                          remote (e.g., if it has a TX ACK interrupt).
> > > > +
> > > > +All the below fields are not mandatory.
> > > > +
> > > > +- ``txdone_poll``: Indicates if the controller can read but not report
> > > > +                          the TX done. For example, some register may show
> > > > +                          the TX status, but no interrupt is raised. This
> > > > +                          field is ignored if `txdone_irq` is set.
> > > > +
> > > > +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > > +                          the last TX status after this many milliseconds.
> > > > +
> > > > +- ``of_xlate``: Controller driver-specific mapping of channel via
> > > > +                          Device Tree (DT).
> > > > +
> > > > +
> > > > +Key Functions
> > > > +-------------
> > > > +
> > > > +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> > > > +  This function registers a mailbox controller with the kernel. It makes the
> > > > +  channels associated with the controller available for client requests. The
> > > > +  function performs sanity checks on the controller structure to ensure all
> > > > +  necessary fields are populated.
> > > > +
> > > > +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> > > > +  This function requests a mailbox channel for a specified client, identified
> > > > +  by an index. It searches for the appropriate mailbox channel, and if found,
> > > > +  it returns a pointer to the channel. If the request fails (e.g., if the
> > > > +  index is invalid), it returns an error pointer.
> > > > +
> > > > +- **void mbox_free_channel(struct mbox_chan *chan)**
> > > > +  This function releases a mailbox channel that was previously allocated for a
> > > > +  client. It ensures that the channel can be reused by other clients. If any
> > > > +  messages are still in the queue, they are aborted, and no callbacks are made.
> > > > +
> > > > +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> > > > +  This function is used by clients to send a message through the specified
> > > > +  mailbox channel. The function can operate in either blocking or non-blocking
> > > > +  mode, depending on the client’s configuration. It will queue the message for
> > > > +  transmission and notify the client once the message is acknowledged.
> > > > +
> > > > +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> > > > +  This function is called by the controller driver to notify the mailbox
> > > > +  framework that a message has been received on the specified channel. The
> > > > +  received message is then passed to the appropriate client's `rx_callback`
> > > > +  function for processing.
> > >
> > > Shouldn't these functions also be documented as kernel-doc comments?
> > >
> > > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > > new file mode 100644
> > > > index 000000000000..e254a8fdb66a
> > > > --- /dev/null
> > > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > > @@ -0,0 +1,45 @@
> > > > +=======================
> > > > +Mailbox documentation
> > > > +=======================
> > > > +
> > > > +Mailbox documentation provides documents for various aspects of mailbox
> > > > +framework.
> > > > +
> > > > +Mailbox development documentation
> > > > +---------------------------------
> > > > +
> > > > +This book helps with mailbox internal APIs and guide for mailbox device
> > > > +driver writers.
> > > > +
> > > > +.. toctree::
> > > > +   :maxdepth: 1
> > > > +
> > > > +   core
> > > > +
> > > > +mailbox controller driver documentation
> > > > +------------------------------
> > > > +
> > > > +This book is a guide to device driver writers on how to register
> > > > +mailbox controller to the mailbox framework.
> > > > +
> > > > +.. toctree::
> > > > +   :maxdepth: 1
> > > > +
> > > > +   writing_mailbox_controller_drivers
> > > > +
> > > > +mailbox client driver documentation
> > > > +------------------------------
> > >
> > > Match up section underline length by its title:
> > >
> > > ---- >8 ----
> > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > index e254a8fdb66ac7..02d7d5e8660999 100644
> > > --- a/Documentation/driver-api/mailbox/index.rst
> > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > @@ -1,6 +1,6 @@
> > > -=======================
> > > +=====================
> > >  Mailbox documentation
> > > -=======================
> > > +=====================
> > >
> > >  Mailbox documentation provides documents for various aspects of mailbox
> > >  framework.
> > > @@ -17,7 +17,7 @@ driver writers.
> > >     core
> > >
> > >  mailbox controller driver documentation
> > > -------------------------------
> > > +---------------------------------------
> > >
> > >  This book is a guide to device driver writers on how to register
> > >  mailbox controller to the mailbox framework.
> > > @@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
> > >     writing_mailbox_controller_drivers
> > >
> > >  mailbox client driver documentation
> > > -------------------------------
> > > +-----------------------------------
> > >
> > >  This book is a guide to mailbox client driver writers.
> > >
> > >
> > > > +
> > > > +This book is a guide to mailbox client driver writers.
> > > > +
> > > > +.. toctree::
> > > > +   :maxdepth: 1
> > > > +
> > > > +   client
> > > > +
> > > > +.. only::  subproject and html
> > > > +
> > > > +   Indices
> > > > +   =======
> > > > +
> > > > +   * :ref:`genindex`
> > >
> > > Fix up also the reference link on parent toctree:
> > >
> > > ---- >8 ----
> > > diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
> > > index 7f83e05769b4a4..b4d78b92fd921a 100644
> > > --- a/Documentation/driver-api/index.rst
> > > +++ b/Documentation/driver-api/index.rst
> > > @@ -102,7 +102,7 @@ Subsystem-specific APIs
> > >     ipmb
> > >     ipmi
> > >     libata
> > > -   mailbox
> > > +   mailbox/index
> > >     md/index
> > >     media/index
> > >     mei/index
> > >
> > > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > new file mode 100644
> > > > index 000000000000..2a82645c1357
> > > > --- /dev/null
> > > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > @@ -0,0 +1,179 @@
> > > > +.. SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +.. _writing_mailbox_controller_drivers:
> > > > +
> > > > +==================================
> > > > +Writing Mailbox Controller Drivers
> > > > +==================================
> > > > +
> > > > +Introduction
> > > > +============
> > > > +
> > > > +This document serves as a basic guideline for driver programmers that need
> > > > +to hack a new mailbox controller driver or understand the essentials of
> > > > +the existing ones.
> > > > +
> > > > +Driver Boilerplate
> > > > +==================
> > > > +
> > > > +As a bare minimum, a mailbox controller driver needs to call
> > > > +``mbox_controller_register`` function to register with the framework.
> > > > +
> > > > +A basic driver skeleton could look like this for a mailbox hardware that
> > > > +has the following characteristics:
> > > > +a. It supports only a single channel, i.e., only the remote processor can
> > > > +   send interrupts.
> > > > +b. Data transfer is over the registers associated with mailbox hardware.
> > > > +c. Mailbox hardware is configured to receive interrupts.
> > > > +d. When the remote processor is ready to send data, it triggers a mailbox
> > > > +   interrupt.
> > > > +e. As part of interrupt handling by Linux, it copies data from the registers.
> > > > +
> > > > +.. code-block:: c
> > > > +
> > > > +   #include <linux/device.h>
> > > > +   #include <linux/interrupt.h>
> > > > +   #include <linux/io.h>
> > > > +   #include <linux/kernel.h>
> > > > +   #include <linux/mailbox_controller.h>
> > > > +   #include <linux/module.h>
> > > > +   #include <linux/of.h>
> > > > +   #include <linux/platform_device.h>
> > > > +   #define DRIVER_NAME "dummy_controller"
> > > > +
> > > > +   struct dummy_mbox {
> > > > +       struct device *dev;
> > > > +       struct mbox_controller controller;
> > > > +       int irq;
> > > > +   };
> > > > +
> > > > +   static void dummy_mbox_receive(struct mbox_chan *chan)
> > > > +   {
> > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > +       int val;
> > > > +
> > > > +       // Data copied from registers
> > > > +       val = read_register();
> > > > +       mbox_chan_received_data(chan, &val);
> > > > +   }
> > > > +
> > > > +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> > > > +   {
> > > > +       struct mbox_chan *chan = data;
> > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > +       u32 reg;
> > > > +
> > > > +       // Read registers to see if data is received
> > > > +       dummy_mbox_receive(chan);
> > > > +       mbox_chan_txdone(chan, 0);
> > > > +       return reg ? IRQ_HANDLED : IRQ_NONE;
> > > > +   }
> > > > +
> > > > +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> > > > +   {
> > > > +       // Write data in registers to send it to the remote processor
> > > > +       return 0;
> > > > +   }
> > > > +
> > > > +   static int dummy_mbox_startup(struct mbox_chan *chan)
> > > > +   {
> > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > +       u32 reg;
> > > > +       int ret;
> > > > +
> > > > +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> > > > +               DRIVER_NAME, chan);
> > > > +       if (ret < 0) {
> > > > +           dev_err(mbox->dev, "Cannot request irq\n");
> > > > +           return ret;
> > > > +       }
> > > > +
> > > > +       /* Register write to enable IRQ generation */
> > > > +
> > > > +       return 0;
> > > > +   }
> > > > +
> > > > +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> > > > +   {
> > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > +
> > > > +       /* Disable interrupt generation */
> > > > +       devm_free_irq(mbox->dev, mbox->irq, chan);
> > > > +   }
> > > > +
> > > > +   static const struct mbox_chan_ops dummy_mbox_ops = {
> > > > +       .send_data = dummy_mbox_send_data,
> > > > +       .startup = dummy_mbox_startup,
> > > > +       .shutdown = dummy_mbox_shutdown,
> > > > +   };
> > > > +
> > > > +   static int dummy_mbox_probe(struct platform_device *pdev)
> > > > +   {
> > > > +       struct dummy_mbox *mbox;
> > > > +       struct mbox_chan *chans;
> > > > +       int ret;
> > > > +
> > > > +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> > > > +       if (!mbox)
> > > > +           return -ENOMEM;
> > > > +
> > > > +       /* Allocate one channel */
> > > > +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> > > > +       if (!chans)
> > > > +           return -ENOMEM;
> > > > +
> > > > +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> > > > +       if (IS_ERR(mbox->base))
> > > > +           return PTR_ERR(mbox->base);
> > > > +
> > > > +       mbox->irq = platform_get_irq(pdev, 0);
> > > > +       if (mbox->irq < 0)
> > > > +           return mbox->irq;
> > > > +
> > > > +       mbox->dev = &pdev->dev;
> > > > +
> > > > +       /* Hardware supports only one channel. */
> > > > +       mbox->controller.dev = mbox->dev;
> > > > +       mbox->controller.num_chans = 1;
> > > > +       mbox->controller.chans = chans;
> > > > +       mbox->controller.ops = &dummy_mbox_ops;
> > > > +       mbox->controller.txdone_irq = true;
> > > > +
> > > > +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> > > > +       if (ret) {
> > > > +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> > > > +           return ret;
> > > > +       }
> > > > +
> > > > +       return ret;
> > > > +   }
> > > > +
> > > > +   static const struct of_device_id dummy_mbox_match[] = {
> > > > +       { .compatible = "dummy,dummy-mailbox" },
> > > > +       { },
> > > > +   };
> > > > +
> > > > +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> > > > +
> > > > +   static struct platform_driver dummy_mbox_driver = {
> > > > +       .probe = dummy_mbox_probe,
> > > > +       .driver = {
> > > > +           .name = DRIVER_NAME,
> > > > +           .of_match_table = dummy_mbox_match,
> > > > +       },
> > > > +   };
> > > > +
> > > > +   module_platform_driver(dummy_mbox_driver);
> > > > +   MODULE_LICENSE("GPL v2");
> > > > +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > > +
> > > > +In the above code, a couple of things are done:
> > > > +a. The controller is registered in the probe along with callbacks, which in
> > > > +   this case are the bare minimum: ``startup``, ``shutdown``, and
> > > > +   ``send_data``.
> > > > +b. IRQ is registered to get notifications from the remote processor.
> > > > +c. In the IRQ handler, registers are read to copy data, and
> > > > +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> > > > +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> > > > +   is the last data and no more data is to be expected for the current transfer.
> > > > +
> > >
> > > Sphinx warns out numerous indentation warnings on the lists, so I have to
> > > fix them up:
> > >
> > > ---- >8 ----
> > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > index 9088f83734230d..17dafaca056777 100644
> > > --- a/Documentation/driver-api/mailbox/client.rst
> > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > @@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
> > >  Key Functions
> > >  -------------
> > >  1. Requesting a Mailbox Channel
> > > +
> > >     - **Function**: `mbox_request_channel(struct mbox_client *client,
> > >       unsigned int channel)`
> > >     - **Description**: Requests a mailbox channel for sending messages.
> > > @@ -41,15 +42,19 @@ Key Functions
> > >       code on failure.
> > >
> > >  2. Sending a Message
> > > +
> > >     - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > >     - **Description**: Sends a message through the mailbox channel.
> > >     - **Parameters**:
> > > +
> > >       - `chan`: The mailbox channel used for communication.
> > >       - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > >         messages).
> > > +
> > >     - **Returns**: 0 on success, or a negative error code on failure.
> > >
> > >  3. Transmitting Completion
> > > +
> > >     - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > >       msg_id)`
> > >     - **Description**: Notifies the mailbox framework that message
> > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > index 8d56d81007c11c..239538f497e41a 100644
> > > --- a/Documentation/driver-api/mailbox/core.rst
> > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > @@ -85,16 +85,20 @@ Data Structures
> > >  - **struct mbox_client**
> > >    This structure represents a client that communicates over a mailbox
> > >    channel. It holds information such as:
> > > +
> > >    - A pointer to the device associated with the client (`dev`).
> > >    - Callback functions for handling message transmission events, including:
> > > +
> > >      - `rx_callback`: Called when a message is received.
> > >      - `tx_done`: Called when a message transmission is acknowledged.
> > > +
> > >    - Flags that specify the client’s configuration, such as whether it operates
> > >      in blocking mode.
> > >
> > >  - **struct mbox_chan**
> > >    This structure represents an individual mailbox channel. It maintains the
> > >    state required for message queuing and transmission. Key members include:
> > > +
> > >    - `msg_data`: Array of messages queued for transmission.
> > >    - `msg_count`: Number of messages currently queued.
> > >    - `msg_free`: Index of the next free slot in the message queue.
> > > @@ -104,6 +108,7 @@ Data Structures
> > >  - **struct mbox_controller**
> > >    This structure represents a mailbox controller that manages multiple
> > >    channels. It includes:
> > > +
> > >    - A pointer to the device managing the mailbox.
> > >    - Operations for sending and receiving messages, as well as initializing
> > >      and shutting down the mailbox.
> > > @@ -133,21 +138,20 @@ need to initialize a few fields in there:
> > >  - ``num_chans``: Number of channels in the `chans` array.
> > >
> > >  - ``txdone_irq``: Indicates if the controller can report to the API
> > > -  when the last transmitted data was read by the
> > > -                          remote (e.g., if it has a TX ACK interrupt).
> > > +  when the last transmitted data was read by the remote (e.g., if it has a
> > > +  TX ACK interrupt).
> > >
> > >  All the below fields are not mandatory.
> > >
> > >  - ``txdone_poll``: Indicates if the controller can read but not report
> > > -                          the TX done. For example, some register may show
> > > -                          the TX status, but no interrupt is raised. This
> > > -                          field is ignored if `txdone_irq` is set.
> > > +  the TX done. For example, some register may show the TX status, but no
> > > +  interrupt is raised. This field is ignored if `txdone_irq` is set.
> > >
> > >  - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > -                          the last TX status after this many milliseconds.
> > > +  the last TX status after this many milliseconds.
> > >
> > >  - ``of_xlate``: Controller driver-specific mapping of channel via
> > > -                          Device Tree (DT).
> > > +  Device Tree (DT).
> > >
> > >
> > >  Key Functions
> > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > index 2a82645c13573e..853adf6918173d 100644
> > > --- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > @@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
> > >
> > >  A basic driver skeleton could look like this for a mailbox hardware that
> > >  has the following characteristics:
> > > +
> > >  a. It supports only a single channel, i.e., only the remote processor can
> > >     send interrupts.
> > >  b. Data transfer is over the registers associated with mailbox hardware.
> > > @@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
> > >     MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > >
> > >  In the above code, a couple of things are done:
> > > +
> > >  a. The controller is registered in the probe along with callbacks, which in
> > >     this case are the bare minimum: ``startup``, ``shutdown``, and
> > >     ``send_data``.
> > >
> > > Thanks.
> > >
> > > --
> > > An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-30 17:41         ` Jassi Brar
@ 2024-10-30 18:13           ` anish kumar
  2024-12-05 20:32             ` anish kumar
  0 siblings, 1 reply; 12+ messages in thread
From: anish kumar @ 2024-10-30 18:13 UTC (permalink / raw)
  To: Jassi Brar; +Cc: Jonathan Corbet, linux-doc, linux-kernel, Bagas Sanjaya

On Wed, Oct 30, 2024 at 10:42 AM Jassi Brar <jassisinghbrar@gmail.com> wrote:
>
> Hi Anish,
>   It is the third ping within 10 days, please avoid. Documentation is

apologies for this.

> not a high priority, esp when it is mostly copying info from header
> files.

It is true for the api but not true for overall documentation.
Reason for writing this document was that I had to read the code
to understand how the mailbox driver works. Couple of things
this document does is:
1. Explain how the controller, client and hardware are connected
2. Separated out documentation of client, controller and mailbox
framework. So, if someone needs to only do a client then they just
read that document.
3. Provided example code for controller.
4. In general a better explanation of the framework.

> I haven't looked closely and you haven't mentioned in the log what new
> info are you adding or clearer?

Yes, I should have done that but I added index.rst so thought
it is not needed but will do for V2.

> From a quick look it seems just api explanation copied into doc
> format. Will look closer later.

Not completely true.
>
> Thanks
>
> On Tue, Oct 29, 2024 at 1:06 PM anish kumar <yesanishhere@gmail.com> wrote:
> >
> > Hello Jassi,
> >
> > Gentle reminder for the review.
> >
> > On Fri, Oct 25, 2024 at 12:24 PM anish kumar <yesanishhere@gmail.com> wrote:
> > >
> > > Hello Jassi,
> > >
> > > I hope to get some more comments from you before
> > > spinning up a new revision.
> > >
> > > On Thu, Oct 24, 2024 at 8:38 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
> > > >
> > > > On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> > > > > 1. added client documentation
> > > > > 2. added controller documentation.
> > > > > 3. added framework documentation
> > > >
> > > > One doc topic on each patch, please.
> > > >
> > > > >
> > > > > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > > > > ---
> > > > >  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
> > > > >  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
> > > > >  Documentation/driver-api/mailbox/index.rst    |  45 ++++
> > > > >  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
> > > > >  4 files changed, 598 insertions(+)
> > > > >  create mode 100644 Documentation/driver-api/mailbox/client.rst
> > > > >  create mode 100644 Documentation/driver-api/mailbox/core.rst
> > > > >  create mode 100644 Documentation/driver-api/mailbox/index.rst
> > > > >  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > >
> > > > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > > > new file mode 100644
> > > > > index 000000000000..9088f8373423
> > > > > --- /dev/null
> > > > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > > > @@ -0,0 +1,192 @@
> > > > > +Mailbox Client Documentation
> > > > > +============================
> > > > > +
> > > > > +Overview
> > > > > +--------
> > > > > +The mailbox client driver is responsible for sending and receiving messages
> > > > > +to and from a remote processor. It uses mailbox APIs provided by the
> > > > > +mailbox framework.
> > > > > +
> > > > > +Mailbox Structure
> > > > > +-----------------
> > > > > +The mailbox structure is defined as follows:
> > > > > +
> > > > > +.. code-block:: c
> > > > > +
> > > > > +   struct mbox_client {
> > > > > +       //device associated with the mailbox
> > > > > +       struct device *dev;
> > > > > +       // callback for transmission completion
> > > > > +       void (*tx_done)(struct mbox_client *client);
> > > > > +       // callback to prepare for sending a message
> > > > > +       void (*tx_prepare)(struct mbox_client *client);
> > > > > +       // callback for received messages
> > > > > +       void (*rx_callback)(struct mbox_client *client, void *data);
> > > > > +       // flag to indicate if transmission should block
> > > > > +       bool tx_block;
> > > > > +       // indicates if the client knows when transmission is done
> > > > > +       bool knows_txdone;
> > > > > +   };
> > > > > +
> > > > > +Key Functions
> > > > > +-------------
> > > > > +1. Requesting a Mailbox Channel
> > > > > +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > > > +     unsigned int channel)`
> > > > > +   - **Description**: Requests a mailbox channel for sending messages.
> > > > > +   - **Parameters**:
> > > > > +     - `client`: Pointer to the mailbox client structure.
> > > > > +     - `channel`: The specific mailbox channel to request.
> > > > > +   - **Returns**: A pointer to the mailbox channel on success, or an error
> > > > > +     code on failure.
> > > > > +
> > > > > +2. Sending a Message
> > > > > +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > > > +   - **Description**: Sends a message through the mailbox channel.
> > > > > +   - **Parameters**:
> > > > > +     - `chan`: The mailbox channel used for communication.
> > > > > +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > > > +       messages).
> > > > > +   - **Returns**: 0 on success, or a negative error code on failure.
> > > > > +
> > > > > +3. Transmitting Completion
> > > > > +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > > > +     msg_id)`
> > > > > +   - **Description**: Notifies the mailbox framework that message
> > > > > +     transmission is complete.
> > > > > +   - **Parameters**:
> > > > > +     - `chan`: The mailbox channel associated with the message.
> > > > > +     - `msg_id`: The identifier of the message that was transmitted.
> > > >
> > > > These functions should've been documented as kernel-doc comments, though.
> > > >
> > > > > +
> > > > > +Usage Example
> > > > > +-------------
> > > > > +In a typical mailbox client driver, the following steps are typically
> > > > > +performed:
> > > > > +
> > > > > +1. Initialize the Mailbox Client:
> > > > > +
> > > > > +   .. code-block:: c
> > > > > +
> > > > > +      struct mbox_client my_mbox_client = {
> > > > > +          .dev = &my_device,
> > > > > +          .tx_done = my_tx_done_callback,
> > > > > +          .rx_callback = my_rx_callback,
> > > > > +          .tx_block = false,
> > > > > +          .knows_txdone = true,
> > > > > +      };
> > > > > +
> > > > > +2. Request a Mailbox Channel:
> > > > > +
> > > > > +   .. code-block:: c
> > > > > +
> > > > > +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> > > > > +      if (IS_ERR(mbox_chan)) {
> > > > > +          // Handle error
> > > > > +      }
> > > > > +
> > > > > +3. Send a Message:
> > > > > +
> > > > > +   .. code-block:: c
> > > > > +
> > > > > +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> > > > > +      if (ret < 0) {
> > > > > +          // Handle error
> > > > > +      }
> > > > > +
> > > > > +4. Complete Transmission:
> > > > > +
> > > > > +   .. code-block:: c
> > > > > +
> > > > > +      mbox_client_txdone(mbox_chan, 0);
> > > > > +
> > > > > +Interrupt Handling
> > > > > +------------------
> > > > > +The mailbox interface can trigger interrupts upon message receipt. Handlers
> > > > > +should be implemented in the `rx_callback` function defined in the mailbox
> > > > > +client structure to process incoming messages.
> > > > > +
> > > > > +Example Mailbox Client Driver
> > > > > +-----------------------------
> > > > > +.. code-block:: c
> > > > > +
> > > > > +   struct demo_client {
> > > > > +       struct mbox_client cl;
> > > > > +       struct mbox_chan *mbox;
> > > > > +       struct completion c;
> > > > > +       bool async;
> > > > > +       /* ... */
> > > > > +   };
> > > > > +
> > > > > +   /*
> > > > > +   * This is the handler for data received from remote. The behaviour is purely
> > > > > +   * dependent upon the protocol. This is just an example.
> > > > > +   */
> > > > > +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> > > > > +   {
> > > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > > +       if (dc->async) {
> > > > > +           if (is_an_ack(mssg)) {
> > > > > +               /* An ACK to our last sample sent */
> > > > > +               return; /* Or do something else here */
> > > > > +           } else { /* A new message from remote */
> > > > > +               queue_req(mssg);
> > > > > +           }
> > > > > +       } else {
> > > > > +           /* Remote f/w sends only ACK packets on this channel */
> > > > > +           return;
> > > > > +       }
> > > > > +   }
> > > > > +
> > > > > +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> > > > > +   {
> > > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > > +       complete(&dc->c);
> > > > > +   }
> > > > > +
> > > > > +   static void client_demo(struct platform_device *pdev)
> > > > > +   {
> > > > > +       struct demo_client *dc_sync, *dc_async;
> > > > > +       /* The controller already knows async_pkt and sync_pkt */
> > > > > +       struct async_pkt ap;
> > > > > +       struct sync_pkt sp;
> > > > > +
> > > > > +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> > > > > +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> > > > > +
> > > > > +       /* Populate non-blocking mode client */
> > > > > +       dc_async->cl.dev = &pdev->dev;
> > > > > +       dc_async->cl.rx_callback = message_from_remote;
> > > > > +       dc_async->cl.tx_done = sample_sent;
> > > > > +       dc_async->cl.tx_block = false;
> > > > > +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> > > > > +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> > > > > +       dc_async->async = true;
> > > > > +       init_completion(&dc_async->c);
> > > > > +
> > > > > +       /* Populate blocking mode client */
> > > > > +       dc_sync->cl.dev = &pdev->dev;
> > > > > +       dc_sync->cl.rx_callback = message_from_remote;
> > > > > +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> > > > > +       dc_sync->cl.tx_block = true;
> > > > > +       dc_sync->cl.tx_tout = 500; /* by half a second */
> > > > > +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> > > > > +       dc_sync->async = false;
> > > > > +
> > > > > +       /* ASync mailbox is listed second in 'mboxes' property */
> > > > > +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> > > > > +       /* Populate data packet */
> > > > > +       /* ap.xxx = 123; etc */
> > > > > +       /* Send async message to remote */
> > > > > +       mbox_send_message(dc_async->mbox, &ap);
> > > > > +
> > > > > +       /* Sync mailbox is listed first in 'mboxes' property */
> > > > > +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> > > > > +       /* Populate data packet */
> > > > > +       /* sp.abc = 123; etc */
> > > > > +       /* Send message to remote in blocking mode */
> > > > > +       mbox_send_message(dc_sync->mbox, &sp);
> > > > > +       /* At this point 'sp' has been sent */
> > > > > +
> > > > > +       /* Now wait for async chan to be done */
> > > > > +       wait_for_completion(&dc_async->c);
> > > > > +   }
> > > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > > new file mode 100644
> > > > > index 000000000000..d1220086da67
> > > > > --- /dev/null
> > > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > > @@ -0,0 +1,182 @@
> > > > > +=====================
> > > > > +mailbox documentation
> > > > > +=====================
> > > > > +
> > > > > +Hardware Introduction
> > > > > +=====================
> > > > > +
> > > > > +Mailbox hardware is a specialized component found in multi-core
> > > > > +processors and embedded systems that facilitates inter-processor
> > > > > +communication (IPC) or communication between different hardware
> > > > > +components. It provides a structured mechanism for sending and
> > > > > +receiving messages, allowing various processors or devices to
> > > > > +exchange data efficiently. Here's an overview of its key
> > > > > +characteristics and functions:
> > > > > +
> > > > > +Key Characteristics of Mailbox Hardware
> > > > > +Interrupt Handling: Many mailbox implementations support
> > > > > +interrupt-driven communication. This allows a receiving processor
> > > > > +to be alerted when a new message arrives, facilitating immediate
> > > > > +processing without polling the mailbox constantly.
> > > > > +
> > > > > +Hardware Registers: Mailbox hardware often includes registers for
> > > > > +configuration and status monitoring. These registers can be used
> > > > > +to control the mailbox's behavior, check for available messages,
> > > > > +or acknowledge message receipt.
> > > > > +
> > > > > +Support for Multiple Protocols: Mailboxes can support various
> > > > > +communication protocols, enabling interoperability between different
> > > > > +hardware components and simplifying the integration of diverse systems.
> > > > > +
> > > > > +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> > > > > +both synchronous and asynchronous modes. In synchronous mode, the
> > > > > +sender may wait for the receiver to acknowledge receipt before
> > > > > +proceeding, while in asynchronous mode, the sender can continue
> > > > > +executing other tasks immediately after sending the message.
> > > > > +
> > > > > +
> > > > > +Mailbox framework design
> > > > > +========================
> > > > > +
> > > > > +The mailbox facilitates interprocessor communication by allowing processors to
> > > > > +exchange messages or signals. The mailbox framework consists of:
> > > > > +
> > > > > +Mailbox Controller: This is platform-specific and is responsible for configuring
> > > > > +and managing interrupts from the remote processor. It offers a generic API for
> > > > > +the mailbox client.
> > > > > +
> > > > > +Mailbox Client: This component handles the sending and receiving of messages.
> > > > > +
> > > > > +
> > > > > +............................................................................
> > > > > +:  client driver      client_a            client_b                         :
> > > > > +............................................................................
> > > > > +                            ^-------------------^
> > > > > +                                    |
> > > > > +                                    |
> > > > > +............................................................................
> > > > > +:  controller framework          mailbox                                   :
> > > > > +....................................|.......................................
> > > > > +                                    |
> > > > > +                                    |
> > > > > +............................................................................
> > > > > +:  controller driver          device specific                              :
> > > > > +....................................|.......................................
> > > > > +                                    |
> > > > > +                                    |
> > > > > +kernel                              |
> > > > > +............................................................................
> > > > > +hardware                            |
> > > > > +                                    |
> > > > > +                                    |
> > > > > +............................................................................
> > > > > +:                             remote processor                             :
> > > > > +............................................................................
> > > >
> > > > htmldocs build errors out:
> > > >
> > > > Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
> > > > Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.
> > > >
> > > > ............................................................................
> > > > :  controller framework          mailbox                                   :
> > > > ....................................|.......................................
> > > >
> > > > reST markup error:
> > > > Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.
> > > >
> > > > ............................................................................
> > > > :  controller framework          mailbox                                   :
> > > > ....................................|.......................................
> > > >
> > > > I have to fix up the design diagram and wrap it:
> > > >
> > > > ---- >8 ----
> > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > index d1220086da679f..8d56d81007c11c 100644
> > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > @@ -47,31 +47,32 @@ the mailbox client.
> > > >
> > > >  Mailbox Client: This component handles the sending and receiving of messages.
> > > >
> > > > +::
> > > >
> > > > -............................................................................
> > > > -:  client driver      client_a            client_b                         :
> > > > -............................................................................
> > > > -                            ^-------------------^
> > > > -                                    |
> > > > -                                    |
> > > > -............................................................................
> > > > -:  controller framework          mailbox                                   :
> > > > -....................................|.......................................
> > > > -                                    |
> > > > -                                    |
> > > > -............................................................................
> > > > -:  controller driver          device specific                              :
> > > > -....................................|.......................................
> > > > -                                    |
> > > > -                                    |
> > > > -kernel                              |
> > > > -............................................................................
> > > > -hardware                            |
> > > > -                                    |
> > > > -                                    |
> > > > -............................................................................
> > > > -:                             remote processor                             :
> > > > -............................................................................
> > > > +  +---------------------------------------------------------------------------+
> > > > +  |  client driver      client_a            client_b                          |
> > > > +  +---------------------------------------------------------------------------+
> > > > +                              ^-------------------^
> > > > +                                      |
> > > > +                                      |
> > > > +  +--------------------------------------------------------------------------+
> > > > +  |  controller framework          mailbox                                   |
> > > > +  +-----------------------------------|--------------------------------------+
> > > > +                                      |
> > > > +                                      |
> > > > +  +--------------------------------------------------------------------------+
> > > > +  |  controller driver          device specific                              |
> > > > +  +-----------------------------------|--------------------------------------+
> > > > +                                      |
> > > > +                                      |
> > > > +  kernel                              |
> > > > +  ----------------------------------------------------------------------------
> > > > +  hardware                            |
> > > > +                                      |
> > > > +                                      |
> > > > +  +--------------------------------------------------------------------------+
> > > > +  |                             remote processor                             |
> > > > +  +--------------------------------------------------------------------------+
> > > >
> > > >
> > > >  In the context of a mailbox framework, a channel refers to a dedicated
> > > >
> > > > > +
> > > > > +
> > > > > +In the context of a mailbox framework, a channel refers to a dedicated
> > > > > +communication pathway between two or more processors or components. By using
> > > > > +channels, the framework abstracts the complexity of interprocessor communication.
> > > > > +
> > > > > +Data Structures
> > > > > +================
> > > > > +
> > > > > +- **struct mbox_client**
> > > > > +  This structure represents a client that communicates over a mailbox
> > > > > +  channel. It holds information such as:
> > > > > +  - A pointer to the device associated with the client (`dev`).
> > > > > +  - Callback functions for handling message transmission events, including:
> > > > > +    - `rx_callback`: Called when a message is received.
> > > > > +    - `tx_done`: Called when a message transmission is acknowledged.
> > > > > +  - Flags that specify the client’s configuration, such as whether it operates
> > > > > +    in blocking mode.
> > > > > +
> > > > > +- **struct mbox_chan**
> > > > > +  This structure represents an individual mailbox channel. It maintains the
> > > > > +  state required for message queuing and transmission. Key members include:
> > > > > +  - `msg_data`: Array of messages queued for transmission.
> > > > > +  - `msg_count`: Number of messages currently queued.
> > > > > +  - `msg_free`: Index of the next free slot in the message queue.
> > > > > +  - `active_req`: Pointer to the currently active message being transmitted.
> > > > > +  - Synchronization primitives to manage access from multiple contexts.
> > > > > +
> > > > > +- **struct mbox_controller**
> > > > > +  This structure represents a mailbox controller that manages multiple
> > > > > +  channels. It includes:
> > > > > +  - A pointer to the device managing the mailbox.
> > > > > +  - Operations for sending and receiving messages, as well as initializing
> > > > > +    and shutting down the mailbox.
> > > > > +  - A list of associated channels and the total number of channels available.
> > > >
> > > > Shouldn't these structs be documented as kernel-doc comments? tl;dr:
> > > > see Documentation/doc-guide/kernel-doc.html
> > > >
> > > > > +
> > > > > +controller framework APIs
> > > > > +=========================
> > > > > +
> > > > > +``struct `mbox_controller` Initialization
> > > > > +-----------------------------------------
> > > >
> > > > Properly double-backquote the struct name to format it as inline code:
> > > >
> > > > ---- >8 ----
> > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > index 239538f497e41a..d83456164464aa 100644
> > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > @@ -117,7 +117,7 @@ Data Structures
> > > >  controller framework APIs
> > > >  =========================
> > > >
> > > > -``struct `mbox_controller` Initialization
> > > > +``struct mbox_controller`` Initialization
> > > >  -----------------------------------------
> > > >
> > > >  Just like any other kernel framework, the whole mailbox controller registration
> > > >
> > > > > +
> > > > > +Just like any other kernel framework, the whole mailbox controller registration
> > > > > +relies on the driver filling a structure and registering against the
> > > > > +framework. In our case, that structure is mbox_controller.
> > > > > +
> > > > > +The first thing you need to do in your driver is to allocate this
> > > > > +structure. Any of the usual memory allocators will do, but you'll also
> > > > > +need to initialize a few fields in there:
> > > > > +
> > > > > +- ``dev``: should hold the pointer to the ``struct device`` associated
> > > > > +  to your current driver instance.
> > > > > +
> > > > > +- ``ops``: Operators that work on each communication channel.
> > > > > +
> > > > > +- ``chans``: Array of channels.
> > > > > +
> > > > > +- ``num_chans``: Number of channels in the `chans` array.
> > > > > +
> > > > > +- ``txdone_irq``: Indicates if the controller can report to the API
> > > > > +  when the last transmitted data was read by the
> > > > > +                          remote (e.g., if it has a TX ACK interrupt).
> > > > > +
> > > > > +All the below fields are not mandatory.
> > > > > +
> > > > > +- ``txdone_poll``: Indicates if the controller can read but not report
> > > > > +                          the TX done. For example, some register may show
> > > > > +                          the TX status, but no interrupt is raised. This
> > > > > +                          field is ignored if `txdone_irq` is set.
> > > > > +
> > > > > +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > > > +                          the last TX status after this many milliseconds.
> > > > > +
> > > > > +- ``of_xlate``: Controller driver-specific mapping of channel via
> > > > > +                          Device Tree (DT).
> > > > > +
> > > > > +
> > > > > +Key Functions
> > > > > +-------------
> > > > > +
> > > > > +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> > > > > +  This function registers a mailbox controller with the kernel. It makes the
> > > > > +  channels associated with the controller available for client requests. The
> > > > > +  function performs sanity checks on the controller structure to ensure all
> > > > > +  necessary fields are populated.
> > > > > +
> > > > > +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> > > > > +  This function requests a mailbox channel for a specified client, identified
> > > > > +  by an index. It searches for the appropriate mailbox channel, and if found,
> > > > > +  it returns a pointer to the channel. If the request fails (e.g., if the
> > > > > +  index is invalid), it returns an error pointer.
> > > > > +
> > > > > +- **void mbox_free_channel(struct mbox_chan *chan)**
> > > > > +  This function releases a mailbox channel that was previously allocated for a
> > > > > +  client. It ensures that the channel can be reused by other clients. If any
> > > > > +  messages are still in the queue, they are aborted, and no callbacks are made.
> > > > > +
> > > > > +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> > > > > +  This function is used by clients to send a message through the specified
> > > > > +  mailbox channel. The function can operate in either blocking or non-blocking
> > > > > +  mode, depending on the client’s configuration. It will queue the message for
> > > > > +  transmission and notify the client once the message is acknowledged.
> > > > > +
> > > > > +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> > > > > +  This function is called by the controller driver to notify the mailbox
> > > > > +  framework that a message has been received on the specified channel. The
> > > > > +  received message is then passed to the appropriate client's `rx_callback`
> > > > > +  function for processing.
> > > >
> > > > Shouldn't these functions also be documented as kernel-doc comments?
> > > >
> > > > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > > > new file mode 100644
> > > > > index 000000000000..e254a8fdb66a
> > > > > --- /dev/null
> > > > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > > > @@ -0,0 +1,45 @@
> > > > > +=======================
> > > > > +Mailbox documentation
> > > > > +=======================
> > > > > +
> > > > > +Mailbox documentation provides documents for various aspects of mailbox
> > > > > +framework.
> > > > > +
> > > > > +Mailbox development documentation
> > > > > +---------------------------------
> > > > > +
> > > > > +This book helps with mailbox internal APIs and guide for mailbox device
> > > > > +driver writers.
> > > > > +
> > > > > +.. toctree::
> > > > > +   :maxdepth: 1
> > > > > +
> > > > > +   core
> > > > > +
> > > > > +mailbox controller driver documentation
> > > > > +------------------------------
> > > > > +
> > > > > +This book is a guide to device driver writers on how to register
> > > > > +mailbox controller to the mailbox framework.
> > > > > +
> > > > > +.. toctree::
> > > > > +   :maxdepth: 1
> > > > > +
> > > > > +   writing_mailbox_controller_drivers
> > > > > +
> > > > > +mailbox client driver documentation
> > > > > +------------------------------
> > > >
> > > > Match up section underline length by its title:
> > > >
> > > > ---- >8 ----
> > > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > > index e254a8fdb66ac7..02d7d5e8660999 100644
> > > > --- a/Documentation/driver-api/mailbox/index.rst
> > > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > > @@ -1,6 +1,6 @@
> > > > -=======================
> > > > +=====================
> > > >  Mailbox documentation
> > > > -=======================
> > > > +=====================
> > > >
> > > >  Mailbox documentation provides documents for various aspects of mailbox
> > > >  framework.
> > > > @@ -17,7 +17,7 @@ driver writers.
> > > >     core
> > > >
> > > >  mailbox controller driver documentation
> > > > -------------------------------
> > > > +---------------------------------------
> > > >
> > > >  This book is a guide to device driver writers on how to register
> > > >  mailbox controller to the mailbox framework.
> > > > @@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
> > > >     writing_mailbox_controller_drivers
> > > >
> > > >  mailbox client driver documentation
> > > > -------------------------------
> > > > +-----------------------------------
> > > >
> > > >  This book is a guide to mailbox client driver writers.
> > > >
> > > >
> > > > > +
> > > > > +This book is a guide to mailbox client driver writers.
> > > > > +
> > > > > +.. toctree::
> > > > > +   :maxdepth: 1
> > > > > +
> > > > > +   client
> > > > > +
> > > > > +.. only::  subproject and html
> > > > > +
> > > > > +   Indices
> > > > > +   =======
> > > > > +
> > > > > +   * :ref:`genindex`
> > > >
> > > > Fix up also the reference link on parent toctree:
> > > >
> > > > ---- >8 ----
> > > > diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
> > > > index 7f83e05769b4a4..b4d78b92fd921a 100644
> > > > --- a/Documentation/driver-api/index.rst
> > > > +++ b/Documentation/driver-api/index.rst
> > > > @@ -102,7 +102,7 @@ Subsystem-specific APIs
> > > >     ipmb
> > > >     ipmi
> > > >     libata
> > > > -   mailbox
> > > > +   mailbox/index
> > > >     md/index
> > > >     media/index
> > > >     mei/index
> > > >
> > > > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > new file mode 100644
> > > > > index 000000000000..2a82645c1357
> > > > > --- /dev/null
> > > > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > @@ -0,0 +1,179 @@
> > > > > +.. SPDX-License-Identifier: GPL-2.0
> > > > > +
> > > > > +.. _writing_mailbox_controller_drivers:
> > > > > +
> > > > > +==================================
> > > > > +Writing Mailbox Controller Drivers
> > > > > +==================================
> > > > > +
> > > > > +Introduction
> > > > > +============
> > > > > +
> > > > > +This document serves as a basic guideline for driver programmers that need
> > > > > +to hack a new mailbox controller driver or understand the essentials of
> > > > > +the existing ones.
> > > > > +
> > > > > +Driver Boilerplate
> > > > > +==================
> > > > > +
> > > > > +As a bare minimum, a mailbox controller driver needs to call
> > > > > +``mbox_controller_register`` function to register with the framework.
> > > > > +
> > > > > +A basic driver skeleton could look like this for a mailbox hardware that
> > > > > +has the following characteristics:
> > > > > +a. It supports only a single channel, i.e., only the remote processor can
> > > > > +   send interrupts.
> > > > > +b. Data transfer is over the registers associated with mailbox hardware.
> > > > > +c. Mailbox hardware is configured to receive interrupts.
> > > > > +d. When the remote processor is ready to send data, it triggers a mailbox
> > > > > +   interrupt.
> > > > > +e. As part of interrupt handling by Linux, it copies data from the registers.
> > > > > +
> > > > > +.. code-block:: c
> > > > > +
> > > > > +   #include <linux/device.h>
> > > > > +   #include <linux/interrupt.h>
> > > > > +   #include <linux/io.h>
> > > > > +   #include <linux/kernel.h>
> > > > > +   #include <linux/mailbox_controller.h>
> > > > > +   #include <linux/module.h>
> > > > > +   #include <linux/of.h>
> > > > > +   #include <linux/platform_device.h>
> > > > > +   #define DRIVER_NAME "dummy_controller"
> > > > > +
> > > > > +   struct dummy_mbox {
> > > > > +       struct device *dev;
> > > > > +       struct mbox_controller controller;
> > > > > +       int irq;
> > > > > +   };
> > > > > +
> > > > > +   static void dummy_mbox_receive(struct mbox_chan *chan)
> > > > > +   {
> > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > +       int val;
> > > > > +
> > > > > +       // Data copied from registers
> > > > > +       val = read_register();
> > > > > +       mbox_chan_received_data(chan, &val);
> > > > > +   }
> > > > > +
> > > > > +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> > > > > +   {
> > > > > +       struct mbox_chan *chan = data;
> > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > +       u32 reg;
> > > > > +
> > > > > +       // Read registers to see if data is received
> > > > > +       dummy_mbox_receive(chan);
> > > > > +       mbox_chan_txdone(chan, 0);
> > > > > +       return reg ? IRQ_HANDLED : IRQ_NONE;
> > > > > +   }
> > > > > +
> > > > > +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> > > > > +   {
> > > > > +       // Write data in registers to send it to the remote processor
> > > > > +       return 0;
> > > > > +   }
> > > > > +
> > > > > +   static int dummy_mbox_startup(struct mbox_chan *chan)
> > > > > +   {
> > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > +       u32 reg;
> > > > > +       int ret;
> > > > > +
> > > > > +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> > > > > +               DRIVER_NAME, chan);
> > > > > +       if (ret < 0) {
> > > > > +           dev_err(mbox->dev, "Cannot request irq\n");
> > > > > +           return ret;
> > > > > +       }
> > > > > +
> > > > > +       /* Register write to enable IRQ generation */
> > > > > +
> > > > > +       return 0;
> > > > > +   }
> > > > > +
> > > > > +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> > > > > +   {
> > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > +
> > > > > +       /* Disable interrupt generation */
> > > > > +       devm_free_irq(mbox->dev, mbox->irq, chan);
> > > > > +   }
> > > > > +
> > > > > +   static const struct mbox_chan_ops dummy_mbox_ops = {
> > > > > +       .send_data = dummy_mbox_send_data,
> > > > > +       .startup = dummy_mbox_startup,
> > > > > +       .shutdown = dummy_mbox_shutdown,
> > > > > +   };
> > > > > +
> > > > > +   static int dummy_mbox_probe(struct platform_device *pdev)
> > > > > +   {
> > > > > +       struct dummy_mbox *mbox;
> > > > > +       struct mbox_chan *chans;
> > > > > +       int ret;
> > > > > +
> > > > > +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> > > > > +       if (!mbox)
> > > > > +           return -ENOMEM;
> > > > > +
> > > > > +       /* Allocate one channel */
> > > > > +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> > > > > +       if (!chans)
> > > > > +           return -ENOMEM;
> > > > > +
> > > > > +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> > > > > +       if (IS_ERR(mbox->base))
> > > > > +           return PTR_ERR(mbox->base);
> > > > > +
> > > > > +       mbox->irq = platform_get_irq(pdev, 0);
> > > > > +       if (mbox->irq < 0)
> > > > > +           return mbox->irq;
> > > > > +
> > > > > +       mbox->dev = &pdev->dev;
> > > > > +
> > > > > +       /* Hardware supports only one channel. */
> > > > > +       mbox->controller.dev = mbox->dev;
> > > > > +       mbox->controller.num_chans = 1;
> > > > > +       mbox->controller.chans = chans;
> > > > > +       mbox->controller.ops = &dummy_mbox_ops;
> > > > > +       mbox->controller.txdone_irq = true;
> > > > > +
> > > > > +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> > > > > +       if (ret) {
> > > > > +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> > > > > +           return ret;
> > > > > +       }
> > > > > +
> > > > > +       return ret;
> > > > > +   }
> > > > > +
> > > > > +   static const struct of_device_id dummy_mbox_match[] = {
> > > > > +       { .compatible = "dummy,dummy-mailbox" },
> > > > > +       { },
> > > > > +   };
> > > > > +
> > > > > +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> > > > > +
> > > > > +   static struct platform_driver dummy_mbox_driver = {
> > > > > +       .probe = dummy_mbox_probe,
> > > > > +       .driver = {
> > > > > +           .name = DRIVER_NAME,
> > > > > +           .of_match_table = dummy_mbox_match,
> > > > > +       },
> > > > > +   };
> > > > > +
> > > > > +   module_platform_driver(dummy_mbox_driver);
> > > > > +   MODULE_LICENSE("GPL v2");
> > > > > +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > > > +
> > > > > +In the above code, a couple of things are done:
> > > > > +a. The controller is registered in the probe along with callbacks, which in
> > > > > +   this case are the bare minimum: ``startup``, ``shutdown``, and
> > > > > +   ``send_data``.
> > > > > +b. IRQ is registered to get notifications from the remote processor.
> > > > > +c. In the IRQ handler, registers are read to copy data, and
> > > > > +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> > > > > +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> > > > > +   is the last data and no more data is to be expected for the current transfer.
> > > > > +
> > > >
> > > > Sphinx warns out numerous indentation warnings on the lists, so I have to
> > > > fix them up:
> > > >
> > > > ---- >8 ----
> > > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > > index 9088f83734230d..17dafaca056777 100644
> > > > --- a/Documentation/driver-api/mailbox/client.rst
> > > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > > @@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
> > > >  Key Functions
> > > >  -------------
> > > >  1. Requesting a Mailbox Channel
> > > > +
> > > >     - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > >       unsigned int channel)`
> > > >     - **Description**: Requests a mailbox channel for sending messages.
> > > > @@ -41,15 +42,19 @@ Key Functions
> > > >       code on failure.
> > > >
> > > >  2. Sending a Message
> > > > +
> > > >     - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > >     - **Description**: Sends a message through the mailbox channel.
> > > >     - **Parameters**:
> > > > +
> > > >       - `chan`: The mailbox channel used for communication.
> > > >       - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > >         messages).
> > > > +
> > > >     - **Returns**: 0 on success, or a negative error code on failure.
> > > >
> > > >  3. Transmitting Completion
> > > > +
> > > >     - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > >       msg_id)`
> > > >     - **Description**: Notifies the mailbox framework that message
> > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > index 8d56d81007c11c..239538f497e41a 100644
> > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > @@ -85,16 +85,20 @@ Data Structures
> > > >  - **struct mbox_client**
> > > >    This structure represents a client that communicates over a mailbox
> > > >    channel. It holds information such as:
> > > > +
> > > >    - A pointer to the device associated with the client (`dev`).
> > > >    - Callback functions for handling message transmission events, including:
> > > > +
> > > >      - `rx_callback`: Called when a message is received.
> > > >      - `tx_done`: Called when a message transmission is acknowledged.
> > > > +
> > > >    - Flags that specify the client’s configuration, such as whether it operates
> > > >      in blocking mode.
> > > >
> > > >  - **struct mbox_chan**
> > > >    This structure represents an individual mailbox channel. It maintains the
> > > >    state required for message queuing and transmission. Key members include:
> > > > +
> > > >    - `msg_data`: Array of messages queued for transmission.
> > > >    - `msg_count`: Number of messages currently queued.
> > > >    - `msg_free`: Index of the next free slot in the message queue.
> > > > @@ -104,6 +108,7 @@ Data Structures
> > > >  - **struct mbox_controller**
> > > >    This structure represents a mailbox controller that manages multiple
> > > >    channels. It includes:
> > > > +
> > > >    - A pointer to the device managing the mailbox.
> > > >    - Operations for sending and receiving messages, as well as initializing
> > > >      and shutting down the mailbox.
> > > > @@ -133,21 +138,20 @@ need to initialize a few fields in there:
> > > >  - ``num_chans``: Number of channels in the `chans` array.
> > > >
> > > >  - ``txdone_irq``: Indicates if the controller can report to the API
> > > > -  when the last transmitted data was read by the
> > > > -                          remote (e.g., if it has a TX ACK interrupt).
> > > > +  when the last transmitted data was read by the remote (e.g., if it has a
> > > > +  TX ACK interrupt).
> > > >
> > > >  All the below fields are not mandatory.
> > > >
> > > >  - ``txdone_poll``: Indicates if the controller can read but not report
> > > > -                          the TX done. For example, some register may show
> > > > -                          the TX status, but no interrupt is raised. This
> > > > -                          field is ignored if `txdone_irq` is set.
> > > > +  the TX done. For example, some register may show the TX status, but no
> > > > +  interrupt is raised. This field is ignored if `txdone_irq` is set.
> > > >
> > > >  - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > > -                          the last TX status after this many milliseconds.
> > > > +  the last TX status after this many milliseconds.
> > > >
> > > >  - ``of_xlate``: Controller driver-specific mapping of channel via
> > > > -                          Device Tree (DT).
> > > > +  Device Tree (DT).
> > > >
> > > >
> > > >  Key Functions
> > > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > index 2a82645c13573e..853adf6918173d 100644
> > > > --- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > @@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
> > > >
> > > >  A basic driver skeleton could look like this for a mailbox hardware that
> > > >  has the following characteristics:
> > > > +
> > > >  a. It supports only a single channel, i.e., only the remote processor can
> > > >     send interrupts.
> > > >  b. Data transfer is over the registers associated with mailbox hardware.
> > > > @@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
> > > >     MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > >
> > > >  In the above code, a couple of things are done:
> > > > +
> > > >  a. The controller is registered in the probe along with callbacks, which in
> > > >     this case are the bare minimum: ``startup``, ``shutdown``, and
> > > >     ``send_data``.
> > > >
> > > > Thanks.
> > > >
> > > > --
> > > > An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] mailbox: Documentation: add the latest documentation
  2024-10-30 18:13           ` anish kumar
@ 2024-12-05 20:32             ` anish kumar
  0 siblings, 0 replies; 12+ messages in thread
From: anish kumar @ 2024-12-05 20:32 UTC (permalink / raw)
  To: Jassi Brar; +Cc: Jonathan Corbet, linux-doc, linux-kernel, Bagas Sanjaya

Hello Jassi,

Wondering if I can remind you now for reviewing?


On Wed, Oct 30, 2024 at 11:13 AM anish kumar <yesanishhere@gmail.com> wrote:
>
> On Wed, Oct 30, 2024 at 10:42 AM Jassi Brar <jassisinghbrar@gmail.com> wrote:
> >
> > Hi Anish,
> >   It is the third ping within 10 days, please avoid. Documentation is
>
> apologies for this.
>
> > not a high priority, esp when it is mostly copying info from header
> > files.
>
> It is true for the api but not true for overall documentation.
> Reason for writing this document was that I had to read the code
> to understand how the mailbox driver works. Couple of things
> this document does is:
> 1. Explain how the controller, client and hardware are connected
> 2. Separated out documentation of client, controller and mailbox
> framework. So, if someone needs to only do a client then they just
> read that document.
> 3. Provided example code for controller.
> 4. In general a better explanation of the framework.
>
> > I haven't looked closely and you haven't mentioned in the log what new
> > info are you adding or clearer?
>
> Yes, I should have done that but I added index.rst so thought
> it is not needed but will do for V2.
>
> > From a quick look it seems just api explanation copied into doc
> > format. Will look closer later.
>
> Not completely true.
> >
> > Thanks
> >
> > On Tue, Oct 29, 2024 at 1:06 PM anish kumar <yesanishhere@gmail.com> wrote:
> > >
> > > Hello Jassi,
> > >
> > > Gentle reminder for the review.
> > >
> > > On Fri, Oct 25, 2024 at 12:24 PM anish kumar <yesanishhere@gmail.com> wrote:
> > > >
> > > > Hello Jassi,
> > > >
> > > > I hope to get some more comments from you before
> > > > spinning up a new revision.
> > > >
> > > > On Thu, Oct 24, 2024 at 8:38 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:
> > > > >
> > > > > On Sat, Oct 19, 2024 at 12:55:34PM -0700, anish kumar wrote:
> > > > > > 1. added client documentation
> > > > > > 2. added controller documentation.
> > > > > > 3. added framework documentation
> > > > >
> > > > > One doc topic on each patch, please.
> > > > >
> > > > > >
> > > > > > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > > > > > ---
> > > > > >  Documentation/driver-api/mailbox/client.rst   | 192 ++++++++++++++++++
> > > > > >  Documentation/driver-api/mailbox/core.rst     | 182 +++++++++++++++++
> > > > > >  Documentation/driver-api/mailbox/index.rst    |  45 ++++
> > > > > >  .../writing_mailbox_controller_drivers.rst    | 179 ++++++++++++++++
> > > > > >  4 files changed, 598 insertions(+)
> > > > > >  create mode 100644 Documentation/driver-api/mailbox/client.rst
> > > > > >  create mode 100644 Documentation/driver-api/mailbox/core.rst
> > > > > >  create mode 100644 Documentation/driver-api/mailbox/index.rst
> > > > > >  create mode 100644 Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > >
> > > > > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > > > > new file mode 100644
> > > > > > index 000000000000..9088f8373423
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > > > > @@ -0,0 +1,192 @@
> > > > > > +Mailbox Client Documentation
> > > > > > +============================
> > > > > > +
> > > > > > +Overview
> > > > > > +--------
> > > > > > +The mailbox client driver is responsible for sending and receiving messages
> > > > > > +to and from a remote processor. It uses mailbox APIs provided by the
> > > > > > +mailbox framework.
> > > > > > +
> > > > > > +Mailbox Structure
> > > > > > +-----------------
> > > > > > +The mailbox structure is defined as follows:
> > > > > > +
> > > > > > +.. code-block:: c
> > > > > > +
> > > > > > +   struct mbox_client {
> > > > > > +       //device associated with the mailbox
> > > > > > +       struct device *dev;
> > > > > > +       // callback for transmission completion
> > > > > > +       void (*tx_done)(struct mbox_client *client);
> > > > > > +       // callback to prepare for sending a message
> > > > > > +       void (*tx_prepare)(struct mbox_client *client);
> > > > > > +       // callback for received messages
> > > > > > +       void (*rx_callback)(struct mbox_client *client, void *data);
> > > > > > +       // flag to indicate if transmission should block
> > > > > > +       bool tx_block;
> > > > > > +       // indicates if the client knows when transmission is done
> > > > > > +       bool knows_txdone;
> > > > > > +   };
> > > > > > +
> > > > > > +Key Functions
> > > > > > +-------------
> > > > > > +1. Requesting a Mailbox Channel
> > > > > > +   - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > > > > +     unsigned int channel)`
> > > > > > +   - **Description**: Requests a mailbox channel for sending messages.
> > > > > > +   - **Parameters**:
> > > > > > +     - `client`: Pointer to the mailbox client structure.
> > > > > > +     - `channel`: The specific mailbox channel to request.
> > > > > > +   - **Returns**: A pointer to the mailbox channel on success, or an error
> > > > > > +     code on failure.
> > > > > > +
> > > > > > +2. Sending a Message
> > > > > > +   - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > > > > +   - **Description**: Sends a message through the mailbox channel.
> > > > > > +   - **Parameters**:
> > > > > > +     - `chan`: The mailbox channel used for communication.
> > > > > > +     - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > > > > +       messages).
> > > > > > +   - **Returns**: 0 on success, or a negative error code on failure.
> > > > > > +
> > > > > > +3. Transmitting Completion
> > > > > > +   - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > > > > +     msg_id)`
> > > > > > +   - **Description**: Notifies the mailbox framework that message
> > > > > > +     transmission is complete.
> > > > > > +   - **Parameters**:
> > > > > > +     - `chan`: The mailbox channel associated with the message.
> > > > > > +     - `msg_id`: The identifier of the message that was transmitted.
> > > > >
> > > > > These functions should've been documented as kernel-doc comments, though.
> > > > >
> > > > > > +
> > > > > > +Usage Example
> > > > > > +-------------
> > > > > > +In a typical mailbox client driver, the following steps are typically
> > > > > > +performed:
> > > > > > +
> > > > > > +1. Initialize the Mailbox Client:
> > > > > > +
> > > > > > +   .. code-block:: c
> > > > > > +
> > > > > > +      struct mbox_client my_mbox_client = {
> > > > > > +          .dev = &my_device,
> > > > > > +          .tx_done = my_tx_done_callback,
> > > > > > +          .rx_callback = my_rx_callback,
> > > > > > +          .tx_block = false,
> > > > > > +          .knows_txdone = true,
> > > > > > +      };
> > > > > > +
> > > > > > +2. Request a Mailbox Channel:
> > > > > > +
> > > > > > +   .. code-block:: c
> > > > > > +
> > > > > > +      mbox_chan = mbox_request_channel(&my_mbox_client, 0);
> > > > > > +      if (IS_ERR(mbox_chan)) {
> > > > > > +          // Handle error
> > > > > > +      }
> > > > > > +
> > > > > > +3. Send a Message:
> > > > > > +
> > > > > > +   .. code-block:: c
> > > > > > +
> > > > > > +      int ret = mbox_send_message(mbox_chan, NULL); // Sending a dummy message
> > > > > > +      if (ret < 0) {
> > > > > > +          // Handle error
> > > > > > +      }
> > > > > > +
> > > > > > +4. Complete Transmission:
> > > > > > +
> > > > > > +   .. code-block:: c
> > > > > > +
> > > > > > +      mbox_client_txdone(mbox_chan, 0);
> > > > > > +
> > > > > > +Interrupt Handling
> > > > > > +------------------
> > > > > > +The mailbox interface can trigger interrupts upon message receipt. Handlers
> > > > > > +should be implemented in the `rx_callback` function defined in the mailbox
> > > > > > +client structure to process incoming messages.
> > > > > > +
> > > > > > +Example Mailbox Client Driver
> > > > > > +-----------------------------
> > > > > > +.. code-block:: c
> > > > > > +
> > > > > > +   struct demo_client {
> > > > > > +       struct mbox_client cl;
> > > > > > +       struct mbox_chan *mbox;
> > > > > > +       struct completion c;
> > > > > > +       bool async;
> > > > > > +       /* ... */
> > > > > > +   };
> > > > > > +
> > > > > > +   /*
> > > > > > +   * This is the handler for data received from remote. The behaviour is purely
> > > > > > +   * dependent upon the protocol. This is just an example.
> > > > > > +   */
> > > > > > +   static void message_from_remote(struct mbox_client *cl, void *mssg)
> > > > > > +   {
> > > > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > > > +       if (dc->async) {
> > > > > > +           if (is_an_ack(mssg)) {
> > > > > > +               /* An ACK to our last sample sent */
> > > > > > +               return; /* Or do something else here */
> > > > > > +           } else { /* A new message from remote */
> > > > > > +               queue_req(mssg);
> > > > > > +           }
> > > > > > +       } else {
> > > > > > +           /* Remote f/w sends only ACK packets on this channel */
> > > > > > +           return;
> > > > > > +       }
> > > > > > +   }
> > > > > > +
> > > > > > +   static void sample_sent(struct mbox_client *cl, void *mssg, int r)
> > > > > > +   {
> > > > > > +       struct demo_client *dc = container_of(cl, struct demo_client, cl);
> > > > > > +       complete(&dc->c);
> > > > > > +   }
> > > > > > +
> > > > > > +   static void client_demo(struct platform_device *pdev)
> > > > > > +   {
> > > > > > +       struct demo_client *dc_sync, *dc_async;
> > > > > > +       /* The controller already knows async_pkt and sync_pkt */
> > > > > > +       struct async_pkt ap;
> > > > > > +       struct sync_pkt sp;
> > > > > > +
> > > > > > +       dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
> > > > > > +       dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
> > > > > > +
> > > > > > +       /* Populate non-blocking mode client */
> > > > > > +       dc_async->cl.dev = &pdev->dev;
> > > > > > +       dc_async->cl.rx_callback = message_from_remote;
> > > > > > +       dc_async->cl.tx_done = sample_sent;
> > > > > > +       dc_async->cl.tx_block = false;
> > > > > > +       dc_async->cl.tx_tout = 0; /* doesn't matter here */
> > > > > > +       dc_async->cl.knows_txdone = false; /* depending upon protocol */
> > > > > > +       dc_async->async = true;
> > > > > > +       init_completion(&dc_async->c);
> > > > > > +
> > > > > > +       /* Populate blocking mode client */
> > > > > > +       dc_sync->cl.dev = &pdev->dev;
> > > > > > +       dc_sync->cl.rx_callback = message_from_remote;
> > > > > > +       dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
> > > > > > +       dc_sync->cl.tx_block = true;
> > > > > > +       dc_sync->cl.tx_tout = 500; /* by half a second */
> > > > > > +       dc_sync->cl.knows_txdone = false; /* depending upon protocol */
> > > > > > +       dc_sync->async = false;
> > > > > > +
> > > > > > +       /* ASync mailbox is listed second in 'mboxes' property */
> > > > > > +       dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
> > > > > > +       /* Populate data packet */
> > > > > > +       /* ap.xxx = 123; etc */
> > > > > > +       /* Send async message to remote */
> > > > > > +       mbox_send_message(dc_async->mbox, &ap);
> > > > > > +
> > > > > > +       /* Sync mailbox is listed first in 'mboxes' property */
> > > > > > +       dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
> > > > > > +       /* Populate data packet */
> > > > > > +       /* sp.abc = 123; etc */
> > > > > > +       /* Send message to remote in blocking mode */
> > > > > > +       mbox_send_message(dc_sync->mbox, &sp);
> > > > > > +       /* At this point 'sp' has been sent */
> > > > > > +
> > > > > > +       /* Now wait for async chan to be done */
> > > > > > +       wait_for_completion(&dc_async->c);
> > > > > > +   }
> > > > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > > > new file mode 100644
> > > > > > index 000000000000..d1220086da67
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > > > @@ -0,0 +1,182 @@
> > > > > > +=====================
> > > > > > +mailbox documentation
> > > > > > +=====================
> > > > > > +
> > > > > > +Hardware Introduction
> > > > > > +=====================
> > > > > > +
> > > > > > +Mailbox hardware is a specialized component found in multi-core
> > > > > > +processors and embedded systems that facilitates inter-processor
> > > > > > +communication (IPC) or communication between different hardware
> > > > > > +components. It provides a structured mechanism for sending and
> > > > > > +receiving messages, allowing various processors or devices to
> > > > > > +exchange data efficiently. Here's an overview of its key
> > > > > > +characteristics and functions:
> > > > > > +
> > > > > > +Key Characteristics of Mailbox Hardware
> > > > > > +Interrupt Handling: Many mailbox implementations support
> > > > > > +interrupt-driven communication. This allows a receiving processor
> > > > > > +to be alerted when a new message arrives, facilitating immediate
> > > > > > +processing without polling the mailbox constantly.
> > > > > > +
> > > > > > +Hardware Registers: Mailbox hardware often includes registers for
> > > > > > +configuration and status monitoring. These registers can be used
> > > > > > +to control the mailbox's behavior, check for available messages,
> > > > > > +or acknowledge message receipt.
> > > > > > +
> > > > > > +Support for Multiple Protocols: Mailboxes can support various
> > > > > > +communication protocols, enabling interoperability between different
> > > > > > +hardware components and simplifying the integration of diverse systems.
> > > > > > +
> > > > > > +Synchronous and Asynchronous Modes: Mailbox hardware can operate in
> > > > > > +both synchronous and asynchronous modes. In synchronous mode, the
> > > > > > +sender may wait for the receiver to acknowledge receipt before
> > > > > > +proceeding, while in asynchronous mode, the sender can continue
> > > > > > +executing other tasks immediately after sending the message.
> > > > > > +
> > > > > > +
> > > > > > +Mailbox framework design
> > > > > > +========================
> > > > > > +
> > > > > > +The mailbox facilitates interprocessor communication by allowing processors to
> > > > > > +exchange messages or signals. The mailbox framework consists of:
> > > > > > +
> > > > > > +Mailbox Controller: This is platform-specific and is responsible for configuring
> > > > > > +and managing interrupts from the remote processor. It offers a generic API for
> > > > > > +the mailbox client.
> > > > > > +
> > > > > > +Mailbox Client: This component handles the sending and receiving of messages.
> > > > > > +
> > > > > > +
> > > > > > +............................................................................
> > > > > > +:  client driver      client_a            client_b                         :
> > > > > > +............................................................................
> > > > > > +                            ^-------------------^
> > > > > > +                                    |
> > > > > > +                                    |
> > > > > > +............................................................................
> > > > > > +:  controller framework          mailbox                                   :
> > > > > > +....................................|.......................................
> > > > > > +                                    |
> > > > > > +                                    |
> > > > > > +............................................................................
> > > > > > +:  controller driver          device specific                              :
> > > > > > +....................................|.......................................
> > > > > > +                                    |
> > > > > > +                                    |
> > > > > > +kernel                              |
> > > > > > +............................................................................
> > > > > > +hardware                            |
> > > > > > +                                    |
> > > > > > +                                    |
> > > > > > +............................................................................
> > > > > > +:                             remote processor                             :
> > > > > > +............................................................................
> > > > >
> > > > > htmldocs build errors out:
> > > > >
> > > > > Documentation/driver-api/mailbox/core.rst:57: WARNING: Block quote ends without a blank line; unexpected unindent.
> > > > > Documentation/driver-api/mailbox/core.rst:57: CRITICAL: Missing matching underline for section title overline.
> > > > >
> > > > > ............................................................................
> > > > > :  controller framework          mailbox                                   :
> > > > > ....................................|.......................................
> > > > >
> > > > > reST markup error:
> > > > > Documentation/driver-api/mailbox/core.rst:57: (SEVERE/4) Missing matching underline for section title overline.
> > > > >
> > > > > ............................................................................
> > > > > :  controller framework          mailbox                                   :
> > > > > ....................................|.......................................
> > > > >
> > > > > I have to fix up the design diagram and wrap it:
> > > > >
> > > > > ---- >8 ----
> > > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > > index d1220086da679f..8d56d81007c11c 100644
> > > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > > @@ -47,31 +47,32 @@ the mailbox client.
> > > > >
> > > > >  Mailbox Client: This component handles the sending and receiving of messages.
> > > > >
> > > > > +::
> > > > >
> > > > > -............................................................................
> > > > > -:  client driver      client_a            client_b                         :
> > > > > -............................................................................
> > > > > -                            ^-------------------^
> > > > > -                                    |
> > > > > -                                    |
> > > > > -............................................................................
> > > > > -:  controller framework          mailbox                                   :
> > > > > -....................................|.......................................
> > > > > -                                    |
> > > > > -                                    |
> > > > > -............................................................................
> > > > > -:  controller driver          device specific                              :
> > > > > -....................................|.......................................
> > > > > -                                    |
> > > > > -                                    |
> > > > > -kernel                              |
> > > > > -............................................................................
> > > > > -hardware                            |
> > > > > -                                    |
> > > > > -                                    |
> > > > > -............................................................................
> > > > > -:                             remote processor                             :
> > > > > -............................................................................
> > > > > +  +---------------------------------------------------------------------------+
> > > > > +  |  client driver      client_a            client_b                          |
> > > > > +  +---------------------------------------------------------------------------+
> > > > > +                              ^-------------------^
> > > > > +                                      |
> > > > > +                                      |
> > > > > +  +--------------------------------------------------------------------------+
> > > > > +  |  controller framework          mailbox                                   |
> > > > > +  +-----------------------------------|--------------------------------------+
> > > > > +                                      |
> > > > > +                                      |
> > > > > +  +--------------------------------------------------------------------------+
> > > > > +  |  controller driver          device specific                              |
> > > > > +  +-----------------------------------|--------------------------------------+
> > > > > +                                      |
> > > > > +                                      |
> > > > > +  kernel                              |
> > > > > +  ----------------------------------------------------------------------------
> > > > > +  hardware                            |
> > > > > +                                      |
> > > > > +                                      |
> > > > > +  +--------------------------------------------------------------------------+
> > > > > +  |                             remote processor                             |
> > > > > +  +--------------------------------------------------------------------------+
> > > > >
> > > > >
> > > > >  In the context of a mailbox framework, a channel refers to a dedicated
> > > > >
> > > > > > +
> > > > > > +
> > > > > > +In the context of a mailbox framework, a channel refers to a dedicated
> > > > > > +communication pathway between two or more processors or components. By using
> > > > > > +channels, the framework abstracts the complexity of interprocessor communication.
> > > > > > +
> > > > > > +Data Structures
> > > > > > +================
> > > > > > +
> > > > > > +- **struct mbox_client**
> > > > > > +  This structure represents a client that communicates over a mailbox
> > > > > > +  channel. It holds information such as:
> > > > > > +  - A pointer to the device associated with the client (`dev`).
> > > > > > +  - Callback functions for handling message transmission events, including:
> > > > > > +    - `rx_callback`: Called when a message is received.
> > > > > > +    - `tx_done`: Called when a message transmission is acknowledged.
> > > > > > +  - Flags that specify the client’s configuration, such as whether it operates
> > > > > > +    in blocking mode.
> > > > > > +
> > > > > > +- **struct mbox_chan**
> > > > > > +  This structure represents an individual mailbox channel. It maintains the
> > > > > > +  state required for message queuing and transmission. Key members include:
> > > > > > +  - `msg_data`: Array of messages queued for transmission.
> > > > > > +  - `msg_count`: Number of messages currently queued.
> > > > > > +  - `msg_free`: Index of the next free slot in the message queue.
> > > > > > +  - `active_req`: Pointer to the currently active message being transmitted.
> > > > > > +  - Synchronization primitives to manage access from multiple contexts.
> > > > > > +
> > > > > > +- **struct mbox_controller**
> > > > > > +  This structure represents a mailbox controller that manages multiple
> > > > > > +  channels. It includes:
> > > > > > +  - A pointer to the device managing the mailbox.
> > > > > > +  - Operations for sending and receiving messages, as well as initializing
> > > > > > +    and shutting down the mailbox.
> > > > > > +  - A list of associated channels and the total number of channels available.
> > > > >
> > > > > Shouldn't these structs be documented as kernel-doc comments? tl;dr:
> > > > > see Documentation/doc-guide/kernel-doc.html
> > > > >
> > > > > > +
> > > > > > +controller framework APIs
> > > > > > +=========================
> > > > > > +
> > > > > > +``struct `mbox_controller` Initialization
> > > > > > +-----------------------------------------
> > > > >
> > > > > Properly double-backquote the struct name to format it as inline code:
> > > > >
> > > > > ---- >8 ----
> > > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > > index 239538f497e41a..d83456164464aa 100644
> > > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > > @@ -117,7 +117,7 @@ Data Structures
> > > > >  controller framework APIs
> > > > >  =========================
> > > > >
> > > > > -``struct `mbox_controller` Initialization
> > > > > +``struct mbox_controller`` Initialization
> > > > >  -----------------------------------------
> > > > >
> > > > >  Just like any other kernel framework, the whole mailbox controller registration
> > > > >
> > > > > > +
> > > > > > +Just like any other kernel framework, the whole mailbox controller registration
> > > > > > +relies on the driver filling a structure and registering against the
> > > > > > +framework. In our case, that structure is mbox_controller.
> > > > > > +
> > > > > > +The first thing you need to do in your driver is to allocate this
> > > > > > +structure. Any of the usual memory allocators will do, but you'll also
> > > > > > +need to initialize a few fields in there:
> > > > > > +
> > > > > > +- ``dev``: should hold the pointer to the ``struct device`` associated
> > > > > > +  to your current driver instance.
> > > > > > +
> > > > > > +- ``ops``: Operators that work on each communication channel.
> > > > > > +
> > > > > > +- ``chans``: Array of channels.
> > > > > > +
> > > > > > +- ``num_chans``: Number of channels in the `chans` array.
> > > > > > +
> > > > > > +- ``txdone_irq``: Indicates if the controller can report to the API
> > > > > > +  when the last transmitted data was read by the
> > > > > > +                          remote (e.g., if it has a TX ACK interrupt).
> > > > > > +
> > > > > > +All the below fields are not mandatory.
> > > > > > +
> > > > > > +- ``txdone_poll``: Indicates if the controller can read but not report
> > > > > > +                          the TX done. For example, some register may show
> > > > > > +                          the TX status, but no interrupt is raised. This
> > > > > > +                          field is ignored if `txdone_irq` is set.
> > > > > > +
> > > > > > +- ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > > > > +                          the last TX status after this many milliseconds.
> > > > > > +
> > > > > > +- ``of_xlate``: Controller driver-specific mapping of channel via
> > > > > > +                          Device Tree (DT).
> > > > > > +
> > > > > > +
> > > > > > +Key Functions
> > > > > > +-------------
> > > > > > +
> > > > > > +- **int devm_mbox_controller_register(struct mbox_controller *mbox)**
> > > > > > +  This function registers a mailbox controller with the kernel. It makes the
> > > > > > +  channels associated with the controller available for client requests. The
> > > > > > +  function performs sanity checks on the controller structure to ensure all
> > > > > > +  necessary fields are populated.
> > > > > > +
> > > > > > +- **struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)**
> > > > > > +  This function requests a mailbox channel for a specified client, identified
> > > > > > +  by an index. It searches for the appropriate mailbox channel, and if found,
> > > > > > +  it returns a pointer to the channel. If the request fails (e.g., if the
> > > > > > +  index is invalid), it returns an error pointer.
> > > > > > +
> > > > > > +- **void mbox_free_channel(struct mbox_chan *chan)**
> > > > > > +  This function releases a mailbox channel that was previously allocated for a
> > > > > > +  client. It ensures that the channel can be reused by other clients. If any
> > > > > > +  messages are still in the queue, they are aborted, and no callbacks are made.
> > > > > > +
> > > > > > +- **int mbox_send_message(struct mbox_chan *chan, void *mssg)**
> > > > > > +  This function is used by clients to send a message through the specified
> > > > > > +  mailbox channel. The function can operate in either blocking or non-blocking
> > > > > > +  mode, depending on the client’s configuration. It will queue the message for
> > > > > > +  transmission and notify the client once the message is acknowledged.
> > > > > > +
> > > > > > +- **void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)**
> > > > > > +  This function is called by the controller driver to notify the mailbox
> > > > > > +  framework that a message has been received on the specified channel. The
> > > > > > +  received message is then passed to the appropriate client's `rx_callback`
> > > > > > +  function for processing.
> > > > >
> > > > > Shouldn't these functions also be documented as kernel-doc comments?
> > > > >
> > > > > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > > > > new file mode 100644
> > > > > > index 000000000000..e254a8fdb66a
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > > > > @@ -0,0 +1,45 @@
> > > > > > +=======================
> > > > > > +Mailbox documentation
> > > > > > +=======================
> > > > > > +
> > > > > > +Mailbox documentation provides documents for various aspects of mailbox
> > > > > > +framework.
> > > > > > +
> > > > > > +Mailbox development documentation
> > > > > > +---------------------------------
> > > > > > +
> > > > > > +This book helps with mailbox internal APIs and guide for mailbox device
> > > > > > +driver writers.
> > > > > > +
> > > > > > +.. toctree::
> > > > > > +   :maxdepth: 1
> > > > > > +
> > > > > > +   core
> > > > > > +
> > > > > > +mailbox controller driver documentation
> > > > > > +------------------------------
> > > > > > +
> > > > > > +This book is a guide to device driver writers on how to register
> > > > > > +mailbox controller to the mailbox framework.
> > > > > > +
> > > > > > +.. toctree::
> > > > > > +   :maxdepth: 1
> > > > > > +
> > > > > > +   writing_mailbox_controller_drivers
> > > > > > +
> > > > > > +mailbox client driver documentation
> > > > > > +------------------------------
> > > > >
> > > > > Match up section underline length by its title:
> > > > >
> > > > > ---- >8 ----
> > > > > diff --git a/Documentation/driver-api/mailbox/index.rst b/Documentation/driver-api/mailbox/index.rst
> > > > > index e254a8fdb66ac7..02d7d5e8660999 100644
> > > > > --- a/Documentation/driver-api/mailbox/index.rst
> > > > > +++ b/Documentation/driver-api/mailbox/index.rst
> > > > > @@ -1,6 +1,6 @@
> > > > > -=======================
> > > > > +=====================
> > > > >  Mailbox documentation
> > > > > -=======================
> > > > > +=====================
> > > > >
> > > > >  Mailbox documentation provides documents for various aspects of mailbox
> > > > >  framework.
> > > > > @@ -17,7 +17,7 @@ driver writers.
> > > > >     core
> > > > >
> > > > >  mailbox controller driver documentation
> > > > > -------------------------------
> > > > > +---------------------------------------
> > > > >
> > > > >  This book is a guide to device driver writers on how to register
> > > > >  mailbox controller to the mailbox framework.
> > > > > @@ -28,7 +28,7 @@ mailbox controller to the mailbox framework.
> > > > >     writing_mailbox_controller_drivers
> > > > >
> > > > >  mailbox client driver documentation
> > > > > -------------------------------
> > > > > +-----------------------------------
> > > > >
> > > > >  This book is a guide to mailbox client driver writers.
> > > > >
> > > > >
> > > > > > +
> > > > > > +This book is a guide to mailbox client driver writers.
> > > > > > +
> > > > > > +.. toctree::
> > > > > > +   :maxdepth: 1
> > > > > > +
> > > > > > +   client
> > > > > > +
> > > > > > +.. only::  subproject and html
> > > > > > +
> > > > > > +   Indices
> > > > > > +   =======
> > > > > > +
> > > > > > +   * :ref:`genindex`
> > > > >
> > > > > Fix up also the reference link on parent toctree:
> > > > >
> > > > > ---- >8 ----
> > > > > diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
> > > > > index 7f83e05769b4a4..b4d78b92fd921a 100644
> > > > > --- a/Documentation/driver-api/index.rst
> > > > > +++ b/Documentation/driver-api/index.rst
> > > > > @@ -102,7 +102,7 @@ Subsystem-specific APIs
> > > > >     ipmb
> > > > >     ipmi
> > > > >     libata
> > > > > -   mailbox
> > > > > +   mailbox/index
> > > > >     md/index
> > > > >     media/index
> > > > >     mei/index
> > > > >
> > > > > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > > new file mode 100644
> > > > > > index 000000000000..2a82645c1357
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > > @@ -0,0 +1,179 @@
> > > > > > +.. SPDX-License-Identifier: GPL-2.0
> > > > > > +
> > > > > > +.. _writing_mailbox_controller_drivers:
> > > > > > +
> > > > > > +==================================
> > > > > > +Writing Mailbox Controller Drivers
> > > > > > +==================================
> > > > > > +
> > > > > > +Introduction
> > > > > > +============
> > > > > > +
> > > > > > +This document serves as a basic guideline for driver programmers that need
> > > > > > +to hack a new mailbox controller driver or understand the essentials of
> > > > > > +the existing ones.
> > > > > > +
> > > > > > +Driver Boilerplate
> > > > > > +==================
> > > > > > +
> > > > > > +As a bare minimum, a mailbox controller driver needs to call
> > > > > > +``mbox_controller_register`` function to register with the framework.
> > > > > > +
> > > > > > +A basic driver skeleton could look like this for a mailbox hardware that
> > > > > > +has the following characteristics:
> > > > > > +a. It supports only a single channel, i.e., only the remote processor can
> > > > > > +   send interrupts.
> > > > > > +b. Data transfer is over the registers associated with mailbox hardware.
> > > > > > +c. Mailbox hardware is configured to receive interrupts.
> > > > > > +d. When the remote processor is ready to send data, it triggers a mailbox
> > > > > > +   interrupt.
> > > > > > +e. As part of interrupt handling by Linux, it copies data from the registers.
> > > > > > +
> > > > > > +.. code-block:: c
> > > > > > +
> > > > > > +   #include <linux/device.h>
> > > > > > +   #include <linux/interrupt.h>
> > > > > > +   #include <linux/io.h>
> > > > > > +   #include <linux/kernel.h>
> > > > > > +   #include <linux/mailbox_controller.h>
> > > > > > +   #include <linux/module.h>
> > > > > > +   #include <linux/of.h>
> > > > > > +   #include <linux/platform_device.h>
> > > > > > +   #define DRIVER_NAME "dummy_controller"
> > > > > > +
> > > > > > +   struct dummy_mbox {
> > > > > > +       struct device *dev;
> > > > > > +       struct mbox_controller controller;
> > > > > > +       int irq;
> > > > > > +   };
> > > > > > +
> > > > > > +   static void dummy_mbox_receive(struct mbox_chan *chan)
> > > > > > +   {
> > > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > > +       int val;
> > > > > > +
> > > > > > +       // Data copied from registers
> > > > > > +       val = read_register();
> > > > > > +       mbox_chan_received_data(chan, &val);
> > > > > > +   }
> > > > > > +
> > > > > > +   static irqreturn_t dummy_mbox_irq_handler(int irq, void *data)
> > > > > > +   {
> > > > > > +       struct mbox_chan *chan = data;
> > > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > > +       u32 reg;
> > > > > > +
> > > > > > +       // Read registers to see if data is received
> > > > > > +       dummy_mbox_receive(chan);
> > > > > > +       mbox_chan_txdone(chan, 0);
> > > > > > +       return reg ? IRQ_HANDLED : IRQ_NONE;
> > > > > > +   }
> > > > > > +
> > > > > > +   static int dummy_mbox_send_data(struct mbox_chan *chan, void *data)
> > > > > > +   {
> > > > > > +       // Write data in registers to send it to the remote processor
> > > > > > +       return 0;
> > > > > > +   }
> > > > > > +
> > > > > > +   static int dummy_mbox_startup(struct mbox_chan *chan)
> > > > > > +   {
> > > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > > +       u32 reg;
> > > > > > +       int ret;
> > > > > > +
> > > > > > +       ret = devm_request_irq(mbox->dev, mbox->irq, dummy_mbox_irq_handler, 0,
> > > > > > +               DRIVER_NAME, chan);
> > > > > > +       if (ret < 0) {
> > > > > > +           dev_err(mbox->dev, "Cannot request irq\n");
> > > > > > +           return ret;
> > > > > > +       }
> > > > > > +
> > > > > > +       /* Register write to enable IRQ generation */
> > > > > > +
> > > > > > +       return 0;
> > > > > > +   }
> > > > > > +
> > > > > > +   static void dummy_mbox_shutdown(struct mbox_chan *chan)
> > > > > > +   {
> > > > > > +       struct dummy_mbox *mbox = chan->con_priv;
> > > > > > +
> > > > > > +       /* Disable interrupt generation */
> > > > > > +       devm_free_irq(mbox->dev, mbox->irq, chan);
> > > > > > +   }
> > > > > > +
> > > > > > +   static const struct mbox_chan_ops dummy_mbox_ops = {
> > > > > > +       .send_data = dummy_mbox_send_data,
> > > > > > +       .startup = dummy_mbox_startup,
> > > > > > +       .shutdown = dummy_mbox_shutdown,
> > > > > > +   };
> > > > > > +
> > > > > > +   static int dummy_mbox_probe(struct platform_device *pdev)
> > > > > > +   {
> > > > > > +       struct dummy_mbox *mbox;
> > > > > > +       struct mbox_chan *chans;
> > > > > > +       int ret;
> > > > > > +
> > > > > > +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> > > > > > +       if (!mbox)
> > > > > > +           return -ENOMEM;
> > > > > > +
> > > > > > +       /* Allocate one channel */
> > > > > > +       chans = devm_kzalloc(&pdev->dev, sizeof(*chans), GFP_KERNEL);
> > > > > > +       if (!chans)
> > > > > > +           return -ENOMEM;
> > > > > > +
> > > > > > +       mbox->base = devm_platform_ioremap_resource(pdev, 0);
> > > > > > +       if (IS_ERR(mbox->base))
> > > > > > +           return PTR_ERR(mbox->base);
> > > > > > +
> > > > > > +       mbox->irq = platform_get_irq(pdev, 0);
> > > > > > +       if (mbox->irq < 0)
> > > > > > +           return mbox->irq;
> > > > > > +
> > > > > > +       mbox->dev = &pdev->dev;
> > > > > > +
> > > > > > +       /* Hardware supports only one channel. */
> > > > > > +       mbox->controller.dev = mbox->dev;
> > > > > > +       mbox->controller.num_chans = 1;
> > > > > > +       mbox->controller.chans = chans;
> > > > > > +       mbox->controller.ops = &dummy_mbox_ops;
> > > > > > +       mbox->controller.txdone_irq = true;
> > > > > > +
> > > > > > +       ret = devm_mbox_controller_register(mbox->dev, &mbox->controller);
> > > > > > +       if (ret) {
> > > > > > +           dev_err(&pdev->dev, "Could not register mailbox controller\n");
> > > > > > +           return ret;
> > > > > > +       }
> > > > > > +
> > > > > > +       return ret;
> > > > > > +   }
> > > > > > +
> > > > > > +   static const struct of_device_id dummy_mbox_match[] = {
> > > > > > +       { .compatible = "dummy,dummy-mailbox" },
> > > > > > +       { },
> > > > > > +   };
> > > > > > +
> > > > > > +   MODULE_DEVICE_TABLE(of, dummy_mbox_match);
> > > > > > +
> > > > > > +   static struct platform_driver dummy_mbox_driver = {
> > > > > > +       .probe = dummy_mbox_probe,
> > > > > > +       .driver = {
> > > > > > +           .name = DRIVER_NAME,
> > > > > > +           .of_match_table = dummy_mbox_match,
> > > > > > +       },
> > > > > > +   };
> > > > > > +
> > > > > > +   module_platform_driver(dummy_mbox_driver);
> > > > > > +   MODULE_LICENSE("GPL v2");
> > > > > > +   MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > > > > +
> > > > > > +In the above code, a couple of things are done:
> > > > > > +a. The controller is registered in the probe along with callbacks, which in
> > > > > > +   this case are the bare minimum: ``startup``, ``shutdown``, and
> > > > > > +   ``send_data``.
> > > > > > +b. IRQ is registered to get notifications from the remote processor.
> > > > > > +c. In the IRQ handler, registers are read to copy data, and
> > > > > > +   ``mbox_chan_received_data`` is called to hand over the data to the client.
> > > > > > +d. ``mbox_chan_txdone`` is called to let the framework know that this data
> > > > > > +   is the last data and no more data is to be expected for the current transfer.
> > > > > > +
> > > > >
> > > > > Sphinx warns out numerous indentation warnings on the lists, so I have to
> > > > > fix them up:
> > > > >
> > > > > ---- >8 ----
> > > > > diff --git a/Documentation/driver-api/mailbox/client.rst b/Documentation/driver-api/mailbox/client.rst
> > > > > index 9088f83734230d..17dafaca056777 100644
> > > > > --- a/Documentation/driver-api/mailbox/client.rst
> > > > > +++ b/Documentation/driver-api/mailbox/client.rst
> > > > > @@ -31,6 +31,7 @@ The mailbox structure is defined as follows:
> > > > >  Key Functions
> > > > >  -------------
> > > > >  1. Requesting a Mailbox Channel
> > > > > +
> > > > >     - **Function**: `mbox_request_channel(struct mbox_client *client,
> > > > >       unsigned int channel)`
> > > > >     - **Description**: Requests a mailbox channel for sending messages.
> > > > > @@ -41,15 +42,19 @@ Key Functions
> > > > >       code on failure.
> > > > >
> > > > >  2. Sending a Message
> > > > > +
> > > > >     - **Function**: `mbox_send_message(struct mbox_chan *chan, void *msg)`
> > > > >     - **Description**: Sends a message through the mailbox channel.
> > > > >     - **Parameters**:
> > > > > +
> > > > >       - `chan`: The mailbox channel used for communication.
> > > > >       - `msg`: Pointer to the message to be sent (usually NULL for dummy
> > > > >         messages).
> > > > > +
> > > > >     - **Returns**: 0 on success, or a negative error code on failure.
> > > > >
> > > > >  3. Transmitting Completion
> > > > > +
> > > > >     - **Function**: `mbox_client_txdone(struct mbox_chan *chan, unsigned int
> > > > >       msg_id)`
> > > > >     - **Description**: Notifies the mailbox framework that message
> > > > > diff --git a/Documentation/driver-api/mailbox/core.rst b/Documentation/driver-api/mailbox/core.rst
> > > > > index 8d56d81007c11c..239538f497e41a 100644
> > > > > --- a/Documentation/driver-api/mailbox/core.rst
> > > > > +++ b/Documentation/driver-api/mailbox/core.rst
> > > > > @@ -85,16 +85,20 @@ Data Structures
> > > > >  - **struct mbox_client**
> > > > >    This structure represents a client that communicates over a mailbox
> > > > >    channel. It holds information such as:
> > > > > +
> > > > >    - A pointer to the device associated with the client (`dev`).
> > > > >    - Callback functions for handling message transmission events, including:
> > > > > +
> > > > >      - `rx_callback`: Called when a message is received.
> > > > >      - `tx_done`: Called when a message transmission is acknowledged.
> > > > > +
> > > > >    - Flags that specify the client’s configuration, such as whether it operates
> > > > >      in blocking mode.
> > > > >
> > > > >  - **struct mbox_chan**
> > > > >    This structure represents an individual mailbox channel. It maintains the
> > > > >    state required for message queuing and transmission. Key members include:
> > > > > +
> > > > >    - `msg_data`: Array of messages queued for transmission.
> > > > >    - `msg_count`: Number of messages currently queued.
> > > > >    - `msg_free`: Index of the next free slot in the message queue.
> > > > > @@ -104,6 +108,7 @@ Data Structures
> > > > >  - **struct mbox_controller**
> > > > >    This structure represents a mailbox controller that manages multiple
> > > > >    channels. It includes:
> > > > > +
> > > > >    - A pointer to the device managing the mailbox.
> > > > >    - Operations for sending and receiving messages, as well as initializing
> > > > >      and shutting down the mailbox.
> > > > > @@ -133,21 +138,20 @@ need to initialize a few fields in there:
> > > > >  - ``num_chans``: Number of channels in the `chans` array.
> > > > >
> > > > >  - ``txdone_irq``: Indicates if the controller can report to the API
> > > > > -  when the last transmitted data was read by the
> > > > > -                          remote (e.g., if it has a TX ACK interrupt).
> > > > > +  when the last transmitted data was read by the remote (e.g., if it has a
> > > > > +  TX ACK interrupt).
> > > > >
> > > > >  All the below fields are not mandatory.
> > > > >
> > > > >  - ``txdone_poll``: Indicates if the controller can read but not report
> > > > > -                          the TX done. For example, some register may show
> > > > > -                          the TX status, but no interrupt is raised. This
> > > > > -                          field is ignored if `txdone_irq` is set.
> > > > > +  the TX done. For example, some register may show the TX status, but no
> > > > > +  interrupt is raised. This field is ignored if `txdone_irq` is set.
> > > > >
> > > > >  - ``txpoll_period``: If `txdone_poll` is in effect, the API polls for
> > > > > -                          the last TX status after this many milliseconds.
> > > > > +  the last TX status after this many milliseconds.
> > > > >
> > > > >  - ``of_xlate``: Controller driver-specific mapping of channel via
> > > > > -                          Device Tree (DT).
> > > > > +  Device Tree (DT).
> > > > >
> > > > >
> > > > >  Key Functions
> > > > > diff --git a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > index 2a82645c13573e..853adf6918173d 100644
> > > > > --- a/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > +++ b/Documentation/driver-api/mailbox/writing_mailbox_controller_drivers.rst
> > > > > @@ -21,6 +21,7 @@ As a bare minimum, a mailbox controller driver needs to call
> > > > >
> > > > >  A basic driver skeleton could look like this for a mailbox hardware that
> > > > >  has the following characteristics:
> > > > > +
> > > > >  a. It supports only a single channel, i.e., only the remote processor can
> > > > >     send interrupts.
> > > > >  b. Data transfer is over the registers associated with mailbox hardware.
> > > > > @@ -168,6 +169,7 @@ e. As part of interrupt handling by Linux, it copies data from the registers.
> > > > >     MODULE_DESCRIPTION("Dummy mailbox controller driver");
> > > > >
> > > > >  In the above code, a couple of things are done:
> > > > > +
> > > > >  a. The controller is registered in the probe along with callbacks, which in
> > > > >     this case are the bare minimum: ``startup``, ``shutdown``, and
> > > > >     ``send_data``.
> > > > >
> > > > > Thanks.
> > > > >
> > > > > --
> > > > > An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-12-05 20:32 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-19 19:55 [PATCH 1/2] mailbox: Documentation: remove the old documentation anish kumar
2024-10-19 19:55 ` [PATCH 2/2] mailbox: Documentation: add the latest documentation anish kumar
2024-10-24 18:42   ` anish kumar
2024-10-25  3:38   ` Bagas Sanjaya
2024-10-25 19:24     ` anish kumar
2024-10-29 18:06       ` anish kumar
2024-10-29 23:51         ` Bagas Sanjaya
2024-10-30  0:42           ` anish kumar
2024-10-30  1:17             ` Bagas Sanjaya
2024-10-30 17:41         ` Jassi Brar
2024-10-30 18:13           ` anish kumar
2024-12-05 20:32             ` anish kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®