Loading Documentation/devicetree/bindings/arm/msm/msm_ipc_router_glink_xprt.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading drivers/soc/qcom/ipc_router_glink_xprt.c +20 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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]; Loading @@ -138,6 +141,7 @@ struct ipc_router_glink_xprt_config { unsigned int xprt_version; unsigned int xprt_option; bool disable_pil_loading; bool dynamic_wakeup_source; }; #define MODULE_NAME "ipc_router_glink_xprt" Loading Loading @@ -294,6 +298,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; Loading Loading @@ -706,6 +718,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, Loading @@ -728,6 +742,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); Loading Loading @@ -822,6 +837,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: Loading include/linux/ipc_router.h +11 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-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 Loading Loading @@ -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( Loading Loading @@ -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 include/linux/ipc_router_xprt.h +5 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading @@ -108,6 +109,7 @@ struct rr_packet { struct sk_buff_head *pkt_fragment_q; uint32_t length; struct kref ref; bool ws_need; }; /** Loading @@ -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; Loading @@ -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, Loading net/ipc_router/ipc_router_core.c +25 −3 Original line number Diff line number Diff line /* 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 Loading Loading @@ -148,6 +148,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 Loading Loading @@ -215,6 +216,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; Loading Loading @@ -580,6 +588,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: Loading Loading @@ -1162,6 +1171,7 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, } mutex_lock(&port_ptr->port_rx_q_lock_lhc3); 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); Loading Loading @@ -4043,6 +4053,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) { Loading Loading @@ -4193,9 +4206,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); 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 Loading
Documentation/devicetree/bindings/arm/msm/msm_ipc_router_glink_xprt.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
drivers/soc/qcom/ipc_router_glink_xprt.c +20 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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]; Loading @@ -138,6 +141,7 @@ struct ipc_router_glink_xprt_config { unsigned int xprt_version; unsigned int xprt_option; bool disable_pil_loading; bool dynamic_wakeup_source; }; #define MODULE_NAME "ipc_router_glink_xprt" Loading Loading @@ -294,6 +298,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; Loading Loading @@ -706,6 +718,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, Loading @@ -728,6 +742,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); Loading Loading @@ -822,6 +837,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: Loading
include/linux/ipc_router.h +11 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-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 Loading Loading @@ -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( Loading Loading @@ -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
include/linux/ipc_router_xprt.h +5 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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; Loading @@ -108,6 +109,7 @@ struct rr_packet { struct sk_buff_head *pkt_fragment_q; uint32_t length; struct kref ref; bool ws_need; }; /** Loading @@ -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; Loading @@ -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, Loading
net/ipc_router/ipc_router_core.c +25 −3 Original line number Diff line number Diff line /* 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 Loading Loading @@ -148,6 +148,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 Loading Loading @@ -215,6 +216,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; Loading Loading @@ -580,6 +588,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: Loading Loading @@ -1162,6 +1171,7 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, } mutex_lock(&port_ptr->port_rx_q_lock_lhc3); 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); Loading Loading @@ -4043,6 +4053,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) { Loading Loading @@ -4193,9 +4206,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); 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