net: qrtr: Support pm_wakeup_event() based on svc
Instead of filtering pm_wakeup_event() call via node ID, add support to do it based on the service ID. This provides more fine control over which incoming packet can wakeup APPS. Change-Id: I1e4a7f6d04a2e37104191bedc5d87070aabc002b Signed-off-by: Tony Truong <quic_truong@quicinc.com>
This commit is contained in:
parent
fe94f61475
commit
1da9ab5d38
@ -185,6 +185,8 @@ struct qrtr_node {
|
||||
|
||||
struct wakeup_source *ws;
|
||||
void *ilc;
|
||||
|
||||
struct xarray no_wake_svc; /* services that will not wake up APPS */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -799,6 +801,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
|
||||
unsigned int ver;
|
||||
size_t hdrlen;
|
||||
int errcode;
|
||||
int svc_id;
|
||||
|
||||
if (len == 0 || len & 3)
|
||||
return -EINVAL;
|
||||
@ -906,8 +909,9 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Force wakeup for all packets except for sensors */
|
||||
if (node->nid != 9)
|
||||
/* Force wakeup based on services */
|
||||
svc_id = qrtr_get_service_id(cb->src_node, cb->src_port);
|
||||
if (!xa_load(&node->no_wake_svc, svc_id))
|
||||
pm_wakeup_ws_event(node->ws, qrtr_wakeup_ms, true);
|
||||
|
||||
qrtr_port_put(ipc);
|
||||
@ -1115,13 +1119,16 @@ static void qrtr_hello_work(struct kthread_work *work)
|
||||
* @ep: endpoint to register
|
||||
* @nid: desired node id; may be QRTR_EP_NID_AUTO for auto-assignment
|
||||
* @rt: flag to notify real time low latency endpoint
|
||||
* @no_wake: array of services to not wake up
|
||||
* Return: 0 on success; negative error code on failure
|
||||
*
|
||||
* The specified endpoint must have the xmit function pointer set on call.
|
||||
*/
|
||||
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
|
||||
bool rt)
|
||||
bool rt, struct qrtr_array *no_wake)
|
||||
{
|
||||
int rc, i;
|
||||
size_t size;
|
||||
struct qrtr_node *node;
|
||||
struct sched_param param = {.sched_priority = 1};
|
||||
|
||||
@ -1151,6 +1158,17 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
|
||||
if (rt)
|
||||
sched_setscheduler(node->task, SCHED_FIFO, ¶m);
|
||||
|
||||
xa_init(&node->no_wake_svc);
|
||||
size = no_wake ? no_wake->size : 0;
|
||||
for (i = 0; i < size; i++) {
|
||||
rc = xa_insert(&node->no_wake_svc, no_wake->arr[i], node,
|
||||
GFP_KERNEL);
|
||||
if (rc) {
|
||||
kfree(node);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL);
|
||||
mutex_init(&node->qrtr_tx_lock);
|
||||
|
||||
|
@ -454,7 +454,8 @@ static int qrtr_gunyah_rm_cb(struct notifier_block *nb, unsigned long cmd,
|
||||
|
||||
if (vm_status_payload->vm_status == GH_RM_VM_STATUS_READY) {
|
||||
qrtr_gunyah_fifo_init(qdev);
|
||||
if (qrtr_endpoint_register(&qdev->ep, QRTR_EP_NET_ID_AUTO, false)) {
|
||||
if (qrtr_endpoint_register(&qdev->ep, QRTR_EP_NET_ID_AUTO,
|
||||
false, NULL)) {
|
||||
pr_err("%s: endpoint register failed\n", __func__);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
@ -649,7 +650,7 @@ static int qrtr_gunyah_probe(struct platform_device *pdev)
|
||||
qdev->ep.xmit = qrtr_gunyah_send;
|
||||
if (!qdev->master) {
|
||||
ret = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NET_ID_AUTO,
|
||||
false);
|
||||
false, NULL);
|
||||
if (ret)
|
||||
goto register_fail;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
|
||||
|
||||
qrtr_mhi_of_parse(mhi_dev, &net_id, &rt);
|
||||
|
||||
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt);
|
||||
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -26,8 +26,20 @@ struct qrtr_endpoint {
|
||||
struct qrtr_node *node;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qrtr_array - array with size
|
||||
* @arr: elements in the array
|
||||
* @size: number of elements
|
||||
*
|
||||
* An array with its size provided.
|
||||
*/
|
||||
struct qrtr_array {
|
||||
u32 *arr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
|
||||
bool rt);
|
||||
bool rt, struct qrtr_array *no_wake);
|
||||
|
||||
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);
|
||||
|
||||
|
@ -66,7 +66,9 @@ static int qcom_smd_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
|
||||
|
||||
static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct qrtr_array svc_arr = {NULL, 0};
|
||||
struct qrtr_smd_dev *qdev;
|
||||
size_t size;
|
||||
u32 net_id;
|
||||
bool rt;
|
||||
int rc;
|
||||
@ -85,7 +87,19 @@ static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev)
|
||||
|
||||
rt = of_property_read_bool(rpdev->dev.of_node, "qcom,low-latency");
|
||||
|
||||
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt);
|
||||
size = of_property_count_u32_elems(rpdev->dev.of_node, "qcom,no-wake-svc");
|
||||
if (size > 0) {
|
||||
svc_arr.size = size;
|
||||
svc_arr.arr = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
|
||||
if (!svc_arr.arr)
|
||||
return -ENOMEM;
|
||||
|
||||
of_property_read_u32_array(rpdev->dev.of_node, "qcom,no-wake-svc",
|
||||
svc_arr.arr, size);
|
||||
}
|
||||
|
||||
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, &svc_arr);
|
||||
kfree(svc_arr.arr);
|
||||
if (rc) {
|
||||
dev_err(qdev->dev, "endpoint register failed: %d, low-latency: %d\n", rc, rt);
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user