diff options
Diffstat (limited to 'drivers/gpio/gpio-zynq.c')
-rw-r--r-- | drivers/gpio/gpio-zynq.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index c0c53fdbf07d..c3145f91fda3 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
@@ -301,6 +301,48 @@ static void zynq_gpio_irq_unmask(struct irq_data *irq_data) | |||
301 | } | 301 | } |
302 | 302 | ||
303 | /** | 303 | /** |
304 | * zynq_gpio_irq_ack - Acknowledge the interrupt of a gpio pin | ||
305 | * @irq_data: irq data containing irq number of gpio pin for the interrupt | ||
306 | * to ack | ||
307 | * | ||
308 | * This function calculates gpio pin number from irq number and sets the bit | ||
309 | * in the Interrupt Status Register of the corresponding bank, to ACK the irq. | ||
310 | */ | ||
311 | static void zynq_gpio_irq_ack(struct irq_data *irq_data) | ||
312 | { | ||
313 | unsigned int device_pin_num, bank_num, bank_pin_num; | ||
314 | struct zynq_gpio *gpio = irq_data_get_irq_chip_data(irq_data); | ||
315 | |||
316 | device_pin_num = irq_data->hwirq; | ||
317 | zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num); | ||
318 | writel_relaxed(BIT(bank_pin_num), | ||
319 | gpio->base_addr + ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * zynq_gpio_irq_enable - Enable the interrupts for a gpio pin | ||
324 | * @irq_data: irq data containing irq number of gpio pin for the interrupt | ||
325 | * to enable | ||
326 | * | ||
327 | * Clears the INTSTS bit and unmasks the given interrrupt. | ||
328 | */ | ||
329 | static void zynq_gpio_irq_enable(struct irq_data *irq_data) | ||
330 | { | ||
331 | /* | ||
332 | * The Zynq GPIO controller does not disable interrupt detection when | ||
333 | * the interrupt is masked and only disables the propagation of the | ||
334 | * interrupt. This means when the controller detects an interrupt | ||
335 | * condition while the interrupt is logically disabled it will propagate | ||
336 | * that interrupt event once the interrupt is enabled. This will cause | ||
337 | * the interrupt consumer to see spurious interrupts to prevent this | ||
338 | * first make sure that the interrupt is not asserted and then enable | ||
339 | * it. | ||
340 | */ | ||
341 | zynq_gpio_irq_ack(irq_data); | ||
342 | zynq_gpio_irq_unmask(irq_data); | ||
343 | } | ||
344 | |||
345 | /** | ||
304 | * zynq_gpio_set_irq_type - Set the irq type for a gpio pin | 346 | * zynq_gpio_set_irq_type - Set the irq type for a gpio pin |
305 | * @irq_data: irq data containing irq number of gpio pin | 347 | * @irq_data: irq data containing irq number of gpio pin |
306 | * @type: interrupt type that is to be set for the gpio pin | 348 | * @type: interrupt type that is to be set for the gpio pin |
@@ -384,6 +426,7 @@ static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) | |||
384 | /* irq chip descriptor */ | 426 | /* irq chip descriptor */ |
385 | static struct irq_chip zynq_gpio_irqchip = { | 427 | static struct irq_chip zynq_gpio_irqchip = { |
386 | .name = DRIVER_NAME, | 428 | .name = DRIVER_NAME, |
429 | .irq_enable = zynq_gpio_irq_enable, | ||
387 | .irq_mask = zynq_gpio_irq_mask, | 430 | .irq_mask = zynq_gpio_irq_mask, |
388 | .irq_unmask = zynq_gpio_irq_unmask, | 431 | .irq_unmask = zynq_gpio_irq_unmask, |
389 | .irq_set_type = zynq_gpio_set_irq_type, | 432 | .irq_set_type = zynq_gpio_set_irq_type, |