aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/mach-fs
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/mach-fs')
-rw-r--r--arch/cris/arch-v32/mach-fs/Kconfig216
-rw-r--r--arch/cris/arch-v32/mach-fs/Makefile11
-rw-r--r--arch/cris/arch-v32/mach-fs/arbiter.c404
-rw-r--r--arch/cris/arch-v32/mach-fs/cpufreq.c146
-rw-r--r--arch/cris/arch-v32/mach-fs/dma.c230
-rw-r--r--arch/cris/arch-v32/mach-fs/dram_init.S116
-rw-r--r--arch/cris/arch-v32/mach-fs/hw_settings.S70
-rw-r--r--arch/cris/arch-v32/mach-fs/io.c191
-rw-r--r--arch/cris/arch-v32/mach-fs/pinmux.c309
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.c100
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.h42
11 files changed, 1835 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
new file mode 100644
index 000000000000..f6d74475f1c6
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -0,0 +1,216 @@
1if ETRAXFS
2
3menu "ETRAX FS options"
4 depends on ETRAXFS
5
6config ETRAX_DRAM_VIRTUAL_BASE
7 hex
8 depends on ETRAX_ARCH_V32
9 default "c0000000"
10
11config ETRAX_SERIAL_PORTS
12 int
13 default 4
14
15config ETRAX_MEM_GRP1_CONFIG
16 hex "MEM_GRP1_CONFIG"
17 depends on ETRAX_ARCH_V32
18 default "4044a"
19 help
20 Waitstates for flash. The default value is suitable for the
21 standard flashes used in axis products (120 ns).
22
23config ETRAX_MEM_GRP2_CONFIG
24 hex "MEM_GRP2_CONFIG"
25 depends on ETRAX_ARCH_V32
26 default "0"
27 help
28 Waitstates for SRAM. 0 is a good choice for most Axis products.
29
30config ETRAX_MEM_GRP3_CONFIG
31 hex "MEM_GRP3_CONFIG"
32 depends on ETRAX_ARCH_V32
33 default "0"
34 help
35 Waitstates for CSP0-3. 0 is a good choice for most Axis products.
36 It may need to be changed if external devices such as extra
37 register-mapped LEDs are used.
38
39config ETRAX_MEM_GRP4_CONFIG
40 hex "MEM_GRP4_CONFIG"
41 depends on ETRAX_ARCH_V32
42 default "0"
43 help
44 Waitstates for CSP4-6. 0 is a good choice for most Axis products.
45
46config ETRAX_SDRAM_GRP0_CONFIG
47 hex "SDRAM_GRP0_CONFIG"
48 depends on ETRAX_ARCH_V32
49 default "336"
50 help
51 SDRAM configuration for group 0. The value depends on the
52 hardware configuration. The default value is suitable
53 for 32 MB organized as two 16 bits chips (e.g. Axis
54 part number 18550) connected as one 32 bit device (i.e. in
55 the same group).
56
57config ETRAX_SDRAM_GRP1_CONFIG
58 hex "SDRAM_GRP1_CONFIG"
59 depends on ETRAX_ARCH_V32
60 default "0"
61 help
62 SDRAM configuration for group 1. The defult value is 0
63 because group 1 is not used in the default configuration,
64 described in the help for SDRAM_GRP0_CONFIG.
65
66config ETRAX_SDRAM_TIMING
67 hex "SDRAM_TIMING"
68 depends on ETRAX_ARCH_V32
69 default "104a"
70 help
71 SDRAM timing parameters. The default value is ok for
72 most hardwares but large SDRAMs may require a faster
73 refresh (a.k.a 8K refresh). The default value implies
74 100MHz clock and SDR mode.
75
76config ETRAX_SDRAM_COMMAND
77 hex "SDRAM_COMMAND"
78 depends on ETRAX_ARCH_V32
79 default "0"
80 help
81 SDRAM command. Should be 0 unless you really know what
82 you are doing (may be != 0 for unusual address line
83 mappings such as in a MCM)..
84
85config ETRAX_DEF_GIO_PA_OE
86 hex "GIO_PA_OE"
87 depends on ETRAX_ARCH_V32
88 default "1c"
89 help
90 Configures the direction of general port A bits. 1 is out, 0 is in.
91 This is often totally different depending on the product used.
92 There are some guidelines though - if you know that only LED's are
93 connected to port PA, then they are usually connected to bits 2-4
94 and you can therefore use 1c. On other boards which don't have the
95 LED's at the general ports, these bits are used for all kinds of
96 stuff. If you don't know what to use, it is always safe to put all
97 as inputs, although floating inputs isn't good.
98
99config ETRAX_DEF_GIO_PA_OUT
100 hex "GIO_PA_OUT"
101 depends on ETRAX_ARCH_V32
102 default "00"
103 help
104 Configures the initial data for the general port A bits. Most
105 products should use 00 here.
106
107config ETRAX_DEF_GIO_PB_OE
108 hex "GIO_PB_OE"
109 depends on ETRAX_ARCH_V32
110 default "00000"
111 help
112 Configures the direction of general port B bits. 1 is out, 0 is in.
113 This is often totally different depending on the product used.
114 There are some guidelines though - if you know that only LED's are
115 connected to port PA, then they are usually connected to bits 2-4
116 and you can therefore use 1c. On other boards which don't have the
117 LED's at the general ports, these bits are used for all kinds of
118 stuff. If you don't know what to use, it is always safe to put all
119 as inputs, although floating inputs isn't good.
120
121config ETRAX_DEF_GIO_PB_OUT
122 hex "GIO_PB_OUT"
123 depends on ETRAX_ARCH_V32
124 default "00000"
125 help
126 Configures the initial data for the general port B bits. Most
127 products should use 00000 here.
128
129config ETRAX_DEF_GIO_PC_OE
130 hex "GIO_PC_OE"
131 depends on ETRAX_ARCH_V32
132 default "00000"
133 help
134 Configures the direction of general port C bits. 1 is out, 0 is in.
135 This is often totally different depending on the product used.
136 There are some guidelines though - if you know that only LED's are
137 connected to port PA, then they are usually connected to bits 2-4
138 and you can therefore use 1c. On other boards which don't have the
139 LED's at the general ports, these bits are used for all kinds of
140 stuff. If you don't know what to use, it is always safe to put all
141 as inputs, although floating inputs isn't good.
142
143config ETRAX_DEF_GIO_PC_OUT
144 hex "GIO_PC_OUT"
145 depends on ETRAX_ARCH_V32
146 default "00000"
147 help
148 Configures the initial data for the general port C bits. Most
149 products should use 00000 here.
150
151config ETRAX_DEF_GIO_PD_OE
152 hex "GIO_PD_OE"
153 depends on ETRAX_ARCH_V32
154 default "00000"
155 help
156 Configures the direction of general port D bits. 1 is out, 0 is in.
157 This is often totally different depending on the product used.
158 There are some guidelines though - if you know that only LED's are
159 connected to port PA, then they are usually connected to bits 2-4
160 and you can therefore use 1c. On other boards which don't have the
161 LED's at the general ports, these bits are used for all kinds of
162 stuff. If you don't know what to use, it is always safe to put all
163 as inputs, although floating inputs isn't good.
164
165config ETRAX_DEF_GIO_PD_OUT
166 hex "GIO_PD_OUT"
167 depends on ETRAX_ARCH_V32
168 default "00000"
169 help
170 Configures the initial data for the general port D bits. Most
171 products should use 00000 here.
172
173config ETRAX_DEF_GIO_PE_OE
174 hex "GIO_PE_OE"
175 depends on ETRAX_ARCH_V32
176 default "00000"
177 help
178 Configures the direction of general port E bits. 1 is out, 0 is in.
179 This is often totally different depending on the product used.
180 There are some guidelines though - if you know that only LED's are
181 connected to port PA, then they are usually connected to bits 2-4
182 and you can therefore use 1c. On other boards which don't have the
183 LED's at the general ports, these bits are used for all kinds of
184 stuff. If you don't know what to use, it is always safe to put all
185 as inputs, although floating inputs isn't good.
186
187config ETRAX_DEF_GIO_PE_OUT
188 hex "GIO_PE_OUT"
189 depends on ETRAX_ARCH_V32
190 default "00000"
191 help
192 Configures the initial data for the general port E bits. Most
193 products should use 00000 here.
194
195config ETRAX_DEF_GIO_PV_OE
196 hex "GIO_PV_OE"
197 depends on ETRAX_VIRTUAL_GPIO
198 default "0000"
199 help
200 Configures the direction of virtual general port V bits. 1 is out,
201 0 is in. This is often totally different depending on the product
202 used. These bits are used for all kinds of stuff. If you don't know
203 what to use, it is always safe to put all as inputs, although
204 floating inputs isn't good.
205
206config ETRAX_DEF_GIO_PV_OUT
207 hex "GIO_PV_OUT"
208 depends on ETRAX_VIRTUAL_GPIO
209 default "0000"
210 help
211 Configures the initial data for the virtual general port V bits.
212 Most products should use 0000 here.
213
214endmenu
215
216endif
diff --git a/arch/cris/arch-v32/mach-fs/Makefile b/arch/cris/arch-v32/mach-fs/Makefile
new file mode 100644
index 000000000000..4ff407a1b931
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/Makefile
@@ -0,0 +1,11 @@
1# $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $
2#
3# Makefile for the linux kernel.
4#
5
6obj-y := dma.o pinmux.o io.o arbiter.o
7bj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
8obj-$(CONFIG_CPU_FREQ) += cpufreq.o
9
10clean:
11
diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c
new file mode 100644
index 000000000000..84d31bd7b692
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/arbiter.c
@@ -0,0 +1,404 @@
1/*
2 * Memory arbiter functions. Allocates bandwidth through the
3 * arbiter and sets up arbiter breakpoints.
4 *
5 * The algorithm first assigns slots to the clients that has specified
6 * bandwidth (e.g. ethernet) and then the remaining slots are divided
7 * on all the active clients.
8 *
9 * Copyright (c) 2004-2007 Axis Communications AB.
10 */
11
12#include <hwregs/reg_map.h>
13#include <hwregs/reg_rdwr.h>
14#include <hwregs/marb_defs.h>
15#include <arbiter.h>
16#include <hwregs/intr_vect.h>
17#include <linux/interrupt.h>
18#include <linux/signal.h>
19#include <linux/errno.h>
20#include <linux/spinlock.h>
21#include <asm/io.h>
22#include <asm/irq_regs.h>
23
24struct crisv32_watch_entry {
25 unsigned long instance;
26 watch_callback *cb;
27 unsigned long start;
28 unsigned long end;
29 int used;
30};
31
32#define NUMBER_OF_BP 4
33#define NBR_OF_CLIENTS 14
34#define NBR_OF_SLOTS 64
35#define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */
36#define INTMEM_BANDWIDTH 400000000
37#define NBR_OF_REGIONS 2
38
39static struct crisv32_watch_entry watches[NUMBER_OF_BP] = {
40 {regi_marb_bp0},
41 {regi_marb_bp1},
42 {regi_marb_bp2},
43 {regi_marb_bp3}
44};
45
46static u8 requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
47static u8 active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
48static int max_bandwidth[NBR_OF_REGIONS] =
49 { SDRAM_BANDWIDTH, INTMEM_BANDWIDTH };
50
51DEFINE_SPINLOCK(arbiter_lock);
52
53static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id);
54
55/*
56 * "I'm the arbiter, I know the score.
57 * From square one I'll be watching all 64."
58 * (memory arbiter slots, that is)
59 *
60 * Or in other words:
61 * Program the memory arbiter slots for "region" according to what's
62 * in requested_slots[] and active_clients[], while minimizing
63 * latency. A caller may pass a non-zero positive amount for
64 * "unused_slots", which must then be the unallocated, remaining
65 * number of slots, free to hand out to any client.
66 */
67
68static void crisv32_arbiter_config(int region, int unused_slots)
69{
70 int slot;
71 int client;
72 int interval = 0;
73
74 /*
75 * This vector corresponds to the hardware arbiter slots (see
76 * the hardware documentation for semantics). We initialize
77 * each slot with a suitable sentinel value outside the valid
78 * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
79 * client indexes. Then it's fed to the hardware.
80 */
81 s8 val[NBR_OF_SLOTS];
82
83 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
84 val[slot] = -1;
85
86 for (client = 0; client < NBR_OF_CLIENTS; client++) {
87 int pos;
88 /* Allocate the requested non-zero number of slots, but
89 * also give clients with zero-requests one slot each
90 * while stocks last. We do the latter here, in client
91 * order. This makes sure zero-request clients are the
92 * first to get to any spare slots, else those slots
93 * could, when bandwidth is allocated close to the limit,
94 * all be allocated to low-index non-zero-request clients
95 * in the default-fill loop below. Another positive but
96 * secondary effect is a somewhat better spread of the
97 * zero-bandwidth clients in the vector, avoiding some of
98 * the latency that could otherwise be caused by the
99 * partitioning of non-zero-bandwidth clients at low
100 * indexes and zero-bandwidth clients at high
101 * indexes. (Note that this spreading can only affect the
102 * unallocated bandwidth.) All the above only matters for
103 * memory-intensive situations, of course.
104 */
105 if (!requested_slots[region][client]) {
106 /*
107 * Skip inactive clients. Also skip zero-slot
108 * allocations in this pass when there are no known
109 * free slots.
110 */
111 if (!active_clients[region][client]
112 || unused_slots <= 0)
113 continue;
114
115 unused_slots--;
116
117 /* Only allocate one slot for this client. */
118 interval = NBR_OF_SLOTS;
119 } else
120 interval =
121 NBR_OF_SLOTS / requested_slots[region][client];
122
123 pos = 0;
124 while (pos < NBR_OF_SLOTS) {
125 if (val[pos] >= 0)
126 pos++;
127 else {
128 val[pos] = client;
129 pos += interval;
130 }
131 }
132 }
133
134 client = 0;
135 for (slot = 0; slot < NBR_OF_SLOTS; slot++) {
136 /*
137 * Allocate remaining slots in round-robin
138 * client-number order for active clients. For this
139 * pass, we ignore requested bandwidth and previous
140 * allocations.
141 */
142 if (val[slot] < 0) {
143 int first = client;
144 while (!active_clients[region][client]) {
145 client = (client + 1) % NBR_OF_CLIENTS;
146 if (client == first)
147 break;
148 }
149 val[slot] = client;
150 client = (client + 1) % NBR_OF_CLIENTS;
151 }
152 if (region == EXT_REGION)
153 REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot,
154 val[slot]);
155 else if (region == INT_REGION)
156 REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot,
157 val[slot]);
158 }
159}
160
161extern char _stext, _etext;
162
163static void crisv32_arbiter_init(void)
164{
165 static int initialized;
166
167 if (initialized)
168 return;
169
170 initialized = 1;
171
172 /*
173 * CPU caches are always set to active, but with zero
174 * bandwidth allocated. It should be ok to allocate zero
175 * bandwidth for the caches, because DMA for other channels
176 * will supposedly finish, once their programmed amount is
177 * done, and then the caches will get access according to the
178 * "fixed scheme" for unclaimed slots. Though, if for some
179 * use-case somewhere, there's a maximum CPU latency for
180 * e.g. some interrupt, we have to start allocating specific
181 * bandwidth for the CPU caches too.
182 */
183 active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
184 crisv32_arbiter_config(EXT_REGION, 0);
185 crisv32_arbiter_config(INT_REGION, 0);
186
187 if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
188 "arbiter", NULL))
189 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
190
191#ifndef CONFIG_ETRAX_KGDB
192 /* Global watch for writes to kernel text segment. */
193 crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
194 arbiter_all_clients, arbiter_all_write, NULL);
195#endif
196}
197
198/* Main entry for bandwidth allocation. */
199
200int crisv32_arbiter_allocate_bandwidth(int client, int region,
201 unsigned long bandwidth)
202{
203 int i;
204 int total_assigned = 0;
205 int total_clients = 0;
206 int req;
207
208 crisv32_arbiter_init();
209
210 for (i = 0; i < NBR_OF_CLIENTS; i++) {
211 total_assigned += requested_slots[region][i];
212 total_clients += active_clients[region][i];
213 }
214
215 /* Avoid division by 0 for 0-bandwidth requests. */
216 req = bandwidth == 0
217 ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
218
219 /*
220 * We make sure that there are enough slots only for non-zero
221 * requests. Requesting 0 bandwidth *may* allocate slots,
222 * though if all bandwidth is allocated, such a client won't
223 * get any and will have to rely on getting memory access
224 * according to the fixed scheme that's the default when one
225 * of the slot-allocated clients doesn't claim their slot.
226 */
227 if (total_assigned + req > NBR_OF_SLOTS)
228 return -ENOMEM;
229
230 active_clients[region][client] = 1;
231 requested_slots[region][client] = req;
232 crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
233
234 return 0;
235}
236
237/*
238 * Main entry for bandwidth deallocation.
239 *
240 * Strictly speaking, for a somewhat constant set of clients where
241 * each client gets a constant bandwidth and is just enabled or
242 * disabled (somewhat dynamically), no action is necessary here to
243 * avoid starvation for non-zero-allocation clients, as the allocated
244 * slots will just be unused. However, handing out those unused slots
245 * to active clients avoids needless latency if the "fixed scheme"
246 * would give unclaimed slots to an eager low-index client.
247 */
248
249void crisv32_arbiter_deallocate_bandwidth(int client, int region)
250{
251 int i;
252 int total_assigned = 0;
253
254 requested_slots[region][client] = 0;
255 active_clients[region][client] = 0;
256
257 for (i = 0; i < NBR_OF_CLIENTS; i++)
258 total_assigned += requested_slots[region][i];
259
260 crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
261}
262
263int crisv32_arbiter_watch(unsigned long start, unsigned long size,
264 unsigned long clients, unsigned long accesses,
265 watch_callback *cb)
266{
267 int i;
268
269 crisv32_arbiter_init();
270
271 if (start > 0x80000000) {
272 printk(KERN_ERR "Arbiter: %lX doesn't look like a "
273 "physical address", start);
274 return -EFAULT;
275 }
276
277 spin_lock(&arbiter_lock);
278
279 for (i = 0; i < NUMBER_OF_BP; i++) {
280 if (!watches[i].used) {
281 reg_marb_rw_intr_mask intr_mask =
282 REG_RD(marb, regi_marb, rw_intr_mask);
283
284 watches[i].used = 1;
285 watches[i].start = start;
286 watches[i].end = start + size;
287 watches[i].cb = cb;
288
289 REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr,
290 watches[i].start);
291 REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr,
292 watches[i].end);
293 REG_WR_INT(marb_bp, watches[i].instance, rw_op,
294 accesses);
295 REG_WR_INT(marb_bp, watches[i].instance, rw_clients,
296 clients);
297
298 if (i == 0)
299 intr_mask.bp0 = regk_marb_yes;
300 else if (i == 1)
301 intr_mask.bp1 = regk_marb_yes;
302 else if (i == 2)
303 intr_mask.bp2 = regk_marb_yes;
304 else if (i == 3)
305 intr_mask.bp3 = regk_marb_yes;
306
307 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
308 spin_unlock(&arbiter_lock);
309
310 return i;
311 }
312 }
313 spin_unlock(&arbiter_lock);
314 return -ENOMEM;
315}
316
317int crisv32_arbiter_unwatch(int id)
318{
319 reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
320
321 crisv32_arbiter_init();
322
323 spin_lock(&arbiter_lock);
324
325 if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
326 spin_unlock(&arbiter_lock);
327 return -EINVAL;
328 }
329
330 memset(&watches[id], 0, sizeof(struct crisv32_watch_entry));
331
332 if (id == 0)
333 intr_mask.bp0 = regk_marb_no;
334 else if (id == 1)
335 intr_mask.bp2 = regk_marb_no;
336 else if (id == 2)
337 intr_mask.bp2 = regk_marb_no;
338 else if (id == 3)
339 intr_mask.bp3 = regk_marb_no;
340
341 REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
342
343 spin_unlock(&arbiter_lock);
344 return 0;
345}
346
347extern void show_registers(struct pt_regs *regs);
348
349static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id)
350{
351 reg_marb_r_masked_intr masked_intr =
352 REG_RD(marb, regi_marb, r_masked_intr);
353 reg_marb_bp_r_brk_clients r_clients;
354 reg_marb_bp_r_brk_addr r_addr;
355 reg_marb_bp_r_brk_op r_op;
356 reg_marb_bp_r_brk_first_client r_first;
357 reg_marb_bp_r_brk_size r_size;
358 reg_marb_bp_rw_ack ack = { 0 };
359 reg_marb_rw_ack_intr ack_intr = {
360 .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1
361 };
362 struct crisv32_watch_entry *watch;
363
364 if (masked_intr.bp0) {
365 watch = &watches[0];
366 ack_intr.bp0 = regk_marb_yes;
367 } else if (masked_intr.bp1) {
368 watch = &watches[1];
369 ack_intr.bp1 = regk_marb_yes;
370 } else if (masked_intr.bp2) {
371 watch = &watches[2];
372 ack_intr.bp2 = regk_marb_yes;
373 } else if (masked_intr.bp3) {
374 watch = &watches[3];
375 ack_intr.bp3 = regk_marb_yes;
376 } else {
377 return IRQ_NONE;
378 }
379
380 /* Retrieve all useful information and print it. */
381 r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients);
382 r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr);
383 r_op = REG_RD(marb_bp, watch->instance, r_brk_op);
384 r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client);
385 r_size = REG_RD(marb_bp, watch->instance, r_brk_size);
386
387 printk(KERN_INFO "Arbiter IRQ\n");
388 printk(KERN_INFO "Clients %X addr %X op %X first %X size %X\n",
389 REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients),
390 REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr),
391 REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op),
392 REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first),
393 REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size));
394
395 REG_WR(marb_bp, watch->instance, rw_ack, ack);
396 REG_WR(marb, regi_marb, rw_ack_intr, ack_intr);
397
398 printk(KERN_INFO "IRQ occured at %lX\n", get_irq_regs()->erp);
399
400 if (watch->cb)
401 watch->cb();
402
403 return IRQ_HANDLED;
404}
diff --git a/arch/cris/arch-v32/mach-fs/cpufreq.c b/arch/cris/arch-v32/mach-fs/cpufreq.c
new file mode 100644
index 000000000000..d57631c0d8d1
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/cpufreq.c
@@ -0,0 +1,146 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/cpufreq.h>
4#include <hwregs/reg_map.h>
5#include <asm/arch/hwregs/reg_rdwr.h>
6#include <asm/arch/hwregs/config_defs.h>
7#include <asm/arch/hwregs/bif_core_defs.h>
8
9static int
10cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
11 void *data);
12
13static struct notifier_block cris_sdram_freq_notifier_block = {
14 .notifier_call = cris_sdram_freq_notifier
15};
16
17static struct cpufreq_frequency_table cris_freq_table[] = {
18 {0x01, 6000},
19 {0x02, 200000},
20 {0, CPUFREQ_TABLE_END},
21};
22
23static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
24{
25 reg_config_rw_clk_ctrl clk_ctrl;
26 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
27 return clk_ctrl.pll ? 200000 : 6000;
28}
29
30static void cris_freq_set_cpu_state(unsigned int state)
31{
32 int i;
33 struct cpufreq_freqs freqs;
34 reg_config_rw_clk_ctrl clk_ctrl;
35 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
36
37 for_each_possible_cpu(i) {
38 freqs.old = cris_freq_get_cpu_frequency(i);
39 freqs.new = cris_freq_table[state].frequency;
40 freqs.cpu = i;
41 }
42
43 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
44
45 local_irq_disable();
46
47 /* Even though we may be SMP they will share the same clock
48 * so all settings are made on CPU0. */
49 if (cris_freq_table[state].frequency == 200000)
50 clk_ctrl.pll = 1;
51 else
52 clk_ctrl.pll = 0;
53 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
54
55 local_irq_enable();
56
57 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
58};
59
60static int cris_freq_verify(struct cpufreq_policy *policy)
61{
62 return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
63}
64
65static int cris_freq_target(struct cpufreq_policy *policy,
66 unsigned int target_freq, unsigned int relation)
67{
68 unsigned int newstate = 0;
69
70 if (cpufreq_frequency_table_target
71 (policy, cris_freq_table, target_freq, relation, &newstate))
72 return -EINVAL;
73
74 cris_freq_set_cpu_state(newstate);
75
76 return 0;
77}
78
79static int cris_freq_cpu_init(struct cpufreq_policy *policy)
80{
81 int result;
82
83 /* cpuinfo and default policy values */
84 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
85 policy->cpuinfo.transition_latency = 1000000; /* 1ms */
86 policy->cur = cris_freq_get_cpu_frequency(0);
87
88 result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
89 if (result)
90 return (result);
91
92 cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
93
94 return 0;
95}
96
97static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
98{
99 cpufreq_frequency_table_put_attr(policy->cpu);
100 return 0;
101}
102
103static struct freq_attr *cris_freq_attr[] = {
104 &cpufreq_freq_attr_scaling_available_freqs,
105 NULL,
106};
107
108static struct cpufreq_driver cris_freq_driver = {
109 .get = cris_freq_get_cpu_frequency,
110 .verify = cris_freq_verify,
111 .target = cris_freq_target,
112 .init = cris_freq_cpu_init,
113 .exit = cris_freq_cpu_exit,
114 .name = "cris_freq",
115 .owner = THIS_MODULE,
116 .attr = cris_freq_attr,
117};
118
119static int __init cris_freq_init(void)
120{
121 int ret;
122 ret = cpufreq_register_driver(&cris_freq_driver);
123 cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
124 CPUFREQ_TRANSITION_NOTIFIER);
125 return ret;
126}
127
128static int
129cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val,
130 void *data)
131{
132 int i;
133 struct cpufreq_freqs *freqs = data;
134 if (val == CPUFREQ_PRECHANGE) {
135 reg_bif_core_rw_sdram_timing timing =
136 REG_RD(bif_core, regi_bif_core, rw_sdram_timing);
137 timing.cpd = (freqs->new == 200000 ? 0 : 1);
138
139 if (freqs->new == 200000)
140 for (i = 0; i < 50000; i++) ;
141 REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
142 }
143 return 0;
144}
145
146module_init(cris_freq_init);
diff --git a/arch/cris/arch-v32/mach-fs/dma.c b/arch/cris/arch-v32/mach-fs/dma.c
new file mode 100644
index 000000000000..a6acf4e6345c
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/dma.c
@@ -0,0 +1,230 @@
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <asm/dma.h>
6#include <hwregs/reg_map.h>
7#include <hwregs/reg_rdwr.h>
8#include <hwregs/marb_defs.h>
9#include <hwregs/config_defs.h>
10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h>
12#include <asm/system.h>
13#include <asm/arch/mach/arbiter.h>
14
15static char used_dma_channels[MAX_DMA_CHANNELS];
16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
17
18static DEFINE_SPINLOCK(dma_lock);
19
20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
21 unsigned options, unsigned int bandwidth,
22 enum dma_owner owner)
23{
24 unsigned long flags;
25 reg_config_rw_clk_ctrl clk_ctrl;
26 reg_strmux_rw_cfg strmux_cfg;
27
28 if (crisv32_arbiter_allocate_bandwidth(dmanr,
29 options & DMA_INT_MEM ?
30 INT_REGION : EXT_REGION,
31 bandwidth))
32 return -ENOMEM;
33
34 spin_lock_irqsave(&dma_lock, flags);
35
36 if (used_dma_channels[dmanr]) {
37 spin_unlock_irqrestore(&dma_lock, flags);
38 if (options & DMA_VERBOSE_ON_ERROR) {
39 printk(KERN_ERR "Failed to request DMA %i for %s, "
40 "already allocated by %s\n",
41 dmanr,
42 device_id,
43 used_dma_channels_users[dmanr]);
44 }
45 if (options & DMA_PANIC_ON_ERROR)
46 panic("request_dma error!");
47 spin_unlock_irqrestore(&dma_lock, flags);
48 return -EBUSY;
49 }
50 clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
51 strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
52
53 switch (dmanr) {
54 case 0:
55 case 1:
56 clk_ctrl.dma01_eth0 = 1;
57 break;
58 case 2:
59 case 3:
60 clk_ctrl.dma23 = 1;
61 break;
62 case 4:
63 case 5:
64 clk_ctrl.dma45 = 1;
65 break;
66 case 6:
67 case 7:
68 clk_ctrl.dma67 = 1;
69 break;
70 case 8:
71 case 9:
72 clk_ctrl.dma89_strcop = 1;
73 break;
74#if MAX_DMA_CHANNELS-1 != 9
75#error Check dma.c
76#endif
77 default:
78 spin_unlock_irqrestore(&dma_lock, flags);
79 if (options & DMA_VERBOSE_ON_ERROR) {
80 printk(KERN_ERR "Failed to request DMA %i for %s, "
81 "only 0-%i valid)\n",
82 dmanr, device_id, MAX_DMA_CHANNELS - 1);
83 }
84
85 if (options & DMA_PANIC_ON_ERROR)
86 panic("request_dma error!");
87 return -EINVAL;
88 }
89
90 switch (owner) {
91 case dma_eth0:
92 if (dmanr == 0)
93 strmux_cfg.dma0 = regk_strmux_eth0;
94 else if (dmanr == 1)
95 strmux_cfg.dma1 = regk_strmux_eth0;
96 else
97 panic("Invalid DMA channel for eth0\n");
98 break;
99 case dma_eth1:
100 if (dmanr == 6)
101 strmux_cfg.dma6 = regk_strmux_eth1;
102 else if (dmanr == 7)
103 strmux_cfg.dma7 = regk_strmux_eth1;
104 else
105 panic("Invalid DMA channel for eth1\n");
106 break;
107 case dma_iop0:
108 if (dmanr == 2)
109 strmux_cfg.dma2 = regk_strmux_iop0;
110 else if (dmanr == 3)
111 strmux_cfg.dma3 = regk_strmux_iop0;
112 else
113 panic("Invalid DMA channel for iop0\n");
114 break;
115 case dma_iop1:
116 if (dmanr == 4)
117 strmux_cfg.dma4 = regk_strmux_iop1;
118 else if (dmanr == 5)
119 strmux_cfg.dma5 = regk_strmux_iop1;
120 else
121 panic("Invalid DMA channel for iop1\n");
122 break;
123 case dma_ser0:
124 if (dmanr == 6)
125 strmux_cfg.dma6 = regk_strmux_ser0;
126 else if (dmanr == 7)
127 strmux_cfg.dma7 = regk_strmux_ser0;
128 else
129 panic("Invalid DMA channel for ser0\n");
130 break;
131 case dma_ser1:
132 if (dmanr == 4)
133 strmux_cfg.dma4 = regk_strmux_ser1;
134 else if (dmanr == 5)
135 strmux_cfg.dma5 = regk_strmux_ser1;
136 else
137 panic("Invalid DMA channel for ser1\n");
138 break;
139 case dma_ser2:
140 if (dmanr == 2)
141 strmux_cfg.dma2 = regk_strmux_ser2;
142 else if (dmanr == 3)
143 strmux_cfg.dma3 = regk_strmux_ser2;
144 else
145 panic("Invalid DMA channel for ser2\n");
146 break;
147 case dma_ser3:
148 if (dmanr == 8)
149 strmux_cfg.dma8 = regk_strmux_ser3;
150 else if (dmanr == 9)
151 strmux_cfg.dma9 = regk_strmux_ser3;
152 else
153 panic("Invalid DMA channel for ser3\n");
154 break;
155 case dma_sser0:
156 if (dmanr == 4)
157 strmux_cfg.dma4 = regk_strmux_sser0;
158 else if (dmanr == 5)
159 strmux_cfg.dma5 = regk_strmux_sser0;
160 else
161 panic("Invalid DMA channel for sser0\n");
162 break;
163 case dma_sser1:
164 if (dmanr == 6)
165 strmux_cfg.dma6 = regk_strmux_sser1;
166 else if (dmanr == 7)
167 strmux_cfg.dma7 = regk_strmux_sser1;
168 else
169 panic("Invalid DMA channel for sser1\n");
170 break;
171 case dma_ata:
172 if (dmanr == 2)
173 strmux_cfg.dma2 = regk_strmux_ata;
174 else if (dmanr == 3)
175 strmux_cfg.dma3 = regk_strmux_ata;
176 else
177 panic("Invalid DMA channel for ata\n");
178 break;
179 case dma_strp:
180 if (dmanr == 8)
181 strmux_cfg.dma8 = regk_strmux_strcop;
182 else if (dmanr == 9)
183 strmux_cfg.dma9 = regk_strmux_strcop;
184 else
185 panic("Invalid DMA channel for strp\n");
186 break;
187 case dma_ext0:
188 if (dmanr == 6)
189 strmux_cfg.dma6 = regk_strmux_ext0;
190 else
191 panic("Invalid DMA channel for ext0\n");
192 break;
193 case dma_ext1:
194 if (dmanr == 7)
195 strmux_cfg.dma7 = regk_strmux_ext1;
196 else
197 panic("Invalid DMA channel for ext1\n");
198 break;
199 case dma_ext2:
200 if (dmanr == 2)
201 strmux_cfg.dma2 = regk_strmux_ext2;
202 else if (dmanr == 8)
203 strmux_cfg.dma8 = regk_strmux_ext2;
204 else
205 panic("Invalid DMA channel for ext2\n");
206 break;
207 case dma_ext3:
208 if (dmanr == 3)
209 strmux_cfg.dma3 = regk_strmux_ext3;
210 else if (dmanr == 9)
211 strmux_cfg.dma9 = regk_strmux_ext2;
212 else
213 panic("Invalid DMA channel for ext2\n");
214 break;
215 }
216
217 used_dma_channels[dmanr] = 1;
218 used_dma_channels_users[dmanr] = device_id;
219 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
220 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
221 spin_unlock_irqrestore(&dma_lock, flags);
222 return 0;
223}
224
225void crisv32_free_dma(unsigned int dmanr)
226{
227 spin_lock(&dma_lock);
228 used_dma_channels[dmanr] = 0;
229 spin_unlock(&dma_lock);
230}
diff --git a/arch/cris/arch-v32/mach-fs/dram_init.S b/arch/cris/arch-v32/mach-fs/dram_init.S
new file mode 100644
index 000000000000..6fbad336527b
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/dram_init.S
@@ -0,0 +1,116 @@
1/*
2 * DRAM/SDRAM initialization - alter with care
3 * This file is intended to be included from other assembler files
4 *
5 * Note: This file may not modify r8 or r9 because they are used to
6 * carry information from the decompresser to the kernel
7 *
8 * Copyright (C) 2000-2007 Axis Communications AB
9 *
10 * Authors: Mikael Starvik <starvik@axis.com>
11 */
12
13/* Just to be certain the config file is included, we include it here
14 * explicitely instead of depending on it being included in the file that
15 * uses this code.
16 */
17
18#include <hwregs/asm/reg_map_asm.h>
19#include <hwregs/asm/bif_core_defs_asm.h>
20
21 ;; WARNING! The registers r8 and r9 are used as parameters carrying
22 ;; information from the decompressor (if the kernel was compressed).
23 ;; They should not be used in the code below.
24
25 ; Refer to BIF MDS for a description of SDRAM initialization
26
27 ; Bank configuration
28 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0), $r0
29 move.d CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
30 move.d $r1, [$r0]
31 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp1), $r0
32 move.d CONFIG_ETRAX_SDRAM_GRP1_CONFIG, $r1
33 move.d $r1, [$r0]
34
35 ; Calculate value of mrs_data
36 ; CAS latency = 2 && bus_width = 32 => 0x40
37 ; CAS latency = 3 && bus_width = 32 => 0x60
38 ; CAS latency = 2 && bus_width = 16 => 0x20
39 ; CAS latency = 3 && bus_width = 16 => 0x30
40
41 ; Check if value is already supplied in kernel config
42 move.d CONFIG_ETRAX_SDRAM_COMMAND, $r2
43 bne _set_timing
44 nop
45
46 move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2
47 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
48 and.d 0x07, $r1 ; Get CAS latency
49 cmpq 2, $r1 ; CL = 2 ?
50 beq _bw_check
51 nop
52 move.d 0x60, $r4
53
54_bw_check:
55 ; Assume that group 0 width is equal to group 1. This assumption
56 ; is wrong for a group 1 only hardware (such as the grand old
57 ; StorPoint+).
58 move.d CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
59 and.d 0x200, $r1 ; DRAM width is bit 9
60 beq _set_timing
61 lslq 2, $r4 ; mrs_data starts at bit 2
62 lsrq 1, $r4 ; 16 bits. Shift down value.
63
64 ; Set timing parameters (refresh off to avoid Guinness TR 83)
65_set_timing:
66 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
67 and.d ~(3 << reg_bif_core_rw_sdram_timing___ref___lsb), $r1
68 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
69 move.d $r1, [$r0]
70
71 ; Issue NOP command
72 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd), $r5
73 moveq regk_bif_core_nop, $r1
74 move.d $r1, [$r5]
75
76 ; Wait 200us
77 move.d 10000, $r2
781: bne 1b
79 subq 1, $r2
80
81 ; Issue initialization command sequence
82 lapc _sdram_commands_start, $r2
83 lapc _sdram_commands_end, $r3
841: clear.d $r6
85 move.b [$r2+], $r6 ; Load command
86 or.d $r4, $r6 ; Add calculated mrs
87 move.d $r6, [$r5] ; Write rw_sdram_cmd
88 ; Wait 80 ns between each command
89 move.d 4000, $r7
902: bne 2b
91 subq 1, $r7
92 cmp.d $r2, $r3 ; Last command?
93 bne 1b
94 nop
95
96 ; Start refresh
97 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
98 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
99 move.d $r1, [$r0]
100
101 ; Initialization finished
102 ba _sdram_commands_end
103 nop
104
105_sdram_commands_start:
106 .byte regk_bif_core_pre ; Precharge
107 .byte regk_bif_core_ref ; refresh
108 .byte regk_bif_core_ref ; refresh
109 .byte regk_bif_core_ref ; refresh
110 .byte regk_bif_core_ref ; refresh
111 .byte regk_bif_core_ref ; refresh
112 .byte regk_bif_core_ref ; refresh
113 .byte regk_bif_core_ref ; refresh
114 .byte regk_bif_core_ref ; refresh
115 .byte regk_bif_core_mrs ; mrs
116_sdram_commands_end:
diff --git a/arch/cris/arch-v32/mach-fs/hw_settings.S b/arch/cris/arch-v32/mach-fs/hw_settings.S
new file mode 100644
index 000000000000..8bde93c36214
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/hw_settings.S
@@ -0,0 +1,70 @@
1/*
2 * This table is used by some tools to extract hardware parameters.
3 * The table should be included in the kernel and the decompressor.
4 * Don't forget to update the tools if you change this table.
5 *
6 * Copyright (C) 2001-2007 Axis Communications AB
7 *
8 * Authors: Mikael Starvik <starvik@axis.com>
9 */
10
11#include <hwregs/asm/reg_map_asm.h>
12#include <hwregs/asm/bif_core_defs_asm.h>
13#include <hwregs/asm/gio_defs_asm.h>
14
15 .ascii "HW_PARAM_MAGIC" ; Magic number
16 .dword 0xc0004000 ; Kernel start address
17
18 ; Debug port
19#ifdef CONFIG_ETRAX_DEBUG_PORT0
20 .dword 0
21#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
22 .dword 1
23#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
24 .dword 2
25#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
26 .dword 3
27#else
28 .dword 4 ; No debug
29#endif
30
31 ; Register values
32 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg)
33 .dword CONFIG_ETRAX_MEM_GRP1_CONFIG
34 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg)
35 .dword CONFIG_ETRAX_MEM_GRP2_CONFIG
36 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg)
37 .dword CONFIG_ETRAX_MEM_GRP3_CONFIG
38 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg)
39 .dword CONFIG_ETRAX_MEM_GRP4_CONFIG
40 .dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0)
41 .dword CONFIG_ETRAX_SDRAM_GRP0_CONFIG
42 .dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp1)
43 .dword CONFIG_ETRAX_SDRAM_GRP1_CONFIG
44 .dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing)
45 .dword CONFIG_ETRAX_SDRAM_TIMING
46 .dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd)
47 .dword CONFIG_ETRAX_SDRAM_COMMAND
48
49 .dword REG_ADDR(gio, regi_gio, rw_pa_dout)
50 .dword CONFIG_ETRAX_DEF_GIO_PA_OUT
51 .dword REG_ADDR(gio, regi_gio, rw_pa_oe)
52 .dword CONFIG_ETRAX_DEF_GIO_PA_OE
53 .dword REG_ADDR(gio, regi_gio, rw_pb_dout)
54 .dword CONFIG_ETRAX_DEF_GIO_PB_OUT
55 .dword REG_ADDR(gio, regi_gio, rw_pb_oe)
56 .dword CONFIG_ETRAX_DEF_GIO_PB_OE
57 .dword REG_ADDR(gio, regi_gio, rw_pc_dout)
58 .dword CONFIG_ETRAX_DEF_GIO_PC_OUT
59 .dword REG_ADDR(gio, regi_gio, rw_pc_oe)
60 .dword CONFIG_ETRAX_DEF_GIO_PC_OE
61 .dword REG_ADDR(gio, regi_gio, rw_pd_dout)
62 .dword CONFIG_ETRAX_DEF_GIO_PD_OUT
63 .dword REG_ADDR(gio, regi_gio, rw_pd_oe)
64 .dword CONFIG_ETRAX_DEF_GIO_PD_OE
65 .dword REG_ADDR(gio, regi_gio, rw_pe_dout)
66 .dword CONFIG_ETRAX_DEF_GIO_PE_OUT
67 .dword REG_ADDR(gio, regi_gio, rw_pe_oe)
68 .dword CONFIG_ETRAX_DEF_GIO_PE_OE
69
70 .dword 0 ; No more register values
diff --git a/arch/cris/arch-v32/mach-fs/io.c b/arch/cris/arch-v32/mach-fs/io.c
new file mode 100644
index 000000000000..a03a3ad3a188
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/io.c
@@ -0,0 +1,191 @@
1/*
2 * Helper functions for I/O pins.
3 *
4 * Copyright (c) 2004-2007 Axis Communications AB.
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9#include <linux/init.h>
10#include <linux/string.h>
11#include <linux/ctype.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/io.h>
15#include <asm/arch/pinmux.h>
16#include <asm/arch/hwregs/gio_defs.h>
17
18#ifndef DEBUG
19#define DEBUG(x)
20#endif
21
22struct crisv32_ioport crisv32_ioports[] = {
23 {
24 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
25 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
26 (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
27 8
28 },
29 {
30 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
31 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
32 (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
33 18
34 },
35 {
36 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
37 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
38 (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
39 18
40 },
41 {
42 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_oe),
43 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_dout),
44 (unsigned long *)REG_ADDR(gio, regi_gio, r_pd_din),
45 18
46 },
47 {
48 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_oe),
49 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_dout),
50 (unsigned long *)REG_ADDR(gio, regi_gio, r_pe_din),
51 18
52 }
53};
54
55#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
56
57struct crisv32_iopin crisv32_led_net0_green;
58struct crisv32_iopin crisv32_led_net0_red;
59struct crisv32_iopin crisv32_led_net1_green;
60struct crisv32_iopin crisv32_led_net1_red;
61struct crisv32_iopin crisv32_led2_green;
62struct crisv32_iopin crisv32_led2_red;
63struct crisv32_iopin crisv32_led3_green;
64struct crisv32_iopin crisv32_led3_red;
65
66/* Dummy port used when green LED and red LED is on the same bit */
67static unsigned long io_dummy;
68static struct crisv32_ioport dummy_port = {
69 &io_dummy,
70 &io_dummy,
71 &io_dummy,
72 18
73};
74static struct crisv32_iopin dummy_led = {
75 &dummy_port,
76 0
77};
78
79static int __init crisv32_io_init(void)
80{
81 int ret = 0;
82
83 u32 i;
84
85 /* Locks *should* be dynamically initialized. */
86 for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
87 spin_lock_init(&crisv32_ioports[i].lock);
88 spin_lock_init(&dummy_port.lock);
89
90 /* Initialize LEDs */
91#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
92 ret +=
93 crisv32_io_get_name(&crisv32_led_net0_green,
94 CONFIG_ETRAX_LED_G_NET0);
95 crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
96 if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
97 ret +=
98 crisv32_io_get_name(&crisv32_led_net0_red,
99 CONFIG_ETRAX_LED_R_NET0);
100 crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
101 } else
102 crisv32_led_net0_red = dummy_led;
103#endif
104
105#ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO
106 ret +=
107 crisv32_io_get_name(&crisv32_led_net1_green,
108 CONFIG_ETRAX_LED_G_NET1);
109 crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out);
110 if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) {
111 crisv32_io_get_name(&crisv32_led_net1_red,
112 CONFIG_ETRAX_LED_R_NET1);
113 crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out);
114 } else
115 crisv32_led_net1_red = dummy_led;
116#endif
117
118 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
119 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
120 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
121 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);
122
123 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
124 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
125 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
126 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
127
128 return ret;
129}
130
131__initcall(crisv32_io_init);
132
133int crisv32_io_get(struct crisv32_iopin *iopin,
134 unsigned int port, unsigned int pin)
135{
136 if (port > NBR_OF_PORTS)
137 return -EINVAL;
138 if (port > crisv32_ioports[port].pin_count)
139 return -EINVAL;
140
141 iopin->bit = 1 << pin;
142 iopin->port = &crisv32_ioports[port];
143
144 /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
145 /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
146 if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
147 return -EIO;
148 DEBUG(printk(KERN_DEBUG "crisv32_io_get: Allocated pin %d on port %d\n",
149 pin, port));
150
151 return 0;
152}
153
154int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
155{
156 int port;
157 int pin;
158
159 if (toupper(*name) == 'P')
160 name++;
161
162 if (toupper(*name) < 'A' || toupper(*name) > 'E')
163 return -EINVAL;
164
165 port = toupper(*name) - 'A';
166 name++;
167 pin = simple_strtoul(name, NULL, 10);
168
169 if (pin < 0 || pin > crisv32_ioports[port].pin_count)
170 return -EINVAL;
171
172 iopin->bit = 1 << pin;
173 iopin->port = &crisv32_ioports[port];
174
175 /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
176 /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
177 if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
178 return -EIO;
179
180 DEBUG(printk(KERN_DEBUG
181 "crisv32_io_get_name: Allocated pin %d on port %d\n",
182 pin, port));
183
184 return 0;
185}
186
187#ifdef CONFIG_PCI
188/* PCI I/O access stuff */
189struct cris_io_operations *cris_iops = NULL;
190EXPORT_SYMBOL(cris_iops);
191#endif
diff --git a/arch/cris/arch-v32/mach-fs/pinmux.c b/arch/cris/arch-v32/mach-fs/pinmux.c
new file mode 100644
index 000000000000..d722ad9ae626
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/pinmux.c
@@ -0,0 +1,309 @@
1/*
2 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
3 * Unassigned pins and GPIO pins can be allocated to a fixed interface
4 * or the I/O processor instead.
5 *
6 * Copyright (c) 2004-2007 Axis Communications AB.
7 */
8
9#include <linux/init.h>
10#include <linux/errno.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/spinlock.h>
14#include <hwregs/reg_map.h>
15#include <hwregs/reg_rdwr.h>
16#include <pinmux.h>
17#include <hwregs/pinmux_defs.h>
18
19#undef DEBUG
20
21#define PORT_PINS 18
22#define PORTS 4
23
24static char pins[PORTS][PORT_PINS];
25static DEFINE_SPINLOCK(pinmux_lock);
26
27static void crisv32_pinmux_set(int port);
28
29int crisv32_pinmux_init(void)
30{
31 static int initialized;
32
33 if (!initialized) {
34 reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
35 initialized = 1;
36 REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
37 pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
38 pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
39 REG_WR(pinmux, regi_pinmux, rw_pa, pa);
40 crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
41 crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
42 crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio);
43 crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio);
44 }
45
46 return 0;
47}
48
49int
50crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
51{
52 int i;
53 unsigned long flags;
54
55 crisv32_pinmux_init();
56
57 if (port > PORTS)
58 return -EINVAL;
59
60 spin_lock_irqsave(&pinmux_lock, flags);
61
62 for (i = first_pin; i <= last_pin; i++) {
63 if ((pins[port][i] != pinmux_none)
64 && (pins[port][i] != pinmux_gpio)
65 && (pins[port][i] != mode)) {
66 spin_unlock_irqrestore(&pinmux_lock, flags);
67#ifdef DEBUG
68 panic("Pinmux alloc failed!\n");
69#endif
70 return -EPERM;
71 }
72 }
73
74 for (i = first_pin; i <= last_pin; i++)
75 pins[port][i] = mode;
76
77 crisv32_pinmux_set(port);
78
79 spin_unlock_irqrestore(&pinmux_lock, flags);
80
81 return 0;
82}
83
84int crisv32_pinmux_alloc_fixed(enum fixed_function function)
85{
86 int ret = -EINVAL;
87 char saved[sizeof pins];
88 unsigned long flags;
89
90 spin_lock_irqsave(&pinmux_lock, flags);
91
92 /* Save internal data for recovery */
93 memcpy(saved, pins, sizeof pins);
94
95 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
96
97 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
98
99 switch (function) {
100 case pinmux_ser1:
101 ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
102 hwprot.ser1 = regk_pinmux_yes;
103 break;
104 case pinmux_ser2:
105 ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
106 hwprot.ser2 = regk_pinmux_yes;
107 break;
108 case pinmux_ser3:
109 ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
110 hwprot.ser3 = regk_pinmux_yes;
111 break;
112 case pinmux_sser0:
113 ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
114 ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
115 hwprot.sser0 = regk_pinmux_yes;
116 break;
117 case pinmux_sser1:
118 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
119 hwprot.sser1 = regk_pinmux_yes;
120 break;
121 case pinmux_ata0:
122 ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
123 ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
124 hwprot.ata0 = regk_pinmux_yes;
125 break;
126 case pinmux_ata1:
127 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
128 ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
129 hwprot.ata1 = regk_pinmux_yes;
130 break;
131 case pinmux_ata2:
132 ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
133 ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
134 hwprot.ata2 = regk_pinmux_yes;
135 break;
136 case pinmux_ata3:
137 ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
138 ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
139 hwprot.ata2 = regk_pinmux_yes;
140 break;
141 case pinmux_ata:
142 ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
143 ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
144 hwprot.ata = regk_pinmux_yes;
145 break;
146 case pinmux_eth1:
147 ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
148 hwprot.eth1 = regk_pinmux_yes;
149 hwprot.eth1_mgm = regk_pinmux_yes;
150 break;
151 case pinmux_timer:
152 ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
153 hwprot.timer = regk_pinmux_yes;
154 spin_unlock_irqrestore(&pinmux_lock, flags);
155 return ret;
156 }
157
158 if (!ret)
159 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
160 else
161 memcpy(pins, saved, sizeof pins);
162
163 spin_unlock_irqrestore(&pinmux_lock, flags);
164
165 return ret;
166}
167
168void crisv32_pinmux_set(int port)
169{
170 int i;
171 int gpio_val = 0;
172 int iop_val = 0;
173
174 for (i = 0; i < PORT_PINS; i++) {
175 if (pins[port][i] == pinmux_gpio)
176 gpio_val |= (1 << i);
177 else if (pins[port][i] == pinmux_iop)
178 iop_val |= (1 << i);
179 }
180
181 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8 * port,
182 gpio_val);
183 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8 * port,
184 iop_val);
185
186#ifdef DEBUG
187 crisv32_pinmux_dump();
188#endif
189}
190
191int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
192{
193 int i;
194 unsigned long flags;
195
196 crisv32_pinmux_init();
197
198 if (port > PORTS)
199 return -EINVAL;
200
201 spin_lock_irqsave(&pinmux_lock, flags);
202
203 for (i = first_pin; i <= last_pin; i++)
204 pins[port][i] = pinmux_none;
205
206 crisv32_pinmux_set(port);
207 spin_unlock_irqrestore(&pinmux_lock, flags);
208
209 return 0;
210}
211
212int crisv32_pinmux_dealloc_fixed(enum fixed_function function)
213{
214 int ret = -EINVAL;
215 char saved[sizeof pins];
216 unsigned long flags;
217
218 spin_lock_irqsave(&pinmux_lock, flags);
219
220 /* Save internal data for recovery */
221 memcpy(saved, pins, sizeof pins);
222
223 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
224
225 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
226
227 switch (function) {
228 case pinmux_ser1:
229 ret = crisv32_pinmux_dealloc(PORT_C, 4, 7);
230 hwprot.ser1 = regk_pinmux_no;
231 break;
232 case pinmux_ser2:
233 ret = crisv32_pinmux_dealloc(PORT_C, 8, 11);
234 hwprot.ser2 = regk_pinmux_no;
235 break;
236 case pinmux_ser3:
237 ret = crisv32_pinmux_dealloc(PORT_C, 12, 15);
238 hwprot.ser3 = regk_pinmux_no;
239 break;
240 case pinmux_sser0:
241 ret = crisv32_pinmux_dealloc(PORT_C, 0, 3);
242 ret |= crisv32_pinmux_dealloc(PORT_C, 16, 16);
243 hwprot.sser0 = regk_pinmux_no;
244 break;
245 case pinmux_sser1:
246 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4);
247 hwprot.sser1 = regk_pinmux_no;
248 break;
249 case pinmux_ata0:
250 ret = crisv32_pinmux_dealloc(PORT_D, 5, 7);
251 ret |= crisv32_pinmux_dealloc(PORT_D, 15, 17);
252 hwprot.ata0 = regk_pinmux_no;
253 break;
254 case pinmux_ata1:
255 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4);
256 ret |= crisv32_pinmux_dealloc(PORT_E, 17, 17);
257 hwprot.ata1 = regk_pinmux_no;
258 break;
259 case pinmux_ata2:
260 ret = crisv32_pinmux_dealloc(PORT_C, 11, 15);
261 ret |= crisv32_pinmux_dealloc(PORT_E, 3, 3);
262 hwprot.ata2 = regk_pinmux_no;
263 break;
264 case pinmux_ata3:
265 ret = crisv32_pinmux_dealloc(PORT_C, 8, 10);
266 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 2);
267 hwprot.ata2 = regk_pinmux_no;
268 break;
269 case pinmux_ata:
270 ret = crisv32_pinmux_dealloc(PORT_B, 0, 15);
271 ret |= crisv32_pinmux_dealloc(PORT_D, 8, 15);
272 hwprot.ata = regk_pinmux_no;
273 break;
274 case pinmux_eth1:
275 ret = crisv32_pinmux_dealloc(PORT_E, 0, 17);
276 hwprot.eth1 = regk_pinmux_no;
277 hwprot.eth1_mgm = regk_pinmux_no;
278 break;
279 case pinmux_timer:
280 ret = crisv32_pinmux_dealloc(PORT_C, 16, 16);
281 hwprot.timer = regk_pinmux_no;
282 spin_unlock_irqrestore(&pinmux_lock, flags);
283 return ret;
284 }
285
286 if (!ret)
287 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
288 else
289 memcpy(pins, saved, sizeof pins);
290
291 spin_unlock_irqrestore(&pinmux_lock, flags);
292
293 return ret;
294}
295
296void crisv32_pinmux_dump(void)
297{
298 int i, j;
299
300 crisv32_pinmux_init();
301
302 for (i = 0; i < PORTS; i++) {
303 printk(KERN_DEBUG "Port %c\n", 'B' + i);
304 for (j = 0; j < PORT_PINS; j++)
305 printk(KERN_DEBUG " Pin %d = %d\n", j, pins[i][j]);
306 }
307}
308
309__initcall(crisv32_pinmux_init);
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.c b/arch/cris/arch-v32/mach-fs/vcs_hook.c
new file mode 100644
index 000000000000..593b10f07ef1
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.c
@@ -0,0 +1,100 @@
1/*
2 * Call simulator hook. This is the part running in the
3 * simulated program.
4 */
5
6#include "vcs_hook.h"
7#include <stdarg.h>
8#include <asm/arch-v32/hwregs/reg_map.h>
9#include <asm/arch-v32/hwregs/intr_vect_defs.h>
10
11#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
12#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
13
14#define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset]
15#define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset]
16#define HOOK_TRIG(funcid) \
17 do { \
18 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19 } while (0)
20#define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset]
21
22int hook_call(unsigned id, unsigned pcnt, ...)
23{
24 va_list ap;
25 unsigned i;
26 unsigned ret;
27#ifdef USING_SOS
28 PREEMPT_OFF_SAVE();
29#endif
30
31 /* pass parameters */
32 HOOK_DATA(0) = id;
33
34 /* Have to make hook_print_str a special case since we call with a
35 * parameter of byte type. Should perhaps be a separate
36 * hook_call. */
37
38 if (id == hook_print_str) {
39 int i;
40 char *str;
41
42 HOOK_DATA(1) = pcnt;
43
44 va_start(ap, pcnt);
45 str = (char *)va_arg(ap, unsigned);
46
47 for (i = 0; i != pcnt; i++)
48 HOOK_DATA_BYTE(8 + i) = str[i];
49
50 HOOK_DATA_BYTE(8 + i) = 0; /* null byte */
51 } else {
52 va_start(ap, pcnt);
53 for (i = 1; i <= pcnt; i++)
54 HOOK_DATA(i) = va_arg(ap, unsigned);
55 va_end(ap);
56 }
57
58 /* read from mem to make sure data has propagated to memory before
59 * trigging */
60 ret = *((volatile unsigned *)HOOK_MEM_BASE_ADDR);
61
62 /* trigger hook */
63 HOOK_TRIG(id);
64
65 /* wait for call to finish */
66 while (VHOOK_DATA(0) > 0) ;
67
68 /* extract return value */
69
70 ret = VHOOK_DATA(1);
71
72#ifdef USING_SOS
73 PREEMPT_RESTORE();
74#endif
75 return ret;
76}
77
78unsigned hook_buf(unsigned i)
79{
80 return (HOOK_DATA(i));
81}
82
83void print_str(const char *str)
84{
85 int i;
86 /* find null at end of string */
87 for (i = 1; str[i]; i++) ;
88 hook_call(hook_print_str, i, str);
89}
90
91void CPU_KICK_DOG(void)
92{
93 (void)hook_call(hook_kick_dog, 0);
94}
95
96void CPU_WATCHDOG_TIMEOUT(unsigned t)
97{
98 (void)hook_call(hook_dog_timeout, 1, t);
99}
100
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.h b/arch/cris/arch-v32/mach-fs/vcs_hook.h
new file mode 100644
index 000000000000..c000b9fece41
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.h
@@ -0,0 +1,42 @@
1/*
2 * Call simulator hook functions
3 */
4
5#ifndef HOOK_H
6#define HOOK_H
7
8int hook_call(unsigned id, unsigned pcnt, ...);
9
10enum hook_ids {
11 hook_debug_on = 1,
12 hook_debug_off,
13 hook_stop_sim_ok,
14 hook_stop_sim_fail,
15 hook_alloc_shared,
16 hook_ptr_shared,
17 hook_free_shared,
18 hook_file2shared,
19 hook_cmp_shared,
20 hook_print_params,
21 hook_sim_time,
22 hook_stop_sim,
23 hook_kick_dog,
24 hook_dog_timeout,
25 hook_rand,
26 hook_srand,
27 hook_rand_range,
28 hook_print_str,
29 hook_print_hex,
30 hook_cmp_offset_shared,
31 hook_fill_random_shared,
32 hook_alloc_random_data,
33 hook_calloc_random_data,
34 hook_print_int,
35 hook_print_uint,
36 hook_fputc,
37 hook_init_fd,
38 hook_sbrk
39
40};
41
42#endif