Btrfs: make sure reserve_metadata_bytes doesn't leak out strange errors
[pandora-kernel.git] / arch / arm / mach-stmp37xx / stmp37xx.c
1 /*
2  * Freescale STMP37XX platform support
3  *
4  * Embedded Alley Solutions, Inc <source@embeddedalley.com>
5  *
6  * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7  * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8  */
9
10 /*
11  * The code contained herein is licensed under the GNU General Public
12  * License. You may obtain a copy of the GNU General Public License
13  * Version 2 or later at the following locations:
14  *
15  * http://www.opensource.org/licenses/gpl-license.html
16  * http://www.gnu.org/copyleft/gpl.html
17  */
18 #include <linux/types.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/device.h>
22 #include <linux/platform_device.h>
23 #include <linux/irq.h>
24 #include <linux/io.h>
25
26 #include <asm/setup.h>
27 #include <asm/mach-types.h>
28
29 #include <asm/mach/arch.h>
30 #include <asm/mach/irq.h>
31 #include <asm/mach/map.h>
32 #include <asm/mach/time.h>
33
34 #include <mach/stmp3xxx.h>
35 #include <mach/dma.h>
36
37 #include <mach/platform.h>
38 #include <mach/regs-icoll.h>
39 #include <mach/regs-apbh.h>
40 #include <mach/regs-apbx.h>
41 #include "stmp37xx.h"
42
43 /*
44  * IRQ handling
45  */
46 static void stmp37xx_ack_irq(struct irq_data *d)
47 {
48         /* Disable IRQ */
49         stmp3xxx_clearl(0x04 << ((d->irq % 4) * 8),
50                 REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
51
52         /* ACK current interrupt */
53         __raw_writel(1, REGS_ICOLL_BASE + HW_ICOLL_LEVELACK);
54
55         /* Barrier */
56         (void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
57 }
58
59 static void stmp37xx_mask_irq(struct irq_data *d)
60 {
61         /* IRQ disable */
62         stmp3xxx_clearl(0x04 << ((d->irq % 4) * 8),
63                 REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
64 }
65
66 static void stmp37xx_unmask_irq(struct irq_data *d)
67 {
68         /* IRQ enable */
69         stmp3xxx_setl(0x04 << ((d->irq % 4) * 8),
70                 REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
71 }
72
73 static struct irq_chip stmp37xx_chip = {
74         .irq_ack        = stmp37xx_ack_irq,
75         .irq_mask       = stmp37xx_mask_irq,
76         .irq_unmask     = stmp37xx_unmask_irq,
77 };
78
79 void __init stmp37xx_init_irq(void)
80 {
81         stmp3xxx_init_irq(&stmp37xx_chip);
82 }
83
84 /*
85  * DMA interrupt handling
86  */
87 void stmp3xxx_arch_dma_enable_interrupt(int channel)
88 {
89         switch (STMP3XXX_DMA_BUS(channel)) {
90         case STMP3XXX_BUS_APBH:
91                 stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
92                         REGS_APBH_BASE + HW_APBH_CTRL1);
93                 break;
94
95         case STMP3XXX_BUS_APBX:
96                 stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
97                         REGS_APBX_BASE + HW_APBX_CTRL1);
98                 break;
99         }
100 }
101 EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
102
103 void stmp3xxx_arch_dma_clear_interrupt(int channel)
104 {
105         switch (STMP3XXX_DMA_BUS(channel)) {
106         case STMP3XXX_BUS_APBH:
107                 stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel),
108                                 REGS_APBH_BASE + HW_APBH_CTRL1);
109                 break;
110
111         case STMP3XXX_BUS_APBX:
112                 stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel),
113                                 REGS_APBX_BASE + HW_APBX_CTRL1);
114                 break;
115         }
116 }
117 EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
118
119 int stmp3xxx_arch_dma_is_interrupt(int channel)
120 {
121         int r = 0;
122
123         switch (STMP3XXX_DMA_BUS(channel)) {
124         case STMP3XXX_BUS_APBH:
125                 r = __raw_readl(REGS_APBH_BASE + HW_APBH_CTRL1) &
126                         (1 << STMP3XXX_DMA_CHANNEL(channel));
127                 break;
128
129         case STMP3XXX_BUS_APBX:
130                 r = __raw_readl(REGS_APBH_BASE + HW_APBH_CTRL1) &
131                         (1 << STMP3XXX_DMA_CHANNEL(channel));
132                 break;
133         }
134         return r;
135 }
136 EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
137
138 void stmp3xxx_arch_dma_reset_channel(int channel)
139 {
140         unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
141
142         switch (STMP3XXX_DMA_BUS(channel)) {
143         case STMP3XXX_BUS_APBH:
144                 /* Reset channel and wait for it to complete */
145                 stmp3xxx_setl(chbit << BP_APBH_CTRL0_RESET_CHANNEL,
146                         REGS_APBH_BASE + HW_APBH_CTRL0);
147                 while (__raw_readl(REGS_APBH_BASE + HW_APBH_CTRL0) &
148                        (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
149                                 cpu_relax();
150                 break;
151
152         case STMP3XXX_BUS_APBX:
153                 stmp3xxx_setl(chbit << BP_APBX_CTRL0_RESET_CHANNEL,
154                         REGS_APBX_BASE + HW_APBX_CTRL0);
155                 while (__raw_readl(REGS_APBX_BASE + HW_APBX_CTRL0) &
156                        (chbit << BP_APBX_CTRL0_RESET_CHANNEL))
157                                 cpu_relax();
158                 break;
159         }
160 }
161 EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
162
163 void stmp3xxx_arch_dma_freeze(int channel)
164 {
165         unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
166
167         switch (STMP3XXX_DMA_BUS(channel)) {
168         case STMP3XXX_BUS_APBH:
169                 stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
170                 break;
171         case STMP3XXX_BUS_APBX:
172                 stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
173                 break;
174         }
175 }
176 EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
177
178 void stmp3xxx_arch_dma_unfreeze(int channel)
179 {
180         unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
181
182         switch (STMP3XXX_DMA_BUS(channel)) {
183         case STMP3XXX_BUS_APBH:
184                 stmp3xxx_clearl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
185                 break;
186         case STMP3XXX_BUS_APBX:
187                 stmp3xxx_clearl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
188                 break;
189         }
190 }
191 EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
192
193 /*
194  * The registers are all very closely mapped, so we might as well map them all
195  * with a single mapping
196  *
197  * Logical      Physical
198  * f0000000     80000000        On-chip registers
199  * f1000000     00000000        32k on-chip SRAM
200  */
201 static struct map_desc stmp37xx_io_desc[] __initdata = {
202         {
203                 .virtual        = (u32)STMP3XXX_REGS_BASE,
204                 .pfn            = __phys_to_pfn(STMP3XXX_REGS_PHBASE),
205                 .length         = SZ_1M,
206                 .type           = MT_DEVICE
207         },
208         {
209                 .virtual        = (u32)STMP3XXX_OCRAM_BASE,
210                 .pfn            = __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
211                 .length         = STMP3XXX_OCRAM_SIZE,
212                 .type           = MT_DEVICE,
213         },
214 };
215
216 void __init stmp37xx_map_io(void)
217 {
218         iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));
219 }