Skip to content

Commit 6f45ecc

Browse files
author
Marek Czerski
committed
gpio: litex: add irq support for litex gpio inputs
This commit adds support for interrupts on input gpio. This driver version support GPIOIn module from https://github.com/enjoy-digital/litex@9113c1a2f9015e2fa86dadb4c61d1993d0e6bced
1 parent 2669e46 commit 6f45ecc

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

drivers/gpio/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ config GPIO_LOGICVC
364364
config GPIO_LITEX
365365
tristate "LiteX GPIO support"
366366
depends on OF && HAS_IOMEM && LITEX_SOC_CONTROLLER
367+
select GPIOLIB_IRQCHIP
367368
help
368369
driver for GPIO functionality on LiteX
369370

drivers/gpio/gpio-litex.c

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,44 @@
2020
#include <linux/platform_device.h>
2121
#include <linux/gpio/driver.h>
2222
#include <linux/gpio.h>
23+
#include <linux/of_irq.h>
2324
#include <linux/types.h>
2425
#include <linux/string.h>
2526
#include <linux/bits.h>
2627
#include <linux/errno.h>
28+
#include <linux/spinlock.h>
2729
#include <linux/litex.h>
2830

2931
#define GPIO_PINS_MAX 32
32+
#define LITEX_GPIO_VALUE_OFFSET 0x0
33+
#define LITEX_GPIO_MODE_OFFSET 0x4
34+
#define LITEX_GPIO_EDGE_OFFSET 0x8
35+
#define LITEX_GPIO_PENDING_OFFSET 0x10
36+
#define LITEX_GPIO_ENABLE_OFFSET 0x14
3037

3138
struct litex_gpio {
3239
void __iomem *membase;
3340
int port_direction;
3441
int reg_span;
3542
struct gpio_chip chip;
43+
struct irq_chip ichip;
44+
spinlock_t gpio_lock;
45+
unsigned int irq_number;
3646
};
3747

48+
/* Helper functions */
49+
50+
static inline u32 litex_gpio_get_reg(struct litex_gpio *gpio_s, int reg_offset)
51+
{
52+
return _litex_get_reg(gpio_s->membase + reg_offset, gpio_s->reg_span);
53+
}
54+
55+
static inline void litex_gpio_set_reg(struct litex_gpio *gpio_s, int reg_offset,
56+
u32 value)
57+
{
58+
_litex_set_reg(gpio_s->membase + reg_offset, gpio_s->reg_span, value);
59+
}
60+
3861
/* API functions */
3962

4063
static int litex_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
@@ -120,8 +143,202 @@ static int litex_gpio_direction_output(struct gpio_chip *chip,
120143
return 0;
121144
}
122145

