Re: [PATCH v2] remoteproc: k3-dsp: Fix log levels where appropriate

2024-07-03 Thread Andrew Davis

On 6/26/24 2:14 PM, Garrett Giordano wrote:

Driver was logging information as errors. Changed dev_err to dev_dbg
where appropriate.

Signed-off-by: Garrett Giordano 
---


Acked-by: Andrew Davis 


-v2
   - Change from dev_info to dev_dbg
   - Drop k3-r5 PATCH
---
  drivers/remoteproc/ti_k3_dsp_remoteproc.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 3555b535b168..a22d41689a7d 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -327,7 +327,7 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
goto put_mbox;
}

-   dev_err(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
+   dev_dbg(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
if (ret)
goto put_mbox;
--
2.25.1






Re: [PATCH 4/4] remoteproc: k3-r5: support for graceful stop of remote cores

2024-06-28 Thread Andrew Davis

On 6/21/24 10:00 AM, Richard Genoud wrote:

Introduce software IPC handshake between the K3-R5 remote proc driver
and the R5 MCU to gracefully stop/reset the remote core.

Upon a stop request, K3-R5 remote proc driver sends a RP_MBOX_SHUTDOWN
mailbox message to the remote R5 core.
The remote core is expected to:
- relinquish all the resources acquired through Device Manager (DM)
- disable its interrupts
- send back a mailbox acknowledgment RP_MBOX_SHUDOWN_ACK
- enter WFI state.

Meanwhile, the K3-R5 remote proc driver does:
- wait for the RP_MBOX_SHUTDOWN_ACK from the remote core
- wait for the remote proc to enter WFI state
- reset the remote core through device manager

Based on work from: Hari Nagalla 

Signed-off-by: Richard Genoud 
---
  drivers/remoteproc/omap_remoteproc.h |  9 +-
  drivers/remoteproc/ti_k3_r5_remoteproc.c | 40 
  2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/omap_remoteproc.h 
b/drivers/remoteproc/omap_remoteproc.h
index 828e13256c02..c008f11fa2a4 100644
--- a/drivers/remoteproc/omap_remoteproc.h
+++ b/drivers/remoteproc/omap_remoteproc.h
@@ -42,6 +42,11 @@
   * @RP_MBOX_SUSPEND_CANCEL: a cancel suspend response from a remote processor
   * on a suspend request
   *
+ * @RP_MBOX_SHUTDOWN: shutdown request for the remote processor
+ *
+ * @RP_MBOX_SHUTDOWN_ACK: successful response from remote processor for a
+ * shutdown request. The remote processor should be in WFI state short after.
+ *
   * Introduce new message definitions if any here.
   *
   * @RP_MBOX_END_MSG: Indicates end of known/defined messages from remote core
@@ -59,7 +64,9 @@ enum omap_rp_mbox_messages {
RP_MBOX_SUSPEND_SYSTEM  = 0xFF11,
RP_MBOX_SUSPEND_ACK = 0xFF12,
RP_MBOX_SUSPEND_CANCEL  = 0xFF13,
-   RP_MBOX_END_MSG = 0xFF14,
+   RP_MBOX_SHUTDOWN= 0xFF14,
+   RP_MBOX_SHUTDOWN_ACK= 0xFF15,
+   RP_MBOX_END_MSG = 0xFF16,
  };
  
  #endif /* _OMAP_RPMSG_H */

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index a2ead87952c7..918a15e1dd9a 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -21,6 +21,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  
@@ -172,8 +173,23 @@ struct k3_r5_rproc {

struct k3_r5_core *core;
struct k3_r5_mem *rmem;
int num_rmems;
+   struct completion shutdown_complete;
  };
  
+/*

+ * This will return true if the remote core is in Wait For Interrupt state.
+ */
+static bool k3_r5_is_core_in_wfi(struct k3_r5_core *core)
+{
+   int ret;
+   u64 boot_vec;
+   u32 cfg, ctrl, stat;
+
+   ret = ti_sci_proc_get_status(core->tsp, _vec, , , );
+
+   return !ret ? !!(stat & PROC_BOOT_STATUS_FLAG_R5_WFI) : false;


Too fancy for me :) Just return if (ret) right after get_status().

Looks like this function is called in a polling loop, if
ti_sci_proc_get_status() fails once, it won't get better,
no need to keep checking, we should just error out of
the polling loop.

Andrew


+}
+
  /**
   * k3_r5_rproc_mbox_callback() - inbound mailbox message handler
   * @client: mailbox client pointer used for requesting the mailbox channel
@@ -209,6 +225,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
case RP_MBOX_ECHO_REPLY:
dev_info(dev, "received echo reply from %s\n", name);
break;
+   case RP_MBOX_SHUTDOWN_ACK:
+   dev_dbg(dev, "received shutdown_ack from %s\n", name);
+   complete(>shutdown_complete);
+   break;
default:
/* silently handle all other valid messages */
if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
@@ -634,6 +654,7 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
struct k3_r5_cluster *cluster = kproc->cluster;
struct device *dev = kproc->dev;
struct k3_r5_core *core1, *core = kproc->core;
+   bool wfi;
int ret;
  
  
@@ -650,6 +671,24 @@ static int k3_r5_rproc_stop(struct rproc *rproc)

}
}
  
+	/* Send SHUTDOWN message to remote proc */

+   reinit_completion(>shutdown_complete);
+   ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_SHUTDOWN);
+   if (ret < 0) {
+   dev_err(dev, "Sending SHUTDOWN message failed: %d. Halting core 
anyway.\n", ret);
+   } else {
+   ret = wait_for_completion_timeout(>shutdown_complete,
+ msecs_to_jiffies(1000));
+   if (ret == 0) {
+   dev_err(dev, "Timeout waiting SHUTDOWN_ACK message. Halting 
core anyway.\n");
+   } else {
+   ret = readx_poll_timeout(k3_r5_is_core_in_wfi, core,
+wfi, wfi, 200, 

Re: [PATCH v2 00/13] OMAP mailbox FIFO removal

2024-06-26 Thread Andrew Davis

On 6/26/24 9:39 AM, Dominic Rath wrote:

On 13.06.2024 14:22, Andrew Davis wrote:

We looked into this some time ago, and noticed that the IRQ approach caused 
problems in the virtio/rpmsg code. I'd like to understand if your change was 
for the same reason, or something else we missed before.



It is most likely the same reason. Seems despite its name, rproc_vq_interrupt() 
cannot
be called from an IRQ/atomic context. As the following backtrace shows, that 
function
calls down into functions which are not IRQ safe. So we needed to keep it 
threaded:

[    5.389374] BUG: scheduling while atomic: (udev-worker)/232/0x00010002
[    5.395917] Modules linked in: videobuf2_dma_contig videobuf2_memops 
videobuf2_v4l2 phy_j721e_wiz display_connector omap_mailbox(+) videodev 
tps6594_i2c(+) videobuf2_common phy_can_transceiver at24 cd6
[    5.433562] CPU: 0 PID: 232 Comm: (udev-worker) Not tainted 
6.10.0-rc1-next-20240528-dirty #10
[    5.442158] Hardware name: Texas Instruments AM69 SK (DT)
[    5.447540] Call trace:
[    5.449976]  dump_backtrace+0x94/0xec
[    5.453640]  show_stack+0x18/0x24
[    5.456944]  dump_stack_lvl+0x78/0x90
[    5.460598]  dump_stack+0x18/0x24
[    5.463900]  __schedule_bug+0x50/0x68
[    5.467552]  __schedule+0x80c/0xb0c
[    5.471029]  schedule+0x34/0x104
[    5.474243]  schedule_preempt_disabled+0x24/0x40
[    5.478845]  rwsem_down_write_slowpath+0x31c/0x56c
[    5.483622]  down_write+0x90/0x94
[    5.486924]  kernfs_add_one+0x3c/0x148
[    5.490661]  kernfs_create_dir_ns+0x50/0x94
[    5.494830]  sysfs_create_dir_ns+0x70/0x10c
[    5.498999]  kobject_add_internal+0x98/0x26c
[    5.503254]  kobject_add+0x9c/0x10c
[    5.506729]  device_add+0xc0/0x790
[    5.510120]  rpmsg_register_device_override+0x10c/0x1c0
[    5.515333]  rpmsg_register_device+0x14/0x20
[    5.519590]  virtio_rpmsg_create_channel+0xb0/0x104
[    5.524452]  rpmsg_create_channel+0x28/0x60
[    5.528622]  rpmsg_ns_cb+0x100/0x1dc
[    5.532185]  rpmsg_recv_done+0x114/0x2e4
[    5.536094]  vring_interrupt+0x68/0xa4
[    5.539833]  rproc_vq_interrupt+0x2c/0x48
[    5.543830]  k3_r5_rproc_mbox_callback+0x84/0x90 [ti_k3_r5_remoteproc]
[    5.550348]  mbox_chan_received_data+0x1c/0x2c
[    5.554779]  mbox_interrupt+0xa0/0x17c [omap_mailbox]
[    5.559820]  __handle_irq_event_percpu+0x48/0x13c
[    5.564511]  handle_irq_event+0x4c/0xac



I looked into this a bit more closely, together with the colleague who 
implemented our internal workaround, and we came up with one more concern:

Have you considered that this synchronous path from the (threaded) IRQ draining 
the mailbox down to the (potentially blocking) rpmsg_* calls might let the 
hardware mailbox grow full?

 From what I remember the vring (?) has room for 512 messages, but the hardware 
mailbox on e.g. the AM64x can only handle four messages. At least with the 
current implementation on TI's MCU+ SDK running on the R5f that could cause the 
R5f to block, waiting for room in the hardware mailbox, while there are plenty 
of vring buffers available.



We would like to switch back to the non-threaded handler at some point. As you 
mention doing this
in a threaded way increase the risk of the hardware message queue filling and 
blocking the remote side.
(Plus the threaded handling can add latency to the message handling which 
should be avoided for real-time
reasons)

The fix might be to have rpmsg_recv_done() callback simply queue the message 
and then schedule another
worker to actually do the next stage processing. That way complex actions on 
messages do not block
vring_interrupt() which should be treated like an atomic context call.

Anyway for now, I'd expect the much faster host core (2xA53 @ 1GHZ in AM64) to 
be able to outpace the
R5s and keep the mailbox drained. Are you actually running into this issue or 
is the concern based on
ensuring RT performance(not blocking on mailbox queue filled) on the R5 side?

Andrew


Best Regards,

Dominic




Re: [PATCH v2 2/3] remoteproc: k3-r5: Acquire mailbox handle during probe

2024-06-21 Thread Andrew Davis

On 6/21/24 6:14 AM, Beleswar Prasad Padhi wrote:

Hi Andrew,

On 04/06/24 22:40, Andrew Davis wrote:

On 6/4/24 12:17 AM, Beleswar Padhi wrote:

Acquire the mailbox handle during device probe and do not release handle
in stop/detach routine or error paths. This removes the redundant
requests for mbox handle later during rproc start/attach. This also
allows to defer remoteproc driver's probe if mailbox is not probed yet.

Signed-off-by: Beleswar Padhi 
---
  drivers/remoteproc/ti_k3_r5_remoteproc.c | 74 +---
  1 file changed, 26 insertions(+), 48 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 26362a509ae3c..7e02e3472ce25 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -194,6 +194,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
  const char *name = kproc->rproc->name;
  u32 msg = omap_mbox_message(data);
  +    /* Do not forward message to a detached core */


s/to/from

This is the receive side from the core.


+    if (kproc->rproc->state == RPROC_DETACHED)
+    return;
+


Do we need a similar check when sending messages to the core in
k3_r5_rproc_kick()? No one should be sending anything as they
all should have detached at this point, but something to double
check on.

Will add this in the next revision.



  dev_dbg(dev, "mbox msg: 0x%x\n", msg);
    switch (msg) {
@@ -399,12 +403,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
  client->knows_txdone = false;
    kproc->mbox = mbox_request_channel(client, 0);
-    if (IS_ERR(kproc->mbox)) {
-    ret = -EBUSY;
-    dev_err(dev, "mbox_request_channel failed: %ld\n",
-    PTR_ERR(kproc->mbox));
-    return ret;
-    }
+    if (IS_ERR(kproc->mbox))
+    return dev_err_probe(dev, PTR_ERR(kproc->mbox),
+ "mbox_request_channel failed\n");


This is good cleanup, but maybe something for its own patch.

I think this cleanup is dependent to this patch itself. The current patch moves 
the mbox_handle_request to probe routine. And the cleanup returns an 
-EDEFER_PROBE ERR code. So, this cleanup is only valid if the current patch is 
applied. Else, if this err code is returned at any point after creation of 
child devices, it could lead to a infinite loop[0]. Please correct me if I am 
wrong..?



Okay I see what you are saying, k3_r5_rproc_request_mbox() is now called from
probe() and not start() as it was before. Then you are correct.

Andrew


[0]: 
https://www.kernel.org/doc/html/v6.5-rc3/driver-api/driver-model/driver.html#callbacks



    /*
   * Ping the remote processor, this is only for sanity-sake for now;
@@ -552,10 +553,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  u32 boot_addr;
  int ret;
  -    ret = k3_r5_rproc_request_mbox(rproc);
-    if (ret)
-    return ret;
-
  boot_addr = rproc->bootaddr;
  /* TODO: add boot_addr sanity checking */
  dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
@@ -564,7 +561,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  core = kproc->core;
  ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
  if (ret)
-    goto put_mbox;
+    return ret;
    /* unhalt/run all applicable cores */
  if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
@@ -580,13 +577,12 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
  dev_err(dev, "%s: can not start core 1 before core 0\n",
  __func__);
-    ret = -EPERM;
-    goto put_mbox;
+    return -EPERM;
  }
    ret = k3_r5_core_run(core);
  if (ret)
-    goto put_mbox;
+    return ret;
  }
    return 0;
@@ -596,8 +592,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  if (k3_r5_core_halt(core))
  dev_warn(core->dev, "core halt back failed\n");
  }
-put_mbox:
-    mbox_free_channel(kproc->mbox);
  return ret;
  }
  @@ -658,8 +652,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  goto out;
  }
  -    mbox_free_channel(kproc->mbox);
-
  return 0;
    unroll_core_halt:
@@ -674,42 +666,22 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  /*
   * Attach to a running R5F remote processor (IPC-only mode)
   *
- * The R5F attach callback only needs to request the mailbox, the remote
- * processor is already booted, so there is no need to issue any TI-SCI
- * commands to boot the R5F cores in IPC-only mode. This callback is invoked
- * only in IPC-only mode.
+ * The R5F attach callback is a NOP. The remote processor is already booted, 
and
+ * all required resources have be

Re: [PATCH v10 2/8] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-06-18 Thread Andrew Davis

On 6/18/24 12:05 PM, Mathieu Poirier wrote:

Good morning,

On Mon, Jun 10, 2024 at 01:06:09PM -0500, Andrew Davis wrote:

From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
  drivers/remoteproc/Kconfig   |  13 +
  drivers/remoteproc/Makefile  |   1 +
  drivers/remoteproc/ti_k3_m4_remoteproc.c | 760 +++
  3 files changed, 774 insertions(+)
  create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
  
+config TI_K3_M4_REMOTEPROC

+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
  config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
  obj-$(CONFIG_ST_SLIM_REMOTEPROC)  += st_slim_rproc.o
  obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
  obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)+= ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
  obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
  obj-$(CONFIG_XLNX_R5_REMOTEPROC)  += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..880e8f0ad1ba3
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,760 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ */
+struct k3_m4_rproc_dev_data {
+   const struct k3_m4_rproc_mem_data *mems;
+   u32 num_mems;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal mem

Re: [PATCH v2 00/13] OMAP mailbox FIFO removal

2024-06-13 Thread Andrew Davis

On 6/13/24 2:58 AM, Dominic Rath wrote:

Hello Andrew,

On 10.04.2024 15:59, Andrew Davis wrote:

Changes for v2:
  - Use threaded irq as suggested by Hari and to
  fix possible "scheduling while atomic" issue


sorry for beeing late, I noticed this already got merged.

I was wondering what the reason was for ending up with the
threaded irq.

In your v1 thread your final conclusion appeared to be


So for now I just kept this using the regular IRQ context as before.


We looked into this some time ago, and noticed that the IRQ approach caused 
problems in the virtio/rpmsg code. I'd like to understand if your change was 
for the same reason, or something else we missed before.



It is most likely the same reason. Seems despite its name, rproc_vq_interrupt() 
cannot
be called from an IRQ/atomic context. As the following backtrace shows, that 
function
calls down into functions which are not IRQ safe. So we needed to keep it 
threaded:

[5.389374] BUG: scheduling while atomic: (udev-worker)/232/0x00010002
[5.395917] Modules linked in: videobuf2_dma_contig videobuf2_memops 
videobuf2_v4l2 phy_j721e_wiz display_connector omap_mailbox(+) videodev 
tps6594_i2c(+) videobuf2_common phy_can_transceiver at24 cd6
[5.433562] CPU: 0 PID: 232 Comm: (udev-worker) Not tainted 
6.10.0-rc1-next-20240528-dirty #10
[5.442158] Hardware name: Texas Instruments AM69 SK (DT)
[5.447540] Call trace:
[5.449976]  dump_backtrace+0x94/0xec
[5.453640]  show_stack+0x18/0x24
[5.456944]  dump_stack_lvl+0x78/0x90
[5.460598]  dump_stack+0x18/0x24
[5.463900]  __schedule_bug+0x50/0x68
[5.467552]  __schedule+0x80c/0xb0c
[5.471029]  schedule+0x34/0x104
[5.474243]  schedule_preempt_disabled+0x24/0x40
[5.478845]  rwsem_down_write_slowpath+0x31c/0x56c
[5.483622]  down_write+0x90/0x94
[5.486924]  kernfs_add_one+0x3c/0x148
[5.490661]  kernfs_create_dir_ns+0x50/0x94
[5.494830]  sysfs_create_dir_ns+0x70/0x10c
[5.498999]  kobject_add_internal+0x98/0x26c
[5.503254]  kobject_add+0x9c/0x10c
[5.506729]  device_add+0xc0/0x790
[5.510120]  rpmsg_register_device_override+0x10c/0x1c0
[5.515333]  rpmsg_register_device+0x14/0x20
[5.519590]  virtio_rpmsg_create_channel+0xb0/0x104
[5.524452]  rpmsg_create_channel+0x28/0x60
[5.528622]  rpmsg_ns_cb+0x100/0x1dc
[5.532185]  rpmsg_recv_done+0x114/0x2e4
[5.536094]  vring_interrupt+0x68/0xa4
[5.539833]  rproc_vq_interrupt+0x2c/0x48
[5.543830]  k3_r5_rproc_mbox_callback+0x84/0x90 [ti_k3_r5_remoteproc]
[5.550348]  mbox_chan_received_data+0x1c/0x2c
[5.554779]  mbox_interrupt+0xa0/0x17c [omap_mailbox]
[5.559820]  __handle_irq_event_percpu+0x48/0x13c
[5.564511]  handle_irq_event+0x4c/0xac

Andrew


Regards,

Dominic




[PATCH v10 2/8] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-06-10 Thread Andrew Davis
From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/Kconfig   |  13 +
 drivers/remoteproc/Makefile  |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c | 760 +++
 3 files changed, 774 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
 
+config TI_K3_M4_REMOTEPROC
+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
 config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
 obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..880e8f0ad1ba3
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,760 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ */
+struct k3_m4_rproc_dev_data {
+   const struct k3_m4_rproc_mem_data *mems;
+   u32 num_mems;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: number of internal memory regions
+ * @rmem: reserved memory regions data
+ * @num_rmems: number of

[PATCH v10 6/8] arm64: dts: ti: k3-am642-sk: Add M4F remoteproc node

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

The AM64x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed. The first region is used
as a DMA pool for the rproc device, and the second region will furnish
the static carveout regions for the firmware memory.

The current carveout addresses and sizes are defined statically for
each rproc device. The M4F processor does not have an MMU, and as such
requires the exact memory used by the firmware to be set-aside.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am642-sk.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts 
b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 5b028b3a3192f..727d467ed2c1d 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -99,6 +99,18 @@ main_r5fss1_core1_memory_region: r5f-memory@a310 {
no-map;
};
 
+   mcu_m4fss_dma_memory_region: m4f-dma-memory@a400 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0xa400 0x00 0x10>;
+   no-map;
+   };
+
+   mcu_m4fss_memory_region: m4f-memory@a410 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0xa410 0x00 0xf0>;
+   no-map;
+   };
+
rtos_ipc_memory_region: ipc-memories@a500 {
reg = <0x00 0xa500 0x00 0x0080>;
alignment = <0x1000>;
@@ -666,6 +678,13 @@ _r5fss1_core1 {
<_r5fss1_core1_memory_region>;
 };
 
+_m4fss {
+   mboxes = <_cluster6 _m4_0>;
+   memory-region = <_m4fss_dma_memory_region>,
+   <_m4fss_memory_region>;
+   status = "okay";
+};
+
  {
status = "okay";
/* PWM is available on Pin 1 of header J3 */
-- 
2.39.2




[PATCH v10 8/8] arm64: defconfig: Enable TI K3 M4 remoteproc driver

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

Some K3 platform devices (AM64x, AM62x) have a Cortex M4 core. Build
the M4 remote proc driver as a module for these platforms.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 57a9abe78ee41..b7a3488ad4f94 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1369,6 +1369,7 @@ CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_TI_K3_DSP_REMOTEPROC=m
+CONFIG_TI_K3_M4_REMOTEPROC=m
 CONFIG_TI_K3_R5_REMOTEPROC=m
 CONFIG_RPMSG_CHAR=m
 CONFIG_RPMSG_CTRL=m
-- 
2.39.2




[PATCH v10 7/8] arm64: dts: ti: k3-am642-evm: Add M4F remoteproc node

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

The AM64x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed. The first region is used
as a DMA pool for the rproc device, and the second region will furnish
the static carveout regions for the firmware memory.

The current carveout addresses and sizes are defined statically for
each rproc device. The M4F processor does not have an MMU, and as such
requires the exact memory used by the firmware to be set-aside.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts 
b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index e20e4ffd0f1fa..6dbb26a1bc768 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -101,6 +101,18 @@ main_r5fss1_core1_memory_region: r5f-memory@a310 {
no-map;
};
 
+   mcu_m4fss_dma_memory_region: m4f-dma-memory@a400 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0xa400 0x00 0x10>;
+   no-map;
+   };
+
+   mcu_m4fss_memory_region: m4f-memory@a410 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0xa410 0x00 0xf0>;
+   no-map;
+   };
+
rtos_ipc_memory_region: ipc-memories@a500 {
reg = <0x00 0xa500 0x00 0x0080>;
alignment = <0x1000>;
@@ -763,6 +775,13 @@ _r5fss1_core1 {
<_r5fss1_core1_memory_region>;
 };
 
+_m4fss {
+   mboxes = <_cluster6 _m4_0>;
+   memory-region = <_m4fss_dma_memory_region>,
+   <_m4fss_memory_region>;
+   status = "okay";
+};
+
 _ln_ctrl {
idle-states = ;
 };
-- 
2.39.2




[PATCH v10 5/8] arm64: dts: ti: k3-am64: Add M4F remoteproc node

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

The AM64x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed.

Disable by default as this node is not complete until mailbox data
is provided in the board level DT.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi 
b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
index ec17285869da6..b98e8ad453289 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
@@ -160,4 +160,17 @@ mcu_esm: esm@410 {
reg = <0x00 0x410 0x00 0x1000>;
ti,esm-pins = <0>, <1>;
};
+
+   mcu_m4fss: m4fss@500 {
+   compatible = "ti,am64-m4fss";
+   reg = <0x00 0x500 0x00 0x3>,
+ <0x00 0x504 0x00 0x1>;
+   reg-names = "iram", "dram";
+   resets = <_reset 9 1>;
+   firmware-name = "am64-mcu-m4f0_0-fw";
+   ti,sci = <>;
+   ti,sci-dev-id = <9>;
+   ti,sci-proc-ids = <0x18 0xff>;
+   status = "disabled";
+   };
 };
-- 
2.39.2




[PATCH v10 4/8] arm64: dts: ti: k3-am625-sk: Add M4F remoteproc node

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

The AM62x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed. The first region is used
as a DMA pool for the rproc device, and the second region will furnish
the static carveout regions for the firmware memory.

The current carveout addresses and sizes are defined statically for
each rproc device. The M4F processor does not have an MMU, and as such
requires the exact memory used by the firmware to be set-aside.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 3c45782ab2b78..167bec5c80006 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -48,6 +48,18 @@ ramoops@9ca0 {
pmsg-size = <0x8000>;
};
 
+   mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cb0 0x00 0x10>;
+   no-map;
+   };
+
+   mcu_m4fss_memory_region: m4f-memory@9cc0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cc0 0x00 0xe0>;
+   no-map;
+   };
+
secure_tfa_ddr: tfa@9e78 {
reg = <0x00 0x9e78 0x00 0x8>;
alignment = <0x1000>;
@@ -457,6 +469,13 @@ mbox_m4_0: mbox-m4-0 {
};
 };
 
+_m4fss {
+   mboxes = <_cluster0 _m4_0>;
+   memory-region = <_m4fss_dma_memory_region>,
+   <_m4fss_memory_region>;
+   status = "okay";
+};
+
  {
bootph-all;
status = "okay";
-- 
2.39.2




[PATCH v10 0/8] TI K3 M4F support on AM62 and AM64 SoCs

2024-06-10 Thread Andrew Davis
Hello all,

This is the continuation of the M4F RProc support series from here[0].
I'm helping out with the upstream task for Hari and so versions (v8+)
is a little different than the previous(v7-) postings[0]. Most notable
change I've introduced being the patches factoring out common support
from the current K3 R5 and DSP drivers have been dropped. I'd like
to do that re-factor *after* getting this driver in shape, that way
we have 3 similar drivers to factor out from vs trying to make those
changes in parallel with the series adding M4 support.

Anyway, details on our M4F subsystem can be found the
the AM62 TRM in the section on the same:

AM62x Technical Reference Manual (SPRUIV7A – MAY 2022)
https://www.ti.com/lit/pdf/SPRUIV7A

Thanks,
Andrew

[0] 
https://lore.kernel.org/linux-arm-kernel/20240202175538.1705-5-hnaga...@ti.com/T/

Changes for v10:
 - Rebased on v6.10-rc3
 - Added AM64 M4 support in DT
 - Addressed comments by Mathieu from v9

Changes for v9:
 - Fixed reserved-memory.yaml text in [1/5]
 - Split dts patch into one for SoC and one for board enable
 - Corrected DT property order and formatting [4/5][5/5]

Hari Nagalla (7):
  dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
  arm64: dts: ti: k3-am62: Add M4F remoteproc node
  arm64: dts: ti: k3-am625-sk: Add M4F remoteproc node
  arm64: dts: ti: k3-am64: Add M4F remoteproc node
  arm64: dts: ti: k3-am642-sk: Add M4F remoteproc node
  arm64: dts: ti: k3-am642-evm: Add M4F remoteproc node
  arm64: defconfig: Enable TI K3 M4 remoteproc driver

Martyn Welch (1):
  remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 125 +++
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi   |  13 +
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  19 +
 arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi   |  13 +
 arch/arm64/boot/dts/ti/k3-am642-evm.dts   |  19 +
 arch/arm64/boot/dts/ti/k3-am642-sk.dts|  19 +
 arch/arm64/configs/defconfig  |   1 +
 drivers/remoteproc/Kconfig|  13 +
 drivers/remoteproc/Makefile   |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c  | 760 ++
 10 files changed, 983 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

-- 
2.39.2




[PATCH v10 1/8] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage domain.
The remote processor's life cycle management and IPC mechanisms are
similar across the R5F and M4F cores from remote processor driver
point of view. However, there are subtle differences in image loading
and starting the M4F subsystems.

The YAML binding document provides the various node properties to be
configured by the consumers of the M4F subsystem.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
Reviewed-by: Conor Dooley 
---
 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 125 ++
 1 file changed, 125 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml 
b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
new file mode 100644
index 0..2bd0752b6ba9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/ti,k3-m4f-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI K3 M4F processor subsystems
+
+maintainers:
+  - Hari Nagalla 
+  - Mathieu Poirier 
+
+description: |
+  Some K3 family SoCs have Arm Cortex M4F cores. AM64x is a SoC in K3
+  family with a M4F core. Typically safety oriented applications may use
+  the M4F core in isolation without an IPC. Where as some industrial and
+  home automation applications, may use the M4F core as a remote processor
+  with IPC communications.
+
+$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
+
+properties:
+  compatible:
+enum:
+  - ti,am64-m4fss
+
+  power-domains:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 2
+
+  reg:
+items:
+  - description: IRAM internal memory region
+  - description: DRAM internal memory region
+
+  reg-names:
+items:
+  - const: iram
+  - const: dram
+
+  resets:
+maxItems: 1
+
+  firmware-name:
+maxItems: 1
+description: Name of firmware to load for the M4F core
+
+  mboxes:
+description:
+  OMAP Mailbox specifier denoting the sub-mailbox, to be used for
+  communication with the remote processor. This property should match
+  with the sub-mailbox node used in the firmware image.
+maxItems: 1
+
+  memory-region:
+description:
+  phandle to the reserved memory nodes to be associated with the
+  remoteproc device. Optional memory regions available for firmware
+  specific purposes.
+  (see reserved-memory/reserved-memory.yaml in dtschema project)
+maxItems: 8
+items:
+  - description: regions used for DMA allocations like vrings, vring 
buffers
+ and memory dedicated to firmware's specific purposes.
+additionalItems: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - ti,sci
+  - ti,sci-dev-id
+  - ti,sci-proc-ids
+  - resets
+  - firmware-name
+
+unevaluatedProperties: false
+
+examples:
+  - |
+reserved-memory {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cb0 0x00 0x10>;
+no-map;
+};
+
+mcu_m4fss_memory_region: m4f-memory@9cc0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cc0 0x00 0xe0>;
+no-map;
+};
+};
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mailbox0_cluster0: mailbox-0 {
+#mbox-cells = <1>;
+};
+
+remoteproc@500 {
+compatible = "ti,am64-m4fss";
+reg = <0x00 0x500 0x00 0x3>,
+  <0x00 0x504 0x00 0x1>;
+reg-names = "iram", "dram";
+resets = <_reset 9 1>;
+firmware-name = "am62-mcu-m4f0_0-fw";
+mboxes = <_cluster0>, <_m4_0>;
+memory-region = <_m4fss_dma_memory_region>,
+<_m4fss_memory_region>;
+ti,sci = <>;
+ti,sci-dev-id = <9>;
+ti,sci-proc-ids = <0x18 0xff>;
+ };
+};
-- 
2.39.2




[PATCH v10 3/8] arm64: dts: ti: k3-am62: Add M4F remoteproc node

2024-06-10 Thread Andrew Davis
From: Hari Nagalla 

The AM62x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed.

Disable by default as this node is not complete until mailbox data
is provided in the board level DT.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index e66d486ef1f21..7f6f0007e8e81 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -173,4 +173,17 @@ mcu_mcan1: can@4e18000 {
bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
status = "disabled";
};
+
+   mcu_m4fss: m4fss@500 {
+   compatible = "ti,am64-m4fss";
+   reg = <0x00 0x500 0x00 0x3>,
+ <0x00 0x504 0x00 0x1>;
+   reg-names = "iram", "dram";
+   resets = <_reset 9 1>;
+   firmware-name = "am62-mcu-m4f0_0-fw";
+   ti,sci = <>;
+   ti,sci-dev-id = <9>;
+   ti,sci-proc-ids = <0x18 0xff>;
+   status = "disabled";
+   };
 };
-- 
2.39.2




[PATCH 1/6] remoteproc: omap: Use devm_rproc_alloc() helper

2024-06-10 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/omap_remoteproc.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/remoteproc/omap_remoteproc.c 
b/drivers/remoteproc/omap_remoteproc.c
index 8f50ab80e56f4..e91e016583802 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -1305,8 +1305,8 @@ static int omap_rproc_probe(struct platform_device *pdev)
return ret;
}
 
-   rproc = rproc_alloc(>dev, dev_name(>dev), _rproc_ops,
-   firmware, sizeof(*oproc));
+   rproc = devm_rproc_alloc(>dev, dev_name(>dev), 
_rproc_ops,
+firmware, sizeof(*oproc));
if (!rproc)
return -ENOMEM;
 
@@ -1318,15 +1318,15 @@ static int omap_rproc_probe(struct platform_device 
*pdev)
 
ret = omap_rproc_of_get_internal_memories(pdev, rproc);
if (ret)
-   goto free_rproc;
+   return ret;
 
ret = omap_rproc_get_boot_data(pdev, rproc);
if (ret)
-   goto free_rproc;
+   return ret;
 
ret = omap_rproc_of_get_timers(pdev, rproc);
if (ret)
-   goto free_rproc;
+   return ret;
 
init_completion(>pm_comp);
oproc->autosuspend_delay = DEFAULT_AUTOSUSPEND_DELAY;
@@ -1337,10 +1337,8 @@ static int omap_rproc_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(>dev, oproc->autosuspend_delay);
 
oproc->fck = devm_clk_get(>dev, 0);
-   if (IS_ERR(oproc->fck)) {
-   ret = PTR_ERR(oproc->fck);
-   goto free_rproc;
-   }
+   if (IS_ERR(oproc->fck))
+   return PTR_ERR(oproc->fck);
 
ret = of_reserved_mem_device_init(>dev);
if (ret) {
@@ -1359,8 +1357,7 @@ static int omap_rproc_probe(struct platform_device *pdev)
 
 release_mem:
of_reserved_mem_device_release(>dev);
-free_rproc:
-   rproc_free(rproc);
+
return ret;
 }
 
@@ -1369,7 +1366,6 @@ static void omap_rproc_remove(struct platform_device 
*pdev)
struct rproc *rproc = platform_get_drvdata(pdev);
 
rproc_del(rproc);
-   rproc_free(rproc);
of_reserved_mem_device_release(>dev);
 }
 
-- 
2.39.2




[PATCH 4/6] remoteproc: da8xx: Use devm_rproc_alloc() helper

2024-06-10 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/da8xx_remoteproc.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/remoteproc/da8xx_remoteproc.c 
b/drivers/remoteproc/da8xx_remoteproc.c
index 9041a0e07fb25..c8b7576937733 100644
--- a/drivers/remoteproc/da8xx_remoteproc.c
+++ b/drivers/remoteproc/da8xx_remoteproc.c
@@ -295,8 +295,8 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
}
}
 
-   rproc = rproc_alloc(dev, "dsp", _rproc_ops, da8xx_fw_name,
-   sizeof(*drproc));
+   rproc = devm_rproc_alloc(dev, "dsp", _rproc_ops, da8xx_fw_name,
+sizeof(*drproc));
if (!rproc) {
ret = -ENOMEM;
goto free_mem;
@@ -313,7 +313,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
 
ret = da8xx_rproc_get_internal_memories(pdev, drproc);
if (ret)
-   goto free_rproc;
+   goto free_mem;
 
platform_set_drvdata(pdev, rproc);
 
@@ -323,7 +323,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
rproc);
if (ret) {
dev_err(dev, "devm_request_threaded_irq error: %d\n", ret);
-   goto free_rproc;
+   goto free_mem;
}
 
/*
@@ -333,7 +333,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
 */
ret = reset_control_assert(dsp_reset);
if (ret)
-   goto free_rproc;
+   goto free_mem;
 
drproc->chipsig = chipsig;
drproc->bootreg = bootreg;
@@ -344,13 +344,11 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "rproc_add failed: %d\n", ret);
-   goto free_rproc;
+   goto free_mem;
}
 
return 0;
 
-free_rproc:
-   rproc_free(rproc);
 free_mem:
if (dev->of_node)
of_reserved_mem_device_release(dev);
@@ -371,7 +369,6 @@ static void da8xx_rproc_remove(struct platform_device *pdev)
disable_irq(drproc->irq);
 
rproc_del(rproc);
-   rproc_free(rproc);
if (dev->of_node)
of_reserved_mem_device_release(dev);
 }
-- 
2.39.2




[PATCH 2/6] remoteproc: omap: Use devm action to release reserved memory

2024-06-10 Thread Andrew Davis
This helps prevent mistakes like freeing out of order in cleanup functions
and forgetting to free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/omap_remoteproc.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/omap_remoteproc.c 
b/drivers/remoteproc/omap_remoteproc.c
index e91e016583802..df46be84658f7 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -1277,6 +1277,13 @@ static int omap_rproc_of_get_timers(struct 
platform_device *pdev,
return 0;
 }
 
+static void omap_rproc_mem_release(void *data)
+{
+   struct device *dev = data;
+
+   of_reserved_mem_device_release(dev);
+}
+
 static int omap_rproc_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
@@ -1346,19 +1353,17 @@ static int omap_rproc_probe(struct platform_device 
*pdev)
dev_warn(>dev, "Typically this should be provided,\n");
dev_warn(>dev, "only omit if you know what you are 
doing.\n");
}
+   ret = devm_add_action_or_reset(>dev, omap_rproc_mem_release, 
>dev);
+   if (ret)
+   return ret;
 
platform_set_drvdata(pdev, rproc);
 
ret = rproc_add(rproc);
if (ret)
-   goto release_mem;
+   return ret;
 
return 0;
-
-release_mem:
-   of_reserved_mem_device_release(>dev);
-
-   return ret;
 }
 
 static void omap_rproc_remove(struct platform_device *pdev)
@@ -1366,7 +1371,6 @@ static void omap_rproc_remove(struct platform_device 
*pdev)
struct rproc *rproc = platform_get_drvdata(pdev);
 
rproc_del(rproc);
-   of_reserved_mem_device_release(>dev);
 }
 
 static const struct dev_pm_ops omap_rproc_pm_ops = {
-- 
2.39.2




[PATCH 5/6] remoteproc: da8xx: Use devm action to release reserved memory

2024-06-10 Thread Andrew Davis
This helps prevent mistakes like freeing out of order in cleanup functions
and forgetting to free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/da8xx_remoteproc.c | 29 +--
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/remoteproc/da8xx_remoteproc.c 
b/drivers/remoteproc/da8xx_remoteproc.c
index c8b7576937733..1ce91516fc6e5 100644
--- a/drivers/remoteproc/da8xx_remoteproc.c
+++ b/drivers/remoteproc/da8xx_remoteproc.c
@@ -233,6 +233,13 @@ static int da8xx_rproc_get_internal_memories(struct 
platform_device *pdev,
return 0;
 }
 
+static void da8xx_rproc_mem_release(void *data)
+{
+   struct device *dev = data;
+
+   of_reserved_mem_device_release(dev);
+}
+
 static int da8xx_rproc_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -293,14 +300,13 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
ret);
return ret;
}
+   devm_add_action_or_reset(>dev, da8xx_rproc_mem_release, 
>dev);
}
 
rproc = devm_rproc_alloc(dev, "dsp", _rproc_ops, da8xx_fw_name,
 sizeof(*drproc));
-   if (!rproc) {
-   ret = -ENOMEM;
-   goto free_mem;
-   }
+   if (!rproc)
+   return -ENOMEM;
 
/* error recovery is not supported at present */
rproc->recovery_disabled = true;
@@ -313,7 +319,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
 
ret = da8xx_rproc_get_internal_memories(pdev, drproc);
if (ret)
-   goto free_mem;
+   return ret;
 
platform_set_drvdata(pdev, rproc);
 
@@ -323,7 +329,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
rproc);
if (ret) {
dev_err(dev, "devm_request_threaded_irq error: %d\n", ret);
-   goto free_mem;
+   return ret;
}
 
/*
@@ -333,7 +339,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
 */
ret = reset_control_assert(dsp_reset);
if (ret)
-   goto free_mem;
+   return ret;
 
drproc->chipsig = chipsig;
drproc->bootreg = bootreg;
@@ -344,15 +350,10 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "rproc_add failed: %d\n", ret);
-   goto free_mem;
+   return ret;
}
 
return 0;
-
-free_mem:
-   if (dev->of_node)
-   of_reserved_mem_device_release(dev);
-   return ret;
 }
 
 static void da8xx_rproc_remove(struct platform_device *pdev)
@@ -369,8 +370,6 @@ static void da8xx_rproc_remove(struct platform_device *pdev)
disable_irq(drproc->irq);
 
rproc_del(rproc);
-   if (dev->of_node)
-   of_reserved_mem_device_release(dev);
 }
 
 static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = {
-- 
2.39.2




[PATCH 6/6] remoteproc: da8xx: Use devm_rproc_add() helper

2024-06-10 Thread Andrew Davis
Use the device lifecycle managed add function. This helps prevent mistakes
like deleting out of order in cleanup functions and forgetting to delete
on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/da8xx_remoteproc.c | 21 +
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/remoteproc/da8xx_remoteproc.c 
b/drivers/remoteproc/da8xx_remoteproc.c
index 1ce91516fc6e5..c20cf33429da9 100644
--- a/drivers/remoteproc/da8xx_remoteproc.c
+++ b/drivers/remoteproc/da8xx_remoteproc.c
@@ -321,8 +321,6 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   platform_set_drvdata(pdev, rproc);
-
/* everything the ISR needs is now setup, so hook it up */
ret = devm_request_threaded_irq(dev, irq, da8xx_rproc_callback,
handle_event, 0, "da8xx-remoteproc",
@@ -347,7 +345,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
drproc->irq_data = irq_data;
drproc->irq = irq;
 
-   ret = rproc_add(rproc);
+   ret = devm_rproc_add(dev, rproc);
if (ret) {
dev_err(dev, "rproc_add failed: %d\n", ret);
return ret;
@@ -356,22 +354,6 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
return 0;
 }
 
-static void da8xx_rproc_remove(struct platform_device *pdev)
-{
-   struct rproc *rproc = platform_get_drvdata(pdev);
-   struct da8xx_rproc *drproc = rproc->priv;
-   struct device *dev = >dev;
-
-   /*
-* The devm subsystem might end up releasing things before
-* freeing the irq, thus allowing an interrupt to sneak in while
-* the device is being removed.  This should prevent that.
-*/
-   disable_irq(drproc->irq);
-
-   rproc_del(rproc);
-}
-
 static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = {
{ .compatible = "ti,da850-dsp", },
{ /* sentinel */ },
@@ -380,7 +362,6 @@ MODULE_DEVICE_TABLE(of, davinci_rproc_of_match);
 
 static struct platform_driver da8xx_rproc_driver = {
.probe = da8xx_rproc_probe,
-   .remove_new = da8xx_rproc_remove,
.driver = {
.name = "davinci-rproc",
.of_match_table = of_match_ptr(davinci_rproc_of_match),
-- 
2.39.2




[PATCH 3/6] remoteproc: omap: Use devm_rproc_add() helper

2024-06-10 Thread Andrew Davis
Use the device lifecycle managed add function. This helps prevent mistakes
like deleting out of order in cleanup functions and forgetting to delete
on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/omap_remoteproc.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/remoteproc/omap_remoteproc.c 
b/drivers/remoteproc/omap_remoteproc.c
index df46be84658f7..9ae2e831456d5 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -1359,20 +1359,13 @@ static int omap_rproc_probe(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, rproc);
 
-   ret = rproc_add(rproc);
+   ret = devm_rproc_add(>dev, rproc);
if (ret)
return ret;
 
return 0;
 }
 
-static void omap_rproc_remove(struct platform_device *pdev)
-{
-   struct rproc *rproc = platform_get_drvdata(pdev);
-
-   rproc_del(rproc);
-}
-
 static const struct dev_pm_ops omap_rproc_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend, omap_rproc_resume)
SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend,
@@ -1381,7 +1374,6 @@ static const struct dev_pm_ops omap_rproc_pm_ops = {
 
 static struct platform_driver omap_rproc_driver = {
.probe = omap_rproc_probe,
-   .remove_new = omap_rproc_remove,
.driver = {
.name = "omap-rproc",
.pm = _rproc_pm_ops,
-- 
2.39.2




Re: [PATCH v2 2/3] remoteproc: k3-r5: Acquire mailbox handle during probe

2024-06-04 Thread Andrew Davis

On 6/4/24 12:17 AM, Beleswar Padhi wrote:

Acquire the mailbox handle during device probe and do not release handle
in stop/detach routine or error paths. This removes the redundant
requests for mbox handle later during rproc start/attach. This also
allows to defer remoteproc driver's probe if mailbox is not probed yet.

Signed-off-by: Beleswar Padhi 
---
  drivers/remoteproc/ti_k3_r5_remoteproc.c | 74 +---
  1 file changed, 26 insertions(+), 48 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 26362a509ae3c..7e02e3472ce25 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -194,6 +194,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
const char *name = kproc->rproc->name;
u32 msg = omap_mbox_message(data);
  
+	/* Do not forward message to a detached core */


s/to/from

This is the receive side from the core.


+   if (kproc->rproc->state == RPROC_DETACHED)
+   return;
+


Do we need a similar check when sending messages to the core in
k3_r5_rproc_kick()? No one should be sending anything as they
all should have detached at this point, but something to double
check on.


dev_dbg(dev, "mbox msg: 0x%x\n", msg);
  
  	switch (msg) {

@@ -399,12 +403,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
client->knows_txdone = false;
  
  	kproc->mbox = mbox_request_channel(client, 0);

-   if (IS_ERR(kproc->mbox)) {
-   ret = -EBUSY;
-   dev_err(dev, "mbox_request_channel failed: %ld\n",
-   PTR_ERR(kproc->mbox));
-   return ret;
-   }
+   if (IS_ERR(kproc->mbox))
+   return dev_err_probe(dev, PTR_ERR(kproc->mbox),
+"mbox_request_channel failed\n");


This is good cleanup, but maybe something for its own patch.

  
  	/*

 * Ping the remote processor, this is only for sanity-sake for now;
@@ -552,10 +553,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
  
-	ret = k3_r5_rproc_request_mbox(rproc);

-   if (ret)
-   return ret;
-
boot_addr = rproc->bootaddr;
/* TODO: add boot_addr sanity checking */
dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
@@ -564,7 +561,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
core = kproc->core;
ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
if (ret)
-   goto put_mbox;
+   return ret;
  
  	/* unhalt/run all applicable cores */

if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
@@ -580,13 +577,12 @@ static int k3_r5_rproc_start(struct rproc *rproc)
if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
dev_err(dev, "%s: can not start core 1 before core 0\n",
__func__);
-   ret = -EPERM;
-   goto put_mbox;
+   return -EPERM;
}
  
  		ret = k3_r5_core_run(core);

if (ret)
-   goto put_mbox;
+   return ret;
}
  
  	return 0;

@@ -596,8 +592,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
if (k3_r5_core_halt(core))
dev_warn(core->dev, "core halt back failed\n");
}
-put_mbox:
-   mbox_free_channel(kproc->mbox);
return ret;
  }
  
@@ -658,8 +652,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)

goto out;
}
  
-	mbox_free_channel(kproc->mbox);

-
return 0;
  
  unroll_core_halt:

@@ -674,42 +666,22 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  /*
   * Attach to a running R5F remote processor (IPC-only mode)
   *
- * The R5F attach callback only needs to request the mailbox, the remote
- * processor is already booted, so there is no need to issue any TI-SCI
- * commands to boot the R5F cores in IPC-only mode. This callback is invoked
- * only in IPC-only mode.
+ * The R5F attach callback is a NOP. The remote processor is already booted, 
and
+ * all required resources have been acquired during probe routine, so there is
+ * no need to issue any TI-SCI commands to boot the R5F cores in IPC-only mode.
+ * This callback is invoked only in IPC-only mode and exists because
+ * rproc_validate() checks for its existence.
   */
-static int k3_r5_rproc_attach(struct rproc *rproc)
-{
-   struct k3_r5_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-   int ret;
-
-   ret = k3_r5_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
-   dev_info(dev, "R5F core initialized in IPC-only mode\n");
-   return 0;
-}
+static int k3_r5_rproc_attach(struct rproc *rproc) { return 0; }


I 

Re: [PATCH 2/3] remoteproc: k3-r5: Acquire mailbox handle during probe

2024-05-30 Thread Andrew Davis

On 5/30/24 4:07 AM, Beleswar Padhi wrote:

Acquire the mailbox handle during device probe and do not release handle
in stop/detach routine or error paths. This removes the redundant
requests for mbox handle later during rproc start/attach. This also
allows to defer remoteproc driver's probe if mailbox is not probed yet.

Signed-off-by: Beleswar Padhi 
---
  drivers/remoteproc/ti_k3_r5_remoteproc.c | 66 
  1 file changed, 21 insertions(+), 45 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 26362a509ae3..157e8fd57665 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -391,6 +391,7 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
struct mbox_client *client = >client;
struct device *dev = kproc->dev;
int ret;
+   long err;
  
  	client->dev = dev;

client->tx_done = NULL;
@@ -400,10 +401,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
  
  	kproc->mbox = mbox_request_channel(client, 0);

if (IS_ERR(kproc->mbox)) {
-   ret = -EBUSY;
-   dev_err(dev, "mbox_request_channel failed: %ld\n",
-   PTR_ERR(kproc->mbox));
-   return ret;
+   err = PTR_ERR(kproc->mbox);
+   dev_err(dev, "mbox_request_channel failed: %ld\n", err);
+   return (err == -EPROBE_DEFER) ? -EPROBE_DEFER : -EBUSY;


Why turn all other errors into EBUSY? If you just return the error as-is you
can simply make these 3 lines just:

return dev_err_probe(dev, PTR_ERR(kproc->mbox), "mbox_request_channel 
failed\n");


}
  
  	/*

@@ -552,10 +552,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
  
-	ret = k3_r5_rproc_request_mbox(rproc);

-   if (ret)
-   return ret;
-
boot_addr = rproc->bootaddr;
/* TODO: add boot_addr sanity checking */
dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
@@ -564,7 +560,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
core = kproc->core;
ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
if (ret)
-   goto put_mbox;
+   goto out;


The label "out" doesn't do anything, just directly `return ret;` here and
in the other cases below.

  
  	/* unhalt/run all applicable cores */

if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
@@ -581,12 +577,12 @@ static int k3_r5_rproc_start(struct rproc *rproc)
dev_err(dev, "%s: can not start core 1 before core 0\n",
__func__);
ret = -EPERM;
-   goto put_mbox;
+   goto out;
}
  
  		ret = k3_r5_core_run(core);

if (ret)
-   goto put_mbox;
+   goto out;
}
  
  	return 0;

@@ -596,8 +592,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
if (k3_r5_core_halt(core))
dev_warn(core->dev, "core halt back failed\n");
}
-put_mbox:
-   mbox_free_channel(kproc->mbox);
+out:
return ret;
  }
  
@@ -658,8 +653,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)

goto out;
}
  
-	mbox_free_channel(kproc->mbox);

-
return 0;
  
  unroll_core_halt:

