Merge tag 'irqchip-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm...
[linux-2.6-microblaze.git] / drivers / gpio / gpio-104-idi-48.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the ACCES 104-IDI-48 family
4  * Copyright (C) 2015 William Breathitt Gray
5  *
6  * This driver supports the following ACCES devices: 104-IDI-48A,
7  * 104-IDI-48AC, 104-IDI-48B, and 104-IDI-48BC.
8  */
9 #include <linux/bitmap.h>
10 #include <linux/bitops.h>
11 #include <linux/device.h>
12 #include <linux/errno.h>
13 #include <linux/gpio/driver.h>
14 #include <linux/io.h>
15 #include <linux/ioport.h>
16 #include <linux/interrupt.h>
17 #include <linux/irqdesc.h>
18 #include <linux/isa.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/spinlock.h>
23
24 #define IDI_48_EXTENT 8
25 #define MAX_NUM_IDI_48 max_num_isa_dev(IDI_48_EXTENT)
26
27 static unsigned int base[MAX_NUM_IDI_48];
28 static unsigned int num_idi_48;
29 module_param_hw_array(base, uint, ioport, &num_idi_48, 0);
30 MODULE_PARM_DESC(base, "ACCES 104-IDI-48 base addresses");
31
32 static unsigned int irq[MAX_NUM_IDI_48];
33 module_param_hw_array(irq, uint, irq, NULL, 0);
34 MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers");
35
36 /**
37  * struct idi_48_gpio - GPIO device private data structure
38  * @chip:       instance of the gpio_chip
39  * @lock:       synchronization lock to prevent I/O race conditions
40  * @ack_lock:   synchronization lock to prevent IRQ handler race conditions
41  * @irq_mask:   input bits affected by interrupts
42  * @base:       base port address of the GPIO device
43  * @cos_enb:    Change-Of-State IRQ enable boundaries mask
44  */
45 struct idi_48_gpio {
46         struct gpio_chip chip;
47         raw_spinlock_t lock;
48         spinlock_t ack_lock;
49         unsigned char irq_mask[6];
50         unsigned base;
51         unsigned char cos_enb;
52 };
53
54 static int idi_48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
55 {
56         return GPIO_LINE_DIRECTION_IN;
57 }
58
59 static int idi_48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
60 {
61         return 0;
62 }
63
64 static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
65 {
66         struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
67         unsigned i;
68         static const unsigned int register_offset[6] = { 0, 1, 2, 4, 5, 6 };
69         unsigned base_offset;
70         unsigned mask;
71
72         for (i = 0; i < 48; i += 8)
73                 if (offset < i + 8) {
74                         base_offset = register_offset[i / 8];
75                         mask = BIT(offset - i);
76
77                         return !!(inb(idi48gpio->base + base_offset) & mask);
78                 }
79
80         /* The following line should never execute since offset < 48 */
81         return 0;
82 }
83
84 static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
85         unsigned long *bits)
86 {
87         struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
88         unsigned long offset;
89         unsigned long gpio_mask;
90         static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
91         unsigned int port_addr;
92         unsigned long port_state;
93
94         /* clear bits array to a clean slate */
95         bitmap_zero(bits, chip->ngpio);
96
97         for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
98                 port_addr = idi48gpio->base + ports[offset / 8];
99                 port_state = inb(port_addr) & gpio_mask;
100
101                 bitmap_set_value8(bits, port_state, offset);
102         }
103
104         return 0;
105 }
106
107 static void idi_48_irq_ack(struct irq_data *data)
108 {
109 }
110
111 static void idi_48_irq_mask(struct irq_data *data)
112 {
113         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
114         struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
115         const unsigned offset = irqd_to_hwirq(data);
116         unsigned i;
117         unsigned mask;
118         unsigned boundary;
119         unsigned long flags;
120
121         for (i = 0; i < 48; i += 8)
122                 if (offset < i + 8) {
123                         mask = BIT(offset - i);
124                         boundary = i / 8;
125
126                         idi48gpio->irq_mask[boundary] &= ~mask;
127
128                         if (!idi48gpio->irq_mask[boundary]) {
129                                 idi48gpio->cos_enb &= ~BIT(boundary);
130
131                                 raw_spin_lock_irqsave(&idi48gpio->lock, flags);
132
133                                 outb(idi48gpio->cos_enb, idi48gpio->base + 7);
134
135                                 raw_spin_unlock_irqrestore(&idi48gpio->lock,
136                                                            flags);
137                         }
138
139                         return;
140                 }
141 }
142
143 static void idi_48_irq_unmask(struct irq_data *data)
144 {
145         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
146         struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
147         const unsigned offset = irqd_to_hwirq(data);
148         unsigned i;
149         unsigned mask;
150         unsigned boundary;
151         unsigned prev_irq_mask;
152         unsigned long flags;
153
154         for (i = 0; i < 48; i += 8)
155                 if (offset < i + 8) {
156                         mask = BIT(offset - i);
157                         boundary = i / 8;
158                         prev_irq_mask = idi48gpio->irq_mask[boundary];
159
160                         idi48gpio->irq_mask[boundary] |= mask;
161
162                         if (!prev_irq_mask) {
163                                 idi48gpio->cos_enb |= BIT(boundary);
164
165                                 raw_spin_lock_irqsave(&idi48gpio->lock, flags);
166
167                                 outb(idi48gpio->cos_enb, idi48gpio->base + 7);
168
169                                 raw_spin_unlock_irqrestore(&idi48gpio->lock,
170                                                            flags);
171                         }
172
173                         return;
174                 }
175 }
176
177 static int idi_48_irq_set_type(struct irq_data *data, unsigned flow_type)
178 {
179         /* The only valid irq types are none and both-edges */
180         if (flow_type != IRQ_TYPE_NONE &&
181                 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
182                 return -EINVAL;
183
184         return 0;
185 }
186
187 static struct irq_chip idi_48_irqchip = {
188         .name = "104-idi-48",
189         .irq_ack = idi_48_irq_ack,
190         .irq_mask = idi_48_irq_mask,
191         .irq_unmask = idi_48_irq_unmask,
192         .irq_set_type = idi_48_irq_set_type
193 };
194
195 static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
196 {
197         struct idi_48_gpio *const idi48gpio = dev_id;
198         unsigned long cos_status;
199         unsigned long boundary;
200         unsigned long irq_mask;
201         unsigned long bit_num;
202         unsigned long gpio;
203         struct gpio_chip *const chip = &idi48gpio->chip;
204
205         spin_lock(&idi48gpio->ack_lock);
206
207         raw_spin_lock(&idi48gpio->lock);
208
209         cos_status = inb(idi48gpio->base + 7);
210
211         raw_spin_unlock(&idi48gpio->lock);
212
213         /* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
214         if (cos_status & BIT(6)) {
215                 spin_unlock(&idi48gpio->ack_lock);
216                 return IRQ_NONE;
217         }
218
219         /* Bit 0-5 indicate which Change-Of-State boundary triggered the IRQ */
220         cos_status &= 0x3F;
221
222         for_each_set_bit(boundary, &cos_status, 6) {
223                 irq_mask = idi48gpio->irq_mask[boundary];
224
225                 for_each_set_bit(bit_num, &irq_mask, 8) {
226                         gpio = bit_num + boundary * 8;
227
228                         generic_handle_irq(irq_find_mapping(chip->irq.domain,
229                                 gpio));
230                 }
231         }
232
233         spin_unlock(&idi48gpio->ack_lock);
234
235         return IRQ_HANDLED;
236 }
237
238 #define IDI48_NGPIO 48
239 static const char *idi48_names[IDI48_NGPIO] = {
240         "Bit 0 A", "Bit 1 A", "Bit 2 A", "Bit 3 A", "Bit 4 A", "Bit 5 A",
241         "Bit 6 A", "Bit 7 A", "Bit 8 A", "Bit 9 A", "Bit 10 A", "Bit 11 A",
242         "Bit 12 A", "Bit 13 A", "Bit 14 A", "Bit 15 A", "Bit 16 A", "Bit 17 A",
243         "Bit 18 A", "Bit 19 A", "Bit 20 A", "Bit 21 A", "Bit 22 A", "Bit 23 A",
244         "Bit 0 B", "Bit 1 B", "Bit 2 B", "Bit 3 B", "Bit 4 B", "Bit 5 B",
245         "Bit 6 B", "Bit 7 B", "Bit 8 B", "Bit 9 B", "Bit 10 B", "Bit 11 B",
246         "Bit 12 B", "Bit 13 B", "Bit 14 B", "Bit 15 B", "Bit 16 B", "Bit 17 B",
247         "Bit 18 B", "Bit 19 B", "Bit 20 B", "Bit 21 B", "Bit 22 B", "Bit 23 B"
248 };
249
250 static int idi_48_irq_init_hw(struct gpio_chip *gc)
251 {
252         struct idi_48_gpio *const idi48gpio = gpiochip_get_data(gc);
253
254         /* Disable IRQ by default */
255         outb(0, idi48gpio->base + 7);
256         inb(idi48gpio->base + 7);
257
258         return 0;
259 }
260
261 static int idi_48_probe(struct device *dev, unsigned int id)
262 {
263         struct idi_48_gpio *idi48gpio;
264         const char *const name = dev_name(dev);
265         struct gpio_irq_chip *girq;
266         int err;
267
268         idi48gpio = devm_kzalloc(dev, sizeof(*idi48gpio), GFP_KERNEL);
269         if (!idi48gpio)
270                 return -ENOMEM;
271
272         if (!devm_request_region(dev, base[id], IDI_48_EXTENT, name)) {
273                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
274                         base[id], base[id] + IDI_48_EXTENT);
275                 return -EBUSY;
276         }
277
278         idi48gpio->chip.label = name;
279         idi48gpio->chip.parent = dev;
280         idi48gpio->chip.owner = THIS_MODULE;
281         idi48gpio->chip.base = -1;
282         idi48gpio->chip.ngpio = IDI48_NGPIO;
283         idi48gpio->chip.names = idi48_names;
284         idi48gpio->chip.get_direction = idi_48_gpio_get_direction;
285         idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
286         idi48gpio->chip.get = idi_48_gpio_get;
287         idi48gpio->chip.get_multiple = idi_48_gpio_get_multiple;
288         idi48gpio->base = base[id];
289
290         girq = &idi48gpio->chip.irq;
291         girq->chip = &idi_48_irqchip;
292         /* This will let us handle the parent IRQ in the driver */
293         girq->parent_handler = NULL;
294         girq->num_parents = 0;
295         girq->parents = NULL;
296         girq->default_type = IRQ_TYPE_NONE;
297         girq->handler = handle_edge_irq;
298         girq->init_hw = idi_48_irq_init_hw;
299
300         raw_spin_lock_init(&idi48gpio->lock);
301         spin_lock_init(&idi48gpio->ack_lock);
302
303         err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio);
304         if (err) {
305                 dev_err(dev, "GPIO registering failed (%d)\n", err);
306                 return err;
307         }
308
309         err = devm_request_irq(dev, irq[id], idi_48_irq_handler, IRQF_SHARED,
310                 name, idi48gpio);
311         if (err) {
312                 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
313                 return err;
314         }
315
316         return 0;
317 }
318
319 static struct isa_driver idi_48_driver = {
320         .probe = idi_48_probe,
321         .driver = {
322                 .name = "104-idi-48"
323         },
324 };
325 module_isa_driver(idi_48_driver, num_idi_48);
326
327 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
328 MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
329 MODULE_LICENSE("GPL v2");