gpio: eic-sprd: Clear interrupt after set the interrupt type
[platform/kernel/linux-rpi.git] / drivers / gpio / gpio-eic-sprd.c
index 5320cf1..b24e349 100644 (file)
@@ -321,20 +321,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
                switch (flow_type) {
                case IRQ_TYPE_LEVEL_HIGH:
                        sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1);
                        break;
                case IRQ_TYPE_LEVEL_LOW:
                        sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1);
                        break;
                case IRQ_TYPE_EDGE_RISING:
                case IRQ_TYPE_EDGE_FALLING:
                case IRQ_TYPE_EDGE_BOTH:
                        state = sprd_eic_get(chip, offset);
-                       if (state)
+                       if (state) {
                                sprd_eic_update(chip, offset,
                                                SPRD_EIC_DBNC_IEV, 0);
-                       else
+                               sprd_eic_update(chip, offset,
+                                               SPRD_EIC_DBNC_IC, 1);
+                       } else {
                                sprd_eic_update(chip, offset,
                                                SPRD_EIC_DBNC_IEV, 1);
+                               sprd_eic_update(chip, offset,
+                                               SPRD_EIC_DBNC_IC, 1);
+                       }
                        break;
                default:
                        return -ENOTSUPP;
@@ -346,20 +353,27 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
                switch (flow_type) {
                case IRQ_TYPE_LEVEL_HIGH:
                        sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1);
                        break;
                case IRQ_TYPE_LEVEL_LOW:
                        sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1);
                        break;
                case IRQ_TYPE_EDGE_RISING:
                case IRQ_TYPE_EDGE_FALLING:
                case IRQ_TYPE_EDGE_BOTH:
                        state = sprd_eic_get(chip, offset);
-                       if (state)
+                       if (state) {
                                sprd_eic_update(chip, offset,
                                                SPRD_EIC_LATCH_INTPOL, 0);
-                       else
+                               sprd_eic_update(chip, offset,
+                                               SPRD_EIC_LATCH_INTCLR, 1);
+                       } else {
                                sprd_eic_update(chip, offset,
                                                SPRD_EIC_LATCH_INTPOL, 1);
+                               sprd_eic_update(chip, offset,
+                                               SPRD_EIC_LATCH_INTCLR, 1);
+                       }
                        break;
                default:
                        return -ENOTSUPP;
@@ -373,29 +387,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_EDGE_FALLING:
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_EDGE_BOTH:
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_LEVEL_HIGH:
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_level_irq);
                        break;
                case IRQ_TYPE_LEVEL_LOW:
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1);
                        sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_level_irq);
                        break;
                default:
@@ -408,29 +427,34 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_EDGE_FALLING:
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_EDGE_BOTH:
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_edge_irq);
                        break;
                case IRQ_TYPE_LEVEL_HIGH:
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1);
+                       sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_level_irq);
                        break;
                case IRQ_TYPE_LEVEL_LOW:
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1);
                        sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0);
+                       sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1);
                        irq_set_handler_locked(data, handle_level_irq);
                        break;
                default: