Commit | Line | Data |
---|---|---|
8726e4f5 CC |
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/legacy_irq.h> | |
22 | ||
23 | #define ICTLR_CPU_IER 0x20 | |
24 | #define ICTLR_CPU_IER_SET 0x24 | |
25 | #define ICTLR_CPU_IER_CLR 0x28 | |
26 | #define ICTLR_CPU_IEP_CLASS 0x2C | |
27 | #define ICTLR_CPU_IEP_VFIQ 0x08 | |
28 | #define ICTLR_CPU_IEP_FIR 0x14 | |
29 | #define ICTLR_CPU_IEP_FIR_SET 0x18 | |
30 | #define ICTLR_CPU_IEP_FIR_CLR 0x1c | |
31 | ||
32 | static void __iomem *ictlr_reg_base[] = { | |
33 | IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), | |
34 | IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), | |
35 | IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), | |
36 | IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), | |
37 | }; | |
38 | ||
39 | /* When going into deep sleep, the CPU is powered down, taking the GIC with it | |
40 | In order to wake, the wake interrupts need to be enabled in the legacy | |
41 | interrupt controller. */ | |
42 | void tegra_legacy_unmask_irq(unsigned int irq) | |
43 | { | |
44 | void __iomem *base; | |
45 | pr_debug("%s: %d\n", __func__, irq); | |
46 | ||
47 | irq -= 32; | |
48 | base = ictlr_reg_base[irq>>5]; | |
49 | writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET); | |
50 | } | |
51 | ||
52 | void tegra_legacy_mask_irq(unsigned int irq) | |
53 | { | |
54 | void __iomem *base; | |
55 | pr_debug("%s: %d\n", __func__, irq); | |
56 | ||
57 | irq -= 32; | |
58 | base = ictlr_reg_base[irq>>5]; | |
59 | writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR); | |
60 | } | |
61 | ||
62 | void tegra_legacy_force_irq_set(unsigned int irq) | |
63 | { | |
64 | void __iomem *base; | |
65 | pr_debug("%s: %d\n", __func__, irq); | |
66 | ||
67 | irq -= 32; | |
68 | base = ictlr_reg_base[irq>>5]; | |
69 | writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET); | |
70 | } | |
71 | ||
72 | void tegra_legacy_force_irq_clr(unsigned int irq) | |
73 | { | |
74 | void __iomem *base; | |
75 | pr_debug("%s: %d\n", __func__, irq); | |
76 | ||
77 | irq -= 32; | |
78 | base = ictlr_reg_base[irq>>5]; | |
79 | writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR); | |
80 | } | |
81 | ||
82 | int tegra_legacy_force_irq_status(unsigned int irq) | |
83 | { | |
84 | void __iomem *base; | |
85 | pr_debug("%s: %d\n", __func__, irq); | |
86 | ||
87 | irq -= 32; | |
88 | base = ictlr_reg_base[irq>>5]; | |
89 | return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31))); | |
90 | } | |
91 | ||
92 | void tegra_legacy_select_fiq(unsigned int irq, bool fiq) | |
93 | { | |
94 | void __iomem *base; | |
95 | pr_debug("%s: %d\n", __func__, irq); | |
96 | ||
97 | irq -= 32; | |
98 | base = ictlr_reg_base[irq>>5]; | |
99 | writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS); | |
100 | } | |
101 | ||
102 | unsigned long tegra_legacy_vfiq(int nr) | |
103 | { | |
104 | void __iomem *base; | |
105 | base = ictlr_reg_base[nr]; | |
106 | return readl(base + ICTLR_CPU_IEP_VFIQ); | |
107 | } | |
108 | ||
109 | unsigned long tegra_legacy_class(int nr) | |
110 | { | |
111 | void __iomem *base; | |
112 | base = ictlr_reg_base[nr]; | |
113 | return readl(base + ICTLR_CPU_IEP_CLASS); | |
114 | } |