146+
static void litex_gpio_irq_unmask(struct irq_data *idata)
147+
{
148+
struct gpio_chip *chip = irq_data_get_irq_chip_data(idata);
149+
struct litex_gpio *gpio_s = gpiochip_get_data(chip);
150+
int offset = irqd_to_hwirq(idata) % GPIO_PINS_MAX;
151+
unsigned long flags;
152+
u32 bit = BIT(offset);
153+
u32 enable;
154+
155+
spin_lock_irqsave(&gpio_s->gpio_lock, flags);
156+
157+
/* Clear any sticky pending interrupts */
158+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_PENDING_OFFSET, bit);
159+
enable = litex_gpio_get_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET);
160+
enable |= bit;
161+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET, enable);
162+
163+
spin_unlock_irqrestore(&gpio_s->gpio_lock, flags);
164+
}
165+
166+
static void litex_gpio_irq_mask(struct irq_data *idata)
167+
{
168+
struct gpio_chip *chip = irq_data_get_irq_chip_data(idata);
169+
struct litex_gpio *gpio_s = gpiochip_get_data(chip);
170+
int offset = irqd_to_hwirq(idata) % GPIO_PINS_MAX;
171+
unsigned long flags;
172+
u32 bit = BIT(offset);
173+
u32 enable;
174+
175+
spin_lock_irqsave(&gpio_s->gpio_lock, flags);
176+
177+
enable = litex_gpio_get_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET);
178+
enable &= ~bit;
179+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET, enable);
180+
181+
spin_unlock_irqrestore(&gpio_s->gpio_lock, flags);
182+
}
183+
184+
static int litex_gpio_irq_set_type(struct irq_data *idata, unsigned int type)
185+
{
186+
struct gpio_chip *chip = irq_data_get_irq_chip_data(idata);
187+
struct litex_gpio *gpio_s = gpiochip_get_data(chip);
188+
int offset = irqd_to_hwirq(idata) % GPIO_PINS_MAX;
189+
unsigned long flags;
190+
u32 bit = BIT(offset);
191+
u32 mode, edge;
192+
193+
spin_lock_irqsave(&gpio_s->gpio_lock, flags);
194+
195+
mode = litex_gpio_get_reg(gpio_s, LITEX_GPIO_MODE_OFFSET);
196+
edge = litex_gpio_get_reg(gpio_s, LITEX_GPIO_EDGE_OFFSET);
197+
198+
switch (type & IRQ_TYPE_SENSE_MASK) {
199+
case IRQ_TYPE_NONE:
200+
break;
201+
202+
case IRQ_TYPE_EDGE_RISING:
203+
mode &= ~bit;
204+
edge &= ~bit;
205+
break;
206+
207+
case IRQ_TYPE_EDGE_FALLING:
208+
mode &= ~bit;
209+
edge |= bit;
210+
break;
211+
212+
case IRQ_TYPE_EDGE_BOTH:
213+
mode |= bit;
214+
break;
215+
216+
default:
217+
return -EINVAL;
218+
}
219+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_MODE_OFFSET, mode);
220+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_EDGE_OFFSET, edge);
221+
222+
spin_unlock_irqrestore(&gpio_s->gpio_lock, flags);
223+
224+
return 0;
225+
}
226+
227+
static void litex_gpio_irq_eoi(struct irq_data *idata)
228+
{
229+
struct gpio_chip *chip = irq_data_get_irq_chip_data(idata);
230+
struct litex_gpio *gpio_s = gpiochip_get_data(chip);
231+
int offset = irqd_to_hwirq(idata) % GPIO_PINS_MAX;
232+
u32 bit = BIT(offset);
233+
unsigned long flags;
234+
235+
spin_lock_irqsave(&gpio_s->gpio_lock, flags);
236+
237+
/* Clear all pending interrupts */
238+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_PENDING_OFFSET, bit);
239+
240+
spin_unlock_irqrestore(&gpio_s->gpio_lock, flags);
241+
242+
irq_chip_eoi_parent(idata);
243+
}
244+
245+
static int litex_gpio_irq_set_affinity(struct irq_data *idata,
246+
const struct cpumask *dest,
247+
bool force)
248+
{
249+
if (idata->parent_data)
250+
return irq_chip_set_affinity_parent(idata, dest, force);
251+
252+
return -EINVAL;
253+
}
254+
255+
static int litex_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
256+
unsigned int child,
257+
unsigned int child_type,
258+
unsigned int *parent,
259+
unsigned int *parent_type)
260+
{
261+
*parent = chip->irq.child_offset_to_irq(chip, child);
262+
*parent_type = child_type;
263+
264+
return 0;
265+
}
266+
267+
static void litex_gpio_irq(struct irq_desc *desc)
268+
{
269+
struct litex_gpio *gpio_s = irq_desc_get_handler_data(desc);
270+
struct irq_domain *domain = gpio_s->chip.irq.domain;
271+
struct irq_chip *ichip = irq_desc_get_chip(desc);
272+
u32 enabled;
273+
u32 pending;
274+
unsigned long int interrupts_to_handle;
275+
unsigned int pin, irq;
276+
277+
chained_irq_enter(ichip, desc);
278+
279+
enabled = litex_gpio_get_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET);
280+
pending = litex_gpio_get_reg(gpio_s, LITEX_GPIO_PENDING_OFFSET);
281+
interrupts_to_handle = pending & enabled;
282+
283+
for_each_set_bit(pin, &interrupts_to_handle, GPIO_PINS_MAX) {
284+
irq = irq_find_mapping(domain, pin);
285+
if (WARN_ON(irq == 0))
286+
continue;
287+
288+
generic_handle_irq(irq);
289+
}
290+
291+
chained_irq_exit(ichip, desc);
292+
}
293+
123294
/* Driver functions */
124295

296+
static int litex_gpio_init_irq(struct platform_device *pdev,
297+
struct litex_gpio *gpio_s)
298+
{
299+
struct device_node *node = pdev->dev.of_node;
300+
struct device_node *irq_parent = of_irq_find_parent(node);
301+
struct irq_domain *parent_domain;
302+
struct gpio_irq_chip *gichip;
303+
304+
if (!irq_parent) {
305+
dev_info(&pdev->dev, "no IRQ parent node\n");
306+
return 0;
307+
}
308+
309+
parent_domain = irq_find_host(irq_parent);
310+
if (!parent_domain) {
311+
dev_err(&pdev->dev, "no IRQ parent domain\n");
312+
return -ENODEV;
313+
}
314+
315+
gpio_s->irq_number = platform_get_irq(pdev, 0);
316+
317+
/* Disable all GPIO interrupts before enabling parent interrupts */
318+
litex_gpio_set_reg(gpio_s, LITEX_GPIO_ENABLE_OFFSET, 0);
319+
320+
gpio_s->ichip.name = pdev->name;
321+
gpio_s->ichip.irq_unmask = litex_gpio_irq_unmask;
322+
gpio_s->ichip.irq_mask = litex_gpio_irq_mask;
323+
gpio_s->ichip.irq_set_type = litex_gpio_irq_set_type;
324+
gpio_s->ichip.irq_eoi = litex_gpio_irq_eoi;
325+
gpio_s->ichip.irq_set_affinity = litex_gpio_irq_set_affinity;
326+
327+
gichip = &gpio_s->chip.irq;
328+
gichip->chip = &gpio_s->ichip;
329+
gichip->fwnode = of_node_to_fwnode(node);
330+
gichip->parent_domain = parent_domain;
331+
gichip->child_to_parent_hwirq = litex_gpio_child_to_parent_hwirq;
332+
gichip->handler = handle_bad_irq;
333+
gichip->default_type = IRQ_TYPE_NONE;
334+
gichip->parent_handler = litex_gpio_irq;
335+
gichip->parent_handler_data = gpio_s;
336+
gichip->num_parents = 1;
337+
gichip->parents = &gpio_s->irq_number;
338+
339+
return 0;
340+
}
341+
125342
static int litex_gpio_probe(struct platform_device *pdev)
126343
{
127344
struct device_node *node = pdev->dev.of_node;
@@ -147,6 +364,8 @@ static int litex_gpio_probe(struct platform_device *pdev)
147364
if (IS_ERR_OR_NULL(gpio_s->membase))
148365
return -EIO;
149366

367+
spin_lock_init(&gpio_s->gpio_lock);
368+
150369
ret_i = of_property_read_u32(node, "litex,ngpio", &dt_ngpio);
151370
if (ret_i < 0) {
152371
dev_err(&pdev->dev, "No litex,ngpio entry in the dts file\n");
@@ -192,6 +411,12 @@ static int litex_gpio_probe(struct platform_device *pdev)
192411
gpio_s->reg_span = (dt_ngpio + LITEX_SUBREG_SIZE_BIT - 1) /
193412
LITEX_SUBREG_SIZE_BIT;
194413

414+
if (gpio_s->port_direction == GPIOF_DIR_IN) {
415+
ret_i = litex_gpio_init_irq(pdev, gpio_s);
416+
if (ret_i < 0)
417+
return ret_i;
418+
}
419+
195420
platform_set_drvdata(pdev, gpio_s);
196421
return devm_gpiochip_add_data(&pdev->dev, &gpio_s->chip, gpio_s);
197422
}

0 commit comments

Comments
 (0)