mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
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:
parent
466924d268
commit
a34dacf4c7
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user