Commit 19afc3d2 authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle

irqchip: i8259: Allow platforms to override poll function

The default i8259 polling function (i8259_irq) is nicely generic but is
fairly costly. Platforms often provide an alternative means of polling
for an i8259 interrupt, and when using the i8259 without device tree
have typically just chained its parent interrupt to their own handler
function. In order to allow for platform-specific polling functions to
be used in cases where the driver is probed via device tree, provide an
i8259_set_poll function that accepts a pointer to an alternative poll
function that will override the default.
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/14270/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 690803ac
...@@ -43,6 +43,17 @@ extern void make_8259A_irq(unsigned int irq); ...@@ -43,6 +43,17 @@ extern void make_8259A_irq(unsigned int irq);
extern void init_i8259_irqs(void); extern void init_i8259_irqs(void);
extern int i8259_of_init(struct device_node *node, struct device_node *parent); extern int i8259_of_init(struct device_node *node, struct device_node *parent);
/**
* i8159_set_poll() - Override the i8259 polling function
* @poll: pointer to platform-specific polling function
*
* Call this to override the generic i8259 polling function, which directly
* accesses i8259 registers, with a platform specific one which may be faster
* in cases where hardware provides a more optimal means of polling for an
* interrupt.
*/
extern void i8259_set_poll(int (*poll)(void));
/* /*
* Do the traditional i8259 interrupt polling thing. This is for the few * Do the traditional i8259 interrupt polling thing. This is for the few
* cases where no better interrupt acknowledge method is available and we * cases where no better interrupt acknowledge method is available and we
......
...@@ -38,6 +38,7 @@ static void disable_8259A_irq(struct irq_data *d); ...@@ -38,6 +38,7 @@ static void disable_8259A_irq(struct irq_data *d);
static void enable_8259A_irq(struct irq_data *d); static void enable_8259A_irq(struct irq_data *d);
static void mask_and_ack_8259A(struct irq_data *d); static void mask_and_ack_8259A(struct irq_data *d);
static void init_8259A(int auto_eoi); static void init_8259A(int auto_eoi);
static int (*i8259_poll)(void) = i8259_irq;
static struct irq_chip i8259A_chip = { static struct irq_chip i8259A_chip = {
.name = "XT-PIC", .name = "XT-PIC",
...@@ -51,6 +52,11 @@ static struct irq_chip i8259A_chip = { ...@@ -51,6 +52,11 @@ static struct irq_chip i8259A_chip = {
* 8259A PIC functions to handle ISA devices: * 8259A PIC functions to handle ISA devices:
*/ */
void i8259_set_poll(int (*poll)(void))
{
i8259_poll = poll;
}
/* /*
* This contains the irq mask for both 8259A irq controllers, * This contains the irq mask for both 8259A irq controllers,
*/ */
...@@ -355,7 +361,7 @@ void __init init_i8259_irqs(void) ...@@ -355,7 +361,7 @@ void __init init_i8259_irqs(void)
static void i8259_irq_dispatch(struct irq_desc *desc) static void i8259_irq_dispatch(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *domain = irq_desc_get_handler_data(desc);
int hwirq = i8259_irq(); int hwirq = i8259_poll();
unsigned int irq; unsigned int irq;
if (hwirq < 0) if (hwirq < 0)
......
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