diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-11 13:45:21 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-11 13:45:21 -0400 |
commit | 254c44ea822066e24ab5efbdff1e43b8fe45ae76 (patch) | |
tree | 547f6fd4ce1bd6dba6a5cc5184df28501d550795 /arch/arm | |
parent | 7b76415375ba91f5a06f8d5179278c03d6151d16 (diff) | |
parent | 6ac77e469e991e9dd91b28e503fa24b5609eedba (diff) |
Merge branch 'gic-fasteoi' of git://linux-arm.org/linux-2.6-wd into devel-stable
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/common/gic.c | 84 | ||||
-rw-r--r-- | arch/arm/configs/at91x40_defconfig | 48 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-at91/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-eb01.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/cpu.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/irq-combiner.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-msm/gpio-v2.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/gpio.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/legacy_irq.h | 35 | ||||
-rw-r--r-- | arch/arm/mach-tegra/irq.c | 174 | ||||
-rw-r--r-- | arch/arm/mach-tegra/legacy_irq.c | 215 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 12 | ||||
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 7 |
15 files changed, 235 insertions, 411 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index f70ec7dadebb..4ddd0a6ac7ff 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -49,7 +49,7 @@ struct gic_chip_data { | |||
49 | * Default make them NULL. | 49 | * Default make them NULL. |
50 | */ | 50 | */ |
51 | struct irq_chip gic_arch_extn = { | 51 | struct irq_chip gic_arch_extn = { |
52 | .irq_ack = NULL, | 52 | .irq_eoi = NULL, |
53 | .irq_mask = NULL, | 53 | .irq_mask = NULL, |
54 | .irq_unmask = NULL, | 54 | .irq_unmask = NULL, |
55 | .irq_retrigger = NULL, | 55 | .irq_retrigger = NULL, |
@@ -84,21 +84,12 @@ static inline unsigned int gic_irq(struct irq_data *d) | |||
84 | /* | 84 | /* |
85 | * Routines to acknowledge, disable and enable interrupts | 85 | * Routines to acknowledge, disable and enable interrupts |
86 | */ | 86 | */ |
87 | static void gic_ack_irq(struct irq_data *d) | ||
88 | { | ||
89 | spin_lock(&irq_controller_lock); | ||
90 | if (gic_arch_extn.irq_ack) | ||
91 | gic_arch_extn.irq_ack(d); | ||
92 | writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); | ||
93 | spin_unlock(&irq_controller_lock); | ||
94 | } | ||
95 | |||
96 | static void gic_mask_irq(struct irq_data *d) | 87 | static void gic_mask_irq(struct irq_data *d) |
97 | { | 88 | { |
98 | u32 mask = 1 << (d->irq % 32); | 89 | u32 mask = 1 << (d->irq % 32); |
99 | 90 | ||
100 | spin_lock(&irq_controller_lock); | 91 | spin_lock(&irq_controller_lock); |
101 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); | 92 | writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); |
102 | if (gic_arch_extn.irq_mask) | 93 | if (gic_arch_extn.irq_mask) |
103 | gic_arch_extn.irq_mask(d); | 94 | gic_arch_extn.irq_mask(d); |
104 | spin_unlock(&irq_controller_lock); | 95 | spin_unlock(&irq_controller_lock); |
@@ -111,10 +102,21 @@ static void gic_unmask_irq(struct irq_data *d) | |||
111 | spin_lock(&irq_controller_lock); | 102 | spin_lock(&irq_controller_lock); |
112 | if (gic_arch_extn.irq_unmask) | 103 | if (gic_arch_extn.irq_unmask) |
113 | gic_arch_extn.irq_unmask(d); | 104 | gic_arch_extn.irq_unmask(d); |
114 | writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); | 105 | writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); |
115 | spin_unlock(&irq_controller_lock); | 106 | spin_unlock(&irq_controller_lock); |
116 | } | 107 | } |
117 | 108 | ||
109 | static void gic_eoi_irq(struct irq_data *d) | ||
110 | { | ||
111 | if (gic_arch_extn.irq_eoi) { | ||
112 | spin_lock(&irq_controller_lock); | ||
113 | gic_arch_extn.irq_eoi(d); | ||
114 | spin_unlock(&irq_controller_lock); | ||
115 | } | ||
116 | |||
117 | writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); | ||
118 | } | ||
119 | |||
118 | static int gic_set_type(struct irq_data *d, unsigned int type) | 120 | static int gic_set_type(struct irq_data *d, unsigned int type) |
119 | { | 121 | { |
120 | void __iomem *base = gic_dist_base(d); | 122 | void __iomem *base = gic_dist_base(d); |
@@ -138,7 +140,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
138 | if (gic_arch_extn.irq_set_type) | 140 | if (gic_arch_extn.irq_set_type) |
139 | gic_arch_extn.irq_set_type(d, type); | 141 | gic_arch_extn.irq_set_type(d, type); |
140 | 142 | ||
141 | val = readl(base + GIC_DIST_CONFIG + confoff); | 143 | val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); |
142 | if (type == IRQ_TYPE_LEVEL_HIGH) | 144 | if (type == IRQ_TYPE_LEVEL_HIGH) |
143 | val &= ~confmask; | 145 | val &= ~confmask; |
144 | else if (type == IRQ_TYPE_EDGE_RISING) | 146 | else if (type == IRQ_TYPE_EDGE_RISING) |
@@ -148,15 +150,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
148 | * As recommended by the spec, disable the interrupt before changing | 150 | * As recommended by the spec, disable the interrupt before changing |
149 | * the configuration | 151 | * the configuration |
150 | */ | 152 | */ |
151 | if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { | 153 | if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { |
152 | writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); | 154 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); |
153 | enabled = true; | 155 | enabled = true; |
154 | } | 156 | } |
155 | 157 | ||
156 | writel(val, base + GIC_DIST_CONFIG + confoff); | 158 | writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); |
157 | 159 | ||
158 | if (enabled) | 160 | if (enabled) |
159 | writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | 161 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); |
160 | 162 | ||
161 | spin_unlock(&irq_controller_lock); | 163 | spin_unlock(&irq_controller_lock); |
162 | 164 | ||
@@ -188,8 +190,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
188 | 190 | ||
189 | spin_lock(&irq_controller_lock); | 191 | spin_lock(&irq_controller_lock); |
190 | d->node = cpu; | 192 | d->node = cpu; |
191 | val = readl(reg) & ~mask; | 193 | val = readl_relaxed(reg) & ~mask; |
192 | writel(val | bit, reg); | 194 | writel_relaxed(val | bit, reg); |
193 | spin_unlock(&irq_controller_lock); | 195 | spin_unlock(&irq_controller_lock); |
194 | 196 | ||
195 | return 0; | 197 | return 0; |
@@ -218,11 +220,10 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
218 | unsigned int cascade_irq, gic_irq; | 220 | unsigned int cascade_irq, gic_irq; |
219 | unsigned long status; | 221 | unsigned long status; |
220 | 222 | ||
221 | /* primary controller ack'ing */ | 223 | chained_irq_enter(chip, desc); |
222 | chip->irq_ack(&desc->irq_data); | ||
223 | 224 | ||
224 | spin_lock(&irq_controller_lock); | 225 | spin_lock(&irq_controller_lock); |
225 | status = readl(chip_data->cpu_base + GIC_CPU_INTACK); | 226 | status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); |
226 | spin_unlock(&irq_controller_lock); | 227 | spin_unlock(&irq_controller_lock); |
227 | 228 | ||
228 | gic_irq = (status & 0x3ff); | 229 | gic_irq = (status & 0x3ff); |
@@ -236,15 +237,14 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
236 | generic_handle_irq(cascade_irq); | 237 | generic_handle_irq(cascade_irq); |
237 | 238 | ||
238 | out: | 239 | out: |
239 | /* primary controller unmasking */ | 240 | chained_irq_exit(chip, desc); |
240 | chip->irq_unmask(&desc->irq_data); | ||
241 | } | 241 | } |
242 | 242 | ||
243 | static struct irq_chip gic_chip = { | 243 | static struct irq_chip gic_chip = { |
244 | .name = "GIC", | 244 | .name = "GIC", |
245 | .irq_ack = gic_ack_irq, | ||
246 | .irq_mask = gic_mask_irq, | 245 | .irq_mask = gic_mask_irq, |
247 | .irq_unmask = gic_unmask_irq, | 246 | .irq_unmask = gic_unmask_irq, |
247 | .irq_eoi = gic_eoi_irq, | ||
248 | .irq_set_type = gic_set_type, | 248 | .irq_set_type = gic_set_type, |
249 | .irq_retrigger = gic_retrigger, | 249 | .irq_retrigger = gic_retrigger, |
250 | #ifdef CONFIG_SMP | 250 | #ifdef CONFIG_SMP |
@@ -272,13 +272,13 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
272 | cpumask |= cpumask << 8; | 272 | cpumask |= cpumask << 8; |
273 | cpumask |= cpumask << 16; | 273 | cpumask |= cpumask << 16; |
274 | 274 | ||
275 | writel(0, base + GIC_DIST_CTRL); | 275 | writel_relaxed(0, base + GIC_DIST_CTRL); |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * Find out how many interrupts are supported. | 278 | * Find out how many interrupts are supported. |
279 | * The GIC only supports up to 1020 interrupt sources. | 279 | * The GIC only supports up to 1020 interrupt sources. |
280 | */ | 280 | */ |
281 | gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f; | 281 | gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f; |
282 | gic_irqs = (gic_irqs + 1) * 32; | 282 | gic_irqs = (gic_irqs + 1) * 32; |
283 | if (gic_irqs > 1020) | 283 | if (gic_irqs > 1020) |
284 | gic_irqs = 1020; | 284 | gic_irqs = 1020; |
@@ -287,26 +287,26 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
287 | * Set all global interrupts to be level triggered, active low. | 287 | * Set all global interrupts to be level triggered, active low. |
288 | */ | 288 | */ |
289 | for (i = 32; i < gic_irqs; i += 16) | 289 | for (i = 32; i < gic_irqs; i += 16) |
290 | writel(0, base + GIC_DIST_CONFIG + i * 4 / 16); | 290 | writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16); |
291 | 291 | ||
292 | /* | 292 | /* |
293 | * Set all global interrupts to this CPU only. | 293 | * Set all global interrupts to this CPU only. |
294 | */ | 294 | */ |
295 | for (i = 32; i < gic_irqs; i += 4) | 295 | for (i = 32; i < gic_irqs; i += 4) |
296 | writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); | 296 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * Set priority on all global interrupts. | 299 | * Set priority on all global interrupts. |
300 | */ | 300 | */ |
301 | for (i = 32; i < gic_irqs; i += 4) | 301 | for (i = 32; i < gic_irqs; i += 4) |
302 | writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); | 302 | writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * Disable all interrupts. Leave the PPI and SGIs alone | 305 | * Disable all interrupts. Leave the PPI and SGIs alone |
306 | * as these enables are banked registers. | 306 | * as these enables are banked registers. |
307 | */ | 307 | */ |
308 | for (i = 32; i < gic_irqs; i += 32) | 308 | for (i = 32; i < gic_irqs; i += 32) |
309 | writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); | 309 | writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); |
310 | 310 | ||
311 | /* | 311 | /* |
312 | * Limit number of interrupts registered to the platform maximum | 312 | * Limit number of interrupts registered to the platform maximum |
@@ -319,12 +319,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
319 | * Setup the Linux IRQ subsystem. | 319 | * Setup the Linux IRQ subsystem. |
320 | */ | 320 | */ |
321 | for (i = irq_start; i < irq_limit; i++) { | 321 | for (i = irq_start; i < irq_limit; i++) { |
322 | irq_set_chip_and_handler(i, &gic_chip, handle_level_irq); | 322 | irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); |
323 | irq_set_chip_data(i, gic); | 323 | irq_set_chip_data(i, gic); |
324 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | 324 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
325 | } | 325 | } |
326 | 326 | ||
327 | writel(1, base + GIC_DIST_CTRL); | 327 | writel_relaxed(1, base + GIC_DIST_CTRL); |
328 | } | 328 | } |
329 | 329 | ||
330 | static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | 330 | static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) |
@@ -337,17 +337,17 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | |||
337 | * Deal with the banked PPI and SGI interrupts - disable all | 337 | * Deal with the banked PPI and SGI interrupts - disable all |
338 | * PPI interrupts, ensure all SGI interrupts are enabled. | 338 | * PPI interrupts, ensure all SGI interrupts are enabled. |
339 | */ | 339 | */ |
340 | writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); | 340 | writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); |
341 | writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); | 341 | writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); |
342 | 342 | ||
343 | /* | 343 | /* |
344 | * Set priority on PPI and SGI interrupts | 344 | * Set priority on PPI and SGI interrupts |
345 | */ | 345 | */ |
346 | for (i = 0; i < 32; i += 4) | 346 | for (i = 0; i < 32; i += 4) |
347 | writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); | 347 | writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); |
348 | 348 | ||
349 | writel(0xf0, base + GIC_CPU_PRIMASK); | 349 | writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); |
350 | writel(1, base + GIC_CPU_CTRL); | 350 | writel_relaxed(1, base + GIC_CPU_CTRL); |
351 | } | 351 | } |
352 | 352 | ||
353 | void __init gic_init(unsigned int gic_nr, unsigned int irq_start, | 353 | void __init gic_init(unsigned int gic_nr, unsigned int irq_start, |
@@ -391,7 +391,13 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
391 | { | 391 | { |
392 | unsigned long map = *cpus_addr(*mask); | 392 | unsigned long map = *cpus_addr(*mask); |
393 | 393 | ||
394 | /* | ||
395 | * Ensure that stores to Normal memory are visible to the | ||
396 | * other CPUs before issuing the IPI. | ||
397 | */ | ||
398 | dsb(); | ||
399 | |||
394 | /* this always happens on GIC0 */ | 400 | /* this always happens on GIC0 */ |
395 | writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); | 401 | writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); |
396 | } | 402 | } |
397 | #endif | 403 | #endif |
diff --git a/arch/arm/configs/at91x40_defconfig b/arch/arm/configs/at91x40_defconfig new file mode 100644 index 000000000000..c55e9212fcbb --- /dev/null +++ b/arch/arm/configs/at91x40_defconfig | |||
@@ -0,0 +1,48 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_LOG_BUF_SHIFT=14 | ||
3 | CONFIG_EMBEDDED=y | ||
4 | # CONFIG_HOTPLUG is not set | ||
5 | # CONFIG_ELF_CORE is not set | ||
6 | # CONFIG_FUTEX is not set | ||
7 | # CONFIG_TIMERFD is not set | ||
8 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
9 | # CONFIG_COMPAT_BRK is not set | ||
10 | CONFIG_SLAB=y | ||
11 | # CONFIG_LBDAF is not set | ||
12 | # CONFIG_BLK_DEV_BSG is not set | ||
13 | # CONFIG_IOSCHED_DEADLINE is not set | ||
14 | # CONFIG_IOSCHED_CFQ is not set | ||
15 | # CONFIG_MMU is not set | ||
16 | CONFIG_ARCH_AT91=y | ||
17 | CONFIG_ARCH_AT91X40=y | ||
18 | CONFIG_MACH_AT91EB01=y | ||
19 | CONFIG_AT91_EARLY_USART0=y | ||
20 | CONFIG_CPU_ARM7TDMI=y | ||
21 | CONFIG_SET_MEM_PARAM=y | ||
22 | CONFIG_DRAM_BASE=0x01000000 | ||
23 | CONFIG_DRAM_SIZE=0x00400000 | ||
24 | CONFIG_FLASH_MEM_BASE=0x01400000 | ||
25 | CONFIG_PROCESSOR_ID=0x14000040 | ||
26 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
27 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
28 | CONFIG_BINFMT_FLAT=y | ||
29 | # CONFIG_SUSPEND is not set | ||
30 | # CONFIG_FW_LOADER is not set | ||
31 | CONFIG_MTD=y | ||
32 | CONFIG_MTD_PARTITIONS=y | ||
33 | CONFIG_MTD_CHAR=y | ||
34 | CONFIG_MTD_BLOCK=y | ||
35 | CONFIG_MTD_RAM=y | ||
36 | CONFIG_MTD_ROM=y | ||
37 | CONFIG_BLK_DEV_RAM=y | ||
38 | # CONFIG_INPUT is not set | ||
39 | # CONFIG_SERIO is not set | ||
40 | # CONFIG_VT is not set | ||
41 | # CONFIG_DEVKMEM is not set | ||
42 | # CONFIG_HW_RANDOM is not set | ||
43 | # CONFIG_HWMON is not set | ||
44 | # CONFIG_USB_SUPPORT is not set | ||
45 | CONFIG_EXT2_FS=y | ||
46 | # CONFIG_DNOTIFY is not set | ||
47 | CONFIG_ROMFS_FS=y | ||
48 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 2bf27f364d09..8182f45ca493 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request, | |||
767 | 767 | ||
768 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 768 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
769 | case PTRACE_GETHBPREGS: | 769 | case PTRACE_GETHBPREGS: |
770 | if (ptrace_get_breakpoints(child) < 0) | ||
771 | return -ESRCH; | ||
772 | |||
770 | ret = ptrace_gethbpregs(child, addr, | 773 | ret = ptrace_gethbpregs(child, addr, |
771 | (unsigned long __user *)data); | 774 | (unsigned long __user *)data); |
775 | ptrace_put_breakpoints(child); | ||
772 | break; | 776 | break; |
773 | case PTRACE_SETHBPREGS: | 777 | case PTRACE_SETHBPREGS: |
778 | if (ptrace_get_breakpoints(child) < 0) | ||
779 | return -ESRCH; | ||
780 | |||
774 | ret = ptrace_sethbpregs(child, addr, | 781 | ret = ptrace_sethbpregs(child, addr, |
775 | (unsigned long __user *)data); | 782 | (unsigned long __user *)data); |
783 | ptrace_put_breakpoints(child); | ||
776 | break; | 784 | break; |
777 | #endif | 785 | #endif |
778 | 786 | ||
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 19390231a0e9..2d299bf5d72f 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -83,6 +83,7 @@ config ARCH_AT91CAP9 | |||
83 | select CPU_ARM926T | 83 | select CPU_ARM926T |
84 | select GENERIC_CLOCKEVENTS | 84 | select GENERIC_CLOCKEVENTS |
85 | select HAVE_FB_ATMEL | 85 | select HAVE_FB_ATMEL |
86 | select HAVE_NET_MACB | ||
86 | 87 | ||
87 | config ARCH_AT572D940HF | 88 | config ARCH_AT572D940HF |
88 | bool "AT572D940HF" | 89 | bool "AT572D940HF" |
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c index 1f9d3cb64c50..d8df59a3426d 100644 --- a/arch/arm/mach-at91/board-eb01.c +++ b/arch/arm/mach-at91/board-eb01.c | |||
@@ -30,6 +30,11 @@ | |||
30 | #include <mach/board.h> | 30 | #include <mach/board.h> |
31 | #include "generic.h" | 31 | #include "generic.h" |
32 | 32 | ||
33 | static void __init at91eb01_init_irq(void) | ||
34 | { | ||
35 | at91x40_init_interrupts(NULL); | ||
36 | } | ||
37 | |||
33 | static void __init at91eb01_map_io(void) | 38 | static void __init at91eb01_map_io(void) |
34 | { | 39 | { |
35 | at91x40_initialize(40000000); | 40 | at91x40_initialize(40000000); |
@@ -38,7 +43,7 @@ static void __init at91eb01_map_io(void) | |||
38 | MACHINE_START(AT91EB01, "Atmel AT91 EB01") | 43 | MACHINE_START(AT91EB01, "Atmel AT91 EB01") |
39 | /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ | 44 | /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ |
40 | .timer = &at91x40_timer, | 45 | .timer = &at91x40_timer, |
41 | .init_irq = at91x40_init_interrupts, | 46 | .init_irq = at91eb01_init_irq, |
42 | .map_io = at91eb01_map_io, | 47 | .map_io = at91eb01_map_io, |
43 | MACHINE_END | 48 | MACHINE_END |
44 | 49 | ||
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index 3bef931d0b1c..0700f2125305 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define ARCH_ID_AT91SAM9G45 0x819b05a0 | 27 | #define ARCH_ID_AT91SAM9G45 0x819b05a0 |
28 | #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ | 28 | #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ |
29 | #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ | 29 | #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ |
30 | #define ARCH_ID_AT91SAM9X5 0x819a05a0 | ||
30 | #define ARCH_ID_AT91CAP9 0x039A03A0 | 31 | #define ARCH_ID_AT91CAP9 0x039A03A0 |
31 | 32 | ||
32 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 | 33 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 |
@@ -55,6 +56,12 @@ static inline unsigned long at91_cpu_fully_identify(void) | |||
55 | #define ARCH_EXID_AT91SAM9G46 0x00000003 | 56 | #define ARCH_EXID_AT91SAM9G46 0x00000003 |
56 | #define ARCH_EXID_AT91SAM9G45 0x00000004 | 57 | #define ARCH_EXID_AT91SAM9G45 0x00000004 |
57 | 58 | ||
59 | #define ARCH_EXID_AT91SAM9G15 0x00000000 | ||
60 | #define ARCH_EXID_AT91SAM9G35 0x00000001 | ||
61 | #define ARCH_EXID_AT91SAM9X35 0x00000002 | ||
62 | #define ARCH_EXID_AT91SAM9G25 0x00000003 | ||
63 | #define ARCH_EXID_AT91SAM9X25 0x00000004 | ||
64 | |||
58 | static inline unsigned long at91_exid_identify(void) | 65 | static inline unsigned long at91_exid_identify(void) |
59 | { | 66 | { |
60 | return at91_sys_read(AT91_DBGU_EXID); | 67 | return at91_sys_read(AT91_DBGU_EXID); |
@@ -143,6 +150,27 @@ static inline unsigned long at91cap9_rev_identify(void) | |||
143 | #define cpu_is_at91sam9m11() (0) | 150 | #define cpu_is_at91sam9m11() (0) |
144 | #endif | 151 | #endif |
145 | 152 | ||
153 | #ifdef CONFIG_ARCH_AT91SAM9X5 | ||
154 | #define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5) | ||
155 | #define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ | ||
156 | (at91_exid_identify() == ARCH_EXID_AT91SAM9G15)) | ||
157 | #define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ | ||
158 | (at91_exid_identify() == ARCH_EXID_AT91SAM9G35)) | ||
159 | #define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ | ||
160 | (at91_exid_identify() == ARCH_EXID_AT91SAM9X35)) | ||
161 | #define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ | ||
162 | (at91_exid_identify() == ARCH_EXID_AT91SAM9G25)) | ||
163 | #define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ | ||
164 | (at91_exid_identify() == ARCH_EXID_AT91SAM9X25)) | ||
165 | #else | ||
166 | #define cpu_is_at91sam9x5() (0) | ||
167 | #define cpu_is_at91sam9g15() (0) | ||
168 | #define cpu_is_at91sam9g35() (0) | ||
169 | #define cpu_is_at91sam9x35() (0) | ||
170 | #define cpu_is_at91sam9g25() (0) | ||
171 | #define cpu_is_at91sam9x25() (0) | ||
172 | #endif | ||
173 | |||
146 | #ifdef CONFIG_ARCH_AT91CAP9 | 174 | #ifdef CONFIG_ARCH_AT91CAP9 |
147 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) | 175 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) |
148 | #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) | 176 | #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) |
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c index f488b66d6806..5a2758ab055e 100644 --- a/arch/arm/mach-exynos4/irq-combiner.c +++ b/arch/arm/mach-exynos4/irq-combiner.c | |||
@@ -59,8 +59,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
59 | unsigned int cascade_irq, combiner_irq; | 59 | unsigned int cascade_irq, combiner_irq; |
60 | unsigned long status; | 60 | unsigned long status; |
61 | 61 | ||
62 | /* primary controller ack'ing */ | 62 | chained_irq_enter(chip, desc); |
63 | chip->irq_ack(&desc->irq_data); | ||
64 | 63 | ||
65 | spin_lock(&irq_controller_lock); | 64 | spin_lock(&irq_controller_lock); |
66 | status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); | 65 | status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); |
@@ -79,8 +78,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
79 | generic_handle_irq(cascade_irq); | 78 | generic_handle_irq(cascade_irq); |
80 | 79 | ||
81 | out: | 80 | out: |
82 | /* primary controller unmasking */ | 81 | chained_irq_exit(chip, desc); |
83 | chip->irq_unmask(&desc->irq_data); | ||
84 | } | 82 | } |
85 | 83 | ||
86 | static struct irq_chip combiner_chip = { | 84 | static struct irq_chip combiner_chip = { |
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c index 56a964e52ad3..cc9c4fd7cccc 100644 --- a/arch/arm/mach-msm/gpio-v2.c +++ b/arch/arm/mach-msm/gpio-v2.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | |||
31 | #include <asm/mach/irq.h> | ||
32 | |||
30 | #include <mach/msm_iomap.h> | 33 | #include <mach/msm_iomap.h> |
31 | #include "gpiomux.h" | 34 | #include "gpiomux.h" |
32 | 35 | ||
@@ -309,8 +312,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) | |||
309 | */ | 312 | */ |
310 | static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) | 313 | static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) |
311 | { | 314 | { |
312 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
313 | unsigned long i; | 315 | unsigned long i; |
316 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
317 | |||
318 | chained_irq_enter(chip, desc); | ||
314 | 319 | ||
315 | for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS); | 320 | for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS); |
316 | i < NR_GPIO_IRQS; | 321 | i < NR_GPIO_IRQS; |
@@ -319,7 +324,8 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
319 | generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip, | 324 | generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip, |
320 | i)); | 325 | i)); |
321 | } | 326 | } |
322 | data->chip->irq_ack(data); | 327 | |
328 | chained_irq_exit(chip, desc); | ||
323 | } | 329 | } |
324 | 330 | ||
325 | static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | 331 | static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 1afe05038c27..823c703e573c 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-y += common.o | 1 | obj-y += common.o |
2 | obj-y += devices.o | 2 | obj-y += devices.o |
3 | obj-y += io.o | 3 | obj-y += io.o |
4 | obj-y += irq.o legacy_irq.o | 4 | obj-y += irq.o |
5 | obj-y += clock.o | 5 | obj-y += clock.o |
6 | obj-y += timer.o | 6 | obj-y += timer.o |
7 | obj-y += gpio.o | 7 | obj-y += gpio.o |
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c index 65a1aba6823d..919d63837736 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/arch/arm/mach-tegra/gpio.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | 26 | ||
27 | #include <asm/mach/irq.h> | ||
28 | |||
27 | #include <mach/iomap.h> | 29 | #include <mach/iomap.h> |
28 | #include <mach/suspend.h> | 30 | #include <mach/suspend.h> |
29 | 31 | ||
@@ -221,8 +223,9 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
221 | int port; | 223 | int port; |
222 | int pin; | 224 | int pin; |
223 | int unmasked = 0; | 225 | int unmasked = 0; |
226 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
224 | 227 | ||
225 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 228 | chained_irq_enter(chip, desc); |
226 | 229 | ||
227 | bank = irq_get_handler_data(irq); | 230 | bank = irq_get_handler_data(irq); |
228 | 231 | ||
@@ -241,7 +244,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
241 | */ | 244 | */ |
242 | if (lvl & (0x100 << pin)) { | 245 | if (lvl & (0x100 << pin)) { |
243 | unmasked = 1; | 246 | unmasked = 1; |
244 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 247 | chained_irq_exit(chip, desc); |
245 | } | 248 | } |
246 | 249 | ||
247 | generic_handle_irq(gpio_to_irq(gpio + pin)); | 250 | generic_handle_irq(gpio_to_irq(gpio + pin)); |
@@ -249,7 +252,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
249 | } | 252 | } |
250 | 253 | ||
251 | if (!unmasked) | 254 | if (!unmasked) |
252 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 255 | chained_irq_exit(chip, desc); |
253 | 256 | ||
254 | } | 257 | } |
255 | 258 | ||
diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h deleted file mode 100644 index d898c0e3d905..000000000000 --- a/arch/arm/mach-tegra/include/mach/legacy_irq.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/include/mach/legacy_irq.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Author: Colin Cross <ccross@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H | ||
19 | #define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H | ||
20 | |||
21 | void tegra_legacy_mask_irq(unsigned int irq); | ||
22 | void tegra_legacy_unmask_irq(unsigned int irq); | ||
23 | void tegra_legacy_select_fiq(unsigned int irq, bool fiq); | ||
24 | void tegra_legacy_force_irq_set(unsigned int irq); | ||
25 | void tegra_legacy_force_irq_clr(unsigned int irq); | ||
26 | int tegra_legacy_force_irq_status(unsigned int irq); | ||
27 | void tegra_legacy_select_fiq(unsigned int irq, bool fiq); | ||
28 | unsigned long tegra_legacy_vfiq(int nr); | ||
29 | unsigned long tegra_legacy_class(int nr); | ||
30 | int tegra_legacy_irq_set_wake(int irq, int enable); | ||
31 | void tegra_legacy_irq_set_lp1_wake_mask(void); | ||
32 | void tegra_legacy_irq_restore_mask(void); | ||
33 | void tegra_init_legacy_irq(void); | ||
34 | |||
35 | #endif | ||
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4330d8995b27..4956c3cea731 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Google, Inc. | 2 | * Copyright (C) 2011 Google, Inc. |
3 | * | 3 | * |
4 | * Author: | 4 | * Author: |
5 | * Colin Cross <ccross@google.com> | 5 | * Colin Cross <ccross@android.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2010, NVIDIA Corporation | 7 | * Copyright (C) 2010, NVIDIA Corporation |
8 | * | 8 | * |
@@ -18,8 +18,6 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/delay.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
25 | #include <linux/io.h> | 23 | #include <linux/io.h> |
@@ -27,134 +25,110 @@ | |||
27 | #include <asm/hardware/gic.h> | 25 | #include <asm/hardware/gic.h> |
28 | 26 | ||
29 | #include <mach/iomap.h> | 27 | #include <mach/iomap.h> |
30 | #include <mach/legacy_irq.h> | ||
31 | #include <mach/suspend.h> | ||
32 | 28 | ||
33 | #include "board.h" | 29 | #include "board.h" |
34 | 30 | ||
35 | #define PMC_CTRL 0x0 | 31 | #define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) |
36 | #define PMC_CTRL_LATCH_WAKEUPS (1 << 5) | 32 | #define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) |
37 | #define PMC_WAKE_MASK 0xc | 33 | #define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) |
38 | #define PMC_WAKE_LEVEL 0x10 | 34 | |
39 | #define PMC_WAKE_STATUS 0x14 | 35 | #define ICTLR_CPU_IEP_VFIQ 0x08 |
40 | #define PMC_SW_WAKE_STATUS 0x18 | 36 | #define ICTLR_CPU_IEP_FIR 0x14 |
41 | #define PMC_DPD_SAMPLE 0x20 | 37 | #define ICTLR_CPU_IEP_FIR_SET 0x18 |
38 | #define ICTLR_CPU_IEP_FIR_CLR 0x1c | ||
39 | |||
40 | #define ICTLR_CPU_IER 0x20 | ||
41 | #define ICTLR_CPU_IER_SET 0x24 | ||
42 | #define ICTLR_CPU_IER_CLR 0x28 | ||
43 | #define ICTLR_CPU_IEP_CLASS 0x2C | ||
44 | |||
45 | #define ICTLR_COP_IER 0x30 | ||
46 | #define ICTLR_COP_IER_SET 0x34 | ||
47 | #define ICTLR_COP_IER_CLR 0x38 | ||
48 | #define ICTLR_COP_IEP_CLASS 0x3c | ||
49 | |||
50 | #define NUM_ICTLRS 4 | ||
51 | #define FIRST_LEGACY_IRQ 32 | ||
52 | |||
53 | static void __iomem *ictlr_reg_base[] = { | ||
54 | IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), | ||
55 | IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), | ||
56 | IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), | ||
57 | IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), | ||
58 | }; | ||
42 | 59 | ||
43 | static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | 60 | static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) |
61 | { | ||
62 | void __iomem *base; | ||
63 | u32 mask; | ||
44 | 64 | ||
45 | static u32 tegra_lp0_wake_enb; | 65 | BUG_ON(irq < FIRST_LEGACY_IRQ || |
46 | static u32 tegra_lp0_wake_level; | 66 | irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32); |
47 | static u32 tegra_lp0_wake_level_any; | ||
48 | 67 | ||
49 | static void (*tegra_gic_mask_irq)(struct irq_data *d); | 68 | base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; |
50 | static void (*tegra_gic_unmask_irq)(struct irq_data *d); | 69 | mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); |
51 | static void (*tegra_gic_ack_irq)(struct irq_data *d); | ||
52 | 70 | ||
53 | /* ensures that sufficient time is passed for a register write to | 71 | __raw_writel(mask, base + reg); |
54 | * serialize into the 32KHz domain */ | ||
55 | static void pmc_32kwritel(u32 val, unsigned long offs) | ||
56 | { | ||
57 | writel(val, pmc + offs); | ||
58 | udelay(130); | ||
59 | } | 72 | } |
60 | 73 | ||
61 | int tegra_set_lp1_wake(int irq, int enable) | 74 | static void tegra_mask(struct irq_data *d) |
62 | { | 75 | { |
63 | return tegra_legacy_irq_set_wake(irq, enable); | 76 | if (d->irq < FIRST_LEGACY_IRQ) |
77 | return; | ||
78 | |||
79 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR); | ||
64 | } | 80 | } |
65 | 81 | ||
66 | void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any) | 82 | static void tegra_unmask(struct irq_data *d) |
67 | { | 83 | { |
68 | u32 temp; | 84 | if (d->irq < FIRST_LEGACY_IRQ) |
69 | u32 status; | 85 | return; |
70 | u32 lvl; | ||
71 | |||
72 | wake_level &= wake_enb; | ||
73 | wake_any &= wake_enb; | ||
74 | 86 | ||
75 | wake_level |= (tegra_lp0_wake_level & tegra_lp0_wake_enb); | 87 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET); |
76 | wake_any |= (tegra_lp0_wake_level_any & tegra_lp0_wake_enb); | ||
77 | |||
78 | wake_enb |= tegra_lp0_wake_enb; | ||
79 | |||
80 | pmc_32kwritel(0, PMC_SW_WAKE_STATUS); | ||
81 | temp = readl(pmc + PMC_CTRL); | ||
82 | temp |= PMC_CTRL_LATCH_WAKEUPS; | ||
83 | pmc_32kwritel(temp, PMC_CTRL); | ||
84 | temp &= ~PMC_CTRL_LATCH_WAKEUPS; | ||
85 | pmc_32kwritel(temp, PMC_CTRL); | ||
86 | status = readl(pmc + PMC_SW_WAKE_STATUS); | ||
87 | lvl = readl(pmc + PMC_WAKE_LEVEL); | ||
88 | |||
89 | /* flip the wakeup trigger for any-edge triggered pads | ||
90 | * which are currently asserting as wakeups */ | ||
91 | lvl ^= status; | ||
92 | lvl &= wake_any; | ||
93 | |||
94 | wake_level |= lvl; | ||
95 | |||
96 | writel(wake_level, pmc + PMC_WAKE_LEVEL); | ||
97 | /* Enable DPD sample to trigger sampling pads data and direction | ||
98 | * in which pad will be driven during lp0 mode*/ | ||
99 | writel(0x1, pmc + PMC_DPD_SAMPLE); | ||
100 | |||
101 | writel(wake_enb, pmc + PMC_WAKE_MASK); | ||
102 | } | 88 | } |
103 | 89 | ||
104 | static void tegra_mask(struct irq_data *d) | 90 | static void tegra_ack(struct irq_data *d) |
105 | { | 91 | { |
106 | tegra_gic_mask_irq(d); | 92 | if (d->irq < FIRST_LEGACY_IRQ) |
107 | tegra_legacy_mask_irq(d->irq); | 93 | return; |
108 | } | ||
109 | 94 | ||
110 | static void tegra_unmask(struct irq_data *d) | 95 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); |
111 | { | ||
112 | tegra_gic_unmask_irq(d); | ||
113 | tegra_legacy_unmask_irq(d->irq); | ||
114 | } | 96 | } |
115 | 97 | ||
116 | static void tegra_ack(struct irq_data *d) | 98 | static void tegra_eoi(struct irq_data *d) |
117 | { | 99 | { |
118 | tegra_legacy_force_irq_clr(d->irq); | 100 | if (d->irq < FIRST_LEGACY_IRQ) |
119 | tegra_gic_ack_irq(d); | 101 | return; |
102 | |||
103 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); | ||
120 | } | 104 | } |
121 | 105 | ||
122 | static int tegra_retrigger(struct irq_data *d) | 106 | static int tegra_retrigger(struct irq_data *d) |
123 | { | 107 | { |
124 | tegra_legacy_force_irq_set(d->irq); | 108 | if (d->irq < FIRST_LEGACY_IRQ) |
109 | return 0; | ||
110 | |||
111 | tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET); | ||
112 | |||
125 | return 1; | 113 | return 1; |
126 | } | 114 | } |
127 | 115 | ||
128 | static struct irq_chip tegra_irq = { | ||
129 | .name = "PPI", | ||
130 | .irq_ack = tegra_ack, | ||
131 | .irq_mask = tegra_mask, | ||
132 | .irq_unmask = tegra_unmask, | ||
133 | .irq_retrigger = tegra_retrigger, | ||
134 | }; | ||
135 | |||
136 | void __init tegra_init_irq(void) | 116 | void __init tegra_init_irq(void) |
137 | { | 117 | { |
138 | struct irq_chip *gic; | 118 | int i; |
139 | unsigned int i; | ||
140 | int irq; | ||
141 | 119 | ||
142 | tegra_init_legacy_irq(); | 120 | for (i = 0; i < NUM_ICTLRS; i++) { |
121 | void __iomem *ictlr = ictlr_reg_base[i]; | ||
122 | writel(~0, ictlr + ICTLR_CPU_IER_CLR); | ||
123 | writel(0, ictlr + ICTLR_CPU_IEP_CLASS); | ||
124 | } | ||
125 | |||
126 | gic_arch_extn.irq_ack = tegra_ack; | ||
127 | gic_arch_extn.irq_eoi = tegra_eoi; | ||
128 | gic_arch_extn.irq_mask = tegra_mask; | ||
129 | gic_arch_extn.irq_unmask = tegra_unmask; | ||
130 | gic_arch_extn.irq_retrigger = tegra_retrigger; | ||
143 | 131 | ||
144 | gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), | 132 | gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), |
145 | IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); | 133 | IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); |
146 | |||
147 | gic = irq_get_chip(29); | ||
148 | tegra_gic_unmask_irq = gic->irq_unmask; | ||
149 | tegra_gic_mask_irq = gic->irq_mask; | ||
150 | tegra_gic_ack_irq = gic->irq_ack; | ||
151 | #ifdef CONFIG_SMP | ||
152 | tegra_irq.irq_set_affinity = gic->irq_set_affinity; | ||
153 | #endif | ||
154 | |||
155 | for (i = 0; i < INT_MAIN_NR; i++) { | ||
156 | irq = INT_PRI_BASE + i; | ||
157 | irq_set_chip_and_handler(irq, &tegra_irq, handle_level_irq); | ||
158 | set_irq_flags(irq, IRQF_VALID); | ||
159 | } | ||
160 | } | 134 | } |
diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c deleted file mode 100644 index 38eb719a4f53..000000000000 --- a/arch/arm/mach-tegra/legacy_irq.c +++ /dev/null | |||
@@ -1,215 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/legacy_irq.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Author: Colin Cross <ccross@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <mach/iomap.h> | ||
21 | #include <mach/irqs.h> | ||
22 | #include <mach/legacy_irq.h> | ||
23 | |||
24 | #define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) | ||
25 | #define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) | ||
26 | #define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) | ||
27 | |||
28 | #define ICTLR_CPU_IEP_VFIQ 0x08 | ||
29 | #define ICTLR_CPU_IEP_FIR 0x14 | ||
30 | #define ICTLR_CPU_IEP_FIR_SET 0x18 | ||
31 | #define ICTLR_CPU_IEP_FIR_CLR 0x1c | ||
32 | |||
33 | #define ICTLR_CPU_IER 0x20 | ||
34 | #define ICTLR_CPU_IER_SET 0x24 | ||
35 | #define ICTLR_CPU_IER_CLR 0x28 | ||
36 | #define ICTLR_CPU_IEP_CLASS 0x2C | ||
37 | |||
38 | #define ICTLR_COP_IER 0x30 | ||
39 | #define ICTLR_COP_IER_SET 0x34 | ||
40 | #define ICTLR_COP_IER_CLR 0x38 | ||
41 | #define ICTLR_COP_IEP_CLASS 0x3c | ||
42 | |||
43 | #define NUM_ICTLRS 4 | ||
44 | |||
45 | static void __iomem *ictlr_reg_base[] = { | ||
46 | IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), | ||
47 | IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), | ||
48 | IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), | ||
49 | IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), | ||
50 | }; | ||
51 | |||
52 | static u32 tegra_legacy_wake_mask[4]; | ||
53 | static u32 tegra_legacy_saved_mask[4]; | ||
54 | |||
55 | /* When going into deep sleep, the CPU is powered down, taking the GIC with it | ||
56 | In order to wake, the wake interrupts need to be enabled in the legacy | ||
57 | interrupt controller. */ | ||
58 | void tegra_legacy_unmask_irq(unsigned int irq) | ||
59 | { | ||
60 | void __iomem *base; | ||
61 | pr_debug("%s: %d\n", __func__, irq); | ||
62 | |||
63 | irq -= 32; | ||
64 | base = ictlr_reg_base[irq>>5]; | ||
65 | writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET); | ||
66 | } | ||
67 | |||
68 | void tegra_legacy_mask_irq(unsigned int irq) | ||
69 | { | ||
70 | void __iomem *base; | ||
71 | pr_debug("%s: %d\n", __func__, irq); | ||
72 | |||
73 | irq -= 32; | ||
74 | base = ictlr_reg_base[irq>>5]; | ||
75 | writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR); | ||
76 | } | ||
77 | |||
78 | void tegra_legacy_force_irq_set(unsigned int irq) | ||
79 | { | ||
80 | void __iomem *base; | ||
81 | pr_debug("%s: %d\n", __func__, irq); | ||
82 | |||
83 | irq -= 32; | ||
84 | base = ictlr_reg_base[irq>>5]; | ||
85 | writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET); | ||
86 | } | ||
87 | |||
88 | void tegra_legacy_force_irq_clr(unsigned int irq) | ||
89 | { | ||
90 | void __iomem *base; | ||
91 | pr_debug("%s: %d\n", __func__, irq); | ||
92 | |||
93 | irq -= 32; | ||
94 | base = ictlr_reg_base[irq>>5]; | ||
95 | writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR); | ||
96 | } | ||
97 | |||
98 | int tegra_legacy_force_irq_status(unsigned int irq) | ||
99 | { | ||
100 | void __iomem *base; | ||
101 | pr_debug("%s: %d\n", __func__, irq); | ||
102 | |||
103 | irq -= 32; | ||
104 | base = ictlr_reg_base[irq>>5]; | ||
105 | return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31))); | ||
106 | } | ||
107 | |||
108 | void tegra_legacy_select_fiq(unsigned int irq, bool fiq) | ||
109 | { | ||
110 | void __iomem *base; | ||
111 | pr_debug("%s: %d\n", __func__, irq); | ||
112 | |||
113 | irq -= 32; | ||
114 | base = ictlr_reg_base[irq>>5]; | ||
115 | writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS); | ||
116 | } | ||
117 | |||
118 | unsigned long tegra_legacy_vfiq(int nr) | ||
119 | { | ||
120 | void __iomem *base; | ||
121 | base = ictlr_reg_base[nr]; | ||
122 | return readl(base + ICTLR_CPU_IEP_VFIQ); | ||
123 | } | ||
124 | |||
125 | unsigned long tegra_legacy_class(int nr) | ||
126 | { | ||
127 | void __iomem *base; | ||
128 | base = ictlr_reg_base[nr]; | ||
129 | return readl(base + ICTLR_CPU_IEP_CLASS); | ||
130 | } | ||
131 | |||
132 | int tegra_legacy_irq_set_wake(int irq, int enable) | ||
133 | { | ||
134 | irq -= 32; | ||
135 | if (enable) | ||
136 | tegra_legacy_wake_mask[irq >> 5] |= 1 << (irq & 31); | ||
137 | else | ||
138 | tegra_legacy_wake_mask[irq >> 5] &= ~(1 << (irq & 31)); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | void tegra_legacy_irq_set_lp1_wake_mask(void) | ||
144 | { | ||
145 | void __iomem *base; | ||
146 | int i; | ||
147 | |||
148 | for (i = 0; i < NUM_ICTLRS; i++) { | ||
149 | base = ictlr_reg_base[i]; | ||
150 | tegra_legacy_saved_mask[i] = readl(base + ICTLR_CPU_IER); | ||
151 | writel(tegra_legacy_wake_mask[i], base + ICTLR_CPU_IER); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | void tegra_legacy_irq_restore_mask(void) | ||
156 | { | ||
157 | void __iomem *base; | ||
158 | int i; | ||
159 | |||
160 | for (i = 0; i < NUM_ICTLRS; i++) { | ||
161 | base = ictlr_reg_base[i]; | ||
162 | writel(tegra_legacy_saved_mask[i], base + ICTLR_CPU_IER); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | void tegra_init_legacy_irq(void) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | for (i = 0; i < NUM_ICTLRS; i++) { | ||
171 | void __iomem *ictlr = ictlr_reg_base[i]; | ||
172 | writel(~0, ictlr + ICTLR_CPU_IER_CLR); | ||
173 | writel(0, ictlr + ICTLR_CPU_IEP_CLASS); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | #ifdef CONFIG_PM | ||
178 | static u32 cop_ier[NUM_ICTLRS]; | ||
179 | static u32 cpu_ier[NUM_ICTLRS]; | ||
180 | static u32 cpu_iep[NUM_ICTLRS]; | ||
181 | |||
182 | void tegra_irq_suspend(void) | ||
183 | { | ||
184 | unsigned long flags; | ||
185 | int i; | ||
186 | |||
187 | local_irq_save(flags); | ||
188 | for (i = 0; i < NUM_ICTLRS; i++) { | ||
189 | void __iomem *ictlr = ictlr_reg_base[i]; | ||
190 | cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER); | ||
191 | cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS); | ||
192 | cop_ier[i] = readl(ictlr + ICTLR_COP_IER); | ||
193 | writel(~0, ictlr + ICTLR_COP_IER_CLR); | ||
194 | } | ||
195 | local_irq_restore(flags); | ||
196 | } | ||
197 | |||
198 | void tegra_irq_resume(void) | ||
199 | { | ||
200 | unsigned long flags; | ||
201 | int i; | ||
202 | |||
203 | local_irq_save(flags); | ||
204 | for (i = 0; i < NUM_ICTLRS; i++) { | ||
205 | void __iomem *ictlr = ictlr_reg_base[i]; | ||
206 | writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); | ||
207 | writel(~0ul, ictlr + ICTLR_CPU_IER_CLR); | ||
208 | writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); | ||
209 | writel(0, ictlr + ICTLR_COP_IEP_CLASS); | ||
210 | writel(~0ul, ictlr + ICTLR_COP_IER_CLR); | ||
211 | writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET); | ||
212 | } | ||
213 | local_irq_restore(flags); | ||
214 | } | ||
215 | #endif | ||
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index f49748eca1a3..307b8131aa8c 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include <asm/mach/irq.h> | ||
27 | |||
26 | #include <plat/pincfg.h> | 28 | #include <plat/pincfg.h> |
27 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
28 | #include <mach/gpio.h> | 30 | #include <mach/gpio.h> |
@@ -681,13 +683,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
681 | struct irq_chip *host_chip = irq_get_chip(irq); | 683 | struct irq_chip *host_chip = irq_get_chip(irq); |
682 | unsigned int first_irq; | 684 | unsigned int first_irq; |
683 | 685 | ||
684 | if (host_chip->irq_mask_ack) | 686 | chained_irq_enter(host_chip, desc); |
685 | host_chip->irq_mask_ack(&desc->irq_data); | ||
686 | else { | ||
687 | host_chip->irq_mask(&desc->irq_data); | ||
688 | if (host_chip->irq_ack) | ||
689 | host_chip->irq_ack(&desc->irq_data); | ||
690 | } | ||
691 | 687 | ||
692 | nmk_chip = irq_get_handler_data(irq); | 688 | nmk_chip = irq_get_handler_data(irq); |
693 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | 689 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); |
@@ -698,7 +694,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
698 | status &= ~BIT(bit); | 694 | status &= ~BIT(bit); |
699 | } | 695 | } |
700 | 696 | ||
701 | host_chip->irq_unmask(&desc->irq_data); | 697 | chained_irq_exit(host_chip, desc); |
702 | } | 698 | } |
703 | 699 | ||
704 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 700 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index d2adcdda23cf..a2478ebb53fa 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -1137,8 +1137,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1137 | struct gpio_bank *bank; | 1137 | struct gpio_bank *bank; |
1138 | u32 retrigger = 0; | 1138 | u32 retrigger = 0; |
1139 | int unmasked = 0; | 1139 | int unmasked = 0; |
1140 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
1140 | 1141 | ||
1141 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 1142 | chained_irq_enter(chip, desc); |
1142 | 1143 | ||
1143 | bank = irq_get_handler_data(irq); | 1144 | bank = irq_get_handler_data(irq); |
1144 | #ifdef CONFIG_ARCH_OMAP1 | 1145 | #ifdef CONFIG_ARCH_OMAP1 |
@@ -1195,7 +1196,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1195 | configured, we could unmask GPIO bank interrupt immediately */ | 1196 | configured, we could unmask GPIO bank interrupt immediately */ |
1196 | if (!level_mask && !unmasked) { | 1197 | if (!level_mask && !unmasked) { |
1197 | unmasked = 1; | 1198 | unmasked = 1; |
1198 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 1199 | chained_irq_exit(chip, desc); |
1199 | } | 1200 | } |
1200 | 1201 | ||
1201 | isr |= retrigger; | 1202 | isr |= retrigger; |
@@ -1231,7 +1232,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1231 | interrupt */ | 1232 | interrupt */ |
1232 | exit: | 1233 | exit: |
1233 | if (!unmasked) | 1234 | if (!unmasked) |
1234 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 1235 | chained_irq_exit(chip, desc); |
1235 | } | 1236 | } |
1236 | 1237 | ||
1237 | static void gpio_irq_shutdown(struct irq_data *d) | 1238 | static void gpio_irq_shutdown(struct irq_data *d) |