aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOctavian Purdila <octavian.purdila@intel.com>2014-12-16 10:57:12 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-01-07 04:37:44 -0500
commit0acb0e712b57b4bcabc5fdcb3e445cfce0f80340 (patch)
tree45b7f1382025d6f175c1d2134e1f6b32d148ba28
parentb7392d2247cfe6771f95d256374f1a8e6a6f48d6 (diff)
gpio: dln2: fix issue when an IRQ is unmasked then enabled
As noticed during suspend/resume operations, the IRQ can be unmasked then disabled in suspend and eventually enabled in resume, but without being unmasked. The current implementation does not take into account interactions between mask/unmask and enable/disable interrupts, and thus in the above scenarios the IRQs remain unactive. To fix this we removed the enable/disable operations as they fallback to mask/unmask anyway. We also remove the pending bitmaks as it is already done in irq_data (i.e. IRQS_PENDING). Signed-off-by: Octavian Purdila <octavian.purdila@intel.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/gpio-dln2.c53
1 files changed, 7 insertions, 46 deletions
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c
index 978b51eae2ec..28a62c48ecba 100644
--- a/drivers/gpio/gpio-dln2.c
+++ b/drivers/gpio/gpio-dln2.c
@@ -64,9 +64,8 @@ struct dln2_gpio {
64 */ 64 */
65 DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); 65 DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);
66 66
67 DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS); 67 /* active IRQs - not synced to hardware */
68 DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS); 68 DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS);
69 DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS);
70 struct dln2_irq_work *irq_work; 69 struct dln2_irq_work *irq_work;
71}; 70};
72 71
@@ -303,29 +302,19 @@ static void dln2_irq_work(struct work_struct *w)
303 struct dln2_gpio *dln2 = iw->dln2; 302 struct dln2_gpio *dln2 = iw->dln2;
304 u8 type = iw->type & DLN2_GPIO_EVENT_MASK; 303 u8 type = iw->type & DLN2_GPIO_EVENT_MASK;
305 304
306 if (test_bit(iw->pin, dln2->irqs_enabled)) 305 if (test_bit(iw->pin, dln2->unmasked_irqs))
307 dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0); 306 dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0);
308 else 307 else
309 dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0); 308 dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0);
310} 309}
311 310
312static void dln2_irq_enable(struct irq_data *irqd) 311static void dln2_irq_unmask(struct irq_data *irqd)
313{
314 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
315 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
316 int pin = irqd_to_hwirq(irqd);
317
318 set_bit(pin, dln2->irqs_enabled);
319 schedule_work(&dln2->irq_work[pin].work);
320}
321
322static void dln2_irq_disable(struct irq_data *irqd)
323{ 312{
324 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); 313 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
325 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); 314 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
326 int pin = irqd_to_hwirq(irqd); 315 int pin = irqd_to_hwirq(irqd);
327 316
328 clear_bit(pin, dln2->irqs_enabled); 317 set_bit(pin, dln2->unmasked_irqs);
329 schedule_work(&dln2->irq_work[pin].work); 318 schedule_work(&dln2->irq_work[pin].work);
330} 319}
331 320
@@ -335,27 +324,8 @@ static void dln2_irq_mask(struct irq_data *irqd)
335 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); 324 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
336 int pin = irqd_to_hwirq(irqd); 325 int pin = irqd_to_hwirq(irqd);
337 326
338 set_bit(pin, dln2->irqs_masked); 327 clear_bit(pin, dln2->unmasked_irqs);
339} 328 schedule_work(&dln2->irq_work[pin].work);
340
341static void dln2_irq_unmask(struct irq_data *irqd)
342{
343 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
344 struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
345 struct device *dev = dln2->gpio.dev;
346 int pin = irqd_to_hwirq(irqd);
347
348 if (test_and_clear_bit(pin, dln2->irqs_pending)) {
349 int irq;
350
351 irq = irq_find_mapping(dln2->gpio.irqdomain, pin);
352 if (!irq) {
353 dev_err(dev, "pin %d not mapped to IRQ\n", pin);
354 return;
355 }
356
357 generic_handle_irq(irq);
358 }
359} 329}
360 330
361static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) 331static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
@@ -389,8 +359,6 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
389 359
390static struct irq_chip dln2_gpio_irqchip = { 360static struct irq_chip dln2_gpio_irqchip = {
391 .name = "dln2-irq", 361 .name = "dln2-irq",
392 .irq_enable = dln2_irq_enable,
393 .irq_disable = dln2_irq_disable,
394 .irq_mask = dln2_irq_mask, 362 .irq_mask = dln2_irq_mask,
395 .irq_unmask = dln2_irq_unmask, 363 .irq_unmask = dln2_irq_unmask,
396 .irq_set_type = dln2_irq_set_type, 364 .irq_set_type = dln2_irq_set_type,
@@ -425,13 +393,6 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
425 return; 393 return;
426 } 394 }
427 395
428 if (!test_bit(pin, dln2->irqs_enabled))
429 return;
430 if (test_bit(pin, dln2->irqs_masked)) {
431 set_bit(pin, dln2->irqs_pending);
432 return;
433 }
434
435 switch (dln2->irq_work[pin].type) { 396 switch (dln2->irq_work[pin].type) {
436 case DLN2_GPIO_EVENT_CHANGE_RISING: 397 case DLN2_GPIO_EVENT_CHANGE_RISING:
437 if (event->value) 398 if (event->value)