diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-04-15 17:38:56 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-06-19 03:31:16 -0400 |
commit | fe44e70db0544e24cd1d00fc594b6e5b0afd333b (patch) | |
tree | 1dd57bfffc722c0df8cce675a6657e46201d5a83 | |
parent | 7171511eaec5bf23fb06078f59784a3a0626b38f (diff) |
gpio: stmpe: switch to use gpiolib irqchip helpers
This switches the STMPE driver to use the gpiolib irqchip
helpers.
Tested-by: Silvio Fricke <silvio.fricke@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 111 |
2 files changed, 28 insertions, 84 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4a1b5113e527..690904a93fb4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -573,6 +573,7 @@ config GPIO_SX150X | |||
573 | config GPIO_STMPE | 573 | config GPIO_STMPE |
574 | bool "STMPE GPIOs" | 574 | bool "STMPE GPIOs" |
575 | depends on MFD_STMPE | 575 | depends on MFD_STMPE |
576 | select GPIOLIB_IRQCHIP | ||
576 | help | 577 | help |
577 | This enables support for the GPIOs found on the STMPE I/O | 578 | This enables support for the GPIOs found on the STMPE I/O |
578 | Expanders. | 579 | Expanders. |
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 628b58494294..ed90adbdb128 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -10,8 +10,6 @@ | |||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/irq.h> | ||
14 | #include <linux/irqdomain.h> | ||
15 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
16 | #include <linux/of.h> | 14 | #include <linux/of.h> |
17 | #include <linux/mfd/stmpe.h> | 15 | #include <linux/mfd/stmpe.h> |
@@ -31,9 +29,7 @@ struct stmpe_gpio { | |||
31 | struct stmpe *stmpe; | 29 | struct stmpe *stmpe; |
32 | struct device *dev; | 30 | struct device *dev; |
33 | struct mutex irq_lock; | 31 | struct mutex irq_lock; |
34 | struct irq_domain *domain; | ||
35 | unsigned norequest_mask; | 32 | unsigned norequest_mask; |
36 | |||
37 | /* Caches of interrupt control registers for bus_lock */ | 33 | /* Caches of interrupt control registers for bus_lock */ |
38 | u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; | 34 | u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; |
39 | u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; | 35 | u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; |
@@ -101,13 +97,6 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, | |||
101 | return stmpe_set_bits(stmpe, reg, mask, 0); | 97 | return stmpe_set_bits(stmpe, reg, mask, 0); |
102 | } | 98 | } |
103 | 99 | ||
104 | static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
105 | { | ||
106 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); | ||
107 | |||
108 | return irq_create_mapping(stmpe_gpio->domain, offset); | ||
109 | } | ||
110 | |||
111 | static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) | 100 | static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) |
112 | { | 101 | { |
113 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); | 102 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); |
@@ -126,14 +115,14 @@ static struct gpio_chip template_chip = { | |||
126 | .get = stmpe_gpio_get, | 115 | .get = stmpe_gpio_get, |
127 | .direction_output = stmpe_gpio_direction_output, | 116 | .direction_output = stmpe_gpio_direction_output, |
128 | .set = stmpe_gpio_set, | 117 | .set = stmpe_gpio_set, |
129 | .to_irq = stmpe_gpio_to_irq, | ||
130 | .request = stmpe_gpio_request, | 118 | .request = stmpe_gpio_request, |
131 | .can_sleep = true, | 119 | .can_sleep = true, |
132 | }; | 120 | }; |
133 | 121 | ||
134 | static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 122 | static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
135 | { | 123 | { |
136 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 124 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
125 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
137 | int offset = d->hwirq; | 126 | int offset = d->hwirq; |
138 | int regoffset = offset / 8; | 127 | int regoffset = offset / 8; |
139 | int mask = 1 << (offset % 8); | 128 | int mask = 1 << (offset % 8); |
@@ -160,14 +149,16 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
160 | 149 | ||
161 | static void stmpe_gpio_irq_lock(struct irq_data *d) | 150 | static void stmpe_gpio_irq_lock(struct irq_data *d) |
162 | { | 151 | { |
163 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 152 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
153 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
164 | 154 | ||
165 | mutex_lock(&stmpe_gpio->irq_lock); | 155 | mutex_lock(&stmpe_gpio->irq_lock); |
166 | } | 156 | } |
167 | 157 | ||
168 | static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) | 158 | static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) |
169 | { | 159 | { |
170 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 160 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
161 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
171 | struct stmpe *stmpe = stmpe_gpio->stmpe; | 162 | struct stmpe *stmpe = stmpe_gpio->stmpe; |
172 | int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); | 163 | int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); |
173 | static const u8 regmap[] = { | 164 | static const u8 regmap[] = { |
@@ -200,7 +191,8 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) | |||
200 | 191 | ||
201 | static void stmpe_gpio_irq_mask(struct irq_data *d) | 192 | static void stmpe_gpio_irq_mask(struct irq_data *d) |
202 | { | 193 | { |
203 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 194 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
195 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
204 | int offset = d->hwirq; | 196 | int offset = d->hwirq; |
205 | int regoffset = offset / 8; | 197 | int regoffset = offset / 8; |
206 | int mask = 1 << (offset % 8); | 198 | int mask = 1 << (offset % 8); |
@@ -210,7 +202,8 @@ static void stmpe_gpio_irq_mask(struct irq_data *d) | |||
210 | 202 | ||
211 | static void stmpe_gpio_irq_unmask(struct irq_data *d) | 203 | static void stmpe_gpio_irq_unmask(struct irq_data *d) |
212 | { | 204 | { |
213 | struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); | 205 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
206 | struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); | ||
214 | int offset = d->hwirq; | 207 | int offset = d->hwirq; |
215 | int regoffset = offset / 8; | 208 | int regoffset = offset / 8; |
216 | int mask = 1 << (offset % 8); | 209 | int mask = 1 << (offset % 8); |
@@ -253,7 +246,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
253 | while (stat) { | 246 | while (stat) { |
254 | int bit = __ffs(stat); | 247 | int bit = __ffs(stat); |
255 | int line = bank * 8 + bit; | 248 | int line = bank * 8 + bit; |
256 | int child_irq = irq_find_mapping(stmpe_gpio->domain, | 249 | int child_irq = irq_find_mapping(stmpe_gpio->chip.irqdomain, |
257 | line); | 250 | line); |
258 | 251 | ||
259 | handle_nested_irq(child_irq); | 252 | handle_nested_irq(child_irq); |
@@ -271,56 +264,6 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
271 | return IRQ_HANDLED; | 264 | return IRQ_HANDLED; |
272 | } | 265 | } |
273 | 266 | ||
274 | static int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int irq, | ||
275 | irq_hw_number_t hwirq) | ||
276 | { | ||
277 | struct stmpe_gpio *stmpe_gpio = d->host_data; | ||
278 | |||
279 | if (!stmpe_gpio) | ||
280 | return -EINVAL; | ||
281 | |||
282 | irq_set_chip_data(irq, stmpe_gpio); | ||
283 | irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip, | ||
284 | handle_simple_irq); | ||
285 | irq_set_nested_thread(irq, 1); | ||
286 | #ifdef CONFIG_ARM | ||
287 | set_irq_flags(irq, IRQF_VALID); | ||
288 | #else | ||
289 | irq_set_noprobe(irq); | ||
290 | #endif | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) | ||
296 | { | ||
297 | #ifdef CONFIG_ARM | ||
298 | set_irq_flags(irq, 0); | ||
299 | #endif | ||
300 | irq_set_chip_and_handler(irq, NULL, NULL); | ||
301 | irq_set_chip_data(irq, NULL); | ||
302 | } | ||
303 | |||
304 | static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { | ||
305 | .unmap = stmpe_gpio_irq_unmap, | ||
306 | .map = stmpe_gpio_irq_map, | ||
307 | .xlate = irq_domain_xlate_twocell, | ||
308 | }; | ||
309 | |||
310 | static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio, | ||
311 | struct device_node *np) | ||
312 | { | ||
313 | stmpe_gpio->domain = irq_domain_add_simple(np, | ||
314 | stmpe_gpio->chip.ngpio, 0, | ||
315 | &stmpe_gpio_irq_simple_ops, stmpe_gpio); | ||
316 | if (!stmpe_gpio->domain) { | ||
317 | dev_err(stmpe_gpio->dev, "failed to create irqdomain\n"); | ||
318 | return -ENOSYS; | ||
319 | } | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int stmpe_gpio_probe(struct platform_device *pdev) | 267 | static int stmpe_gpio_probe(struct platform_device *pdev) |
325 | { | 268 | { |
326 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 269 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
@@ -358,30 +301,37 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
358 | 301 | ||
359 | if (irq < 0) | 302 | if (irq < 0) |
360 | dev_info(&pdev->dev, | 303 | dev_info(&pdev->dev, |
361 | "device configured in no-irq mode; " | 304 | "device configured in no-irq mode: " |
362 | "irqs are not available\n"); | 305 | "irqs are not available\n"); |
363 | 306 | ||
364 | ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); | 307 | ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); |
365 | if (ret) | 308 | if (ret) |
366 | goto out_free; | 309 | goto out_free; |
367 | 310 | ||
368 | if (irq >= 0) { | 311 | if (irq > 0) { |
369 | ret = stmpe_gpio_irq_init(stmpe_gpio, np); | 312 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
370 | if (ret) | 313 | stmpe_gpio_irq, IRQF_ONESHOT, |
371 | goto out_disable; | 314 | "stmpe-gpio", stmpe_gpio); |
372 | |||
373 | ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, | ||
374 | IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); | ||
375 | if (ret) { | 315 | if (ret) { |
376 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | 316 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); |
377 | goto out_disable; | 317 | goto out_disable; |
378 | } | 318 | } |
319 | ret = gpiochip_irqchip_add(&stmpe_gpio->chip, | ||
320 | &stmpe_gpio_irq_chip, | ||
321 | 0, | ||
322 | handle_simple_irq, | ||
323 | IRQ_TYPE_NONE); | ||
324 | if (ret) { | ||
325 | dev_err(&pdev->dev, | ||
326 | "could not connect irqchip to gpiochip\n"); | ||
327 | return ret; | ||
328 | } | ||
379 | } | 329 | } |
380 | 330 | ||
381 | ret = gpiochip_add(&stmpe_gpio->chip); | 331 | ret = gpiochip_add(&stmpe_gpio->chip); |
382 | if (ret) { | 332 | if (ret) { |
383 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); | 333 | dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); |
384 | goto out_freeirq; | 334 | goto out_disable; |
385 | } | 335 | } |
386 | 336 | ||
387 | if (pdata && pdata->setup) | 337 | if (pdata && pdata->setup) |
@@ -391,9 +341,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
391 | 341 | ||
392 | return 0; | 342 | return 0; |
393 | 343 | ||
394 | out_freeirq: | ||
395 | if (irq >= 0) | ||
396 | free_irq(irq, stmpe_gpio); | ||
397 | out_disable: | 344 | out_disable: |
398 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | 345 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); |
399 | out_free: | 346 | out_free: |
@@ -406,7 +353,6 @@ static int stmpe_gpio_remove(struct platform_device *pdev) | |||
406 | struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); | 353 | struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); |
407 | struct stmpe *stmpe = stmpe_gpio->stmpe; | 354 | struct stmpe *stmpe = stmpe_gpio->stmpe; |
408 | struct stmpe_gpio_platform_data *pdata = stmpe->pdata->gpio; | 355 | struct stmpe_gpio_platform_data *pdata = stmpe->pdata->gpio; |
409 | int irq = platform_get_irq(pdev, 0); | ||
410 | int ret; | 356 | int ret; |
411 | 357 | ||
412 | if (pdata && pdata->remove) | 358 | if (pdata && pdata->remove) |
@@ -421,9 +367,6 @@ static int stmpe_gpio_remove(struct platform_device *pdev) | |||
421 | 367 | ||
422 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); | 368 | stmpe_disable(stmpe, STMPE_BLOCK_GPIO); |
423 | 369 | ||
424 | if (irq >= 0) | ||
425 | free_irq(irq, stmpe_gpio); | ||
426 | |||
427 | kfree(stmpe_gpio); | 370 | kfree(stmpe_gpio); |
428 | 371 | ||
429 | return 0; | 372 | return 0; |