@@ -674,42 +667,21 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  /*
   * Attach to a running R5F remote processor (IPC-only mode)
   *
- * The R5F attach callback only needs to request the mailbox, the remote
- * processor is already booted, so there is no need to issue any TI-SCI
- * commands to boot the R5F cores in IPC-only mode. This callback is invoked
- * only in IPC-only mode.
+ * The R5F attach callback is a NOP. The remote processor is already booted, 
and
+ * all required resources have been acquired during probe routine, so there is
+ * no need to issue any TI-SCI commands to boot the R5F cores in IPC-only mode.
+ * This callback is invoked only in IPC-only mode and exists for sanity sake.
   */
-static int k3_r5_rproc_attach(struct rproc *rproc)
-{
-   struct k3_r5_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-   int ret;
-
-   ret = k3_r5_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
-   dev_info(dev, "R5F core initialized in IPC-only mode\n");
-   return 0;
-}
+static int k3_r5_rproc_attach(struct rproc *rproc) { return 0; }
  
  /*

   * Detach from a running R5F remote processor (IPC-only mode)
   *
- * The R5F detach callback performs the opposite operation to attach callback
- * and only needs to release the mailbox, the R5F cores are not stopped and
- * will be left in booted state in IPC-only mode. This callback is invoked
- * only in IPC-only mode.
+ * The R5F detach callback is a 

Re: [PATCH v9 2/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-05-09 Thread Andrew Davis

On 5/9/24 10:32 AM, Mathieu Poirier wrote:

On Wed, 8 May 2024 at 10:54, Andrew Davis  wrote:


On 5/7/24 3:36 PM, Mathieu Poirier wrote:

On Fri, Apr 26, 2024 at 02:18:08PM -0500, Andrew Davis wrote:

From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
   drivers/remoteproc/Kconfig   |  13 +
   drivers/remoteproc/Makefile  |   1 +
   drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
   3 files changed, 799 insertions(+)
   create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
It's safe to say N here if you're not interested in utilizing
the DSP slave processors.

+config TI_K3_M4_REMOTEPROC
+tristate "TI K3 M4 remoteproc support"
+depends on ARCH_K3 || COMPILE_TEST
+select MAILBOX
+select OMAP2PLUS_MBOX
+help
+  Say m here to support TI's M4 remote processor subsystems
+  on various TI K3 family of SoCs through the remote processor
+  framework.
+
+  It's safe to say N here if you're not interested in utilizing
+  a remote processor.
+
   config TI_K3_R5_REMOTEPROC
  tristate "TI K3 R5 remoteproc support"
  depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)+= st_remoteproc.o
   obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
   obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
   obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)   += ti_k3_m4_remoteproc.o
   obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
   obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *  Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+void __iomem *cpu_addr;
+phys_addr_t bus_addr;
+u32 dev_addr;
+size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+const char *name;
+const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_rproc_dev_data {
+const struct k3_m4_rproc_mem_data *mems;
+u32 num_mems;
+bool uses_lreset;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver st

Re: [PATCH v9 2/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-05-09 Thread Andrew Davis

On 5/9/24 10:22 AM, Mathieu Poirier wrote:

On Wed, 8 May 2024 at 09:36, Andrew Davis  wrote:


On 5/6/24 3:46 PM, Mathieu Poirier wrote:

Good day,

I have started reviewing this patchset.  Comments will be scattered over
multiple days and as such, I will explicitly inform you when  am done with the
review.

On Fri, Apr 26, 2024 at 02:18:08PM -0500, Andrew Davis wrote:

From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
   drivers/remoteproc/Kconfig   |  13 +
   drivers/remoteproc/Makefile  |   1 +
   drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
   3 files changed, 799 insertions(+)
   create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
It's safe to say N here if you're not interested in utilizing
the DSP slave processors.

+config TI_K3_M4_REMOTEPROC
+tristate "TI K3 M4 remoteproc support"
+depends on ARCH_K3 || COMPILE_TEST
+select MAILBOX
+select OMAP2PLUS_MBOX
+help
+  Say m here to support TI's M4 remote processor subsystems
+  on various TI K3 family of SoCs through the remote processor
+  framework.
+
+  It's safe to say N here if you're not interested in utilizing
+  a remote processor.
+
   config TI_K3_R5_REMOTEPROC
  tristate "TI K3 R5 remoteproc support"
  depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)+= st_remoteproc.o
   obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
   obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
   obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)   += ti_k3_m4_remoteproc.o
   obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
   obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *  Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+void __iomem *cpu_addr;
+phys_addr_t bus_addr;
+u32 dev_addr;
+size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+const char *name;
+const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ *

Re: [PATCH v9 2/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-05-08 Thread Andrew Davis

On 5/7/24 3:36 PM, Mathieu Poirier wrote:

On Fri, Apr 26, 2024 at 02:18:08PM -0500, Andrew Davis wrote:

From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
  drivers/remoteproc/Kconfig   |  13 +
  drivers/remoteproc/Makefile  |   1 +
  drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
  3 files changed, 799 insertions(+)
  create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
  
+config TI_K3_M4_REMOTEPROC

+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
  config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
  obj-$(CONFIG_ST_SLIM_REMOTEPROC)  += st_slim_rproc.o
  obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
  obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)+= ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
  obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
  obj-$(CONFIG_XLNX_R5_REMOTEPROC)  += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_rproc_dev_data {
+   const struct k3_m4_rproc_mem_data *mems;
+   u32 num_mems;
+   bool uses_lreset;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver structure
+ * @dev: c

Re: [PATCH v9 2/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-05-08 Thread Andrew Davis

On 5/6/24 3:46 PM, Mathieu Poirier wrote:

Good day,

I have started reviewing this patchset.  Comments will be scattered over
multiple days and as such, I will explicitly inform you when  am done with the
review.

On Fri, Apr 26, 2024 at 02:18:08PM -0500, Andrew Davis wrote:

From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
  drivers/remoteproc/Kconfig   |  13 +
  drivers/remoteproc/Makefile  |   1 +
  drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
  3 files changed, 799 insertions(+)
  create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
  
+config TI_K3_M4_REMOTEPROC

+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
  config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
  obj-$(CONFIG_ST_SLIM_REMOTEPROC)  += st_slim_rproc.o
  obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
  obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)+= ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
  obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
  obj-$(CONFIG_XLNX_R5_REMOTEPROC)  += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_rproc_dev_data {
+   co

[PATCH v9 2/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-04-26 Thread Andrew Davis
From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/Kconfig   |  13 +
 drivers/remoteproc/Makefile  |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
 3 files changed, 799 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
 
+config TI_K3_M4_REMOTEPROC
+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
 config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
 obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_rproc_dev_data {
+   const struct k3_m4_rproc_mem_data *mems;
+   u32 num_mems;
+   bool uses_lreset;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: num

[PATCH v9 0/5] TI K3 M4F support on AM62 SoCs

2024-04-26 Thread Andrew Davis
Hello all,

This is the continuation of the M4F RProc support series from here[0].
I'm helping out with the upstream task for Hari and so this version(v8)
is a little different than the previous(v7) postings[0]. Most notable
change I've introduced being the patches factoring out common support
from the current K3 R5 and DSP drivers have been dropped. I'd like
to do that re-factor *after* getting this driver in shape, that way
we have 3 similar drivers to factor out from vs trying to make those
changes in parallel with the series adding M4 support.

Anyway, details on our M4F subsystem can be found the
the AM62 TRM in the section on the same:

AM62x Technical Reference Manual (SPRUIV7A – MAY 2022)
https://www.ti.com/lit/pdf/SPRUIV7A

Thanks,
Andrew

[0] 
https://lore.kernel.org/linux-arm-kernel/20240202175538.1705-5-hnaga...@ti.com/T/

Changes for v9:
 - Fixed reserved-memory.yaml text in [1/5]
 - Split dts patch into one for SoC and one for board enable
 - Corrected DT property order and formatting [4/5][5/5]

Hari Nagalla (4):
  dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
  arm64: dts: ti: k3-am62: Add M4F remoteproc node
  arm64: dts: ti: k3-am625-sk: Add M4F remoteproc node
  arm64: defconfig: Enable TI K3 M4 remoteproc driver

Martyn Welch (1):
  remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 125 +++
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi   |  13 +
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  19 +
 arch/arm64/configs/defconfig  |   1 +
 drivers/remoteproc/Kconfig|  13 +
 drivers/remoteproc/Makefile   |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c  | 785 ++
 7 files changed, 957 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

-- 
2.39.2




[PATCH v9 3/5] arm64: dts: ti: k3-am62: Add M4F remoteproc node

2024-04-26 Thread Andrew Davis
From: Hari Nagalla 

The AM62x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed.

Disable by default as this node is not complete until mailbox data
is provided in the board level DT.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index e66d486ef1f21..7f6f0007e8e81 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -173,4 +173,17 @@ mcu_mcan1: can@4e18000 {
bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
status = "disabled";
};
+
+   mcu_m4fss: m4fss@500 {
+   compatible = "ti,am64-m4fss";
+   reg = <0x00 0x500 0x00 0x3>,
+ <0x00 0x504 0x00 0x1>;
+   reg-names = "iram", "dram";
+   resets = <_reset 9 1>;
+   firmware-name = "am62-mcu-m4f0_0-fw";
+   ti,sci = <>;
+   ti,sci-dev-id = <9>;
+   ti,sci-proc-ids = <0x18 0xff>;
+   status = "disabled";
+   };
 };
-- 
2.39.2




[PATCH v9 5/5] arm64: defconfig: Enable TI K3 M4 remoteproc driver

2024-04-26 Thread Andrew Davis
From: Hari Nagalla 

Some K3 platform devices (AM64x, AM62x) have a Cortex M4 core. Build
the M4 remote proc driver as a module for these platforms.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2c30d617e1802..04e8e2ca4aa10 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1352,6 +1352,7 @@ CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_TI_K3_DSP_REMOTEPROC=m
+CONFIG_TI_K3_M4_REMOTEPROC=m
 CONFIG_TI_K3_R5_REMOTEPROC=m
 CONFIG_RPMSG_CHAR=m
 CONFIG_RPMSG_CTRL=m
-- 
2.39.2




[PATCH v9 1/5] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs

2024-04-26 Thread Andrew Davis
From: Hari Nagalla 

K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage domain.
The remote processor's life cycle management and IPC mechanisms are
similar across the R5F and M4F cores from remote processor driver
point of view. However, there are subtle differences in image loading
and starting the M4F subsystems.

The YAML binding document provides the various node properties to be
configured by the consumers of the M4F subsystem.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
Reviewed-by: Conor Dooley 
---
 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 125 ++
 1 file changed, 125 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml 
b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
new file mode 100644
index 0..2bd0752b6ba9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/ti,k3-m4f-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI K3 M4F processor subsystems
+
+maintainers:
+  - Hari Nagalla 
+  - Mathieu Poirier 
+
+description: |
+  Some K3 family SoCs have Arm Cortex M4F cores. AM64x is a SoC in K3
+  family with a M4F core. Typically safety oriented applications may use
+  the M4F core in isolation without an IPC. Where as some industrial and
+  home automation applications, may use the M4F core as a remote processor
+  with IPC communications.
+
+$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
+
+properties:
+  compatible:
+enum:
+  - ti,am64-m4fss
+
+  power-domains:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 2
+
+  reg:
+items:
+  - description: IRAM internal memory region
+  - description: DRAM internal memory region
+
+  reg-names:
+items:
+  - const: iram
+  - const: dram
+
+  resets:
+maxItems: 1
+
+  firmware-name:
+maxItems: 1
+description: Name of firmware to load for the M4F core
+
+  mboxes:
+description:
+  OMAP Mailbox specifier denoting the sub-mailbox, to be used for
+  communication with the remote processor. This property should match
+  with the sub-mailbox node used in the firmware image.
+maxItems: 1
+
+  memory-region:
+description:
+  phandle to the reserved memory nodes to be associated with the
+  remoteproc device. Optional memory regions available for firmware
+  specific purposes.
+  (see reserved-memory/reserved-memory.yaml in dtschema project)
+maxItems: 8
+items:
+  - description: regions used for DMA allocations like vrings, vring 
buffers
+ and memory dedicated to firmware's specific purposes.
+additionalItems: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - ti,sci
+  - ti,sci-dev-id
+  - ti,sci-proc-ids
+  - resets
+  - firmware-name
+
+unevaluatedProperties: false
+
+examples:
+  - |
+reserved-memory {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cb0 0x00 0x10>;
+no-map;
+};
+
+mcu_m4fss_memory_region: m4f-memory@9cc0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cc0 0x00 0xe0>;
+no-map;
+};
+};
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mailbox0_cluster0: mailbox-0 {
+#mbox-cells = <1>;
+};
+
+remoteproc@500 {
+compatible = "ti,am64-m4fss";
+reg = <0x00 0x500 0x00 0x3>,
+  <0x00 0x504 0x00 0x1>;
+reg-names = "iram", "dram";
+resets = <_reset 9 1>;
+firmware-name = "am62-mcu-m4f0_0-fw";
+mboxes = <_cluster0>, <_m4_0>;
+memory-region = <_m4fss_dma_memory_region>,
+<_m4fss_memory_region>;
+ti,sci = <>;
+ti,sci-dev-id = <9>;
+ti,sci-proc-ids = <0x18 0xff>;
+ };
+};
-- 
2.39.2




[PATCH v9 4/5] arm64: dts: ti: k3-am625-sk: Add M4F remoteproc node

2024-04-26 Thread Andrew Davis
From: Hari Nagalla 

The AM62x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed. The first region is used
as a DMA pool for the rproc device, and the second region will furnish
the static carveout regions for the firmware memory.

The current carveout addresses and sizes are defined statically for
each rproc device. The M4F processor does not have an MMU, and as such
requires the exact memory used by the firmware to be set-aside.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 3c45782ab2b78..167bec5c80006 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -48,6 +48,18 @@ ramoops@9ca0 {
pmsg-size = <0x8000>;
};
 
+   mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cb0 0x00 0x10>;
+   no-map;
+   };
+
+   mcu_m4fss_memory_region: m4f-memory@9cc0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cc0 0x00 0xe0>;
+   no-map;
+   };
+
secure_tfa_ddr: tfa@9e78 {
reg = <0x00 0x9e78 0x00 0x8>;
alignment = <0x1000>;
@@ -457,6 +469,13 @@ mbox_m4_0: mbox-m4-0 {
};
 };
 
+_m4fss {
+   mboxes = <_cluster0 _m4_0>;
+   memory-region = <_m4fss_dma_memory_region>,
+   <_m4fss_memory_region>;
+   status = "okay";
+};
+
  {
bootph-all;
status = "okay";
-- 
2.39.2




Re: [PATCH v8 1/4] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs

2024-04-25 Thread Andrew Davis

On 4/25/24 12:15 PM, Conor Dooley wrote:

On Wed, Apr 24, 2024 at 03:36:39PM -0500, Rob Herring wrote:


On Wed, 24 Apr 2024 14:06:09 -0500, Andrew Davis wrote:

From: Hari Nagalla 

K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage domain.
The remote processor's life cycle management and IPC mechanisms are
similar across the R5F and M4F cores from remote processor driver
point of view. However, there are subtle differences in image loading
and starting the M4F subsystems.

The YAML binding document provides the various node properties to be
configured by the consumers of the M4F subsystem.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
  .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 126 ++
  1 file changed, 126 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml



My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:


doc reference errors (make refcheckdocs):
Warning: Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml 
references a file that doesn't exist: 
Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml: 
Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml


The file is now in dt-schema:
https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/reserved-memory/reserved-memory.yaml


So should I use "reserved-memory/reserved-memory.yaml" here, or just
drop this line completely?

Andrew



[PATCH v8 2/4] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

2024-04-24 Thread Andrew Davis
From: Martyn Welch 

The AM62x and AM64x SoCs of the TI K3 family has a Cortex M4F core in
the MCU domain. This core is typically used for safety applications in a
stand alone mode. However, some application (non safety related) may
want to use the M4F core as a generic remote processor with IPC to the
host processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs for external contiguous memory is defined in the M4F device
node and should match with the external memory declarations in the M4F
image binary. The M4F subsystem has two resets. One reset is for the
entire subsystem i.e including the internal memories and the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/Kconfig   |  13 +
 drivers/remoteproc/Makefile  |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c | 785 +++
 3 files changed, 799 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa852..1a7c0330c91a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
  It's safe to say N here if you're not interested in utilizing
  the DSP slave processors.
 
+config TI_K3_M4_REMOTEPROC
+   tristate "TI K3 M4 remoteproc support"
+   depends on ARCH_K3 || COMPILE_TEST
+   select MAILBOX
+   select OMAP2PLUS_MBOX
+   help
+ Say m here to support TI's M4 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+ It's safe to say N here if you're not interested in utilizing
+ a remote processor.
+
 config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43cef..5ff4e2fee4abd 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
 obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)  += ti_k3_m4_remoteproc.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c 
b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 0..0030e509f6b5d
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Hari Nagalla 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+/**
+ * struct k3_m4_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_m4_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_rproc_dev_data {
+   const struct k3_m4_rproc_mem_data *mems;
+   u32 num_mems;
+   bool uses_lreset;
+};
+
+/**
+ * struct k3_m4_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: num

[PATCH v8 4/4] arm64: dts: ti: k3-am62: Add M4F remoteproc node

2024-04-24 Thread Andrew Davis
From: Hari Nagalla 

The AM62x SoCs of the TI K3 family have a Cortex M4F core in the MCU
domain. This core can be used by non safety applications as a remote
processor. When used as a remote processor with virtio/rpmessage IPC,
two carveout reserved memory nodes are needed. The first region is used
as a DMA pool for the rproc device, and the second region will furnish
the static carveout regions for the firmware memory.

The current carveout addresses and sizes are defined statically for
each rproc device. The M4F processor do not have an MMU, and as such
require the exact memory used by the firmware to be set-aside.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi| 12 
 arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 18 ++
 2 files changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index e66d486ef1f21..0c6ee801f35fc 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -173,4 +173,16 @@ mcu_mcan1: can@4e18000 {
bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
status = "disabled";
};
+
+   mcu_m4fss: m4fss@500 {
+   compatible = "ti,am64-m4fss";
+   reg = <0x00 0x500 0x00 0x3>,
+   <0x00 0x504 0x00 0x1>;
+   reg-names = "iram", "dram";
+   ti,sci = <>;
+   ti,sci-dev-id = <9>;
+   ti,sci-proc-ids = <0x18 0xff>;
+   resets = <_reset 9 1>;
+   firmware-name = "am62-mcu-m4f0_0-fw";
+   };
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi 
b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 3c45782ab2b78..bda9fb2e33eec 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -48,6 +48,18 @@ ramoops@9ca0 {
pmsg-size = <0x8000>;
};
 
+   mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cb0 0x00 0x10>;
+   no-map;
+   };
+
+   mcu_m4fss_memory_region: m4f-memory@9cc0 {
+   compatible = "shared-dma-pool";
+   reg = <0x00 0x9cc0 0x00 0xe0>;
+   no-map;
+   };
+
secure_tfa_ddr: tfa@9e78 {
reg = <0x00 0x9e78 0x00 0x8>;
alignment = <0x1000>;
@@ -457,6 +469,12 @@ mbox_m4_0: mbox-m4-0 {
};
 };
 
+_m4fss {
+   mboxes = <_cluster0>, <_m4_0>;
+   memory-region = <_m4fss_dma_memory_region>,
+   <_m4fss_memory_region>;
+};
+
  {
bootph-all;
status = "okay";
-- 
2.39.2




[PATCH v8 0/4] TI K3 M4F support on AM62 SoCs

2024-04-24 Thread Andrew Davis
Hello all,

This is the continuation of the M4F RProc support series from here[0].
I'm helping out with the upstream task for Hari and so this version(v8)
is a little different than the previous(v7) postings[0]. Most notable
change I've introduced being the patches factoring out common support
from the current K3 R5 and DSP drivers have been dropped. I'd like
to do that re-factor *after* getting this driver in shape, that way
we have 3 similar drivers to factor out from vs trying to make those
changes in parallel with the series adding M4 support.

Anyway, details on our M4F subsystem can be found the
the AM62 TRM in the section on the same:

AM62x Technical Reference Manual (SPRUIV7A – MAY 2022)
https://www.ti.com/lit/pdf/SPRUIV7A

Thanks,
Andrew

[0] 
https://lore.kernel.org/linux-arm-kernel/20240202175538.1705-5-hnaga...@ti.com/T/

Hari Nagalla (3):
  dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
  arm64: defconfig: Enable TI K3 M4 remoteproc driver
  arm64: dts: ti: k3-am62: Add M4F remoteproc node

Martyn Welch (1):
  remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 126 +++
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi   |  12 +
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  18 +
 arch/arm64/configs/defconfig  |   1 +
 drivers/remoteproc/Kconfig|  13 +
 drivers/remoteproc/Makefile   |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c  | 785 ++
 7 files changed, 956 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

-- 
2.39.2




[PATCH v8 3/4] arm64: defconfig: Enable TI K3 M4 remoteproc driver

2024-04-24 Thread Andrew Davis
From: Hari Nagalla 

Some K3 platform devices (AM64x, AM62x) have a Cortex M4 core. Build
the M4 remote proc driver as a module for these platforms.

Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2c30d617e1802..04e8e2ca4aa10 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1352,6 +1352,7 @@ CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_TI_K3_DSP_REMOTEPROC=m
+CONFIG_TI_K3_M4_REMOTEPROC=m
 CONFIG_TI_K3_R5_REMOTEPROC=m
 CONFIG_RPMSG_CHAR=m
 CONFIG_RPMSG_CTRL=m
-- 
2.39.2




[PATCH v8 1/4] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs

2024-04-24 Thread Andrew Davis
From: Hari Nagalla 

K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage domain.
The remote processor's life cycle management and IPC mechanisms are
similar across the R5F and M4F cores from remote processor driver
point of view. However, there are subtle differences in image loading
and starting the M4F subsystems.

The YAML binding document provides the various node properties to be
configured by the consumers of the M4F subsystem.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
Signed-off-by: Andrew Davis 
---
 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 126 ++
 1 file changed, 126 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml 
b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
new file mode 100644
index 0..3629ddd6efa8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/ti,k3-m4f-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI K3 M4F processor subsystems
+
+maintainers:
+  - Hari Nagalla 
+  - Mathieu Poirier 
+
+description: |
+  Some K3 family SoCs have Arm Cortex M4F cores. AM64x is a SoC in K3
+  family with a M4F core. Typically safety oriented applications may use
+  the M4F core in isolation without an IPC. Where as some industrial and
+  home automation applications, may use the M4F core as a remote processor
+  with IPC communications.
+
+$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
+
+properties:
+  compatible:
+enum:
+  - ti,am64-m4fss
+
+  power-domains:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 2
+
+  reg:
+items:
+  - description: IRAM internal memory region
+  - description: DRAM internal memory region
+
+  reg-names:
+items:
+  - const: iram
+  - const: dram
+
+  resets:
+maxItems: 1
+
+  firmware-name:
+maxItems: 1
+description: Name of firmware to load for the M4F core
+
+  mboxes:
+description: |
+  OMAP Mailbox specifier denoting the sub-mailbox, to be used for
+  communication with the remote processor. This property should match
+  with the sub-mailbox node used in the firmware image.
+maxItems: 1
+
+  memory-region:
+description: |
+  phandle to the reserved memory nodes to be associated with the
+  remoteproc device. The reserved memory nodes should be carveout nodes,
+  and should be defined with a "no-map" property as per the bindings in
+  Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml
+  Optional memory regions available for firmware specific purposes.
+maxItems: 8
+items:
+  - description: regions used for DMA allocations like vrings, vring 
buffers
+ and memory dedicated to firmware's specific purposes.
+additionalItems: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - ti,sci
+  - ti,sci-dev-id
+  - ti,sci-proc-ids
+  - resets
+  - firmware-name
+
+unevaluatedProperties: false
+
+examples:
+  - |
+reserved-memory {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cb0 0x00 0x10>;
+no-map;
+};
+
+mcu_m4fss_memory_region: m4f-memory@9cc0 {
+compatible = "shared-dma-pool";
+reg = <0x00 0x9cc0 0x00 0xe0>;
+no-map;
+};
+};
+
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+mailbox0_cluster0: mailbox-0 {
+#mbox-cells = <1>;
+};
+
+remoteproc@500 {
+compatible = "ti,am64-m4fss";
+reg = <0x00 0x500 0x00 0x3>,
+  <0x00 0x504 0x00 0x1>;
+reg-names = "iram", "dram";
+ti,sci = <>;
+ti,sci-dev-id = <9>;
+ti,sci-proc-ids = <0x18 0xff>;
+resets = <_reset 9 1>;
+firmware-name = "am62-mcu-m4f0_0-fw";
+mboxes = <_cluster0>, <_m4_0>;
+memory-region = <_m4fss_dma_memory_region>,
+<_m4fss_memory_region>;
+ };
+};
-- 
2.39.2




[PATCH v2 09/13] mailbox: omap: Use function local struct mbox_controller

2024-04-10 Thread Andrew Davis
The mbox_controller struct is only needed in the probe function. Make
it a local variable instead of storing a copy in omap_mbox_device
to simplify that struct.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 17c9b9df78b1d..97f59d9f9f319 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -86,7 +86,6 @@ struct omap_mbox_device {
u32 num_fifos;
u32 intr_type;
struct omap_mbox **mboxes;
-   struct mbox_controller controller;
 };
 
 struct omap_mbox {
@@ -541,7 +540,7 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
struct omap_mbox_device *mdev;
struct omap_mbox *mbox;
 
-   mdev = container_of(controller, struct omap_mbox_device, controller);
+   mdev = dev_get_drvdata(controller->dev);
if (WARN_ON(!mdev))
return ERR_PTR(-EINVAL);
 
@@ -567,6 +566,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct device_node *child;
const struct omap_mbox_match_data *match_data;
+   struct mbox_controller *controller;
u32 intr_type, info_count;
u32 num_users, num_fifos;
u32 tmp[3];
@@ -685,17 +685,20 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->intr_type = intr_type;
mdev->mboxes = list;
 
+   controller = devm_kzalloc(>dev, sizeof(*controller), GFP_KERNEL);
+   if (!controller)
+   return -ENOMEM;
/*
 * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
 * IRQ and is needed to run the Tx state machine
 */
-   mdev->controller.txdone_irq = true;
-   mdev->controller.dev = mdev->dev;
-   mdev->controller.ops = _mbox_chan_ops;
-   mdev->controller.chans = chnls;
-   mdev->controller.num_chans = info_count;
-   mdev->controller.of_xlate = omap_mbox_of_xlate;
-   ret = devm_mbox_controller_register(mdev->dev, >controller);
+   controller->txdone_irq = true;
+   controller->dev = mdev->dev;
+   controller->ops = _mbox_chan_ops;
+   controller->chans = chnls;
+   controller->num_chans = info_count;
+   controller->of_xlate = omap_mbox_of_xlate;
+   ret = devm_mbox_controller_register(mdev->dev, controller);
if (ret)
return ret;
 
-- 
2.39.2




[PATCH v2 11/13] mailbox: omap: Remove mbox_chan_to_omap_mbox()

2024-04-10 Thread Andrew Davis
This function only checks if mbox_chan *chan is not NULL, but that cannot
be the case and if it was returning NULL which is not later checked
doesn't save us from this. The second check for chan->con_priv is
completely redundant as if it was NULL we would return NULL just the
same. Simply dereference con_priv directly and remove this function.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8e42266cb31a5..8e2760d2c5b0c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -103,14 +103,6 @@ static unsigned int mbox_kfifo_size = 
CONFIG_OMAP_MBOX_KFIFO_SIZE;
 module_param(mbox_kfifo_size, uint, S_IRUGO);
 MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
 
-static struct omap_mbox *mbox_chan_to_omap_mbox(struct mbox_chan *chan)
-{
-   if (!chan || !chan->con_priv)
-   return NULL;
-
-   return (struct omap_mbox *)chan->con_priv;
-}
-
 static inline
 unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
 {
@@ -357,7 +349,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
 
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
int ret = 0;
 
@@ -372,7 +364,7 @@ static int omap_mbox_chan_startup(struct mbox_chan *chan)
 
 static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
 
mutex_lock(>cfg_lock);
@@ -415,7 +407,7 @@ static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 
msg)
 
 static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
int ret;
u32 msg = (u32)(uintptr_t)(data);
 
-- 
2.39.2




[PATCH v2 05/13] mailbox: omap: Remove unneeded header omap-mailbox.h

2024-04-10 Thread Andrew Davis
The type of message sent using omap-mailbox is always u32. The definition
of mbox_msg_t is uintptr_t which is wrong as that type changes based on
the architecture (32bit vs 64bit). This type should have been defined as
u32. Instead of making that change here, simply remove the header usage
and fix the last couple users of the same in this driver.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 167348fb1b33b..4c673cb732ed1 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -239,16 +238,14 @@ static void mbox_rx_work(struct work_struct *work)
 {
struct omap_mbox_queue *mq =
container_of(work, struct omap_mbox_queue, work);
-   mbox_msg_t data;
u32 msg;
int len;
 
while (kfifo_len(>fifo) >= sizeof(msg)) {
len = kfifo_out(>fifo, (unsigned char *), sizeof(msg));
WARN_ON(len != sizeof(msg));
-   data = msg;
 
-   mbox_chan_received_data(mq->mbox->chan, (void *)data);
+   mbox_chan_received_data(mq->mbox->chan, (void *)(uintptr_t)msg);
spin_lock_irq(>lock);
if (mq->full) {
mq->full = false;
@@ -515,7 +512,7 @@ static int omap_mbox_chan_send_data(struct mbox_chan *chan, 
void *data)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
int ret;
-   u32 msg = omap_mbox_message(data);
+   u32 msg = (u32)(uintptr_t)(data);
 
if (!mbox)
return -EINVAL;
-- 
2.39.2




[PATCH v2 13/13] mailbox: omap: Remove kernel FIFO message queuing

2024-04-10 Thread Andrew Davis
The kernel FIFO queue has a couple issues. The biggest issue is that
it causes extra latency in a path that can be used in real-time tasks,
such as communication with real-time remote processors.

The whole FIFO idea itself looks to be a leftover from before the
unified mailbox framework. The current mailbox framework expects
mbox_chan_received_data() to be called with data immediately as it
arrives. Remove the FIFO and pass the messages to the mailbox
framework directly as part of a threaded IRQ handler.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/Kconfig|   9 ---
 drivers/mailbox/omap-mailbox.c | 107 ++---
 2 files changed, 5 insertions(+), 111 deletions(-)

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 42940108a1874..78e4c74fbe5c2 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -68,15 +68,6 @@ config OMAP2PLUS_MBOX
  OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you
  want to use OMAP2+ Mailbox framework support.
 
-config OMAP_MBOX_KFIFO_SIZE
-   int "Mailbox kfifo default buffer size (bytes)"
-   depends on OMAP2PLUS_MBOX
-   default 256
-   help
- Specify the default size of mailbox's kfifo buffers (bytes).
- This can also be changed at runtime (via the mbox_kfifo_size
- module parameter).
-
 config ROCKCHIP_MBOX
bool "Rockchip Soc Integrated Mailbox Support"
depends on ARCH_ROCKCHIP || COMPILE_TEST
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c5d4083125856..46747559b438f 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -65,14 +65,6 @@ struct omap_mbox_fifo {
u32 intr_bit;
 };
 
-struct omap_mbox_queue {
-   spinlock_t  lock;
-   struct kfifofifo;
-   struct work_struct  work;
-   struct omap_mbox*mbox;
-   bool full;
-};
-
 struct omap_mbox_match_data {
u32 intr_type;
 };
@@ -90,7 +82,6 @@ struct omap_mbox_device {
 struct omap_mbox {
const char  *name;
int irq;
-   struct omap_mbox_queue  *rxq;
struct omap_mbox_device *parent;
struct omap_mbox_fifo   tx_fifo;
struct omap_mbox_fifo   rx_fifo;
@@ -99,10 +90,6 @@ struct omap_mbox {
boolsend_no_irq;
 };
 
-static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
-module_param(mbox_kfifo_size, uint, S_IRUGO);
-MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
-
 static inline
 unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
 {
@@ -202,30 +189,6 @@ static void omap_mbox_disable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, bit, irqdisable);
 }
 
-/*
- * Message receiver(workqueue)
- */
-static void mbox_rx_work(struct work_struct *work)
-{
-   struct omap_mbox_queue *mq =
-   container_of(work, struct omap_mbox_queue, work);
-   u32 msg;
-   int len;
-
-   while (kfifo_len(>fifo) >= sizeof(msg)) {
-   len = kfifo_out(>fifo, (unsigned char *), sizeof(msg));
-   WARN_ON(len != sizeof(msg));
-
-   mbox_chan_received_data(mq->mbox->chan, (void *)(uintptr_t)msg);
-   spin_lock_irq(>lock);
-   if (mq->full) {
-   mq->full = false;
-   omap_mbox_enable_irq(mq->mbox, IRQ_RX);
-   }
-   spin_unlock_irq(>lock);
-   }
-}
-
 /*
  * Mailbox interrupt handler
  */
@@ -238,27 +201,15 @@ static void __mbox_tx_interrupt(struct omap_mbox *mbox)
 
 static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 {
-   struct omap_mbox_queue *mq = mbox->rxq;
u32 msg;
-   int len;
 
while (!mbox_fifo_empty(mbox)) {
-   if (unlikely(kfifo_avail(>fifo) < sizeof(msg))) {
-   omap_mbox_disable_irq(mbox, IRQ_RX);
-   mq->full = true;
-   goto nomem;
-   }
-
msg = mbox_fifo_read(mbox);
-
-   len = kfifo_in(>fifo, (unsigned char *), sizeof(msg));
-   WARN_ON(len != sizeof(msg));
+   mbox_chan_received_data(mbox->chan, (void *)(uintptr_t)msg);
}
 
-   /* no more messages in the fifo. clear IRQ source. */
+   /* clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX);
-nomem:
-   schedule_work(>rxq->work);
 }
 
 static irqreturn_t mbox_interrupt(int irq, void *p)
@@ -274,57 +225,15 @@ static irqreturn_t mbox_interrupt(int irq, void *p)
return IRQ_HANDLED;
 }
 
-static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
-   void (*work)(struct work_struct *))
-{
-   struct omap_mbox_queue *mq;
- 

[PATCH v2 10/13] mailbox: omap: Use mbox_controller channel list directly

2024-04-10 Thread Andrew Davis
The driver stores a list of omap_mbox structs so it can later use it to
lookup the mailbox names in of_xlate. This same information is already
available in the mbox_controller passed into of_xlate. Simply use that
data and remove the extra allocation and storage of the omap_mbox list.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 42 +-
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 97f59d9f9f319..8e42266cb31a5 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -85,7 +85,6 @@ struct omap_mbox_device {
u32 num_users;
u32 num_fifos;
u32 intr_type;
-   struct omap_mbox **mboxes;
 };
 
 struct omap_mbox {
@@ -356,25 +355,6 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
mbox_queue_free(mbox->rxq);
 }
 
-static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev,
-  const char *mbox_name)
-{
-   struct omap_mbox *_mbox, *mbox = NULL;
-   struct omap_mbox **mboxes = mdev->mboxes;
-   int i;
-
-   if (!mboxes)
-   return NULL;
-
-   for (i = 0; (_mbox = mboxes[i]); i++) {
-   if (!strcmp(_mbox->name, mbox_name)) {
-   mbox = _mbox;
-   break;
-   }
-   }
-   return mbox;
-}
-
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
@@ -539,6 +519,7 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
struct device_node *node;
struct omap_mbox_device *mdev;
struct omap_mbox *mbox;
+   int i;
 
mdev = dev_get_drvdata(controller->dev);
if (WARN_ON(!mdev))
@@ -551,16 +532,23 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
return ERR_PTR(-ENODEV);
}
 
-   mbox = omap_mbox_device_find(mdev, node->name);
+   for (i = 0; i < controller->num_chans; i++) {
+   mbox = controller->chans[i].con_priv;
+   if (!strcmp(mbox->name, node->name)) {
+   of_node_put(node);
+   return >chans[i];
+   }
+   }
+
of_node_put(node);
-   return mbox ? mbox->chan : ERR_PTR(-ENOENT);
+   return ERR_PTR(-ENOENT);
 }
 
 static int omap_mbox_probe(struct platform_device *pdev)
 {
int ret;
struct mbox_chan *chnls;
-   struct omap_mbox **list, *mbox;
+   struct omap_mbox *mbox;
struct omap_mbox_device *mdev;
struct omap_mbox_fifo *fifo;
struct device_node *node = pdev->dev.of_node;
@@ -608,12 +596,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
if (!mdev->irq_ctx)
return -ENOMEM;
 
-   /* allocate one extra for marking end of list */
-   list = devm_kcalloc(>dev, info_count + 1, sizeof(*list),
-   GFP_KERNEL);
-   if (!list)
-   return -ENOMEM;
-
chnls = devm_kcalloc(>dev, info_count + 1, sizeof(*chnls),
 GFP_KERNEL);
if (!chnls)
@@ -675,7 +657,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
return mbox->irq;
mbox->chan = [i];
chnls[i].con_priv = mbox;
-   list[i] = mbox++;
}
 
mutex_init(>cfg_lock);
@@ -683,7 +664,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->num_users = num_users;
mdev->num_fifos = num_fifos;
mdev->intr_type = intr_type;
-   mdev->mboxes = list;
 
controller = devm_kzalloc(>dev, sizeof(*controller), GFP_KERNEL);
if (!controller)
-- 
2.39.2




[PATCH v2 03/13] mailbox: omap: Move omap_mbox_irq_t into driver

2024-04-10 Thread Andrew Davis
This is only used internal to the driver, move it out of the
public header and into the driver file. While we are here,
this is not used as a bitwise, so drop that and make it a
simple enum type.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 5 +
 include/linux/omap-mailbox.h   | 4 
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8151722eef383..c083734b6954c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -51,6 +51,11 @@
 #define MBOX_INTR_CFG_TYPE10
 #define MBOX_INTR_CFG_TYPE21
 
+typedef enum {
+   IRQ_TX = 1,
+   IRQ_RX = 2,
+} omap_mbox_irq_t;
+
 struct omap_mbox_fifo {
unsigned long msg;
unsigned long fifo_stat;
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index f8ddf8e814167..3cc5c4ed7f5a6 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -10,8 +10,4 @@ typedef uintptr_t mbox_msg_t;
 
 #define omap_mbox_message(data) (u32)(mbox_msg_t)(data)
 
-typedef int __bitwise omap_mbox_irq_t;
-#define IRQ_TX ((__force omap_mbox_irq_t) 1)
-#define IRQ_RX ((__force omap_mbox_irq_t) 2)
-
 #endif /* OMAP_MAILBOX_H */
-- 
2.39.2




[PATCH v2 12/13] mailbox: omap: Reverse FIFO busy check logic

2024-04-10 Thread Andrew Davis
It is much more clear to check if the hardware FIFO is full and return
EBUSY if true. This allows us to also remove one level of indention
from the core of this function. It also makes the similarities between
omap_mbox_chan_send_noirq() and omap_mbox_chan_send() more obvious.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8e2760d2c5b0c..c5d4083125856 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -375,34 +375,33 @@ static void omap_mbox_chan_shutdown(struct mbox_chan 
*chan)
 
 static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg)
 {
-   int ret = -EBUSY;
+   if (mbox_fifo_full(mbox))
+   return -EBUSY;
 
-   if (!mbox_fifo_full(mbox)) {
-   omap_mbox_enable_irq(mbox, IRQ_RX);
-   mbox_fifo_write(mbox, msg);
-   ret = 0;
-   omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
+   mbox_fifo_write(mbox, msg);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
 
-   /* we must read and ack the interrupt directly from here */
-   mbox_fifo_read(mbox);
-   ack_mbox_irq(mbox, IRQ_RX);
-   }
+   /* we must read and ack the interrupt directly from here */
+   mbox_fifo_read(mbox);
+   ack_mbox_irq(mbox, IRQ_RX);
 
-   return ret;
+   return 0;
 }
 
 static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg)
 {
-   int ret = -EBUSY;
-
-   if (!mbox_fifo_full(mbox)) {
-   mbox_fifo_write(mbox, msg);
-   ret = 0;
+   if (mbox_fifo_full(mbox)) {
+   /* always enable the interrupt */
+   omap_mbox_enable_irq(mbox, IRQ_TX);
+   return -EBUSY;
}
 
+   mbox_fifo_write(mbox, msg);
+
/* always enable the interrupt */
omap_mbox_enable_irq(mbox, IRQ_TX);
-   return ret;
+   return 0;
 }
 
 static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
-- 
2.39.2




[PATCH v2 08/13] mailbox: omap: Merge mailbox child node setup loops

2024-04-10 Thread Andrew Davis
Currently the driver loops through all mailbox child nodes twice, once
to read in data from each node, and again to make use of this data.
Instead read the data and make use of it in one pass. This removes
the need for several temporary data structures and reduces the
complexity of this main loop in probe.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 119 +
 1 file changed, 46 insertions(+), 73 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 4f956c7b4072c..17c9b9df78b1d 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -89,19 +89,6 @@ struct omap_mbox_device {
struct mbox_controller controller;
 };
 
-struct omap_mbox_fifo_info {
-   int tx_id;
-   int tx_usr;
-   int tx_irq;
-
-   int rx_id;
-   int rx_usr;
-   int rx_irq;
-
-   const char *name;
-   bool send_no_irq;
-};
-
 struct omap_mbox {
const char  *name;
int irq;
@@ -574,8 +561,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
 {
int ret;
struct mbox_chan *chnls;
-   struct omap_mbox **list, *mbox, *mboxblk;
-   struct omap_mbox_fifo_info *finfo, *finfoblk;
+   struct omap_mbox **list, *mbox;
struct omap_mbox_device *mdev;
struct omap_mbox_fifo *fifo;
struct device_node *node = pdev->dev.of_node;
@@ -609,40 +595,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   finfoblk = devm_kcalloc(>dev, info_count, sizeof(*finfoblk),
-   GFP_KERNEL);
-   if (!finfoblk)
-   return -ENOMEM;
-
-   finfo = finfoblk;
-   child = NULL;
-   for (i = 0; i < info_count; i++, finfo++) {
-   child = of_get_next_available_child(node, child);
-   ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
-ARRAY_SIZE(tmp));
-   if (ret)
-   return ret;
-   finfo->tx_id = tmp[0];
-   finfo->tx_irq = tmp[1];
-   finfo->tx_usr = tmp[2];
-
-   ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
-ARRAY_SIZE(tmp));
-   if (ret)
-   return ret;
-   finfo->rx_id = tmp[0];
-   finfo->rx_irq = tmp[1];
-   finfo->rx_usr = tmp[2];
-
-   finfo->name = child->name;
-
-   finfo->send_no_irq = of_property_read_bool(child, 
"ti,mbox-send-noirq");
-
-   if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
-   finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
-   return -EINVAL;
-   }
-
mdev = devm_kzalloc(>dev, sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return -ENOMEM;
@@ -667,36 +619,58 @@ static int omap_mbox_probe(struct platform_device *pdev)
if (!chnls)
return -ENOMEM;
 
-   mboxblk = devm_kcalloc(>dev, info_count, sizeof(*mbox),
-  GFP_KERNEL);
-   if (!mboxblk)
-   return -ENOMEM;
+   child = NULL;
+   for (i = 0; i < info_count; i++) {
+   int tx_id, tx_irq, tx_usr;
+   int rx_id, rx_usr;
+
+   mbox = devm_kzalloc(>dev, sizeof(*mbox), GFP_KERNEL);
+   if (!mbox)
+   return -ENOMEM;
+
+   child = of_get_next_available_child(node, child);
+   ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
+ARRAY_SIZE(tmp));
+   if (ret)
+   return ret;
+   tx_id = tmp[0];
+   tx_irq = tmp[1];
+   tx_usr = tmp[2];
+
+   ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
+ARRAY_SIZE(tmp));
+   if (ret)
+   return ret;
+   rx_id = tmp[0];
+   /* rx_irq = tmp[1]; */
+   rx_usr = tmp[2];
+
+   if (tx_id >= num_fifos || rx_id >= num_fifos ||
+   tx_usr >= num_users || rx_usr >= num_users)
+   return -EINVAL;
 
-   mbox = mboxblk;
-   finfo = finfoblk;
-   for (i = 0; i < info_count; i++, finfo++) {
fifo = >tx_fifo;
-   fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
-   fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
-   fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
-   fifo->irqenab

[PATCH v2 07/13] mailbox: omap: Use devm_pm_runtime_enable() helper

2024-04-10 Thread Andrew Davis
Use device life-cycle managed runtime enable function to simplify probe
and exit paths.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 18 +++---
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index ea467931faf46..4f956c7b4072c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -726,11 +726,11 @@ static int omap_mbox_probe(struct platform_device *pdev)
return ret;
 
platform_set_drvdata(pdev, mdev);
-   pm_runtime_enable(mdev->dev);
+   devm_pm_runtime_enable(mdev->dev);
 
ret = pm_runtime_resume_and_get(mdev->dev);
if (ret < 0)
-   goto unregister;
+   return ret;
 
/*
 * just print the raw revision register, the format is not
@@ -741,26 +741,14 @@ static int omap_mbox_probe(struct platform_device *pdev)
 
ret = pm_runtime_put_sync(mdev->dev);
if (ret < 0 && ret != -ENOSYS)
-   goto unregister;
+   return ret;
 
devm_kfree(>dev, finfoblk);
return 0;
-
-unregister:
-   pm_runtime_disable(mdev->dev);
-   return ret;
-}
-
-static void omap_mbox_remove(struct platform_device *pdev)
-{
-   struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
-
-   pm_runtime_disable(mdev->dev);
 }
 
 static struct platform_driver omap_mbox_driver = {
.probe  = omap_mbox_probe,
-   .remove_new = omap_mbox_remove,
.driver = {
.name = "omap-mailbox",
.pm = _mbox_pm_ops,
-- 
2.39.2




[PATCH v2 06/13] mailbox: omap: Remove device class

2024-04-10 Thread Andrew Davis
The driver currently creates a new device class "mbox". Then for each
mailbox adds a device to that class. This class provides no file
operations provided for any userspace users of this device class.
It may have been extended to be functional in our vendor tree at
some point, but that is not the case anymore, nor does it matter
for the upstream tree.

Remove this device class and related functions and variables.
This also allows us to switch to module_platform_driver() as
there is nothing left to do in module_init().

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 89 +-
 1 file changed, 2 insertions(+), 87 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 4c673cb732ed1..ea467931faf46 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -87,7 +87,6 @@ struct omap_mbox_device {
u32 intr_type;
struct omap_mbox **mboxes;
struct mbox_controller controller;
-   struct list_head elem;
 };
 
 struct omap_mbox_fifo_info {
@@ -107,7 +106,6 @@ struct omap_mbox {
const char  *name;
int irq;
struct omap_mbox_queue  *rxq;
-   struct device   *dev;
struct omap_mbox_device *parent;
struct omap_mbox_fifo   tx_fifo;
struct omap_mbox_fifo   rx_fifo;
@@ -116,10 +114,6 @@ struct omap_mbox {
boolsend_no_irq;
 };
 
-/* global variables for the mailbox devices */
-static DEFINE_MUTEX(omap_mbox_devices_lock);
-static LIST_HEAD(omap_mbox_devices);
-
 static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
 module_param(mbox_kfifo_size, uint, S_IRUGO);
 MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
@@ -395,61 +389,6 @@ static struct omap_mbox *omap_mbox_device_find(struct 
omap_mbox_device *mdev,
return mbox;
 }
 
-static struct class omap_mbox_class = { .name = "mbox", };
-
-static int omap_mbox_register(struct omap_mbox_device *mdev)
-{
-   int ret;
-   int i;
-   struct omap_mbox **mboxes;
-
-   if (!mdev || !mdev->mboxes)
-   return -EINVAL;
-
-   mboxes = mdev->mboxes;
-   for (i = 0; mboxes[i]; i++) {
-   struct omap_mbox *mbox = mboxes[i];
-
-   mbox->dev = device_create(_mbox_class, mdev->dev,
-   0, mbox, "%s", mbox->name);
-   if (IS_ERR(mbox->dev)) {
-   ret = PTR_ERR(mbox->dev);
-   goto err_out;
-   }
-   }
-
-   mutex_lock(_mbox_devices_lock);
-   list_add(>elem, _mbox_devices);
-   mutex_unlock(_mbox_devices_lock);
-
-   ret = devm_mbox_controller_register(mdev->dev, >controller);
-
-err_out:
-   if (ret) {
-   while (i--)
-   device_unregister(mboxes[i]->dev);
-   }
-   return ret;
-}
-
-static int omap_mbox_unregister(struct omap_mbox_device *mdev)
-{
-   int i;
-   struct omap_mbox **mboxes;
-
-   if (!mdev || !mdev->mboxes)
-   return -EINVAL;
-
-   mutex_lock(_mbox_devices_lock);
-   list_del(>elem);
-   mutex_unlock(_mbox_devices_lock);
-
-   mboxes = mdev->mboxes;
-   for (i = 0; mboxes[i]; i++)
-   device_unregister(mboxes[i]->dev);
-   return 0;
-}
-
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
@@ -782,7 +721,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->controller.chans = chnls;
mdev->controller.num_chans = info_count;
mdev->controller.of_xlate = omap_mbox_of_xlate;
-   ret = omap_mbox_register(mdev);
+   ret = devm_mbox_controller_register(mdev->dev, >controller);
if (ret)
return ret;
 
@@ -809,7 +748,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
 
 unregister:
pm_runtime_disable(mdev->dev);
-   omap_mbox_unregister(mdev);
return ret;
 }
 
@@ -818,7 +756,6 @@ static void omap_mbox_remove(struct platform_device *pdev)
struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
 
pm_runtime_disable(mdev->dev);
-   omap_mbox_unregister(mdev);
 }
 
 static struct platform_driver omap_mbox_driver = {
@@ -830,29 +767,7 @@ static struct platform_driver omap_mbox_driver = {
.of_match_table = of_match_ptr(omap_mailbox_of_match),
},
 };
-
-static int __init omap_mbox_init(void)
-{
-   int err;
-
-   err = class_register(_mbox_class);
-   if (err)
-   return err;
-
-   err = platform_driver_register(_mbox_driver);
-   if (err)
-   class_unregister(_mbox_class);
-
-   return err;
-}
-subsys_initcall(omap_mbox_init);
-
-static void

[PATCH v2 04/13] mailbox: omap: Move fifo size check to point of use

2024-04-10 Thread Andrew Davis
The mbox_kfifo_size can be changed at runtime, the sanity
check on it's value should be done when it is used, not
only once at init time.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c083734b6954c..167348fb1b33b 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -310,6 +310,7 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct 
omap_mbox *mbox,
void (*work)(struct work_struct *))
 {
struct omap_mbox_queue *mq;
+   unsigned int size;
 
if (!work)
return NULL;
@@ -320,7 +321,10 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct 
omap_mbox *mbox,
 
spin_lock_init(>lock);
 
-   if (kfifo_alloc(>fifo, mbox_kfifo_size, GFP_KERNEL))
+   /* kfifo size sanity check: alignment and minimal size */
+   size = ALIGN(mbox_kfifo_size, sizeof(u32));
+   size = max_t(unsigned int, size, sizeof(u32));
+   if (kfifo_alloc(>fifo, size, GFP_KERNEL))
goto error;
 
INIT_WORK(>work, work);
@@ -838,10 +842,6 @@ static int __init omap_mbox_init(void)
if (err)
return err;
 
-   /* kfifo size sanity check: alignment and minimal size */
-   mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(u32));
-   mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(u32));
-
err = platform_driver_register(_mbox_driver);
if (err)
class_unregister(_mbox_class);
-- 
2.39.2




[PATCH v2 01/13] mailbox: omap: Remove unused omap_mbox_{enable,disable}_irq() functions

2024-04-10 Thread Andrew Davis
These function are not used, remove these here.

While here, remove the leading _ from the driver internal functions that
do the same thing as the functions removed.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 42 --
 include/linux/omap-mailbox.h   |  3 ---
 2 files changed, 10 insertions(+), 35 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c961706fe61d5..624a7ccc27285 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -197,7 +197,7 @@ static int is_mbox_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
return (int)(enable & status & bit);
 }
 
-static void _omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
 {
u32 l;
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
@@ -210,7 +210,7 @@ static void _omap_mbox_enable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, l, irqenable);
 }
 
-static void _omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
 {
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
>tx_fifo : >rx_fifo;
@@ -227,28 +227,6 @@ static void _omap_mbox_disable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, bit, irqdisable);
 }
 
-void omap_mbox_enable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
-   if (WARN_ON(!mbox))
-   return;
-
-   _omap_mbox_enable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_enable_irq);
-
-void omap_mbox_disable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
-   if (WARN_ON(!mbox))
-   return;
-
-   _omap_mbox_disable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_disable_irq);
-
 /*
  * Message receiver(workqueue)
  */
@@ -269,7 +247,7 @@ static void mbox_rx_work(struct work_struct *work)
spin_lock_irq(>lock);
if (mq->full) {
mq->full = false;
-   _omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+   omap_mbox_enable_irq(mq->mbox, IRQ_RX);
}
spin_unlock_irq(>lock);
}
@@ -280,7 +258,7 @@ static void mbox_rx_work(struct work_struct *work)
  */
 static void __mbox_tx_interrupt(struct omap_mbox *mbox)
 {
-   _omap_mbox_disable_irq(mbox, IRQ_TX);
+   omap_mbox_disable_irq(mbox, IRQ_TX);
ack_mbox_irq(mbox, IRQ_TX);
mbox_chan_txdone(mbox->chan, 0);
 }
@@ -293,7 +271,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 
while (!mbox_fifo_empty(mbox)) {
if (unlikely(kfifo_avail(>fifo) < sizeof(msg))) {
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
mq->full = true;
goto nomem;
}
@@ -375,7 +353,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
if (mbox->send_no_irq)
mbox->chan->txdone_method = TXDONE_BY_ACK;
 
-   _omap_mbox_enable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
 
return 0;
 
@@ -386,7 +364,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
 
 static void omap_mbox_fini(struct omap_mbox *mbox)
 {
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
free_irq(mbox->irq, mbox);
flush_work(>rxq->work);
mbox_queue_free(mbox->rxq);
@@ -533,10 +511,10 @@ static int omap_mbox_chan_send_noirq(struct omap_mbox 
*mbox, u32 msg)
int ret = -EBUSY;
 
if (!mbox_fifo_full(mbox)) {
-   _omap_mbox_enable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
mbox_fifo_write(mbox, msg);
ret = 0;
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
 
/* we must read and ack the interrupt directly from here */
mbox_fifo_read(mbox);
@@ -556,7 +534,7 @@ static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 
msg)
}
 
/* always enable the interrupt */
-   _omap_mbox_enable_irq(mbox, IRQ_TX);
+   omap_mbox_enable_irq(mbox, IRQ_TX);
return ret;
 }
 
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index 8aa984ec1f38b..426a80fb32b5c 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -20,7 +20,4 @@ struct mbox_client;
 struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,

[PATCH v2 00/13] OMAP mailbox FIFO removal

2024-04-10 Thread Andrew Davis
Hello all,

Core of this series is the last patch removing the message FIFO
from OMAP mailbox. This hurts our real-time performance. It was a
legacy leftover from before the common mailbox framework anyway.

The rest of the patches are cleanups found along the way.

Thanks,
Andrew

Changes for v2:
 - Use threaded irq as suggested by Hari and to
 fix possible "scheduling while atomic" issue
 - Use oneshot irq as we do not want to enable the
 irq again until we clear our the messages
 - Rebase on v6.9-rc3

Andrew Davis (13):
  mailbox: omap: Remove unused omap_mbox_{enable,disable}_irq()
functions
  mailbox: omap: Remove unused omap_mbox_request_channel() function
  mailbox: omap: Move omap_mbox_irq_t into driver
  mailbox: omap: Move fifo size check to point of use
  mailbox: omap: Remove unneeded header omap-mailbox.h
  mailbox: omap: Remove device class
  mailbox: omap: Use devm_pm_runtime_enable() helper
  mailbox: omap: Merge mailbox child node setup loops
  mailbox: omap: Use function local struct mbox_controller
  mailbox: omap: Use mbox_controller channel list directly
  mailbox: omap: Remove mbox_chan_to_omap_mbox()
  mailbox: omap: Reverse FIFO busy check logic
  mailbox: omap: Remove kernel FIFO message queuing

 drivers/mailbox/Kconfig|   9 -
 drivers/mailbox/omap-mailbox.c | 519 +++--
 include/linux/omap-mailbox.h   |  13 -
 3 files changed, 108 insertions(+), 433 deletions(-)

-- 
2.39.2




[PATCH v2 02/13] mailbox: omap: Remove unused omap_mbox_request_channel() function

2024-04-10 Thread Andrew Davis
This function is not used, remove this function.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 36 --
 include/linux/omap-mailbox.h   |  6 --
 2 files changed, 42 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 624a7ccc27285..8151722eef383 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -389,42 +389,6 @@ static struct omap_mbox *omap_mbox_device_find(struct 
omap_mbox_device *mdev,
return mbox;
 }
 
-struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
-   const char *chan_name)
-{
-   struct device *dev = cl->dev;
-   struct omap_mbox *mbox = NULL;
-   struct omap_mbox_device *mdev;
-   int ret;
-
-   if (!dev)
-   return ERR_PTR(-ENODEV);
-
-   if (dev->of_node) {
-   pr_err("%s: please use mbox_request_channel(), this API is 
supported only for OMAP non-DT usage\n",
-  __func__);
-   return ERR_PTR(-ENODEV);
-   }
-
-   mutex_lock(_mbox_devices_lock);
-   list_for_each_entry(mdev, _mbox_devices, elem) {
-   mbox = omap_mbox_device_find(mdev, chan_name);
-   if (mbox)
-   break;
-   }
-   mutex_unlock(_mbox_devices_lock);
-
-   if (!mbox || !mbox->chan)
-   return ERR_PTR(-ENOENT);
-
-   ret = mbox_bind_client(mbox->chan, cl);
-   if (ret)
-   return ERR_PTR(ret);
-
-   return mbox->chan;
-}
-EXPORT_SYMBOL(omap_mbox_request_channel);
-
 static struct class omap_mbox_class = { .name = "mbox", };
 
 static int omap_mbox_register(struct omap_mbox_device *mdev)
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index 426a80fb32b5c..f8ddf8e814167 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -14,10 +14,4 @@ typedef int __bitwise omap_mbox_irq_t;
 #define IRQ_TX ((__force omap_mbox_irq_t) 1)
 #define IRQ_RX ((__force omap_mbox_irq_t) 2)
 
-struct mbox_chan;
-struct mbox_client;
-
-struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
-   const char *chan_name);
-
 #endif /* OMAP_MAILBOX_H */
-- 
2.39.2




Re: [PATCH 13/13] mailbox: omap: Remove kernel FIFO message queuing

2024-04-01 Thread Andrew Davis

On 4/1/24 6:39 PM, Hari Nagalla wrote:

On 3/25/24 12:20, Andrew Davis wrote:

The kernel FIFO queue has a couple issues. The biggest issue is that
it causes extra latency in a path that can be used in real-time tasks,
such as communication with real-time remote processors.

The whole FIFO idea itself looks to be a leftover from before the
unified mailbox framework. The current mailbox framework expects
mbox_chan_received_data() to be called with data immediately as it
arrives. Remove the FIFO and pass the messages to the mailbox
framework directly.

Yes, this would definitely speed up the message receive path. With RT linux, 
the irq runs in thread context, so that is Ok. But with non-RT the whole 
receive path runs in interrupt context. So, i think it would be appropriate to 
use a threaded_irq()?


I was thinking the same at first, but seems some mailbox drivers use threaded, 
others
use non-threaded context. Since all we do in the IRQ context anymore is call
mbox_chan_received_data(), which is supposed to be IRQ safe, then it should be 
fine
either way. So for now I just kept this using the regular IRQ context as before.

If that does turn out to be an issue then let's switch to threaded.

Andrew



Re: [PATCH 12/13] mailbox: omap: Reverse FIFO busy check logic

2024-04-01 Thread Andrew Davis

On 4/1/24 6:31 PM, Hari Nagalla wrote:

On 3/25/24 12:20, Andrew Davis wrote:

  static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg)
  {
-    int ret = -EBUSY;
+    if (mbox_fifo_full(mbox))
+    return -EBUSY;
-    if (!mbox_fifo_full(mbox)) {
-    omap_mbox_enable_irq(mbox, IRQ_RX);
-    mbox_fifo_write(mbox, msg);
-    ret = 0;
-    omap_mbox_disable_irq(mbox, IRQ_RX);
+    omap_mbox_enable_irq(mbox, IRQ_RX);
+    mbox_fifo_write(mbox, msg);
+    omap_mbox_disable_irq(mbox, IRQ_RX);
-    /* we must read and ack the interrupt directly from here */
-    mbox_fifo_read(mbox);
-    ack_mbox_irq(mbox, IRQ_RX);
-    }
+    /* we must read and ack the interrupt directly from here */
+    mbox_fifo_read(mbox);
+    ack_mbox_irq(mbox, IRQ_RX);
-    return ret;
+    return 0;
  }

Is n't the interrupt supposed to be IRQ_TX above? i.e TX ready signal?


Hmm, could be, but this patch doesn't actually change anything, only moves code
around for readability. So if we were are ack'ing the wrong interrupt, then it
was wrong before. We should check that and fix it if needed in a follow up 
patch.

Andrew



Re: [PATCH 1/3] remoteproc: k3-dsp: Fix usage of omap_mbox_message and mbox_msg_t

2024-03-28 Thread Andrew Davis

On 3/28/24 10:28 AM, Mathieu Poirier wrote:

Hi Andrew,

On Mon, Mar 25, 2024 at 11:58:06AM -0500, Andrew Davis wrote:

The type of message sent using omap-mailbox is always u32. The definition
of mbox_msg_t is uintptr_t which is wrong as that type changes based on
the architecture (32bit vs 64bit). Use u32 unconditionally and remove
the now unneeded omap-mailbox.h include.

Signed-off-by: Andrew Davis 
---
  drivers/remoteproc/ti_k3_dsp_remoteproc.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 3555b535b1683..33b30cfb86c9d 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -11,7 +11,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
@@ -113,7 +112,7 @@ static void k3_dsp_rproc_mbox_callback(struct mbox_client 
*client, void *data)
  client);
struct device *dev = kproc->rproc->dev.parent;
const char *name = kproc->rproc->name;
-   u32 msg = omap_mbox_message(data);
+   u32 msg = (u32)(uintptr_t)(data);
  


Looking at omap-mailbox.h and unless I'm missing something, the end result is
the same.



dev_dbg(dev, "mbox msg: 0x%x\n", msg);
  
