Merge "net: ipc_router: Add dynamic enable/disable wakeup source feature"
This commit is contained in:
commit
0899f88b10
5 changed files with 63 additions and 6 deletions
|
@ -17,6 +17,8 @@ Optional properties:
|
|||
by pil. Absence of this property indicates that
|
||||
subsystem loading through pil voting is disabled for
|
||||
that subsystem.
|
||||
-qcom,dynamic-wakeup-source: Boolean property to indicate that G-Link
|
||||
transport supports dynamic wakeup source
|
||||
|
||||
Example:
|
||||
qcom,ipc_router_modem_xprt {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -70,6 +70,7 @@ if (ipc_router_glink_xprt_debug_mask) \
|
|||
* @xprt_version: IPC Router header version supported by this XPRT.
|
||||
* @xprt_option: XPRT specific options to be handled by IPC Router.
|
||||
* @disable_pil_loading: Disable PIL Loading of the subsystem.
|
||||
* @dynamic_wakeup_source: Dynamic wakeup source for this subsystem.
|
||||
*/
|
||||
struct ipc_router_glink_xprt {
|
||||
struct list_head list;
|
||||
|
@ -91,6 +92,7 @@ struct ipc_router_glink_xprt {
|
|||
uint32_t cur_lo_intents_cnt;
|
||||
uint32_t cur_md_intents_cnt;
|
||||
uint32_t cur_hi_intents_cnt;
|
||||
bool dynamic_wakeup_source;
|
||||
};
|
||||
|
||||
struct ipc_router_glink_xprt_work {
|
||||
|
@ -127,6 +129,7 @@ static void glink_xprt_close_event(struct work_struct *work);
|
|||
* @link_id: Network Cluster ID to which this XPRT belongs to.
|
||||
* @xprt_version: IPC Router header version supported by this XPRT.
|
||||
* @disable_pil_loading:Disable PIL Loading of the subsystem.
|
||||
* @dynamic_wakeup_source: Dynamic wakeup source for this subsystem.
|
||||
*/
|
||||
struct ipc_router_glink_xprt_config {
|
||||
char ch_name[GLINK_NAME_SIZE];
|
||||
|
@ -138,6 +141,7 @@ struct ipc_router_glink_xprt_config {
|
|||
unsigned xprt_version;
|
||||
unsigned xprt_option;
|
||||
bool disable_pil_loading;
|
||||
bool dynamic_wakeup_source;
|
||||
};
|
||||
|
||||
#define MODULE_NAME "ipc_router_glink_xprt"
|
||||
|
@ -292,6 +296,14 @@ static void glink_xprt_sft_close_done(struct msm_ipc_router_xprt *xprt)
|
|||
complete_all(&glink_xprtp->sft_close_complete);
|
||||
}
|
||||
|
||||
static bool ipc_router_glink_xprt_get_ws_info(struct msm_ipc_router_xprt *xprt)
|
||||
{
|
||||
struct ipc_router_glink_xprt *glink_xprtp =
|
||||
container_of(xprt, struct ipc_router_glink_xprt, xprt);
|
||||
|
||||
return glink_xprtp->dynamic_wakeup_source;
|
||||
}
|
||||
|
||||
static struct rr_packet *glink_xprt_copy_data(struct read_work *rx_work)
|
||||
{
|
||||
void *buf, *pbuf, *dest_buf;
|
||||
|
@ -705,6 +717,8 @@ static int ipc_router_glink_config_init(
|
|||
glink_xprtp->xprt_option = glink_xprt_config->xprt_option;
|
||||
glink_xprtp->disable_pil_loading =
|
||||
glink_xprt_config->disable_pil_loading;
|
||||
glink_xprtp->dynamic_wakeup_source =
|
||||
glink_xprt_config->dynamic_wakeup_source;
|
||||
|
||||
if (!glink_xprtp->disable_pil_loading)
|
||||
strlcpy(glink_xprtp->pil_edge, glink_xprt_config->pil_edge,
|
||||
|
@ -727,6 +741,7 @@ static int ipc_router_glink_config_init(
|
|||
glink_xprtp->xprt.write = ipc_router_glink_xprt_write;
|
||||
glink_xprtp->xprt.close = ipc_router_glink_xprt_close;
|
||||
glink_xprtp->xprt.sft_close_done = glink_xprt_sft_close_done;
|
||||
glink_xprtp->xprt.get_ws_info = ipc_router_glink_xprt_get_ws_info;
|
||||
glink_xprtp->xprt.priv = NULL;
|
||||
|
||||
init_rwsem(&glink_xprtp->ss_reset_rwlock);
|
||||
|
@ -821,6 +836,10 @@ static int parse_devicetree(struct device_node *node,
|
|||
scnprintf(glink_xprt_config->ipc_rtr_xprt_name, IPC_RTR_XPRT_NAME_LEN,
|
||||
"%s_%s", edge, ch_name);
|
||||
|
||||
key = "qcom,dynamic-wakeup-source";
|
||||
glink_xprt_config->dynamic_wakeup_source =
|
||||
of_property_read_bool(node, key);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -269,6 +269,14 @@ int register_ipcrtr_af_init_notifier(struct notifier_block *nb);
|
|||
*/
|
||||
int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* msm_ipc_router_set_ws_allowed() - To Enable/disable the wakeup source allowed
|
||||
* flag
|
||||
* @flag: Flag to set/clear the wakeup soruce allowed
|
||||
*
|
||||
*/
|
||||
void msm_ipc_router_set_ws_allowed(bool flag);
|
||||
|
||||
#else
|
||||
|
||||
struct msm_ipc_port *msm_ipc_router_create_port(
|
||||
|
@ -341,6 +349,8 @@ int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
void msm_ipc_router_set_ws_allowed(bool flag) { }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2015,2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -100,6 +100,7 @@ struct rr_opt_hdr {
|
|||
* @pkt_fragment_q: Queue of SKBs containing payload.
|
||||
* @length: Length of data in the chain of SKBs
|
||||
* @ref: Reference count for the packet.
|
||||
* @ws_need: Flag to check wakeup soruce need
|
||||
*/
|
||||
struct rr_packet {
|
||||
struct list_head list;
|
||||
|
@ -108,6 +109,7 @@ struct rr_packet {
|
|||
struct sk_buff_head *pkt_fragment_q;
|
||||
uint32_t length;
|
||||
struct kref ref;
|
||||
bool ws_need;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -125,6 +127,7 @@ struct rr_packet {
|
|||
* @close: Method to close the XPRT.
|
||||
* @sft_close_done: Method to indicate to the XPRT that handling of reset
|
||||
* event is complete.
|
||||
* @get_ws_info: Method to get the wakeup soruce inforamtion of the XPRT
|
||||
*/
|
||||
struct msm_ipc_router_xprt {
|
||||
char *name;
|
||||
|
@ -143,6 +146,7 @@ struct msm_ipc_router_xprt {
|
|||
struct msm_ipc_router_xprt *xprt);
|
||||
int (*close)(struct msm_ipc_router_xprt *xprt);
|
||||
void (*sft_close_done)(struct msm_ipc_router_xprt *xprt);
|
||||
bool (*get_ws_info)(struct msm_ipc_router_xprt *xprt);
|
||||
};
|
||||
|
||||
void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -149,6 +149,7 @@ struct msm_ipc_router_xprt_info {
|
|||
void *log_ctx;
|
||||
struct kref ref;
|
||||
struct completion ref_complete;
|
||||
bool dynamic_ws;
|
||||
};
|
||||
|
||||
#define RT_HASH_SIZE 4
|
||||
|
@ -216,6 +217,13 @@ enum {
|
|||
UP,
|
||||
};
|
||||
|
||||
static bool is_wakeup_source_allowed;
|
||||
|
||||
void msm_ipc_router_set_ws_allowed(bool flag)
|
||||
{
|
||||
is_wakeup_source_allowed = flag;
|
||||
}
|
||||
|
||||
static void init_routing_table(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -581,6 +589,7 @@ struct rr_packet *clone_pkt(struct rr_packet *pkt)
|
|||
}
|
||||
cloned_pkt->pkt_fragment_q = pkt_fragment_q;
|
||||
cloned_pkt->length = pkt->length;
|
||||
cloned_pkt->ws_need = pkt->ws_need;
|
||||
return cloned_pkt;
|
||||
|
||||
fail_clone:
|
||||
|
@ -1164,7 +1173,8 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr,
|
|||
}
|
||||
|
||||
mutex_lock(&port_ptr->port_rx_q_lock_lhc3);
|
||||
__pm_stay_awake(port_ptr->port_rx_ws);
|
||||
if (pkt->ws_need)
|
||||
__pm_stay_awake(port_ptr->port_rx_ws);
|
||||
list_add_tail(&temp_pkt->list, &port_ptr->port_rx_q);
|
||||
wake_up(&port_ptr->port_rx_wait_q);
|
||||
notify = port_ptr->notify;
|
||||
|
@ -4064,6 +4074,9 @@ static int msm_ipc_router_add_xprt(struct msm_ipc_router_xprt *xprt)
|
|||
INIT_LIST_HEAD(&xprt_info->list);
|
||||
kref_init(&xprt_info->ref);
|
||||
init_completion(&xprt_info->ref_complete);
|
||||
xprt_info->dynamic_ws = 0;
|
||||
if (xprt->get_ws_info)
|
||||
xprt_info->dynamic_ws = xprt->get_ws_info(xprt);
|
||||
|
||||
xprt_info->workqueue = create_singlethread_workqueue(xprt->name);
|
||||
if (!xprt_info->workqueue) {
|
||||
|
@ -4218,9 +4231,18 @@ void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
|
|||
if (!pkt)
|
||||
return;
|
||||
|
||||
pkt->ws_need = false;
|
||||
mutex_lock(&xprt_info->rx_lock_lhb2);
|
||||
list_add_tail(&pkt->list, &xprt_info->pkt_list);
|
||||
__pm_stay_awake(&xprt_info->ws);
|
||||
if (!xprt_info->dynamic_ws) {
|
||||
__pm_stay_awake(&xprt_info->ws);
|
||||
pkt->ws_need = true;
|
||||
} else {
|
||||
if (is_wakeup_source_allowed) {
|
||||
__pm_stay_awake(&xprt_info->ws);
|
||||
pkt->ws_need = true;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&xprt_info->rx_lock_lhb2);
|
||||
queue_work(xprt_info->workqueue, &xprt_info->read_data);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue