int ara_key_enable(const struct ara_board_info *info, int (*longpress_callback)(void *priv), bool enable) { if (enable) { if (!info->ara_key_configured) { dbg_error("%s: no ara key gpio defined\n", __func__); return -EINVAL; } the_ara_key.longpress_callback = longpress_callback; the_ara_key.db.gpio = info->ara_key_gpio; the_ara_key.db.ms = ARA_KEY_DEBOUNCE_TIME_MS; the_ara_key.db.isr = ara_key_irqhandler; the_ara_key.db.db_state = DB_ST_INVALID; the_ara_key.rising_edge = info->ara_key_rising_edge; gpio_activate(info->ara_key_gpio); gpio_direction_in(info->ara_key_gpio); gpio_irq_mask(info->ara_key_gpio); gpio_irq_settriggering(info->ara_key_gpio, IRQ_TYPE_EDGE_BOTH); gpio_irq_attach(info->ara_key_gpio, ara_key_irqhandler); } else { gpio_irq_mask(info->ara_key_gpio); gpio_deactivate(info->ara_key_gpio); } return OK; }
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { unsigned pin; struct irq_desc *gpio; struct at91_gpio_bank *bank; void __iomem *pio; u32 isr; bank = get_irq_chip_data(irq); pio = bank->regbase; /* temporarily mask (level sensitive) parent IRQ */ desc->chip->ack(irq); for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * When there none are pending, we're finished unless we need * to process multiple banks (like ID_PIOCDE on sam9263). */ isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); if (!isr) { if (!bank->next) break; bank = bank->next; pio = bank->regbase; continue; } pin = bank->chipbase; gpio = &irq_desc[pin]; while (isr) { if (isr & 1) { if (unlikely(gpio->depth)) { /* * The core ARM interrupt handler lazily disables IRQs so * another IRQ must be generated before it actually gets * here to be disabled on the GPIO controller. */ gpio_irq_mask(pin); } else desc_handle_irq(pin, gpio); } pin++; gpio++; isr >>= 1; } } desc->chip->unmask(irq); /* now it may re-trigger */ }
static void fh_gpio_interrupt(int irq, void *param) { rt_uint32_t irq_status; int gpio_num, gpio; rt_uint32_t base; // struct fh_gpio_obj *gpio_obj = (struct fh_gpio_obj *)param; // rt_kprintf("fh_gpio_interrupt start\n"); // fixme: spin lock??? base = (irq == 40) ? GPIO0_REG_BASE : GPIO1_REG_BASE; irq_status = GET_REG(base + REG_GPIO_INTSTATUS); if (irq_status == 0) { rt_kprintf("gpio irq status is zero.\n"); return; } /* temporarily mask (level sensitive) parent IRQ */ gpio_irq_mask(irq); gpio_num = __rt_ffs(irq_status) - 1; SET_REG(base + REG_GPIO_PORTA_EOI, BIT(gpio_num)); gpio = gpio_num + ((irq == 40) ? 0 : 32); // generic_handle_irq(gpio_to_irq(gpio)); if (irq_desc[gpio_to_irq(gpio)].handler) irq_desc[gpio_to_irq(gpio)].handler(gpio_to_irq(gpio), irq_desc[gpio_to_irq(gpio)].param); gpio_irq_mask(irq); /* now it may re-trigger */ }
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { unsigned pin; struct irq_desc *gpio; void __iomem *pio; u32 isr; pio = get_irq_chip_data(irq); /* temporarily mask (level sensitive) parent IRQ */ desc->chip->ack(irq); for (;;) { /* reading ISR acks the pending (edge triggered) GPIO interrupt */ isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); if (!isr) break; pin = (unsigned) get_irq_data(irq); gpio = &irq_desc[pin]; while (isr) { if (isr & 1) { if (unlikely(gpio->depth)) { /* * The core ARM interrupt handler lazily disables IRQs so * another IRQ must be generated before it actually gets * here to be disabled on the GPIO controller. */ gpio_irq_mask(pin); } else desc_handle_irq(pin, gpio); } pin++; gpio++; isr >>= 1; } } desc->chip->unmask(irq); /* now it may re-trigger */ }