2 * Copyright (c) 2011 Jamie Iles
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * All enquiries to support@picochip.com
10 #include <linux/basic_mmio_gpio.h>
11 #include <linux/err.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
15 #include <linux/ioport.h>
16 #include <linux/irq.h>
17 #include <linux/irqdomain.h>
18 #include <linux/module.h>
20 #include <linux/of_address.h>
21 #include <linux/of_irq.h>
22 #include <linux/platform_device.h>
23 #include <linux/spinlock.h>
25 #define GPIO_SWPORTA_DR 0x00
26 #define GPIO_SWPORTA_DDR 0x04
27 #define GPIO_SWPORTB_DR 0x0c
28 #define GPIO_SWPORTB_DDR 0x10
29 #define GPIO_SWPORTC_DR 0x18
30 #define GPIO_SWPORTC_DDR 0x1c
31 #define GPIO_SWPORTD_DR 0x24
32 #define GPIO_SWPORTD_DDR 0x28
33 #define GPIO_INTEN 0x30
34 #define GPIO_INTMASK 0x34
35 #define GPIO_INTTYPE_LEVEL 0x38
36 #define GPIO_INT_POLARITY 0x3c
37 #define GPIO_INTSTATUS 0x40
38 #define GPIO_PORTA_EOI 0x4c
39 #define GPIO_EXT_PORTA 0x50
40 #define GPIO_EXT_PORTB 0x54
41 #define GPIO_EXT_PORTC 0x58
42 #define GPIO_EXT_PORTD 0x5c
44 #define DWAPB_MAX_PORTS 4
45 #define GPIO_EXT_PORT_SIZE (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
46 #define GPIO_SWPORT_DR_SIZE (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
47 #define GPIO_SWPORT_DDR_SIZE (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
51 struct dwapb_gpio_port
{
52 struct bgpio_chip bgc
;
54 struct dwapb_gpio
*gpio
;
60 struct dwapb_gpio_port
*ports
;
61 unsigned int nr_ports
;
62 struct irq_domain
*domain
;
65 static int dwapb_gpio_to_irq(struct gpio_chip
*gc
, unsigned offset
)
67 struct bgpio_chip
*bgc
= to_bgpio_chip(gc
);
68 struct dwapb_gpio_port
*port
= container_of(bgc
, struct
69 dwapb_gpio_port
, bgc
);
70 struct dwapb_gpio
*gpio
= port
->gpio
;
72 return irq_find_mapping(gpio
->domain
, offset
);
75 static void dwapb_toggle_trigger(struct dwapb_gpio
*gpio
, unsigned int offs
)
77 u32 v
= readl(gpio
->regs
+ GPIO_INT_POLARITY
);
79 if (gpio_get_value(gpio
->ports
[0].bgc
.gc
.base
+ offs
))
84 writel(v
, gpio
->regs
+ GPIO_INT_POLARITY
);
87 static void dwapb_irq_handler(u32 irq
, struct irq_desc
*desc
)
89 struct dwapb_gpio
*gpio
= irq_get_handler_data(irq
);
90 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
91 u32 irq_status
= readl_relaxed(gpio
->regs
+ GPIO_INTSTATUS
);
94 int hwirq
= fls(irq_status
) - 1;
95 int gpio_irq
= irq_find_mapping(gpio
->domain
, hwirq
);
97 generic_handle_irq(gpio_irq
);
98 irq_status
&= ~BIT(hwirq
);
100 if ((irq_get_trigger_type(gpio_irq
) & IRQ_TYPE_SENSE_MASK
)
101 == IRQ_TYPE_EDGE_BOTH
)
102 dwapb_toggle_trigger(gpio
, hwirq
);
106 chip
->irq_eoi(irq_desc_get_irq_data(desc
));
109 static void dwapb_irq_enable(struct irq_data
*d
)
111 struct irq_chip_generic
*igc
= irq_data_get_irq_chip_data(d
);
112 struct dwapb_gpio
*gpio
= igc
->private;
113 struct bgpio_chip
*bgc
= &gpio
->ports
[0].bgc
;
117 spin_lock_irqsave(&bgc
->lock
, flags
);
118 val
= readl(gpio
->regs
+ GPIO_INTEN
);
119 val
|= BIT(d
->hwirq
);
120 writel(val
, gpio
->regs
+ GPIO_INTEN
);
121 spin_unlock_irqrestore(&bgc
->lock
, flags
);
124 static void dwapb_irq_disable(struct irq_data
*d
)
126 struct irq_chip_generic
*igc
= irq_data_get_irq_chip_data(d
);
127 struct dwapb_gpio
*gpio
= igc
->private;
128 struct bgpio_chip
*bgc
= &gpio
->ports
[0].bgc
;
132 spin_lock_irqsave(&bgc
->lock
, flags
);
133 val
= readl(gpio
->regs
+ GPIO_INTEN
);
134 val
&= ~BIT(d
->hwirq
);
135 writel(val
, gpio
->regs
+ GPIO_INTEN
);
136 spin_unlock_irqrestore(&bgc
->lock
, flags
);
139 static int dwapb_irq_reqres(struct irq_data
*d
)
141 struct irq_chip_generic
*igc
= irq_data_get_irq_chip_data(d
);
142 struct dwapb_gpio
*gpio
= igc
->private;
143 struct bgpio_chip
*bgc
= &gpio
->ports
[0].bgc
;
145 if (gpio_lock_as_irq(&bgc
->gc
, irqd_to_hwirq(d
))) {
146 dev_err(gpio
->dev
, "unable to lock HW IRQ %lu for IRQ\n",
153 static void dwapb_irq_relres(struct irq_data
*d
)
155 struct irq_chip_generic
*igc
= irq_data_get_irq_chip_data(d
);
156 struct dwapb_gpio
*gpio
= igc
->private;
157 struct bgpio_chip
*bgc
= &gpio
->ports
[0].bgc
;
159 gpio_unlock_as_irq(&bgc
->gc
, irqd_to_hwirq(d
));
162 static int dwapb_irq_set_type(struct irq_data
*d
, u32 type
)
164 struct irq_chip_generic
*igc
= irq_data_get_irq_chip_data(d
);
165 struct dwapb_gpio
*gpio
= igc
->private;
166 struct bgpio_chip
*bgc
= &gpio
->ports
[0].bgc
;
168 unsigned long level
, polarity
, flags
;
170 if (type
& ~(IRQ_TYPE_EDGE_RISING
| IRQ_TYPE_EDGE_FALLING
|
171 IRQ_TYPE_LEVEL_HIGH
| IRQ_TYPE_LEVEL_LOW
))
174 spin_lock_irqsave(&bgc
->lock
, flags
);
175 level
= readl(gpio
->regs
+ GPIO_INTTYPE_LEVEL
);
176 polarity
= readl(gpio
->regs
+ GPIO_INT_POLARITY
);
179 case IRQ_TYPE_EDGE_BOTH
:
181 dwapb_toggle_trigger(gpio
, bit
);
183 case IRQ_TYPE_EDGE_RISING
:
185 polarity
|= BIT(bit
);
187 case IRQ_TYPE_EDGE_FALLING
:
189 polarity
&= ~BIT(bit
);
191 case IRQ_TYPE_LEVEL_HIGH
:
193 polarity
|= BIT(bit
);
195 case IRQ_TYPE_LEVEL_LOW
:
197 polarity
&= ~BIT(bit
);
201 writel(level
, gpio
->regs
+ GPIO_INTTYPE_LEVEL
);
202 writel(polarity
, gpio
->regs
+ GPIO_INT_POLARITY
);
203 spin_unlock_irqrestore(&bgc
->lock
, flags
);
208 static void dwapb_configure_irqs(struct dwapb_gpio
*gpio
,
209 struct dwapb_gpio_port
*port
)
211 struct gpio_chip
*gc
= &port
->bgc
.gc
;
212 struct device_node
*node
= gc
->of_node
;
213 struct irq_chip_generic
*irq_gc
;
214 unsigned int hwirq
, ngpio
= gc
->ngpio
;
215 struct irq_chip_type
*ct
;
218 irq
= irq_of_parse_and_map(node
, 0);
220 dev_warn(gpio
->dev
, "no irq for bank %s\n",
221 port
->bgc
.gc
.of_node
->full_name
);
225 gpio
->domain
= irq_domain_add_linear(node
, ngpio
,
226 &irq_generic_chip_ops
, gpio
);
230 err
= irq_alloc_domain_generic_chips(gpio
->domain
, ngpio
, 1,
231 "gpio-dwapb", handle_level_irq
,
233 IRQ_GC_INIT_NESTED_LOCK
);
235 dev_info(gpio
->dev
, "irq_alloc_domain_generic_chips failed\n");
236 irq_domain_remove(gpio
->domain
);
241 irq_gc
= irq_get_domain_generic_chip(gpio
->domain
, 0);
243 irq_domain_remove(gpio
->domain
);
248 irq_gc
->reg_base
= gpio
->regs
;
249 irq_gc
->private = gpio
;
251 ct
= irq_gc
->chip_types
;
252 ct
->chip
.irq_ack
= irq_gc_ack_set_bit
;
253 ct
->chip
.irq_mask
= irq_gc_mask_set_bit
;
254 ct
->chip
.irq_unmask
= irq_gc_mask_clr_bit
;
255 ct
->chip
.irq_set_type
= dwapb_irq_set_type
;
256 ct
->chip
.irq_enable
= dwapb_irq_enable
;
257 ct
->chip
.irq_disable
= dwapb_irq_disable
;
258 ct
->chip
.irq_request_resources
= dwapb_irq_reqres
;
259 ct
->chip
.irq_release_resources
= dwapb_irq_relres
;
260 ct
->regs
.ack
= GPIO_PORTA_EOI
;
261 ct
->regs
.mask
= GPIO_INTMASK
;
263 irq_setup_generic_chip(irq_gc
, IRQ_MSK(port
->bgc
.gc
.ngpio
),
264 IRQ_GC_INIT_NESTED_LOCK
, IRQ_NOREQUEST
, 0);
266 irq_set_chained_handler(irq
, dwapb_irq_handler
);
267 irq_set_handler_data(irq
, gpio
);
269 for (hwirq
= 0 ; hwirq
< ngpio
; hwirq
++)
270 irq_create_mapping(gpio
->domain
, hwirq
);
272 port
->bgc
.gc
.to_irq
= dwapb_gpio_to_irq
;
275 static void dwapb_irq_teardown(struct dwapb_gpio
*gpio
)
277 struct dwapb_gpio_port
*port
= &gpio
->ports
[0];
278 struct gpio_chip
*gc
= &port
->bgc
.gc
;
279 unsigned int ngpio
= gc
->ngpio
;
280 irq_hw_number_t hwirq
;
285 for (hwirq
= 0 ; hwirq
< ngpio
; hwirq
++)
286 irq_dispose_mapping(irq_find_mapping(gpio
->domain
, hwirq
));
288 irq_domain_remove(gpio
->domain
);
292 static int dwapb_gpio_add_port(struct dwapb_gpio
*gpio
,
293 struct device_node
*port_np
,
296 struct dwapb_gpio_port
*port
;
298 void __iomem
*dat
, *set
, *dirout
;
301 if (of_property_read_u32(port_np
, "reg", &port_idx
) ||
302 port_idx
>= DWAPB_MAX_PORTS
) {
303 dev_err(gpio
->dev
, "missing/invalid port index for %s\n",
308 port
= &gpio
->ports
[offs
];
311 if (of_property_read_u32(port_np
, "snps,nr-gpios", &ngpio
)) {
312 dev_info(gpio
->dev
, "failed to get number of gpios for %s\n",
317 dat
= gpio
->regs
+ GPIO_EXT_PORTA
+ (port_idx
* GPIO_EXT_PORT_SIZE
);
318 set
= gpio
->regs
+ GPIO_SWPORTA_DR
+ (port_idx
* GPIO_SWPORT_DR_SIZE
);
319 dirout
= gpio
->regs
+ GPIO_SWPORTA_DDR
+
320 (port_idx
* GPIO_SWPORT_DDR_SIZE
);
322 err
= bgpio_init(&port
->bgc
, gpio
->dev
, 4, dat
, set
, NULL
, dirout
,
325 dev_err(gpio
->dev
, "failed to init gpio chip for %s\n",
330 port
->bgc
.gc
.ngpio
= ngpio
;
331 port
->bgc
.gc
.of_node
= port_np
;
334 * Only port A can provide interrupts in all configurations of the IP.
337 of_property_read_bool(port_np
, "interrupt-controller"))
338 dwapb_configure_irqs(gpio
, port
);
340 err
= gpiochip_add(&port
->bgc
.gc
);
342 dev_err(gpio
->dev
, "failed to register gpiochip for %s\n",
345 port
->is_registered
= true;
350 static void dwapb_gpio_unregister(struct dwapb_gpio
*gpio
)
354 for (m
= 0; m
< gpio
->nr_ports
; ++m
)
355 if (gpio
->ports
[m
].is_registered
)
356 WARN_ON(gpiochip_remove(&gpio
->ports
[m
].bgc
.gc
));
359 static int dwapb_gpio_probe(struct platform_device
*pdev
)
361 struct resource
*res
;
362 struct dwapb_gpio
*gpio
;
363 struct device_node
*np
;
365 unsigned int offs
= 0;
367 gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*gpio
), GFP_KERNEL
);
370 gpio
->dev
= &pdev
->dev
;
372 gpio
->nr_ports
= of_get_child_count(pdev
->dev
.of_node
);
373 if (!gpio
->nr_ports
) {
377 gpio
->ports
= devm_kzalloc(&pdev
->dev
, gpio
->nr_ports
*
378 sizeof(*gpio
->ports
), GFP_KERNEL
);
384 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
385 gpio
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
386 if (IS_ERR(gpio
->regs
)) {
387 err
= PTR_ERR(gpio
->regs
);
391 for_each_child_of_node(pdev
->dev
.of_node
, np
) {
392 err
= dwapb_gpio_add_port(gpio
, np
, offs
++);
396 platform_set_drvdata(pdev
, gpio
);
401 dwapb_gpio_unregister(gpio
);
402 dwapb_irq_teardown(gpio
);
408 static int dwapb_gpio_remove(struct platform_device
*pdev
)
410 struct dwapb_gpio
*gpio
= platform_get_drvdata(pdev
);
412 dwapb_gpio_unregister(gpio
);
413 dwapb_irq_teardown(gpio
);
418 static const struct of_device_id dwapb_of_match
[] = {
419 { .compatible
= "snps,dw-apb-gpio" },
422 MODULE_DEVICE_TABLE(of
, dwapb_of_match
);
424 static struct platform_driver dwapb_gpio_driver
= {
426 .name
= "gpio-dwapb",
427 .owner
= THIS_MODULE
,
428 .of_match_table
= of_match_ptr(dwapb_of_match
),
430 .probe
= dwapb_gpio_probe
,
431 .remove
= dwapb_gpio_remove
,
434 module_platform_driver(dwapb_gpio_driver
);
436 MODULE_LICENSE("GPL");
437 MODULE_AUTHOR("Jamie Iles");
438 MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");