Skip to content

Commit 84aef4e

Browse files
Wenhua LinBartosz Golaszewski
authored andcommitted
gpio: eic-sprd: Clear interrupt after set the interrupt type
The raw interrupt status of eic maybe set before the interrupt is enabled, since the eic interrupt has a latch function, which would trigger the interrupt event once enabled it from user side. To solve this problem, interrupts generated before setting the interrupt trigger type are ignored. Fixes: 25518e0 ("gpio: Add Spreadtrum EIC driver support") Acked-by: Chunyan Zhang <[email protected]> Signed-off-by: Wenhua Lin <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 805c74e commit 84aef4e

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

drivers/gpio/gpio-eic-sprd.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,20 +330,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
330330
switch (flow_type) {
331331
case IRQ_TYPE_LEVEL_HIGH:
332332
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1);
333+
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1);
333334
break;
334335
case IRQ_TYPE_LEVEL_LOW:
335336
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0);
337+
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1);
336338
break;
337339
case IRQ_TYPE_EDGE_RISING:
338340
case IRQ_TYPE_EDGE_FALLING:
339341
case IRQ_TYPE_EDGE_BOTH:
340342
state = sprd_eic_get(chip, offset);
341-
if (state)
343+
if (state) {
342344
sprd_eic_update(chip, offset,
343345
SPRD_EIC_DBNC_IEV, 0);
344-
else
346+
sprd_eic_update(chip, offset,
347+
SPRD_EIC_DBNC_IC, 1);
348+
} else {
345349
sprd_eic_update(chip, offset,
346350
SPRD_EIC_DBNC_IEV, 1);
351+
sprd_eic_update(chip, offset,
352+
SPRD_EIC_DBNC_IC, 1);
353+
}
347354
break;
348355
default:
349356
return -ENOTSUPP;
@@ -355,20 +362,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
355362
switch (flow_type) {
356363
case IRQ_TYPE_LEVEL_HIGH:
357364
sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0);
365+
sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1);
358366
break;
359367
case IRQ_TYPE_LEVEL_LOW:
360368
sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1);
369+
sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1);
361370
break;
362371
case IRQ_TYPE_EDGE_RISING:
363372
case IRQ_TYPE_EDGE_FALLING:
364373
case IRQ_TYPE_EDGE_BOTH:
365374
state = sprd_eic_get(chip, offset);
366-
if (state)
375+
if (state) {
367376
sprd_eic_update(chip, offset,
368377
SPRD_EIC_LATCH_INTPOL, 0);
369-
else
378+
sprd_eic_update(chip, offset,
379+
SPRD_EIC_LATCH_INTCLR, 1);
380+
} else {
370381
sprd_eic_update(chip, offset,
371382
SPRD_EIC_LATCH_INTPOL, 1);
383+
sprd_eic_update(chip, offset,
384+
SPRD_EIC_LATCH_INTCLR, 1);
385+
}
372386
break;
373387
default:
374388
return -ENOTSUPP;
@@ -382,29 +396,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
382396
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
383397
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
384398
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
399+
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
385400
irq_set_handler_locked(data, handle_edge_irq);
386401
break;
387402
case IRQ_TYPE_EDGE_FALLING:
388403
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
389404
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
390405
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
406+
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
391407
irq_set_handler_locked(data, handle_edge_irq);
392408
break;
393409
case IRQ_TYPE_EDGE_BOTH:
394410
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
395411
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
412+
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
396413
irq_set_handler_locked(data, handle_edge_irq);
397414
break;
398415
case IRQ_TYPE_LEVEL_HIGH:
399416
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
400417
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
401418
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
419+
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
402420
irq_set_handler_locked(data, handle_level_irq);
403421
break;
404422
case IRQ_TYPE_LEVEL_LOW:
405423
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
406424
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
407425
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
426+
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
408427
irq_set_handler_locked(data, handle_level_irq);
409428
break;
410429
default:
@@ -417,29 +436,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
417436
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
418437
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
419438
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
439+
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
420440
irq_set_handler_locked(data, handle_edge_irq);
421441
break;
422442
case IRQ_TYPE_EDGE_FALLING:
423443
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
424444
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
425445
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
446+
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
426447
irq_set_handler_locked(data, handle_edge_irq);
427448
break;
428449
case IRQ_TYPE_EDGE_BOTH:
429450
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
430451
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1);
452+
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
431453
irq_set_handler_locked(data, handle_edge_irq);
432454
break;
433455
case IRQ_TYPE_LEVEL_HIGH:
434456
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
435457
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
436458
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
459+
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
437460
irq_set_handler_locked(data, handle_level_irq);
438461
break;
439462
case IRQ_TYPE_LEVEL_LOW:
440463
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
441464
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
442465
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
466+
sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
443467
irq_set_handler_locked(data, handle_level_irq);
444468
break;
445469
default:

0 commit comments

Comments
 (0)