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/plat-versatile | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
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 | 12 | ||||
-rw-r--r-- | arch/arm/plat-versatile/localtimer.c | 27 |
3 files changed, 111 insertions, 0 deletions
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c new file mode 100644 index 00000000000..f0cc8e19b09 --- /dev/null +++ b/arch/arm/plat-versatile/fpga-irq.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Support for Versatile FPGA-based IRQ controllers | ||
3 | */ | ||
4 | #include <linux/irq.h> | ||
5 | #include <linux/io.h> | ||
6 | |||
7 | #include <asm/mach/irq.h> | ||
8 | #include <plat/fpga-irq.h> | ||
9 | |||
10 | #define IRQ_STATUS 0x00 | ||
11 | #define IRQ_RAW_STATUS 0x04 | ||
12 | #define IRQ_ENABLE_SET 0x08 | ||
13 | #define IRQ_ENABLE_CLEAR 0x0c | ||
14 | |||
15 | static void fpga_irq_mask(struct irq_data *d) | ||
16 | { | ||
17 | struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); | ||
18 | u32 mask = 1 << (d->irq - f->irq_start); | ||
19 | |||
20 | writel(mask, f->base + IRQ_ENABLE_CLEAR); | ||
21 | } | ||
22 | |||
23 | static void fpga_irq_unmask(struct irq_data *d) | ||
24 | { | ||
25 | struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); | ||
26 | u32 mask = 1 << (d->irq - f->irq_start); | ||
27 | |||
28 | writel(mask, f->base + IRQ_ENABLE_SET); | ||
29 | } | ||
30 | |||
31 | static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) | ||
32 | { | ||
33 | struct fpga_irq_data *f = irq_desc_get_handler_data(desc); | ||
34 | u32 status = readl(f->base + IRQ_STATUS); | ||
35 | |||
36 | if (status == 0) { | ||
37 | do_bad_IRQ(irq, desc); | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | do { | ||
42 | irq = ffs(status) - 1; | ||
43 | status &= ~(1 << irq); | ||
44 | |||
45 | generic_handle_irq(irq + f->irq_start); | ||
46 | } while (status); | ||
47 | } | ||
48 | |||
49 | void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f) | ||
50 | { | ||
51 | unsigned int i; | ||
52 | |||
53 | f->chip.irq_ack = fpga_irq_mask; | ||
54 | f->chip.irq_mask = fpga_irq_mask; | ||
55 | f->chip.irq_unmask = fpga_irq_unmask; | ||
56 | |||
57 | if (parent_irq != -1) { | ||
58 | irq_set_handler_data(parent_irq, f); | ||
59 | irq_set_chained_handler(parent_irq, fpga_irq_handle); | ||
60 | } | ||
61 | |||
62 | for (i = 0; i < 32; i++) { | ||
63 | if (valid & (1 << i)) { | ||
64 | unsigned int irq = f->irq_start + i; | ||
65 | |||
66 | irq_set_chip_data(irq, f); | ||
67 | irq_set_chip_and_handler(irq, &f->chip, | ||
68 | handle_level_irq); | ||
69 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
70 | } | ||
71 | } | ||
72 | } | ||
diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h new file mode 100644 index 00000000000..627fafd1e59 --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef PLAT_FPGA_IRQ_H | ||
2 | #define PLAT_FPGA_IRQ_H | ||
3 | |||
4 | struct fpga_irq_data { | ||
5 | void __iomem *base; | ||
6 | unsigned int irq_start; | ||
7 | struct irq_chip chip; | ||
8 | }; | ||
9 | |||
10 | void fpga_irq_init(int, u32, struct fpga_irq_data *); | ||
11 | |||
12 | #endif | ||
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c new file mode 100644 index 00000000000..0fb3961999b --- /dev/null +++ b/arch/arm/plat-versatile/localtimer.c | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-versatile/localtimer.c | ||
3 | * | ||
4 | * Copyright (C) 2002 ARM Ltd. | ||
5 | * All Rights Reserved | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/smp.h> | ||
13 | #include <linux/clockchips.h> | ||
14 | |||
15 | #include <asm/smp_twd.h> | ||
16 | #include <asm/localtimer.h> | ||
17 | #include <mach/irqs.h> | ||
18 | |||
19 | /* | ||
20 | * Setup the local clock events for a CPU. | ||
21 | */ | ||
22 | int __cpuinit local_timer_setup(struct clock_event_device *evt) | ||
23 | { | ||
24 | evt->irq = IRQ_LOCALTIMER; | ||
25 | twd_timer_setup(evt); | ||
26 | return 0; | ||
27 | } | ||