[PATCH v2 2/2] remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs

2024-04-24 Thread Beleswar Padhi
PSC controller has a limitation that it can only power-up the second
core when the first core is in ON state. Power-state for core0 should be
equal to or higher than core1.

Therefore, prevent core1 from powering up before core0 during the start
process from sysfs. Similarly, prevent core0 from shutting down before
core1 has been shut down from sysfs.

Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F 
subsystem")

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

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 5a9bd5d4a2ea..b9d2a16af563 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -548,7 +548,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster;
struct device *dev = kproc->dev;
-   struct k3_r5_core *core;
+   struct k3_r5_core *core0, *core;
u32 boot_addr;
int ret;
 
@@ -574,6 +574,15 @@ static int k3_r5_rproc_start(struct rproc *rproc)
goto unroll_core_run;
}
} else {
+   /* do not allow core 1 to start before core 0 */
+   core0 = list_first_entry(>cores, struct k3_r5_core,
+elem);
+   if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
+   dev_err(dev, "%s: can not start core 1 before core 0\n",
+   __func__);
+   return -EPERM;
+   }
+
ret = k3_r5_core_run(core);
if (ret)
goto put_mbox;
@@ -619,7 +628,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
 {
struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster;
-   struct k3_r5_core *core = kproc->core;
+   struct device *dev = kproc->dev;
+   struct k3_r5_core *core1, *core = kproc->core;
int ret;
 
/* halt all applicable cores */
@@ -632,6 +642,15 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
}
}
} else {
+   /* do not allow core 0 to stop before core 1 */
+   core1 = list_last_entry(>cores, struct k3_r5_core,
+   elem);
+   if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
+   dev_err(dev, "%s: can not stop core 0 before core 1\n",
+   __func__);
+   return -EPERM;
+   }
+
ret = k3_r5_core_halt(core);
if (ret)
goto out;
-- 
2.34.1




[PATCH v2 1/2] remoteproc: k3-r5: Wait for core0 power-up before powering up core1

2024-04-24 Thread Beleswar Padhi
From: Apurva Nandan 

PSC controller has a limitation that it can only power-up the second core
when the first core is in ON state. Power-state for core0 should be equal
to or higher than core1, else the kernel is seen hanging during rproc
loading.

Make the powering up of cores sequential, by waiting for the current core
to power-up before proceeding to the next core, with a timeout of 2sec.
Add a wait queue event in k3_r5_cluster_rproc_init call, that will wait
for the current core to be released from reset before proceeding with the
next core.

Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F 
subsystem")

