rpmsg updates for v6.4
The remove functions of the Qualcomm SMD and GLINK RPM platform drivers are transitioned to the new void returning prototype. Likewise is qcom_smd_unregister_edge() transitioned to void, as it unconditionally returned 0. An assumption about the ordering of the intent request acknowledgement and advertisement of a new intent in the GLINK implementation is corrected. Faulty error handling is corrected is improved in the TX path, and duplicated code, in the same path, is cleaned up. -----BEGIN PGP SIGNATURE----- iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmRGmHkVHGFuZGVyc3Nv bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FuzgQAIX/G8EKL6fR6Q6aeHUqcyGtwZiu Rp9HA3xWp9WM+vQfCCH+dxaQiQJ7qmnUVxycWyj+os85aGj4Kvz7XnY3w1vU+NRB L7f3vejJHQgbQ1hGRHhsidDsbOjXDfXM2d2YrqvpKKrRyfLMLwLxWFmVRIpXzXsP TYOOtZzvTZBPkSD/qUlSou+65v8xSnrFZstAy3sRhtI/KqrrKO1IKbDqmZ2aVM2k 1j+8dlLmrE+6VhKOBNT21wY9bz2D553pPiyuulhhMpOKHR1jMSmcjiVmhEqm2qQN TirAcgtRcnqP5qn9+fiu8MZ1IbwOO3R4q01VMx1fXPPkVyq0ncNS/dyRFiVZF7fa 21Wtdp6kAFCdKd9AiUkcAecuUlYs9UU1WMGmvfZV2rgMcd2ii4JzY++kR8dbz55p NvNgNNAYwCNXxjqwBi5KLCeLvXnMbRiEEO82McDc5gw44tFCcrJcMiVbLab626/S ITUc8dLTNMG4cEs61ob3wz7sesxwlfWeuTDwRFnlV9JcCzldrc3/GDVBoIgjsBSN trs2/kPXa4sjRKedB+iUEnsfWTrlnYVMMcPgzgbLADc0dPnGQ/evOD+AMMqznDra nIvmWjuNL2IGq1EO9wXcRHFACy3AqrrGUTbaadue7Xb/78gXABHFIK54iFhviKWx oBNyJyJpcogebJe3 =Nbf+ -----END PGP SIGNATURE----- Merge tag 'rpmsg-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux Pull rpmsg updates from Bjorn Andersson: "The remove functions of the Qualcomm SMD and GLINK RPM platform drivers are transitioned to the new void returning prototype. Likewise is qcom_smd_unregister_edge() transitioned to void, as it unconditionally returned 0. An assumption about the ordering of the intent request acknowledgement and advertisement of a new intent in the GLINK implementation is corrected. Faulty error handling is corrected is improved in the TX path, and duplicated code, in the same path, is cleaned up" * tag 'rpmsg-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: rpmsg: glink: Consolidate TX_DATA and TX_DATA_CONT rpmsg: glink: Propagate TX failures in intentless mode as well rpmsg: glink: Wait for intent, not just request ack rpmsg: glink: Transition intent request signaling to wait queue rpmsg: qcom_smd: Convert to platform remove callback returning void rpmsg: qcom_glink_rpm: Convert to platform remove callback returning void rpmsg: qcom_smd: Make qcom_smd_unregister_edge() return void
This commit is contained in:
commit
fe89e9b1af
@ -16,6 +16,7 @@
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
|
||||
@ -145,7 +146,8 @@ enum {
|
||||
* @open_req: completed once open-request has been received
|
||||
* @intent_req_lock: Synchronises multiple intent requests
|
||||
* @intent_req_result: Result of intent request
|
||||
* @intent_req_comp: Completion for intent_req signalling
|
||||
* @intent_received: flag indicating that an intent has been received
|
||||
* @intent_req_wq: wait queue for intent_req signalling
|
||||
*/
|
||||
struct glink_channel {
|
||||
struct rpmsg_endpoint ept;
|
||||
@ -175,8 +177,9 @@ struct glink_channel {
|
||||
struct completion open_req;
|
||||
|
||||
struct mutex intent_req_lock;
|
||||
bool intent_req_result;
|
||||
struct completion intent_req_comp;
|
||||
int intent_req_result;
|
||||
bool intent_received;
|
||||
wait_queue_head_t intent_req_wq;
|
||||
};
|
||||
|
||||
#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
|
||||
@ -221,7 +224,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
|
||||
|
||||
init_completion(&channel->open_req);
|
||||
init_completion(&channel->open_ack);
|
||||
init_completion(&channel->intent_req_comp);
|
||||
init_waitqueue_head(&channel->intent_req_wq);
|
||||
|
||||
INIT_LIST_HEAD(&channel->done_intents);
|
||||
INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
|
||||
@ -419,14 +422,14 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
|
||||
return;
|
||||
}
|
||||
|
||||
channel->intent_req_result = granted;
|
||||
complete(&channel->intent_req_comp);
|
||||
WRITE_ONCE(channel->intent_req_result, granted);
|
||||
wake_up_all(&channel->intent_req_wq);
|
||||
}
|
||||
|
||||
static void qcom_glink_intent_req_abort(struct glink_channel *channel)
|
||||
{
|
||||
channel->intent_req_result = 0;
|
||||
complete(&channel->intent_req_comp);
|
||||
WRITE_ONCE(channel->intent_req_result, 0);
|
||||
wake_up_all(&channel->intent_req_wq);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -756,6 +759,11 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
|
||||
kfree(intent);
|
||||
}
|
||||
spin_unlock_irqrestore(&channel->intent_lock, flags);
|
||||
|
||||
if (reuse) {
|
||||
WRITE_ONCE(channel->intent_received, true);
|
||||
wake_up_all(&channel->intent_req_wq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -993,6 +1001,9 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
|
||||
dev_err(glink->dev, "failed to store remote intent\n");
|
||||
}
|
||||
|
||||
WRITE_ONCE(channel->intent_received, true);
|
||||
wake_up_all(&channel->intent_req_wq);
|
||||
|
||||
kfree(msg);
|
||||
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
|
||||
}
|
||||
@ -1271,7 +1282,8 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
|
||||
|
||||
mutex_lock(&channel->intent_req_lock);
|
||||
|
||||
reinit_completion(&channel->intent_req_comp);
|
||||
WRITE_ONCE(channel->intent_req_result, -1);
|
||||
WRITE_ONCE(channel->intent_received, false);
|
||||
|
||||
cmd.id = GLINK_CMD_RX_INTENT_REQ;
|
||||
cmd.cid = channel->lcid;
|
||||
@ -1281,12 +1293,15 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
ret = wait_for_completion_timeout(&channel->intent_req_comp, 10 * HZ);
|
||||
ret = wait_event_timeout(channel->intent_req_wq,
|
||||
READ_ONCE(channel->intent_req_result) >= 0 &&
|
||||
READ_ONCE(channel->intent_received),
|
||||
10 * HZ);
|
||||
if (!ret) {
|
||||
dev_err(glink->dev, "intent request timed out\n");
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
ret = channel->intent_req_result ? 0 : -ECANCELED;
|
||||
ret = READ_ONCE(channel->intent_req_result) ? 0 : -ECANCELED;
|
||||
}
|
||||
|
||||
unlock:
|
||||
@ -1309,7 +1324,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
int chunk_size = len;
|
||||
int left_size = 0;
|
||||
size_t offset = 0;
|
||||
|
||||
if (!glink->intentless) {
|
||||
while (!intent) {
|
||||
@ -1343,47 +1358,29 @@ static int __qcom_glink_send(struct glink_channel *channel,
|
||||
iid = intent->id;
|
||||
}
|
||||
|
||||
if (wait && chunk_size > SZ_8K) {
|
||||
chunk_size = SZ_8K;
|
||||
left_size = len - chunk_size;
|
||||
}
|
||||
req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA);
|
||||
req.msg.param1 = cpu_to_le16(channel->lcid);
|
||||
req.msg.param2 = cpu_to_le32(iid);
|
||||
req.chunk_size = cpu_to_le32(chunk_size);
|
||||
req.left_size = cpu_to_le32(left_size);
|
||||
|
||||
ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
|
||||
|
||||
/* Mark intent available if we failed */
|
||||
if (ret && intent) {
|
||||
intent->in_use = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (left_size > 0) {
|
||||
data = (void *)((char *)data + chunk_size);
|
||||
chunk_size = left_size;
|
||||
if (chunk_size > SZ_8K)
|
||||
while (offset < len) {
|
||||
chunk_size = len - offset;
|
||||
if (chunk_size > SZ_8K && wait)
|
||||
chunk_size = SZ_8K;
|
||||
left_size -= chunk_size;
|
||||
|
||||
req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA_CONT);
|
||||
req.msg.cmd = cpu_to_le16(offset == 0 ? GLINK_CMD_TX_DATA : GLINK_CMD_TX_DATA_CONT);
|
||||
req.msg.param1 = cpu_to_le16(channel->lcid);
|
||||
req.msg.param2 = cpu_to_le32(iid);
|
||||
req.chunk_size = cpu_to_le32(chunk_size);
|
||||
req.left_size = cpu_to_le32(left_size);
|
||||
req.left_size = cpu_to_le32(len - offset - chunk_size);
|
||||
|
||||
ret = qcom_glink_tx(glink, &req, sizeof(req), data,
|
||||
chunk_size, wait);
|
||||
|
||||
/* Mark intent available if we failed */
|
||||
if (ret && intent) {
|
||||
intent->in_use = false;
|
||||
break;
|
||||
ret = qcom_glink_tx(glink, &req, sizeof(req), data + offset, chunk_size, wait);
|
||||
if (ret) {
|
||||
/* Mark intent available if we failed */
|
||||
if (intent)
|
||||
intent->in_use = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset += chunk_size;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_glink_send(struct rpmsg_endpoint *ept, void *data, int len)
|
||||
|
@ -361,7 +361,7 @@ static int glink_rpm_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int glink_rpm_remove(struct platform_device *pdev)
|
||||
static void glink_rpm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct glink_rpm *rpm = platform_get_drvdata(pdev);
|
||||
struct qcom_glink *glink = rpm->glink;
|
||||
@ -371,8 +371,6 @@ static int glink_rpm_remove(struct platform_device *pdev)
|
||||
qcom_glink_native_remove(glink);
|
||||
|
||||
mbox_free_channel(rpm->mbox_chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id glink_rpm_of_match[] = {
|
||||
@ -383,7 +381,7 @@ MODULE_DEVICE_TABLE(of, glink_rpm_of_match);
|
||||
|
||||
static struct platform_driver glink_rpm_driver = {
|
||||
.probe = glink_rpm_probe,
|
||||
.remove = glink_rpm_remove,
|
||||
.remove_new = glink_rpm_remove,
|
||||
.driver = {
|
||||
.name = "qcom_glink_rpm",
|
||||
.of_match_table = glink_rpm_of_match,
|
||||
|
@ -1533,7 +1533,7 @@ static int qcom_smd_remove_device(struct device *dev, void *data)
|
||||
* qcom_smd_unregister_edge() - release an edge and its children
|
||||
* @edge: edge reference acquired from qcom_smd_register_edge
|
||||
*/
|
||||
int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
|
||||
void qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1547,8 +1547,6 @@ int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
|
||||
|
||||
mbox_free_channel(edge->mbox_chan);
|
||||
device_unregister(&edge->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_smd_unregister_edge);
|
||||
|
||||
@ -1572,22 +1570,22 @@ static int qcom_smd_remove_edge(struct device *dev, void *data)
|
||||
{
|
||||
struct qcom_smd_edge *edge = to_smd_edge(dev);
|
||||
|
||||
return qcom_smd_unregister_edge(edge);
|
||||
qcom_smd_unregister_edge(edge);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shut down all smd clients by making sure that each edge stops processing
|
||||
* events and scanning for new channels, then call destroy on the devices.
|
||||
*/
|
||||
static int qcom_smd_remove(struct platform_device *pdev)
|
||||
static void qcom_smd_remove(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "can't remove smd device: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
/*
|
||||
* qcom_smd_remove_edge always returns zero, so there is no need to
|
||||
* check the return value of device_for_each_child.
|
||||
*/
|
||||
device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge);
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_smd_of_match[] = {
|
||||
@ -1598,7 +1596,7 @@ MODULE_DEVICE_TABLE(of, qcom_smd_of_match);
|
||||
|
||||
static struct platform_driver qcom_smd_driver = {
|
||||
.probe = qcom_smd_probe,
|
||||
.remove = qcom_smd_remove,
|
||||
.remove_new = qcom_smd_remove,
|
||||
.driver = {
|
||||
.name = "qcom-smd",
|
||||
.of_match_table = qcom_smd_of_match,
|
||||
|
@ -11,7 +11,7 @@ struct qcom_smd_edge;
|
||||
|
||||
struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
|
||||
struct device_node *node);
|
||||
int qcom_smd_unregister_edge(struct qcom_smd_edge *edge);
|
||||
void qcom_smd_unregister_edge(struct qcom_smd_edge *edge);
|
||||
|
||||
#else
|
||||
|
||||
@ -22,9 +22,8 @@ qcom_smd_register_edge(struct device *parent,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
|
||||
static inline void qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user