1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * AMD CS5535/CS5536 GPIO driver
4*4882a593Smuzhiyun * Copyright (C) 2006 Advanced Micro Devices, Inc.
5*4882a593Smuzhiyun * Copyright (C) 2007-2009 Andres Salomon <dilinger@collabora.co.uk>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/spinlock.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/platform_device.h>
12*4882a593Smuzhiyun #include <linux/gpio/driver.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/cs5535.h>
15*4882a593Smuzhiyun #include <asm/msr.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define DRV_NAME "cs5535-gpio"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun * Some GPIO pins
21*4882a593Smuzhiyun * 31-29,23 : reserved (always mask out)
22*4882a593Smuzhiyun * 28 : Power Button
23*4882a593Smuzhiyun * 26 : PME#
24*4882a593Smuzhiyun * 22-16 : LPC
25*4882a593Smuzhiyun * 14,15 : SMBus
26*4882a593Smuzhiyun * 9,8 : UART1
27*4882a593Smuzhiyun * 7 : PCI INTB
28*4882a593Smuzhiyun * 3,4 : UART2/DDC
29*4882a593Smuzhiyun * 2 : IDE_IRQ0
30*4882a593Smuzhiyun * 1 : AC_BEEP
31*4882a593Smuzhiyun * 0 : PCI INTA
32*4882a593Smuzhiyun *
33*4882a593Smuzhiyun * If a mask was not specified, allow all except
34*4882a593Smuzhiyun * reserved and Power Button
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun #define GPIO_DEFAULT_MASK 0x0F7FFFFF
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun static ulong mask = GPIO_DEFAULT_MASK;
39*4882a593Smuzhiyun module_param_named(mask, mask, ulong, 0444);
40*4882a593Smuzhiyun MODULE_PARM_DESC(mask, "GPIO channel mask.");
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun * FIXME: convert this singleton driver to use the state container
44*4882a593Smuzhiyun * design pattern, see Documentation/driver-api/driver-model/design-patterns.rst
45*4882a593Smuzhiyun */
46*4882a593Smuzhiyun static struct cs5535_gpio_chip {
47*4882a593Smuzhiyun struct gpio_chip chip;
48*4882a593Smuzhiyun resource_size_t base;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun struct platform_device *pdev;
51*4882a593Smuzhiyun spinlock_t lock;
52*4882a593Smuzhiyun } cs5535_gpio_chip;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun * The CS5535/CS5536 GPIOs support a number of extra features not defined
56*4882a593Smuzhiyun * by the gpio_chip API, so these are exported. For a full list of the
57*4882a593Smuzhiyun * registers, see include/linux/cs5535.h.
58*4882a593Smuzhiyun */
59*4882a593Smuzhiyun
errata_outl(struct cs5535_gpio_chip * chip,u32 val,unsigned int reg)60*4882a593Smuzhiyun static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
61*4882a593Smuzhiyun unsigned int reg)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun unsigned long addr = chip->base + 0x80 + reg;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * According to the CS5536 errata (#36), after suspend
67*4882a593Smuzhiyun * a write to the high bank GPIO register will clear all
68*4882a593Smuzhiyun * non-selected bits; the recommended workaround is a
69*4882a593Smuzhiyun * read-modify-write operation.
70*4882a593Smuzhiyun *
71*4882a593Smuzhiyun * Don't apply this errata to the edge status GPIOs, as writing
72*4882a593Smuzhiyun * to their lower bits will clear them.
73*4882a593Smuzhiyun */
74*4882a593Smuzhiyun if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
75*4882a593Smuzhiyun if (val & 0xffff)
76*4882a593Smuzhiyun val |= (inl(addr) & 0xffff); /* ignore the high bits */
77*4882a593Smuzhiyun else
78*4882a593Smuzhiyun val |= (inl(addr) ^ (val >> 16));
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun outl(val, addr);
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
__cs5535_gpio_set(struct cs5535_gpio_chip * chip,unsigned offset,unsigned int reg)83*4882a593Smuzhiyun static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
84*4882a593Smuzhiyun unsigned int reg)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun if (offset < 16)
87*4882a593Smuzhiyun /* low bank register */
88*4882a593Smuzhiyun outl(1 << offset, chip->base + reg);
89*4882a593Smuzhiyun else
90*4882a593Smuzhiyun /* high bank register */
91*4882a593Smuzhiyun errata_outl(chip, 1 << (offset - 16), reg);
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun
cs5535_gpio_set(unsigned offset,unsigned int reg)94*4882a593Smuzhiyun void cs5535_gpio_set(unsigned offset, unsigned int reg)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
97*4882a593Smuzhiyun unsigned long flags;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
100*4882a593Smuzhiyun __cs5535_gpio_set(chip, offset, reg);
101*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(cs5535_gpio_set);
104*4882a593Smuzhiyun
__cs5535_gpio_clear(struct cs5535_gpio_chip * chip,unsigned offset,unsigned int reg)105*4882a593Smuzhiyun static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
106*4882a593Smuzhiyun unsigned int reg)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun if (offset < 16)
109*4882a593Smuzhiyun /* low bank register */
110*4882a593Smuzhiyun outl(1 << (offset + 16), chip->base + reg);
111*4882a593Smuzhiyun else
112*4882a593Smuzhiyun /* high bank register */
113*4882a593Smuzhiyun errata_outl(chip, 1 << offset, reg);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
cs5535_gpio_clear(unsigned offset,unsigned int reg)116*4882a593Smuzhiyun void cs5535_gpio_clear(unsigned offset, unsigned int reg)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
119*4882a593Smuzhiyun unsigned long flags;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
122*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, reg);
123*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
126*4882a593Smuzhiyun
cs5535_gpio_isset(unsigned offset,unsigned int reg)127*4882a593Smuzhiyun int cs5535_gpio_isset(unsigned offset, unsigned int reg)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
130*4882a593Smuzhiyun unsigned long flags;
131*4882a593Smuzhiyun long val;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
134*4882a593Smuzhiyun if (offset < 16)
135*4882a593Smuzhiyun /* low bank register */
136*4882a593Smuzhiyun val = inl(chip->base + reg);
137*4882a593Smuzhiyun else {
138*4882a593Smuzhiyun /* high bank register */
139*4882a593Smuzhiyun val = inl(chip->base + 0x80 + reg);
140*4882a593Smuzhiyun offset -= 16;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun return (val & (1 << offset)) ? 1 : 0;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
147*4882a593Smuzhiyun
cs5535_gpio_set_irq(unsigned group,unsigned irq)148*4882a593Smuzhiyun int cs5535_gpio_set_irq(unsigned group, unsigned irq)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun uint32_t lo, hi;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (group > 7 || irq > 15)
153*4882a593Smuzhiyun return -EINVAL;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun lo &= ~(0xF << (group * 4));
158*4882a593Smuzhiyun lo |= (irq & 0xF) << (group * 4);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
161*4882a593Smuzhiyun return 0;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq);
164*4882a593Smuzhiyun
cs5535_gpio_setup_event(unsigned offset,int pair,int pme)165*4882a593Smuzhiyun void cs5535_gpio_setup_event(unsigned offset, int pair, int pme)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
168*4882a593Smuzhiyun uint32_t shift = (offset % 8) * 4;
169*4882a593Smuzhiyun unsigned long flags;
170*4882a593Smuzhiyun uint32_t val;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (offset >= 24)
173*4882a593Smuzhiyun offset = GPIO_MAP_W;
174*4882a593Smuzhiyun else if (offset >= 16)
175*4882a593Smuzhiyun offset = GPIO_MAP_Z;
176*4882a593Smuzhiyun else if (offset >= 8)
177*4882a593Smuzhiyun offset = GPIO_MAP_Y;
178*4882a593Smuzhiyun else
179*4882a593Smuzhiyun offset = GPIO_MAP_X;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
182*4882a593Smuzhiyun val = inl(chip->base + offset);
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* Clear whatever was there before */
185*4882a593Smuzhiyun val &= ~(0xF << shift);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun /* Set the new value */
188*4882a593Smuzhiyun val |= ((pair & 7) << shift);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* Set the PME bit if this is a PME event */
191*4882a593Smuzhiyun if (pme)
192*4882a593Smuzhiyun val |= (1 << (shift + 3));
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun outl(val, chip->base + offset);
195*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /*
200*4882a593Smuzhiyun * Generic gpio_chip API support.
201*4882a593Smuzhiyun */
202*4882a593Smuzhiyun
chip_gpio_request(struct gpio_chip * c,unsigned offset)203*4882a593Smuzhiyun static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
206*4882a593Smuzhiyun unsigned long flags;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /* check if this pin is available */
211*4882a593Smuzhiyun if ((mask & (1 << offset)) == 0) {
212*4882a593Smuzhiyun dev_info(&chip->pdev->dev,
213*4882a593Smuzhiyun "pin %u is not available (check mask)\n", offset);
214*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
215*4882a593Smuzhiyun return -EINVAL;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* disable output aux 1 & 2 on this pin */
219*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
220*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* disable input aux 1 on this pin */
223*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun return 0;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
chip_gpio_get(struct gpio_chip * chip,unsigned offset)230*4882a593Smuzhiyun static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun return cs5535_gpio_isset(offset, GPIO_READ_BACK);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
chip_gpio_set(struct gpio_chip * chip,unsigned offset,int val)235*4882a593Smuzhiyun static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun if (val)
238*4882a593Smuzhiyun cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
239*4882a593Smuzhiyun else
240*4882a593Smuzhiyun cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
chip_direction_input(struct gpio_chip * c,unsigned offset)243*4882a593Smuzhiyun static int chip_direction_input(struct gpio_chip *c, unsigned offset)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
246*4882a593Smuzhiyun unsigned long flags;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
249*4882a593Smuzhiyun __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
250*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
251*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun return 0;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
chip_direction_output(struct gpio_chip * c,unsigned offset,int val)256*4882a593Smuzhiyun static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
259*4882a593Smuzhiyun unsigned long flags;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun spin_lock_irqsave(&chip->lock, flags);
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
264*4882a593Smuzhiyun __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
265*4882a593Smuzhiyun if (val)
266*4882a593Smuzhiyun __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
267*4882a593Smuzhiyun else
268*4882a593Smuzhiyun __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->lock, flags);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun return 0;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun static const char * const cs5535_gpio_names[] = {
276*4882a593Smuzhiyun "GPIO0", "GPIO1", "GPIO2", "GPIO3",
277*4882a593Smuzhiyun "GPIO4", "GPIO5", "GPIO6", "GPIO7",
278*4882a593Smuzhiyun "GPIO8", "GPIO9", "GPIO10", "GPIO11",
279*4882a593Smuzhiyun "GPIO12", "GPIO13", "GPIO14", "GPIO15",
280*4882a593Smuzhiyun "GPIO16", "GPIO17", "GPIO18", "GPIO19",
281*4882a593Smuzhiyun "GPIO20", "GPIO21", "GPIO22", NULL,
282*4882a593Smuzhiyun "GPIO24", "GPIO25", "GPIO26", "GPIO27",
283*4882a593Smuzhiyun "GPIO28", NULL, NULL, NULL,
284*4882a593Smuzhiyun };
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun static struct cs5535_gpio_chip cs5535_gpio_chip = {
287*4882a593Smuzhiyun .chip = {
288*4882a593Smuzhiyun .owner = THIS_MODULE,
289*4882a593Smuzhiyun .label = DRV_NAME,
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun .base = 0,
292*4882a593Smuzhiyun .ngpio = 32,
293*4882a593Smuzhiyun .names = cs5535_gpio_names,
294*4882a593Smuzhiyun .request = chip_gpio_request,
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun .get = chip_gpio_get,
297*4882a593Smuzhiyun .set = chip_gpio_set,
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun .direction_input = chip_direction_input,
300*4882a593Smuzhiyun .direction_output = chip_direction_output,
301*4882a593Smuzhiyun },
302*4882a593Smuzhiyun };
303*4882a593Smuzhiyun
cs5535_gpio_probe(struct platform_device * pdev)304*4882a593Smuzhiyun static int cs5535_gpio_probe(struct platform_device *pdev)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun struct resource *res;
307*4882a593Smuzhiyun int err = -EIO;
308*4882a593Smuzhiyun ulong mask_orig = mask;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* There are two ways to get the GPIO base address; one is by
311*4882a593Smuzhiyun * fetching it from MSR_LBAR_GPIO, the other is by reading the
312*4882a593Smuzhiyun * PCI BAR info. The latter method is easier (especially across
313*4882a593Smuzhiyun * different architectures), so we'll stick with that for now. If
314*4882a593Smuzhiyun * it turns out to be unreliable in the face of crappy BIOSes, we
315*4882a593Smuzhiyun * can always go back to using MSRs.. */
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_IO, 0);
318*4882a593Smuzhiyun if (!res) {
319*4882a593Smuzhiyun dev_err(&pdev->dev, "can't fetch device resource info\n");
320*4882a593Smuzhiyun return err;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
324*4882a593Smuzhiyun pdev->name)) {
325*4882a593Smuzhiyun dev_err(&pdev->dev, "can't request region\n");
326*4882a593Smuzhiyun return err;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun /* set up the driver-specific struct */
330*4882a593Smuzhiyun cs5535_gpio_chip.base = res->start;
331*4882a593Smuzhiyun cs5535_gpio_chip.pdev = pdev;
332*4882a593Smuzhiyun spin_lock_init(&cs5535_gpio_chip.lock);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun dev_info(&pdev->dev, "reserved resource region %pR\n", res);
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* mask out reserved pins */
337*4882a593Smuzhiyun mask &= 0x1F7FFFFF;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /* do not allow pin 28, Power Button, as there's special handling
340*4882a593Smuzhiyun * in the PMC needed. (note 12, p. 48) */
341*4882a593Smuzhiyun mask &= ~(1 << 28);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun if (mask_orig != mask)
344*4882a593Smuzhiyun dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
345*4882a593Smuzhiyun mask_orig, mask);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun /* finally, register with the generic GPIO API */
348*4882a593Smuzhiyun err = devm_gpiochip_add_data(&pdev->dev, &cs5535_gpio_chip.chip,
349*4882a593Smuzhiyun &cs5535_gpio_chip);
350*4882a593Smuzhiyun if (err)
351*4882a593Smuzhiyun return err;
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun return 0;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun static struct platform_driver cs5535_gpio_driver = {
357*4882a593Smuzhiyun .driver = {
358*4882a593Smuzhiyun .name = DRV_NAME,
359*4882a593Smuzhiyun },
360*4882a593Smuzhiyun .probe = cs5535_gpio_probe,
361*4882a593Smuzhiyun };
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun module_platform_driver(cs5535_gpio_driver);
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
366*4882a593Smuzhiyun MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
367*4882a593Smuzhiyun MODULE_LICENSE("GPL");
368*4882a593Smuzhiyun MODULE_ALIAS("platform:" DRV_NAME);
369