Commit f04d3165 authored by Philippe Gerum's avatar Philippe Gerum

pinctrl: sunxi: ipipe: enable interrupt pipelining

Fix up the pin controller driver of the Allwinner A1x SoCs in order to
channel interrupts through the interrupt pipeline.
parent cff26083
......@@ -15,6 +15,7 @@
#include <linux/gpio/driver.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/ipipe.h>
#include <linux/export.h>
#include <linux/of.h>
#include <linux/of_address.h>
......@@ -934,14 +935,33 @@ static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
.irq_request_resources = sunxi_pinctrl_irq_request_resources,
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE,
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_PIPELINE_SAFE,
};
#ifdef CONFIG_IPIPE
static void sunxi_pinctrl_irq_hold(struct irq_data *d)
{
sunxi_pinctrl_irq_mask(d);
sunxi_pinctrl_irq_ack(d);
}
static void sunxi_pinctrl_irq_release(struct irq_data *d)
{
sunxi_pinctrl_irq_unmask(d);
}
#endif
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,
#ifdef CONFIG_IPIPE
.irq_hold = sunxi_pinctrl_irq_hold,
.irq_release = sunxi_pinctrl_irq_release,
#endif
/* Define irq_enable / disable to avoid spurious irqs for drivers
* using these to suppress irqs while they clear the irq source */
.irq_enable = sunxi_pinctrl_irq_ack_unmask,
......@@ -950,7 +970,7 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip = {
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
IRQCHIP_EOI_IF_HANDLED,
IRQCHIP_EOI_IF_HANDLED | IRQCHIP_PIPELINE_SAFE,
};
static int sunxi_pinctrl_irq_of_xlate(struct irq_domain *d,
......@@ -1008,7 +1028,7 @@ static void sunxi_pinctrl_irq_handler(struct irq_desc *desc)
for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
int pin_irq = irq_find_mapping(pctl->domain,
bank * IRQ_PER_BANK + irqoffset);
generic_handle_irq(pin_irq);
ipipe_handle_demuxed_irq(pin_irq);
}
chained_irq_exit(chip, desc);
}
......
......@@ -137,7 +137,11 @@ struct sunxi_pinctrl {
unsigned ngroups;
int *irq;
unsigned *irq_array;
#ifdef CONFIG_IPIPE
ipipe_spinlock_t lock;
#else
raw_spinlock_t lock;
#endif
struct pinctrl_dev *pctl_dev;
unsigned long variant;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment