Merge branch 'rcu/next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck...
[cascardo/linux.git] / drivers / gpio / cs5535-gpio.c
1 /*
2  * AMD CS5535/CS5536 GPIO driver
3  * Copyright (C) 2006  Advanced Micro Devices, Inc.
4  * Copyright (C) 2007-2009  Andres Salomon <dilinger@collabora.co.uk>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public License
8  * as published by the Free Software Foundation.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/gpio.h>
16 #include <linux/io.h>
17 #include <linux/cs5535.h>
18
19 #define DRV_NAME "cs5535-gpio"
20 #define GPIO_BAR 1
21
22 /*
23  * Some GPIO pins
24  *  31-29,23 : reserved (always mask out)
25  *  28       : Power Button
26  *  26       : PME#
27  *  22-16    : LPC
28  *  14,15    : SMBus
29  *  9,8      : UART1
30  *  7        : PCI INTB
31  *  3,4      : UART2/DDC
32  *  2        : IDE_IRQ0
33  *  1        : AC_BEEP
34  *  0        : PCI INTA
35  *
36  * If a mask was not specified, allow all except
37  * reserved and Power Button
38  */
39 #define GPIO_DEFAULT_MASK 0x0F7FFFFF
40
41 static ulong mask = GPIO_DEFAULT_MASK;
42 module_param_named(mask, mask, ulong, 0444);
43 MODULE_PARM_DESC(mask, "GPIO channel mask.");
44
45 static struct cs5535_gpio_chip {
46         struct gpio_chip chip;
47         resource_size_t base;
48
49         struct pci_dev *pdev;
50         spinlock_t lock;
51 } cs5535_gpio_chip;
52
53 /*
54  * The CS5535/CS5536 GPIOs support a number of extra features not defined
55  * by the gpio_chip API, so these are exported.  For a full list of the
56  * registers, see include/linux/cs5535.h.
57  */
58
59 static void errata_outl(u32 val, unsigned long addr)
60 {
61         /*
62          * According to the CS5536 errata (#36), after suspend
63          * a write to the high bank GPIO register will clear all
64          * non-selected bits; the recommended workaround is a
65          * read-modify-write operation.
66          */
67         val |= inl(addr);
68         outl(val, addr);
69 }
70
71 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
72                 unsigned int reg)
73 {
74         if (offset < 16)
75                 /* low bank register */
76                 outl(1 << offset, chip->base + reg);
77         else
78                 /* high bank register */
79                 errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
80 }
81
82 void cs5535_gpio_set(unsigned offset, unsigned int reg)
83 {
84         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
85         unsigned long flags;
86
87         spin_lock_irqsave(&chip->lock, flags);
88         __cs5535_gpio_set(chip, offset, reg);
89         spin_unlock_irqrestore(&chip->lock, flags);
90 }
91 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
92
93 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
94                 unsigned int reg)
95 {
96         if (offset < 16)
97                 /* low bank register */
98                 outl(1 << (offset + 16), chip->base + reg);
99         else
100                 /* high bank register */
101                 errata_outl(1 << offset, chip->base + 0x80 + reg);
102 }
103
104 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
105 {
106         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
107         unsigned long flags;
108
109         spin_lock_irqsave(&chip->lock, flags);
110         __cs5535_gpio_clear(chip, offset, reg);
111         spin_unlock_irqrestore(&chip->lock, flags);
112 }
113 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
114
115 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
116 {
117         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
118         unsigned long flags;
119         long val;
120
121         spin_lock_irqsave(&chip->lock, flags);
122         if (offset < 16)
123                 /* low bank register */
124                 val = inl(chip->base + reg);
125         else {
126                 /* high bank register */
127                 val = inl(chip->base + 0x80 + reg);
128                 offset -= 16;
129         }
130         spin_unlock_irqrestore(&chip->lock, flags);
131
132         return (val & (1 << offset)) ? 1 : 0;
133 }
134 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
135
136 /*
137  * Generic gpio_chip API support.
138  */
139
140 static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
141 {
142         struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
143         unsigned long flags;
144
145         spin_lock_irqsave(&chip->lock, flags);
146
147         /* check if this pin is available */
148         if ((mask & (1 << offset)) == 0) {
149                 dev_info(&chip->pdev->dev,
150                         "pin %u is not available (check mask)\n", offset);
151                 spin_unlock_irqrestore(&chip->lock, flags);
152                 return -EINVAL;
153         }
154
155         /* disable output aux 1 & 2 on this pin */
156         __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
157         __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
158
159         /* disable input aux 1 on this pin */
160         __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
161
162         spin_unlock_irqrestore(&chip->lock, flags);
163
164         return 0;
165 }
166
167 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
168 {
169         return cs5535_gpio_isset(offset, GPIO_READ_BACK);
170 }
171
172 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
173 {
174         if (val)
175                 cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
176         else
177                 cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
178 }
179
180 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
181 {
182         struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
183         unsigned long flags;
184
185         spin_lock_irqsave(&chip->lock, flags);
186         __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
187         __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
188         spin_unlock_irqrestore(&chip->lock, flags);
189
190         return 0;
191 }
192
193 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
194 {
195         struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
196         unsigned long flags;
197
198         spin_lock_irqsave(&chip->lock, flags);
199
200         __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
201         __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
202         if (val)
203                 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
204         else
205                 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
206
207         spin_unlock_irqrestore(&chip->lock, flags);
208
209         return 0;
210 }
211
212 static const char * const cs5535_gpio_names[] = {
213         "GPIO0", "GPIO1", "GPIO2", "GPIO3",
214         "GPIO4", "GPIO5", "GPIO6", "GPIO7",
215         "GPIO8", "GPIO9", "GPIO10", "GPIO11",
216         "GPIO12", "GPIO13", "GPIO14", "GPIO15",
217         "GPIO16", "GPIO17", "GPIO18", "GPIO19",
218         "GPIO20", "GPIO21", "GPIO22", NULL,
219         "GPIO24", "GPIO25", "GPIO26", "GPIO27",
220         "GPIO28", NULL, NULL, NULL,
221 };
222
223 static struct cs5535_gpio_chip cs5535_gpio_chip = {
224         .chip = {
225                 .owner = THIS_MODULE,
226                 .label = DRV_NAME,
227
228                 .base = 0,
229                 .ngpio = 32,
230                 .names = cs5535_gpio_names,
231                 .request = chip_gpio_request,
232
233                 .get = chip_gpio_get,
234                 .set = chip_gpio_set,
235
236                 .direction_input = chip_direction_input,
237                 .direction_output = chip_direction_output,
238         },
239 };
240
241 static int __init cs5535_gpio_probe(struct pci_dev *pdev,
242                 const struct pci_device_id *pci_id)
243 {
244         int err;
245         ulong mask_orig = mask;
246
247         /* There are two ways to get the GPIO base address; one is by
248          * fetching it from MSR_LBAR_GPIO, the other is by reading the
249          * PCI BAR info.  The latter method is easier (especially across
250          * different architectures), so we'll stick with that for now.  If
251          * it turns out to be unreliable in the face of crappy BIOSes, we
252          * can always go back to using MSRs.. */
253
254         err = pci_enable_device_io(pdev);
255         if (err) {
256                 dev_err(&pdev->dev, "can't enable device IO\n");
257                 goto done;
258         }
259
260         err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
261         if (err) {
262                 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
263                 goto done;
264         }
265
266         /* set up the driver-specific struct */
267         cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
268         cs5535_gpio_chip.pdev = pdev;
269         spin_lock_init(&cs5535_gpio_chip.lock);
270
271         dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
272                         (unsigned long long) cs5535_gpio_chip.base);
273
274         /* mask out reserved pins */
275         mask &= 0x1F7FFFFF;
276
277         /* do not allow pin 28, Power Button, as there's special handling
278          * in the PMC needed. (note 12, p. 48) */
279         mask &= ~(1 << 28);
280
281         if (mask_orig != mask)
282                 dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
283                                 mask_orig, mask);
284
285         /* finally, register with the generic GPIO API */
286         err = gpiochip_add(&cs5535_gpio_chip.chip);
287         if (err)
288                 goto release_region;
289
290         dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
291         return 0;
292
293 release_region:
294         pci_release_region(pdev, GPIO_BAR);
295 done:
296         return err;
297 }
298
299 static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
300 {
301         int err;
302
303         err = gpiochip_remove(&cs5535_gpio_chip.chip);
304         if (err) {
305                 /* uhh? */
306                 dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
307         }
308         pci_release_region(pdev, GPIO_BAR);
309 }
310
311 static struct pci_device_id cs5535_gpio_pci_tbl[] = {
312         { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
313         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
314         { 0, },
315 };
316 MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
317
318 /*
319  * We can't use the standard PCI driver registration stuff here, since
320  * that allows only one driver to bind to each PCI device (and we want
321  * multiple drivers to be able to bind to the device).  Instead, manually
322  * scan for the PCI device, request a single region, and keep track of the
323  * devices that we're using.
324  */
325
326 static int __init cs5535_gpio_scan_pci(void)
327 {
328         struct pci_dev *pdev;
329         int err = -ENODEV;
330         int i;
331
332         for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
333                 pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
334                                 cs5535_gpio_pci_tbl[i].device, NULL);
335                 if (pdev) {
336                         err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
337                         if (err)
338                                 pci_dev_put(pdev);
339
340                         /* we only support a single CS5535/6 southbridge */
341                         break;
342                 }
343         }
344
345         return err;
346 }
347
348 static void __exit cs5535_gpio_free_pci(void)
349 {
350         cs5535_gpio_remove(cs5535_gpio_chip.pdev);
351         pci_dev_put(cs5535_gpio_chip.pdev);
352 }
353
354 static int __init cs5535_gpio_init(void)
355 {
356         return cs5535_gpio_scan_pci();
357 }
358
359 static void __exit cs5535_gpio_exit(void)
360 {
361         cs5535_gpio_free_pci();
362 }
363
364 module_init(cs5535_gpio_init);
365 module_exit(cs5535_gpio_exit);
366
367 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
368 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
369 MODULE_LICENSE("GPL");