aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-zynq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-zynq.c')
-rw-r--r--drivers/gpio/gpio-zynq.c43
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 */
311static 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 */
329static 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 */
385static struct irq_chip zynq_gpio_irqchip = { 427static 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,