Merge tag 'pm+acpi-4.6-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-block.git] / drivers / gpio / gpio-ws16c48.c
1 /*
2  * GPIO driver for the WinSystems WS16C48
3  * Copyright (C) 2016 William Breathitt Gray
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License, version 2, as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14 #include <linux/bitops.h>
15 #include <linux/device.h>
16 #include <linux/errno.h>
17 #include <linux/gpio/driver.h>
18 #include <linux/io.h>
19 #include <linux/ioport.h>
20 #include <linux/interrupt.h>
21 #include <linux/irqdesc.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <linux/platform_device.h>
26 #include <linux/spinlock.h>
27
28 static unsigned ws16c48_base;
29 module_param(ws16c48_base, uint, 0);
30 MODULE_PARM_DESC(ws16c48_base, "WinSystems WS16C48 base address");
31 static unsigned ws16c48_irq;
32 module_param(ws16c48_irq, uint, 0);
33 MODULE_PARM_DESC(ws16c48_irq, "WinSystems WS16C48 interrupt line number");
34
35 /**
36  * struct ws16c48_gpio - GPIO device private data structure
37  * @chip:       instance of the gpio_chip
38  * @io_state:   bit I/O state (whether bit is set to input or output)
39  * @out_state:  output bits state
40  * @lock:       synchronization lock to prevent I/O race conditions
41  * @irq_mask:   I/O bits affected by interrupts
42  * @flow_mask:  IRQ flow type mask for the respective I/O bits
43  * @base:       base port address of the GPIO device
44  * @irq:        Interrupt line number
45  */
46 struct ws16c48_gpio {
47         struct gpio_chip chip;
48         unsigned char io_state[6];
49         unsigned char out_state[6];
50         spinlock_t lock;
51         unsigned long irq_mask;
52         unsigned long flow_mask;
53         unsigned base;
54         unsigned irq;
55 };
56
57 static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
58 {
59         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
60         const unsigned port = offset / 8;
61         const unsigned mask = BIT(offset % 8);
62
63         return !!(ws16c48gpio->io_state[port] & mask);
64 }
65
66 static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
67 {
68         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
69         const unsigned port = offset / 8;
70         const unsigned mask = BIT(offset % 8);
71         unsigned long flags;
72
73         spin_lock_irqsave(&ws16c48gpio->lock, flags);
74
75         ws16c48gpio->io_state[port] |= mask;
76         ws16c48gpio->out_state[port] &= ~mask;
77         outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
78
79         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
80
81         return 0;
82 }
83
84 static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
85         unsigned offset, int value)
86 {
87         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
88         const unsigned port = offset / 8;
89         const unsigned mask = BIT(offset % 8);
90         unsigned long flags;
91
92         spin_lock_irqsave(&ws16c48gpio->lock, flags);
93
94         ws16c48gpio->io_state[port] &= ~mask;
95         if (value)
96                 ws16c48gpio->out_state[port] |= mask;
97         else
98                 ws16c48gpio->out_state[port] &= ~mask;
99         outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
100
101         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
102
103         return 0;
104 }
105
106 static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
107 {
108         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
109         const unsigned port = offset / 8;
110         const unsigned mask = BIT(offset % 8);
111         unsigned long flags;
112         unsigned port_state;
113
114         spin_lock_irqsave(&ws16c48gpio->lock, flags);
115
116         /* ensure that GPIO is set for input */
117         if (!(ws16c48gpio->io_state[port] & mask)) {
118                 spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
119                 return -EINVAL;
120         }
121
122         port_state = inb(ws16c48gpio->base + port);
123
124         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
125
126         return !!(port_state & mask);
127 }
128
129 static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
130 {
131         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
132         const unsigned port = offset / 8;
133         const unsigned mask = BIT(offset % 8);
134         unsigned long flags;
135
136         spin_lock_irqsave(&ws16c48gpio->lock, flags);
137
138         /* ensure that GPIO is set for output */
139         if (ws16c48gpio->io_state[port] & mask) {
140                 spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
141                 return;
142         }
143
144         if (value)
145                 ws16c48gpio->out_state[port] |= mask;
146         else
147                 ws16c48gpio->out_state[port] &= ~mask;
148         outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
149
150         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
151 }
152
153 static void ws16c48_irq_ack(struct irq_data *data)
154 {
155         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
156         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
157         const unsigned long offset = irqd_to_hwirq(data);
158         const unsigned port = offset / 8;
159         const unsigned mask = BIT(offset % 8);
160         unsigned long flags;
161         unsigned port_state;
162
163         /* only the first 3 ports support interrupts */
164         if (port > 2)
165                 return;
166
167         spin_lock_irqsave(&ws16c48gpio->lock, flags);
168
169         port_state = ws16c48gpio->irq_mask >> (8*port);
170
171         outb(0x80, ws16c48gpio->base + 7);
172         outb(port_state & ~mask, ws16c48gpio->base + 8 + port);
173         outb(port_state | mask, ws16c48gpio->base + 8 + port);
174         outb(0xC0, ws16c48gpio->base + 7);
175
176         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
177 }
178
179 static void ws16c48_irq_mask(struct irq_data *data)
180 {
181         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
182         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
183         const unsigned long offset = irqd_to_hwirq(data);
184         const unsigned long mask = BIT(offset);
185         const unsigned port = offset / 8;
186         unsigned long flags;
187
188         /* only the first 3 ports support interrupts */
189         if (port > 2)
190                 return;
191
192         spin_lock_irqsave(&ws16c48gpio->lock, flags);
193
194         ws16c48gpio->irq_mask &= ~mask;
195
196         outb(0x80, ws16c48gpio->base + 7);
197         outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
198         outb(0xC0, ws16c48gpio->base + 7);
199
200         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
201 }
202
203 static void ws16c48_irq_unmask(struct irq_data *data)
204 {
205         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
206         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
207         const unsigned long offset = irqd_to_hwirq(data);
208         const unsigned long mask = BIT(offset);
209         const unsigned port = offset / 8;
210         unsigned long flags;
211
212         /* only the first 3 ports support interrupts */
213         if (port > 2)
214                 return;
215
216         spin_lock_irqsave(&ws16c48gpio->lock, flags);
217
218         ws16c48gpio->irq_mask |= mask;
219
220         outb(0x80, ws16c48gpio->base + 7);
221         outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
222         outb(0xC0, ws16c48gpio->base + 7);
223
224         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
225 }
226
227 static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
228 {
229         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
230         struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
231         const unsigned long offset = irqd_to_hwirq(data);
232         const unsigned long mask = BIT(offset);
233         const unsigned port = offset / 8;
234         unsigned long flags;
235
236         /* only the first 3 ports support interrupts */
237         if (port > 2)
238                 return -EINVAL;
239
240         spin_lock_irqsave(&ws16c48gpio->lock, flags);
241
242         switch (flow_type) {
243         case IRQ_TYPE_NONE:
244                 break;
245         case IRQ_TYPE_EDGE_RISING:
246                 ws16c48gpio->flow_mask |= mask;
247                 break;
248         case IRQ_TYPE_EDGE_FALLING:
249                 ws16c48gpio->flow_mask &= ~mask;
250                 break;
251         default:
252                 spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
253                 return -EINVAL;
254         }
255
256         outb(0x40, ws16c48gpio->base + 7);
257         outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
258         outb(0xC0, ws16c48gpio->base + 7);
259
260         spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
261
262         return 0;
263 }
264
265 static struct irq_chip ws16c48_irqchip = {
266         .name = "ws16c48",
267         .irq_ack = ws16c48_irq_ack,
268         .irq_mask = ws16c48_irq_mask,
269         .irq_unmask = ws16c48_irq_unmask,
270         .irq_set_type = ws16c48_irq_set_type
271 };
272
273 static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
274 {
275         struct ws16c48_gpio *const ws16c48gpio = dev_id;
276         struct gpio_chip *const chip = &ws16c48gpio->chip;
277         unsigned long int_pending;
278         unsigned long port;
279         unsigned long int_id;
280         unsigned long gpio;
281
282         int_pending = inb(ws16c48gpio->base + 6) & 0x7;
283         if (!int_pending)
284                 return IRQ_NONE;
285
286         /* loop until all pending interrupts are handled */
287         do {
288                 for_each_set_bit(port, &int_pending, 3) {
289                         int_id = inb(ws16c48gpio->base + 8 + port);
290                         for_each_set_bit(gpio, &int_id, 8)
291                                 generic_handle_irq(irq_find_mapping(
292                                         chip->irqdomain, gpio + 8*port));
293                 }
294
295                 int_pending = inb(ws16c48gpio->base + 6) & 0x7;
296         } while (int_pending);
297
298         return IRQ_HANDLED;
299 }
300
301 static int __init ws16c48_probe(struct platform_device *pdev)
302 {
303         struct device *dev = &pdev->dev;
304         struct ws16c48_gpio *ws16c48gpio;
305         const unsigned base = ws16c48_base;
306         const unsigned extent = 16;
307         const char *const name = dev_name(dev);
308         int err;
309         const unsigned irq = ws16c48_irq;
310
311         ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL);
312         if (!ws16c48gpio)
313                 return -ENOMEM;
314
315         if (!devm_request_region(dev, base, extent, name)) {
316                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
317                         base, base + extent);
318                 return -EBUSY;
319         }
320
321         ws16c48gpio->chip.label = name;
322         ws16c48gpio->chip.parent = dev;
323         ws16c48gpio->chip.owner = THIS_MODULE;
324         ws16c48gpio->chip.base = -1;
325         ws16c48gpio->chip.ngpio = 48;
326         ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction;
327         ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input;
328         ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output;
329         ws16c48gpio->chip.get = ws16c48_gpio_get;
330         ws16c48gpio->chip.set = ws16c48_gpio_set;
331         ws16c48gpio->base = base;
332         ws16c48gpio->irq = irq;
333
334         spin_lock_init(&ws16c48gpio->lock);
335
336         dev_set_drvdata(dev, ws16c48gpio);
337
338         err = gpiochip_add_data(&ws16c48gpio->chip, ws16c48gpio);
339         if (err) {
340                 dev_err(dev, "GPIO registering failed (%d)\n", err);
341                 return err;
342         }
343
344         /* Disable IRQ by default */
345         outb(0x80, base + 7);
346         outb(0, base + 8);
347         outb(0, base + 9);
348         outb(0, base + 10);
349         outb(0xC0, base + 7);
350
351         err = gpiochip_irqchip_add(&ws16c48gpio->chip, &ws16c48_irqchip, 0,
352                 handle_edge_irq, IRQ_TYPE_NONE);
353         if (err) {
354                 dev_err(dev, "Could not add irqchip (%d)\n", err);
355                 goto err_gpiochip_remove;
356         }
357
358         err = request_irq(irq, ws16c48_irq_handler, IRQF_SHARED, name,
359                 ws16c48gpio);
360         if (err) {
361                 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
362                 goto err_gpiochip_remove;
363         }
364
365         return 0;
366
367 err_gpiochip_remove:
368         gpiochip_remove(&ws16c48gpio->chip);
369         return err;
370 }
371
372 static int ws16c48_remove(struct platform_device *pdev)
373 {
374         struct ws16c48_gpio *const ws16c48gpio = platform_get_drvdata(pdev);
375
376         free_irq(ws16c48gpio->irq, ws16c48gpio);
377         gpiochip_remove(&ws16c48gpio->chip);
378
379         return 0;
380 }
381
382 static struct platform_device *ws16c48_device;
383
384 static struct platform_driver ws16c48_driver = {
385         .driver = {
386                 .name = "ws16c48"
387         },
388         .remove = ws16c48_remove
389 };
390
391 static void __exit ws16c48_exit(void)
392 {
393         platform_device_unregister(ws16c48_device);
394         platform_driver_unregister(&ws16c48_driver);
395 }
396
397 static int __init ws16c48_init(void)
398 {
399         int err;
400
401         ws16c48_device = platform_device_alloc(ws16c48_driver.driver.name, -1);
402         if (!ws16c48_device)
403                 return -ENOMEM;
404
405         err = platform_device_add(ws16c48_device);
406         if (err)
407                 goto err_platform_device;
408
409         err = platform_driver_probe(&ws16c48_driver, ws16c48_probe);
410         if (err)
411                 goto err_platform_driver;
412
413         return 0;
414
415 err_platform_driver:
416         platform_device_del(ws16c48_device);
417 err_platform_device:
418         platform_device_put(ws16c48_device);
419         return err;
420 }
421
422 module_init(ws16c48_init);
423 module_exit(ws16c48_exit);
424
425 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
426 MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver");
427 MODULE_LICENSE("GPL v2");