aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-lynxpoint.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2014-07-25 02:54:46 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-07-28 06:23:56 -0400
commit7f87210eff7a26a0215b493e9dd7322b16d8dc72 (patch)
tree1bdf99aaab68b8cc1088cb33040fead683cbac7c /drivers/gpio/gpio-lynxpoint.c
parent0a6d315827eedc733d404ecff3cd4cc0e6437865 (diff)
gpio: lynxpoint: Convert to use gpiolib irqchip
Instead of open-coding irqchip handling in the driver we can take advantage of the new irqchip helpers provided by the gpiolib core. While doing this we also make sure that we call gpiochip_irqchip_add() after the gpiochip itself is registered as required. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-lynxpoint.c')
-rw-r--r--drivers/gpio/gpio-lynxpoint.c93
1 files changed, 25 insertions, 68 deletions
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c
index 7c141dd850a1..ff9eb911b5e4 100644
--- a/drivers/gpio/gpio-lynxpoint.c
+++ b/drivers/gpio/gpio-lynxpoint.c
@@ -25,9 +25,7 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/bitops.h> 26#include <linux/bitops.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/irq.h>
29#include <linux/gpio.h> 28#include <linux/gpio.h>
30#include <linux/irqdomain.h>
31#include <linux/slab.h> 29#include <linux/slab.h>
32#include <linux/acpi.h> 30#include <linux/acpi.h>
33#include <linux/platform_device.h> 31#include <linux/platform_device.h>
@@ -62,7 +60,6 @@
62 60
63struct lp_gpio { 61struct lp_gpio {
64 struct gpio_chip chip; 62 struct gpio_chip chip;
65 struct irq_domain *domain;
66 struct platform_device *pdev; 63 struct platform_device *pdev;
67 spinlock_t lock; 64 spinlock_t lock;
68 unsigned long reg_base; 65 unsigned long reg_base;
@@ -151,7 +148,8 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
151 148
152static int lp_irq_type(struct irq_data *d, unsigned type) 149static int lp_irq_type(struct irq_data *d, unsigned type)
153{ 150{
154 struct lp_gpio *lg = irq_data_get_irq_chip_data(d); 151 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
152 struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
155 u32 hwirq = irqd_to_hwirq(d); 153 u32 hwirq = irqd_to_hwirq(d);
156 unsigned long flags; 154 unsigned long flags;
157 u32 value; 155 u32 value;
@@ -236,16 +234,11 @@ static int lp_gpio_direction_output(struct gpio_chip *chip,
236 return 0; 234 return 0;
237} 235}
238 236
239static int lp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
240{
241 struct lp_gpio *lg = container_of(chip, struct lp_gpio, chip);
242 return irq_create_mapping(lg->domain, offset);
243}
244
245static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) 237static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
246{ 238{
247 struct irq_data *data = irq_desc_get_irq_data(desc); 239 struct irq_data *data = irq_desc_get_irq_data(desc);
248 struct lp_gpio *lg = irq_data_get_irq_handler_data(data); 240 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
241 struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
249 struct irq_chip *chip = irq_data_get_irq_chip(data); 242 struct irq_chip *chip = irq_data_get_irq_chip(data);
250 u32 base, pin, mask; 243 u32 base, pin, mask;
251 unsigned long reg, ena, pending; 244 unsigned long reg, ena, pending;
@@ -262,7 +255,7 @@ static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
262 mask = BIT(pin); 255 mask = BIT(pin);
263 /* Clear before handling so we don't lose an edge */ 256 /* Clear before handling so we don't lose an edge */
264 outl(mask, reg); 257 outl(mask, reg);
265 irq = irq_find_mapping(lg->domain, base + pin); 258 irq = irq_find_mapping(lg->chip.irqdomain, base + pin);
266 generic_handle_irq(irq); 259 generic_handle_irq(irq);
267 } 260 }
268 } 261 }
@@ -279,7 +272,8 @@ static void lp_irq_mask(struct irq_data *d)
279 272
280static void lp_irq_enable(struct irq_data *d) 273static void lp_irq_enable(struct irq_data *d)
281{ 274{
282 struct lp_gpio *lg = irq_data_get_irq_chip_data(d); 275 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
276 struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
283 u32 hwirq = irqd_to_hwirq(d); 277 u32 hwirq = irqd_to_hwirq(d);
284 unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); 278 unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
285 unsigned long flags; 279 unsigned long flags;
@@ -291,7 +285,8 @@ static void lp_irq_enable(struct irq_data *d)
291 285
292static void lp_irq_disable(struct irq_data *d) 286static void lp_irq_disable(struct irq_data *d)
293{ 287{
294 struct lp_gpio *lg = irq_data_get_irq_chip_data(d); 288 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
289 struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
295 u32 hwirq = irqd_to_hwirq(d); 290 u32 hwirq = irqd_to_hwirq(d);
296 unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); 291 unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
297 unsigned long flags; 292 unsigned long flags;
@@ -301,26 +296,6 @@ static void lp_irq_disable(struct irq_data *d)
301 spin_unlock_irqrestore(&lg->lock, flags); 296 spin_unlock_irqrestore(&lg->lock, flags);
302} 297}
303 298
304static int lp_irq_reqres(struct irq_data *d)
305{
306 struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
307
308 if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d))) {
309 dev_err(lg->chip.dev,
310 "unable to lock HW IRQ %lu for IRQ\n",
311 irqd_to_hwirq(d));
312 return -EINVAL;
313 }
314 return 0;
315}
316
317static void lp_irq_relres(struct irq_data *d)
318{
319 struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
320
321 gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d));
322}
323
324static struct irq_chip lp_irqchip = { 299static struct irq_chip lp_irqchip = {
325 .name = "LP-GPIO", 300 .name = "LP-GPIO",
326 .irq_mask = lp_irq_mask, 301 .irq_mask = lp_irq_mask,
@@ -328,8 +303,6 @@ static struct irq_chip lp_irqchip = {
328 .irq_enable = lp_irq_enable, 303 .irq_enable = lp_irq_enable,
329 .irq_disable = lp_irq_disable, 304 .irq_disable = lp_irq_disable,
330 .irq_set_type = lp_irq_type, 305 .irq_set_type = lp_irq_type,
331 .irq_request_resources = lp_irq_reqres,
332 .irq_release_resources = lp_irq_relres,
333 .flags = IRQCHIP_SKIP_SET_WAKE, 306 .flags = IRQCHIP_SKIP_SET_WAKE,
334}; 307};
335 308
@@ -348,22 +321,6 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg)
348 } 321 }
349} 322}
350 323
351static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq,
352 irq_hw_number_t hwirq)
353{
354 struct lp_gpio *lg = d->host_data;
355
356 irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq);
357 irq_set_chip_data(irq, lg);
358 irq_set_irq_type(irq, IRQ_TYPE_NONE);
359
360 return 0;
361}
362
363static const struct irq_domain_ops lp_gpio_irq_ops = {
364 .map = lp_gpio_irq_map,
365};
366
367static int lp_gpio_probe(struct platform_device *pdev) 324static int lp_gpio_probe(struct platform_device *pdev)
368{ 325{
369 struct lp_gpio *lg; 326 struct lp_gpio *lg;
@@ -371,7 +328,6 @@ static int lp_gpio_probe(struct platform_device *pdev)
371 struct resource *io_rc, *irq_rc; 328 struct resource *io_rc, *irq_rc;
372 struct device *dev = &pdev->dev; 329 struct device *dev = &pdev->dev;
373 unsigned long reg_len; 330 unsigned long reg_len;
374 unsigned hwirq;
375 int ret = -ENODEV; 331 int ret = -ENODEV;
376 332
377 lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); 333 lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
@@ -414,27 +370,28 @@ static int lp_gpio_probe(struct platform_device *pdev)
414 gc->can_sleep = false; 370 gc->can_sleep = false;
415 gc->dev = dev; 371 gc->dev = dev;
416 372
373 ret = gpiochip_add(gc);
374 if (ret) {
375 dev_err(dev, "failed adding lp-gpio chip\n");
376 return ret;
377 }
378
417 /* set up interrupts */ 379 /* set up interrupts */
418 if (irq_rc && irq_rc->start) { 380 if (irq_rc && irq_rc->start) {
419 hwirq = irq_rc->start;
420 gc->to_irq = lp_gpio_to_irq;
421
422 lg->domain = irq_domain_add_linear(NULL, LP_NUM_GPIO,
423 &lp_gpio_irq_ops, lg);
424 if (!lg->domain)
425 return -ENXIO;
426
427 lp_gpio_irq_init_hw(lg); 381 lp_gpio_irq_init_hw(lg);
382 ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0,
383 handle_simple_irq, IRQ_TYPE_NONE);
384 if (ret) {
385 dev_err(dev, "failed to add irqchip\n");
386 gpiochip_remove(gc);
387 return ret;
388 }
428 389
429 irq_set_handler_data(hwirq, lg); 390 gpiochip_set_chained_irqchip(gc, &lp_irqchip,
430 irq_set_chained_handler(hwirq, lp_gpio_irq_handler); 391 (unsigned)irq_rc->start,
392 lp_gpio_irq_handler);
431 } 393 }
432 394
433 ret = gpiochip_add(gc);
434 if (ret) {
435 dev_err(dev, "failed adding lp-gpio chip\n");
436 return ret;
437 }
438 pm_runtime_enable(dev); 395 pm_runtime_enable(dev);
439 396
440 return 0; 397 return 0;