@@ -152,11 +151,11 @@ static void k3_dsp_rproc_kick(struct rproc *rproc, int vqid)

  {
struct k3_dsp_rproc *kproc = rproc->priv;
struct device *dev = rproc->dev.parent;
-   mbox_msg_t msg = (mbox_msg_t)vqid;
+   u32 msg = vqid;
int ret;



Here @vqid becomes a 'u32' rather than a 'uintptr'...



u32 is the correct type for messages sent with OMAP mailbox. It
only sends 32bit messages, uintptr is 64bit when compiled on
64bit hardware (like our ARM64 cores on K3). mbox_msg_t should
have been defined as u32, this was a mistake we missed as we only
ever used to compile it for 32bit cores (where uintptr is 32bit).


/* send the index of the triggered virtqueue in the mailbox payload */
-   ret = mbox_send_message(kproc->mbox, (void *)msg);
+   ret = mbox_send_message(kproc->mbox, (void *)(uintptr_t)msg);


... but here it is casted as a 'uintptr_t', which yields the same result.



The function mbox_send_message() takes a void*, so we need to cast our 32bit
message to that first, it is cast back to u32 inside the OMAP mailbox driver.
Doing that in one step (u32 -> void*) causes a warning when void* is 64bit
(cast from int to pointer of different size).



I am puzzled - other than getting rid of a header file I don't see what else
this patch does.



Getting rid of the header is the main point of this patch (I have a later
series that needs that header gone). But the difference this patch makes is that
before we passed a pointer to a 64bit int to OMAP mailbox which takes a pointer
to a 32bit int. Sure, the result is the same in little-endian systems, but that
isn't a strictly correct in general.

Thanks,
Andrew


Thanks,
Mathieu


if (ret < 0)
dev_err(dev, "failed to send mailbox message (%pe)\n",
ERR_PTR(ret));
--
2.39.2





[PATCH 05/13] mailbox: omap: Remove unneeded header omap-mailbox.h

2024-03-25 Thread Andrew Davis
The type of message sent using omap-mailbox is always u32. The definition
of mbox_msg_t is uintptr_t which is wrong as that type changes based on
the architecture (32bit vs 64bit). This type should have been defined as
u32. Instead of making that change here, simply remove the header usage
and fix the last couple users of the same in this driver.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 167348fb1b33b..4c673cb732ed1 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -239,16 +238,14 @@ static void mbox_rx_work(struct work_struct *work)
 {
struct omap_mbox_queue *mq =
container_of(work, struct omap_mbox_queue, work);
-   mbox_msg_t data;
u32 msg;
int len;
 
while (kfifo_len(>fifo) >= sizeof(msg)) {
len = kfifo_out(>fifo, (unsigned char *), sizeof(msg));
WARN_ON(len != sizeof(msg));
-   data = msg;
 
-   mbox_chan_received_data(mq->mbox->chan, (void *)data);
+   mbox_chan_received_data(mq->mbox->chan, (void *)(uintptr_t)msg);
spin_lock_irq(>lock);
if (mq->full) {
mq->full = false;
@@ -515,7 +512,7 @@ static int omap_mbox_chan_send_data(struct mbox_chan *chan, 
void *data)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
int ret;
-   u32 msg = omap_mbox_message(data);
+   u32 msg = (u32)(uintptr_t)(data);
 
if (!mbox)
return -EINVAL;
-- 
2.39.2




[PATCH 03/13] mailbox: omap: Move omap_mbox_irq_t into driver

2024-03-25 Thread Andrew Davis
This is only used internal to the driver, move it out of the
public header and into the driver file. While we are here,
this is not used as a bitwise, so drop that and make it a
simple enum type.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 5 +
 include/linux/omap-mailbox.h   | 4 
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8151722eef383..c083734b6954c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -51,6 +51,11 @@
 #define MBOX_INTR_CFG_TYPE10
 #define MBOX_INTR_CFG_TYPE21
 
+typedef enum {
+   IRQ_TX = 1,
+   IRQ_RX = 2,
+} omap_mbox_irq_t;
+
 struct omap_mbox_fifo {
unsigned long msg;
unsigned long fifo_stat;
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index f8ddf8e814167..3cc5c4ed7f5a6 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -10,8 +10,4 @@ typedef uintptr_t mbox_msg_t;
 
 #define omap_mbox_message(data) (u32)(mbox_msg_t)(data)
 
-typedef int __bitwise omap_mbox_irq_t;
-#define IRQ_TX ((__force omap_mbox_irq_t) 1)
-#define IRQ_RX ((__force omap_mbox_irq_t) 2)
-
 #endif /* OMAP_MAILBOX_H */
-- 
2.39.2




[PATCH 09/13] mailbox: omap: Use function local struct mbox_controller

2024-03-25 Thread Andrew Davis
The mbox_controller struct is only needed in the probe function. Make
it a local variable instead of storing a copy in omap_mbox_device
to simplify that struct.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 17c9b9df78b1d..97f59d9f9f319 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -86,7 +86,6 @@ struct omap_mbox_device {
u32 num_fifos;
u32 intr_type;
struct omap_mbox **mboxes;
-   struct mbox_controller controller;
 };
 
 struct omap_mbox {
@@ -541,7 +540,7 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
struct omap_mbox_device *mdev;
struct omap_mbox *mbox;
 
-   mdev = container_of(controller, struct omap_mbox_device, controller);
+   mdev = dev_get_drvdata(controller->dev);
if (WARN_ON(!mdev))
return ERR_PTR(-EINVAL);
 
@@ -567,6 +566,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct device_node *child;
const struct omap_mbox_match_data *match_data;
+   struct mbox_controller *controller;
u32 intr_type, info_count;
u32 num_users, num_fifos;
u32 tmp[3];
@@ -685,17 +685,20 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->intr_type = intr_type;
mdev->mboxes = list;
 
+   controller = devm_kzalloc(>dev, sizeof(*controller), GFP_KERNEL);
+   if (!controller)
+   return -ENOMEM;
/*
 * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
 * IRQ and is needed to run the Tx state machine
 */
-   mdev->controller.txdone_irq = true;
-   mdev->controller.dev = mdev->dev;
-   mdev->controller.ops = _mbox_chan_ops;
-   mdev->controller.chans = chnls;
-   mdev->controller.num_chans = info_count;
-   mdev->controller.of_xlate = omap_mbox_of_xlate;
-   ret = devm_mbox_controller_register(mdev->dev, >controller);
+   controller->txdone_irq = true;
+   controller->dev = mdev->dev;
+   controller->ops = _mbox_chan_ops;
+   controller->chans = chnls;
+   controller->num_chans = info_count;
+   controller->of_xlate = omap_mbox_of_xlate;
+   ret = devm_mbox_controller_register(mdev->dev, controller);
if (ret)
return ret;
 
-- 
2.39.2




[PATCH 10/13] mailbox: omap: Use mbox_controller channel list directly

2024-03-25 Thread Andrew Davis
The driver stores a list of omap_mbox structs so it can later use it to
lookup the mailbox names in of_xlate. This same information is already
available in the mbox_controller passed into of_xlate. Simply use that
data and remove the extra allocation and storage of the omap_mbox list.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 42 +-
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 97f59d9f9f319..8e42266cb31a5 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -85,7 +85,6 @@ struct omap_mbox_device {
u32 num_users;
u32 num_fifos;
u32 intr_type;
-   struct omap_mbox **mboxes;
 };
 
 struct omap_mbox {
@@ -356,25 +355,6 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
mbox_queue_free(mbox->rxq);
 }
 
-static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev,
-  const char *mbox_name)
-{
-   struct omap_mbox *_mbox, *mbox = NULL;
-   struct omap_mbox **mboxes = mdev->mboxes;
-   int i;
-
-   if (!mboxes)
-   return NULL;
-
-   for (i = 0; (_mbox = mboxes[i]); i++) {
-   if (!strcmp(_mbox->name, mbox_name)) {
-   mbox = _mbox;
-   break;
-   }
-   }
-   return mbox;
-}
-
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
@@ -539,6 +519,7 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
struct device_node *node;
struct omap_mbox_device *mdev;
struct omap_mbox *mbox;
+   int i;
 
mdev = dev_get_drvdata(controller->dev);
if (WARN_ON(!mdev))
@@ -551,16 +532,23 @@ static struct mbox_chan *omap_mbox_of_xlate(struct 
mbox_controller *controller,
return ERR_PTR(-ENODEV);
}
 
-   mbox = omap_mbox_device_find(mdev, node->name);
+   for (i = 0; i < controller->num_chans; i++) {
+   mbox = controller->chans[i].con_priv;
+   if (!strcmp(mbox->name, node->name)) {
+   of_node_put(node);
+   return >chans[i];
+   }
+   }
+
of_node_put(node);
-   return mbox ? mbox->chan : ERR_PTR(-ENOENT);
+   return ERR_PTR(-ENOENT);
 }
 
 static int omap_mbox_probe(struct platform_device *pdev)
 {
int ret;
struct mbox_chan *chnls;
-   struct omap_mbox **list, *mbox;
+   struct omap_mbox *mbox;
struct omap_mbox_device *mdev;
struct omap_mbox_fifo *fifo;
struct device_node *node = pdev->dev.of_node;
@@ -608,12 +596,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
if (!mdev->irq_ctx)
return -ENOMEM;
 
-   /* allocate one extra for marking end of list */
-   list = devm_kcalloc(>dev, info_count + 1, sizeof(*list),
-   GFP_KERNEL);
-   if (!list)
-   return -ENOMEM;
-
chnls = devm_kcalloc(>dev, info_count + 1, sizeof(*chnls),
 GFP_KERNEL);
if (!chnls)
@@ -675,7 +657,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
return mbox->irq;
mbox->chan = [i];
chnls[i].con_priv = mbox;
-   list[i] = mbox++;
}
 
mutex_init(>cfg_lock);
@@ -683,7 +664,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->num_users = num_users;
mdev->num_fifos = num_fifos;
mdev->intr_type = intr_type;
-   mdev->mboxes = list;
 
controller = devm_kzalloc(>dev, sizeof(*controller), GFP_KERNEL);
if (!controller)
-- 
2.39.2




[PATCH 12/13] mailbox: omap: Reverse FIFO busy check logic

2024-03-25 Thread Andrew Davis
It is much more clear to check if the hardware FIFO is full and return
EBUSY if true. This allows us to also remove one level of indention
from the core of this function. It also makes the similarities between
omap_mbox_chan_send_noirq() and omap_mbox_chan_send() more obvious.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8e2760d2c5b0c..c5d4083125856 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -375,34 +375,33 @@ static void omap_mbox_chan_shutdown(struct mbox_chan 
*chan)
 
 static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg)
 {
-   int ret = -EBUSY;
+   if (mbox_fifo_full(mbox))
+   return -EBUSY;
 
-   if (!mbox_fifo_full(mbox)) {
-   omap_mbox_enable_irq(mbox, IRQ_RX);
-   mbox_fifo_write(mbox, msg);
-   ret = 0;
-   omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
+   mbox_fifo_write(mbox, msg);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
 
-   /* we must read and ack the interrupt directly from here */
-   mbox_fifo_read(mbox);
-   ack_mbox_irq(mbox, IRQ_RX);
-   }
+   /* we must read and ack the interrupt directly from here */
+   mbox_fifo_read(mbox);
+   ack_mbox_irq(mbox, IRQ_RX);
 
-   return ret;
+   return 0;
 }
 
 static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg)
 {
-   int ret = -EBUSY;
-
-   if (!mbox_fifo_full(mbox)) {
-   mbox_fifo_write(mbox, msg);
-   ret = 0;
+   if (mbox_fifo_full(mbox)) {
+   /* always enable the interrupt */
+   omap_mbox_enable_irq(mbox, IRQ_TX);
+   return -EBUSY;
}
 
+   mbox_fifo_write(mbox, msg);
+
/* always enable the interrupt */
omap_mbox_enable_irq(mbox, IRQ_TX);
-   return ret;
+   return 0;
 }
 
 static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
-- 
2.39.2




[PATCH 00/13] OMAP mailbox FIFO removal

2024-03-25 Thread Andrew Davis
Hello all,

Core of this series is the last patch removing the message FIFO
from OMAP mailbox. This hurts our real-time performance. It was a
legacy leftover from before the common mailbox framework anyway.

The rest of the patches are cleanups found along the way.

Thanks,
Andrew

Andrew Davis (13):
  mailbox: omap: Remove unused omap_mbox_{enable,disable}_irq()
functions
  mailbox: omap: Remove unused omap_mbox_request_channel() function
  mailbox: omap: Move omap_mbox_irq_t into driver
  mailbox: omap: Move fifo size check to point of use
  mailbox: omap: Remove unneeded header omap-mailbox.h
  mailbox: omap: Remove device class
  mailbox: omap: Use devm_pm_runtime_enable() helper
  mailbox: omap: Merge mailbox child node setup loops
  mailbox: omap: Use function local struct mbox_controller
  mailbox: omap: Use mbox_controller channel list directly
  mailbox: omap: Remove mbox_chan_to_omap_mbox()
  mailbox: omap: Reverse FIFO busy check logic
  mailbox: omap: Remove kernel FIFO message queuing

 drivers/mailbox/Kconfig|   9 -
 drivers/mailbox/omap-mailbox.c | 515 +++--
 include/linux/omap-mailbox.h   |  13 -
 3 files changed, 106 insertions(+), 431 deletions(-)

-- 
2.39.2




[PATCH 13/13] mailbox: omap: Remove kernel FIFO message queuing

2024-03-25 Thread Andrew Davis
The kernel FIFO queue has a couple issues. The biggest issue is that
it causes extra latency in a path that can be used in real-time tasks,
such as communication with real-time remote processors.

The whole FIFO idea itself looks to be a leftover from before the
unified mailbox framework. The current mailbox framework expects
mbox_chan_received_data() to be called with data immediately as it
arrives. Remove the FIFO and pass the messages to the mailbox
framework directly.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/Kconfig|   9 ---
 drivers/mailbox/omap-mailbox.c | 103 +
 2 files changed, 3 insertions(+), 109 deletions(-)

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 42940108a1874..78e4c74fbe5c2 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -68,15 +68,6 @@ config OMAP2PLUS_MBOX
  OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you
  want to use OMAP2+ Mailbox framework support.
 
-config OMAP_MBOX_KFIFO_SIZE
-   int "Mailbox kfifo default buffer size (bytes)"
-   depends on OMAP2PLUS_MBOX
-   default 256
-   help
- Specify the default size of mailbox's kfifo buffers (bytes).
- This can also be changed at runtime (via the mbox_kfifo_size
- module parameter).
-
 config ROCKCHIP_MBOX
bool "Rockchip Soc Integrated Mailbox Support"
depends on ARCH_ROCKCHIP || COMPILE_TEST
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c5d4083125856..4e7e0e2f537b0 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -65,14 +65,6 @@ struct omap_mbox_fifo {
u32 intr_bit;
 };
 
-struct omap_mbox_queue {
-   spinlock_t  lock;
-   struct kfifofifo;
-   struct work_struct  work;
-   struct omap_mbox*mbox;
-   bool full;
-};
-
 struct omap_mbox_match_data {
u32 intr_type;
 };
@@ -90,7 +82,6 @@ struct omap_mbox_device {
 struct omap_mbox {
const char  *name;
int irq;
-   struct omap_mbox_queue  *rxq;
struct omap_mbox_device *parent;
struct omap_mbox_fifo   tx_fifo;
struct omap_mbox_fifo   rx_fifo;
@@ -99,10 +90,6 @@ struct omap_mbox {
boolsend_no_irq;
 };
 
-static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
-module_param(mbox_kfifo_size, uint, S_IRUGO);
-MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
-
 static inline
 unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
 {
@@ -202,30 +189,6 @@ static void omap_mbox_disable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, bit, irqdisable);
 }
 
-/*
- * Message receiver(workqueue)
- */
-static void mbox_rx_work(struct work_struct *work)
-{
-   struct omap_mbox_queue *mq =
-   container_of(work, struct omap_mbox_queue, work);
-   u32 msg;
-   int len;
-
-   while (kfifo_len(>fifo) >= sizeof(msg)) {
-   len = kfifo_out(>fifo, (unsigned char *), sizeof(msg));
-   WARN_ON(len != sizeof(msg));
-
-   mbox_chan_received_data(mq->mbox->chan, (void *)(uintptr_t)msg);
-   spin_lock_irq(>lock);
-   if (mq->full) {
-   mq->full = false;
-   omap_mbox_enable_irq(mq->mbox, IRQ_RX);
-   }
-   spin_unlock_irq(>lock);
-   }
-}
-
 /*
  * Mailbox interrupt handler
  */
@@ -238,27 +201,15 @@ static void __mbox_tx_interrupt(struct omap_mbox *mbox)
 
 static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 {
-   struct omap_mbox_queue *mq = mbox->rxq;
u32 msg;
-   int len;
 
while (!mbox_fifo_empty(mbox)) {
-   if (unlikely(kfifo_avail(>fifo) < sizeof(msg))) {
-   omap_mbox_disable_irq(mbox, IRQ_RX);
-   mq->full = true;
-   goto nomem;
-   }
-
msg = mbox_fifo_read(mbox);
-
-   len = kfifo_in(>fifo, (unsigned char *), sizeof(msg));
-   WARN_ON(len != sizeof(msg));
+   mbox_chan_received_data(mbox->chan, (void *)(uintptr_t)msg);
}
 
-   /* no more messages in the fifo. clear IRQ source. */
+   /* clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX);
-nomem:
-   schedule_work(>rxq->work);
 }
 
 static irqreturn_t mbox_interrupt(int irq, void *p)
@@ -274,57 +225,15 @@ static irqreturn_t mbox_interrupt(int irq, void *p)
return IRQ_HANDLED;
 }
 
-static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
-   void (*work)(struct work_struct *))
-{
-   struct omap_mbox_queue *mq;
-   unsigned int size;
-
-  

[PATCH 11/13] mailbox: omap: Remove mbox_chan_to_omap_mbox()

2024-03-25 Thread Andrew Davis
This function only checks if mbox_chan *chan is not NULL, but that cannot
be the case and if it was returning NULL which is not later checked
doesn't save us from this. The second check for chan->con_priv is
completely redundant as if it was NULL we would return NULL just the
same. Simply dereference con_priv directly and remove this function.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 8e42266cb31a5..8e2760d2c5b0c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -103,14 +103,6 @@ static unsigned int mbox_kfifo_size = 
CONFIG_OMAP_MBOX_KFIFO_SIZE;
 module_param(mbox_kfifo_size, uint, S_IRUGO);
 MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
 
-static struct omap_mbox *mbox_chan_to_omap_mbox(struct mbox_chan *chan)
-{
-   if (!chan || !chan->con_priv)
-   return NULL;
-
-   return (struct omap_mbox *)chan->con_priv;
-}
-
 static inline
 unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
 {
@@ -357,7 +349,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
 
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
int ret = 0;
 
@@ -372,7 +364,7 @@ static int omap_mbox_chan_startup(struct mbox_chan *chan)
 
 static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
struct omap_mbox_device *mdev = mbox->parent;
 
mutex_lock(>cfg_lock);
@@ -415,7 +407,7 @@ static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 
msg)
 
 static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
 {
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
+   struct omap_mbox *mbox = chan->con_priv;
int ret;
u32 msg = (u32)(uintptr_t)(data);
 
-- 
2.39.2




[PATCH 01/13] mailbox: omap: Remove unused omap_mbox_{enable,disable}_irq() functions

2024-03-25 Thread Andrew Davis
These function are not used, remove these here.

While here, remove the leading _ from the driver internal functions that
do the same thing as the functions removed.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 42 --
 include/linux/omap-mailbox.h   |  3 ---
 2 files changed, 10 insertions(+), 35 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c961706fe61d5..624a7ccc27285 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -197,7 +197,7 @@ static int is_mbox_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
return (int)(enable & status & bit);
 }
 
-static void _omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
 {
u32 l;
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
@@ -210,7 +210,7 @@ static void _omap_mbox_enable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, l, irqenable);
 }
 
-static void _omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+static void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
 {
struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
>tx_fifo : >rx_fifo;
@@ -227,28 +227,6 @@ static void _omap_mbox_disable_irq(struct omap_mbox *mbox, 
omap_mbox_irq_t irq)
mbox_write_reg(mbox->parent, bit, irqdisable);
 }
 
-void omap_mbox_enable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
-   if (WARN_ON(!mbox))
-   return;
-
-   _omap_mbox_enable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_enable_irq);
-
-void omap_mbox_disable_irq(struct mbox_chan *chan, omap_mbox_irq_t irq)
-{
-   struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
-
-   if (WARN_ON(!mbox))
-   return;
-
-   _omap_mbox_disable_irq(mbox, irq);
-}
-EXPORT_SYMBOL(omap_mbox_disable_irq);
-
 /*
  * Message receiver(workqueue)
  */
@@ -269,7 +247,7 @@ static void mbox_rx_work(struct work_struct *work)
spin_lock_irq(>lock);
if (mq->full) {
mq->full = false;
-   _omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+   omap_mbox_enable_irq(mq->mbox, IRQ_RX);
}
spin_unlock_irq(>lock);
}
@@ -280,7 +258,7 @@ static void mbox_rx_work(struct work_struct *work)
  */
 static void __mbox_tx_interrupt(struct omap_mbox *mbox)
 {
-   _omap_mbox_disable_irq(mbox, IRQ_TX);
+   omap_mbox_disable_irq(mbox, IRQ_TX);
ack_mbox_irq(mbox, IRQ_TX);
mbox_chan_txdone(mbox->chan, 0);
 }
@@ -293,7 +271,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 
while (!mbox_fifo_empty(mbox)) {
if (unlikely(kfifo_avail(>fifo) < sizeof(msg))) {
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
mq->full = true;
goto nomem;
}
@@ -375,7 +353,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
if (mbox->send_no_irq)
mbox->chan->txdone_method = TXDONE_BY_ACK;
 
-   _omap_mbox_enable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
 
return 0;
 
@@ -386,7 +364,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
 
 static void omap_mbox_fini(struct omap_mbox *mbox)
 {
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
free_irq(mbox->irq, mbox);
flush_work(>rxq->work);
mbox_queue_free(mbox->rxq);
@@ -533,10 +511,10 @@ static int omap_mbox_chan_send_noirq(struct omap_mbox 
*mbox, u32 msg)
int ret = -EBUSY;
 
if (!mbox_fifo_full(mbox)) {
-   _omap_mbox_enable_irq(mbox, IRQ_RX);
+   omap_mbox_enable_irq(mbox, IRQ_RX);
mbox_fifo_write(mbox, msg);
ret = 0;
-   _omap_mbox_disable_irq(mbox, IRQ_RX);
+   omap_mbox_disable_irq(mbox, IRQ_RX);
 
/* we must read and ack the interrupt directly from here */
mbox_fifo_read(mbox);
@@ -556,7 +534,7 @@ static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 
msg)
}
 
/* always enable the interrupt */
-   _omap_mbox_enable_irq(mbox, IRQ_TX);
+   omap_mbox_enable_irq(mbox, IRQ_TX);
return ret;
 }
 
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index 8aa984ec1f38b..426a80fb32b5c 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -20,7 +20,4 @@ struct mbox_client;
 struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,

[PATCH 08/13] mailbox: omap: Merge mailbox child node setup loops

2024-03-25 Thread Andrew Davis
Currently the driver loops through all mailbox child nodes twice, once
to read in data from each node, and again to make use of this data.
Instead read the data and make use of it in one pass. This removes
the need for several temporary data structures and reduces the
complexity of this main loop in probe.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 119 +
 1 file changed, 46 insertions(+), 73 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 4f956c7b4072c..17c9b9df78b1d 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -89,19 +89,6 @@ struct omap_mbox_device {
struct mbox_controller controller;
 };
 
-struct omap_mbox_fifo_info {
-   int tx_id;
-   int tx_usr;
-   int tx_irq;
-
-   int rx_id;
-   int rx_usr;
-   int rx_irq;
-
-   const char *name;
-   bool send_no_irq;
-};
-
 struct omap_mbox {
const char  *name;
int irq;
@@ -574,8 +561,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
 {
int ret;
struct mbox_chan *chnls;
-   struct omap_mbox **list, *mbox, *mboxblk;
-   struct omap_mbox_fifo_info *finfo, *finfoblk;
+   struct omap_mbox **list, *mbox;
struct omap_mbox_device *mdev;
struct omap_mbox_fifo *fifo;
struct device_node *node = pdev->dev.of_node;
@@ -609,40 +595,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   finfoblk = devm_kcalloc(>dev, info_count, sizeof(*finfoblk),
-   GFP_KERNEL);
-   if (!finfoblk)
-   return -ENOMEM;
-
-   finfo = finfoblk;
-   child = NULL;
-   for (i = 0; i < info_count; i++, finfo++) {
-   child = of_get_next_available_child(node, child);
-   ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
-ARRAY_SIZE(tmp));
-   if (ret)
-   return ret;
-   finfo->tx_id = tmp[0];
-   finfo->tx_irq = tmp[1];
-   finfo->tx_usr = tmp[2];
-
-   ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
-ARRAY_SIZE(tmp));
-   if (ret)
-   return ret;
-   finfo->rx_id = tmp[0];
-   finfo->rx_irq = tmp[1];
-   finfo->rx_usr = tmp[2];
-
-   finfo->name = child->name;
-
-   finfo->send_no_irq = of_property_read_bool(child, 
"ti,mbox-send-noirq");
-
-   if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
-   finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
-   return -EINVAL;
-   }
-
mdev = devm_kzalloc(>dev, sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return -ENOMEM;
@@ -667,36 +619,58 @@ static int omap_mbox_probe(struct platform_device *pdev)
if (!chnls)
return -ENOMEM;
 
-   mboxblk = devm_kcalloc(>dev, info_count, sizeof(*mbox),
-  GFP_KERNEL);
-   if (!mboxblk)
-   return -ENOMEM;
+   child = NULL;
+   for (i = 0; i < info_count; i++) {
+   int tx_id, tx_irq, tx_usr;
+   int rx_id, rx_usr;
+
+   mbox = devm_kzalloc(>dev, sizeof(*mbox), GFP_KERNEL);
+   if (!mbox)
+   return -ENOMEM;
+
+   child = of_get_next_available_child(node, child);
+   ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp,
+ARRAY_SIZE(tmp));
+   if (ret)
+   return ret;
+   tx_id = tmp[0];
+   tx_irq = tmp[1];
+   tx_usr = tmp[2];
+
+   ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp,
+ARRAY_SIZE(tmp));
+   if (ret)
+   return ret;
+   rx_id = tmp[0];
+   /* rx_irq = tmp[1]; */
+   rx_usr = tmp[2];
+
+   if (tx_id >= num_fifos || rx_id >= num_fifos ||
+   tx_usr >= num_users || rx_usr >= num_users)
+   return -EINVAL;
 
-   mbox = mboxblk;
-   finfo = finfoblk;
-   for (i = 0; i < info_count; i++, finfo++) {
fifo = >tx_fifo;
-   fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
-   fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
-   fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
-   fifo->irqenab

[PATCH 06/13] mailbox: omap: Remove device class

2024-03-25 Thread Andrew Davis
The driver currently creates a new device class "mbox". Then for each
mailbox adds a device to that class. This class provides no file
operations provided for any userspace users of this device class.
It may have been extended to be functional in our vendor tree at
some point, but that is not the case anymore, nor does it matter
for the upstream tree.

Remove this device class and related functions and variables.
This also allows us to switch to module_platform_driver() as
there is nothing left to do in module_init().

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 89 +-
 1 file changed, 2 insertions(+), 87 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 4c673cb732ed1..ea467931faf46 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -87,7 +87,6 @@ struct omap_mbox_device {
u32 intr_type;
struct omap_mbox **mboxes;
struct mbox_controller controller;
-   struct list_head elem;
 };
 
 struct omap_mbox_fifo_info {
@@ -107,7 +106,6 @@ struct omap_mbox {
const char  *name;
int irq;
struct omap_mbox_queue  *rxq;
-   struct device   *dev;
struct omap_mbox_device *parent;
struct omap_mbox_fifo   tx_fifo;
struct omap_mbox_fifo   rx_fifo;
@@ -116,10 +114,6 @@ struct omap_mbox {
boolsend_no_irq;
 };
 
-/* global variables for the mailbox devices */
-static DEFINE_MUTEX(omap_mbox_devices_lock);
-static LIST_HEAD(omap_mbox_devices);
-
 static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
 module_param(mbox_kfifo_size, uint, S_IRUGO);
 MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
@@ -395,61 +389,6 @@ static struct omap_mbox *omap_mbox_device_find(struct 
omap_mbox_device *mdev,
return mbox;
 }
 
-static struct class omap_mbox_class = { .name = "mbox", };
-
-static int omap_mbox_register(struct omap_mbox_device *mdev)
-{
-   int ret;
-   int i;
-   struct omap_mbox **mboxes;
-
-   if (!mdev || !mdev->mboxes)
-   return -EINVAL;
-
-   mboxes = mdev->mboxes;
-   for (i = 0; mboxes[i]; i++) {
-   struct omap_mbox *mbox = mboxes[i];
-
-   mbox->dev = device_create(_mbox_class, mdev->dev,
-   0, mbox, "%s", mbox->name);
-   if (IS_ERR(mbox->dev)) {
-   ret = PTR_ERR(mbox->dev);
-   goto err_out;
-   }
-   }
-
-   mutex_lock(_mbox_devices_lock);
-   list_add(>elem, _mbox_devices);
-   mutex_unlock(_mbox_devices_lock);
-
-   ret = devm_mbox_controller_register(mdev->dev, >controller);
-
-err_out:
-   if (ret) {
-   while (i--)
-   device_unregister(mboxes[i]->dev);
-   }
-   return ret;
-}
-
-static int omap_mbox_unregister(struct omap_mbox_device *mdev)
-{
-   int i;
-   struct omap_mbox **mboxes;
-
-   if (!mdev || !mdev->mboxes)
-   return -EINVAL;
-
-   mutex_lock(_mbox_devices_lock);
-   list_del(>elem);
-   mutex_unlock(_mbox_devices_lock);
-
-   mboxes = mdev->mboxes;
-   for (i = 0; mboxes[i]; i++)
-   device_unregister(mboxes[i]->dev);
-   return 0;
-}
-
 static int omap_mbox_chan_startup(struct mbox_chan *chan)
 {
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
@@ -782,7 +721,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->controller.chans = chnls;
mdev->controller.num_chans = info_count;
mdev->controller.of_xlate = omap_mbox_of_xlate;
-   ret = omap_mbox_register(mdev);
+   ret = devm_mbox_controller_register(mdev->dev, >controller);
if (ret)
return ret;
 
@@ -809,7 +748,6 @@ static int omap_mbox_probe(struct platform_device *pdev)
 
 unregister:
pm_runtime_disable(mdev->dev);
-   omap_mbox_unregister(mdev);
return ret;
 }
 
@@ -818,7 +756,6 @@ static void omap_mbox_remove(struct platform_device *pdev)
struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
 
pm_runtime_disable(mdev->dev);
-   omap_mbox_unregister(mdev);
 }
 
 static struct platform_driver omap_mbox_driver = {
@@ -830,29 +767,7 @@ static struct platform_driver omap_mbox_driver = {
.of_match_table = of_match_ptr(omap_mailbox_of_match),
},
 };
-
-static int __init omap_mbox_init(void)
-{
-   int err;
-
-   err = class_register(_mbox_class);
-   if (err)
-   return err;
-
-   err = platform_driver_register(_mbox_driver);
-   if (err)
-   class_unregister(_mbox_class);
-
-   return err;
-}
-subsys_initcall(omap_mbox_init);
-
-static void

[PATCH 07/13] mailbox: omap: Use devm_pm_runtime_enable() helper

2024-03-25 Thread Andrew Davis
Use device life-cycle managed runtime enable function to simplify probe
and exit paths.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 18 +++---
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index ea467931faf46..4f956c7b4072c 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -726,11 +726,11 @@ static int omap_mbox_probe(struct platform_device *pdev)
return ret;
 
platform_set_drvdata(pdev, mdev);
-   pm_runtime_enable(mdev->dev);
+   devm_pm_runtime_enable(mdev->dev);
 
ret = pm_runtime_resume_and_get(mdev->dev);
if (ret < 0)
-   goto unregister;
+   return ret;
 
/*
 * just print the raw revision register, the format is not
@@ -741,26 +741,14 @@ static int omap_mbox_probe(struct platform_device *pdev)
 
ret = pm_runtime_put_sync(mdev->dev);
if (ret < 0 && ret != -ENOSYS)
-   goto unregister;
+   return ret;
 
devm_kfree(>dev, finfoblk);
return 0;
-
-unregister:
-   pm_runtime_disable(mdev->dev);
-   return ret;
-}
-
-static void omap_mbox_remove(struct platform_device *pdev)
-{
-   struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
-
-   pm_runtime_disable(mdev->dev);
 }
 
 static struct platform_driver omap_mbox_driver = {
.probe  = omap_mbox_probe,
-   .remove_new = omap_mbox_remove,
.driver = {
.name = "omap-mailbox",
.pm = _mbox_pm_ops,
-- 
2.39.2




[PATCH 04/13] mailbox: omap: Move fifo size check to point of use

2024-03-25 Thread Andrew Davis
The mbox_kfifo_size can be changed at runtime, the sanity
check on it's value should be done when it is used, not
only once at init time.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index c083734b6954c..167348fb1b33b 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -310,6 +310,7 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct 
omap_mbox *mbox,
void (*work)(struct work_struct *))
 {
struct omap_mbox_queue *mq;
+   unsigned int size;
 
if (!work)
return NULL;
@@ -320,7 +321,10 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct 
omap_mbox *mbox,
 
spin_lock_init(>lock);
 
-   if (kfifo_alloc(>fifo, mbox_kfifo_size, GFP_KERNEL))
+   /* kfifo size sanity check: alignment and minimal size */
+   size = ALIGN(mbox_kfifo_size, sizeof(u32));
+   size = max_t(unsigned int, size, sizeof(u32));
+   if (kfifo_alloc(>fifo, size, GFP_KERNEL))
goto error;
 
INIT_WORK(>work, work);
@@ -838,10 +842,6 @@ static int __init omap_mbox_init(void)
if (err)
return err;
 
-   /* kfifo size sanity check: alignment and minimal size */
-   mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(u32));
-   mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(u32));
-
err = platform_driver_register(_mbox_driver);
if (err)
class_unregister(_mbox_class);
-- 
2.39.2




[PATCH 02/13] mailbox: omap: Remove unused omap_mbox_request_channel() function

2024-03-25 Thread Andrew Davis
This function is not used, remove this function.

Signed-off-by: Andrew Davis 
---
 drivers/mailbox/omap-mailbox.c | 36 --
 include/linux/omap-mailbox.h   |  6 --
 2 files changed, 42 deletions(-)

diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 624a7ccc27285..8151722eef383 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -389,42 +389,6 @@ static struct omap_mbox *omap_mbox_device_find(struct 
omap_mbox_device *mdev,
return mbox;
 }
 
-struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
-   const char *chan_name)
-{
-   struct device *dev = cl->dev;
-   struct omap_mbox *mbox = NULL;
-   struct omap_mbox_device *mdev;
-   int ret;
-
-   if (!dev)
-   return ERR_PTR(-ENODEV);
-
-   if (dev->of_node) {
-   pr_err("%s: please use mbox_request_channel(), this API is 
supported only for OMAP non-DT usage\n",
-  __func__);
-   return ERR_PTR(-ENODEV);
-   }
-
-   mutex_lock(_mbox_devices_lock);
-   list_for_each_entry(mdev, _mbox_devices, elem) {
-   mbox = omap_mbox_device_find(mdev, chan_name);
-   if (mbox)
-   break;
-   }
-   mutex_unlock(_mbox_devices_lock);
-
-   if (!mbox || !mbox->chan)
-   return ERR_PTR(-ENOENT);
-
-   ret = mbox_bind_client(mbox->chan, cl);
-   if (ret)
-   return ERR_PTR(ret);
-
-   return mbox->chan;
-}
-EXPORT_SYMBOL(omap_mbox_request_channel);
-
 static struct class omap_mbox_class = { .name = "mbox", };
 
 static int omap_mbox_register(struct omap_mbox_device *mdev)
diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h
index 426a80fb32b5c..f8ddf8e814167 100644
--- a/include/linux/omap-mailbox.h
+++ b/include/linux/omap-mailbox.h
@@ -14,10 +14,4 @@ typedef int __bitwise omap_mbox_irq_t;
 #define IRQ_TX ((__force omap_mbox_irq_t) 1)
 #define IRQ_RX ((__force omap_mbox_irq_t) 2)
 
-struct mbox_chan;
-struct mbox_client;
-
-struct mbox_chan *omap_mbox_request_channel(struct mbox_client *cl,
-   const char *chan_name);
-
 #endif /* OMAP_MAILBOX_H */
-- 
2.39.2




[PATCH 2/3] remoteproc: k3-r5: Fix usage of omap_mbox_message and mbox_msg_t

2024-03-25 Thread Andrew Davis
The type of message sent using omap-mailbox is always u32. The definition
of mbox_msg_t is uintptr_t which is wrong as that type changes based on
the architecture (32bit vs 64bit). Use u32 unconditionally and remove
the now unneeded omap-mailbox.h include.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index ad3415a3851b2..3bcde6d00b56a 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -16,7 +16,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -188,7 +187,7 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
client);
struct device *dev = kproc->rproc->dev.parent;
const char *name = kproc->rproc->name;
-   u32 msg = omap_mbox_message(data);
+   u32 msg = (u32)(uintptr_t)(data);
 
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
 
@@ -222,11 +221,11 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int 
vqid)
 {
struct k3_r5_rproc *kproc = rproc->priv;
struct device *dev = rproc->dev.parent;
-   mbox_msg_t msg = (mbox_msg_t)vqid;
+   u32 msg = vqid;
int ret;
 
/* send the index of the triggered virtqueue in the mailbox payload */
-   ret = mbox_send_message(kproc->mbox, (void *)msg);
+   ret = mbox_send_message(kproc->mbox, (void *)(uintptr_t)msg);
if (ret < 0)
dev_err(dev, "failed to send mailbox message, status = %d\n",
ret);
-- 
2.39.2




[PATCH 3/3] remoteproc: omap: Remove unused header omap-mailbox.h

2024-03-25 Thread Andrew Davis
This header no longer used, remove this include.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/omap_remoteproc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/remoteproc/omap_remoteproc.c 
b/drivers/remoteproc/omap_remoteproc.c
index 8f50ab80e56f4..bde04e3e6d966 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
2.39.2




[PATCH 1/3] remoteproc: k3-dsp: Fix usage of omap_mbox_message and mbox_msg_t

2024-03-25 Thread Andrew Davis
The type of message sent using omap-mailbox is always u32. The definition
of mbox_msg_t is uintptr_t which is wrong as that type changes based on
the architecture (32bit vs 64bit). Use u32 unconditionally and remove
the now unneeded omap-mailbox.h include.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 3555b535b1683..33b30cfb86c9d 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -113,7 +112,7 @@ static void k3_dsp_rproc_mbox_callback(struct mbox_client 
*client, void *data)
  client);
struct device *dev = kproc->rproc->dev.parent;
const char *name = kproc->rproc->name;
-   u32 msg = omap_mbox_message(data);
+   u32 msg = (u32)(uintptr_t)(data);
 
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
 
@@ -152,11 +151,11 @@ static void k3_dsp_rproc_kick(struct rproc *rproc, int 
vqid)
 {
struct k3_dsp_rproc *kproc = rproc->priv;
struct device *dev = rproc->dev.parent;
-   mbox_msg_t msg = (mbox_msg_t)vqid;
+   u32 msg = vqid;
int ret;
 
/* send the index of the triggered virtqueue in the mailbox payload */
-   ret = mbox_send_message(kproc->mbox, (void *)msg);
+   ret = mbox_send_message(kproc->mbox, (void *)(uintptr_t)msg);
if (ret < 0)
dev_err(dev, "failed to send mailbox message (%pe)\n",
ERR_PTR(ret));
-- 
2.39.2




[PATCH v2 2/4] hwspinlock: omap: Use devm_pm_runtime_enable() helper

2024-02-08 Thread Andrew Davis
This disables runtime PM on module exit automatically for us, currently
we manually disable runtime PM which can be error-prone if not done
in the right order or missed in some exit path. This also allows us
to simplify the probe exit path and remove callbacks. Do that here.

While here, as we can now return right after registering our hwspinlock,
simply return directly and remove the extra debug message.

Signed-off-by: Andrew Davis 
---

Changes for v2:
 - Return directly from register as suggested on v1
 - Clarify commit message

 drivers/hwspinlock/omap_hwspinlock.c | 33 +++-
 1 file changed, 8 insertions(+), 25 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c 
b/drivers/hwspinlock/omap_hwspinlock.c
index cca55143d24d4..3bd3ffab92100 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -89,10 +89,10 @@ static int omap_hwspinlock_probe(struct platform_device 
*pdev)
 * make sure the module is enabled and clocked before reading
 * the module SYSSTATUS register
 */
-   pm_runtime_enable(>dev);
+   devm_pm_runtime_enable(>dev);
ret = pm_runtime_resume_and_get(>dev);
if (ret < 0)
-   goto runtime_err;
+   return ret;
 
/* Determine number of locks */
i = readl(io_base + SYSSTATUS_OFFSET);
@@ -104,41 +104,26 @@ static int omap_hwspinlock_probe(struct platform_device 
*pdev)
 */
ret = pm_runtime_put(>dev);
if (ret < 0)
-   goto runtime_err;
+   return ret;
 
/* one of the four lsb's must be set, and nothing else */
-   if (hweight_long(i & 0xf) != 1 || i > 8) {
-   ret = -EINVAL;
-   goto runtime_err;
-   }
+   if (hweight_long(i & 0xf) != 1 || i > 8)
+   return -EINVAL;
 
num_locks = i * 32; /* actual number of locks in this device */
 
bank = devm_kzalloc(>dev, struct_size(bank, lock, num_locks),
GFP_KERNEL);
-   if (!bank) {
-   ret = -ENOMEM;
-   goto runtime_err;
-   }
+   if (!bank)
+   return -ENOMEM;
 
platform_set_drvdata(pdev, bank);
 
for (i = 0, hwlock = >lock[0]; i < num_locks; i++, hwlock++)
hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
-   ret = hwspin_lock_register(bank, >dev, _hwspinlock_ops,
+   return hwspin_lock_register(bank, >dev, _hwspinlock_ops,
base_id, num_locks);
-   if (ret)
-   goto runtime_err;
-
-   dev_dbg(>dev, "Registered %d locks with HwSpinlock core\n",
-   num_locks);
-
-   return 0;
-
-runtime_err:
-   pm_runtime_disable(>dev);
-   return ret;
 }
 
 static void omap_hwspinlock_remove(struct platform_device *pdev)
@@ -151,8 +136,6 @@ static void omap_hwspinlock_remove(struct platform_device 
*pdev)
dev_err(>dev, "%s failed: %d\n", __func__, ret);
return;
}
-
-   pm_runtime_disable(>dev);
 }
 
 static const struct of_device_id omap_hwspinlock_of_match[] = {
-- 
2.39.2




[PATCH v2 3/4] hwspinlock: omap: Use devm_hwspin_lock_register() helper

2024-02-08 Thread Andrew Davis
This will unregister the HW spinlock on module exit automatically for us,
currently we manually unregister which can be error-prone if not done in
the right order. This also allows us to remove the remove callback.
Do that here.

Signed-off-by: Andrew Davis 
---

Changes for v2:
 - Clarify commit message

 drivers/hwspinlock/omap_hwspinlock.c | 17 +
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c 
b/drivers/hwspinlock/omap_hwspinlock.c
index 3bd3ffab92100..fe73da80018b1 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -117,27 +117,13 @@ static int omap_hwspinlock_probe(struct platform_device 
*pdev)
if (!bank)
return -ENOMEM;
 
-   platform_set_drvdata(pdev, bank);
-
for (i = 0, hwlock = >lock[0]; i < num_locks; i++, hwlock++)
hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
-   return hwspin_lock_register(bank, >dev, _hwspinlock_ops,
+   return devm_hwspin_lock_register(>dev, bank, _hwspinlock_ops,
base_id, num_locks);
 }
 
-static void omap_hwspinlock_remove(struct platform_device *pdev)
-{
-   struct hwspinlock_device *bank = platform_get_drvdata(pdev);
-   int ret;
-
-   ret = hwspin_lock_unregister(bank);
-   if (ret) {
-   dev_err(>dev, "%s failed: %d\n", __func__, ret);
-   return;
-   }
-}
-
 static const struct of_device_id omap_hwspinlock_of_match[] = {
{ .compatible = "ti,omap4-hwspinlock", },
{ .compatible = "ti,am64-hwspinlock", },
@@ -148,7 +134,6 @@ MODULE_DEVICE_TABLE(of, omap_hwspinlock_of_match);
 
 static struct platform_driver omap_hwspinlock_driver = {
.probe  = omap_hwspinlock_probe,
-   .remove_new = omap_hwspinlock_remove,
.driver = {
.name   = "omap_hwspinlock",
.of_match_table = omap_hwspinlock_of_match,
-- 
2.39.2




[PATCH v2 1/4] hwspinlock: omap: Remove unneeded check for OF node

2024-02-08 Thread Andrew Davis
We do not use the OF node anymore, nor does it matter how
we got to probe, so remove the check for of_node.

Signed-off-by: Andrew Davis 
---
 drivers/hwspinlock/omap_hwspinlock.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c 
b/drivers/hwspinlock/omap_hwspinlock.c
index a9fd9ca45f2a8..cca55143d24d4 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -74,7 +74,6 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 
 static int omap_hwspinlock_probe(struct platform_device *pdev)
 {
-   struct device_node *node = pdev->dev.of_node;
struct hwspinlock_device *bank;
struct hwspinlock *hwlock;
void __iomem *io_base;
@@ -82,9 +81,6 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
/* Only a single hwspinlock block device is supported */
int base_id = 0;
 
-   if (!node)
-   return -ENODEV;
-
io_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(io_base))
return PTR_ERR(io_base);
-- 
2.39.2




[PATCH v2 4/4] hwspinlock: omap: Use index to get hwspinlock pointer

2024-02-08 Thread Andrew Davis
For loops with multiple initializers and increments are hard to read
and reason about, simplify this by using the looping index to index
into the hwspinlock array.

Signed-off-by: Andrew Davis 
---
 drivers/hwspinlock/omap_hwspinlock.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c 
b/drivers/hwspinlock/omap_hwspinlock.c
index fe73da80018b1..27b47b8623c09 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -75,7 +75,6 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 static int omap_hwspinlock_probe(struct platform_device *pdev)
 {
struct hwspinlock_device *bank;
-   struct hwspinlock *hwlock;
void __iomem *io_base;
int num_locks, i, ret;
/* Only a single hwspinlock block device is supported */
@@ -117,8 +116,8 @@ static int omap_hwspinlock_probe(struct platform_device 
*pdev)
if (!bank)
return -ENOMEM;
 
-   for (i = 0, hwlock = >lock[0]; i < num_locks; i++, hwlock++)
-   hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
+   for (i = 0; i < num_locks; i++)
+   bank->lock[i].priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * 
i;
 
return devm_hwspin_lock_register(>dev, bank, _hwspinlock_ops,
base_id, num_locks);
-- 
2.39.2




Re: [PATCH 2/4] hwspinlock: omap: Use devm_pm_runtime_enable() helper

2024-02-06 Thread Andrew Davis

On 2/6/24 1:06 PM, Bjorn Andersson wrote:

On Tue, Jan 23, 2024 at 10:04:03AM -0600, Andrew Davis wrote:

This disables runtime PM on module exit, allowing us to simplify
the probe exit path and remove callbacks. Do that here.


As with the later patch, unless I'm misreading the code, you already do
disable runtime PM in omap_hwspinlock_remove().



Right, what I meant to say in the commit message was

"This disables runtime PM on module exit *automatically for us*.."

As in we don't have to manually do it anymore, and that simplifies
the code, which is the "fix" that this patch does.

Will update the commit message to make that more clear in this
and the next patch.



Signed-off-by: Andrew Davis 
---
  drivers/hwspinlock/omap_hwspinlock.c | 26 --
  1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c 
b/drivers/hwspinlock/omap_hwspinlock.c

[..]

@@ -129,16 +125,12 @@ static int omap_hwspinlock_probe(struct platform_device 
*pdev)
ret = hwspin_lock_register(bank, >dev, _hwspinlock_ops,
base_id, num_locks);
if (ret)
-   goto runtime_err;
+   return ret;
  
  	dev_dbg(>dev, "Registered %d locks with HwSpinlock core\n",

num_locks);


I don't fancy these debug information messages, there are other ways to
confirm that the device probed successfully etc.

Now that you don't need the goto runtime_err, I'd prefer the tail of
this function:

return hwspin_lock_register(...);



Sure, will update.

Thanks,
Andrew


Regards,
Bjorn

  
  	return 0;

-
-runtime_err:
-   pm_runtime_disable(>dev);
-   return ret;
  }
  
  static void omap_hwspinlock_remove(struct platform_device *pdev)

@@ -151,8 +143,6 @@ static void omap_hwspinlock_remove(struct platform_device 
*pdev)
dev_err(>dev, "%s failed: %d\n", __func__, ret);
return;
}
-
-   pm_runtime_disable(>dev);
  }
  
  static const struct of_device_id omap_hwspinlock_of_match[] = {

--
2.39.2





Re: [PATCH v7 3/5] remoteproc: k3: Move out functions common with M4 driver

2024-02-05 Thread Andrew Davis

On 2/2/24 11:55 AM, Hari Nagalla wrote:

From: Martyn Welch 

In the next commit we will be adding the M4F driver which shares a lot of
commonality with the DSP driver. Move this shared functionality out so
that it can be used by both drivers.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
---
Changes since v2:
  - New patch (reordered refactored from v2)

Changes since v3:
  - Removed "ipc_only" element from k3_rproc structure
  - Refactored to bring 3 more common functions

Changes since v4:
  - None

Changes since v5:
  - Rearranged the functions order to match with the functions in
ti_k3_dsp_remoteproc.c to ease review.

Changes since v6:
  - Generated patch with -M/-B/-C options



You where asked to generate this patch "correctly" with these options,
not just use them all and hope for the best.. Now it looks like you
re-wrote all of ti_k3_dsp_remoteproc.c when you only factored out
a couple functions to a different file.

Build up the new ti_k3_common.c one function per patch if it helps.
And factor the functions out of ti_k3_r5 also as it seems many
of these are common to that driver too.

Andrew


link to v6:
https://lore.kernel.org/all/20230913111644.29889-4-hnaga...@ti.com/

  drivers/remoteproc/Makefile   |2 +-
  drivers/remoteproc/ti_k3_common.c |  583 ++
  drivers/remoteproc/ti_k3_dsp_remoteproc.c | 1277 ++---
  3 files changed, 952 insertions(+), 910 deletions(-)
  create mode 100644 drivers/remoteproc/ti_k3_common.c
  rewrite drivers/remoteproc/ti_k3_dsp_remoteproc.c (67%)

diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43ce..55c552e27a45 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -36,6 +36,6 @@ obj-$(CONFIG_RCAR_REMOTEPROC) += rcar_rproc.o
  obj-$(CONFIG_ST_REMOTEPROC)   += st_remoteproc.o
  obj-$(CONFIG_ST_SLIM_REMOTEPROC)  += st_slim_rproc.o
  obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
-obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
+obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o ti_k3_common.o
  obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
  obj-$(CONFIG_XLNX_R5_REMOTEPROC)  += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_common.c 
b/drivers/remoteproc/ti_k3_common.c
new file mode 100644
index ..62c7c5dba78a
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_common.c
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored from ti_k3_dsp_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Suman Anna 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+#include "ti_k3_common.h"
+
+/**
+ * k3_rproc_mbox_callback() - inbound mailbox message handler
+ * @client: mailbox client pointer used for requesting the mailbox channel
+ * @data: mailbox payload
+ *
+ * This handler is invoked by the K3 mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let remoteproc core handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicate different events. Those values are deliberately very
+ * large so they don't coincide with virtqueue indices.
+ */
+static void k3_rproc_mbox_callback(struct mbox_client *client, void *data)
+{
+   struct k3_rproc *kproc = container_of(client, struct k3_rproc,
+ client);
+   struct device *dev = kproc->rproc->dev.parent;
+   const char *name = kproc->rproc->name;
+   u32 msg = omap_mbox_message(data);
+
+   dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+
+   switch (msg) {
+   case RP_MBOX_CRASH:
+   /*
+* remoteproc detected an exception, but error recovery is not
+* supported. So, just log this for now
+*/
+   dev_err(dev, "K3 rproc %s crashed\n", name);
+   break;
+   case RP_MBOX_ECHO_REPLY:
+   dev_info(dev, "received echo reply from %s\n", name);
+   break;
+   default:
+   /* silently handle all other valid messages */
+   if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
+   return;
+   if (msg > kproc->rproc->max_notifyid) {
+   dev_dbg(dev, "dropping unknown message 0x%x", msg);
+   return;
+   }
+   /* msg contains the index of the triggered vring */
+   if (rproc_vq_interrupt(kproc->rproc, msg) == IRQ_NONE)

Re: [PATCH v7 2/5] remoteproc: k3: Move out data structures common with M4 driver

2024-02-05 Thread Andrew Davis

On 2/2/24 11:55 AM, Hari Nagalla wrote:

From: Martyn Welch 

We will be adding the M4F driver which shares a lot of commonality
with the DSP driver. Common data structures are introduced here.

Signed-off-by: Martyn Welch 
Signed-off-by: Hari Nagalla 
---
Changes since v5:
  - Created a separate patch for data structures to ease review

Changes since v6:
  - Reworded 'split' to 'move' as the common data structures between
DSP and M4 remote rpoc drivers are moved into common driver.



Is this a joke? In v6 Krzysztof commented the following:


Where is the split? I see only addition here.

Where is the usage of this header? This is basically dead code. Don't
add dead code, but instead actually move the structures here! Move is
cut and paste, not just paste.


Instead of changing the patch in any way to address this comment you
just replaced the word 'split' to 'move' in the commit subject.. Maybe
no one will notice this is all still dead code since you didn't say the
word 'split' anymore..

Andrew


link to v6:
https://lore.kernel.org/all/20230913111644.29889-3-hnaga...@ti.com/

  drivers/remoteproc/ti_k3_common.h | 107 ++
  1 file changed, 107 insertions(+)
  create mode 100644 drivers/remoteproc/ti_k3_common.h

diff --git a/drivers/remoteproc/ti_k3_common.h 
b/drivers/remoteproc/ti_k3_common.h
new file mode 100644
index ..f1bab83dd0fc
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_common.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored from ti_k3_dsp_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Suman Anna 
+ */
+
+#ifndef REMOTEPROC_TI_K3_COMMON_H
+#define REMOTEPROC_TI_K3_COMMON_H
+
+#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK  (SZ_16M - 1)
+
+/**
+ * struct k3_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_rproc_mem {
+   void __iomem *cpu_addr;
+   phys_addr_t bus_addr;
+   u32 dev_addr;
+   size_t size;
+};
+
+/**
+ * struct k3_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_rproc_mem_data {
+   const char *name;
+   const u32 dev_addr;
+};
+
+/**
+ * struct k3_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @boot_align_addr: boot vector address alignment granularity
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_rproc_dev_data {
+   const struct k3_rproc_mem_data *mems;
+   u32 num_mems;
+   u32 boot_align_addr;
+   bool uses_lreset;
+};
+
+/**
+ * struct k3_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: number of internal memory regions
+ * @rmem: reserved memory regions data
+ * @num_rmems: number of reserved memory regions
+ * @reset: reset control handle
+ * @data: pointer to device data
+ * @tsp: TI-SCI processor control handle
+ * @ti_sci: TI-SCI handle
+ * @ti_sci_id: TI-SCI device identifier
+ * @mbox: mailbox channel handle
+ * @client: mailbox client to request the mailbox channel
+ */
+struct k3_rproc {
+   struct device *dev;
+   struct rproc *rproc;
+   struct k3_rproc_mem *mem;
+   int num_mems;
+   struct k3_rproc_mem *sram;
+   int num_sram;
+   struct k3_rproc_mem *rmem;
+   int num_rmems;
+   struct reset_control *reset;
+   const struct k3_rproc_dev_data *data;
+   struct ti_sci_proc *tsp;
+   const struct ti_sci_handle *ti_sci;
+   u32 ti_sci_id;
+   struct mbox_chan *mbox;
+   struct mbox_client client;
+};
+
+void k3_rproc_kick(struct rproc *rproc, int vqid);
+int k3_rproc_reset(struct k3_rproc *kproc);
+int k3_rproc_release(struct k3_rproc *kproc);
+int k3_rproc_request_mbox(struct rproc *rproc);
+int k3_rproc_prepare(struct rproc *rproc);
+int k3_rproc_unprepare(struct rproc *rproc);
+struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
+  size_t *rsc_table_sz);
+void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len,
+   bool *is_iomem);
+int k3_rproc_of_get_memories(struct platform_device *pdev,
+struct k3_rproc *kproc);
+int k3_rproc_of_get_sram_memories(struct platform_device *pdev,
+struct k3_rproc *kproc);
+int k3_reserved_mem_init(struct k3_rproc *kproc);
+void 

[PATCH v2 4/5] remoteproc: k3-dsp: Use devm_ioremap_wc() helper

2024-02-05 Thread Andrew Davis
Use a device lifecycle managed ioremap helper function. This helps prevent
mistakes like unmapping out of order in cleanup functions and forgetting
to unmap on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 48 +--
 1 file changed, 10 insertions(+), 38 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 800c8c6767086..f799f74734b4a 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -598,16 +598,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
-   if (!rmem_np) {
-   ret = -EINVAL;
-   goto unmap_rmem;
-   }
+   if (!rmem_np)
+   return -EINVAL;
 
rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) {
of_node_put(rmem_np);
-   ret = -EINVAL;
-   goto unmap_rmem;
+   return -EINVAL;
}
of_node_put(rmem_np);
 
@@ -615,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
/* 64-bit address regions currently not supported */
kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size;
-   kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
+   kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, 
rmem->size);
if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa 
of size %pa\n",
i + 1, >base, >size);
-   ret = -ENOMEM;
-   goto unmap_rmem;
+   return -ENOMEM;
}
 
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK 
da 0x%x\n",
@@ -631,19 +627,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
kproc->num_rmems = num_rmems;
 
