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