|
@@ -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);
|
|
|
|