Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
10818 views
1
/*
2
* MPC52xx gpio driver
3
*
4
* Copyright (c) 2008 Sascha Hauer <[email protected]>, Pengutronix
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2
8
* as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
*/
19
20
#include <linux/of.h>
21
#include <linux/kernel.h>
22
#include <linux/slab.h>
23
#include <linux/of_gpio.h>
24
#include <linux/io.h>
25
#include <linux/of_platform.h>
26
27
#include <asm/gpio.h>
28
#include <asm/mpc52xx.h>
29
#include <sysdev/fsl_soc.h>
30
31
static DEFINE_SPINLOCK(gpio_lock);
32
33
struct mpc52xx_gpiochip {
34
struct of_mm_gpio_chip mmchip;
35
unsigned int shadow_dvo;
36
unsigned int shadow_gpioe;
37
unsigned int shadow_ddr;
38
};
39
40
/*
41
* GPIO LIB API implementation for wakeup GPIOs.
42
*
43
* There's a maximum of 8 wakeup GPIOs. Which of these are available
44
* for use depends on your board setup.
45
*
46
* 0 -> GPIO_WKUP_7
47
* 1 -> GPIO_WKUP_6
48
* 2 -> PSC6_1
49
* 3 -> PSC6_0
50
* 4 -> ETH_17
51
* 5 -> PSC3_9
52
* 6 -> PSC2_4
53
* 7 -> PSC1_4
54
*
55
*/
56
static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
57
{
58
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
59
struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
60
unsigned int ret;
61
62
ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
63
64
pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
65
66
return ret;
67
}
68
69
static inline void
70
__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
71
{
72
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
73
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
74
struct mpc52xx_gpiochip, mmchip);
75
struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
76
77
if (val)
78
chip->shadow_dvo |= 1 << (7 - gpio);
79
else
80
chip->shadow_dvo &= ~(1 << (7 - gpio));
81
82
out_8(&regs->wkup_dvo, chip->shadow_dvo);
83
}
84
85
static void
86
mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
87
{
88
unsigned long flags;
89
90
spin_lock_irqsave(&gpio_lock, flags);
91
92
__mpc52xx_wkup_gpio_set(gc, gpio, val);
93
94
spin_unlock_irqrestore(&gpio_lock, flags);
95
96
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
97
}
98
99
static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
100
{
101
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
102
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
103
struct mpc52xx_gpiochip, mmchip);
104
struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
105
unsigned long flags;
106
107
spin_lock_irqsave(&gpio_lock, flags);
108
109
/* set the direction */
110
chip->shadow_ddr &= ~(1 << (7 - gpio));
111
out_8(&regs->wkup_ddr, chip->shadow_ddr);
112
113
/* and enable the pin */
114
chip->shadow_gpioe |= 1 << (7 - gpio);
115
out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
116
117
spin_unlock_irqrestore(&gpio_lock, flags);
118
119
return 0;
120
}
121
122
static int
123
mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
124
{
125
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
126
struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
127
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
128
struct mpc52xx_gpiochip, mmchip);
129
unsigned long flags;
130
131
spin_lock_irqsave(&gpio_lock, flags);
132
133
__mpc52xx_wkup_gpio_set(gc, gpio, val);
134
135
/* Then set direction */
136
chip->shadow_ddr |= 1 << (7 - gpio);
137
out_8(&regs->wkup_ddr, chip->shadow_ddr);
138
139
/* Finally enable the pin */
140
chip->shadow_gpioe |= 1 << (7 - gpio);
141
out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
142
143
spin_unlock_irqrestore(&gpio_lock, flags);
144
145
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
146
147
return 0;
148
}
149
150
static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
151
{
152
struct mpc52xx_gpiochip *chip;
153
struct mpc52xx_gpio_wkup __iomem *regs;
154
struct gpio_chip *gc;
155
int ret;
156
157
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
158
if (!chip)
159
return -ENOMEM;
160
161
gc = &chip->mmchip.gc;
162
163
gc->ngpio = 8;
164
gc->direction_input = mpc52xx_wkup_gpio_dir_in;
165
gc->direction_output = mpc52xx_wkup_gpio_dir_out;
166
gc->get = mpc52xx_wkup_gpio_get;
167
gc->set = mpc52xx_wkup_gpio_set;
168
169
ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
170
if (ret)
171
return ret;
172
173
regs = chip->mmchip.regs;
174
chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
175
chip->shadow_ddr = in_8(&regs->wkup_ddr);
176
chip->shadow_dvo = in_8(&regs->wkup_dvo);
177
178
return 0;
179
}
180
181
static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
182
{
183
return -EBUSY;
184
}
185
186
static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
187
{
188
.compatible = "fsl,mpc5200-gpio-wkup",
189
},
190
{}
191
};
192
193
static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
194
.driver = {
195
.name = "gpio_wkup",
196
.owner = THIS_MODULE,
197
.of_match_table = mpc52xx_wkup_gpiochip_match,
198
},
199
.probe = mpc52xx_wkup_gpiochip_probe,
200
.remove = mpc52xx_gpiochip_remove,
201
};
202
203
/*
204
* GPIO LIB API implementation for simple GPIOs
205
*
206
* There's a maximum of 32 simple GPIOs. Which of these are available
207
* for use depends on your board setup.
208
* The numbering reflects the bit numbering in the port registers:
209
*
210
* 0..1 > reserved
211
* 2..3 > IRDA
212
* 4..7 > ETHR
213
* 8..11 > reserved
214
* 12..15 > USB
215
* 16..17 > reserved
216
* 18..23 > PSC3
217
* 24..27 > PSC2
218
* 28..31 > PSC1
219
*/
220
static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
221
{
222
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
223
struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
224
unsigned int ret;
225
226
ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
227
228
return ret;
229
}
230
231
static inline void
232
__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
233
{
234
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
235
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
236
struct mpc52xx_gpiochip, mmchip);
237
struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
238
239
if (val)
240
chip->shadow_dvo |= 1 << (31 - gpio);
241
else
242
chip->shadow_dvo &= ~(1 << (31 - gpio));
243
out_be32(&regs->simple_dvo, chip->shadow_dvo);
244
}
245
246
static void
247
mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
248
{
249
unsigned long flags;
250
251
spin_lock_irqsave(&gpio_lock, flags);
252
253
__mpc52xx_simple_gpio_set(gc, gpio, val);
254
255
spin_unlock_irqrestore(&gpio_lock, flags);
256
257
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
258
}
259
260
static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
261
{
262
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
263
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
264
struct mpc52xx_gpiochip, mmchip);
265
struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
266
unsigned long flags;
267
268
spin_lock_irqsave(&gpio_lock, flags);
269
270
/* set the direction */
271
chip->shadow_ddr &= ~(1 << (31 - gpio));
272
out_be32(&regs->simple_ddr, chip->shadow_ddr);
273
274
/* and enable the pin */
275
chip->shadow_gpioe |= 1 << (31 - gpio);
276
out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
277
278
spin_unlock_irqrestore(&gpio_lock, flags);
279
280
return 0;
281
}
282
283
static int
284
mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
285
{
286
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
287
struct mpc52xx_gpiochip *chip = container_of(mm_gc,
288
struct mpc52xx_gpiochip, mmchip);
289
struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
290
unsigned long flags;
291
292
spin_lock_irqsave(&gpio_lock, flags);
293
294
/* First set initial value */
295
__mpc52xx_simple_gpio_set(gc, gpio, val);
296
297
/* Then set direction */
298
chip->shadow_ddr |= 1 << (31 - gpio);
299
out_be32(&regs->simple_ddr, chip->shadow_ddr);
300
301
/* Finally enable the pin */
302
chip->shadow_gpioe |= 1 << (31 - gpio);
303
out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
304
305
spin_unlock_irqrestore(&gpio_lock, flags);
306
307
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
308
309
return 0;
310
}
311
312
static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
313
{
314
struct mpc52xx_gpiochip *chip;
315
struct gpio_chip *gc;
316
struct mpc52xx_gpio __iomem *regs;
317
int ret;
318
319
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
320
if (!chip)
321
return -ENOMEM;
322
323
gc = &chip->mmchip.gc;
324
325
gc->ngpio = 32;
326
gc->direction_input = mpc52xx_simple_gpio_dir_in;
327
gc->direction_output = mpc52xx_simple_gpio_dir_out;
328
gc->get = mpc52xx_simple_gpio_get;
329
gc->set = mpc52xx_simple_gpio_set;
330
331
ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
332
if (ret)
333
return ret;
334
335
regs = chip->mmchip.regs;
336
chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
337
chip->shadow_ddr = in_be32(&regs->simple_ddr);
338
chip->shadow_dvo = in_be32(&regs->simple_dvo);
339
340
return 0;
341
}
342
343
static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
344
{
345
.compatible = "fsl,mpc5200-gpio",
346
},
347
{}
348
};
349
350
static struct platform_driver mpc52xx_simple_gpiochip_driver = {
351
.driver = {
352
.name = "gpio",
353
.owner = THIS_MODULE,
354
.of_match_table = mpc52xx_simple_gpiochip_match,
355
},
356
.probe = mpc52xx_simple_gpiochip_probe,
357
.remove = mpc52xx_gpiochip_remove,
358
};
359
360
static int __init mpc52xx_gpio_init(void)
361
{
362
if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver))
363
printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
364
365
if (platform_driver_register(&mpc52xx_simple_gpiochip_driver))
366
printk(KERN_ERR "Unable to register simple GPIO driver\n");
367
368
return 0;
369
}
370
371
372
/* Make sure we get initialised before anyone else tries to use us */
373
subsys_initcall(mpc52xx_gpio_init);
374
375
/* No exit call at the moment as we cannot unregister of gpio chips */
376
377
MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
378
MODULE_AUTHOR("Sascha Hauer <[email protected]");
379
MODULE_LICENSE("GPL v2");
380
381
382