diff options
| author | Prashanth Bhatta <bhattap@qca.qualcomm.com> | 2014-07-15 15:01:58 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-07-19 18:03:47 -0700 |
| commit | 000ae06ce1dbfc860d7a3cf84dbabe10b75d54a2 (patch) | |
| tree | 8febc75000f740e6f96c677ca08e5e69e4be479d | |
| parent | 5ca4cb9a69b050968e53989364c64e9b4e2f02d3 (diff) | |
qcacld: ipa: Request PROD resource on seeing activity on CONS
IPA RM has a limitation where in modem side IPA driver and APSS
side IPA driver doesn't have any communication because of which
IPA could be clocked down any time. Now adding changes such that
request PROD resource on seeing activity on CONS pipe so that IPA
clock will not be in low power mode while there is data flowing
over CONS pipe.
Change-Id: I328d0bd73cc8569050fff95e7a9cd46584293a71
CRs-fixed: 669894
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_ipa.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index a2742be3575e..37eae808bdc6 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -287,6 +287,7 @@ struct hdd_ipa_priv { struct work_struct rm_work; enum ipa_client_type prod_client; + atomic_t tx_ref_cnt; uint32_t pending_hw_desc_cnt; uint32_t hw_desc_cnt; spinlock_t q_lock; @@ -893,6 +894,9 @@ static int hdd_ipa_rm_try_release(struct hdd_ipa_priv *hdd_ipa) if (!hdd_ipa_is_rm_enabled(hdd_ipa)) return 0; + if (atomic_read(&hdd_ipa->tx_ref_cnt)) + return -EAGAIN; + spin_lock_bh(&hdd_ipa->q_lock); if (hdd_ipa->pending_hw_desc_cnt || hdd_ipa->pend_q_cnt) { spin_unlock_bh(&hdd_ipa->q_lock); @@ -1138,6 +1142,7 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) adf_os_spinlock_init(&hdd_ipa->rm_lock); hdd_ipa->rm_state = HDD_IPA_RM_RELEASED; + atomic_set(&hdd_ipa->tx_ref_cnt, 0); return ret; @@ -1553,6 +1558,10 @@ static void hdd_ipa_nbuf_cb(adf_nbuf_t skb) ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb)); hdd_ipa->stats.num_tx_comp_cnt++; + + atomic_dec(&hdd_ipa->tx_ref_cnt); + + hdd_ipa_rm_try_release(hdd_ipa); } static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, @@ -1624,6 +1633,17 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, return; } + atomic_inc(&hdd_ipa->tx_ref_cnt); + + /* + * If PROD resource is not requested here then there may be cases where + * IPA hardware may be clocked down because of not having proper + * dependency graph between WLAN CONS and modem PROD pipes. Adding the + * workaround to request PROD resource while data is going over CONS + * pipe to prevent the IPA hardware clockdown. + */ + hdd_ipa_rm_request(hdd_ipa); + iface_context->stats.num_tx++; } @@ -2373,6 +2393,9 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, len += scnprintf(buf + len, buf_len - len, "%30s: %s\n", "rm_state", hdd_ipa_rm_state_to_str(hdd_ipa->rm_state)); + len += scnprintf(buf + len, buf_len - len, "%30s: %d\n", "tx_ref_cnt", + atomic_read(&hdd_ipa->tx_ref_cnt)); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_rm_grant); len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_rm_release); len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, |
