diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra/syncpt.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'arch/arm/mach-tegra/syncpt.c')
-rw-r--r-- | arch/arm/mach-tegra/syncpt.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/syncpt.c b/arch/arm/mach-tegra/syncpt.c new file mode 100644 index 00000000000..8ebab3801a8 --- /dev/null +++ b/arch/arm/mach-tegra/syncpt.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Google, Inc. | ||
3 | * | ||
4 | * Author: | ||
5 | * Erik Gilling <konkers@google.com> | ||
6 | * | ||
7 | * Copyright (C) 2010, NVIDIA Corporation | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <asm/mach/irq.h> | ||
27 | |||
28 | #include <mach/iomap.h> | ||
29 | #include <mach/irqs.h> | ||
30 | |||
31 | #define HOST1X_SYNC_OFFSET 0x3000 | ||
32 | #define HOST1X_SYNC_SIZE 0x800 | ||
33 | enum { | ||
34 | HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS = 0x40, | ||
35 | HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE = 0x60 | ||
36 | }; | ||
37 | |||
38 | static void syncpt_thresh_mask(struct irq_data *data) | ||
39 | { | ||
40 | (void)data; | ||
41 | } | ||
42 | |||
43 | static void syncpt_thresh_unmask(struct irq_data *data) | ||
44 | { | ||
45 | (void)data; | ||
46 | } | ||
47 | |||
48 | static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc) | ||
49 | { | ||
50 | void __iomem *sync_regs = irq_desc_get_handler_data(desc); | ||
51 | unsigned long reg; | ||
52 | int id; | ||
53 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
54 | |||
55 | chained_irq_enter(chip, desc); | ||
56 | |||
57 | reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS); | ||
58 | |||
59 | for_each_set_bit(id, ®, 32) | ||
60 | generic_handle_irq(id + INT_SYNCPT_THRESH_BASE); | ||
61 | |||
62 | chained_irq_exit(chip, desc); | ||
63 | } | ||
64 | |||
65 | static struct irq_chip syncpt_thresh_irq = { | ||
66 | .name = "syncpt", | ||
67 | .irq_mask = syncpt_thresh_mask, | ||
68 | .irq_unmask = syncpt_thresh_unmask | ||
69 | }; | ||
70 | |||
71 | static int __init syncpt_init_irq(void) | ||
72 | { | ||
73 | void __iomem *sync_regs; | ||
74 | unsigned int i; | ||
75 | int irq; | ||
76 | |||
77 | sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET, | ||
78 | HOST1X_SYNC_SIZE); | ||
79 | BUG_ON(!sync_regs); | ||
80 | |||
81 | writel(0xffffffffUL, | ||
82 | sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE); | ||
83 | writel(0xffffffffUL, | ||
84 | sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS); | ||
85 | |||
86 | for (i = 0; i < INT_SYNCPT_THRESH_NR; i++) { | ||
87 | irq = INT_SYNCPT_THRESH_BASE + i; | ||
88 | irq_set_chip_and_handler(irq, &syncpt_thresh_irq, | ||
89 | handle_simple_irq); | ||
90 | irq_set_chip_data(irq, sync_regs); | ||
91 | set_irq_flags(irq, IRQF_VALID); | ||
92 | } | ||
93 | irq_set_chained_handler(INT_HOST1X_MPCORE_SYNCPT, | ||
94 | syncpt_thresh_cascade); | ||
95 | irq_set_handler_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | core_initcall(syncpt_init_irq); | ||