Signed-off-by: Apurva Nandan 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index ad3415a3851b..5a9bd5d4a2ea 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -103,12 +103,14 @@ struct k3_r5_soc_data {
  * @dev: cached device pointer
  * @mode: Mode to configure the Cluster - Split or LockStep
  * @cores: list of R5 cores within the cluster
+ * @core_transition: wait queue to sync core state changes
  * @soc_data: SoC-specific feature data for a R5FSS
  */
 struct k3_r5_cluster {
struct device *dev;
enum cluster_mode mode;
struct list_head cores;
+   wait_queue_head_t core_transition;
const struct k3_r5_soc_data *soc_data;
 };
 
@@ -128,6 +130,7 @@ struct k3_r5_cluster {
  * @atcm_enable: flag to control ATCM enablement
  * @btcm_enable: flag to control BTCM enablement
  * @loczrama: flag to dictate which TCM is at device address 0x0
+ * @released_from_reset: flag to signal when core is out of reset
  */
 struct k3_r5_core {
struct list_head elem;
@@ -144,6 +147,7 @@ struct k3_r5_core {
u32 atcm_enable;
u32 btcm_enable;
u32 loczrama;
+   bool released_from_reset;
 };
 
 /**
@@ -460,6 +464,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
ret);
return ret;
}
+   core->released_from_reset = true;
+   wake_up_interruptible(>core_transition);
 
/*
 * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
@@ -1140,6 +1146,7 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc 
*kproc)
return ret;
}
 
+   core->released_from_reset = c_state;
ret = ti_sci_proc_get_status(core->tsp, _vec, , ,
 );
if (ret < 0) {
@@ -1280,6 +1287,26 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
cluster->mode == CLUSTER_MODE_SINGLECPU ||
cluster->mode == CLUSTER_MODE_SINGLECORE)
break;
+
+   /*
+* R5 cores require to be powered on sequentially, core0
+* should be in higher power state than core1 in a cluster
+* So, wait for current core to power up before proceeding
+* to next core and put timeout of 2sec for each core.
+*
+* This waiting mechanism is necessary because
+* rproc_auto_boot_callback() for core1 can be called before
+* core0 due to thread execution order.
+*/
+   ret = wait_event_interruptible_timeout(cluster->core_transition,
+  
core->released_from_reset,
+  msecs_to_jiffies(2000));
+   if (ret <= 0) {
+   dev_err(dev,
+   "Timed out waiting for %s core to power up!\n",
+   rproc->name);
+   return ret;
+   }
}
 
return 0;
@@ -1709,6 +1736,7 @@ static int k3_r5_probe(struct platform_device *pdev)
cluster->dev = dev;
cluster->soc_data = data;
INIT_LIST_HEAD(>cores);
+   init_waitqueue_head(>core_transition);
 
ret = of_property_read_u32(np, "ti,cluster-mode", >mode);
if (ret < 0 && ret != -EINVAL) {
-- 
2.34.1




[PATCH v2 0/2] remoteproc: k3-r5: Wait for core0 power-up before powering up core1

2024-04-24 Thread Beleswar Padhi
PSC controller has a limitation that it can only power-up the second core
when the first core is in ON state. Power-state for core0 should be equal
to or higher than core1, else the kernel is seen hanging during rproc
loading.

Make the powering up of cores sequential, by waiting for the current core
to power-up before proceeding to the next core, with a timeout of 2sec.
Add a wait queue event in k3_r5_cluster_rproc_init call, that will wait
for the current core to be released from reset before proceeding with the
next core.

Also, ensure that core1 can not be powered on before core0 when starting
cores from sysfs. Similarly, ensure that core0 can not be shutdown
before core1 from sysfs.

v2: Changelog:
1) Fixed multi-line comment format
2) Included root cause of bug in comments
3) Added a patch to ensure power-up/shutdown is sequential via sysfs

Link to v1:
https://lore.kernel.org/all/20230906124756.3480579-1-a-nan...@ti.com/

Apurva Nandan (1):
  remoteproc: k3-r5: Wait for core0 power-up before powering up core1

Beleswar Padhi (1):
  remoteproc: k3-r5: Do not allow core1 to power up before core0 via
sysfs

 drivers/remoteproc/ti_k3_r5_remoteproc.c | 51 +++-
 1 file changed, 49 insertions(+), 2 deletions(-)

-- 
2.34.1




[PATCH v3 0/2] remoteproc: k3-r5: Wait for core0 power-up before powering up core1

2024-04-30 Thread Beleswar Padhi
PSC controller has a limitation that it can only power-up the second core
when the first core is in ON state. Power-state for core0 should be equal
to or higher than core1, else the kernel is seen hanging during rproc
loading.

Make the powering up of cores sequential, by waiting for the current core
to power-up before proceeding to the next core, with a timeout of 2sec.
Add a wait queue event in k3_r5_cluster_rproc_init call, that will wait
for the current core to be released from reset before proceeding with the
next core.

Also, ensure that core1 can not be powered on before core0 when starting
cores from sysfs. Similarly, ensure that core0 can not be shutdown
before core1 from sysfs.

v3: Changelog:
1) Added my own Signed-off-by in PATCH 1, specifying the changes done
2) Addressed changes requested by adding comments in code in PATCH 1

Link to v2:
https://lore.kernel.org/all/20240424130504.494916-1-b-pa...@ti.com/

v2: Changelog:
1) Fixed multi-line comment format
2) Included root cause of bug in comments
3) Added a patch to ensure power-up/shutdown is sequential via sysfs

Link to v1:
https://lore.kernel.org/all/20230906124756.3480579-1-a-nan...@ti.com/

Apurva Nandan (1):
  remoteproc: k3-r5: Wait for core0 power-up before powering up core1

Beleswar Padhi (1):
  remoteproc: k3-r5: Do not allow core1 to power up before core0 via
sysfs

 drivers/remoteproc/ti_k3_r5_remoteproc.c | 56 +++-
 1 file changed, 54 insertions(+), 2 deletions(-)

-- 
2.34.1




[PATCH v3 1/2] remoteproc: k3-r5: Wait for core0 power-up before powering up core1

2024-04-30 Thread Beleswar Padhi
From: Apurva Nandan 

PSC controller has a limitation that it can only power-up the second core
when the first core is in ON state. Power-state for core0 should be equal
to or higher than core1, else the kernel is seen hanging during rproc
loading.

Make the powering up of cores sequential, by waiting for the current core
to power-up before proceeding to the next core, with a timeout of 2sec.
Add a wait queue event in k3_r5_cluster_rproc_init call, that will wait
for the current core to be released from reset before proceeding with the
next core.

Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F 
subsystem")

Signed-off-by: Apurva Nandan 
[added comments and fixed code style]
Signed-off-by: Beleswar Padhi 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 33 
 1 file changed, 33 insertions(+)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index ad3415a3851b..6d6afd6beb3a 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -103,12 +103,14 @@ struct k3_r5_soc_data {
  * @dev: cached device pointer
  * @mode: Mode to configure the Cluster - Split or LockStep
  * @cores: list of R5 cores within the cluster
+ * @core_transition: wait queue to sync core state changes
  * @soc_data: SoC-specific feature data for a R5FSS
  */
 struct k3_r5_cluster {
struct device *dev;
enum cluster_mode mode;
struct list_head cores;
+   wait_queue_head_t core_transition;
const struct k3_r5_soc_data *soc_data;
 };
 
@@ -128,6 +130,7 @@ struct k3_r5_cluster {
  * @atcm_enable: flag to control ATCM enablement
  * @btcm_enable: flag to control BTCM enablement
  * @loczrama: flag to dictate which TCM is at device address 0x0
+ * @released_from_reset: flag to signal when core is out of reset
  */
 struct k3_r5_core {
struct list_head elem;
@@ -144,6 +147,7 @@ struct k3_r5_core {
u32 atcm_enable;
u32 btcm_enable;
u32 loczrama;
+   bool released_from_reset;
 };
 
 /**
@@ -460,6 +464,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
ret);
return ret;
}
+   core->released_from_reset = true;
+   wake_up_interruptible(>core_transition);
 
/*
 * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
@@ -1140,6 +1146,12 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc 
*kproc)
return ret;
}
 
+   /*
+* Skip the waiting mechanism for sequential power-on of cores if the
+* core has already been booted by another entity.
+*/
+   core->released_from_reset = c_state;
+
ret = ti_sci_proc_get_status(core->tsp, _vec, , ,
 );
if (ret < 0) {
@@ -1280,6 +1292,26 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
cluster->mode == CLUSTER_MODE_SINGLECPU ||
cluster->mode == CLUSTER_MODE_SINGLECORE)
break;
+
+   /*
+* R5 cores require to be powered on sequentially, core0
+* should be in higher power state than core1 in a cluster
+* So, wait for current core to power up before proceeding
+* to next core and put timeout of 2sec for each core.
+*
+* This waiting mechanism is necessary because
+* rproc_auto_boot_callback() for core1 can be called before
+* core0 due to thread execution order.
+*/
+   ret = wait_event_interruptible_timeout(cluster->core_transition,
+  
core->released_from_reset,
+  msecs_to_jiffies(2000));
+   if (ret <= 0) {
+   dev_err(dev,
+   "Timed out waiting for %s core to power up!\n",
+   rproc->name);
+   return ret;
+   }
}
 
return 0;
@@ -1709,6 +1741,7 @@ static int k3_r5_probe(struct platform_device *pdev)
cluster->dev = dev;
cluster->soc_data = data;
INIT_LIST_HEAD(>cores);
+   init_waitqueue_head(>core_transition);
 
ret = of_property_read_u32(np, "ti,cluster-mode", >mode);
if (ret < 0 && ret != -EINVAL) {
-- 
2.34.1




[PATCH v3 2/2] remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs

2024-04-30 Thread Beleswar Padhi
PSC controller has a limitation that it can only power-up the second
core when the first core is in ON state. Power-state for core0 should be
equal to or higher than core1.

Therefore, prevent core1 from powering up before core0 during the start
process from sysfs. Similarly, prevent core0 from shutting down before
core1 has been shut down from sysfs.

Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F 
subsystem")

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

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 6d6afd6beb3a..1799b4f6d11e 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -548,7 +548,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster;
struct device *dev = kproc->dev;
-   struct k3_r5_core *core;
+   struct k3_r5_core *core0, *core;
u32 boot_addr;
int ret;
 
@@ -574,6 +574,15 @@ static int k3_r5_rproc_start(struct rproc *rproc)
goto unroll_core_run;
}
} else {
+   /* do not allow core 1 to start before core 0 */
+   core0 = list_first_entry(>cores, struct k3_r5_core,
+elem);
+   if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
+   dev_err(dev, "%s: can not start core 1 before core 0\n",
+   __func__);
+   return -EPERM;
+   }
+
ret = k3_r5_core_run(core);
if (ret)
goto put_mbox;
@@ -619,7 +628,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
 {
struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster;
-   struct k3_r5_core *core = kproc->core;
+   struct device *dev = kproc->dev;
+   struct k3_r5_core *core1, *core = kproc->core;
int ret;
 
/* halt all applicable cores */
@@ -632,6 +642,15 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
}
}
} else {
+   /* do not allow core 0 to stop before core 1 */
+   core1 = list_last_entry(>cores, struct k3_r5_core,
+   elem);
+   if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
+   dev_err(dev, "%s: can not stop core 0 before core 1\n",
+   __func__);
+   return -EPERM;
+   }
+
ret = k3_r5_core_halt(core);
if (ret)
goto out;
-- 
2.34.1




[PATCH] remoteproc: k3-r5: Jump to error handling labels in start/stop errors

2024-05-06 Thread Beleswar Padhi
In case of errors during core start operation from sysfs, the driver
directly returns with the -EPERM error code. Fix this to ensure that
mailbox channels are freed on error before returning by jumping to the
'put_mbox' error handling label. Similarly, jump to the 'out' error
handling label to return with required -EPERM error code during the
core stop operation from sysfs.

Fixes: 3c8a9066d584 ("remoteproc: k3-r5: Do not allow core1 to power up before 
core0 via sysfs")

Signed-off-by: Beleswar Padhi 
---
As stated in the bug-report[0], Smatch complains that:
drivers/remoteproc/ti_k3_r5_remoteproc.c:583 k3_r5_rproc_start() warn: missing 
unwind goto?
drivers/remoteproc/ti_k3_r5_remoteproc.c:651 k3_r5_rproc_stop() warn: missing 
unwind goto?

This patch addresses the warnings by jumping to appropriate error
labels in case an error occurs during start/stop operation from sysfs.

[0]-https://lore.kernel.org/all/acc4f7a0-3bb5-4842-95a5-fb3c3fc8554b@moroto.mountain/

 drivers/remoteproc/ti_k3_r5_remoteproc.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 1799b4f6d11e..50e486bcfa10 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -580,7 +580,8 @@ 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__);
-   return -EPERM;
+   ret = -EPERM;
+   goto put_mbox;
}
 
ret = k3_r5_core_run(core);
@@ -648,7 +649,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
dev_err(dev, "%s: can not stop core 0 before core 1\n",
__func__);
-   return -EPERM;
+   ret = -EPERM;
+   goto out;
}
 
ret = k3_r5_core_halt(core);
-- 
2.34.1




[PATCH 0/3] Defer TI's Remoteproc's Probe until Mailbox is Probed

2024-05-30 Thread Beleswar Padhi
Hello All,

This series adds deferred probe functionality in the TI's Remoteproc
drivers. The remoteproc drivers are dependent on the omap-mailbox driver
for mbox functionalities. Sometimes, the remoteproc driver could be
probed before the mailbox driver leading to rproc boot failures. Thus,
defer the probe routine of remoteproc drivers until mailbox driver is
probed by checking the mbox_request_channel handle in probe. 

Also, use the acquired mbox handle in probe during rproc start/attach
routine instead of re-requesting. Do not free mbox handle during
stop/detach routine or error paths. This makes our k3_rproc_attach() &
k3_rproc_detach() functions NOP.

Also, use the devm_rproc_alloc() helper to automatically free created
rprocs incase of a probe defer.

Beleswar Padhi (3):
  remoteproc: k3-r5: Use devm_rproc_alloc() helper
  remoteproc: k3-r5: Acquire mailbox handle during probe
  remoteproc: k3-dsp: Acquire mailbox handle during probe routine

 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 67 +++--
 drivers/remoteproc/ti_k3_r5_remoteproc.c  | 72 ---
 2 files changed, 44 insertions(+), 95 deletions(-)

-- 
2.34.1




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

2024-05-30 Thread Beleswar Padhi
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;
}
 
/*
@@ -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;
 
/* 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 NOP. 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 and exists for sanity sake.
  */
-static int k3_r5_rproc_detach(s

[PATCH 3/3] remoteproc: k3-dsp: Acquire mailbox handle during probe routine

2024-05-30 Thread Beleswar Padhi
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_dsp_remoteproc.c | 67 +++
 1 file changed, 21 insertions(+), 46 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 3555b535b168..88cda609a5eb 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -222,6 +222,7 @@ static int k3_dsp_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;
@@ -231,10 +232,9 @@ static int k3_dsp_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;
}
 
/*
@@ -315,31 +315,25 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
 
-   ret = k3_dsp_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
boot_addr = rproc->bootaddr;
if (boot_addr & (kproc->data->boot_align_addr - 1)) {
dev_err(dev, "invalid boot address 0x%x, must be aligned on a 
0x%x boundary\n",
boot_addr, kproc->data->boot_align_addr);
ret = -EINVAL;
-   goto put_mbox;
+   goto out;
}
 
dev_err(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;
+   goto out;
 
ret = k3_dsp_rproc_release(kproc);
if (ret)
-   goto put_mbox;
+   goto out;
 
return 0;
-
-put_mbox:
-   mbox_free_channel(kproc->mbox);
+out:
return ret;
 }
 
@@ -353,8 +347,6 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
 {
struct k3_dsp_rproc *kproc = rproc->priv;
 
-   mbox_free_channel(kproc->mbox);
-
k3_dsp_rproc_reset(kproc);
 
return 0;
@@ -363,42 +355,21 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
 /*
  * Attach to a running DSP remote processor (IPC-only mode)
  *
- * This rproc 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 DSP core. This callback is invoked only in IPC-only
- * mode.
+ * This rproc 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 DSP core. This callback
+ * is invoked only in IPC-only mode and exists for sanity sake.
  */
-static int k3_dsp_rproc_attach(struct rproc *rproc)
-{
-   struct k3_dsp_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-   int ret;
-
-   ret = k3_dsp_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
-   dev_info(dev, "DSP initialized in IPC-only mode\n");
-   return 0;
-}
+static int k3_dsp_rproc_attach(struct rproc *rproc) { return 0; }
 
 /*
  * Detach from a running DSP remote processor (IPC-only mode)
  *
- * This rproc detach callback performs the opposite operation to attach 
callback
- * and only needs to release the mailbox, the DSP core is not stopped and will
- * be left to continue to run its booted firmware. This callback is invoked 
only
- * in IPC-only mode.
+ * This rproc detach callback is a NOP. The DSP core is not stopped and will be
+ * left to continue to run its booted firmware. This callback is invoked only 
in
+ * IPC-only mode and exists for sanity sake.
  */
-static int k3_dsp_rproc_detach(struct rproc *rproc)
-{
-   struct k3_dsp_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-
-   mbox_free_channel(kproc->mbox);
-   dev_info(dev, "DSP deinitialized in IPC-only mode\n");
-   return 0;
-}
+static int k3_dsp_rproc_detach(struct rproc *rproc) { return 0; }
 
 /*
  * This function implements the .get_loaded_rsc_table() callback and is used
@@ -697,6 +668,10 @@ static int k3_dsp_rproc_probe(s

[PATCH 1/3] remoteproc: k3-r5: Use devm_rproc_alloc() helper

2024-05-30 Thread Beleswar Padhi
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: Beleswar Padhi 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 50e486bcfa10..26362a509ae3 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -1258,8 +1258,8 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
goto out;
}
 
-   rproc = rproc_alloc(cdev, dev_name(cdev), _r5_rproc_ops,
-   fw_name, sizeof(*kproc));
+   rproc = devm_rproc_alloc(cdev, dev_name(cdev), _r5_rproc_ops,
+fw_name, sizeof(*kproc));
if (!rproc) {
ret = -ENOMEM;
goto out;
@@ -1351,7 +1351,6 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
 err_add:
k3_r5_reserved_mem_exit(kproc);
 err_config:
-   rproc_free(rproc);
core->rproc = NULL;
 out:
/* undo core0 upon any failures on core1 in split-mode */
@@ -1398,7 +1397,6 @@ static void k3_r5_cluster_rproc_exit(void *data)
 
k3_r5_reserved_mem_exit(kproc);
 
-   rproc_free(rproc);
core->rproc = NULL;
}
 }
-- 
2.34.1




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

2024-06-03 Thread Beleswar Padhi
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 */
+   if (kproc->rproc->state == RPROC_DETACHED)
+   return;
+
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");
 
/*
 * 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; }
 
 /*
  * 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

[PATCH v2 3/3] remoteproc: k3-dsp: Acquire mailbox handle during probe routine

2024-06-03 Thread Beleswar Padhi
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_dsp_remoteproc.c | 76 ---
 1 file changed, 26 insertions(+), 50 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c 
b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
index 3555b535b1683..edaa5e91aebe9 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -115,6 +115,10 @@ static void k3_dsp_rproc_mbox_callback(struct mbox_client 
*client, void *data)
const char *name = kproc->rproc->name;
u32 msg = omap_mbox_message(data);
 
+   /* Do not forward messages to a detached core */
+   if (kproc->rproc->state == RPROC_DETACHED)
+   return;
+
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
 
switch (msg) {
@@ -230,12 +234,9 @@ static int k3_dsp_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");
 
/*
 * Ping the remote processor, this is only for sanity-sake for now;
@@ -315,32 +316,23 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
 
-   ret = k3_dsp_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
boot_addr = rproc->bootaddr;
if (boot_addr & (kproc->data->boot_align_addr - 1)) {
dev_err(dev, "invalid boot address 0x%x, must be aligned on a 
0x%x boundary\n",
boot_addr, kproc->data->boot_align_addr);
-   ret = -EINVAL;
-   goto put_mbox;
+   return -EINVAL;
}
 
dev_err(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;
+   return ret;
 
ret = k3_dsp_rproc_release(kproc);
if (ret)
-   goto put_mbox;
+   return ret;
 
return 0;
-
-put_mbox:
-   mbox_free_channel(kproc->mbox);
-   return ret;
 }
 
 /*
@@ -353,8 +345,6 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
 {
struct k3_dsp_rproc *kproc = rproc->priv;
 
-   mbox_free_channel(kproc->mbox);
-
k3_dsp_rproc_reset(kproc);
 
return 0;
@@ -363,42 +353,22 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
 /*
  * Attach to a running DSP remote processor (IPC-only mode)
  *
- * This rproc 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 DSP core. This callback is invoked only in IPC-only
- * mode.
+ * This rproc 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 DSP core. This callback
+ * is invoked only in IPC-only mode and exists because rproc_validate() checks
+ * for its existence.
  */
-static int k3_dsp_rproc_attach(struct rproc *rproc)
-{
-   struct k3_dsp_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-   int ret;
-
-   ret = k3_dsp_rproc_request_mbox(rproc);
-   if (ret)
-   return ret;
-
-   dev_info(dev, "DSP initialized in IPC-only mode\n");
-   return 0;
-}
+static int k3_dsp_rproc_attach(struct rproc *rproc) { return 0; }
 
 /*
  * Detach from a running DSP remote processor (IPC-only mode)
  *
- * This rproc detach callback performs the opposite operation to attach 
callback
- * and only needs to release the mailbox, the DSP core is not stopped and will
- * be left to continue to run its booted firmware. This callback is invoked 
only
- * in IPC-only mode.
+ * This rproc detach callback is a NOP. The DSP core is not stopped and will be
+ * left to continue to run its booted firmware. This callback is invoked only 
in
+ * IPC-only mode and exists for sanity sake.
  */
-static int k3_dsp_rproc_detach(struct rproc *rproc)
-{
-   struct k3_dsp_rproc *kproc = rproc->priv;
-   struct device *dev = kproc->dev;
-
-   mbox_free_channel(kproc->mbox);
-   dev

[PATCH v2 0/3] Defer TI's Remoteproc's Probe until Mailbox is Probed

2024-06-03 Thread Beleswar Padhi
Hello All,

This series adds deferred probe functionality in the TI's Remoteproc
drivers. The remoteproc drivers are dependent on the omap-mailbox driver
for mbox functionalities. Sometimes, the remoteproc driver could be
probed before the mailbox driver leading to rproc boot failures. Thus,
defer the probe routine of remoteproc drivers until mailbox driver is
probed by checking the mbox_request_channel handle in probe. 

Also, use the acquired mbox handle in probe during rproc start/attach
routine instead of re-requesting. Do not free mbox handle during
stop/detach routine or error paths. This makes our k3_rproc_attach() &
k3_rproc_detach() functions NOP.

Also, use the devm_rproc_alloc() helper to automatically free created
rprocs incase of a probe defer.

v2: Changelog:
1) Added a check in k3_mbox_callback() to prevent forwarding messages to
a detached core.
2) Addressed Andrew's comments in v1 regarding some cleanup (Using
dev_err_probe, removing unused labels, adding matching mbox_free_channel
call during device removal).

Link to v1:
https://lore.kernel.org/all/20240530090737.655054-1-b-pa...@ti.com/

Beleswar Padhi (3):
  remoteproc: k3-r5: Use devm_rproc_alloc() helper
  remoteproc: k3-r5: Acquire mailbox handle during probe
  remoteproc: k3-dsp: Acquire mailbox handle during probe routine

 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 76 -
 drivers/remoteproc/ti_k3_r5_remoteproc.c  | 80 ---
 2 files changed, 54 insertions(+), 102 deletions(-)

-- 
2.34.1




[PATCH v2 1/3] remoteproc: k3-r5: Use devm_rproc_alloc() helper

2024-06-03 Thread Beleswar Padhi
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: Beleswar Padhi 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 50e486bcfa103..26362a509ae3c 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -1258,8 +1258,8 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
goto out;
}
 
-   rproc = rproc_alloc(cdev, dev_name(cdev), _r5_rproc_ops,
-   fw_name, sizeof(*kproc));
+   rproc = devm_rproc_alloc(cdev, dev_name(cdev), _r5_rproc_ops,
+fw_name, sizeof(*kproc));
if (!rproc) {
ret = -ENOMEM;
goto out;
@@ -1351,7 +1351,6 @@ static int k3_r5_cluster_rproc_init(struct 
platform_device *pdev)
 err_add:
k3_r5_reserved_mem_exit(kproc);
 err_config:
-   rproc_free(rproc);
core->rproc = NULL;
 out:
/* undo core0 upon any failures on core1 in split-mode */
@@ -1398,7 +1397,6 @@ static void k3_r5_cluster_rproc_exit(void *data)
 
k3_r5_reserved_mem_exit(kproc);
 
-   rproc_free(rproc);
core->rproc = NULL;
}
 }
-- 
2.34.1