Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 149670
b: refs/heads/master
c: 1745fbc
h: refs/heads/master
v: v3
  • Loading branch information
Grant Likely committed Jun 6, 2009
1 parent 2aa4065 commit 8a13295
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 64f16502475ddf663169369fffff6da9b10ea9fb
refs/heads/master: 1745fbc744a934b235c2e5ecb5380079fa54be38
76 changes: 58 additions & 18 deletions trunk/arch/powerpc/sysdev/xilinx_intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/of.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/i8259.h>
#include <asm/irq.h>

/*
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
}

Expand All @@ -227,28 +223,72 @@ 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);
BUG_ON(!master_irqhost);

irq_set_default_host(master_irqhost);
of_node_put(np);

xilinx_i8259_setup_cascade();
}

0 comments on commit 8a13295

Please sign in to comment.