mirror of https://gitee.com/openkylin/linux.git
powerpc/virtex: refactor intc driver and add support for i8259 cascading
This patch refactors some of the xilinx_intc interrupt controller driver and adds support for cascading an i8259 off one of the irq lines. This patch was based on the ML510 support work done by Roderick Colenbrander. Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
This commit is contained in:
parent
64f1650247
commit
1745fbc744
|
@ -25,6 +25,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/*
|
||||
|
@ -191,20 +192,14 @@ struct irq_host * __init
|
|||
xilinx_intc_init(struct device_node *np)
|
||||
{
|
||||
struct irq_host * irq;
|
||||
struct resource res;
|
||||
void * regs;
|
||||
int rc;
|
||||
|
||||
/* Find and map the intc registers */
|
||||
rc = of_address_to_resource(np, 0, &res);
|
||||
if (rc) {
|
||||
printk(KERN_ERR __FILE__ ": of_address_to_resource() failed\n");
|
||||
regs = of_iomap(np, 0);
|
||||
if (!regs) {
|
||||
pr_err("xilinx_intc: could not map registers\n");
|
||||
return NULL;
|
||||
}
|
||||
regs = ioremap(res.start, 32);
|
||||
|
||||
printk(KERN_INFO "Xilinx intc at 0x%08llx mapped to 0x%p\n",
|
||||
(unsigned long long) res.start, regs);
|
||||
|
||||
/* Setup interrupt controller */
|
||||
out_be32(regs + XINTC_IER, 0); /* disable all irqs */
|
||||
|
@ -217,6 +212,7 @@ xilinx_intc_init(struct device_node *np)
|
|||
if (!irq)
|
||||
panic(__FILE__ ": Cannot allocate IRQ host\n");
|
||||
irq->host_data = regs;
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
|
@ -227,23 +223,65 @@ int xilinx_intc_get_irq(void)
|
|||
return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PPC_I8259)
|
||||
/*
|
||||
* Support code for cascading to 8259 interrupt controllers
|
||||
*/
|
||||
static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned int cascade_irq = i8259_irq();
|
||||
if (cascade_irq)
|
||||
generic_handle_irq(cascade_irq);
|
||||
|
||||
/* Let xilinx_intc end the interrupt */
|
||||
desc->chip->ack(irq);
|
||||
desc->chip->unmask(irq);
|
||||
}
|
||||
|
||||
static void __init xilinx_i8259_setup_cascade(void)
|
||||
{
|
||||
struct device_node *cascade_node;
|
||||
int cascade_irq;
|
||||
|
||||
/* Initialize i8259 controller */
|
||||
cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic");
|
||||
if (!cascade_node)
|
||||
return;
|
||||
|
||||
cascade_irq = irq_of_parse_and_map(cascade_node, 0);
|
||||
if (!cascade_irq) {
|
||||
pr_err("virtex_ml510: Failed to map cascade interrupt\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
i8259_init(cascade_node, 0);
|
||||
set_irq_chained_handler(cascade_irq, xilinx_i8259_cascade);
|
||||
|
||||
out:
|
||||
of_node_put(cascade_node);
|
||||
}
|
||||
#else
|
||||
static inline void xilinx_i8259_setup_cascade(void) { return; }
|
||||
#endif /* defined(CONFIG_PPC_I8259) */
|
||||
|
||||
static struct of_device_id xilinx_intc_match[] __initconst = {
|
||||
{ .compatible = "xlnx,opb-intc-1.00.c", },
|
||||
{ .compatible = "xlnx,xps-intc-1.00.a", },
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize master Xilinx interrupt controller
|
||||
*/
|
||||
void __init xilinx_intc_init_tree(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
/* find top level interrupt controller */
|
||||
for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") {
|
||||
for_each_matching_node(np, xilinx_intc_match) {
|
||||
if (!of_get_property(np, "interrupts", NULL))
|
||||
break;
|
||||
}
|
||||
if (!np) {
|
||||
for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") {
|
||||
if (!of_get_property(np, "interrupts", NULL))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* xilinx interrupt controller needs to be top level */
|
||||
BUG_ON(!np);
|
||||
|
||||
master_irqhost = xilinx_intc_init(np);
|
||||
|
@ -251,4 +289,6 @@ void __init xilinx_intc_init_tree(void)
|
|||
|
||||
irq_set_default_host(master_irqhost);
|
||||
of_node_put(np);
|
||||
|
||||
xilinx_i8259_setup_cascade();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue