[v3,18/32] common/cnxk: support for retrieving irq stack

Message ID 20210621150449.19070-19-tduszynski@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series add support for baseband phy |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Tomasz Duszynski June 21, 2021, 3:04 p.m. UTC
  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>
Reviewed-by: Jerin Jacob <jerinj@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(+)
  

Patch

diff --git a/drivers/common/cnxk/roc_bphy_irq.c b/drivers/common/cnxk/roc_bphy_irq.c
index bea2b7f73..04ad129ac 100644
--- a/drivers/common/cnxk/roc_bphy_irq.c
+++ b/drivers/common/cnxk/roc_bphy_irq.c
@@ -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)
 {
diff --git a/drivers/common/cnxk/roc_bphy_irq.h b/drivers/common/cnxk/roc_bphy_irq.h
index f481f4456..e66b2aa7c 100644
--- a/drivers/common/cnxk/roc_bphy_irq.h
+++ b/drivers/common/cnxk/roc_bphy_irq.h
@@ -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);
 
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 427321c41..542364926 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -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;