Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 368d97d6 authored by Sergio Paracuellos's avatar Sergio Paracuellos Committed by Greg Kroah-Hartman
Browse files

staging: mt7621-gpio: implement high level and low level irqs



This chip support high level and low level interrupts. Those
have to be implemented also to get a complete and clean driver.

Signed-off-by: default avatarSergio Paracuellos <sergio.paracuellos@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fe84f0c9
Loading
Loading
Loading
Loading
+37 −10
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
 * @bank: gpio bank number for the chip
 * @rising: mask for rising irqs
 * @falling: mask for falling irqs
 * @hlevel: mask for high level irqs
 * @llevel: mask for low level irqs
 */
struct mtk_gc {
	struct gpio_chip chip;
@@ -45,6 +47,8 @@ struct mtk_gc {
	int bank;
	u32 rising;
	u32 falling;
	u32 hlevel;
	u32 llevel;
};

/**
@@ -184,7 +188,7 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
	int bank = pin / MTK_BANK_WIDTH;
	struct mtk_gc *rg = &gpio_data->gc_map[bank];
	unsigned long flags;
	u32 rise, fall;
	u32 rise, fall, high, low;

	if (!rg)
		return;
@@ -192,8 +196,12 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
	spin_lock_irqsave(&rg->lock, flags);
	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (PIN_MASK(pin) & rg->rising));
	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (PIN_MASK(pin) & rg->falling));
	mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (PIN_MASK(pin) & rg->hlevel));
	mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (PIN_MASK(pin) & rg->llevel));
	spin_unlock_irqrestore(&rg->lock, flags);
}

@@ -205,7 +213,7 @@ mediatek_gpio_irq_mask(struct irq_data *d)
	int bank = pin / MTK_BANK_WIDTH;
	struct mtk_gc *rg = &gpio_data->gc_map[bank];
	unsigned long flags;
	u32 rise, fall;
	u32 rise, fall, high, low;

	if (!rg)
		return;
@@ -213,8 +221,12 @@ mediatek_gpio_irq_mask(struct irq_data *d)
	spin_lock_irqsave(&rg->lock, flags);
	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~PIN_MASK(pin));
	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~PIN_MASK(pin));
	mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~PIN_MASK(pin));
	mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~PIN_MASK(pin));
	spin_unlock_irqrestore(&rg->lock, flags);
}

@@ -231,21 +243,36 @@ mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
		return -1;

	if (type == IRQ_TYPE_PROBE) {
		if ((rg->rising | rg->falling) & mask)
		if ((rg->rising | rg->falling |
		     rg->hlevel | rg->llevel) & mask)
			return 0;

		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
	}

	if (type & IRQ_TYPE_EDGE_RISING)
		rg->rising |= mask;
	else
	rg->rising &= ~mask;
	rg->falling &= ~mask;
	rg->hlevel &= ~mask;
	rg->llevel &= ~mask;

	if (type & IRQ_TYPE_EDGE_FALLING)
	switch (type & IRQ_TYPE_SENSE_MASK) {
	case IRQ_TYPE_EDGE_BOTH:
		rg->rising |= mask;
		rg->falling |= mask;
	else
		rg->falling &= ~mask;
		break;
	case IRQ_TYPE_EDGE_RISING:
		rg->rising |= mask;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		rg->falling |= mask;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		rg->hlevel |= mask;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		rg->llevel |= mask;
		break;
	}

	return 0;
}