diff options
author | Linus Torvalds | 2012-10-07 21:20:57 +0900 |
---|---|---|
committer | Linus Torvalds | 2012-10-07 21:20:57 +0900 |
commit | 0e51793e162ca432fc5f04178cf82b80a92c2659 (patch) | |
tree | cf7ffdb5064e2f7b6647a63e7323d1c4e99b7739 /arch/arm/plat-versatile | |
parent | 5cad3598ea0cdb817681f74518d3213583a04f7a (diff) | |
parent | b4874a3d298606c20118d1ead73235439bbc2823 (diff) |
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM updates from Russell King:
"This is the first chunk of ARM updates for this merge window.
Conflicts are expected in two files - asm/timex.h and
mach-integrator/integrator_cp.c. Nothing particularly stands out more
than anything else.
Most of the growth is down to the opcodes stuff from Dave Martin,
which is countered by Rob's patches to use more of the asm-generic
headers on ARM."
(A few more conflicts grew since then, but it all looked fairly trivial)
* 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (44 commits)
ARM: 7548/1: include linux/sched.h in syscall.h
ARM: 7541/1: Add ARM ERRATA 775420 workaround
ARM: ensure vm_struct has its phys_addr member filled in
ARM: 7540/1: kexec: Check segment memory addresses
ARM: 7539/1: kexec: scan for dtb magic in segments
ARM: 7538/1: delay: add registration mechanism for delay timer sources
ARM: 7536/1: smp: Formalize an IPI for wakeup
ARM: 7525/1: ptrace: use updated syscall number for syscall auditing
ARM: 7524/1: support syscall tracing
ARM: 7519/1: integrator: convert platform devices to Device Tree
ARM: 7518/1: integrator: convert AMBA devices to device tree
ARM: 7517/1: integrator: initial device tree support
ARM: 7516/1: plat-versatile: add DT support to FPGA IRQ
ARM: 7515/1: integrator: check PL010 base address from resource
ARM: 7514/1: integrator: call common init function from machine
ARM: 7522/1: arch_timers: register a time/cycle counter
ARM: 7523/1: arch_timers: enable the use of the virtual timer
ARM: 7531/1: mark kernelmode mem{cpy,set} non-experimental
ARM: 7520/1: Build dtb files in all target
ARM: Fix build warning in arch/arm/mm/alignment.c
...
Diffstat (limited to 'arch/arm/plat-versatile')
-rw-r--r-- | arch/arm/plat-versatile/fpga-irq.c | 72 | ||||
-rw-r--r-- | arch/arm/plat-versatile/include/plat/fpga-irq.h | 2 |
2 files changed, 64 insertions, 10 deletions
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c index 6e70d03824a1..091ae1030045 100644 --- a/arch/arm/plat-versatile/fpga-irq.c +++ b/arch/arm/plat-versatile/fpga-irq.c @@ -5,6 +5,8 @@ #include <linux/io.h> #include <linux/irqdomain.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <asm/exception.h> #include <asm/mach/irq.h> @@ -14,11 +16,17 @@ #define IRQ_RAW_STATUS 0x04 #define IRQ_ENABLE_SET 0x08 #define IRQ_ENABLE_CLEAR 0x0c +#define INT_SOFT_SET 0x10 +#define INT_SOFT_CLEAR 0x14 +#define FIQ_STATUS 0x20 +#define FIQ_RAW_STATUS 0x24 +#define FIQ_ENABLE 0x28 +#define FIQ_ENABLE_SET 0x28 +#define FIQ_ENABLE_CLEAR 0x2C /** * struct fpga_irq_data - irq data container for the FPGA IRQ controller * @base: memory offset in virtual memory - * @irq_start: first IRQ number handled by this instance * @chip: chip container for this instance * @domain: IRQ domain for this instance * @valid: mask for valid IRQs on this controller @@ -26,7 +34,6 @@ */ struct fpga_irq_data { void __iomem *base; - unsigned int irq_start; struct irq_chip chip; u32 valid; struct irq_domain *domain; @@ -125,34 +132,79 @@ static struct irq_domain_ops fpga_irqdomain_ops = { .xlate = irq_domain_xlate_onetwocell, }; -void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, - int parent_irq, u32 valid, struct device_node *node) -{ +static __init struct fpga_irq_data * +fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) { struct fpga_irq_data *f; if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); - return; + return NULL; } - f = &fpga_irq_devices[fpga_irq_id]; f->base = base; - f->irq_start = irq_start; f->chip.name = name; f->chip.irq_ack = fpga_irq_mask; f->chip.irq_mask = fpga_irq_mask; f->chip.irq_unmask = fpga_irq_unmask; f->valid = valid; + fpga_irq_id++; + + return f; +} + +void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, + int parent_irq, u32 valid, struct device_node *node) +{ + struct fpga_irq_data *f; + + f = fpga_irq_prep_struct(base, name, valid); + if (!f) + return; if (parent_irq != -1) { irq_set_handler_data(parent_irq, f); irq_set_chained_handler(parent_irq, fpga_irq_handle); } - f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0, + f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0, &fpga_irqdomain_ops, f); pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", fpga_irq_id, name, base, f->used_irqs); +} - fpga_irq_id++; +#ifdef CONFIG_OF +int __init fpga_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + struct fpga_irq_data *f; + void __iomem *base; + u32 clear_mask; + u32 valid_mask; + + if (WARN_ON(!node)) + return -ENODEV; + + base = of_iomap(node, 0); + WARN(!base, "unable to map fpga irq registers\n"); + + if (of_property_read_u32(node, "clear-mask", &clear_mask)) + clear_mask = 0; + + if (of_property_read_u32(node, "valid-mask", &valid_mask)) + valid_mask = 0; + + f = fpga_irq_prep_struct(base, node->name, valid_mask); + if (!f) + return -ENOMEM; + + writel(clear_mask, base + IRQ_ENABLE_CLEAR); + writel(clear_mask, base + FIQ_ENABLE_CLEAR); + + f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f); + f->used_irqs = hweight32(valid_mask); + + pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", + fpga_irq_id, node->name, base, f->used_irqs); + return 0; } +#endif diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h index 91bcfb67551d..1fac9651d3ca 100644 --- a/arch/arm/plat-versatile/include/plat/fpga-irq.h +++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h @@ -7,5 +7,7 @@ struct pt_regs; void fpga_handle_irq(struct pt_regs *regs); void fpga_irq_init(void __iomem *, const char *, int, int, u32, struct device_node *node); +int fpga_irq_of_init(struct device_node *node, + struct device_node *parent); #endif |