1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
12 #include <rte_rawdev_pmd.h>
16 #include "cnxk_gpio.h"
18 #define OTX_IOC_MAGIC 0xF2
19 #define OTX_IOC_SET_GPIO_HANDLER \
20 _IOW(OTX_IOC_MAGIC, 1, struct otx_gpio_usr_data)
21 #define OTX_IOC_CLR_GPIO_HANDLER \
24 struct otx_gpio_usr_data {
31 struct cnxk_gpio_irq_stack {
32 LIST_ENTRY(cnxk_gpio_irq_stack) next;
38 struct cnxk_gpio_irqchip {
40 /* serialize access to this struct */
42 LIST_HEAD(, cnxk_gpio_irq_stack) stacks;
44 struct cnxk_gpiochip *gpiochip;
47 static struct cnxk_gpio_irqchip *irqchip;
50 cnxk_gpio_irq_stack_free(int cpu)
52 struct cnxk_gpio_irq_stack *stack;
54 LIST_FOREACH(stack, &irqchip->stacks, next) {
55 if (stack->cpu == cpu)
65 if (stack->inuse == 0) {
66 LIST_REMOVE(stack, next);
67 rte_free(stack->sp_buffer);
73 cnxk_gpio_irq_stack_alloc(int cpu)
75 #define ARM_STACK_ALIGNMENT (2 * sizeof(void *))
76 #define IRQ_STACK_SIZE 0x200000
78 struct cnxk_gpio_irq_stack *stack;
80 LIST_FOREACH(stack, &irqchip->stacks, next) {
81 if (stack->cpu == cpu)
87 return (char *)stack->sp_buffer + IRQ_STACK_SIZE;
90 stack = rte_malloc(NULL, sizeof(*stack), 0);
95 rte_zmalloc(NULL, IRQ_STACK_SIZE * 2, ARM_STACK_ALIGNMENT);
96 if (!stack->sp_buffer) {
103 LIST_INSERT_HEAD(&irqchip->stacks, stack, next);
105 return (char *)stack->sp_buffer + IRQ_STACK_SIZE;
109 cnxk_gpio_irq_handler(int gpio_num)
111 struct cnxk_gpiochip *gpiochip = irqchip->gpiochip;
112 struct cnxk_gpio *gpio;
114 if (gpio_num >= gpiochip->num_gpios)
117 gpio = gpiochip->gpios[gpio_num];
118 if (likely(gpio->handler))
119 gpio->handler(gpio_num, gpio->data);
126 cnxk_gpio_irq_init(struct cnxk_gpiochip *gpiochip)
131 irqchip = rte_zmalloc(NULL, sizeof(*irqchip), 0);
135 irqchip->fd = open("/dev/otx-gpio-ctr", O_RDWR | O_SYNC);
136 if (irqchip->fd < 0) {
141 pthread_mutex_init(&irqchip->lock, NULL);
142 LIST_INIT(&irqchip->stacks);
143 irqchip->gpiochip = gpiochip;
149 cnxk_gpio_irq_fini(void)
160 cnxk_gpio_irq_request(int gpio, int cpu)
162 struct otx_gpio_usr_data data;
166 pthread_mutex_lock(&irqchip->lock);
168 sp = cnxk_gpio_irq_stack_alloc(cpu);
174 data.isr_base = (uint64_t)cnxk_gpio_irq_handler;
175 data.sp = (uint64_t)sp;
176 data.cpu = (uint64_t)cpu;
177 data.gpio_num = (uint64_t)gpio;
179 mlockall(MCL_CURRENT | MCL_FUTURE);
180 ret = ioctl(irqchip->fd, OTX_IOC_SET_GPIO_HANDLER, &data);
186 pthread_mutex_unlock(&irqchip->lock);
191 cnxk_gpio_irq_stack_free(cpu);
193 pthread_mutex_unlock(&irqchip->lock);
199 cnxk_gpio_irq_free(int gpio)
203 pthread_mutex_lock(&irqchip->lock);
205 ret = ioctl(irqchip->fd, OTX_IOC_CLR_GPIO_HANDLER, gpio);
207 pthread_mutex_unlock(&irqchip->lock);
211 cnxk_gpio_irq_stack_free(irqchip->gpiochip->gpios[gpio]->cpu);
213 pthread_mutex_unlock(&irqchip->lock);