aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r--arch/avr32/mach-at32ap/pio.c172
-rw-r--r--arch/avr32/mach-at32ap/pio.h2
2 files changed, 93 insertions, 81 deletions
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index d61a02da898c..38a8fa31c0b5 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -24,11 +24,11 @@
24#define MAX_NR_PIO_DEVICES 8 24#define MAX_NR_PIO_DEVICES 8
25 25
26struct pio_device { 26struct pio_device {
27 struct gpio_chip chip;
27 void __iomem *regs; 28 void __iomem *regs;
28 const struct platform_device *pdev; 29 const struct platform_device *pdev;
29 struct clk *clk; 30 struct clk *clk;
30 u32 pinmux_mask; 31 u32 pinmux_mask;
31 u32 gpio_mask;
32 char name[8]; 32 char name[8];
33}; 33};
34 34
@@ -64,7 +64,8 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph,
64 goto fail; 64 goto fail;
65 } 65 }
66 66
67 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { 67 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask)
68 || gpiochip_is_requested(&pio->chip, pin_index))) {
68 printk("%s: pin %u is busy\n", pio->name, pin_index); 69 printk("%s: pin %u is busy\n", pio->name, pin_index);
69 goto fail; 70 goto fail;
70 } 71 }
@@ -79,9 +80,6 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph,
79 if (!(flags & AT32_GPIOF_PULLUP)) 80 if (!(flags & AT32_GPIOF_PULLUP))
80 pio_writel(pio, PUDR, mask); 81 pio_writel(pio, PUDR, mask);
81 82
82 /* gpio_request NOT allowed */
83 set_bit(pin_index, &pio->gpio_mask);
84
85 return; 83 return;
86 84
87fail: 85fail:
@@ -130,9 +128,6 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
130 128
131 pio_writel(pio, PER, mask); 129 pio_writel(pio, PER, mask);
132 130
133 /* gpio_request now allowed */
134 clear_bit(pin_index, &pio->gpio_mask);
135
136 return; 131 return;
137 132
138fail: 133fail:
@@ -166,96 +161,50 @@ fail:
166 161
167/* GPIO API */ 162/* GPIO API */
168 163
169int gpio_request(unsigned int gpio, const char *label) 164static int direction_input(struct gpio_chip *chip, unsigned offset)
170{ 165{
171 struct pio_device *pio; 166 struct pio_device *pio = container_of(chip, struct pio_device, chip);
172 unsigned int pin; 167 u32 mask = 1 << offset;
173
174 pio = gpio_to_pio(gpio);
175 if (!pio)
176 return -ENODEV;
177 168
178 pin = gpio & 0x1f; 169 if (!(pio_readl(pio, PSR) & mask))
179 if (test_and_set_bit(pin, &pio->gpio_mask)) 170 return -EINVAL;
180 return -EBUSY;
181 171
172 pio_writel(pio, ODR, mask);
182 return 0; 173 return 0;
183} 174}
184EXPORT_SYMBOL(gpio_request);
185 175
186void gpio_free(unsigned int gpio) 176static int gpio_get(struct gpio_chip *chip, unsigned offset)
187{ 177{
188 struct pio_device *pio; 178 struct pio_device *pio = container_of(chip, struct pio_device, chip);
189 unsigned int pin;
190 179
191 pio = gpio_to_pio(gpio); 180 return (pio_readl(pio, PDSR) >> offset) & 1;
192 if (!pio) {
193 printk(KERN_ERR
194 "gpio: attempted to free invalid pin %u\n", gpio);
195 return;
196 }
197
198 pin = gpio & 0x1f;
199 if (!test_and_clear_bit(pin, &pio->gpio_mask))
200 printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n",
201 pio->name, pin);
202} 181}
203EXPORT_SYMBOL(gpio_free);
204 182
205int gpio_direction_input(unsigned int gpio) 183static void gpio_set(struct gpio_chip *chip, unsigned offset, int value);
206{
207 struct pio_device *pio;
208 unsigned int pin;
209
210 pio = gpio_to_pio(gpio);
211 if (!pio)
212 return -ENODEV;
213
214 pin = gpio & 0x1f;
215 pio_writel(pio, ODR, 1 << pin);
216
217 return 0;
218}
219EXPORT_SYMBOL(gpio_direction_input);
220 184
221int gpio_direction_output(unsigned int gpio, int value) 185static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
222{ 186{
223 struct pio_device *pio; 187 struct pio_device *pio = container_of(chip, struct pio_device, chip);
224 unsigned int pin; 188 u32 mask = 1 << offset;
225
226 pio = gpio_to_pio(gpio);
227 if (!pio)
228 return -ENODEV;
229 189
230 gpio_set_value(gpio, value); 190 if (!(pio_readl(pio, PSR) & mask))
231 191 return -EINVAL;
232 pin = gpio & 0x1f;
233 pio_writel(pio, OER, 1 << pin);
234 192
193 gpio_set(chip, offset, value);
194 pio_writel(pio, OER, mask);
235 return 0; 195 return 0;
236} 196}
237EXPORT_SYMBOL(gpio_direction_output);
238 197
239int gpio_get_value(unsigned int gpio) 198static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
240{ 199{
241 struct pio_device *pio = &pio_dev[gpio >> 5]; 200 struct pio_device *pio = container_of(chip, struct pio_device, chip);
201 u32 mask = 1 << offset;
242 202
243 return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1;
244}
245EXPORT_SYMBOL(gpio_get_value);
246
247void gpio_set_value(unsigned int gpio, int value)
248{
249 struct pio_device *pio = &pio_dev[gpio >> 5];
250 u32 mask;
251
252 mask = 1 << (gpio & 0x1f);
253 if (value) 203 if (value)
254 pio_writel(pio, SODR, mask); 204 pio_writel(pio, SODR, mask);
255 else 205 else
256 pio_writel(pio, CODR, mask); 206 pio_writel(pio, CODR, mask);
257} 207}
258EXPORT_SYMBOL(gpio_set_value);
259 208
260/*--------------------------------------------------------------------------*/ 209/*--------------------------------------------------------------------------*/
261 210
@@ -339,6 +288,63 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
339 288
340/*--------------------------------------------------------------------------*/ 289/*--------------------------------------------------------------------------*/
341 290
291#ifdef CONFIG_DEBUG_FS
292
293#include <linux/seq_file.h>
294
295/*
296 * This shows more info than the generic gpio dump code:
297 * pullups, deglitching, open drain drive.
298 */
299static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip)
300{
301 struct pio_device *pio = container_of(chip, struct pio_device, chip);
302 u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr;
303 unsigned i;
304 u32 mask;
305 char bank;
306
307 psr = pio_readl(pio, PSR);
308 osr = pio_readl(pio, OSR);
309 imr = pio_readl(pio, IMR);
310 pdsr = pio_readl(pio, PDSR);
311 pusr = pio_readl(pio, PUSR);
312 ifsr = pio_readl(pio, IFSR);
313 mdsr = pio_readl(pio, MDSR);
314
315 bank = 'A' + pio->pdev->id;
316
317 for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
318 const char *label;
319
320 label = gpiochip_is_requested(chip, i);
321 if (!label)
322 continue;
323
324 seq_printf(s, " gpio-%-3d P%c%-2d (%-12s) %s %s %s",
325 chip->base + i, bank, i,
326 label,
327 (osr & mask) ? "out" : "in ",
328 (mask & pdsr) ? "hi" : "lo",
329 (mask & pusr) ? " " : "up");
330 if (ifsr & mask)
331 seq_printf(s, " deglitch");
332 if ((osr & mdsr) & mask)
333 seq_printf(s, " open-drain");
334 if (imr & mask)
335 seq_printf(s, " irq-%d edge-both",
336 gpio_to_irq(chip->base + i));
337 seq_printf(s, "\n");
338 }
339}
340
341#else
342#define pio_bank_show NULL
343#endif
344
345
346/*--------------------------------------------------------------------------*/
347
342static int __init pio_probe(struct platform_device *pdev) 348static int __init pio_probe(struct platform_device *pdev)
343{ 349{
344 struct pio_device *pio = NULL; 350 struct pio_device *pio = NULL;
@@ -349,6 +355,18 @@ static int __init pio_probe(struct platform_device *pdev)
349 pio = &pio_dev[pdev->id]; 355 pio = &pio_dev[pdev->id];
350 BUG_ON(!pio->regs); 356 BUG_ON(!pio->regs);
351 357
358 pio->chip.label = pio->name;
359 pio->chip.base = pdev->id * 32;
360 pio->chip.ngpio = 32;
361
362 pio->chip.direction_input = direction_input;
363 pio->chip.get = gpio_get;
364 pio->chip.direction_output = direction_output;
365 pio->chip.set = gpio_set;
366 pio->chip.dbg_show = pio_bank_show;
367
368 gpiochip_add(&pio->chip);
369
352 gpio_irq_setup(pio, irq, gpio_irq_base); 370 gpio_irq_setup(pio, irq, gpio_irq_base);
353 371
354 platform_set_drvdata(pdev, pio); 372 platform_set_drvdata(pdev, pio);
@@ -406,12 +424,6 @@ void __init at32_init_pio(struct platform_device *pdev)
406 pio->pdev = pdev; 424 pio->pdev = pdev;
407 pio->regs = ioremap(regs->start, regs->end - regs->start + 1); 425 pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
408 426
409 /*
410 * request_gpio() is only valid for pins that have been
411 * explicitly configured as GPIO and not previously requested
412 */
413 pio->gpio_mask = ~0UL;
414
415 /* start with irqs disabled and acked */ 427 /* start with irqs disabled and acked */
416 pio_writel(pio, IDR, ~0UL); 428 pio_writel(pio, IDR, ~0UL);
417 (void) pio_readl(pio, ISR); 429 (void) pio_readl(pio, ISR);
diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h
index 50fa3aca32c5..7795116a483a 100644
--- a/arch/avr32/mach-at32ap/pio.h
+++ b/arch/avr32/mach-at32ap/pio.h
@@ -19,7 +19,7 @@
19#define PIO_OSR 0x0018 19#define PIO_OSR 0x0018
20#define PIO_IFER 0x0020 20#define PIO_IFER 0x0020
21#define PIO_IFDR 0x0024 21#define PIO_IFDR 0x0024
22#define PIO_ISFR 0x0028 22#define PIO_IFSR 0x0028
23#define PIO_SODR 0x0030 23#define PIO_SODR 0x0030
24#define PIO_CODR 0x0034 24#define PIO_CODR 0x0034
25#define PIO_ODSR 0x0038 25#define PIO_ODSR 0x0038