GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / dream / generic_gpio.c
blobfe24d38345d0fafe3667d0e6dc8e5ab0282473aa
1 /* arch/arm/mach-msm/generic_gpio.c
3 * Copyright (C) 2007 Google, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
20 #include <linux/spinlock.h>
21 #include <asm/gpio.h>
22 #include "gpio_chip.h"
24 #define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5)
26 struct gpio_state {
27 unsigned long flags;
28 int refcount;
31 static DEFINE_SPINLOCK(gpio_chips_lock);
32 static LIST_HEAD(gpio_chip_list);
33 static struct gpio_chip **gpio_chip_array;
34 static unsigned long gpio_chip_array_size;
36 int register_gpio_chip(struct gpio_chip *new_gpio_chip)
38 int err = 0;
39 struct gpio_chip *gpio_chip;
40 int i;
41 unsigned long irq_flags;
42 unsigned int chip_array_start_index, chip_array_end_index;
44 new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL);
45 if (new_gpio_chip->state == NULL) {
46 printk(KERN_ERR "register_gpio_chip: failed to allocate state\n");
47 return -ENOMEM;
50 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
51 chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start);
52 chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end);
53 if (chip_array_end_index >= gpio_chip_array_size) {
54 struct gpio_chip **new_gpio_chip_array;
55 unsigned long new_gpio_chip_array_size = chip_array_end_index + 1;
57 new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC);
58 if (new_gpio_chip_array == NULL) {
59 printk(KERN_ERR "register_gpio_chip: failed to allocate array\n");
60 err = -ENOMEM;
61 goto failed;
63 for (i = 0; i < gpio_chip_array_size; i++)
64 new_gpio_chip_array[i] = gpio_chip_array[i];
65 for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++)
66 new_gpio_chip_array[i] = NULL;
67 gpio_chip_array = new_gpio_chip_array;
68 gpio_chip_array_size = new_gpio_chip_array_size;
70 list_for_each_entry(gpio_chip, &gpio_chip_list, list) {
71 if (gpio_chip->start > new_gpio_chip->end) {
72 list_add_tail(&new_gpio_chip->list, &gpio_chip->list);
73 goto added;
75 if (gpio_chip->end >= new_gpio_chip->start) {
76 printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n",
77 new_gpio_chip->start, new_gpio_chip->end,
78 gpio_chip->start, gpio_chip->end);
79 err = -EBUSY;
80 goto failed;
83 list_add_tail(&new_gpio_chip->list, &gpio_chip_list);
84 added:
85 for (i = chip_array_start_index; i <= chip_array_end_index; i++) {
86 if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start)
87 gpio_chip_array[i] = new_gpio_chip;
89 failed:
90 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
91 if (err)
92 kfree(new_gpio_chip->state);
93 return err;
96 static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio)
98 unsigned long i;
99 struct gpio_chip *chip;
101 i = GPIO_NUM_TO_CHIP_INDEX(gpio);
102 if (i >= gpio_chip_array_size)
103 return NULL;
104 chip = gpio_chip_array[i];
105 if (chip == NULL)
106 return NULL;
107 list_for_each_entry_from(chip, &gpio_chip_list, list) {
108 if (gpio < chip->start)
109 return NULL;
110 if (gpio <= chip->end)
111 return chip;
113 return NULL;
116 static int request_gpio(unsigned int gpio, unsigned long flags)
118 int err = 0;
119 struct gpio_chip *chip;
120 unsigned long irq_flags;
121 unsigned long chip_index;
123 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
124 chip = get_gpio_chip_locked(gpio);
125 if (chip == NULL) {
126 err = -EINVAL;
127 goto err;
129 chip_index = gpio - chip->start;
130 if (chip->state[chip_index].refcount == 0) {
131 chip->configure(chip, gpio, flags);
132 chip->state[chip_index].flags = flags;
133 chip->state[chip_index].refcount++;
134 } else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED))
135 chip->state[chip_index].refcount++;
136 else
137 err = -EBUSY;
138 err:
139 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
140 return err;
143 int gpio_request(unsigned gpio, const char *label)
145 return request_gpio(gpio, 0);
147 EXPORT_SYMBOL(gpio_request);
149 void gpio_free(unsigned gpio)
151 struct gpio_chip *chip;
152 unsigned long irq_flags;
153 unsigned long chip_index;
155 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
156 chip = get_gpio_chip_locked(gpio);
157 if (chip) {
158 chip_index = gpio - chip->start;
159 chip->state[chip_index].refcount--;
161 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
163 EXPORT_SYMBOL(gpio_free);
165 static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp)
167 int ret = -ENOTSUPP;
168 struct gpio_chip *chip;
169 unsigned long irq_flags;
171 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
172 chip = get_gpio_chip_locked(gpio);
173 if (chip && chip->get_irq_num)
174 ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp);
175 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
176 return ret;
179 int gpio_to_irq(unsigned gpio)
181 int ret, irq;
182 ret = gpio_get_irq_num(gpio, &irq, NULL);
183 if (ret)
184 return ret;
185 return irq;
187 EXPORT_SYMBOL(gpio_to_irq);
189 int gpio_configure(unsigned int gpio, unsigned long flags)
191 int ret = -ENOTSUPP;
192 struct gpio_chip *chip;
193 unsigned long irq_flags;
195 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
196 chip = get_gpio_chip_locked(gpio);
197 if (chip)
198 ret = chip->configure(chip, gpio, flags);
199 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
200 return ret;
202 EXPORT_SYMBOL(gpio_configure);
204 int gpio_direction_input(unsigned gpio)
206 return gpio_configure(gpio, GPIOF_INPUT);
208 EXPORT_SYMBOL(gpio_direction_input);
210 int gpio_direction_output(unsigned gpio, int value)
212 gpio_set_value(gpio, value);
213 return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT);
215 EXPORT_SYMBOL(gpio_direction_output);
217 int gpio_get_value(unsigned gpio)
219 int ret = -ENOTSUPP;
220 struct gpio_chip *chip;
221 unsigned long irq_flags;
223 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
224 chip = get_gpio_chip_locked(gpio);
225 if (chip && chip->read)
226 ret = chip->read(chip, gpio);
227 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
228 return ret;
230 EXPORT_SYMBOL(gpio_get_value);
232 void gpio_set_value(unsigned gpio, int on)
234 int ret = -ENOTSUPP;
235 struct gpio_chip *chip;
236 unsigned long irq_flags;
238 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
239 chip = get_gpio_chip_locked(gpio);
240 if (chip && chip->write)
241 ret = chip->write(chip, gpio, on);
242 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
244 EXPORT_SYMBOL(gpio_set_value);
246 int gpio_read_detect_status(unsigned int gpio)
248 int ret = -ENOTSUPP;
249 struct gpio_chip *chip;
250 unsigned long irq_flags;
252 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
253 chip = get_gpio_chip_locked(gpio);
254 if (chip && chip->read_detect_status)
255 ret = chip->read_detect_status(chip, gpio);
256 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
257 return ret;
259 EXPORT_SYMBOL(gpio_read_detect_status);
261 int gpio_clear_detect_status(unsigned int gpio)
263 int ret = -ENOTSUPP;
264 struct gpio_chip *chip;
265 unsigned long irq_flags;
267 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
268 chip = get_gpio_chip_locked(gpio);
269 if (chip && chip->clear_detect_status)
270 ret = chip->clear_detect_status(chip, gpio);
271 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
272 return ret;
274 EXPORT_SYMBOL(gpio_clear_detect_status);