mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 19:47:08 +02:00
rpmsg: glink: Add early reset notifier
Currently when a remote subsystem goes down, remove_subdev will be called from rproc for removing that subsystem from the list, but this could be too late. Register for early SSR notifications for getting notified about before shutdown, so that the glink_send calls to the dead processor will not get blocked. Change-Id: Ief7f90caf69f2855272579bc63140837e0efc447 Signed-off-by: Chris Lew <quic_clew@quicinc.com>
This commit is contained in:
parent
1332236bd1
commit
1b8b9571dd
|
|
@ -1777,6 +1777,29 @@ static void qcom_glink_work(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
void qcom_glink_early_ssr_notify(void *data)
|
||||
{
|
||||
struct qcom_glink *glink = data;
|
||||
struct glink_channel *channel;
|
||||
unsigned long flags;
|
||||
int cid;
|
||||
|
||||
if (!glink)
|
||||
return;
|
||||
atomic_inc(&glink->in_reset);
|
||||
|
||||
/* To wakeup any blocking writers */
|
||||
wake_up_all(&glink->tx_avail_notify);
|
||||
|
||||
spin_lock_irqsave(&glink->idr_lock, flags);
|
||||
idr_for_each_entry(&glink->lcids, channel, cid) {
|
||||
wake_up(&channel->intent_req_ack);
|
||||
wake_up(&channel->intent_req_comp);
|
||||
}
|
||||
spin_unlock_irqrestore(&glink->idr_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_glink_early_ssr_notify);
|
||||
|
||||
static void qcom_glink_cancel_rx_work(struct qcom_glink *glink)
|
||||
{
|
||||
struct glink_defer_cmd *dcmd;
|
||||
|
|
@ -1895,6 +1918,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
|
|||
}
|
||||
|
||||
scnprintf(glink->irqname, 32, "glink-native-%s", glink->name);
|
||||
|
||||
irq = of_irq_get(dev->of_node, 0);
|
||||
ret = devm_request_irq(dev, irq,
|
||||
qcom_glink_native_intr,
|
||||
|
|
@ -1929,22 +1953,13 @@ static int qcom_glink_remove_device(struct device *dev, void *data)
|
|||
void qcom_glink_native_remove(struct qcom_glink *glink)
|
||||
{
|
||||
struct glink_channel *channel;
|
||||
unsigned long flags;
|
||||
int cid;
|
||||
int ret;
|
||||
|
||||
atomic_inc(&glink->in_reset);
|
||||
qcom_glink_early_ssr_notify(glink);
|
||||
disable_irq(glink->irq);
|
||||
qcom_glink_cancel_rx_work(glink);
|
||||
|
||||
/* Signal all threads to cancel tx */
|
||||
spin_lock_irqsave(&glink->idr_lock, flags);
|
||||
idr_for_each_entry(&glink->lcids, channel, cid) {
|
||||
wake_up(&channel->intent_req_ack);
|
||||
wake_up(&channel->intent_req_comp);
|
||||
}
|
||||
spin_unlock_irqrestore(&glink->idr_lock, flags);
|
||||
|
||||
ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device);
|
||||
if (ret)
|
||||
dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
void qcom_glink_early_ssr_notify(void *data);
|
||||
|
||||
#else
|
||||
|
||||
|
|
@ -29,6 +30,8 @@ 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) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user