return 0;
-
-unmap_rmem:
-   for (i--; i >= 0; i--)
-   iounmap(kproc->rmem[i].cpu_addr);
-   return ret;
-}
-
-static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc)
-{
-   int i;
-
-   for (i = 0; i < kproc->num_rmems; i++)
-   iounmap(kproc->rmem[i].cpu_addr);
 }
 
 static void k3_dsp_release_tsp(void *data)
@@ -752,10 +735,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
   NULL, _state);
-   if (ret) {
-   dev_err_probe(dev, ret, "failed to get initial state, mode 
cannot be determined\n");
-   goto release_mem;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "failed to get initial state, 
mode cannot be determined\n");
 
/* configure J721E devices for either remoteproc or IPC-only mode */
if (p_state) {
@@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (data->uses_lreset) {
ret = reset_control_status(kproc->reset);
if (ret < 0) {
-   dev_err_probe(dev, ret, "failed to get reset 
status\n");
-   goto release_mem;
+   return dev_err_probe(dev, ret, "failed to get 
reset status\n");
} else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for 
device\n");
k3_dsp_rproc_reset(kproc);
@@ -789,18 +769,12 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
}
 
ret = rproc_add(rproc);
-   if (ret) {
-   dev_err_probe(dev, ret, "failed to add register device with 
remoteproc core\n");
-   goto release_mem;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "failed to add register device 
with remoteproc core\n");
 
platform_set_drvdata(pdev, kproc);
 
return 0;
-
-release_mem:
-   k3_dsp_reserved_mem_exit(kproc);
-   return ret;
 }
 
 static void k3_dsp_rproc_remove(struct platform_device *pdev)
@@ -820,8 +794,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
}
 
rproc_del(kproc->rproc);
-
-   k3_dsp_reserved_mem_exit(kproc);
 }
 
 static const struct k3_dsp_mem_data c66_mems[] = {
-- 
2.39.2




[PATCH v2 5/5] remoteproc: k3-dsp: Use devm_rproc_add() helper

2024-02-05 Thread Andrew Davis
Use device lifecycle managed devm_rproc_add() helper function. This helps
prevent mistakes like deleting out of order in cleanup functions and
forgetting to delete on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index f799f74734b4a..3555b535b1683 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -768,7 +768,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
}
}
 
-   ret = rproc_add(rproc);
+   ret = devm_rproc_add(dev, rproc);
if (ret)
return dev_err_probe(dev, ret, "failed to add register device 
with remoteproc core\n");
 
@@ -786,14 +786,9 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
if (rproc->state == RPROC_ATTACHED) {
ret = rproc_detach(rproc);
-   if (ret) {
-   /* Note this error path leaks resources */
+   if (ret)
dev_err(dev, "failed to detach proc (%pe)\n", 
ERR_PTR(ret));
-   return;
-   }
}
-
-   rproc_del(kproc->rproc);
 }
 
 static const struct k3_dsp_mem_data c66_mems[] = {
-- 
2.39.2




[PATCH v2 2/5] remoteproc: k3-dsp: Use devm_kzalloc() helper

2024-02-05 Thread Andrew Davis
Use device lifecycle managed devm_kzalloc() helper function. This helps
prevent mistakes like freeing out of order in cleanup functions and
forgetting to free on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 64ec5759c4ec1..b9332c66a52ab 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -659,7 +659,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device 
*dev,
if (ret < 0)
return ERR_PTR(ret);
 
-   tsp = kzalloc(sizeof(*tsp), GFP_KERNEL);
+   tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
 
@@ -730,7 +730,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
-   goto free_tsp;
+   return ret;
}
 
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
@@ -797,8 +797,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
ret1 = ti_sci_proc_release(kproc->tsp);
if (ret1)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
-free_tsp:
-   kfree(kproc->tsp);
return ret;
 }
 
@@ -824,8 +822,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
if (ret)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
 
-   kfree(kproc->tsp);
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




[PATCH v2 3/5] remoteproc: k3-dsp: Add devm action to release tsp

2024-02-05 Thread Andrew Davis
Use a device lifecycle managed action to release tps ti_sci_proc handle.
This helps prevent mistakes like releasing out of order in cleanup
functions and forgetting to release on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 27 +++
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index b9332c66a52ab..800c8c6767086 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -646,6 +646,13 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc 
*kproc)
iounmap(kproc->rmem[i].cpu_addr);
 }
 
+static void k3_dsp_release_tsp(void *data)
+{
+   struct ti_sci_proc *tsp = data;
+
+   ti_sci_proc_release(tsp);
+}
+
 static
 struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
const struct ti_sci_handle *sci)
@@ -682,7 +689,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
const char *fw_name;
bool p_state = false;
int ret = 0;
-   int ret1;
 
data = of_device_get_match_data(dev);
if (!data)
@@ -732,16 +738,17 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
return ret;
}
+   ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);
+   if (ret)
+   return ret;
 
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret)
-   goto release_tsp;
+   return ret;
 
ret = k3_dsp_reserved_mem_init(kproc);
-   if (ret) {
-   dev_err_probe(dev, ret, "reserved memory init failed\n");
-   goto release_tsp;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "reserved memory init failed\n");
 
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
   NULL, _state);
@@ -793,10 +800,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 
 release_mem:
k3_dsp_reserved_mem_exit(kproc);
-release_tsp:
-   ret1 = ti_sci_proc_release(kproc->tsp);
-   if (ret1)
-   dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
return ret;
 }
 
@@ -818,10 +821,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
rproc_del(kproc->rproc);
 
-   ret = ti_sci_proc_release(kproc->tsp);
-   if (ret)
-   dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




[PATCH v2 0/5] K3 DSP Remoteproc remove cleanup

2024-02-05 Thread Andrew Davis
Hello all,

This series uses various devm_ helpers to simplify the device
removal path.

Removing an unused var "ret1" got squashed into the wrong patch in
the v1 series causing a bisectability error. v2 is based on -next
with the first 3 already taken. These are the last 5 patches of the
v1 series[0].

Thanks,
Andrew

[0] https://lore.kernel.org/lkml/20240123184913.725435-4-...@ti.com/T/

