diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 20:32:52 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-15 20:32:52 +0400 |
commit | 0fa213310cd8fa7a51071cdcf130e26fa56e9549 (patch) | |
tree | 2a7e5cc33c8938ec82604a99c3797a3132fd91ec /arch/powerpc/sysdev/xilinx_intc.c | |
parent | d3bf80bff13597004b5724ee4549cd68eb0badf0 (diff) | |
parent | bc47ab0241c7c86da4f5e5f82fbca7d45387c18d (diff) | |
download | linux-0fa213310cd8fa7a51071cdcf130e26fa56e9549.tar.xz |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (103 commits)
powerpc: Fix bug in move of altivec code to vector.S
powerpc: Add support for swiotlb on 32-bit
powerpc/spufs: Remove unused error path
powerpc: Fix warning when printing a resource_size_t
powerpc/xmon: Remove unused variable in xmon.c
powerpc/pseries: Fix warnings when printing resource_size_t
powerpc: Shield code specific to 64-bit server processors
powerpc: Separate PACA fields for server CPUs
powerpc: Split exception handling out of head_64.S
powerpc: Introduce CONFIG_PPC_BOOK3S
powerpc: Move VMX and VSX asm code to vector.S
powerpc: Set init_bootmem_done on NUMA platforms as well
powerpc/mm: Fix a AB->BA deadlock scenario with nohash MMU context lock
powerpc/mm: Fix some SMP issues with MMU context handling
powerpc: Add PTRACE_SINGLEBLOCK support
fbdev: Add PLB support and cleanup DCR in xilinxfb driver.
powerpc/virtex: Add ml510 reference design device tree
powerpc/virtex: Add Xilinx ML510 reference design support
powerpc/virtex: refactor intc driver and add support for i8259 cascading
powerpc/virtex: Add support for Xilinx PCI host bridge
...
Diffstat (limited to 'arch/powerpc/sysdev/xilinx_intc.c')
-rw-r--r-- | arch/powerpc/sysdev/xilinx_intc.c | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c index c658b413c9b4..3ee1fd37bbfc 100644 --- a/arch/powerpc/sysdev/xilinx_intc.c +++ b/arch/powerpc/sysdev/xilinx_intc.c @@ -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,70 @@ 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); + + /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */ + /* This looks like a dirty hack to me --gcl */ + outb(0xc0, 0x4d0); + outb(0xc0, 0x4d1); + + 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 +294,6 @@ void __init xilinx_intc_init_tree(void) irq_set_default_host(master_irqhost); of_node_put(np); + + xilinx_i8259_setup_cascade(); } |