diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-30 13:46:19 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-30 13:46:19 +1100 |
commit | 0a3108beea9143225119d5e7c72a8e2c64f3eb7d (patch) | |
tree | 89ec500c03f0704799407265db21966b721c6d3f /arch/powerpc/platforms | |
parent | ec78c8ac16e7a5f45e21838ab2f5573200bfcdd3 (diff) | |
parent | df4b6806d35ca6adedd5c0a7e36ac74af1c32d7a (diff) |
Merge commit 'kumar/next' into next
Diffstat (limited to 'arch/powerpc/platforms')
27 files changed, 505 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index bb30d67ad0a..aa0d84d2258 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c @@ -58,6 +58,7 @@ static struct __initdata of_device_id asp8347_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 76092d37c7d..81e44fa1c64 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -42,6 +42,7 @@ static struct of_device_id __initdata mpc834x_itx_ids[] = { { .compatible = "fsl,pq2pro-localbus", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index fc3f2ed1f3e..d0a634b056c 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -112,6 +112,7 @@ static struct of_device_id mpc834x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 634785cc452..51df7e75469 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -96,6 +96,7 @@ static struct of_device_id mpc837x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 3d7b953d40e..76f3b32a155 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -48,6 +48,7 @@ static struct of_device_id mpc837x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index 156c4e21800..49023dbe157 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c @@ -84,6 +84,7 @@ static struct __initdata of_device_id sbc834x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index b79dc710ed3..7f066adc068 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -51,6 +51,12 @@ config MPC85xx_DS help This option enables support for the MPC85xx DS (MPC8544 DS) board +config SOCRATES + bool "Socrates" + select DEFAULT_UIMAGE + help + This option enables support for the Socrates board. + config KSI8560 bool "Emerson KSI8560" select DEFAULT_UIMAGE diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index f0798c09980..a857b35b982 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -13,4 +13,5 @@ obj-$(CONFIG_STX_GP3) += stx_gp3.o obj-$(CONFIG_TQM85xx) += tqm85xx.o obj-$(CONFIG_SBC8560) += sbc8560.o obj-$(CONFIG_SBC8548) += sbc8548.o +obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o obj-$(CONFIG_KSI8560) += ksi8560.o diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index 66f29235ff0..f4d36b5a2e0 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c @@ -219,6 +219,7 @@ static struct of_device_id __initdata of_bus_ids[] = { { .type = "simple-bus", }, { .name = "cpm", }, { .name = "localbus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 1bf5aefdfeb..63efca20d7b 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -92,6 +92,7 @@ static struct of_device_id __initdata mpc8536_ds_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 21f009023e2..9438a892afc 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -226,6 +226,7 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "cpm", }, { .name = "localbus", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index aeb6a5bc552..0a9e49104bd 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -336,6 +336,7 @@ static struct of_device_id __initdata of_bus_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 7326d904202..de66de7a9ca 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -204,6 +204,7 @@ static struct of_device_id __initdata mpc85xxds_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 658a36fab3a..7dd029034ae 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -265,6 +265,7 @@ static struct of_device_id mpc85xx_ids[] = { { .compatible = "simple-bus", }, { .type = "qe", }, { .compatible = "fsl,qe", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 7ec77ce12da..ecdd8c09e4e 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -154,6 +154,7 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "soc", }, { .type = "soc", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index 472f254a19d..cc27807a8b6 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c @@ -213,6 +213,7 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "cpm", }, { .name = "localbus", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c new file mode 100644 index 00000000000..d0e8443b12c --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2008 Emcraft Systems + * Sergei Poselenov <sposelenov@emcraft.com> + * + * Based on MPC8560 ADS and arch/ppc tqm85xx ports + * + * Maintained by Kumar Gala (see MAINTAINERS for contact information) + * + * Copyright 2008 Freescale Semiconductor Inc. + * + * Copyright (c) 2005-2006 DENX Software Engineering + * Stefan Roese <sr@denx.de> + * + * Based on original work by + * Kumar Gala <kumar.gala@freescale.com> + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/of_platform.h> + +#include <asm/system.h> +#include <asm/time.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/mpic.h> +#include <asm/prom.h> +#include <mm/mmu_decl.h> +#include <asm/udbg.h> + +#include <sysdev/fsl_soc.h> +#include <sysdev/fsl_pci.h> + +#include "socrates_fpga_pic.h" + +static void __init socrates_pic_init(void) +{ + struct mpic *mpic; + struct resource r; + struct device_node *np; + + np = of_find_node_by_type(NULL, "open-pic"); + if (!np) { + printk(KERN_ERR "Could not find open-pic node\n"); + return; + } + + if (of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "Could not map mpic register space\n"); + of_node_put(np); + return; + } + + mpic = mpic_alloc(np, r.start, + MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + 0, 256, " OpenPIC "); + BUG_ON(mpic == NULL); + of_node_put(np); + + mpic_init(mpic); + + np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); + if (!np) { + printk(KERN_ERR "Could not find socrates-fpga-pic node\n"); + return; + } + socrates_fpga_pic_init(np); + of_node_put(np); +} + +/* + * Setup the architecture + */ +static void __init socrates_setup_arch(void) +{ +#ifdef CONFIG_PCI + struct device_node *np; +#endif + + if (ppc_md.progress) + ppc_md.progress("socrates_setup_arch()", 0); + +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") + fsl_add_bridge(np, 1); +#endif +} + +static struct of_device_id __initdata socrates_of_bus_ids[] = { + { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, + {}, +}; + +static void __init socrates_init(void) +{ + of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); +} + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init socrates_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (of_flat_dt_is_compatible(root, "abb,socrates")) + return 1; + + return 0; +} + +define_machine(socrates) { + .name = "Socrates", + .probe = socrates_probe, + .setup_arch = socrates_setup_arch, + .init = socrates_init, + .init_IRQ = socrates_pic_init, + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c new file mode 100644 index 00000000000..60edf63d015 --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2008 Ilya Yanok, Emcraft Systems + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/irq.h> +#include <linux/of_platform.h> +#include <linux/io.h> + +/* + * The FPGA supports 9 interrupt sources, which can be routed to 3 + * interrupt request lines of the MPIC. The line to be used can be + * specified through the third cell of FDT property "interrupts". + */ + +#define SOCRATES_FPGA_NUM_IRQS 9 + +#define FPGA_PIC_IRQCFG (0x0) +#define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n)) + +#define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1) + +struct socrates_fpga_irq_info { + unsigned int irq_line; + int type; +}; + +/* + * Interrupt routing and type table + * + * IRQ_TYPE_NONE means the interrupt type is configurable, + * otherwise it's fixed to the specified value. + */ +static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { + [0] = {0, IRQ_TYPE_NONE}, + [1] = {0, IRQ_TYPE_LEVEL_HIGH}, + [2] = {0, IRQ_TYPE_LEVEL_LOW}, + [3] = {0, IRQ_TYPE_NONE}, + [4] = {0, IRQ_TYPE_NONE}, + [5] = {0, IRQ_TYPE_NONE}, + [6] = {0, IRQ_TYPE_NONE}, + [7] = {0, IRQ_TYPE_NONE}, + [8] = {0, IRQ_TYPE_LEVEL_HIGH}, +}; + +#define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) + +static DEFINE_SPINLOCK(socrates_fpga_pic_lock); + +static void __iomem *socrates_fpga_pic_iobase; +static struct irq_host *socrates_fpga_pic_irq_host; +static unsigned int socrates_fpga_irqs[3]; + +static inline uint32_t socrates_fpga_pic_read(int reg) +{ + return in_be32(socrates_fpga_pic_iobase + reg); +} + +static inline void socrates_fpga_pic_write(int reg, uint32_t val) +{ + out_be32(socrates_fpga_pic_iobase + reg, val); +} + +static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) +{ + uint32_t cause; + unsigned long flags; + int i; + + /* Check irq line routed to the MPIC */ + for (i = 0; i < 3; i++) { + if (irq == socrates_fpga_irqs[i]) + break; + } + if (i == 3) + return NO_IRQ; + + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) { + if (cause >> (i + 16)) + break; + } + return irq_linear_revmap(socrates_fpga_pic_irq_host, + (irq_hw_number_t)i); +} + +void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc) +{ + unsigned int cascade_irq; + + /* + * See if we actually have an interrupt, call generic handling code if + * we do. + */ + cascade_irq = socrates_fpga_pic_get_irq(irq); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + desc->chip->eoi(irq); + +} + +static void socrates_fpga_pic_ack(unsigned int virq) +{ + unsigned long flags; + unsigned int hwirq, irq_line; + uint32_t mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + irq_line = fpga_irqs[hwirq].irq_line; + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) + & SOCRATES_FPGA_IRQ_MASK; + mask |= (1 << (hwirq + 16)); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); +} + +static void socrates_fpga_pic_mask(unsigned int virq) +{ + unsigned long flags; + unsigned int hwirq; + int irq_line; + u32 mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + irq_line = fpga_irqs[hwirq].irq_line; + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) + & SOCRATES_FPGA_IRQ_MASK; + mask &= ~(1 << hwirq); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); +} + +static void socrates_fpga_pic_mask_ack(unsigned int virq) +{ + unsigned long flags; + unsigned int hwirq; + int irq_line; + u32 mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + irq_line = fpga_irqs[hwirq].irq_line; + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) + & SOCRATES_FPGA_IRQ_MASK; + mask &= ~(1 << hwirq); + mask |= (1 << (hwirq + 16)); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); +} + +static void socrates_fpga_pic_unmask(unsigned int virq) +{ + unsigned long flags; + unsigned int hwirq; + int irq_line; + u32 mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + irq_line = fpga_irqs[hwirq].irq_line; + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) + & SOCRATES_FPGA_IRQ_MASK; + mask |= (1 << hwirq); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); +} + +static void socrates_fpga_pic_eoi(unsigned int virq) +{ + unsigned long flags; + unsigned int hwirq; + int irq_line; + u32 mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + irq_line = fpga_irqs[hwirq].irq_line; + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) + & SOCRATES_FPGA_IRQ_MASK; + mask |= (1 << (hwirq + 16)); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); +} + +static int socrates_fpga_pic_set_type(unsigned int virq, + unsigned int flow_type) +{ + unsigned long flags; + unsigned int hwirq; + int polarity; + u32 mask; + + hwirq = socrates_fpga_irq_to_hw(virq); + + if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE) + return -EINVAL; + + switch (flow_type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_LEVEL_HIGH: + polarity = 1; + break; + case IRQ_TYPE_LEVEL_LOW: + polarity = 0; + break; + default: + return -EINVAL; + } + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG); + if (polarity) + mask |= (1 << hwirq); + else + mask &= ~(1 << hwirq); + socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + return 0; +} + +static struct irq_chip socrates_fpga_pic_chip = { + .typename = " FPGA-PIC ", + .ack = socrates_fpga_pic_ack, + .mask = socrates_fpga_pic_mask, + .mask_ack = socrates_fpga_pic_mask_ack, + .unmask = socrates_fpga_pic_unmask, + .eoi = socrates_fpga_pic_eoi, + .set_type = socrates_fpga_pic_set_type, +}; + +static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hwirq) +{ + /* All interrupts are LEVEL sensitive */ + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip, + handle_fasteoi_irq); + + return 0; +} + +static int socrates_fpga_pic_host_xlate(struct irq_host *h, + struct device_node *ct, u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) +{ + struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]]; + + *out_hwirq = intspec[0]; + if (fpga_irq->type == IRQ_TYPE_NONE) { + /* type is configurable */ + if (intspec[1] != IRQ_TYPE_LEVEL_LOW && + intspec[1] != IRQ_TYPE_LEVEL_HIGH) { + pr_warning("FPGA PIC: invalid irq type, " + "setting default active low\n"); + *out_flags = IRQ_TYPE_LEVEL_LOW; + } else { + *out_flags = intspec[1]; + } + } else { + /* type is fixed */ + *out_flags = fpga_irq->type; + } + + /* Use specified interrupt routing */ + if (intspec[2] <= 2) + fpga_irq->irq_line = intspec[2]; + else + pr_warning("FPGA PIC: invalid irq routing\n"); + + return 0; +} + +static struct irq_host_ops socrates_fpga_pic_host_ops = { + .map = socrates_fpga_pic_host_map, + .xlate = socrates_fpga_pic_host_xlate, +}; + +void socrates_fpga_pic_init(struct device_node *pic) +{ + unsigned long flags; + int i; + + /* Setup an irq_host structure */ + socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, + SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, + SOCRATES_FPGA_NUM_IRQS); + if (socrates_fpga_pic_irq_host == NULL) { + pr_err("FPGA PIC: Unable to allocate host\n"); + return; + } + + for (i = 0; i < 3; i++) { + socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i); + if (socrates_fpga_irqs[i] == NO_IRQ) { + pr_warning("FPGA PIC: can't get irq%d.\n", i); + continue; + } + set_irq_chained_handler(socrates_fpga_irqs[i], + socrates_fpga_pic_cascade); + } + + socrates_fpga_pic_iobase = of_iomap(pic, 0); + + spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0), + SOCRATES_FPGA_IRQ_MASK << 16); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1), + SOCRATES_FPGA_IRQ_MASK << 16); + socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2), + SOCRATES_FPGA_IRQ_MASK << 16); + spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + + pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n"); +} diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.h b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h new file mode 100644 index 00000000000..21d7d8e4219 --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2008 Ilya Yanok, Emcraft Systems + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef SOCRATES_FPGA_PIC_H +#define SOCRATES_FPGA_PIC_H + +void socrates_fpga_pic_init(struct device_node *pic); + +#endif diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 0cca8f5cb27..f559918f3c6 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c @@ -145,6 +145,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 2933a8e827d..5b0ab9966e9 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c @@ -153,6 +153,7 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 830fd9a23b5..d79104669cd 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index ba3ce438161..af14f852d74 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -205,6 +205,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index d6b772ba3b8..ea236063965 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index e8d54ac5292..3f49a6f893a 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -46,6 +46,7 @@ static unsigned char *pixis_bdcfg0, *pixis_arch; static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "fsl,mpc8610-immr", }, { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {} }; diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 27e0e682d8e..c4ec49b5f7f 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -148,6 +148,7 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "fsl,rapidio-delta", }, + { .compatible = "gianfar", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 5fd7ed40986..2886a36fc08 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -103,6 +103,7 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, + { .compatible = "gianfar", }, {}, }; |