Andrew Davis (5):
  remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper
  remoteproc: k3-dsp: Use devm_kzalloc() helper
  remoteproc: k3-dsp: Add devm action to release tsp
  remoteproc: k3-dsp: Use devm_ioremap_wc() helper
  remoteproc: k3-dsp: Use devm_rproc_add() helper

 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 116 ++
 1 file changed, 32 insertions(+), 84 deletions(-)

-- 
2.39.2




[PATCH v2 1/5] remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper

2024-02-05 Thread Andrew Davis
Use the device lifecycle managed TI-SCI get() function. This helps prevent
mistakes like not put()'ing in the wrong order in cleanup functions and
forgetting to put() on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 32 +++
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index a13552c71f440..64ec5759c4ec1 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -708,30 +708,24 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
kproc->dev = dev;
kproc->data = data;
 
-   kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
+   kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci))
return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
 "failed to get ti-sci handle\n");
 
ret = of_property_read_u32(np, "ti,sci-dev-id", >ti_sci_id);
-   if (ret) {
-   dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
-   goto put_sci;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' 
property\n");
 
kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
-   if (IS_ERR(kproc->reset)) {
-   ret = dev_err_probe(dev, PTR_ERR(kproc->reset),
-   "failed to get reset\n");
-   goto put_sci;
-   }
+   if (IS_ERR(kproc->reset))
+   return dev_err_probe(dev, PTR_ERR(kproc->reset),
+"failed to get reset\n");
 
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
-   if (IS_ERR(kproc->tsp)) {
-   ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
-   "failed to construct ti-sci proc 
control\n");
-   goto put_sci;
-   }
+   if (IS_ERR(kproc->tsp))
+   return dev_err_probe(dev, PTR_ERR(kproc->tsp),
+"failed to construct ti-sci proc 
control\n");
 
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
@@ -805,10 +799,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
 free_tsp:
kfree(kproc->tsp);
-put_sci:
-   ret1 = ti_sci_put_handle(kproc->ti_sci);
-   if (ret1)
-   dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret1));
return ret;
 }
 
@@ -836,10 +826,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
kfree(kproc->tsp);
 
-   ret = ti_sci_put_handle(kproc->ti_sci);
-   if (ret)
-   dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret));
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




Re: [PATCH 6/9] remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc() helper

2024-02-02 Thread Andrew Davis

On 2/2/24 2:51 PM, Unnathi Chalicheemala wrote:



On 1/23/2024 10:46 AM, Andrew Davis wrote:

Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
  drivers/remoteproc/qcom_q6v5_wcss.c | 24 +---
  1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index cff1fa07d1def..94f68c919ee62 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
  
-	rproc = rproc_alloc(>dev, pdev->name, desc->ops,

-   desc->firmware_name, sizeof(*wcss));
+   rproc = devm_rproc_alloc(>dev, pdev->name, desc->ops,
+desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(>dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
  
  	ret = q6v5_wcss_init_mmio(wcss, pdev);

if (ret)
-   goto free_rproc;
+   return ret;
  
  	ret = q6v5_alloc_memory_region(wcss);

if (ret)
-   goto free_rproc;
+   return ret;
  
  	if (wcss->version == WCSS_QCS404) {

ret = q6v5_wcss_init_clock(wcss);
if (ret)
-   goto free_rproc;
+   return ret;
  
  		ret = q6v5_wcss_init_regulator(wcss);

if (ret)
-   goto free_rproc;
+   return ret;
}
  
  	ret = q6v5_wcss_init_reset(wcss, desc);

if (ret)
-   goto free_rproc;
+   return ret;
  
  	ret = qcom_q6v5_init(>q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);

if (ret)
-   goto free_rproc;
+   return ret;
  
  	qcom_add_glink_subdev(rproc, >glink_subdev, "q6wcss");

qcom_add_ssr_subdev(rproc, >ssr_subdev, "q6wcss");
@@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
  
  	ret = rproc_add(rproc);

if (ret)
-   goto free_rproc;
+   return ret;
  
  	platform_set_drvdata(pdev, rproc);
  
  	return 0;

-
-free_rproc:
-   rproc_free(rproc);
-
-   return ret;


This return statement should stay, right?



No path goes to "free_rproc" anymore, so we always do the "return 0;"
above on non-error paths.

Andrew


  }
  
  static void q6v5_wcss_remove(struct platform_device *pdev)

@@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
  
  	qcom_q6v5_deinit(>q6v5);

rproc_del(rproc);
-   rproc_free(rproc);
  }
  
  static const struct wcss_data wcss_ipq8074_res_init = {




[PATCH 5/8] remoteproc: k3-dsp: Use devm_kzalloc() helper

2024-01-23 Thread Andrew Davis
Use device lifecycle managed devm_kzalloc() helper function. This helps
prevent mistakes like freeing out of order in cleanup functions and
forgetting to free on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 0240340a83e90..2aac25d013985 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -659,7 +659,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device 
*dev,
if (ret < 0)
return ERR_PTR(ret);
 
-   tsp = kzalloc(sizeof(*tsp), GFP_KERNEL);
+   tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
 
@@ -729,7 +729,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
-   goto free_tsp;
+   return ret;
}
 
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
@@ -796,8 +796,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
ret1 = ti_sci_proc_release(kproc->tsp);
if (ret1)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
-free_tsp:
-   kfree(kproc->tsp);
return ret;
 }
 
@@ -823,8 +821,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
if (ret)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
 
-   kfree(kproc->tsp);
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




[PATCH 8/8] remoteproc: k3-dsp: Use devm_rproc_add() helper

2024-01-23 Thread Andrew Davis
Use device lifecycle managed devm_rproc_add() helper function. This helps
prevent mistakes like deleting out of order in cleanup functions and
forgetting to delete on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index f799f74734b4a..3555b535b1683 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -768,7 +768,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
}
}
 
-   ret = rproc_add(rproc);
+   ret = devm_rproc_add(dev, rproc);
if (ret)
return dev_err_probe(dev, ret, "failed to add register device 
with remoteproc core\n");
 
@@ -786,14 +786,9 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
if (rproc->state == RPROC_ATTACHED) {
ret = rproc_detach(rproc);
-   if (ret) {
-   /* Note this error path leaks resources */
+   if (ret)
dev_err(dev, "failed to detach proc (%pe)\n", 
ERR_PTR(ret));
-   return;
-   }
}
-
-   rproc_del(kproc->rproc);
 }
 
 static const struct k3_dsp_mem_data c66_mems[] = {
-- 
2.39.2




[PATCH 6/8] remoteproc: k3-dsp: Add devm action to release tsp

2024-01-23 Thread Andrew Davis
Use a device lifecycle managed action to release tps ti_sci_proc handle.
This helps prevent mistakes like releasing out of order in cleanup
functions and forgetting to release on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 26 +++
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 2aac25d013985..800c8c6767086 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -646,6 +646,13 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc 
*kproc)
iounmap(kproc->rmem[i].cpu_addr);
 }
 
+static void k3_dsp_release_tsp(void *data)
+{
+   struct ti_sci_proc *tsp = data;
+
+   ti_sci_proc_release(tsp);
+}
+
 static
 struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
const struct ti_sci_handle *sci)
@@ -731,16 +738,17 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
return ret;
}
+   ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);
+   if (ret)
+   return ret;
 
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret)
-   goto release_tsp;
+   return ret;
 
ret = k3_dsp_reserved_mem_init(kproc);
-   if (ret) {
-   dev_err_probe(dev, ret, "reserved memory init failed\n");
-   goto release_tsp;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "reserved memory init failed\n");
 
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
   NULL, _state);
@@ -792,10 +800,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 
 release_mem:
k3_dsp_reserved_mem_exit(kproc);
-release_tsp:
-   ret1 = ti_sci_proc_release(kproc->tsp);
-   if (ret1)
-   dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
return ret;
 }
 
@@ -817,10 +821,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
rproc_del(kproc->rproc);
 
-   ret = ti_sci_proc_release(kproc->tsp);
-   if (ret)
-   dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




[PATCH 7/8] remoteproc: k3-dsp: Use devm_ioremap_wc() helper

2024-01-23 Thread Andrew Davis
Use a device lifecycle managed ioremap helper function. This helps prevent
mistakes like unmapping out of order in cleanup functions and forgetting
to unmap on all error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 48 +--
 1 file changed, 10 insertions(+), 38 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 800c8c6767086..f799f74734b4a 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -598,16 +598,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
-   if (!rmem_np) {
-   ret = -EINVAL;
-   goto unmap_rmem;
-   }
+   if (!rmem_np)
+   return -EINVAL;
 
rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) {
of_node_put(rmem_np);
-   ret = -EINVAL;
-   goto unmap_rmem;
+   return -EINVAL;
}
of_node_put(rmem_np);
 
@@ -615,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
/* 64-bit address regions currently not supported */
kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size;
-   kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
+   kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, 
rmem->size);
if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa 
of size %pa\n",
i + 1, >base, >size);
-   ret = -ENOMEM;
-   goto unmap_rmem;
+   return -ENOMEM;
}
 
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK 
da 0x%x\n",
@@ -631,19 +627,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
kproc->num_rmems = num_rmems;
 
return 0;
-
-unmap_rmem:
-   for (i--; i >= 0; i--)
-   iounmap(kproc->rmem[i].cpu_addr);
-   return ret;
-}
-
-static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc)
-{
-   int i;
-
-   for (i = 0; i < kproc->num_rmems; i++)
-   iounmap(kproc->rmem[i].cpu_addr);
 }
 
 static void k3_dsp_release_tsp(void *data)
@@ -752,10 +735,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
 
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
   NULL, _state);
-   if (ret) {
-   dev_err_probe(dev, ret, "failed to get initial state, mode 
cannot be determined\n");
-   goto release_mem;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "failed to get initial state, 
mode cannot be determined\n");
 
/* configure J721E devices for either remoteproc or IPC-only mode */
if (p_state) {
@@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (data->uses_lreset) {
ret = reset_control_status(kproc->reset);
if (ret < 0) {
-   dev_err_probe(dev, ret, "failed to get reset 
status\n");
-   goto release_mem;
+   return dev_err_probe(dev, ret, "failed to get 
reset status\n");
} else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for 
device\n");
k3_dsp_rproc_reset(kproc);
@@ -789,18 +769,12 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
}
 
ret = rproc_add(rproc);
-   if (ret) {
-   dev_err_probe(dev, ret, "failed to add register device with 
remoteproc core\n");
-   goto release_mem;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "failed to add register device 
with remoteproc core\n");
 
platform_set_drvdata(pdev, kproc);
 
return 0;
-
-release_mem:
-   k3_dsp_reserved_mem_exit(kproc);
-   return ret;
 }
 
 static void k3_dsp_rproc_remove(struct platform_device *pdev)
@@ -820,8 +794,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
}
 
rproc_del(kproc->rproc);
-
-   k3_dsp_reserved_mem_exit(kproc);
 }
 
 static const struct k3_dsp_mem_data c66_mems[] = {
-- 
2.39.2




[PATCH 4/8] remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed TI-SCI get() function. This helps prevent
mistakes like not put()'ing in the wrong order in cleanup functions and
forgetting to put() on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 33 +++
 1 file changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index a13552c71f440..0240340a83e90 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -682,7 +682,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
const char *fw_name;
bool p_state = false;
int ret = 0;
-   int ret1;
 
data = of_device_get_match_data(dev);
if (!data)
@@ -708,30 +707,24 @@ static int k3_dsp_rproc_probe(struct platform_device 
*pdev)
kproc->dev = dev;
kproc->data = data;
 
-   kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
+   kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci))
return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
 "failed to get ti-sci handle\n");
 
ret = of_property_read_u32(np, "ti,sci-dev-id", >ti_sci_id);
-   if (ret) {
-   dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
-   goto put_sci;
-   }
+   if (ret)
+   return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' 
property\n");
 
kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
-   if (IS_ERR(kproc->reset)) {
-   ret = dev_err_probe(dev, PTR_ERR(kproc->reset),
-   "failed to get reset\n");
-   goto put_sci;
-   }
+   if (IS_ERR(kproc->reset))
+   return dev_err_probe(dev, PTR_ERR(kproc->reset),
+"failed to get reset\n");
 
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
-   if (IS_ERR(kproc->tsp)) {
-   ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
-   "failed to construct ti-sci proc 
control\n");
-   goto put_sci;
-   }
+   if (IS_ERR(kproc->tsp))
+   return dev_err_probe(dev, PTR_ERR(kproc->tsp),
+"failed to construct ti-sci proc 
control\n");
 
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
@@ -805,10 +798,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
 free_tsp:
kfree(kproc->tsp);
-put_sci:
-   ret1 = ti_sci_put_handle(kproc->ti_sci);
-   if (ret1)
-   dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret1));
return ret;
 }
 
@@ -836,10 +825,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
 
kfree(kproc->tsp);
 
-   ret = ti_sci_put_handle(kproc->ti_sci);
-   if (ret)
-   dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret));
-
k3_dsp_reserved_mem_exit(kproc);
 }
 
-- 
2.39.2




[PATCH 3/8] remoteproc: k3-dsp: Use devm_kcalloc() helper

2024-01-23 Thread Andrew Davis
Use a device lifecycle managed action to free memory. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 0cb00146fe977..a13552c71f440 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -591,7 +591,7 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
return ret;
 
num_rmems--;
-   kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
+   kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), 
GFP_KERNEL);
if (!kproc->rmem)
return -ENOMEM;
 
@@ -635,7 +635,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
 unmap_rmem:
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
-   kfree(kproc->rmem);
return ret;
 }
 
@@ -645,7 +644,6 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc 
*kproc)
 
for (i = 0; i < kproc->num_rmems; i++)
iounmap(kproc->rmem[i].cpu_addr);
-   kfree(kproc->rmem);
 }
 
 static
-- 
2.39.2




[PATCH 2/8] remoteproc: k3-dsp: Add devm action to release reserved memory

2024-01-23 Thread Andrew Davis
Use a device lifecycle managed action to release reserved memory. This
helps prevent mistakes like releasing out of order in cleanup functions
and forgetting to release on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 93fbc89307d6a..0cb00146fe977 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct 
platform_device *pdev,
return 0;
 }
 
+static void k3_dsp_mem_release(void *data)
+{
+   struct device *dev = data;
+
+   of_reserved_mem_device_release(dev);
+}
+
 static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
 {
struct device *dev = kproc->dev;
@@ -579,13 +586,14 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
ERR_PTR(ret));
return ret;
}
+   ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);
+   if (ret)
+   return ret;
 
num_rmems--;
kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
-   if (!kproc->rmem) {
-   ret = -ENOMEM;
-   goto release_rmem;
-   }
+   if (!kproc->rmem)
+   return -ENOMEM;
 
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
@@ -628,8 +636,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc 
*kproc)
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
-release_rmem:
-   of_reserved_mem_device_release(kproc->dev);
return ret;
 }
 
@@ -640,8 +646,6 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc 
*kproc)
for (i = 0; i < kproc->num_rmems; i++)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
-
-   of_reserved_mem_device_release(kproc->dev);
 }
 
 static
-- 
2.39.2




[PATCH 1/8] remoteproc: k3-dsp: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index ab882e3b7130b..93fbc89307d6a 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -690,8 +690,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to parse firmware-name 
property\n");
 
-   rproc = rproc_alloc(dev, dev_name(dev), _dsp_rproc_ops, fw_name,
-   sizeof(*kproc));
+   rproc = devm_rproc_alloc(dev, dev_name(dev), _dsp_rproc_ops,
+fw_name, sizeof(*kproc));
if (!rproc)
return -ENOMEM;
 
@@ -707,12 +707,9 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
kproc->data = data;
 
kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
-   if (IS_ERR(kproc->ti_sci)) {
-   ret = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
-   "failed to get ti-sci handle\n");
-   kproc->ti_sci = NULL;
-   goto free_rproc;
-   }
+   if (IS_ERR(kproc->ti_sci))
+   return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
+"failed to get ti-sci handle\n");
 
ret = of_property_read_u32(np, "ti,sci-dev-id", >ti_sci_id);
if (ret) {
@@ -810,8 +807,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
ret1 = ti_sci_put_handle(kproc->ti_sci);
if (ret1)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret1));
-free_rproc:
-   rproc_free(rproc);
return ret;
 }
 
@@ -844,7 +839,6 @@ static void k3_dsp_rproc_remove(struct platform_device 
*pdev)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", 
ERR_PTR(ret));
 
k3_dsp_reserved_mem_exit(kproc);
-   rproc_free(kproc->rproc);
 }
 
 static const struct k3_dsp_mem_data c66_mems[] = {
-- 
2.39.2




[PATCH 9/9] remoteproc: stm32: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/stm32_rproc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 4f469f0bcf8b2..fed0866de1819 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   rproc = rproc_alloc(dev, np->name, _rproc_ops, NULL, sizeof(*ddata));
+   rproc = devm_rproc_alloc(dev, np->name, _rproc_ops, NULL, 
sizeof(*ddata));
if (!rproc)
return -ENOMEM;
 
@@ -897,7 +897,6 @@ static int stm32_rproc_probe(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
-   rproc_free(rproc);
return ret;
 }
 
@@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
-   rproc_free(rproc);
 }
 
 static int stm32_rproc_suspend(struct device *dev)
-- 
2.39.2




[PATCH 2/9] remoteproc: imx_rproc: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/imx_rproc.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 8bb293b9f327c..55ecce3ab5f75 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -1104,16 +1104,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
int ret;
 
/* set some other name then imx */
-   rproc = rproc_alloc(dev, "imx-rproc", _rproc_ops,
-   NULL, sizeof(*priv));
+   rproc = devm_rproc_alloc(dev, "imx-rproc", _rproc_ops,
+NULL, sizeof(*priv));
if (!rproc)
return -ENOMEM;
 
dcfg = of_device_get_match_data(dev);
-   if (!dcfg) {
-   ret = -EINVAL;
-   goto err_put_rproc;
-   }
+   if (!dcfg)
+   return -EINVAL;
 
priv = rproc->priv;
priv->rproc = rproc;
@@ -1124,8 +1122,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv->workqueue = create_workqueue(dev_name(dev));
if (!priv->workqueue) {
dev_err(dev, "cannot create workqueue\n");
-   ret = -ENOMEM;
-   goto err_put_rproc;
+   return -ENOMEM;
}
 
ret = imx_rproc_xtr_mbox_init(rproc);
@@ -1167,8 +1164,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
imx_rproc_free_mbox(rproc);
 err_put_wkq:
destroy_workqueue(priv->workqueue);
-err_put_rproc:
-   rproc_free(rproc);
 
return ret;
 }
@@ -1183,7 +1178,6 @@ static void imx_rproc_remove(struct platform_device *pdev)
imx_rproc_put_scu(rproc);
imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue);
-   rproc_free(rproc);
 }
 
 static const struct of_device_id imx_rproc_of_match[] = {
-- 
2.39.2




[PATCH 4/9] remoteproc: qcom_q6v5_mss: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/qcom_q6v5_mss.c | 28 
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_mss.c 
b/drivers/remoteproc/qcom_q6v5_mss.c
index 394b2c1cb5e21..1779fc890e102 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev)
return ret;
}
 
-   rproc = rproc_alloc(>dev, pdev->name, _ops,
-   mba_image, sizeof(*qproc));
+   rproc = devm_rproc_alloc(>dev, pdev->name, _ops,
+mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(>dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev)
1, >hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(>dev, "unable to read mpss firmware-name\n");
-   goto free_rproc;
+   return ret;
}
 
platform_set_drvdata(pdev, qproc);
@@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
-   goto free_rproc;
+   return ret;
 
ret = q6v5_alloc_memory_region(qproc);
if (ret)
-   goto free_rproc;
+   return ret;
 
ret = q6v5_init_clocks(>dev, qproc->proxy_clks,
   desc->proxy_clk_names);
if (ret < 0) {
dev_err(>dev, "Failed to get proxy clocks.\n");
-   goto free_rproc;
+   return ret;
}
qproc->proxy_clk_count = ret;
 
@@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev)
   desc->reset_clk_names);
if (ret < 0) {
dev_err(>dev, "Failed to get reset clocks.\n");
-   goto free_rproc;
+   return ret;
}
qproc->reset_clk_count = ret;
 
@@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev)
   desc->active_clk_names);
if (ret < 0) {
dev_err(>dev, "Failed to get active clocks.\n");
-   goto free_rproc;
+   return ret;
}
qproc->active_clk_count = ret;
 
@@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev)
  desc->proxy_supply);
if (ret < 0) {
dev_err(>dev, "Failed to get proxy regulators.\n");
-   goto free_rproc;
+   return ret;
}
qproc->proxy_reg_count = ret;
 
@@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev)
  desc->active_supply);
if (ret < 0) {
dev_err(>dev, "Failed to get active regulators.\n");
-   goto free_rproc;
+   return ret;
}
qproc->active_reg_count = ret;
 
@@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev)
  desc->fallback_proxy_supply);
if (ret < 0) {
dev_err(>dev, "Failed to get fallback proxy 
regulators.\n");
-   goto free_rproc;
+   return ret;
}
qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) {
dev_err(>dev, "Failed to init power domains\n");
-   goto free_rproc;
+   return ret;
} else {
qproc->proxy_pd_count = ret;
}
@@ -2127,8 +2127,6 @@ static int q6v5_probe(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, >glink_subdev);
 detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
-free_rproc:
-   rproc_free(rproc);
 
return ret;
 }
@@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, >glink_subdev);
 
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
-
-   rproc_free(rproc);
 }
 
 static const struct rproc_hexagon_res sc7180_mss = {
-- 
2.39.2




[PATCH 8/9] remoteproc: st: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/st_remoteproc.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/remoteproc/st_remoteproc.c 
b/drivers/remoteproc/st_remoteproc.c
index cb163766c56d5..1340be9d01101 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -347,23 +347,21 @@ static int st_rproc_probe(struct platform_device *pdev)
int enabled;
int ret, i;
 
-   rproc = rproc_alloc(dev, np->name, _rproc_ops, NULL, sizeof(*ddata));
+   rproc = devm_rproc_alloc(dev, np->name, _rproc_ops, NULL, 
sizeof(*ddata));
if (!rproc)
return -ENOMEM;
 
rproc->has_iommu = false;
ddata = rproc->priv;
ddata->config = (struct st_rproc_config *)device_get_match_data(dev);
-   if (!ddata->config) {
-   ret = -ENODEV;
-   goto free_rproc;
-   }
+   if (!ddata->config)
+   return -ENODEV;
 
platform_set_drvdata(pdev, rproc);
 
ret = st_rproc_parse_dt(pdev);
if (ret)
-   goto free_rproc;
+   return ret;
 
enabled = st_rproc_state(pdev);
if (enabled < 0) {
@@ -439,8 +437,7 @@ static int st_rproc_probe(struct platform_device *pdev)
mbox_free_channel(ddata->mbox_chan[i]);
 free_clk:
clk_unprepare(ddata->clk);
-free_rproc:
-   rproc_free(rproc);
+
return ret;
 }
 
@@ -456,8 +453,6 @@ static void st_rproc_remove(struct platform_device *pdev)
 
for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
mbox_free_channel(ddata->mbox_chan[i]);
-
-   rproc_free(rproc);
 }
 
 static struct platform_driver st_rproc_driver = {
-- 
2.39.2




[PATCH 7/9] remoteproc: qcom_wcnss: Use devm_rproc_alloc() helper

2024-01-23 Thread Andrew Davis
Use the device lifecycle managed allocation function. This helps prevent
mistakes like freeing out of order in cleanup functions and forgetting to
free on error paths.

Signed-off-by: Andrew Davis 
---
 drivers/remoteproc/qcom_wcnss.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
index 90de22c81da97..a7bb9da27029d 100644
--- a/drivers/remoteproc/qcom_wcnss.c
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev)
if (ret < 0 && ret != -EINVAL)
return ret;
 
-   rproc = rproc_alloc(>dev, pdev->name, _ops,
-   fw_name, sizeof(*wcnss));
+   rproc = devm_rproc_alloc(>dev, pdev->name, _ops,
+fw_name, sizeof(*wcnss));
if (!rproc) {
dev_err(>dev, "unable to allocate remoteproc\n");
return -ENOMEM;
@@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev)
mutex_init(>iris_lock);
 
mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
-   if (IS_ERR(mmio)) {
-   ret = PTR_ERR(mmio);
-   goto free_rproc;
-   }
+   if (IS_ERR(mmio))
+   return PTR_ERR(mmio);
 
ret = wcnss_alloc_memory_region(wcnss);
if (ret)
-   goto free_rproc;
+   return ret;
 
wcnss->pmu_cfg = mmio + data->pmu_offset;
wcnss->spare_out = mmio + data->spare_offset;
@@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev)
 */
ret = wcnss_init_pds(wcnss, data->pd_names);
if (ret && (ret != -ENODATA || !data->num_pd_vregs))
-   goto free_rproc;
+   return ret;
 
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
data->num_pd_vregs);
@@ -656,8 +654,6 @@ static int wcnss_probe(struct platform_device *pdev)
qcom_iris_remove(wcnss->iris);
 detach_pds:
wcnss_release_pds(wcnss);
-free_rproc:
-   rproc_free(rproc);
 
return ret;
 }
@@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(wcnss->sysmon);
qcom_remove_smd_subdev(wcnss->rproc, >smd_subdev);
wcnss_release_pds(wcnss);
-   rproc_free(wcnss->rproc);
 }
 
 static const struct of_device_id wcnss_of_match[] = {
-- 
2.39.2




  1   2   >