qcacmn: Add framework for external group interrupt handling
Change-Id: I68a3c597e452e1975a97f9262870e16538f6dc4c
CRs-Fixed: 1042915
diff --git a/hif/inc/hif.h b/hif/inc/hif.h
index 8468117..c648caf 100644
--- a/hif/inc/hif.h
+++ b/hif/inc/hif.h
@@ -100,8 +100,52 @@
#define TARGET_TYPE_QCA8074 20
#endif
+/* enum hif_ic_irq - enum defining integrated chip irq numbers
+ * defining irq nubers that can be used by external modules like datapath
+ */
+enum hif_ic_irq {
+ host2wbm_desc_feed = 18,
+ host2reo_re_injection,
+ host2reo_command,
+ host2rxdma_monitor_ring3,
+ host2rxdma_monitor_ring2,
+ host2rxdma_monitor_ring1,
+ reo2ost_exception,
+ wbm2host_rx_release,
+ reo2host_status,
+ reo2host_destination_ring4,
+ reo2host_destination_ring3,
+ reo2host_destination_ring2,
+ reo2host_destination_ring1,
+ rxdma2host_monitor_destination_mac3,
+ rxdma2host_monitor_destination_mac2,
+ rxdma2host_monitor_destination_mac1,
+ ppdu_end_interrupts_mac3,
+ ppdu_end_interrupts_mac2,
+ ppdu_end_interrupts_mac1,
+ rxdma2host_monitor_status_ring_mac3,
+ rxdma2host_monitor_status_ring_mac2,
+ rxdma2host_monitor_status_ring_mac1,
+ host2rxdma_host_buf_ring_mac3,
+ host2rxdma_host_buf_ring_mac2,
+ host2rxdma_host_buf_ring_mac1,
+ rxdma2host_destination_ring_mac3,
+ rxdma2host_destination_ring_mac2,
+ rxdma2host_destination_ring_mac1,
+ host2tcl_input_ring4,
+ host2tcl_input_ring3,
+ host2tcl_input_ring2,
+ host2tcl_input_ring1,
+ wbm2host_tx_completions_ring3,
+ wbm2host_tx_completions_ring2,
+ wbm2host_tx_completions_ring1,
+ tcl2host_status_ring,
+};
+
struct CE_state;
#define CE_COUNT_MAX 12
+#define HIF_MAX_GRP_IRQ 16
+#define HIF_MAX_GROUP 8
#ifdef CONFIG_SLUB_DEBUG_ON
#define QCA_NAPI_BUDGET 64
@@ -407,6 +451,7 @@
uint8_t *data, int nbytes);
typedef void (*fastpath_msg_handler)(void *, qdf_nbuf_t *, uint32_t);
+typedef uint32_t (*ext_intr_handler)(void *, uint32_t);
/*
* Set the FASTPATH_mode_on flag in sc, for use by data path
@@ -682,6 +727,10 @@
void hif_fake_apps_suspend(hdd_fake_resume_callback callback);
#endif
+uint32_t hif_register_ext_group_int_handler(struct hif_opaque_softc *hif_ctx,
+ uint32_t numirq, uint32_t irq[], ext_intr_handler handler,
+ void *context);
+
#ifdef __cplusplus
}
#endif
diff --git a/hif/inc/hif_napi.h b/hif/inc/hif_napi.h
index 243301f..edf1fd0 100644
--- a/hif/inc/hif_napi.h
+++ b/hif/inc/hif_napi.h
@@ -194,6 +194,9 @@
static inline int hif_napi_enabled(struct hif_opaque_softc *hif, int ce)
{ return 0; }
+static inline int hif_ext_napi_enabled(struct hif_opaque_softc *hif, int ce)
+{ return 0; }
+
/* called from hdd (napi_poll), using napi id as a selector */
static inline void hif_napi_enable_irq(struct hif_opaque_softc *hif, int id)
{ return; }
@@ -201,6 +204,10 @@
static inline int hif_napi_schedule(struct hif_opaque_softc *hif, int ce_id)
{ return 0; }
+static inline int hif_napi_schedule_grp(struct hif_opaque_softc *hif,
+ uint32_t grp_id)
+{ return 0; }
+
static inline int hif_napi_poll(struct napi_struct *napi, int budget)
{ return -EPERM; }
diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h
index e58f30a..fbc0f6c 100644
--- a/hif/src/ce/ce_main.h
+++ b/hif/src/ce/ce_main.h
@@ -113,6 +113,18 @@
void *hif_ce_state;
};
+struct hif_ext_group_entry {
+ uint32_t numirq;
+ uint32_t irq[HIF_MAX_GRP_IRQ];
+ uint32_t grp_id;
+ void *context;
+ ext_intr_handler handler;
+ struct tasklet_struct intr_tq;
+ bool configured;
+ bool inited;
+ void *hif_state;
+};
+
struct ce_intr_stats {
uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU];
};
@@ -121,6 +133,8 @@
struct hif_softc ol_sc;
bool started;
struct ce_tasklet_entry tasklets[CE_COUNT_MAX];
+ struct hif_ext_group_entry hif_ext_group[HIF_MAX_GROUP];
+ uint32_t hif_num_extgroup;
qdf_spinlock_t keep_awake_lock;
qdf_spinlock_t irq_reg_lock;
unsigned int keep_awake_count;
diff --git a/hif/src/dispatcher/ahb_api.h b/hif/src/dispatcher/ahb_api.h
index 3a715fd..75f1506 100644
--- a/hif/src/dispatcher/ahb_api.h
+++ b/hif/src/dispatcher/ahb_api.h
@@ -35,6 +35,8 @@
int hif_ahb_bus_configure(struct hif_softc *scn);
void hif_ahb_irq_disable(struct hif_softc *scn, int ce_id);
void hif_ahb_irq_enable(struct hif_softc *scn, int ce_id);
+void hif_ahb_grp_irq_disable(struct hif_softc *scn, uint32_t grp_id);
+void hif_ahb_grp_irq_enable(struct hif_softc *scn, uint32_t grp_id);
int hif_ahb_dump_registers(struct hif_softc *scn);
int hif_ahb_configure_legacy_irq(struct hif_pci_softc *sc);
diff --git a/hif/src/dispatcher/dummy.c b/hif/src/dispatcher/dummy.c
index 1690e05..6c2ebd7 100644
--- a/hif/src/dispatcher/dummy.c
+++ b/hif/src/dispatcher/dummy.c
@@ -233,6 +233,16 @@
{}
/**
+ * hif_dummy_grp_irq_enable - dummy call
+ * hif_ctx: hif context
+ * @irq_id: grp id
+ *
+ * Return: none
+ */
+void hif_dummy_grp_irq_enable(struct hif_softc *hif_sc, uint32_t grp_id)
+{}
+
+/**
* hif_dummy_irq_disable - dummy call
* hif_ctx: hif context
* @irq_id: irq id
@@ -243,6 +253,15 @@
{}
/**
+ * hif_dummy_grp_irq_disable- dummy call
+ * hif_ctx: hif context
+ * @grp_id: grp id
+ *
+ * Return: none
+ */
+void hif_dummy_grp_irq_disable(struct hif_softc *hif_sc, uint32_t grp_id)
+{}
+/**
* hif_dummy_dump_registers - dummy call
* hif_sc: hif context
*
diff --git a/hif/src/dispatcher/dummy.h b/hif/src/dispatcher/dummy.h
index b531c1d..6d8a2c7 100644
--- a/hif/src/dispatcher/dummy.h
+++ b/hif/src/dispatcher/dummy.h
@@ -47,6 +47,8 @@
void hif_dummy_cancel_deferred_target_sleep(struct hif_softc *hif_sc);
void hif_dummy_irq_enable(struct hif_softc *hif_sc, int irq_id);
void hif_dummy_irq_disable(struct hif_softc *hif_sc, int irq_id);
+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_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);
diff --git a/hif/src/dispatcher/multibus.c b/hif/src/dispatcher/multibus.c
index 5643b6f..8b4e463 100644
--- a/hif/src/dispatcher/multibus.c
+++ b/hif/src/dispatcher/multibus.c
@@ -59,6 +59,8 @@
bus_ops->hif_bus_reset_resume = &hif_dummy_bus_reset_resume;
bus_ops->hif_bus_suspend_noirq = &hif_dummy_bus_suspend_noirq;
bus_ops->hif_bus_resume_noirq = &hif_dummy_bus_resume_noirq;
+ bus_ops->hif_grp_irq_disable = &hif_dummy_grp_irq_disable;
+ bus_ops->hif_grp_irq_enable = &hif_dummy_grp_irq_enable;
}
#define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *))
@@ -286,11 +288,21 @@
hif_sc->bus_ops.hif_irq_enable(hif_sc, irq_id);
}
+void hif_grp_irq_enable(struct hif_softc *hif_sc, uint32_t grp_id)
+{
+ hif_sc->bus_ops.hif_grp_irq_enable(hif_sc, grp_id);
+}
+
void hif_irq_disable(struct hif_softc *hif_sc, int irq_id)
{
hif_sc->bus_ops.hif_irq_disable(hif_sc, irq_id);
}
+void hif_grp_irq_disable(struct hif_softc *hif_sc, uint32_t grp_id)
+{
+ hif_sc->bus_ops.hif_grp_irq_disable(hif_sc, grp_id);
+}
+
int hif_dump_registers(struct hif_opaque_softc *hif_hdl)
{
struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl);
diff --git a/hif/src/dispatcher/multibus.h b/hif/src/dispatcher/multibus.h
index 6342363..e90a945 100644
--- a/hif/src/dispatcher/multibus.h
+++ b/hif/src/dispatcher/multibus.h
@@ -61,7 +61,9 @@
void (*hif_stop)(struct hif_softc *hif_sc);
void (*hif_cancel_deferred_target_sleep)(struct hif_softc *hif_sc);
void (*hif_irq_disable)(struct hif_softc *hif_sc, int ce_id);
+ void (*hif_grp_irq_disable)(struct hif_softc *hif_sc, uint32_t grp_id);
void (*hif_irq_enable)(struct hif_softc *hif_sc, int ce_id);
+ void (*hif_grp_irq_enable)(struct hif_softc *hif_sc, uint32_t grp_id);
int (*hif_dump_registers)(struct hif_softc *hif_sc);
void (*hif_dump_target_memory)(struct hif_softc *hif_sc,
void *ramdump_base,
diff --git a/hif/src/dispatcher/multibus_ahb.c b/hif/src/dispatcher/multibus_ahb.c
index d1bee78..d67c9ec 100644
--- a/hif/src/dispatcher/multibus_ahb.c
+++ b/hif/src/dispatcher/multibus_ahb.c
@@ -66,6 +66,8 @@
&hif_dummy_enable_power_management;
bus_ops->hif_disable_power_management =
&hif_dummy_disable_power_management;
+ bus_ops->hif_grp_irq_disable = &hif_ahb_grp_irq_disable;
+ bus_ops->hif_grp_irq_enable = &hif_ahb_grp_irq_enable;
return QDF_STATUS_SUCCESS;
}
diff --git a/hif/src/dispatcher/multibus_pci.c b/hif/src/dispatcher/multibus_pci.c
index 5459105..44f2953 100644
--- a/hif/src/dispatcher/multibus_pci.c
+++ b/hif/src/dispatcher/multibus_pci.c
@@ -85,6 +85,8 @@
&hif_pci_display_stats;
bus_ops->hif_clear_stats =
&hif_pci_clear_stats;
+ bus_ops->hif_grp_irq_disable = &hif_dummy_grp_irq_disable;
+ bus_ops->hif_grp_irq_enable = &hif_dummy_grp_irq_enable;
return QDF_STATUS_SUCCESS;
}
diff --git a/hif/src/dispatcher/multibus_sdio.c b/hif/src/dispatcher/multibus_sdio.c
index fc27202..1f957c4 100644
--- a/hif/src/dispatcher/multibus_sdio.c
+++ b/hif/src/dispatcher/multibus_sdio.c
@@ -64,6 +64,8 @@
&hif_dummy_enable_power_management;
bus_ops->hif_disable_power_management =
&hif_dummy_disable_power_management;
+ bus_ops->hif_grp_irq_disable = &hif_dummy_grp_irq_disable;
+ bus_ops->hif_grp_irq_enable = &hif_dummy_grp_irq_enable;
return QDF_STATUS_SUCCESS;
}
diff --git a/hif/src/dispatcher/multibus_snoc.c b/hif/src/dispatcher/multibus_snoc.c
index 2dc80d6..3d31077 100644
--- a/hif/src/dispatcher/multibus_snoc.c
+++ b/hif/src/dispatcher/multibus_snoc.c
@@ -79,6 +79,8 @@
&hif_snoc_display_stats;
bus_ops->hif_clear_stats =
&hif_snoc_clear_stats;
+ bus_ops->hif_grp_irq_disable = &hif_dummy_grp_irq_disable;
+ bus_ops->hif_grp_irq_enable = &hif_dummy_grp_irq_enable;
return QDF_STATUS_SUCCESS;
}
diff --git a/hif/src/hif_io32.h b/hif/src/hif_io32.h
index 8c39893..8c1453f 100644
--- a/hif/src/hif_io32.h
+++ b/hif/src/hif_io32.h
@@ -104,6 +104,7 @@
void hif_irq_enable(struct hif_softc *scn, int irq_id);
void hif_irq_disable(struct hif_softc *scn, int irq_id);
-
+void hif_grp_irq_enable(struct hif_softc *scn, uint32_t grp_id);
+void hif_grp_irq_disable(struct hif_softc *scn, uint32_t grp_id);
#endif /* __HIF_IO32_H__ */
diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c
index 96c3241..936a451 100644
--- a/hif/src/hif_main.c
+++ b/hif/src/hif_main.c
@@ -375,6 +375,7 @@
scn->qdf_dev = qdf_ctx;
scn->hif_con_param = mode;
qdf_atomic_init(&scn->active_tasklet_cnt);
+ qdf_atomic_init(&scn->active_grp_tasklet_cnt);
qdf_atomic_init(&scn->link_suspended);
qdf_atomic_init(&scn->tasklet_from_intr);
qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks));
@@ -1017,3 +1018,93 @@
hif_usb_ramdump_handler();
}
#endif
+
+/**
+ * hif_register_ext_group_int_handler() - API to register external group
+ * interrupt handler.
+ * @hif_ctx : HIF Context
+ * @numirq: number of irq's in the group
+ * @irq: array of irq values
+ * @ext_intr_handler: callback interrupt handler function
+ * @context: context to passed in callback
+ *
+ * Return: status
+ */
+uint32_t hif_register_ext_group_int_handler(struct hif_opaque_softc *hif_ctx,
+ uint32_t numirq, uint32_t irq[], ext_intr_handler handler,
+ void *context)
+{
+ struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+ struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+ struct hif_ext_group_entry *hif_ext_group;
+
+ if (scn->hif_init_done) {
+ HIF_ERROR("%s Called after HIF initialization \n", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ if (hif_state->hif_num_extgroup >= HIF_MAX_GROUP) {
+ HIF_ERROR("%s Max groups reached\n", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ if (numirq >= HIF_MAX_GRP_IRQ) {
+ HIF_ERROR("%s invalid numirq\n", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ hif_ext_group = &hif_state->hif_ext_group[hif_state->hif_num_extgroup];
+
+ hif_ext_group->numirq = numirq;
+ qdf_mem_copy(&hif_ext_group->irq[0], irq, numirq * sizeof(irq[0]));
+ hif_ext_group->context = context;
+ hif_ext_group->handler = handler;
+ hif_ext_group->configured = true;
+ hif_ext_group->grp_id = hif_state->hif_num_extgroup;
+
+ hif_state->hif_num_extgroup++;
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hif_ext_grp_tasklet() - grp tasklet
+ * data: context
+ *
+ * return: void
+ */
+void hif_ext_grp_tasklet(unsigned long data)
+{
+ struct hif_ext_group_entry *hif_ext_group =
+ (struct hif_ext_group_entry *)data;
+ struct HIF_CE_state *hif_state = hif_ext_group->hif_state;
+ struct hif_softc *scn = HIF_GET_SOFTC(hif_state);
+
+ if (hif_ext_group->grp_id < HIF_MAX_GROUP) {
+ hif_ext_group->handler(hif_ext_group->context, HIF_MAX_BUDGET);
+ hif_grp_irq_enable(scn, hif_ext_group->grp_id);
+ } else {
+ HIF_ERROR("%s: ERROR - invalid grp_id = %d",
+ __func__, hif_ext_group->grp_id);
+ }
+
+ qdf_atomic_dec(&scn->active_grp_tasklet_cnt);
+}
+
+/**
+ * hif_grp_tasklet_kill() - grp tasklet kill
+ * scn: hif_softc
+ *
+ * return: void
+ */
+void hif_grp_tasklet_kill(struct hif_softc *scn)
+{
+ int i;
+ struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+
+ for (i = 0; i < HIF_MAX_GROUP; i++)
+ if (hif_state->hif_ext_group[i].inited) {
+ tasklet_kill(&hif_state->hif_ext_group[i].intr_tq);
+ hif_state->hif_ext_group[i].inited = false;
+ }
+ qdf_atomic_set(&scn->active_grp_tasklet_cnt, 0);
+}
diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h
index 7e5d62c..0d0ae16 100644
--- a/hif/src/hif_main.h
+++ b/hif/src/hif_main.h
@@ -51,6 +51,8 @@
#define HIF_MIN_SLEEP_INACTIVITY_TIME_MS 50
#define HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS 60
+#define HIF_MAX_BUDGET 0xFFFF
+
/*
* This macro implementation is exposed for efficiency only.
* The implementation may change and callers should
@@ -136,6 +138,7 @@
/* No of copy engines supported */
unsigned int ce_count;
atomic_t active_tasklet_cnt;
+ atomic_t active_grp_tasklet_cnt;
atomic_t link_suspended;
uint32_t *vaddr_rri_on_ddr;
int linkstate_vote;
@@ -218,4 +221,6 @@
static inline void hif_usb_get_hw_info(struct hif_softc *scn) {}
static inline void hif_ramdump_handler(struct hif_opaque_softc *scn) {}
#endif
+void hif_ext_grp_tasklet(unsigned long data);
+void hif_grp_tasklet_kill(struct hif_softc *scn);
#endif /* __HIF_MAIN_H__ */
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index 0558d3d..2a280fb 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -2952,8 +2952,10 @@
hif_free_msi_ctx(scn);
/* Cancel the pending tasklet */
ce_tasklet_kill(scn);
+ hif_grp_tasklet_kill(scn);
tasklet_kill(&sc->intr_tq);
qdf_atomic_set(&scn->active_tasklet_cnt, 0);
+ qdf_atomic_set(&scn->active_grp_tasklet_cnt, 0);
}
/* Function to reset SoC */
diff --git a/hif/src/snoc/if_ahb.c b/hif/src/snoc/if_ahb.c
index 23c2b6a..0b9bf31 100644
--- a/hif/src/snoc/if_ahb.c
+++ b/hif/src/snoc/if_ahb.c
@@ -32,6 +32,7 @@
#include "if_pci.h"
#include "ahb_api.h"
#include "pci_api.h"
+#include "hif_napi.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
#define IRQF_DISABLED 0x00000020
@@ -40,6 +41,7 @@
#define HIF_IC_CE0_IRQ_OFFSET 4
#define HIF_IC_MAX_IRQ 54
+static uint8_t ic_irqnum[HIF_IC_MAX_IRQ];
/* integrated chip irq names */
const char *ic_irqname[HIF_IC_MAX_IRQ] = {
"misc_pulse1",
@@ -98,7 +100,6 @@
"tcl2host_status_ring",
};
-irqreturn_t hif_ahb_interrupt_handler(int irq, void *context);
/**
* hif_disable_isr() - disable isr
*
@@ -114,8 +115,10 @@
hif_nointrs(scn);
ce_tasklet_kill(scn);
+ hif_grp_tasklet_kill(scn);
tasklet_kill(&sc->intr_tq);
qdf_atomic_set(&scn->active_tasklet_cnt, 0);
+ qdf_atomic_set(&scn->active_grp_tasklet_cnt, 0);
}
/**
@@ -246,17 +249,19 @@
int ret = 0;
struct hif_softc *scn = HIF_GET_SOFTC(sc);
struct platform_device *pdev = (struct platform_device *)sc->pdev;
- struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(scn);
+ struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+ struct hif_ext_group_entry *hif_ext_group;
int irq = 0;
- int i;
+ int i, j;
/* configure per CE interrupts */
for (i = 0; i < scn->ce_count; i++) {
irq = platform_get_irq_byname(pdev, ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i]);
+ ic_irqnum[HIF_IC_CE0_IRQ_OFFSET + i] = irq;
ret = request_irq(irq ,
hif_ahb_interrupt_handler,
IRQF_TRIGGER_RISING, ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i],
- &hif_ce_state->tasklets[i]);
+ &hif_state->tasklets[i]);
if (ret) {
dev_err(&pdev->dev, "ath_request_irq failed\n");
ret = -1;
@@ -265,6 +270,36 @@
hif_ahb_irq_enable(scn, i);
}
+ /* configure external interrupts */
+ for (i = 0; i < hif_state->hif_num_extgroup; i++) {
+
+ hif_ext_group = &hif_state->hif_ext_group[i];
+ if (hif_ext_group->configured) {
+
+ tasklet_init(&hif_ext_group->intr_tq,
+ hif_ext_grp_tasklet,
+ (unsigned long)hif_ext_group);
+ hif_ext_group->inited = true;
+
+ for (j = 0; j < hif_ext_group->numirq; j++) {
+ irq = platform_get_irq_byname(pdev,
+ ic_irqname[hif_ext_group->irq[j]]);
+
+ ic_irqnum[hif_ext_group->irq[j]] = irq;
+ ret = request_irq(irq,
+ hif_ext_group_ahb_interrupt_handler,
+ IRQF_TRIGGER_RISING, "wlan_ahb",
+ hif_ext_group);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "ath_request_irq failed\n");
+ ret = -1;
+ goto end;
+ }
+ }
+ }
+ }
+
end:
return ret;
}
@@ -275,6 +310,26 @@
return ce_dispatch_interrupt(tasklet_entry->ce_id, tasklet_entry);
}
+irqreturn_t hif_ext_group_ahb_interrupt_handler(int irq, void *context)
+{
+ struct hif_ext_group_entry *hif_ext_group = context;
+ struct HIF_CE_state *hif_state = hif_ext_group->hif_state;
+ struct hif_softc *scn = HIF_GET_SOFTC(hif_state);
+ struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
+ uint32_t grp_id = hif_ext_group->grp_id;
+
+ hif_grp_irq_disable(scn, grp_id);
+
+ qdf_atomic_inc(&scn->active_grp_tasklet_cnt);
+
+ if (hif_ext_napi_enabled(hif_hdl, grp_id)) {
+ hif_napi_schedule_grp(hif_hdl, grp_id);
+ } else {
+ tasklet_schedule(&hif_ext_group->intr_tq);
+ }
+
+ return IRQ_HANDLED;
+}
/**
* hif_target_sync() : ensure the target is ready
@@ -493,9 +548,7 @@
void hif_ahb_nointrs(struct hif_softc *scn)
{
int i;
- int irq;
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
- struct platform_device *pdev = (struct platform_device *)sc->pdev;
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
if (scn->request_irq_done == false)
@@ -512,8 +565,8 @@
free_irq(sc->irq, sc);
} else {
for (i = 0; i < scn->ce_count; i++) {
- irq = platform_get_irq_byname(pdev, ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i]);
- free_irq(irq, sc);
+ free_irq(ic_irqnum[HIF_IC_CE0_IRQ_OFFSET + i],
+ sc);
}
}
}
@@ -592,3 +645,29 @@
}
}
}
+
+void hif_ahb_grp_irq_disable(struct hif_softc *scn, uint32_t grp_id)
+{
+ struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+ struct hif_ext_group_entry *hif_ext_group;
+ uint32_t i;
+
+ hif_ext_group = &hif_state->hif_ext_group[grp_id];
+
+ for (i = 0; i < hif_ext_group->numirq; i++) {
+ disable_irq(ic_irqnum[hif_ext_group->irq[i]]);
+ }
+}
+
+void hif_ahb_grp_irq_enable(struct hif_softc *scn, uint32_t grp_id)
+{
+ struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+ struct hif_ext_group_entry *hif_ext_group;
+ uint32_t i;
+
+ hif_ext_group = &hif_state->hif_ext_group[grp_id];
+
+ for (i = 0; i < hif_ext_group->numirq; i++) {
+ enable_irq(ic_irqnum[hif_ext_group->irq[i]]);
+ }
+}
diff --git a/hif/src/snoc/if_ahb.h b/hif/src/snoc/if_ahb.h
index f5c9081..990d300 100644
--- a/hif/src/snoc/if_ahb.h
+++ b/hif/src/snoc/if_ahb.h
@@ -45,5 +45,9 @@
#define TCSR_WCSS0_HALTACK 0x52010
#define TCSR_WCSS1_HALTACK 0x52014
#define ATH_AHB_RESET_WAIT_MAX 10 /* Ms */
+
+irqreturn_t hif_ahb_interrupt_handler(int irq, void *context);
+irqreturn_t hif_ext_group_ahb_interrupt_handler(int irq, void *context);
+
#endif
diff --git a/hif/src/snoc/if_snoc.c b/hif/src/snoc/if_snoc.c
index 74acfbe..5eb123e 100644
--- a/hif/src/snoc/if_snoc.c
+++ b/hif/src/snoc/if_snoc.c
@@ -55,7 +55,9 @@
{
hif_nointrs(scn);
ce_tasklet_kill(scn);
+ hif_grp_tasklet_kill(scn);
qdf_atomic_set(&scn->active_tasklet_cnt, 0);
+ qdf_atomic_set(&scn->active_grp_tasklet_cnt, 0);
}
/**