Add support for retrieving irq stack. If stack does not exist
then it gets created.
Signed-off-by: Jakub Palider <jpalider@marvell.com>
Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com>
---
drivers/common/cnxk/roc_bphy_irq.c | 62 ++++++++++++++++++++++++++++++
drivers/common/cnxk/roc_bphy_irq.h | 1 +
drivers/common/cnxk/version.map | 1 +
3 files changed, 64 insertions(+)
@@ -2,12 +2,21 @@
* Copyright(C) 2021 Marvell.
*/
#include <fcntl.h>
+#include <pthread.h>
#include <sys/ioctl.h>
+#include <sys/queue.h>
#include <unistd.h>
#include "roc_api.h"
#include "roc_bphy_irq.h"
+struct roc_bphy_irq_stack {
+ STAILQ_ENTRY(roc_bphy_irq_stack) entries;
+ void *sp_buffer;
+ int cpu;
+ int inuse;
+};
+
#define ROC_BPHY_MEMZONE_NAME "roc_bphy_mz"
#define ROC_BPHY_CTR_DEV_PATH "/dev/otx-bphy-ctr"
@@ -15,6 +24,12 @@
#define ROC_BPHY_IOC_GET_BPHY_MAX_IRQ _IOR(ROC_BPHY_IOC_MAGIC, 3, uint64_t)
#define ROC_BPHY_IOC_GET_BPHY_BMASK_IRQ _IOR(ROC_BPHY_IOC_MAGIC, 4, uint64_t)
+static STAILQ_HEAD(slisthead, roc_bphy_irq_stack)
+ irq_stacks = STAILQ_HEAD_INITIALIZER(irq_stacks);
+
+/* Note: it is assumed that as for now there is no multiprocess support */
+static pthread_mutex_t stacks_mutex = PTHREAD_MUTEX_INITIALIZER;
+
struct roc_bphy_irq_chip *
roc_bphy_intr_init(void)
{
@@ -95,6 +110,53 @@ roc_bphy_intr_fini(struct roc_bphy_irq_chip *irq_chip)
plt_free(irq_chip);
}
+void *
+roc_bphy_irq_stack_get(int cpu)
+{
+#define ARM_STACK_ALIGNMENT (2 * sizeof(void *))
+#define IRQ_ISR_STACK_SIZE 0x200000
+
+ struct roc_bphy_irq_stack *curr_stack;
+ void *retval = NULL;
+
+ if (pthread_mutex_lock(&stacks_mutex))
+ return NULL;
+
+ STAILQ_FOREACH(curr_stack, &irq_stacks, entries) {
+ if (curr_stack->cpu == cpu) {
+ curr_stack->inuse++;
+ retval = ((char *)curr_stack->sp_buffer) +
+ IRQ_ISR_STACK_SIZE;
+ goto found_stack;
+ }
+ }
+
+ curr_stack = plt_zmalloc(sizeof(struct roc_bphy_irq_stack), 0);
+ if (curr_stack == NULL)
+ goto err_stack;
+
+ curr_stack->sp_buffer =
+ plt_zmalloc(IRQ_ISR_STACK_SIZE * 2, ARM_STACK_ALIGNMENT);
+ if (curr_stack->sp_buffer == NULL)
+ goto err_buffer;
+
+ curr_stack->cpu = cpu;
+ curr_stack->inuse = 0;
+ STAILQ_INSERT_TAIL(&irq_stacks, curr_stack, entries);
+ retval = ((char *)curr_stack->sp_buffer) + IRQ_ISR_STACK_SIZE;
+
+found_stack:
+ pthread_mutex_unlock(&stacks_mutex);
+ return retval;
+
+err_buffer:
+ plt_free(curr_stack);
+
+err_stack:
+ pthread_mutex_unlock(&stacks_mutex);
+ return NULL;
+}
+
bool
roc_bphy_intr_available(struct roc_bphy_irq_chip *irq_chip, int irq_num)
{
@@ -23,6 +23,7 @@ struct roc_bphy_irq_chip {
__roc_api struct roc_bphy_irq_chip *roc_bphy_intr_init(void);
__roc_api void roc_bphy_intr_fini(struct roc_bphy_irq_chip *irq_chip);
+__roc_api void *roc_bphy_irq_stack_get(int cpu);
__roc_api bool roc_bphy_intr_available(struct roc_bphy_irq_chip *irq_chip,
int irq_num);
@@ -25,6 +25,7 @@ INTERNAL {
roc_bphy_intr_available;
roc_bphy_intr_fini;
roc_bphy_intr_init;
+ roc_bphy_irq_stack_get;
roc_clk_freq_get;
roc_error_msg_get;
roc_idev_lmt_base_addr_get;