diff options
Diffstat (limited to 'drivers/gpio/stmpe-gpio.c')
-rw-r--r-- | drivers/gpio/stmpe-gpio.c | 61 |
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 | ||
121 | static int stmpe_gpio_irq_set_type(unsigned int irq, unsigned int type) | 125 | static 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 | ||
144 | static void stmpe_gpio_irq_lock(unsigned int irq) | 148 | static 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 | ||
151 | static void stmpe_gpio_irq_sync_unlock(unsigned int irq) | 155 | static 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 | ||
179 | static void stmpe_gpio_irq_mask(unsigned int irq) | 183 | static 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 | ||
189 | static void stmpe_gpio_irq_unmask(unsigned int irq) | 193 | static 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 | ||
199 | static struct irq_chip stmpe_gpio_irq_chip = { | 203 | static 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 | ||
208 | static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | 212 | static 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); |
343 | out_removeirq: | 346 | out_removeirq: |
344 | stmpe_gpio_irq_remove(stmpe_gpio); | 347 | stmpe_gpio_irq_remove(stmpe_gpio); |
348 | out_disable: | ||
349 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | ||
345 | out_free: | 350 | out_free: |
346 | kfree(stmpe_gpio); | 351 | kfree(stmpe_gpio); |
347 | return ret; | 352 | return ret; |