xref: /linux/drivers/irqchip/irq-meson-gpio.c (revision 4ae68b26c3ab5a82aa271e6e9fc9b1a06e1d6b40)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015 Endless Mobile, Inc.
4  * Author: Carlo Caione <carlo@endlessm.com>
5  * Copyright (c) 2016 BayLibre, SAS.
6  * Author: Jerome Brunet <jbrunet@baylibre.com>
7  */
8 
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 
11 #include <linux/io.h>
12 #include <linux/module.h>
13 #include <linux/irq.h>
14 #include <linux/irqdomain.h>
15 #include <linux/irqchip.h>
16 #include <linux/of.h>
17 #include <linux/of_address.h>
18 
19 #define MAX_NUM_CHANNEL 64
20 #define MAX_INPUT_MUX 256
21 
22 #define REG_EDGE_POL	0x00
23 #define REG_PIN_03_SEL	0x04
24 #define REG_PIN_47_SEL	0x08
25 #define REG_FILTER_SEL	0x0c
26 
27 /* use for A1 like chips */
28 #define REG_PIN_A1_SEL	0x04
29 /* Used for s4 chips */
30 #define REG_EDGE_POL_S4	0x1c
31 
32 /*
33  * Note: The S905X3 datasheet reports that BOTH_EDGE is controlled by
34  * bits 24 to 31. Tests on the actual HW show that these bits are
35  * stuck at 0. Bits 8 to 15 are responsive and have the expected
36  * effect.
37  */
38 #define REG_EDGE_POL_EDGE(params, x)	BIT((params)->edge_single_offset + (x))
39 #define REG_EDGE_POL_LOW(params, x)	BIT((params)->pol_low_offset + (x))
40 #define REG_BOTH_EDGE(params, x)	BIT((params)->edge_both_offset + (x))
41 #define REG_EDGE_POL_MASK(params, x)    (	\
42 		REG_EDGE_POL_EDGE(params, x) |	\
43 		REG_EDGE_POL_LOW(params, x)  |	\
44 		REG_BOTH_EDGE(params, x))
45 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
46 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
47 
48 struct meson_gpio_irq_controller;
49 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
50 				    unsigned int channel, unsigned long hwirq);
51 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl);
52 static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
53 				      unsigned int channel,
54 				      unsigned long hwirq);
55 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
56 static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
57 				    unsigned int type, u32 *channel_hwirq);
58 static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
59 				      unsigned int type, u32 *channel_hwirq);
60 
61 struct irq_ctl_ops {
62 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
63 				 unsigned int channel, unsigned long hwirq);
64 	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
65 	int (*gpio_irq_set_type)(struct meson_gpio_irq_controller *ctl,
66 				 unsigned int type, u32 *channel_hwirq);
67 };
68 
69 struct meson_gpio_irq_params {
70 	unsigned int nr_hwirq;
71 	unsigned int nr_channels;
72 	bool support_edge_both;
73 	unsigned int edge_both_offset;
74 	unsigned int edge_single_offset;
75 	unsigned int pol_low_offset;
76 	unsigned int pin_sel_mask;
77 	struct irq_ctl_ops ops;
78 };
79 
80 #define INIT_MESON_COMMON(irqs, init, sel, type)		\
81 	.nr_hwirq = irqs,					\
82 	.ops = {						\
83 		.gpio_irq_init = init,				\
84 		.gpio_irq_sel_pin = sel,			\
85 		.gpio_irq_set_type = type,			\
86 	},
87 
88 #define INIT_MESON8_COMMON_DATA(irqs)				\
89 	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
90 			  meson8_gpio_irq_sel_pin,		\
91 			  meson8_gpio_irq_set_type)		\
92 	.edge_single_offset = 0,				\
93 	.pol_low_offset = 16,					\
94 	.pin_sel_mask = 0xff,					\
95 	.nr_channels = 8,					\
96 
97 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
98 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
99 			  meson_a1_gpio_irq_sel_pin,		\
100 			  meson8_gpio_irq_set_type)		\
101 	.support_edge_both = true,				\
102 	.edge_both_offset = 16,					\
103 	.edge_single_offset = 8,				\
104 	.pol_low_offset = 0,					\
105 	.pin_sel_mask = 0x7f,					\
106 	.nr_channels = 8,					\
107 
108 #define INIT_MESON_S4_COMMON_DATA(irqs)				\
109 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
110 			  meson_a1_gpio_irq_sel_pin,		\
111 			  meson_s4_gpio_irq_set_type)		\
112 	.support_edge_both = true,				\
113 	.edge_both_offset = 0,					\
114 	.edge_single_offset = 12,				\
115 	.pol_low_offset = 0,					\
116 	.pin_sel_mask = 0xff,					\
117 	.nr_channels = 12,					\
118 
119 static const struct meson_gpio_irq_params meson8_params = {
120 	INIT_MESON8_COMMON_DATA(134)
121 };
122 
123 static const struct meson_gpio_irq_params meson8b_params = {
124 	INIT_MESON8_COMMON_DATA(119)
125 };
126 
127 static const struct meson_gpio_irq_params gxbb_params = {
128 	INIT_MESON8_COMMON_DATA(133)
129 };
130 
131 static const struct meson_gpio_irq_params gxl_params = {
132 	INIT_MESON8_COMMON_DATA(110)
133 };
134 
135 static const struct meson_gpio_irq_params axg_params = {
136 	INIT_MESON8_COMMON_DATA(100)
137 };
138 
139 static const struct meson_gpio_irq_params sm1_params = {
140 	INIT_MESON8_COMMON_DATA(100)
141 	.support_edge_both = true,
142 	.edge_both_offset = 8,
143 };
144 
145 static const struct meson_gpio_irq_params a1_params = {
146 	INIT_MESON_A1_COMMON_DATA(62)
147 };
148 
149 static const struct meson_gpio_irq_params s4_params = {
150 	INIT_MESON_S4_COMMON_DATA(82)
151 };
152 
153 static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = {
154 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
155 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
156 	{ .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params },
157 	{ .compatible = "amlogic,meson-gxl-gpio-intc", .data = &gxl_params },
158 	{ .compatible = "amlogic,meson-axg-gpio-intc", .data = &axg_params },
159 	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
160 	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
161 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
162 	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
163 	{ }
164 };
165 
166 struct meson_gpio_irq_controller {
167 	const struct meson_gpio_irq_params *params;
168 	void __iomem *base;
169 	u32 channel_irqs[MAX_NUM_CHANNEL];
170 	DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
171 	spinlock_t lock;
172 };
173 
174 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
175 				       unsigned int reg, u32 mask, u32 val)
176 {
177 	unsigned long flags;
178 	u32 tmp;
179 
180 	spin_lock_irqsave(&ctl->lock, flags);
181 
182 	tmp = readl_relaxed(ctl->base + reg);
183 	tmp &= ~mask;
184 	tmp |= val;
185 	writel_relaxed(tmp, ctl->base + reg);
186 
187 	spin_unlock_irqrestore(&ctl->lock, flags);
188 }
189 
190 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
191 {
192 }
193 
194 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
195 				    unsigned int channel, unsigned long hwirq)
196 {
197 	unsigned int reg_offset;
198 	unsigned int bit_offset;
199 
200 	reg_offset = (channel < 4) ? REG_PIN_03_SEL : REG_PIN_47_SEL;
201 	bit_offset = REG_PIN_SEL_SHIFT(channel);
202 
203 	meson_gpio_irq_update_bits(ctl, reg_offset,
204 				   ctl->params->pin_sel_mask << bit_offset,
205 				   hwirq << bit_offset);
206 }
207 
208 static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
209 				      unsigned int channel,
210 				      unsigned long hwirq)
211 {
212 	unsigned int reg_offset;
213 	unsigned int bit_offset;
214 
215 	bit_offset = ((channel % 2) == 0) ? 0 : 16;
216 	reg_offset = REG_PIN_A1_SEL + ((channel / 2) << 2);
217 
218 	meson_gpio_irq_update_bits(ctl, reg_offset,
219 				   ctl->params->pin_sel_mask << bit_offset,
220 				   hwirq << bit_offset);
221 }
222 
223 /* For a1 or later chips like a1 there is a switch to enable/disable irq */
224 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
225 {
226 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
227 }
228 
229 static int
230 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
231 			       unsigned long  hwirq,
232 			       u32 **channel_hwirq)
233 {
234 	unsigned long flags;
235 	unsigned int idx;
236 
237 	spin_lock_irqsave(&ctl->lock, flags);
238 
239 	/* Find a free channel */
240 	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
241 	if (idx >= ctl->params->nr_channels) {
242 		spin_unlock_irqrestore(&ctl->lock, flags);
243 		pr_err("No channel available\n");
244 		return -ENOSPC;
245 	}
246 
247 	/* Mark the channel as used */
248 	set_bit(idx, ctl->channel_map);
249 
250 	spin_unlock_irqrestore(&ctl->lock, flags);
251 
252 	/*
253 	 * Setup the mux of the channel to route the signal of the pad
254 	 * to the appropriate input of the GIC
255 	 */
256 	ctl->params->ops.gpio_irq_sel_pin(ctl, idx, hwirq);
257 
258 	/*
259 	 * Get the hwirq number assigned to this channel through
260 	 * a pointer the channel_irq table. The added benefit of this
261 	 * method is that we can also retrieve the channel index with
262 	 * it, using the table base.
263 	 */
264 	*channel_hwirq = &(ctl->channel_irqs[idx]);
265 
266 	pr_debug("hwirq %lu assigned to channel %d - irq %u\n",
267 		 hwirq, idx, **channel_hwirq);
268 
269 	return 0;
270 }
271 
272 static unsigned int
273 meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl,
274 			       u32 *channel_hwirq)
275 {
276 	return channel_hwirq - ctl->channel_irqs;
277 }
278 
279 static void
280 meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl,
281 			       u32 *channel_hwirq)
282 {
283 	unsigned int idx;
284 
285 	idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
286 	clear_bit(idx, ctl->channel_map);
287 }
288 
289 static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
290 				    unsigned int type, u32 *channel_hwirq)
291 {
292 	u32 val = 0;
293 	unsigned int idx;
294 	const struct meson_gpio_irq_params *params;
295 
296 	params = ctl->params;
297 	idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
298 
299 	/*
300 	 * The controller has a filter block to operate in either LEVEL or
301 	 * EDGE mode, then signal is sent to the GIC. To enable LEVEL_LOW and
302 	 * EDGE_FALLING support (which the GIC does not support), the filter
303 	 * block is also able to invert the input signal it gets before
304 	 * providing it to the GIC.
305 	 */
306 	type &= IRQ_TYPE_SENSE_MASK;
307 
308 	/*
309 	 * New controller support EDGE_BOTH trigger. This setting takes
310 	 * precedence over the other edge/polarity settings
311 	 */
312 	if (type == IRQ_TYPE_EDGE_BOTH) {
313 		if (!params->support_edge_both)
314 			return -EINVAL;
315 
316 		val |= REG_BOTH_EDGE(params, idx);
317 	} else {
318 		if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
319 			val |= REG_EDGE_POL_EDGE(params, idx);
320 
321 		if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
322 			val |= REG_EDGE_POL_LOW(params, idx);
323 	}
324 
325 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
326 				   REG_EDGE_POL_MASK(params, idx), val);
327 
328 	return 0;
329 }
330 
331 /*
332  * gpio irq relative registers for s4
333  * -PADCTRL_GPIO_IRQ_CTRL0
334  * bit[31]:    enable/disable all the irq lines
335  * bit[12-23]: single edge trigger
336  * bit[0-11]:  polarity trigger
337  *
338  * -PADCTRL_GPIO_IRQ_CTRL[X]
339  * bit[0-16]: 7 bits to choose gpio source for irq line 2*[X] - 2
340  * bit[16-22]:7 bits to choose gpio source for irq line 2*[X] - 1
341  * where X = 1-6
342  *
343  * -PADCTRL_GPIO_IRQ_CTRL[7]
344  * bit[0-11]: both edge trigger
345  */
346 static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
347 				      unsigned int type, u32 *channel_hwirq)
348 {
349 	u32 val = 0;
350 	unsigned int idx;
351 
352 	idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
353 
354 	type &= IRQ_TYPE_SENSE_MASK;
355 
356 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
357 
358 	if (type == IRQ_TYPE_EDGE_BOTH) {
359 		val |= BIT(ctl->params->edge_both_offset + idx);
360 		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
361 					   BIT(ctl->params->edge_both_offset + idx), val);
362 		return 0;
363 	}
364 
365 	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
366 		val |= BIT(ctl->params->pol_low_offset + idx);
367 
368 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
369 		val |= BIT(ctl->params->edge_single_offset + idx);
370 
371 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
372 				   BIT(idx) | BIT(12 + idx), val);
373 	return 0;
374 };
375 
376 static unsigned int meson_gpio_irq_type_output(unsigned int type)
377 {
378 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
379 
380 	type &= ~IRQ_TYPE_SENSE_MASK;
381 
382 	/*
383 	 * The polarity of the signal provided to the GIC should always
384 	 * be high.
385 	 */
386 	if (sense & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
387 		type |= IRQ_TYPE_LEVEL_HIGH;
388 	else
389 		type |= IRQ_TYPE_EDGE_RISING;
390 
391 	return type;
392 }
393 
394 static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type)
395 {
396 	struct meson_gpio_irq_controller *ctl = data->domain->host_data;
397 	u32 *channel_hwirq = irq_data_get_irq_chip_data(data);
398 	int ret;
399 
400 	ret = ctl->params->ops.gpio_irq_set_type(ctl, type, channel_hwirq);
401 	if (ret)
402 		return ret;
403 
404 	return irq_chip_set_type_parent(data,
405 					meson_gpio_irq_type_output(type));
406 }
407 
408 static struct irq_chip meson_gpio_irq_chip = {
409 	.name			= "meson-gpio-irqchip",
410 	.irq_mask		= irq_chip_mask_parent,
411 	.irq_unmask		= irq_chip_unmask_parent,
412 	.irq_eoi		= irq_chip_eoi_parent,
413 	.irq_set_type		= meson_gpio_irq_set_type,
414 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
415 #ifdef CONFIG_SMP
416 	.irq_set_affinity	= irq_chip_set_affinity_parent,
417 #endif
418 	.flags			= IRQCHIP_SET_TYPE_MASKED,
419 };
420 
421 static int meson_gpio_irq_domain_translate(struct irq_domain *domain,
422 					   struct irq_fwspec *fwspec,
423 					   unsigned long *hwirq,
424 					   unsigned int *type)
425 {
426 	if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
427 		*hwirq	= fwspec->param[0];
428 		*type	= fwspec->param[1];
429 		return 0;
430 	}
431 
432 	return -EINVAL;
433 }
434 
435 static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain,
436 					   unsigned int virq,
437 					   u32 hwirq,
438 					   unsigned int type)
439 {
440 	struct irq_fwspec fwspec;
441 
442 	fwspec.fwnode = domain->parent->fwnode;
443 	fwspec.param_count = 3;
444 	fwspec.param[0] = 0;	/* SPI */
445 	fwspec.param[1] = hwirq;
446 	fwspec.param[2] = meson_gpio_irq_type_output(type);
447 
448 	return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
449 }
450 
451 static int meson_gpio_irq_domain_alloc(struct irq_domain *domain,
452 				       unsigned int virq,
453 				       unsigned int nr_irqs,
454 				       void *data)
455 {
456 	struct irq_fwspec *fwspec = data;
457 	struct meson_gpio_irq_controller *ctl = domain->host_data;
458 	unsigned long hwirq;
459 	u32 *channel_hwirq;
460 	unsigned int type;
461 	int ret;
462 
463 	if (WARN_ON(nr_irqs != 1))
464 		return -EINVAL;
465 
466 	ret = meson_gpio_irq_domain_translate(domain, fwspec, &hwirq, &type);
467 	if (ret)
468 		return ret;
469 
470 	ret = meson_gpio_irq_request_channel(ctl, hwirq, &channel_hwirq);
471 	if (ret)
472 		return ret;
473 
474 	ret = meson_gpio_irq_allocate_gic_irq(domain, virq,
475 					      *channel_hwirq, type);
476 	if (ret < 0) {
477 		pr_err("failed to allocate gic irq %u\n", *channel_hwirq);
478 		meson_gpio_irq_release_channel(ctl, channel_hwirq);
479 		return ret;
480 	}
481 
482 	irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
483 				      &meson_gpio_irq_chip, channel_hwirq);
484 
485 	return 0;
486 }
487 
488 static void meson_gpio_irq_domain_free(struct irq_domain *domain,
489 				       unsigned int virq,
490 				       unsigned int nr_irqs)
491 {
492 	struct meson_gpio_irq_controller *ctl = domain->host_data;
493 	struct irq_data *irq_data;
494 	u32 *channel_hwirq;
495 
496 	if (WARN_ON(nr_irqs != 1))
497 		return;
498 
499 	irq_domain_free_irqs_parent(domain, virq, 1);
500 
501 	irq_data = irq_domain_get_irq_data(domain, virq);
502 	channel_hwirq = irq_data_get_irq_chip_data(irq_data);
503 
504 	meson_gpio_irq_release_channel(ctl, channel_hwirq);
505 }
506 
507 static const struct irq_domain_ops meson_gpio_irq_domain_ops = {
508 	.alloc		= meson_gpio_irq_domain_alloc,
509 	.free		= meson_gpio_irq_domain_free,
510 	.translate	= meson_gpio_irq_domain_translate,
511 };
512 
513 static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_irq_controller *ctl)
514 {
515 	const struct of_device_id *match;
516 	int ret;
517 
518 	match = of_match_node(meson_irq_gpio_matches, node);
519 	if (!match)
520 		return -ENODEV;
521 
522 	ctl->params = match->data;
523 
524 	ret = of_property_read_variable_u32_array(node,
525 						  "amlogic,channel-interrupts",
526 						  ctl->channel_irqs,
527 						  ctl->params->nr_channels,
528 						  ctl->params->nr_channels);
529 	if (ret < 0) {
530 		pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
531 		return ret;
532 	}
533 
534 	ctl->params->ops.gpio_irq_init(ctl);
535 
536 	return 0;
537 }
538 
539 static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *parent)
540 {
541 	struct irq_domain *domain, *parent_domain;
542 	struct meson_gpio_irq_controller *ctl;
543 	int ret;
544 
545 	if (!parent) {
546 		pr_err("missing parent interrupt node\n");
547 		return -ENODEV;
548 	}
549 
550 	parent_domain = irq_find_host(parent);
551 	if (!parent_domain) {
552 		pr_err("unable to obtain parent domain\n");
553 		return -ENXIO;
554 	}
555 
556 	ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
557 	if (!ctl)
558 		return -ENOMEM;
559 
560 	spin_lock_init(&ctl->lock);
561 
562 	ctl->base = of_iomap(node, 0);
563 	if (!ctl->base) {
564 		ret = -ENOMEM;
565 		goto free_ctl;
566 	}
567 
568 	ret = meson_gpio_irq_parse_dt(node, ctl);
569 	if (ret)
570 		goto free_channel_irqs;
571 
572 	domain = irq_domain_create_hierarchy(parent_domain, 0,
573 					     ctl->params->nr_hwirq,
574 					     of_node_to_fwnode(node),
575 					     &meson_gpio_irq_domain_ops,
576 					     ctl);
577 	if (!domain) {
578 		pr_err("failed to add domain\n");
579 		ret = -ENODEV;
580 		goto free_channel_irqs;
581 	}
582 
583 	pr_info("%d to %d gpio interrupt mux initialized\n",
584 		ctl->params->nr_hwirq, ctl->params->nr_channels);
585 
586 	return 0;
587 
588 free_channel_irqs:
589 	iounmap(ctl->base);
590 free_ctl:
591 	kfree(ctl);
592 
593 	return ret;
594 }
595 
596 IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc)
597 IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
598 IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc)
599 
600 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
601 MODULE_LICENSE("GPL v2");
602 MODULE_ALIAS("platform:meson-gpio-intc");
603