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_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"); }