qcacmn: add hif_grp_irq_deconfigure bus_ops to free ext grp IRQs
As per current design, in failure path of hdd_wlan_start_modules, mem_free of hif_ext_group is done (in cds_dp_close) before free_irq (in hdd_hif_close), during next hdd_wlan_start_modules, request_irq adds new handler entry to the list in irq_desc, this leads to a crash on accessing older stale entry from irq handler, so adding a bus_ops hif_grp_irq_deconfigure to free ext grp IRQs. Change-Id: I4d0a2bee1fabee388cea8a85226fae641165a8d5 CRs-Fixed: 2949400
This commit is contained in:

committed by
Madan Koyyalamudi

parent
e914459b55
commit
7d79770907
@@ -2853,6 +2853,7 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc)
|
||||
if (soc->intr_mode == DP_INTR_POLL) {
|
||||
qdf_timer_free(&soc->int_timer);
|
||||
} else {
|
||||
hif_deconfigure_ext_group_interrupts(soc->hif_handle);
|
||||
hif_deregister_exec_group(soc->hif_handle, "dp_intr");
|
||||
}
|
||||
|
||||
|
@@ -1494,6 +1494,14 @@ int32_t hif_get_int_ctx_irq_num(struct hif_opaque_softc *softc,
|
||||
*/
|
||||
QDF_STATUS hif_configure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx);
|
||||
|
||||
/**
|
||||
* hif_deconfigure_ext_group_interrupts() - Deconfigure ext group intrrupts
|
||||
* @hif_ctx: hif opaque context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hif_deconfigure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx);
|
||||
|
||||
/**
|
||||
* hif_register_ext_group() - API to register external group
|
||||
* interrupt handler.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018,2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2018,2020-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -50,6 +50,7 @@ int hif_ahb_configure_irq(struct hif_pci_softc *sc);
|
||||
int hif_ahb_configure_irq_by_ceid(struct hif_softc *sc, int ce_id);
|
||||
int hif_ahb_configure_grp_irq(struct hif_softc *scn,
|
||||
struct hif_exec_context *hif_ext_grp);
|
||||
void hif_ahb_deconfigure_grp_irq(struct hif_softc *scn);
|
||||
bool hif_ahb_needs_bmi(struct hif_softc *scn);
|
||||
void hif_ahb_display_stats(struct hif_softc *scn);
|
||||
void hif_ahb_clear_stats(struct hif_softc *scn);
|
||||
|
@@ -262,6 +262,16 @@ int hif_dummy_grp_irq_configure(struct hif_softc *hif_sc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_dummy_grp_irq_deconfigure - dummy call
|
||||
* hif_sc: hif context
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hif_dummy_grp_irq_deconfigure(struct hif_softc *hif_sc)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_dummy_dump_registers - dummy call
|
||||
* hif_sc: hif context
|
||||
|
@@ -44,6 +44,7 @@ void hif_dummy_grp_irq_enable(struct hif_softc *hif_sc, uint32_t grp_id);
|
||||
void hif_dummy_grp_irq_disable(struct hif_softc *hif_sc, uint32_t grp_id);
|
||||
int hif_dummy_grp_irq_configure(struct hif_softc *hif_sc,
|
||||
struct hif_exec_context *exec);
|
||||
void hif_dummy_grp_irq_deconfigure(struct hif_softc *hif_sc);
|
||||
int hif_dummy_dump_registers(struct hif_softc *hif_sc);
|
||||
void hif_dummy_dump_target_memory(struct hif_softc *hif_sc, void *ramdump_base,
|
||||
uint32_t address, uint32_t size);
|
||||
|
@@ -205,6 +205,14 @@ int hif_ipci_configure_grp_irq(
|
||||
struct hif_softc *scn,
|
||||
struct hif_exec_context *exec);
|
||||
|
||||
/**
|
||||
* hif_ipci_deconfigure_grp_irq() - deconfigure HW block irq
|
||||
* @scn: hif context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hif_ipci_deconfigure_grp_irq(struct hif_softc *scn);
|
||||
|
||||
/**
|
||||
* hif_ipci_display_stats() - display stats
|
||||
* @hif_ctx: hif context
|
||||
|
@@ -58,6 +58,7 @@ static void hif_initialize_default_ops(struct hif_softc *hif_sc)
|
||||
bus_ops->hif_bus_late_resume = &hif_dummy_bus_resume;
|
||||
bus_ops->hif_map_ce_to_irq = &hif_dummy_map_ce_to_irq;
|
||||
bus_ops->hif_grp_irq_configure = &hif_dummy_grp_irq_configure;
|
||||
bus_ops->hif_grp_irq_deconfigure = &hif_dummy_grp_irq_deconfigure;
|
||||
bus_ops->hif_config_irq_affinity =
|
||||
&hif_dummy_config_irq_affinity;
|
||||
bus_ops->hif_config_irq_by_ceid = &hif_dummy_config_irq_by_ceid;
|
||||
@@ -346,6 +347,11 @@ int hif_grp_irq_configure(struct hif_softc *hif_sc,
|
||||
return hif_sc->bus_ops.hif_grp_irq_configure(hif_sc, hif_exec);
|
||||
}
|
||||
|
||||
void hif_grp_irq_deconfigure(struct hif_softc *hif_sc)
|
||||
{
|
||||
hif_sc->bus_ops.hif_grp_irq_deconfigure(hif_sc);
|
||||
}
|
||||
|
||||
int hif_dump_registers(struct hif_opaque_softc *hif_hdl)
|
||||
{
|
||||
struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl);
|
||||
|
@@ -65,6 +65,7 @@ struct hif_bus_ops {
|
||||
void (*hif_irq_enable)(struct hif_softc *hif_sc, int ce_id);
|
||||
int (*hif_grp_irq_configure)(struct hif_softc *hif_sc,
|
||||
struct hif_exec_context *exec);
|
||||
void (*hif_grp_irq_deconfigure)(struct hif_softc *hif_sc);
|
||||
int (*hif_dump_registers)(struct hif_softc *hif_sc);
|
||||
void (*hif_dump_target_memory)(struct hif_softc *hif_sc,
|
||||
void *ramdump_base,
|
||||
@@ -234,6 +235,7 @@ static inline int hif_sdio_get_context_size(void)
|
||||
|
||||
int hif_grp_irq_configure(struct hif_softc *hif_sc,
|
||||
struct hif_exec_context *hif_exec);
|
||||
void hif_grp_irq_deconfigure(struct hif_softc *hif_sc);
|
||||
#ifdef HIF_USB
|
||||
QDF_STATUS hif_initialize_usb_ops(struct hif_bus_ops *bus_ops);
|
||||
int hif_usb_get_context_size(void);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018,2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2018,2020-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -69,6 +69,7 @@ QDF_STATUS hif_initialize_ahb_ops(struct hif_bus_ops *bus_ops)
|
||||
bus_ops->hif_disable_power_management =
|
||||
&hif_dummy_disable_power_management;
|
||||
bus_ops->hif_grp_irq_configure = &hif_ahb_configure_grp_irq;
|
||||
bus_ops->hif_grp_irq_deconfigure = &hif_ahb_deconfigure_grp_irq;
|
||||
bus_ops->hif_addr_in_boundary = &hif_dummy_addr_in_boundary;
|
||||
bus_ops->hif_needs_bmi = &hif_ahb_needs_bmi;
|
||||
bus_ops->hif_display_stats = &hif_ahb_display_stats;
|
||||
|
@@ -71,6 +71,7 @@ QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc)
|
||||
bus_ops->hif_disable_power_management =
|
||||
&hif_ipci_disable_power_management;
|
||||
bus_ops->hif_grp_irq_configure = &hif_ipci_configure_grp_irq;
|
||||
bus_ops->hif_grp_irq_deconfigure = &hif_ipci_deconfigure_grp_irq;
|
||||
bus_ops->hif_display_stats =
|
||||
&hif_ipci_display_stats;
|
||||
bus_ops->hif_clear_stats =
|
||||
|
@@ -81,6 +81,7 @@ QDF_STATUS hif_initialize_pci_ops(struct hif_softc *hif_sc)
|
||||
bus_ops->hif_disable_power_management =
|
||||
&hif_pci_disable_power_management;
|
||||
bus_ops->hif_grp_irq_configure = &hif_pci_configure_grp_irq;
|
||||
bus_ops->hif_grp_irq_deconfigure = &hif_pci_deconfigure_grp_irq;
|
||||
bus_ops->hif_display_stats =
|
||||
&hif_pci_display_stats;
|
||||
bus_ops->hif_clear_stats =
|
||||
@@ -113,6 +114,7 @@ QDF_STATUS hif_update_irq_ops_with_pci(struct hif_softc *hif_sc)
|
||||
struct hif_bus_ops *bus_ops = &hif_sc->bus_ops;
|
||||
|
||||
bus_ops->hif_grp_irq_configure = &hif_pci_configure_grp_irq;
|
||||
bus_ops->hif_grp_irq_deconfigure = &hif_pci_deconfigure_grp_irq;
|
||||
bus_ops->hif_nointrs = &hif_pci_nointrs;
|
||||
bus_ops->hif_irq_disable = &hif_pci_irq_disable;
|
||||
bus_ops->hif_irq_enable = &hif_pci_irq_enable;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -52,6 +52,7 @@ void hif_pci_enable_power_management(struct hif_softc *hif_ctx,
|
||||
void hif_pci_disable_power_management(struct hif_softc *hif_ctx);
|
||||
int hif_pci_configure_grp_irq(struct hif_softc *scn,
|
||||
struct hif_exec_context *exec);
|
||||
void hif_pci_deconfigure_grp_irq(struct hif_softc *scn);
|
||||
|
||||
/**
|
||||
* hif_pci_reg_read32() - Read register in 32bits
|
||||
|
@@ -835,6 +835,21 @@ QDF_STATUS hif_configure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx)
|
||||
|
||||
qdf_export_symbol(hif_configure_ext_group_interrupts);
|
||||
|
||||
void hif_deconfigure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx)
|
||||
{
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
|
||||
|
||||
if (!scn || !scn->ext_grp_irq_configured) {
|
||||
hif_err("scn(%pk) is NULL or grp irq not configured", scn);
|
||||
return;
|
||||
}
|
||||
|
||||
hif_grp_irq_deconfigure(scn);
|
||||
scn->ext_grp_irq_configured = false;
|
||||
}
|
||||
|
||||
qdf_export_symbol(hif_deconfigure_ext_group_interrupts);
|
||||
|
||||
#ifdef WLAN_SUSPEND_RESUME_TEST
|
||||
/**
|
||||
* hif_check_and_trigger_ut_resume() - check if unit-test command was used to
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -153,6 +153,7 @@ void hif_exec_destroy(struct hif_exec_context *ctx);
|
||||
|
||||
int hif_grp_irq_configure(struct hif_softc *scn,
|
||||
struct hif_exec_context *hif_exec);
|
||||
void hif_grp_irq_deconfigure(struct hif_softc *scn);
|
||||
irqreturn_t hif_ext_group_interrupt_handler(int irq, void *context);
|
||||
|
||||
struct hif_exec_context *hif_exec_get_ctx(struct hif_opaque_softc *hif,
|
||||
|
@@ -225,7 +225,7 @@ static int hif_ce_srng_msi_free_irq(struct hif_softc *scn)
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hif_ipci_deconfigure_grp_irq(struct hif_softc *scn)
|
||||
void hif_ipci_deconfigure_grp_irq(struct hif_softc *scn)
|
||||
{
|
||||
int i, j, irq;
|
||||
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
|
||||
|
@@ -2098,7 +2098,7 @@ static int hif_ce_srng_msi_free_irq(struct hif_softc *scn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hif_pci_deconfigure_grp_irq(struct hif_softc *scn)
|
||||
void hif_pci_deconfigure_grp_irq(struct hif_softc *scn)
|
||||
{
|
||||
int i, j, irq;
|
||||
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
|
||||
|
Reference in New Issue
Block a user