static void __em_gio_set(struct gpio_chip *chip, unsigned int reg, unsigned shift, int value) { /* upper 16 bits contains mask and lower 16 actual value */ em_gio_write(gpio_to_priv(chip), reg, (BIT(shift + 16)) | (value << shift)); }
static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { /* write GPIO value to output before selecting output mode of pin */ em_gio_set(chip, offset, value); em_gio_write(gpio_to_priv(chip), GIO_E1, BIT(offset)); return 0; }
static int em_gio_irq_set_type(struct irq_data *d, unsigned int type) { unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK]; struct em_gio_priv *p = irq_data_get_irq_chip_data(d); unsigned int reg, offset, shift; unsigned long flags; unsigned long tmp; if (!value) return -EINVAL; offset = irqd_to_hwirq(d); pr_debug("gio: sense irq = %d, mode = %d\n", offset, value); /* 8 x 4 bit fields in 4 IDT registers */ reg = GIO_IDT(offset >> 3); shift = (offset & 0x07) << 4; spin_lock_irqsave(&p->sense_lock, flags); /* disable the interrupt in IIA */ tmp = em_gio_read(p, GIO_IIA); tmp &= ~BIT(offset); em_gio_write(p, GIO_IIA, tmp); /* change the sense setting in IDT */ tmp = em_gio_read(p, reg); tmp &= ~(0xf << shift); tmp |= value << shift; em_gio_write(p, reg, tmp); /* clear pending interrupts */ em_gio_write(p, GIO_IIR, BIT(offset)); /* enable the interrupt in IIA */ tmp = em_gio_read(p, GIO_IIA); tmp |= BIT(offset); em_gio_write(p, GIO_IIA, tmp); spin_unlock_irqrestore(&p->sense_lock, flags); return 0; }
static irqreturn_t em_gio_irq_handler(int irq, void *dev_id) { struct em_gio_priv *p = dev_id; unsigned long pending; unsigned int offset, irqs_handled = 0; while ((pending = em_gio_read(p, GIO_MST))) { offset = __ffs(pending); em_gio_write(p, GIO_IIR, BIT(offset)); generic_handle_irq(irq_find_mapping(p->irq_domain, offset)); irqs_handled++; } return irqs_handled ? IRQ_HANDLED : IRQ_NONE; }
static void em_gio_irq_enable(struct irq_data *d) { struct em_gio_priv *p = irq_data_get_irq_chip_data(d); em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d))); }
static int em_gio_direction_input(struct gpio_chip *chip, unsigned offset) { em_gio_write(gpio_to_priv(chip), GIO_E0, BIT(offset)); return 0; }
static void em_gio_irq_disable(struct irq_data *d) { struct em_gio_priv *p = irq_to_priv(d); em_gio_write(p, GIO_IDS, BIT(irqd_to_hwirq(d))); }