diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 29df6aeae084..4dfb0aaf317a 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -3819,6 +3819,11 @@ int __gsi_populate_tre(struct gsi_chan_ctx *ctx, tre.ieob = (xfer->flags & GSI_XFER_FLAG_EOB) ? 1 : 0; tre.chain = (xfer->flags & GSI_XFER_FLAG_CHAIN) ? 1 : 0; + if (unlikely(ctx->state == GSI_CHAN_STATE_NOT_ALLOCATED)) { + GSIERR("bad state %d\n", ctx->state); + return -GSI_STATUS_UNSUPPORTED_OP; + } + idx = gsi_find_idx_from_addr(&ctx->ring, ctx->ring.wp_local); tre_ptr = (struct gsi_tre *)(ctx->ring.base_va + idx * ctx->ring.elem_sz); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 42cd1260601e..40aab9eee4c4 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -131,6 +131,8 @@ static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work); static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work, ipa_dec_clients_disable_clks_on_wq); +static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_suspend_irq_wq_work, + ipa_dec_clients_disable_clks_on_wq); static void ipa_inc_clients_enable_clks_on_wq(struct work_struct *work); static DECLARE_WORK(ipa_inc_clients_enable_clks_on_wq_work, ipa_inc_clients_enable_clks_on_wq); @@ -5573,6 +5575,22 @@ void ipa3_dec_client_disable_clks_no_block( &ipa_dec_clients_disable_clks_on_wq_work, 0); } +/** + * ipa3_dec_client_disable_clks_delay_wq() - Decrease active clients counter + * in delayed workqueue. + * + * Return codes: + * None + */ +void ipa3_dec_client_disable_clks_delay_wq( + struct ipa_active_client_logging_info *id, unsigned long delay) +{ + ipa3_active_clients_log_dec(id, true); + + if (!queue_delayed_work(ipa3_ctx->power_mgmt_wq, + &ipa_dec_clients_disable_clks_on_suspend_irq_wq_work, delay)) + IPAERR("Scheduling delayed work failed\n"); +} /** * ipa3_inc_acquire_wakelock() - Increase active clients counter, and * acquire wakelock if necessary diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index a89e44c642a9..b2b1903f7ac9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -4608,7 +4608,7 @@ static void ipa_gsi_irq_tx_notify_cb(struct gsi_chan_xfer_notify *notify) void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) { - bool clk_off; + bool clk_off = true; enum ipa_client_type client_type; atomic_set(&sys->curr_polling_state, 1); @@ -4628,7 +4628,9 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) * switch. Use the active no block instead * where we would have ref counts. */ - clk_off = IPA_ACTIVE_CLIENTS_INC_EP_NO_BLOCK(client_type); + if (sys->napi_obj || + IPA_CLIENT_IS_LOW_LAT_CONS(sys->ep->client)) + clk_off = IPA_ACTIVE_CLIENTS_INC_EP_NO_BLOCK(client_type); if (!clk_off && sys->napi_obj) { trace_ipa3_napi_schedule(sys->ep->client); napi_schedule(sys->napi_obj); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 81f842ec735f..a8b1094a8a1f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2854,6 +2854,8 @@ int ipa3_inc_client_enable_clks_no_block(struct ipa_active_client_logging_info *id); void ipa3_dec_client_disable_clks_no_block( struct ipa_active_client_logging_info *id); +void ipa3_dec_client_disable_clks_delay_wq( + struct ipa_active_client_logging_info *id, unsigned long delay); void ipa3_active_clients_log_dec(struct ipa_active_client_logging_info *id, bool int_ctx); void ipa3_active_clients_log_inc(struct ipa_active_client_logging_info *id, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c index 102962aec826..d52a80003b2d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_interrupts.c @@ -9,6 +9,7 @@ #define INTERRUPT_WORKQUEUE_NAME "ipa_interrupt_wq" #define DIS_SUSPEND_INTERRUPT_TIMEOUT 5 #define IPA_IRQ_NUM_MAX 32 +#define IPA_AGG_BUSY_TIMEOUT (msecs_to_jiffies(5)) struct ipa3_interrupt_info { ipa_irq_handler_t handler; @@ -322,10 +323,14 @@ static void ipa3_process_interrupts(bool isr_context) static void ipa3_interrupt_defer(struct work_struct *work) { + struct ipa_active_client_logging_info log_info; + IPADBG("processing interrupts in wq\n"); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); ipa3_process_interrupts(false); - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + IPA_ACTIVE_CLIENTS_PREP_SIMPLE(log_info); + /* Delay the devote process to have time to get gsi ieob irq */ + ipa3_dec_client_disable_clks_delay_wq(&log_info, IPA_AGG_BUSY_TIMEOUT); IPADBG("Done\n"); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c index 86c37da0c7df..eb74bbac4c02 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -465,6 +465,11 @@ static void delayed_deferred_deactivate_work_func(struct work_struct *work) dwork = container_of(work, struct delayed_work, work); client = container_of(dwork, struct ipa_pm_client, deactivate_work); + if (unlikely(client == NULL)) { + IPA_PM_ERR("Client already deregistered\n"); + return; + } + spin_lock_irqsave(&client->state_lock, flags); IPA_PM_DBG_STATE(client->hdl, client->name, client->state); switch (client->state) { @@ -1199,6 +1204,8 @@ int ipa_pm_deactivate_sync(u32 hdl) client->state = IPA_PM_DEACTIVATED; IPA_PM_DBG_STATE(hdl, client->name, client->state); spin_unlock_irqrestore(&client->state_lock, flags); + /*Check any delayed work queue scheduled*/ + cancel_delayed_work_sync(&client->deactivate_work); deactivate_client(hdl); do_clk_scaling(); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index ce5498d13e8b..4758fd2c7d8a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -3989,19 +3989,19 @@ static struct ipa3_mem_partition ipa_4_11_mem_part = { .apps_hdr_size = 0x200, .apps_hdr_size_ddr = 0x800, .modem_hdr_proc_ctx_ofst = 0xad0, - .modem_hdr_proc_ctx_size = 0x200, - .apps_hdr_proc_ctx_ofst = 0xcd0, + .modem_hdr_proc_ctx_size = 0xAC0, + .apps_hdr_proc_ctx_ofst = 0x1590, .apps_hdr_proc_ctx_size = 0x200, .apps_hdr_proc_ctx_size_ddr = 0x0, - .nat_tbl_ofst = 0xee0, - .nat_tbl_size = 0xd00, - .pdn_config_ofst = 0x1be8, + .nat_tbl_ofst = 0x17A0, + .nat_tbl_size = 0x800, + .pdn_config_ofst = 0x24A8, .pdn_config_size = 0x50, - .stats_quota_q6_ofst = 0x1c40, + .stats_quota_q6_ofst = 0x2500, .stats_quota_q6_size = 0x30, - .stats_quota_ap_ofst = 0x1c70, + .stats_quota_ap_ofst = 0x2530, .stats_quota_ap_size = 0x48, - .stats_tethering_ofst = 0x1cb8, + .stats_tethering_ofst = 0x2578, .stats_tethering_size = 0x238, .stats_flt_v4_ofst = 0, .stats_flt_v4_size = 0, @@ -4011,29 +4011,29 @@ static struct ipa3_mem_partition ipa_4_11_mem_part = { .stats_rt_v4_size = 0, .stats_rt_v6_ofst = 0, .stats_rt_v6_size = 0, - .stats_fnr_ofst = 0x1ef0, + .stats_fnr_ofst = 0x27B0, .stats_fnr_size = 0x0, - .stats_drop_ofst = 0x1ef0, + .stats_drop_ofst = 0x27B0, .stats_drop_size = 0x20, .modem_comp_decomp_ofst = 0x0, .modem_comp_decomp_size = 0x0, - .modem_ofst = 0x1f18, - .modem_size = 0x100c, - .apps_v4_flt_hash_ofst = 0x1f18, + .modem_ofst = 0x27D8, + .modem_size = 0x800, + .apps_v4_flt_hash_ofst = 0x27B0, .apps_v4_flt_hash_size = 0x0, - .apps_v4_flt_nhash_ofst = 0x1f18, + .apps_v4_flt_nhash_ofst = 0x27B0, .apps_v4_flt_nhash_size = 0x0, - .apps_v6_flt_hash_ofst = 0x1f18, + .apps_v6_flt_hash_ofst = 0x27B0, .apps_v6_flt_hash_size = 0x0, - .apps_v6_flt_nhash_ofst = 0x1f18, + .apps_v6_flt_nhash_ofst = 0x27B0, .apps_v6_flt_nhash_size = 0x0, - .apps_v4_rt_hash_ofst = 0x1f18, + .apps_v4_rt_hash_ofst = 0x27B0, .apps_v4_rt_hash_size = 0x0, - .apps_v4_rt_nhash_ofst = 0x1f18, + .apps_v4_rt_nhash_ofst = 0x27B0, .apps_v4_rt_nhash_size = 0x0, - .apps_v6_rt_hash_ofst = 0x1f18, + .apps_v6_rt_hash_ofst = 0x27B0, .apps_v6_rt_hash_size = 0x0, - .apps_v6_rt_nhash_ofst = 0x1f18, + .apps_v6_rt_nhash_ofst = 0x27B0, .apps_v6_rt_nhash_size = 0x0, .uc_descriptor_ram_ofst = 0x3000, .uc_descriptor_ram_size = 0x0000,