~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/gpio/gpio-generic.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Generic driver for memory-mapped GPIO controllers.
 
3
 *
 
4
 * Copyright 2008 MontaVista Software, Inc.
 
5
 * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
 
6
 *
 
7
 * This program is free software; you can redistribute  it and/or modify it
 
8
 * under  the terms of  the GNU General  Public License as published by the
 
9
 * Free Software Foundation;  either version 2 of the  License, or (at your
 
10
 * option) any later version.
 
11
 *
 
12
 * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`.......
 
13
 * ...``                                                         ```````..
 
14
 * ..The simplest form of a GPIO controller that the driver supports is``
 
15
 *  `.just a single "data" register, where GPIO state can be read and/or `
 
16
 *    `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.```````
 
17
 *        `````````
 
18
                                    ___
 
19
_/~~|___/~|   . ```~~~~~~       ___/___\___     ,~.`.`.`.`````.~~...,,,,...
 
20
__________|~$@~~~        %~    /o*o*o*o*o*o\   .. Implementing such a GPIO .
 
21
o        `                     ~~~~\___/~~~~    ` controller in FPGA is ,.`
 
22
                                                 `....trivial..'~`.```.```
 
23
 *                                                    ```````
 
24
 *  .```````~~~~`..`.``.``.
 
25
 * .  The driver supports  `...       ,..```.`~~~```````````````....````.``,,
 
26
 * .   big-endian notation, just`.  .. A bit more sophisticated controllers ,
 
27
 *  . register the device with -be`. .with a pair of set/clear-bit registers ,
 
28
 *   `.. suffix.  ```~~`````....`.`   . affecting the data register and the .`
 
29
 *     ``.`.``...```                  ```.. output pins are also supported.`
 
30
 *                        ^^             `````.`````````.,``~``~``~~``````
 
31
 *                                                   .                  ^^
 
32
 *   ,..`.`.`...````````````......`.`.`.`.`.`..`.`.`..
 
33
 * .. The expectation is that in at least some cases .    ,-~~~-,
 
34
 *  .this will be used with roll-your-own ASIC/FPGA .`     \   /
 
35
 *  .logic in Verilog or VHDL. ~~~`````````..`````~~`       \ /
 
36
 *  ..````````......```````````                             \o_
 
37
 *                                                           |
 
38
 *                              ^^                          / \
 
39
 *
 
40
 *           ...`````~~`.....``.`..........``````.`.``.```........``.
 
41
 *            `  8, 16, 32 and 64 bits registers are supported, and``.
 
42
 *            . the number of GPIOs is determined by the width of   ~
 
43
 *             .. the registers. ,............```.`.`..`.`.~~~.`.`.`~
 
44
 *               `.......````.```
 
45
 */
 
46
 
 
47
#include <linux/init.h>
 
48
#include <linux/err.h>
 
49
#include <linux/bug.h>
 
50
#include <linux/kernel.h>
 
51
#include <linux/module.h>
 
52
#include <linux/spinlock.h>
 
53
#include <linux/compiler.h>
 
54
#include <linux/types.h>
 
55
#include <linux/errno.h>
 
56
#include <linux/log2.h>
 
57
#include <linux/ioport.h>
 
58
#include <linux/io.h>
 
59
#include <linux/gpio.h>
 
60
#include <linux/slab.h>
 
61
#include <linux/platform_device.h>
 
62
#include <linux/mod_devicetable.h>
 
63
#include <linux/basic_mmio_gpio.h>
 
64
 
 
65
static void bgpio_write8(void __iomem *reg, unsigned long data)
 
66
{
 
67
        writeb(data, reg);
 
68
}
 
69
 
 
70
static unsigned long bgpio_read8(void __iomem *reg)
 
71
{
 
72
        return readb(reg);
 
73
}
 
74
 
 
75
static void bgpio_write16(void __iomem *reg, unsigned long data)
 
76
{
 
77
        writew(data, reg);
 
78
}
 
79
 
 
80
static unsigned long bgpio_read16(void __iomem *reg)
 
81
{
 
82
        return readw(reg);
 
83
}
 
84
 
 
85
static void bgpio_write32(void __iomem *reg, unsigned long data)
 
86
{
 
87
        writel(data, reg);
 
88
}
 
89
 
 
90
static unsigned long bgpio_read32(void __iomem *reg)
 
91
{
 
92
        return readl(reg);
 
93
}
 
94
 
 
95
#if BITS_PER_LONG >= 64
 
96
static void bgpio_write64(void __iomem *reg, unsigned long data)
 
97
{
 
98
        writeq(data, reg);
 
99
}
 
100
 
 
101
static unsigned long bgpio_read64(void __iomem *reg)
 
102
{
 
103
        return readq(reg);
 
104
}
 
105
#endif /* BITS_PER_LONG >= 64 */
 
106
 
 
107
static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin)
 
108
{
 
109
        return 1 << pin;
 
110
}
 
111
 
 
112
static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc,
 
113
                                       unsigned int pin)
 
114
{
 
115
        return 1 << (bgc->bits - 1 - pin);
 
116
}
 
117
 
 
118
static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
 
119
{
 
120
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
121
 
 
122
        return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio);
 
123
}
 
124
 
 
125
static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 
126
{
 
127
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
128
        unsigned long mask = bgc->pin2mask(bgc, gpio);
 
129
        unsigned long flags;
 
130
 
 
131
        spin_lock_irqsave(&bgc->lock, flags);
 
132
 
 
133
        if (val)
 
134
                bgc->data |= mask;
 
135
        else
 
136
                bgc->data &= ~mask;
 
137
 
 
138
        bgc->write_reg(bgc->reg_dat, bgc->data);
 
139
 
 
140
        spin_unlock_irqrestore(&bgc->lock, flags);
 
141
}
 
142
 
 
143
static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
 
144
                                 int val)
 
145
{
 
146
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
147
        unsigned long mask = bgc->pin2mask(bgc, gpio);
 
148
 
 
149
        if (val)
 
150
                bgc->write_reg(bgc->reg_set, mask);
 
151
        else
 
152
                bgc->write_reg(bgc->reg_clr, mask);
 
153
}
 
154
 
 
155
static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
 
156
{
 
157
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
158
        unsigned long mask = bgc->pin2mask(bgc, gpio);
 
159
        unsigned long flags;
 
160
 
 
161
        spin_lock_irqsave(&bgc->lock, flags);
 
162
 
 
163
        if (val)
 
164
                bgc->data |= mask;
 
165
        else
 
166
                bgc->data &= ~mask;
 
167
 
 
168
        bgc->write_reg(bgc->reg_set, bgc->data);
 
169
 
 
170
        spin_unlock_irqrestore(&bgc->lock, flags);
 
171
}
 
172
 
 
173
static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
 
174
{
 
175
        return 0;
 
176
}
 
177
 
 
178
static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio,
 
179
                                int val)
 
180
{
 
181
        gc->set(gc, gpio, val);
 
182
 
 
183
        return 0;
 
184
}
 
185
 
 
186
static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 
187
{
 
188
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
189
        unsigned long flags;
 
190
 
 
191
        spin_lock_irqsave(&bgc->lock, flags);
 
192
 
 
193
        bgc->dir &= ~bgc->pin2mask(bgc, gpio);
 
194
        bgc->write_reg(bgc->reg_dir, bgc->dir);
 
195
 
 
196
        spin_unlock_irqrestore(&bgc->lock, flags);
 
197
 
 
198
        return 0;
 
199
}
 
200
 
 
201
static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 
202
{
 
203
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
204
        unsigned long flags;
 
205
 
 
206
        gc->set(gc, gpio, val);
 
207
 
 
208
        spin_lock_irqsave(&bgc->lock, flags);
 
209
 
 
210
        bgc->dir |= bgc->pin2mask(bgc, gpio);
 
211
        bgc->write_reg(bgc->reg_dir, bgc->dir);
 
212
 
 
213
        spin_unlock_irqrestore(&bgc->lock, flags);
 
214
 
 
215
        return 0;
 
216
}
 
217
 
 
218
static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
 
219
{
 
220
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
221
        unsigned long flags;
 
222
 
 
223
        spin_lock_irqsave(&bgc->lock, flags);
 
224
 
 
225
        bgc->dir |= bgc->pin2mask(bgc, gpio);
 
226
        bgc->write_reg(bgc->reg_dir, bgc->dir);
 
227
 
 
228
        spin_unlock_irqrestore(&bgc->lock, flags);
 
229
 
 
230
        return 0;
 
231
}
 
232
 
 
233
static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
 
234
{
 
235
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
236
        unsigned long flags;
 
237
 
 
238
        gc->set(gc, gpio, val);
 
239
 
 
240
        spin_lock_irqsave(&bgc->lock, flags);
 
241
 
 
242
        bgc->dir &= ~bgc->pin2mask(bgc, gpio);
 
243
        bgc->write_reg(bgc->reg_dir, bgc->dir);
 
244
 
 
245
        spin_unlock_irqrestore(&bgc->lock, flags);
 
246
 
 
247
        return 0;
 
248
}
 
249
 
 
250
static int bgpio_setup_accessors(struct device *dev,
 
251
                                 struct bgpio_chip *bgc,
 
252
                                 bool be)
 
253
{
 
254
 
 
255
        switch (bgc->bits) {
 
256
        case 8:
 
257
                bgc->read_reg   = bgpio_read8;
 
258
                bgc->write_reg  = bgpio_write8;
 
259
                break;
 
260
        case 16:
 
261
                bgc->read_reg   = bgpio_read16;
 
262
                bgc->write_reg  = bgpio_write16;
 
263
                break;
 
264
        case 32:
 
265
                bgc->read_reg   = bgpio_read32;
 
266
                bgc->write_reg  = bgpio_write32;
 
267
                break;
 
268
#if BITS_PER_LONG >= 64
 
269
        case 64:
 
270
                bgc->read_reg   = bgpio_read64;
 
271
                bgc->write_reg  = bgpio_write64;
 
272
                break;
 
273
#endif /* BITS_PER_LONG >= 64 */
 
274
        default:
 
275
                dev_err(dev, "unsupported data width %u bits\n", bgc->bits);
 
276
                return -EINVAL;
 
277
        }
 
278
 
 
279
        bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask;
 
280
 
 
281
        return 0;
 
282
}
 
283
 
 
284
/*
 
285
 * Create the device and allocate the resources.  For setting GPIO's there are
 
286
 * three supported configurations:
 
287
 *
 
288
 *      - single input/output register resource (named "dat").
 
289
 *      - set/clear pair (named "set" and "clr").
 
290
 *      - single output register resource and single input resource ("set" and
 
291
 *      dat").
 
292
 *
 
293
 * For the single output register, this drives a 1 by setting a bit and a zero
 
294
 * by clearing a bit.  For the set clr pair, this drives a 1 by setting a bit
 
295
 * in the set register and clears it by setting a bit in the clear register.
 
296
 * The configuration is detected by which resources are present.
 
297
 *
 
298
 * For setting the GPIO direction, there are three supported configurations:
 
299
 *
 
300
 *      - simple bidirection GPIO that requires no configuration.
 
301
 *      - an output direction register (named "dirout") where a 1 bit
 
302
 *      indicates the GPIO is an output.
 
303
 *      - an input direction register (named "dirin") where a 1 bit indicates
 
304
 *      the GPIO is an input.
 
305
 */
 
306
static int bgpio_setup_io(struct bgpio_chip *bgc,
 
307
                          void __iomem *dat,
 
308
                          void __iomem *set,
 
309
                          void __iomem *clr)
 
310
{
 
311
 
 
312
        bgc->reg_dat = dat;
 
313
        if (!bgc->reg_dat)
 
314
                return -EINVAL;
 
315
 
 
316
        if (set && clr) {
 
317
                bgc->reg_set = set;
 
318
                bgc->reg_clr = clr;
 
319
                bgc->gc.set = bgpio_set_with_clear;
 
320
        } else if (set && !clr) {
 
321
                bgc->reg_set = set;
 
322
                bgc->gc.set = bgpio_set_set;
 
323
        } else {
 
324
                bgc->gc.set = bgpio_set;
 
325
        }
 
326
 
 
327
        bgc->gc.get = bgpio_get;
 
328
 
 
329
        return 0;
 
330
}
 
331
 
 
332
static int bgpio_setup_direction(struct bgpio_chip *bgc,
 
333
                                 void __iomem *dirout,
 
334
                                 void __iomem *dirin)
 
335
{
 
336
        if (dirout && dirin) {
 
337
                return -EINVAL;
 
338
        } else if (dirout) {
 
339
                bgc->reg_dir = dirout;
 
340
                bgc->gc.direction_output = bgpio_dir_out;
 
341
                bgc->gc.direction_input = bgpio_dir_in;
 
342
        } else if (dirin) {
 
343
                bgc->reg_dir = dirin;
 
344
                bgc->gc.direction_output = bgpio_dir_out_inv;
 
345
                bgc->gc.direction_input = bgpio_dir_in_inv;
 
346
        } else {
 
347
                bgc->gc.direction_output = bgpio_simple_dir_out;
 
348
                bgc->gc.direction_input = bgpio_simple_dir_in;
 
349
        }
 
350
 
 
351
        return 0;
 
352
}
 
353
 
 
354
int bgpio_remove(struct bgpio_chip *bgc)
 
355
{
 
356
        int err = gpiochip_remove(&bgc->gc);
 
357
 
 
358
        kfree(bgc);
 
359
 
 
360
        return err;
 
361
}
 
362
EXPORT_SYMBOL_GPL(bgpio_remove);
 
363
 
 
364
int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
 
365
               unsigned long sz, void __iomem *dat, void __iomem *set,
 
366
               void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
 
367
               bool big_endian)
 
368
{
 
369
        int ret;
 
370
 
 
371
        if (!is_power_of_2(sz))
 
372
                return -EINVAL;
 
373
 
 
374
        bgc->bits = sz * 8;
 
375
        if (bgc->bits > BITS_PER_LONG)
 
376
                return -EINVAL;
 
377
 
 
378
        spin_lock_init(&bgc->lock);
 
379
        bgc->gc.dev = dev;
 
380
        bgc->gc.label = dev_name(dev);
 
381
        bgc->gc.base = -1;
 
382
        bgc->gc.ngpio = bgc->bits;
 
383
 
 
384
        ret = bgpio_setup_io(bgc, dat, set, clr);
 
385
        if (ret)
 
386
                return ret;
 
387
 
 
388
        ret = bgpio_setup_accessors(dev, bgc, big_endian);
 
389
        if (ret)
 
390
                return ret;
 
391
 
 
392
        ret = bgpio_setup_direction(bgc, dirout, dirin);
 
393
        if (ret)
 
394
                return ret;
 
395
 
 
396
        bgc->data = bgc->read_reg(bgc->reg_dat);
 
397
 
 
398
        return ret;
 
399
}
 
400
EXPORT_SYMBOL_GPL(bgpio_init);
 
401
 
 
402
#ifdef CONFIG_GPIO_GENERIC_PLATFORM
 
403
 
 
404
static void __iomem *bgpio_map(struct platform_device *pdev,
 
405
                               const char *name,
 
406
                               resource_size_t sane_sz,
 
407
                               int *err)
 
408
{
 
409
        struct device *dev = &pdev->dev;
 
410
        struct resource *r;
 
411
        resource_size_t start;
 
412
        resource_size_t sz;
 
413
        void __iomem *ret;
 
414
 
 
415
        *err = 0;
 
416
 
 
417
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 
418
        if (!r)
 
419
                return NULL;
 
420
 
 
421
        sz = resource_size(r);
 
422
        if (sz != sane_sz) {
 
423
                *err = -EINVAL;
 
424
                return NULL;
 
425
        }
 
426
 
 
427
        start = r->start;
 
428
        if (!devm_request_mem_region(dev, start, sz, r->name)) {
 
429
                *err = -EBUSY;
 
430
                return NULL;
 
431
        }
 
432
 
 
433
        ret = devm_ioremap(dev, start, sz);
 
434
        if (!ret) {
 
435
                *err = -ENOMEM;
 
436
                return NULL;
 
437
        }
 
438
 
 
439
        return ret;
 
440
}
 
441
 
 
442
static int __devinit bgpio_pdev_probe(struct platform_device *pdev)
 
443
{
 
444
        struct device *dev = &pdev->dev;
 
445
        struct resource *r;
 
446
        void __iomem *dat;
 
447
        void __iomem *set;
 
448
        void __iomem *clr;
 
449
        void __iomem *dirout;
 
450
        void __iomem *dirin;
 
451
        unsigned long sz;
 
452
        bool be;
 
453
        int err;
 
454
        struct bgpio_chip *bgc;
 
455
        struct bgpio_pdata *pdata = dev_get_platdata(dev);
 
456
 
 
457
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
 
458
        if (!r)
 
459
                return -EINVAL;
 
460
 
 
461
        sz = resource_size(r);
 
462
 
 
463
        dat = bgpio_map(pdev, "dat", sz, &err);
 
464
        if (!dat)
 
465
                return err ? err : -EINVAL;
 
466
 
 
467
        set = bgpio_map(pdev, "set", sz, &err);
 
468
        if (err)
 
469
                return err;
 
470
 
 
471
        clr = bgpio_map(pdev, "clr", sz, &err);
 
472
        if (err)
 
473
                return err;
 
474
 
 
475
        dirout = bgpio_map(pdev, "dirout", sz, &err);
 
476
        if (err)
 
477
                return err;
 
478
 
 
479
        dirin = bgpio_map(pdev, "dirin", sz, &err);
 
480
        if (err)
 
481
                return err;
 
482
 
 
483
        be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be");
 
484
 
 
485
        bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL);
 
486
        if (!bgc)
 
487
                return -ENOMEM;
 
488
 
 
489
        err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be);
 
490
        if (err)
 
491
                return err;
 
492
 
 
493
        if (pdata) {
 
494
                bgc->gc.base = pdata->base;
 
495
                if (pdata->ngpio > 0)
 
496
                        bgc->gc.ngpio = pdata->ngpio;
 
497
        }
 
498
 
 
499
        platform_set_drvdata(pdev, bgc);
 
500
 
 
501
        return gpiochip_add(&bgc->gc);
 
502
}
 
503
 
 
504
static int __devexit bgpio_pdev_remove(struct platform_device *pdev)
 
505
{
 
506
        struct bgpio_chip *bgc = platform_get_drvdata(pdev);
 
507
 
 
508
        return bgpio_remove(bgc);
 
509
}
 
510
 
 
511
static const struct platform_device_id bgpio_id_table[] = {
 
512
        { "basic-mmio-gpio", },
 
513
        { "basic-mmio-gpio-be", },
 
514
        {},
 
515
};
 
516
MODULE_DEVICE_TABLE(platform, bgpio_id_table);
 
517
 
 
518
static struct platform_driver bgpio_driver = {
 
519
        .driver = {
 
520
                .name = "basic-mmio-gpio",
 
521
        },
 
522
        .id_table = bgpio_id_table,
 
523
        .probe = bgpio_pdev_probe,
 
524
        .remove = __devexit_p(bgpio_pdev_remove),
 
525
};
 
526
 
 
527
static int __init bgpio_platform_init(void)
 
528
{
 
529
        return platform_driver_register(&bgpio_driver);
 
530
}
 
531
module_init(bgpio_platform_init);
 
532
 
 
533
static void __exit bgpio_platform_exit(void)
 
534
{
 
535
        platform_driver_unregister(&bgpio_driver);
 
536
}
 
537
module_exit(bgpio_platform_exit);
 
538
 
 
539
#endif /* CONFIG_GPIO_GENERIC_PLATFORM */
 
540
 
 
541
MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
 
542
MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
 
543
MODULE_LICENSE("GPL");