diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index cd946fff31a9..8a588d26e827 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -3715,30 +3715,49 @@ static void ipa3_destroy_flt_tbl_idrs(void) static void ipa3_freeze_clock_vote_and_notify_modem(void) { int res; - u32 ipa_clk_state; struct ipa_active_client_logging_info log_info; if (ipa3_ctx->smp2p_info.res_sent) return; + if (ipa3_ctx->smp2p_info.out_base_id == 0) { + IPAERR("smp2p out gpio not assigned\n"); + return; + } + IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, "FREEZE_VOTE"); res = ipa3_inc_client_enable_clks_no_block(&log_info); if (res) - ipa_clk_state = 0; + ipa3_ctx->smp2p_info.ipa_clk_on = false; else - ipa_clk_state = 1; + ipa3_ctx->smp2p_info.ipa_clk_on = true; - if (ipa3_ctx->smp2p_info.out_base_id) { - gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + - IPA_GPIO_OUT_CLK_VOTE_IDX, ipa_clk_state); - gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + - IPA_GPIO_OUT_CLK_RSP_CMPLT_IDX, 1); - ipa3_ctx->smp2p_info.res_sent = true; - } else { - IPAERR("smp2p out gpio not assigned\n"); - } + gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + + IPA_GPIO_OUT_CLK_VOTE_IDX, + ipa3_ctx->smp2p_info.ipa_clk_on); + gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + + IPA_GPIO_OUT_CLK_RSP_CMPLT_IDX, 1); - IPADBG("IPA clocks are %s\n", ipa_clk_state ? "ON" : "OFF"); + ipa3_ctx->smp2p_info.res_sent = true; + IPADBG("IPA clocks are %s\n", + ipa3_ctx->smp2p_info.ipa_clk_on ? "ON" : "OFF"); +} + +void ipa3_reset_freeze_vote(void) +{ + if (ipa3_ctx->smp2p_info.res_sent == false) + return; + + if (ipa3_ctx->smp2p_info.ipa_clk_on) + IPA_ACTIVE_CLIENTS_DEC_SPECIAL("FREEZE_VOTE"); + + gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + + IPA_GPIO_OUT_CLK_VOTE_IDX, 0); + gpio_set_value(ipa3_ctx->smp2p_info.out_base_id + + IPA_GPIO_OUT_CLK_RSP_CMPLT_IDX, 0); + + ipa3_ctx->smp2p_info.res_sent = false; + ipa3_ctx->smp2p_info.ipa_clk_on = false; } static int ipa3_panic_notifier(struct notifier_block *this, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 7feb1c1ce178..9938221e34b0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1002,6 +1002,7 @@ struct ipa3cm_client_info { struct ipa3_smp2p_info { u32 out_base_id; u32 in_base_id; + bool ipa_clk_on; bool res_sent; }; @@ -2045,6 +2046,7 @@ void ipa3_recycle_wan_skb(struct sk_buff *skb); int ipa3_smmu_map_peer_reg(phys_addr_t phys_addr, bool map); int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map); +void ipa3_reset_freeze_vote(void); int ipa3_ntn_init(void); int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index f042d19f196a..de2b110ef8bd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -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 @@ -2435,6 +2435,7 @@ static int ipa3_ssr_notifier_cb(struct notifier_block *this, ipa3_qmi_service_exit(); /*hold a proxy vote for the modem*/ ipa3_proxy_clk_vote(); + ipa3_reset_freeze_vote(); IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n"); break; case SUBSYS_AFTER_POWERUP: