gpio: grgpio: Add device driver for GRGPIO cores
[cascardo/linux.git] / drivers / gpio / gpio-grgpio.c
1 /*
2  * Driver for Aeroflex Gaisler GRGPIO General Purpose I/O cores.
3  *
4  * 2013 (c) Aeroflex Gaisler AB
5  *
6  * This driver supports the GRGPIO GPIO core available in the GRLIB VHDL
7  * IP core library.
8  *
9  * Full documentation of the GRGPIO core can be found here:
10  * http://www.gaisler.com/products/grlib/grip.pdf
11  *
12  * See "Documentation/devicetree/bindings/gpio/gpio-grgpio.txt" for
13  * information on open firmware properties.
14  *
15  * This program is free software; you can redistribute it and/or modify it
16  * under the terms of the GNU General Public License as published by the
17  * Free Software Foundation; either version 2 of the License, or (at your
18  * option) any later version.
19  *
20  * Contributors: Andreas Larsson <andreas@gaisler.com>
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/spinlock.h>
27 #include <linux/io.h>
28 #include <linux/of.h>
29 #include <linux/of_gpio.h>
30 #include <linux/of_platform.h>
31 #include <linux/gpio.h>
32 #include <linux/slab.h>
33 #include <linux/err.h>
34 #include <linux/basic_mmio_gpio.h>
35
36 #define GRGPIO_MAX_NGPIO 32
37
38 #define GRGPIO_DATA             0x00
39 #define GRGPIO_OUTPUT           0x04
40 #define GRGPIO_DIR              0x08
41 #define GRGPIO_IMASK            0x0c
42 #define GRGPIO_IPOL             0x10
43 #define GRGPIO_IEDGE            0x14
44 #define GRGPIO_BYPASS           0x18
45 #define GRGPIO_IMAP_BASE        0x20
46
47 struct grgpio_priv {
48         struct bgpio_chip bgc;
49         void __iomem *regs;
50         struct device *dev;
51 };
52
53 static inline struct grgpio_priv *grgpio_gc_to_priv(struct gpio_chip *gc)
54 {
55         struct bgpio_chip *bgc = to_bgpio_chip(gc);
56
57         return container_of(bgc, struct grgpio_priv, bgc);
58 }
59
60 static int grgpio_probe(struct platform_device *ofdev)
61 {
62         struct device_node *np = ofdev->dev.of_node;
63         void  __iomem *regs;
64         struct gpio_chip *gc;
65         struct bgpio_chip *bgc;
66         struct grgpio_priv *priv;
67         struct resource *res;
68         int err;
69         u32 prop;
70
71         priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
72         if (!priv)
73                 return -ENOMEM;
74
75         res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
76         regs = devm_ioremap_resource(&ofdev->dev, res);
77         if (IS_ERR(regs))
78                 return PTR_ERR(regs);
79
80         bgc = &priv->bgc;
81         err = bgpio_init(bgc, &ofdev->dev, 4, regs + GRGPIO_DATA,
82                          regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL,
83                          BGPIOF_BIG_ENDIAN_BYTE_ORDER);
84         if (err) {
85                 dev_err(&ofdev->dev, "bgpio_init() failed\n");
86                 return err;
87         }
88
89         priv->regs = regs;
90         priv->dev = &ofdev->dev;
91
92         gc = &bgc->gc;
93         gc->of_node = np;
94         gc->owner = THIS_MODULE;
95         gc->label = np->full_name;
96         gc->base = -1;
97
98         err = of_property_read_u32(np, "nbits", &prop);
99         if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) {
100                 gc->ngpio = GRGPIO_MAX_NGPIO;
101                 dev_dbg(&ofdev->dev,
102                         "No or invalid nbits property: assume %d\n", gc->ngpio);
103         } else {
104                 gc->ngpio = prop;
105         }
106
107         platform_set_drvdata(ofdev, priv);
108
109         err = gpiochip_add(gc);
110         if (err) {
111                 dev_err(&ofdev->dev, "Could not add gpiochip\n");
112                 return err;
113         }
114
115         dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d\n",
116                  priv->regs, gc->base, gc->ngpio);
117
118         return 0;
119 }
120
121 static int grgpio_remove(struct platform_device *ofdev)
122 {
123         struct grgpio_priv *priv = platform_get_drvdata(ofdev);
124
125         return gpiochip_remove(&priv->bgc.gc);
126 }
127
128 static struct of_device_id grgpio_match[] = {
129         {.name = "GAISLER_GPIO"},
130         {.name = "01_01a"},
131         {},
132 };
133
134 MODULE_DEVICE_TABLE(of, grgpio_match);
135
136 static struct platform_driver grgpio_driver = {
137         .driver = {
138                 .name = "grgpio",
139                 .owner = THIS_MODULE,
140                 .of_match_table = grgpio_match,
141         },
142         .probe = grgpio_probe,
143         .remove = grgpio_remove,
144 };
145 module_platform_driver(grgpio_driver);
146
147 MODULE_AUTHOR("Aeroflex Gaisler AB.");
148 MODULE_DESCRIPTION("Driver for Aeroflex Gaisler GRGPIO");
149 MODULE_LICENSE("GPL");