From a619aab34b4b2236989788d5100deca71bfa24be Mon Sep 17 00:00:00 2001 From: Bojun Pan Date: Tue, 10 Dec 2019 17:17:29 -0800 Subject: [PATCH] msm: ipa4: debug patch gsi interrupt issue Debug patch for GSI interrupt issue. Change-Id: I705cd893233e1afcaeed6fedb424830e39621114 Acked-by: Ashok Vuyyuru Signed-off-by: Bojun Pan --- drivers/platform/msm/gsi/gsi.c | 11 +++++++++-- drivers/platform/msm/gsi/gsi.h | 2 ++ drivers/platform/msm/ipa/ipa_v3/ipa.c | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 6f5316e2a1d0..37ca728c98dc 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -20,6 +20,7 @@ #define GSI_CMD_POLL_CNT 5 #define GSI_STOP_CMD_TIMEOUT_MS 200 #define GSI_MAX_CH_LOW_WEIGHT 15 +#define GSI_IRQ_STORM_THR 5 #define GSI_STOP_CMD_POLL_CNT 4 #define GSI_STOP_IN_PROC_CMD_POLL_CNT 2 @@ -805,9 +806,15 @@ static irqreturn_t gsi_isr(int irq, void *ctxt) gsi_handle_irq(); gsi_ctx->per.rel_clk_cb(gsi_ctx->per.user_data); } + } else if (!gsi_ctx->per.clk_status_cb()) { + /* we only want to capture the gsi isr storm here */ + if (atomic_read(&gsi_ctx->num_unclock_irq) == + GSI_IRQ_STORM_THR) + gsi_ctx->per.enable_clk_bug_on(); + atomic_inc(&gsi_ctx->num_unclock_irq); + return IRQ_HANDLED; } else { - if (!gsi_ctx->per.clk_status_cb()) - return IRQ_HANDLED; + atomic_set(&gsi_ctx->num_unclock_irq, 0); gsi_handle_irq(); } return IRQ_HANDLED; diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h index dd83b7ba2820..3e3f6d138da9 100644 --- a/drivers/platform/msm/gsi/gsi.h +++ b/drivers/platform/msm/gsi/gsi.h @@ -235,6 +235,8 @@ struct gsi_ctx { u32 intcntrlr_mem_size; irq_handler_t intcntrlr_gsi_isr; irq_handler_t intcntrlr_client_isr; + + atomic_t num_unclock_irq; }; enum gsi_re_type { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 99dbd528190e..5770a7f4f995 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -122,6 +122,10 @@ 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 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); + static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg); static int ipa3_ioctl_add_rt_rule_ext_v2(unsigned long arg); static int ipa3_ioctl_add_rt_rule_after_v2(unsigned long arg); @@ -4839,6 +4843,12 @@ void ipa3_disable_clks(void) IPADBG("disabling IPA clocks and bus voting\n"); + /* + * We see a NoC error on GSI on this flag sequence. + * Need to set this flag first before clock off. + */ + atomic_set(&ipa3_ctx->ipa_clk_vote, 0); + ipa3_ctx->ctrl->ipa3_disable_clks(); ipa_pm_set_clock_index(0); @@ -5024,6 +5034,12 @@ void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id) mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex); } +static void ipa3_handle_gsi_differ_irq(void) +{ + queue_work(ipa3_ctx->power_mgmt_wq, + &ipa_inc_clients_enable_clks_on_wq_work); +} + /** * ipa3_active_clks_status() - update the current msm bus clock vote * status @@ -5140,6 +5156,13 @@ static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work) __ipa3_dec_client_disable_clks(); } +static void ipa_inc_clients_enable_clks_on_wq(struct work_struct *work) +{ + ipa3_enable_clks(); + IPAERR("unexpected clk access, clock on IPA to save reg"); + ipa_assert(); +} + /** * ipa3_dec_client_disable_clks_no_block() - Decrease active clients counter * if possible without blocking. If this is the last client then the desrease @@ -5960,6 +5983,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p, gsi_props.req_clk_cb = NULL; gsi_props.rel_clk_cb = NULL; gsi_props.clk_status_cb = ipa3_active_clks_status; + gsi_props.enable_clk_bug_on = ipa3_handle_gsi_differ_irq; if (ipa3_ctx->ipa_config_is_mhi) { gsi_props.mhi_er_id_limits_valid = true;