acpiphp: Execute ACPI _REG method for hotadded devices
[linux/fpc-iii.git] / arch / arm / mach-ns9xxx / gpio.c
blob5503ca09c4aee4a1d2dc8e5a249ddb6e9c31814a
1 /*
2 * arch/arm/mach-ns9xxx/gpio.c
4 * Copyright (C) 2006,2007 by Digi International Inc.
5 * All rights reserved.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/compiler.h>
13 #include <linux/init.h>
14 #include <linux/spinlock.h>
15 #include <linux/module.h>
16 #include <linux/bitops.h>
18 #include <mach/gpio.h>
19 #include <mach/processor.h>
20 #include <mach/processor-ns9360.h>
21 #include <asm/bug.h>
22 #include <asm/types.h>
24 #include "gpio-ns9360.h"
26 #if defined(CONFIG_PROCESSOR_NS9360)
27 #define GPIO_MAX 72
28 #elif defined(CONFIG_PROCESSOR_NS9750)
29 #define GPIO_MAX 49
30 #endif
32 /* protects BBU_GCONFx and BBU_GCTRLx */
33 static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock);
35 /* only access gpiores with atomic ops */
36 static DECLARE_BITMAP(gpiores, GPIO_MAX + 1);
38 static inline int ns9xxx_valid_gpio(unsigned gpio)
40 #if defined(CONFIG_PROCESSOR_NS9360)
41 if (processor_is_ns9360())
42 return gpio <= 72;
43 else
44 #endif
45 #if defined(CONFIG_PROCESSOR_NS9750)
46 if (processor_is_ns9750())
47 return gpio <= 49;
48 else
49 #endif
51 BUG();
52 return 0;
56 int gpio_request(unsigned gpio, const char *label)
58 if (likely(ns9xxx_valid_gpio(gpio)))
59 return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0;
60 else
61 return -EINVAL;
63 EXPORT_SYMBOL(gpio_request);
65 void gpio_free(unsigned gpio)
67 might_sleep();
68 clear_bit(gpio, gpiores);
69 return;
71 EXPORT_SYMBOL(gpio_free);
73 int gpio_direction_input(unsigned gpio)
75 if (likely(ns9xxx_valid_gpio(gpio))) {
76 int ret = -EINVAL;
77 unsigned long flags;
79 spin_lock_irqsave(&gpio_lock, flags);
80 #if defined(CONFIG_PROCESSOR_NS9360)
81 if (processor_is_ns9360())
82 ret = __ns9360_gpio_configure(gpio, 0, 0, 3);
83 else
84 #endif
85 BUG();
87 spin_unlock_irqrestore(&gpio_lock, flags);
89 return ret;
91 } else
92 return -EINVAL;
94 EXPORT_SYMBOL(gpio_direction_input);
96 int gpio_direction_output(unsigned gpio, int value)
98 if (likely(ns9xxx_valid_gpio(gpio))) {
99 int ret = -EINVAL;
100 unsigned long flags;
102 gpio_set_value(gpio, value);
104 spin_lock_irqsave(&gpio_lock, flags);
105 #if defined(CONFIG_PROCESSOR_NS9360)
106 if (processor_is_ns9360())
107 ret = __ns9360_gpio_configure(gpio, 1, 0, 3);
108 else
109 #endif
110 BUG();
112 spin_unlock_irqrestore(&gpio_lock, flags);
114 return ret;
115 } else
116 return -EINVAL;
118 EXPORT_SYMBOL(gpio_direction_output);
120 int gpio_get_value(unsigned gpio)
122 #if defined(CONFIG_PROCESSOR_NS9360)
123 if (processor_is_ns9360())
124 return ns9360_gpio_get_value(gpio);
125 else
126 #endif
128 BUG();
129 return -EINVAL;
132 EXPORT_SYMBOL(gpio_get_value);
134 void gpio_set_value(unsigned gpio, int value)
136 unsigned long flags;
137 spin_lock_irqsave(&gpio_lock, flags);
138 #if defined(CONFIG_PROCESSOR_NS9360)
139 if (processor_is_ns9360())
140 ns9360_gpio_set_value(gpio, value);
141 else
142 #endif
143 BUG();
145 spin_unlock_irqrestore(&gpio_lock, flags);
147 EXPORT_SYMBOL(gpio_set_value);