2929#define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */
3030#define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */
3131
32+ #define TQMX86_GPII_NONE 0
3233#define TQMX86_GPII_FALLING BIT(0)
3334#define TQMX86_GPII_RISING BIT(1)
3435#define TQMX86_GPII_MASK (BIT(0) | BIT(1))
3536#define TQMX86_GPII_BITS 2
37+ /* Stored in irq_type with GPII bits */
38+ #define TQMX86_INT_UNMASKED BIT(2)
3639
3740struct tqmx86_gpio_data {
3841 struct gpio_chip chip ;
3942 void __iomem * io_base ;
4043 int irq ;
44+ /* Lock must be held for accessing output and irq_type fields */
4145 raw_spinlock_t spinlock ;
4246 DECLARE_BITMAP (output , TQMX86_NGPIO );
4347 u8 irq_type [TQMX86_NGPI ];
@@ -104,21 +108,32 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
104108 return GPIO_LINE_DIRECTION_OUT ;
105109}
106110
111+ static void tqmx86_gpio_irq_config (struct tqmx86_gpio_data * gpio , int offset )
112+ __must_hold (& gpio - > spinlock )
113+ {
114+ u8 type = TQMX86_GPII_NONE , gpiic ;
115+
116+ if (gpio -> irq_type [offset ] & TQMX86_INT_UNMASKED )
117+ type = gpio -> irq_type [offset ] & TQMX86_GPII_MASK ;
118+
119+ gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
120+ gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS ));
121+ gpiic |= type << (offset * TQMX86_GPII_BITS );
122+ tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
123+ }
124+
107125static void tqmx86_gpio_irq_mask (struct irq_data * data )
108126{
109127 unsigned int offset = (data -> hwirq - TQMX86_NGPO );
110128 struct tqmx86_gpio_data * gpio = gpiochip_get_data (
111129 irq_data_get_irq_chip_data (data ));
112130 unsigned long flags ;
113- u8 gpiic , mask ;
114-
115- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS );
116131
117132 raw_spin_lock_irqsave (& gpio -> spinlock , flags );
118- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
119- gpiic &= ~mask ;
120- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
133+ gpio -> irq_type [offset ] &= ~TQMX86_INT_UNMASKED ;
134+ tqmx86_gpio_irq_config (gpio , offset );
121135 raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
136+
122137 gpiochip_disable_irq (& gpio -> chip , irqd_to_hwirq (data ));
123138}
124139
@@ -128,16 +143,12 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
128143 struct tqmx86_gpio_data * gpio = gpiochip_get_data (
129144 irq_data_get_irq_chip_data (data ));
130145 unsigned long flags ;
131- u8 gpiic , mask ;
132-
133- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS );
134146
135147 gpiochip_enable_irq (& gpio -> chip , irqd_to_hwirq (data ));
148+
136149 raw_spin_lock_irqsave (& gpio -> spinlock , flags );
137- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
138- gpiic &= ~mask ;
139- gpiic |= gpio -> irq_type [offset ] << (offset * TQMX86_GPII_BITS );
140- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
150+ gpio -> irq_type [offset ] |= TQMX86_INT_UNMASKED ;
151+ tqmx86_gpio_irq_config (gpio , offset );
141152 raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
142153}
143154
@@ -148,7 +159,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
148159 unsigned int offset = (data -> hwirq - TQMX86_NGPO );
149160 unsigned int edge_type = type & IRQF_TRIGGER_MASK ;
150161 unsigned long flags ;
151- u8 new_type , gpiic ;
162+ u8 new_type ;
152163
153164 switch (edge_type ) {
154165 case IRQ_TYPE_EDGE_RISING :
@@ -164,13 +175,10 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
164175 return - EINVAL ; /* not supported */
165176 }
166177
167- gpio -> irq_type [offset ] = new_type ;
168-
169178 raw_spin_lock_irqsave (& gpio -> spinlock , flags );
170- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
171- gpiic &= ~((TQMX86_GPII_MASK ) << (offset * TQMX86_GPII_BITS ));
172- gpiic |= new_type << (offset * TQMX86_GPII_BITS );
173- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
179+ gpio -> irq_type [offset ] &= ~TQMX86_GPII_MASK ;
180+ gpio -> irq_type [offset ] |= new_type ;
181+ tqmx86_gpio_irq_config (gpio , offset );
174182 raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
175183
176184 return 0 ;
0 commit comments