1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/gpio.h>
4 #include <linux/gpio/driver.h>
5 #include <linux/of_gpio.h>
7 #include <linux/interrupt.h>
8 #include <linux/platform_device.h>
9 #include <linux/basic_mmio_gpio.h>
11 #define ETRAX_FS_rw_pa_dout 0
12 #define ETRAX_FS_r_pa_din 4
13 #define ETRAX_FS_rw_pa_oe 8
14 #define ETRAX_FS_rw_intr_cfg 12
15 #define ETRAX_FS_rw_intr_mask 16
16 #define ETRAX_FS_rw_ack_intr 20
17 #define ETRAX_FS_r_intr 24
18 #define ETRAX_FS_r_masked_intr 28
19 #define ETRAX_FS_rw_pb_dout 32
20 #define ETRAX_FS_r_pb_din 36
21 #define ETRAX_FS_rw_pb_oe 40
22 #define ETRAX_FS_rw_pc_dout 48
23 #define ETRAX_FS_r_pc_din 52
24 #define ETRAX_FS_rw_pc_oe 56
25 #define ETRAX_FS_rw_pd_dout 64
26 #define ETRAX_FS_r_pd_din 68
27 #define ETRAX_FS_rw_pd_oe 72
28 #define ETRAX_FS_rw_pe_dout 80
29 #define ETRAX_FS_r_pe_din 84
30 #define ETRAX_FS_rw_pe_oe 88
32 #define ARTPEC3_r_pa_din 0
33 #define ARTPEC3_rw_pa_dout 4
34 #define ARTPEC3_rw_pa_oe 8
35 #define ARTPEC3_r_pb_din 44
36 #define ARTPEC3_rw_pb_dout 48
37 #define ARTPEC3_rw_pb_oe 52
38 #define ARTPEC3_r_pc_din 88
39 #define ARTPEC3_rw_pc_dout 92
40 #define ARTPEC3_rw_pc_oe 96
41 #define ARTPEC3_r_pd_din 116
42 #define ARTPEC3_rw_intr_cfg 120
43 #define ARTPEC3_rw_intr_pins 124
44 #define ARTPEC3_rw_intr_mask 128
45 #define ARTPEC3_rw_ack_intr 132
46 #define ARTPEC3_r_masked_intr 140
52 #define GIO_CFG_POSEDGE 5
53 #define GIO_CFG_NEGEDGE 6
54 #define GIO_CFG_ANYEDGE 7
56 struct etraxfs_gpio_info;
58 struct etraxfs_gpio_block {
63 unsigned int group[8];
66 const struct etraxfs_gpio_info *info;
69 struct etraxfs_gpio_chip {
70 struct bgpio_chip bgc;
71 struct etraxfs_gpio_block *block;
74 struct etraxfs_gpio_port {
82 struct etraxfs_gpio_info {
83 unsigned int num_ports;
84 const struct etraxfs_gpio_port *ports;
86 unsigned int rw_ack_intr;
87 unsigned int rw_intr_mask;
88 unsigned int rw_intr_cfg;
89 unsigned int rw_intr_pins;
90 unsigned int r_masked_intr;
93 static const struct etraxfs_gpio_port etraxfs_gpio_etraxfs_ports[] = {
97 .oe = ETRAX_FS_rw_pa_oe,
98 .dout = ETRAX_FS_rw_pa_dout,
99 .din = ETRAX_FS_r_pa_din,
104 .oe = ETRAX_FS_rw_pb_oe,
105 .dout = ETRAX_FS_rw_pb_dout,
106 .din = ETRAX_FS_r_pb_din,
111 .oe = ETRAX_FS_rw_pc_oe,
112 .dout = ETRAX_FS_rw_pc_dout,
113 .din = ETRAX_FS_r_pc_din,
118 .oe = ETRAX_FS_rw_pd_oe,
119 .dout = ETRAX_FS_rw_pd_dout,
120 .din = ETRAX_FS_r_pd_din,
125 .oe = ETRAX_FS_rw_pe_oe,
126 .dout = ETRAX_FS_rw_pe_dout,
127 .din = ETRAX_FS_r_pe_din,
131 static const struct etraxfs_gpio_info etraxfs_gpio_etraxfs = {
132 .num_ports = ARRAY_SIZE(etraxfs_gpio_etraxfs_ports),
133 .ports = etraxfs_gpio_etraxfs_ports,
134 .rw_ack_intr = ETRAX_FS_rw_ack_intr,
135 .rw_intr_mask = ETRAX_FS_rw_intr_mask,
136 .rw_intr_cfg = ETRAX_FS_rw_intr_cfg,
137 .r_masked_intr = ETRAX_FS_r_masked_intr,
140 static const struct etraxfs_gpio_port etraxfs_gpio_artpec3_ports[] = {
144 .oe = ARTPEC3_rw_pa_oe,
145 .dout = ARTPEC3_rw_pa_dout,
146 .din = ARTPEC3_r_pa_din,
151 .oe = ARTPEC3_rw_pb_oe,
152 .dout = ARTPEC3_rw_pb_dout,
153 .din = ARTPEC3_r_pb_din,
158 .oe = ARTPEC3_rw_pc_oe,
159 .dout = ARTPEC3_rw_pc_dout,
160 .din = ARTPEC3_r_pc_din,
165 .din = ARTPEC3_r_pd_din,
169 static const struct etraxfs_gpio_info etraxfs_gpio_artpec3 = {
170 .num_ports = ARRAY_SIZE(etraxfs_gpio_artpec3_ports),
171 .ports = etraxfs_gpio_artpec3_ports,
172 .rw_ack_intr = ARTPEC3_rw_ack_intr,
173 .rw_intr_mask = ARTPEC3_rw_intr_mask,
174 .rw_intr_cfg = ARTPEC3_rw_intr_cfg,
175 .r_masked_intr = ARTPEC3_r_masked_intr,
176 .rw_intr_pins = ARTPEC3_rw_intr_pins,
179 static struct etraxfs_gpio_chip *to_etraxfs(struct gpio_chip *gc)
181 return container_of(gc, struct etraxfs_gpio_chip, bgc.gc);
184 static unsigned int etraxfs_gpio_chip_to_port(struct gpio_chip *gc)
186 return gc->label[0] - 'A';
189 static int etraxfs_gpio_of_xlate(struct gpio_chip *gc,
190 const struct of_phandle_args *gpiospec,
194 * Port numbers are A to E, and the properties are integers, so we
195 * specify them as 0xA - 0xE.
197 if (etraxfs_gpio_chip_to_port(gc) + 0xA != gpiospec->args[2])
200 return of_gpio_simple_xlate(gc, gpiospec, flags);
203 static const struct of_device_id etraxfs_gpio_of_table[] = {
205 .compatible = "axis,etraxfs-gio",
206 .data = &etraxfs_gpio_etraxfs,
209 .compatible = "axis,artpec3-gio",
210 .data = &etraxfs_gpio_artpec3,
215 static unsigned int etraxfs_gpio_to_group_irq(unsigned int gpio)
220 static unsigned int etraxfs_gpio_to_group_pin(struct etraxfs_gpio_chip *chip,
223 return 4 * etraxfs_gpio_chip_to_port(&chip->bgc.gc) + gpio / 8;
226 static void etraxfs_gpio_irq_ack(struct irq_data *d)
228 struct etraxfs_gpio_chip *chip =
229 to_etraxfs(irq_data_get_irq_chip_data(d));
230 struct etraxfs_gpio_block *block = chip->block;
231 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
233 writel(BIT(grpirq), block->regs + block->info->rw_ack_intr);
236 static void etraxfs_gpio_irq_mask(struct irq_data *d)
238 struct etraxfs_gpio_chip *chip =
239 to_etraxfs(irq_data_get_irq_chip_data(d));
240 struct etraxfs_gpio_block *block = chip->block;
241 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
243 spin_lock(&block->lock);
244 block->mask &= ~BIT(grpirq);
245 writel(block->mask, block->regs + block->info->rw_intr_mask);
246 spin_unlock(&block->lock);
249 static void etraxfs_gpio_irq_unmask(struct irq_data *d)
251 struct etraxfs_gpio_chip *chip =
252 to_etraxfs(irq_data_get_irq_chip_data(d));
253 struct etraxfs_gpio_block *block = chip->block;
254 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
256 spin_lock(&block->lock);
257 block->mask |= BIT(grpirq);
258 writel(block->mask, block->regs + block->info->rw_intr_mask);
259 spin_unlock(&block->lock);
262 static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type)
264 struct etraxfs_gpio_chip *chip =
265 to_etraxfs(irq_data_get_irq_chip_data(d));
266 struct etraxfs_gpio_block *block = chip->block;
267 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
271 case IRQ_TYPE_EDGE_RISING:
272 cfg = GIO_CFG_POSEDGE;
274 case IRQ_TYPE_EDGE_FALLING:
275 cfg = GIO_CFG_NEGEDGE;
277 case IRQ_TYPE_EDGE_BOTH:
278 cfg = GIO_CFG_ANYEDGE;
280 case IRQ_TYPE_LEVEL_LOW:
283 case IRQ_TYPE_LEVEL_HIGH:
290 spin_lock(&block->lock);
291 block->cfg &= ~(0x7 << (grpirq * 3));
292 block->cfg |= (cfg << (grpirq * 3));
293 writel(block->cfg, block->regs + block->info->rw_intr_cfg);
294 spin_unlock(&block->lock);
299 static int etraxfs_gpio_irq_request_resources(struct irq_data *d)
301 struct etraxfs_gpio_chip *chip =
302 to_etraxfs(irq_data_get_irq_chip_data(d));
303 struct etraxfs_gpio_block *block = chip->block;
304 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
307 spin_lock(&block->lock);
308 if (block->group[grpirq])
311 ret = gpiochip_lock_as_irq(&chip->bgc.gc, d->hwirq);
315 block->group[grpirq] = d->irq;
316 if (block->info->rw_intr_pins) {
317 unsigned int pin = etraxfs_gpio_to_group_pin(chip, d->hwirq);
319 block->pins &= ~(0xf << (grpirq * 4));
320 block->pins |= (pin << (grpirq * 4));
322 writel(block->pins, block->regs + block->info->rw_intr_pins);
326 spin_unlock(&block->lock);
330 static void etraxfs_gpio_irq_release_resources(struct irq_data *d)
332 struct etraxfs_gpio_chip *chip =
333 to_etraxfs(irq_data_get_irq_chip_data(d));
334 struct etraxfs_gpio_block *block = chip->block;
335 unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
337 spin_lock(&block->lock);
338 block->group[grpirq] = 0;
339 gpiochip_unlock_as_irq(&chip->bgc.gc, d->hwirq);
340 spin_unlock(&block->lock);
343 static struct irq_chip etraxfs_gpio_irq_chip = {
344 .name = "gpio-etraxfs",
345 .irq_ack = etraxfs_gpio_irq_ack,
346 .irq_mask = etraxfs_gpio_irq_mask,
347 .irq_unmask = etraxfs_gpio_irq_unmask,
348 .irq_set_type = etraxfs_gpio_irq_set_type,
349 .irq_request_resources = etraxfs_gpio_irq_request_resources,
350 .irq_release_resources = etraxfs_gpio_irq_release_resources,
353 static irqreturn_t etraxfs_gpio_interrupt(int irq, void *dev_id)
355 struct etraxfs_gpio_block *block = dev_id;
356 unsigned long intr = readl(block->regs + block->info->r_masked_intr);
359 for_each_set_bit(bit, &intr, 8)
360 generic_handle_irq(block->group[bit]);
362 return IRQ_RETVAL(intr & 0xff);
365 static int etraxfs_gpio_probe(struct platform_device *pdev)
367 struct device *dev = &pdev->dev;
368 const struct etraxfs_gpio_info *info;
369 const struct of_device_id *match;
370 struct etraxfs_gpio_block *block;
371 struct etraxfs_gpio_chip *chips;
372 struct resource *res, *irq;
373 bool allportsirq = false;
378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
379 regs = devm_ioremap_resource(dev, res);
381 return PTR_ERR(regs);
383 match = of_match_node(etraxfs_gpio_of_table, dev->of_node);
389 chips = devm_kzalloc(dev, sizeof(*chips) * info->num_ports, GFP_KERNEL);
393 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
397 block = devm_kzalloc(dev, sizeof(*block), GFP_KERNEL);
401 spin_lock_init(&block->lock);
406 writel(0, block->regs + info->rw_intr_mask);
407 writel(0, block->regs + info->rw_intr_cfg);
408 if (info->rw_intr_pins) {
410 writel(0, block->regs + info->rw_intr_pins);
413 ret = devm_request_irq(dev, irq->start, etraxfs_gpio_interrupt,
414 IRQF_SHARED, dev_name(dev), block);
416 dev_err(dev, "Unable to request irq %d\n", ret);
420 for (i = 0; i < info->num_ports; i++) {
421 struct etraxfs_gpio_chip *chip = &chips[i];
422 struct bgpio_chip *bgc = &chip->bgc;
423 const struct etraxfs_gpio_port *port = &info->ports[i];
424 unsigned long flags = BGPIOF_READ_OUTPUT_REG_SET;
425 void __iomem *dat = regs + port->din;
426 void __iomem *set = regs + port->dout;
427 void __iomem *dirout = regs + port->oe;
433 flags = BGPIOF_NO_OUTPUT;
436 ret = bgpio_init(bgc, dev, 4,
437 dat, set, NULL, dirout, NULL,
440 dev_err(dev, "Unable to init port %s\n",
445 bgc->gc.ngpio = port->ngpio;
446 bgc->gc.label = port->label;
448 bgc->gc.of_node = dev->of_node;
449 bgc->gc.of_gpio_n_cells = 3;
450 bgc->gc.of_xlate = etraxfs_gpio_of_xlate;
452 ret = gpiochip_add(&bgc->gc);
454 dev_err(dev, "Unable to register port %s\n",
459 if (i > 0 && !allportsirq)
462 ret = gpiochip_irqchip_add(&bgc->gc, &etraxfs_gpio_irq_chip, 0,
463 handle_level_irq, IRQ_TYPE_NONE);
465 dev_err(dev, "Unable to add irqchip to port %s\n",
473 static struct platform_driver etraxfs_gpio_driver = {
475 .name = "etraxfs-gpio",
476 .of_match_table = of_match_ptr(etraxfs_gpio_of_table),
478 .probe = etraxfs_gpio_probe,
481 static int __init etraxfs_gpio_init(void)
483 return platform_driver_register(&etraxfs_gpio_driver);
486 device_initcall(etraxfs_gpio_init);