spin_lock_irqsave(&pctl->lock, flags);
if (type & IRQ_TYPE_LEVEL_MASK)
- __irq_set_chip_handler_name_locked(d->irq,
- &sunxi_pinctrl_level_irq_chip,
- handle_fasteoi_irq, NULL);
+ irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_level_irq_chip,
+ handle_fasteoi_irq, NULL);
else
- __irq_set_chip_handler_name_locked(d->irq,
- &sunxi_pinctrl_edge_irq_chip,
- handle_edge_irq, NULL);
+ irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_edge_irq_chip,
+ handle_edge_irq, NULL);
regval = readl(pctl->membase + reg);
regval &= ~(IRQ_CFG_IRQ_MASK << index);
}
static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
+ .name = "sunxi_pio_edge",
.irq_ack = sunxi_pinctrl_irq_ack,
.irq_mask = sunxi_pinctrl_irq_mask,
.irq_unmask = sunxi_pinctrl_irq_unmask,
};
static struct irq_chip sunxi_pinctrl_level_irq_chip = {
+ .name = "sunxi_pio_level",
.irq_eoi = sunxi_pinctrl_irq_ack,
.irq_mask = sunxi_pinctrl_irq_mask,
.irq_unmask = sunxi_pinctrl_irq_unmask,
IRQCHIP_EOI_IF_HANDLED,
};
-static void sunxi_pinctrl_irq_handler(unsigned __irq, struct irq_desc *desc)
+static int sunxi_pinctrl_irq_of_xlate(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ struct sunxi_desc_function *desc;
+ int pin, base;
+
+ if (intsize < 3)
+ return -EINVAL;
+
+ base = PINS_PER_BANK * intspec[0];
+ pin = base + intspec[1];
+
+ desc = sunxi_pinctrl_desc_find_function_by_pin(d->host_data,
+ pin, "irq");
+ if (!desc)
+ return -EINVAL;
+
+ *out_hwirq = desc->irqbank * PINS_PER_BANK + desc->irqnum;
+ *out_type = intspec[2];
+
+ return 0;
+}
+
+static struct irq_domain_ops sunxi_pinctrl_irq_domain_ops = {
+ .xlate = sunxi_pinctrl_irq_of_xlate,
+};
+
+static void sunxi_pinctrl_irq_handler(struct irq_desc *desc)
{
unsigned int irq = irq_desc_get_irq(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
pctl->domain = irq_domain_add_linear(node,
pctl->desc->irq_banks * IRQ_PER_BANK,
- &irq_domain_simple_ops,
- NULL);
+ &sunxi_pinctrl_irq_domain_ops,
+ pctl);
if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM;