aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-versatile
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 08:20:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 08:20:57 -0400
commit0e51793e162ca432fc5f04178cf82b80a92c2659 (patch)
treecf7ffdb5064e2f7b6647a63e7323d1c4e99b7739 /arch/arm/plat-versatile
parent5cad3598ea0cdb817681f74518d3213583a04f7a (diff)
parentb4874a3d298606c20118d1ead73235439bbc2823 (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.c72
-rw-r--r--arch/arm/plat-versatile/include/plat/fpga-irq.h2
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 @@
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/irqdomain.h> 6#include <linux/irqdomain.h>
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/of.h>
9#include <linux/of_address.h>
8 10
9#include <asm/exception.h> 11#include <asm/exception.h>
10#include <asm/mach/irq.h> 12#include <asm/mach/irq.h>
@@ -14,11 +16,17 @@
14#define IRQ_RAW_STATUS 0x04 16#define IRQ_RAW_STATUS 0x04
15#define IRQ_ENABLE_SET 0x08 17#define IRQ_ENABLE_SET 0x08
16#define IRQ_ENABLE_CLEAR 0x0c 18#define IRQ_ENABLE_CLEAR 0x0c
19#define INT_SOFT_SET 0x10
20#define INT_SOFT_CLEAR 0x14
21#define FIQ_STATUS 0x20
22#define FIQ_RAW_STATUS 0x24
23#define FIQ_ENABLE 0x28
24#define FIQ_ENABLE_SET 0x28
25#define FIQ_ENABLE_CLEAR 0x2C
17 26
18/** 27/**
19 * struct fpga_irq_data - irq data container for the FPGA IRQ controller 28 * struct fpga_irq_data - irq data container for the FPGA IRQ controller
20 * @base: memory offset in virtual memory 29 * @base: memory offset in virtual memory
21 * @irq_start: first IRQ number handled by this instance
22 * @chip: chip container for this instance 30 * @chip: chip container for this instance
23 * @domain: IRQ domain for this instance 31 * @domain: IRQ domain for this instance
24 * @valid: mask for valid IRQs on this controller 32 * @valid: mask for valid IRQs on this controller
@@ -26,7 +34,6 @@
26 */ 34 */
27struct fpga_irq_data { 35struct fpga_irq_data {
28 void __iomem *base; 36 void __iomem *base;
29 unsigned int irq_start;
30 struct irq_chip chip; 37 struct irq_chip chip;
31 u32 valid; 38 u32 valid;
32 struct irq_domain *domain; 39 struct irq_domain *domain;
@@ -125,34 +132,79 @@ static struct irq_domain_ops fpga_irqdomain_ops = {
125 .xlate = irq_domain_xlate_onetwocell, 132 .xlate = irq_domain_xlate_onetwocell,
126}; 133};
127 134
128void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, 135static __init struct fpga_irq_data *
129 int parent_irq, u32 valid, struct device_node *node) 136fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) {
130{
131 struct fpga_irq_data *f; 137 struct fpga_irq_data *f;
132 138
133 if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { 139 if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
134 printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); 140 printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
135 return; 141 return NULL;
136 } 142 }
137
138 f = &fpga_irq_devices[fpga_irq_id]; 143 f = &fpga_irq_devices[fpga_irq_id];
139 f->base = base; 144 f->base = base;
140 f->irq_start = irq_start;
141 f->chip.name = name; 145 f->chip.name = name;
142 f->chip.irq_ack = fpga_irq_mask; 146 f->chip.irq_ack = fpga_irq_mask;
143 f->chip.irq_mask = fpga_irq_mask; 147 f->chip.irq_mask = fpga_irq_mask;
144 f->chip.irq_unmask = fpga_irq_unmask; 148 f->chip.irq_unmask = fpga_irq_unmask;
145 f->valid = valid; 149 f->valid = valid;
150 fpga_irq_id++;
151
152 return f;
153}
154
155void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
156 int parent_irq, u32 valid, struct device_node *node)
157{
158 struct fpga_irq_data *f;
159
160 f = fpga_irq_prep_struct(base, name, valid);
161 if (!f)
162 return;
146 163
147 if (parent_irq != -1) { 164 if (parent_irq != -1) {
148 irq_set_handler_data(parent_irq, f); 165 irq_set_handler_data(parent_irq, f);
149 irq_set_chained_handler(parent_irq, fpga_irq_handle); 166 irq_set_chained_handler(parent_irq, fpga_irq_handle);
150 } 167 }
151 168
152 f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0, 169 f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0,
153 &fpga_irqdomain_ops, f); 170 &fpga_irqdomain_ops, f);
154 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", 171 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
155 fpga_irq_id, name, base, f->used_irqs); 172 fpga_irq_id, name, base, f->used_irqs);
173}
156 174
157 fpga_irq_id++; 175#ifdef CONFIG_OF
176int __init fpga_irq_of_init(struct device_node *node,
177 struct device_node *parent)
178{
179 struct fpga_irq_data *f;
180 void __iomem *base;
181 u32 clear_mask;
182 u32 valid_mask;
183
184 if (WARN_ON(!node))
185 return -ENODEV;
186
187 base = of_iomap(node, 0);
188 WARN(!base, "unable to map fpga irq registers\n");
189
190 if (of_property_read_u32(node, "clear-mask", &clear_mask))
191 clear_mask = 0;
192
193 if (of_property_read_u32(node, "valid-mask", &valid_mask))
194 valid_mask = 0;
195
196 f = fpga_irq_prep_struct(base, node->name, valid_mask);
197 if (!f)
198 return -ENOMEM;
199
200 writel(clear_mask, base + IRQ_ENABLE_CLEAR);
201 writel(clear_mask, base + FIQ_ENABLE_CLEAR);
202
203 f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f);
204 f->used_irqs = hweight32(valid_mask);
205
206 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
207 fpga_irq_id, node->name, base, f->used_irqs);
208 return 0;
158} 209}
210#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;
7void fpga_handle_irq(struct pt_regs *regs); 7void fpga_handle_irq(struct pt_regs *regs);
8void fpga_irq_init(void __iomem *, const char *, int, int, u32, 8void fpga_irq_init(void __iomem *, const char *, int, int, u32,
9 struct device_node *node); 9 struct device_node *node);
10int fpga_irq_of_init(struct device_node *node,
11 struct device_node *parent);
10 12
11#endif 13#endif