rpmsg: glink: Modify fifo reset order

Glink pipe indices are reset by apps in the remoteproc
subdev stop path. There is a chance that the remote that
is being shutdown is in the middle of reading from the
pipe. This causes the remote that is shutting down
gracefully to crash as index 0 is invalid.

Remove the fifo reset from the remoteproc subdev stop
path. Register a function pointer with remoteproc for the
subdev to be called during prepare stage of ssr. Split
the glink probe to have pipes initialization, rx thread
creation and setting up glink structures happen in prepare
stage and version negotiation and char device creation in
prepare stage.

Given that the pipes get re-initialized during prepare
stage, the fifo indices will be intact until after the
remote has been shutdown completely and reset before the
remote is up again.

Spliting glink probe to prepare (in BEFORE_POWERUP) and
start (in AFTER_POWERUP) stage in spss results in glink
link up callback arriving earlier on spss when one of the
destination services is not yet created. This results in
spss not finishing the boot flow after ssr.

Adding glink fifo reset to be called as part of BEFORE_SHUTDOWN
if the underlying driver has callbacks setup for it as is the
case in spss rpmsg driver.

Change-Id: I74cae7ce49cb212af9e7ec2391956339c3427aec
Signed-off-by: Jay Jayanna <jayanna@codeaurora.org>
This commit is contained in:
Jay Jayanna 2021-08-04 09:34:41 -07:00 committed by Chris Lew
parent 466924d268
commit a34dacf4c7
4 changed files with 32 additions and 19 deletions

View File

@ -1881,7 +1881,6 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
struct qcom_glink_pipe *tx,
bool intentless)
{
int irq;
int ret;
struct qcom_glink *glink;
@ -1928,6 +1927,16 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
scnprintf(glink->irqname, 32, "glink-native-%s", glink->name);
return glink;
}
EXPORT_SYMBOL(qcom_glink_native_probe);
int qcom_glink_native_start(struct qcom_glink *glink)
{
struct device *dev = glink->dev;
int irq;
int ret;
irq = of_irq_get(dev->of_node, 0);
ret = devm_request_irq(dev, irq,
qcom_glink_native_intr,
@ -1935,22 +1944,22 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
glink->irqname, glink);
if (ret) {
dev_err(dev, "failed to request IRQ\n");
return ERR_PTR(ret);
return ret;
}
glink->irq = irq;
ret = qcom_glink_send_version(glink);
if (ret)
return ERR_PTR(ret);
return ret;
ret = qcom_glink_create_chrdev(glink);
if (ret)
dev_err(glink->dev, "failed to register chrdev\n");
return glink;
return 0;
}
EXPORT_SYMBOL_GPL(qcom_glink_native_probe);
EXPORT_SYMBOL(qcom_glink_native_start);
static int qcom_glink_remove_device(struct device *dev, void *data)
{
@ -1992,7 +2001,12 @@ void qcom_glink_native_remove(struct qcom_glink *glink)
idr_destroy(&glink->lcids);
idr_destroy(&glink->rcids);
/*
* Required for spss only. A cb is provided for this in spss driver. For
* others, its done in prepare stage in smem driver. No cb is given.
*/
qcom_glink_pipe_reset(glink);
mbox_free_channel(glink->mbox_chan);
}
EXPORT_SYMBOL_GPL(qcom_glink_native_remove);

View File

@ -33,6 +33,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
struct qcom_glink_pipe *rx,
struct qcom_glink_pipe *tx,
bool intentless);
int qcom_glink_native_start(struct qcom_glink *glink);
void qcom_glink_native_remove(struct qcom_glink *glink);
void qcom_glink_native_unregister(struct qcom_glink *glink);

View File

@ -46,12 +46,6 @@ struct glink_smem_pipe {
#define to_smem_pipe(p) container_of(p, struct glink_smem_pipe, native)
static void glink_smem_rx_reset(struct qcom_glink_pipe *np)
{
struct glink_smem_pipe *pipe = to_smem_pipe(np);
*pipe->tail = 0;
}
static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np)
{
struct glink_smem_pipe *pipe = to_smem_pipe(np);
@ -126,12 +120,6 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np,
*pipe->tail = cpu_to_le32(tail);
}
static void glink_smem_tx_reset(struct qcom_glink_pipe *np)
{
struct glink_smem_pipe *pipe = to_smem_pipe(np);
*pipe->head = 0;
}
static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np)
{
struct glink_smem_pipe *pipe = to_smem_pipe(np);
@ -291,13 +279,11 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent,
goto err_put_dev;
}
rx_pipe->native.reset = glink_smem_rx_reset;
rx_pipe->native.avail = glink_smem_rx_avail;
rx_pipe->native.peak = glink_smem_rx_peak;
rx_pipe->native.advance = glink_smem_rx_advance;
rx_pipe->remote_pid = remote_pid;
tx_pipe->native.reset = glink_smem_tx_reset;
tx_pipe->native.avail = glink_smem_tx_avail;
tx_pipe->native.write = glink_smem_tx_write;
tx_pipe->remote_pid = remote_pid;
@ -323,6 +309,12 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent,
}
EXPORT_SYMBOL_GPL(qcom_glink_smem_register);
int qcom_glink_smem_start(struct qcom_glink *glink)
{
return qcom_glink_native_start(glink);
}
EXPORT_SYMBOL(qcom_glink_smem_start);
void qcom_glink_smem_unregister(struct qcom_glink *glink)
{
qcom_glink_native_remove(glink);

View File

@ -18,6 +18,7 @@ static inline void qcom_glink_ssr_notify(const char *ssr_name) {}
struct qcom_glink *qcom_glink_smem_register(struct device *parent,
struct device_node *node);
void qcom_glink_smem_unregister(struct qcom_glink *glink);
int qcom_glink_smem_start(struct qcom_glink *glink);
void qcom_glink_early_ssr_notify(void *data);
#else
@ -32,6 +33,11 @@ qcom_glink_smem_register(struct device *parent,
static inline void qcom_glink_smem_unregister(struct qcom_glink *glink) {}
static inline void qcom_glink_ssr_notify(const char *ssr_name) {}
static inline void qcom_glink_early_ssr_notify(void *data) {}
int qcom_glink_smem_start(struct qcom_glink *glink)
{
return -ENXIO;
}
#endif
#endif