Loading drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +18 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2016, 2018, 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 @@ -2098,6 +2098,18 @@ static void ipa_usb_debugfs_init(void){} static void ipa_usb_debugfs_remove(void){} #endif /* CONFIG_DEBUG_FS */ static int ipa_usb_set_lock_unlock(bool is_lock) { IPA_USB_DBG("entry\n"); if (is_lock) mutex_lock(&ipa3_usb_ctx->general_mutex); else mutex_unlock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("exit\n"); return 0; } int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, Loading Loading @@ -2160,6 +2172,9 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, goto connect_fail; } /* Register for xdci lock/unlock callback with ipa core driver */ ipa3_register_lock_unlock_callback(&ipa_usb_set_lock_unlock, ul_out_params->clnt_hdl); IPA_USB_DBG_LOW("exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; Loading Loading @@ -2236,6 +2251,8 @@ static int ipa_usb_xdci_dismiss_channels(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } } ipa3_deregister_lock_unlock_callback(ul_clnt_hdl); /* Change state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED, false, ttype)) IPA_USB_ERR("failed to change state to stopped\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -2566,6 +2566,8 @@ void ipa3_q6_pre_shutdown_cleanup(void) */ ipa3_q6_pipe_delay(false); ipa3_set_usb_prod_pipe_delay(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG_LOW("Exit with success\n"); } Loading drivers/platform/msm/ipa/ipa_v3/ipa_client.c +104 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -1167,6 +1167,69 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map) return 0; } void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock), u32 ipa_ep_idx) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (client_cb == NULL) { IPAERR("Bad Param"); return; } ep->client_lock_unlock = client_cb; IPADBG("exit\n"); } void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (ep->client_lock_unlock == NULL) { IPAERR("client_lock_unlock is already NULL"); return; } ep->client_lock_unlock = NULL; IPADBG("exit\n"); } static void client_lock_unlock_cb(u32 ipa_ep_idx, bool is_lock) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (ep->client_lock_unlock) ep->client_lock_unlock(is_lock); IPADBG("exit\n"); } int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params, struct ipa_req_chan_out_params *out_params) Loading Loading @@ -1784,6 +1847,46 @@ exit: return result; } /* * Set USB PROD pipe delay for MBIM/RMNET config * Clocks, should be voted before calling this API * locks should be taken before calling this API */ void ipa3_set_usb_prod_pipe_delay(void) { int result; int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_ctrl; memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl)); ep_ctrl.ipa_ep_delay = true; pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD); return; } ep = &ipa3_ctx->ep[pipe_idx]; /* Setting delay on USB_PROD with skip_ep_cfg */ client_lock_unlock_cb(pipe_idx, true); if (ep->valid && ep->skip_ep_cfg) { ep->ep_delay_set = ep_ctrl.ipa_ep_delay; result = ipa3_cfg_ep_ctrl(pipe_idx, &ep_ctrl); if (result) IPAERR("client (ep: %d) failed result=%d\n", pipe_idx, result); else IPADBG("client (ep: %d) success\n", pipe_idx); } client_lock_unlock_cb(pipe_idx, false); } void ipa3_xdci_ep_delay_rm(u32 clnt_hdl) { struct ipa3_ep_context *ep; Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -577,6 +577,8 @@ struct ipa3_status_stats { * @disconnect_in_progress: Indicates client disconnect in progress. * @qmi_request_sent: Indicates whether QMI request to enable clear data path * request is sent or not. * @client_lock_unlock: callback function to take mutex lock/unlock for USB * clients */ struct ipa3_ep_context { int valid; Loading Loading @@ -615,6 +617,8 @@ struct ipa3_ep_context { u32 qmi_request_sent; bool ep_delay_set; int (*client_lock_unlock)(bool is_lock); /* sys MUST be the last element of this struct */ struct ipa3_sys_context *sys; }; Loading Loading @@ -1524,6 +1528,9 @@ int ipa3_xdci_connect(u32 clnt_hdl); int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); void ipa3_xdci_ep_delay_rm(u32 clnt_hdl); void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx); void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx); void ipa3_set_usb_prod_pipe_delay(void); int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, bool should_force_clear, u32 qmi_req_id, bool is_dpl); Loading Loading
drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +18 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2016, 2018, 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 @@ -2098,6 +2098,18 @@ static void ipa_usb_debugfs_init(void){} static void ipa_usb_debugfs_remove(void){} #endif /* CONFIG_DEBUG_FS */ static int ipa_usb_set_lock_unlock(bool is_lock) { IPA_USB_DBG("entry\n"); if (is_lock) mutex_lock(&ipa3_usb_ctx->general_mutex); else mutex_unlock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("exit\n"); return 0; } int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, Loading Loading @@ -2160,6 +2172,9 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, goto connect_fail; } /* Register for xdci lock/unlock callback with ipa core driver */ ipa3_register_lock_unlock_callback(&ipa_usb_set_lock_unlock, ul_out_params->clnt_hdl); IPA_USB_DBG_LOW("exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; Loading Loading @@ -2236,6 +2251,8 @@ static int ipa_usb_xdci_dismiss_channels(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } } ipa3_deregister_lock_unlock_callback(ul_clnt_hdl); /* Change state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED, false, ttype)) IPA_USB_ERR("failed to change state to stopped\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -2566,6 +2566,8 @@ void ipa3_q6_pre_shutdown_cleanup(void) */ ipa3_q6_pipe_delay(false); ipa3_set_usb_prod_pipe_delay(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG_LOW("Exit with success\n"); } Loading
drivers/platform/msm/ipa/ipa_v3/ipa_client.c +104 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -1167,6 +1167,69 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map) return 0; } void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock), u32 ipa_ep_idx) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (client_cb == NULL) { IPAERR("Bad Param"); return; } ep->client_lock_unlock = client_cb; IPADBG("exit\n"); } void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (ep->client_lock_unlock == NULL) { IPAERR("client_lock_unlock is already NULL"); return; } ep->client_lock_unlock = NULL; IPADBG("exit\n"); } static void client_lock_unlock_cb(u32 ipa_ep_idx, bool is_lock) { struct ipa3_ep_context *ep; IPADBG("entry\n"); ep = &ipa3_ctx->ep[ipa_ep_idx]; if (!ep->valid) { IPAERR("Invalid EP\n"); return; } if (ep->client_lock_unlock) ep->client_lock_unlock(is_lock); IPADBG("exit\n"); } int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params, struct ipa_req_chan_out_params *out_params) Loading Loading @@ -1784,6 +1847,46 @@ exit: return result; } /* * Set USB PROD pipe delay for MBIM/RMNET config * Clocks, should be voted before calling this API * locks should be taken before calling this API */ void ipa3_set_usb_prod_pipe_delay(void) { int result; int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_ctrl; memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl)); ep_ctrl.ipa_ep_delay = true; pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD); return; } ep = &ipa3_ctx->ep[pipe_idx]; /* Setting delay on USB_PROD with skip_ep_cfg */ client_lock_unlock_cb(pipe_idx, true); if (ep->valid && ep->skip_ep_cfg) { ep->ep_delay_set = ep_ctrl.ipa_ep_delay; result = ipa3_cfg_ep_ctrl(pipe_idx, &ep_ctrl); if (result) IPAERR("client (ep: %d) failed result=%d\n", pipe_idx, result); else IPADBG("client (ep: %d) success\n", pipe_idx); } client_lock_unlock_cb(pipe_idx, false); } void ipa3_xdci_ep_delay_rm(u32 clnt_hdl) { struct ipa3_ep_context *ep; Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, 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 @@ -577,6 +577,8 @@ struct ipa3_status_stats { * @disconnect_in_progress: Indicates client disconnect in progress. * @qmi_request_sent: Indicates whether QMI request to enable clear data path * request is sent or not. * @client_lock_unlock: callback function to take mutex lock/unlock for USB * clients */ struct ipa3_ep_context { int valid; Loading Loading @@ -615,6 +617,8 @@ struct ipa3_ep_context { u32 qmi_request_sent; bool ep_delay_set; int (*client_lock_unlock)(bool is_lock); /* sys MUST be the last element of this struct */ struct ipa3_sys_context *sys; }; Loading Loading @@ -1524,6 +1528,9 @@ int ipa3_xdci_connect(u32 clnt_hdl); int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); void ipa3_xdci_ep_delay_rm(u32 clnt_hdl); void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx); void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx); void ipa3_set_usb_prod_pipe_delay(void); int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, bool should_force_clear, u32 qmi_req_id, bool is_dpl); Loading