aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/stmpe-gpio.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/gpio/stmpe-gpio.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/gpio/stmpe-gpio.c')
-rw-r--r--drivers/gpio/stmpe-gpio.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/stmpe-gpio.c
index 4e1f1b9d5e67..4c980b573328 100644
--- a/drivers/gpio/stmpe-gpio.c
+++ b/drivers/gpio/stmpe-gpio.c
@@ -30,6 +30,7 @@ struct stmpe_gpio {
30 struct mutex irq_lock; 30 struct mutex irq_lock;
31 31
32 int irq_base; 32 int irq_base;
33 unsigned norequest_mask;
33 34
34 /* Caches of interrupt control registers for bus_lock */ 35 /* Caches of interrupt control registers for bus_lock */
35 u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; 36 u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
@@ -103,6 +104,9 @@ static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset)
103 struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); 104 struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip);
104 struct stmpe *stmpe = stmpe_gpio->stmpe; 105 struct stmpe *stmpe = stmpe_gpio->stmpe;
105 106
107 if (stmpe_gpio->norequest_mask & (1 << offset))
108 return -EINVAL;
109
106 return stmpe_set_altfunc(stmpe, 1 << offset, STMPE_BLOCK_GPIO); 110 return stmpe_set_altfunc(stmpe, 1 << offset, STMPE_BLOCK_GPIO);
107} 111}
108 112
@@ -118,10 +122,10 @@ static struct gpio_chip template_chip = {
118 .can_sleep = 1, 122 .can_sleep = 1,
119}; 123};
120 124
121static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type) 125static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
122{ 126{
123 struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); 127 struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
124 int offset = irq - stmpe_gpio->irq_base; 128 int offset = d->irq - stmpe_gpio->irq_base;
125 int regoffset = offset / 8; 129 int regoffset = offset / 8;
126 int mask = 1 << (offset % 8); 130 int mask = 1 << (offset % 8);
127 131
@@ -141,16 +145,16 @@ static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type)
141 return 0; 145 return 0;
142} 146}
143 147
144static void stmpe_gpio_irq_lock(unsigned int irq) 148static void stmpe_gpio_irq_lock(struct irq_data *d)
145{ 149{
146 struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); 150 struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
147 151
148 mutex_lock(&stmpe_gpio->irq_lock); 152 mutex_lock(&stmpe_gpio->irq_lock);
149} 153}
150 154
151static void stmpe_gpio_irq_sync_unlock(unsigned int irq) 155static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
152{ 156{
153 struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); 157 struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
154 struct stmpe *stmpe = stmpe_gpio->stmpe; 158 struct stmpe *stmpe = stmpe_gpio->stmpe;
155 int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); 159 int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8);
156 static const u8 regmap[] = { 160 static const u8 regmap[] = {
@@ -176,20 +180,20 @@ static void stmpe_gpio_irq_sync_unlock(unsigned int irq)
176 mutex_unlock(&stmpe_gpio->irq_lock); 180 mutex_unlock(&stmpe_gpio->irq_lock);
177} 181}
178 182
179static void stmpe_gpio_irq_mask(unsigned int irq) 183static void stmpe_gpio_irq_mask(struct irq_data *d)
180{ 184{
181 struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); 185 struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
182 int offset = irq - stmpe_gpio->irq_base; 186 int offset = d->irq - stmpe_gpio->irq_base;
183 int regoffset = offset / 8; 187 int regoffset = offset / 8;
184 int mask = 1 << (offset % 8); 188 int mask = 1 << (offset % 8);
185 189
186 stmpe_gpio->regs[REG_IE][regoffset] &= ~mask; 190 stmpe_gpio->regs[REG_IE][regoffset] &= ~mask;
187} 191}
188 192
189static void stmpe_gpio_irq_unmask(unsigned int irq) 193static void stmpe_gpio_irq_unmask(struct irq_data *d)
190{ 194{
191 struct stmpe_gpio *stmpe_gpio = get_irq_chip_data(irq); 195 struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
192 int offset = irq - stmpe_gpio->irq_base; 196 int offset = d->irq - stmpe_gpio->irq_base;
193 int regoffset = offset / 8; 197 int regoffset = offset / 8;
194 int mask = 1 << (offset % 8); 198 int mask = 1 << (offset % 8);
195 199
@@ -198,11 +202,11 @@ static void stmpe_gpio_irq_unmask(unsigned int irq)
198 202
199static struct irq_chip stmpe_gpio_irq_chip = { 203static struct irq_chip stmpe_gpio_irq_chip = {
200 .name = "stmpe-gpio", 204 .name = "stmpe-gpio",
201 .bus_lock = stmpe_gpio_irq_lock, 205 .irq_bus_lock = stmpe_gpio_irq_lock,
202 .bus_sync_unlock = stmpe_gpio_irq_sync_unlock, 206 .irq_bus_sync_unlock = stmpe_gpio_irq_sync_unlock,
203 .mask = stmpe_gpio_irq_mask, 207 .irq_mask = stmpe_gpio_irq_mask,
204 .unmask = stmpe_gpio_irq_unmask, 208 .irq_unmask = stmpe_gpio_irq_unmask,
205 .set_type = stmpe_gpio_irq_set_type, 209 .irq_set_type = stmpe_gpio_irq_set_type,
206}; 210};
207 211
208static irqreturn_t stmpe_gpio_irq(int irq, void *dev) 212static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
@@ -250,14 +254,14 @@ static int __devinit stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio)
250 int irq; 254 int irq;
251 255
252 for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) { 256 for (irq = base; irq < base + stmpe_gpio->chip.ngpio; irq++) {
253 set_irq_chip_data(irq, stmpe_gpio); 257 irq_set_chip_data(irq, stmpe_gpio);
254 set_irq_chip_and_handler(irq, &stmpe_gpio_irq_chip, 258 irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip,
255 handle_simple_irq); 259 handle_simple_irq);
256 set_irq_nested_thread(irq, 1); 260 irq_set_nested_thread(irq, 1);
257#ifdef CONFIG_ARM 261#ifdef CONFIG_ARM
258 set_irq_flags(irq, IRQF_VALID); 262 set_irq_flags(irq, IRQF_VALID);
259#else 263#else
260 set_irq_noprobe(irq); 264 irq_set_noprobe(irq);
261#endif 265#endif
262 } 266 }
263 267
@@ -273,8 +277,8 @@ static void stmpe_gpio_irq_remove(struct stmpe_gpio *stmpe_gpio)
273#ifdef CONFIG_ARM 277#ifdef CONFIG_ARM
274 set_irq_flags(irq, 0); 278 set_irq_flags(irq, 0);
275#endif 279#endif
276 set_irq_chip_and_handler(irq, NULL, NULL); 280 irq_set_chip_and_handler(irq, NULL, NULL);
277 set_irq_chip_data(irq, NULL); 281 irq_set_chip_data(irq, NULL);
278 } 282 }
279} 283}
280 284
@@ -287,8 +291,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
287 int irq; 291 int irq;
288 292
289 pdata = stmpe->pdata->gpio; 293 pdata = stmpe->pdata->gpio;
290 if (!pdata)
291 return -ENODEV;
292 294
293 irq = platform_get_irq(pdev, 0); 295 irq = platform_get_irq(pdev, 0);
294 if (irq < 0) 296 if (irq < 0)
@@ -302,6 +304,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
302 304
303 stmpe_gpio->dev = &pdev->dev; 305 stmpe_gpio->dev = &pdev->dev;
304 stmpe_gpio->stmpe = stmpe; 306 stmpe_gpio->stmpe = stmpe;
307 stmpe_gpio->norequest_mask = pdata ? pdata->norequest_mask : 0;
305 308
306 stmpe_gpio->chip = template_chip; 309 stmpe_gpio->chip = template_chip;
307 stmpe_gpio->chip.ngpio = stmpe->num_gpios; 310 stmpe_gpio->chip.ngpio = stmpe->num_gpios;
@@ -312,11 +315,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
312 315
313 ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); 316 ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
314 if (ret) 317 if (ret)
315 return ret; 318 goto out_free;
316 319
317 ret = stmpe_gpio_irq_init(stmpe_gpio); 320 ret = stmpe_gpio_irq_init(stmpe_gpio);
318 if (ret) 321 if (ret)
319 goto out_free; 322 goto out_disable;
320 323
321 ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT, 324 ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT,
322 "stmpe-gpio", stmpe_gpio); 325 "stmpe-gpio", stmpe_gpio);
@@ -342,6 +345,8 @@ out_freeirq:
342 free_irq(irq, stmpe_gpio); 345 free_irq(irq, stmpe_gpio);
343out_removeirq: 346out_removeirq:
344 stmpe_gpio_irq_remove(stmpe_gpio); 347 stmpe_gpio_irq_remove(stmpe_gpio);
348out_disable:
349 stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
345out_free: 350out_free:
346 kfree(stmpe_gpio); 351 kfree(stmpe_gpio);
347 return ret; 352 return ret;