1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/of.h>
21#include <linux/kernel.h>
22#include <linux/of_gpio.h>
23#include <linux/io.h>
24#include <linux/of_platform.h>
25
26#include <asm/gpio.h>
27#include <asm/mpc52xx.h>
28#include <sysdev/fsl_soc.h>
29
30static DEFINE_SPINLOCK(gpio_lock);
31
32struct mpc52xx_gpiochip {
33 struct of_mm_gpio_chip mmchip;
34 unsigned int shadow_dvo;
35 unsigned int shadow_gpioe;
36 unsigned int shadow_ddr;
37};
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
56{
57 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
58 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
59 unsigned int ret;
60
61 ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1;
62
63 pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
64
65 return ret;
66}
67
68static inline void
69__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
70{
71 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
72 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
73 struct mpc52xx_gpiochip, mmchip);
74 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
75
76 if (val)
77 chip->shadow_dvo |= 1 << (7 - gpio);
78 else
79 chip->shadow_dvo &= ~(1 << (7 - gpio));
80
81 out_8(®s->wkup_dvo, chip->shadow_dvo);
82}
83
84static void
85mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
86{
87 unsigned long flags;
88
89 spin_lock_irqsave(&gpio_lock, flags);
90
91 __mpc52xx_wkup_gpio_set(gc, gpio, val);
92
93 spin_unlock_irqrestore(&gpio_lock, flags);
94
95 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
96}
97
98static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
99{
100 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
101 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
102 struct mpc52xx_gpiochip, mmchip);
103 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
104 unsigned long flags;
105
106 spin_lock_irqsave(&gpio_lock, flags);
107
108
109 chip->shadow_ddr &= ~(1 << (7 - gpio));
110 out_8(®s->wkup_ddr, chip->shadow_ddr);
111
112
113 chip->shadow_gpioe |= 1 << (7 - gpio);
114 out_8(®s->wkup_gpioe, chip->shadow_gpioe);
115
116 spin_unlock_irqrestore(&gpio_lock, flags);
117
118 return 0;
119}
120
121static int
122mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
123{
124 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
125 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
126 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
127 struct mpc52xx_gpiochip, mmchip);
128 unsigned long flags;
129
130 spin_lock_irqsave(&gpio_lock, flags);
131
132 __mpc52xx_wkup_gpio_set(gc, gpio, val);
133
134
135 chip->shadow_ddr |= 1 << (7 - gpio);
136 out_8(®s->wkup_ddr, chip->shadow_ddr);
137
138
139 chip->shadow_gpioe |= 1 << (7 - gpio);
140 out_8(®s->wkup_gpioe, chip->shadow_gpioe);
141
142 spin_unlock_irqrestore(&gpio_lock, flags);
143
144 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
145
146 return 0;
147}
148
149static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
150 const struct of_device_id *match)
151{
152 struct mpc52xx_gpiochip *chip;
153 struct mpc52xx_gpio_wkup __iomem *regs;
154 struct of_gpio_chip *ofchip;
155 int ret;
156
157 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
158 if (!chip)
159 return -ENOMEM;
160
161 ofchip = &chip->mmchip.of_gc;
162
163 ofchip->gpio_cells = 2;
164 ofchip->gc.ngpio = 8;
165 ofchip->gc.direction_input = mpc52xx_wkup_gpio_dir_in;
166 ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
167 ofchip->gc.get = mpc52xx_wkup_gpio_get;
168 ofchip->gc.set = mpc52xx_wkup_gpio_set;
169
170 ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip);
171 if (ret)
172 return ret;
173
174 regs = chip->mmchip.regs;
175 chip->shadow_gpioe = in_8(®s->wkup_gpioe);
176 chip->shadow_ddr = in_8(®s->wkup_ddr);
177 chip->shadow_dvo = in_8(®s->wkup_dvo);
178
179 return 0;
180}
181
182static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
183{
184 return -EBUSY;
185}
186
187static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
188 {
189 .compatible = "fsl,mpc5200-gpio-wkup",
190 },
191 {}
192};
193
194static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = {
195 .name = "gpio_wkup",
196 .match_table = mpc52xx_wkup_gpiochip_match,
197 .probe = mpc52xx_wkup_gpiochip_probe,
198 .remove = mpc52xx_gpiochip_remove,
199};
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
219{
220 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
221 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
222 unsigned int ret;
223
224 ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1;
225
226 return ret;
227}
228
229static inline void
230__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
231{
232 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
233 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
234 struct mpc52xx_gpiochip, mmchip);
235 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
236
237 if (val)
238 chip->shadow_dvo |= 1 << (31 - gpio);
239 else
240 chip->shadow_dvo &= ~(1 << (31 - gpio));
241 out_be32(®s->simple_dvo, chip->shadow_dvo);
242}
243
244static void
245mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
246{
247 unsigned long flags;
248
249 spin_lock_irqsave(&gpio_lock, flags);
250
251 __mpc52xx_simple_gpio_set(gc, gpio, val);
252
253 spin_unlock_irqrestore(&gpio_lock, flags);
254
255 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
256}
257
258static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
259{
260 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
261 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
262 struct mpc52xx_gpiochip, mmchip);
263 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
264 unsigned long flags;
265
266 spin_lock_irqsave(&gpio_lock, flags);
267
268
269 chip->shadow_ddr &= ~(1 << (31 - gpio));
270 out_be32(®s->simple_ddr, chip->shadow_ddr);
271
272
273 chip->shadow_gpioe |= 1 << (31 - gpio);
274 out_be32(®s->simple_gpioe, chip->shadow_gpioe);
275
276 spin_unlock_irqrestore(&gpio_lock, flags);
277
278 return 0;
279}
280
281static int
282mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
283{
284 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
285 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
286 struct mpc52xx_gpiochip, mmchip);
287 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
288 unsigned long flags;
289
290 spin_lock_irqsave(&gpio_lock, flags);
291
292
293 __mpc52xx_simple_gpio_set(gc, gpio, val);
294
295
296 chip->shadow_ddr |= 1 << (31 - gpio);
297 out_be32(®s->simple_ddr, chip->shadow_ddr);
298
299
300 chip->shadow_gpioe |= 1 << (31 - gpio);
301 out_be32(®s->simple_gpioe, chip->shadow_gpioe);
302
303 spin_unlock_irqrestore(&gpio_lock, flags);
304
305 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
306
307 return 0;
308}
309
310static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
311 const struct of_device_id *match)
312{
313 struct mpc52xx_gpiochip *chip;
314 struct of_gpio_chip *ofchip;
315 struct mpc52xx_gpio __iomem *regs;
316 int ret;
317
318 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
319 if (!chip)
320 return -ENOMEM;
321
322 ofchip = &chip->mmchip.of_gc;
323
324 ofchip->gpio_cells = 2;
325 ofchip->gc.ngpio = 32;
326 ofchip->gc.direction_input = mpc52xx_simple_gpio_dir_in;
327 ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
328 ofchip->gc.get = mpc52xx_simple_gpio_get;
329 ofchip->gc.set = mpc52xx_simple_gpio_set;
330
331 ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip);
332 if (ret)
333 return ret;
334
335 regs = chip->mmchip.regs;
336 chip->shadow_gpioe = in_be32(®s->simple_gpioe);
337 chip->shadow_ddr = in_be32(®s->simple_ddr);
338 chip->shadow_dvo = in_be32(®s->simple_dvo);
339
340 return 0;
341}
342
343static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
344 {
345 .compatible = "fsl,mpc5200-gpio",
346 },
347 {}
348};
349
350static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
351 .name = "gpio",
352 .match_table = mpc52xx_simple_gpiochip_match,
353 .probe = mpc52xx_simple_gpiochip_probe,
354 .remove = mpc52xx_gpiochip_remove,
355};
356
357static int __init mpc52xx_gpio_init(void)
358{
359 if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
360 printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
361
362 if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
363 printk(KERN_ERR "Unable to register simple GPIO driver\n");
364
365 return 0;
366}
367
368
369
370subsys_initcall(mpc52xx_gpio_init);
371
372
373
374MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
375MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
376MODULE_LICENSE("GPL v2");
377
378