summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/mvebu/pinctrl-armada-37xx.c')
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index b8b6ab072cd0..71b944748304 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -550,9 +550,9 @@ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
spin_lock_irqsave(&info->irq_lock, flags);
val = readl(info->base + reg);
if (on)
- val |= d->mask;
+ val |= (BIT(d->hwirq % GPIO_PER_REG));
else
- val &= ~d->mask;
+ val &= ~(BIT(d->hwirq % GPIO_PER_REG));
writel(val, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
@@ -571,10 +571,10 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
val = readl(info->base + reg);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
- val &= ~d->mask;
+ val &= ~(BIT(d->hwirq % GPIO_PER_REG));
break;
case IRQ_TYPE_EDGE_FALLING:
- val |= d->mask;
+ val |= (BIT(d->hwirq % GPIO_PER_REG));
break;
default:
spin_unlock_irqrestore(&info->irq_lock, flags);
@@ -624,11 +624,27 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+static unsigned int armada_37xx_irq_startup(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ int irq = d->hwirq - chip->irq_base;
+ /*
+ * The mask field is a "precomputed bitmask for accessing the
+ * chip registers" which was introduced for the generic
+ * irqchip framework. As we don't use this framework, we can
+ * reuse this field for our own usage.
+ */
+ d->mask = BIT(irq % GPIO_PER_REG);
+
+ armada_37xx_irq_unmask(d);
+
+ return 0;
+}
+
static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device_node *np = info->dev->of_node;
- int nrirqs = info->data->nr_pins;
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct resource res;
@@ -666,8 +682,8 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
irqchip->irq_unmask = armada_37xx_irq_unmask;
irqchip->irq_set_wake = armada_37xx_irq_set_wake;
irqchip->irq_set_type = armada_37xx_irq_set_type;
+ irqchip->irq_startup = armada_37xx_irq_startup;
irqchip->name = info->data->name;
-
ret = gpiochip_irqchip_add(gc, irqchip, 0,
handle_edge_irq, IRQ_TYPE_NONE);
if (ret) {
@@ -680,19 +696,6 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
* controller. But we do not take advantage of this and use
* the chained irq with all of them.
*/
- for (i = 0; i < nrirqs; i++) {
- struct irq_data *d = irq_get_irq_data(gc->irq_base + i);
-
- /*
- * The mask field is a "precomputed bitmask for
- * accessing the chip registers" which was introduced
- * for the generic irqchip framework. As we don't use
- * this framework, we can reuse this field for our own
- * usage.
- */
- d->mask = BIT(i % GPIO_PER_REG);
- }
-
for (i = 0; i < nr_irq_parent; i++) {
int irq = irq_of_parse_and_map(np, i);