ubicom32: remove some more unnecessary stuff from the kernel patch
[openwrt.git] / target / linux / ubicom32 / patches-2.6.28 / 100-ubicom32_support.patch
1 --- /dev/null
2 +++ b/arch/ubicom32/crypto/aes_ubicom32.c
3 @@ -0,0 +1,458 @@
4 +/*
5 + * arch/ubicom32/crypto/aes_ubicom32.c
6 + *   Ubicom32 implementation of the AES Cipher Algorithm.
7 + *
8 + * (C) Copyright 2009, Ubicom, Inc.
9 + *
10 + * This file is part of the Ubicom32 Linux Kernel Port.
11 + *
12 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13 + * it and/or modify it under the terms of the GNU General Public License
14 + * as published by the Free Software Foundation, either version 2 of the
15 + * License, or (at your option) any later version.
16 + *
17 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
18 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20 + * the GNU General Public License for more details.
21 + *
22 + * You should have received a copy of the GNU General Public License
23 + * along with the Ubicom32 Linux Kernel Port.  If not, 
24 + * see <http://www.gnu.org/licenses/>.
25 + *
26 + * Ubicom32 implementation derived from (with many thanks):
27 + *   arch/m68knommu
28 + *   arch/blackfin
29 + *   arch/parisc
30 + */
31 +#include <crypto/aes.h>
32 +#include <crypto/algapi.h>
33 +#include <linux/err.h>
34 +#include <linux/module.h>
35 +#include <linux/init.h>
36 +#include <linux/spinlock.h>
37 +#include "crypto_ubicom32.h"
38 +#include <asm/linkage.h>
39 +
40 +struct ubicom32_aes_ctx {
41 +       u8 key[AES_MAX_KEY_SIZE];
42 +       u32 ctrl;
43 +       int key_len;
44 +};
45 +
46 +static inline void aes_hw_set_key(const u8 *key, u8 key_len)
47 +{
48 +       /*
49 +        * switch case has more overhead than 4 move.4 instructions, so just copy 256 bits
50 +        */
51 +       SEC_SET_KEY_256(key);
52 +}
53 +
54 +static inline void aes_hw_set_iv(const u8 *iv)
55 +{
56 +       SEC_SET_IV_4W(iv);
57 +}
58 +
59 +static inline void aes_hw_cipher(u8 *out, const u8 *in)
60 +{
61 +       SEC_SET_INPUT_4W(in);
62 +
63 +       asm volatile (                                                
64 +       "       ; start AES by writing 0x40(SECURITY_BASE)      \n\t" 
65 +       "       move.4 0x40(%0), #0x01                          \n\t" 
66 +       "       pipe_flush 0                                    \n\t" 
67 +       "                                                       \n\t" 
68 +       "       ; wait for the module to calculate the output   \n\t" 
69 +       "       btst 0x04(%0), #0                               \n\t" 
70 +       "       jmpne.f .-4                                     \n\t" 
71 +               :                                                             
72 +               : "a" (SEC_BASE)                                                      
73 +               : "cc"
74 +       );
75 +       
76 +       SEC_GET_OUTPUT_4W(out);
77 +}
78 +
79 +static int __ocm_text aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
80 +                      unsigned int key_len)
81 +{
82 +       struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
83 +
84 +       uctx->key_len = key_len;
85 +       memcpy(uctx->key, in_key, key_len);
86 +
87 +       /*
88 +        * leave out HASH_ALG (none = 0), CBC (no = 0), DIR (unknown) yet
89 +        */
90 +       switch (uctx->key_len) {
91 +       case 16:
92 +               uctx->ctrl = SEC_KEY_128_BITS | SEC_ALG_AES;
93 +               break;
94 +       case 24:
95 +               uctx->ctrl = SEC_KEY_192_BITS | SEC_ALG_AES;
96 +               break;
97 +       case 32:
98 +               uctx->ctrl = SEC_KEY_256_BITS | SEC_ALG_AES;
99 +               break;
100 +       }
101 +
102 +       return 0;
103 +}
104 +
105 +static inline void aes_cipher(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
106 +{
107 +       const struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
108 +
109 +       hw_crypto_lock();
110 +       hw_crypto_check();
111 +       hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
112 +
113 +       aes_hw_set_key(uctx->key, uctx->key_len);
114 +       aes_hw_cipher(out, in);
115 +
116 +       hw_crypto_unlock();     
117 +}
118 +
119 +static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
120 +{
121 +       aes_cipher(tfm, out, in, SEC_DIR_ENCRYPT);
122 +}
123 +
124 +static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
125 +{
126 +       aes_cipher(tfm, out, in, SEC_DIR_DECRYPT);
127 +}
128 +
129 +static struct crypto_alg aes_alg = {
130 +       .cra_name               =       "aes",
131 +       .cra_driver_name        =       "aes-ubicom32",
132 +       .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
133 +       .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER, 
134 +       .cra_blocksize          =       AES_BLOCK_SIZE,
135 +       .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
136 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
137 +       .cra_module             =       THIS_MODULE,
138 +       .cra_list               =       LIST_HEAD_INIT(aes_alg.cra_list),
139 +       .cra_u                  =       {
140 +               .cipher = {
141 +                       .cia_min_keysize        =       AES_MIN_KEY_SIZE,
142 +                       .cia_max_keysize        =       AES_MAX_KEY_SIZE,
143 +                       .cia_setkey             =       aes_set_key,
144 +                       .cia_encrypt            =       aes_encrypt,
145 +                       .cia_decrypt            =       aes_decrypt,
146 +               }
147 +       }
148 +};
149 +
150 +static void __ocm_text ecb_aes_crypt_loop(u8 *out, u8 *in, unsigned int n)
151 +{
152 +       while (likely(n)) {
153 +               aes_hw_cipher(out, in);
154 +               out += AES_BLOCK_SIZE;
155 +               in += AES_BLOCK_SIZE;
156 +               n -= AES_BLOCK_SIZE;
157 +       }
158 +}
159 +
160 +static int __ocm_text ecb_aes_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, 
161 +                        struct scatterlist *src, unsigned int nbytes, u32 extra_flags)
162 +{
163 +       const struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
164 +       int ret;
165 +       
166 +       struct blkcipher_walk walk;
167 +       blkcipher_walk_init(&walk, dst, src, nbytes);
168 +       ret = blkcipher_walk_virt(desc, &walk);
169 +        if (ret) {
170 +                return ret;
171 +        }
172 +
173 +       hw_crypto_lock();
174 +       hw_crypto_check();
175 +
176 +        hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
177 +        aes_hw_set_key(uctx->key, uctx->key_len);
178 +       
179 +       while (likely((nbytes = walk.nbytes))) {
180 +               /* only use complete blocks */
181 +               unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
182 +               u8 *out = walk.dst.virt.addr;
183 +               u8 *in = walk.src.virt.addr;
184 +
185 +               /* finish n/16 blocks */
186 +               ecb_aes_crypt_loop(out, in, n);
187 +               
188 +               nbytes &= AES_BLOCK_SIZE - 1;
189 +               ret = blkcipher_walk_done(desc, &walk, nbytes);
190 +       }
191 +
192 +       hw_crypto_unlock();
193 +       return ret;
194 +}
195 +
196 +static int ecb_aes_encrypt(struct blkcipher_desc *desc,
197 +                          struct scatterlist *dst, struct scatterlist *src,
198 +                          unsigned int nbytes)
199 +{
200 +       return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT);
201 +}
202 +
203 +static int ecb_aes_decrypt(struct blkcipher_desc *desc,
204 +                          struct scatterlist *dst, struct scatterlist *src,
205 +                          unsigned int nbytes)
206 +{
207 +       return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT);
208 +}
209 +
210 +static struct crypto_alg ecb_aes_alg = {
211 +       .cra_name               =       "ecb(aes)",
212 +       .cra_driver_name        =       "ecb-aes-ubicom32",
213 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
214 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER, 
215 +       .cra_blocksize          =       AES_BLOCK_SIZE,
216 +       .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
217 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
218 +       .cra_type               =       &crypto_blkcipher_type,
219 +       .cra_module             =       THIS_MODULE,
220 +       .cra_list               =       LIST_HEAD_INIT(ecb_aes_alg.cra_list),
221 +       .cra_u                  =       {
222 +               .blkcipher = {
223 +                       .min_keysize            =       AES_MIN_KEY_SIZE,
224 +                       .max_keysize            =       AES_MAX_KEY_SIZE,
225 +                       .setkey                 =       aes_set_key,
226 +                       .encrypt                =       ecb_aes_encrypt,
227 +                       .decrypt                =       ecb_aes_decrypt,
228 +               }
229 +       }
230 +};
231 +
232 +#if CRYPTO_UBICOM32_LOOP_ASM 
233 +void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
234 +{
235 +       asm volatile (
236 +       "; set init. iv 4w                      \n\t"
237 +       "       move.4 0x50(%0), 0x0(%3)        \n\t"
238 +       "       move.4 0x54(%0), 0x4(%3)        \n\t"
239 +       "       move.4 0x58(%0), 0x8(%3)        \n\t"
240 +       "       move.4 0x5c(%0), 0xc(%3)        \n\t"
241 +       "                                       \n\t"
242 +       "; we know n > 0, so we can always      \n\t"
243 +       "; load the first block                 \n\t"
244 +       "; set input 4w                         \n\t"
245 +       "       move.4 0x30(%0), 0x0(%2)        \n\t"
246 +       "       move.4 0x34(%0), 0x4(%2)        \n\t"
247 +       "       move.4 0x38(%0), 0x8(%2)        \n\t"
248 +       "       move.4 0x3c(%0), 0xc(%2)        \n\t"
249 +       "                                       \n\t"
250 +       "; kickoff hw                           \n\t"
251 +       "       move.4 0x40(%0), %2             \n\t"
252 +       "                                       \n\t"
253 +       "; update n & flush                     \n\t"
254 +       "       add.4 %4, #-16, %4              \n\t"
255 +       "       pipe_flush 0                    \n\t"
256 +       "                                       \n\t"
257 +       "; while (n):  work on 2nd block        \n\t"
258 +       " 1:    lsl.4 d15, %4, #0x0             \n\t"
259 +       "       jmpeq.f 5f                      \n\t"
260 +       "                                       \n\t"
261 +       "; set input 4w (2nd)                   \n\t"
262 +       "       move.4 0x30(%0), 0x10(%2)       \n\t"
263 +       "       move.4 0x34(%0), 0x14(%2)       \n\t"
264 +       "       move.4 0x38(%0), 0x18(%2)       \n\t"
265 +       "       move.4 0x3c(%0), 0x1c(%2)       \n\t"
266 +       "                                       \n\t"
267 +       "; update n/in asap while waiting       \n\t"
268 +       "       add.4 %4, #-16, %4              \n\t"
269 +       "       move.4 d15, 16(%2)++            \n\t"
270 +       "                                       \n\t"
271 +       "; wait for the previous output         \n\t"
272 +       "       btst 0x04(%0), #0               \n\t"
273 +       "       jmpne.f -4                      \n\t"
274 +       "                                       \n\t"
275 +       "; read previous output                 \n\t"
276 +       "       move.4 0x0(%1), 0x50(%0)        \n\t"
277 +       "       move.4 0x4(%1), 0x54(%0)        \n\t"
278 +       "       move.4 0x8(%1), 0x58(%0)        \n\t"
279 +       "       move.4 0xc(%1), 0x5c(%0)        \n\t"
280 +       "                                       \n\t"
281 +       "; kick off hw for 2nd input            \n\t"
282 +       "       move.4 0x40(%0), %2             \n\t"
283 +       "                                       \n\t"
284 +       "; update out asap                      \n\t"
285 +       "       move.4 d15, 16(%1)++            \n\t"
286 +       "                                       \n\t"
287 +       "; go back to loop                      \n\t"
288 +       "       jmpt 1b                         \n\t"
289 +       "                                       \n\t"
290 +       "; wait for last output                 \n\t" 
291 +       " 5:    btst 0x04(%0), #0               \n\t"
292 +        "       jmpne.f -4                      \n\t"
293 +        "                                       \n\t"
294 +       "; read last output                     \n\t"
295 +       "       move.4 0x0(%1), 0x50(%0)        \n\t"
296 +       "       move.4 0x4(%1), 0x54(%0)        \n\t"
297 +       "       move.4 0x8(%1), 0x58(%0)        \n\t"
298 +       "       move.4 0xc(%1), 0x5c(%0)        \n\t"
299 +        "                                       \n\t"
300 +       "; copy out iv                          \n\t"
301 +       "       move.4 0x0(%3), 0x50(%0)        \n\t"
302 +       "       move.4 0x4(%3), 0x54(%0)        \n\t"
303 +       "       move.4 0x8(%3), 0x58(%0)        \n\t"
304 +       "       move.4 0xc(%3), 0x5c(%0)        \n\t"
305 +        "                                       \n\t"
306 +               :
307 +               : "a" (SEC_BASE), "a" (out), "a" (in), "a" (iv), "d" (n)
308 +               : "d15", "cc"
309 +       );
310 +}
311 +
312 +#else
313 +
314 +static void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
315 +{
316 +       aes_hw_set_iv(iv);
317 +       while (likely(n)) {
318 +               aes_hw_cipher(out, in);
319 +               out += AES_BLOCK_SIZE;
320 +               in += AES_BLOCK_SIZE;
321 +               n -= AES_BLOCK_SIZE;    
322 +       }
323 +       SEC_COPY_4W(iv, out - AES_BLOCK_SIZE);
324 +}
325 +
326 +#endif
327 +
328 +static void __ocm_text cbc_aes_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
329 +{
330 +        while (likely(n)) {
331 +                aes_hw_set_iv(iv);
332 +               SEC_COPY_4W(iv, in);
333 +                aes_hw_cipher(out, in);
334 +                out += AES_BLOCK_SIZE;
335 +                in += AES_BLOCK_SIZE;
336 +                n -= AES_BLOCK_SIZE;
337 +        }
338 +}
339 +
340 +static int __ocm_text cbc_aes_crypt(struct blkcipher_desc *desc, 
341 +                           struct scatterlist *dst, struct scatterlist *src,
342 +                           unsigned int nbytes, u32 extra_flags)
343 +{
344 +       struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
345 +       int ret;
346 +
347 +        struct blkcipher_walk walk;
348 +        blkcipher_walk_init(&walk, dst, src, nbytes);
349 +       ret = blkcipher_walk_virt(desc, &walk);
350 +       if (unlikely(ret)) {
351 +               return ret;
352 +       }
353 +       
354 +        hw_crypto_lock();
355 +       hw_crypto_check();
356 +
357 +        hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
358 +        aes_hw_set_key(uctx->key, uctx->key_len);
359 +
360 +       while (likely((nbytes = walk.nbytes))) {
361 +                /* only use complete blocks */
362 +                unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
363 +               if (likely(n)) {
364 +                       u8 *out = walk.dst.virt.addr;
365 +                       u8 *in = walk.src.virt.addr;
366 +
367 +                       if (extra_flags & SEC_DIR_ENCRYPT) {
368 +                               cbc_aes_encrypt_loop(out, in, walk.iv, n);
369 +                       } else {
370 +                               cbc_aes_decrypt_loop(out, in, walk.iv, n);
371 +                       }
372 +               }
373 +
374 +               nbytes &= AES_BLOCK_SIZE - 1;
375 +                ret = blkcipher_walk_done(desc, &walk, nbytes);
376 +       }
377 +       hw_crypto_unlock();
378 +
379 +       return ret;
380 +}
381 +
382 +static int __ocm_text cbc_aes_encrypt(struct blkcipher_desc *desc,
383 +                          struct scatterlist *dst, struct scatterlist *src,
384 +                          unsigned int nbytes)
385 +{
386 +       return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT | SEC_CBC_SET);
387 +}
388 +
389 +static int __ocm_text cbc_aes_decrypt(struct blkcipher_desc *desc,
390 +                          struct scatterlist *dst, struct scatterlist *src,
391 +                          unsigned int nbytes)
392 +{
393 +       return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT | SEC_CBC_SET);
394 +}
395 +
396 +static struct crypto_alg cbc_aes_alg = {
397 +       .cra_name               =       "cbc(aes)",
398 +       .cra_driver_name        =       "cbc-aes-ubicom32",
399 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
400 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER, 
401 +       .cra_blocksize          =       AES_BLOCK_SIZE,
402 +       .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
403 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
404 +       .cra_type               =       &crypto_blkcipher_type,
405 +       .cra_module             =       THIS_MODULE,
406 +       .cra_list               =       LIST_HEAD_INIT(cbc_aes_alg.cra_list),
407 +       .cra_u                  =       {
408 +               .blkcipher = {
409 +                       .min_keysize            =       AES_MIN_KEY_SIZE,
410 +                       .max_keysize            =       AES_MAX_KEY_SIZE,
411 +                       .ivsize                 =       AES_BLOCK_SIZE,
412 +                       .setkey                 =       aes_set_key,
413 +                       .encrypt                =       cbc_aes_encrypt,
414 +                       .decrypt                =       cbc_aes_decrypt,
415 +               }
416 +       }
417 +};
418 +
419 +static int __init aes_init(void)
420 +{
421 +       int ret;
422 +
423 +       hw_crypto_init();
424 +
425 +       ret = crypto_register_alg(&aes_alg);
426 +       if (ret)
427 +               goto aes_err;
428 +
429 +       ret = crypto_register_alg(&ecb_aes_alg);
430 +       if (ret)
431 +               goto ecb_aes_err;
432 +
433 +       ret = crypto_register_alg(&cbc_aes_alg);
434 +       if (ret)
435 +               goto cbc_aes_err;
436 +
437 +out:
438 +       return ret;
439 +
440 +cbc_aes_err:
441 +       crypto_unregister_alg(&ecb_aes_alg);
442 +ecb_aes_err:
443 +       crypto_unregister_alg(&aes_alg);
444 +aes_err:
445 +       goto out;
446 +}
447 +
448 +static void __exit aes_fini(void)
449 +{
450 +       crypto_unregister_alg(&cbc_aes_alg);
451 +       crypto_unregister_alg(&ecb_aes_alg);
452 +       crypto_unregister_alg(&aes_alg);
453 +}
454 +
455 +module_init(aes_init);
456 +module_exit(aes_fini);
457 +
458 +MODULE_ALIAS("aes");
459 +
460 +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
461 +MODULE_LICENSE("GPL");
462 --- /dev/null
463 +++ b/arch/ubicom32/crypto/crypto_des.h
464 @@ -0,0 +1,34 @@
465 +/*
466 + * arch/ubicom32/crypto/crypto_des.h
467 + *   Function for checking keys for the DES and Triple DES Encryption
468 + *   algorithms.
469 + *
470 + * (C) Copyright 2009, Ubicom, Inc.
471 + *
472 + * This file is part of the Ubicom32 Linux Kernel Port.
473 + *
474 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
475 + * it and/or modify it under the terms of the GNU General Public License
476 + * as published by the Free Software Foundation, either version 2 of the
477 + * License, or (at your option) any later version.
478 + *
479 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
480 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
481 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
482 + * the GNU General Public License for more details.
483 + *
484 + * You should have received a copy of the GNU General Public License
485 + * along with the Ubicom32 Linux Kernel Port.  If not, 
486 + * see <http://www.gnu.org/licenses/>.
487 + *
488 + * Ubicom32 implementation derived from (with many thanks):
489 + *   arch/m68knommu
490 + *   arch/blackfin
491 + *   arch/parisc
492 + */
493 +#ifndef __CRYPTO_DES_H__
494 +#define __CRYPTO_DES_H__
495 +
496 +extern int crypto_des_check_key(const u8*, unsigned int, u32*);
497 +
498 +#endif /* __CRYPTO_DES_H__ */
499 --- /dev/null
500 +++ b/arch/ubicom32/crypto/crypto_ubicom32.c
501 @@ -0,0 +1,50 @@
502 +/*
503 + * arch/ubicom32/crypto/crypto_ubicom32.c
504 + *   Generic code to support ubicom32 hardware crypto accelerator
505 + *
506 + * (C) Copyright 2009, Ubicom, Inc.
507 + *
508 + * This file is part of the Ubicom32 Linux Kernel Port.
509 + *
510 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
511 + * it and/or modify it under the terms of the GNU General Public License
512 + * as published by the Free Software Foundation, either version 2 of the
513 + * License, or (at your option) any later version.
514 + *
515 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
516 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
517 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
518 + * the GNU General Public License for more details.
519 + *
520 + * You should have received a copy of the GNU General Public License
521 + * along with the Ubicom32 Linux Kernel Port.  If not, 
522 + * see <http://www.gnu.org/licenses/>.
523 + *
524 + * Ubicom32 implementation derived from (with many thanks):
525 + *   arch/m68knommu
526 + *   arch/blackfin
527 + *   arch/parisc
528 + */
529 +#include "crypto_ubicom32.h"
530 +
531 +spinlock_t crypto_ubicom32_lock;
532 +bool crypto_ubicom32_inited = false;
533 +volatile bool crypto_ubicom32_on = false;
534 +volatile unsigned long crypto_ubicom32_last_use;
535 +
536 +struct timer_list crypto_ubicom32_ps_timer;
537 +void crypto_ubicom32_ps_check(unsigned long data)
538 +{
539 +       unsigned long idle_time = msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS);
540 +
541 +       BUG_ON(!crypto_ubicom32_on);
542 +
543 +       if (((jiffies - crypto_ubicom32_last_use) > idle_time) && spin_trylock_bh(&crypto_ubicom32_lock)) {
544 +                hw_crypto_turn_off();
545 +                spin_unlock_bh(&crypto_ubicom32_lock);
546 +               return;
547 +       }
548 +
549 +       /* keep monitoring */
550 +       hw_crypto_ps_start();
551 +}
552 --- /dev/null
553 +++ b/arch/ubicom32/crypto/crypto_ubicom32.h
554 @@ -0,0 +1,346 @@
555 +/*
556 + * arch/ubicom32/crypto/crypto_ubicom32.h
557 + *   Support for Ubicom32 cryptographic instructions.
558 + *
559 + * (C) Copyright 2009, Ubicom, Inc.
560 + *
561 + * This file is part of the Ubicom32 Linux Kernel Port.
562 + *
563 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
564 + * it and/or modify it under the terms of the GNU General Public License
565 + * as published by the Free Software Foundation, either version 2 of the
566 + * License, or (at your option) any later version.
567 + *
568 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
569 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
570 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
571 + * the GNU General Public License for more details.
572 + *
573 + * You should have received a copy of the GNU General Public License
574 + * along with the Ubicom32 Linux Kernel Port.  If not, 
575 + * see <http://www.gnu.org/licenses/>.
576 + *
577 + * Ubicom32 implementation derived from (with many thanks):
578 + *   arch/m68knommu
579 + *   arch/blackfin
580 + *   arch/parisc
581 + */
582 +#ifndef _CRYPTO_ARCH_UBICOM32_CRYPT_H
583 +#define _CRYPTO_ARCH_UBICOM32_CRYPT_H
584 +
585 +#include <linux/module.h>
586 +#include <linux/kernel.h>
587 +#include <linux/jiffies.h>
588 +#include <linux/timer.h>
589 +#include <linux/spinlock.h>
590 +#include <asm/errno.h>
591 +#include <asm/io.h>
592 +#include <asm/ip5000.h>
593 +
594 +#define CRYPTO_UBICOM32_LOOP_ASM 1
595 +#define CRYPTO_UBICOM32_ALIGNMENT 4
596 +#define SEC_ALIGNED(p) (((u32)p & 3) == 0)
597 +
598 +#define SEC_BASE               SECURITY_BASE
599 +#define SEC_KEY_OFFSET         SECURITY_KEY_VALUE(0)
600 +#define SEC_INPUT_OFFSET       SECURITY_KEY_IN(0)
601 +#define SEC_OUTPUT_OFFSET      SECURITY_KEY_OUT(0)
602 +#define SEC_HASH_OFFSET                SECURITY_KEY_HASH(0)
603 +
604 +#define SEC_KEY_128_BITS       SECURITY_CTRL_KEY_SIZE(0)
605 +#define SEC_KEY_192_BITS       SECURITY_CTRL_KEY_SIZE(1)
606 +#define SEC_KEY_256_BITS       SECURITY_CTRL_KEY_SIZE(2)
607 +
608 +#define SEC_HASH_NONE          SECURITY_CTRL_HASH_ALG_NONE
609 +#define SEC_HASH_MD5           SECURITY_CTRL_HASH_ALG_MD5
610 +#define SEC_HASH_SHA1          SECURITY_CTRL_HASH_ALG_SHA1
611 +
612 +#define SEC_CBC_SET            SECURITY_CTRL_CBC
613 +#define SEC_CBC_NONE           0
614 +
615 +#define SEC_ALG_AES            SECURITY_CTRL_CIPHER_ALG_AES
616 +#define SEC_ALG_NONE           SECURITY_CTRL_CIPHER_ALG_NONE
617 +#define SEC_ALG_DES            SECURITY_CTRL_CIPHER_ALG_DES
618 +#define SEC_ALG_3DES           SECURITY_CTRL_CIPHER_ALG_3DES
619 +
620 +#define SEC_DIR_ENCRYPT                SECURITY_CTRL_ENCIPHER
621 +#define SEC_DIR_DECRYPT                0
622 +
623 +#define CRYPTO_UBICOM32_PRIORITY 300
624 +#define CRYPTO_UBICOM32_COMPOSITE_PRIORITY 400
625 +
626 +#define HW_CRYPTO_PS_MAX_IDLE_MS 100    /* idle time (ms) before shuting down sm */
627 +
628 +extern spinlock_t crypto_ubicom32_lock;
629 +extern bool crypto_ubicom32_inited;
630 +extern volatile bool crypto_ubicom32_on;
631 +extern volatile unsigned long crypto_ubicom32_last_use;
632 +extern struct timer_list crypto_ubicom32_ps_timer;
633 +extern void crypto_ubicom32_ps_check(unsigned long data);
634 +
635 +#define SEC_COPY_2W(t, s)                              \
636 +       asm volatile (                                  \
637 +       "       move.4 0(%0), 0(%1)             \n\t"   \
638 +       "       move.4 4(%0), 4(%1)             \n\t"   \
639 +                                                       \
640 +               :                                       \
641 +               : "a" (t), "a" (s)                      \
642 +       )
643 +
644 +#define SEC_COPY_4W(t, s)                              \
645 +       asm volatile (                                  \
646 +       "       move.4 0(%0), 0(%1)             \n\t"   \
647 +       "       move.4 4(%0), 4(%1)             \n\t"   \
648 +       "       move.4 8(%0), 8(%1)             \n\t"   \
649 +       "       move.4 12(%0), 12(%1)           \n\t"   \
650 +               :                                       \
651 +               : "a" (t), "a" (s)                      \
652 +       )
653 +
654 +#define SEC_COPY_5W(t, s)                              \
655 +       asm volatile (                                  \
656 +       "       move.4 0(%0), 0(%1)             \n\t"   \
657 +       "       move.4 4(%0), 4(%1)             \n\t"   \
658 +       "       move.4 8(%0), 8(%1)             \n\t"   \
659 +       "       move.4 12(%0), 12(%1)           \n\t"   \
660 +       "       move.4 16(%0), 16(%1)           \n\t"   \
661 +               :                                       \
662 +               : "a" (t), "a" (s)                      \
663 +       )
664 +
665 +#define SEC_SET_KEY_2W(x)                              \
666 +       asm volatile (                                  \
667 +       "       ; write key to Security Keyblock \n\t"  \
668 +       "       move.4 0x10(%0), 0(%1)          \n\t"   \
669 +       "       move.4 0x14(%0), 4(%1)          \n\t"   \
670 +               :                                       \
671 +               : "a" (SECURITY_BASE), "a" (x)          \
672 +       )
673 +
674 +#define SEC_SET_KEY_4W(x) \
675 +       asm volatile ( \
676 +       "       ; write key to Security Keyblock \n\t"  \
677 +       "       move.4 0x10(%0), 0(%1)          \n\t"   \
678 +       "       move.4 0x14(%0), 4(%1)          \n\t"   \
679 +       "       move.4 0x18(%0), 8(%1)          \n\t"   \
680 +       "       move.4 0x1c(%0), 12(%1)         \n\t"   \
681 +               :                                       \
682 +               : "a"(SECURITY_BASE), "a"(x)            \
683 +       )
684 +
685 +#define SEC_SET_KEY_6W(x)                              \
686 +       asm volatile (                                  \
687 +       "       ; write key to Security Keyblock \n\t"  \
688 +       "       move.4 0x10(%0), 0(%1)          \n\t"   \
689 +       "       move.4 0x14(%0), 4(%1)          \n\t"   \
690 +       "       move.4 0x18(%0), 8(%1)          \n\t"   \
691 +       "       move.4 0x1c(%0), 12(%1)         \n\t"   \
692 +       "       move.4 0x20(%0), 16(%1)         \n\t"   \
693 +       "       move.4 0x24(%0), 20(%1)         \n\t"   \
694 +               :                                       \
695 +               : "a" (SECURITY_BASE), "a" (x)          \
696 +       )
697 +
698 +#define SEC_SET_KEY_8W(x)                              \
699 +       asm volatile (                                  \
700 +       "       ; write key to Security Keyblock \n\t"  \
701 +       "       move.4 0x10(%0), 0(%1)          \n\t"   \
702 +       "       move.4 0x14(%0), 4(%1)          \n\t"   \
703 +       "       move.4 0x18(%0), 8(%1)          \n\t"   \
704 +       "       move.4 0x1c(%0), 12(%1)         \n\t"   \
705 +       "       move.4 0x20(%0), 16(%1)         \n\t"   \
706 +       "       move.4 0x24(%0), 20(%1)         \n\t"   \
707 +       "       move.4 0x28(%0), 24(%1)         \n\t"   \
708 +       "       move.4 0x2c(%0), 28(%1)         \n\t"   \
709 +               :                                       \
710 +               : "a" (SECURITY_BASE), "a" (x)          \
711 +       )
712 +
713 +#define SEC_SET_KEY_64(k)      SEC_SET_KEY_2W(k)
714 +#define SEC_SET_KEY_128(k)     SEC_SET_KEY_4W(k)
715 +#define SEC_SET_KEY_192(k)     SEC_SET_KEY_6W(k)
716 +#define SEC_SET_KEY_256(k)     SEC_SET_KEY_8W(k)
717 +
718 +#define DES_SET_KEY(x)                 SEC_SET_KEY_64(x) 
719 +#define DES3_SET_KEY(x)        SEC_SET_KEY_192(x)
720 +
721 +#define SEC_SET_INPUT_2W(x)                            \
722 +       asm volatile (                                  \
723 +       "       ; write key to Security Keyblock \n\t"  \
724 +       "       move.4 0x30(%0), 0(%1)          \n\t"   \
725 +       "       move.4 0x34(%0), 4(%1)          \n\t"   \
726 +               :                                       \
727 +               : "a" (SECURITY_BASE), "a" (x)          \
728 +       )
729 +
730 +#define SEC_GET_OUTPUT_2W(x)                           \
731 +       asm volatile (                                  \
732 +       "       ; write key to Security Keyblock \n\t"  \
733 +       "       move.4 0(%1), 0x50(%0)          \n\t"   \
734 +       "       move.4 4(%1), 0x54(%0)          \n\t"   \
735 +               :                                       \
736 +               : "a" (SECURITY_BASE), "a" (x)          \
737 +       )
738 +
739 +#define SEC_SET_INPUT_4W(x) \
740 +       asm volatile ( \
741 +       "       ; write key to Security Keyblock \n\t"  \
742 +       "       move.4 0x30(%0), 0(%1)          \n\t"   \
743 +       "       move.4 0x34(%0), 4(%1)          \n\t"   \
744 +       "       move.4 0x38(%0), 8(%1)          \n\t"   \
745 +       "       move.4 0x3c(%0), 12(%1)         \n\t"   \
746 +               :                                       \
747 +               : "a" (SECURITY_BASE), "a" (x)          \
748 +       )
749 +
750 +#define SEC_GET_OUTPUT_4W(x)                           \
751 +       asm volatile (                                  \
752 +       "       ; read output from Security Keyblock \n\t" \
753 +       "       move.4 0(%1), 0x50(%0)          \n\t"   \
754 +       "       move.4 4(%1), 0x54(%0)          \n\t"   \
755 +       "       move.4 8(%1), 0x58(%0)          \n\t"   \
756 +       "       move.4 12(%1), 0x5c(%0)         \n\t"   \
757 +               :                                       \
758 +               : "a" (SECURITY_BASE), "a" (x)          \
759 +       )
760 +
761 +#define SEC_SET_IV_4W(x)                               \
762 +       asm volatile (                                  \
763 +       "       ; write IV to Security Keyblock  \n\t"  \
764 +       "       move.4 0x50(%0), 0(%1)          \n\t"   \
765 +       "       move.4 0x54(%0), 4(%1)          \n\t"   \
766 +       "       move.4 0x58(%0), 8(%1)          \n\t"   \
767 +       "       move.4 0x5c(%0), 12(%1)         \n\t"   \
768 +               :                                       \
769 +               : "a" (SECURITY_BASE), "a" (x)          \
770 +       )
771 +
772 +#define SEC_PIPE_FLUSH() asm volatile ( " pipe_flush 0 \n\t" )
773 +
774 +static inline void hw_crypto_set_ctrl(uint32_t c)
775 +{
776 +       asm volatile (                                  
777 +       "       move.4  0(%0), %1               \n\t"   
778 +               :                                       
779 +               : "a" (SECURITY_BASE + SECURITY_CTRL), "d" (c)  
780 +       );
781 +}
782 +
783 +static inline void hw_crypto_ps_start(void)
784 +{
785 +       crypto_ubicom32_ps_timer.expires = jiffies + msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS >> 1);
786 +       add_timer(&crypto_ubicom32_ps_timer);
787 +}
788 +
789 +static inline void hw_crypto_turn_on(void)
790 +{
791 +       asm volatile (                            
792 +       "       moveai  A4, %0                  \n\t" 
793 +       "       bset    0x0(A4), 0x0(A4), %1    \n\t"
794 +       "       cycles 11                       \n\t" 
795 +               :                                               
796 +               : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO) 
797 +               : "a4", "cc"
798 +       );
799 +       crypto_ubicom32_on = true;
800 +}
801 +
802 +static inline void hw_crypto_turn_off(void)
803 +{
804 +       asm volatile (                            
805 +       "       moveai  A4, %0                  \n\t" 
806 +       "       bclr    0x0(A4), 0x0(A4), %1    \n\t" 
807 +               :                                               
808 +               : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)    
809 +               : "a4", "cc"
810 +       );
811 +       crypto_ubicom32_on = false;
812 +}
813 +
814 +/*
815 + * hw_crypto_check
816 + *     Most probably hw crypto is called in clusters and it makes no sense to turn it off
817 + *     and on and waster 13 cycles every time.
818 + */
819 +static inline void hw_crypto_check(void)
820 +{
821 +       if (likely(crypto_ubicom32_on)) {
822 +               return;
823 +       }
824 +       crypto_ubicom32_last_use = jiffies;
825 +       hw_crypto_turn_on();
826 +       hw_crypto_ps_start();
827 +}
828 +
829 +/*
830 + * hw_crypto_ps_init
831 + *     Init power save timer
832 + */
833 +static inline void hw_crypto_ps_init(void)
834 +{
835 +       init_timer_deferrable(&crypto_ubicom32_ps_timer);
836 +       crypto_ubicom32_ps_timer.function = crypto_ubicom32_ps_check;
837 +       crypto_ubicom32_ps_timer.data = 0;
838 +}
839 +
840 +/*
841 + * hw_crypto_init()
842 + *      Initialize OCP security module lock and disables its clock.
843 + */
844 +static inline void hw_crypto_init(void)
845 +{
846 +       if (!crypto_ubicom32_inited) {
847 +               crypto_ubicom32_inited = true;
848 +               spin_lock_init(&crypto_ubicom32_lock);
849 +               hw_crypto_ps_init();
850 +               hw_crypto_turn_off();
851 +       }
852 +}
853 +
854 +/*
855 + * hw_crypto_lock()
856 + *      Locks the OCP security module and enables its clock.
857 + */
858 +static inline void hw_crypto_lock(void)
859 +{
860 +       spin_lock_bh(&crypto_ubicom32_lock);
861 +}
862 +
863 +/*
864 + * hw_crypto_unlock()
865 + *      Unlocks the OCP security module and disables its clock.
866 + */
867 +static inline void hw_crypto_unlock(void)
868 +{
869 +       crypto_ubicom32_last_use = jiffies;
870 +       spin_unlock_bh(&crypto_ubicom32_lock);
871 +}
872 +
873 +#define CONFIG_CRYPTO_UBICOM32_DEBUG 1
874 +
875 +#ifdef CONFIG_CRYPTO_UBICOM32_DEBUG
876 +static inline void hex_dump(void *buf, int b_size, const char *msg)
877 +{
878 +       u8 *b = (u8 *)buf;
879 +       int i;
880 +       if (msg) {
881 +               printk("%s:\t", msg);
882 +       }
883 +
884 +       for (i=0; i < b_size; i++) {
885 +               printk("%02x ", b[i]);
886 +               if ((i & 3) == 3) {
887 +                       printk(" ");
888 +               }
889 +               if ((i & 31) == 31) {
890 +                       printk("\n");
891 +               }
892 +       }
893 +       printk("\n");
894 +}
895 +#define UBICOM32_SEC_DUMP(a, b, c) hex_dump(a, b, c)
896 +#else
897 +#define UBICOM32_SEC_DUMP(a, b, c)
898 +#endif
899 +
900 +#endif /* _CRYPTO_ARCH_UBICOM32_CRYPT_H */
901 --- /dev/null
902 +++ b/arch/ubicom32/crypto/des_check_key.c
903 @@ -0,0 +1,148 @@
904 +/*
905 + * arch/ubicom32/crypto/des_check_key.c
906 + *   Ubicom32 architecture function for checking keys for the DES and
907 + *   Tripple DES Encryption algorithms.
908 + *
909 + * (C) Copyright 2009, Ubicom, Inc.
910 + *
911 + * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
912 + * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
913 + * Derived from Cryptoapi and Nettle implementations, adapted for in-place
914 + * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
915 + *
916 + * s390 Version:
917 + *   Copyright IBM Corp. 2003
918 + *   Author(s): Thomas Spatzier
919 + *             Jan Glauber (jan.glauber@de.ibm.com)
920 + *
921 + * Derived from "crypto/des.c"
922 + *   Copyright (c) 1992 Dana L. How.
923 + *   Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
924 + *   Copyright (c) Gisle Sflensminde <gisle@ii.uib.no>
925 + *   Copyright (C) 2001 Niels Mvller.
926 + *   Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
927 + *
928 + * This file is part of the Ubicom32 Linux Kernel Port.
929 + *
930 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
931 + * it and/or modify it under the terms of the GNU General Public License
932 + * as published by the Free Software Foundation, either version 2 of the
933 + * License, or (at your option) any later version.
934 + *
935 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
936 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
937 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
938 + * the GNU General Public License for more details.
939 + *
940 + * You should have received a copy of the GNU General Public License
941 + * along with the Ubicom32 Linux Kernel Port.  If not, 
942 + * see <http://www.gnu.org/licenses/>.
943 + *
944 + * Ubicom32 implementation derived from (with many thanks):
945 + *   arch/m68knommu
946 + *   arch/blackfin
947 + *   arch/parisc
948 + */
949 +#include <linux/init.h>
950 +#include <linux/module.h>
951 +#include <linux/errno.h>
952 +#include <linux/crypto.h>
953 +#include "crypto_des.h"
954 +
955 +#define ROR(d,c,o)     ((d) = (d) >> (c) | (d) << (o))
956 +
957 +static const u8 parity[] = {
958 +       8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
959 +       0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
960 +       0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
961 +       8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
962 +       0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
963 +       8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
964 +       8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
965 +       4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
966 +};
967 +
968 +/*
969 + * RFC2451: Weak key checks SHOULD be performed.
970 + */
971 +int
972 +crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags)
973 +{
974 +       u32 n, w;
975 +
976 +       n  = parity[key[0]]; n <<= 4;
977 +       n |= parity[key[1]]; n <<= 4;
978 +       n |= parity[key[2]]; n <<= 4;
979 +       n |= parity[key[3]]; n <<= 4;
980 +       n |= parity[key[4]]; n <<= 4;
981 +       n |= parity[key[5]]; n <<= 4;
982 +       n |= parity[key[6]]; n <<= 4;
983 +       n |= parity[key[7]];
984 +       w = 0x88888888L;
985 +
986 +       if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
987 +           && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
988 +               if (n < 0x41415151) {
989 +                       if (n < 0x31312121) {
990 +                               if (n < 0x14141515) {
991 +                                       /* 01 01 01 01 01 01 01 01 */
992 +                                       if (n == 0x11111111) goto weak;
993 +                                       /* 01 1F 01 1F 01 0E 01 0E */
994 +                                       if (n == 0x13131212) goto weak;
995 +                               } else {
996 +                                       /* 01 E0 01 E0 01 F1 01 F1 */
997 +                                       if (n == 0x14141515) goto weak;
998 +                                       /* 01 FE 01 FE 01 FE 01 FE */
999 +                                       if (n == 0x16161616) goto weak;
1000 +                               }
1001 +                       } else {
1002 +                               if (n < 0x34342525) {
1003 +                                       /* 1F 01 1F 01 0E 01 0E 01 */
1004 +                                       if (n == 0x31312121) goto weak;
1005 +                                       /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
1006 +                                       if (n == 0x33332222) goto weak;
1007 +                               } else {
1008 +                                       /* 1F E0 1F E0 0E F1 0E F1 */
1009 +                                       if (n == 0x34342525) goto weak;
1010 +                                       /* 1F FE 1F FE 0E FE 0E FE */
1011 +                                       if (n == 0x36362626) goto weak;
1012 +                               }
1013 +                       }
1014 +               } else {
1015 +                       if (n < 0x61616161) {
1016 +                               if (n < 0x44445555) {
1017 +                                       /* E0 01 E0 01 F1 01 F1 01 */
1018 +                                       if (n == 0x41415151) goto weak;
1019 +                                       /* E0 1F E0 1F F1 0E F1 0E */
1020 +                                       if (n == 0x43435252) goto weak;
1021 +                               } else {
1022 +                                       /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
1023 +                                       if (n == 0x44445555) goto weak;
1024 +                                       /* E0 FE E0 FE F1 FE F1 FE */
1025 +                                       if (n == 0x46465656) goto weak;
1026 +                               }
1027 +                       } else {
1028 +                               if (n < 0x64646565) {
1029 +                                       /* FE 01 FE 01 FE 01 FE 01 */
1030 +                                       if (n == 0x61616161) goto weak;
1031 +                                       /* FE 1F FE 1F FE 0E FE 0E */
1032 +                                       if (n == 0x63636262) goto weak;
1033 +                               } else {
1034 +                                       /* FE E0 FE E0 FE F1 FE F1 */
1035 +                                       if (n == 0x64646565) goto weak;
1036 +                                       /* FE FE FE FE FE FE FE FE */
1037 +                                       if (n == 0x66666666) goto weak;
1038 +                               }
1039 +                       }
1040 +               }
1041 +       }
1042 +       return 0;
1043 +weak:
1044 +       *flags |= CRYPTO_TFM_RES_WEAK_KEY;
1045 +       return -EINVAL;
1046 +}
1047 +
1048 +EXPORT_SYMBOL(crypto_des_check_key);
1049 +
1050 +MODULE_LICENSE("GPL");
1051 +MODULE_DESCRIPTION("Key Check function for DES &  DES3 Cipher Algorithms");
1052 --- /dev/null
1053 +++ b/arch/ubicom32/crypto/des_ubicom32.c
1054 @@ -0,0 +1,761 @@
1055 +/*
1056 + * arch/ubicom32/crypto/des_ubicom32.c
1057 + *   Ubicom32 implementation of the DES Cipher Algorithm.
1058 + *
1059 + * (C) Copyright 2009, Ubicom, Inc.
1060 + *
1061 + * This file is part of the Ubicom32 Linux Kernel Port.
1062 + *
1063 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
1064 + * it and/or modify it under the terms of the GNU General Public License
1065 + * as published by the Free Software Foundation, either version 2 of the
1066 + * License, or (at your option) any later version.
1067 + *
1068 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
1069 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
1070 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
1071 + * the GNU General Public License for more details.
1072 + *
1073 + * You should have received a copy of the GNU General Public License
1074 + * along with the Ubicom32 Linux Kernel Port.  If not, 
1075 + * see <http://www.gnu.org/licenses/>.
1076 + *
1077 + * Ubicom32 implementation derived from (with many thanks):
1078 + *   arch/m68knommu
1079 + *   arch/blackfin
1080 + *   arch/parisc
1081 + */
1082 +#include <crypto/algapi.h>
1083 +#include <linux/init.h>
1084 +#include <linux/module.h>
1085 +
1086 +#include "crypto_ubicom32.h"
1087 +extern int crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags);
1088 +
1089 +#define DES_BLOCK_SIZE 8
1090 +#define DES_KEY_SIZE 8
1091 +
1092 +#define DES3_192_KEY_SIZE      (3 * DES_KEY_SIZE)
1093 +#define DES3_192_BLOCK_SIZE    DES_BLOCK_SIZE
1094 +
1095 +#define DES3_SUB_KEY(key, i)   (((u8 *)key) + (i * DES_KEY_SIZE))
1096 +
1097 +enum des_ops {
1098 +       DES_ENCRYPT,
1099 +       DES_DECRYPT,
1100 +
1101 +       DES3_EDE_ENCRYPT,
1102 +       DES3_EDE_DECRYPT,
1103 +
1104 +#ifdef DES3_EEE
1105 +       DES3_EEE_ENCRYPT,
1106 +       DES3_EEE_DECRYPT,
1107 +#endif
1108 +};
1109 +
1110 +struct ubicom32_des_ctx {
1111 +       u8 key[3 * DES_KEY_SIZE];
1112 +       u32 ctrl;
1113 +       int key_len;
1114 +};
1115 +
1116 +static inline void des_hw_set_key(const u8 *key, u8 key_len)
1117 +{
1118 +       /*
1119 +        * HW 3DES is not tested yet, use DES just as ipOS
1120 +        */
1121 +       DES_SET_KEY(key);
1122 +}
1123 +
1124 +static inline void des_hw_cipher(u8 *out, const u8 *in)
1125 +{
1126 +       SEC_SET_INPUT_2W(in);
1127 +
1128 +       asm volatile (
1129 +       "       ; start DES by writing 0x38(SECURITY_BASE)      \n\t" 
1130 +       "       move.4 0x38(%0), #0x01                          \n\t" 
1131 +       "       pipe_flush 0                                    \n\t" 
1132 +       "                                                       \n\t" 
1133 +       "       ; wait for the module to calculate the output   \n\t" 
1134 +       "       btst 0x04(%0), #0                               \n\t" 
1135 +       "       jmpne.f .-4                                     \n\t" 
1136 +               :
1137 +               : "a" (SEC_BASE)
1138 +               : "cc"
1139 +       );
1140 +       
1141 +       SEC_GET_OUTPUT_2W(out);
1142 +}
1143 +
1144 +
1145 +static void inline des3_hw_ede_encrypt(u8 *keys, u8 *out, const u8 *in)
1146 +{
1147 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1148 +       des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
1149 +       des_hw_cipher(out, in);
1150 +
1151 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1152 +       des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
1153 +       des_hw_cipher(out, out);
1154 +
1155 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1156 +       des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
1157 +       des_hw_cipher(out, out);
1158 +}
1159 +
1160 +static void inline des3_hw_ede_decrypt(u8 *keys, u8 *out, const u8 *in)
1161 +{
1162 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1163 +       des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
1164 +       des_hw_cipher(out, in);
1165 +
1166 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1167 +       des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
1168 +       des_hw_cipher(out, out);
1169 +
1170 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1171 +       des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
1172 +       des_hw_cipher(out, out);
1173 +}
1174 +
1175 +#ifdef DES3_EEE
1176 +static void inline des3_hw_eee_encrypt(u8 *keys, u8 *out, const u8 *in)
1177 +{
1178 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1179 +       des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
1180 +       des_hw_cipher(out, in);
1181 +
1182 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1183 +       des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
1184 +       des_hw_cipher(out, out);
1185 +
1186 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1187 +       des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
1188 +       des_hw_cipher(out, out);
1189 +}
1190 +
1191 +static void inline des3_hw_eee_decrypt(u8 *keys, u8 *out, const u8 *in)
1192 +{
1193 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1194 +       des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
1195 +       des_hw_cipher(out, in);
1196 +
1197 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1198 +       des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
1199 +       des_hw_cipher(out, out);
1200 +
1201 +       hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1202 +       des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
1203 +       des_hw_cipher(out, out);
1204 +}
1205 +#endif
1206 +
1207 +static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
1208 +                     unsigned int keylen)
1209 +{
1210 +       struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
1211 +       u32 *flags = &tfm->crt_flags;
1212 +       int ret;
1213 +
1214 +       /* test if key is valid (not a weak key) */
1215 +       ret = crypto_des_check_key(key, keylen, flags);
1216 +       if (ret == 0) {
1217 +               memcpy(dctx->key, key, keylen);
1218 +               dctx->key_len = keylen;
1219 +               //dctx->ctrl = (keylen == DES_KEY_SIZE) ? SEC_ALG_DES : SEC_ALG_3DES
1220 +               /* 2DES and 3DES are both implemented with DES hw function */
1221 +               dctx->ctrl = SEC_ALG_DES;
1222 +       }
1223 +       return ret;
1224 +}
1225 +
1226 +static inline void des_cipher_1b(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
1227 +{
1228 +       const struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1229 +
1230 +       hw_crypto_lock();
1231 +       hw_crypto_check();
1232 +       hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
1233 +
1234 +       des_hw_set_key(uctx->key, uctx->key_len);
1235 +       des_hw_cipher(out, in);
1236 +
1237 +       hw_crypto_unlock();     
1238 +}
1239 +
1240 +static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1241 +{
1242 +       des_cipher_1b(tfm, out, in, SEC_DIR_ENCRYPT);
1243 +}
1244 +
1245 +static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1246 +{
1247 +       des_cipher_1b(tfm, out, in, SEC_DIR_DECRYPT);
1248 +}
1249 +
1250 +static struct crypto_alg des_alg = {
1251 +       .cra_name               =       "des",
1252 +       .cra_driver_name        =       "des-ubicom32",
1253 +       .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
1254 +       .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
1255 +       .cra_blocksize          =       DES_BLOCK_SIZE,
1256 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1257 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1258 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1259 +       .cra_module             =       THIS_MODULE,
1260 +       .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
1261 +       .cra_u                  = {
1262 +               .cipher = {
1263 +                       .cia_min_keysize        =       DES_KEY_SIZE,
1264 +                       .cia_max_keysize        =       DES_KEY_SIZE,
1265 +                       .cia_setkey             =       des_setkey,
1266 +                       .cia_encrypt            =       des_encrypt,
1267 +                       .cia_decrypt            =       des_decrypt,
1268 +               }
1269 +       }
1270 +};
1271 +
1272 +static void ecb_des_ciper_loop(u8 *out, u8 *in, unsigned int n)
1273 +{
1274 +       while (likely(n)) {
1275 +               des_hw_cipher(out, in);
1276 +               out += DES_BLOCK_SIZE;
1277 +               in += DES_BLOCK_SIZE;
1278 +               n -= DES_BLOCK_SIZE;
1279 +       }
1280 +}
1281 +
1282 +static void ecb_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1283 +{
1284 +       while (likely(n)) {
1285 +               des3_hw_ede_encrypt(keys, out, in);
1286 +               
1287 +               out += DES_BLOCK_SIZE;
1288 +               in += DES_BLOCK_SIZE;
1289 +               n -= DES_BLOCK_SIZE;
1290 +       }
1291 +}
1292 +
1293 +static void ecb_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1294 +{
1295 +       while (likely(n)) {
1296 +               des3_hw_ede_decrypt(keys, out, in);
1297 +
1298 +               out += DES_BLOCK_SIZE;
1299 +               in += DES_BLOCK_SIZE;
1300 +               n -= DES_BLOCK_SIZE;
1301 +       }
1302 +}
1303 +
1304 +#ifdef DES3_EEE
1305 +static void ecb_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1306 +{
1307 +       while (likely(n)) {
1308 +               des3_hw_eee_encrypt(keys, out, in);
1309 +
1310 +               out += DES_BLOCK_SIZE;
1311 +               in += DES_BLOCK_SIZE;
1312 +               n -= DES_BLOCK_SIZE;
1313 +       }
1314 +}
1315 +
1316 +static void ecb_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1317 +{
1318 +       while (likely(n)) {
1319 +               des3_hw_eee_decrypt(keys, out, in);
1320 +
1321 +               out += DES_BLOCK_SIZE;
1322 +               in += DES_BLOCK_SIZE;
1323 +               n -= DES_BLOCK_SIZE;
1324 +       }
1325 +}
1326 +#endif
1327 +
1328 +static inline void ecb_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, unsigned int n)
1329 +{
1330 +       switch (op) {
1331 +       case DES_ENCRYPT:
1332 +       case DES_DECRYPT:
1333 +               /* set the right algo, direction and key once */
1334 +               hw_crypto_set_ctrl(SEC_ALG_DES | (op == DES_ENCRYPT ? SEC_DIR_ENCRYPT : 0));
1335 +               des_hw_set_key(uctx->key, uctx->key_len);
1336 +               ecb_des_ciper_loop(out, in, n);
1337 +               break;
1338 +
1339 +       case DES3_EDE_ENCRYPT:
1340 +               ecb_des3_ede_encrypt_loop(uctx->key, out, in, n);
1341 +               break;
1342 +
1343 +       case DES3_EDE_DECRYPT:
1344 +               ecb_des3_ede_decrypt_loop(uctx->key, out, in, n);
1345 +               break;
1346 +
1347 +#ifdef DES3_EEE
1348 +       case DES3_EEE_ENCRYPT:
1349 +               ecb_des3_eee_encrypt_loop(uctx->key, out, in, n);
1350 +               break;
1351 +
1352 +       case DES3_EEE_DECRYPT:
1353 +               ecb_des3_eee_decrypt_loop(uctx->key, out, in, n);
1354 +               break;
1355 +#endif
1356 +       }
1357 +}
1358 +
1359 +static inline void des_xor_2w(u32 *data, u32 *iv)
1360 +{
1361 +       data[0] ^= iv[0];
1362 +       data[1] ^= iv[1];
1363 +}
1364 +
1365 +static void cbc_des_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
1366 +{
1367 +       while (likely(n)) {
1368 +               des_xor_2w((u32 *)in, (u32 *)iv);
1369 +               des_hw_cipher(out, in);
1370 +               SEC_COPY_2W(iv, out);
1371 +               out += DES_BLOCK_SIZE;
1372 +               in += DES_BLOCK_SIZE;
1373 +               n -= DES_BLOCK_SIZE;
1374 +       }
1375 +}
1376 +
1377 +static void cbc_des_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
1378 +{
1379 +       u8 next_iv[DES_BLOCK_SIZE];
1380 +       while (likely(n)) {
1381 +               SEC_COPY_2W(next_iv, in);
1382 +               des_hw_cipher(out, in);
1383 +               des_xor_2w((u32 *)out, (u32 *)iv);
1384 +               SEC_COPY_2W(iv, next_iv);
1385 +
1386 +               out += DES_BLOCK_SIZE;
1387 +               in += DES_BLOCK_SIZE;
1388 +               n -= DES_BLOCK_SIZE;
1389 +       }
1390 +}
1391 +
1392 +static void cbc_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
1393 +{
1394 +       while (likely(n)) {
1395 +               des_xor_2w((u32 *)in, (u32 *)iv);
1396 +               des3_hw_ede_encrypt(keys, out, in);
1397 +               SEC_COPY_2W(iv, out);
1398 +
1399 +               out += DES_BLOCK_SIZE;
1400 +               in += DES_BLOCK_SIZE;
1401 +               n -= DES_BLOCK_SIZE;
1402 +       }
1403 +}
1404 +
1405 +static void cbc_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
1406 +{
1407 +       u8 next_iv[DES_BLOCK_SIZE];
1408 +       while (likely(n)) {
1409 +               SEC_COPY_2W(next_iv, in);
1410 +               des3_hw_ede_decrypt(keys, out, in);
1411 +               des_xor_2w((u32 *)out, (u32 *)iv);
1412 +               SEC_COPY_2W(iv, next_iv);
1413 +
1414 +               out += DES_BLOCK_SIZE;
1415 +               in += DES_BLOCK_SIZE;
1416 +               n -= DES_BLOCK_SIZE;
1417 +       }
1418 +}
1419 +
1420 +#ifdef DES3_EEE
1421 +static void cbc_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
1422 +{
1423 +       while (likely(n)) {
1424 +               des_xor_2w((u32 *)in, (u32 *)iv);
1425 +               des3_hw_eee_encrypt(keys, out, in);
1426 +               SEC_COPY_2W(iv, out);
1427 +
1428 +               out += DES_BLOCK_SIZE;
1429 +               in += DES_BLOCK_SIZE;
1430 +               n -= DES_BLOCK_SIZE;
1431 +       }
1432 +}
1433 +
1434 +static void cbc_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
1435 +{
1436 +       u8 next_iv[DES_BLOCK_SIZE];
1437 +       while (likely(n)) {
1438 +               SEC_COPY_2W(next_iv, in);
1439 +               des3_hw_eee_decrypt(keys, out, in);
1440 +               des_xor_2w((u32 *)out, (u32 *)iv);
1441 +               SEC_COPY_2W(iv, next_iv);
1442 +
1443 +               out += DES_BLOCK_SIZE;
1444 +               in += DES_BLOCK_SIZE;
1445 +               n -= DES_BLOCK_SIZE;
1446 +       }
1447 +}
1448 +#endif
1449 +
1450 +static inline void cbc_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, u8 *iv, unsigned int n)
1451 +{
1452 +       switch (op) {
1453 +       case DES_ENCRYPT:
1454 +               hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
1455 +               des_hw_set_key(uctx->key, uctx->key_len);
1456 +               cbc_des_encrypt_loop(out, in, iv, n);
1457 +               break;
1458 +               
1459 +       case DES_DECRYPT:
1460 +               /* set the right algo, direction and key once */
1461 +               hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
1462 +               des_hw_set_key(uctx->key, uctx->key_len);
1463 +               cbc_des_decrypt_loop(out, in, iv, n);
1464 +               break;
1465 +
1466 +       case DES3_EDE_ENCRYPT:
1467 +               cbc_des3_ede_encrypt_loop(uctx->key, out, in, iv, n);
1468 +               break;
1469 +
1470 +       case DES3_EDE_DECRYPT:
1471 +               cbc_des3_ede_decrypt_loop(uctx->key, out, in, iv, n);
1472 +               break;
1473 +
1474 +#ifdef DES3_EEE
1475 +       case DES3_EEE_ENCRYPT:
1476 +               cbc_des3_eee_encrypt_loop(uctx->key, out, in, iv, n);
1477 +               break;
1478 +
1479 +       case DES3_EEE_DECRYPT:
1480 +               cbc_des3_eee_decrypt_loop(uctx->key, out, in, iv, n);
1481 +               break;
1482 +#endif
1483 +       }
1484 +}
1485 +
1486 +static int des_cipher(struct blkcipher_desc *desc, struct scatterlist *dst, 
1487 +                     struct scatterlist *src, unsigned int nbytes, u32 extra_flags, enum des_ops op)
1488 +{
1489 +       struct ubicom32_des_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
1490 +       int ret;
1491 +       
1492 +       struct blkcipher_walk walk;
1493 +       blkcipher_walk_init(&walk, dst, src, nbytes);
1494 +       ret = blkcipher_walk_virt(desc, &walk);
1495 +       if (ret) {
1496 +               return ret;
1497 +       }
1498 +
1499 +       hw_crypto_lock();
1500 +       hw_crypto_check();
1501 +
1502 +       while ((nbytes = walk.nbytes)) {
1503 +               /* only use complete blocks */
1504 +               unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
1505 +               u8 *out = walk.dst.virt.addr;
1506 +               u8 *in = walk.src.virt.addr;
1507 +
1508 +               /* finish n/16 blocks */
1509 +               if (extra_flags & SEC_CBC_SET) {
1510 +                       cbc_des_cipher_n(uctx, op, out, in, walk.iv, n);
1511 +               } else {
1512 +                       ecb_des_cipher_n(uctx, op, out, in, n);
1513 +               }
1514 +
1515 +               nbytes &= DES_BLOCK_SIZE - 1;
1516 +               ret = blkcipher_walk_done(desc, &walk, nbytes);
1517 +       }
1518 +
1519 +       hw_crypto_unlock();
1520 +       return ret;
1521 +}
1522 +
1523 +static int ecb_des_encrypt(struct blkcipher_desc *desc,
1524 +                          struct scatterlist *dst, struct scatterlist *src,
1525 +                          unsigned int nbytes)
1526 +{
1527 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_ENCRYPT);
1528 +}
1529 +
1530 +static int ecb_des_decrypt(struct blkcipher_desc *desc,
1531 +                          struct scatterlist *dst, struct scatterlist *src,
1532 +                          unsigned int nbytes)
1533 +{
1534 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_DECRYPT);
1535 +}
1536 +
1537 +static struct crypto_alg ecb_des_alg = {
1538 +       .cra_name               =       "ecb(des)",
1539 +       .cra_driver_name        =       "ecb-des-ubicom32",
1540 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
1541 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
1542 +       .cra_blocksize          =       DES_BLOCK_SIZE,
1543 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1544 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1545 +       .cra_type               =       &crypto_blkcipher_type,
1546 +       .cra_module             =       THIS_MODULE,
1547 +       .cra_list               =       LIST_HEAD_INIT(ecb_des_alg.cra_list),
1548 +       .cra_u                  = {
1549 +               .blkcipher = {
1550 +                       .min_keysize            =       DES_KEY_SIZE,
1551 +                       .max_keysize            =       DES_KEY_SIZE,
1552 +                       .setkey                 =       des_setkey,
1553 +                       .encrypt                =       ecb_des_encrypt,
1554 +                       .decrypt                =       ecb_des_decrypt,
1555 +               }
1556 +       }
1557 +};
1558 +
1559 +static int cbc_des_encrypt(struct blkcipher_desc *desc,
1560 +                          struct scatterlist *dst, struct scatterlist *src,
1561 +                          unsigned int nbytes)
1562 +{
1563 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_ENCRYPT);
1564 +}
1565 +
1566 +static int cbc_des_decrypt(struct blkcipher_desc *desc,
1567 +                          struct scatterlist *dst, struct scatterlist *src,
1568 +                          unsigned int nbytes)
1569 +{
1570 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_DECRYPT);
1571 +}
1572 +
1573 +static struct crypto_alg cbc_des_alg = {
1574 +       .cra_name               =       "cbc(des)",
1575 +       .cra_driver_name        =       "cbc-des-ubicom32",
1576 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
1577 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
1578 +       .cra_blocksize          =       DES_BLOCK_SIZE,
1579 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1580 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1581 +       .cra_type               =       &crypto_blkcipher_type,
1582 +       .cra_module             =       THIS_MODULE,
1583 +       .cra_list               =       LIST_HEAD_INIT(cbc_des_alg.cra_list),
1584 +       .cra_u                  = {
1585 +               .blkcipher = {
1586 +                       .min_keysize            =       DES_KEY_SIZE,
1587 +                       .max_keysize            =       DES_KEY_SIZE,
1588 +                       .ivsize                 =       DES_BLOCK_SIZE,
1589 +                       .setkey                 =       des_setkey,
1590 +                       .encrypt                =       cbc_des_encrypt,
1591 +                       .decrypt                =       cbc_des_decrypt,
1592 +               }
1593 +       }
1594 +};
1595 +
1596 +/*
1597 + * RFC2451:
1598 + *
1599 + *   For DES-EDE3, there is no known need to reject weak or
1600 + *   complementation keys.  Any weakness is obviated by the use of
1601 + *   multiple keys.
1602 + *
1603 + *   However, if the first two or last two independent 64-bit keys are
1604 + *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
1605 + *   same as DES.  Implementers MUST reject keys that exhibit this
1606 + *   property.
1607 + *
1608 + */
1609 +static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
1610 +                          unsigned int keylen)
1611 +{
1612 +       int i, ret;
1613 +       struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
1614 +       const u8 *temp_key = key;
1615 +       u32 *flags = &tfm->crt_flags;
1616 +
1617 +       if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
1618 +           memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
1619 +                  DES_KEY_SIZE))) {
1620 +
1621 +               *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
1622 +               return -EINVAL;
1623 +       }
1624 +       for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
1625 +               ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
1626 +               if (ret < 0)
1627 +                       return ret;
1628 +       }
1629 +       memcpy(dctx->key, key, keylen);
1630 +       dctx->ctrl = SEC_ALG_DES;       //hw 3DES not working yet
1631 +       dctx->key_len = keylen;
1632 +       return 0;
1633 +}
1634 +
1635 +static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1636 +{
1637 +       struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1638 +
1639 +       hw_crypto_lock();
1640 +       hw_crypto_check();
1641 +
1642 +       des3_hw_ede_encrypt(uctx->key, dst, src);
1643 +
1644 +       hw_crypto_unlock();     
1645 +}
1646 +
1647 +static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1648 +{
1649 +       struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1650 +
1651 +       hw_crypto_lock();
1652 +       hw_crypto_check();
1653 +
1654 +       des3_hw_ede_decrypt(uctx->key, dst, src);
1655 +
1656 +       hw_crypto_unlock();     
1657 +}
1658 +
1659 +static struct crypto_alg des3_192_alg = {
1660 +       .cra_name               =       "des3_ede",
1661 +       .cra_driver_name        =       "des3_ede-ubicom32",
1662 +       .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
1663 +       .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
1664 +       .cra_blocksize          =       DES3_192_BLOCK_SIZE,
1665 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1666 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1667 +       .cra_module             =       THIS_MODULE,
1668 +       .cra_list               =       LIST_HEAD_INIT(des3_192_alg.cra_list),
1669 +       .cra_u                  = {
1670 +               .cipher = {
1671 +                       .cia_min_keysize        =       DES3_192_KEY_SIZE,
1672 +                       .cia_max_keysize        =       DES3_192_KEY_SIZE,
1673 +                       .cia_setkey             =       des3_192_setkey,
1674 +                       .cia_encrypt            =       des3_192_encrypt,
1675 +                       .cia_decrypt            =       des3_192_decrypt,
1676 +               }
1677 +       }
1678 +};
1679 +
1680 +static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
1681 +                               struct scatterlist *dst,
1682 +                               struct scatterlist *src, unsigned int nbytes)
1683 +{
1684 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_ENCRYPT);
1685 +}
1686 +
1687 +static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
1688 +                               struct scatterlist *dst,
1689 +                               struct scatterlist *src, unsigned int nbytes)
1690 +{
1691 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_DECRYPT);
1692 +}
1693 +
1694 +static struct crypto_alg ecb_des3_192_alg = {
1695 +       .cra_name               =       "ecb(des3_ede)",
1696 +       .cra_driver_name        =       "ecb-des3_ede-ubicom32",
1697 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
1698 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
1699 +       .cra_blocksize          =       DES3_192_BLOCK_SIZE,
1700 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1701 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1702 +       .cra_type               =       &crypto_blkcipher_type,
1703 +       .cra_module             =       THIS_MODULE,
1704 +       .cra_list               =       LIST_HEAD_INIT(
1705 +                                               ecb_des3_192_alg.cra_list),
1706 +       .cra_u                  = {
1707 +               .blkcipher = {
1708 +                       .min_keysize            =       DES3_192_KEY_SIZE,
1709 +                       .max_keysize            =       DES3_192_KEY_SIZE,
1710 +                       .setkey                 =       des3_192_setkey,
1711 +                       .encrypt                =       ecb_des3_192_encrypt,
1712 +                       .decrypt                =       ecb_des3_192_decrypt,
1713 +               }
1714 +       }
1715 +};
1716 +
1717 +static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
1718 +                               struct scatterlist *dst,
1719 +                               struct scatterlist *src, unsigned int nbytes)
1720 +{
1721 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_ENCRYPT);
1722 +}
1723 +
1724 +static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
1725 +                               struct scatterlist *dst,
1726 +                               struct scatterlist *src, unsigned int nbytes)
1727 +{
1728 +       return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_DECRYPT);
1729 +}
1730 +
1731 +static struct crypto_alg cbc_des3_192_alg = {
1732 +       .cra_name               =       "cbc(des3_ede)",
1733 +       .cra_driver_name        =       "cbc-des3_ede-ubicom32",
1734 +       .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
1735 +       .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
1736 +       .cra_blocksize          =       DES3_192_BLOCK_SIZE,
1737 +       .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
1738 +       .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
1739 +       .cra_type               =       &crypto_blkcipher_type,
1740 +       .cra_module             =       THIS_MODULE,
1741 +       .cra_list               =       LIST_HEAD_INIT(
1742 +                                               cbc_des3_192_alg.cra_list),
1743 +       .cra_u                  = {
1744 +               .blkcipher = {
1745 +                       .min_keysize            =       DES3_192_KEY_SIZE,
1746 +                       .max_keysize            =       DES3_192_KEY_SIZE,
1747 +                       .ivsize                 =       DES3_192_BLOCK_SIZE,
1748 +                       .setkey                 =       des3_192_setkey,
1749 +                       .encrypt                =       cbc_des3_192_encrypt,
1750 +                       .decrypt                =       cbc_des3_192_decrypt,
1751 +               }
1752 +       }
1753 +};
1754 +
1755 +static int init(void)
1756 +{
1757 +       int ret = 0;
1758 +
1759 +       hw_crypto_init();
1760 +
1761 +       ret = crypto_register_alg(&des_alg);
1762 +       if (ret)
1763 +               goto des_err;
1764 +       ret = crypto_register_alg(&ecb_des_alg);
1765 +       if (ret)
1766 +               goto ecb_des_err;
1767 +       ret = crypto_register_alg(&cbc_des_alg);
1768 +       if (ret)
1769 +               goto cbc_des_err;
1770 +
1771 +       ret = crypto_register_alg(&des3_192_alg);
1772 +       if (ret)
1773 +               goto des3_192_err;
1774 +       ret = crypto_register_alg(&ecb_des3_192_alg);
1775 +       if (ret)
1776 +               goto ecb_des3_192_err;
1777 +       ret = crypto_register_alg(&cbc_des3_192_alg);
1778 +       if (ret)
1779 +               goto cbc_des3_192_err;
1780 +
1781 +out:
1782 +       return ret;
1783 +
1784 +cbc_des3_192_err:
1785 +       crypto_unregister_alg(&ecb_des3_192_alg);
1786 +ecb_des3_192_err:
1787 +       crypto_unregister_alg(&des3_192_alg);
1788 +des3_192_err:
1789 +       crypto_unregister_alg(&cbc_des_alg);
1790 +cbc_des_err:
1791 +       crypto_unregister_alg(&ecb_des_alg);
1792 +ecb_des_err:
1793 +       crypto_unregister_alg(&des_alg);
1794 +des_err:
1795 +       goto out;
1796 +}
1797 +
1798 +static void __exit fini(void)
1799 +{
1800 +       crypto_unregister_alg(&cbc_des3_192_alg);
1801 +       crypto_unregister_alg(&ecb_des3_192_alg);
1802 +       crypto_unregister_alg(&des3_192_alg);
1803 +       crypto_unregister_alg(&cbc_des_alg);
1804 +       crypto_unregister_alg(&ecb_des_alg);
1805 +       crypto_unregister_alg(&des_alg);
1806 +}
1807 +
1808 +module_init(init);
1809 +module_exit(fini);
1810 +
1811 +MODULE_ALIAS("des");
1812 +MODULE_ALIAS("des3_ede");
1813 +
1814 +MODULE_LICENSE("GPL");
1815 +MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1816 --- /dev/null
1817 +++ b/arch/ubicom32/crypto/Makefile
1818 @@ -0,0 +1,36 @@
1819 +#
1820 +# arch/ubicom32/crypto/Makefile
1821 +#      <TODO: Replace with short file description>
1822 +#
1823 +# (C) Copyright 2009, Ubicom, Inc.
1824 +#
1825 +# This file is part of the Ubicom32 Linux Kernel Port.
1826 +#
1827 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
1828 +# it and/or modify it under the terms of the GNU General Public License
1829 +# as published by the Free Software Foundation, either version 2 of the
1830 +# License, or (at your option) any later version.
1831 +#
1832 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
1833 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
1834 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
1835 +# the GNU General Public License for more details.
1836 +#
1837 +# You should have received a copy of the GNU General Public License
1838 +# along with the Ubicom32 Linux Kernel Port.  If not, 
1839 +# see <http://www.gnu.org/licenses/>.
1840 +#
1841 +# Ubicom32 implementation derived from (with many thanks):
1842 +#   arch/m68knommu
1843 +#   arch/blackfin
1844 +#   arch/parisc
1845 +#
1846 +obj-$(CONFIG_CRYPTO_UBICOM32) += crypto_ubicom32.o
1847 +obj-$(CONFIG_CRYPTO_AES_UBICOM32) += aes_ubicom32.o
1848 +obj-$(CONFIG_CRYPTO_DES_UBICOM32) += des.o
1849 +obj-$(CONFIG_CRYPTO_MD5_UBICOM32) += md5.o
1850 +obj-$(CONFIG_CRYPTO_SHA1_UBICOM32) += sha1.o
1851 +
1852 +des-y := des_ubicom32.o des_check_key.o
1853 +md5-y := md5_ubicom32.o md5_ubicom32_asm.o
1854 +sha1-y := sha1_ubicom32.o 
1855 --- /dev/null
1856 +++ b/arch/ubicom32/crypto/md5_ubicom32_asm.S
1857 @@ -0,0 +1,235 @@
1858 +/*
1859 + * arch/ubicom32/crypto/md5_ubicom32_asm.S
1860 + *     MD5 (Message Digest 5) support for Ubicom32 v3 architecture
1861 + *
1862 + * (C) Copyright 2009, Ubicom, Inc.
1863 + *
1864 + * This file is part of the Ubicom32 Linux Kernel Port.
1865 + *
1866 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
1867 + * it and/or modify it under the terms of the GNU General Public License
1868 + * as published by the Free Software Foundation, either version 2 of the
1869 + * License, or (at your option) any later version.
1870 + *
1871 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
1872 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
1873 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
1874 + * the GNU General Public License for more details.
1875 + *
1876 + * You should have received a copy of the GNU General Public License
1877 + * along with the Ubicom32 Linux Kernel Port.  If not, 
1878 + * see <http://www.gnu.org/licenses/>.
1879 + *
1880 + * Ubicom32 implementation derived from (with many thanks):
1881 + *   arch/m68knommu
1882 + *   arch/blackfin
1883 + *   arch/parisc
1884 + */
1885 +
1886 +#define __ASM__
1887 +#include <asm/ip5000.h>
1888 +
1889 +#ifndef RP
1890 +#define RP A5
1891 +#endif
1892 +
1893 +;*****************************************************************************************
1894 +; The function prototypes
1895 +;*****************************************************************************************
1896 +; void md5_ip5k_init(void)
1897 +; void md5_ip5k_transform(u32_t *data_input)
1898 +; void md5_get_digest(u32_t *digest)
1899 +
1900 +;*****************************************************************************************
1901 +; Inputs
1902 +;*****************************************************************************************;
1903 +; data_input is the pointer to the block of data over which the digest will be calculated.
1904 +;      It should be word aligned.
1905 +;
1906 +; digest is the pointer to the block of data into which the digest (the output) will be written.
1907 +;      It should be word aligned.
1908 +;
1909 +
1910 +;*****************************************************************************************
1911 +; Outputs
1912 +;*****************************************************************************************
1913 +; None
1914 +
1915 +;*****************************************************************************************
1916 +; An: Address Registers
1917 +;*****************************************************************************************
1918 +#define an_digest A3
1919 +#define an_data_input A3
1920 +#define an_security_block A4
1921 +
1922 +;*****************************************************************************************
1923 +; Hash Constants
1924 +;*****************************************************************************************
1925 +#define HASH_MD5_IN0 0x01234567
1926 +#define HASH_MD5_IN1 0x89abcdef
1927 +#define HASH_MD5_IN2 0xfedcba98
1928 +#define HASH_MD5_IN3 0x76543210
1929 +
1930 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
1931 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_MD5 ((1 << 4) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
1932 +
1933 +;*****************************************************************************************
1934 +; Hash related defines
1935 +;*****************************************************************************************
1936 +#define hash_control 0x00(an_security_block)
1937 +#define hash_control_low 0x02(an_security_block)
1938 +#define hash_status 0x04(an_security_block)
1939 +
1940 +#define hash_input_0 0x30(an_security_block)
1941 +#define hash_input_1 0x34(an_security_block)
1942 +#define hash_input_2 0x38(an_security_block)
1943 +#define hash_input_3 0x3c(an_security_block)
1944 +#define hash_input_4 0x40(an_security_block)
1945 +
1946 +#define hash_output_0 0x70(an_security_block)
1947 +#define hash_output_0_low 0x72(an_security_block)
1948 +#define hash_output_1 0x74(an_security_block)
1949 +#define hash_output_1_low 0x76(an_security_block)
1950 +#define hash_output_2 0x78(an_security_block)
1951 +#define hash_output_2_low 0x7a(an_security_block)
1952 +#define hash_output_3 0x7c(an_security_block)
1953 +#define hash_output_3_low 0x7e(an_security_block)
1954 +
1955 +;*****************************************************************************************
1956 +; Assembly macros
1957 +;*****************************************************************************************
1958 +       ; C compiler reserves RP (A5) for return address during subroutine call.
1959 +       ; Use RP to return to caller
1960 +.macro call_return_macro
1961 +       calli   RP, 0(RP)
1962 +.endm
1963 +
1964 +#if 0
1965 +;*****************************************************************************************
1966 +;      void md5_ip5k_init(void)
1967 +;              initialize the output registers of the hash module
1968 +;
1969 +       ;.section .text.md5_ip5k_init,"ax",@progbits
1970 +       .section .text
1971 +       .global _md5_ip5k_init
1972 +       .func md5_ip5k_init, _md5_ip5k_init
1973 +
1974 +_md5_ip5k_init:
1975 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
1976 +
1977 +       movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
1978 +       movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
1979 +
1980 +       movei hash_output_0, #%hi(HASH_MD5_IN0)
1981 +       movei hash_output_0_low, #%lo(HASH_MD5_IN0)
1982 +
1983 +       movei hash_output_1, #%hi(HASH_MD5_IN1)
1984 +       movei hash_output_1_low, #%lo(HASH_MD5_IN1)
1985 +
1986 +       movei hash_output_2, #%hi(HASH_MD5_IN2)
1987 +       movei hash_output_2_low, #%lo(HASH_MD5_IN2)
1988 +
1989 +       movei hash_output_3, #%hi(HASH_MD5_IN3)
1990 +       movei hash_output_3_low, #%lo(HASH_MD5_IN3)
1991 +
1992 +       call_return_macro
1993 +       .endfunc
1994 +#endif
1995 +
1996 +;*****************************************************************************************
1997 +;      void md5_ip5k_init_digest(u32_t *hash_input)
1998 +;              initialize the output registers of the hash module
1999 +
2000 +       ;.section .text.md5_ip5k_init_digest,"ax",@progbits
2001 +       .section .text
2002 +       .global _md5_ip5k_init_digest
2003 +       .func md5_ip5k_init_digest, _md5_ip5k_init_digest
2004 +
2005 +_md5_ip5k_init_digest:
2006 +       movea an_data_input, D0
2007 +
2008 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2009 +
2010 +       movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
2011 +       movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
2012 +
2013 +       move.4 hash_output_0, (an_data_input)4++
2014 +       move.4 hash_output_1, (an_data_input)4++
2015 +       move.4 hash_output_2, (an_data_input)4++
2016 +       move.4 hash_output_3, (an_data_input)4++
2017 +
2018 +       call_return_macro
2019 +       .endfunc
2020 +
2021 +;*****************************************************************************************
2022 +;      void md5_ip5k_transform(u32_t *data_input)
2023 +;              performs intermediate transformation step for the hash calculation
2024 +;
2025 +       ;.sect .text.md5_ip5k_transform,"ax",@progbits
2026 +       .section .text
2027 +       .global _md5_ip5k_transform
2028 +       .func md5_ip5k_transform, _md5_ip5k_transform
2029 +
2030 +_md5_ip5k_transform:
2031 +       movea an_data_input, D0
2032 +
2033 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2034 +
2035 +       ; Write the first 128bits (16 bytes)
2036 +       move.4 hash_input_0, (an_data_input)4++
2037 +       move.4 hash_input_1, (an_data_input)4++
2038 +       move.4 hash_input_2, (an_data_input)4++
2039 +       move.4 hash_input_3, (an_data_input)4++
2040 +       move.4 hash_input_4, D0
2041 +
2042 +       move.4 hash_input_0, (an_data_input)4++
2043 +       move.4 hash_input_1, (an_data_input)4++
2044 +       move.4 hash_input_2, (an_data_input)4++
2045 +       move.4 hash_input_3, (an_data_input)4++
2046 +       move.4 hash_input_4, D0
2047 +
2048 +       move.4 hash_input_0, (an_data_input)4++
2049 +       move.4 hash_input_1, (an_data_input)4++
2050 +       move.4 hash_input_2, (an_data_input)4++
2051 +       move.4 hash_input_3, (an_data_input)4++
2052 +       move.4 hash_input_4, D0
2053 +
2054 +       move.4 hash_input_0, (an_data_input)4++
2055 +       move.4 hash_input_1, (an_data_input)4++
2056 +       move.4 hash_input_2, (an_data_input)4++
2057 +       move.4 hash_input_3, (an_data_input)4++
2058 +       move.4 hash_input_4, D0
2059 +
2060 +       pipe_flush 0
2061 +
2062 +md5_ip5k_transform_wait:
2063 +       ; wait for the module to calculate the output hash
2064 +       btst hash_status, #0
2065 +       jmpne.f md5_ip5k_transform_wait
2066 +
2067 +       call_return_macro
2068 +       .endfunc
2069 +
2070 +;*****************************************************************************************
2071 +;      void md5_ip5k_get_digest(u32_t *digest)
2072 +;              Return the hash of the input data
2073 +;
2074 +       ;.sect .text.md5_get_digest,"ax",@progbits
2075 +       .section .text
2076 +       .global _md5_ip5k_get_digest
2077 +       .func md5_ip5k_get_digest, _md5_ip5k_get_digest
2078 +
2079 +_md5_ip5k_get_digest:
2080 +       movea an_digest, D0
2081 +
2082 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2083 +
2084 +       ; we have finished
2085 +       move.4 0(an_digest), hash_output_0
2086 +       move.4 4(an_digest), hash_output_1
2087 +       move.4 8(an_digest), hash_output_2
2088 +       move.4 12(an_digest), hash_output_3
2089 +
2090 +       call_return_macro
2091 +       .endfunc
2092 +
2093 --- /dev/null
2094 +++ b/arch/ubicom32/crypto/md5_ubicom32.c
2095 @@ -0,0 +1,200 @@
2096 +/*
2097 + * arch/ubicom32/crypto/md5_ubicom32.c
2098 + *   Ubicom32 implementation of the MD5 Secure Hash Algorithm
2099 + *
2100 + * (C) Copyright 2009, Ubicom, Inc.
2101 + *
2102 + * This file is part of the Ubicom32 Linux Kernel Port.
2103 + *
2104 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
2105 + * it and/or modify it under the terms of the GNU General Public License
2106 + * as published by the Free Software Foundation, either version 2 of the
2107 + * License, or (at your option) any later version.
2108 + *
2109 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
2110 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
2111 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
2112 + * the GNU General Public License for more details.
2113 + *
2114 + * You should have received a copy of the GNU General Public License
2115 + * along with the Ubicom32 Linux Kernel Port.  If not, 
2116 + * see <http://www.gnu.org/licenses/>.
2117 + *
2118 + * Ubicom32 implementation derived from (with many thanks):
2119 + *   arch/m68knommu
2120 + *   arch/blackfin
2121 + *   arch/parisc
2122 + */
2123 +#include <linux/init.h>
2124 +#include <linux/module.h>
2125 +#include <linux/crypto.h>
2126 +
2127 +#include "crypto_ubicom32.h"
2128 +
2129 +#define MD5_DIGEST_SIZE        16
2130 +#define MD5_BLOCK_SIZE 64
2131 +#define MD5_HASH_WORDS 4
2132 +
2133 +extern void _md5_ip5k_init_digest(u32_t *digest);
2134 +extern void _md5_ip5k_transform(u32_t *data_input);
2135 +extern void _md5_ip5k_get_digest(u32_t *digest);
2136 +
2137 +struct ubicom32_md5_ctx {
2138 +       u64 count;              /* message length */
2139 +       u32 state[MD5_HASH_WORDS];
2140 +       u8 buf[2 * MD5_BLOCK_SIZE];
2141 +};
2142 +
2143 +static void md5_init(struct crypto_tfm *tfm)
2144 +{
2145 +       struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
2146 +       mctx->state[0] = 0x01234567;
2147 +       mctx->state[1] = 0x89abcdef;
2148 +       mctx->state[2] = 0xfedcba98;
2149 +       mctx->state[3] = 0x76543210;
2150 +
2151 +       mctx->count = 0;
2152 +}
2153 +
2154 +static inline void _md5_process(u32 *digest, const u8 *data)
2155 +{
2156 +       _md5_ip5k_transform((u32 *)data);
2157 +}
2158 +
2159 +static void md5_update(struct crypto_tfm *tfm, const u8 *data,
2160 +                       unsigned int len)
2161 +{
2162 +       struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
2163 +       int index, clen;
2164 +
2165 +       /* how much is already in the buffer? */
2166 +       index = mctx->count & 0x3f;
2167 +
2168 +       mctx->count += len;
2169 +
2170 +       if (index + len < MD5_BLOCK_SIZE) {
2171 +               goto store_only;
2172 +       }
2173 +
2174 +       hw_crypto_lock();
2175 +       hw_crypto_check();
2176 +
2177 +       /* init digest set ctrl register too */
2178 +       _md5_ip5k_init_digest(mctx->state);
2179 +
2180 +       if (unlikely(index == 0 && SEC_ALIGNED(data))) {
2181 +fast_process:
2182 +               while (len >= MD5_BLOCK_SIZE) {
2183 +                       _md5_process(mctx->state, data);
2184 +                       data += MD5_BLOCK_SIZE;
2185 +                       len -= MD5_BLOCK_SIZE;
2186 +               }
2187 +               goto store;
2188 +       }
2189 +
2190 +       /* process one stored block */
2191 +       if (index) {
2192 +               clen = MD5_BLOCK_SIZE - index;
2193 +               memcpy(mctx->buf + index, data, clen);
2194 +               _md5_process(mctx->state, mctx->buf);
2195 +               data += clen;
2196 +               len -= clen;
2197 +               index = 0;
2198 +       }
2199 +
2200 +       if (likely(SEC_ALIGNED(data))) {
2201 +               goto fast_process;
2202 +       }
2203 +
2204 +       /* process as many blocks as possible */
2205 +       while (len >= MD5_BLOCK_SIZE) {
2206 +               memcpy(mctx->buf, data, MD5_BLOCK_SIZE);
2207 +               _md5_process(mctx->state, mctx->buf);
2208 +               data += MD5_BLOCK_SIZE;
2209 +               len -= MD5_BLOCK_SIZE;
2210 +       }
2211 +
2212 +store:
2213 +       _md5_ip5k_get_digest(mctx->state);
2214 +       hw_crypto_unlock();
2215 +
2216 +store_only:
2217 +       /* anything left? */
2218 +       if (len)
2219 +               memcpy(mctx->buf + index , data, len);
2220 +}
2221 +
2222 +/* Add padding and return the message digest. */
2223 +static void md5_final(struct crypto_tfm *tfm, u8 *out)
2224 +{
2225 +       struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
2226 +       u32 bits[2];
2227 +       unsigned int index, end;
2228 +
2229 +       /* must perform manual padding */
2230 +       index = mctx->count & 0x3f;
2231 +       end =  (index < 56) ? MD5_BLOCK_SIZE : (2 * MD5_BLOCK_SIZE);
2232 +
2233 +       /* start pad with 1 */
2234 +       mctx->buf[index] = 0x80;
2235 +
2236 +       /* pad with zeros */
2237 +       index++;
2238 +       memset(mctx->buf + index, 0x00, end - index - 8);
2239 +
2240 +       /* append message length */
2241 +       bits[0] = mctx->count << 3;
2242 +       bits[1] = mctx->count >> 29;
2243 +       __cpu_to_le32s(bits);
2244 +       __cpu_to_le32s(bits + 1);
2245 +
2246 +       memcpy(mctx->buf + end - 8, &bits, sizeof(bits));
2247 +
2248 +       /* force to use the mctx->buf and ignore the partial buf */
2249 +       mctx->count = mctx->count & ~0x3f;
2250 +       md5_update(tfm, mctx->buf, end);
2251 +
2252 +       /* copy digest to out */
2253 +       memcpy(out, mctx->state, MD5_DIGEST_SIZE);
2254 +
2255 +       /* wipe context */
2256 +       memset(mctx, 0, sizeof *mctx);
2257 +}
2258 +
2259 +static struct crypto_alg alg = {
2260 +       .cra_name       =       "md5",
2261 +       .cra_driver_name=       "md5-ubicom32",
2262 +       .cra_priority   =       CRYPTO_UBICOM32_PRIORITY,
2263 +       .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
2264 +       .cra_blocksize  =       MD5_BLOCK_SIZE,
2265 +       .cra_ctxsize    =       sizeof(struct ubicom32_md5_ctx),
2266 +       .cra_module     =       THIS_MODULE,
2267 +       .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
2268 +       .cra_u = {
2269 +               .digest = {
2270 +                       .dia_digestsize =       MD5_DIGEST_SIZE,
2271 +                       .dia_init       =       md5_init,
2272 +                       .dia_update     =       md5_update,
2273 +                       .dia_final      =       md5_final,
2274 +               }
2275 +       }
2276 +};
2277 +
2278 +static int __init init(void)
2279 +{
2280 +       hw_crypto_init();
2281 +       return crypto_register_alg(&alg);
2282 +}
2283 +
2284 +static void __exit fini(void)
2285 +{
2286 +       crypto_unregister_alg(&alg);
2287 +}
2288 +
2289 +module_init(init);
2290 +module_exit(fini);
2291 +
2292 +MODULE_ALIAS("md5");
2293 +
2294 +MODULE_LICENSE("GPL");
2295 +MODULE_DESCRIPTION("MD5 Secure Hash Algorithm");
2296 --- /dev/null
2297 +++ b/arch/ubicom32/crypto/sha1_ubicom32_asm.S
2298 @@ -0,0 +1,244 @@
2299 +/*
2300 + * arch/ubicom32/crypto/sha1_ubicom32_asm.S
2301 + *     SHA1 hash support for Ubicom32 architecture V3.
2302 + *
2303 + * (C) Copyright 2009, Ubicom, Inc.
2304 + *
2305 + * This file is part of the Ubicom32 Linux Kernel Port.
2306 + *
2307 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
2308 + * it and/or modify it under the terms of the GNU General Public License
2309 + * as published by the Free Software Foundation, either version 2 of the
2310 + * License, or (at your option) any later version.
2311 + *
2312 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
2313 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
2314 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
2315 + * the GNU General Public License for more details.
2316 + *
2317 + * You should have received a copy of the GNU General Public License
2318 + * along with the Ubicom32 Linux Kernel Port.  If not, 
2319 + * see <http://www.gnu.org/licenses/>.
2320 + *
2321 + * Ubicom32 implementation derived from (with many thanks):
2322 + *   arch/m68knommu
2323 + *   arch/blackfin
2324 + *   arch/parisc
2325 + */
2326 +
2327 +#define __ASM__
2328 +#include <asm/ip5000.h>
2329 +
2330 +#ifndef RP
2331 +#define RP A5
2332 +#endif
2333 +
2334 +;*****************************************************************************************
2335 +; The function prototype
2336 +;*****************************************************************************************
2337 +; void sha1_ip5k_init(void)
2338 +; void sha1_ip5k_transform(u32_t *data_input)
2339 +; void sha1_ip5k_output(u32_t *digest)
2340 +
2341 +;*****************************************************************************************
2342 +; Inputs
2343 +;*****************************************************************************************
2344 +; data_input is the pointer to the block of data over which the digest will be calculated.
2345 +;      It should be word aligned.
2346 +;
2347 +; digest is the pointer to the block of data into which the digest (the output) will be written.
2348 +;      It should be word aligned.
2349 +;
2350 +
2351 +;*****************************************************************************************
2352 +; Outputs
2353 +;*****************************************************************************************
2354 +; None
2355 +
2356 +;*****************************************************************************************
2357 +; Hash Constants
2358 +;*****************************************************************************************
2359 +#define HASH_SHA1_IN0 0x67452301
2360 +#define HASH_SHA1_IN1 0xefcdab89
2361 +#define HASH_SHA1_IN2 0x98badcfe
2362 +#define HASH_SHA1_IN3 0x10325476
2363 +#define HASH_SHA1_IN4 0xc3d2e1f0
2364 +
2365 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
2366 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1 ((1 << 5) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
2367 +
2368 +;*****************************************************************************************
2369 +; An: Address Registers
2370 +;*****************************************************************************************
2371 +#define an_digest a4
2372 +#define an_data_input a4
2373 +#define an_security_block a3
2374 +
2375 +;*****************************************************************************************
2376 +; Hash related defines
2377 +;*****************************************************************************************
2378 +#define hash_control 0x00(an_security_block)
2379 +#define hash_control_low 0x02(an_security_block)
2380 +#define hash_status 0x04(an_security_block)
2381 +
2382 +#define hash_input_0 0x30(an_security_block)
2383 +#define hash_input_1 0x34(an_security_block)
2384 +#define hash_input_2 0x38(an_security_block)
2385 +#define hash_input_3 0x3c(an_security_block)
2386 +#define hash_input_4 0x40(an_security_block)
2387 +
2388 +#define hash_output_0 0x70(an_security_block)
2389 +#define hash_output_0_low 0x72(an_security_block)
2390 +#define hash_output_1 0x74(an_security_block)
2391 +#define hash_output_1_low 0x76(an_security_block)
2392 +#define hash_output_2 0x78(an_security_block)
2393 +#define hash_output_2_low 0x7a(an_security_block)
2394 +#define hash_output_3 0x7c(an_security_block)
2395 +#define hash_output_3_low 0x7e(an_security_block)
2396 +#define hash_output_4 0x80(an_security_block)
2397 +#define hash_output_4_low 0x82(an_security_block)
2398 +
2399 +;*****************************************************************************************
2400 +; Assembly macros
2401 +;*****************************************************************************************
2402 +       ; C compiler reserves RP (A5) for return address during subroutine call.
2403 +       ; Use RP to return to caller
2404 +.macro call_return_macro
2405 +       calli   RP, 0(RP)
2406 +.endm
2407 +
2408 +;*****************************************************************************************
2409 +;      void sha1_ip5k_init(void)
2410 +;              initialize the output registers of the hash module
2411 +
2412 +       ;.section .text.sha1_ip5k_init,"ax",@progbits
2413 +       .section .ocm_text,"ax",@progbits
2414 +       .global _sha1_ip5k_init
2415 +       .func sha1_ip5k_init, _sha1_ip5k_init
2416 +
2417 +_sha1_ip5k_init:
2418 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2419 +
2420 +       movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2421 +       movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2422 +
2423 +       movei hash_output_0, #%hi(HASH_SHA1_IN0)
2424 +       movei hash_output_0_low, #%lo(HASH_SHA1_IN0)
2425 +
2426 +       movei hash_output_1, #%hi(HASH_SHA1_IN1)
2427 +       movei hash_output_1_low, #%lo(HASH_SHA1_IN1)
2428 +
2429 +       movei hash_output_2, #%hi(HASH_SHA1_IN2)
2430 +       movei hash_output_2_low, #%lo(HASH_SHA1_IN2)
2431 +
2432 +       movei hash_output_3, #%hi(HASH_SHA1_IN3)
2433 +       movei hash_output_3_low, #%lo(HASH_SHA1_IN3)
2434 +
2435 +       movei hash_output_4, #%hi(HASH_SHA1_IN4)
2436 +       movei hash_output_4_low, #%lo(HASH_SHA1_IN4)
2437 +
2438 +       call_return_macro
2439 +       .endfunc
2440 +
2441 +;*****************************************************************************************
2442 +;      void sha1_ip5k_init_digest(u32_t *hash_input)
2443 +;              initialize the output registers of the hash module
2444 +
2445 +       ;.section .text.sha1_ip5k_init_digest,"ax",@progbits
2446 +       .section .ocm_text,"ax",@progbits
2447 +       .global _sha1_ip5k_init_digest
2448 +       .func sha1_ip5k_init_digest, _sha1_ip5k_init_digest
2449 +
2450 +_sha1_ip5k_init_digest:
2451 +       movea an_data_input, D0
2452 +
2453 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2454 +
2455 +       movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2456 +       movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2457 +
2458 +       move.4 hash_output_0, (an_data_input)4++
2459 +       move.4 hash_output_1, (an_data_input)4++
2460 +       move.4 hash_output_2, (an_data_input)4++
2461 +       move.4 hash_output_3, (an_data_input)4++
2462 +       move.4 hash_output_4, (an_data_input)4++
2463 +
2464 +       call_return_macro
2465 +       .endfunc
2466 +
2467 +;*****************************************************************************************
2468 +;      void sha1_ip5k_transform(u32_t *data_input)
2469 +;              performs intermediate transformation step for the hash calculation
2470 +
2471 +       ;.section .text.sha1_ip5k_transform,"ax",@progbits
2472 +       .section .ocm_text,"ax",@progbits
2473 +       .global _sha1_ip5k_transform
2474 +       .func sha1_ip5k_transform, _sha1_ip5k_transform
2475 +
2476 +_sha1_ip5k_transform:
2477 +       movea an_data_input, D0
2478 +
2479 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2480 +
2481 +       ; Write the first 128bits (16 bytes)
2482 +       move.4 hash_input_0, (an_data_input)4++
2483 +       move.4 hash_input_1, (an_data_input)4++
2484 +       move.4 hash_input_2, (an_data_input)4++
2485 +       move.4 hash_input_3, (an_data_input)4++
2486 +       move.4 hash_input_4, D0
2487 +
2488 +       move.4 hash_input_0, (an_data_input)4++
2489 +       move.4 hash_input_1, (an_data_input)4++
2490 +       move.4 hash_input_2, (an_data_input)4++
2491 +       move.4 hash_input_3, (an_data_input)4++
2492 +       move.4 hash_input_4, D0
2493 +
2494 +       move.4 hash_input_0, (an_data_input)4++
2495 +       move.4 hash_input_1, (an_data_input)4++
2496 +       move.4 hash_input_2, (an_data_input)4++
2497 +       move.4 hash_input_3, (an_data_input)4++
2498 +       move.4 hash_input_4, D0
2499 +
2500 +       move.4 hash_input_0, (an_data_input)4++
2501 +       move.4 hash_input_1, (an_data_input)4++
2502 +       move.4 hash_input_2, (an_data_input)4++
2503 +       move.4 hash_input_3, (an_data_input)4++
2504 +       move.4 hash_input_4, D0
2505 +
2506 +       pipe_flush 0
2507 +
2508 +sha1_ip5k_transform_wait:
2509 +       ; wait for the module to calculate the output hash
2510 +       btst hash_status, #0
2511 +       jmpne.f sha1_ip5k_transform_wait
2512 +
2513 +       call_return_macro
2514 +       .endfunc
2515 +
2516 +;*****************************************************************************************
2517 +;      void sha1_ip5k_output(u32_t *digest)
2518 +;              Return the hash of the input data
2519 +
2520 +       ;.section .text.sha1_ip5k_output,"ax",@progbits
2521 +       .section .ocm_text,"ax",@progbits
2522 +       .global _sha1_ip5k_output
2523 +       .func sha1_ip5k_output, _sha1_ip5k_output
2524 +
2525 +_sha1_ip5k_output:
2526 +       movea an_digest, D0
2527 +
2528 +       moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2529 +
2530 +       ; we have finished
2531 +       move.4 0(an_digest), hash_output_0
2532 +       move.4 4(an_digest), hash_output_1
2533 +       move.4 8(an_digest), hash_output_2
2534 +       move.4 12(an_digest), hash_output_3
2535 +       move.4 16(an_digest), hash_output_4
2536 +
2537 +       call_return_macro
2538 +       .endfunc
2539 +
2540 +;*****************************************************************************************
2541 +;END                   ;End of program code
2542 +;*****************************************************************************************
2543 --- /dev/null
2544 +++ b/arch/ubicom32/crypto/sha1_ubicom32.c
2545 @@ -0,0 +1,354 @@
2546 +/*
2547 + * arch/ubicom32/crypto/sha1_ubicom32.c
2548 + *   Ubicom32 implementation of the SHA1 Secure Hash Algorithm.
2549 + *
2550 + * (C) Copyright 2009, Ubicom, Inc.
2551 + *
2552 + * This file is part of the Ubicom32 Linux Kernel Port.
2553 + *
2554 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
2555 + * it and/or modify it under the terms of the GNU General Public License
2556 + * as published by the Free Software Foundation, either version 2 of the
2557 + * License, or (at your option) any later version.
2558 + *
2559 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
2560 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
2561 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
2562 + * the GNU General Public License for more details.
2563 + *
2564 + * You should have received a copy of the GNU General Public License
2565 + * along with the Ubicom32 Linux Kernel Port.  If not, 
2566 + * see <http://www.gnu.org/licenses/>.
2567 + *
2568 + * Ubicom32 implementation derived from (with many thanks):
2569 + *   arch/m68knommu
2570 + *   arch/blackfin
2571 + *   arch/parisc
2572 + */
2573 +#include <linux/init.h>
2574 +#include <linux/module.h>
2575 +#include <linux/crypto.h>
2576 +#include <crypto/sha.h>
2577 +#include <asm/linkage.h>
2578 +
2579 +#include "crypto_ubicom32.h"
2580 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
2581 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1 ((1 << 5) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
2582 +
2583 +struct ubicom32_sha1_ctx {
2584 +       u64 count;              /* message length */
2585 +       u32 state[5];
2586 +       u8 buf[2 * SHA1_BLOCK_SIZE];
2587 +};
2588 +
2589 +static inline void sha1_clear_2ws(u8 *buf, int wc)
2590 +{
2591 +       asm volatile (
2592 +       "1:     move.4  (%0)4++, #0             \n\t"
2593 +       "       move.4  (%0)4++, #0             \n\t"
2594 +       "       sub.4   %1, #2, %1              \n\t"
2595 +       "       jmple.f 1b                      \n\t"
2596 +               :
2597 +               : "a" (buf), "d" (wc)
2598 +               : "cc"
2599 +       );
2600 +}
2601 +
2602 +/* only wipe out count, state, and 1st half of buf - 9 bytes at most */
2603 +#define sha1_wipe_out(sctx) sha1_clear_2ws((u8 *)sctx, 2 + 5 + 16 - 2)
2604 +
2605 +static inline void sha1_init_digest(u32 *digest)
2606 +{
2607 +       hw_crypto_set_ctrl(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1);
2608 +       asm volatile (
2609 +       "       ; move digests to hash_output regs      \n\t"
2610 +       "       move.4  0x70(%0), 0x0(%1)               \n\t"
2611 +       "       move.4  0x74(%0), 0x4(%1)               \n\t"
2612 +       "       move.4  0x78(%0), 0x8(%1)               \n\t"
2613 +       "       move.4  0x7c(%0), 0xc(%1)               \n\t"
2614 +       "       move.4  0x80(%0), 0x10(%1)              \n\t"
2615 +               :
2616 +               : "a" (SEC_BASE), "a" (digest)
2617 +       );
2618 +}
2619 +
2620 +static inline void sha1_transform_feed(const u8 *in)
2621 +{
2622 +       asm volatile (
2623 +       "       ; write the 1st 16 bytes        \n\t"
2624 +       "       move.4  0x30(%0), 0x0(%1)       \n\t"
2625 +       "       move.4  0x34(%0), 0x4(%1)       \n\t"
2626 +       "       move.4  0x38(%0), 0x8(%1)       \n\t"
2627 +       "       move.4  0x3c(%0), 0xc(%1)       \n\t"
2628 +       "       move.4  0x40(%0), %1            \n\t"
2629 +       "       ; write the 2nd 16 bytes        \n\t"
2630 +       "       move.4  0x30(%0), 0x10(%1)      \n\t"
2631 +       "       move.4  0x34(%0), 0x14(%1)      \n\t"
2632 +       "       move.4  0x38(%0), 0x18(%1)      \n\t"
2633 +       "       move.4  0x3c(%0), 0x1c(%1)      \n\t"
2634 +       "       move.4  0x40(%0), %1            \n\t"
2635 +       "       ; write the 3rd 16 bytes        \n\t"
2636 +       "       move.4  0x30(%0), 0x20(%1)      \n\t"
2637 +       "       move.4  0x34(%0), 0x24(%1)      \n\t"
2638 +       "       move.4  0x38(%0), 0x28(%1)      \n\t"
2639 +       "       move.4  0x3c(%0), 0x2c(%1)      \n\t"
2640 +       "       move.4  0x40(%0), %1            \n\t"
2641 +       "       ; write the 4th 16 bytes        \n\t"
2642 +       "       move.4  0x30(%0), 0x30(%1)      \n\t"
2643 +       "       move.4  0x34(%0), 0x34(%1)      \n\t"
2644 +       "       move.4  0x38(%0), 0x38(%1)      \n\t"
2645 +       "       move.4  0x3c(%0), 0x3c(%1)      \n\t"
2646 +       "       move.4  0x40(%0), %1            \n\t"
2647 +       "       pipe_flush 0                    \n\t" 
2648 +               :
2649 +               : "a"(SEC_BASE), "a"(in)
2650 +       );
2651 +}
2652 +
2653 +static inline void sha1_transform_wait(void)
2654 +{
2655 +       asm volatile (
2656 +       "       btst    0x04(%0), #0            \n\t"
2657 +       "       jmpne.f -4                      \n\t"
2658 +               :
2659 +               : "a"(SEC_BASE)
2660 +               : "cc"
2661 +       );
2662 +}
2663 +
2664 +static inline void sha1_output_digest(u32 *digest)
2665 +{
2666 +       asm volatile (
2667 +       "       move.4  0x0(%1), 0x70(%0)               \n\t"
2668 +       "       move.4  0x4(%1), 0x74(%0)               \n\t"
2669 +       "       move.4  0x8(%1), 0x78(%0)               \n\t"
2670 +       "       move.4  0xc(%1), 0x7c(%0)               \n\t"
2671 +       "       move.4  0x10(%1), 0x80(%0)              \n\t"
2672 +               : 
2673 +               : "a" (SEC_BASE), "a" (digest)
2674 +       );
2675 +}
2676 +
2677 +static __ocm_text void sha1_init(struct crypto_tfm *tfm)
2678 +{
2679 +       struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
2680 +
2681 +       sctx->state[0] = SHA1_H0;
2682 +       sctx->state[1] = SHA1_H1;
2683 +       sctx->state[2] = SHA1_H2;
2684 +       sctx->state[3] = SHA1_H3;
2685 +       sctx->state[4] = SHA1_H4;
2686 +       sctx->count = 0;
2687 +}
2688 +
2689 +static void __ocm_text sha1_update(struct crypto_tfm *tfm, const u8 *data,
2690 +                       unsigned int len)
2691 +{
2692 +       struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
2693 +       int index, clen;
2694 +
2695 +       /* how much is already in the buffer? */
2696 +       index = sctx->count & 0x3f;
2697 +
2698 +       sctx->count += len;
2699 +
2700 +       if (index + len < SHA1_BLOCK_SIZE) {
2701 +               goto store_only;
2702 +       }
2703 +
2704 +       hw_crypto_lock();
2705 +       hw_crypto_check();
2706 +
2707 +       /* init digest set ctrl register too */
2708 +       sha1_init_digest(sctx->state);
2709 +
2710 +       if (unlikely(index == 0 && SEC_ALIGNED(data))) {
2711 +fast_process:
2712 +#if CRYPTO_UBICOM32_LOOP_ASM 
2713 +               if (likely(len >= SHA1_BLOCK_SIZE)) {
2714 +                       register unsigned int cnt = len >> 6;   // loop = len / 64;
2715 +                       sha1_transform_feed(data);
2716 +                       data += SHA1_BLOCK_SIZE;
2717 +
2718 +                       /* cnt is pre-decremented in the loop */
2719 +                       asm volatile (
2720 +                       "; while (--loop):  work on 2nd block   \n\t"
2721 +                       "1:     add.4   %2, #-1, %2             \n\t"
2722 +                       "       jmpeq.f 5f                      \n\t"
2723 +                       "                                       \n\t"
2724 +                       "       ; write the 1st 16 bytes        \n\t"
2725 +                       "       move.4  0x30(%1), (%0)4++       \n\t"
2726 +                       "       move.4  0x34(%1), (%0)4++       \n\t"
2727 +                       "       move.4  0x38(%1), (%0)4++       \n\t"
2728 +                       "       move.4  0x3c(%1), (%0)4++       \n\t"
2729 +                       "       ; can not kick off hw before it \n\t"
2730 +                       "       ; is done with the prev block   \n\t"
2731 +                       "                                       \n\t"
2732 +                       "       btst    0x04(%1), #0            \n\t"
2733 +                       "       jmpne.f -4                      \n\t"
2734 +                       "                                       \n\t"
2735 +                       "       ; tell hw to load 1st 16 bytes  \n\t"
2736 +                       "       move.4  0x40(%1), %2            \n\t"
2737 +                       "                                       \n\t"
2738 +                       "       ; write the 2nd 16 bytes        \n\t"
2739 +                       "       move.4  0x30(%1), (%0)4++       \n\t"
2740 +                       "       move.4  0x34(%1), (%0)4++       \n\t"
2741 +                       "       move.4  0x38(%1), (%0)4++       \n\t"
2742 +                       "       move.4  0x3c(%1), (%0)4++       \n\t"
2743 +                       "       move.4  0x40(%1), %2            \n\t"
2744 +                       "                                       \n\t"
2745 +                       "       ; write the 3rd 16 bytes        \n\t"
2746 +                       "       move.4  0x30(%1), (%0)4++       \n\t"
2747 +                       "       move.4  0x34(%1), (%0)4++       \n\t"
2748 +                       "       move.4  0x38(%1), (%0)4++       \n\t"
2749 +                       "       move.4  0x3c(%1), (%0)4++       \n\t"
2750 +                       "       move.4  0x40(%1), %2            \n\t"
2751 +                       "                                       \n\t"
2752 +                       "       ; write the 4th 16 bytes        \n\t"
2753 +                       "       move.4  0x30(%1), (%0)4++       \n\t"
2754 +                       "       move.4  0x34(%1), (%0)4++       \n\t"
2755 +                       "       move.4  0x38(%1), (%0)4++       \n\t"
2756 +                       "       move.4  0x3c(%1), (%0)4++       \n\t"
2757 +                       "       move.4  0x40(%1), %2            \n\t"
2758 +                       "                                       \n\t"
2759 +                       "; no need flush, enough insts          \n\t"
2760 +                       "; before next hw wait                  \n\t"
2761 +                       "                                       \n\t"
2762 +                       "; go back to loop                      \n\t"
2763 +                       "       jmpt 1b                         \n\t"
2764 +                       "                                       \n\t"
2765 +                       "; wait hw for last block               \n\t"
2766 +                       "5:     btst 0x04(%1), #0               \n\t"
2767 +                       "       jmpne.f -4                      \n\t"
2768 +                       "                                       \n\t"
2769 +                               : "+a" (data)
2770 +                               : "a"( SEC_BASE), "d" (cnt)
2771 +                               : "cc"
2772 +                       );
2773 +
2774 +                       len = len & (64 - 1);
2775 +               }
2776 +#else
2777 +               while (likely(len >= SHA1_BLOCK_SIZE)) {
2778 +                       sha1_transform_feed(data);
2779 +                       data += SHA1_BLOCK_SIZE;
2780 +                       len -= SHA1_BLOCK_SIZE;
2781 +                       sha1_transform_wait();
2782 +               }
2783 +#endif
2784 +               goto store;
2785 +       }
2786 +
2787 +       /* process one stored block */
2788 +       if (index) {
2789 +               clen = SHA1_BLOCK_SIZE - index;
2790 +               memcpy(sctx->buf + index, data, clen);
2791 +               sha1_transform_feed(sctx->buf);
2792 +               data += clen;
2793 +               len -= clen;
2794 +               index = 0;
2795 +               sha1_transform_wait();
2796 +       }
2797 +
2798 +       if (likely(SEC_ALIGNED(data))) {
2799 +               goto fast_process;
2800 +       }
2801 +
2802 +       /* process as many blocks as possible */
2803 +       if (likely(len >= SHA1_BLOCK_SIZE)) {
2804 +               memcpy(sctx->buf, data, SHA1_BLOCK_SIZE);
2805 +               do {
2806 +                       sha1_transform_feed(sctx->buf);
2807 +                       data += SHA1_BLOCK_SIZE;
2808 +                       len -= SHA1_BLOCK_SIZE;
2809 +                       if (likely(len >= SHA1_BLOCK_SIZE)) {
2810 +                               memcpy(sctx->buf, data, SHA1_BLOCK_SIZE);
2811 +                               sha1_transform_wait();
2812 +                               continue;
2813 +                       }
2814 +                       /* it is the last block */      
2815 +                       sha1_transform_wait();
2816 +                       break;
2817 +               } while (1);
2818 +       }
2819 +
2820 +store:
2821 +       sha1_output_digest(sctx->state);
2822 +       hw_crypto_unlock();
2823 +
2824 +store_only:
2825 +       /* anything left? */
2826 +       if (len)
2827 +               memcpy(sctx->buf + index , data, len);
2828 +}
2829 +
2830 +/* Add padding and return the message digest. */
2831 +static void __ocm_text sha1_final(struct crypto_tfm *tfm, u8 *out)
2832 +{
2833 +       struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
2834 +       u64 bits;
2835 +       unsigned int index, end;
2836 +
2837 +       /* must perform manual padding */
2838 +       index = sctx->count & 0x3f;
2839 +       end =  (index < 56) ? SHA1_BLOCK_SIZE : (2 * SHA1_BLOCK_SIZE);
2840 +
2841 +       /* start pad with 1 */
2842 +       sctx->buf[index] = 0x80;
2843 +
2844 +       /* pad with zeros */
2845 +       index++;
2846 +       memset(sctx->buf + index, 0x00, end - index - 8);
2847 +
2848 +       /* append message length */
2849 +       bits = sctx->count << 3 ;
2850 +       SEC_COPY_2W(sctx->buf + end - 8, &bits);
2851 +
2852 +       /* force to use the sctx->buf and ignore the partial buf */
2853 +       sctx->count = sctx->count & ~0x3f;
2854 +       sha1_update(tfm, sctx->buf, end);
2855 +
2856 +       /* copy digest to out */
2857 +       SEC_COPY_5W(out, sctx->state);
2858 +
2859 +       /* wipe context */
2860 +       sha1_wipe_out(sctx);
2861 +}
2862 +
2863 +static struct crypto_alg alg = {
2864 +       .cra_name       =       "sha1",
2865 +       .cra_driver_name=       "sha1-ubicom32",
2866 +       .cra_priority   =       CRYPTO_UBICOM32_PRIORITY,
2867 +       .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
2868 +       .cra_blocksize  =       SHA1_BLOCK_SIZE,
2869 +       .cra_ctxsize    =       sizeof(struct ubicom32_sha1_ctx),
2870 +       .cra_module     =       THIS_MODULE,
2871 +       .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
2872 +       .cra_u    = {
2873 +               .digest = {
2874 +                       .dia_digestsize =       SHA1_DIGEST_SIZE,
2875 +                       .dia_init       =       sha1_init,
2876 +                       .dia_update     =       sha1_update,
2877 +                       .dia_final      =       sha1_final,
2878 +               }
2879 +       }
2880 +};
2881 +
2882 +static int __init init(void)
2883 +{
2884 +       hw_crypto_init();
2885 +       return crypto_register_alg(&alg);
2886 +}
2887 +
2888 +static void __exit fini(void)
2889 +{
2890 +       crypto_unregister_alg(&alg);
2891 +}
2892 +
2893 +module_init(init);
2894 +module_exit(fini);
2895 +
2896 +MODULE_ALIAS("sha1");
2897 +
2898 +MODULE_LICENSE("GPL");
2899 +MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
2900 --- /dev/null
2901 +++ b/arch/ubicom32/include/asm/a.out.h
2902 @@ -0,0 +1,47 @@
2903 +/*
2904 + * arch/ubicom32/include/asm/a.out.h
2905 + *   Definitions for Ubicom32 a.out executable format.
2906 + *
2907 + * (C) Copyright 2009, Ubicom, Inc.
2908 + *
2909 + * This file is part of the Ubicom32 Linux Kernel Port.
2910 + *
2911 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
2912 + * it and/or modify it under the terms of the GNU General Public License
2913 + * as published by the Free Software Foundation, either version 2 of the
2914 + * License, or (at your option) any later version.
2915 + *
2916 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
2917 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
2918 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
2919 + * the GNU General Public License for more details.
2920 + *
2921 + * You should have received a copy of the GNU General Public License
2922 + * along with the Ubicom32 Linux Kernel Port.  If not, 
2923 + * see <http://www.gnu.org/licenses/>.
2924 + *
2925 + * Ubicom32 implementation derived from (with many thanks):
2926 + *   arch/m68knommu
2927 + *   arch/blackfin
2928 + *   arch/parisc
2929 + */
2930 +#ifndef _ASM_UBICOM32_A_OUT_H
2931 +#define _ASM_UBICOM32_A_OUT_H
2932 +
2933 +struct exec
2934 +{
2935 +  unsigned long a_info;                /* Use macros N_MAGIC, etc for access */
2936 +  unsigned a_text;             /* length of text, in bytes */
2937 +  unsigned a_data;             /* length of data, in bytes */
2938 +  unsigned a_bss;              /* length of uninitialized data area for file, in bytes */
2939 +  unsigned a_syms;             /* length of symbol table data in file, in bytes */
2940 +  unsigned a_entry;            /* start address */
2941 +  unsigned a_trsize;           /* length of relocation info for text, in bytes */
2942 +  unsigned a_drsize;           /* length of relocation info for data, in bytes */
2943 +};
2944 +
2945 +#define N_TRSIZE(a)    ((a).a_trsize)
2946 +#define N_DRSIZE(a)    ((a).a_drsize)
2947 +#define N_SYMSIZE(a)   ((a).a_syms)
2948 +
2949 +#endif /* _ASM_UBICOM32_A_OUT_H */
2950 --- /dev/null
2951 +++ b/arch/ubicom32/include/asm/atomic.h
2952 @@ -0,0 +1,352 @@
2953 +/*
2954 + * arch/ubicom32/include/asm/atomic.h
2955 + *   Atomic operations definitions for Ubicom32 architecture.
2956 + *
2957 + * (C) Copyright 2009, Ubicom, Inc.
2958 + *
2959 + * This file is part of the Ubicom32 Linux Kernel Port.
2960 + *
2961 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
2962 + * it and/or modify it under the terms of the GNU General Public License
2963 + * as published by the Free Software Foundation, either version 2 of the
2964 + * License, or (at your option) any later version.
2965 + *
2966 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
2967 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
2968 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
2969 + * the GNU General Public License for more details.
2970 + *
2971 + * You should have received a copy of the GNU General Public License
2972 + * along with the Ubicom32 Linux Kernel Port.  If not, 
2973 + * see <http://www.gnu.org/licenses/>.
2974 + *
2975 + * Ubicom32 implementation derived from (with many thanks):
2976 + *   arch/m68knommu
2977 + *   arch/blackfin
2978 + *   arch/parisc
2979 + */
2980 +#ifndef _ASM_UBICOM32_ATOMIC_H
2981 +#define _ASM_UBICOM32_ATOMIC_H
2982 +
2983 +#include <asm/system.h>
2984 +#include <asm/ubicom32-common.h>
2985 +#include <asm/types.h>
2986 +
2987 +/*
2988 + * Most instructions on the Ubicom32 processor are atomic in that they
2989 + * execute in one clock cycle.  However, Linux has several operations
2990 + * (e.g. compare and swap) which will require more than a single instruction
2991 + * to perform.   To achieve this, the Ubicom32 processor uses a single
2992 + * global bit in a scratchpad register as a critical section lock. All
2993 + * atomic operations acquire this lock.
2994 + *
2995 + * NOTE: To AVOID DEADLOCK(s), the atomic lock must only be used for atomic
2996 + * operations or by the ldsr to avoid disabling a thread performing an atomic
2997 + * operation.
2998 + *
2999 + * Do not attempt to disable interrupts while holding the atomic operations
3000 + * lock or you will DEADLOCK the system.
3001 + */
3002 +
3003 +typedef struct {
3004 +       volatile int counter;
3005 +} atomic_t;
3006 +
3007 +#define ATOMIC_INIT(i) { (i) }
3008 +
3009 +/*
3010 + * __atomic_add()
3011 + *     Add i to v and return the result.
3012 + */
3013 +static inline void __atomic_add(int i, atomic_t *v)
3014 +{
3015 +       atomic_t *vt = v;
3016 +
3017 +       __atomic_lock_acquire();
3018 +       vt->counter += i;
3019 +       __atomic_lock_release();
3020 +}
3021 +
3022 +/*
3023 + * __atomic_sub()
3024 + *     Subtract i from v and return the result.
3025 + */
3026 +static inline void __atomic_sub(int i, atomic_t *v)
3027 +{
3028 +       atomic_t *vt = v;
3029 +
3030 +       __atomic_lock_acquire();
3031 +       vt->counter -= i;
3032 +       __atomic_lock_release();
3033 +}
3034 +
3035 +/*
3036 + * __atomic_add_return()
3037 + *     Add i to v and return the result.
3038 + *
3039 + * The implementation here looks rather odd because we appear to be doing
3040 + * the addition twice.  In fact that's exactly what we're doing but with
3041 + * the ubicom32 instruction set we can do the inner load and add with two
3042 + * instructions whereas generating both the atomic result and the "ret"
3043 + * result requires three instructions.  The second add is generally only as
3044 + * costly as a move instruction and in cases where we compare the result
3045 + * with a constant the compiler can fold two constant values and do a
3046 + * single instruction, thus saving an instruction overall!
3047 + *
3048 + * At the worst we save one instruction inside the atomic lock.
3049 + */
3050 +static inline int __atomic_add_return(int i, atomic_t *v)
3051 +{
3052 +       int ret;
3053 +       atomic_t *vt = v;
3054 +
3055 +       __atomic_lock_acquire();
3056 +       ret = vt->counter;
3057 +       vt->counter = ret + i;
3058 +       __atomic_lock_release();
3059 +
3060 +       return ret + i;
3061 +}
3062 +
3063 +/*
3064 + * __atomic_sub_return()
3065 + *     Subtract i from v and return the result.
3066 + *
3067 + * The implementation here looks rather odd because we appear to be doing
3068 + * the subtraction twice.  In fact that's exactly what we're doing but with
3069 + * the ubicom32 instruction set we can do the inner load and sub with two
3070 + * instructions whereas generating both the atomic result and the "ret"
3071 + * result requires three instructions.  The second sub is generally only as
3072 + * costly as a move instruction and in cases where we compare the result
3073 + * with a constant the compiler can fold two constant values and do a
3074 + * single instruction, thus saving an instruction overall!
3075 + *
3076 + * At the worst we save one instruction inside the atomic lock.
3077 + */
3078 +static inline int __atomic_sub_return(int i, atomic_t *v)
3079 +{
3080 +       int ret;
3081 +       atomic_t *vt = v;
3082 +
3083 +       __atomic_lock_acquire();
3084 +       ret = vt->counter;
3085 +       vt->counter = ret - i;
3086 +       __atomic_lock_release();
3087 +
3088 +       return ret - i;
3089 +}
3090 +
3091 +/*
3092 + * PUBLIC API FOR ATOMIC!
3093 + */
3094 +#define atomic_add(i,v)        (__atomic_add( ((int)i),(v)))
3095 +#define atomic_sub(i,v)        (__atomic_sub( ((int)i),(v)))
3096 +#define atomic_inc(v)  (__atomic_add(   1,(v)))
3097 +#define atomic_dec(v)  (__atomic_sub(   1,(v)))
3098 +#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v)))
3099 +#define atomic_sub_return(i,v) (__atomic_sub_return( ((int)i),(v)))
3100 +#define atomic_inc_return(v)   (__atomic_add_return(   1,(v)))
3101 +#define atomic_dec_return(v)   (__atomic_sub_return(   1,(v)))
3102 +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
3103 +#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
3104 +#define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
3105 +#define atomic_sub_and_test(i,v)       (atomic_sub_return((i),(v)) == 0)
3106 +
3107 +/*
3108 + * atomic_read()
3109 + *     Acquire the atomic lock and read the variable.
3110 + */
3111 +static inline int atomic_read(const atomic_t *v)
3112 +{
3113 +       int ret;
3114 +       const atomic_t *vt = v;
3115 +
3116 +       __atomic_lock_acquire();
3117 +       ret = vt->counter;
3118 +       __atomic_lock_release();
3119 +
3120 +       return ret;
3121 +}
3122 +
3123 +/*
3124 + * atomic_set()
3125 + *     Acquire the atomic lock and set the variable.
3126 + */
3127 +static inline void atomic_set(atomic_t *v, int i)
3128 +{
3129 +       atomic_t *vt = v;
3130 +
3131 +       __atomic_lock_acquire();
3132 +       vt->counter = i;
3133 +       __atomic_lock_release();
3134 +}
3135 +
3136 +/*
3137 + * atomic_cmpxchg
3138 + *     Acquire the atomic lock and exchange if current == old.
3139 + */
3140 +static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
3141 +{
3142 +       int prev;
3143 +       atomic_t *vt = v;
3144 +
3145 +       __atomic_lock_acquire();
3146 +       prev = vt->counter;
3147 +       if (prev == old) {
3148 +               vt->counter = new;
3149 +       }
3150 +       __atomic_lock_release();
3151 +
3152 +       return prev;
3153 +}
3154 +
3155 +/*
3156 + * atomic_xchg()
3157 + *     Acquire the atomic lock and exchange values.
3158 + */
3159 +static inline int atomic_xchg(atomic_t *v, int new)
3160 +{
3161 +       int prev;
3162 +       atomic_t *vt = v;
3163 +
3164 +       __atomic_lock_acquire();
3165 +       prev = vt->counter;
3166 +       vt->counter = new;
3167 +       __atomic_lock_release();
3168 +
3169 +       return prev;
3170 +}
3171 +
3172 +/*
3173 + * atomic_add_unless()
3174 + *     Acquire the atomic lock and add a unless the value is u.
3175 + */
3176 +static inline int atomic_add_unless(atomic_t *v, int a, int u)
3177 +{
3178 +       int prev;
3179 +       atomic_t *vt = v;
3180 +
3181 +       __atomic_lock_acquire();
3182 +       prev = vt->counter;
3183 +       if (prev != u) {
3184 +               vt->counter += a;
3185 +               __atomic_lock_release();
3186 +               return 1;
3187 +       }
3188 +
3189 +       __atomic_lock_release();
3190 +       return 0;
3191 +}
3192 +
3193 +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
3194 +
3195 +#include <asm-generic/atomic.h>
3196 +
3197 +/* 
3198 + * The following is not a real function.  The compiler should remove the function
3199 + * call as long as the user does not pass in a size that __xchg and __cmpxchg
3200 + * are not prepared for.  If the user does pass in an unknown size, the user
3201 + * will get a link time error.
3202 + *
3203 + * The no return is to prevent a compiler error that can occur when dealing with
3204 + * uninitialized variables. Given that the function doesn't exist there is no
3205 + * net effect (and if it did it would not return).
3206 + */
3207 +extern void __xchg_called_with_bad_pointer(void) __attribute__((noreturn));
3208 +
3209 +/*
3210 + * __xchg()
3211 + *     Xchange *ptr for x atomically.
3212 + *
3213 + * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
3214 + * atomic exchange instruction so we use the global atomic_lock.
3215 + */
3216 +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
3217 +{
3218 +       unsigned long ret;
3219 +
3220 +       __atomic_lock_acquire();
3221 +
3222 +       switch (size) {
3223 +       case 1:
3224 +               ret = *(volatile unsigned char *)ptr;
3225 +               *(volatile unsigned char *)ptr = x;
3226 +               break;
3227 +
3228 +       case 2:
3229 +               ret = *(volatile unsigned short *)ptr;
3230 +               *(volatile unsigned short *)ptr = x;
3231 +               break;
3232 +
3233 +       case 4:
3234 +               ret = *(volatile unsigned int *)ptr;
3235 +               *(volatile unsigned int *)ptr = x;
3236 +               break;
3237 +
3238 +       default:
3239 +               __xchg_called_with_bad_pointer();
3240 +               break;
3241 +       }
3242 +       __atomic_lock_release();
3243 +       return ret;
3244 +}
3245 +
3246 +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
3247 +
3248 +/*
3249 + * __cmpxchg()
3250 + *     Compare and Xchange *ptr for x atomically.
3251 + *
3252 + * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
3253 + * atomic exchange instruction so we use the global atomic_lock.
3254 + */
3255 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long next, int size)
3256 +{
3257 +       unsigned long prev;
3258 +
3259 +       __atomic_lock_acquire();
3260 +       switch (size) {
3261 +       case 1: 
3262 +               prev = *(u8 *)ptr;
3263 +               if (prev == old) {
3264 +                       *(u8 *)ptr = (u8)next;
3265 +               }
3266 +               break;
3267 +
3268 +       case 2: 
3269 +               prev = *(u16 *)ptr;
3270 +               if (prev == old) {
3271 +                       *(u16 *)ptr = (u16)next;
3272 +               }
3273 +               break;
3274 +
3275 +       case 4: 
3276 +               prev = *(u32 *)ptr;
3277 +               if (prev == old) {
3278 +                       *(u32 *)ptr = (u32)next;
3279 +               }
3280 +               break;
3281 +
3282 +       default:
3283 +               __xchg_called_with_bad_pointer();
3284 +               break;
3285 +       }
3286 +       __atomic_lock_release();
3287 +       return prev;
3288 +}
3289 +
3290 +/*
3291 + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
3292 + * them available.
3293 + */
3294 +#define cmpxchg_local(ptr, o, n) \
3295 +       ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
3296 +
3297 +#define cmpxchg(ptr, o, n) __cmpxchg((ptr), (o), (n), sizeof(*(ptr)))
3298 +
3299 +#define smp_mb__before_atomic_inc() asm volatile ("" : : : "memory")
3300 +#define smp_mb__after_atomic_inc() asm volatile ("" : : : "memory")
3301 +#define smp_mb__before_atomic_dec() asm volatile ("" : : : "memory")
3302 +#define smp_mb__after_atomic_dec() asm volatile ("" : : : "memory")
3303 +
3304 +#endif /* _ASM_UBICOM32_ATOMIC_H */
3305 --- /dev/null
3306 +++ b/arch/ubicom32/include/asm/audio_tio.h
3307 @@ -0,0 +1,124 @@
3308 +/*
3309 + * arch/ubicom32/include/asm/audio_tio.h
3310 + *     AudioTIO include file
3311 + *
3312 + * (C) Copyright 2009, Ubicom, Inc.
3313 + *
3314 + * This file is part of the Ubicom32 Linux Kernel Port.
3315 + *
3316 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3317 + * it and/or modify it under the terms of the GNU General Public License
3318 + * as published by the Free Software Foundation, either version 2 of the
3319 + * License, or (at your option) any later version.
3320 + *
3321 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3322 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3323 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3324 + * the GNU General Public License for more details.
3325 + *
3326 + * You should have received a copy of the GNU General Public License
3327 + * along with the Ubicom32 Linux Kernel Port.  If not,
3328 + * see <http://www.gnu.org/licenses/>.
3329 + */
3330 +
3331 +#ifndef _AUDIO_TIO_H
3332 +#define _AUDIO_TIO_H
3333 +
3334 +#include <asm/devtree.h>
3335 +#include <asm/ubi32-pcm.h>
3336 +
3337 +#define UBI32_AUDIO_INT_FLAG_MORE_SAMPLES 0x00000001
3338 +#define UBI32_AUDIO_INT_FLAG_COMMAND      0x00000002
3339 +
3340 +/*
3341 + * Commands the Primary OS sends to the audio device
3342 + */
3343 +enum ubi32_audio_command {
3344 +       UBI32_AUDIO_CMD_NONE,
3345 +       UBI32_AUDIO_CMD_START,
3346 +       UBI32_AUDIO_CMD_STOP,
3347 +       UBI32_AUDIO_CMD_PAUSE,
3348 +       UBI32_AUDIO_CMD_RESUME,
3349 +       UBI32_AUDIO_CMD_MUTE,
3350 +       UBI32_AUDIO_CMD_UNMUTE,
3351 +       UBI32_AUDIO_CMD_SETUP,
3352 +       UBI32_AUDIO_CMD_ENABLE,
3353 +       UBI32_AUDIO_CMD_DISABLE,
3354 +};
3355 +
3356 +/*
3357 + * Flag bits passed in the registers
3358 + */
3359 +#define UBI32_CMD_SETUP_FLAG_LE                (1 << 0)        /* Use Little Endian Mode */
3360 +
3361 +/*
3362 + * Status bits that audio device can set to indicate reason
3363 + * for interrupting the Primary OS
3364 + */
3365 +#define UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST (1 << 0) /* Audio device needs samples in DMA0 for playback */
3366 +#define UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST (1 << 1) /* Audio device needs samples in DMA1 for playback */
3367 +
3368 +struct ubi32_audio_dma {
3369 +       /*
3370 +        * NOTE: The active flag shall only be SET by the producer and CLEARED
3371 +        * by the consumer, NEVER the other way around.  For playback, the
3372 +        * Primary OS sets this flag and ipAudioTIO clears it.
3373 +        *
3374 +        * The producer shall not modify the ptr or ctr fields when the transfer
3375 +        * is marked as active, as these are used by the consumer to do the
3376 +        * transfer.
3377 +        */
3378 +       volatile uint32_t active;               /* Nonzero if data in ptr/ctr ready to be transferred */
3379 +       //volatile u32_t active;                /* Nonzero if data in ptr/ctr ready to be transferred */
3380 +       volatile void *ptr;             /* Pointer to data to be transferred */
3381 +       volatile uint32_t ctr;  /* Counter: number of data units to transfer */
3382 +       //volatile u32_t ctr;           /* Counter: number of data units to transfer */
3383 +};
3384 +
3385 +#define AUDIOTIONODE_CAP_BE    (1 << 0)
3386 +#define AUDIOTIONODE_CAP_LE    (1 << 1)
3387 +
3388 +/*
3389 + * Resource indices used to access IRQs via platform_get_resource
3390 + */
3391 +#define AUDIOTIO_MEM_RESOURCE          0
3392 +#define AUDIOTIO_TX_IRQ_RESOURCE       0
3393 +#define AUDIOTIO_RX_IRQ_RESOURCE       1
3394 +
3395 +#define AUDIOTIONODE_VERSION   5
3396 +struct audiotionode {
3397 +       struct devtree_node dn;
3398 +       uint32_t version;                               /* Version of this node */
3399 +       struct audiotioregs *regs;
3400 +};
3401 +
3402 +#define AUDIOTIOREGS_VERSION   3
3403 +struct audiotioregs {
3404 +       uint32_t version;
3405 +       uint32_t caps;                                  /* Capabilities of the driver */
3406 +       u32_t *sample_rates;                            /* Sample Rates supported by this driver */
3407 +       u32_t n_sample_rates;                           /* Number of sample rates supported by this driver */
3408 +       u32_t channel_mask;                             /* The channel configs supported by this driver (bit 1 = 1 channel, etc) */
3409 +       volatile uint32_t int_flags;                    /* Reason for interrupting audio device */
3410 +       volatile enum ubi32_audio_command command;      /* Command from Primary OS */
3411 +       volatile uint32_t flags;                        /* Flag bits for this command */
3412 +       volatile uint32_t channels;                     /* Number of channels in stream */
3413 +       volatile uint32_t sample_rate;                  /* Sample rate */
3414 +       volatile uint32_t status;                       /* Status bits sent from AudioTIO to Primary OS */
3415 +       volatile void *current_read_pos;                /* Position of next sample to be removed from Primary OS sample buffer */
3416 +
3417 +       /*
3418 +        * These are the transfer requests.  They are used in alternating
3419 +        * order so that when ipAudioTIO is processing one request, the
3420 +        * Primary OS can fill in the other one.
3421 +        *
3422 +        * NOTE: The active bit shall always be SET by the producer and
3423 +        * CLEARED by the consumer, NEVER the other way around.
3424 +        */
3425 +       struct ubi32_audio_dma playback_xfer_requests[2];
3426 +};
3427 +
3428 +extern struct platform_device * __init audio_tio_alloc(const char *driver_name, const char *node_name, int priv_size);
3429 +
3430 +#define audio_tio_priv(pdev) (((struct ubi32pcm_platform_data *)(((struct platform_device *)(pdev))->dev.platform_data))->priv_data)
3431 +#endif
3432 --- /dev/null
3433 +++ b/arch/ubicom32/include/asm/auxvec.h
3434 @@ -0,0 +1,32 @@
3435 +/*
3436 + * arch/ubicom32/include/asm/auxvec.h
3437 + *   Symbolic values for the entries in the auxiliary table
3438 + *   put on the initial stack.
3439 + *
3440 + * (C) Copyright 2009, Ubicom, Inc.
3441 + *
3442 + * This file is part of the Ubicom32 Linux Kernel Port.
3443 + *
3444 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3445 + * it and/or modify it under the terms of the GNU General Public License
3446 + * as published by the Free Software Foundation, either version 2 of the
3447 + * License, or (at your option) any later version.
3448 + *
3449 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3450 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3451 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3452 + * the GNU General Public License for more details.
3453 + *
3454 + * You should have received a copy of the GNU General Public License
3455 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3456 + * see <http://www.gnu.org/licenses/>.
3457 + *
3458 + * Ubicom32 implementation derived from (with many thanks):
3459 + *   arch/m68knommu
3460 + *   arch/blackfin
3461 + *   arch/parisc
3462 + */
3463 +#ifndef _ASM_UBICOM32_AUXVEC_H
3464 +#define _ASM_UBICOM32_AUXVEC_H
3465 +
3466 +#endif /* _ASM_UBICOM32_AUXVEC_H */
3467 --- /dev/null
3468 +++ b/arch/ubicom32/include/asm/bitops.h
3469 @@ -0,0 +1,171 @@
3470 +/*
3471 + * arch/ubicom32/include/asm/bitops.h
3472 + *   Bit manipulation definitions for Ubicom32 architecture.
3473 + *
3474 + * (C) Copyright 2009, Ubicom, Inc.
3475 + *
3476 + * This file is part of the Ubicom32 Linux Kernel Port.
3477 + *
3478 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3479 + * it and/or modify it under the terms of the GNU General Public License
3480 + * as published by the Free Software Foundation, either version 2 of the
3481 + * License, or (at your option) any later version.
3482 + *
3483 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3484 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3485 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3486 + * the GNU General Public License for more details.
3487 + *
3488 + * You should have received a copy of the GNU General Public License
3489 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3490 + * see <http://www.gnu.org/licenses/>.
3491 + *
3492 + * Ubicom32 implementation derived from (with many thanks):
3493 + *   arch/m68knommu
3494 + *   arch/blackfin
3495 + *   arch/parisc
3496 + */
3497 +#ifndef _ASM_UBICOM32_BITOPS_H
3498 +#define _ASM_UBICOM32_BITOPS_H
3499 +
3500 +/*
3501 + * Copyright 1992, Linus Torvalds.
3502 + */
3503 +
3504 +#include <linux/compiler.h>
3505 +#include <asm/byteorder.h>     /* swab32 */
3506 +
3507 +#ifdef __KERNEL__
3508 +
3509 +#ifndef _LINUX_BITOPS_H
3510 +#error only <linux/bitops.h> can be included directly
3511 +#endif
3512 +
3513 +#include <asm-generic/bitops/ffs.h>
3514 +#include <asm-generic/bitops/__ffs.h>
3515 +
3516 +#include <asm-generic/bitops/sched.h>
3517 +#include <asm-generic/bitops/ffz.h>
3518 +
3519 +#include <asm/ubicom32-common.h>
3520 +
3521 +static inline void set_bit(int bit, volatile unsigned long *p)
3522 +{
3523 +       unsigned long mask = 1UL << (bit & 31);
3524 +
3525 +       p += bit >> 5;
3526 +
3527 +       __atomic_lock_acquire();
3528 +       *p |= mask;
3529 +       __atomic_lock_release();
3530 +}
3531 +
3532 +static inline void clear_bit(int bit, volatile unsigned long *p)
3533 +{
3534 +       unsigned long mask = 1UL << (bit & 31);
3535 +
3536 +       p += bit >> 5;
3537 +
3538 +       __atomic_lock_acquire();
3539 +       *p &= ~mask;
3540 +       __atomic_lock_release();
3541 +}
3542 +
3543 +/*
3544 + * clear_bit() doesn't provide any barrier for the compiler.
3545 + */
3546 +#define smp_mb__before_clear_bit()     barrier()
3547 +#define smp_mb__after_clear_bit()      barrier()
3548 +
3549 +static inline void change_bit(int bit, volatile unsigned long *p)
3550 +{
3551 +       unsigned long mask = 1UL << (bit & 31);
3552 +
3553 +       p += bit >> 5;
3554 +
3555 +       __atomic_lock_acquire();
3556 +       *p ^= mask;
3557 +       __atomic_lock_release();
3558 +}
3559 +
3560 +static inline int test_and_set_bit(int bit, volatile unsigned long *p)
3561 +{
3562 +       unsigned int res;
3563 +       unsigned long mask = 1UL << (bit & 31);
3564 +
3565 +       p += bit >> 5;
3566 +
3567 +       __atomic_lock_acquire();
3568 +       res = *p;
3569 +       *p = res | mask;
3570 +       __atomic_lock_release();
3571 +
3572 +       return res & mask;
3573 +}
3574 +
3575 +static inline int test_and_clear_bit(int bit, volatile unsigned long *p)
3576 +{
3577 +       unsigned int res;
3578 +       unsigned long mask = 1UL << (bit & 31);
3579 +
3580 +       p += bit >> 5;
3581 +
3582 +       __atomic_lock_acquire();
3583 +       res = *p;
3584 +       *p = res & ~mask;
3585 +       __atomic_lock_release();
3586 +
3587 +       return res & mask;
3588 +}
3589 +
3590 +static inline int test_and_change_bit(int bit, volatile unsigned long *p)
3591 +{
3592 +       unsigned int res;
3593 +       unsigned long mask = 1UL << (bit & 31);
3594 +
3595 +       p += bit >> 5;
3596 +
3597 +       __atomic_lock_acquire();
3598 +       res = *p;
3599 +       *p = res ^ mask;
3600 +       __atomic_lock_release();
3601 +
3602 +       return res & mask;
3603 +}
3604 +
3605 +#include <asm-generic/bitops/non-atomic.h>
3606 +
3607 +/*
3608 + * This routine doesn't need to be atomic.
3609 + */
3610 +static inline int __constant_test_bit(int nr, const volatile unsigned long *addr)
3611 +{
3612 +       return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
3613 +}
3614 +
3615 +static inline int __test_bit(int nr, const volatile unsigned long *addr)
3616 +{
3617 +       int     * a = (int *) addr;
3618 +       int     mask;
3619 +
3620 +       a += nr >> 5;
3621 +       mask = 1 << (nr & 0x1f);
3622 +       return ((mask & *a) != 0);
3623 +}
3624 +
3625 +#define test_bit(nr,addr) (__builtin_constant_p(nr) ?  __constant_test_bit((nr),(addr)) :  __test_bit((nr),(addr)))
3626 +
3627 +#include <asm-generic/bitops/find.h>
3628 +#include <asm-generic/bitops/hweight.h>
3629 +#include <asm-generic/bitops/lock.h>
3630 +
3631 +#include <asm-generic/bitops/ext2-non-atomic.h>
3632 +#include <asm-generic/bitops/ext2-atomic.h>
3633 +#include <asm-generic/bitops/minix.h>
3634 +
3635 +#endif /* __KERNEL__ */
3636 +
3637 +#include <asm-generic/bitops/fls.h>
3638 +#include <asm-generic/bitops/fls64.h>
3639 +
3640 +#endif /* _ASM_UBICOM32_BITOPS_H */
3641 --- /dev/null
3642 +++ b/arch/ubicom32/include/asm/board.h
3643 @@ -0,0 +1,34 @@
3644 +/*
3645 + * arch/ubicom32/include/asm/board.h
3646 + *   Board init and revision definitions for Ubicom32 architecture.
3647 + *
3648 + * (C) Copyright 2009, Ubicom, Inc.
3649 + *
3650 + * This file is part of the Ubicom32 Linux Kernel Port.
3651 + *
3652 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3653 + * it and/or modify it under the terms of the GNU General Public License
3654 + * as published by the Free Software Foundation, either version 2 of the
3655 + * License, or (at your option) any later version.
3656 + *
3657 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3658 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3659 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3660 + * the GNU General Public License for more details.
3661 + *
3662 + * You should have received a copy of the GNU General Public License
3663 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3664 + * see <http://www.gnu.org/licenses/>.
3665 + *
3666 + * Ubicom32 implementation derived from (with many thanks):
3667 + *   arch/m68knommu
3668 + *   arch/blackfin
3669 + *   arch/parisc
3670 + */
3671 +#ifndef _ASM_UBICOM32_BOARD_H
3672 +#define _ASM_UBICOM32_BOARD_H
3673 +
3674 +extern const char *board_get_revision(void);
3675 +extern void __init board_init(void);
3676 +
3677 +#endif /* _ASM_UBICOM32_BOARD_H */
3678 --- /dev/null
3679 +++ b/arch/ubicom32/include/asm/bootargs.h
3680 @@ -0,0 +1,34 @@
3681 +/*
3682 + * arch/ubicom32/include/asm/bootargs.h
3683 + *   Kernel command line via the devtree API.
3684 + *
3685 + * (C) Copyright 2009, Ubicom, Inc.
3686 + *
3687 + * This file is part of the Ubicom32 Linux Kernel Port.
3688 + *
3689 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3690 + * it and/or modify it under the terms of the GNU General Public License
3691 + * as published by the Free Software Foundation, either version 2 of the
3692 + * License, or (at your option) any later version.
3693 + *
3694 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3695 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3696 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3697 + * the GNU General Public License for more details.
3698 + *
3699 + * You should have received a copy of the GNU General Public License
3700 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3701 + * see <http://www.gnu.org/licenses/>.
3702 + *
3703 + * Ubicom32 implementation derived from (with many thanks):
3704 + *   arch/m68knommu
3705 + *   arch/blackfin
3706 + *   arch/parisc
3707 + */
3708 +#ifndef _ASM_UBICOM32_BOOTARGS_H
3709 +#define _ASM_UBICOM32_BOOTARGS_H
3710 +
3711 +extern const char *bootargs_get_cmdline(void);
3712 +extern void __init bootargs_init(void);
3713 +
3714 +#endif /* _ASM_UBICOM32_BOOTARGS_H */
3715 --- /dev/null
3716 +++ b/arch/ubicom32/include/asm/bootinfo.h
3717 @@ -0,0 +1,34 @@
3718 +/*
3719 + * arch/ubicom32/include/asm/bootinfo.h
3720 + *   Definitions of firmware boot parameters passed to the kernel.
3721 + *
3722 + * (C) Copyright 2009, Ubicom, Inc.
3723 + *
3724 + * This file is part of the Ubicom32 Linux Kernel Port.
3725 + *
3726 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3727 + * it and/or modify it under the terms of the GNU General Public License
3728 + * as published by the Free Software Foundation, either version 2 of the
3729 + * License, or (at your option) any later version.
3730 + *
3731 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3732 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3733 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3734 + * the GNU General Public License for more details.
3735 + *
3736 + * You should have received a copy of the GNU General Public License
3737 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3738 + * see <http://www.gnu.org/licenses/>.
3739 + *
3740 + * Ubicom32 implementation derived from (with many thanks):
3741 + *   arch/m68knommu
3742 + *   arch/blackfin
3743 + *   arch/parisc
3744 + */
3745 +
3746 +#ifndef _ASM_UBICOM32_BOOTINFO_H
3747 +#define _ASM_UBICOM32_BOOTINFO_H
3748 +
3749 +/* Nothing for ubicom32 */
3750 +
3751 +#endif /* _ASM_UBICOM32_BOOTINFO_H */
3752 --- /dev/null
3753 +++ b/arch/ubicom32/include/asm/bug.h
3754 @@ -0,0 +1,53 @@
3755 +/*
3756 + * arch/ubicom32/include/asm/bug.h
3757 + *   Generic bug.h for Ubicom32 architecture.
3758 + *
3759 + * (C) Copyright 2009, Ubicom, Inc.
3760 + *
3761 + * This file is part of the Ubicom32 Linux Kernel Port.
3762 + *
3763 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3764 + * it and/or modify it under the terms of the GNU General Public License
3765 + * as published by the Free Software Foundation, either version 2 of the
3766 + * License, or (at your option) any later version.
3767 + *
3768 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3769 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3770 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3771 + * the GNU General Public License for more details.
3772 + *
3773 + * You should have received a copy of the GNU General Public License
3774 + * along with the Ubicom32 Linux Kernel Port.  If not,
3775 + * see <http://www.gnu.org/licenses/>.
3776 + *
3777 + * Ubicom32 implementation derived from (with many thanks):
3778 + *   arch/m68knommu
3779 + *   arch/blackfin
3780 + *   arch/parisc
3781 + */
3782 +#ifndef _ASM_UBICOM32_BUG_H
3783 +#define _ASM_UBICOM32_BUG_H
3784 +
3785 +#include <linux/kernel.h>
3786 +#include <asm/thread.h>
3787 +
3788 +#if defined(CONFIG_STOP_ON_BUG)
3789 +/*
3790 + *  __BUG_ON()
3791 + *     Stall all threads to enable debugging.
3792 + */
3793 +static inline void __BUG_ON(unsigned long c)
3794 +{
3795 +       if (unlikely(c)) {
3796 +               THREAD_STALL;
3797 +       }
3798 +       return;
3799 +}
3800 +
3801 +#define BUG_ON(c) __BUG_ON((unsigned long)(c))
3802 +#define HAVE_ARCH_BUG_ON
3803 +#endif
3804 +
3805 +#include <asm-generic/bug.h>
3806 +
3807 +#endif /* _ASM_UBICOM32_BUG_H */
3808 --- /dev/null
3809 +++ b/arch/ubicom32/include/asm/bugs.h
3810 @@ -0,0 +1,44 @@
3811 +/*
3812 + * arch/ubicom32/include/asm/bugs.h
3813 + *   Definition of check_bugs() for Ubicom32 architecture.
3814 + *
3815 + * (C) Copyright 2009, Ubicom, Inc.
3816 + * Copyright (C) 1994  Linus Torvalds
3817 + *
3818 + * This file is part of the Ubicom32 Linux Kernel Port.
3819 + *
3820 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3821 + * it and/or modify it under the terms of the GNU General Public License
3822 + * as published by the Free Software Foundation, either version 2 of the
3823 + * License, or (at your option) any later version.
3824 + *
3825 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3826 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3827 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3828 + * the GNU General Public License for more details.
3829 + *
3830 + * You should have received a copy of the GNU General Public License
3831 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3832 + * see <http://www.gnu.org/licenses/>.
3833 + *
3834 + * Ubicom32 implementation derived from (with many thanks):
3835 + *   arch/m68knommu
3836 + *   arch/blackfin
3837 + *   arch/parisc
3838 + */
3839 +
3840 +/*
3841 + * This is included by init/main.c to check for architecture-dependent bugs.
3842 + *
3843 + * Needs:
3844 + *     void check_bugs(void);
3845 + */
3846 +
3847 +#ifndef _ASM_UBICOM32_BUGS_H
3848 +#define _ASM_UBICOM32_BUGS_H
3849 +
3850 +static void check_bugs(void)
3851 +{
3852 +}
3853 +
3854 +#endif /* _ASM_UBICOM32_BUGS_H */
3855 --- /dev/null
3856 +++ b/arch/ubicom32/include/asm/byteorder.h
3857 @@ -0,0 +1,48 @@
3858 +/*
3859 + * arch/ubicom32/include/asm/byteorder.h
3860 + *   Byte order swapping utility routines.
3861 + *
3862 + * (C) Copyright 2009, Ubicom, Inc.
3863 + *
3864 + * This file is part of the Ubicom32 Linux Kernel Port.
3865 + *
3866 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3867 + * it and/or modify it under the terms of the GNU General Public License
3868 + * as published by the Free Software Foundation, either version 2 of the
3869 + * License, or (at your option) any later version.
3870 + *
3871 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3872 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3873 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3874 + * the GNU General Public License for more details.
3875 + *
3876 + * You should have received a copy of the GNU General Public License
3877 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3878 + * see <http://www.gnu.org/licenses/>.
3879 + *
3880 + * Ubicom32 implementation derived from (with many thanks):
3881 + *   arch/m68knommu
3882 + *   arch/blackfin
3883 + *   arch/parisc
3884 + */
3885 +#ifndef _ASM_UBICOM32_BYTEORDER_H
3886 +#define _ASM_UBICOM32_BYTEORDER_H
3887 +
3888 +#include <linux/types.h>
3889 +
3890 +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
3891 +#  define __BYTEORDER_HAS_U64__
3892 +#  define __SWAB_64_THRU_32__
3893 +#endif
3894 +
3895 +#if defined(IP7000) || defined(IP7000_REV2)
3896 +
3897 +#define __arch__swab16 __builtin_ubicom32_swapb_2
3898 +#define __arch__swab32 __builtin_ubicom32_swapb_4
3899 +
3900 +#endif /* IP7000 */
3901 +
3902 +#include <linux/byteorder/big_endian.h>
3903 +
3904 +#endif /* _ASM_UBICOM32_BYTEORDER_H */
3905 +
3906 --- /dev/null
3907 +++ b/arch/ubicom32/include/asm/cachectl.h
3908 @@ -0,0 +1,39 @@
3909 +/*
3910 + * arch/ubicom32/include/asm/cachectl.h
3911 + *   Ubicom32 cache control definitions.
3912 + *
3913 + * (C) Copyright 2009, Ubicom, Inc.
3914 + *
3915 + * This file is part of the Ubicom32 Linux Kernel Port.
3916 + *
3917 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3918 + * it and/or modify it under the terms of the GNU General Public License
3919 + * as published by the Free Software Foundation, either version 2 of the
3920 + * License, or (at your option) any later version.
3921 + *
3922 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3923 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3924 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3925 + * the GNU General Public License for more details.
3926 + *
3927 + * You should have received a copy of the GNU General Public License
3928 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3929 + * see <http://www.gnu.org/licenses/>.
3930 + *
3931 + * Ubicom32 implementation derived from (with many thanks):
3932 + *   arch/m68knommu
3933 + *   arch/blackfin
3934 + *   arch/parisc
3935 + */
3936 +#ifndef _ASM_UBICOM32_CACHECTL_H
3937 +#define _ASM_UBICOM32_CACHECTL_H
3938 +
3939 +#include <asm/ip5000.h>
3940 +
3941 +/*
3942 + * mem_cache_control()
3943 + *     Special cache control operation
3944 + */
3945 +extern void mem_cache_control(unsigned long cc, unsigned long begin_addr, unsigned long end_addr, unsigned long op);
3946 +
3947 +#endif /* _ASM_UBICOM32_CACHECTL_H */
3948 --- /dev/null
3949 +++ b/arch/ubicom32/include/asm/cacheflush.h
3950 @@ -0,0 +1,104 @@
3951 +/*
3952 + * arch/ubicom32/include/asm/cacheflush.h
3953 + *   Cache flushing definitions for Ubicom32 architecture.
3954 + *
3955 + * (C) Copyright 2009, Ubicom, Inc.
3956 + *
3957 + * This file is part of the Ubicom32 Linux Kernel Port.
3958 + *
3959 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
3960 + * it and/or modify it under the terms of the GNU General Public License
3961 + * as published by the Free Software Foundation, either version 2 of the
3962 + * License, or (at your option) any later version.
3963 + *
3964 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
3965 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
3966 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
3967 + * the GNU General Public License for more details.
3968 + *
3969 + * You should have received a copy of the GNU General Public License
3970 + * along with the Ubicom32 Linux Kernel Port.  If not, 
3971 + * see <http://www.gnu.org/licenses/>.
3972 + *
3973 + * Ubicom32 implementation derived from (with many thanks):
3974 + *   arch/m68knommu
3975 + *   arch/blackfin
3976 + *   arch/parisc
3977 + */
3978 +#ifndef _ASM_UBICOM32_CACHEFLUSH_H
3979 +#define _ASM_UBICOM32_CACHEFLUSH_H
3980 +
3981 +/*
3982 + * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
3983 + */
3984 +#include <linux/mm.h>
3985 +#include <asm/cachectl.h>
3986 +#include <asm/ip5000.h>
3987 +
3988 +#define flush_cache_all()                      __flush_cache_all()
3989 +#define flush_cache_mm(mm)                     do { } while (0)
3990 +#define flush_cache_dup_mm(mm)                 do { } while (0)
3991 +#define flush_cache_range(vma, start, end)     __flush_cache_all()
3992 +#define flush_cache_page(vma, vmaddr)          do { } while (0)
3993 +#define flush_dcache_page(page)                        do { } while (0)
3994 +#define flush_dcache_mmap_lock(mapping)                do { } while (0)
3995 +#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
3996 +
3997 +#define flush_dcache_range(start, end)                                 \
3998 +do {                                                                   \
3999 +       /* Flush the data cache and invalidate the I cache. */          \
4000 +       local_irq_disable();                                            \
4001 +       mem_cache_control(DCCR_BASE, start, end, CCR_CTRL_FLUSH_ADDR);  \
4002 +       mem_cache_control(ICCR_BASE, start, end, CCR_CTRL_INV_ADDR);    \
4003 +       local_irq_enable();                                             \
4004 +} while (0)
4005 +
4006 +#define flush_icache_range(start, end)                                 \
4007 +do {                                                                   \
4008 +       /* Flush the data cache and invalidate the I cache. */          \
4009 +       local_irq_disable();                                            \
4010 +       mem_cache_control(DCCR_BASE, start, end, CCR_CTRL_FLUSH_ADDR);  \
4011 +       mem_cache_control(ICCR_BASE, start, end, CCR_CTRL_INV_ADDR);    \
4012 +       local_irq_enable();                                             \
4013 +} while (0)
4014 +
4015 +#define flush_icache_page(vma,pg)              do { } while (0)
4016 +#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
4017 +#define flush_cache_vmap(start, end)           do { } while (0)
4018 +#define flush_cache_vunmap(start, end)         do { } while (0)
4019 +
4020 +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
4021 +       memcpy(dst, src, len)
4022 +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
4023 +       memcpy(dst, src, len)
4024 +
4025 +/*
4026 + * Cache handling for IP5000
4027 + */
4028 +extern inline void mem_cache_invalidate_all(unsigned long cc)
4029 +{
4030 +       asm volatile (
4031 +       "       bset    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)"      \n\t"
4032 +       "       nop                                                                     \n\t"
4033 +       "       bclr    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)"      \n\t"
4034 +       "       pipe_flush 0                                                            \n\t"
4035 +               :
4036 +               : "a"(cc)
4037 +               : "cc"
4038 +       );
4039 +}
4040 +
4041 +static inline void __flush_cache_all(void)
4042 +{
4043 +       /*
4044 +        * Flush Icache
4045 +        */
4046 +       mem_cache_invalidate_all(ICCR_BASE);
4047 +
4048 +       /*
4049 +        * Flush Dcache
4050 +        */
4051 +       mem_cache_invalidate_all(DCCR_BASE);
4052 +}
4053 +
4054 +#endif /* _ASM_UBICOM32_CACHEFLUSH_H */
4055 --- /dev/null
4056 +++ b/arch/ubicom32/include/asm/cache.h
4057 @@ -0,0 +1,40 @@
4058 +/*
4059 + * arch/ubicom32/include/asm/cache.h
4060 + *   Cache line definitions for Ubicom32 architecture.
4061 + *
4062 + * (C) Copyright 2009, Ubicom, Inc.
4063 + *
4064 + * This file is part of the Ubicom32 Linux Kernel Port.
4065 + *
4066 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4067 + * it and/or modify it under the terms of the GNU General Public License
4068 + * as published by the Free Software Foundation, either version 2 of the
4069 + * License, or (at your option) any later version.
4070 + *
4071 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4072 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4073 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4074 + * the GNU General Public License for more details.
4075 + *
4076 + * You should have received a copy of the GNU General Public License
4077 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4078 + * see <http://www.gnu.org/licenses/>.
4079 + *
4080 + * Ubicom32 implementation derived from (with many thanks):
4081 + *   arch/m68knommu
4082 + *   arch/blackfin
4083 + *   arch/parisc
4084 + */
4085 +#ifndef _ASM_UBICOM32_CACHE_H
4086 +#define _ASM_UBICOM32_CACHE_H
4087 +
4088 +/*
4089 + * bytes per L1 cache line
4090 + */
4091 +#define L1_CACHE_SHIFT  5
4092 +#define L1_CACHE_BYTES  (1 << L1_CACHE_SHIFT)
4093 +
4094 +#define __cacheline_aligned
4095 +#define ____cacheline_aligned
4096 +
4097 +#endif /* _ASM_UBICOM32_CACHE_H */
4098 --- /dev/null
4099 +++ b/arch/ubicom32/include/asm/checksum.h
4100 @@ -0,0 +1,149 @@
4101 +/*
4102 + * arch/ubicom32/include/asm/checksum.h
4103 + *   Checksum utilities for Ubicom32 architecture.
4104 + *
4105 + * (C) Copyright 2009, Ubicom, Inc.
4106 + *
4107 + * This file is part of the Ubicom32 Linux Kernel Port.
4108 + *
4109 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4110 + * it and/or modify it under the terms of the GNU General Public License
4111 + * as published by the Free Software Foundation, either version 2 of the
4112 + * License, or (at your option) any later version.
4113 + *
4114 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4115 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4116 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4117 + * the GNU General Public License for more details.
4118 + *
4119 + * You should have received a copy of the GNU General Public License
4120 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4121 + * see <http://www.gnu.org/licenses/>.
4122 + *
4123 + * Ubicom32 implementation derived from (with many thanks):
4124 + *   arch/m68knommu
4125 + *   arch/blackfin
4126 + *   arch/parisc
4127 + */
4128 +#ifndef _ASM_UBICOM32_CHECKSUM_H
4129 +#define _ASM_UBICOM32_CHECKSUM_H
4130 +
4131 +#include <linux/in6.h>
4132 +
4133 +/*
4134 + * computes the checksum of a memory block at buff, length len,
4135 + * and adds in "sum" (32-bit)
4136 + *
4137 + * returns a 32-bit number suitable for feeding into itself
4138 + * or csum_tcpudp_magic
4139 + *
4140 + * this function must be called with even lengths, except
4141 + * for the last fragment, which may be odd
4142 + *
4143 + * it's best to have buff aligned on a 32-bit boundary
4144 + */
4145 +__wsum csum_partial(const void *buff, int len, __wsum sum);
4146 +
4147 +/*
4148 + * the same as csum_partial, but copies from src while it
4149 + * checksums
4150 + *
4151 + * here even more important to align src and dst on a 32-bit (or even
4152 + * better 64-bit) boundary
4153 + */
4154 +
4155 +__wsum csum_partial_copy_nocheck(const void *src, void *dst,
4156 +       int len, __wsum sum);
4157 +
4158 +
4159 +/*
4160 + * the same as csum_partial_copy, but copies from user space.
4161 + *
4162 + * here even more important to align src and dst on a 32-bit (or even
4163 + * better 64-bit) boundary
4164 + */
4165 +
4166 +extern __wsum csum_partial_copy_from_user(const void __user *src,
4167 +       void *dst, int len, __wsum sum, int *csum_err);
4168 +
4169 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
4170 +
4171 +/*
4172 + *     Fold a partial checksum
4173 + */
4174 +
4175 +static inline __sum16 csum_fold(__wsum sum)
4176 +{
4177 +       asm volatile (
4178 +       "       lsr.4   d15, %0, #16    \n\t"
4179 +       "       bfextu  %0, %0, #16     \n\t"
4180 +       "       add.4   %0, d15, %0     \n\t"
4181 +       "       lsr.4   d15, %0, #16    \n\t"
4182 +       "       bfextu  %0, %0, #16     \n\t"
4183 +       "       add.4   %0, d15, %0     \n\t"
4184 +               : "=&d" (sum)
4185 +               : "0"(sum)
4186 +               : "d15"
4187 +       );
4188 +       return (__force __sum16)~sum;
4189 +}
4190 +
4191 +
4192 +/*
4193 + * computes the checksum of the TCP/UDP pseudo-header
4194 + * returns a 16-bit checksum, already complemented
4195 + */
4196 +
4197 +static inline __wsum
4198 +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
4199 +                 unsigned short proto, __wsum sum)
4200 +{
4201 +       asm volatile (
4202 +       "       add.4   %0, %2, %0      \n\t"
4203 +       "       addc    %0, %3, %0      \n\t"
4204 +       "       addc    %0, %4, %0      \n\t"
4205 +       "       addc    %0, %5, %0      \n\t"
4206 +       "       addc    %0, #0, %0      \n\t"
4207 +               : "=&d" (sum)
4208 +               : "0"(sum), "r" (saddr), "r" (daddr), "r" (len), "r"(proto)
4209 +       );
4210 +       return sum;
4211 +}
4212 +
4213 +static inline __sum16
4214 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
4215 +                 unsigned short proto, __wsum sum)
4216 +{
4217 +       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
4218 +}
4219 +
4220 +/*
4221 + * this routine is used for miscellaneous IP-like checksums, mainly
4222 + * in icmp.c
4223 + */
4224 +extern __sum16 ip_compute_csum(const void *buff, int len);
4225 +
4226 +#define _HAVE_ARCH_IPV6_CSUM
4227 +
4228 +static __inline__ __sum16
4229 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
4230 +               __u32 len, unsigned short proto, __wsum sum)
4231 +{
4232 +       asm volatile (
4233 +       "       add.4   %0, 0(%2), %0   \n\t"
4234 +       "       addc    %0, 4(%2), %0   \n\t"
4235 +       "       addc    %0, 8(%2), %0   \n\t"
4236 +       "       addc    %0, 12(%2), %0  \n\t"
4237 +       "       addc    %0, 0(%3), %0   \n\t"
4238 +       "       addc    %0, 4(%3), %0   \n\t"
4239 +       "       addc    %0, 8(%3), %0   \n\t"
4240 +       "       addc    %0, 12(%3), %0  \n\t"
4241 +       "       addc    %0, %4, %0      \n\t"
4242 +       "       addc    %0, #0, %0      \n\t"
4243 +               : "=&d" (sum)
4244 +               : "0" (sum), "a" (saddr), "a" (daddr), "d" (len + proto)
4245 +       );
4246 +       return csum_fold(sum);
4247 +}
4248 +
4249 +#endif /* _ASM_UBICOM32_CHECKSUM_H */
4250 --- /dev/null
4251 +++ b/arch/ubicom32/include/asm/cpu.h
4252 @@ -0,0 +1,45 @@
4253 +/*
4254 + * arch/ubicom32/include/asm/cpu.h
4255 + *   CPU definitions for Ubicom32 architecture.
4256 + *
4257 + * (C) Copyright 2009, Ubicom, Inc.
4258 + * Copyright (C) 2004-2005 ARM Ltd.
4259 + *
4260 + * This file is part of the Ubicom32 Linux Kernel Port.
4261 + *
4262 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4263 + * it and/or modify it under the terms of the GNU General Public License
4264 + * as published by the Free Software Foundation, either version 2 of the
4265 + * License, or (at your option) any later version.
4266 + *
4267 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4268 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4269 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4270 + * the GNU General Public License for more details.
4271 + *
4272 + * You should have received a copy of the GNU General Public License
4273 + * along with the Ubicom32 Linux Kernel Port.  If not,
4274 + * see <http://www.gnu.org/licenses/>.
4275 + *
4276 + * Ubicom32 implementation derived from (with many thanks):
4277 + *   arch/m68knommu
4278 + *   arch/blackfin
4279 + *   arch/parisc
4280 + */
4281 +#ifndef _ASM_UBICOM32_CPU_H
4282 +#define _ASM_UBICOM32_CPU_H
4283 +
4284 +#include <linux/percpu.h>
4285 +
4286 +struct cpuinfo_ubicom32 {
4287 +       unsigned long tid;                      /* Hardware thread number */
4288 +
4289 +#ifdef CONFIG_SMP
4290 +       volatile unsigned long ipi_pending;     /* Bit map of operations to execute */
4291 +       unsigned long ipi_count;                /* Number of IPI(s) taken on this cpu */
4292 +#endif
4293 +};
4294 +
4295 +DECLARE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
4296 +
4297 +#endif /* _ASM_UBICOM32_CPU_H */
4298 --- /dev/null
4299 +++ b/arch/ubicom32/include/asm/cputime.h
4300 @@ -0,0 +1,33 @@
4301 +/*
4302 + * arch/ubicom32/include/asm/cputime.h
4303 + *   Generic cputime.h for Ubicom32 architecture.
4304 + *
4305 + * (C) Copyright 2009, Ubicom, Inc.
4306 + *
4307 + * This file is part of the Ubicom32 Linux Kernel Port.
4308 + *
4309 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4310 + * it and/or modify it under the terms of the GNU General Public License
4311 + * as published by the Free Software Foundation, either version 2 of the
4312 + * License, or (at your option) any later version.
4313 + *
4314 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4315 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4316 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4317 + * the GNU General Public License for more details.
4318 + *
4319 + * You should have received a copy of the GNU General Public License
4320 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4321 + * see <http://www.gnu.org/licenses/>.
4322 + *
4323 + * Ubicom32 implementation derived from (with many thanks):
4324 + *   arch/m68knommu
4325 + *   arch/blackfin
4326 + *   arch/parisc
4327 + */
4328 +#ifndef _ASM_UBICOM32_CPUTIME_H
4329 +#define _ASM_UBICOM32_CPUTIME_H
4330 +
4331 +#include <asm-generic/cputime.h>
4332 +
4333 +#endif /* _ASM_UBICOM32_CPUTIME_H */
4334 --- /dev/null
4335 +++ b/arch/ubicom32/include/asm/current.h
4336 @@ -0,0 +1,44 @@
4337 +/*
4338 + * arch/ubicom32/include/asm/current.h
4339 + *   Definition of get_current() for Ubicom32 architecture.
4340 + *
4341 + * (C) Copyright 2009, Ubicom, Inc.
4342 + * (C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
4343 + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
4344 + *
4345 + * This file is part of the Ubicom32 Linux Kernel Port.
4346 + *
4347 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4348 + * it and/or modify it under the terms of the GNU General Public License
4349 + * as published by the Free Software Foundation, either version 2 of the
4350 + * License, or (at your option) any later version.
4351 + *
4352 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4353 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4354 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4355 + * the GNU General Public License for more details.
4356 + *
4357 + * You should have received a copy of the GNU General Public License
4358 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4359 + * see <http://www.gnu.org/licenses/>.
4360 + *
4361 + * Ubicom32 implementation derived from (with many thanks):
4362 + *   arch/m68knommu
4363 + *   arch/blackfin
4364 + *   arch/parisc
4365 + */
4366 +#ifndef _ASM_UBICOM32_CURRENT_H
4367 +#define _ASM_UBICOM32_CURRENT_H
4368 +
4369 +#include <linux/thread_info.h>
4370 +
4371 +struct task_struct;
4372 +
4373 +static inline struct task_struct *get_current(void)
4374 +{
4375 +       return(current_thread_info()->task);
4376 +}
4377 +
4378 +#define        current get_current()
4379 +
4380 +#endif /* _ASM_UBICOM32_CURRENT_H */
4381 --- /dev/null
4382 +++ b/arch/ubicom32/include/asm/delay.h
4383 @@ -0,0 +1,75 @@
4384 +/*
4385 + * arch/ubicom32/include/asm/delay.h
4386 + *   Definition of delay routines for Ubicom32 architecture.
4387 + *
4388 + * (C) Copyright 2009, Ubicom, Inc.
4389 + *
4390 + * This file is part of the Ubicom32 Linux Kernel Port.
4391 + *
4392 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4393 + * it and/or modify it under the terms of the GNU General Public License
4394 + * as published by the Free Software Foundation, either version 2 of the
4395 + * License, or (at your option) any later version.
4396 + *
4397 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4398 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4399 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4400 + * the GNU General Public License for more details.
4401 + *
4402 + * You should have received a copy of the GNU General Public License
4403 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4404 + * see <http://www.gnu.org/licenses/>.
4405 + *
4406 + * Ubicom32 implementation derived from (with many thanks):
4407 + *   arch/m68knommu
4408 + *   arch/blackfin
4409 + *   arch/parisc
4410 + */
4411 +#ifndef _ASM_UBICOM32_DELAY_H
4412 +#define _ASM_UBICOM32_DELAY_H
4413 +
4414 +#include <asm/param.h>
4415 +#include <asm/ip5000.h>
4416 +
4417 +static inline void __delay(unsigned long loops)
4418 +{
4419 +       if (loops == 0) {
4420 +               return;
4421 +       }
4422 +
4423 +       asm volatile (
4424 +       "1:     add.4   %0, #-1, %0             \n\t"
4425 +       "       jmpne.t 1b                      \n\t"
4426 +       : "+d" (loops)
4427 +       );
4428 +}
4429 +
4430 +/*
4431 + *     Ubicom32 processor uses fixed 12MHz external OSC.
4432 + *     So we use that as reference to count 12 cycles/us
4433 + */
4434 +
4435 +extern unsigned long loops_per_jiffy;
4436 +
4437 +static inline void _udelay(unsigned long usecs)
4438 +{
4439 +#if defined(CONFIG_UBICOM32_V4) || defined(CONFIG_UBICOM32_V3)
4440 +       asm volatile (
4441 +               "       add.4           d15, 0(%0), %1                  \n\t"
4442 +               "       sub.4           #0, 0(%0), d15                  \n\t"
4443 +               "       jmpmi.w.f       .-4                             \n\t"
4444 +               :
4445 +               : "a"(TIMER_BASE + TIMER_MPTVAL), "d"(usecs * (12000000/1000000))
4446 +               : "d15"
4447 +       );
4448 +#else
4449 +       BUG();
4450 +#endif
4451 +}
4452 +
4453 +/*
4454 + *     Moved the udelay() function into library code, no longer inlined.
4455 + */
4456 +extern void udelay(unsigned long usecs);
4457 +
4458 +#endif /* _ASM_UBICOM32_DELAY_H */
4459 --- /dev/null
4460 +++ b/arch/ubicom32/include/asm/device.h
4461 @@ -0,0 +1,35 @@
4462 +/*
4463 + * arch/ubicom32/include/asm/device.h
4464 + *   Generic device.h for Ubicom32 architecture.
4465 + *
4466 + *   Used for arch specific extensions to struct device
4467 + *
4468 + * (C) Copyright 2009, Ubicom, Inc.
4469 + *
4470 + * This file is part of the Ubicom32 Linux Kernel Port.
4471 + *
4472 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4473 + * it and/or modify it under the terms of the GNU General Public License
4474 + * as published by the Free Software Foundation, either version 2 of the
4475 + * License, or (at your option) any later version.
4476 + *
4477 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4478 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4479 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4480 + * the GNU General Public License for more details.
4481 + *
4482 + * You should have received a copy of the GNU General Public License
4483 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4484 + * see <http://www.gnu.org/licenses/>.
4485 + *
4486 + * Ubicom32 implementation derived from (with many thanks):
4487 + *   arch/m68knommu
4488 + *   arch/blackfin
4489 + *   arch/parisc
4490 + */
4491 +#ifndef _ASM_UBICOM32_DEVICE_H
4492 +#define _ASM_UBICOM32_DEVICE_H
4493 +
4494 +#include <asm-generic/device.h>
4495 +
4496 +#endif /* _ASM_UBICOM32_DEVICE_H */
4497 --- /dev/null
4498 +++ b/arch/ubicom32/include/asm/devtree.h
4499 @@ -0,0 +1,52 @@
4500 +/*
4501 + * arch/ubicom32/include/asm/devtree.h
4502 + *   Device Tree Header File (Shared between ultra and the Host OS)
4503 + *
4504 + * (C) Copyright 2009, Ubicom, Inc.
4505 + *
4506 + * This file is part of the Ubicom32 Linux Kernel Port.
4507 + *
4508 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4509 + * it and/or modify it under the terms of the GNU General Public License
4510 + * as published by the Free Software Foundation, either version 2 of the
4511 + * License, or (at your option) any later version.
4512 + *
4513 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4514 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4515 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4516 + * the GNU General Public License for more details.
4517 + *
4518 + * You should have received a copy of the GNU General Public License
4519 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4520 + * see <http://www.gnu.org/licenses/>.
4521 + *
4522 + * Ubicom32 implementation derived from (with many thanks):
4523 + *   arch/m68knommu
4524 + *   arch/blackfin
4525 + *   arch/parisc
4526 + */
4527 +
4528 +#ifndef _ASM_UBICOM32_DEVTREE_H
4529 +#define _ASM_UBICOM32_DEVTREE_H
4530 +
4531 +#define DEVTREE_MAX_NAME 32
4532 +#define DEVTREE_IRQ_NONE 0xff
4533 +#define DEVTREE_IRQ_DONTCARE 0xff
4534 +#define DEVTREE_NODE_MAGIC 0x10203040
4535 +
4536 +struct devtree_node {
4537 +       struct devtree_node *next;
4538 +       unsigned char sendirq;
4539 +       unsigned char recvirq;
4540 +       char name[DEVTREE_MAX_NAME];
4541 +       unsigned int magic;
4542 +};
4543 +
4544 +extern struct devtree_node *devtree;
4545 +extern struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq);
4546 +extern struct devtree_node *devtree_find_node(const char *str);
4547 +extern struct devtree_node *devtree_find_next(struct devtree_node **cur);
4548 +extern int devtree_irq(struct devtree_node *dn, unsigned char *sendirq, unsigned char *recvirq);
4549 +extern void devtree_print(void);
4550 +
4551 +#endif /* _ASM_UBICOM32_DEVTREE_H */
4552 --- /dev/null
4553 +++ b/arch/ubicom32/include/asm/div64.h
4554 @@ -0,0 +1,33 @@
4555 +/*
4556 + * arch/ubicom32/include/asm/div64.h
4557 + *   Generic div64.h for Ubicom32 architecture.
4558 + *
4559 + * (C) Copyright 2009, Ubicom, Inc.
4560 + *
4561 + * This file is part of the Ubicom32 Linux Kernel Port.
4562 + *
4563 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4564 + * it and/or modify it under the terms of the GNU General Public License
4565 + * as published by the Free Software Foundation, either version 2 of the
4566 + * License, or (at your option) any later version.
4567 + *
4568 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4569 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4570 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4571 + * the GNU General Public License for more details.
4572 + *
4573 + * You should have received a copy of the GNU General Public License
4574 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4575 + * see <http://www.gnu.org/licenses/>.
4576 + *
4577 + * Ubicom32 implementation derived from (with many thanks):
4578 + *   arch/m68knommu
4579 + *   arch/blackfin
4580 + *   arch/parisc
4581 + */
4582 +#ifndef _ASM_UBICOM32_DIV64_H
4583 +#define _ASM_UBICOM32_DIV64_H
4584 +
4585 +#include <asm-generic/div64.h>
4586 +
4587 +#endif /* _ASM_UBICOM32_DIV64_H */
4588 --- /dev/null
4589 +++ b/arch/ubicom32/include/asm/dma.h
4590 @@ -0,0 +1,34 @@
4591 +/*
4592 + * arch/ubicom32/include/asm/dma.h
4593 + *   DMA definitions for Ubicom32 architecture.
4594 + *
4595 + * (C) Copyright 2009, Ubicom, Inc.
4596 + *
4597 + * This file is part of the Ubicom32 Linux Kernel Port.
4598 + *
4599 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4600 + * it and/or modify it under the terms of the GNU General Public License
4601 + * as published by the Free Software Foundation, either version 2 of the
4602 + * License, or (at your option) any later version.
4603 + *
4604 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4605 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4606 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4607 + * the GNU General Public License for more details.
4608 + *
4609 + * You should have received a copy of the GNU General Public License
4610 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4611 + * see <http://www.gnu.org/licenses/>.
4612 + *
4613 + * Ubicom32 implementation derived from (with many thanks):
4614 + *   arch/m68knommu
4615 + *   arch/blackfin
4616 + *   arch/parisc
4617 + */
4618 +#ifndef _ASM_UBICOM32_DMA_H
4619 +#define _ASM_UBICOM32_DMA_H
4620 +
4621 +/* Nothing so far */
4622 +#define MAX_DMA_ADDRESS 0x00   /* This is quite suspicious */
4623 +
4624 +#endif /* _ASM_UBICOM32_DMA_H */
4625 --- /dev/null
4626 +++ b/arch/ubicom32/include/asm/dma-mapping.h
4627 @@ -0,0 +1,34 @@
4628 +/*
4629 + * arch/ubicom32/include/asm/dma-mapping.h
4630 + *   Generic dma-mapping.h for Ubicom32 architecture.
4631 + *
4632 + * (C) Copyright 2009, Ubicom, Inc.
4633 + *
4634 + * This file is part of the Ubicom32 Linux Kernel Port.
4635 + *
4636 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4637 + * it and/or modify it under the terms of the GNU General Public License
4638 + * as published by the Free Software Foundation, either version 2 of the
4639 + * License, or (at your option) any later version.
4640 + *
4641 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4642 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4643 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4644 + * the GNU General Public License for more details.
4645 + *
4646 + * You should have received a copy of the GNU General Public License
4647 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4648 + * see <http://www.gnu.org/licenses/>.
4649 + *
4650 + * Ubicom32 implementation derived from (with many thanks):
4651 + *   arch/m68knommu
4652 + *   arch/blackfin
4653 + *   arch/parisc
4654 + */
4655 +#ifndef _ASM_UBICOM32_DMA_MAPPING_H
4656 +#define _ASM_UBICOM32_DMA_MAPPING_H
4657 +
4658 +#include <linux/scatterlist.h>
4659 +#include <asm-generic/dma-mapping.h>
4660 +
4661 +#endif /* _ASM_UBICOM32_DMA_MAPPING_H */
4662 --- /dev/null
4663 +++ b/arch/ubicom32/include/asm/elf.h
4664 @@ -0,0 +1,167 @@
4665 +/*
4666 + * arch/ubicom32/include/asm/elf.h
4667 + *   Definitions for elf executable format for Ubicom32 architecture.
4668 + *
4669 + * (C) Copyright 2009, Ubicom, Inc.
4670 + *
4671 + * This file is part of the Ubicom32 Linux Kernel Port.
4672 + *
4673 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4674 + * it and/or modify it under the terms of the GNU General Public License
4675 + * as published by the Free Software Foundation, either version 2 of the
4676 + * License, or (at your option) any later version.
4677 + *
4678 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4679 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4680 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4681 + * the GNU General Public License for more details.
4682 + *
4683 + * You should have received a copy of the GNU General Public License
4684 + * along with the Ubicom32 Linux Kernel Port.  If not,
4685 + * see <http://www.gnu.org/licenses/>.
4686 + *
4687 + * Ubicom32 implementation derived from (with many thanks):
4688 + *   arch/m68knommu
4689 + *   arch/blackfin
4690 + *   arch/parisc
4691 + */
4692 +#ifndef _ASM_UBICOM32_ELF_H
4693 +#define _ASM_UBICOM32_ELF_H
4694 +
4695 +/*
4696 + * ELF register definitions..
4697 + */
4698 +
4699 +#include <asm/ptrace.h>
4700 +#include <asm/user.h>
4701 +
4702 +/*
4703 + * Processor specific flags for the ELF header e_flags field.
4704 + */
4705 +#define EF_UBICOM32_V3         0x00000001      /* -fmarch=ubicom32v3 */
4706 +#define EF_UBICOM32_V4         0x00000002      /* -fmarch=ubicom32v4 */
4707 +#define EF_UBICOM32_PIC                0x80000000      /* -fpic */
4708 +#define EF_UBICOM32_FDPIC      0x40000000      /* -mfdpic */
4709 +
4710 +/*
4711 + * Ubicom32 ELF relocation types
4712 + */
4713 +#define R_UBICOM32_NONE                        0
4714 +#define R_UBICOM32_16                  1
4715 +#define R_UBICOM32_32                  2
4716 +#define R_UBICOM32_LO16                        3
4717 +#define R_UBICOM32_HI16                        4
4718 +#define R_UBICOM32_21_PCREL            5
4719 +#define R_UBICOM32_24_PCREL            6
4720 +#define R_UBICOM32_HI24                        7
4721 +#define R_UBICOM32_LO7_S               8
4722 +#define R_UBICOM32_LO7_2_S             9
4723 +#define R_UBICOM32_LO7_4_S             10
4724 +#define R_UBICOM32_LO7_D               11
4725 +#define R_UBICOM32_LO7_2_D             12
4726 +#define R_UBICOM32_LO7_4_D             13
4727 +#define R_UBICOM32_32_HARVARD          14
4728 +#define R_UBICOM32_LO7_CALLI           15
4729 +#define R_UBICOM32_LO16_CALLI          16
4730 +#define R_UBICOM32_GOT_HI24            17
4731 +#define R_UBICOM32_GOT_LO7_S           18
4732 +#define R_UBICOM32_GOT_LO7_2_S         19
4733 +#define R_UBICOM32_GOT_LO7_4_S         20
4734 +#define R_UBICOM32_GOT_LO7_D           21
4735 +#define R_UBICOM32_GOT_LO7_2_D         22
4736 +#define R_UBICOM32_GOT_LO7_4_D         23
4737 +#define R_UBICOM32_FUNCDESC_GOT_HI24    24
4738 +#define R_UBICOM32_FUNCDESC_GOT_LO7_S   25
4739 +#define R_UBICOM32_FUNCDESC_GOT_LO7_2_S 26
4740 +#define R_UBICOM32_FUNCDESC_GOT_LO7_4_S 27
4741 +#define R_UBICOM32_FUNCDESC_GOT_LO7_D   28
4742 +#define R_UBICOM32_FUNCDESC_GOT_LO7_2_D 29
4743 +#define R_UBICOM32_FUNCDESC_GOT_LO7_4_D 30
4744 +#define R_UBICOM32_GOT_LO7_CALLI        31
4745 +#define R_UBICOM32_FUNCDESC_GOT_LO7_CALLI 32
4746 +#define R_UBICOM32_FUNCDESC_VALUE       33
4747 +#define R_UBICOM32_FUNCDESC             34
4748 +#define R_UBICOM32_GOTOFFSET_LO         35
4749 +#define R_UBICOM32_GOTOFFSET_HI         36
4750 +#define R_UBICOM32_FUNCDESC_GOTOFFSET_LO 37
4751 +#define R_UBICOM32_FUNCDESC_GOTOFFSET_HI 38
4752 +#define R_UBICOM32_GNU_VTINHERIT        200
4753 +#define R_UBICOM32_GNU_VTENTRY          201
4754 +
4755 +typedef unsigned long elf_greg_t;
4756 +
4757 +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
4758 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
4759 +
4760 +typedef struct user_ubicom32fp_struct elf_fpregset_t;
4761 +
4762 +/*
4763 + * This is used to ensure we don't load something for the wrong architecture.
4764 + */
4765 +#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
4766 +
4767 +#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
4768 +
4769 +#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
4770 +
4771 +/*
4772 + * These are used to set parameters in the core dumps.
4773 + */
4774 +#define ELF_CLASS      ELFCLASS32
4775 +#define ELF_DATA       ELFDATA2MSB
4776 +#define ELF_ARCH       EM_UBICOM32
4777 +
4778 +/* For SVR4/m68k the function pointer to be registered with `atexit' is
4779 +   passed in %a1.  Although my copy of the ABI has no such statement, it
4780 +   is actually used on ASV.  */
4781 +#define ELF_PLAT_INIT(_r, load_addr)   _r->a1 = 0
4782 +
4783 +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr,   \
4784 +                           _dynamic_addr)                              \
4785 +       do {                                                            \
4786 +               _regs->dn[1]    = _exec_map_addr;                       \
4787 +               _regs->dn[2]    = _interp_map_addr;                     \
4788 +               _regs->dn[3]    = _dynamic_addr;                        \
4789 +               _regs->an[1]    = 0; /* dl_fini will be set by ldso */  \
4790 +       } while (0)
4791 +
4792 +#define USE_ELF_CORE_DUMP
4793 +#define ELF_EXEC_PAGESIZE      4096
4794 +
4795 +#ifdef __KERNEL__
4796 +#ifdef CONFIG_UBICOM32_V4
4797 +#define ELF_FDPIC_CORE_EFLAGS  (EF_UBICOM32_FDPIC | EF_UBICOM32_V4)
4798 +#elif defined CONFIG_UBICOM32_V3
4799 +#define ELF_FDPIC_CORE_EFLAGS  (EF_UBICOM32_FDPIC | EF_UBICOM32_V3)
4800 +#else
4801 +#error Unknown/Unsupported ubicom32 architecture.
4802 +#endif
4803 +#endif
4804 +
4805 +/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
4806 +   use of this is to invoke "./ld.so someprog" to test out a new version of
4807 +   the loader.  We need to make sure that it is out of the way of the program
4808 +   that it will "exec", and that there is sufficient room for the brk.  */
4809 +
4810 +#define ELF_ET_DYN_BASE         0xD0000000UL
4811 +
4812 +/*
4813 + * For Ubicom32, the elf_gregset_t and struct pt_regs are the same size
4814 + * data structure so a copy is performed instead of providing the
4815 + * ELF_CORE_COPY_REGS macro.
4816 + */
4817 +
4818 +/* This yields a mask that user programs can use to figure out what
4819 +   instruction set this cpu supports.  */
4820 +
4821 +#define ELF_HWCAP      (0)
4822 +
4823 +/* This yields a string that ld.so will use to load implementation
4824 +   specific libraries for optimization.  This is more specific in
4825 +   intent than poking at uname or /proc/cpuinfo.  */
4826 +
4827 +#define ELF_PLATFORM  (NULL)
4828 +
4829 +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
4830 +
4831 +#endif /* _ASM_UBICOM32_ELF_H */
4832 --- /dev/null
4833 +++ b/arch/ubicom32/include/asm/emergency-restart.h
4834 @@ -0,0 +1,33 @@
4835 +/*
4836 + * arch/ubicom32/include/asm/emergency-restart.h
4837 + *   Generic emergency-restart.h for Ubicom32 architecture.
4838 + *
4839 + * (C) Copyright 2009, Ubicom, Inc.
4840 + *
4841 + * This file is part of the Ubicom32 Linux Kernel Port.
4842 + *
4843 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4844 + * it and/or modify it under the terms of the GNU General Public License
4845 + * as published by the Free Software Foundation, either version 2 of the
4846 + * License, or (at your option) any later version.
4847 + *
4848 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4849 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4850 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4851 + * the GNU General Public License for more details.
4852 + *
4853 + * You should have received a copy of the GNU General Public License
4854 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4855 + * see <http://www.gnu.org/licenses/>.
4856 + *
4857 + * Ubicom32 implementation derived from (with many thanks):
4858 + *   arch/m68knommu
4859 + *   arch/blackfin
4860 + *   arch/parisc
4861 + */
4862 +#ifndef _ASM_UBICOM32_EMERGENCY_RESTART_H
4863 +#define _ASM_UBICOM32_EMERGENCY_RESTART_H
4864 +
4865 +#include <asm-generic/emergency-restart.h>
4866 +
4867 +#endif /* _ASM_UBICOM32_EMERGENCY_RESTART_H */
4868 --- /dev/null
4869 +++ b/arch/ubicom32/include/asm/entry.h
4870 @@ -0,0 +1,34 @@
4871 +/*
4872 + * arch/ubicom32/include/asm/entry.h
4873 + *   Entry register/stack definitions for Ubicom32 architecture.
4874 + *
4875 + * (C) Copyright 2009, Ubicom, Inc.
4876 + *
4877 + * This file is part of the Ubicom32 Linux Kernel Port.
4878 + *
4879 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4880 + * it and/or modify it under the terms of the GNU General Public License
4881 + * as published by the Free Software Foundation, either version 2 of the
4882 + * License, or (at your option) any later version.
4883 + *
4884 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4885 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4886 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4887 + * the GNU General Public License for more details.
4888 + *
4889 + * You should have received a copy of the GNU General Public License
4890 + * along with the Ubicom32 Linux Kernel Port.  If not,
4891 + * see <http://www.gnu.org/licenses/>.
4892 + *
4893 + * Ubicom32 implementation derived from (with many thanks):
4894 + *   arch/m68knommu
4895 + *   arch/blackfin
4896 + *   arch/parisc
4897 + */
4898 +#ifndef _ASM_UBICOM32_ENTRY_H
4899 +#define _ASM_UBICOM32_ENTRY_H
4900 +
4901 +#include <asm/setup.h>
4902 +#include <asm/page.h>
4903 +
4904 +#endif /* _ASM_UBICOM32_ENTRY_H */
4905 --- /dev/null
4906 +++ b/arch/ubicom32/include/asm/errno.h
4907 @@ -0,0 +1,33 @@
4908 +/*
4909 + * arch/ubicom32/include/asm/errno.h
4910 + *   Generic errno.h for Ubicom32 architecture.
4911 + *
4912 + * (C) Copyright 2009, Ubicom, Inc.
4913 + *
4914 + * This file is part of the Ubicom32 Linux Kernel Port.
4915 + *
4916 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4917 + * it and/or modify it under the terms of the GNU General Public License
4918 + * as published by the Free Software Foundation, either version 2 of the
4919 + * License, or (at your option) any later version.
4920 + *
4921 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4922 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4923 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4924 + * the GNU General Public License for more details.
4925 + *
4926 + * You should have received a copy of the GNU General Public License
4927 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4928 + * see <http://www.gnu.org/licenses/>.
4929 + *
4930 + * Ubicom32 implementation derived from (with many thanks):
4931 + *   arch/m68knommu
4932 + *   arch/blackfin
4933 + *   arch/parisc
4934 + */
4935 +#ifndef _ASM_UBICOM32_ERRNO_H
4936 +#define _ASM_UBICOM32_ERRNO_H
4937 +
4938 +#include <asm-generic/errno.h>
4939 +
4940 +#endif /* _ASM_UBICOM32_ERRNO_H */
4941 --- /dev/null
4942 +++ b/arch/ubicom32/include/asm/fb.h
4943 @@ -0,0 +1,39 @@
4944 +/*
4945 + * arch/ubicom32/include/asm/fb.h
4946 + *   Definition of fb_is_primary_device() for Ubicom32 architecture.
4947 + *
4948 + * (C) Copyright 2009, Ubicom, Inc.
4949 + *
4950 + * This file is part of the Ubicom32 Linux Kernel Port.
4951 + *
4952 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4953 + * it and/or modify it under the terms of the GNU General Public License
4954 + * as published by the Free Software Foundation, either version 2 of the
4955 + * License, or (at your option) any later version.
4956 + *
4957 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
4958 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
4959 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
4960 + * the GNU General Public License for more details.
4961 + *
4962 + * You should have received a copy of the GNU General Public License
4963 + * along with the Ubicom32 Linux Kernel Port.  If not, 
4964 + * see <http://www.gnu.org/licenses/>.
4965 + *
4966 + * Ubicom32 implementation derived from (with many thanks):
4967 + *   arch/m68knommu
4968 + *   arch/blackfin
4969 + *   arch/parisc
4970 + */
4971 +#ifndef _ASM_UBICOM32_FB_H
4972 +#define _ASM_UBICOM32_FB_H
4973 +#include <linux/fb.h>
4974 +
4975 +#define fb_pgprotect(...) do {} while (0)
4976 +
4977 +static inline int fb_is_primary_device(struct fb_info *info)
4978 +{
4979 +       return 0;
4980 +}
4981 +
4982 +#endif /* _ASM_UBICOM32_FB_H */
4983 --- /dev/null
4984 +++ b/arch/ubicom32/include/asm/fcntl.h
4985 @@ -0,0 +1,38 @@
4986 +/*
4987 + * arch/ubicom32/include/asm/fcntl.h
4988 + *   File control bit definitions for Ubicom32 architecture.
4989 + *
4990 + * (C) Copyright 2009, Ubicom, Inc.
4991 + *
4992 + * This file is part of the Ubicom32 Linux Kernel Port.
4993 + *
4994 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
4995 + * it and/or modify it under the terms of the GNU General Public License
4996 + * as published by the Free Software Foundation, either version 2 of the
4997 + * License, or (at your option) any later version.
4998 + *
4999 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5000 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5001 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5002 + * the GNU General Public License for more details.
5003 + *
5004 + * You should have received a copy of the GNU General Public License
5005 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5006 + * see <http://www.gnu.org/licenses/>.
5007 + *
5008 + * Ubicom32 implementation derived from (with many thanks):
5009 + *   arch/m68knommu
5010 + *   arch/blackfin
5011 + *   arch/parisc
5012 + */
5013 +#ifndef _ASM_UBICOM32_FCNTL_H
5014 +#define _ASM_UBICOM32_FCNTL_H
5015 +
5016 +#define O_DIRECTORY    040000  /* must be a directory */
5017 +#define O_NOFOLLOW     0100000 /* don't follow links */
5018 +#define O_DIRECT       0200000 /* direct disk access hint - currently ignored */
5019 +#define O_LARGEFILE    0400000
5020 +
5021 +#include <asm-generic/fcntl.h>
5022 +
5023 +#endif /* _ASM_UBICOM32_FCNTL_H */
5024 --- /dev/null
5025 +++ b/arch/ubicom32/include/asm/flat.h
5026 @@ -0,0 +1,73 @@
5027 +/*
5028 + * arch/ubicom32/include/asm/flat.h
5029 + *   Definitions to support flat-format executables.
5030 + *
5031 + * (C) Copyright 2009, Ubicom, Inc.
5032 + *
5033 + * This file is part of the Ubicom32 Linux Kernel Port.
5034 + *
5035 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5036 + * it and/or modify it under the terms of the GNU General Public License
5037 + * as published by the Free Software Foundation, either version 2 of the
5038 + * License, or (at your option) any later version.
5039 + *
5040 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5041 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5042 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5043 + * the GNU General Public License for more details.
5044 + *
5045 + * You should have received a copy of the GNU General Public License
5046 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5047 + * see <http://www.gnu.org/licenses/>.
5048 + *
5049 + * Ubicom32 implementation derived from (with many thanks):
5050 + *   arch/m68knommu
5051 + *   arch/blackfin
5052 + *   arch/parisc
5053 + */
5054 +
5055 +#ifndef _ASM_UBICOM32_FLAT_H
5056 +#define _ASM_UBICOM32_FLAT_H
5057 +
5058 +#define ARCH_FLAT_ALIGN 0x80
5059 +#define ARCH_FLAT_ALIGN_TEXT 1
5060 +
5061 +#define  R_UBICOM32_32         2
5062 +#define  R_UBICOM32_HI24       7
5063 +#define  R_UBICOM32_LO7_S      8
5064 +#define  R_UBICOM32_LO7_2_S    9
5065 +#define  R_UBICOM32_LO7_4_S    10
5066 +#define  R_UBICOM32_LO7_D      11
5067 +#define  R_UBICOM32_LO7_2_D    12
5068 +#define  R_UBICOM32_LO7_4_D    13
5069 +#define  R_UBICOM32_LO7_CALLI  15
5070 +#define  R_UBICOM32_LO16_CALLI 16
5071 +
5072 +extern void ubicom32_flat_put_addr_at_rp(unsigned long *rp, u32_t val, u32_t rval, unsigned long  *p);
5073 +extern unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp, u32_t relval, u32_t flags, unsigned long *p);
5074 +
5075 +#define        flat_stack_align(sp)                    /* nothing needed */
5076 +#define        flat_argvp_envp_on_stack()              1
5077 +#define        flat_old_ram_flag(flags)                (flags)
5078 +#define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
5079 +#define        flat_get_addr_from_rp(rp, relval, flags, p)     (ubicom32_flat_get_addr_from_rp(rp, relval,flags, p))
5080 +#define        flat_put_addr_at_rp(rp, val, relval)    do {ubicom32_flat_put_addr_at_rp(rp, val, relval, &persistent);} while(0)
5081 +#define        flat_get_relocate_addr(rel)             ((persistent) ? (persistent & 0x07ffffff) : (rel & 0x07ffffff))
5082 +
5083 +static inline int flat_set_persistent(unsigned int relval, unsigned long *p)
5084 +{
5085 +       if (*p) {
5086 +               return 0;
5087 +       } else {
5088 +               if ((relval >> 27) != R_UBICOM32_32) {
5089 +                       /*
5090 +                        * Something other than UBICOM32_32. The next entry has the relocation.
5091 +                        */
5092 +                       *p = relval;
5093 +                       return 1;
5094 +               }
5095 +       }
5096 +       return 0;
5097 +}
5098 +
5099 +#endif /* _ASM_UBICOM32_FLAT_H */
5100 --- /dev/null
5101 +++ b/arch/ubicom32/include/asm/fpu.h
5102 @@ -0,0 +1,37 @@
5103 +/*
5104 + * arch/ubicom32/include/asm/fpu.h
5105 + *   Floating point state definitions for Ubicom32 architecture.
5106 + *
5107 + * (C) Copyright 2009, Ubicom, Inc.
5108 + *
5109 + * This file is part of the Ubicom32 Linux Kernel Port.
5110 + *
5111 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5112 + * it and/or modify it under the terms of the GNU General Public License
5113 + * as published by the Free Software Foundation, either version 2 of the
5114 + * License, or (at your option) any later version.
5115 + *
5116 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5117 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5118 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5119 + * the GNU General Public License for more details.
5120 + *
5121 + * You should have received a copy of the GNU General Public License
5122 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5123 + * see <http://www.gnu.org/licenses/>.
5124 + *
5125 + * Ubicom32 implementation derived from (with many thanks):
5126 + *   arch/m68knommu
5127 + *   arch/blackfin
5128 + *   arch/parisc
5129 + */
5130 +#ifndef _ASM_UBICOM32_FPU_H
5131 +#define _ASM_UBICOM32_FPU_H
5132 +
5133 +/*
5134 + * MAX floating point unit state size (FSAVE/FRESTORE)
5135 + */
5136 +/* No FP unit present then... */
5137 +#define FPSTATESIZE (2) /* dummy size */
5138 +
5139 +#endif /* _ASM_UBICOM32_FPU_H */
5140 --- /dev/null
5141 +++ b/arch/ubicom32/include/asm/futex.h
5142 @@ -0,0 +1,33 @@
5143 +/*
5144 + * arch/ubicom32/include/asm/futex.h
5145 + *   Generic futex.h for Ubicom32 architecture.
5146 + *
5147 + * (C) Copyright 2009, Ubicom, Inc.
5148 + *
5149 + * This file is part of the Ubicom32 Linux Kernel Port.
5150 + *
5151 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5152 + * it and/or modify it under the terms of the GNU General Public License
5153 + * as published by the Free Software Foundation, either version 2 of the
5154 + * License, or (at your option) any later version.
5155 + *
5156 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5157 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5158 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5159 + * the GNU General Public License for more details.
5160 + *
5161 + * You should have received a copy of the GNU General Public License
5162 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5163 + * see <http://www.gnu.org/licenses/>.
5164 + *
5165 + * Ubicom32 implementation derived from (with many thanks):
5166 + *   arch/m68knommu
5167 + *   arch/blackfin
5168 + *   arch/parisc
5169 + */
5170 +#ifndef _ASM_UBICOM32_FUTEX_H
5171 +#define _ASM_UBICOM32_FUTEX_H
5172 +
5173 +#include <asm-generic/futex.h>
5174 +
5175 +#endif /* _ASM_UBICOM32_FUTEX_H */
5176 --- /dev/null
5177 +++ b/arch/ubicom32/include/asm/gpio.h
5178 @@ -0,0 +1,451 @@
5179 +/*
5180 + * arch/ubicom32/include/asm/gpio.h
5181 + *   Definitions for GPIO operations on Ubicom32 architecture.
5182 + *
5183 + * (C) Copyright 2009, Ubicom, Inc.
5184 + *
5185 + * This file is part of the Ubicom32 Linux Kernel Port.
5186 + *
5187 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5188 + * it and/or modify it under the terms of the GNU General Public License
5189 + * as published by the Free Software Foundation, either version 2 of the
5190 + * License, or (at your option) any later version.
5191 + *
5192 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5193 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5194 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5195 + * the GNU General Public License for more details.
5196 + *
5197 + * You should have received a copy of the GNU General Public License
5198 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5199 + * see <http://www.gnu.org/licenses/>.
5200 + *
5201 + * Ubicom32 implementation derived from (with many thanks):
5202 + *   arch/m68knommu
5203 + *   arch/blackfin
5204 + *   arch/parisc
5205 + */
5206 +#ifndef _ASM_UBICOM32_GPIO_H
5207 +#define _ASM_UBICOM32_GPIO_H
5208 +
5209 +#include <linux/compiler.h>
5210 +#include <asm/irq.h>
5211 +
5212 +#include <asm/ip5000.h>
5213 +
5214 +#define ARCH_NR_GPIOS           512
5215 +#define MAX_UBICOM_ONCHIP_GPIO   (9 * 32)
5216 +
5217 +/*
5218 + * Macros for manipulating GPIO numbers
5219 + */
5220 +#define gpio_bit(gn)                   (1 << (gn & 0x1f))
5221 +#define gpio_bank(gn)                  (gn >> 5)
5222 +
5223 +#define gpio_pin_index(gn)             (gn & 0x1f)
5224 +#define gpio_port_index(gn)            (gn >> 5)
5225 +
5226 +#define GPIO_RA_0    ((32 * 0) + 0)
5227 +#define GPIO_RA_1    ((32 * 0) + 1)
5228 +#define GPIO_RA_2    ((32 * 0) + 2)
5229 +#define GPIO_RA_3    ((32 * 0) + 3)
5230 +#define GPIO_RA_4    ((32 * 0) + 4)
5231 +#define GPIO_RA_5    ((32 * 0) + 5)
5232 +#define GPIO_RA_6    ((32 * 0) + 6)
5233 +#define GPIO_RA_7    ((32 * 0) + 7)
5234 +
5235 +#define GPIO_RB_0    ((32 * 1) + 0)
5236 +#define GPIO_RB_1    ((32 * 1) + 1)
5237 +#define GPIO_RB_2    ((32 * 1) + 2)
5238 +#define GPIO_RB_3    ((32 * 1) + 3)
5239 +#define GPIO_RB_4    ((32 * 1) + 4)
5240 +#define GPIO_RB_5    ((32 * 1) + 5)
5241 +#define GPIO_RB_6    ((32 * 1) + 6)
5242 +#define GPIO_RB_7    ((32 * 1) + 7)
5243 +#define GPIO_RB_8    ((32 * 1) + 8)
5244 +#define GPIO_RB_9    ((32 * 1) + 9)
5245 +#define GPIO_RB_10   ((32 * 1) + 10)
5246 +#define GPIO_RB_11   ((32 * 1) + 11)
5247 +#define GPIO_RB_12   ((32 * 1) + 12)
5248 +#define GPIO_RB_13   ((32 * 1) + 13)
5249 +#define GPIO_RB_14   ((32 * 1) + 14)
5250 +#define GPIO_RB_15   ((32 * 1) + 15)
5251 +#define GPIO_RB_16   ((32 * 1) + 16)
5252 +#define GPIO_RB_17   ((32 * 1) + 17)
5253 +#define GPIO_RB_18   ((32 * 1) + 18)
5254 +#define GPIO_RB_19   ((32 * 1) + 19)
5255 +
5256 +#define GPIO_RC_0    ((32 * 2) + 0)
5257 +#define GPIO_RC_1    ((32 * 2) + 1)
5258 +#define GPIO_RC_2    ((32 * 2) + 2)
5259 +#define GPIO_RC_3    ((32 * 2) + 3)
5260 +#define GPIO_RC_4    ((32 * 2) + 4)
5261 +#define GPIO_RC_5    ((32 * 2) + 5)
5262 +#define GPIO_RC_6    ((32 * 2) + 6)
5263 +#define GPIO_RC_7    ((32 * 2) + 7)
5264 +#define GPIO_RC_8    ((32 * 2) + 8)
5265 +#define GPIO_RC_9    ((32 * 2) + 9)
5266 +#define GPIO_RC_10   ((32 * 2) + 10)
5267 +#define GPIO_RC_11   ((32 * 2) + 11)
5268 +#define GPIO_RC_12   ((32 * 2) + 12)
5269 +#define GPIO_RC_13   ((32 * 2) + 13)
5270 +#define GPIO_RC_14   ((32 * 2) + 14)
5271 +#define GPIO_RC_15   ((32 * 2) + 15)
5272 +#define GPIO_RC_16   ((32 * 2) + 16)
5273 +#define GPIO_RC_17   ((32 * 2) + 17)
5274 +#define GPIO_RC_18   ((32 * 2) + 18)
5275 +#define GPIO_RC_19   ((32 * 2) + 19)
5276 +#define GPIO_RC_20   ((32 * 2) + 20)
5277 +#define GPIO_RC_21   ((32 * 2) + 21)
5278 +#define GPIO_RC_22   ((32 * 2) + 22)
5279 +#define GPIO_RC_23   ((32 * 2) + 23)
5280 +#define GPIO_RC_24   ((32 * 2) + 24)
5281 +#define GPIO_RC_25   ((32 * 2) + 25)
5282 +#define GPIO_RC_26   ((32 * 2) + 26)
5283 +#define GPIO_RC_27   ((32 * 2) + 27)
5284 +#define GPIO_RC_28   ((32 * 2) + 28)
5285 +#define GPIO_RC_29   ((32 * 2) + 29)
5286 +#define GPIO_RC_30   ((32 * 2) + 30)
5287 +#define GPIO_RC_31   ((32 * 2) + 31)
5288 +
5289 +#define GPIO_RD_0    ((32 * 3) + 0)
5290 +#define GPIO_RD_1    ((32 * 3) + 1)
5291 +#define GPIO_RD_2    ((32 * 3) + 2)
5292 +#define GPIO_RD_3    ((32 * 3) + 3)
5293 +#define GPIO_RD_4    ((32 * 3) + 4)
5294 +#define GPIO_RD_5    ((32 * 3) + 5)
5295 +#define GPIO_RD_6    ((32 * 3) + 6)
5296 +#define GPIO_RD_7    ((32 * 3) + 7)
5297 +#define GPIO_RD_8    ((32 * 3) + 8)
5298 +#define GPIO_RD_9    ((32 * 3) + 9)
5299 +#define GPIO_RD_10   ((32 * 3) + 10)
5300 +#define GPIO_RD_11   ((32 * 3) + 11)
5301 +
5302 +#define GPIO_RE_0    ((32 * 4) + 0)
5303 +#define GPIO_RE_1    ((32 * 4) + 1)
5304 +#define GPIO_RE_2    ((32 * 4) + 2)
5305 +#define GPIO_RE_3    ((32 * 4) + 3)
5306 +#define GPIO_RE_4    ((32 * 4) + 4)
5307 +#define GPIO_RE_5    ((32 * 4) + 5)
5308 +#define GPIO_RE_6    ((32 * 4) + 6)
5309 +#define GPIO_RE_7    ((32 * 4) + 7)
5310 +
5311 +#define GPIO_RF_0    ((32 * 5) + 0)
5312 +#define GPIO_RF_1    ((32 * 5) + 1)
5313 +#define GPIO_RF_2    ((32 * 5) + 2)
5314 +#define GPIO_RF_3    ((32 * 5) + 3)
5315 +#define GPIO_RF_4    ((32 * 5) + 4)
5316 +#define GPIO_RF_5    ((32 * 5) + 5)
5317 +#define GPIO_RF_6    ((32 * 5) + 6)
5318 +#define GPIO_RF_7    ((32 * 5) + 7)
5319 +#define GPIO_RF_8    ((32 * 5) + 8)
5320 +#define GPIO_RF_9    ((32 * 5) + 9)
5321 +#define GPIO_RF_10   ((32 * 5) + 10)
5322 +#define GPIO_RF_11   ((32 * 5) + 11)
5323 +#define GPIO_RF_12   ((32 * 5) + 12)
5324 +#define GPIO_RF_13   ((32 * 5) + 13)
5325 +#define GPIO_RF_14   ((32 * 5) + 14)
5326 +#define GPIO_RF_15   ((32 * 5) + 15)
5327 +
5328 +#define GPIO_RG_0    ((32 * 6) + 0)
5329 +#define GPIO_RG_1    ((32 * 6) + 1)
5330 +#define GPIO_RG_2    ((32 * 6) + 2)
5331 +#define GPIO_RG_3    ((32 * 6) + 3)
5332 +#define GPIO_RG_4    ((32 * 6) + 4)
5333 +#define GPIO_RG_5    ((32 * 6) + 5)
5334 +#define GPIO_RG_6    ((32 * 6) + 6)
5335 +#define GPIO_RG_7    ((32 * 6) + 7)
5336 +#define GPIO_RG_8    ((32 * 6) + 8)
5337 +#define GPIO_RG_9    ((32 * 6) + 9)
5338 +#define GPIO_RG_10   ((32 * 6) + 10)
5339 +#define GPIO_RG_11   ((32 * 6) + 11)
5340 +#define GPIO_RG_12   ((32 * 6) + 12)
5341 +#define GPIO_RG_13   ((32 * 6) + 13)
5342 +#define GPIO_RG_14   ((32 * 6) + 14)
5343 +#define GPIO_RG_15   ((32 * 6) + 15)
5344 +#define GPIO_RG_16   ((32 * 6) + 16)
5345 +#define GPIO_RG_17   ((32 * 6) + 17)
5346 +#define GPIO_RG_18   ((32 * 6) + 18)
5347 +#define GPIO_RG_19   ((32 * 6) + 19)
5348 +#define GPIO_RG_20   ((32 * 6) + 20)
5349 +#define GPIO_RG_21   ((32 * 6) + 21)
5350 +#define GPIO_RG_22   ((32 * 6) + 22)
5351 +#define GPIO_RG_23   ((32 * 6) + 23)
5352 +#define GPIO_RG_24   ((32 * 6) + 24)
5353 +#define GPIO_RG_25   ((32 * 6) + 25)
5354 +#define GPIO_RG_26   ((32 * 6) + 26)
5355 +#define GPIO_RG_27   ((32 * 6) + 27)
5356 +#define GPIO_RG_28   ((32 * 6) + 28)
5357 +#define GPIO_RG_29   ((32 * 6) + 29)
5358 +#define GPIO_RG_30   ((32 * 6) + 30)
5359 +#define GPIO_RG_31   ((32 * 6) + 31)
5360 +
5361 +#define GPIO_RH_0    ((32 * 7) + 0)
5362 +#define GPIO_RH_1    ((32 * 7) + 1)
5363 +#define GPIO_RH_2    ((32 * 7) + 2)
5364 +#define GPIO_RH_3    ((32 * 7) + 3)
5365 +#define GPIO_RH_4    ((32 * 7) + 4)
5366 +#define GPIO_RH_5    ((32 * 7) + 5)
5367 +#define GPIO_RH_6    ((32 * 7) + 6)
5368 +#define GPIO_RH_7    ((32 * 7) + 7)
5369 +#define GPIO_RH_8    ((32 * 7) + 8)
5370 +#define GPIO_RH_9    ((32 * 7) + 9)
5371 +
5372 +#define GPIO_RI_0    ((32 * 8) + 0)
5373 +#define GPIO_RI_1    ((32 * 8) + 1)
5374 +#define GPIO_RI_2    ((32 * 8) + 2)
5375 +#define GPIO_RI_3    ((32 * 8) + 3)
5376 +#define GPIO_RI_4    ((32 * 8) + 4)
5377 +#define GPIO_RI_5    ((32 * 8) + 5)
5378 +#define GPIO_RI_6    ((32 * 8) + 6)
5379 +#define GPIO_RI_7    ((32 * 8) + 7)
5380 +#define GPIO_RI_8    ((32 * 8) + 8)
5381 +#define GPIO_RI_9    ((32 * 8) + 9)
5382 +#define GPIO_RI_10   ((32 * 8) + 10)
5383 +#define GPIO_RI_11   ((32 * 8) + 11)
5384 +#define GPIO_RI_12   ((32 * 8) + 12)
5385 +#define GPIO_RI_13   ((32 * 8) + 13)
5386 +
5387 +/*
5388 + * The following section defines extra GPIO available to some boards.
5389 + * These GPIO are generally external to the processor (i.e. SPI/I2C
5390 + * expander chips).
5391 + *
5392 + * Note that these defines show all possible GPIO available, however,
5393 + * depending on the actual board configuration, some GPIO are not
5394 + * available for use.
5395 + */
5396 +#ifdef CONFIG_IP7500MEDIA
5397 +/*
5398 + * U15
5399 + */
5400 +#define IP7500MEDIA_U15_BASE   (32 * 10)
5401 +#define IP7500MEDIA_IO0                (IP7500MEDIA_U15_BASE + 0)
5402 +#define IP7500MEDIA_IO1                (IP7500MEDIA_U15_BASE + 1)
5403 +#define IP7500MEDIA_IO2                (IP7500MEDIA_U15_BASE + 2)
5404 +#define IP7500MEDIA_IO3                (IP7500MEDIA_U15_BASE + 3)
5405 +#define IP7500MEDIA_IO4                (IP7500MEDIA_U15_BASE + 4)
5406 +#define IP7500MEDIA_IO5                (IP7500MEDIA_U15_BASE + 5)
5407 +#define IP7500MEDIA_IO6                (IP7500MEDIA_U15_BASE + 6)
5408 +#define IP7500MEDIA_IO7                (IP7500MEDIA_U15_BASE + 7)
5409 +
5410 +/*
5411 + * U16
5412 + */
5413 +#define IP7500MEDIA_U16_BASE   (32 * 11)
5414 +#define IP7500MEDIA_IO8                (IP7500MEDIA_U16_BASE + 0)
5415 +#define IP7500MEDIA_IO9                (IP7500MEDIA_U16_BASE + 1)
5416 +#define IP7500MEDIA_IO10       (IP7500MEDIA_U16_BASE + 2)
5417 +#define IP7500MEDIA_IO11       (IP7500MEDIA_U16_BASE + 3)
5418 +#define IP7500MEDIA_IO12       (IP7500MEDIA_U16_BASE + 4)
5419 +#define IP7500MEDIA_IO13       (IP7500MEDIA_U16_BASE + 5)
5420 +#define IP7500MEDIA_IO14       (IP7500MEDIA_U16_BASE + 6)
5421 +#define IP7500MEDIA_IO15       (IP7500MEDIA_U16_BASE + 7)
5422 +
5423 +/*
5424 + * U17
5425 + */
5426 +#define IP7500MEDIA_U17_BASE   (32 * 12)
5427 +#define IP7500MEDIA_IO16       (IP7500MEDIA_U17_BASE + 0)
5428 +#define IP7500MEDIA_IO17       (IP7500MEDIA_U17_BASE + 1)
5429 +#define IP7500MEDIA_IO18       (IP7500MEDIA_U17_BASE + 2)
5430 +#define IP7500MEDIA_IO19       (IP7500MEDIA_U17_BASE + 3)
5431 +#define IP7500MEDIA_IO20       (IP7500MEDIA_U17_BASE + 4)
5432 +#define IP7500MEDIA_IO21       (IP7500MEDIA_U17_BASE + 5)
5433 +#define IP7500MEDIA_IO22       (IP7500MEDIA_U17_BASE + 6)
5434 +#define IP7500MEDIA_IO23       (IP7500MEDIA_U17_BASE + 7)
5435 +
5436 +/*
5437 + * U18
5438 + */
5439 +#define IP7500MEDIA_U18_BASE   (32 * 13)
5440 +#define IP7500MEDIA_IO24       (IP7500MEDIA_U18_BASE + 0)
5441 +#define IP7500MEDIA_IO25       (IP7500MEDIA_U18_BASE + 1)
5442 +#define IP7500MEDIA_IO26       (IP7500MEDIA_U18_BASE + 2)
5443 +#define IP7500MEDIA_IO27       (IP7500MEDIA_U18_BASE + 3)
5444 +#define IP7500MEDIA_IO28       (IP7500MEDIA_U18_BASE + 4)
5445 +#define IP7500MEDIA_IO29       (IP7500MEDIA_U18_BASE + 5)
5446 +#define IP7500MEDIA_IO30       (IP7500MEDIA_U18_BASE + 6)
5447 +#define IP7500MEDIA_IO31       (IP7500MEDIA_U18_BASE + 7)
5448 +#endif
5449 +
5450 +#ifdef CONFIG_IP7145DPF
5451 +/*
5452 + * U48
5453 + */
5454 +#define IP7145DPF_U48_BASE     (32 * 10)
5455 +#define IP7145DPF_IO0          (IP7145DPF_U48_BASE + 0)
5456 +#define IP7145DPF_IO1          (IP7145DPF_U48_BASE + 1)
5457 +#define IP7145DPF_IO2          (IP7145DPF_U48_BASE + 2)
5458 +#define IP7145DPF_IO3          (IP7145DPF_U48_BASE + 3)
5459 +#define IP7145DPF_IO4          (IP7145DPF_U48_BASE + 4)
5460 +#define IP7145DPF_IO5          (IP7145DPF_U48_BASE + 5)
5461 +#define IP7145DPF_IO6          (IP7145DPF_U48_BASE + 6)
5462 +#define IP7145DPF_IO7          (IP7145DPF_U48_BASE + 7)
5463 +
5464 +/*
5465 + * U72
5466 + */
5467 +#define IP7145DPF_U72_BASE     (32 * 11)
5468 +#define IP7145DPF_IOB0         (IP7145DPF_U72_BASE + 0)
5469 +#define IP7145DPF_IOB1         (IP7145DPF_U72_BASE + 1)
5470 +#define IP7145DPF_IOB2         (IP7145DPF_U72_BASE + 2)
5471 +#define IP7145DPF_IOB3         (IP7145DPF_U72_BASE + 3)
5472 +#define IP7145DPF_IOB4         (IP7145DPF_U72_BASE + 4)
5473 +#define IP7145DPF_IOB5         (IP7145DPF_U72_BASE + 5)
5474 +#define IP7145DPF_IOB6         (IP7145DPF_U72_BASE + 6)
5475 +#define IP7145DPF_IOB7         (IP7145DPF_U72_BASE + 7)
5476 +#endif
5477 +
5478 +#include <asm-generic/gpio.h>
5479 +
5480 +/*
5481 + * The following macros bypass gpiolib to generate direct references
5482 + * to the port registers.  These assume, minimally, that either
5483 + * gpio_direction_input() or gpio_direction_output() have already been
5484 + * called to setup the pin direction and to enable the pin function to
5485 + * be gpio.  These macros generate the hardware port address based on
5486 + * the assumption that all ports are 32 bits wide (even though we know
5487 + * they are not).  This is so we can efficiently turn pin numbers into
5488 + * port addresses without a lookup.
5489 + *
5490 + * These operations must be done in one instruction to prevent clobbering
5491 + * other thread's accesses to the same port.
5492 + */
5493 +#define UBICOM32_GPIO_ENABLE(pin)                              \
5494 +       do {                                                    \
5495 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5496 +                               :                                                                               \
5497 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
5498 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5499 +                               : "cc", "memory"                                                                \
5500 +               );                                                                                              \
5501 +       } while (0);
5502 +
5503 +#define UBICOM32_GPIO_DISABLE(pin)                             \
5504 +       do {                                                    \
5505 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5506 +                               :                                                                               \
5507 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
5508 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5509 +                               : "cc", "memory"                                                                \
5510 +               );                                                                                              \
5511 +       } while (0);
5512 +
5513 +#define UBICOM32_GPIO_SET_PIN_INPUT(pin)                       \
5514 +       do {                                                    \
5515 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5516 +                               :                                                                               \
5517 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
5518 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5519 +                               : "cc", "memory"                                                                \
5520 +               );                                                                                              \
5521 +       } while (0);
5522 +
5523 +#define UBICOM32_GPIO_SET_PIN_OUTPUT(pin)                      \
5524 +       do {                                                    \
5525 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5526 +                               :                                                                               \
5527 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
5528 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5529 +                               : "cc", "memory"                                                                \
5530 +               );                                                                                              \
5531 +       } while (0);
5532 +
5533 +#define UBICOM32_GPIO_SET_PIN_TOGGLE(pin)                      \
5534 +       do {                                                    \
5535 +               asm volatile ("xor.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5536 +                               :                                                                               \
5537 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5538 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5539 +                               : "cc", "memory"                                                                \
5540 +               );                                                                                              \
5541 +       } while (0);
5542 +
5543 +#define UBICOM32_GPIO_SET_PIN_HIGH(pin)                                \
5544 +       do {                                                    \
5545 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5546 +                               :                                                                               \
5547 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5548 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5549 +                               : "cc", "memory"                                                                \
5550 +               );                                                                                              \
5551 +       } while (0);
5552 +
5553 +#define UBICOM32_GPIO_SET_PIN_LOW(pin)                         \
5554 +       do {                                                    \
5555 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5556 +                               :                                                                               \
5557 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5558 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5559 +                               : "cc", "memory"                                                                \
5560 +               );                                                                                              \
5561 +       } while (0);
5562 +
5563 +#define UBICOM32_GPIO_SET_PIN(pin, val) \
5564 +  if ( val ) {                          \
5565 +    UBICOM32_GPIO_SET_PIN_HIGH(pin);    \
5566 +  } else {                              \
5567 +    UBICOM32_GPIO_SET_PIN_LOW(pin);    \
5568 +  }
5569 +
5570 +#define UBICOM32_GPIO_GET_PIN(pin)                                    \
5571 +  (0 != (UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_in  \
5572 +        & gpio_bit(pin)))
5573 +
5574 +
5575 +static inline int gpio_get_value(unsigned gpio) 
5576 +{
5577 +  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5578 +    return UBICOM32_GPIO_GET_PIN(gpio);
5579 +  else
5580 +    return __gpio_get_value(gpio);
5581 +}
5582 +
5583 +static inline void gpio_set_value(unsigned gpio, int value)
5584 +{
5585 +  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5586 +    {
5587 +      UBICOM32_GPIO_SET_PIN(gpio, value);
5588 +    }
5589 +  else
5590 +    {
5591 +      __gpio_set_value(gpio, value);
5592 +    }
5593 +}
5594 +
5595 +static inline int gpio_cansleep(unsigned gpio)
5596 +{
5597 +  return __gpio_cansleep(gpio);
5598 +}
5599 +
5600 +static inline int gpio_to_irq(unsigned gpio)
5601 +{
5602 +#if defined(IP5000) || defined(IP5000_REV2)
5603 +  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5604 +    return 25;
5605 +  else
5606 +    return -ENXIO;
5607 +
5608 +#elif defined(IP7000) || defined(IP7000_REV2)
5609 +  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5610 +    return 44 + (gpio - GPIO_RA_4);
5611 +  else
5612 +    return -ENXIO;
5613 +
5614 +#else
5615 +    return -ENXIO;
5616 +
5617 +#endif
5618 +}
5619 +
5620 +static inline int irq_to_gpio(unsigned gpio)
5621 +{
5622 +       return -ENXIO;
5623 +}
5624 +
5625 +extern struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio);
5626 +
5627 +extern int __init ubi_gpio_init(void);
5628 +
5629 +#endif /* _ASM_UBICOM32_GPIO_H */
5630 --- /dev/null
5631 +++ b/arch/ubicom32/include/asm/hardirq.h
5632 @@ -0,0 +1,55 @@
5633 +/*
5634 + * arch/ubicom32/include/asm/hardirq.h
5635 + *   Definition of ack_bad_irq() for Ubicom32 architecture.
5636 + *
5637 + * (C) Copyright 2009, Ubicom, Inc.
5638 + * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
5639 + * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
5640 + * Copyright (C) 2001 MIPS Technologies, Inc.
5641 + *
5642 + * This file is part of the Ubicom32 Linux Kernel Port.
5643 + *
5644 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5645 + * it and/or modify it under the terms of the GNU General Public License
5646 + * as published by the Free Software Foundation, either version 2 of the
5647 + * License, or (at your option) any later version.
5648 + *
5649 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5650 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5651 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5652 + * the GNU General Public License for more details.
5653 + *
5654 + * You should have received a copy of the GNU General Public License
5655 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5656 + * see <http://www.gnu.org/licenses/>.
5657 + *
5658 + * Ubicom32 implementation derived from (with many thanks):
5659 + *   arch/m68knommu
5660 + *   arch/blackfin
5661 + *   arch/parisc
5662 + */
5663 +#ifndef _ASM_UBICOM32_HARDIRQ_H
5664 +#define _ASM_UBICOM32_HARDIRQ_H
5665 +
5666 +#include <linux/threads.h>
5667 +#include <linux/irq.h>
5668 +
5669 +/*
5670 + * The hardirq mask has to be large enough to have space
5671 + * for potentially all IRQ sources in the system nesting
5672 + * on a single CPU.  For Ubicom32, we have 64 IRQ sources.
5673 + */
5674 +#define HARDIRQ_BITS   6
5675 +#if (1 << HARDIRQ_BITS) < NR_IRQS
5676 +# error HARDIRQ_BITS is too low!
5677 +#endif
5678 +
5679 +typedef struct {
5680 +       unsigned int __softirq_pending;
5681 +} ____cacheline_aligned irq_cpustat_t;
5682 +
5683 +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
5684 +
5685 +extern void ack_bad_irq(unsigned int irq);
5686 +
5687 +#endif /* _ASM_UBICOM32_HARDIRQ_H */
5688 --- /dev/null
5689 +++ b/arch/ubicom32/include/asm/hw_irq.h
5690 @@ -0,0 +1,31 @@
5691 +/*
5692 + * arch/ubicom32/include/asm/hw_irq.h
5693 + *   Ubicom32 architecture APIC support.
5694 + *
5695 + * (C) Copyright 2009, Ubicom, Inc.
5696 + *
5697 + * This file is part of the Ubicom32 Linux Kernel Port.
5698 + *
5699 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5700 + * it and/or modify it under the terms of the GNU General Public License
5701 + * as published by the Free Software Foundation, either version 2 of the
5702 + * License, or (at your option) any later version.
5703 + *
5704 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5705 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5706 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5707 + * the GNU General Public License for more details.
5708 + *
5709 + * You should have received a copy of the GNU General Public License
5710 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5711 + * see <http://www.gnu.org/licenses/>.
5712 + *
5713 + * Ubicom32 implementation derived from (with many thanks):
5714 + *   arch/m68knommu
5715 + *   arch/blackfin
5716 + *   arch/parisc
5717 + */
5718 +#ifndef _ASM_UBICOM32_HW_IRQ_H
5719 +#define _ASM_UBICOM32_HW_IRQ_H
5720 +
5721 +#endif /* _ASM_UBICOM32_HW_IRQ_H */
5722 --- /dev/null
5723 +++ b/arch/ubicom32/include/asm/ioctl.h
5724 @@ -0,0 +1,33 @@
5725 +/*
5726 + * arch/ubicom32/include/asm/ioctl.h
5727 + *   Generic ioctl.h for Ubicom32 architecture.
5728 + *
5729 + * (C) Copyright 2009, Ubicom, Inc.
5730 + *
5731 + * This file is part of the Ubicom32 Linux Kernel Port.
5732 + *
5733 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5734 + * it and/or modify it under the terms of the GNU General Public License
5735 + * as published by the Free Software Foundation, either version 2 of the
5736 + * License, or (at your option) any later version.
5737 + *
5738 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5739 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5740 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5741 + * the GNU General Public License for more details.
5742 + *
5743 + * You should have received a copy of the GNU General Public License
5744 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5745 + * see <http://www.gnu.org/licenses/>.
5746 + *
5747 + * Ubicom32 implementation derived from (with many thanks):
5748 + *   arch/m68knommu
5749 + *   arch/blackfin
5750 + *   arch/parisc
5751 + */
5752 +#ifndef _ASM_UBICOM32_IOCTL_H
5753 +#define _ASM_UBICOM32_IOCTL_H
5754 +
5755 +#include <asm-generic/ioctl.h>
5756 +
5757 +#endif /* _ASM_UBICOM32_IOCTL_H */
5758 --- /dev/null
5759 +++ b/arch/ubicom32/include/asm/ioctls.h
5760 @@ -0,0 +1,111 @@
5761 +/*
5762 + * arch/ubicom32/include/asm/ioctls.h
5763 + *   Definitions of ioctls for Ubicom32 architecture.
5764 + *
5765 + * (C) Copyright 2009, Ubicom, Inc.
5766 + *
5767 + * This file is part of the Ubicom32 Linux Kernel Port.
5768 + *
5769 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5770 + * it and/or modify it under the terms of the GNU General Public License
5771 + * as published by the Free Software Foundation, either version 2 of the
5772 + * License, or (at your option) any later version.
5773 + *
5774 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5775 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5776 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5777 + * the GNU General Public License for more details.
5778 + *
5779 + * You should have received a copy of the GNU General Public License
5780 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5781 + * see <http://www.gnu.org/licenses/>.
5782 + *
5783 + * Ubicom32 implementation derived from (with many thanks):
5784 + *   arch/m68knommu
5785 + *   arch/blackfin
5786 + *   arch/parisc
5787 + */
5788 +#ifndef _ASM_UBICOM32_IOCTLS_H
5789 +#define _ASM_UBICOM32_IOCTLS_H
5790 +
5791 +#include <asm/ioctl.h>
5792 +
5793 +/* 0x54 is just a magic number to make these relatively unique ('T') */
5794 +
5795 +#define TCGETS         0x5401
5796 +#define TCSETS         0x5402
5797 +#define TCSETSW                0x5403
5798 +#define TCSETSF                0x5404
5799 +#define TCGETA         0x5405
5800 +#define TCSETA         0x5406
5801 +#define TCSETAW                0x5407
5802 +#define TCSETAF                0x5408
5803 +#define TCSBRK         0x5409
5804 +#define TCXONC         0x540A
5805 +#define TCFLSH         0x540B
5806 +#define TIOCEXCL       0x540C
5807 +#define TIOCNXCL       0x540D
5808 +#define TIOCSCTTY      0x540E
5809 +#define TIOCGPGRP      0x540F
5810 +#define TIOCSPGRP      0x5410
5811 +#define TIOCOUTQ       0x5411
5812 +#define TIOCSTI                0x5412
5813 +#define TIOCGWINSZ     0x5413
5814 +#define TIOCSWINSZ     0x5414
5815 +#define TIOCMGET       0x5415
5816 +#define TIOCMBIS       0x5416
5817 +#define TIOCMBIC       0x5417
5818 +#define TIOCMSET       0x5418
5819 +#define TIOCGSOFTCAR   0x5419
5820 +#define TIOCSSOFTCAR   0x541A
5821 +#define FIONREAD       0x541B
5822 +#define TIOCINQ                FIONREAD
5823 +#define TIOCLINUX      0x541C
5824 +#define TIOCCONS       0x541D
5825 +#define TIOCGSERIAL    0x541E
5826 +#define TIOCSSERIAL    0x541F
5827 +#define TIOCPKT                0x5420
5828 +#define FIONBIO                0x5421
5829 +#define TIOCNOTTY      0x5422
5830 +#define TIOCSETD       0x5423
5831 +#define TIOCGETD       0x5424
5832 +#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
5833 +#define TIOCSBRK       0x5427  /* BSD compatibility */
5834 +#define TIOCCBRK       0x5428  /* BSD compatibility */
5835 +#define TIOCGSID       0x5429  /* Return the session ID of FD */
5836 +#define TCGETS2                _IOR('T',0x2A, struct termios2)
5837 +#define TCSETS2                _IOW('T',0x2B, struct termios2)
5838 +#define TCSETSW2       _IOW('T',0x2C, struct termios2)
5839 +#define TCSETSF2       _IOW('T',0x2D, struct termios2)
5840 +#define TIOCGPTN       _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
5841 +#define TIOCSPTLCK     _IOW('T',0x31, int)  /* Lock/unlock Pty */
5842 +
5843 +#define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
5844 +#define FIOCLEX                0x5451
5845 +#define FIOASYNC       0x5452
5846 +#define TIOCSERCONFIG  0x5453
5847 +#define TIOCSERGWILD   0x5454
5848 +#define TIOCSERSWILD   0x5455
5849 +#define TIOCGLCKTRMIOS 0x5456
5850 +#define TIOCSLCKTRMIOS 0x5457
5851 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
5852 +#define TIOCSERGETLSR   0x5459 /* Get line status register */
5853 +#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
5854 +#define TIOCSERSETMULTI 0x545B /* Set multiport config */
5855 +
5856 +#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
5857 +#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
5858 +#define FIOQSIZE       0x545E
5859 +
5860 +/* Used for packet mode */
5861 +#define TIOCPKT_DATA            0
5862 +#define TIOCPKT_FLUSHREAD       1
5863 +#define TIOCPKT_FLUSHWRITE      2
5864 +#define TIOCPKT_STOP            4
5865 +#define TIOCPKT_START           8
5866 +#define TIOCPKT_NOSTOP         16
5867 +#define TIOCPKT_DOSTOP         32
5868 +
5869 +#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
5870 +
5871 +#endif /* _ASM_UBICOM32_IOCTLS_H */
5872 --- /dev/null
5873 +++ b/arch/ubicom32/include/asm/io.h
5874 @@ -0,0 +1,313 @@
5875 +/*
5876 + * arch/ubicom32/include/asm/io.h
5877 + *   I/O memory accessor functions for Ubicom32 architecture.
5878 + *
5879 + * (C) Copyright 2009, Ubicom, Inc.
5880 + *
5881 + * This file is part of the Ubicom32 Linux Kernel Port.
5882 + *
5883 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5884 + * it and/or modify it under the terms of the GNU General Public License
5885 + * as published by the Free Software Foundation, either version 2 of the
5886 + * License, or (at your option) any later version.
5887 + *
5888 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5889 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5890 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5891 + * the GNU General Public License for more details.
5892 + *
5893 + * You should have received a copy of the GNU General Public License
5894 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5895 + * see <http://www.gnu.org/licenses/>.
5896 + *
5897 + * Ubicom32 implementation derived from (with many thanks):
5898 + *   arch/m68knommu
5899 + *   arch/blackfin
5900 + *   arch/parisc
5901 + */
5902 +#ifndef _ASM_UBICOM32_IO_H
5903 +#define _ASM_UBICOM32_IO_H
5904 +
5905 +#ifdef __KERNEL__
5906 +#include <linux/string.h>
5907 +#include <linux/compiler.h>
5908 +
5909 +static inline unsigned short _swapw(volatile unsigned short v)
5910 +{
5911 +    return ((v << 8) | (v >> 8));
5912 +}
5913 +
5914 +static inline unsigned int _swapl(volatile unsigned long v)
5915 +{
5916 +    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
5917 +}
5918 +
5919 +#ifndef CONFIG_PCI
5920 +#define readb(addr) \
5921 +    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
5922 +#define readw(addr) \
5923 +    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
5924 +#define readl(addr) \
5925 +    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
5926 +
5927 +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
5928 +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
5929 +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
5930 +#else /*CONFIG_PCI */
5931 +
5932 +#define PCI_CPU_REG_BASE (0x00000000UL)   /* taking lower 2GB space */
5933 +#define PCI_DEV_REG_BASE (0x80000000UL)
5934 +
5935 +#if PCI_CPU_REG_BASE > PCI_DEV_REG_BASE
5936 +#define IS_PCI_ADDRESS(x) (((unsigned int)(x)&(PCI_CPU_REG_BASE)) == 0)
5937 +#else
5938 +#define IS_PCI_ADDRESS(x) ((unsigned int)(x)&(PCI_DEV_REG_BASE))
5939 +#endif 
5940 +
5941 +extern unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr);
5942 +extern unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr);
5943 +extern unsigned char ubi32_pci_read_u8(const volatile void __iomem *addr);
5944 +extern  void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr);
5945 +extern  void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr);
5946 +extern  void ubi32_pci_write_u8(unsigned char val, const volatile void __iomem *addr);
5947 +
5948 +static  inline unsigned char readb(const volatile void __iomem *addr)
5949 +{
5950 +       if (IS_PCI_ADDRESS(addr))
5951 +               return ubi32_pci_read_u8(addr);
5952 +       else 
5953 +               return (unsigned char)(*(volatile unsigned char *)addr); 
5954 +}
5955 +static inline unsigned short readw(const volatile void __iomem *addr)
5956 +{
5957 +       if (IS_PCI_ADDRESS(addr))
5958 +               return ubi32_pci_read_u16(addr);
5959 +       else 
5960 +               return (unsigned short)(*(volatile unsigned short *)addr);      
5961 +}
5962 +
5963 +static  inline unsigned int  readl(const volatile void __iomem *addr)
5964 +{
5965 +       if (IS_PCI_ADDRESS(addr))
5966 +               return ubi32_pci_read_u32(addr);
5967 +       else 
5968 +               return (unsigned int)(*(volatile unsigned int *)addr);
5969 +}
5970 +
5971 +static inline void writel(unsigned int val, volatile void __iomem *addr)
5972 +{
5973 +       if (IS_PCI_ADDRESS(addr))
5974 +                ubi32_pci_write_u32(val, addr);
5975 +        else
5976 +                       *(volatile unsigned int *)addr = val; 
5977 +}
5978 +
5979 +static inline void writew(unsigned short val, volatile void __iomem *addr)
5980 +{
5981 +       if (IS_PCI_ADDRESS(addr))
5982 +                ubi32_pci_write_u16(val, addr);
5983 +        else
5984 +                       *(volatile unsigned short *)addr = val; 
5985 +}
5986 +
5987 +static inline void writeb(unsigned char val, volatile void __iomem *addr)
5988 +{
5989 +       if (IS_PCI_ADDRESS(addr))
5990 +                ubi32_pci_write_u8(val, addr);
5991 +        else
5992 +                       *(volatile unsigned char *)addr = val; 
5993 +}
5994 +#endif
5995 +
5996 +#define readb_relaxed(addr) readb(addr)
5997 +#define readw_relaxed(addr) readw(addr)
5998 +#define readl_relaxed(addr) readl(addr)
5999 +
6000 +
6001 +#define __raw_readb readb
6002 +#define __raw_readw readw
6003 +#define __raw_readl readl
6004 +#define __raw_writeb writeb
6005 +#define __raw_writew writew
6006 +#define __raw_writel writel
6007 +
6008 +static inline void io_outsb(unsigned int addr, const void *buf, int len)
6009 +{
6010 +       volatile unsigned char *ap = (volatile unsigned char *) addr;
6011 +       unsigned char *bp = (unsigned char *) buf;
6012 +       while (len--)
6013 +               *ap = *bp++;
6014 +}
6015 +
6016 +static inline void io_outsw(unsigned int addr, const void *buf, int len)
6017 +{
6018 +       volatile unsigned short *ap = (volatile unsigned short *) addr;
6019 +       unsigned short *bp = (unsigned short *) buf;
6020 +       while (len--)
6021 +               *ap = _swapw(*bp++);
6022 +}
6023 +
6024 +static inline void io_outsl(unsigned int addr, const void *buf, int len)
6025 +{
6026 +       volatile unsigned int *ap = (volatile unsigned int *) addr;
6027 +       unsigned int *bp = (unsigned int *) buf;
6028 +       while (len--)
6029 +               *ap = _swapl(*bp++);
6030 +}
6031 +
6032 +static inline void io_insb(unsigned int addr, void *buf, int len)
6033 +{
6034 +       volatile unsigned char *ap = (volatile unsigned char *) addr;
6035 +       unsigned char *bp = (unsigned char *) buf;
6036 +       while (len--)
6037 +               *bp++ = *ap;
6038 +}
6039 +
6040 +static inline void io_insw(unsigned int addr, void *buf, int len)
6041 +{
6042 +       volatile unsigned short *ap = (volatile unsigned short *) addr;
6043 +       unsigned short *bp = (unsigned short *) buf;
6044 +       while (len--)
6045 +               *bp++ = _swapw(*ap);
6046 +}
6047 +
6048 +static inline void io_insl(unsigned int addr, void *buf, int len)
6049 +{
6050 +       volatile unsigned int *ap = (volatile unsigned int *) addr;
6051 +       unsigned int *bp = (unsigned int *) buf;
6052 +       while (len--)
6053 +               *bp++ = _swapl(*ap);
6054 +}
6055 +
6056 +#define mmiowb()
6057 +
6058 +/*
6059 + *     make the short names macros so specific devices
6060 + *     can override them as required
6061 + */
6062 +#ifndef CONFIG_PCI
6063 +#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
6064 +#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
6065 +#define memcpy_toio(a,b,c)     memcpy((void *)(a),(b),(c))
6066 +#else 
6067 +extern void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len);
6068 +extern void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len);
6069 +extern void memset_io(volatile void __iomem *addr, int val, size_t count);
6070 +#endif
6071 +
6072 +#define inb(addr)    readb(addr)
6073 +#define inw(addr)    readw(addr)
6074 +#define inl(addr)    readl(addr)
6075 +#define outb(x,addr) ((void) writeb(x,addr))
6076 +#define outw(x,addr) ((void) writew(x,addr))
6077 +#define outl(x,addr) ((void) writel(x,addr))
6078 +
6079 +#define inb_p(addr)    inb(addr)
6080 +#define inw_p(addr)    inw(addr)
6081 +#define inl_p(addr)    inl(addr)
6082 +#define outb_p(x,addr) outb(x,addr)
6083 +#define outw_p(x,addr) outw(x,addr)
6084 +#define outl_p(x,addr) outl(x,addr)
6085 +
6086 +#define outsb(a,b,l) io_outsb(a,b,l)
6087 +#define outsw(a,b,l) io_outsw(a,b,l)
6088 +#define outsl(a,b,l) io_outsl(a,b,l)
6089 +
6090 +#define insb(a,b,l) io_insb(a,b,l)
6091 +#define insw(a,b,l) io_insw(a,b,l)
6092 +#define insl(a,b,l) io_insl(a,b,l)
6093 +
6094 +#ifndef CONFIG_PCI
6095 +#define ioread8_rep(a,d,c)     insb(a,d,c)
6096 +#define ioread16_rep(a,d,c)    insw(a,d,c)
6097 +#define ioread32_rep(a,d,c)    insl(a,d,c)
6098 +#define iowrite8_rep(a,s,c)    outsb(a,s,c)
6099 +#define iowrite16_rep(a,s,c)   outsw(a,s,c)
6100 +#define iowrite32_rep(a,s,c)   outsl(a,s,c)
6101 +#else
6102 +extern void  ioread8_rep(void __iomem *port, void *buf, unsigned long count);
6103 +extern void  ioread16_rep(void __iomem *port, void *buf, unsigned long count);
6104 +extern void  ioread32_rep(void __iomem *port, void *buf, unsigned long count);
6105 +extern void  iowrite8_rep(void __iomem *port, const void *buf, unsigned long count);
6106 +extern void  iowrite16_rep(void __iomem *port, const void *buf, unsigned long count);
6107 +extern void  iowrite32_rep(void __iomem *port, const void *buf, unsigned long count);
6108 +#endif
6109 +
6110 +
6111 +#ifndef CONFIG_PCI
6112 +#define ioread8(X)                     readb(X)
6113 +#define ioread16(X)                    readw(X)
6114 +#define ioread32(X)                    readl(X)
6115 +#define iowrite8(val,X)                        writeb(val,X)
6116 +#define iowrite16(val,X)               writew(val,X)
6117 +#define iowrite32(val,X)               writel(val,X)
6118 +#else /*CONFIG_PCI */
6119 +extern  unsigned char  ioread8(void __iomem *addr);
6120 +extern  unsigned short ioread16(void __iomem *addr);
6121 +extern  unsigned int  ioread32(void __iomem *addr);
6122 +extern  void iowrite8(unsigned char val, void __iomem *addr);
6123 +extern  void iowrite16(unsigned short val, void __iomem *addr);
6124 +extern  void iowrite32(unsigned int val, void __iomem *addr);
6125 +#endif /* CONFIG_PCI */
6126 +
6127 +#define IO_SPACE_LIMIT 0xffff
6128 +
6129 +/* Values for nocacheflag and cmode */
6130 +#define IOMAP_FULL_CACHING             0
6131 +#define IOMAP_NOCACHE_SER              1
6132 +#define IOMAP_NOCACHE_NONSER           2
6133 +#define IOMAP_WRITETHROUGH             3
6134 +
6135 +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
6136 +extern void __iounmap(void *addr, unsigned long size);
6137 +
6138 +static inline void *ioremap(unsigned long physaddr, unsigned long size)
6139 +{
6140 +       return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6141 +}
6142 +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
6143 +{
6144 +       return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6145 +}
6146 +static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
6147 +{
6148 +       return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
6149 +}
6150 +static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
6151 +{
6152 +       return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
6153 +}
6154 +
6155 +extern void iounmap(void *addr);
6156 +
6157 +#define ioport_map(port, nr)            ((void __iomem*)(port))
6158 +#define ioport_unmap(addr)
6159 +
6160 +
6161 +/* Pages to physical address... */
6162 +#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
6163 +#define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
6164 +
6165 +/*
6166 + * Macros used for converting between virtual and physical mappings.
6167 + */
6168 +#define phys_to_virt(vaddr)    ((void *) (vaddr))
6169 +#define virt_to_phys(vaddr)    ((unsigned long) (vaddr))
6170 +
6171 +#define virt_to_bus virt_to_phys
6172 +#define bus_to_virt phys_to_virt
6173 +
6174 +/*
6175 + * Convert a physical pointer to a virtual kernel pointer for /dev/mem
6176 + * access
6177 + */
6178 +#define xlate_dev_mem_ptr(p)   __va(p)
6179 +
6180 +/*
6181 + * Convert a virtual cached pointer to an uncached pointer
6182 + */
6183 +#define xlate_dev_kmem_ptr(p)  p
6184 +
6185 +#endif /* __KERNEL__ */
6186 +
6187 +#endif /* _ASM_UBICOM32_IO_H */
6188 --- /dev/null
6189 +++ b/arch/ubicom32/include/asm/ip5000-asm.h
6190 @@ -0,0 +1,156 @@
6191 +/*
6192 + * arch/ubicom32/include/asm/ip5000-asm.h
6193 + *     Instruction macros for the IP5000.
6194 + *
6195 + * (C) Copyright 2009, Ubicom, Inc.
6196 + *
6197 + * This file is part of the Ubicom32 Linux Kernel Port.
6198 + *
6199 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
6200 + * it and/or modify it under the terms of the GNU General Public License
6201 + * as published by the Free Software Foundation, either version 2 of the
6202 + * License, or (at your option) any later version.
6203 + *
6204 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
6205 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
6206 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
6207 + * the GNU General Public License for more details.
6208 + *
6209 + * You should have received a copy of the GNU General Public License
6210 + * along with the Ubicom32 Linux Kernel Port.  If not,
6211 + * see <http://www.gnu.org/licenses/>.
6212 + *
6213 + * Ubicom32 implementation derived from (with many thanks):
6214 + *   arch/m68knommu
6215 + *   arch/blackfin
6216 + *   arch/parisc
6217 + */
6218 +
6219 +#ifndef _ASM_UBICOM32_IP5000_ASM_H
6220 +#define _ASM_UBICOM32_IP5000_ASM_H
6221 +
6222 +#if !defined(__LINKER__)
6223 +
6224 +#if defined(__ASSEMBLY__)
6225 +.macro cycles  quant
6226 +.if    (\quant) == 1
6227 +       nop
6228 +.else
6229 +.if    (((\quant) + 3) / 8) > 0
6230 +.rept  (((\quant) + 3) / 8)
6231 +       jmpt.f          .+4
6232 +.endr
6233 +.endif
6234 +.if    ((((\quant) + 3) % 8) / 4) > 0
6235 +       jmpt.t          .+4
6236 +.endif
6237 +.endif
6238 +.endm
6239 +#else
6240 +/*
6241 + * Same macro as above just in C inline asm
6242 + */
6243 +asm ("                                 \n\
6244 +.macro cycles  quant                   \n\
6245 +.if    (\\quant) == 1                  \n\
6246 +       nop                             \n\
6247 +.else                                  \n\
6248 +.if    (((\\quant) + 3) / 8) > 0       \n\
6249 +.rept  (((\\quant) + 3) / 8)           \n\
6250 +       jmpt.f          .+4             \n\
6251 +.endr                                  \n\
6252 +.endif                                 \n\
6253 +.if    ((((\\quant) + 3) % 8) / 4) > 0 \n\
6254 +       jmpt.t          .+4             \n\
6255 +.endif                                 \n\
6256 +.endif                                 \n\
6257 +.endm                                  \n\
6258 +");
6259 +#endif
6260 +
6261 +
6262 +#if defined(__ASSEMBLY__)
6263 +.macro pipe_flush      cyc
6264 +       cycles          11 - (\cyc)
6265 +.endm
6266 +#else
6267 +/*
6268 + * Same macro as above just in C inline asm
6269 + */
6270 +asm ("                                 \n\
6271 +.macro pipe_flush      cyc             \n\
6272 +       cycles          11 - (\\cyc)    \n\
6273 +.endm                                  \n\
6274 +");
6275 +
6276 +#endif
6277 +
6278 +#if defined(__ASSEMBLY__)
6279 +.macro setcsr_flush    cyc
6280 +       cycles          5 - (\cyc)
6281 +.endm
6282 +#else
6283 +/*
6284 + * Same macro as above just in C inline asm
6285 + */
6286 +asm ("                                 \n\
6287 +.macro setcsr_flush    cyc             \n\
6288 +       cycles          5 - (\\cyc)     \n\
6289 +.endm                                  \n\
6290 +");
6291 +#endif
6292 +
6293 +/*
6294 + * Macros for prefetch (using miss-aligned memory write)
6295 + */
6296 +#if defined(__ASSEMBLY__)
6297 +
6298 +.macro pre_fetch_macro thread_num, Ascratch, Aaddress length
6299 +       bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
6300 +       bset            \Ascratch, \Aaddress, #0        ; force a miss-aligned address
6301 +       jmpt.t          .+4                             ; delay for both address setup and trap disable
6302 +       move.4          (\Ascratch), #0
6303 +       .if             (\length > 32)
6304 +       move.4          32(\Ascratch), #0
6305 +       .endif
6306 +       .if             (\length > 64)
6307 +       move.4          64(\Ascratch), #0
6308 +       .endif
6309 +       .if             (\length > 96)
6310 +       move.4          96(\Ascratch), #0
6311 +       .endif
6312 +       .if             (\length > 128)
6313 +       invalid_instruction                             ; maximum pre-fetch size is 4 cache lines
6314 +       .endif
6315 +       bset            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
6316 +.endm
6317 +
6318 +#else
6319 +/*
6320 + * Same macro as above just in C inline asm
6321 + */
6322 +asm ("                                                         \n\
6323 +.macro pre_fetch_macro thread_num, Ascratch, Aaddress length   \n\
6324 +       bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)  \n\
6325 +       bset            \\Ascratch, \\Aaddress, #0      ; force a miss-aligned address \n\
6326 +       jmpt.t          .+4                             ; delay for both address setup and trap disable \n\
6327 +       move.4          (\\Ascratch), #0                        \n\
6328 +       .if             (\\length > 32)                         \n\
6329 +       move.4          32(\\Ascratch), #0                      \n\
6330 +       .endif                                                  \n\
6331 +       .if             (\\length > 64)                         \n\
6332 +       move.4          64(\\Ascratch), #0                      \n\
6333 +       .endif                                                  \n\
6334 +       .if             (\\length > 96)                         \n\
6335 +       move.4          96(\\Ascratch), #0                      \n\
6336 +       .endif                                                  \n\
6337 +       .if             (\\length > 128)                        \n\
6338 +       invalid_instruction                             ; maximum pre-fetch size is 4 cache lines \n\
6339 +       .endif                                                  \n\
6340 +       bset            MT_TRAP_EN, MT_TRAP_EN, #(\\thread_num) \n\
6341 +.endm                                                          \n\
6342 +");
6343 +#endif
6344 +
6345 +#endif /* !defined(__LINKER__) */
6346 +#endif /* defined _ASM_UBICOM32_IP5000_ASM_H */
6347 --- /dev/null
6348 +++ b/arch/ubicom32/include/asm/ip5000.h
6349 @@ -0,0 +1,860 @@
6350 +/*
6351 + * arch/ubicom32/include/asm/ip5000.h
6352 + *   Specific details for the Ubicom IP5000 processor.
6353 + *
6354 + * (C) Copyright 2009, Ubicom, Inc.
6355 + *
6356 + * This file is part of the Ubicom32 Linux Kernel Port.
6357 + *
6358 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
6359 + * it and/or modify it under the terms of the GNU General Public License
6360 + * as published by the Free Software Foundation, either version 2 of the
6361 + * License, or (at your option) any later version.
6362 + *
6363 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
6364 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
6365 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
6366 + * the GNU General Public License for more details.
6367 + *
6368 + * You should have received a copy of the GNU General Public License
6369 + * along with the Ubicom32 Linux Kernel Port.  If not,
6370 + * see <http://www.gnu.org/licenses/>.
6371 + *
6372 + * Ubicom32 implementation derived from (with many thanks):
6373 + *   arch/m68knommu
6374 + *   arch/blackfin
6375 + *   arch/parisc
6376 + */
6377 +
6378 +#ifndef _ASM_UBICOM32_IP5000_H
6379 +#define _ASM_UBICOM32_IP5000_H
6380 +
6381 +/*
6382 + * Inline assembly define
6383 + */
6384 +#define S(arg) #arg
6385 +#define D(arg) S(arg)
6386 +
6387 +/*
6388 + * Assembler include file
6389 + */
6390 +#include <asm/ip5000-asm.h>
6391 +
6392 +/*
6393 + * Timing
6394 + */
6395 +#define JMPT_PENALTY 3
6396 +#define JMPF_PENALTY 7
6397 +#define RET_PENALTY 7
6398 +
6399 +/*
6400 + * Threads
6401 + */
6402 +#if defined(IP5000) || defined(IP5000_REV2)
6403 +#define THREAD_COUNT 10
6404 +#elif defined(IP7000) || defined(IP7000_REV2)
6405 +#define THREAD_COUNT 12
6406 +#else
6407 +#error "Unknown IP5K silicon"
6408 +#endif
6409 +
6410 +/*
6411 + * Arch
6412 + */
6413 +#if defined(IP5000) || defined(IP5000_REV2)
6414 +#define UBICOM32_ARCH_VERSION 3
6415 +#elif defined(IP7000) || defined(IP7000_REV2)
6416 +#define UBICOM32_ARCH_VERSION 4
6417 +#else
6418 +#error "Unknown IP5K silicon"
6419 +#endif
6420 +
6421 +/*
6422 + * Memory Size
6423 + */
6424 +#define OCM_SECTOR_SIZE        0x00008000              /* 32K */
6425 +
6426 +#if defined(IP5000) || defined(IP5000_REV2)
6427 +#define OCMSIZE        0x00030000              /* 192K on-chip RAM for both program and data */
6428 +#elif defined(IP7000) || defined(IP7000_REV2)
6429 +#define OCMSIZE        0x0003C000              /* 240K on-chip RAM for both program and data */
6430 +#else
6431 +#error "Unknown IP5K silicon"
6432 +#endif
6433 +
6434 +#define OCMSTART       0x3ffc0000              /* alias from 0x03000000 for easy jump to/from SDRAM */
6435 +#define OCMEND         (OCMSTART + OCMSIZE)
6436 +#define SDRAMSTART     0x40000000
6437 +#define FLASHSTART     0x60000000
6438 +
6439 +/*
6440 + * Registers
6441 + */
6442 +#define ROSR_INT (1 << 0)
6443 +
6444 +/* Interrupts */
6445 +#define INT_CHIP(reg, bit) (((reg) << 5) | (bit))
6446 +#define INT_REG(interrupt) (((interrupt) >> 5) * 4)
6447 +#define INT_SET(interrupt) 0x0114 + INT_REG(interrupt)
6448 +#define INT_CLR(interrupt) 0x0124 + INT_REG(interrupt)
6449 +#define INT_STAT(interrupt) 0x0104 + INT_REG(interrupt)
6450 +#define INT_MASK(interrupt) 0x00C0 + INT_REG(interrupt)
6451 +#define INT_BIT(interrupt) ((interrupt) & 0x1F)
6452 +#define INT_BIT_MASK(interrupt) (1 << INT_BIT(interrupt))
6453 +
6454 +/*
6455 + * The LOCK_INT and THREAD_INT are used to wake up corresponding thread. They are sharing
6456 + * the same set of SW interrupt resource.
6457 + *
6458 + * LOCK_INT(n): One SW INT per NRT thread that can participate lock operation.
6459 + *     The threads that can participate lock are application threads and DSR thread.
6460 + *     (Lock locks - numbers are hard-coded in lock.h)
6461 + * THREAD_INT(n):   One SW INT per HRT thread for wake up trigger.
6462 + */
6463 +#define LOCK_INT(thread)       INT_CHIP(0, (thread))
6464 +#define THREAD_INT(thread)     INT_CHIP(0, (thread))
6465 +
6466 +/*
6467 + * The SYSTEM_INT and DSR_INT are sharing the same set of SW interrupt resource.
6468 + *
6469 + * SYSTEM_INT(n): One SW INT per NRT threads (application threads) as system queue interrupt,
6470 + *     and for DSR as self-trigger interrupt.
6471 + *     (The application threads include at least thread 0)
6472 + * DSR_INT(n):    One SW INT per HRT thread to request DSR service.
6473 + */
6474 +#define SYSTEM_INT(thread)     INT_CHIP(0, THREAD_COUNT + (thread))
6475 +#define DSR_INT(thread)                INT_CHIP(0, THREAD_COUNT + (thread))
6476 +
6477 +/* GLOBAL_CTRL */
6478 +#define GLOBAL_CTRL_TRAP_RST_EN (1 << 9)
6479 +#define GLOBAL_CTRL_AERROR_RST_EN (1 << 8)
6480 +#define GLOBAL_CTRL_MT_MIN_DELAY(x) ((x) << 3)
6481 +#define GLOBAL_CTRL_HRT_BANK_SELECT (1 << 2)
6482 +#define GLOBAL_CTRL_INT_EN (1 << 0)
6483 +
6484 +/*
6485 + * HRT Tables
6486 + */
6487 +#define HRT_TABLE0_BASE 0x0800
6488 +#define HRT_TABLE1_BASE 0x0900
6489 +#define HRT_TABLE_SIZE 64
6490 +
6491 +/*
6492 + * Break Point Trap Register
6493 + */
6494 +#define ASYNCERROR_INT INT_CHIP(0, 31)
6495 +#define BREAKPOINT_INT INT_CHIP(1, 31)
6496 +
6497 +/*
6498 + * Port interrupts
6499 + *     The non-existing FIFO INTs are mapped to INT2 for the ports.
6500 + */
6501 +#define IO_PORT_PTR_TO_NUM(port) (((port) & 0x0000ffff) >> 12)
6502 +#define RX_FIFO_INT(port) \
6503 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
6504 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 26) : \
6505 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6506 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 24) : \
6507 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 27) : \
6508 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 16) : \
6509 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6510 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6511 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 21) : \
6512 +       INT_CHIP(1, 15))))))))))
6513 +#define TX_FIFO_INT(port) \
6514 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 24) : \
6515 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 27) : \
6516 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6517 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 25) : \
6518 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 28) : \
6519 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 17) : \
6520 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6521 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6522 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 22) : \
6523 +       INT_CHIP(1, 15))))))))))
6524 +#define PORT_OTHER_INT(port) \
6525 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
6526 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 28) : \
6527 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6528 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 26) : \
6529 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 29) : \
6530 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 18) : \
6531 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6532 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6533 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 23) : \
6534 +       INT_CHIP(1, 15))))))))))
6535 +
6536 +/*
6537 + * On Chip Peripherals Base.
6538 + */
6539 +#define OCP_BASE       0x01000000
6540 +#define OCP_GENERAL    0x000
6541 +#define OCP_TIMERS     0x100
6542 +#define OCP_TRNG       0x200   /* True Random Number Generator Control Reigsters */
6543 +#define OCP_DEBUG      0x300
6544 +#define OCP_SECURITY   0x400
6545 +#define OCP_ICCR       0x500   /* I-Cache Control Registers */
6546 +#define OCP_DCCR       0x600   /* D-Cache Control Registers */
6547 +#define OCP_OCMC       0x700   /* On Chip Memory Control Registers */
6548 +#define OCP_STATISTICS 0x800   /* Statistics Counters */
6549 +#define OCP_MTEST      0x900   /* Memory Test Registers */
6550 +#define OCP_MCFG       0xa00   /* Memory Configuration Registers -- IP7000 only */
6551 +#define OCP_DEBUG_INST 0x000   /* Up to 16M */
6552 +
6553 +/*
6554 + * General Configuration Registers (PLL)
6555 + */
6556 +#define GENERAL_CFG_BASE (OCP_BASE + OCP_GENERAL)
6557 +#define GEN_CLK_CORE_CFG 0x00
6558 +#define GEN_CLK_IO_CFG 0x04
6559 +#define GEN_CLK_DDR_CFG 0x08
6560 +#define GEN_CLK_DDRDS_CFG 0x0c
6561 +#define GEN_CLK_SLIP_CLR 0x10
6562 +#define GEN_CLK_SLIP_START 0x14
6563 +#define GEN_CLK_SERDES_SEL 0x18        /* IP7000 only */
6564 +#define GEN_CLK_DDR_CFG2 0x1c  /* IP7000 only */
6565 +#define GEN_DDR_CAL_CTRL 0x30  /* IP5000 only */
6566 +#define GEN_DDR_CAL_STAT 0x34  /* IP5000 only */
6567 +#define GEN_USB_DFT_CTRL 0x38  /* IP5000 only */
6568 +#define GEN_USB_DFT_STAT 0x3c  /* IP5000 only */
6569 +#define GEN_USB_PHY_CFG 0x40   /* IP7000 only */
6570 +#define GEN_USB_PHY_TEST 0x44  /* IP7000 only */
6571 +#define GEN_USB_PHY_STAT 0x48  /* IP7000 only */
6572 +#define GEN_SW_RESET 0x80
6573 +#define GEN_RESET_REASON 0x84
6574 +#define GEN_BOND_CFG 0x88
6575 +#define GEN_IO_PU_CFG 0x8c
6576 +#define GEN_MEM_RM_CFG 0x90
6577 +#define GEN_IO_CONFIG 0x94
6578 +
6579 +#define GEN_CLK_PLL_SECURITY_BIT_NO 31
6580 +#define GEN_CLK_PLL_SECURITY (1 << GEN_CLK_PLL_SECURITY_BIT_NO)
6581 +#define GEN_CLK_PLL_ENSAT (1 << 30)
6582 +#define GEN_CLK_PLL_FASTEN (1 << 29)
6583 +#define GEN_CLK_PLL_NR(v) (((v) - 1) << 23)
6584 +#define GEN_CLK_PLL_NF(v) (((v) - 1) << 11)
6585 +#define GEN_CLK_PLL_OD(v) (((v) - 1) << 8)
6586 +#define GEN_CLK_PLL_RESET (1 << 7)
6587 +#define GEN_CLK_PLL_BYPASS (1 << 6)
6588 +#define GEN_CLK_PLL_POWERDOWN (1 << 5)
6589 +#define GEN_CLK_PLL_SELECT (1 << 4)
6590 +
6591 +#define GEN_GET_CLK_PLL_NR(v) ((((v) >> 23) & 0x003f) + 1)
6592 +#define GEN_GET_CLK_PLL_NF(v) ((((v) >> 11) & 0x0fff) + 1)
6593 +#define GEN_GET_CLK_PLL_OD(v) ((((v) >> 8) & 0x7) + 1)
6594 +
6595 +
6596 +#define RESET_FLAG_DST_MEM_ERROR (1 << 18)
6597 +#define RESET_FLAG_SRC1_MEM_ERROR (1 << 17)
6598 +#define RESET_FLAG_WRITE_ADDR (1 << 16)
6599 +#define RESET_FLAG_DST_SYNC_ERROR (1 << 15)
6600 +#define RESET_FLAG_SRC1_SYNC_ERROR (1 << 14)
6601 +#define RESET_FLAG_DST_ALGN_ERROR (1 << 13)
6602 +#define RESET_FLAG_SRC1_ALGN_ERROR (1 << 12)
6603 +#define RESET_FLAG_DST_ADDR_ERROR (1 << 11)
6604 +#define RESET_FLAG_SRC1_ADDR_ERROR (1 << 10)
6605 +#define RESET_FLAG_ILLEGAL_INST (1 << 9)
6606 +#define RESET_FLAG_INST_SYNC_ERROR (1 << 8)
6607 +#define RESET_FLAG_INST_ADDR_ERROR (1 << 7)
6608 +#define RESET_FLAG_DATA_PORT_ERROR (1 << 6)
6609 +#define RESET_FLAG_INST_PORT_ERROR (1 << 5)
6610 +#define RESET_FLAG_SW_RESET (1 << 4)
6611 +#define RESET_FLAG_DEBUG (1 << 3)
6612 +#define RESET_FLAG_WATCHDOG (1 << 2)
6613 +#define RESET_FLAG_POWER_ON (1 << 1)
6614 +#define RESET_FLAG_EXTERNAL (1 << 0)
6615 +
6616 +/*
6617 + * Timer block
6618 + */
6619 +#define TIMER_BASE (OCP_BASE + OCP_TIMERS)
6620 +#define TIMER_MPTVAL 0x00
6621 +#define TIMER_RTCOM 0x04
6622 +#define TIMER_TKEY 0x08
6623 +#define TIMER_WDCOM 0x0c
6624 +#define TIMER_WDCFG 0x10
6625 +#define TIMER_SYSVAL 0x14
6626 +#define TIMER_SYSCOM(tmr) (0x18 + (tmr) * 4)
6627 +#define TIMER_TRN_CFG 0x100
6628 +#define TIMER_TRN 0x104
6629 +
6630 +#define TIMER_COUNT 10
6631 +#define TIMER_INT(tmr) INT_CHIP(1, (tmr))
6632 +#define TIMER_TKEYVAL 0xa1b2c3d4
6633 +#define TIMER_WATCHDOG_DISABLE 0x4d3c2b1a
6634 +#define TIMER_TRN_CFG_ENABLE_OSC 0x00000007
6635 +
6636 +#ifndef __ASSEMBLY__
6637 +/*
6638 + * ubicom32_io_timer
6639 + */
6640 +struct ubicom32_io_timer {
6641 +       volatile u32_t mptval;
6642 +       volatile u32_t rtcom;
6643 +       volatile u32_t tkey;
6644 +       volatile u32_t wdcom;
6645 +       volatile u32_t wdcfg;
6646 +       volatile u32_t sysval;
6647 +       volatile u32_t syscom[TIMER_COUNT];
6648 +       volatile u32_t reserved[64 - 6 - TIMER_COUNT];  // skip all the way to OCP-TRNG section
6649 +       volatile u32_t rsgcfg;
6650 +       volatile u32_t trn;
6651 +};
6652 +
6653 +#define UBICOM32_IO_TIMER ((struct ubicom32_io_timer *)TIMER_BASE)
6654 +#endif
6655 +
6656 +#define UBICOM32_VECTOR_TO_TIMER_INDEX(vector) (vector - TIMER_INT(0))
6657 +
6658 +/*
6659 + * OCP-Debug Module (Mailbox)
6660 + */
6661 +#define ISD_MAILBOX_BASE (OCP_BASE + OCP_DEBUG)
6662 +#define ISD_MAILBOX_IN 0x00
6663 +#define ISD_MAILBOX_OUT 0x04
6664 +#define ISD_MAILBOX_STATUS 0x08
6665 +
6666 +#define ISD_MAILBOX_INT INT_CHIP(1, 30)
6667 +
6668 +#define ISD_MAILBOX_STATUS_IN_FULL (1 << 31)
6669 +#define ISD_MAILBOX_STATUS_IN_EMPTY (1 << 30)
6670 +#define ISD_MAILBOX_STATUS_OUT_FULL (1 << 29)
6671 +#define ISD_MAILBOX_STATUS_OUT_EMPTY (1 << 28)
6672 +
6673 +/*
6674 + * OCP-Security
6675 + */
6676 +#define SECURITY_BASE (OCP_BASE + OCP_SECURITY)
6677 +#define SECURITY_BASE_EFFECTIVE_ADDRESS (SECURITY_BASE >> 7) // To load the base address in a single instruction
6678 +#define SECURITY_CTRL 0x00
6679 +#define SECURITY_CTRL_BYTE_OFFSET(x) ((x) << 16)
6680 +#define SECURITY_CTRL_KEY_SIZE(x) ((x) << 8)
6681 +#define SECURITY_CTRL_HASH_ALG_NONE (0 << 4)
6682 +#define SECURITY_CTRL_HASH_ALG_MD5 (1 << 4)
6683 +#define SECURITY_CTRL_HASH_ALG_SHA1 (2 << 4)
6684 +#define SECURITY_CTRL_CBC (1 << 3)
6685 +#define SECURITY_CTRL_CIPHER_ALG_AES (0 << 1)
6686 +#define SECURITY_CTRL_CIPHER_ALG_NONE (1 << 1)
6687 +#define SECURITY_CTRL_CIPHER_ALG_DES (2 << 1)
6688 +#define SECURITY_CTRL_CIPHER_ALG_3DES (3 << 1)
6689 +#define SECURITY_CTRL_ENCIPHER (1 << 0)
6690 +#define SECURITY_CTRL_DECIPHER (0 << 0)
6691 +#define SECURITY_STAT 0x04
6692 +#define SECURITY_STAT_BUSY (1 << 0)
6693 +#define SECURITY_KEY_VALUE(x) (0x10 + (x) * 4)
6694 +#define SECURITY_KEY_IN(x) (0x30 + (x) * 4)
6695 +#define SECURITY_KEY_OUT(x) (0x50 + (x) * 4)
6696 +#define SECURITY_KEY_HASH(x) (0x70 + (x) * 4)
6697 +
6698 +/*
6699 + * OCP-ICCR
6700 + */
6701 +#define ICCR_BASE (OCP_BASE + OCP_ICCR)
6702 +#define ICACHE_TOTAL_SIZE 16384                        /* in bytes */
6703 +
6704 +/*
6705 + * OCP-DCCR
6706 + */
6707 +#define DCCR_BASE (OCP_BASE + OCP_DCCR)
6708 +#if defined(IP5000) || defined(IP5000_REV2)
6709 +#define DCACHE_TOTAL_SIZE 8192                 /* in bytes */
6710 +#elif defined(IP7000) || defined(IP7000_REV2)
6711 +#define DCACHE_TOTAL_SIZE 16384                        /* in bytes */
6712 +#endif
6713 +
6714 +#if defined(IP5000) || defined(IP5000_REV2) || defined(IP7000) || defined(IP7000_REV2)
6715 +#define DCACHE_WRITE_QUEUE_LENGTH 6
6716 +#else
6717 +#error "Unknown IP5K silicon"
6718 +#endif
6719 +
6720 +#define CACHE_LINE_SIZE 32                     /* in bytes */
6721 +
6722 +#define CCR_ADDR 0x00
6723 +#define CCR_RDD 0x04
6724 +#define CCR_WRD 0x08
6725 +#define CCR_STAT 0x0c
6726 +#define CCR_CTRL 0x10
6727 +
6728 +#define CCR_STAT_MCBE 0
6729 +#define CCR_STAT_WIDEL 1                       /* D-cache only */
6730 +
6731 +#define CCR_CTRL_DONE 0
6732 +#define CCR_CTRL_RESET 2
6733 +#define CCR_CTRL_VALID 3
6734 +#define CCR_CTRL_RD_DATA (1 << 4)
6735 +#define CCR_CTRL_RD_TAG (2 << 4)
6736 +#define CCR_CTRL_WR_DATA (3 << 4)
6737 +#define CCR_CTRL_WR_TAG (4 << 4)
6738 +#define CCR_CTRL_INV_INDEX (5 << 4)
6739 +#define CCR_CTRL_INV_ADDR (6 << 4)
6740 +#define CCR_CTRL_FLUSH_INDEX (7 << 4)          /* D-cache only */
6741 +#define CCR_CTRL_FLUSH_INV_INDEX (8 << 4)      /* D-cache only */
6742 +#define CCR_CTRL_FLUSH_ADDR (9 << 4)           /* D-cache only */
6743 +#define CCR_CTRL_FLUSH_INV_ADDR (10 << 4)      /* D-cache only */
6744 +
6745 +/*
6746 + * OCP-OCMC
6747 + */
6748 +#define OCMC_BASE (OCP_BASE + OCP_OCMC)
6749 +#define OCMC_BANK_MASK 0x00
6750 +#define OCMC_BIST_CNTL 0x04    /* IP5000 only */
6751 +#define OCMC_BIST_STAT 0x08    /* IP5000 only */
6752 +
6753 +#define OCMC_BANK_PROG(n) ((1<<(n))-1)
6754 +
6755 +#define OCMC_BIST_WRCK (1 << 7)
6756 +#define OCMC_BIST_RESET (1 << 5)
6757 +#define OCMC_BIST_SMART (1 << 4)
6758 +#define OCMC_BIST_RUN (1 << 3)
6759 +#define OCMC_BIST_REPAIR (1 << 2)
6760 +
6761 +#define OCMC_BIST_READY (1 << 3)
6762 +#define OCMC_BIST_FAIL (1 << 2)
6763 +
6764 +/*
6765 + * OCP-STATISTICS
6766 + */
6767 +#define STATISTICS_BASE (OCP_BASE + OCP_STATISTICS)
6768 +#define STAT_COUNTER_CTRL(n) ((n)*8)
6769 +#define STAT_COUNTER(n) ((n)*8 + 4)
6770 +
6771 +#define STAT_EVENT_MP_INST 0
6772 +#define STAT_EVENT_OCM_ACCESS 4
6773 +#define STAT_EVENT_OCM_REQ 5
6774 +#define STAT_EVENT_IC_REQ_INVAL 13
6775 +#define STAT_EVENT_IC_MISS_INVAL 14
6776 +#define STAT_EVENT_IC_REQ_INVAL_NACK 15
6777 +#define STAT_EVENT_IC_REQ_VAL 16
6778 +#define STAT_EVENT_IC_MISS_VAL 17
6779 +#define STAT_EVENT_IC_REQ_VAL_NACK 18
6780 +#define STAT_EVENT_IC_MISS_Q 19
6781 +#define STAT_EVENT_DC_RD_REQ 20
6782 +#define STAT_EVENT_DC_RD_MISS 21
6783 +#define STAT_EVENT_DC_WR_REQ 22
6784 +#define STAT_EVENT_DC_WR_MISS 23
6785 +#define STAT_EVENT_DC_MISS_Q 24
6786 +#define STAT_EVENT_DC_WB_FULL 25
6787 +#define STAT_EVENT_DC_REQ_NACK 26
6788 +#define STAT_EVENT_DC_CORE_REQ 27
6789 +#define STAT_EVENT_DC_MISS 28
6790 +#define STAT_EVENT_DC_EVICT 29
6791 +#define STAT_EVENT_TRUE 30
6792 +#define STAT_EVENT_FALSE 31
6793 +
6794 +/*
6795 + * OCP_MTEST
6796 + */
6797 +#define MTEST_BASE (OCP_BASE + OCP_MTEST)
6798 +#define MTEST_ADDR 0x00
6799 +#define MTEST_WR 0x04
6800 +#define MTEST_RD 0x08
6801 +#define MTEST_CTRL 0x0c
6802 +
6803 +/*
6804 + * OCP_MCFG (IP7000 only)
6805 + */
6806 +#define MCFG_BASE (OCP_BASE + OCP_MCFG)
6807 +#define MCFG_CTRL 0x00
6808 +#define MCFG_WCFG 0x04
6809 +#define MCFG_RCFG 0x08
6810 +
6811 +/*
6812 + * Port registers
6813 + */
6814 +#define IO_BASE 0x02000000
6815 +#define RA (IO_BASE + 0x00000000)
6816 +#define RB (IO_BASE + 0x00001000)
6817 +#define RC (IO_BASE + 0x00002000)
6818 +#define RD (IO_BASE + 0x00003000)
6819 +#define RE (IO_BASE + 0x00004000)
6820 +#define RF (IO_BASE + 0x00005000)
6821 +#define RG (IO_BASE + 0x00006000)
6822 +#define RH (IO_BASE + 0x00007000)
6823 +#define RI (IO_BASE + 0x00008000)
6824 +#define RJ (IO_BASE + 0x00009000)
6825 +#define RLATCH (IO_BASE + 0x00ff0000)  // For latched output only
6826 +#define IO_PORT_BR_OFFSET 0x00000800
6827 +
6828 +/*
6829 + * General I/O Register Map (per port)
6830 + */
6831 +#define IO_FUNC 0x00
6832 +#define IO_GPIO_CTL 0x04
6833 +#define IO_GPIO_OUT 0x08
6834 +#define IO_GPIO_IN 0x0C
6835 +#define IO_INT_STATUS 0x10
6836 +#define IO_INT_MASK 0x14
6837 +#define IO_INT_SET 0x18
6838 +#define IO_INT_CLR 0x1C
6839 +#define IO_TX_FIFO 0x20
6840 +#define IO_TX_FIFO_HI 0x24
6841 +#define IO_RX_FIFO 0x28
6842 +#define IO_RX_FIFO_HI 0x2c
6843 +#define IO_CTL0 0x30
6844 +#define IO_CTL1 0x34
6845 +#define IO_CTL2 0x38
6846 +#define IO_STATUS0 0x3c
6847 +#define IO_STATUS1 0x40
6848 +#define IO_STATUS2 0x44
6849 +#define IO_FIFO_WATER 0x48
6850 +#define IO_FIFO_LEVEL 0x4c
6851 +#define IO_GPIO_MASK 0x50
6852 +
6853 +#define IO_FUNC_FUNCTION_RESET(func) ((1 << ((func) - 1)) << 4)        /* Function 0 doesn't need reset */
6854 +#define IO_FUNC_RX_FIFO (1 << 3)
6855 +#define IO_FUNC_SELECT(func) ((func) << 0)
6856 +
6857 +/*
6858 + * External interrupt pins.
6859 + */
6860 +#define EXT_INT_IO_BIT(pin) ((pin) + 5)        // Interrupt pin number -> I/O INT bit
6861 +#define EXT_INT_RISING_EDGE(pin) (0x2 << (2*(pin) + 7))
6862 +#define EXT_INT_FALLING_EDGE(pin) (0x1 << (2*(pin) + 7))
6863 +
6864 +/*
6865 + * Flash
6866 + */
6867 +#define IO_XFL_BASE RA
6868 +
6869 +#define IO_XFL_INT_START (1 << 16)
6870 +#define IO_XFL_INT_ERR (1 << 8)
6871 +#define IO_XFL_INT_DONE (1 << 0)
6872 +
6873 +#define IO_XFL_CTL0_MASK (0xffe07fff)
6874 +#define IO_XFL_CTL0_RD_CMD(cmd) (((cmd) & 0xff) << 24)
6875 +#define IO_XFL_CTL0_RD_DUMMY(n) (((n) & 0x7) << 21)
6876 +#define IO_XFL_CTL0_CLK_WIDTH(core_cycles) ((((core_cycles) + 1) & 0x7e) << 8) /* must be even number */
6877 +#define IO_XFL_CTL0_CE_WAIT(spi_cycles) (((spi_cycles) & 0x3f) << 2)
6878 +#define IO_XFL_CTL0_MCB_LOCK (1 << 1)
6879 +#define IO_XFL_CTL0_ENABLE (1 << 0)
6880 +#define IO_XFL_CTL0_FAST_VALUE(div, wait) (IO_XFL_CTL0_RD_CMD(0xb) | IO_XFL_CTL0_RD_DUMMY(1) | IO_XFL_CTL0_CLK_WIDTH(div) | IO_XFL_CTL0_CE_WAIT(wait) | IO_XFL_CTL0_ENABLE)
6881 +#define IO_XFL_CTL0_VALUE(div, wait) (IO_XFL_CTL0_RD_CMD(3) | IO_XFL_CTL0_CLK_WIDTH(div) | IO_XFL_CTL0_CE_WAIT(wait) | IO_XFL_CTL0_ENABLE)
6882 +
6883 +#define IO_XFL_CTL1_MASK (0xc0003fff)
6884 +#define IO_XFL_CTL1_FC_INST(inst) (((inst) & 0x3) << 30)
6885 +#define IO_XFL_CTL1_FC_DATA(n) (((n) & 0x3ff) << 4)
6886 +#define IO_XFL_CTL1_FC_DUMMY(n) (((n) & 0x7) << 1)
6887 +#define IO_XFL_CTL1_FC_ADDR (1 << 0)
6888 +
6889 +#define IO_XFL_CTL2_FC_CMD(cmd) (((cmd) & 0xff) << 24)
6890 +#define IO_XFL_CTL2_FC_ADDR(addr) ((addr) & 0x00ffffff)        /* Only up to 24 bits */
6891 +
6892 +#define IO_XFL_STATUS0_MCB_ACTIVE (1 << 0)
6893 +#define IO_XFL_STATUS0_IOPCS_ACTIVE (1 << 1)
6894 +
6895 +/*
6896 + * SDRAM
6897 + */
6898 +#define IO_SDRAM_DATA_BASE RG
6899 +#define IO_SDRAM_CNTL_BASE RH
6900 +
6901 +#define IO_SDRAM_CTRL0_EN_REF (1 << 0)
6902 +
6903 +/*
6904 + * Port function code (common fucntion codes for all I/O ports)
6905 + */
6906 +#define IO_PORTX_FUNC_GPIO 0x00
6907 +#define IO_PORTX_FUNC_XFL 0x01
6908 +#define IO_PORTX_FUNC_PCI 0x01
6909 +#define IO_PORTX_FUNC_SERDES 0x01
6910 +#define IO_PORTX_FUNC_GMII 0x01
6911 +#define IO_PORTX_FUNC_DDR 0x01
6912 +#define IO_PORTX_FUNC_PCIX 0x01
6913 +#define IO_PORTX_FUNC_USB2_0 0x01
6914 +#define IO_PORTX_FUNC_GPIO_INT_CLK 0x02
6915 +#define IO_PORTX_FUNC_PLIO 0x02
6916 +#define IO_PORTX_FUNC_GPIO_INT 0x03
6917 +#define IO_PORTX_FUNC_MII 0x03
6918 +
6919 +/*
6920 + * Port 0
6921 + */
6922 +#define IO_PORT0_FUNC_GPIO IO_PORTX_FUNC_GPIO
6923 +#define IO_PORT0_FUNC_XFL_INT_CLK IO_PORTX_FUNC_XFL    // Default mode after reset
6924 +#define IO_PORT0_FUNC_GPIO_INT_CLK IO_PORTX_FUNC_GPIO_INT_CLK
6925 +#define IO_PORT0_FUNC_GPIO_INT IO_PORTX_FUNC_GPIO_INT
6926 +
6927 +/*
6928 + * Port 1
6929 + */
6930 +#define IO_PORT1_FUNC_GPIO IO_PORTX_FUNC_GPIO
6931 +#define IO_PORT1_FUNC_PCI IO_PORTX_FUNC_PCI            // PCI control
6932 +#define IO_PORT1_FUNC_MII IO_PORTX_FUNC_MII            // port 4 MII extension
6933 +
6934 +/*
6935 + * Port 2
6936 + */
6937 +#define IO_PORT2_FUNC_GPIO IO_PORTX_FUNC_GPIO
6938 +#define IO_PORT2_FUNC_PCI IO_PORTX_FUNC_PCI            // PCI data I/O
6939 +#define IO_PORT2_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
6940 +
6941 +/*
6942 + * Port 3
6943 + */
6944 +#define IO_PORT3_FUNC_GPIO IO_PORTX_FUNC_GPIO
6945 +#define IO_PORT3_FUNC_SERDES IO_PORTX_FUNC_SERDES
6946 +#define IO_PORT3_FUNC_PLIO IO_PORTX_FUNC_PLIO
6947 +
6948 +/*
6949 + * Port 4
6950 + */
6951 +#define IO_PORT4_FUNC_GPIO IO_PORTX_FUNC_GPIO
6952 +#define IO_PORT4_FUNC_SERDES IO_PORTX_FUNC_SERDES
6953 +#define IO_PORT4_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
6954 +#define IO_PORT4_FUNC_MII IO_PORTX_FUNC_MII
6955 +
6956 +/*
6957 + * Port 5
6958 + */
6959 +#define IO_PORT5_FUNC_GPIO IO_PORTX_FUNC_GPIO
6960 +#define IO_PORT5_FUNC_GMII IO_PORTX_FUNC_GMII
6961 +
6962 +/*
6963 + * Port 6
6964 + */
6965 +#define IO_PORT6_FUNC_GPIO IO_PORTX_FUNC_GPIO
6966 +#define IO_PORT6_FUNC_DDR IO_PORTX_FUNC_DDR
6967 +
6968 +/*
6969 + * Port 7
6970 + */
6971 +#define IO_PORT7_FUNC_GPIO IO_PORTX_FUNC_GPIO
6972 +#define IO_PORT7_FUNC_DDR IO_PORTX_FUNC_DDR
6973 +
6974 +/*
6975 + * Port 8
6976 + */
6977 +#define IO_PORT8_FUNC_GPIO IO_PORTX_FUNC_GPIO
6978 +#define IO_PORT8_FUNC_PCIX IO_PORTX_FUNC_PCIX
6979 +#define IO_PORT8_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
6980 +#define IO_PORT8_FUNC_MII IO_PORTX_FUNC_MII            // port 4 MII extension
6981 +
6982 +/*
6983 + * Port 9
6984 + */
6985 +#define IO_PORT9_FUNC_USB2_0 IO_PORTX_FUNC_USB2_0
6986 +
6987 +/*
6988 + * FIFO
6989 + */
6990 +#define IO_PORTX_INT_FIFO_TX_RESET (1 << 31)
6991 +#define IO_PORTX_INT_FIFO_RX_RESET (1 << 30)
6992 +#define IO_PORTX_INT_FIFO_TX_UF (1 << 15)
6993 +#define IO_PORTX_INT_FIFO_TX_WM (1 << 14)
6994 +#define IO_PORTX_INT_FIFO_RX_OF (1 << 13)
6995 +#define IO_PORTX_INT_FIFO_RX_WM (1 << 12)
6996 +
6997 +#define IO_PORTX_FUNC_FIFO_TX_WM(n) ((n) << 16)
6998 +#define IO_PORTX_FUNC_FIFO_RX_WM(n) ((n) << 0)
6999 +
7000 +/*
7001 + * MII
7002 + */
7003 +#define IO_PORTX_INT_MII_TX_ERR_SEND (1 << 18)
7004 +#define IO_PORTX_INT_MII_TX_HALT (1 << 17)
7005 +#define IO_PORTX_INT_MII_TX_START (1 << 16)
7006 +#define IO_PORTX_INT_MII_THRESHOLD (1 << 8)
7007 +#define IO_PORTX_INT_MII_RX_EOP (1 << 7)
7008 +#define IO_PORTX_INT_MII_RX_SFD (1 << 6)
7009 +#define IO_PORTX_INT_MII_RX_ERR (1 << 5)
7010 +#define IO_PORTX_INT_MII_TX_EOP (1 << 4)
7011 +#define IO_PORTX_INT_MII_COL (1 << 3)
7012 +#define IO_PORTX_INT_MII_CRS (1 << 2)
7013 +#define IO_PORTX_INT_MII_ODD_NIB_ERR (1 << 1)
7014 +#define IO_PORTX_INT_MII_FALSE_CARRIER (1 << 0)
7015 +
7016 +/*
7017 + * SerDes
7018 + */
7019 +#define IO_PORTX_INT_SERDES_TXBUF_VALID (1 << 16)
7020 +#define IO_PORTX_INT_SERDES_RXERR (1 << 7)
7021 +#define IO_PORTX_INT_SERDES_RXEOP (1 << 6)
7022 +#define IO_PORTX_INT_SERDES_SYND (1 << 5)
7023 +#define IO_PORTX_INT_SERDES_TXBE (1 << 4)
7024 +#define IO_PORTX_INT_SERDES_TXEOP (1 << 3)
7025 +#define IO_PORTX_INT_SERDES_SXLP (1 << 2)
7026 +#define IO_PORTX_INT_SERDES_RXBF (1 << 1)
7027 +#define IO_PORTX_INT_SERDES_RXCRS (1 << 0)
7028 +
7029 +#ifndef __ASSEMBLY__
7030 +struct ubicom32_io_port {
7031 +       volatile u32_t function;
7032 +       volatile u32_t gpio_ctl;
7033 +       volatile u32_t gpio_out;
7034 +       volatile u32_t gpio_in;
7035 +       volatile u32_t int_status;
7036 +       volatile u32_t int_mask;
7037 +       volatile u32_t int_set;
7038 +       volatile u32_t int_clr;
7039 +       volatile u32_t tx_fifo;
7040 +       volatile u32_t tx_fifo_hi;
7041 +       volatile u32_t rx_fifo;
7042 +       volatile u32_t rx_fifo_hi;
7043 +       volatile u32_t ctl0;
7044 +       volatile u32_t ctl1;
7045 +       volatile u32_t ctl2;
7046 +       volatile u32_t status0;
7047 +       volatile u32_t status1;
7048 +       volatile u32_t status2;
7049 +       volatile u32_t fifo_watermark;
7050 +       volatile u32_t fifo_level;
7051 +       volatile u32_t gpio_mask;
7052 +};
7053 +
7054 +#define UBICOM32_IO_PORT(port) ((struct ubicom32_io_port *)((port)))
7055 +#endif
7056 +
7057 +#ifndef __ASSEMBLY__
7058 +/*
7059 + * ubicom32_set_interrupt()
7060 + */
7061 +extern inline void ubicom32_set_interrupt(u8_t interrupt)
7062 +{
7063 +       u32_t ibit = INT_BIT_MASK(interrupt);
7064 +
7065 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7066 +               asm volatile (
7067 +                       "move.4         "D(INT_SET(INT_CHIP(0, 0)))", %0\n\t"
7068 +                       :
7069 +                       : "r" (ibit)
7070 +               );
7071 +
7072 +               return;
7073 +       }
7074 +
7075 +       asm volatile (
7076 +               "move.4         "D(INT_SET(INT_CHIP(1, 0)))", %0\n\t"
7077 +               :
7078 +               : "r" (ibit)
7079 +       );
7080 +}
7081 +
7082 +/*
7083 + * ubicom32_clear_interrupt()
7084 + */
7085 +extern inline void ubicom32_clear_interrupt(u8_t interrupt)
7086 +{
7087 +       u32_t ibit = INT_BIT_MASK(interrupt);
7088 +
7089 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7090 +               asm volatile (
7091 +                       "move.4         "D(INT_CLR(INT_CHIP(0, 0)))", %0\n\t"
7092 +                       :
7093 +                       : "r" (ibit)
7094 +               );
7095 +
7096 +               return;
7097 +       }
7098 +
7099 +       asm volatile (
7100 +               "move.4         "D(INT_CLR(INT_CHIP(1, 0)))", %0\n\t"
7101 +               :
7102 +               : "r" (ibit)
7103 +       );
7104 +}
7105 +
7106 +/*
7107 + * ubicom32_enable_interrupt()
7108 + */
7109 +extern inline void ubicom32_enable_interrupt(u8_t interrupt)
7110 +{
7111 +       u32_t ibit = INT_BIT_MASK(interrupt);
7112 +
7113 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7114 +               asm volatile (
7115 +                       "or.4           "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7116 +                       :
7117 +                       : "d" (ibit)
7118 +               );
7119 +
7120 +               return;
7121 +       }
7122 +
7123 +       asm volatile (
7124 +               "or.4           "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7125 +               :
7126 +               : "d" (ibit)
7127 +       );
7128 +}
7129 +
7130 +/*
7131 + * ubicom32_disable_interrupt()
7132 + */
7133 +extern inline void ubicom32_disable_interrupt(u8_t interrupt)
7134 +{
7135 +       u32_t ibit = ~INT_BIT_MASK(interrupt);
7136 +
7137 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7138 +               asm volatile (
7139 +                       "and.4          "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7140 +                       :
7141 +                       : "d" (ibit)
7142 +               );
7143 +
7144 +               return;
7145 +       }
7146 +
7147 +       asm volatile (
7148 +               "and.4          "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7149 +               :
7150 +               : "d" (ibit)
7151 +       );
7152 +}
7153 +
7154 +/*
7155 + * ubicom32_enable_global_interrupts()
7156 + */
7157 +extern inline void ubicom32_enable_global_interrupts(void)
7158 +{
7159 +       asm volatile(
7160 +               "bset           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7161 +       );
7162 +}
7163 +
7164 +/*
7165 + * ubicom32_disable_global_interrupts()
7166 + */
7167 +extern inline void ubicom32_disable_global_interrupts(void)
7168 +{
7169 +       asm volatile(
7170 +               "bclr           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7171 +       );
7172 +}
7173 +
7174 +/*
7175 + * ubicom32_get_reset_reason()
7176 + */
7177 +extern inline u32_t ubicom32_get_reset_reason(void)
7178 +{
7179 +       return *(u32_t *)(GENERAL_CFG_BASE + GEN_RESET_REASON);
7180 +}
7181 +
7182 +/*
7183 + * ubicom32_read_reg()
7184 + */
7185 +extern inline u32_t ubicom32_read_reg(volatile void *reg)
7186 +{
7187 +       u32_t v;
7188 +       asm volatile (
7189 +               "move.4         %[dest], %[src] \n\t"
7190 +               : [dest] "=r" (v)
7191 +               : [src] "m" (*(u32_t *)reg)
7192 +       );
7193 +       return v;
7194 +}
7195 +
7196 +/*
7197 + * ubicom32_write_reg()
7198 + */
7199 +extern inline void ubicom32_write_reg(volatile void *reg, u32_t v)
7200 +{
7201 +       asm volatile (
7202 +               "move.4         %[dest], %[src] \n\t"
7203 +               :
7204 +               : [src] "r" (v), [dest] "m" (*(u32_t *)reg)
7205 +       );
7206 +}
7207 +
7208 +#endif /* __ASSEMBLY__ */
7209 +#endif /* _ASM_UBICOM32_IP5000_H */
7210 --- /dev/null
7211 +++ b/arch/ubicom32/include/asm/ipcbuf.h
7212 @@ -0,0 +1,55 @@
7213 +/*
7214 + * arch/ubicom32/include/asm/ipcbuf.h
7215 + *   Definition of ipc64_perm struct for Ubicom32 architecture.
7216 + *
7217 + * (C) Copyright 2009, Ubicom, Inc.
7218 + *
7219 + * This file is part of the Ubicom32 Linux Kernel Port.
7220 + *
7221 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7222 + * it and/or modify it under the terms of the GNU General Public License
7223 + * as published by the Free Software Foundation, either version 2 of the
7224 + * License, or (at your option) any later version.
7225 + *
7226 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7227 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7228 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7229 + * the GNU General Public License for more details.
7230 + *
7231 + * You should have received a copy of the GNU General Public License
7232 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7233 + * see <http://www.gnu.org/licenses/>.
7234 + *
7235 + * Ubicom32 implementation derived from (with many thanks):
7236 + *   arch/m68knommu
7237 + *   arch/blackfin
7238 + *   arch/parisc
7239 + */
7240 +#ifndef _ASM_UBICOM32_IPCBUF_H
7241 +#define _ASM_UBICOM32_IPCBUF_H
7242 +
7243 +/*
7244 + * The user_ipc_perm structure for m68k architecture.
7245 + * Note extra padding because this structure is passed back and forth
7246 + * between kernel and user space.
7247 + *
7248 + * Pad space is left for:
7249 + * - 32-bit mode_t and seq
7250 + * - 2 miscellaneous 32-bit values
7251 + */
7252 +struct ipc64_perm
7253 +{
7254 +       __kernel_key_t          key;
7255 +       __kernel_uid32_t        uid;
7256 +       __kernel_gid32_t        gid;
7257 +       __kernel_uid32_t        cuid;
7258 +       __kernel_gid32_t        cgid;
7259 +       __kernel_mode_t         mode;
7260 +       unsigned short          __pad1;
7261 +       unsigned short          seq;
7262 +       unsigned short          __pad2;
7263 +       unsigned long           __unused1;
7264 +       unsigned long           __unused2;
7265 +};
7266 +
7267 +#endif /* _ASM_UBICOM32_IPCBUF_H */
7268 --- /dev/null
7269 +++ b/arch/ubicom32/include/asm/irqflags.h
7270 @@ -0,0 +1,94 @@
7271 +/*
7272 + * arch/ubicom32/include/asm/irqflags.h
7273 + *   Raw implementation of local IRQ functions.
7274 + *
7275 + * (C) Copyright 2009, Ubicom, Inc.
7276 + *
7277 + * This file is part of the Ubicom32 Linux Kernel Port.
7278 + *
7279 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7280 + * it and/or modify it under the terms of the GNU General Public License
7281 + * as published by the Free Software Foundation, either version 2 of the
7282 + * License, or (at your option) any later version.
7283 + *
7284 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7285 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7286 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7287 + * the GNU General Public License for more details.
7288 + *
7289 + * You should have received a copy of the GNU General Public License
7290 + * along with the Ubicom32 Linux Kernel Port.  If not,
7291 + * see <http://www.gnu.org/licenses/>.
7292 + *
7293 + * Ubicom32 implementation derived from (with many thanks):
7294 + *   arch/m68knommu
7295 + *   arch/blackfin
7296 + *   arch/parisc
7297 + */
7298 +#ifndef _ASM_UBICOM32_IRQFLAGS_H
7299 +#define _ASM_UBICOM32_IRQFLAGS_H
7300 +
7301 +#include <linux/thread_info.h>
7302 +#include <asm/ubicom32-common.h>
7303 +#include <asm/smp.h>
7304 +#include <asm/ldsr.h>
7305 +
7306 +#if defined(CONFIG_PREEMPT)
7307 +#error Not supported by Ubicom32 irq handling, yet!
7308 +#endif
7309 +
7310 +/*
7311 + * raw_local_irq_enable()
7312 + *     Enable interrupts for this thread.
7313 + */
7314 +static inline void raw_local_irq_enable(void)
7315 +{
7316 +       ldsr_local_irq_enable();
7317 +}
7318 +
7319 +/*
7320 + * raw_local_irq_disable()
7321 + *     Disable interrupts for this thread.
7322 + */
7323 +static inline void raw_local_irq_disable(void)
7324 +{
7325 +       ldsr_local_irq_disable();
7326 +}
7327 +
7328 +/*
7329 + * raw_local_save_flags()
7330 + *     Get the current IRQ state.
7331 + */
7332 +#define raw_local_save_flags(flags)            \
7333 +do {                                           \
7334 +       (flags) = ldsr_local_irq_is_disabled(); \
7335 +} while (0)
7336 +
7337 +/*
7338 + * raw_local_irq_save()
7339 + *     Save the current interrupt state and disable interrupts.
7340 + */
7341 +#define raw_local_irq_save(flags)              \
7342 +do {                                           \
7343 +       (flags) = ldsr_local_irq_save();        \
7344 +} while (0)
7345 +
7346 +/*
7347 + * raw_local_irq_restore()
7348 + *     Restore the IRQ state back to flags.
7349 + */
7350 +static inline void raw_local_irq_restore(unsigned long flags)
7351 +{
7352 +       ldsr_local_irq_restore(flags);
7353 +}
7354 +
7355 +/*
7356 + * raw_irqs_disabled_flags()
7357 + *     Return true if the flags indicate that IRQ(s) are disabled.
7358 + */
7359 +static inline int raw_irqs_disabled_flags(unsigned long flags)
7360 +{
7361 +       return (flags);
7362 +}
7363 +
7364 +#endif /* _ASM_UBICOM32_IRQFLAGS_H */
7365 --- /dev/null
7366 +++ b/arch/ubicom32/include/asm/irq.h
7367 @@ -0,0 +1,45 @@
7368 +/*
7369 + * arch/ubicom32/include/asm/irq.h
7370 + *   IRQ definitions for Ubicom32 architecture.
7371 + *
7372 + * (C) Copyright 2009, Ubicom, Inc.
7373 + *
7374 + * This file is part of the Ubicom32 Linux Kernel Port.
7375 + *
7376 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7377 + * it and/or modify it under the terms of the GNU General Public License
7378 + * as published by the Free Software Foundation, either version 2 of the
7379 + * License, or (at your option) any later version.
7380 + *
7381 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7382 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7383 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7384 + * the GNU General Public License for more details.
7385 + *
7386 + * You should have received a copy of the GNU General Public License
7387 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7388 + * see <http://www.gnu.org/licenses/>.
7389 + *
7390 + * Ubicom32 implementation derived from (with many thanks):
7391 + *   arch/m68knommu
7392 + *   arch/blackfin
7393 + *   arch/parisc
7394 + */
7395 +#ifndef _ASM_UBICOM32_IRQ_H
7396 +#define _ASM_UBICOM32_IRQ_H
7397 +
7398 +#include <asm/irqflags.h>
7399 +
7400 +/*
7401 + * We setup the IRQS to cover the full range of interrupt registers in
7402 + * processor.
7403 + */
7404 +#define NR_IRQS                64
7405 +
7406 +#define irq_canonicalize(irq) (irq)
7407 +
7408 +extern int irq_soft_alloc(unsigned int *soft);
7409 +extern void ack_bad_irq(unsigned int irq);
7410 +extern void do_IRQ(int irq, struct pt_regs *fp);
7411 +
7412 +#endif /* _ASM_UBICOM32_IRQ_H */
7413 --- /dev/null
7414 +++ b/arch/ubicom32/include/asm/irq_regs.h
7415 @@ -0,0 +1,33 @@
7416 +/*
7417 + * arch/ubicom32/include/asm/irq_regs.h
7418 + *   Generic irq_regs.h for Ubicom32 architecture.
7419 + *
7420 + * (C) Copyright 2009, Ubicom, Inc.
7421 + *
7422 + * This file is part of the Ubicom32 Linux Kernel Port.
7423 + *
7424 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7425 + * it and/or modify it under the terms of the GNU General Public License
7426 + * as published by the Free Software Foundation, either version 2 of the
7427 + * License, or (at your option) any later version.
7428 + *
7429 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7430 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7431 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7432 + * the GNU General Public License for more details.
7433 + *
7434 + * You should have received a copy of the GNU General Public License
7435 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7436 + * see <http://www.gnu.org/licenses/>.
7437 + *
7438 + * Ubicom32 implementation derived from (with many thanks):
7439 + *   arch/m68knommu
7440 + *   arch/blackfin
7441 + *   arch/parisc
7442 + */
7443 +#ifndef _ASM_UBICOM32_IRQ_REGS_H
7444 +#define _ASM_UBICOM32_IRQ_REGS_H
7445 +
7446 +#include <asm-generic/irq_regs.h>
7447 +
7448 +#endif /* _ASM_UBICOM32_IRQ_REGS_H */
7449 --- /dev/null
7450 +++ b/arch/ubicom32/include/asm/Kbuild
7451 @@ -0,0 +1 @@
7452 +include include/asm-generic/Kbuild.asm
7453 --- /dev/null
7454 +++ b/arch/ubicom32/include/asm/kdebug.h
7455 @@ -0,0 +1,33 @@
7456 +/*
7457 + * arch/ubicom32/include/asm/kdebug.h
7458 + *   Generic kdebug.h for Ubicom32 architecture.
7459 + *
7460 + * (C) Copyright 2009, Ubicom, Inc.
7461 + *
7462 + * This file is part of the Ubicom32 Linux Kernel Port.
7463 + *
7464 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7465 + * it and/or modify it under the terms of the GNU General Public License
7466 + * as published by the Free Software Foundation, either version 2 of the
7467 + * License, or (at your option) any later version.
7468 + *
7469 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7470 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7471 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7472 + * the GNU General Public License for more details.
7473 + *
7474 + * You should have received a copy of the GNU General Public License
7475 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7476 + * see <http://www.gnu.org/licenses/>.
7477 + *
7478 + * Ubicom32 implementation derived from (with many thanks):
7479 + *   arch/m68knommu
7480 + *   arch/blackfin
7481 + *   arch/parisc
7482 + */
7483 +#ifndef _ASM_UBICOM32_KDEBUG_H
7484 +#define _ASM_UBICOM32_KDEBUG_H
7485 +
7486 +#include <asm-generic/kdebug.h>
7487 +
7488 +#endif /* _ASM_UBICOM32_KDEBUG_H */
7489 --- /dev/null
7490 +++ b/arch/ubicom32/include/asm/kmap_types.h
7491 @@ -0,0 +1,48 @@
7492 +/*
7493 + * arch/ubicom32/include/asm/kmap_types.h
7494 + *   Definition of km_type's for Ubicom32 architecture.
7495 + *
7496 + * (C) Copyright 2009, Ubicom, Inc.
7497 + *
7498 + * This file is part of the Ubicom32 Linux Kernel Port.
7499 + *
7500 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7501 + * it and/or modify it under the terms of the GNU General Public License
7502 + * as published by the Free Software Foundation, either version 2 of the
7503 + * License, or (at your option) any later version.
7504 + *
7505 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7506 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7507 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7508 + * the GNU General Public License for more details.
7509 + *
7510 + * You should have received a copy of the GNU General Public License
7511 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7512 + * see <http://www.gnu.org/licenses/>.
7513 + *
7514 + * Ubicom32 implementation derived from (with many thanks):
7515 + *   arch/m68knommu
7516 + *   arch/blackfin
7517 + *   arch/parisc
7518 + */
7519 +#ifndef _ASM_UBICOM32_KMAP_TYPES_H
7520 +#define _ASM_UBICOM32_KMAP_TYPES_H
7521 +
7522 +enum km_type {
7523 +       KM_BOUNCE_READ,
7524 +       KM_SKB_SUNRPC_DATA,
7525 +       KM_SKB_DATA_SOFTIRQ,
7526 +       KM_USER0,
7527 +       KM_USER1,
7528 +       KM_BIO_SRC_IRQ,
7529 +       KM_BIO_DST_IRQ,
7530 +       KM_PTE0,
7531 +       KM_PTE1,
7532 +       KM_IRQ0,
7533 +       KM_IRQ1,
7534 +       KM_SOFTIRQ0,
7535 +       KM_SOFTIRQ1,
7536 +       KM_TYPE_NR
7537 +};
7538 +
7539 +#endif /* _ASM_UBICOM32_KMAP_TYPES_H */
7540 --- /dev/null
7541 +++ b/arch/ubicom32/include/asm/ldsr.h
7542 @@ -0,0 +1,186 @@
7543 +/*
7544 + * arch/ubicom32/include/asm/ldsr.h
7545 + *   Ubicom32 LDSR interface definitions.
7546 + *
7547 + * (C) Copyright 2009, Ubicom, Inc.
7548 + *
7549 + * This file is part of the Ubicom32 Linux Kernel Port.
7550 + *
7551 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7552 + * it and/or modify it under the terms of the GNU General Public License
7553 + * as published by the Free Software Foundation, either version 2 of the
7554 + * License, or (at your option) any later version.
7555 + *
7556 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7557 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7558 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7559 + * the GNU General Public License for more details.
7560 + *
7561 + * You should have received a copy of the GNU General Public License
7562 + * along with the Ubicom32 Linux Kernel Port.  If not,
7563 + * see <http://www.gnu.org/licenses/>.
7564 + *
7565 + * Ubicom32 implementation derived from (with many thanks):
7566 + *   arch/m68knommu
7567 + *   arch/blackfin
7568 + *   arch/parisc
7569 + */
7570 +#ifndef _ASM_UBICOM32_LDSR_H
7571 +#define _ASM_UBICOM32_LDSR_H
7572 +
7573 +#include <asm/ubicom32-common.h>
7574 +#include <asm/types.h>
7575 +#include <asm/thread.h>
7576 +
7577 +extern unsigned int ldsr_soft_irq_mask;
7578 +
7579 +/*
7580 + * ldsr_local_irq_is_disabled()
7581 + *     Test if interrupts are disabled for this thread?
7582 + */
7583 +static inline int ldsr_local_irq_is_disabled(void)
7584 +{
7585 +       int ret;
7586 +       thread_t self = thread_get_self();
7587 +       unsigned int mask = (1 << self);
7588 +
7589 +       asm volatile (
7590 +       "       and.4   %0, scratchpad1, %1     \n\t"
7591 +               : "=r" (ret)
7592 +               : "d" (mask)
7593 +               : "cc"
7594 +       );
7595 +
7596 +       /*
7597 +        *  We return a simple 1 == disabled, 0 == enabled
7598 +        *  losing which tid this is for, because Linux
7599 +        *  can restore interrupts on a different thread.
7600 +        */
7601 +       return ret >> self;
7602 +}
7603 +
7604 +/*
7605 + * ldsr_local_irq_save()
7606 + *     Get the current interrupt state and disable interrupts.
7607 + */
7608 +static inline unsigned int ldsr_local_irq_save(void)
7609 +{
7610 +       int ret;
7611 +       thread_t self = thread_get_self();
7612 +       unsigned int mask = (1 << self);
7613 +
7614 +       /*
7615 +        * Ensure the compiler can not optimize out the code
7616 +        * (volatile) and that it does not "cache" values around
7617 +        * the interrupt state change (memory).  This ensures
7618 +        * that interrupt changes are treated as a critical
7619 +        * section.
7620 +        */
7621 +       asm volatile (
7622 +       "       and.4   %0, scratchpad1, %1             \n\t"
7623 +       "       or.4    scratchpad1, scratchpad1, %1    \n\t"
7624 +               : "=&r" (ret)
7625 +               : "d" (mask)
7626 +               : "cc", "memory"
7627 +       );
7628 +
7629 +       /*
7630 +        *  We return a simple 1 == disabled, 0 == enabled
7631 +        *  losing which tid this is for, because Linux
7632 +        *  can restore interrupts on a different thread.
7633 +        */
7634 +       return ret >> self;
7635 +}
7636 +
7637 +/*
7638 + * ldsr_local_irq_restore()
7639 + *     Restore this cpu's interrupt enable/disable state.
7640 + *
7641 + * Note: flags is either 0 or 1.
7642 + */
7643 +static inline void ldsr_local_irq_restore(unsigned int flags)
7644 +{
7645 +       unsigned int temp;
7646 +       thread_t self = thread_get_self();
7647 +       unsigned int mask = (1 << self);
7648 +       flags = (flags << self);
7649 +
7650 +       /*
7651 +        * Ensure the compiler can not optimize out the code
7652 +        * (volatile) and that it does not "cache" values around
7653 +        * the interrupt state change (memory).  This ensures
7654 +        * that interrupt changes are treated as a critical
7655 +        * section.
7656 +        *
7657 +        * Atomic change to our bit in scratchpad1 without
7658 +        * causing any temporary glitch in the value and
7659 +        * without effecting other values.  Also this uses
7660 +        * no branches so no penalties.
7661 +        */
7662 +       asm volatile (
7663 +       "       xor.4   %0, scratchpad1, %1             \n\t"
7664 +       "       and.4   %0, %2, %0                      \n\t"
7665 +       "       xor.4   scratchpad1, scratchpad1, %0    \n\t"
7666 +       "       move.4  int_set0, %3                    \n\t"
7667 +               : "=&d"(temp)
7668 +               : "d"(flags), "r"(mask), "r"(ldsr_soft_irq_mask)
7669 +               : "cc", "memory"
7670 +       );
7671 +}
7672 +
7673 +/*
7674 + * ldsr_local_irq_disable_interrupt()
7675 + *     Disable ints for this thread.
7676 + */
7677 +static inline void ldsr_local_irq_disable(void)
7678 +{
7679 +       unsigned int mask = (1 << thread_get_self());
7680 +
7681 +       /*
7682 +        * Ensure the compiler can not optimize out the code
7683 +        * (volatile) and that it does not "cache" values around
7684 +        * the interrupt state change (memory).  This ensures
7685 +        * that interrupt changes are treated as a critical
7686 +        * section.
7687 +        */
7688 +       asm  volatile (
7689 +       "       or.4    scratchpad1, scratchpad1, %0    \n\t"
7690 +               :
7691 +               : "d" (mask)
7692 +               : "cc", "memory"
7693 +       );
7694 +}
7695 +
7696 +/*
7697 + * ldsr_local_irq_enable_interrupt
7698 + *     Enable ints for this thread.
7699 + */
7700 +static inline void ldsr_local_irq_enable(void)
7701 +{
7702 +       unsigned int mask = (1 << thread_get_self());
7703 +
7704 +       /*
7705 +        * Ensure the compiler can not optimize out the code
7706 +        * (volatile) and that it does not "cache" values around
7707 +        * the interrupt state change (memory).  This ensures
7708 +        * that interrupt changes are treated as a critical
7709 +        * section.
7710 +        */
7711 +       asm volatile (
7712 +       "       and.4   scratchpad1, scratchpad1, %0    \n\t"
7713 +       "       move.4  int_set0, %1                    \n\t"
7714 +               :
7715 +               : "d" (~mask), "r" (ldsr_soft_irq_mask)
7716 +               : "cc", "memory"
7717 +       );
7718 +}
7719 +
7720 +extern void ldsr_init(void);
7721 +extern void ldsr_set_trap_irq(unsigned int irq);
7722 +extern void ldsr_mask_vector(unsigned int vector);
7723 +extern void ldsr_unmask_vector(unsigned int vector);
7724 +extern void ldsr_enable_vector(unsigned int vector);
7725 +extern void ldsr_disable_vector(unsigned int vector);
7726 +extern thread_t ldsr_get_threadid(void);
7727 +
7728 +#endif /* _ASM_UBICOM32_LDSR_H */
7729 --- /dev/null
7730 +++ b/arch/ubicom32/include/asm/linkage.h
7731 @@ -0,0 +1,34 @@
7732 +/*
7733 + * arch/ubicom32/include/asm/linkage.h
7734 + *   Definition of Ubicom32 architecture specific linkage types.
7735 + *
7736 + * (C) Copyright 2009, Ubicom, Inc.
7737 + *
7738 + * This file is part of the Ubicom32 Linux Kernel Port.
7739 + *
7740 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7741 + * it and/or modify it under the terms of the GNU General Public License
7742 + * as published by the Free Software Foundation, either version 2 of the
7743 + * License, or (at your option) any later version.
7744 + *
7745 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7746 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7747 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7748 + * the GNU General Public License for more details.
7749 + *
7750 + * You should have received a copy of the GNU General Public License
7751 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7752 + * see <http://www.gnu.org/licenses/>.
7753 + *
7754 + * Ubicom32 implementation derived from (with many thanks):
7755 + *   arch/m68knommu
7756 + *   arch/blackfin
7757 + *   arch/parisc
7758 + */
7759 +#ifndef _ASM_UBICOM32_LINKAGE_H
7760 +#define _ASM_UBICOM32_LINKAGE_H
7761 +
7762 +#define __ocm_text __section(.ocm_text)
7763 +#define __ocm_data __section(.ocm_data)
7764 +
7765 +#endif /* _ASM_UBICOM32_LINKAGE_H */
7766 --- /dev/null
7767 +++ b/arch/ubicom32/include/asm/local.h
7768 @@ -0,0 +1,33 @@
7769 +/*
7770 + * arch/ubicom32/include/asm/local.h
7771 + *   Generic local.h for Ubicom32 architecture.
7772 + *
7773 + * (C) Copyright 2009, Ubicom, Inc.
7774 + *
7775 + * This file is part of the Ubicom32 Linux Kernel Port.
7776 + *
7777 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7778 + * it and/or modify it under the terms of the GNU General Public License
7779 + * as published by the Free Software Foundation, either version 2 of the
7780 + * License, or (at your option) any later version.
7781 + *
7782 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7783 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7784 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7785 + * the GNU General Public License for more details.
7786 + *
7787 + * You should have received a copy of the GNU General Public License
7788 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7789 + * see <http://www.gnu.org/licenses/>.
7790 + *
7791 + * Ubicom32 implementation derived from (with many thanks):
7792 + *   arch/m68knommu
7793 + *   arch/blackfin
7794 + *   arch/parisc
7795 + */
7796 +#ifndef _ASM_UBICOM32_LOCAL_H
7797 +#define _ASM_UBICOM32_LOCAL_H
7798 +
7799 +#include <asm-generic/local.h>
7800 +
7801 +#endif /* _ASM_UBICOM32_LOCAL_H */
7802 --- /dev/null
7803 +++ b/arch/ubicom32/include/asm/machdep.h
7804 @@ -0,0 +1,43 @@
7805 +/*
7806 + * arch/ubicom32/include/asm/machdep.h
7807 + *   Machine dependent utility routines.
7808 + *
7809 + * (C) Copyright 2009, Ubicom, Inc.
7810 + *
7811 + * This file is part of the Ubicom32 Linux Kernel Port.
7812 + *
7813 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7814 + * it and/or modify it under the terms of the GNU General Public License
7815 + * as published by the Free Software Foundation, either version 2 of the
7816 + * License, or (at your option) any later version.
7817 + *
7818 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7819 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7820 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7821 + * the GNU General Public License for more details.
7822 + *
7823 + * You should have received a copy of the GNU General Public License
7824 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7825 + * see <http://www.gnu.org/licenses/>.
7826 + *
7827 + * Ubicom32 implementation derived from (with many thanks):
7828 + *   arch/m68knommu
7829 + *   arch/blackfin
7830 + *   arch/parisc
7831 + */
7832 +#ifndef _ASM_UBICOM32_MACHDEP_H
7833 +#define _ASM_UBICOM32_MACHDEP_H
7834 +
7835 +#include <linux/interrupt.h>
7836 +
7837 +/* Hardware clock functions */
7838 +extern unsigned long hw_timer_offset(void);
7839 +
7840 +/* machine dependent power off functions */
7841 +extern void (*mach_reset)(void);
7842 +extern void (*mach_halt)(void);
7843 +extern void (*mach_power_off)(void);
7844 +
7845 +extern void config_BSP(char *command, int len);
7846 +
7847 +#endif /* _ASM_UBICOM32_MACHDEP_H */
7848 --- /dev/null
7849 +++ b/arch/ubicom32/include/asm/mc146818rtc.h
7850 @@ -0,0 +1,36 @@
7851 +/*
7852 + * arch/ubicom32/include/asm/mc146818rtc.h
7853 + *   Generic mc146818rtc.h for Ubicom32 architecture.
7854 + *
7855 + * (C) Copyright 2009, Ubicom, Inc.
7856 + *
7857 + * This file is part of the Ubicom32 Linux Kernel Port.
7858 + *
7859 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7860 + * it and/or modify it under the terms of the GNU General Public License
7861 + * as published by the Free Software Foundation, either version 2 of the
7862 + * License, or (at your option) any later version.
7863 + *
7864 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7865 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7866 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7867 + * the GNU General Public License for more details.
7868 + *
7869 + * You should have received a copy of the GNU General Public License
7870 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7871 + * see <http://www.gnu.org/licenses/>.
7872 + *
7873 + * Ubicom32 implementation derived from (with many thanks):
7874 + *   arch/m68knommu
7875 + *   arch/blackfin
7876 + *   arch/parisc
7877 + */
7878 +/*
7879 + * Machine dependent access functions for RTC registers.
7880 + */
7881 +#ifndef _ASM_UBICOM32_MC146818RTC_H
7882 +#define _ASM_UBICOM32_MC146818RTC_H
7883 +
7884 +/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
7885 +
7886 +#endif /* _ASM_UBICOM32_MC146818RTC_H */
7887 --- /dev/null
7888 +++ b/arch/ubicom32/include/asm/mman.h
7889 @@ -0,0 +1,44 @@
7890 +/*
7891 + * arch/ubicom32/include/asm/mman.h
7892 + *   Memory mapping definitions for Ubicom32 architecture.
7893 + *
7894 + * (C) Copyright 2009, Ubicom, Inc.
7895 + *
7896 + * This file is part of the Ubicom32 Linux Kernel Port.
7897 + *
7898 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7899 + * it and/or modify it under the terms of the GNU General Public License
7900 + * as published by the Free Software Foundation, either version 2 of the
7901 + * License, or (at your option) any later version.
7902 + *
7903 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7904 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7905 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7906 + * the GNU General Public License for more details.
7907 + *
7908 + * You should have received a copy of the GNU General Public License
7909 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7910 + * see <http://www.gnu.org/licenses/>.
7911 + *
7912 + * Ubicom32 implementation derived from (with many thanks):
7913 + *   arch/m68knommu
7914 + *   arch/blackfin
7915 + *   arch/parisc
7916 + */
7917 +#ifndef _ASM_UBICOM32_MMAN_H
7918 +#define _ASM_UBICOM32_MMAN_H
7919 +
7920 +#include <asm-generic/mman.h>
7921 +
7922 +#define MAP_GROWSDOWN  0x0100          /* stack-like segment */
7923 +#define MAP_DENYWRITE  0x0800          /* ETXTBSY */
7924 +#define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
7925 +#define MAP_LOCKED     0x2000          /* pages are locked */
7926 +#define MAP_NORESERVE  0x4000          /* don't check for reservations */
7927 +#define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
7928 +#define MAP_NONBLOCK   0x10000         /* do not block on IO */
7929 +
7930 +#define MCL_CURRENT    1               /* lock all current mappings */
7931 +#define MCL_FUTURE     2               /* lock all future mappings */
7932 +
7933 +#endif /* _ASM_UBICOM32_MMAN_H */
7934 --- /dev/null
7935 +++ b/arch/ubicom32/include/asm/mmu_context.h
7936 @@ -0,0 +1,60 @@
7937 +/*
7938 + * arch/ubicom32/include/asm/mmu_context.h
7939 + *   MMU context definitions for Ubicom32 architecture.
7940 + *
7941 + * (C) Copyright 2009, Ubicom, Inc.
7942 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.          
7943 + *
7944 + * This file is part of the Ubicom32 Linux Kernel Port.
7945 + *
7946 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7947 + * it and/or modify it under the terms of the GNU General Public License
7948 + * as published by the Free Software Foundation, either version 2 of the
7949 + * License, or (at your option) any later version.
7950 + *
7951 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7952 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7953 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7954 + * the GNU General Public License for more details.
7955 + *
7956 + * You should have received a copy of the GNU General Public License
7957 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7958 + * see <http://www.gnu.org/licenses/>.
7959 + *
7960 + * Ubicom32 implementation derived from (with many thanks):
7961 + *   arch/m68knommu
7962 + *   arch/blackfin
7963 + *   arch/parisc
7964 + */
7965 +
7966 +#ifndef _ASM_UBICOM32_MMU_CONTEXT_H
7967 +#define _ASM_UBICOM32_MMU_CONTEXT_H
7968 +
7969 +#include <asm/setup.h>
7970 +#include <asm/page.h>
7971 +#include <asm/pgalloc.h>
7972 +
7973 +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
7974 +{
7975 +}
7976 +
7977 +extern inline int
7978 +init_new_context(struct task_struct *tsk, struct mm_struct *mm)
7979 +{
7980 +       // mm->context = virt_to_phys(mm->pgd);
7981 +       return(0);
7982 +}
7983 +
7984 +#define destroy_context(mm)            do { } while(0)
7985 +
7986 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
7987 +{
7988 +}
7989 +
7990 +#define deactivate_mm(tsk,mm)  do { } while (0)
7991 +
7992 +extern inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
7993 +{
7994 +}
7995 +
7996 +#endif /* _ASM_UBICOM32_MMU_CONTEXT_H */
7997 --- /dev/null
7998 +++ b/arch/ubicom32/include/asm/mmu.h
7999 @@ -0,0 +1,41 @@
8000 +/*
8001 + * arch/ubicom32/include/asm/mmu.h
8002 + *   Definition of mm_context_t struct for Ubicom32 architecture.
8003 + *
8004 + * (C) Copyright 2009, Ubicom, Inc.
8005 + * Copyright (C) 2002, David McCullough <davidm@snapgear.com>
8006 + *
8007 + * This file is part of the Ubicom32 Linux Kernel Port.
8008 + *
8009 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8010 + * it and/or modify it under the terms of the GNU General Public License
8011 + * as published by the Free Software Foundation, either version 2 of the
8012 + * License, or (at your option) any later version.
8013 + *
8014 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8015 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8016 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8017 + * the GNU General Public License for more details.
8018 + *
8019 + * You should have received a copy of the GNU General Public License
8020 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8021 + * see <http://www.gnu.org/licenses/>.
8022 + *
8023 + * Ubicom32 implementation derived from (with many thanks):
8024 + *   arch/m68knommu
8025 + *   arch/blackfin
8026 + *   arch/parisc
8027 + */
8028 +#ifndef _ASM_UBICOM32_MMU_H
8029 +#define _ASM_UBICOM32_MMU_H
8030 +
8031 +typedef struct {
8032 +       struct vm_list_struct   *vmlist;
8033 +       unsigned long           end_brk;
8034 +#ifdef CONFIG_BINFMT_ELF_FDPIC
8035 +       unsigned long   exec_fdpic_loadmap;
8036 +       unsigned long   interp_fdpic_loadmap;
8037 +#endif
8038 +} mm_context_t;
8039 +
8040 +#endif /* _ASM_UBICOM32_MMU_H */
8041 --- /dev/null
8042 +++ b/arch/ubicom32/include/asm/module.h
8043 @@ -0,0 +1,44 @@
8044 +/*
8045 + * arch/ubicom32/include/asm/module.h
8046 + *   Ubicom32 architecture specific module definitions.
8047 + *
8048 + * (C) Copyright 2009, Ubicom, Inc.
8049 + *
8050 + * This file is part of the Ubicom32 Linux Kernel Port.
8051 + *
8052 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8053 + * it and/or modify it under the terms of the GNU General Public License
8054 + * as published by the Free Software Foundation, either version 2 of the
8055 + * License, or (at your option) any later version.
8056 + *
8057 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8058 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8059 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8060 + * the GNU General Public License for more details.
8061 + *
8062 + * You should have received a copy of the GNU General Public License
8063 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8064 + * see <http://www.gnu.org/licenses/>.
8065 + *
8066 + * Ubicom32 implementation derived from (with many thanks):
8067 + *   arch/m68knommu
8068 + *   arch/blackfin
8069 + *   arch/parisc
8070 + */
8071 +#ifndef _ASM_UBICOM32_MODULE_H
8072 +#define _ASM_UBICOM32_MODULE_H
8073 +
8074 +struct mod_arch_specific {
8075 +       void *ocm_inst;
8076 +       int ocm_inst_size;
8077 +};
8078 +
8079 +#define Elf_Shdr Elf32_Shdr
8080 +#define Elf_Sym Elf32_Sym
8081 +#define Elf_Ehdr Elf32_Ehdr
8082 +
8083 +#define ARCH_PROC_MODULES_EXTRA(m,mod) \
8084 +       seq_printf(m, " OCM(%d bytes @ 0x%p)", \
8085 +                  (mod)->arch.ocm_inst_size, (mod)->arch.ocm_inst)
8086 +
8087 +#endif /* _ASM_UBICOM32_MODULE_H */
8088 --- /dev/null
8089 +++ b/arch/ubicom32/include/asm/msgbuf.h
8090 @@ -0,0 +1,58 @@
8091 +/*
8092 + * arch/ubicom32/include/asm/msgbuf.h
8093 + *   Definition of msqid64_ds struct for Ubicom32 architecture.
8094 + *
8095 + * (C) Copyright 2009, Ubicom, Inc.
8096 + *
8097 + * This file is part of the Ubicom32 Linux Kernel Port.
8098 + *
8099 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8100 + * it and/or modify it under the terms of the GNU General Public License
8101 + * as published by the Free Software Foundation, either version 2 of the
8102 + * License, or (at your option) any later version.
8103 + *
8104 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8105 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8106 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8107 + * the GNU General Public License for more details.
8108 + *
8109 + * You should have received a copy of the GNU General Public License
8110 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8111 + * see <http://www.gnu.org/licenses/>.
8112 + *
8113 + * Ubicom32 implementation derived from (with many thanks):
8114 + *   arch/m68knommu
8115 + *   arch/blackfin
8116 + *   arch/parisc
8117 + */
8118 +#ifndef _ASM_UBICOM32_MSGBUF_H
8119 +#define _ASM_UBICOM32_MSGBUF_H
8120 +
8121 +/*
8122 + * The msqid64_ds structure for ubicom32 architecture.
8123 + * Note extra padding because this structure is passed back and forth
8124 + * between kernel and user space.
8125 + *
8126 + * Pad space is left for:
8127 + * - 64-bit time_t to solve y2038 problem
8128 + * - 2 miscellaneous 32-bit values
8129 + */
8130 +
8131 +struct msqid64_ds {
8132 +       struct ipc64_perm msg_perm;
8133 +       __kernel_time_t msg_stime;      /* last msgsnd time */
8134 +       unsigned long   __unused1;
8135 +       __kernel_time_t msg_rtime;      /* last msgrcv time */
8136 +       unsigned long   __unused2;
8137 +       __kernel_time_t msg_ctime;      /* last change time */
8138 +       unsigned long   __unused3;
8139 +       unsigned long  msg_cbytes;      /* current number of bytes on queue */
8140 +       unsigned long  msg_qnum;        /* number of messages in queue */
8141 +       unsigned long  msg_qbytes;      /* max number of bytes on queue */
8142 +       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
8143 +       __kernel_pid_t msg_lrpid;       /* last receive pid */
8144 +       unsigned long  __unused4;
8145 +       unsigned long  __unused5;
8146 +};
8147 +
8148 +#endif /* _ASM_UBICOM32_MSGBUF_H */
8149 --- /dev/null
8150 +++ b/arch/ubicom32/include/asm/mutex.h
8151 @@ -0,0 +1,41 @@
8152 +/*
8153 + * arch/ubicom32/include/asm/mutex.h
8154 + *   Generic mutex.h for Ubicom32 architecture.
8155 + *
8156 + * (C) Copyright 2009, Ubicom, Inc.
8157 + *
8158 + * This file is part of the Ubicom32 Linux Kernel Port.
8159 + *
8160 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8161 + * it and/or modify it under the terms of the GNU General Public License
8162 + * as published by the Free Software Foundation, either version 2 of the
8163 + * License, or (at your option) any later version.
8164 + *
8165 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8166 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8167 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8168 + * the GNU General Public License for more details.
8169 + *
8170 + * You should have received a copy of the GNU General Public License
8171 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8172 + * see <http://www.gnu.org/licenses/>.
8173 + *
8174 + * Ubicom32 implementation derived from (with many thanks):
8175 + *   arch/m68knommu
8176 + *   arch/blackfin
8177 + *   arch/parisc
8178 + */
8179 +/*
8180 + * Pull in the generic implementation for the mutex fastpath.
8181 + *
8182 + * TODO: implement optimized primitives instead, or leave the generic
8183 + * implementation in place, or pick the atomic_xchg() based generic
8184 + * implementation. (see asm-generic/mutex-xchg.h for details)
8185 + */
8186 +
8187 +#ifndef _ASM_UBICOM32_MUTEX_H
8188 +#define _ASM_UBICOM32_MUTEX_H
8189 +
8190 +#include <asm-generic/mutex-dec.h>
8191 +
8192 +#endif /* _ASM_UBICOM32_MUTEX_H */
8193 --- /dev/null
8194 +++ b/arch/ubicom32/include/asm/namei.h
8195 @@ -0,0 +1,38 @@
8196 +/*
8197 + * arch/ubicom32/include/asm/namei.h
8198 + *   Definition of __emul_prefix() for Ubicom32 architecture.
8199 + *
8200 + * (C) Copyright 2009, Ubicom, Inc.
8201 + *
8202 + * This file is part of the Ubicom32 Linux Kernel Port.
8203 + *
8204 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8205 + * it and/or modify it under the terms of the GNU General Public License
8206 + * as published by the Free Software Foundation, either version 2 of the
8207 + * License, or (at your option) any later version.
8208 + *
8209 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8210 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8211 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8212 + * the GNU General Public License for more details.
8213 + *
8214 + * You should have received a copy of the GNU General Public License
8215 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8216 + * see <http://www.gnu.org/licenses/>.
8217 + *
8218 + * Ubicom32 implementation derived from (with many thanks):
8219 + *   arch/m68knommu
8220 + *   arch/blackfin
8221 + *   arch/parisc
8222 + */
8223 +#ifndef _ASM_UBICOM32_NAMEI_H
8224 +#define _ASM_UBICOM32_NAMEI_H
8225 +
8226 +/* This dummy routine maybe changed to something useful
8227 + * for /usr/gnemul/ emulation stuff.
8228 + * Look at asm-sparc/namei.h for details.
8229 + */
8230 +
8231 +#define __emul_prefix() NULL
8232 +
8233 +#endif /* _ASM_UBICOM32_NAMEI_H */
8234 --- /dev/null
8235 +++ b/arch/ubicom32/include/asm/ocm-alloc.h
8236 @@ -0,0 +1,36 @@
8237 +/*
8238 + * arch/ubicom32/include/asm/ocm-alloc.h
8239 + *   Ubicom32 architecture specific ocm definitions.
8240 + *
8241 + * (C) Copyright 2009, Ubicom, Inc.
8242 + *
8243 + * This file is part of the Ubicom32 Linux Kernel Port.
8244 + *
8245 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8246 + * it and/or modify it under the terms of the GNU General Public License
8247 + * as published by the Free Software Foundation, either version 2 of the
8248 + * License, or (at your option) any later version.
8249 + *
8250 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8251 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8252 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8253 + * the GNU General Public License for more details.
8254 + *
8255 + * You should have received a copy of the GNU General Public License
8256 + * along with the Ubicom32 Linux Kernel Port.  If not,
8257 + * see <http://www.gnu.org/licenses/>.
8258 + *
8259 + * Ubicom32 implementation derived from (with many thanks):
8260 + *   arch/m68knommu
8261 + *   arch/blackfin
8262 + *   arch/parisc
8263 + */
8264 +#ifndef _ASM_UBICOM32_OCM_ALLOC_H
8265 +#define _ASM_UBICOM32_OCM_ALLOC_H
8266 +
8267 +
8268 +extern void *ocm_inst_alloc(size_t size, pid_t pid);
8269 +extern int ocm_free(const void *ptr);
8270 +extern int ocm_inst_free(const void *ptr);
8271 +
8272 +#endif /* _ASM_UBICOM32_OCM_ALLOC_H */
8273 --- /dev/null
8274 +++ b/arch/ubicom32/include/asm/ocm_size.h
8275 @@ -0,0 +1,2 @@
8276 +#define APP_OCM_CODE_SIZE (0x3ffc2e00-0x3ffc0000)
8277 +#define APP_OCM_DATA_SIZE (0x3ffd3500-0x3ffc8000)
8278 --- /dev/null
8279 +++ b/arch/ubicom32/include/asm/ocm_text.lds.inc
8280 @@ -0,0 +1,175 @@
8281 +/*
8282 + * arch/ubicom32/include/asm/ocm_text.lds.inc
8283 + *     <TODO: Replace with short file description>
8284 + *
8285 + * (C) Copyright 2009, Ubicom, Inc.
8286 + *
8287 + * This file is part of the Ubicom32 Linux Kernel Port.
8288 + *
8289 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8290 + * it and/or modify it under the terms of the GNU General Public License
8291 + * as published by the Free Software Foundation, either version 2 of the
8292 + * License, or (at your option) any later version.
8293 + *
8294 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8295 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8296 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8297 + * the GNU General Public License for more details.
8298 + *
8299 + * You should have received a copy of the GNU General Public License
8300 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8301 + * see <http://www.gnu.org/licenses/>.
8302 + *
8303 + * Ubicom32 implementation derived from (with many thanks):
8304 + *   arch/m68knommu
8305 + *   arch/blackfin
8306 + *   arch/parisc
8307 + */
8308 +*(.text.do_csum)
8309 +*(.text.tcp_packet)
8310 +*(.text.ipt_do_table)
8311 +*(.text.nf_conntrack_in)
8312 +*(.text.ip_forward)
8313 +*(.text.dev_queue_xmit)
8314 +*(.text.netif_receive_skb)
8315 +*(.text.ip_route_input)
8316 +*(.text.ip_finish_output)
8317 +*(.text.nf_iterate)
8318 +*(.text.__hash_conntrack)
8319 +*(.text.memset)
8320 +*(.text.memcpy)
8321 +*(.text.ip_rcv)
8322 +*(.text.__nf_conntrack_find)
8323 +*(.text.dev_hard_start_xmit)
8324 +*(.text.vlan_dev_hard_start_xmit)
8325 +*(.text.vlan_dev_hard_header)
8326 +*(.text.__nf_ct_refresh_acct)
8327 +*(.text.tcp_error)
8328 +*(.text.pfifo_fast_enqueue)
8329 +*(.text.ipv4_confirm)
8330 +*(.text.ip_output)
8331 +*(.text.neigh_connected_output)
8332 +*(.text.nf_hook_slow)
8333 +*(.text.nf_nat_packet)
8334 +*(.text.local_bh_enable)
8335 +*(.text.pfifo_fast_dequeue)
8336 +*(.text.ubi32_eth_receive)
8337 +*(.text.nf_nat_fn)
8338 +*(.text.skb_checksum)
8339 +*(.text.memmove)
8340 +*(.text.ubi32_eth_tx_done)
8341 +*(.text.eth_header)
8342 +*(.text.skb_release_data)
8343 +*(.text.nf_conntrack_find_get)
8344 +*(.text.process_backlog)
8345 +*(.text.vlan_skb_recv)
8346 +*(.text.ip_rcv_finish)
8347 +*(.text.__qdisc_run)
8348 +*(.text.skb_push)
8349 +*(.text.eth_type_trans)
8350 +*(.text.__alloc_skb)
8351 +*(.text.netif_rx)
8352 +*(.text.nf_ip_checksum)
8353 +*(.text.__skb_checksum_complete_head)
8354 +*(.text.ipv4_conntrack_defrag)
8355 +*(.text.tcp_pkt_to_tuple)
8356 +*(.text.kfree)
8357 +*(.text.tcp_manip_pkt)
8358 +*(.text.skb_put)
8359 +*(.text.nf_ct_get_tuple)
8360 +*(.text.__kmalloc)
8361 +*(.text.ubi32_eth_start_xmit)
8362 +*(.text.free_block)
8363 +*(.text.ipt_hook)
8364 +*(.text.kmem_cache_free)
8365 +*(.text.skb_pull_rcsum)
8366 +*(.text.cache_alloc_refill)
8367 +*(.text.skb_release_head_state)
8368 +*(.text.manip_pkt)
8369 +*(.text.ip_sabotage_in)
8370 +*(.text.ip_forward_finish)
8371 +*(.text.kmem_cache_alloc)
8372 +*(.text.local_bh_disable)
8373 +*(.text.ipv4_pkt_to_tuple)
8374 +*(.text.inet_proto_csum_replace4)
8375 +*(.text.__nf_ct_l4proto_find)
8376 +*(.text.csum_partial)
8377 +*(.text.neigh_resolve_output)
8378 +*(.text.__kfree_skb)
8379 +*(.text.kfree_skb)
8380 +*(.text.__find_vlan_dev)
8381 +*(.text.ldsr_ctxsw_thread)
8382 +*(.text.__do_IRQ)
8383 +*(.text.skb_pull)
8384 +*(.text.ipv4_invert_tuple)
8385 +*(.text.nf_ct_invert_tuplepr)
8386 +*(.text.skb_make_writable)
8387 +*(.text.ipv4_get_l4proto)
8388 +*(.text.handle_IRQ_event)
8389 +*(.text.net_rx_action)
8390 +*(.text.__do_softirq)
8391 +*(.text.nf_nat_in)
8392 +*(.text.note_interrupt)
8393 +*(.text.ipv4_conntrack_in)
8394 +*(.text.dst_release)
8395 +*(.text.tasklet_action)
8396 +*(.text.nf_nat_out)
8397 +*(.text.nf_ct_invert_tuple)
8398 +*(.text.do_IRQ)
8399 +*(.text.__tasklet_schedule)
8400 +*(.text.__skb_checksum_complete)
8401 +*(.text.ubi32_eth_interrupt)
8402 +*(.text.dev_kfree_skb_any)
8403 +*(.text.ret_from_interrupt_to_kernel)
8404 +*(.text.preemptive_context_save)
8405 +*(.text.irq_ack_vector)
8406 +*(.text.update_wall_time)
8407 +*(.text.ldsr_thread)
8408 +*(.text.irq_exit)
8409 +*(.text.ubi32_eth_do_tasklet)
8410 +*(.text.__napi_schedule)
8411 +*(.text.idle_cpu)
8412 +*(.text.run_timer_softirq)
8413 +*(.text.ldsr_mask_vector)
8414 +*(.text.irq_enter)
8415 +*(.text.ldsr_get_lsb)
8416 +*(.text.ldsr_unmask_vector)
8417 +*(.text.ip_fast_csum)
8418 +*(.text.hrtimer_run_queues)
8419 +*(.text.tcp_invert_tuple)
8420 +*(.text.T___705)
8421 +*(.text.run_posix_cpu_timers)
8422 +*(.text.free_hot_cold_page)
8423 +*(.text.lock_timer_base)
8424 +*(.text.calc_delta_mine)
8425 +*(.text.slab_destroy)
8426 +*(.text.rcu_pending)
8427 +*(.text.scheduler_tick)
8428 +*(.text.hrtimer_run_pending)
8429 +*(.text.do_softirq)
8430 +*(.text.del_timer)
8431 +*(.text.irq_end_vector)
8432 +*(.text.pci_read_u32)
8433 +*(.text.udivmodsi4)
8434 +*(.text.memcmp)
8435 +*(.text.memset)
8436 +*(.text.__slab_alloc)
8437 +*(.text.br_handle_frame)
8438 +*(.text.br_fdb_update)
8439 +*(.text.__br_fdb_get)
8440 +*(.text.br_forward)
8441 +*(.text.br_handle_frame_finish)
8442 +*(.text.pci_write_u32)
8443 +*(.text.kmem_freepages)
8444 +*(.text.br_dev_queue_push_xmit)
8445 +*(.text.ioread32)
8446 +*(.text.next_zones_zonelist)
8447 +*(.text.ubi32_pci_read_u32)
8448 +*(.text.zone_watermark_ok)
8449 +*(.text.__rmqueue_smallest)
8450 +*(.text.ubi32_eth_napi_poll)
8451 +*(.text.ubi32_pci_write_u32)
8452 +*(.text.ubi32_pci_read_u32)
8453 +*(.text._local_bh_enable)
8454 +*(.text._local_bh_disable)
8455 +*(.text.get_slab)
8456 --- /dev/null
8457 +++ b/arch/ubicom32/include/asm/page.h
8458 @@ -0,0 +1,106 @@
8459 +/*
8460 + * arch/ubicom32/include/asm/page.h
8461 + *   Memory page related operations and definitions.
8462 + *
8463 + * (C) Copyright 2009, Ubicom, Inc.
8464 + *
8465 + * This file is part of the Ubicom32 Linux Kernel Port.
8466 + *
8467 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8468 + * it and/or modify it under the terms of the GNU General Public License
8469 + * as published by the Free Software Foundation, either version 2 of the
8470 + * License, or (at your option) any later version.
8471 + *
8472 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8473 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8474 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8475 + * the GNU General Public License for more details.
8476 + *
8477 + * You should have received a copy of the GNU General Public License
8478 + * along with the Ubicom32 Linux Kernel Port.  If not,
8479 + * see <http://www.gnu.org/licenses/>.
8480 + *
8481 + * Ubicom32 implementation derived from (with many thanks):
8482 + *   arch/m68knommu
8483 + *   arch/blackfin
8484 + *   arch/parisc
8485 + */
8486 +#ifndef _ASM_UBICOM32_PAGE_H
8487 +#define _ASM_UBICOM32_PAGE_H
8488 +
8489 +/* PAGE_SHIFT determines the page size */
8490 +
8491 +#define PAGE_SHIFT     12
8492 +#define PAGE_SIZE      (1 << PAGE_SHIFT)
8493 +#define PAGE_MASK      (~(PAGE_SIZE-1))
8494 +
8495 +#include <asm/setup.h>
8496 +
8497 +#ifndef __ASSEMBLY__
8498 +
8499 +#define get_user_page(vaddr)           __get_free_page(GFP_KERNEL)
8500 +#define free_user_page(page, addr)     free_page(addr)
8501 +
8502 +#define clear_page(page)       memset((page), 0, PAGE_SIZE)
8503 +#define copy_page(to,from)     memcpy((to), (from), PAGE_SIZE)
8504 +
8505 +#define clear_user_page(page, vaddr, pg)       clear_page(page)
8506 +#define copy_user_page(to, from, vaddr, pg)    copy_page(to, from)
8507 +
8508 +#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
8509 +       alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
8510 +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
8511 +
8512 +/*
8513 + * These are used to make use of C type-checking..
8514 + */
8515 +typedef struct { unsigned long pte; } pte_t;
8516 +typedef struct { unsigned long pmd[16]; } pmd_t;
8517 +typedef struct { unsigned long pgd; } pgd_t;
8518 +typedef struct { unsigned long pgprot; } pgprot_t;
8519 +typedef struct page *pgtable_t;
8520 +
8521 +#define pte_val(x)     ((x).pte)
8522 +#define pmd_val(x)     ((&x)->pmd[0])
8523 +#define pgd_val(x)     ((x).pgd)
8524 +#define pgprot_val(x)  ((x).pgprot)
8525 +
8526 +#define __pte(x)       ((pte_t) { (x) } )
8527 +#define __pmd(x)       ((pmd_t) { (x) } )
8528 +#define __pgd(x)       ((pgd_t) { (x) } )
8529 +#define __pgprot(x)    ((pgprot_t) { (x) } )
8530 +
8531 +extern unsigned long memory_start;
8532 +extern unsigned long memory_end;
8533 +
8534 +#endif /* !__ASSEMBLY__ */
8535 +
8536 +#include <asm/page_offset.h>
8537 +
8538 +#define PAGE_OFFSET            (PAGE_OFFSET_RAW)
8539 +
8540 +#ifndef __ASSEMBLY__
8541 +
8542 +#define __pa(vaddr)            virt_to_phys((void *)(vaddr))
8543 +#define __va(paddr)            phys_to_virt((unsigned long)(paddr))
8544 +
8545 +#define virt_to_pfn(kaddr)     (__pa(kaddr) >> PAGE_SHIFT)
8546 +#define pfn_to_virt(pfn)       __va((pfn) << PAGE_SHIFT)
8547 +
8548 +#define virt_to_page(addr)     (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
8549 +#define page_to_virt(page)     ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
8550 +
8551 +#define pfn_to_page(pfn)       virt_to_page(pfn_to_virt(pfn))
8552 +#define page_to_pfn(page)      virt_to_pfn(page_to_virt(page))
8553 +#define pfn_valid(pfn)         ((pfn) < max_mapnr)
8554 +
8555 +#define        virt_addr_valid(kaddr)  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
8556 +                               ((void *)(kaddr) < (void *)memory_end))
8557 +
8558 +#endif /* __ASSEMBLY__ */
8559 +
8560 +#ifdef __KERNEL__
8561 +#include <asm-generic/page.h>
8562 +#endif
8563 +
8564 +#endif /* _ASM_UBICOM32_PAGE_H */
8565 --- /dev/null
8566 +++ b/arch/ubicom32/include/asm/page_offset.h
8567 @@ -0,0 +1,35 @@
8568 +/*
8569 + * arch/ubicom32/include/asm/page_offset.h
8570 + *   Definition of PAGE_OFFSET_RAW for Ubicom32 architecture.
8571 + *
8572 + * (C) Copyright 2009, Ubicom, Inc.
8573 + *
8574 + * This file is part of the Ubicom32 Linux Kernel Port.
8575 + *
8576 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8577 + * it and/or modify it under the terms of the GNU General Public License
8578 + * as published by the Free Software Foundation, either version 2 of the
8579 + * License, or (at your option) any later version.
8580 + *
8581 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8582 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8583 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8584 + * the GNU General Public License for more details.
8585 + *
8586 + * You should have received a copy of the GNU General Public License
8587 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8588 + * see <http://www.gnu.org/licenses/>.
8589 + *
8590 + * Ubicom32 implementation derived from (with many thanks):
8591 + *   arch/m68knommu
8592 + *   arch/blackfin
8593 + *   arch/parisc
8594 + */
8595 +
8596 +#ifndef _ASM_UBICOM32_PAGE_OFFSET_H
8597 +#define _ASM_UBICOM32_PAGE_OFFSET_H
8598 +
8599 +/* This handles the memory map.. */
8600 +#define        PAGE_OFFSET_RAW         0x3ffc0000
8601 +
8602 +#endif /* _ASM_UBICOM32_PAGE_OFFSET_H */
8603 --- /dev/null
8604 +++ b/arch/ubicom32/include/asm/param.h
8605 @@ -0,0 +1,49 @@
8606 +/*
8607 + * arch/ubicom32/include/asm/param.h
8608 + *   Definition of miscellaneous constants, including HZ.
8609 + *
8610 + * (C) Copyright 2009, Ubicom, Inc.
8611 + *
8612 + * This file is part of the Ubicom32 Linux Kernel Port.
8613 + *
8614 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8615 + * it and/or modify it under the terms of the GNU General Public License
8616 + * as published by the Free Software Foundation, either version 2 of the
8617 + * License, or (at your option) any later version.
8618 + *
8619 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8620 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8621 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8622 + * the GNU General Public License for more details.
8623 + *
8624 + * You should have received a copy of the GNU General Public License
8625 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8626 + * see <http://www.gnu.org/licenses/>.
8627 + *
8628 + * Ubicom32 implementation derived from (with many thanks):
8629 + *   arch/m68knommu
8630 + *   arch/blackfin
8631 + *   arch/parisc
8632 + */
8633 +#ifndef _ASM_UBICOM32_PARAM_H
8634 +#define _ASM_UBICOM32_PARAM_H
8635 +
8636 +#ifdef __KERNEL__
8637 +#define HZ CONFIG_HZ
8638 +#define        USER_HZ         HZ
8639 +#define        CLOCKS_PER_SEC  (USER_HZ)
8640 +#endif
8641 +
8642 +#ifndef HZ
8643 +#define HZ     100
8644 +#endif
8645 +
8646 +#define EXEC_PAGESIZE  4096
8647 +
8648 +#ifndef NOGROUP
8649 +#define NOGROUP                (-1)
8650 +#endif
8651 +
8652 +#define MAXHOSTNAMELEN 64      /* max length of hostname */
8653 +
8654 +#endif /* _ASM_UBICOM32_PARAM_H */
8655 --- /dev/null
8656 +++ b/arch/ubicom32/include/asm/pci.h
8657 @@ -0,0 +1,210 @@
8658 +/*
8659 + * arch/ubicom32/include/asm/pci.h
8660 + *   Definitions of PCI operations for Ubicom32 architecture.
8661 + *
8662 + * (C) Copyright 2009, Ubicom, Inc.
8663 + *
8664 + * This file is part of the Ubicom32 Linux Kernel Port.
8665 + *
8666 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8667 + * it and/or modify it under the terms of the GNU General Public License
8668 + * as published by the Free Software Foundation, either version 2 of the
8669 + * License, or (at your option) any later version.
8670 + *
8671 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8672 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8673 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8674 + * the GNU General Public License for more details.
8675 + *
8676 + * You should have received a copy of the GNU General Public License
8677 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8678 + * see <http://www.gnu.org/licenses/>.
8679 + *
8680 + * Ubicom32 implementation derived from (with many thanks):
8681 + *   arch/m68knommu
8682 + *   arch/blackfin
8683 + *   arch/parisc
8684 + */
8685 +#ifndef _ASM_UBICOM32_PCI_H
8686 +#define _ASM_UBICOM32_PCI_H
8687 +
8688 +#include <asm/io.h>
8689 +
8690 +/* The PCI address space does equal the physical memory
8691 + * address space.  The networking and block device layers use
8692 + * this boolean for bounce buffer decisions.
8693 + */
8694 +#define PCI_DMA_BUS_IS_PHYS    (1)
8695 +
8696 +
8697 +
8698 +/*
8699 + * Perform a master read/write to the PCI bus.
8700 + * These functions return a PCI_RESP_xxx code.
8701 + */
8702 +extern u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data);
8703 +extern u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data);
8704 +extern u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data);
8705 +extern u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data);
8706 +extern u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data);
8707 +extern u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data);
8708 +
8709 +
8710 +#define PCIBIOS_MIN_IO          0x100
8711 +#define PCIBIOS_MIN_MEM         0x10000000
8712 +
8713 +#define pcibios_assign_all_busses()    0
8714 +#define pcibios_scan_all_fns(a, b)     0
8715 +extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
8716 +       struct resource *res);
8717 +
8718 +extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
8719 +       struct pci_bus_region *region);
8720 +
8721 +struct pci_sys_data;
8722 +struct pci_bus;
8723 +
8724 +struct hw_pci {
8725 +        struct list_head buses;
8726 +        int             nr_controllers;
8727 +        int             (*setup)(int nr, struct pci_sys_data *);
8728 +        struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
8729 +        void            (*preinit)(void);
8730 +        void            (*postinit)(void);
8731 +        u8              (*swizzle)(struct pci_dev *dev, u8 *pin);
8732 +        int             (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
8733 +};
8734 +
8735 +/*
8736 + * Per-controller structure
8737 + */
8738 +struct pci_sys_data {
8739 +        struct list_head node;
8740 +        int             busnr;          /* primary bus number                   */
8741 +        u64             mem_offset;     /* bus->cpu memory mapping offset       */
8742 +        unsigned long   io_offset;      /* bus->cpu IO mapping offset           */
8743 +        struct pci_bus  *bus;           /* PCI bus                              */
8744 +        struct resource *resource[3];   /* Primary PCI bus resources            */
8745 +                                        /* Bridge swizzling                     */
8746 +        u8              (*swizzle)(struct pci_dev *, u8 *);
8747 +                                        /* IRQ mapping                          */
8748 +        int             (*map_irq)(struct pci_dev *, u8, u8);
8749 +        struct hw_pci   *hw;
8750 +};
8751 +
8752 +static  inline struct resource *
8753 +pcibios_select_root(struct pci_dev *pdev, struct resource *res)
8754 +{
8755 +        struct resource *root = NULL;
8756 +
8757 +        if (res->flags & IORESOURCE_IO)
8758 +                root = &ioport_resource;
8759 +        if (res->flags & IORESOURCE_MEM)
8760 +                root = &iomem_resource;
8761 +
8762 +        return root;
8763 +}
8764 +
8765 +static inline void pcibios_set_master(struct pci_dev *dev)
8766 +{
8767 +        /* No special bus mastering setup handling */
8768 +}
8769 +#define HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE 1
8770 +#define HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY 1
8771 +
8772 +#ifdef CONFIG_PCI
8773 +static inline void * pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
8774 +                     dma_addr_t *dma_handle)
8775 +{
8776 +    void *vaddr = kmalloc(size, GFP_KERNEL);
8777 +    if(vaddr != NULL) {
8778 +        *dma_handle = virt_to_phys(vaddr);
8779 +    }
8780 +    return vaddr;
8781 +}
8782 +
8783 +static  inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
8784 +{
8785 +       return 1;
8786 +}
8787 +
8788 +static  inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
8789 +       void *cpu_addr, dma_addr_t dma_handle)
8790 +{ 
8791 +       kfree(cpu_addr);
8792 +       return;
8793 +}
8794 +
8795 +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
8796 +       size_t size, int direction)
8797 +{
8798 +        return virt_to_phys(ptr);
8799 +}
8800 +
8801 +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
8802 +       size_t size, int direction)
8803 +{
8804 +        return;
8805 +}
8806 +
8807 +static inline dma_addr_t
8808 +pci_map_page(struct pci_dev *hwdev, struct page *page,
8809 +             unsigned long offset, size_t size, int direction)
8810 +{
8811 +        return pci_map_single(hwdev, page_address(page) + offset, size, (int)direction);
8812 +}
8813 +
8814 +static inline void
8815 +pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
8816 +               size_t size, int direction)
8817 +{
8818 +       pci_unmap_single(hwdev, dma_address, size, direction);
8819 +}
8820 +
8821 +static inline int
8822 +pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
8823 +           int nents, int direction)
8824 +{
8825 +        return nents; 
8826 +}
8827 +
8828 +static inline void
8829 +pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
8830 +             int nents, int direction)
8831 +{
8832 +}
8833 +
8834 +static inline void
8835 +pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
8836 +                int nelems, int direction)
8837 +{
8838 +}
8839 +
8840 +static inline void
8841 +pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
8842 +                int nelems, int direction)
8843 +{
8844 +}
8845 +
8846 +static inline void
8847 +pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
8848 +                    size_t size, int direction)
8849 +{
8850 +}
8851 +
8852 +static inline void
8853 +pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
8854 +                    size_t size, int direction)
8855 +{
8856 +}
8857 +
8858 +static inline int
8859 +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
8860 +{
8861 +        return dma_addr == 0;
8862 +}
8863 +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
8864 +extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
8865 +#endif
8866 +
8867 +#endif /* _ASM_UBICOM32_PCI_H */
8868 --- /dev/null
8869 +++ b/arch/ubicom32/include/asm/percpu.h
8870 @@ -0,0 +1,33 @@
8871 +/*
8872 + * arch/ubicom32/include/asm/percpu.h
8873 + *   Generic percpu.h for the Ubicom32 architecture.
8874 + *
8875 + * (C) Copyright 2009, Ubicom, Inc.
8876 + *
8877 + * This file is part of the Ubicom32 Linux Kernel Port.
8878 + *
8879 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8880 + * it and/or modify it under the terms of the GNU General Public License
8881 + * as published by the Free Software Foundation, either version 2 of the
8882 + * License, or (at your option) any later version.
8883 + *
8884 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8885 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8886 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8887 + * the GNU General Public License for more details.
8888 + *
8889 + * You should have received a copy of the GNU General Public License
8890 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8891 + * see <http://www.gnu.org/licenses/>.
8892 + *
8893 + * Ubicom32 implementation derived from (with many thanks):
8894 + *   arch/m68knommu
8895 + *   arch/blackfin
8896 + *   arch/parisc
8897 + */
8898 +#ifndef _ASM_UBICOM32_PERCPU_H
8899 +#define _ASM_UBICOM32_PERCPU_H
8900 +
8901 +#include <asm-generic/percpu.h>
8902 +
8903 +#endif /* _ASM_UBICOM32_PERCPU_H */
8904 --- /dev/null
8905 +++ b/arch/ubicom32/include/asm/pgalloc.h
8906 @@ -0,0 +1,36 @@
8907 +/*
8908 + * arch/ubicom32/include/asm/pgalloc.h
8909 + *   Page table allocation definitions.
8910 + *
8911 + * (C) Copyright 2009, Ubicom, Inc.
8912 + *
8913 + * This file is part of the Ubicom32 Linux Kernel Port.
8914 + *
8915 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8916 + * it and/or modify it under the terms of the GNU General Public License
8917 + * as published by the Free Software Foundation, either version 2 of the
8918 + * License, or (at your option) any later version.
8919 + *
8920 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8921 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8922 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8923 + * the GNU General Public License for more details.
8924 + *
8925 + * You should have received a copy of the GNU General Public License
8926 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8927 + * see <http://www.gnu.org/licenses/>.
8928 + *
8929 + * Ubicom32 implementation derived from (with many thanks):
8930 + *   arch/m68knommu
8931 + *   arch/blackfin
8932 + *   arch/parisc
8933 + */
8934 +#ifndef _ASM_UBICOM32_PGALLOC_H
8935 +#define _ASM_UBICOM32_PGALLOC_H
8936 +
8937 +#include <linux/mm.h>
8938 +#include <asm/setup.h>
8939 +
8940 +#define check_pgt_cache()      do { } while (0)
8941 +
8942 +#endif /* _ASM_UBICOM32_PGALLOC_H */
8943 --- /dev/null
8944 +++ b/arch/ubicom32/include/asm/pgtable.h
8945 @@ -0,0 +1,124 @@
8946 +/*
8947 + * arch/ubicom32/include/asm/pgtable.h
8948 + *   Ubicom32 pseudo page table definitions and operations.
8949 + *
8950 + * (C) Copyright 2009, Ubicom, Inc.
8951 + * Copyright (C) 2004   Microtronix Datacom Ltd
8952 + *
8953 + * This file is part of the Ubicom32 Linux Kernel Port.
8954 + *
8955 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8956 + * it and/or modify it under the terms of the GNU General Public License
8957 + * as published by the Free Software Foundation, either version 2 of the
8958 + * License, or (at your option) any later version.
8959 + *
8960 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8961 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8962 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8963 + * the GNU General Public License for more details.
8964 + *
8965 + * You should have received a copy of the GNU General Public License
8966 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8967 + * see <http://www.gnu.org/licenses/>.
8968 + *
8969 + * Ubicom32 implementation derived from (with many thanks):
8970 + *   arch/m68knommu
8971 + *   arch/blackfin
8972 + *   arch/parisc
8973 + *   and various works, Alpha, ix86, M68K, Sparc, ...et al
8974 + */
8975 +#ifndef _ASM_UBICOM32_PGTABLE_H
8976 +#define _ASM_UBICOM32_PGTABLE_H
8977 +
8978 +#include <asm-generic/4level-fixup.h>
8979 +
8980 +//vic - this bit copied from m68knommu version
8981 +#include <asm/setup.h>
8982 +#include <asm/io.h>
8983 +#include <linux/sched.h>
8984 +
8985 +typedef pte_t *pte_addr_t;
8986 +
8987 +#define pgd_present(pgd)       (1)       /* pages are always present on NO_MM */
8988 +#define pgd_none(pgd)          (0)
8989 +#define pgd_bad(pgd)           (0)
8990 +#define pgd_clear(pgdp)
8991 +#define kern_addr_valid(addr)  (1)
8992 +#define        pmd_offset(a, b)        ((void *)0)
8993 +
8994 +#define PAGE_NONE              __pgprot(0)    /* these mean nothing to NO_MM */
8995 +#define PAGE_SHARED            __pgprot(0)    /* these mean nothing to NO_MM */
8996 +#define PAGE_COPY              __pgprot(0)    /* these mean nothing to NO_MM */
8997 +#define PAGE_READONLY          __pgprot(0)    /* these mean nothing to NO_MM */
8998 +#define PAGE_KERNEL            __pgprot(0)    /* these mean nothing to NO_MM */
8999 +//vic - this bit copied from m68knommu version
9000 +
9001 +extern void paging_init(void);
9002 +#define swapper_pg_dir ((pgd_t *) 0)
9003 +
9004 +#define __swp_type(x)          (0)
9005 +#define __swp_offset(x)                (0)
9006 +#define __swp_entry(typ,off)   ((swp_entry_t) { ((typ) | ((off) << 7)) })
9007 +#define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
9008 +#define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
9009 +
9010 +/*
9011 + * pgprot_noncached() is only for infiniband pci support, and a real
9012 + * implementation for RAM would be more complicated.
9013 + */
9014 +#define pgprot_noncached(prot) (prot)
9015 +
9016 +static inline int pte_file(pte_t pte) { return 0; }
9017 +
9018 +/*
9019 + * ZERO_PAGE is a global shared page that is always zero: used
9020 + * for zero-mapped memory areas etc..
9021 + */
9022 +#define ZERO_PAGE(vaddr)       (virt_to_page(0))
9023 +
9024 +extern unsigned int kobjsize(const void *objp);
9025 +extern int is_in_rom(unsigned long);
9026 +
9027 +/*
9028 + * No page table caches to initialise
9029 + */
9030 +#define pgtable_cache_init()   do { } while (0)
9031 +
9032 +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
9033 +               remap_pfn_range(vma, vaddr, pfn, size, prot)
9034 +
9035 +extern inline void flush_cache_mm(struct mm_struct *mm)
9036 +{
9037 +}
9038 +
9039 +extern inline void flush_cache_range(struct mm_struct *mm,
9040 +                                    unsigned long start,
9041 +                                    unsigned long end)
9042 +{
9043 +}
9044 +
9045 +/* Push the page at kernel virtual address and clear the icache */
9046 +extern inline void flush_page_to_ram (unsigned long address)
9047 +{
9048 +}
9049 +
9050 +/* Push n pages at kernel virtual address and clear the icache */
9051 +extern inline void flush_pages_to_ram (unsigned long address, int n)
9052 +{
9053 +}
9054 +
9055 +/*
9056 + * All 32bit addresses are effectively valid for vmalloc...
9057 + * Sort of meaningless for non-VM targets.
9058 + */
9059 +#define        VMALLOC_START   0
9060 +#define        VMALLOC_END     0xffffffff
9061 +
9062 +#define arch_enter_lazy_mmu_mode()     do {} while (0)
9063 +#define arch_leave_lazy_mmu_mode()     do {} while (0)
9064 +#define arch_flush_lazy_mmu_mode()     do {} while (0)
9065 +#define arch_enter_lazy_cpu_mode()     do {} while (0)
9066 +#define arch_leave_lazy_cpu_mode()     do {} while (0)
9067 +#define arch_flush_lazy_cpu_mode()     do {} while (0)
9068 +
9069 +#endif /* _ASM_UBICOM32_PGTABLE_H */
9070 --- /dev/null
9071 +++ b/arch/ubicom32/include/asm/poll.h
9072 @@ -0,0 +1,36 @@
9073 +/*
9074 + * arch/ubicom32/include/asm/poll.h
9075 + *   Ubicom32 specific poll() related flags definitions.
9076 + *
9077 + * (C) Copyright 2009, Ubicom, Inc.
9078 + *
9079 + * This file is part of the Ubicom32 Linux Kernel Port.
9080 + *
9081 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9082 + * it and/or modify it under the terms of the GNU General Public License
9083 + * as published by the Free Software Foundation, either version 2 of the
9084 + * License, or (at your option) any later version.
9085 + *
9086 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9087 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9088 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9089 + * the GNU General Public License for more details.
9090 + *
9091 + * You should have received a copy of the GNU General Public License
9092 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9093 + * see <http://www.gnu.org/licenses/>.
9094 + *
9095 + * Ubicom32 implementation derived from (with many thanks):
9096 + *   arch/m68knommu
9097 + *   arch/blackfin
9098 + *   arch/parisc
9099 + */
9100 +#ifndef _ASM_UBICOM32_POLL_H
9101 +#define _ASM_UBICOM32_POLL_H
9102 +
9103 +#define POLLWRNORM     POLLOUT
9104 +#define POLLWRBAND     0x0100
9105 +
9106 +#include <asm-generic/poll.h>
9107 +
9108 +#endif /* _ASM_UBICOM32_POLL_H */
9109 --- /dev/null
9110 +++ b/arch/ubicom32/include/asm/posix_types.h
9111 @@ -0,0 +1,93 @@
9112 +/*
9113 + * arch/ubicom32/include/asm/posix_types.h
9114 + *   Ubicom32 architecture posix types.
9115 + *
9116 + * (C) Copyright 2009, Ubicom, Inc.
9117 + * Copyright (C) 2004   Microtronix Datacom Ltd
9118 + *
9119 + * This file is part of the Ubicom32 Linux Kernel Port.
9120 + *
9121 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9122 + * it and/or modify it under the terms of the GNU General Public License
9123 + * as published by the Free Software Foundation, either version 2 of the
9124 + * License, or (at your option) any later version.
9125 + *
9126 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9127 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9128 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9129 + * the GNU General Public License for more details.
9130 + *
9131 + * You should have received a copy of the GNU General Public License
9132 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9133 + * see <http://www.gnu.org/licenses/>.
9134 + *
9135 + * Ubicom32 implementation derived from (with many thanks):
9136 + *   arch/m68knommu
9137 + *   arch/blackfin
9138 + *   arch/parisc
9139 + */
9140 +#ifndef __ARCH_UBICOM32_POSIX_TYPES_H
9141 +#define __ARCH_UBICOM32_POSIX_TYPES_H
9142 +
9143 +/*
9144 + * This file is generally used by user-level software, so you need to
9145 + * be a little careful about namespace pollution etc.  Also, we cannot
9146 + * assume GCC is being used.
9147 + */
9148 +
9149 +typedef unsigned long  __kernel_ino_t;
9150 +typedef unsigned short __kernel_mode_t;
9151 +typedef unsigned short __kernel_nlink_t;
9152 +typedef long           __kernel_off_t;
9153 +typedef int            __kernel_pid_t;
9154 +typedef unsigned short __kernel_ipc_pid_t;
9155 +typedef unsigned short __kernel_uid_t;
9156 +typedef unsigned short __kernel_gid_t;
9157 +typedef unsigned int   __kernel_size_t;
9158 +typedef int            __kernel_ssize_t;
9159 +typedef int            __kernel_ptrdiff_t;
9160 +typedef long           __kernel_time_t;
9161 +typedef long           __kernel_suseconds_t;
9162 +typedef long           __kernel_clock_t;
9163 +typedef int            __kernel_timer_t;
9164 +typedef int            __kernel_clockid_t;
9165 +typedef int            __kernel_daddr_t;
9166 +typedef char *         __kernel_caddr_t;
9167 +typedef unsigned short __kernel_uid16_t;
9168 +typedef unsigned short __kernel_gid16_t;
9169 +typedef unsigned int   __kernel_uid32_t;
9170 +typedef unsigned int   __kernel_gid32_t;
9171 +
9172 +typedef unsigned short __kernel_old_uid_t;
9173 +typedef unsigned short __kernel_old_gid_t;
9174 +typedef unsigned short __kernel_old_dev_t;
9175 +
9176 +#ifdef __GNUC__
9177 +typedef long long      __kernel_loff_t;
9178 +#endif
9179 +
9180 +typedef struct {
9181 +#if defined(__KERNEL__) || defined(__USE_ALL)
9182 +       int     val[2];
9183 +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9184 +       int     __val[2];
9185 +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9186 +} __kernel_fsid_t;
9187 +
9188 +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
9189 +
9190 +#undef __FD_SET
9191 +#define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
9192 +
9193 +#undef __FD_CLR
9194 +#define        __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
9195 +
9196 +#undef __FD_ISSET
9197 +#define        __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
9198 +
9199 +#undef __FD_ZERO
9200 +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
9201 +
9202 +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
9203 +
9204 +#endif
9205 --- /dev/null
9206 +++ b/arch/ubicom32/include/asm/processor.h
9207 @@ -0,0 +1,163 @@
9208 +/*
9209 + * arch/ubicom32/include/asm/processor.h
9210 + *   Thread related definitions for Ubicom32 architecture.
9211 + *
9212 + * (C) Copyright 2009, Ubicom, Inc.
9213 + * Copyright (C) 1995 Hamish Macdonald
9214 + *
9215 + * This file is part of the Ubicom32 Linux Kernel Port.
9216 + *
9217 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9218 + * it and/or modify it under the terms of the GNU General Public License
9219 + * as published by the Free Software Foundation, either version 2 of the
9220 + * License, or (at your option) any later version.
9221 + *
9222 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9223 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9224 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9225 + * the GNU General Public License for more details.
9226 + *
9227 + * You should have received a copy of the GNU General Public License
9228 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9229 + * see <http://www.gnu.org/licenses/>.
9230 + *
9231 + * Ubicom32 implementation derived from (with many thanks):
9232 + *   arch/m68knommu
9233 + *   arch/blackfin
9234 + *   arch/parisc
9235 + */
9236 +
9237 +#ifndef _ASM_UBICOM32_PROCESSOR_H
9238 +#define _ASM_UBICOM32_PROCESSOR_H
9239 +
9240 +/*
9241 + * Default implementation of macro that returns current
9242 + * instruction pointer ("program counter").
9243 + */
9244 +#define current_text_addr() ({ __label__ _l; _l: &&_l;})
9245 +
9246 +#include <linux/compiler.h>
9247 +#include <linux/threads.h>
9248 +#include <asm/types.h>
9249 +#include <asm/segment.h>
9250 +#include <asm/fpu.h>
9251 +#include <asm/ptrace.h>
9252 +#include <asm/current.h>
9253 +#include <asm/thread_info.h>
9254 +
9255 +#if defined(CONFIG_UBICOM32_V3)
9256 +       #define CPU "IP5K"
9257 +#endif
9258 +#if defined(CONFIG_UBICOM32_V4)
9259 +       #define CPU "IP7K"
9260 +#endif
9261 +#ifndef CPU
9262 +       #define CPU "UNKNOWN"
9263 +#endif
9264 +
9265 +/*
9266 + * User space process size: 1st byte beyond user address space.
9267 + */
9268 +extern unsigned long memory_end;
9269 +#define TASK_SIZE      (memory_end)
9270 +
9271 +/*
9272 + * This decides where the kernel will search for a free chunk of vm
9273 + * space during mmap's. We won't be using it
9274 + */
9275 +#define TASK_UNMAPPED_BASE     0
9276 +
9277 +/*
9278 + * This is the structure where we are going to save callee-saved registers.
9279 + * A5 is the return address, A7 is the stack pointer, A6 is the frame
9280 + * pointer.  This is the frame that is created because of switch_to. This
9281 + * is not the frame due to interrupt preemption or because of syscall entry.
9282 + */
9283 +
9284 +struct thread_struct {
9285 +       unsigned long  d10;             /* D10  */
9286 +       unsigned long  d11;             /* D11  */
9287 +       unsigned long  d12;             /* D12  */
9288 +       unsigned long  d13;             /* D13  */
9289 +       unsigned long  a1;              /* A1  */
9290 +       unsigned long  a2;              /* A2  */
9291 +       unsigned long  a5;              /* A5 return address. */
9292 +       unsigned long  a6;              /* A6 */
9293 +       unsigned long  sp;              /* A7 kernel stack pointer. */
9294 +};
9295 +
9296 +#define INIT_THREAD  { \
9297 +       0, 0, 0, 0, 0, 0, 0, 0, \
9298 +       sizeof(init_stack) + (unsigned long) init_stack - 8, \
9299 +}
9300 +
9301 +/*
9302 + * Do necessary setup to start up a newly executed thread.
9303 + *
9304 + * pass the data segment into user programs if it exists,
9305 + * it can't hurt anything as far as I can tell
9306 + */
9307 +/*
9308 + * Do necessary setup to start up a newly executed thread.
9309 + */
9310 +#define start_thread(regs, new_pc, new_sp)      \
9311 +       do {                                     \
9312 +               regs->pc = new_pc & ~3;          \
9313 +               regs->an[5] = new_pc & ~3;       \
9314 +               regs->an[7] = new_sp;            \
9315 +               regs->nesting_level = -1;        \
9316 +               regs->frame_type = UBICOM32_FRAME_TYPE_NEW_THREAD; \
9317 +               regs->thread_type = NORMAL_THREAD; \
9318 +       } while(0)
9319 +
9320 +/* Forward declaration, a strange C thing */
9321 +struct task_struct;
9322 +
9323 +/* Free all resources held by a thread. */
9324 +static inline void release_thread(struct task_struct *dead_task)
9325 +{
9326 +}
9327 +
9328 +/* Prepare to copy thread state - unlazy all lazy status */
9329 +#define prepare_to_copy(tsk)   do { } while (0)
9330 +
9331 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
9332 +
9333 +/*
9334 + * Free current thread data structures etc..
9335 + */
9336 +static inline void exit_thread(void)
9337 +{
9338 +}
9339 +
9340 +unsigned long thread_saved_pc(struct task_struct *tsk);
9341 +unsigned long get_wchan(struct task_struct *p);
9342 +
9343 +#define        KSTK_EIP(tsk)   (tsk->thread.a5)
9344 +#define        KSTK_ESP(tsk)   (tsk->thread.sp)
9345 +
9346 +#define cpu_relax()    barrier()
9347 +
9348 +extern void processor_init(void);
9349 +extern unsigned int processor_timers(void);
9350 +extern unsigned int processor_threads(void);
9351 +extern unsigned int processor_frequency(void);
9352 +extern int processor_interrupts(unsigned int *int0, unsigned int *int1);
9353 +extern int processor_ocm(void **socm, void **eocm);
9354 +extern int processor_dram(void **sdram, void **edram);
9355 +
9356 +#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
9357 +#define KSTK_TOP(info)                                                 \
9358 +({                                                                     \
9359 +       unsigned long *__ptr = (unsigned long *)(info);                 \
9360 +       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
9361 +})
9362 +
9363 +#define task_pt_regs(task)                                             \
9364 +({                                                                     \
9365 +       struct pt_regs *__regs__;                                       \
9366 +       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
9367 +       __regs__ - 1;                                                   \
9368 +})
9369 +
9370 +#endif /* _ASM_UBICOM32_PROCESSOR_H */
9371 --- /dev/null
9372 +++ b/arch/ubicom32/include/asm/ptrace.h
9373 @@ -0,0 +1,177 @@
9374 +/*
9375 + * arch/ubicom32/include/asm/ptrace.h
9376 + *   Ubicom32 architecture ptrace support.
9377 + *
9378 + * (C) Copyright 2009, Ubicom, Inc.
9379 + *
9380 + * This file is part of the Ubicom32 Linux Kernel Port.
9381 + *
9382 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9383 + * it and/or modify it under the terms of the GNU General Public License
9384 + * as published by the Free Software Foundation, either version 2 of the
9385 + * License, or (at your option) any later version.
9386 + *
9387 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9388 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9389 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9390 + * the GNU General Public License for more details.
9391 + *
9392 + * You should have received a copy of the GNU General Public License
9393 + * along with the Ubicom32 Linux Kernel Port.  If not,
9394 + * see <http://www.gnu.org/licenses/>.
9395 + *
9396 + * Ubicom32 implementation derived from (with many thanks):
9397 + *   arch/m68knommu
9398 + *   arch/blackfin
9399 + *   arch/parisc
9400 + */
9401 +#ifndef _ASM_UBICOM32_PTRACE_H
9402 +#define _ASM_UBICOM32_PTRACE_H
9403 +
9404 +#ifndef __ASSEMBLY__
9405 +
9406 +/*
9407 + * We use hard coded constants because this is shared with user
9408 + * space and the values are NOT allowed to change.  Only fields
9409 + * that are intended to be exposed get values.
9410 + */
9411 +#define PT_D0           0
9412 +#define PT_D1           4
9413 +#define PT_D2           8
9414 +#define PT_D3           12
9415 +#define PT_D4           16
9416 +#define PT_D5           20
9417 +#define PT_D6           24
9418 +#define PT_D7           28
9419 +#define PT_D8           32
9420 +#define PT_D9           36
9421 +#define PT_D10          40
9422 +#define PT_D11          44
9423 +#define PT_D12          48
9424 +#define PT_D13          52
9425 +#define PT_D14          56
9426 +#define PT_D15          60
9427 +#define PT_A0           64
9428 +#define PT_A1           68
9429 +#define PT_A2           72
9430 +#define PT_A3           76
9431 +#define PT_A4           80
9432 +#define PT_A5           84
9433 +#define PT_A6           88
9434 +#define PT_A7           92
9435 +#define PT_SP           92
9436 +#define PT_ACC0HI       96
9437 +#define PT_ACC0LO       100
9438 +#define PT_MAC_RC16     104
9439 +#define PT_ACC1HI       108
9440 +#define PT_ACC1LO       112
9441 +#define PT_SOURCE3      116
9442 +#define PT_INST_CNT     120
9443 +#define PT_CSR          124
9444 +#define PT_DUMMY_UNUSED 128
9445 +#define PT_INT_MASK0    132
9446 +#define PT_INT_MASK1    136
9447 +#define PT_TRAP_CAUSE   140
9448 +#define PT_PC           144
9449 +#define PT_ORIGINAL_D0  148
9450 +#define PT_FRAME_TYPE   152
9451 +
9452 +/*
9453 + * The following 'registers' are not registers at all but are used
9454 + * locate the relocated sections.
9455 + */
9456 +#define PT_TEXT_ADDR           200
9457 +#define PT_TEXT_END_ADDR       204
9458 +#define PT_DATA_ADDR           208
9459 +#define PT_EXEC_FDPIC_LOADMAP  212
9460 +#define PT_INTERP_FDPIC_LOADMAP        216
9461 +
9462 +/*
9463 + * This struct defines the way the registers are stored on the
9464 + * stack during a system call.
9465 + */
9466 +enum thread_type {
9467 +       NORMAL_THREAD,
9468 +       KERNEL_THREAD,
9469 +};
9470 +
9471 +#define UBICOM32_FRAME_TYPE_SYSCALL    -1 /* System call frame */
9472 +#define UBICOM32_FRAME_TYPE_INVALID    0 /* Invalid frame, no longer in use */
9473 +#define UBICOM32_FRAME_TYPE_INTERRUPT  1 /* Interrupt frame */
9474 +#define UBICOM32_FRAME_TYPE_TRAP       2 /* Trap frame */
9475 +#define UBICOM32_FRAME_TYPE_SIGTRAMP   3 /* Signal trampoline frame. */
9476 +#define UBICOM32_FRAME_TYPE_NEW_THREAD 4 /* New Thread. */
9477 +
9478 +struct pt_regs {
9479 +       /*
9480 +        * Data Registers
9481 +        */
9482 +       unsigned long dn[16];
9483 +
9484 +       /*
9485 +        * Address Registers
9486 +        */
9487 +       unsigned long an[8];
9488 +
9489 +       /*
9490 +        * Per thread misc registers.
9491 +        */
9492 +       unsigned long acc0[2];
9493 +       unsigned long mac_rc16;
9494 +       unsigned long acc1[2];
9495 +       unsigned long source3;
9496 +       unsigned long inst_cnt;
9497 +       unsigned long csr;
9498 +       unsigned long dummy_unused;
9499 +       unsigned long int_mask0;
9500 +       unsigned long int_mask1;
9501 +       unsigned long trap_cause;
9502 +       unsigned long pc;
9503 +       unsigned long original_dn_0;
9504 +
9505 +       /*
9506 +        * Frame type. Syscall frames are -1. For other types look above.
9507 +        */
9508 +       unsigned long frame_type;
9509 +
9510 +       /*
9511 +        * These fields are not exposed to ptrace.
9512 +        */
9513 +       unsigned long previous_pc;
9514 +       long nesting_level;             /* When the kernel in in user space this
9515 +                                        * will be -1. */
9516 +       unsigned long thread_type;      /* This indicates if this is a kernel
9517 +                                        * thread. */
9518 +};
9519 +
9520 +/*
9521 + * This is the extended stack used by signal handlers and the context
9522 + * switcher: it's pushed after the normal "struct pt_regs".
9523 + */
9524 +struct switch_stack {
9525 +       unsigned long  dummy;
9526 +};
9527 +
9528 +#ifdef __KERNEL__
9529 +
9530 +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
9531 +#define PTRACE_GETREGS         12
9532 +#define PTRACE_SETREGS         13
9533 +
9534 +#ifndef PS_S
9535 +#define PS_S  (0x2000)
9536 +#define PS_M  (0x1000)
9537 +#endif
9538 +
9539 +extern  int __user_mode(unsigned long sp);
9540 +
9541 +#define user_mode(regs) (__user_mode((regs->an[7])))
9542 +#define user_stack(regs) ((regs)->an[7])
9543 +#define instruction_pointer(regs) ((regs)->pc)
9544 +#define profile_pc(regs) instruction_pointer(regs)
9545 +extern void show_regs(struct pt_regs *);
9546 +#endif /* __KERNEL__ */
9547 +
9548 +#endif /* __ASSEMBLY__ */
9549 +
9550 +#endif /* _ASM_UBICOM32_PTRACE_H */
9551 --- /dev/null
9552 +++ b/arch/ubicom32/include/asm/range-protect-asm.h
9553 @@ -0,0 +1,91 @@
9554 +/*
9555 + * arch/ubicom32/include/asm/range-protect-asm.h
9556 + *   Assembly macros for enabling memory protection.
9557 + *
9558 + * (C) Copyright 2009, Ubicom, Inc.
9559 + *
9560 + * This file is part of the Ubicom32 Linux Kernel Port.
9561 + *
9562 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9563 + * it and/or modify it under the terms of the GNU General Public License
9564 + * as published by the Free Software Foundation, either version 2 of the
9565 + * License, or (at your option) any later version.
9566 + *
9567 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9568 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9569 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9570 + * the GNU General Public License for more details.
9571 + *
9572 + * You should have received a copy of the GNU General Public License
9573 + * along with the Ubicom32 Linux Kernel Port.  If not,
9574 + * see <http://www.gnu.org/licenses/>.
9575 + *
9576 + * Ubicom32 implementation derived from (with many thanks):
9577 + *   arch/m68knommu
9578 + *   arch/blackfin
9579 + *   arch/parisc
9580 + */
9581 +
9582 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9583 +#define _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9584 +
9585 +#if defined(__ASSEMBLY__)
9586 +
9587 +#include <asm/thread-asm.h>
9588 +
9589 +/*
9590 + * You should only use the enable/disable ranges when you have the atomic lock,
9591 + * if you do not there will be problems.
9592 + */
9593 +
9594 +/*
9595 + * enable_kernel_ranges
9596 + *     Enable the kernel ranges (disabling protection) for thread,
9597 + *     where thread == (1 << thread number)
9598 + */
9599 +.macro enable_kernel_ranges thread
9600 +#ifdef CONFIG_PROTECT_KERNEL
9601 +       or.4    I_RANGE0_EN, I_RANGE0_EN, \thread        /* Enable Range Register */
9602 +       or.4    D_RANGE0_EN, D_RANGE0_EN, \thread
9603 +       or.4    D_RANGE1_EN, D_RANGE1_EN, \thread
9604 +#endif
9605 +.endm
9606 +
9607 +/*
9608 + * enable_kernel_ranges_for_current
9609 + *     Enable the kernel ranges (disabling protection) for this thread
9610 + */
9611 +.macro enable_kernel_ranges_for_current scratch_reg
9612 +#ifdef CONFIG_PROTECT_KERNEL
9613 +       thread_get_self_mask \scratch_reg
9614 +       enable_kernel_ranges \scratch_reg
9615 +#endif
9616 +.endm
9617 +
9618 +/*
9619 + * disable_kernel_ranges
9620 + *     Disables the kernel ranges (enabling protection) for thread
9621 + *     where thread == (1 << thread number)
9622 + */
9623 +.macro disable_kernel_ranges thread
9624 +#ifdef CONFIG_PROTECT_KERNEL
9625 +       not.4   \thread, \thread
9626 +       and.4   I_RANGE0_EN, I_RANGE0_EN, \thread        /* Disable Range Register */
9627 +       and.4   D_RANGE0_EN, D_RANGE0_EN, \thread
9628 +       and.4   D_RANGE1_EN, D_RANGE1_EN, \thread
9629 +#endif
9630 +.endm
9631 +
9632 +/*
9633 + * disable_kernel_ranges_for_current
9634 + *     Disable kernel ranges (enabling protection) for this thread
9635 + */
9636 +.macro disable_kernel_ranges_for_current scratch_reg
9637 +#ifdef CONFIG_PROTECT_KERNEL
9638 +       thread_get_self_mask \scratch_reg
9639 +       disable_kernel_ranges \scratch_reg
9640 +#endif
9641 +.endm
9642 +#endif
9643 +
9644 +#endif  /* _ASM_UBICOM32_RANGE_PROTECT_ASM_H */
9645 --- /dev/null
9646 +++ b/arch/ubicom32/include/asm/range-protect.h
9647 @@ -0,0 +1,62 @@
9648 +/*
9649 + * arch/ubicom32/include/asm/range-protect.h
9650 + *   Assembly macros declared in C for enabling memory protection.
9651 + *
9652 + * (C) Copyright 2009, Ubicom, Inc.
9653 + *
9654 + * This file is part of the Ubicom32 Linux Kernel Port.
9655 + *
9656 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9657 + * it and/or modify it under the terms of the GNU General Public License
9658 + * as published by the Free Software Foundation, either version 2 of the
9659 + * License, or (at your option) any later version.
9660 + *
9661 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9662 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9663 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9664 + * the GNU General Public License for more details.
9665 + *
9666 + * You should have received a copy of the GNU General Public License
9667 + * along with the Ubicom32 Linux Kernel Port.  If not,
9668 + * see <http://www.gnu.org/licenses/>.
9669 + *
9670 + * Ubicom32 implementation derived from (with many thanks):
9671 + *   arch/m68knommu
9672 + *   arch/blackfin
9673 + *   arch/parisc
9674 + */
9675 +
9676 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_H
9677 +#define _ASM_UBICOM32_RANGE_PROTECT_H
9678 +
9679 +#if !defined(__ASSEMBLY__)
9680 +#include <asm/thread.h>
9681 +/*
9682 + * The following macros should be the identical to the ones in
9683 + * range-protect-asm.h
9684 + *
9685 + * You should only use the enable/disable ranges when you have the atomic lock,
9686 + * if you do not there will be problems.
9687 + */
9688 +
9689 +/*
9690 + * enable_kernel_ranges
9691 + *     Enable the kernel ranges (disabling protection) for thread,
9692 + *     where thread == (1 << thread number)
9693 + */
9694 +asm (
9695 +       ".macro enable_kernel_ranges thread                     \n\t"
9696 +#ifdef CONFIG_PROTECT_KERNEL
9697 +       "       or.4    I_RANGE0_EN, I_RANGE0_EN, \\thread      \n\t" /* Enable Range Register */
9698 +       "       or.4    D_RANGE0_EN, D_RANGE0_EN, \\thread      \n\t"
9699 +       "       or.4    D_RANGE1_EN, D_RANGE1_EN, \\thread      \n\t"
9700 +#endif
9701 +       ".endm                                                  \n\t"
9702 +);
9703 +
9704 +#else /* __ASSEMBLY__ */
9705 +
9706 +#include <asm/range-protect-asm.h>
9707 +
9708 +#endif
9709 +#endif  /* _ASM_UBICOM32_RANGE_PROTECT_H */
9710 --- /dev/null
9711 +++ b/arch/ubicom32/include/asm/resource.h
9712 @@ -0,0 +1,33 @@
9713 +/*
9714 + * arch/ubicom32/include/asm/resource.h
9715 + *   Generic definitions for Ubicom32 architecture.
9716 + *
9717 + * (C) Copyright 2009, Ubicom, Inc.
9718 + *
9719 + * This file is part of the Ubicom32 Linux Kernel Port.
9720 + *
9721 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9722 + * it and/or modify it under the terms of the GNU General Public License
9723 + * as published by the Free Software Foundation, either version 2 of the
9724 + * License, or (at your option) any later version.
9725 + *
9726 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9727 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9728 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9729 + * the GNU General Public License for more details.
9730 + *
9731 + * You should have received a copy of the GNU General Public License
9732 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9733 + * see <http://www.gnu.org/licenses/>.
9734 + *
9735 + * Ubicom32 implementation derived from (with many thanks):
9736 + *   arch/m68knommu
9737 + *   arch/blackfin
9738 + *   arch/parisc
9739 + */
9740 +#ifndef _ASM_UBICOM32_RESOURCE_H
9741 +#define _ASM_UBICOM32_RESOURCE_H
9742 +
9743 +#include <asm-generic/resource.h>
9744 +
9745 +#endif /* _ASM_UBICOM32_RESOURCE_H */
9746 --- /dev/null
9747 +++ b/arch/ubicom32/include/asm/ring_tio.h
9748 @@ -0,0 +1,42 @@
9749 +/*
9750 + * arch/ubicom32/include/asm/ring_tio.h
9751 + *   Ubicom32 architecture Ring TIO definitions.
9752 + *
9753 + * (C) Copyright 2009, Ubicom, Inc.
9754 + *
9755 + * This file is part of the Ubicom32 Linux Kernel Port.
9756 + *
9757 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9758 + * it and/or modify it under the terms of the GNU General Public License
9759 + * as published by the Free Software Foundation, either version 2 of the
9760 + * License, or (at your option) any later version.
9761 + *
9762 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9763 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9764 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9765 + * the GNU General Public License for more details.
9766 + *
9767 + * You should have received a copy of the GNU General Public License
9768 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9769 + * see <http://www.gnu.org/licenses/>.
9770 + */
9771 +#ifndef _ASM_UBICOM32_RING_TIO_H
9772 +#define _ASM_UBICOM32_RING_TIO_H
9773 +
9774 +#include <asm/devtree.h>
9775 +
9776 +#define RING_TIO_NODE_VERSION  2
9777 +
9778 +/*
9779 + * Devtree node for ring
9780 + */
9781 +struct ring_tio_node {
9782 +       struct devtree_node     dn;
9783 +
9784 +       u32_t                   version;
9785 +       void                    *regs;
9786 +};
9787 +
9788 +extern void ring_tio_init(const char *node_name);
9789 +
9790 +#endif /* _ASM_UBICOM32_RING_TIO_H */
9791 --- /dev/null
9792 +++ b/arch/ubicom32/include/asm/scatterlist.h
9793 @@ -0,0 +1,49 @@
9794 +/*
9795 + * arch/ubicom32/include/asm/scatterlist.h
9796 + *   Definitions of struct scatterlist for Ubicom32 architecture.
9797 + *
9798 + * (C) Copyright 2009, Ubicom, Inc.
9799 + *
9800 + * This file is part of the Ubicom32 Linux Kernel Port.
9801 + *
9802 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9803 + * it and/or modify it under the terms of the GNU General Public License
9804 + * as published by the Free Software Foundation, either version 2 of the
9805 + * License, or (at your option) any later version.
9806 + *
9807 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9808 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9809 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9810 + * the GNU General Public License for more details.
9811 + *
9812 + * You should have received a copy of the GNU General Public License
9813 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9814 + * see <http://www.gnu.org/licenses/>.
9815 + *
9816 + * Ubicom32 implementation derived from (with many thanks):
9817 + *   arch/m68knommu
9818 + *   arch/blackfin
9819 + *   arch/parisc
9820 + */
9821 +#ifndef _ASM_UBICOM32_SCATTERLIST_H
9822 +#define _ASM_UBICOM32_SCATTERLIST_H
9823 +
9824 +#include <linux/mm.h>
9825 +#include <asm/types.h>
9826 +
9827 +struct scatterlist {
9828 +#ifdef CONFIG_DEBUG_SG
9829 +       unsigned long   sg_magic;
9830 +#endif
9831 +       unsigned long   page_link;
9832 +       unsigned int    offset;
9833 +       dma_addr_t      dma_address;
9834 +       unsigned int    length;
9835 +};
9836 +
9837 +#define sg_dma_address(sg)      ((sg)->dma_address)
9838 +#define sg_dma_len(sg)          ((sg)->length)
9839 +
9840 +#define ISA_DMA_THRESHOLD      (0xffffffff)
9841 +
9842 +#endif /* _ASM_UBICOM32_SCATTERLIST_H */
9843 --- /dev/null
9844 +++ b/arch/ubicom32/include/asm/sd_tio.h
9845 @@ -0,0 +1,36 @@
9846 +/*
9847 + * arch/ubicom32/include/asm/sd_tio.h
9848 + *   SD TIO definitions
9849 + *
9850 + * (C) Copyright 2009, Ubicom, Inc.
9851 + *
9852 + * This file is part of the Ubicom32 Linux Kernel Port.
9853 + *
9854 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9855 + * it and/or modify it under the terms of the GNU General Public License
9856 + * as published by the Free Software Foundation, either version 2 of the
9857 + * License, or (at your option) any later version.
9858 + *
9859 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9860 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9861 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9862 + * the GNU General Public License for more details.
9863 + *
9864 + * You should have received a copy of the GNU General Public License
9865 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9866 + * see <http://www.gnu.org/licenses/>.
9867 + */
9868 +#ifndef _ASM_UBICOM32_SD_TIO_H
9869 +#define _ASM_UBICOM32_SD_TIO_H
9870 +
9871 +#include <asm/devtree.h>
9872 +
9873 +/*
9874 + * Devtree node for SD
9875 + */
9876 +struct sd_tio_node {
9877 +       struct devtree_node     dn;
9878 +       void                    *regs;
9879 +};
9880 +
9881 +#endif /* _ASM_UBICOM32_SD_TIO_H */
9882 --- /dev/null
9883 +++ b/arch/ubicom32/include/asm/sections.h
9884 @@ -0,0 +1,33 @@
9885 +/*
9886 + * arch/ubicom32/include/asm/sections.h
9887 + *   Generic sections.h definitions for Ubicom32 architecture.
9888 + *
9889 + * (C) Copyright 2009, Ubicom, Inc.
9890 + *
9891 + * This file is part of the Ubicom32 Linux Kernel Port.
9892 + *
9893 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9894 + * it and/or modify it under the terms of the GNU General Public License
9895 + * as published by the Free Software Foundation, either version 2 of the
9896 + * License, or (at your option) any later version.
9897 + *
9898 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9899 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9900 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9901 + * the GNU General Public License for more details.
9902 + *
9903 + * You should have received a copy of the GNU General Public License
9904 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9905 + * see <http://www.gnu.org/licenses/>.
9906 + *
9907 + * Ubicom32 implementation derived from (with many thanks):
9908 + *   arch/m68knommu
9909 + *   arch/blackfin
9910 + *   arch/parisc
9911 + */
9912 +#ifndef _ASM_UBICOM32_SECTIONS_H
9913 +#define _ASM_UBICOM32_SECTIONS_H
9914 +
9915 +#include <asm-generic/sections.h>
9916 +
9917 +#endif /* _ASM_UBICOM32_SECTIONS_H */
9918 --- /dev/null
9919 +++ b/arch/ubicom32/include/asm/segment.h
9920 @@ -0,0 +1,78 @@
9921 +/*
9922 + * arch/ubicom32/include/asm/segment.h
9923 + *   Memory segment definitions for Ubicom32 architecture.
9924 + *
9925 + * (C) Copyright 2009, Ubicom, Inc.
9926 + *
9927 + * This file is part of the Ubicom32 Linux Kernel Port.
9928 + *
9929 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9930 + * it and/or modify it under the terms of the GNU General Public License
9931 + * as published by the Free Software Foundation, either version 2 of the
9932 + * License, or (at your option) any later version.
9933 + *
9934 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9935 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9936 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9937 + * the GNU General Public License for more details.
9938 + *
9939 + * You should have received a copy of the GNU General Public License
9940 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9941 + * see <http://www.gnu.org/licenses/>.
9942 + *
9943 + * Ubicom32 implementation derived from (with many thanks):
9944 + *   arch/m68knommu
9945 + *   arch/blackfin
9946 + *   arch/parisc
9947 + */
9948 +#ifndef _ASM_UBICOM32_SEGMENT_H
9949 +#define _ASM_UBICOM32_SEGMENT_H
9950 +
9951 +/* define constants */
9952 +/* Address spaces (FC0-FC2) */
9953 +#define USER_DATA     (1)
9954 +#ifndef __USER_DS
9955 +#define __USER_DS     (USER_DATA)
9956 +#endif
9957 +#define USER_PROGRAM  (2)
9958 +#define SUPER_DATA    (5)
9959 +#ifndef __KERNEL_DS
9960 +#define __KERNEL_DS   (SUPER_DATA)
9961 +#endif
9962 +#define SUPER_PROGRAM (6)
9963 +#define CPU_SPACE     (7)
9964 +
9965 +#ifndef __ASSEMBLY__
9966 +
9967 +typedef struct {
9968 +       unsigned long seg;
9969 +} mm_segment_t;
9970 +
9971 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
9972 +#define USER_DS                MAKE_MM_SEG(__USER_DS)
9973 +#define KERNEL_DS      MAKE_MM_SEG(__KERNEL_DS)
9974 +
9975 +/*
9976 + * Get/set the SFC/DFC registers for MOVES instructions
9977 + */
9978 +
9979 +static inline mm_segment_t get_fs(void)
9980 +{
9981 +    return USER_DS;
9982 +}
9983 +
9984 +static inline mm_segment_t get_ds(void)
9985 +{
9986 +    /* return the supervisor data space code */
9987 +    return KERNEL_DS;
9988 +}
9989 +
9990 +static inline void set_fs(mm_segment_t val)
9991 +{
9992 +}
9993 +
9994 +#define segment_eq(a,b)        ((a).seg == (b).seg)
9995 +
9996 +#endif /* __ASSEMBLY__ */
9997 +
9998 +#endif /* _ASM_UBICOM32_SEGMENT_H */
9999 --- /dev/null
10000 +++ b/arch/ubicom32/include/asm/semaphore.h
10001 @@ -0,0 +1,140 @@
10002 +/*
10003 + * arch/ubicom32/include/asm/semaphore.h
10004 + *   Interrupt-safe semaphores for Ubicom32 architecture.
10005 + *
10006 + * (C) Copyright 2009, Ubicom, Inc.
10007 + * (C) Copyright 1996 Linus Torvalds
10008 + * m68k version by Andreas Schwab
10009 + * Copyright (C) 2004   Microtronix Datacom Ltd
10010 + *
10011 + * This file is part of the Ubicom32 Linux Kernel Port.
10012 + *
10013 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10014 + * it and/or modify it under the terms of the GNU General Public License
10015 + * as published by the Free Software Foundation, either version 2 of the
10016 + * License, or (at your option) any later version.
10017 + *
10018 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10019 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10020 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10021 + * the GNU General Public License for more details.
10022 + *
10023 + * You should have received a copy of the GNU General Public License
10024 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10025 + * see <http://www.gnu.org/licenses/>.
10026 + *
10027 + * Ubicom32 implementation derived from (with many thanks):
10028 + *   arch/m68knommu
10029 + *   arch/blackfin
10030 + *   arch/parisc
10031 + */
10032 +#ifndef _ASM_UBICOM32_SEMAPHORE_H
10033 +#define _ASM_UBICOM32_SEMAPHORE_H
10034 +
10035 +#define RW_LOCK_BIAS            0x01000000
10036 +
10037 +#ifndef __ASSEMBLY__
10038 +
10039 +#include <linux/linkage.h>
10040 +#include <linux/wait.h>
10041 +#include <linux/spinlock.h>
10042 +#include <linux/rwsem.h>
10043 +
10044 +#include <asm/system.h>
10045 +#include <asm/atomic.h>
10046 +
10047 +struct semaphore {
10048 +       atomic_t count;
10049 +       atomic_t waking;
10050 +       wait_queue_head_t wait;
10051 +};
10052 +
10053 +#define __SEMAPHORE_INITIALIZER(name, n)                               \
10054 +{                                                                      \
10055 +       .count          = ATOMIC_INIT(n),                               \
10056 +       .waking         = ATOMIC_INIT(0),                               \
10057 +       .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
10058 +}
10059 +
10060 +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
10061 +       struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
10062 +
10063 +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
10064 +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
10065 +
10066 +static inline void sema_init (struct semaphore *sem, int val)
10067 +{
10068 +       *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
10069 +}
10070 +
10071 +static inline void init_MUTEX (struct semaphore *sem)
10072 +{
10073 +       sema_init(sem, 1);
10074 +}
10075 +
10076 +static inline void init_MUTEX_LOCKED (struct semaphore *sem)
10077 +{
10078 +       sema_init(sem, 0);
10079 +}
10080 +
10081 +asmlinkage void __down_failed(void /* special register calling convention */);
10082 +asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
10083 +asmlinkage int  __down_failed_trylock(void  /* params in registers */);
10084 +asmlinkage void __up_wakeup(void /* special register calling convention */);
10085 +
10086 +asmlinkage void __down(struct semaphore * sem);
10087 +asmlinkage int  __down_interruptible(struct semaphore * sem);
10088 +asmlinkage int  __down_trylock(struct semaphore * sem);
10089 +asmlinkage void __up(struct semaphore * sem);
10090 +
10091 +extern spinlock_t semaphore_wake_lock;
10092 +
10093 +/*
10094 + * This is ugly, but we want the default case to fall through.
10095 + * "down_failed" is a special asm handler that calls the C
10096 + * routine that actually waits.
10097 + */
10098 +static inline void down(struct semaphore * sem)
10099 +{
10100 +       might_sleep();
10101 +
10102 +       if (atomic_dec_return(&sem->count) < 0)
10103 +               __down(sem);
10104 +}
10105 +
10106 +static inline int down_interruptible(struct semaphore * sem)
10107 +{
10108 +       int ret = 0;
10109 +
10110 +
10111 +       might_sleep();
10112 +
10113 +       if(atomic_dec_return(&sem->count) < 0)
10114 +               ret = __down_interruptible(sem);
10115 +       return ret;
10116 +}
10117 +
10118 +static inline int down_trylock(struct semaphore * sem)
10119 +{
10120 +       int ret = 0;
10121 +
10122 +       if (atomic_dec_return (&sem->count) < 0)
10123 +               ret = __down_trylock(sem);
10124 +       return ret;
10125 +}
10126 +
10127 +/*
10128 + * Note! This is subtle. We jump to wake people up only if
10129 + * the semaphore was negative (== somebody was waiting on it).
10130 + * The default case (no contention) will result in NO
10131 + * jumps for both down() and up().
10132 + */
10133 +static inline void up(struct semaphore * sem)
10134 +{
10135 +       if (atomic_inc_return(&sem->count) <= 0)
10136 +               __up(sem);
10137 +}
10138 +
10139 +#endif /* __ASSEMBLY__ */
10140 +
10141 +#endif /* _ASM_UBICOM32_SEMAPHORE_H */
10142 --- /dev/null
10143 +++ b/arch/ubicom32/include/asm/semaphore-helper.h
10144 @@ -0,0 +1,109 @@
10145 +/*
10146 + * arch/ubicom32/include/asm/semaphore-helper.h
10147 + *   Semaphore related definitions for Ubicom32 architecture.
10148 + *
10149 + * (C) Copyright 2009, Ubicom, Inc.
10150 + *
10151 + * This file is part of the Ubicom32 Linux Kernel Port.
10152 + *
10153 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10154 + * it and/or modify it under the terms of the GNU General Public License
10155 + * as published by the Free Software Foundation, either version 2 of the
10156 + * License, or (at your option) any later version.
10157 + *
10158 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10159 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10160 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10161 + * the GNU General Public License for more details.
10162 + *
10163 + * You should have received a copy of the GNU General Public License
10164 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10165 + * see <http://www.gnu.org/licenses/>.
10166 + *
10167 + * Ubicom32 implementation derived from (with many thanks):
10168 + *   arch/m68knommu
10169 + *   arch/blackfin
10170 + *   arch/parisc
10171 + */
10172 +#ifndef _ASM_UBICOM32_SEMAPHORE_HELPER_H
10173 +#define _ASM_UBICOM32_SEMAPHORE_HELPER_H
10174 +
10175 +/*
10176 + * SMP- and interrupt-safe semaphores helper functions.
10177 + *
10178 + * (C) Copyright 1996 Linus Torvalds
10179 + *
10180 + * m68k version by Andreas Schwab
10181 + */
10182 +
10183 +
10184 +/*
10185 + * These two _must_ execute atomically wrt each other.
10186 + */
10187 +static inline void wake_one_more(struct semaphore * sem)
10188 +{
10189 +       atomic_inc(&sem->waking);
10190 +}
10191 +
10192 +static inline int waking_non_zero(struct semaphore *sem)
10193 +{
10194 +       int ret;
10195 +       unsigned long flags;
10196 +
10197 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10198 +       ret = 0;
10199 +       if (atomic_read(&sem->waking) > 0) {
10200 +               atomic_dec(&sem->waking);
10201 +               ret = 1;
10202 +       }
10203 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10204 +       return ret;
10205 +}
10206 +
10207 +/*
10208 + * waking_non_zero_interruptible:
10209 + *     1       got the lock
10210 + *     0       go to sleep
10211 + *     -EINTR  interrupted
10212 + */
10213 +static inline int waking_non_zero_interruptible(struct semaphore *sem,
10214 +                                               struct task_struct *tsk)
10215 +{
10216 +       int ret;
10217 +       unsigned long flags;
10218 +
10219 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10220 +       ret = 0;
10221 +       if (atomic_read(&sem->waking) > 0) {
10222 +               atomic_dec(&sem->waking);
10223 +               ret = 1;
10224 +       } else if (signal_pending(tsk)) {
10225 +               atomic_inc(&sem->count);
10226 +               ret = -EINTR;
10227 +       }
10228 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10229 +       return ret;
10230 +}
10231 +
10232 +/*
10233 + * waking_non_zero_trylock:
10234 + *     1       failed to lock
10235 + *     0       got the lock
10236 + */
10237 +static inline int waking_non_zero_trylock(struct semaphore *sem)
10238 +{
10239 +       int ret;
10240 +       unsigned long flags;
10241 +
10242 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10243 +       ret = 1;
10244 +       if (atomic_read(&sem->waking) > 0) {
10245 +               atomic_dec(&sem->waking);
10246 +               ret = 0;
10247 +       } else
10248 +               atomic_inc(&sem->count);
10249 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10250 +       return ret;
10251 +}
10252 +
10253 +#endif /* _ASM_UBICOM32_SEMAPHORE_HELPER_H */
10254 --- /dev/null
10255 +++ b/arch/ubicom32/include/asm/sembuf.h
10256 @@ -0,0 +1,52 @@
10257 +/*
10258 + * arch/ubicom32/include/asm/sembuf.h
10259 + *   The semid64_ds structure for Ubicom32 architecture.
10260 + *
10261 + * (C) Copyright 2009, Ubicom, Inc.
10262 + *
10263 + * This file is part of the Ubicom32 Linux Kernel Port.
10264 + *
10265 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10266 + * it and/or modify it under the terms of the GNU General Public License
10267 + * as published by the Free Software Foundation, either version 2 of the
10268 + * License, or (at your option) any later version.
10269 + *
10270 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10271 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10272 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10273 + * the GNU General Public License for more details.
10274 + *
10275 + * You should have received a copy of the GNU General Public License
10276 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10277 + * see <http://www.gnu.org/licenses/>.
10278 + *
10279 + * Ubicom32 implementation derived from (with many thanks):
10280 + *   arch/m68knommu
10281 + *   arch/blackfin
10282 + *   arch/parisc
10283 + */
10284 +#ifndef _ASM_UBICOM32_SEMBUF_H
10285 +#define _ASM_UBICOM32_SEMBUF_H
10286 +
10287 +/*
10288 + * The semid64_ds structure for ubicom32 architecture.
10289 + * Note extra padding because this structure is passed back and forth
10290 + * between kernel and user space.
10291 + *
10292 + * Pad space is left for:
10293 + * - 64-bit time_t to solve y2038 problem
10294 + * - 2 miscellaneous 32-bit values
10295 + */
10296 +
10297 +struct semid64_ds {
10298 +       struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
10299 +       __kernel_time_t sem_otime;              /* last semop time */
10300 +       unsigned long   __unused1;
10301 +       __kernel_time_t sem_ctime;              /* last change time */
10302 +       unsigned long   __unused2;
10303 +       unsigned long   sem_nsems;              /* no. of semaphores in array */
10304 +       unsigned long   __unused3;
10305 +       unsigned long   __unused4;
10306 +};
10307 +
10308 +#endif /* _ASM_UBICOM32_SEMBUF_H */
10309 --- /dev/null
10310 +++ b/arch/ubicom32/include/asm/setup.h
10311 @@ -0,0 +1,35 @@
10312 +/*
10313 + * arch/ubicom32/include/asm/setup.h
10314 + *   Kernel command line length definition.
10315 + *
10316 + * (C) Copyright 2009, Ubicom, Inc.
10317 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.
10318 + *
10319 + * This file is part of the Ubicom32 Linux Kernel Port.
10320 + *
10321 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10322 + * it and/or modify it under the terms of the GNU General Public License
10323 + * as published by the Free Software Foundation, either version 2 of the
10324 + * License, or (at your option) any later version.
10325 + *
10326 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10327 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10328 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10329 + * the GNU General Public License for more details.
10330 + *
10331 + * You should have received a copy of the GNU General Public License
10332 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10333 + * see <http://www.gnu.org/licenses/>.
10334 + *
10335 + * Ubicom32 implementation derived from (with many thanks):
10336 + *   arch/m68knommu
10337 + *   arch/blackfin
10338 + *   arch/parisc
10339 + */
10340 +
10341 +#ifndef _ASM_UBICOM32_SETUP_H
10342 +#define _ASM_UBICOM32_SETUP_H
10343 +
10344 +#define COMMAND_LINE_SIZE 512
10345 +
10346 +#endif /* _ASM_UBICOM32_SETUP_H */
10347 --- /dev/null
10348 +++ b/arch/ubicom32/include/asm/shmbuf.h
10349 @@ -0,0 +1,69 @@
10350 +/*
10351 + * arch/ubicom32/include/asm/shmbuf.h
10352 + *   The shmid64_ds structure for the Ubicom32 architecture.
10353 + *
10354 + * (C) Copyright 2009, Ubicom, Inc.
10355 + *
10356 + * This file is part of the Ubicom32 Linux Kernel Port.
10357 + *
10358 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10359 + * it and/or modify it under the terms of the GNU General Public License
10360 + * as published by the Free Software Foundation, either version 2 of the
10361 + * License, or (at your option) any later version.
10362 + *
10363 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10364 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10365 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10366 + * the GNU General Public License for more details.
10367 + *
10368 + * You should have received a copy of the GNU General Public License
10369 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10370 + * see <http://www.gnu.org/licenses/>.
10371 + *
10372 + * Ubicom32 implementation derived from (with many thanks):
10373 + *   arch/m68knommu
10374 + *   arch/blackfin
10375 + *   arch/parisc
10376 + */
10377 +#ifndef _ASM_UBICOM32_SHMBUF_H
10378 +#define _ASM_UBICOM32_SHMBUF_H
10379 +
10380 +/*
10381 + * The shmid64_ds structure for m68k architecture.
10382 + * Note extra padding because this structure is passed back and forth
10383 + * between kernel and user space.
10384 + *
10385 + * Pad space is left for:
10386 + * - 64-bit time_t to solve y2038 problem
10387 + * - 2 miscellaneous 32-bit values
10388 + */
10389 +
10390 +struct shmid64_ds {
10391 +       struct ipc64_perm       shm_perm;       /* operation perms */
10392 +       size_t                  shm_segsz;      /* size of segment (bytes) */
10393 +       __kernel_time_t         shm_atime;      /* last attach time */
10394 +       unsigned long           __unused1;
10395 +       __kernel_time_t         shm_dtime;      /* last detach time */
10396 +       unsigned long           __unused2;
10397 +       __kernel_time_t         shm_ctime;      /* last change time */
10398 +       unsigned long           __unused3;
10399 +       __kernel_pid_t          shm_cpid;       /* pid of creator */
10400 +       __kernel_pid_t          shm_lpid;       /* pid of last operator */
10401 +       unsigned long           shm_nattch;     /* no. of current attaches */
10402 +       unsigned long           __unused4;
10403 +       unsigned long           __unused5;
10404 +};
10405 +
10406 +struct shminfo64 {
10407 +       unsigned long   shmmax;
10408 +       unsigned long   shmmin;
10409 +       unsigned long   shmmni;
10410 +       unsigned long   shmseg;
10411 +       unsigned long   shmall;
10412 +       unsigned long   __unused1;
10413 +       unsigned long   __unused2;
10414 +       unsigned long   __unused3;
10415 +       unsigned long   __unused4;
10416 +};
10417 +
10418 +#endif /* _ASM_UBICOM32_SHMBUF_H */
10419 --- /dev/null
10420 +++ b/arch/ubicom32/include/asm/shmparam.h
10421 @@ -0,0 +1,35 @@
10422 +/*
10423 + * arch/ubicom32/include/asm/shmparam.h
10424 + *   Shared memory definitions for Ubicom32 architecture.
10425 + *
10426 + * (C) Copyright 2009, Ubicom, Inc.
10427 + * Copyright (C) 2004   Microtronix Datacom Ltd
10428 + *
10429 + * This file is part of the Ubicom32 Linux Kernel Port.
10430 + *
10431 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10432 + * it and/or modify it under the terms of the GNU General Public License
10433 + * as published by the Free Software Foundation, either version 2 of the
10434 + * License, or (at your option) any later version.
10435 + *
10436 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10437 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10438 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10439 + * the GNU General Public License for more details.
10440 + *
10441 + * You should have received a copy of the GNU General Public License
10442 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10443 + * see <http://www.gnu.org/licenses/>.
10444 + *
10445 + * Ubicom32 implementation derived from (with many thanks):
10446 + *   arch/m68knommu
10447 + *   arch/blackfin
10448 + *   arch/parisc
10449 + *   Alpha, ix86, M68K, Sparc, ...et al
10450 + */
10451 +#ifndef _ASM_UBICOM32_SHMPARAM_H
10452 +#define _ASM_UBICOM32_SHMPARAM_H
10453 +
10454 +#define        SHMLBA          PAGE_SIZE       /* attach addr a multiple of this */
10455 +
10456 +#endif /* _ASM_UBICOM32_SHMPARAM_H */
10457 --- /dev/null
10458 +++ b/arch/ubicom32/include/asm/sigcontext.h
10459 @@ -0,0 +1,37 @@
10460 +/*
10461 + * arch/ubicom32/include/asm/sigcontext.h
10462 + *   Definition of sigcontext struct for Ubicom32 architecture.
10463 + *
10464 + * (C) Copyright 2009, Ubicom, Inc.
10465 + *
10466 + * This file is part of the Ubicom32 Linux Kernel Port.
10467 + *
10468 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10469 + * it and/or modify it under the terms of the GNU General Public License
10470 + * as published by the Free Software Foundation, either version 2 of the
10471 + * License, or (at your option) any later version.
10472 + *
10473 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10474 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10475 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10476 + * the GNU General Public License for more details.
10477 + *
10478 + * You should have received a copy of the GNU General Public License
10479 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10480 + * see <http://www.gnu.org/licenses/>.
10481 + *
10482 + * Ubicom32 implementation derived from (with many thanks):
10483 + *   arch/m68knommu
10484 + *   arch/blackfin
10485 + *   arch/parisc
10486 + */
10487 +#ifndef _ASM_UBICOM32_SIGCONTEXT_H
10488 +#define _ASM_UBICOM32_SIGCONTEXT_H
10489 +
10490 +#include <asm/ptrace.h>
10491 +
10492 +struct sigcontext {
10493 +       struct pt_regs sc_regs;
10494 +};
10495 +
10496 +#endif /* _ASM_UBICOM32_SIGCONTEXT_H */
10497 --- /dev/null
10498 +++ b/arch/ubicom32/include/asm/siginfo.h
10499 @@ -0,0 +1,33 @@
10500 +/*
10501 + * arch/ubicom32/include/asm/siginfo.h
10502 + *   Generic siginfo.h definitions for Ubicom32 architecture.
10503 + *
10504 + * (C) Copyright 2009, Ubicom, Inc.
10505 + *
10506 + * This file is part of the Ubicom32 Linux Kernel Port.
10507 + *
10508 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10509 + * it and/or modify it under the terms of the GNU General Public License
10510 + * as published by the Free Software Foundation, either version 2 of the
10511 + * License, or (at your option) any later version.
10512 + *
10513 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10514 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10515 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10516 + * the GNU General Public License for more details.
10517 + *
10518 + * You should have received a copy of the GNU General Public License
10519 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10520 + * see <http://www.gnu.org/licenses/>.
10521 + *
10522 + * Ubicom32 implementation derived from (with many thanks):
10523 + *   arch/m68knommu
10524 + *   arch/blackfin
10525 + *   arch/parisc
10526 + */
10527 +#ifndef _ASM_UBICOM32_SIGINFO_H
10528 +#define _ASM_UBICOM32_SIGINFO_H
10529 +
10530 +#include <asm-generic/siginfo.h>
10531 +
10532 +#endif /* _ASM_UBICOM32_SIGINFO_H */
10533 --- /dev/null
10534 +++ b/arch/ubicom32/include/asm/signal.h
10535 @@ -0,0 +1,180 @@
10536 +/*
10537 + * arch/ubicom32/include/asm/signal.h
10538 + *   Signal related definitions for Ubicom32 architecture.
10539 + *
10540 + * (C) Copyright 2009, Ubicom, Inc.
10541 + *
10542 + * This file is part of the Ubicom32 Linux Kernel Port.
10543 + *
10544 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10545 + * it and/or modify it under the terms of the GNU General Public License
10546 + * as published by the Free Software Foundation, either version 2 of the
10547 + * License, or (at your option) any later version.
10548 + *
10549 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10550 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10551 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10552 + * the GNU General Public License for more details.
10553 + *
10554 + * You should have received a copy of the GNU General Public License
10555 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10556 + * see <http://www.gnu.org/licenses/>.
10557 + *
10558 + * Ubicom32 implementation derived from (with many thanks):
10559 + *   arch/m68knommu
10560 + *   arch/blackfin
10561 + *   arch/parisc
10562 + */
10563 +#ifndef _ASM_UBICOM32_SIGNAL_H
10564 +#define _ASM_UBICOM32_SIGNAL_H
10565 +
10566 +#include <linux/types.h>
10567 +
10568 +/* Avoid too many header ordering problems.  */
10569 +struct siginfo;
10570 +
10571 +#ifdef __KERNEL__
10572 +/* Most things should be clean enough to redefine this at will, if care
10573 +   is taken to make libc match.  */
10574 +
10575 +#define _NSIG          64
10576 +#define _NSIG_BPW      32
10577 +#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
10578 +
10579 +typedef unsigned long old_sigset_t;            /* at least 32 bits */
10580 +
10581 +typedef struct {
10582 +       unsigned long sig[_NSIG_WORDS];
10583 +} sigset_t;
10584 +
10585 +#endif /* __KERNEL__ */
10586 +
10587 +#define SIGHUP          1
10588 +#define SIGINT          2
10589 +#define SIGQUIT                 3
10590 +#define SIGILL          4
10591 +#define SIGTRAP                 5
10592 +#define SIGABRT                 6
10593 +#define SIGIOT          6
10594 +#define SIGBUS          7
10595 +#define SIGFPE          8
10596 +#define SIGKILL                 9
10597 +#define SIGUSR1                10
10598 +#define SIGSEGV                11
10599 +#define SIGUSR2                12
10600 +#define SIGPIPE                13
10601 +#define SIGALRM                14
10602 +#define SIGTERM                15
10603 +#define SIGSTKFLT      16
10604 +#define SIGCHLD                17
10605 +#define SIGCONT                18
10606 +#define SIGSTOP                19
10607 +#define SIGTSTP                20
10608 +#define SIGTTIN                21
10609 +#define SIGTTOU                22
10610 +#define SIGURG         23
10611 +#define SIGXCPU                24
10612 +#define SIGXFSZ                25
10613 +#define SIGVTALRM      26
10614 +#define SIGPROF                27
10615 +#define SIGWINCH       28
10616 +#define SIGIO          29
10617 +#define SIGPOLL                SIGIO
10618 +/*
10619 +#define SIGLOST                29
10620 +*/
10621 +#define SIGPWR         30
10622 +#define SIGSYS         31
10623 +#define        SIGUNUSED       31
10624 +
10625 +/* These should not be considered constants from userland.  */
10626 +#define SIGRTMIN       32
10627 +#define SIGRTMAX       _NSIG
10628 +
10629 +/*
10630 + * SA_FLAGS values:
10631 + *
10632 + * SA_ONSTACK indicates that a registered stack_t will be used.
10633 + * SA_RESTART flag to get restarting signals (which were the default long ago)
10634 + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
10635 + * SA_RESETHAND clears the handler when the signal is delivered.
10636 + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
10637 + * SA_NODEFER prevents the current signal from being masked in the handler.
10638 + *
10639 + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
10640 + * Unix names RESETHAND and NODEFER respectively.
10641 + */
10642 +#define SA_NOCLDSTOP   0x00000001
10643 +#define SA_NOCLDWAIT   0x00000002
10644 +#define SA_SIGINFO     0x00000004
10645 +#define SA_ONSTACK     0x08000000
10646 +#define SA_RESTART     0x10000000
10647 +#define SA_NODEFER     0x40000000
10648 +#define SA_RESETHAND   0x80000000
10649 +
10650 +#define SA_NOMASK      SA_NODEFER
10651 +#define SA_ONESHOT     SA_RESETHAND
10652 +
10653 +/* 
10654 + * sigaltstack controls
10655 + */
10656 +#define SS_ONSTACK     1
10657 +#define SS_DISABLE     2
10658 +
10659 +#define MINSIGSTKSZ    2048
10660 +#define SIGSTKSZ       8192
10661 +
10662 +#include <asm-generic/signal.h>
10663 +
10664 +#ifdef __KERNEL__
10665 +struct old_sigaction {
10666 +       __sighandler_t sa_handler;
10667 +       old_sigset_t sa_mask;
10668 +       unsigned long sa_flags;
10669 +       void (*sa_restorer)(void);
10670 +};
10671 +
10672 +struct sigaction {
10673 +       __sighandler_t sa_handler;
10674 +       unsigned long sa_flags;
10675 +       void (*sa_restorer)(void);
10676 +       sigset_t sa_mask;               /* mask last for extensibility */
10677 +};
10678 +
10679 +struct k_sigaction {
10680 +       struct sigaction sa;
10681 +};
10682 +#else
10683 +/* Here we must cater to libcs that poke about in kernel headers.  */
10684 +
10685 +struct sigaction {
10686 +       union {
10687 +         __sighandler_t _sa_handler;
10688 +         void (*_sa_sigaction)(int, struct siginfo *, void *);
10689 +       } _u;
10690 +       sigset_t sa_mask;
10691 +       unsigned long sa_flags;
10692 +       void (*sa_restorer)(void);
10693 +};
10694 +
10695 +#define sa_handler     _u._sa_handler
10696 +#define sa_sigaction   _u._sa_sigaction
10697 +
10698 +#endif /* __KERNEL__ */
10699 +
10700 +typedef struct sigaltstack {
10701 +       void *ss_sp;
10702 +       int ss_flags;
10703 +       size_t ss_size;
10704 +} stack_t;
10705 +
10706 +#ifdef __KERNEL__
10707 +
10708 +#include <asm/sigcontext.h>
10709 +#undef __HAVE_ARCH_SIG_BITOPS
10710 +
10711 +#define ptrace_signal_deliver(regs, cookie) do { } while (0)
10712 +
10713 +#endif /* __KERNEL__ */
10714 +
10715 +#endif /* _ASM_UBICOM32_SIGNAL_H */
10716 --- /dev/null
10717 +++ b/arch/ubicom32/include/asm/smp.h
10718 @@ -0,0 +1,83 @@
10719 +/*
10720 + * arch/ubicom32/include/asm/smp.h
10721 + *   SMP definitions for Ubicom32 architecture.
10722 + *
10723 + * (C) Copyright 2009, Ubicom, Inc.
10724 + *
10725 + * This file is part of the Ubicom32 Linux Kernel Port.
10726 + *
10727 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10728 + * it and/or modify it under the terms of the GNU General Public License
10729 + * as published by the Free Software Foundation, either version 2 of the
10730 + * License, or (at your option) any later version.
10731 + *
10732 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10733 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10734 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10735 + * the GNU General Public License for more details.
10736 + *
10737 + * You should have received a copy of the GNU General Public License
10738 + * along with the Ubicom32 Linux Kernel Port.  If not,
10739 + * see <http://www.gnu.org/licenses/>.
10740 + *
10741 + * Ubicom32 implementation derived from (with many thanks):
10742 + *   arch/m68knommu
10743 + *   arch/blackfin
10744 + *   arch/parisc
10745 + */
10746 +#ifndef _ASM_UBICOM32_SMP_H
10747 +#define _ASM_UBICOM32_SMP_H
10748 +
10749 +#ifndef ASSEMBLY
10750 +#include <linux/bitops.h>
10751 +#include <linux/threads.h>
10752 +#include <linux/cpumask.h>
10753 +#include <asm/ip5000.h>
10754 +
10755 +typedef unsigned long address_t;
10756 +extern cpumask_t cpu_online_map;
10757 +extern unsigned int smp_ipi_irq;
10758 +
10759 +/*
10760 + * This magic constant controls our willingness to transfer
10761 + * a process across CPUs.
10762 + *
10763 + * Such a transfer incurs cache and tlb
10764 + * misses. The current value is inherited from i386. Still needs
10765 + * to be tuned for parisc.
10766 + */
10767 +#define PROC_CHANGE_PENALTY    15              /* Schedule penalty */
10768 +#define NO_PROC_ID             0xFF            /* No processor magic marker */
10769 +#define ANY_PROC_ID            0xFF            /* Any processor magic marker */
10770 +
10771 +#ifdef CONFIG_SMP
10772 +#define raw_smp_processor_id() (current_thread_info()->cpu)
10773 +#endif /* CONFIG_SMP */
10774 +
10775 +static inline int __cpu_disable (void)
10776 +{
10777 +  return 0;
10778 +}
10779 +
10780 +static inline void __cpu_die (unsigned int cpu)
10781 +{
10782 +       while(1) {
10783 +       };
10784 +}
10785 +
10786 +extern int __cpu_up(unsigned int cpu);
10787 +extern void smp_send_timer_all(void);
10788 +extern void smp_timer_broadcast(cpumask_t mask);
10789 +extern void smp_set_affinity(unsigned int irq, cpumask_t dest);
10790 +extern void arch_send_call_function_single_ipi(int cpu);
10791 +extern void arch_send_call_function_ipi(cpumask_t mask);
10792 +
10793 +/*
10794 + * TODO: Once these are fully tested, we should turn them into
10795 + * inline macros for performance.
10796 + */
10797 +extern unsigned long smp_get_affinity(unsigned int irq, int *all);
10798 +extern void smp_reset_ipi(unsigned long mask);
10799 +
10800 +#endif /* !ASSEMBLY */
10801 +#endif /*  _ASM_UBICOM32_SMP_H */
10802 --- /dev/null
10803 +++ b/arch/ubicom32/include/asm/socket.h
10804 @@ -0,0 +1,84 @@
10805 +/*
10806 + * arch/ubicom32/include/asm/socket.h
10807 + *   Socket options definitions for Ubicom32 architecture.
10808 + *
10809 + * (C) Copyright 2009, Ubicom, Inc.
10810 + *
10811 + * This file is part of the Ubicom32 Linux Kernel Port.
10812 + *
10813 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10814 + * it and/or modify it under the terms of the GNU General Public License
10815 + * as published by the Free Software Foundation, either version 2 of the
10816 + * License, or (at your option) any later version.
10817 + *
10818 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10819 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10820 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10821 + * the GNU General Public License for more details.
10822 + *
10823 + * You should have received a copy of the GNU General Public License
10824 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10825 + * see <http://www.gnu.org/licenses/>.
10826 + *
10827 + * Ubicom32 implementation derived from (with many thanks):
10828 + *   arch/m68knommu
10829 + *   arch/blackfin
10830 + *   arch/parisc
10831 + */
10832 +#ifndef _ASM_UBICOM32_SOCKET_H
10833 +#define _ASM_UBICOM32_SOCKET_H
10834 +
10835 +#include <asm/sockios.h>
10836 +
10837 +/* For setsockopt(2) */
10838 +#define SOL_SOCKET     1
10839 +
10840 +#define SO_DEBUG       1
10841 +#define SO_REUSEADDR   2
10842 +#define SO_TYPE                3
10843 +#define SO_ERROR       4
10844 +#define SO_DONTROUTE   5
10845 +#define SO_BROADCAST   6
10846 +#define SO_SNDBUF      7
10847 +#define SO_RCVBUF      8
10848 +#define SO_SNDBUFFORCE 32
10849 +#define SO_RCVBUFFORCE 33
10850 +#define SO_KEEPALIVE   9
10851 +#define SO_OOBINLINE   10
10852 +#define SO_NO_CHECK    11
10853 +#define SO_PRIORITY    12
10854 +#define SO_LINGER      13
10855 +#define SO_BSDCOMPAT   14
10856 +/* To add :#define SO_REUSEPORT 15 */
10857 +#define SO_PASSCRED    16
10858 +#define SO_PEERCRED    17
10859 +#define SO_RCVLOWAT    18
10860 +#define SO_SNDLOWAT    19
10861 +#define SO_RCVTIMEO    20
10862 +#define SO_SNDTIMEO    21
10863 +
10864 +/* Security levels - as per NRL IPv6 - don't actually do anything */
10865 +#define SO_SECURITY_AUTHENTICATION             22
10866 +#define SO_SECURITY_ENCRYPTION_TRANSPORT       23
10867 +#define SO_SECURITY_ENCRYPTION_NETWORK         24
10868 +
10869 +#define SO_BINDTODEVICE        25
10870 +
10871 +/* Socket filtering */
10872 +#define SO_ATTACH_FILTER        26
10873 +#define SO_DETACH_FILTER        27
10874 +
10875 +#define SO_PEERNAME             28
10876 +#define SO_TIMESTAMP           29
10877 +#define SCM_TIMESTAMP          SO_TIMESTAMP
10878 +
10879 +#define SO_ACCEPTCONN          30
10880 +
10881 +#define SO_PEERSEC              31
10882 +#define SO_PASSSEC             34
10883 +#define SO_TIMESTAMPNS         35
10884 +#define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
10885 +
10886 +#define SO_MARK                        36
10887 +
10888 +#endif /* _ASM_UBICOM32_SOCKET_H */
10889 --- /dev/null
10890 +++ b/arch/ubicom32/include/asm/sockios.h
10891 @@ -0,0 +1,40 @@
10892 +/*
10893 + * arch/ubicom32/include/asm/sockios.h
10894 + *   Socket-level ioctl definitions for Ubicom32 architecture.
10895 + *
10896 + * (C) Copyright 2009, Ubicom, Inc.
10897 + *
10898 + * This file is part of the Ubicom32 Linux Kernel Port.
10899 + *
10900 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10901 + * it and/or modify it under the terms of the GNU General Public License
10902 + * as published by the Free Software Foundation, either version 2 of the
10903 + * License, or (at your option) any later version.
10904 + *
10905 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10906 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10907 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10908 + * the GNU General Public License for more details.
10909 + *
10910 + * You should have received a copy of the GNU General Public License
10911 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10912 + * see <http://www.gnu.org/licenses/>.
10913 + *
10914 + * Ubicom32 implementation derived from (with many thanks):
10915 + *   arch/m68knommu
10916 + *   arch/blackfin
10917 + *   arch/parisc
10918 + */
10919 +#ifndef _ASM_UBICOM32_SOCKIOS_H
10920 +#define _ASM_UBICOM32_SOCKIOS_H
10921 +
10922 +/* Socket-level I/O control calls. */
10923 +#define FIOSETOWN      0x8901
10924 +#define SIOCSPGRP      0x8902
10925 +#define FIOGETOWN      0x8903
10926 +#define SIOCGPGRP      0x8904
10927 +#define SIOCATMARK     0x8905
10928 +#define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
10929 +#define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
10930 +
10931 +#endif /* _ASM_UBICOM32_SOCKIOS_H */
10932 --- /dev/null
10933 +++ b/arch/ubicom32/include/asm/spinlock.h
10934 @@ -0,0 +1,293 @@
10935 +/*
10936 + * arch/ubicom32/include/asm/spinlock.h
10937 + *   Spinlock related definitions for Ubicom32 architecture.
10938 + *
10939 + * (C) Copyright 2009, Ubicom, Inc.
10940 + *
10941 + * This file is part of the Ubicom32 Linux Kernel Port.
10942 + *
10943 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10944 + * it and/or modify it under the terms of the GNU General Public License
10945 + * as published by the Free Software Foundation, either version 2 of the
10946 + * License, or (at your option) any later version.
10947 + *
10948 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10949 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10950 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10951 + * the GNU General Public License for more details.
10952 + *
10953 + * You should have received a copy of the GNU General Public License
10954 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10955 + * see <http://www.gnu.org/licenses/>.
10956 + *
10957 + * Ubicom32 implementation derived from (with many thanks):
10958 + *   arch/m68knommu
10959 + *   arch/blackfin
10960 + *   arch/parisc
10961 + */
10962 +#ifndef _ASM_UBICOM32_SPINLOCK_H
10963 +#define _ASM_UBICOM32_SPINLOCK_H
10964 +
10965 +#include <asm/system.h>
10966 +#include <asm/processor.h>
10967 +#include <asm/spinlock_types.h>
10968 +
10969 +/*
10970 + * __raw_spin_lock()
10971 + *     Lock the lock.
10972 + */
10973 +static inline void __raw_spin_lock(raw_spinlock_t *x)
10974 +{
10975 +       asm volatile (
10976 +       "1:     bset    %0, %0, #0      \n\t"
10977 +       "       jmpne.f 1b              \n\t"
10978 +               : "+U4" (x->lock)
10979 +               :
10980 +               : "memory", "cc"
10981 +       );
10982 +}
10983 +
10984 +/*
10985 + * __raw_spin_unlock()
10986 + *     Unlock the lock.
10987 + */
10988 +static inline void __raw_spin_unlock(raw_spinlock_t *x)
10989 +{
10990 +       asm volatile (
10991 +       "       bclr    %0, %0, #0      \n\t"
10992 +               : "+U4" (x->lock)
10993 +               :
10994 +               : "memory", "cc"
10995 +       );
10996 +}
10997 +
10998 +/*
10999 + * __raw_spin_is_locked()
11000 + *     Test if the lock is locked.
11001 + */
11002 +static inline int __raw_spin_is_locked(raw_spinlock_t *x)
11003 +{
11004 +       return x->lock;
11005 +}
11006 +
11007 +/*
11008 + * __raw_spin_unlock_wait()
11009 + *     Wait for the lock to be unlocked.
11010 + *
11011 + * Note: the caller has not guarantee that the lock will not
11012 + * be acquired before they get to it.
11013 + */
11014 +static inline void __raw_spin_unlock_wait(raw_spinlock_t *x)
11015 +{
11016 +       do { 
11017 +               cpu_relax(); 
11018 +       } while (__raw_spin_is_locked(x));
11019 +}
11020 +
11021 +/*
11022 + * __raw_spin_trylock()
11023 + *     Try the lock, return 0 on failure, 1 on success.
11024 + */
11025 +static inline int __raw_spin_trylock(raw_spinlock_t *x)
11026 +{
11027 +       int ret = 0;
11028 +
11029 +       asm volatile (
11030 +       "       bset    %1, %1, #0      \n\t"
11031 +       "       jmpne.f 1f              \n\t"
11032 +       "       move.4  %0, #1          \n\t"
11033 +       "1:                             \n\t"
11034 +               : "+r" (ret), "+U4" (x->lock)
11035 +               :
11036 +               : "memory", "cc"
11037 +       );
11038 +
11039 +       return ret;
11040 +}
11041 +
11042 +/*
11043 + * __raw_spin_lock_flags()
11044 + *     Spin waiting for the lock (enabling IRQ(s))
11045 + */
11046 +static inline void __raw_spin_lock_flags(raw_spinlock_t *x, unsigned long flags)
11047 +{
11048 +       mb();
11049 +       while (!__raw_spin_trylock(x)) {
11050 +               /*
11051 +                * If the flags from the IRQ are set, interrupts are disabled and we 
11052 +                * need to re-enable them.
11053 +                */
11054 +               if (!flags) {
11055 +                       cpu_relax();
11056 +               } else {
11057 +                       raw_local_irq_enable();
11058 +                       cpu_relax();
11059 +                       raw_local_irq_disable();
11060 +               }
11061 +       }
11062 +       mb();
11063 +}
11064 +
11065 +/*
11066 + * Read-write spinlocks, allowing multiple readers but only one writer.
11067 + * Linux rwlocks are unfair to writers; they can be starved for an indefinite
11068 + * time by readers.  With care, they can also be taken in interrupt context.
11069 + *
11070 + * In Ubicom32 architecture implementation, we have a spinlock and a counter.
11071 + * Readers use the lock to serialise their access to the counter (which
11072 + * records how many readers currently hold the lock).
11073 + * Writers hold the spinlock, preventing any readers or other writers from
11074 + * grabbing the rwlock.
11075 + */
11076 +
11077 +/*
11078 + * __raw_read_lock()
11079 + *     Increment the counter in the rwlock.
11080 + *
11081 + * Note that we have to ensure interrupts are disabled in case we're
11082 + * interrupted by some other code that wants to grab the same read lock 
11083 + */
11084 +static inline void __raw_read_lock(raw_rwlock_t *rw)
11085 +{
11086 +       unsigned long flags;
11087 +       raw_local_irq_save(flags);
11088 +       __raw_spin_lock_flags(&rw->lock, flags);
11089 +       rw->counter++;
11090 +       __raw_spin_unlock(&rw->lock);
11091 +       raw_local_irq_restore(flags);
11092 +}
11093 +
11094 +/*
11095 + * __raw_read_unlock()
11096 + *     Decrement the counter.
11097 + *
11098 + * Note that we have to ensure interrupts are disabled in case we're
11099 + * interrupted by some other code that wants to grab the same read lock 
11100 + */
11101 +static inline void __raw_read_unlock(raw_rwlock_t *rw)
11102 +{
11103 +       unsigned long flags;
11104 +       raw_local_irq_save(flags);
11105 +       __raw_spin_lock_flags(&rw->lock, flags);
11106 +       rw->counter--;
11107 +       __raw_spin_unlock(&rw->lock);
11108 +       raw_local_irq_restore(flags);
11109 +}
11110 +
11111 +/* 
11112 + * __raw_read_trylock()
11113 + *     Increment the counter if we can.
11114 + *
11115 + * Note that we have to ensure interrupts are disabled in case we're
11116 + * interrupted by some other code that wants to grab the same read lock 
11117 + */
11118 +static inline int __raw_read_trylock(raw_rwlock_t *rw)
11119 +{
11120 +       unsigned long flags;
11121 + retry:
11122 +       raw_local_irq_save(flags);
11123 +       if (__raw_spin_trylock(&rw->lock)) {
11124 +               rw->counter++;
11125 +               __raw_spin_unlock(&rw->lock);
11126 +               raw_local_irq_restore(flags);
11127 +               return 1;
11128 +       }
11129 +
11130 +       raw_local_irq_restore(flags);
11131 +
11132 +       /* 
11133 +        * If write-locked, we fail to acquire the lock 
11134 +        */
11135 +       if (rw->counter < 0) {
11136 +               return 0;
11137 +       }
11138 +
11139 +       /* 
11140 +        * Wait until we have a realistic chance at the lock 
11141 +        */
11142 +       while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0) {
11143 +               cpu_relax();
11144 +       }
11145 +
11146 +       goto retry;
11147 +}
11148 +
11149 +/*
11150 + * __raw_write_lock()
11151 + *     
11152 + * Note that we have to ensure interrupts are disabled in case we're
11153 + * interrupted by some other code that wants to read_trylock() this lock 
11154 + */
11155 +static inline void __raw_write_lock(raw_rwlock_t *rw)
11156 +{
11157 +       unsigned long flags;
11158 +retry:
11159 +       raw_local_irq_save(flags);
11160 +       __raw_spin_lock_flags(&rw->lock, flags);
11161 +
11162 +       if (rw->counter != 0) {
11163 +               __raw_spin_unlock(&rw->lock);
11164 +               raw_local_irq_restore(flags);
11165 +
11166 +               while (rw->counter != 0)
11167 +                       cpu_relax();
11168 +
11169 +               goto retry;
11170 +       }
11171 +
11172 +       rw->counter = -1; /* mark as write-locked */
11173 +       mb();
11174 +       raw_local_irq_restore(flags);
11175 +}
11176 +
11177 +static inline void __raw_write_unlock(raw_rwlock_t *rw)
11178 +{
11179 +       rw->counter = 0;
11180 +       __raw_spin_unlock(&rw->lock);
11181 +}
11182 +
11183 +/* Note that we have to ensure interrupts are disabled in case we're
11184 + * interrupted by some other code that wants to read_trylock() this lock */
11185 +static inline int __raw_write_trylock(raw_rwlock_t *rw)
11186 +{
11187 +       unsigned long flags;
11188 +       int result = 0;
11189 +
11190 +       raw_local_irq_save(flags);
11191 +       if (__raw_spin_trylock(&rw->lock)) {
11192 +               if (rw->counter == 0) {
11193 +                       rw->counter = -1;
11194 +                       result = 1;
11195 +               } else {
11196 +                       /* Read-locked.  Oh well. */
11197 +                       __raw_spin_unlock(&rw->lock);
11198 +               }
11199 +       }
11200 +       raw_local_irq_restore(flags);
11201 +
11202 +       return result;
11203 +}
11204 +
11205 +/*
11206 + * read_can_lock - would read_trylock() succeed?
11207 + * @lock: the rwlock in question.
11208 + */
11209 +static inline int __raw_read_can_lock(raw_rwlock_t *rw)
11210 +{
11211 +       return rw->counter >= 0;
11212 +}
11213 +
11214 +/*
11215 + * write_can_lock - would write_trylock() succeed?
11216 + * @lock: the rwlock in question.
11217 + */
11218 +static inline int __raw_write_can_lock(raw_rwlock_t *rw)
11219 +{
11220 +       return !rw->counter;
11221 +}
11222 +
11223 +#define _raw_spin_relax(lock)  cpu_relax()
11224 +#define _raw_read_relax(lock)  cpu_relax()
11225 +#define _raw_write_relax(lock) cpu_relax()
11226 +
11227 +#endif /* _ASM_UBICOM32_SPINLOCK_H */
11228 --- /dev/null
11229 +++ b/arch/ubicom32/include/asm/spinlock_types.h
11230 @@ -0,0 +1,43 @@
11231 +/*
11232 + * arch/ubicom32/include/asm/spinlock_types.h
11233 + *   Spinlock related structure definitions for Ubicom32 architecture.
11234 + *
11235 + * (C) Copyright 2009, Ubicom, Inc.
11236 + *
11237 + * This file is part of the Ubicom32 Linux Kernel Port.
11238 + *
11239 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11240 + * it and/or modify it under the terms of the GNU General Public License
11241 + * as published by the Free Software Foundation, either version 2 of the
11242 + * License, or (at your option) any later version.
11243 + *
11244 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11245 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11246 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11247 + * the GNU General Public License for more details.
11248 + *
11249 + * You should have received a copy of the GNU General Public License
11250 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11251 + * see <http://www.gnu.org/licenses/>.
11252 + *
11253 + * Ubicom32 implementation derived from (with many thanks):
11254 + *   arch/m68knommu
11255 + *   arch/blackfin
11256 + *   arch/parisc
11257 + */
11258 +#ifndef _ASM_UBICOM32_SPINLOCK_TYPES_H
11259 +#define _ASM_UBICOM32_SPINLOCK_TYPES_H
11260 +
11261 +typedef struct {
11262 +       volatile unsigned int lock;
11263 +} raw_spinlock_t;
11264 +
11265 +typedef struct {
11266 +       raw_spinlock_t lock;
11267 +       volatile int counter;
11268 +} raw_rwlock_t;
11269 +
11270 +#define __RAW_SPIN_LOCK_UNLOCKED       { 0 }
11271 +#define __RAW_RW_LOCK_UNLOCKED         { __RAW_SPIN_LOCK_UNLOCKED, 0 }
11272 +
11273 +#endif /* _ASM_UBICOM32_SPINLOCK_TYPES_H */
11274 --- /dev/null
11275 +++ b/arch/ubicom32/include/asm/stacktrace.h
11276 @@ -0,0 +1,72 @@
11277 +/*
11278 + * arch/ubicom32/include/asm/stacktrace.h
11279 + *   Stacktrace functions for the Ubicom32 architecture.
11280 + *
11281 + * (C) Copyright 2009, Ubicom, Inc.
11282 + *
11283 + * This file is part of the Ubicom32 Linux Kernel Port.
11284 + *
11285 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11286 + * it and/or modify it under the terms of the GNU General Public License
11287 + * as published by the Free Software Foundation, either version 2 of the
11288 + * License, or (at your option) any later version.
11289 + *
11290 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11291 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11292 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11293 + * the GNU General Public License for more details.
11294 + *
11295 + * You should have received a copy of the GNU General Public License
11296 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11297 + * see <http://www.gnu.org/licenses/>.
11298 + *
11299 + * Ubicom32 implementation derived from (with many thanks):
11300 + *   arch/m68knommu
11301 + *   arch/blackfin
11302 + *   arch/parisc
11303 + */
11304 +#ifndef _ASM_UBICOM32_STACKTRACE_H
11305 +#define _ASM_UBICOM32_STACKTRACE_H
11306 +
11307 +#define between(a, b, c)       (( \
11308 +                       ((unsigned long) a) >= ((unsigned long) b)) && \
11309 +                       (((unsigned long)a) <= ((unsigned long)c)))
11310 +
11311 +/*
11312 + * These symbols are filled in by the linker.
11313 + */
11314 +extern unsigned long _stext;
11315 +extern unsigned long _etext;
11316 +
11317 +/* OCM text goes from __ocm_text_run_begin to __data_begin */
11318 +extern unsigned long __ocm_text_run_begin;
11319 +extern unsigned long __data_begin;
11320 +
11321 +/* Account for OCM case - see stacktrace.c maybe combine(also trap.c) */
11322 +/*
11323 + * ubicom32_is_kernel()
11324 + *
11325 + *     Check to see if the given address belongs to the kernel.
11326 + * NOMMU does not permit any other means.
11327 + */
11328 +static inline int ubicom32_is_kernel(unsigned long addr)
11329 +{
11330 +       int is_kernel = between(addr, &_stext, &_etext) || \
11331 +                       between(addr, &__ocm_text_run_begin, &__data_begin);
11332 +
11333 +#ifdef CONFIG_MODULES
11334 +       if (!is_kernel)
11335 +               is_kernel = is_module_address(addr);
11336 +#endif
11337 +       return is_kernel;
11338 +}
11339 +
11340 +extern unsigned long stacktrace_iterate(
11341 +                               unsigned long **trace, 
11342 +                               unsigned long stext, unsigned long etext,
11343 +                               unsigned long ocm_stext, unsigned long ocm_etext, 
11344 +                               unsigned long sstack, unsigned long estack);
11345 +#ifdef CONFIG_STACKTRACE
11346 +void stacktrace_save_entries(struct task_struct *tsk, struct stack_trace *trace, unsigned long sp);
11347 +#endif
11348 +#endif /* _ASM_UBICOM32_STACKTRACE_H */
11349 --- /dev/null
11350 +++ b/arch/ubicom32/include/asm/statfs.h
11351 @@ -0,0 +1,33 @@
11352 +/*
11353 + * arch/ubicom32/include/asm/statfs.h
11354 + *   Generic statfs.h definitions
11355 + *
11356 + * (C) Copyright 2009, Ubicom, Inc.
11357 + *
11358 + * This file is part of the Ubicom32 Linux Kernel Port.
11359 + *
11360 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11361 + * it and/or modify it under the terms of the GNU General Public License
11362 + * as published by the Free Software Foundation, either version 2 of the
11363 + * License, or (at your option) any later version.
11364 + *
11365 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11366 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11367 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11368 + * the GNU General Public License for more details.
11369 + *
11370 + * You should have received a copy of the GNU General Public License
11371 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11372 + * see <http://www.gnu.org/licenses/>.
11373 + *
11374 + * Ubicom32 implementation derived from (with many thanks):
11375 + *   arch/m68knommu
11376 + *   arch/blackfin
11377 + *   arch/parisc
11378 + */
11379 +#ifndef _ASM_UBICOM32_STATFS_H
11380 +#define _ASM_UBICOM32_STATFS_H
11381 +
11382 +#include <asm-generic/statfs.h>
11383 +
11384 +#endif /* _ASM_UBICOM32_STATFS_H */
11385 --- /dev/null
11386 +++ b/arch/ubicom32/include/asm/stat.h
11387 @@ -0,0 +1,104 @@
11388 +/*
11389 + * arch/ubicom32/include/asm/stat.h
11390 + *   File status definitions for Ubicom32 architecture.
11391 + *
11392 + * (C) Copyright 2009, Ubicom, Inc.
11393 + *
11394 + * This file is part of the Ubicom32 Linux Kernel Port.
11395 + *
11396 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11397 + * it and/or modify it under the terms of the GNU General Public License
11398 + * as published by the Free Software Foundation, either version 2 of the
11399 + * License, or (at your option) any later version.
11400 + *
11401 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11402 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11403 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11404 + * the GNU General Public License for more details.
11405 + *
11406 + * You should have received a copy of the GNU General Public License
11407 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11408 + * see <http://www.gnu.org/licenses/>.
11409 + *
11410 + * Ubicom32 implementation derived from (with many thanks):
11411 + *   arch/m68knommu
11412 + *   arch/blackfin
11413 + *   arch/parisc
11414 + */
11415 +#ifndef _ASM_UBICOM32_STAT_H
11416 +#define _ASM_UBICOM32_STAT_H
11417 +
11418 +struct __old_kernel_stat {
11419 +       unsigned short st_dev;
11420 +       unsigned short st_ino;
11421 +       unsigned short st_mode;
11422 +       unsigned short st_nlink;
11423 +       unsigned short st_uid;
11424 +       unsigned short st_gid;
11425 +       unsigned short st_rdev;
11426 +       unsigned long  st_size;
11427 +       unsigned long  st_atime;
11428 +       unsigned long  st_mtime;
11429 +       unsigned long  st_ctime;
11430 +};
11431 +
11432 +struct stat {
11433 +       unsigned short st_dev;
11434 +       unsigned short __pad1;
11435 +       unsigned long  st_ino;
11436 +       unsigned short st_mode;
11437 +       unsigned short st_nlink;
11438 +       unsigned short st_uid;
11439 +       unsigned short st_gid;
11440 +       unsigned short st_rdev;
11441 +       unsigned short __pad2;
11442 +       unsigned long  st_size;
11443 +       unsigned long  st_blksize;
11444 +       unsigned long  st_blocks;
11445 +       unsigned long  st_atime;
11446 +       unsigned long  __unused1;
11447 +       unsigned long  st_mtime;
11448 +       unsigned long  __unused2;
11449 +       unsigned long  st_ctime;
11450 +       unsigned long  __unused3;
11451 +       unsigned long  __unused4;
11452 +       unsigned long  __unused5;
11453 +};
11454 +
11455 +/* This matches struct stat64 in glibc2.1, hence the absolutely
11456 + * insane amounts of padding around dev_t's.
11457 + */
11458 +struct stat64 {
11459 +       unsigned long long      st_dev;
11460 +       unsigned char   __pad1[2];
11461 +
11462 +#define STAT64_HAS_BROKEN_ST_INO       1
11463 +       unsigned long   __st_ino;
11464 +
11465 +       unsigned int    st_mode;
11466 +       unsigned int    st_nlink;
11467 +
11468 +       unsigned long   st_uid;
11469 +       unsigned long   st_gid;
11470 +
11471 +       unsigned long long      st_rdev;
11472 +       unsigned char   __pad3[2];
11473 +
11474 +       long long       st_size;
11475 +       unsigned long   st_blksize;
11476 +
11477 +       unsigned long long      st_blocks;      /* Number 512-byte blocks allocated. */
11478 +
11479 +       unsigned long   st_atime;
11480 +       unsigned long   st_atime_nsec;
11481 +
11482 +       unsigned long   st_mtime;
11483 +       unsigned long   st_mtime_nsec;
11484 +
11485 +       unsigned long   st_ctime;
11486 +       unsigned long   st_ctime_nsec;
11487 +
11488 +       unsigned long long      st_ino;
11489 +};
11490 +
11491 +#endif /* _ASM_UBICOM32_STAT_H */
11492 --- /dev/null
11493 +++ b/arch/ubicom32/include/asm/string.h
11494 @@ -0,0 +1,37 @@
11495 +/*
11496 + * arch/ubicom32/include/asm/string.h
11497 + *   String operation definitions for Ubicom32 architecture.
11498 + *
11499 + * (C) Copyright 2009, Ubicom, Inc.
11500 + *
11501 + * This file is part of the Ubicom32 Linux Kernel Port.
11502 + *
11503 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11504 + * it and/or modify it under the terms of the GNU General Public License
11505 + * as published by the Free Software Foundation, either version 2 of the
11506 + * License, or (at your option) any later version.
11507 + *
11508 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11509 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11510 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11511 + * the GNU General Public License for more details.
11512 + *
11513 + * You should have received a copy of the GNU General Public License
11514 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11515 + * see <http://www.gnu.org/licenses/>.
11516 + *
11517 + * Ubicom32 implementation derived from (with many thanks):
11518 + *   arch/m68knommu
11519 + *   arch/blackfin
11520 + *   arch/parisc
11521 + */
11522 +#ifndef _ASM_UBICOM32_STRING_H
11523 +#define _ASM_UBICOM32_STRING_H
11524 +
11525 +#define __HAVE_ARCH_MEMSET
11526 +extern void *memset(void *b, int c, size_t len);
11527 +
11528 +#define __HAVE_ARCH_MEMCPY
11529 +extern void *memcpy(void *to, const void *from, size_t len);
11530 +
11531 +#endif /* _ASM_UBICOM32_STRING_H */
11532 --- /dev/null
11533 +++ b/arch/ubicom32/include/asm/switch-bcm539x.h
11534 @@ -0,0 +1,57 @@
11535 +/*
11536 + * arch/ubicom32/include/asm/switch-bcm539x.h
11537 + *   Broadcom bcm539x platform data definitions for Ubicom32 architecture.
11538 + *
11539 + * (C) Copyright 2009, Ubicom, Inc.
11540 + *
11541 + * This file is part of the Ubicom32 Linux Kernel Port.
11542 + *
11543 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11544 + * it and/or modify it under the terms of the GNU General Public License
11545 + * as published by the Free Software Foundation, either version 2 of the
11546 + * License, or (at your option) any later version.
11547 + *
11548 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11549 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11550 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11551 + * the GNU General Public License for more details.
11552 + *
11553 + * You should have received a copy of the GNU General Public License
11554 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11555 + * see <http://www.gnu.org/licenses/>.
11556 + *
11557 + * Ubicom32 implementation derived from (with many thanks):
11558 + *   arch/m68knommu
11559 + *   arch/blackfin
11560 + *   arch/parisc
11561 + */
11562 +#ifndef _ASM_UBICOM32_SWITCH_BCM539X_H
11563 +#define _ASM_UBICOM32_SWITCH_BCM539X_H
11564 +
11565 +#define SWITCH_BCM539X_FLAG_HW_RESET   0x01
11566 +#define SWITCH_BCM539X_FLAG_SW_RESET   0x02
11567 +
11568 +struct switch_bcm539x_platform_data {
11569 +       /*
11570 +        * See flags above
11571 +        */
11572 +       u32_t           flags;
11573 +
11574 +       /*
11575 +        * GPIO to use for nReset
11576 +        */
11577 +       int             pin_reset;
11578 +
11579 +
11580 +       /*
11581 +        * GPIO to use for chip select
11582 +        */
11583 +       int             pin_cs;
11584 +
11585 +       /*
11586 +        * Name of this switch
11587 +        */
11588 +       const char      *name;
11589 +};
11590 +
11591 +#endif /* _ASM_UBICOM32_SWITCH_BCM539X_H */
11592 --- /dev/null
11593 +++ b/arch/ubicom32/include/asm/system.h
11594 @@ -0,0 +1,101 @@
11595 +/*
11596 + * arch/ubicom32/include/asm/system.h
11597 + *   Low level switching definitions.
11598 + *
11599 + * (C) Copyright 2009, Ubicom, Inc.
11600 + *
11601 + * This file is part of the Ubicom32 Linux Kernel Port.
11602 + *
11603 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11604 + * it and/or modify it under the terms of the GNU General Public License
11605 + * as published by the Free Software Foundation, either version 2 of the
11606 + * License, or (at your option) any later version.
11607 + *
11608 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11609 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11610 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11611 + * the GNU General Public License for more details.
11612 + *
11613 + * You should have received a copy of the GNU General Public License
11614 + * along with the Ubicom32 Linux Kernel Port.  If not,
11615 + * see <http://www.gnu.org/licenses/>.
11616 + *
11617 + * Ubicom32 implementation derived from (with many thanks):
11618 + *   arch/m68knommu
11619 + *   arch/blackfin
11620 + *   arch/parisc
11621 + */
11622 +#ifndef _ASM_UBICOM32_SYSTEM_H
11623 +#define _ASM_UBICOM32_SYSTEM_H
11624 +
11625 +#include <linux/irqflags.h>
11626 +#include <linux/linkage.h>
11627 +#include <asm/segment.h>
11628 +#include <asm/entry.h>
11629 +#include <asm/ldsr.h>
11630 +#include <asm/irq.h>
11631 +#include <asm/percpu.h>
11632 +#include <asm/ubicom32-common.h>
11633 +#include <asm/processor.h>
11634 +
11635 +/*
11636 + * switch_to(n) should switch tasks to task ptr, first checking that
11637 + * ptr isn't the current task, in which case it does nothing.
11638 + */
11639 +asmlinkage void resume(void);
11640 +extern void *__switch_to(struct task_struct *prev,
11641 +               struct thread_struct *prev_switch,
11642 +               struct thread_struct *next_switch);
11643 +
11644 +/*
11645 + * We will need a per linux thread sw_ksp for the switch_to macro to
11646 + * track the kernel stack pointer for the current thread on that linux thread.
11647 + */
11648 +#define switch_to(prev,next,last)                                      \
11649 +({                                                                     \
11650 +       void *_last;                                                    \
11651 +       _last = (void *)                                                \
11652 +               __switch_to(prev, &prev->thread, &next->thread);        \
11653 +       (last) = _last;                                                 \
11654 +})
11655 +
11656 +/*
11657 + * Force strict CPU ordering.
11658 + * Not really required on ubicom32...
11659 + */
11660 +#define nop()  asm volatile ("nop"::)
11661 +#define mb()   asm volatile (""   : : :"memory")
11662 +#define rmb()  asm volatile (""   : : :"memory")
11663 +#define wmb()  asm volatile (""   : : :"memory")
11664 +#define set_mb(var, value)     ({ (var) = (value); wmb(); })
11665 +
11666 +#ifdef CONFIG_SMP
11667 +#define smp_mb()       mb()
11668 +#define smp_rmb()      rmb()
11669 +#define smp_wmb()      wmb()
11670 +#define smp_read_barrier_depends()     read_barrier_depends()
11671 +#else
11672 +#define smp_mb()       mb()
11673 +#define smp_rmb()      rmb()
11674 +#define smp_wmb()      wmb()
11675 +#define smp_read_barrier_depends()     do { } while(0)
11676 +#endif
11677 +
11678 +#define read_barrier_depends()  ((void)0)
11679 +
11680 +/*
11681 + * The following defines change how the scheduler calls the switch_to()
11682 + * macro.
11683 + *
11684 + * 1) The first causes the runqueue to be unlocked on entry to
11685 + * switch_to().  Since our ctx code does not play with the runqueue
11686 + * we do not need it unlocked.
11687 + *
11688 + * 2) The later turns interrupts on during a ctxsw to reduce the latency of
11689 + * interrupts during ctx.  At this point in the port, we believe that this
11690 + * latency is not a problem since we have very little code to perform a ctxsw.
11691 + */
11692 +// #define __ARCH_WANT_UNLOCKED_CTXSW
11693 +// #define __ARCH_WANT_INTERRUPTS_ON_CTXSW
11694 +
11695 +#endif /* _ASM_UBICOM32_SYSTEM_H */
11696 --- /dev/null
11697 +++ b/arch/ubicom32/include/asm/termbits.h
11698 @@ -0,0 +1,227 @@
11699 +/*
11700 + * arch/ubicom32/include/asm/termbits.h
11701 + *   Terminal/serial port definitions for Ubicom32 architecture.
11702 + *
11703 + * (C) Copyright 2009, Ubicom, Inc.
11704 + *
11705 + * This file is part of the Ubicom32 Linux Kernel Port.
11706 + *
11707 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11708 + * it and/or modify it under the terms of the GNU General Public License
11709 + * as published by the Free Software Foundation, either version 2 of the
11710 + * License, or (at your option) any later version.
11711 + *
11712 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11713 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11714 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11715 + * the GNU General Public License for more details.
11716 + *
11717 + * You should have received a copy of the GNU General Public License
11718 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11719 + * see <http://www.gnu.org/licenses/>.
11720 + *
11721 + * Ubicom32 implementation derived from (with many thanks):
11722 + *   arch/m68knommu
11723 + *   arch/blackfin
11724 + *   arch/parisc
11725 + */
11726 +#ifndef _ASM_UBICOM32_TERMBITS_H
11727 +#define _ASM_UBICOM32_TERMBITS_H
11728 +
11729 +#include <linux/posix_types.h>
11730 +
11731 +typedef unsigned char  cc_t;
11732 +typedef unsigned int   speed_t;
11733 +typedef unsigned int   tcflag_t;
11734 +
11735 +#define NCCS 19
11736 +struct termios {
11737 +       tcflag_t c_iflag;               /* input mode flags */
11738 +       tcflag_t c_oflag;               /* output mode flags */
11739 +       tcflag_t c_cflag;               /* control mode flags */
11740 +       tcflag_t c_lflag;               /* local mode flags */
11741 +       cc_t c_line;                    /* line discipline */
11742 +       cc_t c_cc[NCCS];                /* control characters */
11743 +};
11744 +
11745 +struct termios2 {
11746 +       tcflag_t c_iflag;               /* input mode flags */
11747 +       tcflag_t c_oflag;               /* output mode flags */
11748 +       tcflag_t c_cflag;               /* control mode flags */
11749 +       tcflag_t c_lflag;               /* local mode flags */
11750 +       cc_t c_line;                    /* line discipline */
11751 +       cc_t c_cc[NCCS];                /* control characters */
11752 +       speed_t c_ispeed;               /* input speed */
11753 +       speed_t c_ospeed;               /* output speed */
11754 +};
11755 +
11756 +struct ktermios {
11757 +       tcflag_t c_iflag;               /* input mode flags */
11758 +       tcflag_t c_oflag;               /* output mode flags */
11759 +       tcflag_t c_cflag;               /* control mode flags */
11760 +       tcflag_t c_lflag;               /* local mode flags */
11761 +       cc_t c_line;                    /* line discipline */
11762 +       cc_t c_cc[NCCS];                /* control characters */
11763 +       speed_t c_ispeed;               /* input speed */
11764 +       speed_t c_ospeed;               /* output speed */
11765 +};
11766 +
11767 +/* c_cc characters */
11768 +#define VINTR 0
11769 +#define VQUIT 1
11770 +#define VERASE 2
11771 +#define VKILL 3
11772 +#define VEOF 4
11773 +#define VTIME 5
11774 +#define VMIN 6
11775 +#define VSWTC 7
11776 +#define VSTART 8
11777 +#define VSTOP 9
11778 +#define VSUSP 10
11779 +#define VEOL 11
11780 +#define VREPRINT 12
11781 +#define VDISCARD 13
11782 +#define VWERASE 14
11783 +#define VLNEXT 15
11784 +#define VEOL2 16
11785 +
11786 +
11787 +/* c_iflag bits */
11788 +#define IGNBRK 0000001
11789 +#define BRKINT 0000002
11790 +#define IGNPAR 0000004
11791 +#define PARMRK 0000010
11792 +#define INPCK  0000020
11793 +#define ISTRIP 0000040
11794 +#define INLCR  0000100
11795 +#define IGNCR  0000200
11796 +#define ICRNL  0000400
11797 +#define IUCLC  0001000
11798 +#define IXON   0002000
11799 +#define IXANY  0004000
11800 +#define IXOFF  0010000
11801 +#define IMAXBEL        0020000
11802 +#define IUTF8  0040000
11803 +
11804 +/* c_oflag bits */
11805 +#define OPOST  0000001
11806 +#define OLCUC  0000002
11807 +#define ONLCR  0000004
11808 +#define OCRNL  0000010
11809 +#define ONOCR  0000020
11810 +#define ONLRET 0000040
11811 +#define OFILL  0000100
11812 +#define OFDEL  0000200
11813 +#define NLDLY  0000400
11814 +#define   NL0  0000000
11815 +#define   NL1  0000400
11816 +#define CRDLY  0003000
11817 +#define   CR0  0000000
11818 +#define   CR1  0001000
11819 +#define   CR2  0002000
11820 +#define   CR3  0003000
11821 +#define TABDLY 0014000
11822 +#define   TAB0 0000000
11823 +#define   TAB1 0004000
11824 +#define   TAB2 0010000
11825 +#define   TAB3 0014000
11826 +#define   XTABS        0014000
11827 +#define BSDLY  0020000
11828 +#define   BS0  0000000
11829 +#define   BS1  0020000
11830 +#define VTDLY  0040000
11831 +#define   VT0  0000000
11832 +#define   VT1  0040000
11833 +#define FFDLY  0100000
11834 +#define   FF0  0000000
11835 +#define   FF1  0100000
11836 +
11837 +/* c_cflag bit meaning */
11838 +#define CBAUD  0010017
11839 +#define  B0    0000000         /* hang up */
11840 +#define  B50   0000001
11841 +#define  B75   0000002
11842 +#define  B110  0000003
11843 +#define  B134  0000004
11844 +#define  B150  0000005
11845 +#define  B200  0000006
11846 +#define  B300  0000007
11847 +#define  B600  0000010
11848 +#define  B1200 0000011
11849 +#define  B1800 0000012
11850 +#define  B2400 0000013
11851 +#define  B4800 0000014
11852 +#define  B9600 0000015
11853 +#define  B19200        0000016
11854 +#define  B38400        0000017
11855 +#define EXTA B19200
11856 +#define EXTB B38400
11857 +#define CSIZE  0000060
11858 +#define   CS5  0000000
11859 +#define   CS6  0000020
11860 +#define   CS7  0000040
11861 +#define   CS8  0000060
11862 +#define CSTOPB 0000100
11863 +#define CREAD  0000200
11864 +#define PARENB 0000400
11865 +#define PARODD 0001000
11866 +#define HUPCL  0002000
11867 +#define CLOCAL 0004000
11868 +#define CBAUDEX 0010000
11869 +#define    BOTHER 0010000
11870 +#define    B57600 0010001
11871 +#define   B115200 0010002
11872 +#define   B230400 0010003
11873 +#define   B460800 0010004
11874 +#define   B500000 0010005
11875 +#define   B576000 0010006
11876 +#define   B921600 0010007
11877 +#define  B1000000 0010010
11878 +#define  B1152000 0010011
11879 +#define  B1500000 0010012
11880 +#define  B2000000 0010013
11881 +#define  B2500000 0010014
11882 +#define  B3000000 0010015
11883 +#define  B3500000 0010016
11884 +#define  B4000000 0010017
11885 +#define CIBAUD   002003600000          /* input baud rate */
11886 +#define CMSPAR   010000000000          /* mark or space (stick) parity */
11887 +#define CRTSCTS          020000000000          /* flow control */
11888 +
11889 +#define IBSHIFT        16                      /* Shift from CBAUD to CIBAUD */
11890 +
11891 +/* c_lflag bits */
11892 +#define ISIG   0000001
11893 +#define ICANON 0000002
11894 +#define XCASE  0000004
11895 +#define ECHO   0000010
11896 +#define ECHOE  0000020
11897 +#define ECHOK  0000040
11898 +#define ECHONL 0000100
11899 +#define NOFLSH 0000200
11900 +#define TOSTOP 0000400
11901 +#define ECHOCTL        0001000
11902 +#define ECHOPRT        0002000
11903 +#define ECHOKE 0004000
11904 +#define FLUSHO 0010000
11905 +#define PENDIN 0040000
11906 +#define IEXTEN 0100000
11907 +
11908 +
11909 +/* tcflow() and TCXONC use these */
11910 +#define        TCOOFF          0
11911 +#define        TCOON           1
11912 +#define        TCIOFF          2
11913 +#define        TCION           3
11914 +
11915 +/* tcflush() and TCFLSH use these */
11916 +#define        TCIFLUSH        0
11917 +#define        TCOFLUSH        1
11918 +#define        TCIOFLUSH       2
11919 +
11920 +/* tcsetattr uses these */
11921 +#define        TCSANOW         0
11922 +#define        TCSADRAIN       1
11923 +#define        TCSAFLUSH       2
11924 +
11925 +#endif /* _ASM_UBICOM32_TERMBITS_H */
11926 --- /dev/null
11927 +++ b/arch/ubicom32/include/asm/termios.h
11928 @@ -0,0 +1,119 @@
11929 +/*
11930 + * arch/ubicom32/include/asm/termios.h
11931 + *   Ubicom32 termio definitions.
11932 + *
11933 + * (C) Copyright 2009, Ubicom, Inc.
11934 + *
11935 + * This file is part of the Ubicom32 Linux Kernel Port.
11936 + *
11937 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11938 + * it and/or modify it under the terms of the GNU General Public License
11939 + * as published by the Free Software Foundation, either version 2 of the
11940 + * License, or (at your option) any later version.
11941 + *
11942 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11943 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11944 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11945 + * the GNU General Public License for more details.
11946 + *
11947 + * You should have received a copy of the GNU General Public License
11948 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11949 + * see <http://www.gnu.org/licenses/>.
11950 + *
11951 + * Ubicom32 implementation derived from (with many thanks):
11952 + *   arch/m68knommu
11953 + *   arch/blackfin
11954 + *   arch/parisc
11955 + */
11956 +#ifndef _ASM_UBICOM32_TERMIOS_H
11957 +#define _ASM_UBICOM32_TERMIOS_H
11958 +
11959 +#include <asm/termbits.h>
11960 +#include <asm/ioctls.h>
11961 +
11962 +struct winsize {
11963 +       unsigned short ws_row;
11964 +       unsigned short ws_col;
11965 +       unsigned short ws_xpixel;
11966 +       unsigned short ws_ypixel;
11967 +};
11968 +
11969 +#define NCC 8
11970 +struct termio {
11971 +       unsigned short c_iflag;         /* input mode flags */
11972 +       unsigned short c_oflag;         /* output mode flags */
11973 +       unsigned short c_cflag;         /* control mode flags */
11974 +       unsigned short c_lflag;         /* local mode flags */
11975 +       unsigned char c_line;           /* line discipline */
11976 +       unsigned char c_cc[NCC];        /* control characters */
11977 +};
11978 +
11979 +#ifdef __KERNEL__
11980 +/*     intr=^C         quit=^|         erase=del       kill=^U
11981 +       eof=^D          vtime=\0        vmin=\1         sxtc=\0
11982 +       start=^Q        stop=^S         susp=^Z         eol=\0
11983 +       reprint=^R      discard=^U      werase=^W       lnext=^V
11984 +       eol2=\0
11985 +*/
11986 +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
11987 +#endif
11988 +
11989 +/* modem lines */
11990 +#define TIOCM_LE       0x001
11991 +#define TIOCM_DTR      0x002
11992 +#define TIOCM_RTS      0x004
11993 +#define TIOCM_ST       0x008
11994 +#define TIOCM_SR       0x010
11995 +#define TIOCM_CTS      0x020
11996 +#define TIOCM_CAR      0x040
11997 +#define TIOCM_RNG      0x080
11998 +#define TIOCM_DSR      0x100
11999 +#define TIOCM_CD       TIOCM_CAR
12000 +#define TIOCM_RI       TIOCM_RNG
12001 +#define TIOCM_OUT1     0x2000
12002 +#define TIOCM_OUT2     0x4000
12003 +#define TIOCM_LOOP     0x8000
12004 +
12005 +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
12006 +
12007 +#ifdef __KERNEL__
12008 +
12009 +/*
12010 + * Translate a "termio" structure into a "termios". Ugh.
12011 + */
12012 +#define user_termio_to_kernel_termios(termios, termio) \
12013 +({ \
12014 +       unsigned short tmp; \
12015 +       get_user(tmp, &(termio)->c_iflag); \
12016 +       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
12017 +       get_user(tmp, &(termio)->c_oflag); \
12018 +       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
12019 +       get_user(tmp, &(termio)->c_cflag); \
12020 +       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
12021 +       get_user(tmp, &(termio)->c_lflag); \
12022 +       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
12023 +       get_user((termios)->c_line, &(termio)->c_line); \
12024 +       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
12025 +})
12026 +
12027 +/*
12028 + * Translate a "termios" structure into a "termio". Ugh.
12029 + */
12030 +#define kernel_termios_to_user_termio(termio, termios) \
12031 +({ \
12032 +       put_user((termios)->c_iflag, &(termio)->c_iflag); \
12033 +       put_user((termios)->c_oflag, &(termio)->c_oflag); \
12034 +       put_user((termios)->c_cflag, &(termio)->c_cflag); \
12035 +       put_user((termios)->c_lflag, &(termio)->c_lflag); \
12036 +       put_user((termios)->c_line,  &(termio)->c_line); \
12037 +       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
12038 +})
12039 +
12040 +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
12041 +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
12042 +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
12043 +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
12044 +
12045 +#endif /* __KERNEL__ */
12046 +
12047 +#endif /* _ASM_UBICOM32_TERMIOS_H */
12048 --- /dev/null
12049 +++ b/arch/ubicom32/include/asm/thread-asm.h
12050 @@ -0,0 +1,49 @@
12051 +/*
12052 + * arch/ubicom32/include/asm/thread-asm.h
12053 + *   Ubicom32 architecture specific thread definitions.
12054 + *
12055 + * (C) Copyright 2009, Ubicom, Inc.
12056 + *
12057 + * This file is part of the Ubicom32 Linux Kernel Port.
12058 + *
12059 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12060 + * it and/or modify it under the terms of the GNU General Public License
12061 + * as published by the Free Software Foundation, either version 2 of the
12062 + * License, or (at your option) any later version.
12063 + *
12064 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12065 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12066 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12067 + * the GNU General Public License for more details.
12068 + *
12069 + * You should have received a copy of the GNU General Public License
12070 + * along with the Ubicom32 Linux Kernel Port.  If not,
12071 + * see <http://www.gnu.org/licenses/>.
12072 + *
12073 + * Ubicom32 implementation derived from (with many thanks):
12074 + *   arch/m68knommu
12075 + *   arch/blackfin
12076 + *   arch/parisc
12077 + */
12078 +#ifndef _ASM_UBICOM32_THREAD_ASM_H
12079 +#define _ASM_UBICOM32_THREAD_ASM_H
12080 +
12081 +/*
12082 + * thread_get_self
12083 + *     Read and shift the current thread into reg
12084 + */
12085 +.macro thread_get_self reg
12086 +       lsr.4   \reg, ROSR, #2
12087 +       and.4   \reg, #31, \reg  /* Mask to get thread number into register */
12088 +.endm
12089 +
12090 +/*
12091 + * thread_get_self_mask
12092 + *     Read and shift the current thread mask into reg
12093 + */
12094 +.macro thread_get_self_mask reg
12095 +       lsr.4   \reg, ROSR, #2
12096 +       lsl.4   \reg, #1, \reg   /* Thread bit */
12097 +.endm
12098 +
12099 +#endif /* _ASM_UBICOM32_THREAD_ASM_H */
12100 --- /dev/null
12101 +++ b/arch/ubicom32/include/asm/thread.h
12102 @@ -0,0 +1,313 @@
12103 +/*
12104 + * arch/ubicom32/include/asm/thread.h
12105 + *   Ubicom32 architecture specific thread definitions.
12106 + *
12107 + * (C) Copyright 2009, Ubicom, Inc.
12108 + *
12109 + * This file is part of the Ubicom32 Linux Kernel Port.
12110 + *
12111 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12112 + * it and/or modify it under the terms of the GNU General Public License
12113 + * as published by the Free Software Foundation, either version 2 of the
12114 + * License, or (at your option) any later version.
12115 + *
12116 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12117 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12118 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12119 + * the GNU General Public License for more details.
12120 + *
12121 + * You should have received a copy of the GNU General Public License
12122 + * along with the Ubicom32 Linux Kernel Port.  If not,
12123 + * see <http://www.gnu.org/licenses/>.
12124 + *
12125 + * Ubicom32 implementation derived from (with many thanks):
12126 + *   arch/m68knommu
12127 + *   arch/blackfin
12128 + *   arch/parisc
12129 + */
12130 +#ifndef _ASM_UBICOM32_THREAD_H
12131 +#define _ASM_UBICOM32_THREAD_H
12132 +
12133 +#if !defined(__ASSEMBLY__)
12134 +
12135 +#include <asm/ptrace.h>
12136 +#include <asm/ubicom32-common.h>
12137 +
12138 +typedef int thread_t;
12139 +typedef unsigned char thread_type_t;
12140 +typedef void (*thread_exec_fn_t)(void *arg);
12141 +
12142 +#define THREAD_NULL 0x40
12143 +#define THREAD_TYPE_HRT (1 << 0)
12144 +#define THREAD_TYPE_SPECIAL 0
12145 +#define THREAD_TYPE_NORMAL 0
12146 +#define THREAD_TYPE_BACKGROUND (1 << 1)
12147 +
12148 +/*
12149 + * This is the upper bound on the maximum hardware threads that one will find
12150 + * on a Ubicom processor. It is used to size per hardware thread data structures.
12151 + */
12152 +#define THREAD_ARCHITECTURAL_MAX 16
12153 +
12154 +/*
12155 + * TODO: Rename this at some point to be thread_
12156 + */
12157 +extern unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
12158 +
12159 +
12160 +/*
12161 + * thread_get_self()
12162 + */
12163 +static inline thread_t thread_get_self(void)
12164 +{
12165 +       thread_t result;
12166 +       asm (
12167 +               "lsr.4  %0, ROSR, #2    \n\t"
12168 +               : "=d" (result)
12169 +               :
12170 +               : "cc"
12171 +       );
12172 +       return result & 31;
12173 +}
12174 +
12175 +/*
12176 + * thread_suspend()
12177 + */
12178 +static inline void thread_suspend(void)
12179 +{
12180 +       asm volatile (
12181 +               "suspend\n\t"
12182 +               :
12183 +               :
12184 +       );
12185 +}
12186 +
12187 +/*
12188 + * thread_resume()
12189 + */
12190 +static inline void thread_resume(thread_t thread)
12191 +{
12192 +       asm volatile (
12193 +               "move.4         MT_ACTIVE_SET, %0       \n\t"
12194 +               "pipe_flush     0                       \n\t"
12195 +               "pipe_flush     0                       \n\t"
12196 +               :
12197 +               : "d" (1 << thread)
12198 +       );
12199 +}
12200 +
12201 +
12202 +
12203 +/*
12204 + * thread_enable_mask()
12205 + *     Enable all threads in the mask.
12206 + *
12207 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12208 + */
12209 +static inline void thread_enable_mask(unsigned int mask)
12210 +{
12211 +       /*
12212 +        * must flush the pipeline twice.
12213 +        * first pipe_flush is to ensure write to MT_EN is completed
12214 +        * second one is to ensure any new instructions from
12215 +        * the targeted thread (the one being disabled), that
12216 +        * are issued while the write to MT_EN is being executed,
12217 +        * are completed.
12218 +        */
12219 +       UBICOM32_LOCK(MT_EN_LOCK_BIT);
12220 +       asm volatile (
12221 +               "or.4           MT_EN, MT_EN, %0        \n\t"
12222 +               "pipe_flush     0                       \n\t"
12223 +               "pipe_flush     0                       \n\t"
12224 +               :
12225 +               : "d" (mask)
12226 +               : "cc"
12227 +       );
12228 +       UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12229 +}
12230 +
12231 +/*
12232 + * thread_enable()
12233 + */
12234 +static inline void thread_enable(thread_t thread)
12235 +{
12236 +       thread_enable_mask(1 << thread);
12237 +}
12238 +
12239 +/*
12240 + * thread_disable_mask()
12241 + *     Disable all threads in the mask.
12242 + *
12243 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12244 + */
12245 +static inline void thread_disable_mask(unsigned int mask)
12246 +{
12247 +       /*
12248 +        * must flush the pipeline twice.
12249 +        * first pipe_flush is to ensure write to MT_EN is completed
12250 +        * second one is to ensure any new instructions from
12251 +        * the targeted thread (the one being disabled), that
12252 +        * are issued while the write to MT_EN is being executed,
12253 +        * are completed.
12254 +        */
12255 +       UBICOM32_LOCK(MT_EN_LOCK_BIT);
12256 +       asm volatile (
12257 +               "and.4          MT_EN, MT_EN, %0        \n\t"
12258 +               "pipe_flush     0                       \n\t"
12259 +               "pipe_flush     0                       \n\t"
12260 +               :
12261 +               : "d" (~mask)
12262 +               : "cc"
12263 +       );
12264 +       UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12265 +}
12266 +
12267 +/*
12268 + * thread_disable()
12269 + */
12270 +static inline void thread_disable(thread_t thread)
12271 +{
12272 +       thread_disable_mask(1 << thread);
12273 +}
12274 +
12275 +/*
12276 + * thread_disable_others()
12277 + *     Disable all other threads
12278 + */
12279 +static inline void thread_disable_others(void)
12280 +{
12281 +       thread_t self = thread_get_self();
12282 +       thread_disable_mask(~(1 << self));
12283 +}
12284 +
12285 +/*
12286 + * thread_is_trapped()
12287 + *     Is the specified tid trapped?
12288 + */
12289 +static inline int thread_is_trapped(thread_t tid)
12290 +{
12291 +       int thread_mask = (1 << tid);
12292 +       int trap_thread;
12293 +
12294 +       asm (
12295 +               "move.4         %0, MT_TRAP             \n\t"
12296 +               : "=d" (trap_thread)
12297 +               :
12298 +       );
12299 +       return (trap_thread & thread_mask);
12300 +}
12301 +
12302 +/*
12303 + * thread_is_enabled()
12304 + *     Is the specified tid enabled?
12305 + */
12306 +static inline int thread_is_enabled(thread_t tid)
12307 +{
12308 +       int thread_mask = (1 << tid);
12309 +       int enabled_threads;
12310 +
12311 +       asm (
12312 +               "move.4         %0, MT_EN               \n\t"
12313 +               : "=d" (enabled_threads)
12314 +               :
12315 +       );
12316 +       return (enabled_threads & thread_mask);
12317 +}
12318 +
12319 +/*
12320 + * thread_get_instruction_count()
12321 + */
12322 +static inline unsigned int thread_get_instruction_count(void)
12323 +{
12324 +       unsigned int result;
12325 +       asm (
12326 +               "move.4         %0, INST_CNT            \n\t"
12327 +               : "=r" (result)
12328 +       );
12329 +       return result;
12330 +}
12331 +
12332 +/*
12333 + * thread_get_pc()
12334 + *     pc could point to a speculative and cancelled instruction unless thread is disabled
12335 + */
12336 +static inline void *thread_get_pc(thread_t thread)
12337 +{
12338 +       void *result;
12339 +       asm (
12340 +               "move.4         csr, %1         \n\t"
12341 +               "setcsr_flush   0               \n\t"
12342 +               "move.4         %0, pc          \n\t"
12343 +               "move.4         csr, #0         \n\t"
12344 +               "setcsr_flush   0               \n\t"
12345 +               : "=r" (result)
12346 +               : "r" ((thread << 9) | (1 << 8))
12347 +       );
12348 +       return result;
12349 +}
12350 +
12351 +/*
12352 + * thread_get_trap_cause()
12353 + *     This should be called only when the thread is not running
12354 + */
12355 +static inline unsigned int thread_get_trap_cause(thread_t thread)
12356 +{
12357 +       unsigned int result;
12358 +       asm (
12359 +               "move.4         csr, %1         \n\t"
12360 +               "setcsr_flush   0               \n\t"
12361 +               "move.4         %0, trap_cause  \n\t"
12362 +               "move.4         csr, #0         \n\t"
12363 +               "setcsr_flush   0               \n\t"
12364 +               : "=r" (result)
12365 +               : "r" ((thread << 9) | (1 << 8))
12366 +       );
12367 +       return result;
12368 +}
12369 +
12370 +/*
12371 + * THREAD_STALL macro.
12372 + */
12373 +#define THREAD_STALL \
12374 +               asm volatile ( \
12375 +                       "move.4 mt_dbg_active_clr, #-1  \n\t" \
12376 +                       "pipe_flush 0                   \n\t" \
12377 +                       : \
12378 +                       : \
12379 +               )
12380 +
12381 +extern unsigned int thread_get_mainline(void);
12382 +extern void thread_set_mainline(thread_t tid);
12383 +extern thread_t thread_alloc(void);
12384 +extern thread_t thread_start(thread_t thread, thread_exec_fn_t exec, void *arg, unsigned int *sp_high, thread_type_t type);
12385 +
12386 +/*
12387 + * asm macros
12388 + */
12389 +asm (
12390 +/*
12391 + * thread_get_self
12392 + *     Read and shift the current thread into reg
12393 + */
12394 +".macro        thread_get_self reg             \n\t"
12395 +"      lsr.4   \\reg, ROSR, #2         \n\t"
12396 +"      and.4   \\reg, #31, \\reg       \n\t"/* Mask to get thread number into
12397 +                                             * register */
12398 +".endm                                 \n\t"
12399 +
12400 +/*
12401 + * thread_get_self_mask
12402 + *     Read and shift the current thread mask into reg
12403 + */
12404 +".macro        thread_get_self_mask reg        \n\t"
12405 +"      lsr.4   \\reg, ROSR, #2         \n\t"
12406 +"      lsl.4   \\reg, #1, \\reg        \n\t"    /* Thread bit */
12407 +".endm                                 \n\t"
12408 +       );
12409 +
12410 +#else /* __ASSEMBLY__ */
12411 +
12412 +#include <asm/thread-asm.h>
12413 +
12414 +#endif /* __ASSEMBLY__ */
12415 +#endif /* _ASM_UBICOM32_THREAD_H */
12416 --- /dev/null
12417 +++ b/arch/ubicom32/include/asm/thread_info.h
12418 @@ -0,0 +1,134 @@
12419 +/*
12420 + * arch/ubicom32/include/asm/thread_info.h
12421 + *   Ubicom32 architecture low-level thread information.
12422 + *
12423 + * (C) Copyright 2009, Ubicom, Inc.
12424 + * Adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com)
12425 + * Copyright (C) 2002  David Howells (dhowells@redhat.com)
12426 + * - Incorporating suggestions made by Linus Torvalds and Dave Miller
12427 + *
12428 + * This file is part of the Ubicom32 Linux Kernel Port.
12429 + *
12430 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12431 + * it and/or modify it under the terms of the GNU General Public License
12432 + * as published by the Free Software Foundation, either version 2 of the
12433 + * License, or (at your option) any later version.
12434 + *
12435 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12436 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12437 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12438 + * the GNU General Public License for more details.
12439 + *
12440 + * You should have received a copy of the GNU General Public License
12441 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12442 + * see <http://www.gnu.org/licenses/>.
12443 + *
12444 + * Ubicom32 implementation derived from (with many thanks):
12445 + *   arch/m68knommu
12446 + *   arch/blackfin
12447 + *   arch/parisc
12448 + */
12449 +
12450 +#ifndef _ASM_UBICOM32_THREAD_INFO_H
12451 +#define _ASM_UBICOM32_THREAD_INFO_H
12452 +
12453 +#include <asm/page.h>
12454 +
12455 +/*
12456 + * Size of kernel stack for each process. This must be a power of 2...
12457 + */
12458 +#ifdef CONFIG_4KSTACKS
12459 +#define THREAD_SIZE_ORDER (0)
12460 +#else
12461 +#define THREAD_SIZE_ORDER (1)
12462 +#endif
12463 +
12464 +/*
12465 + * for asm files, THREAD_SIZE is now generated by asm-offsets.c
12466 + */
12467 +#define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
12468 +
12469 +#ifdef __KERNEL__
12470 +
12471 +#ifndef __ASSEMBLY__
12472 +
12473 +/*
12474 + * low level task data.
12475 + */
12476 +struct thread_info {
12477 +       struct task_struct *task;               /* main task structure */
12478 +       struct exec_domain *exec_domain;        /* execution domain */
12479 +       unsigned long      flags;               /* low level flags */
12480 +       int                cpu;                 /* cpu we're on */
12481 +       int                preempt_count;       /* 0 => preemptable, <0 => BUG */
12482 +       int                interrupt_nesting;   /* Interrupt nesting level. */
12483 +       struct restart_block restart_block;
12484 +};
12485 +
12486 +/*
12487 + * macros/functions for gaining access to the thread information structure
12488 + */
12489 +#define INIT_THREAD_INFO(tsk)                  \
12490 +{                                              \
12491 +       .task           = &tsk,                 \
12492 +       .exec_domain    = &default_exec_domain, \
12493 +       .flags          = 0,                    \
12494 +       .cpu            = 0,                    \
12495 +       .interrupt_nesting      = 0,            \
12496 +       .restart_block  = {                     \
12497 +               .fn = do_no_restart_syscall,    \
12498 +       },                                      \
12499 +}
12500 +
12501 +#define init_thread_info       (init_thread_union.thread_info)
12502 +#define init_stack             (init_thread_union.stack)
12503 +
12504 +
12505 +/* how to get the thread information struct from C */
12506 +static inline struct thread_info *current_thread_info(void)
12507 +{
12508 +       struct thread_info *ti;
12509 +
12510 +       asm (
12511 +               "and.4  %0, sp, %1\n\t"
12512 +               : "=&r" (ti)
12513 +               : "d" (~(THREAD_SIZE-1))
12514 +               : "cc"
12515 +       );
12516 +
12517 +       return ti;
12518 +}
12519 +
12520 +#define STACK_WARN (THREAD_SIZE / 8)
12521 +
12522 +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 1
12523 +
12524 +/* thread information allocation */
12525 +#define alloc_thread_info(tsk) ((struct thread_info *) \
12526 +                               __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER))
12527 +#define free_thread_info(ti)   free_pages((unsigned long) (ti), THREAD_SIZE_ORDER)
12528 +#endif /* __ASSEMBLY__ */
12529 +
12530 +#define        PREEMPT_ACTIVE  0x4000000
12531 +
12532 +/*
12533 + * thread information flag bit numbers
12534 + */
12535 +#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
12536 +#define TIF_SIGPENDING         1       /* signal pending */
12537 +#define TIF_NEED_RESCHED       2       /* rescheduling necessary */
12538 +#define TIF_POLLING_NRFLAG     3       /* true if poll_idle() is polling
12539 +                                          TIF_NEED_RESCHED */
12540 +#define TIF_MEMDIE             4
12541 +
12542 +/* as above, but as bit values */
12543 +#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
12544 +#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
12545 +#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
12546 +#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
12547 +
12548 +#define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
12549 +
12550 +#endif /* __KERNEL__ */
12551 +
12552 +#endif /* _ASM_UBICOM32_THREAD_INFO_H */
12553 --- /dev/null
12554 +++ b/arch/ubicom32/include/asm/timex.h
12555 @@ -0,0 +1,56 @@
12556 +/*
12557 + * arch/ubicom32/include/asm/timex.h
12558 + *   Ubicom32 architecture timex specifications.
12559 + *
12560 + * (C) Copyright 2009, Ubicom, Inc.
12561 + *
12562 + * This file is part of the Ubicom32 Linux Kernel Port.
12563 + *
12564 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12565 + * it and/or modify it under the terms of the GNU General Public License
12566 + * as published by the Free Software Foundation, either version 2 of the
12567 + * License, or (at your option) any later version.
12568 + *
12569 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12570 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12571 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12572 + * the GNU General Public License for more details.
12573 + *
12574 + * You should have received a copy of the GNU General Public License
12575 + * along with the Ubicom32 Linux Kernel Port.  If not,
12576 + * see <http://www.gnu.org/licenses/>.
12577 + *
12578 + * Ubicom32 implementation derived from (with many thanks):
12579 + *   arch/m68knommu
12580 + *   arch/blackfin
12581 + *   arch/parisc
12582 + */
12583 +#ifndef _ASM_UBICOM32_TIMEX_H
12584 +#define _ASM_UBICOM32_TIMEX_H
12585 +
12586 +#define CLOCK_TICK_RATE        266000000
12587 +
12588 +// #define ARCH_HAS_READ_CURRENT_TIMER
12589 +
12590 +typedef unsigned long cycles_t;
12591 +
12592 +static inline cycles_t get_cycles(void)
12593 +{
12594 +       return 0;
12595 +}
12596 +
12597 +extern int timer_alloc(void);
12598 +extern void timer_set(int timervector, unsigned int cycles);
12599 +extern int timer_reset(int timervector, unsigned int cycles);
12600 +extern void timer_tick_init(void);
12601 +extern void timer_device_init(void);
12602 +
12603 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12604 +extern void local_timer_interrupt(void);
12605 +#endif
12606 +
12607 +#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12608 +extern int local_timer_setup(unsigned int cpu);
12609 +#endif
12610 +
12611 +#endif /* _ASM_UBICOM32_TIMEX_H */
12612 --- /dev/null
12613 +++ b/arch/ubicom32/include/asm/tlbflush.h
12614 @@ -0,0 +1,79 @@
12615 +/*
12616 + * arch/ubicom32/include/asm/tlbflush.h
12617 + *   TLB operations for Ubicom32 architecture.
12618 + *
12619 + * (C) Copyright 2009, Ubicom, Inc.
12620 + * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
12621 + * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
12622 + *
12623 + * This file is part of the Ubicom32 Linux Kernel Port.
12624 + *
12625 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12626 + * it and/or modify it under the terms of the GNU General Public License
12627 + * as published by the Free Software Foundation, either version 2 of the
12628 + * License, or (at your option) any later version.
12629 + *
12630 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12631 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12632 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12633 + * the GNU General Public License for more details.
12634 + *
12635 + * You should have received a copy of the GNU General Public License
12636 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12637 + * see <http://www.gnu.org/licenses/>.
12638 + *
12639 + * Ubicom32 implementation derived from (with many thanks):
12640 + *   arch/m68knommu
12641 + *   arch/blackfin
12642 + *   arch/parisc
12643 + */
12644 +#ifndef _ASM_UBICOM32_TLB_FLUSH_H
12645 +#define _ASM_UBICOM32_TLB_FLUSH_H
12646 +
12647 +#include <asm/setup.h>
12648 +
12649 +/*
12650 + * flush all user-space atc entries.
12651 + */
12652 +static inline void __flush_tlb(void)
12653 +{
12654 +       BUG();
12655 +}
12656 +
12657 +static inline void __flush_tlb_one(unsigned long addr)
12658 +{
12659 +       BUG();
12660 +}
12661 +
12662 +#define flush_tlb() __flush_tlb()
12663 +
12664 +/*
12665 + * flush all atc entries (both kernel and user-space entries).
12666 + */
12667 +static inline void flush_tlb_all(void)
12668 +{
12669 +       BUG();
12670 +}
12671 +
12672 +static inline void flush_tlb_mm(struct mm_struct *mm)
12673 +{
12674 +       BUG();
12675 +}
12676 +
12677 +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
12678 +{
12679 +       BUG();
12680 +}
12681 +
12682 +static inline void flush_tlb_range(struct mm_struct *mm,
12683 +                                  unsigned long start, unsigned long end)
12684 +{
12685 +       BUG();
12686 +}
12687 +
12688 +static inline void flush_tlb_kernel_page(unsigned long addr)
12689 +{
12690 +       BUG();
12691 +}
12692 +
12693 +#endif /* _ASM_UBICOM32_TLB_FLUSH_H */
12694 --- /dev/null
12695 +++ b/arch/ubicom32/include/asm/tlb.h
12696 @@ -0,0 +1,47 @@
12697 +/*
12698 + * arch/ubicom32/include/asm/tlb.h
12699 + *   Ubicom32 architecture TLB operations.
12700 + *
12701 + * (C) Copyright 2009, Ubicom, Inc.
12702 + *
12703 + * This file is part of the Ubicom32 Linux Kernel Port.
12704 + *
12705 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12706 + * it and/or modify it under the terms of the GNU General Public License
12707 + * as published by the Free Software Foundation, either version 2 of the
12708 + * License, or (at your option) any later version.
12709 + *
12710 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12711 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12712 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12713 + * the GNU General Public License for more details.
12714 + *
12715 + * You should have received a copy of the GNU General Public License
12716 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12717 + * see <http://www.gnu.org/licenses/>.
12718 + *
12719 + * Ubicom32 implementation derived from (with many thanks):
12720 + *   arch/m68knommu
12721 + *   arch/blackfin
12722 + *   arch/parisc
12723 + */
12724 +#ifndef _ASM_UBICOM32_TLB_H
12725 +#define _ASM_UBICOM32_TLB_H
12726 +
12727 +/*
12728 + * ubicom32 doesn't need any special per-pte or
12729 + * per-vma handling..
12730 + */
12731 +#define tlb_start_vma(tlb, vma)        do { } while (0)
12732 +#define tlb_end_vma(tlb, vma)  do { } while (0)
12733 +#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
12734 +
12735 +/*
12736 + * .. because we flush the whole mm when it
12737 + * fills up.
12738 + */
12739 +#define tlb_flush(tlb)
12740 +
12741 +#include <asm-generic/tlb.h>
12742 +
12743 +#endif /* _ASM_UBICOM32_TLB_H */
12744 --- /dev/null
12745 +++ b/arch/ubicom32/include/asm/topology.h
12746 @@ -0,0 +1,33 @@
12747 +/*
12748 + * arch/ubicom32/include/asm/topology.h
12749 + *   Generic topology.h definitions for Ubicom32 architecture.
12750 + *
12751 + * (C) Copyright 2009, Ubicom, Inc.
12752 + *
12753 + * This file is part of the Ubicom32 Linux Kernel Port.
12754 + *
12755 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12756 + * it and/or modify it under the terms of the GNU General Public License
12757 + * as published by the Free Software Foundation, either version 2 of the
12758 + * License, or (at your option) any later version.
12759 + *
12760 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12761 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12762 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12763 + * the GNU General Public License for more details.
12764 + *
12765 + * You should have received a copy of the GNU General Public License
12766 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12767 + * see <http://www.gnu.org/licenses/>.
12768 + *
12769 + * Ubicom32 implementation derived from (with many thanks):
12770 + *   arch/m68knommu
12771 + *   arch/blackfin
12772 + *   arch/parisc
12773 + */
12774 +#ifndef _ASM_UBICOM32_TOPOLOGY_H
12775 +#define _ASM_UBICOM32_TOPOLOGY_H
12776 +
12777 +#include <asm-generic/topology.h>
12778 +
12779 +#endif /* _ASM_UBICOM32_TOPOLOGY_H */
12780 --- /dev/null
12781 +++ b/arch/ubicom32/include/asm/traps.h
12782 @@ -0,0 +1,55 @@
12783 +/*
12784 + * arch/ubicom32/include/asm/traps.h
12785 + *   Trap related definitions for Ubicom32 architecture.
12786 + *
12787 + * (C) Copyright 2009, Ubicom, Inc.
12788 + *
12789 + * This file is part of the Ubicom32 Linux Kernel Port.
12790 + *
12791 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12792 + * it and/or modify it under the terms of the GNU General Public License
12793 + * as published by the Free Software Foundation, either version 2 of the
12794 + * License, or (at your option) any later version.
12795 + *
12796 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12797 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12798 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12799 + * the GNU General Public License for more details.
12800 + *
12801 + * You should have received a copy of the GNU General Public License
12802 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12803 + * see <http://www.gnu.org/licenses/>.
12804 + *
12805 + * Ubicom32 implementation derived from (with many thanks):
12806 + *   arch/m68knommu
12807 + *   arch/blackfin
12808 + *   arch/parisc
12809 + */
12810 +
12811 +#ifndef _ASM_UBICOM32_TRAPS_H
12812 +#define _ASM_UBICOM32_TRAPS_H
12813 +
12814 +/*
12815 + * Trap causes passed from ultra to Host OS
12816 + */
12817 +#define TRAP_CAUSE_TOTAL               13
12818 +#define TRAP_CAUSE_DST_RANGE_ERR       12
12819 +#define TRAP_CAUSE_SRC1_RANGE_ERR      11
12820 +#define TRAP_CAUSE_I_RANGE_ERR         10
12821 +#define TRAP_CAUSE_DCAPT               9
12822 +#define TRAP_CAUSE_DST_SERROR          8
12823 +#define TRAP_CAUSE_SRC1_SERROR         7
12824 +#define TRAP_CAUSE_DST_MISALIGNED      6
12825 +#define TRAP_CAUSE_SRC1_MISALIGNED     5
12826 +#define TRAP_CAUSE_DST_DECODE_ERR      4
12827 +#define TRAP_CAUSE_SRC1_DECODE_ERR     3
12828 +#define TRAP_CAUSE_ILLEGAL_INST                2
12829 +#define TRAP_CAUSE_I_SERROR            1
12830 +#define TRAP_CAUSE_I_DECODE_ERR                0
12831 +
12832 +extern void trap_handler(int irq, struct pt_regs *regs);
12833 +extern void trap_init_interrupt(void);
12834 +extern void unaligned_emulate(unsigned int thread);
12835 +extern int unaligned_only(unsigned int cause);
12836 +
12837 +#endif /* _ASM_UBICOM32_TRAPS_H */
12838 --- /dev/null
12839 +++ b/arch/ubicom32/include/asm/types.h
12840 @@ -0,0 +1,75 @@
12841 +/*
12842 + * arch/ubicom32/include/asm/types.h
12843 + *   Date type definitions for Ubicom32 architecture.
12844 + *
12845 + * (C) Copyright 2009, Ubicom, Inc.
12846 + *
12847 + * This file is part of the Ubicom32 Linux Kernel Port.
12848 + *
12849 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12850 + * it and/or modify it under the terms of the GNU General Public License
12851 + * as published by the Free Software Foundation, either version 2 of the
12852 + * License, or (at your option) any later version.
12853 + *
12854 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12855 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12856 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12857 + * the GNU General Public License for more details.
12858 + *
12859 + * You should have received a copy of the GNU General Public License
12860 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12861 + * see <http://www.gnu.org/licenses/>.
12862 + *
12863 + * Ubicom32 implementation derived from (with many thanks):
12864 + *   arch/m68knommu
12865 + *   arch/blackfin
12866 + *   arch/parisc
12867 + */
12868 +#ifndef _ASM_UBICOM32_TYPES_H
12869 +#define _ASM_UBICOM32_TYPES_H
12870 +
12871 +/*
12872 + * This file is never included by application software unless
12873 + * explicitly requested (e.g., via linux/types.h) in which case the
12874 + * application is Linux specific so (user-) name space pollution is
12875 + * not a major issue.  However, for interoperability, libraries still
12876 + * need to be careful to avoid a name clashes.
12877 + */
12878 +
12879 +#include <asm-generic/int-ll64.h>
12880 +
12881 +#ifndef __ASSEMBLY__
12882 +
12883 +typedef unsigned short umode_t;
12884 +
12885 +#endif /* __ASSEMBLY__ */
12886 +
12887 +/*
12888 + * These aren't exported outside the kernel to avoid name space clashes
12889 + */
12890 +#ifdef __KERNEL__
12891 +
12892 +#define BITS_PER_LONG 32
12893 +
12894 +#ifndef __ASSEMBLY__
12895 +
12896 +/* DMA addresses are always 32-bits wide */
12897 +
12898 +typedef u32 dma_addr_t;
12899 +typedef u32 dma64_addr_t;
12900 +
12901 +/*
12902 + * XXX These are "Ubicom style" typedefs. They should be removed in all files used by linux.
12903 + */
12904 +typedef u32 u32_t;
12905 +typedef s32 s32_t;
12906 +typedef u16 u16_t;
12907 +typedef s16 s16_t;
12908 +typedef u8 u8_t;
12909 +typedef s8 s8_t;
12910 +
12911 +#endif /* __ASSEMBLY__ */
12912 +
12913 +#endif /* __KERNEL__ */
12914 +
12915 +#endif /* _ASM_UBICOM32_TYPES_H */
12916 --- /dev/null
12917 +++ b/arch/ubicom32/include/asm/uaccess.h
12918 @@ -0,0 +1,347 @@
12919 +/*
12920 + * arch/ubicom32/include/asm/uaccess.h
12921 + *   User space memory access functions for Ubicom32 architecture.
12922 + *
12923 + * (C) Copyright 2009, Ubicom, Inc.
12924 + *
12925 + * This file is part of the Ubicom32 Linux Kernel Port.
12926 + *
12927 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12928 + * it and/or modify it under the terms of the GNU General Public License
12929 + * as published by the Free Software Foundation, either version 2 of the
12930 + * License, or (at your option) any later version.
12931 + *
12932 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12933 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12934 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12935 + * the GNU General Public License for more details.
12936 + *
12937 + * You should have received a copy of the GNU General Public License
12938 + * along with the Ubicom32 Linux Kernel Port.  If not,
12939 + * see <http://www.gnu.org/licenses/>.
12940 + *
12941 + * Ubicom32 implementation derived from (with many thanks):
12942 + *   arch/m68knommu
12943 + *   arch/blackfin
12944 + *   arch/parisc
12945 + *   arch/alpha
12946 + */
12947 +#ifndef _ASM_UBICOM32_UACCESS_H
12948 +#define _ASM_UBICOM32_UACCESS_H
12949 +
12950 +/*
12951 + * User space memory access functions
12952 + */
12953 +#include <linux/sched.h>
12954 +#include <linux/mm.h>
12955 +#include <linux/string.h>
12956 +
12957 +#include <asm/segment.h>
12958 +
12959 +#define VERIFY_READ    0
12960 +#define VERIFY_WRITE   1
12961 +
12962 +/*
12963 + * The exception table consists of pairs of addresses: the first is the
12964 + * address of an instruction that is allowed to fault, and the second is
12965 + * the address at which the program should continue.  No registers are
12966 + * modified, so it is entirely up to the continuation code to figure out
12967 + * what to do.
12968 + *
12969 + * All the routines below use bits of fixup code that are out of line
12970 + * with the main instruction path.  This means when everything is well,
12971 + * we don't even have to jump over them.  Further, they do not intrude
12972 + * on our cache or tlb entries.
12973 + */
12974 +struct exception_table_entry
12975 +{
12976 +       unsigned long insn, fixup;
12977 +};
12978 +
12979 +/* 
12980 + * Ubicom32 does not currently support the exception table handling.
12981 + */
12982 +extern unsigned long search_exception_table(unsigned long);
12983 +
12984 +
12985 +#if defined(CONFIG_ACCESS_OK_CHECKS_ENABLED)
12986 +extern int __access_ok(unsigned long addr, unsigned long size);
12987 +#else
12988 +static inline int __access_ok(unsigned long addr, unsigned long size)
12989 +{
12990 +       return 1;
12991 +}
12992 +#endif
12993 +#define access_ok(type, addr, size) \
12994 +       likely(__access_ok((unsigned long)(addr), (size)))
12995 +
12996 +/*
12997 + * The following functions do not exist.  They keep callers
12998 + * of put_user and get_user from passing unsupported argument
12999 + * types.  They result in a link time error.
13000 + */
13001 +extern int __put_user_bad(void);
13002 +extern int __get_user_bad(void);
13003 +
13004 +/*
13005 + * __put_user_no_check()
13006 + *     Put the requested data into the user space verifying the address
13007 + *
13008 + * Careful to not
13009 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13010 + * (b) require any knowledge of processes at this stage
13011 + */
13012 +#define __put_user_no_check(x, ptr, size)              \
13013 +({                                                     \
13014 +       int __pu_err = 0;                               \
13015 +       __typeof__(*(ptr)) __user *__pu_addr = (ptr);   \
13016 +       switch (size) {                                 \
13017 +       case 1:                                         \
13018 +       case 2:                                         \
13019 +       case 4:                                         \
13020 +       case 8:                                         \
13021 +               *__pu_addr = (__typeof__(*(ptr)))x;     \
13022 +               break;                                  \
13023 +       default:                                        \
13024 +               __pu_err = __put_user_bad();            \
13025 +               break;                                  \
13026 +       }                                               \
13027 +       __pu_err;                                       \
13028 +})
13029 +
13030 +/*
13031 + * __put_user_check()
13032 + *     Put the requested data into the user space verifying the address
13033 + *
13034 + * Careful to not
13035 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13036 + * (b) require any knowledge of processes at this stage
13037 + *
13038 + * If requested, access_ok() will verify that ptr is a valid user
13039 + * pointer.
13040 + */
13041 +#define __put_user_check(x, ptr, size)                         \
13042 +({                                                             \
13043 +       int __pu_err = -EFAULT;                                 \
13044 +       __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
13045 +       if (access_ok(VERIFY_WRITE, __pu_addr, size)) {         \
13046 +               __pu_err = 0;                                   \
13047 +               switch (size) {                                 \
13048 +               case 1:                                         \
13049 +               case 2:                                         \
13050 +               case 4:                                         \
13051 +               case 8:                                         \
13052 +                       *__pu_addr = (__typeof__(*(ptr)))x;     \
13053 +                       break;                                  \
13054 +               default:                                        \
13055 +                       __pu_err = __put_user_bad();            \
13056 +                       break;                                  \
13057 +               }                                               \
13058 +       }                                                       \
13059 +       __pu_err;                                               \
13060 +})
13061 +
13062 +/*
13063 + * __get_user_no_check()
13064 + *     Read the value at ptr into x.
13065 + *
13066 + * If requested, access_ok() will verify that ptr is a valid user
13067 + * pointer.  If the caller passes a modifying argument for ptr (e.g. x++)
13068 + * this macro will not work.
13069 + */
13070 +#define __get_user_no_check(x, ptr, size)                      \
13071 +({                                                             \
13072 +       int __gu_err = 0;                                       \
13073 +       __typeof__((x)) __gu_val = 0;                           \
13074 +       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);     \
13075 +       switch (size) {                                         \
13076 +       case 1:                                                 \
13077 +       case 2:                                                 \
13078 +       case 4:                                                 \
13079 +       case 8:                                                 \
13080 +               __gu_val = (__typeof__((x)))*(__gu_addr);       \
13081 +               break;                                          \
13082 +       default:                                                \
13083 +               __gu_err = __get_user_bad();                    \
13084 +               (x) = 0;                                        \
13085 +               break;                                          \
13086 +       }                                                       \
13087 +       (x) = __gu_val;                                         \
13088 +       __gu_err;                                               \
13089 +})
13090 +
13091 +/*
13092 + * __get_user_check()
13093 + *     Read the value at ptr into x.
13094 + *
13095 + * If requested, access_ok() will verify that ptr is a valid user
13096 + * pointer.
13097 + */
13098 +#define __get_user_check(x, ptr, size)                                 \
13099 +({                                                                     \
13100 +       int __gu_err = -EFAULT;                                         \
13101 +       __typeof__(x) __gu_val = 0;                                     \
13102 +       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);             \
13103 +       if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
13104 +               __gu_err = 0;                                           \
13105 +               switch (size) {                                         \
13106 +               case 1:                                                 \
13107 +               case 2:                                                 \
13108 +               case 4:                                                 \
13109 +               case 8:                                                 \
13110 +                       __gu_val = (__typeof__((x)))*(__gu_addr);       \
13111 +                       break;                                          \
13112 +               default:                                                \
13113 +                       __gu_err = __get_user_bad();                    \
13114 +                       (x) = 0;                                        \
13115 +                       break;                                          \
13116 +               }                                                       \
13117 +       }                                                               \
13118 +       (x) = __gu_val;                                                 \
13119 +       __gu_err;                                                       \
13120 +})
13121 +
13122 +/*
13123 + * The "xxx" versions are allowed to perform some amount of address
13124 + * space checking.  See access_ok().
13125 + */
13126 +#define put_user(x,ptr) \
13127 +       __put_user_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
13128 +#define get_user(x,ptr) \
13129 +       __get_user_check((x), (ptr), sizeof(*(ptr)))
13130 +
13131 +/*
13132 + * The "__xxx" versions do not do address space checking, useful when
13133 + * doing multiple accesses to the same area (the programmer has to do the
13134 + * checks by hand with "access_ok()")
13135 + */
13136 +#define __put_user(x,ptr) \
13137 +       __put_user_no_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
13138 +#define __get_user(x,ptr) \
13139 +       __get_user_no_check((x), (ptr), sizeof(*(ptr)))
13140 +
13141 +/*
13142 + * __copy_tofrom_user_no_check()
13143 + *     Copy the data either to or from user space.
13144 + *
13145 + * Return the number of bytes NOT copied.
13146 + */
13147 +static inline unsigned long
13148 +__copy_tofrom_user_no_check(void *to, const void *from, unsigned long n)
13149 +{
13150 +       memcpy(to, from, n);
13151 +       return 0;
13152 +}
13153 +
13154 +/*
13155 + * copy_to_user()
13156 + *     Copy the kernel data to user space.
13157 + *
13158 + * Return the number of bytes that were copied.
13159 + */
13160 +static inline unsigned long 
13161 +copy_to_user(void __user *to, const void *from, unsigned long n)
13162 +{
13163 +       if (!access_ok(VERIFY_WRITE, to, n)) {
13164 +               return n;
13165 +       }
13166 +       return __copy_tofrom_user_no_check((__force void *)to, from, n);
13167 +}
13168 +
13169 +/*
13170 + * copy_from_user()
13171 + *     Copy the user data to kernel space.
13172 + *
13173 + * Return the number of bytes that were copied.  On error, we zero 
13174 + * out the destination.
13175 + */
13176 +static inline unsigned long
13177 +copy_from_user(void *to, const void __user *from, unsigned long n)
13178 +{
13179 +       if (!access_ok(VERIFY_READ, from, n)) {
13180 +               return n;
13181 +       }
13182 +       return __copy_tofrom_user_no_check(to, (__force void *)from, n);
13183 +}
13184 +
13185 +#define __copy_to_user(to, from, n) \
13186 +       __copy_tofrom_user_no_check((__force void *)to, from, n)
13187 +#define __copy_from_user(to, from, n) \
13188 +       __copy_tofrom_user_no_check(to, (__force void *)from, n)
13189 +#define __copy_to_user_inatomic(to, from, n) \
13190 +       __copy_tofrom_user_no_check((__force void *)to, from, n)
13191 +#define __copy_from_user_inatomic(to, from, n) \
13192 +       __copy_tofrom_user_no_check(to, (__force void *)from, n)
13193 +
13194 +#define copy_to_user_ret(to, from, n, retval) \
13195 +       ({ if (copy_to_user(to, from, n)) return retval; })
13196 +
13197 +#define copy_from_user_ret(to, from, n, retval) \
13198 +       ({ if (copy_from_user(to, from, n)) return retval; })
13199 +
13200 +/*
13201 + * strncpy_from_user()
13202 + *     Copy a null terminated string from userspace.
13203 + *
13204 + * dst - Destination in kernel space.  The buffer must be at least count.
13205 + * src - Address of string in user space.
13206 + * count - Maximum number of bytes to copy (including the trailing NULL).
13207 + * 
13208 + * Returns the length of the string (not including the trailing NULL.  If 
13209 + * count is smaller than the length of the string, we copy count bytes
13210 + * and return count.
13211 + *
13212 + */
13213 +static inline long strncpy_from_user(char *dst, const __user char *src, long count)
13214 +{
13215 +       char *tmp;
13216 +       if (!access_ok(VERIFY_READ, src, 1)) {
13217 +               return -EFAULT;
13218 +       }
13219 +
13220 +       strncpy(dst, src, count);
13221 +       for (tmp = dst; *tmp && count > 0; tmp++, count--) {
13222 +               ;
13223 +       }
13224 +       return(tmp - dst);
13225 +}
13226 +
13227 +/*
13228 + * strnlen_user()
13229 + *     Return the size of a string (including the ending 0)
13230 + *
13231 + * Return -EFAULT on exception, a value greater than <n> if too long
13232 + */
13233 +static inline long strnlen_user(const __user char *src, long n)
13234 +{
13235 +       if (!access_ok(VERIFY_READ, src, 1)) {
13236 +               return -EFAULT;
13237 +       }
13238 +       return(strlen(src) + 1);
13239 +}
13240 +
13241 +#define strlen_user(str) strnlen_user(str, 32767)
13242 +
13243 +/*
13244 + * __clear_user()
13245 + *     Zero Userspace
13246 + */
13247 +static inline unsigned long __clear_user(__user void *to, unsigned long n)
13248 +{
13249 +       memset(to, 0, n);
13250 +       return 0;
13251 +}
13252 +
13253 +/*
13254 + * clear_user()
13255 + *     Zero user space (check for valid addresses)
13256 + */
13257 +static inline unsigned long clear_user(__user void *to, unsigned long n)
13258 +{
13259 +       if (!access_ok(VERIFY_WRITE, to, n)) {
13260 +               return -EFAULT;
13261 +       }
13262 +       return __clear_user(to, n);
13263 +}
13264 +
13265 +#endif /* _ASM_UBICOM32_UACCESS_H */
13266 --- /dev/null
13267 +++ b/arch/ubicom32/include/asm/ubi32-cs4384.h
13268 @@ -0,0 +1,53 @@
13269 +/*
13270 + * arch/ubicom32/include/asm/ubi32-cs4384.h
13271 + *   Ubicom32 architecture CS4384 driver platform data definitions.
13272 + *
13273 + * (C) Copyright 2009, Ubicom, Inc.
13274 + *
13275 + * This file is part of the Ubicom32 Linux Kernel Port.
13276 + *
13277 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13278 + * it and/or modify it under the terms of the GNU General Public License
13279 + * as published by the Free Software Foundation, either version 2 of the
13280 + * License, or (at your option) any later version.
13281 + *
13282 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13283 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13284 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13285 + * the GNU General Public License for more details.
13286 + *
13287 + * You should have received a copy of the GNU General Public License
13288 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13289 + * see <http://www.gnu.org/licenses/>.
13290 + */
13291 +#ifndef _ASM_UBICOM32_UBI32_CS4384_H
13292 +#define _ASM_UBICOM32_UBI32_CS4384_H
13293 +
13294 +enum ubi32_cs4384_mclk_source {
13295 +       UBI32_CS4384_MCLK_PWM_0,
13296 +       UBI32_CS4384_MCLK_PWM_1,
13297 +       UBI32_CS4384_MCLK_PWM_2,
13298 +       UBI32_CS4384_MCLK_CLKDIV_1,
13299 +       UBI32_CS4384_MCLK_OTHER,
13300 +};
13301 +
13302 +struct ubi32_cs4384_mclk_entry {
13303 +       /*
13304 +        * Rate, in Hz, of this entry
13305 +        */
13306 +       int rate;
13307 +
13308 +       /*
13309 +        * The divider to program to get the rate
13310 +        */
13311 +       int div;
13312 +};
13313 +
13314 +struct ubi32_cs4384_platform_data {
13315 +       enum ubi32_cs4384_mclk_source   mclk_src;
13316 +
13317 +       int                             n_mclk;
13318 +       struct ubi32_cs4384_mclk_entry  *mclk_entries;
13319 +};
13320 +#endif /* _ASM_UBICOM32_UBI32_CS4384_H */
13321 +
13322 --- /dev/null
13323 +++ b/arch/ubicom32/include/asm/ubi32-pcm.h
13324 @@ -0,0 +1,53 @@
13325 +/*
13326 + * arch/ubicom32/include/asm/ubi32-pcm.h
13327 + *   Ubicom32 architecture PCM driver platform data definitions.
13328 + *
13329 + * (C) Copyright 2009, Ubicom, Inc.
13330 + *
13331 + * This file is part of the Ubicom32 Linux Kernel Port.
13332 + *
13333 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13334 + * it and/or modify it under the terms of the GNU General Public License
13335 + * as published by the Free Software Foundation, either version 2 of the
13336 + * License, or (at your option) any later version.
13337 + *
13338 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13339 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13340 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13341 + * the GNU General Public License for more details.
13342 + *
13343 + * You should have received a copy of the GNU General Public License
13344 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13345 + * see <http://www.gnu.org/licenses/>.
13346 + */
13347 +#ifndef _ASM_UBICOM32_UBI32_PCM_H
13348 +#define _ASM_UBICOM32_UBI32_PCM_H
13349 +
13350 +/*
13351 + * This function is called when the sample rate has changed
13352 + */
13353 +typedef int (*ubi32_pcm_set_rate_fn_t)(void *appdata, int rate);
13354 +
13355 +struct ubi32pcm_platform_data {
13356 +       /*
13357 +        * Name of the audiotio node
13358 +        */
13359 +       const char              *node_name;
13360 +
13361 +       /*
13362 +        * Application specific data provided when calling functions
13363 +        */
13364 +       void                    *appdata;
13365 +
13366 +       /*
13367 +        * Functions called when various things happen
13368 +        */
13369 +       ubi32_pcm_set_rate_fn_t set_rate;
13370 +
13371 +       /*
13372 +        * Pointer to optional upper layer data (i.e. DAC config, etc)
13373 +        */
13374 +       void                    *priv_data;
13375 +};
13376 +#endif /* _ASM_UBICOM32_UBI32_PCM_H */
13377 +
13378 --- /dev/null
13379 +++ b/arch/ubicom32/include/asm/ubicom32bl.h
13380 @@ -0,0 +1,84 @@
13381 +/*
13382 + * arch/ubicom32/include/asm/ubicom32bl.h
13383 + *   Ubicom32 architecture backlight driver platform data definitions.
13384 + *
13385 + * (C) Copyright 2009, Ubicom, Inc.
13386 + *
13387 + * This file is part of the Ubicom32 Linux Kernel Port.
13388 + *
13389 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13390 + * it and/or modify it under the terms of the GNU General Public License
13391 + * as published by the Free Software Foundation, either version 2 of the
13392 + * License, or (at your option) any later version.
13393 + *
13394 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13395 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13396 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13397 + * the GNU General Public License for more details.
13398 + *
13399 + * You should have received a copy of the GNU General Public License
13400 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13401 + * see <http://www.gnu.org/licenses/>.
13402 + *
13403 + * Ubicom32 implementation derived from (with many thanks):
13404 + *   arch/m68knommu
13405 + *   arch/blackfin
13406 + *   arch/parisc
13407 + */
13408 +#ifndef _ASM_UBICOM32_UBICOM32_BL_H
13409 +#define _ASM_UBICOM32_UBICOM32_BL_H
13410 +
13411 +/*
13412 + * Different backlight control mechanisms
13413 + */
13414 +enum ubicom32bl_pwm_types {
13415 +       /*
13416 +        * PWM controlled backlight
13417 +        */
13418 +       UBICOM32BL_TYPE_PWM,
13419 +
13420 +       /*
13421 +        * HRT based PWM backlight
13422 +        */
13423 +       UBICOM32BL_TYPE_PWM_HRT,
13424 +
13425 +       /*
13426 +        * No dimming, just on or off
13427 +        */
13428 +       UBICOM32BL_TYPE_BINARY,
13429 +};
13430 +
13431 +struct ubicom32bl_platform_data {
13432 +       /*
13433 +        * Default intensity of the backlight 0-255
13434 +        */
13435 +       u8_t                            default_intensity;
13436 +
13437 +       /*
13438 +        * TRUE if the backlight sense is active low. (inverted)
13439 +        * FALSE if the backlight sense is active high.
13440 +        */
13441 +       bool                            invert;
13442 +
13443 +       /*
13444 +        * Type of the backlight
13445 +        */
13446 +       enum ubicom32bl_pwm_types       type;
13447 +
13448 +       /*
13449 +        * GPIO of the backlight if UBICOM32BL_TYPE_PWM_HRT, UBICOM32BL_TYPE_BINARY
13450 +        */
13451 +       unsigned                        gpio;
13452 +
13453 +       /*
13454 +        * PWM channel and parameters of the backlight if UBICOM32BL_TYPE_PWM
13455 +        *      pre_scaler: sets the rate at which the PWM timer is clocked. (clk_core / 2^pre_scaler)
13456 +        *      period: sets the period of the timer in timer cycles
13457 +        * The duty cycle will be directly proportional to the brightness setting.
13458 +        */
13459 +       u32_t                           pwm_channel;
13460 +       u8_t                            pwm_prescale;
13461 +       u16_t                           pwm_period;
13462 +};
13463 +
13464 +#endif /* _ASM_UBICOM32_UBICOM32_BL_H */
13465 --- /dev/null
13466 +++ b/arch/ubicom32/include/asm/ubicom32-common-asm.h
13467 @@ -0,0 +1,49 @@
13468 +/*
13469 + * arch/ubicom32/include/asm/ubicom32-common-asm.h
13470 + *   Ubicom32 atomic lock operations.
13471 + *
13472 + * (C) Copyright 2009, Ubicom, Inc.
13473 + *
13474 + * This file is part of the Ubicom32 Linux Kernel Port.
13475 + *
13476 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13477 + * it and/or modify it under the terms of the GNU General Public License
13478 + * as published by the Free Software Foundation, either version 2 of the
13479 + * License, or (at your option) any later version.
13480 + *
13481 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13482 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13483 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13484 + * the GNU General Public License for more details.
13485 + *
13486 + * You should have received a copy of the GNU General Public License
13487 + * along with the Ubicom32 Linux Kernel Port.  If not,
13488 + * see <http://www.gnu.org/licenses/>.
13489 + *
13490 + * Ubicom32 implementation derived from (with many thanks):
13491 + *   arch/m68knommu
13492 + *   arch/blackfin
13493 + *   arch/parisc
13494 + */
13495 +
13496 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13497 +#define _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13498 +
13499 +/*
13500 + * atomic_lock_acquire macro
13501 + *     Equivalent to __atomic_lock_acquire()
13502 + */
13503 +.macro atomic_lock_acquire
13504 +       bset scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13505 +       jmpne.f .-4
13506 +.endm
13507 +
13508 +/*
13509 + * atomic_lock_release macro
13510 + *     Equivalent to __atomic_lock_release()
13511 + */
13512 +.macro atomic_lock_release
13513 +       bclr scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13514 +.endm
13515 +
13516 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_ASM_H */
13517 --- /dev/null
13518 +++ b/arch/ubicom32/include/asm/ubicom32-common.h
13519 @@ -0,0 +1,124 @@
13520 +/*
13521 + * arch/ubicom32/include/asm/ubicom32-common.h
13522 + *   Ubicom32 atomic lock operations.
13523 + *
13524 + * (C) Copyright 2009, Ubicom, Inc.
13525 + *
13526 + * This file is part of the Ubicom32 Linux Kernel Port.
13527 + *
13528 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13529 + * it and/or modify it under the terms of the GNU General Public License
13530 + * as published by the Free Software Foundation, either version 2 of the
13531 + * License, or (at your option) any later version.
13532 + *
13533 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13534 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13535 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13536 + * the GNU General Public License for more details.
13537 + *
13538 + * You should have received a copy of the GNU General Public License
13539 + * along with the Ubicom32 Linux Kernel Port.  If not,
13540 + * see <http://www.gnu.org/licenses/>.
13541 + *
13542 + * Ubicom32 implementation derived from (with many thanks):
13543 + *   arch/m68knommu
13544 + *   arch/blackfin
13545 + *   arch/parisc
13546 + */
13547 +
13548 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_H
13549 +#define _ASM_UBICOM32_UBICOM32_COMMON_H
13550 +
13551 +#define S(arg) #arg
13552 +#define D(arg) S(arg)
13553 +/*
13554 + * scratchpad1 is owned by the LDSR.  
13555 + * 
13556 + * The upper bits provide 16 global spinlocks.  Acquiring one of these
13557 + * global spinlocks synchornizes across multiple threads and prevents 
13558 + * the LDSR from delivering any interrupts while the lock is held.
13559 + * Use these locks only when absolutely required.
13560 + *
13561 + * The lower 16 bits of scratchpad1 are used as per thread interrupt
13562 + * enable/disable bits.  These bits will prevent a thread from receiving
13563 + * any interrupts.
13564 + *
13565 + * Bit Usage:
13566 + * - MT_EN_LOCK_BIT   - Protects writes to MT_EN, so code can read current value
13567 + *                     then write a new value atomically (profiler for example)
13568 + * - ATOMIC_LOCK_BIT - Used to provide general purpose atomic handling.
13569 + * - LDSR_LOCK_BIT   - Used by the LDSR exclusively to provide protection.
13570 + * - LSB 16 bits     - Used by the LDSR to represent thread enable/disable bits.
13571 + */
13572 +#define MT_EN_LOCK_BIT 31
13573 +#define ATOMIC_LOCK_BIT 30
13574 +#define LDSR_LOCK_BIT   29
13575 +#define PCI_LOCK_BIT   28
13576 +
13577 +#if !defined(__ASSEMBLY__)
13578 +
13579 +#define UBICOM32_TRYLOCK(bit) \
13580 +       asm volatile (                                                \
13581 +       "       move.4 %0, #0                                   \n\t" \
13582 +       "       bset scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13583 +       "       jmpne.f 1f                                      \n\t" \
13584 +       "       move.4 %0, #1                                   \n\t" \
13585 +       "1:                                                     \n\t" \
13586 +               : "=r" (ret)                                          \
13587 +               :                                                     \
13588 +               : "cc", "memory"                                      \
13589 +       );                                                            \
13590 +
13591 +#define UBICOM32_UNLOCK(bit) \
13592 +       asm volatile (                                                \
13593 +       "       bclr scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13594 +               :                                                     \
13595 +               :                                                     \
13596 +               : "cc", "memory"                                      \
13597 +       );                                                            \
13598 +
13599 +#define UBICOM32_LOCK(bit) \
13600 +       asm volatile (                                                \
13601 +       "1:     bset scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13602 +       "       jmpne.f 1b                                      \n\t" \
13603 +               :                                                     \
13604 +               :                                                     \
13605 +               : "cc", "memory"                                      \
13606 +       );                                                            \
13607 +
13608 +/*
13609 + * __atomic_lock_trylock()
13610 + *     Attempt to acquire the lock, return TRUE if acquired.
13611 + */
13612 +static inline int __atomic_lock_trylock(void)
13613 +{
13614 +       int ret;
13615 +       UBICOM32_TRYLOCK(ATOMIC_LOCK_BIT);
13616 +       return ret;
13617 +}
13618 +
13619 +/*
13620 + * __atomic_lock_release()
13621 + *     Release the global atomic lock.
13622 + *
13623 + * Note: no one is suspended waiting since this lock is a spinning lock.
13624 + */
13625 +static inline void __atomic_lock_release(void)
13626 +{
13627 +       UBICOM32_UNLOCK(ATOMIC_LOCK_BIT);
13628 +}
13629 +
13630 +/*
13631 + * __atomic_lock_acquire()
13632 + *     Acquire the global atomic lock, spin if not available.
13633 + */
13634 +static inline void __atomic_lock_acquire(void)
13635 +{
13636 +       UBICOM32_LOCK(ATOMIC_LOCK_BIT);
13637 +}
13638 +#else /* __ASSEMBLY__ */
13639 +
13640 +#include <asm/ubicom32-common-asm.h>
13641 +
13642 +#endif /* __ASSEMBLY__ */
13643 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_H */
13644 --- /dev/null
13645 +++ b/arch/ubicom32/include/asm/ubicom32fb.h
13646 @@ -0,0 +1,56 @@
13647 +/*
13648 + * arch/ubicom32/include/asm/ubicom32fb.h
13649 + *   Ubicom32 architecture video frame buffer definitions.
13650 + *
13651 + * (C) Copyright 2009, Ubicom, Inc.
13652 + *
13653 + * This file is part of the Ubicom32 Linux Kernel Port.
13654 + *
13655 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13656 + * it and/or modify it under the terms of the GNU General Public License
13657 + * as published by the Free Software Foundation, either version 2 of the
13658 + * License, or (at your option) any later version.
13659 + *
13660 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13661 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13662 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13663 + * the GNU General Public License for more details.
13664 + *
13665 + * You should have received a copy of the GNU General Public License
13666 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13667 + * see <http://www.gnu.org/licenses/>.
13668 + */
13669 +#ifndef _ASM_UBICOM32_UBICOM32FB_H
13670 +#define _ASM_UBICOM32_UBICOM32FB_H
13671 +
13672 +#include <linux/ioctl.h>
13673 +
13674 +/* 
13675 + * Set next frame
13676 + */
13677 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME                _IOW('r',  1, void *) 
13678 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC   _IOW('r',  2, void *) 
13679 +
13680 +/*
13681 + * Set Mode
13682 + */
13683 +#define UBICOM32FB_IOCTL_SET_MODE              _IOW('r',  3, void *) 
13684 +struct ubicom32fb_mode {
13685 +       unsigned long   width;
13686 +       unsigned long   height;
13687 +       unsigned long   flags;
13688 +       void            *next_frame;
13689 +};
13690 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER  (1 << 8)
13691 +
13692 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER (1 << 7)
13693 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV             (1 << 6)
13694 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB            (1 << 5)
13695 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255   (1 << 4)
13696 +
13697 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255    (1 << 3)
13698 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1                (1 << 2)
13699 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1                (1 << 1)
13700 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE    (1 << 0)
13701 +
13702 +#endif /* _ASM_UBICOM32_UBICOM32FB_H */
13703 --- /dev/null
13704 +++ b/arch/ubicom32/include/asm/ubicom32hid.h
13705 @@ -0,0 +1,133 @@
13706 +/*
13707 + * arch/ubicom32/include/asm/ubicom32hid.h
13708 + *   Ubicom32 architecture HID driver platform data definitions.
13709 + *
13710 + * (C) Copyright 2009, Ubicom, Inc.
13711 + *
13712 + * This file is part of the Ubicom32 Linux Kernel Port.
13713 + *
13714 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13715 + * it and/or modify it under the terms of the GNU General Public License
13716 + * as published by the Free Software Foundation, either version 2 of the
13717 + * License, or (at your option) any later version.
13718 + *
13719 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13720 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13721 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13722 + * the GNU General Public License for more details.
13723 + *
13724 + * You should have received a copy of the GNU General Public License
13725 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13726 + * see <http://www.gnu.org/licenses/>.
13727 + *
13728 + * Ubicom32 implementation derived from (with many thanks):
13729 + *   arch/m68knommu
13730 + *   arch/blackfin
13731 + *   arch/parisc
13732 + */
13733 +#ifndef _ASM_UBICOM32_UBICOM32_HID_H
13734 +#define _ASM_UBICOM32_UBICOM32_HID_H
13735 +
13736 +enum ubicom32hid_bl_types {
13737 +       /*
13738 +        * On or off, using command SET_BL_EN, PB4
13739 +        */
13740 +       UBICOM32HID_BL_TYPE_BINARY,
13741 +
13742 +       /*
13743 +        * Dimmable, using command SET_PWM, PB3
13744 +        */
13745 +       UBICOM32HID_BL_TYPE_PWM,
13746 +};
13747 +
13748 +/*
13749 + * IR code mapping to event code.
13750 + *     If there are no button mappings and no ir mappings 
13751 + *     then no input driver will be registered.
13752 + */
13753 +struct ubicom32hid_ir {
13754 +       /*
13755 +        * Input event code (KEY_*, SW_*, etc)
13756 +        */
13757 +       int             code;
13758 +
13759 +       /*
13760 +        * Input event type (EV_KEY, EV_SW, etc)
13761 +        */
13762 +       int             type;
13763 +
13764 +       /*
13765 +        * The IR code of this button.
13766 +        */
13767 +       uint32_t        ir_code;
13768 +};
13769 +
13770 +/*
13771 + * Button mapping to event code.
13772 + *     If there are no button mappings and no ir mappings 
13773 + *     then no input driver will be registered.
13774 + */
13775 +struct ubicom32hid_button {
13776 +       /*
13777 +        * Input event code (KEY_*, SW_*, etc)
13778 +        */
13779 +       int             code;
13780 +
13781 +       /*
13782 +        * Input event type (EV_KEY, EV_SW, etc)
13783 +        */
13784 +       int             type;
13785 +
13786 +       /*
13787 +        * Bit number of this button.
13788 +        */
13789 +       uint8_t         bit;
13790 +};
13791 +
13792 +struct ubicom32hid_platform_data {
13793 +       /*
13794 +        * Default intensity of the backlight 0-255
13795 +        */
13796 +       u8_t                            default_intensity;
13797 +
13798 +       /*
13799 +        * GPIO number of the reset line and its polarity.
13800 +        */
13801 +       unsigned                        gpio_reset;
13802 +       int                             gpio_reset_polarity;
13803 +
13804 +       /*
13805 +        * TRUE if the backlight sense is active low. (inverted)
13806 +        * FALSE if the backlight sense is active high.
13807 +        */
13808 +       bool                            invert;
13809 +
13810 +       /*
13811 +        * Type of the backlight we are controlling
13812 +        */
13813 +       enum ubicom32hid_bl_types       type;
13814 +
13815 +       /*
13816 +        * Optional polling rate for input, in ms, defaults to 100ms
13817 +        */
13818 +       int                             poll_interval;
13819 +       
13820 +       /*
13821 +        * Optional name to register as input device
13822 +        */
13823 +       const char                      *input_name;
13824 +
13825 +       /*
13826 +        * Button mapping array
13827 +        */
13828 +       const struct ubicom32hid_button *buttons;
13829 +       int                             nbuttons;
13830 +
13831 +       /*
13832 +        * IR mapping array
13833 +        */
13834 +       const struct ubicom32hid_ir     *ircodes;
13835 +       int                             nircodes;
13836 +};
13837 +
13838 +#endif /* _ASM_UBICOM32_UBICOM32_HID_H */
13839 --- /dev/null
13840 +++ b/arch/ubicom32/include/asm/ubicom32input.h
13841 @@ -0,0 +1,76 @@
13842 +/*
13843 + * arch/ubicom32/include/asm/ubicom32input.h
13844 + *   Ubicom32 Input driver, based on gpio-keys
13845 + *
13846 + * (C) Copyright 2009, Ubicom, Inc.
13847 + *
13848 + * This file is part of the Ubicom32 Linux Kernel Port.
13849 + *
13850 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13851 + * it and/or modify it under the terms of the GNU General Public License
13852 + * as published by the Free Software Foundation, either version 2 of the
13853 + * License, or (at your option) any later version.
13854 + *
13855 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13856 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13857 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13858 + * the GNU General Public License for more details.
13859 + *
13860 + * You should have received a copy of the GNU General Public License
13861 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13862 + * see <http://www.gnu.org/licenses/>.
13863 + *
13864 + * Ubicom32 implementation derived from (with many thanks):
13865 + *   arch/m68knommu
13866 + *   arch/blackfin
13867 + *   arch/parisc
13868 + *
13869 + * TODO: add groups for inputs which can be sampled together
13870 + */
13871 +
13872 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_H
13873 +#define _ASM_UBICOM32_UBICOM32_INPUT_H
13874 +
13875 +struct ubicom32input_button {
13876 +       /*
13877 +        * Input event code (KEY_*, SW_*, etc)
13878 +        */
13879 +       int             code;
13880 +
13881 +       /*
13882 +        * Input event type (EV_KEY, EV_SW, etc)
13883 +        */
13884 +       int             type;
13885 +
13886 +       /*
13887 +        * GPIO to poll
13888 +        */
13889 +       int             gpio;
13890 +
13891 +       /*
13892 +        * 1 for active low, 0 for active high
13893 +        */
13894 +       int             active_low;
13895 +
13896 +       /*
13897 +        * Description, used for reserving GPIOs
13898 +        */
13899 +       const char      *desc;
13900 +};
13901 +
13902 +struct ubicom32input_platform_data {
13903 +       struct ubicom32input_button     *buttons;
13904 +       int                             nbuttons;
13905 +
13906 +       /*
13907 +        * Optional poll interval, in ms, defaults to 50ms
13908 +        */
13909 +       int                             poll_interval;
13910 +
13911 +       /*
13912 +        * Option Name of this driver
13913 +        */
13914 +       const char                      *name;
13915 +};
13916 +
13917 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_H */
13918 --- /dev/null
13919 +++ b/arch/ubicom32/include/asm/ubicom32input_i2c.h
13920 @@ -0,0 +1,71 @@
13921 +/*
13922 + * arch/ubicom32/include/asm/ubicom32input_i2c.h
13923 + *   Ubicom32 architecture Input driver over I2C platform data definitions.
13924 + *
13925 + * (C) Copyright 2009, Ubicom, Inc.
13926 + *
13927 + * This file is part of the Ubicom32 Linux Kernel Port.
13928 + *
13929 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13930 + * it and/or modify it under the terms of the GNU General Public License
13931 + * as published by the Free Software Foundation, either version 2 of the
13932 + * License, or (at your option) any later version.
13933 + *
13934 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13935 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13936 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13937 + * the GNU General Public License for more details.
13938 + *
13939 + * You should have received a copy of the GNU General Public License
13940 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13941 + * see <http://www.gnu.org/licenses/>.
13942 + *
13943 + * Ubicom32 implementation derived from (with many thanks):
13944 + *   arch/m68knommu
13945 + *   arch/blackfin
13946 + *   arch/parisc
13947 + *
13948 + * TODO: add groups for inputs which can be sampled together
13949 + */
13950 +
13951 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
13952 +#define _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
13953 +
13954 +struct ubicom32input_i2c_button {
13955 +       /*
13956 +        * Input event code (KEY_*, SW_*, etc)
13957 +        */
13958 +       int             code;
13959 +
13960 +       /*
13961 +        * Input event type (EV_KEY, EV_SW, etc)
13962 +        */
13963 +       int             type;
13964 +
13965 +       /*
13966 +        * Bit number of this button. (0 - ngpio)
13967 +        */
13968 +       int             bit;
13969 +
13970 +       /*
13971 +        * 1 for active low, 0 for active high
13972 +        */
13973 +       int             active_low;
13974 +};
13975 +
13976 +struct ubicom32input_i2c_platform_data {
13977 +       struct ubicom32input_i2c_button *buttons;
13978 +       int                             nbuttons;
13979 +
13980 +       /*
13981 +        * Optional poll interval, in ms, defaults to 100ms
13982 +        */
13983 +       int                             poll_interval;
13984 +
13985 +       /*
13986 +        * Option Name of this driver
13987 +        */
13988 +       const char                      *name;
13989 +};
13990 +
13991 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_I2C_H */
13992 --- /dev/null
13993 +++ b/arch/ubicom32/include/asm/ubicom32lcd.h
13994 @@ -0,0 +1,39 @@
13995 +/*
13996 + * arch/ubicom32/include/asm/ubicom32lcd.h
13997 + *   Ubicom32 architecture LCD driver platform data definitions.
13998 + *
13999 + * (C) Copyright 2009, Ubicom, Inc.
14000 + *
14001 + * This file is part of the Ubicom32 Linux Kernel Port.
14002 + *
14003 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14004 + * it and/or modify it under the terms of the GNU General Public License
14005 + * as published by the Free Software Foundation, either version 2 of the
14006 + * License, or (at your option) any later version.
14007 + *
14008 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14009 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14010 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14011 + * the GNU General Public License for more details.
14012 + *
14013 + * You should have received a copy of the GNU General Public License
14014 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14015 + * see <http://www.gnu.org/licenses/>.
14016 + *
14017 + * Ubicom32 implementation derived from (with many thanks):
14018 + *   arch/m68knommu
14019 + *   arch/blackfin
14020 + *   arch/parisc
14021 + */
14022 +#ifndef _ASM_UBICOM32_UBICOM32_LCD_H
14023 +#define _ASM_UBICOM32_UBICOM32_LCD_H
14024 +
14025 +struct ubicom32lcd_platform_data {
14026 +       /*
14027 +        * GPIO and polarity for VGH signal.  A FALSE polarity is active low, TRUE is active high.
14028 +        */
14029 +       int             vgh_gpio;
14030 +       bool            vgh_polarity;
14031 +};
14032 +
14033 +#endif /* _ASM_UBICOM32_UBICOM32_LCD_H */
14034 --- /dev/null
14035 +++ b/arch/ubicom32/include/asm/ubicom32ring.h
14036 @@ -0,0 +1,103 @@
14037 +/*
14038 + * arch/ubicom32/include/asm/ubicom32ring.h
14039 + * Userspace I/O platform driver for Ubicom32 ring buffers
14040 + *
14041 + * (C) Copyright 2009, Ubicom, Inc.
14042 + *
14043 + * This file is part of the Ubicom32 Linux Kernel Port.
14044 + *
14045 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14046 + * it and/or modify it under the terms of the GNU General Public License
14047 + * as published by the Free Software Foundation, either version 2 of the
14048 + * License, or (at your option) any later version.
14049 + *
14050 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14051 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14052 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14053 + * the GNU General Public License for more details.
14054 + *
14055 + * You should have received a copy of the GNU General Public License
14056 + * along with the Ubicom32 Linux Kernel Port.  If not,
14057 + * see <http://www.gnu.org/licenses/>.
14058 + */
14059 +
14060 +#ifndef _ASM_UBICOM32_UBICOM32RING_H
14061 +#define _ASM_UBICOM32_UBICOM32RING_H
14062 +
14063 +#define UIO_UBICOM32RING_REG_VERSION   2
14064 +
14065 +struct uio_ubicom32ring_desc {
14066 +       volatile unsigned int           head;
14067 +       volatile unsigned int           tail;
14068 +       unsigned int                    entries;
14069 +       volatile unsigned int           ring[0];
14070 +};
14071 +
14072 +struct uio_ubicom32ring_regs {
14073 +       unsigned int                    version;
14074 +
14075 +       /*
14076 +        * Magic type used to identify the ring set.  Each driver will
14077 +        * have a different magic value.
14078 +        */
14079 +       unsigned int                    magic;
14080 +
14081 +       /*
14082 +        * Registers defined by the driver
14083 +        */
14084 +       unsigned int                    regs_size;
14085 +       void                            *regs;
14086 +
14087 +       /*
14088 +        * The locations of the rings
14089 +        *
14090 +        * DO NOT ADD ANYTHING BELOW THIS LINE
14091 +        */
14092 +       unsigned int                    num_rings;
14093 +       struct uio_ubicom32ring_desc    *rings[0];
14094 +};
14095 +
14096 +/*
14097 + * ringtio_ring_flush
14098 + */
14099 +static inline void ringtio_ring_flush(struct uio_ubicom32ring_desc *rd)
14100 +{
14101 +       rd->head = rd->tail = 0;
14102 +}
14103 +
14104 +/*
14105 + * ringtio_ring_get
14106 + */
14107 +static inline int ringtio_ring_get(struct uio_ubicom32ring_desc *rd, void **val)
14108 +{
14109 +       if (rd->head == rd->tail) {
14110 +               return 0;
14111 +       }
14112 +
14113 +       *val = (void *)rd->ring[rd->head++];
14114 +       if (rd->head == rd->entries) {
14115 +               rd->head = 0;
14116 +       }
14117 +       return 1;
14118 +}
14119 +
14120 +/*
14121 + * ringtio_ring_put
14122 + */
14123 +static inline int ringtio_ring_put(struct uio_ubicom32ring_desc *rd, void *val)
14124 +{
14125 +       unsigned int newtail = rd->tail + 1;
14126 +       if (newtail == rd->entries) {
14127 +               newtail = 0;
14128 +       }
14129 +
14130 +       if (newtail == rd->head) {
14131 +               return 0;
14132 +       }
14133 +
14134 +       rd->ring[rd->tail] = (unsigned int)val;
14135 +       rd->tail = newtail;
14136 +       return 1;
14137 +}
14138 +
14139 +#endif /* _ASM_UBICOM32_UBICOM32RING_H */
14140 --- /dev/null
14141 +++ b/arch/ubicom32/include/asm/ubicom32sd.h
14142 @@ -0,0 +1,45 @@
14143 +/*
14144 + * arch/ubicom32/include/asm/ubicom32sd.h
14145 + *   Ubicom32SD public include file
14146 + *
14147 + * (C) Copyright 2009, Ubicom, Inc.
14148 + *
14149 + * This file is part of the Ubicom32 Linux Kernel Port.
14150 + *
14151 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14152 + * it and/or modify it under the terms of the GNU General Public License
14153 + * as published by the Free Software Foundation, either version 2 of the
14154 + * License, or (at your option) any later version.
14155 + *
14156 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14157 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14158 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14159 + * the GNU General Public License for more details.
14160 + *
14161 + * You should have received a copy of the GNU General Public License
14162 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14163 + * see <http://www.gnu.org/licenses/>.
14164 + */
14165 +#ifndef _ASM_UBICOM32_UBICOM32_SD_H
14166 +#define _ASM_UBICOM32_UBICOM32_SD_H
14167 +
14168 +struct ubicom32sd_card {
14169 +       /*
14170 +        * GPIOs of PWR, WP and CD lines.
14171 +        * Polarity is 1 for active high and 0 for active low
14172 +        */
14173 +       int                             pin_pwr;
14174 +       bool                            pwr_polarity;
14175 +       int                             pin_wp;
14176 +       bool                            wp_polarity;
14177 +       int                             pin_cd;
14178 +       bool                            cd_polarity;
14179 +};
14180 +
14181 +struct ubicom32sd_platform_data {
14182 +       int                     ncards;
14183 +
14184 +       struct ubicom32sd_card  *cards;
14185 +};
14186 +
14187 +#endif /* _ASM_UBICOM32_UBICOM32_SD_H */
14188 --- /dev/null
14189 +++ b/arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14190 @@ -0,0 +1,62 @@
14191 +/*
14192 + * arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14193 + *   Platform driver data definitions for GPIO based SPI driver.
14194 + *
14195 + * (C) Copyright 2009, Ubicom, Inc.
14196 + *
14197 + * This file is part of the Ubicom32 Linux Kernel Port.
14198 + *
14199 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14200 + * it and/or modify it under the terms of the GNU General Public License
14201 + * as published by the Free Software Foundation, either version 2 of the
14202 + * License, or (at your option) any later version.
14203 + *
14204 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14205 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14206 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14207 + * the GNU General Public License for more details.
14208 + *
14209 + * You should have received a copy of the GNU General Public License
14210 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14211 + * see <http://www.gnu.org/licenses/>.
14212 + *
14213 + * Ubicom32 implementation derived from (with many thanks):
14214 + *   arch/m68knommu
14215 + *   arch/blackfin
14216 + *   arch/parisc
14217 + */
14218 +#ifndef _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14219 +#define _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14220 +
14221 +struct ubicom32_spi_gpio_platform_data {
14222 +       /*
14223 +        * GPIO to use for MOSI, MISO, CLK
14224 +        */
14225 +       int     pin_mosi;
14226 +       int     pin_miso;
14227 +       int     pin_clk;
14228 +
14229 +       /*
14230 +        * Default state of CLK line
14231 +        */
14232 +       int     clk_default;
14233 +
14234 +       /*
14235 +        * Number of chip selects on this bus
14236 +        */
14237 +       int     num_chipselect;
14238 +
14239 +       /*
14240 +        * The bus number of this chip
14241 +        */
14242 +       int     bus_num;
14243 +};
14244 +
14245 +struct ubicom32_spi_gpio_controller_data {
14246 +       /*
14247 +        * GPIO to use for chip select
14248 +        */
14249 +       int     pin_cs;
14250 +};
14251 +
14252 +#endif /* _ASM_UBICOM32_UBICOM32_SPI_GPIO_H */
14253 --- /dev/null
14254 +++ b/arch/ubicom32/include/asm/ubicom32suart.h
14255 @@ -0,0 +1,36 @@
14256 +/*
14257 + * arch/ubicom32/include/asm/ubicom32suart.h
14258 + *   <TODO: Replace with short file description>
14259 + *
14260 + * (C) Copyright 2009, Ubicom, Inc.
14261 + *
14262 + * This file is part of the Ubicom32 Linux Kernel Port.
14263 + *
14264 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14265 + * it and/or modify it under the terms of the GNU General Public License
14266 + * as published by the Free Software Foundation, either version 2 of the
14267 + * License, or (at your option) any later version.
14268 + *
14269 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14270 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14271 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14272 + * the GNU General Public License for more details.
14273 + *
14274 + * You should have received a copy of the GNU General Public License
14275 + * along with the Ubicom32 Linux Kernel Port.  If not,
14276 + * see <http://www.gnu.org/licenses/>.
14277 + *
14278 + * Ubicom32 implementation derived from (with many thanks):
14279 + *   arch/m68knommu
14280 + *   arch/blackfin
14281 + *   arch/parisc
14282 + */
14283 +#ifndef _ASM_UBICOM32_UBICOM32_SUART_H
14284 +#define _ASM_UBICOM32_UBICOM32_SUART_H
14285 +
14286 +/*
14287 + * Platform resource id for serdes uart clock parameter
14288 + */
14289 +#define UBICOM32_SUART_IORESOURCE_CLOCK                (1)
14290 +
14291 +#endif /* _ASM_UBICOM32_UBICOM32_SUART_H */
14292 --- /dev/null
14293 +++ b/arch/ubicom32/include/asm/ubicom32-tio.h
14294 @@ -0,0 +1,42 @@
14295 +/*
14296 + * arch/ubicom32/include/asm/ubicom32-tio.h
14297 + *   Threaded I/O interface definitions.
14298 + *
14299 + * (C) Copyright 2009, Ubicom, Inc.
14300 + *
14301 + * This file is part of the Ubicom32 Linux Kernel Port.
14302 + *
14303 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14304 + * it and/or modify it under the terms of the GNU General Public License
14305 + * as published by the Free Software Foundation, either version 2 of the
14306 + * License, or (at your option) any later version.
14307 + *
14308 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14309 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14310 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14311 + * the GNU General Public License for more details.
14312 + *
14313 + * You should have received a copy of the GNU General Public License
14314 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14315 + * see <http://www.gnu.org/licenses/>.
14316 + *
14317 + * Ubicom32 implementation derived from (with many thanks):
14318 + *   arch/m68knommu
14319 + *   arch/blackfin
14320 + *   arch/parisc
14321 + */
14322 +#ifndef _ASM_UBICOM32_UBICOM32_TIO_H
14323 +#define _ASM_UBICOM32_UBICOM32_TIO_H
14324 +
14325 +extern u8_t usb_tio_read_u16(u32_t address, u16_t *data);
14326 +extern u8_t usb_tio_read_u8(u32_t address, u8_t *data);
14327 +
14328 +extern u8_t usb_tio_write_u16(u32_t address, u16_t data);
14329 +extern u8_t usb_tio_write_u8(u32_t address, u8_t data);
14330 +
14331 +extern u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes);
14332 +extern u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes);
14333 +extern u8_t usb_tio_write_fifo_sync(u32_t address, u32_t buffer, u32_t bytes);
14334 +extern void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx);
14335 +
14336 +#endif /* _ASM_UBICOM32_UBICOM32_TIO_H */
14337 --- /dev/null
14338 +++ b/arch/ubicom32/include/asm/ucontext.h
14339 @@ -0,0 +1,39 @@
14340 +/*
14341 + * arch/ubicom32/include/asm/ucontext.h
14342 + *   Definition of ucontext structure for Ubicom32 architecture.
14343 + *
14344 + * (C) Copyright 2009, Ubicom, Inc.
14345 + *
14346 + * This file is part of the Ubicom32 Linux Kernel Port.
14347 + *
14348 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14349 + * it and/or modify it under the terms of the GNU General Public License
14350 + * as published by the Free Software Foundation, either version 2 of the
14351 + * License, or (at your option) any later version.
14352 + *
14353 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14354 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14355 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14356 + * the GNU General Public License for more details.
14357 + *
14358 + * You should have received a copy of the GNU General Public License
14359 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14360 + * see <http://www.gnu.org/licenses/>.
14361 + *
14362 + * Ubicom32 implementation derived from (with many thanks):
14363 + *   arch/m68knommu
14364 + *   arch/blackfin
14365 + *   arch/parisc
14366 + */
14367 +#ifndef _ASM_UBICOM32_UCONTEXT_H
14368 +#define _ASM_UBICOM32_UCONTEXT_H
14369 +
14370 +struct ucontext {
14371 +       unsigned long     uc_flags;
14372 +       struct ucontext  *uc_link;
14373 +       stack_t           uc_stack;
14374 +       struct sigcontext         uc_mcontext;
14375 +       sigset_t          uc_sigmask;   /* mask last for extensibility */
14376 +};
14377 +
14378 +#endif /* _ASM_UBICOM32_UCONTEXT_H */
14379 --- /dev/null
14380 +++ b/arch/ubicom32/include/asm/unaligned.h
14381 @@ -0,0 +1,44 @@
14382 +/*
14383 + * arch/ubicom32/include/asm/unaligned.h
14384 + *   Ubicom32 architecture unaligned memory access definitions.
14385 + *
14386 + * (C) Copyright 2009, Ubicom, Inc.
14387 + *
14388 + * This file is part of the Ubicom32 Linux Kernel Port.
14389 + *
14390 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14391 + * it and/or modify it under the terms of the GNU General Public License
14392 + * as published by the Free Software Foundation, either version 2 of the
14393 + * License, or (at your option) any later version.
14394 + *
14395 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14396 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14397 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14398 + * the GNU General Public License for more details.
14399 + *
14400 + * You should have received a copy of the GNU General Public License
14401 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14402 + * see <http://www.gnu.org/licenses/>.
14403 + *
14404 + * Ubicom32 implementation derived from (with many thanks):
14405 + *   arch/m68knommu
14406 + *   arch/blackfin
14407 + *   arch/parisc
14408 + *
14409 + * TODO: This is a copy of arm unaligned handling that probably needs
14410 + * to be optimized for UBICOM32, but it works for now.
14411 + */
14412 +
14413 +#ifndef _ASM_UBICOM32_UNALIGNED_H
14414 +#define _ASM_UBICOM32_UNALIGNED_H
14415 +
14416 +#include <asm/types.h>
14417 +
14418 +#include <linux/unaligned/le_byteshift.h>
14419 +#include <linux/unaligned/be_byteshift.h>
14420 +#include <linux/unaligned/generic.h>
14421 +
14422 +#define get_unaligned  __get_unaligned_be
14423 +#define put_unaligned  __put_unaligned_be
14424 +
14425 +#endif /* _ASM_UBICOM32_UNALIGNED_H */
14426 --- /dev/null
14427 +++ b/arch/ubicom32/include/asm/unistd.h
14428 @@ -0,0 +1,400 @@
14429 +/*
14430 + * arch/ubicom32/include/asm/unistd.h
14431 + *   Ubicom32 architecture syscall definitions.
14432 + *
14433 + * (C) Copyright 2009, Ubicom, Inc.
14434 + *
14435 + * This file is part of the Ubicom32 Linux Kernel Port.
14436 + *
14437 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14438 + * it and/or modify it under the terms of the GNU General Public License
14439 + * as published by the Free Software Foundation, either version 2 of the
14440 + * License, or (at your option) any later version.
14441 + *
14442 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14443 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14444 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14445 + * the GNU General Public License for more details.
14446 + *
14447 + * You should have received a copy of the GNU General Public License
14448 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14449 + * see <http://www.gnu.org/licenses/>.
14450 + *
14451 + * Ubicom32 implementation derived from (with many thanks):
14452 + *   arch/m68knommu
14453 + *   arch/blackfin
14454 + *   arch/parisc
14455 + */
14456 +#ifndef _ASM_UBICOM32_UNISTD_H
14457 +#define _ASM_UBICOM32_UNISTD_H
14458 +
14459 +/*
14460 + * This file contains the system call numbers.
14461 + */
14462 +
14463 +#define __NR_restart_syscall      0
14464 +#define __NR_exit                1
14465 +#define __NR_fork                2
14466 +#define __NR_read                3
14467 +#define __NR_write               4
14468 +#define __NR_open                5
14469 +#define __NR_close               6
14470 +#define __NR_waitpid             7
14471 +#define __NR_creat               8
14472 +#define __NR_link                9
14473 +#define __NR_unlink             10
14474 +#define __NR_execve             11
14475 +#define __NR_chdir              12
14476 +#define __NR_time               13
14477 +#define __NR_mknod              14
14478 +#define __NR_chmod              15
14479 +#define __NR_chown              16
14480 +#define __NR_break              17
14481 +#define __NR_oldstat            18
14482 +#define __NR_lseek              19
14483 +#define __NR_getpid             20
14484 +#define __NR_mount              21
14485 +#define __NR_umount             22
14486 +#define __NR_setuid             23
14487 +#define __NR_getuid             24
14488 +#define __NR_stime              25
14489 +#define __NR_ptrace             26
14490 +#define __NR_alarm              27
14491 +#define __NR_oldfstat           28
14492 +#define __NR_pause              29
14493 +#define __NR_utime              30
14494 +#define __NR_stty               31
14495 +#define __NR_gtty               32
14496 +#define __NR_access             33
14497 +#define __NR_nice               34
14498 +#define __NR_ftime              35
14499 +#define __NR_sync               36
14500 +#define __NR_kill               37
14501 +#define __NR_rename             38
14502 +#define __NR_mkdir              39
14503 +#define __NR_rmdir              40
14504 +#define __NR_dup                41
14505 +#define __NR_pipe               42
14506 +#define __NR_times              43
14507 +#define __NR_prof               44
14508 +#define __NR_brk                45
14509 +#define __NR_setgid             46
14510 +#define __NR_getgid             47
14511 +#define __NR_signal             48
14512 +#define __NR_geteuid            49
14513 +#define __NR_getegid            50
14514 +#define __NR_acct               51
14515 +#define __NR_umount2            52
14516 +#define __NR_lock               53
14517 +#define __NR_ioctl              54
14518 +#define __NR_fcntl              55
14519 +#define __NR_mpx                56
14520 +#define __NR_setpgid            57
14521 +#define __NR_ulimit             58
14522 +#define __NR_oldolduname        59
14523 +#define __NR_umask              60
14524 +#define __NR_chroot             61
14525 +#define __NR_ustat              62
14526 +#define __NR_dup2               63
14527 +#define __NR_getppid            64
14528 +#define __NR_getpgrp            65
14529 +#define __NR_setsid             66
14530 +#define __NR_sigaction          67
14531 +#define __NR_sgetmask           68
14532 +#define __NR_ssetmask           69
14533 +#define __NR_setreuid           70
14534 +#define __NR_setregid           71
14535 +#define __NR_sigsuspend                 72
14536 +#define __NR_sigpending                 73
14537 +#define __NR_sethostname        74
14538 +#define __NR_setrlimit          75
14539 +#define __NR_getrlimit          76
14540 +#define __NR_getrusage          77
14541 +#define __NR_gettimeofday       78
14542 +#define __NR_settimeofday       79
14543 +#define __NR_getgroups          80
14544 +#define __NR_setgroups          81
14545 +#define __NR_select             82
14546 +#define __NR_symlink            83
14547 +#define __NR_oldlstat           84
14548 +#define __NR_readlink           85
14549 +#define __NR_uselib             86
14550 +#define __NR_swapon             87
14551 +#define __NR_reboot             88
14552 +#define __NR_readdir            89
14553 +#define __NR_mmap               90
14554 +#define __NR_munmap             91
14555 +#define __NR_truncate           92
14556 +#define __NR_ftruncate          93
14557 +#define __NR_fchmod             94
14558 +#define __NR_fchown             95
14559 +#define __NR_getpriority        96
14560 +#define __NR_setpriority        97
14561 +#define __NR_profil             98
14562 +#define __NR_statfs             99
14563 +#define __NR_fstatfs           100
14564 +#define __NR_ioperm            101
14565 +#define __NR_socketcall                102
14566 +#define __NR_syslog            103
14567 +#define __NR_setitimer         104
14568 +#define __NR_getitimer         105
14569 +#define __NR_stat              106
14570 +#define __NR_lstat             107
14571 +#define __NR_fstat             108
14572 +#define __NR_olduname          109
14573 +#define __NR_iopl              /* 110 */ not supported
14574 +#define __NR_vhangup           111
14575 +#define __NR_idle              /* 112 */ Obsolete
14576 +#define __NR_vm86              /* 113 */ not supported
14577 +#define __NR_wait4             114
14578 +#define __NR_swapoff           115
14579 +#define __NR_sysinfo           116
14580 +#define __NR_ipc               117
14581 +#define __NR_fsync             118
14582 +#define __NR_sigreturn         119
14583 +#define __NR_clone             120
14584 +#define __NR_setdomainname     121
14585 +#define __NR_uname             122
14586 +#define __NR_cacheflush                123
14587 +#define __NR_adjtimex          124
14588 +#define __NR_mprotect          125
14589 +#define __NR_sigprocmask       126
14590 +#define __NR_create_module     127
14591 +#define __NR_init_module       128
14592 +#define __NR_delete_module     129
14593 +#define __NR_get_kernel_syms   130
14594 +#define __NR_quotactl          131
14595 +#define __NR_getpgid           132
14596 +#define __NR_fchdir            133
14597 +#define __NR_bdflush           134
14598 +#define __NR_sysfs             135
14599 +#define __NR_personality       136
14600 +#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
14601 +#define __NR_setfsuid          138
14602 +#define __NR_setfsgid          139
14603 +#define __NR__llseek           140
14604 +#define __NR_getdents          141
14605 +#define __NR__newselect                142
14606 +#define __NR_flock             143
14607 +#define __NR_msync             144
14608 +#define __NR_readv             145
14609 +#define __NR_writev            146
14610 +#define __NR_getsid            147
14611 +#define __NR_fdatasync         148
14612 +#define __NR__sysctl           149
14613 +#define __NR_mlock             150
14614 +#define __NR_munlock           151
14615 +#define __NR_mlockall          152
14616 +#define __NR_munlockall                153
14617 +#define __NR_sched_setparam            154
14618 +#define __NR_sched_getparam            155
14619 +#define __NR_sched_setscheduler                156
14620 +#define __NR_sched_getscheduler                157
14621 +#define __NR_sched_yield               158
14622 +#define __NR_sched_get_priority_max    159
14623 +#define __NR_sched_get_priority_min    160
14624 +#define __NR_sched_rr_get_interval     161
14625 +#define __NR_nanosleep         162
14626 +#define __NR_mremap            163
14627 +#define __NR_setresuid         164
14628 +#define __NR_getresuid         165
14629 +#define __NR_getpagesize       166
14630 +#define __NR_query_module      167
14631 +#define __NR_poll              168
14632 +#define __NR_nfsservctl                169
14633 +#define __NR_setresgid         170
14634 +#define __NR_getresgid         171
14635 +#define __NR_prctl             172
14636 +#define __NR_rt_sigreturn      173
14637 +#define __NR_rt_sigaction      174
14638 +#define __NR_rt_sigprocmask    175
14639 +#define __NR_rt_sigpending     176
14640 +#define __NR_rt_sigtimedwait   177
14641 +#define __NR_rt_sigqueueinfo   178
14642 +#define __NR_rt_sigsuspend     179
14643 +#define __NR_pread64           180
14644 +#define __NR_pwrite64          181
14645 +#define __NR_lchown            182
14646 +#define __NR_getcwd            183
14647 +#define __NR_capget            184
14648 +#define __NR_capset            185
14649 +#define __NR_sigaltstack       186
14650 +#define __NR_sendfile          187
14651 +#define __NR_getpmsg           188     /* some people actually want streams */
14652 +#define __NR_putpmsg           189     /* some people actually want streams */
14653 +#define __NR_vfork             190
14654 +#define __NR_ugetrlimit                191
14655 +#define __NR_mmap2             192
14656 +#define __NR_truncate64                193
14657 +#define __NR_ftruncate64       194
14658 +#define __NR_stat64            195
14659 +#define __NR_lstat64           196
14660 +#define __NR_fstat64           197
14661 +#define __NR_chown32           198
14662 +#define __NR_getuid32          199
14663 +#define __NR_getgid32          200
14664 +#define __NR_geteuid32         201
14665 +#define __NR_getegid32         202
14666 +#define __NR_setreuid32                203
14667 +#define __NR_setregid32                204
14668 +#define __NR_getgroups32       205
14669 +#define __NR_setgroups32       206
14670 +#define __NR_fchown32          207
14671 +#define __NR_setresuid32       208
14672 +#define __NR_getresuid32       209
14673 +#define __NR_setresgid32       210
14674 +#define __NR_getresgid32       211
14675 +#define __NR_lchown32          212
14676 +#define __NR_setuid32          213
14677 +#define __NR_setgid32          214
14678 +#define __NR_setfsuid32                215
14679 +#define __NR_setfsgid32                216
14680 +#define __NR_pivot_root                217
14681 +#define __NR_getdents64                220
14682 +#define __NR_gettid            221
14683 +#define __NR_tkill             222
14684 +#define __NR_setxattr          223
14685 +#define __NR_lsetxattr         224
14686 +#define __NR_fsetxattr         225
14687 +#define __NR_getxattr          226
14688 +#define __NR_lgetxattr         227
14689 +#define __NR_fgetxattr         228
14690 +#define __NR_listxattr         229
14691 +#define __NR_llistxattr                230
14692 +#define __NR_flistxattr                231
14693 +#define __NR_removexattr       232
14694 +#define __NR_lremovexattr      233
14695 +#define __NR_fremovexattr      234
14696 +#define __NR_futex             235
14697 +#define __NR_sendfile64                236
14698 +#define __NR_mincore           237
14699 +#define __NR_madvise           238
14700 +#define __NR_fcntl64           239
14701 +#define __NR_readahead         240
14702 +#define __NR_io_setup          241
14703 +#define __NR_io_destroy                242
14704 +#define __NR_io_getevents      243
14705 +#define __NR_io_submit         244
14706 +#define __NR_io_cancel         245
14707 +#define __NR_fadvise64         246
14708 +#define __NR_exit_group                247
14709 +#define __NR_lookup_dcookie    248
14710 +#define __NR_epoll_create      249
14711 +#define __NR_epoll_ctl         250
14712 +#define __NR_epoll_wait                251
14713 +#define __NR_remap_file_pages  252
14714 +#define __NR_set_tid_address   253
14715 +#define __NR_timer_create      254
14716 +#define __NR_timer_settime     255
14717 +#define __NR_timer_gettime     256
14718 +#define __NR_timer_getoverrun  257
14719 +#define __NR_timer_delete      258
14720 +#define __NR_clock_settime     259
14721 +#define __NR_clock_gettime     260
14722 +#define __NR_clock_getres      261
14723 +#define __NR_clock_nanosleep   262
14724 +#define __NR_statfs64          263
14725 +#define __NR_fstatfs64         264
14726 +#define __NR_tgkill            265
14727 +#define __NR_utimes            266
14728 +#define __NR_fadvise64_64      267
14729 +#define __NR_mbind             268
14730 +#define __NR_get_mempolicy     269
14731 +#define __NR_set_mempolicy     270
14732 +#define __NR_mq_open           271
14733 +#define __NR_mq_unlink         272
14734 +#define __NR_mq_timedsend      273
14735 +#define __NR_mq_timedreceive   274
14736 +#define __NR_mq_notify         275
14737 +#define __NR_mq_getsetattr     276
14738 +#define __NR_waitid            277
14739 +#define __NR_vserver           278
14740 +#define __NR_add_key           279
14741 +#define __NR_request_key       280
14742 +#define __NR_keyctl            281
14743 +#define __NR_ioprio_set                282
14744 +#define __NR_ioprio_get                283
14745 +#define __NR_inotify_init      284
14746 +#define __NR_inotify_add_watch 285
14747 +#define __NR_inotify_rm_watch  286
14748 +#define __NR_migrate_pages     287
14749 +#define __NR_openat            288
14750 +#define __NR_mkdirat           289
14751 +#define __NR_mknodat           290
14752 +#define __NR_fchownat          291
14753 +#define __NR_futimesat         292
14754 +#define __NR_fstatat64         293
14755 +#define __NR_unlinkat          294
14756 +#define __NR_renameat          295
14757 +#define __NR_linkat            296
14758 +#define __NR_symlinkat         297
14759 +#define __NR_readlinkat                298
14760 +#define __NR_fchmodat          299
14761 +#define __NR_faccessat         300
14762 +#define __NR_pselect6          301
14763 +#define __NR_ppoll             302
14764 +#define __NR_unshare           303
14765 +#define __NR_set_robust_list   304
14766 +#define __NR_get_robust_list   305
14767 +#define __NR_splice            306
14768 +#define __NR_sync_file_range   307
14769 +#define __NR_tee               308
14770 +#define __NR_vmsplice          309
14771 +#define __NR_move_pages                310
14772 +#define __NR_sched_setaffinity 311
14773 +#define __NR_sched_getaffinity 312
14774 +#define __NR_kexec_load                313
14775 +#define __NR_getcpu            314
14776 +#define __NR_epoll_pwait       315
14777 +#define __NR_utimensat         316
14778 +#define __NR_signalfd          317
14779 +#define __NR_timerfd_create    318
14780 +#define __NR_eventfd           319
14781 +#define __NR_fallocate         320
14782 +#define __NR_timerfd_settime   321
14783 +#define __NR_timerfd_gettime   322
14784 +#define __NR_signalfd4         323
14785 +#define __NR_eventfd2          324
14786 +#define __NR_epoll_create1     325
14787 +#define __NR_dup3              326
14788 +#define __NR_pipe2             327
14789 +#define __NR_inotify_init1     328
14790 +
14791 +#ifdef __KERNEL__
14792 +
14793 +#define NR_syscalls            329
14794 +
14795 +#define __ARCH_WANT_IPC_PARSE_VERSION
14796 +#define __ARCH_WANT_OLD_READDIR
14797 +#define __ARCH_WANT_OLD_STAT
14798 +#define __ARCH_WANT_STAT64
14799 +#define __ARCH_WANT_SYS_ALARM
14800 +#define __ARCH_WANT_SYS_GETHOSTNAME
14801 +#define __ARCH_WANT_SYS_PAUSE
14802 +#define __ARCH_WANT_SYS_SGETMASK
14803 +#define __ARCH_WANT_SYS_SIGNAL
14804 +#define __ARCH_WANT_SYS_TIME
14805 +#define __ARCH_WANT_SYS_UTIME
14806 +#define __ARCH_WANT_SYS_WAITPID
14807 +#define __ARCH_WANT_SYS_SOCKETCALL
14808 +#define __ARCH_WANT_SYS_FADVISE64
14809 +#define __ARCH_WANT_SYS_GETPGRP
14810 +#define __ARCH_WANT_SYS_LLSEEK
14811 +#define __ARCH_WANT_SYS_NICE
14812 +#define __ARCH_WANT_SYS_OLD_GETRLIMIT
14813 +#define __ARCH_WANT_SYS_OLDUMOUNT
14814 +#define __ARCH_WANT_SYS_SIGPENDING
14815 +#define __ARCH_WANT_SYS_SIGPROCMASK
14816 +#define __ARCH_WANT_SYS_RT_SIGACTION
14817 +
14818 +/*
14819 + * "Conditional" syscalls
14820 + *
14821 + * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
14822 + * but it doesn't work on all toolchains, so we just do it by hand
14823 + */
14824 +//#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
14825 +#define cond_syscall(x) long x(void)  __attribute__((weak,alias("sys_ni_syscall")))
14826 +#endif /* __KERNEL__ */
14827 +
14828 +#endif /* _ASM_UBICOM32_UNISTD_H */
14829 --- /dev/null
14830 +++ b/arch/ubicom32/include/asm/user.h
14831 @@ -0,0 +1,82 @@
14832 +/*
14833 + * arch/ubicom32/include/asm/user.h
14834 + *   Ubicom32 architecture core file definitions.
14835 + *
14836 + * (C) Copyright 2009, Ubicom, Inc.
14837 + *
14838 + * This file is part of the Ubicom32 Linux Kernel Port.
14839 + *
14840 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14841 + * it and/or modify it under the terms of the GNU General Public License
14842 + * as published by the Free Software Foundation, either version 2 of the
14843 + * License, or (at your option) any later version.
14844 + *
14845 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14846 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14847 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14848 + * the GNU General Public License for more details.
14849 + *
14850 + * You should have received a copy of the GNU General Public License
14851 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14852 + * see <http://www.gnu.org/licenses/>.
14853 + *
14854 + * Ubicom32 implementation derived from (with many thanks):
14855 + *   arch/m68knommu
14856 + *   arch/blackfin
14857 + *   arch/parisc
14858 + */
14859 +#ifndef _ASM_UBICOM32_USER_H
14860 +#define _ASM_UBICOM32_USER_H
14861 +
14862 +#include <asm/ptrace.h>
14863 +#include <asm/page.h>
14864 +/*
14865 + * Adapted from <asm-powerpc/user.h>
14866 + *
14867 + * Core file format: The core file is written in such a way that gdb
14868 + * can understand it and provide useful information to the user (under
14869 + * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
14870 + * are as follows:
14871 + *
14872 + *  upage: 1 page consisting of a user struct that tells gdb
14873 + *     what is present in the file.  Directly after this is a
14874 + *     copy of the task_struct, which is currently not used by gdb,
14875 + *     but it may come in handy at some point.  All of the registers
14876 + *     are stored as part of the upage.  The upage should always be
14877 + *     only one page long.
14878 + *  data: The data segment follows next.  We use current->end_text to
14879 + *     current->brk to pick up all of the user variables, plus any memory
14880 + *     that may have been sbrk'ed.  No attempt is made to determine if a
14881 + *     page is demand-zero or if a page is totally unused, we just cover
14882 + *     the entire range.  All of the addresses are rounded in such a way
14883 + *     that an integral number of pages is written.
14884 + *  stack: We need the stack information in order to get a meaningful
14885 + *     backtrace.  We need to write the data from usp to
14886 + *     current->start_stack, so we round each of these in order to be able
14887 + *     to write an integer number of pages.
14888 + */
14889 +
14890 +struct user_ubicom32fp_struct {
14891 +};
14892 +
14893 +struct user {
14894 +       struct pt_regs  regs;                   /* entire machine state */
14895 +       size_t          u_tsize;                /* text size (pages) */
14896 +       size_t          u_dsize;                /* data size (pages) */
14897 +       size_t          u_ssize;                /* stack size (pages) */
14898 +       unsigned long   start_code;             /* text starting address */
14899 +       unsigned long   start_data;             /* data starting address */
14900 +       unsigned long   start_stack;            /* stack starting address */
14901 +       long int        signal;                 /* signal causing core dump */
14902 +       unsigned long   u_ar0;                  /* help gdb find registers */
14903 +       unsigned long   magic;                  /* identifies a core file */
14904 +       char            u_comm[32];             /* user command name */
14905 +};
14906 +
14907 +#define NBPG                   PAGE_SIZE
14908 +#define UPAGES                 1
14909 +#define HOST_TEXT_START_ADDR   (u.start_code)
14910 +#define HOST_DATA_START_ADDR   (u.start_data)
14911 +#define HOST_STACK_END_ADDR    (u.start_stack + u.u_ssize * NBPG)
14912 +
14913 +#endif /* _ASM_UBICOM32_USER_H */
14914 --- /dev/null
14915 +++ b/arch/ubicom32/include/asm/vdc_tio.h
14916 @@ -0,0 +1,129 @@
14917 +/*
14918 + * arch/ubicom32/include/asm/vdc_tio.h
14919 + *   Ubicom32 architecture VDC TIO definitions.
14920 + *
14921 + * (C) Copyright 2009, Ubicom, Inc.
14922 + *
14923 + * This file is part of the Ubicom32 Linux Kernel Port.
14924 + *
14925 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14926 + * it and/or modify it under the terms of the GNU General Public License
14927 + * as published by the Free Software Foundation, either version 2 of the
14928 + * License, or (at your option) any later version.
14929 + *
14930 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14931 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14932 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14933 + * the GNU General Public License for more details.
14934 + *
14935 + * You should have received a copy of the GNU General Public License
14936 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14937 + * see <http://www.gnu.org/licenses/>.
14938 + *
14939 + * Ubicom32 implementation derived from (with many thanks):
14940 + *   arch/m68knommu
14941 + *   arch/blackfin
14942 + *   arch/parisc
14943 + */
14944 +#ifndef _ASM_UBICOM32_VDC_TIO_H
14945 +#define _ASM_UBICOM32_VDC_TIO_H
14946 +
14947 +#include <asm/devtree.h>
14948 +
14949 +#define VDCTIO_VP_VERSION                      5
14950 +
14951 +#define VDCTIO_SCALE_FLAG_VSUB                 (1 << 9)
14952 +#define VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER       (1 << 8)
14953 +#define VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER      (1 << 7)
14954 +#define VDCTIO_SCALE_FLAG_YUV                  (1 << 6)
14955 +#define VDCTIO_SCALE_FLAG_VRANGE_16_255                (1 << 5)
14956 +#define VDCTIO_SCALE_FLAG_VRANGE_0_255         (1 << 4)
14957 +#define VDCTIO_SCALE_FLAG_HSUB_2_1             (1 << 3)
14958 +#define VDCTIO_SCALE_FLAG_HSUB_1_1             (1 << 2)
14959 +#define VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER     (1 << 1)
14960 +#define VDCTIO_SCALE_FLAG_ENABLE               (1 << 0)
14961 +
14962 +#define VDCTIO_NEXT_FRAME_FLAG_YUV_BIT         0
14963 +#define VDCTIO_NEXT_FRAME_FLAG_YUV             (1 << (VDCTIO_NEXT_FRAME_FLAG_YUV_BIT))
14964 +
14965 +#define VDCTIO_CAPS_SUPPORTS_SCALING           (1 << 0)
14966 +
14967 +#define VDCTIO_COMMAND_START                   (1 << 3)
14968 +#define VDCTIO_COMMAND_SET_COEFF               (1 << 2)
14969 +#define VDCTIO_COMMAND_SET_LUT                 (1 << 1)
14970 +#define VDCTIO_COMMAND_SET_SCALE_MODE          (1 << 0)
14971 +
14972 +/*
14973 + * Command / Data registers to access the VDC
14974 + */
14975 +struct vdc_tio_vp_regs {
14976 +       /*
14977 +        * Version of this TIO register map
14978 +        */
14979 +       u32_t           version;
14980 +
14981 +       volatile u32_t  command;
14982 +
14983 +       /*
14984 +        * Next frame pointer, when the command VDCTIO_COMMAND_SET_FRAME_BUFFER is set,
14985 +        * the vdc will take the pointer here and display it.
14986 +        */
14987 +       void            *next_frame;
14988 +       u32_t           next_frame_flags;
14989 +
14990 +       /*
14991 +        * These map directly into the PIXP registers 0x20-0x80.  
14992 +        * DO NOT change the order of these three variables.
14993 +        */
14994 +       u32_t           red_lut[6];
14995 +       u32_t           blue_lut[6];
14996 +       u32_t           green_lut[13];
14997 +
14998 +       /*
14999 +        * These map directly into the PIXP registers 0x04, 0x08
15000 +        */
15001 +       u32_t           coeff0;
15002 +       u32_t           coeff1;
15003 +
15004 +       /*
15005 +        * There are used to set the scaling parameters
15006 +        */
15007 +       u32_t           x_in;
15008 +       u32_t           x_out;
15009 +       u32_t           y_in;
15010 +       u32_t           y_out;
15011 +       u32_t           scale_flags;
15012 +
15013 +       /*
15014 +        * Current frame number, monotonically increasing number
15015 +        */
15016 +       u32_t           frame_number;
15017 +
15018 +       /*
15019 +        * These variables tell the guest OS what the underlying hardware looks like
15020 +        */
15021 +       u32_t           caps;
15022 +       u32_t           xres;
15023 +       u32_t           yres;
15024 +       u32_t           fb_align;
15025 +       u8_t            bpp;
15026 +       u8_t            rbits;
15027 +       u8_t            gbits;
15028 +       u8_t            bbits;
15029 +       u8_t            rshift;
15030 +       u8_t            gshift;
15031 +       u8_t            bshift;
15032 +};
15033 +
15034 +/*
15035 + * Devtree node for VDC
15036 + */
15037 +struct vdc_tio_node {
15038 +       struct devtree_node     dn;
15039 +
15040 +       struct vdc_tio_vp_regs  *regs;
15041 +};
15042 +
15043 +extern void vdc_tio_init(void);
15044 +
15045 +#endif /* _ASM_UBICOM32_VDC_TIO_H */
15046 --- /dev/null
15047 +++ b/arch/ubicom32/include/asm/vga.h
15048 @@ -0,0 +1,71 @@
15049 +/*
15050 + * arch/ubicom32/include/asm/vga.h
15051 + *   Ubicom32 low level  VGA/frame buffer definitions.
15052 + *
15053 + * (C) Copyright 2009, Ubicom, Inc.
15054 + * (c) 1998 Martin Mares <mj@ucw.cz>
15055 + *
15056 + * This file is part of the Ubicom32 Linux Kernel Port.
15057 + *
15058 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15059 + * it and/or modify it under the terms of the GNU General Public License
15060 + * as published by the Free Software Foundation, either version 2 of the
15061 + * License, or (at your option) any later version.
15062 + *
15063 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15064 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15065 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15066 + * the GNU General Public License for more details.
15067 + *
15068 + * You should have received a copy of the GNU General Public License
15069 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15070 + * see <http://www.gnu.org/licenses/>.
15071 + *
15072 + * Ubicom32 implementation derived from (with many thanks):
15073 + *   arch/m68knommu
15074 + *   arch/blackfin
15075 + *   arch/parisc
15076 + */
15077 +
15078 +#ifndef _ASM_UBICOM32_VGA_H
15079 +#define _ASM_UBICOM32_VGA_H
15080 +
15081 +#include <asm/byteorder.h>
15082 +
15083 +/*
15084 + *     On the PC, we can just recalculate addresses and then
15085 + *     access the videoram directly without any black magic.
15086 + */
15087 +
15088 +#define VGA_MAP_MEM(x, s)      (0xb0000000L + (unsigned long)(x))
15089 +
15090 +#define vga_readb(x)   (*(x))
15091 +#define vga_writeb(x, y)       (*(y) = (x))
15092 +
15093 +#define VT_BUF_HAVE_RW
15094 +/*
15095 + *  These are only needed for supporting VGA or MDA text mode, which use little
15096 + *  endian byte ordering.
15097 + *  In other cases, we can optimize by using native byte ordering and
15098 + *  <linux/vt_buffer.h> has already done the right job for us.
15099 + */
15100 +
15101 +#undef scr_writew
15102 +#undef scr_readw
15103 +
15104 +static inline void scr_writew(u16 val, volatile u16 *addr)
15105 +{
15106 +       *addr = cpu_to_le16(val);
15107 +}
15108 +
15109 +static inline u16 scr_readw(volatile const u16 *addr)
15110 +{
15111 +       return le16_to_cpu(*addr);
15112 +}
15113 +
15114 +#define scr_memcpyw(d, s, c) memcpy(d, s, c)
15115 +#define scr_memmovew(d, s, c) memmove(d, s, c)
15116 +#define VT_BUF_HAVE_MEMCPYW
15117 +#define VT_BUF_HAVE_MEMMOVEW
15118 +
15119 +#endif /* _ASM_UBICOM32_VGA_H */
15120 --- /dev/null
15121 +++ b/arch/ubicom32/include/asm/xor.h
15122 @@ -0,0 +1,33 @@
15123 +/*
15124 + * arch/ubicom32/include/asm/xor.h
15125 + *   Generic xor.h definitions for Ubicom32 architecture.
15126 + *
15127 + * (C) Copyright 2009, Ubicom, Inc.
15128 + *
15129 + * This file is part of the Ubicom32 Linux Kernel Port.
15130 + *
15131 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15132 + * it and/or modify it under the terms of the GNU General Public License
15133 + * as published by the Free Software Foundation, either version 2 of the
15134 + * License, or (at your option) any later version.
15135 + *
15136 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15137 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15138 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15139 + * the GNU General Public License for more details.
15140 + *
15141 + * You should have received a copy of the GNU General Public License
15142 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15143 + * see <http://www.gnu.org/licenses/>.
15144 + *
15145 + * Ubicom32 implementation derived from (with many thanks):
15146 + *   arch/m68knommu
15147 + *   arch/blackfin
15148 + *   arch/parisc
15149 + */
15150 +#ifndef _ASM_UBICOM32_XOR_H
15151 +#define _ASM_UBICOM32_XOR_H
15152 +
15153 +#include <asm-generic/xor.h>
15154 +
15155 +#endif /* _ASM_UBICOM32_XOR_H */
15156 --- /dev/null
15157 +++ b/arch/ubicom32/Kconfig
15158 @@ -0,0 +1,455 @@
15159 +#
15160 +# For a description of the syntax of this configuration file,
15161 +# see Documentation/kbuild/kconfig-language.txt.
15162 +#
15163 +
15164 +mainmenu "uClinux/ubicom32 (w/o MMU) Kernel Configuration"
15165 +
15166 +config RAMBASE
15167 +       hex
15168 +       default "0x40000000"
15169 +       help
15170 +               Define the address that RAM starts at.
15171 +
15172 +config UBICOM32
15173 +       bool
15174 +       select HAVE_OPROFILE
15175 +       default y
15176 +
15177 +config RAMKERNEL
15178 +       bool
15179 +       default y
15180 +
15181 +config CPU_BIG_ENDIAN
15182 +       bool
15183 +       default y
15184 +
15185 +config FORCE_MAX_ZONEORDER
15186 +       int
15187 +       default "14"
15188 +
15189 +config HAVE_CLK
15190 +       bool
15191 +       default y
15192 +
15193 +config MMU
15194 +       bool
15195 +       default n
15196 +
15197 +config FPU
15198 +       bool
15199 +       default n
15200 +
15201 +config ZONE_DMA
15202 +       bool
15203 +       default y
15204 +
15205 +config RWSEM_GENERIC_SPINLOCK
15206 +       bool
15207 +       default y
15208 +
15209 +config RWSEM_XCHGADD_ALGORITHM
15210 +       bool
15211 +       default n
15212 +
15213 +config ARCH_HAS_ILOG2_U32
15214 +       bool
15215 +       default n
15216 +
15217 +config ARCH_HAS_ILOG2_U64
15218 +       bool
15219 +       default n
15220 +
15221 +config GENERIC_FIND_NEXT_BIT
15222 +       bool
15223 +       default y
15224 +
15225 +config GENERIC_GPIO
15226 +       bool
15227 +       default y
15228 +
15229 +config GPIOLIB
15230 +       bool
15231 +       default y
15232 +
15233 +config GENERIC_HWEIGHT
15234 +       bool
15235 +       default y
15236 +
15237 +config GENERIC_HARDIRQS
15238 +       bool
15239 +       default y
15240 +
15241 +config STACKTRACE_SUPPORT
15242 +       bool
15243 +       default y
15244 +
15245 +config LOCKDEP_SUPPORT
15246 +       bool
15247 +       default y
15248 +
15249 +config GENERIC_CALIBRATE_DELAY
15250 +       bool
15251 +       default y
15252 +
15253 +config GENERIC_TIME
15254 +       bool
15255 +       default y
15256 +
15257 +config TIME_LOW_RES
15258 +       bool
15259 +       default y
15260 +
15261 +config GENERIC_CLOCKEVENTS
15262 +       bool
15263 +       default y
15264 +
15265 +config GENERIC_CLOCKEVENTS_BROADCAST
15266 +       bool
15267 +       depends on GENERIC_CLOCKEVENTS
15268 +       default y if SMP && !LOCAL_TIMERS
15269 +
15270 +config NO_IOPORT
15271 +       def_bool y
15272 +
15273 +config ARCH_SUPPORTS_AOUT
15274 +       def_bool y
15275 +
15276 +config IRQ_PER_CPU
15277 +       bool
15278 +       default y
15279 +
15280 +config SCHED_NO_NO_OMIT_FRAME_POINTER
15281 +       bool
15282 +       default y
15283 +
15284 +menu "Processor type and features"
15285 +
15286 +config BRD_32MB
15287 +       bool
15288 +       depends on IP5160EVAL
15289 +       help
15290 +               Board has 32MB of RAM on it.  It is a hidden option used to select default for size of RAM
15291 +       default n
15292 +
15293 +config BRD_64MB
15294 +       bool
15295 +       depends on IP7145DPF || IP7160RGW || IP7160BRINGUP || IP7160DPF || IP5170DPF || IP5160DEV
15296 +       help
15297 +               Board has 64MB of RAM on it.  It is a hidden option used to select default for size of RAM
15298 +       default n
15299 +
15300 +config BRD_128MB
15301 +       bool
15302 +       depends on IP7500MODULE || IP7500AV || IP7500MEDIA
15303 +       help
15304 +               Board has 128MB of RAM on it.  It is a hidden option used to select default for size of RAM
15305 +       default n
15306 +
15307 +comment "Processor type will be selected by Board"
15308 +
15309 +config UBICOM32_V3
15310 +       bool
15311 +       help
15312 +         Ubicom IP5xxx series processor support.
15313 +
15314 +config UBICOM32_V4
15315 +       bool
15316 +       help
15317 +         Ubicom IP7xxx series processor support.
15318 +
15319 +comment "Board"
15320 +choice
15321 +       prompt "Board type"
15322 +       help
15323 +               Select your board.
15324 +
15325 +config NOBOARD
15326 +       bool "No board selected"
15327 +       help
15328 +               Default. Don't select any board specific config. Will not build unless you change!
15329 +
15330 +# Add your boards here
15331 +source "arch/ubicom32/mach-ip5k/Kconfig"
15332 +source "arch/ubicom32/mach-ip7k/Kconfig"
15333 +
15334 +endchoice
15335 +
15336 +comment "Kernel Options"
15337 +config SMP
15338 +       bool "Symmetric multi-processing support"
15339 +       select USE_GENERIC_SMP_HELPERS
15340 +       default n
15341 +       help
15342 +         Enables multithreading support.  Enabling SMP support increases
15343 +         the size of system data structures.  SMP support can have either 
15344 +         positive or negative impact on performance depending on workloads. 
15345 +
15346 +         If you do not know what to do here, say N.
15347 +
15348 +config NR_CPUS
15349 +       int "Number of configured CPUs"
15350 +       range 2 32
15351 +       default 2
15352 +       depends on SMP
15353 +       help
15354 +               Upper bound on the number of CPUs. Space is reserved 
15355 +               at compile time for this many CPUs.
15356 +               
15357 +config LOCAL_TIMERS
15358 +       bool "Use local timer interrupts"
15359 +       depends on SMP
15360 +       default y
15361 +       help
15362 +         Enable support for local timers on SMP platforms, rather then the
15363 +         legacy IPI broadcast method.  Local timers allows the system
15364 +         accounting to be spread across the timer interval, preventing a
15365 +         "thundering herd" at every timer tick.  A physical timer is allocated
15366 +         per cpu.              
15367 +
15368 +config TIMER_EXTRA_ALLOC
15369 +       int "Number of additional physical timer events to create"
15370 +       depends on GENERIC_CLOCKEVENTS
15371 +       default 0
15372 +       help
15373 +               The Ubicom32 processor has a number of event timers that can be wrapped
15374 +               in Linux clock event structures (assuming that the timers are not being
15375 +               used for another purpose).  Based on the value of LOCAL_TIMERS, either 
15376 +               2 timers will be used or a timer will be used for every CPU.  This value
15377 +               allows the programmer to select additional timers over that amount.
15378 +                       
15379 +config IRQSTACKS
15380 +       bool "Create separate stacks for interrupt handling"
15381 +       default n
15382 +       help
15383 +               Selecting this causes interrupts to be created on a separate
15384 +               stack instead of nesting the interrupts on the kernel stack.
15385 +               
15386 +config IRQSTACKS_USEOCM
15387 +       bool "Use OCM for interrupt stacks"
15388 +       default n
15389 +       depends on IRQSTACKS
15390 +       help
15391 +               Selecting this cause the interrupt stacks to be placed in OCM
15392 +               reducing cache misses at the expense of using the OCM for servicing
15393 +               interrupts.
15394 +
15395 +menu "OCM Instruction Heap"
15396 +
15397 +config OCM_MODULES_RESERVATION
15398 +       int "OCM Instruction heap reservation. 0-192 kB"
15399 +       range 0 192
15400 +       default "0"
15401 +       help
15402 +         The minimum amount of OCM memory to reserve for kernel loadable module
15403 +         code. If you are not using this memory it cannot be used for anything
15404 +         else. Leave it as 0 if you have prebuilt modules that are compiled with
15405 +         OCM support.
15406 +
15407 +config OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
15408 +       bool "Give all unused ocm code space to the ocm instruction heap."
15409 +       default n
15410 +       help
15411 +         Allow the OCM instruction heap allocation to consume any remaining
15412 +         unused OCM code space.  The result of this is that you will not have
15413 +         and deterministic results, but you will not have any waste either.
15414 +
15415 +config OCM_MODULES_FALLBACK_TO_DDR
15416 +       bool "Loadable Modules requiring OCM may fallback to use DDR."
15417 +       default n
15418 +       help
15419 +         If a module cannot get the OCM code it requires allow DDR to
15420 +         be used instead.
15421 +endmenu
15422 +
15423 +config HZ
15424 +       int "Frequency of 'jiffies' (for polling)"
15425 +       default 1000
15426 +       help
15427 +               100 is common for embedded systems, but 1000 allows
15428 +               you to do more drivers without actually having
15429 +               interrupts working properly.
15430 +
15431 +comment "RAM configuration"
15432 +
15433 +if BRD_32MB
15434 +
15435 +config RAMSIZE
15436 +       hex "Size of RAM (in bytes)"
15437 +       range 0x00000000 0x02000000
15438 +       default "0x02000000"
15439 +       help
15440 +               Define the size of the system RAM. If you select 0 then the
15441 +               kernel will try to probe the RAM size at runtime. This is not
15442 +               supported on all CPU types.
15443 +
15444 +endif
15445 +
15446 +if BRD_64MB
15447 +
15448 +config RAMSIZE
15449 +       hex "Size of RAM (in bytes)"
15450 +       range 0x00000000 0x04000000
15451 +       default "0x04000000"
15452 +       help
15453 +               Define the size of the system RAM. If you select 0 then the
15454 +               kernel will try to probe the RAM size at runtime. This is not
15455 +               supported on all CPU types.
15456 +
15457 +endif
15458 +
15459 +if BRD_128MB
15460 +
15461 +config RAMSIZE
15462 +       hex "Size of RAM (in bytes)"
15463 +       range 0x00000000 0x08000000
15464 +       default "0x08000000"
15465 +       help
15466 +               Define the size of the system RAM. If you select 0 then the
15467 +               kernel will try to probe the RAM size at runtime. This is not
15468 +               supported on all CPU types.
15469 +
15470 +endif
15471 +
15472 +config KERNELBASE
15473 +       hex "Address of the base of kernel code"
15474 +       default "0x40400000"
15475 +       help
15476 +               For the time being we are going to start the Kernel at a 4 meg offset.
15477 +
15478 +comment "Build options"
15479 +config LINKER_RELAXATION
15480 +       bool "Linker Relaxation"
15481 +       default y
15482 +       help
15483 +         Turns on linker relaxation that will produce smaller
15484 +         faster code. Increases link time.
15485 +
15486 +comment "Driver options"
15487 +menu "PCI Bus"
15488 +config PCI
15489 +       bool "PCI bus"
15490 +       default true
15491 +       help
15492 +         Enable/Disable PCI bus
15493 +       source "drivers/pci/Kconfig"
15494 +
15495 +
15496 +config PCI_DEV0_IDSEL
15497 +       hex "slot 0 address"
15498 +       depends on PCI
15499 +       default "0x01000000"
15500 +       help
15501 +         Slot 0 address.  This address should correspond to the address line
15502 +         which the IDSEL bit for this slot is connected to.
15503 +
15504 +config PCI_DEV1_IDSEL
15505 +       hex "slot 1 address"
15506 +       depends on PCI
15507 +       default "0x02000000"
15508 +       help
15509 +         Slot 1 address.  This address should correspond to the address line
15510 +         which the IDSEL bit for this slot is connected to.
15511 +endmenu
15512 +# End PCI
15513 +
15514 +menu "Input devices"
15515 +config UBICOM_INPUT
15516 +       bool "Ubicom polled GPIO input driver"
15517 +       select INPUT
15518 +       select INPUT_POLLDEV
15519 +       help
15520 +               Polling input driver, much like the GPIO input driver, except that it doesn't
15521 +               rely on interrupts.  It will report events via the input subsystem.
15522 +       default n
15523 +
15524 +config UBICOM_INPUT_I2C
15525 +       bool "Ubicom polled GPIO input driver over I2C"
15526 +       select INPUT
15527 +       select INPUT_POLLDEV
15528 +       help
15529 +               Polling input driver, much like the PCA953x driver, it can support a variety of
15530 +               different I2C I/O expanders.  This device polls the I2C I/O expander for events
15531 +               and reports them via the input subsystem.
15532 +       default n
15533 +endmenu
15534 +# Input devices
15535 +
15536 +menu "Misc devices"
15537 +config UBICOM_HID
15538 +       bool "Ubicom HID driver"
15539 +       select INPUT
15540 +       select INPUT_POLLDEV
15541 +       select LCD_CLASS_DEVICE
15542 +       help
15543 +               Driver for HID chip found on some Ubicom reference designs.  This chip handles
15544 +               PWM, button input, and IR remote control.  It registers as an input device and
15545 +               a backlight device.
15546 +       default n
15547 +endmenu
15548 +# Misc devices
15549 +
15550 +config CMDLINE_BOOL
15551 +       bool "Built-in kernel command line"
15552 +       default n
15553 +       help
15554 +         Allow for specifying boot arguments to the kernel at
15555 +         build time.  On some systems (e.g. embedded ones), it is
15556 +         necessary or convenient to provide some or all of the
15557 +         kernel boot arguments with the kernel itself (that is,
15558 +         to not rely on the boot loader to provide them.)
15559 +
15560 +         To compile command line arguments into the kernel,
15561 +         set this option to 'Y', then fill in the
15562 +         the boot arguments in CONFIG_CMDLINE.
15563 +
15564 +         Systems with fully functional boot loaders (i.e. non-embedded)
15565 +         should leave this option set to 'N'.
15566 +
15567 +config CMDLINE
15568 +       string "Built-in kernel command string"
15569 +       depends on CMDLINE_BOOL
15570 +       default ""
15571 +       help
15572 +         Enter arguments here that should be compiled into the kernel
15573 +         image and used at boot time.  If the boot loader provides a
15574 +         command line at boot time, it is appended to this string to
15575 +         form the full kernel command line, when the system boots.
15576 +
15577 +         However, you can use the CONFIG_CMDLINE_OVERRIDE option to
15578 +         change this behavior.
15579 +
15580 +         In most cases, the command line (whether built-in or provided
15581 +         by the boot loader) should specify the device for the root
15582 +         file system.
15583 +
15584 +config CMDLINE_OVERRIDE
15585 +       bool "Built-in command line overrides boot loader arguments"
15586 +       default n
15587 +       depends on CMDLINE_BOOL
15588 +       help
15589 +         Set this option to 'Y' to have the kernel ignore the boot loader
15590 +         command line, and use ONLY the built-in command line.
15591 +
15592 +         This is used to work around broken boot loaders.  This should
15593 +         be set to 'N' under normal conditions.
15594 +
15595 +endmenu
15596 +# End Processor type and features
15597 +
15598 +source "arch/ubicom32/Kconfig.debug"
15599 +
15600 +menu "Executable file formats"
15601 +source "fs/Kconfig.binfmt"
15602 +endmenu
15603 +
15604 +source "init/Kconfig"
15605 +source "kernel/Kconfig.preempt"
15606 +source "kernel/time/Kconfig"
15607 +source "mm/Kconfig"
15608 +source "net/Kconfig"
15609 +source "drivers/Kconfig"
15610 +source "fs/Kconfig"
15611 +source "security/Kconfig"
15612 +source "crypto/Kconfig"
15613 +source "lib/Kconfig"
15614 --- /dev/null
15615 +++ b/arch/ubicom32/Kconfig.debug
15616 @@ -0,0 +1,117 @@
15617 +menu "Kernel hacking"
15618 +
15619 +config TRACE_IRQFLAGS_SUPPORT
15620 +       def_bool y
15621 +       
15622 +config PROTECT_KERNEL
15623 +       default y
15624 +       bool 'Enable Kernel range register Protection'
15625 +       help
15626 +         Adds code to enable/disable range registers to protect static
15627 +         kernel code/data from userspace.  Currently the ranges covered
15628 +         do no protect kernel loadable modules or dynamically allocated
15629 +         kernel data.
15630 +
15631 +config NO_KERNEL_MSG
15632 +       bool "Suppress Kernel BUG Messages"
15633 +       help
15634 +         Do not output any debug BUG messages within the kernel.
15635 +
15636 +config EARLY_PRINTK
15637 +       bool "Use the driver that you selected as console also for early printk (to debug kernel bootup)."
15638 +       default n
15639 +       help
15640 +         If you want to use the serdes driver (console=ttyUS0) for
15641 +         early printk, you must also supply an additional kernel boot
15642 +         parameter like this:
15643 +
15644 +               serdes=ioportaddr,irq,clockrate,baud
15645 +
15646 +         For an IP7160RGW eval board, you could use this:
15647 +
15648 +               serdes=0x2004000,61,250000000,57600
15649 +
15650 +         which will let you see early printk output at 57600 baud.
15651 +
15652 +config STOP_ON_TRAP
15653 +       bool "Enable stopping at the LDSR for all traps"
15654 +       default n
15655 +       help
15656 +       Cause the LDSR to stop all threads whenever a trap is about to be serviced
15657 +       
15658 +config STOP_ON_BUG
15659 +       bool "Enable stopping on failed BUG_ON()"
15660 +       default n
15661 +       help
15662 +       Cause all BUG_ON failures to stop all threads
15663 +       
15664 +config DEBUG_IRQMEASURE
15665 +       bool "Enable IRQ handler measurements"
15666 +       default n
15667 +       help
15668 +       When enabled each IRQ's min/avg/max times will be printed.  If the handler
15669 +       re-enables interrupt, the times will show the full time including to service
15670 +       nested interrupts.  See /proc/irq_measurements.
15671 +       
15672 +config DEBUG_PCIMEASURE
15673 +       bool "Enable PCI transaction measurements"
15674 +       default n
15675 +       help
15676 +       When enabled the system will measure the min/avg/max timer for each PCI transactions.
15677 +       See /proc/pci_measurements.
15678 +
15679 +config ACCESS_OK_CHECKS_ENABLED
15680 +       bool "Enable user space access checks"
15681 +       default n
15682 +       help
15683 +       Enabling this check causes the kernel to verify that addresses passed
15684 +       to the kernel by the user space code are within the processes 
15685 +       address space.  On a no-mmu system, this is done by examining the
15686 +       processes memory data structures (adversly affecting performance) but
15687 +       ensuring that a process does not ask the kernel to violate another 
15688 +       processes address space.  Sadly, the kernel uses access_ok() for 
15689 +       address that are in the kernel which results in a large volume of 
15690 +       false positives.
15691 +
15692 +choice
15693 +       prompt "Unaligned Access Support"
15694 +       default UNALIGNED_ACCESS_ENABLED
15695 +       help
15696 +               Kernel / Userspace unaligned access handling.
15697 +
15698 +config  UNALIGNED_ACCESS_ENABLED
15699 +       bool "Kernel and Userspace"
15700 +       help
15701 +
15702 +config  UNALIGNED_ACCESS_USERSPACE_ONLY
15703 +       bool "Userspace Only"
15704 +       help
15705 +
15706 +config  UNALIGNED_ACCESS_DISABLED
15707 +       bool "Disabled"
15708 +       help
15709 +
15710 +endchoice
15711 +
15712 +config DEBUG_STACKOVERFLOW
15713 +       bool "Check for stack overflows"
15714 +       default n
15715 +       depends on DEBUG_KERNEL
15716 +       help
15717 +         This option will cause messages to be printed if free kernel stack space
15718 +         drops below a certain limit (THREAD_SIZE /8).
15719 +
15720 +config DEBUG_STACK_USAGE
15721 +       bool "Stack utilization instrumentation"
15722 +       default n
15723 +       depends on DEBUG_KERNEL
15724 +       help
15725 +         Enables the display of the minimum amount of free kernel stack which each
15726 +         task has ever had available in the sysrq-T and sysrq-P debug output.
15727 +
15728 +         This option will slow down process creation somewhat.
15729 +
15730 +source "lib/Kconfig.debug"
15731 +
15732 +endmenu
15733 +
15734 --- /dev/null
15735 +++ b/arch/ubicom32/kernel/asm-offsets.c
15736 @@ -0,0 +1,162 @@
15737 +/*
15738 + * arch/ubicom32/kernel/asm-offsets.c
15739 + *   Ubicom32 architecture definitions needed by assembly language modules.
15740 + *
15741 + * (C) Copyright 2009, Ubicom, Inc.
15742 + *
15743 + * This file is part of the Ubicom32 Linux Kernel Port.
15744 + *
15745 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15746 + * it and/or modify it under the terms of the GNU General Public License
15747 + * as published by the Free Software Foundation, either version 2 of the
15748 + * License, or (at your option) any later version.
15749 + *
15750 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15751 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15752 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15753 + * the GNU General Public License for more details.
15754 + *
15755 + * You should have received a copy of the GNU General Public License
15756 + * along with the Ubicom32 Linux Kernel Port.  If not,
15757 + * see <http://www.gnu.org/licenses/>.
15758 + *
15759 + * Ubicom32 implementation derived from (with many thanks):
15760 + *   arch/m68knommu
15761 + *   arch/blackfin
15762 + *   arch/parisc
15763 + */
15764 +/*
15765 + * This program is used to generate definitions needed by
15766 + * assembly language modules.
15767 + *
15768 + * We use the technique used in the OSF Mach kernel code:
15769 + * generate asm statements containing #defines,
15770 + * compile this file to assembler, and then extract the
15771 + * #defines from the assembly-language output.
15772 + */
15773 +
15774 +#include <linux/module.h>
15775 +#include <linux/stddef.h>
15776 +#include <linux/sched.h>
15777 +#include <linux/kernel_stat.h>
15778 +#include <linux/ptrace.h>
15779 +#include <linux/hardirq.h>
15780 +#include <asm/bootinfo.h>
15781 +#include <asm/irq.h>
15782 +#include <asm/thread_info.h>
15783 +
15784 +#define DEFINE(sym, val) \
15785 +        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
15786 +
15787 +#define BLANK() asm volatile("\n->" : : )
15788 +
15789 +int main(void)
15790 +{
15791 +       /* offsets into the task struct */
15792 +       DEFINE(TASK_STATE, offsetof(struct task_struct, state));
15793 +       DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
15794 +       DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
15795 +       DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
15796 +       DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
15797 +       DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
15798 +       DEFINE(TASK_MM, offsetof(struct task_struct, mm));
15799 +       DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
15800 +
15801 +       /* offsets into the kernel_stat struct */
15802 +       DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
15803 +
15804 +       /* offsets into the irq_cpustat_t struct */
15805 +       DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
15806 +
15807 +       /* offsets into the thread struct */
15808 +       DEFINE(THREAD_D10, offsetof(struct thread_struct, d10));
15809 +       DEFINE(THREAD_D11, offsetof(struct thread_struct, d11));
15810 +       DEFINE(THREAD_D12, offsetof(struct thread_struct, d12));
15811 +       DEFINE(THREAD_D13, offsetof(struct thread_struct, d13));
15812 +       DEFINE(THREAD_A1, offsetof(struct thread_struct, a1));
15813 +       DEFINE(THREAD_A2, offsetof(struct thread_struct, a2));
15814 +       DEFINE(THREAD_A5, offsetof(struct thread_struct, a5));
15815 +       DEFINE(THREAD_A6, offsetof(struct thread_struct, a6));
15816 +       DEFINE(THREAD_SP, offsetof(struct thread_struct, sp));
15817 +
15818 +       /* offsets into the pt_regs */
15819 +       DEFINE(PT_D0, offsetof(struct pt_regs, dn[0]));
15820 +       DEFINE(PT_D1, offsetof(struct pt_regs, dn[1]));
15821 +       DEFINE(PT_D2, offsetof(struct pt_regs, dn[2]));
15822 +       DEFINE(PT_D3, offsetof(struct pt_regs, dn[3]));
15823 +       DEFINE(PT_D4, offsetof(struct pt_regs, dn[4]));
15824 +       DEFINE(PT_D5, offsetof(struct pt_regs, dn[5]));
15825 +       DEFINE(PT_D6, offsetof(struct pt_regs, dn[6]));
15826 +       DEFINE(PT_D7, offsetof(struct pt_regs, dn[7]));
15827 +       DEFINE(PT_D8, offsetof(struct pt_regs, dn[8]));
15828 +       DEFINE(PT_D9, offsetof(struct pt_regs, dn[9]));
15829 +       DEFINE(PT_D10, offsetof(struct pt_regs, dn[10]));
15830 +       DEFINE(PT_D11, offsetof(struct pt_regs, dn[11]));
15831 +       DEFINE(PT_D12, offsetof(struct pt_regs, dn[12]));
15832 +       DEFINE(PT_D13, offsetof(struct pt_regs, dn[13]));
15833 +       DEFINE(PT_D14, offsetof(struct pt_regs, dn[14]));
15834 +       DEFINE(PT_D15, offsetof(struct pt_regs, dn[15]));
15835 +       DEFINE(PT_A0, offsetof(struct pt_regs, an[0]));
15836 +       DEFINE(PT_A1, offsetof(struct pt_regs, an[1]));
15837 +       DEFINE(PT_A2, offsetof(struct pt_regs, an[2]));
15838 +       DEFINE(PT_A3, offsetof(struct pt_regs, an[3]));
15839 +       DEFINE(PT_A4, offsetof(struct pt_regs, an[4]));
15840 +       DEFINE(PT_A5, offsetof(struct pt_regs, an[5]));
15841 +       DEFINE(PT_A6, offsetof(struct pt_regs, an[6]));
15842 +       DEFINE(PT_A7, offsetof(struct pt_regs, an[7]));
15843 +       DEFINE(PT_SP, offsetof(struct pt_regs, an[7]));
15844 +
15845 +       DEFINE(PT_ACC0HI, offsetof(struct pt_regs, acc0[0]));
15846 +       DEFINE(PT_ACC0LO, offsetof(struct pt_regs, acc0[1]));
15847 +       DEFINE(PT_MAC_RC16, offsetof(struct pt_regs, mac_rc16));
15848 +
15849 +       DEFINE(PT_ACC1HI, offsetof(struct pt_regs, acc1[0]));
15850 +       DEFINE(PT_ACC1LO, offsetof(struct pt_regs, acc1[1]));
15851 +
15852 +       DEFINE(PT_SOURCE3, offsetof(struct pt_regs, source3));
15853 +       DEFINE(PT_INST_CNT, offsetof(struct pt_regs, inst_cnt));
15854 +       DEFINE(PT_CSR, offsetof(struct pt_regs, csr));
15855 +       DEFINE(PT_DUMMY_UNUSED, offsetof(struct pt_regs, dummy_unused));
15856 +
15857 +       DEFINE(PT_INT_MASK0, offsetof(struct pt_regs, int_mask0));
15858 +       DEFINE(PT_INT_MASK1, offsetof(struct pt_regs, int_mask1));
15859 +
15860 +       DEFINE(PT_PC, offsetof(struct pt_regs, pc));
15861 +
15862 +       DEFINE(PT_TRAP_CAUSE, offsetof(struct pt_regs, trap_cause));
15863 +
15864 +       DEFINE(PT_SIZE, sizeof(struct pt_regs));
15865 +
15866 +       DEFINE(PT_FRAME_TYPE, offsetof(struct pt_regs, frame_type));
15867 +
15868 +       DEFINE(PT_ORIGINAL_D0, offsetof(struct pt_regs, original_dn_0));
15869 +       DEFINE(PT_PREVIOUS_PC, offsetof(struct pt_regs, previous_pc));
15870 +
15871 +       /* offsets into the kernel_stat struct */
15872 +       DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
15873 +
15874 +       /* signal defines */
15875 +       DEFINE(SIGSEGV, SIGSEGV);
15876 +       //DEFINE(SEGV_MAPERR, SEGV_MAPERR);
15877 +       DEFINE(SIGTRAP, SIGTRAP);
15878 +       //DEFINE(TRAP_TRACE, TRAP_TRACE);
15879 +
15880 +       DEFINE(PT_PTRACED, PT_PTRACED);
15881 +       DEFINE(PT_DTRACE, PT_DTRACE);
15882 +
15883 +       DEFINE(ASM_THREAD_SIZE, THREAD_SIZE);
15884 +
15885 +       /* Offsets in thread_info structure */
15886 +       DEFINE(TI_TASK, offsetof(struct thread_info, task));
15887 +       DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
15888 +       DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
15889 +       DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
15890 +       DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
15891 +       DEFINE(TI_INTR_NESTING, offsetof(struct thread_info, interrupt_nesting));
15892 +       DEFINE(ASM_TIF_NEED_RESCHED, TIF_NEED_RESCHED);
15893 +       DEFINE(ASM_TIF_SYSCALL_TRACE, TIF_SYSCALL_TRACE);
15894 +       DEFINE(ASM_TIF_SIGPENDING, TIF_SIGPENDING);
15895 +
15896 +       DEFINE(ASM_RAM_END, (CONFIG_RAMBASE + CONFIG_RAMSIZE));
15897 +       return 0;
15898 +}
15899 --- /dev/null
15900 +++ b/arch/ubicom32/kernel/devtree.c
15901 @@ -0,0 +1,173 @@
15902 +/*
15903 + * arch/ubicom32/kernel/devtree.c
15904 + *   Ubicom32 architecture device tree implementation.
15905 + *
15906 + * (C) Copyright 2009, Ubicom, Inc.
15907 + *
15908 + * This file is part of the Ubicom32 Linux Kernel Port.
15909 + *
15910 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15911 + * it and/or modify it under the terms of the GNU General Public License
15912 + * as published by the Free Software Foundation, either version 2 of the
15913 + * License, or (at your option) any later version.
15914 + *
15915 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15916 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15917 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15918 + * the GNU General Public License for more details.
15919 + *
15920 + * You should have received a copy of the GNU General Public License
15921 + * along with the Ubicom32 Linux Kernel Port.  If not,
15922 + * see <http://www.gnu.org/licenses/>.
15923 + *
15924 + * Ubicom32 implementation derived from (with many thanks):
15925 + *   arch/m68knommu
15926 + *   arch/blackfin
15927 + *   arch/parisc
15928 + */
15929 +
15930 +#include <linux/module.h>
15931 +#include <linux/kernel.h>
15932 +#include <linux/string.h>
15933 +#include <linux/errno.h>
15934 +#include <asm/devtree.h>
15935 +
15936 +/*
15937 + * The device tree.
15938 + */
15939 +struct devtree_node *devtree;
15940 +
15941 +/*
15942 + * devtree_print()
15943 + *     Print the device tree.
15944 + */
15945 +void devtree_print(void)
15946 +{
15947 +       struct devtree_node *p = devtree;
15948 +       printk(KERN_INFO "Device Tree:\n");
15949 +       while (p) {
15950 +               if (p->magic != DEVTREE_NODE_MAGIC) {
15951 +                       printk(KERN_EMERG
15952 +                              "device tree has improper node: %p\n", p);
15953 +                       return;
15954 +               }
15955 +               printk(KERN_INFO "\t%p: sendirq=%03d, recvirq=%03d, "
15956 +                      " name=%s\n", p, p->sendirq, p->recvirq, p->name);
15957 +               p = p->next;
15958 +       }
15959 +}
15960 +EXPORT_SYMBOL(devtree_print);
15961 +
15962 +/*
15963 + * devtree_irq()
15964 + *     Return the IRQ(s) associated with devtree node.
15965 + */
15966 +int devtree_irq(struct devtree_node *dn,
15967 +               unsigned char *sendirq,
15968 +               unsigned char *recvirq)
15969 +{
15970 +       if (dn->magic != DEVTREE_NODE_MAGIC) {
15971 +               printk(KERN_EMERG "improper node: %p\n", dn);
15972 +               if (sendirq) {
15973 +                       *sendirq = DEVTREE_IRQ_NONE;
15974 +               }
15975 +               if (recvirq) {
15976 +                       *recvirq = DEVTREE_IRQ_NONE;
15977 +               }
15978 +               return -EFAULT;
15979 +       }
15980 +
15981 +       /*
15982 +        * Copy the devtree irq(s) to the output parameters.
15983 +        */
15984 +       if (sendirq) {
15985 +               *sendirq = dn->sendirq;
15986 +       }
15987 +       if (recvirq) {
15988 +               *recvirq = dn->recvirq;
15989 +       }
15990 +       return 0;
15991 +}
15992 +EXPORT_SYMBOL(devtree_irq);
15993 +
15994 +/*
15995 + * devtree_find_next()
15996 + *     Provide an iterator for walking the device tree.
15997 + */
15998 +struct devtree_node *devtree_find_next(struct devtree_node **cur)
15999 +{
16000 +       struct devtree_node *p = *cur;
16001 +       if (!p) {
16002 +               *cur = devtree;
16003 +               return devtree;
16004 +       }
16005 +       p = p->next;
16006 +       *cur = p;
16007 +       return p;
16008 +}
16009 +
16010 +/*
16011 + * devtree_find_by_irq()
16012 + *     Return the node associated with a given irq.
16013 + */
16014 +struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq)
16015 +{
16016 +       struct devtree_node *p = devtree;
16017 +
16018 +       if (sendirq == recvirq) {
16019 +               printk(KERN_EMERG "identical request makes no sense sendirq = "
16020 +                      "%d, recvirq= %d\n", sendirq, recvirq);
16021 +               return NULL;
16022 +       }
16023 +
16024 +       while (p) {
16025 +               if (p->magic != DEVTREE_NODE_MAGIC) {
16026 +                       printk(KERN_EMERG
16027 +                              "device tree has improper node: %p\n", p);
16028 +                       return NULL;
16029 +               }
16030 +
16031 +               /*
16032 +                * See if we can find a match on the IRQ(s) specified.
16033 +                */
16034 +               if ((sendirq == p->sendirq) && (recvirq == p->recvirq)) {
16035 +                       return p;
16036 +               }
16037 +
16038 +               if ((sendirq == DEVTREE_IRQ_DONTCARE) &&
16039 +                   (p->recvirq == recvirq)) {
16040 +                       return p;
16041 +               }
16042 +
16043 +               if ((recvirq == DEVTREE_IRQ_DONTCARE) &&
16044 +                   (p->sendirq == sendirq)) {
16045 +                       return p;
16046 +               }
16047 +
16048 +               p = p->next;
16049 +       }
16050 +       return NULL;
16051 +}
16052 +EXPORT_SYMBOL(devtree_find_by_irq);
16053 +
16054 +/*
16055 + * devtree_find_node()
16056 + *     Find a node in the device tree by name.
16057 + */
16058 +struct devtree_node *devtree_find_node(const char *str)
16059 +{
16060 +       struct devtree_node *p = devtree;
16061 +       while (p) {
16062 +               if (p->magic != DEVTREE_NODE_MAGIC) {
16063 +                       printk(KERN_EMERG
16064 +                              "device tree has improper node: %p\n", p);
16065 +                       return NULL;
16066 +               }
16067 +               if (strcmp(p->name, str) == 0) {
16068 +                       return p;
16069 +               }
16070 +               p = p->next;
16071 +       }
16072 +       return NULL;
16073 +}
16074 +EXPORT_SYMBOL(devtree_find_node);
16075 --- /dev/null
16076 +++ b/arch/ubicom32/kernel/dma.c
16077 @@ -0,0 +1,60 @@
16078 +/*
16079 + * arch/ubicom32/kernel/dma.c
16080 + *   Ubicom32 architecture dynamic DMA mapping support.
16081 + *
16082 + * (C) Copyright 2009, Ubicom, Inc.
16083 + *
16084 + * This file is part of the Ubicom32 Linux Kernel Port.
16085 + *
16086 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16087 + * it and/or modify it under the terms of the GNU General Public License
16088 + * as published by the Free Software Foundation, either version 2 of the
16089 + * License, or (at your option) any later version.
16090 + *
16091 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16092 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16093 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16094 + * the GNU General Public License for more details.
16095 + *
16096 + * You should have received a copy of the GNU General Public License
16097 + * along with the Ubicom32 Linux Kernel Port.  If not,
16098 + * see <http://www.gnu.org/licenses/>.
16099 + *
16100 + * Ubicom32 implementation derived from (with many thanks):
16101 + *   arch/m68knommu
16102 + *   arch/blackfin
16103 + *   arch/parisc
16104 + *
16105 + * We never have any address translations to worry about, so this
16106 + * is just alloc/free.
16107 + */
16108 +
16109 +#include <linux/types.h>
16110 +#include <linux/mm.h>
16111 +#include <linux/string.h>
16112 +#include <linux/device.h>
16113 +#include <linux/io.h>
16114 +
16115 +void *dma_alloc_coherent(struct device *dev, size_t size,
16116 +                          dma_addr_t *dma_handle, int gfp)
16117 +{
16118 +       void *ret;
16119 +       /* ignore region specifiers */
16120 +       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
16121 +
16122 +       if (dev == NULL || (*dev->dma_mask < 0xffffffff))
16123 +               gfp |= GFP_DMA;
16124 +       ret = (void *)__get_free_pages(gfp, get_order(size));
16125 +
16126 +       if (ret != NULL) {
16127 +               memset(ret, 0, size);
16128 +               *dma_handle = virt_to_phys(ret);
16129 +       }
16130 +       return ret;
16131 +}
16132 +
16133 +void dma_free_coherent(struct device *dev, size_t size,
16134 +                        void *vaddr, dma_addr_t dma_handle)
16135 +{
16136 +       free_pages((unsigned long)vaddr, get_order(size));
16137 +}
16138 --- /dev/null
16139 +++ b/arch/ubicom32/kernel/flat.c
16140 @@ -0,0 +1,206 @@
16141 +/*
16142 + * arch/ubicom32/kernel/flat.c
16143 + *   Ubicom32 architecture flat executable format support.
16144 + *
16145 + * (C) Copyright 2009, Ubicom, Inc.
16146 + *
16147 + * This file is part of the Ubicom32 Linux Kernel Port.
16148 + *
16149 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16150 + * it and/or modify it under the terms of the GNU General Public License
16151 + * as published by the Free Software Foundation, either version 2 of the
16152 + * License, or (at your option) any later version.
16153 + *
16154 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16155 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16156 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16157 + * the GNU General Public License for more details.
16158 + *
16159 + * You should have received a copy of the GNU General Public License
16160 + * along with the Ubicom32 Linux Kernel Port.  If not,
16161 + * see <http://www.gnu.org/licenses/>.
16162 + *
16163 + * Ubicom32 implementation derived from (with many thanks):
16164 + *   arch/m68knommu
16165 + *   arch/blackfin
16166 + *   arch/parisc
16167 + */
16168 +#include <linux/module.h>
16169 +#include <linux/types.h>
16170 +#include <linux/flat.h>
16171 +
16172 +unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp,
16173 +                                            u32_t relval,
16174 +                                            u32_t flags,
16175 +                                            unsigned long *persistent)
16176 +{
16177 +       u32_t relval_reloc_type = relval >> 27;
16178 +       u32_t insn = *rp;
16179 +
16180 +       if (*persistent) {
16181 +               /*
16182 +                * relval holds the relocation that has to be adjusted.
16183 +                */
16184 +               if (relval == 0) {
16185 +                       *persistent = 0;
16186 +               }
16187 +
16188 +               return relval;
16189 +       }
16190 +
16191 +       if (relval_reloc_type == R_UBICOM32_32) {
16192 +               /*
16193 +                * insn holds the relocation
16194 +                */
16195 +               return insn;
16196 +       }
16197 +
16198 +       /*
16199 +        * We don't know this one.
16200 +        */
16201 +       return 0;
16202 +}
16203 +
16204 +void ubicom32_flat_put_addr_at_rp(unsigned long *rp,
16205 +                                 u32_t val,
16206 +                                 u32_t relval,
16207 +                                 unsigned long *persistent)
16208 +{
16209 +       u32_t reloc_type = (relval >> 27) & 0x1f;
16210 +       u32_t insn = *rp;
16211 +
16212 +       /*
16213 +        * If persistent is set then it contains the relocation type.
16214 +        */
16215 +       if (*persistent) {
16216 +               /*
16217 +                * If persistent is set then it contains the relocation type.
16218 +                */
16219 +               reloc_type = (*persistent >> 27) & 0x1f;
16220 +       }
16221 +
16222 +       switch (reloc_type) {
16223 +       case R_UBICOM32_32:
16224 +               /*
16225 +                * Store the 32 bits as is.
16226 +                */
16227 +               *rp = val;
16228 +               break;
16229 +       case R_UBICOM32_HI24:
16230 +               {
16231 +                       /*
16232 +                        * 24 bit relocation that is part of the MOVEAI
16233 +                        * instruction. The 24 bits come from bits 7 - 30 of the
16234 +                        * relocation. The 24 bits eventually get split into 2
16235 +                        * fields in the instruction encoding.
16236 +                        *
16237 +                        * - Bits 7 - 27 of the relocation are encoded into bits
16238 +                        * 0 - 20 of the instruction.
16239 +                        *
16240 +                        * - Bits 28 - 30 of the relocation are encoded into bit
16241 +                        * 24 - 26 of the instruction.
16242 +                        */
16243 +                       u32_t mask = 0x1fffff | (0x7 << 24);
16244 +                       u32_t valid24bits = (val >> 7) & 0xffffff;
16245 +                       u32_t bot_21 = valid24bits & 0x1fffff;
16246 +                       u32_t upper_3_bits = ((valid24bits & 0xe00000) << 3);
16247 +                       insn &= ~mask;
16248 +
16249 +                       insn |= bot_21;
16250 +                       insn |= upper_3_bits;
16251 +                       *rp = insn;
16252 +               }
16253 +               break;
16254 +       case R_UBICOM32_LO7_S:
16255 +       case R_UBICOM32_LO7_2_S:
16256 +       case R_UBICOM32_LO7_4_S:
16257 +               {
16258 +                       /*
16259 +                        * Bits 0 - 6 of the relocation are encoded into the
16260 +                        * 7bit unsigned immediate fields of the SOURCE-1 field
16261 +                        * of the instruction.  The immediate value is left
16262 +                        * shifted by (0, 1, 2) based on the operand size.
16263 +                        */
16264 +                       u32_t mask = 0x1f | (0x3 << 8);
16265 +                       u32_t bottom, top;
16266 +                       val &= 0x7f;
16267 +                       if (reloc_type == R_UBICOM32_LO7_2_S) {
16268 +                               val >>= 1;
16269 +                       } else if (reloc_type == R_UBICOM32_LO7_4_S) {
16270 +                               val >>= 2;
16271 +                       }
16272 +
16273 +                       bottom  = val & 0x1f;
16274 +                       top = val >> 5;
16275 +                       insn &= ~mask;
16276 +                       insn |= bottom;
16277 +                       insn |= (top << 8);
16278 +                       BUG_ON(*rp != insn);
16279 +                       *rp = insn;
16280 +                       break;
16281 +               }
16282 +       case R_UBICOM32_LO7_D:
16283 +       case R_UBICOM32_LO7_2_D:
16284 +       case R_UBICOM32_LO7_4_D:
16285 +               {
16286 +                       /*
16287 +                        * Bits 0 - 6 of the relocation are encoded into the
16288 +                        * 7bit unsigned immediate fields of the DESTINATION
16289 +                        * field of the instruction.  The immediate value is
16290 +                        * left shifted by (0, 1, 2) based on the operand size.
16291 +                        */
16292 +                       u32_t mask = (0x1f | (0x3 << 8)) << 16;
16293 +                       u32_t bottom, top;
16294 +                       val &= 0x7f;
16295 +                       if (reloc_type == R_UBICOM32_LO7_2_D) {
16296 +                               val >>= 1;
16297 +                       } else if (reloc_type == R_UBICOM32_LO7_4_D) {
16298 +                               val >>= 2;
16299 +                       }
16300 +                       bottom  = (val & 0x1f) << 16;
16301 +                       top = (val >> 5) << 16;
16302 +                       insn &= ~mask;
16303 +                       insn |= bottom;
16304 +                       insn |= (top << 8);
16305 +                       BUG_ON(*rp != insn);
16306 +                       *rp = insn;
16307 +                       break;
16308 +               }
16309 +       case R_UBICOM32_LO7_CALLI:
16310 +       case R_UBICOM32_LO16_CALLI:
16311 +               {
16312 +                       /*
16313 +                        * Extract the offset for a CALLI instruction. The
16314 +                        * offsets can be either 7 bits or 18 bits. Since all
16315 +                        * instructions in ubicom32 architecture are at work
16316 +                        * aligned addresses the truncated offset is right
16317 +                        * shifted by 2 before being encoded in the instruction.
16318 +                        */
16319 +                       if (reloc_type == R_UBICOM32_LO7_CALLI) {
16320 +                               val &= 0x7f;
16321 +                       } else {
16322 +                               val &= 0x3ffff;
16323 +                       }
16324 +
16325 +                       val >>= 2;
16326 +
16327 +                       insn &= ~0x071f071f;
16328 +                       insn |= (val & 0x1f) << 0;
16329 +                       val >>= 5;
16330 +                       insn |= (val & 0x07) << 8;
16331 +                       val >>= 3;
16332 +                       insn |= (val & 0x1f) << 16;
16333 +                       val >>= 5;
16334 +                       insn |= (val & 0x07) << 24;
16335 +                       if (reloc_type == R_UBICOM32_LO7_CALLI) {
16336 +                               BUG_ON(*rp != insn);
16337 +                       }
16338 +                       *rp = insn;
16339 +               }
16340 +               break;
16341 +       }
16342 +
16343 +       if (*persistent) {
16344 +               *persistent = 0;
16345 +       }
16346 +}
16347 --- /dev/null
16348 +++ b/arch/ubicom32/kernel/head.S
16349 @@ -0,0 +1,247 @@
16350 +/*
16351 + * arch/ubicom32/kernel/head.S
16352 + *     <TODO: Replace with short file description>
16353 + *
16354 + * (C) Copyright 2009, Ubicom, Inc.
16355 + *
16356 + * This file is part of the Ubicom32 Linux Kernel Port.
16357 + *
16358 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16359 + * it and/or modify it under the terms of the GNU General Public License
16360 + * as published by the Free Software Foundation, either version 2 of the
16361 + * License, or (at your option) any later version.
16362 + *
16363 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16364 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16365 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16366 + * the GNU General Public License for more details.
16367 + *
16368 + * You should have received a copy of the GNU General Public License
16369 + * along with the Ubicom32 Linux Kernel Port.  If not,
16370 + * see <http://www.gnu.org/licenses/>.
16371 + *
16372 + * Ubicom32 implementation derived from (with many thanks):
16373 + *   arch/m68knommu
16374 + *   arch/blackfin
16375 + *   arch/parisc
16376 + */
16377 +#include <linux/sys.h>
16378 +#include <linux/linkage.h>
16379 +#include <asm/asm-offsets.h>
16380 +#include <asm/page_offset.h>
16381 +#define __ASM__
16382 +#include <asm/ip5000.h>
16383 +
16384 +
16385 +#define SRC_AN A3
16386 +#define DST_AN A4
16387 +
16388 +#define PARAM_DN D0
16389 +#define TMP_DN D15
16390 +#define TMP2_DN D14
16391 +
16392 +/*
16393 + * The following code is placed at the start of the Linux section of memory.
16394 + * This is the primary entry point for Linux.
16395 + *
16396 + * However, we also want the syscall entry/exit code to be at a fixed address.
16397 + * So we take the primary entry point and reserve 16 bytes.  That address is
16398 + * where the system_call entry point exists.  This 16 bytes basically allows
16399 + * us to jump around the system_call entry point code to the actual startup
16400 + * code.
16401 + *
16402 + * Linux Memory Map (see vlinux.lds.S):
16403 + * 0x40400000 - Primary Entry Point for Linux (jump around code below).
16404 + * 0x40400010 - Syscall Entry Point.
16405 + */
16406 +
16407 +       .sect   .skip_syscall, "ax", @progbits
16408 +       .global __skip_syscall_section
16409 +__skip_syscall_section:
16410 +       moveai          A3, #%hi(_start)
16411 +       lea.1           A3, %lo(_start)(A3)
16412 +       ret             A3
16413 +/*
16414 + * __os_node_offset contains the offset from KERNELBASE to the os_node, it is
16415 + * not intended to be used by anything except the boot code.
16416 + */
16417 +__os_node_offset:
16418 +.long  (_os_node - CONFIG_KERNELBASE)
16419 +
16420 +.text
16421 +.global        _start
16422 +
16423 +/*
16424 + * start()
16425 + *     This is the start of the Linux kernel.
16426 + */
16427 +_start:
16428 +       move.4          SCRATCHPAD1, #0
16429 +
16430 +
16431 +/*
16432 + * Setup the range registers... the loader has setup a few, but we will go ahead
16433 + * and correct them for our own limits. Note that once set these are never
16434 + * changed again.  The ranges are as follows
16435 + *
16436 + *  D_RANGE0 - io block (set up by loaded)
16437 + *
16438 + *  I_RANGE0 and D_RANGE1 - kernel/ultra loader address space bottom of ocm-> top
16439 + *     of ram typically 0x3ffc0000 - 0x440000000
16440 + *  I_RANGE1 - kernel / userspace transition area (aka syscalls, context switches)
16441 + *     typically 0x40400000 - ~0x40400400
16442 + *  I_RANGE2 / D_RANGE2 - slab area
16443 + *     typically 0x40A00000 - ~0x44000000
16444 + *
16445 + *  I_RANGE4, D_RANGE3, D_RANGE3 - unused.
16446 + */
16447 +       moveai          SRC_AN, #%hi(PAGE_OFFSET_RAW)
16448 +       lea.4           SRC_AN, %lo(PAGE_OFFSET_RAW)(SRC_AN)
16449 +       move.4          D_RANGE1_LO, SRC_AN
16450 +       move.4          I_RANGE0_LO, SRC_AN
16451 +
16452 +; don't try to calculate I_RANGE_HI, see below
16453 +;      moveai          SRC_AN, #%hi(___init_end-4)
16454 +;      lea.4           SRC_AN, %lo(___init_end-4)(SRC_AN)
16455 +;      move.4          I_RANGE0_HI, SRC_AN
16456 +
16457 +       moveai          SRC_AN, #%hi(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)
16458 +       lea.4           SRC_AN, %lo(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)(SRC_AN)
16459 +       move.4          D_RANGE1_HI, SRC_AN
16460 +
16461 +; for now allow the whole ram to be executable as well so we don't run into problems
16462 +; once we load user more code.
16463 +       move.4          I_RANGE0_HI, SRC_AN
16464 +
16465 +#ifdef CONFIG_PROTECT_KERNEL
16466 +; when kernel protection is enabled, we only open up syscall and non kernel text
16467 +; for userspace apps, for now only irange registers registers 1 and 2 are used for userspace.
16468 +
16469 +       ;; syscall range
16470 +       moveai          SRC_AN, #%hi(_begin)
16471 +       lea.4           SRC_AN, %lo(_begin)(SRC_AN)
16472 +       move.4          I_RANGE1_LO, SRC_AN
16473 +       moveai          SRC_AN, #%hi(__fixed_text_end)
16474 +       lea.4           SRC_AN, %lo(__fixed_text_end)(SRC_AN)
16475 +       move.4          I_RANGE1_HI, SRC_AN
16476 +
16477 +       ;; slab instructions
16478 +       moveai          SRC_AN, #%hi(_edata)
16479 +       lea.4           SRC_AN, %lo(_edata)(SRC_AN)
16480 +       move.4          I_RANGE2_LO, SRC_AN
16481 +       ;; End of DDR is already in range0 hi so just copy it.
16482 +       move.4          I_RANGE2_HI, I_RANGE0_HI
16483 +
16484 +       ;; slab data (same as slab instructions but starting a little earlier).
16485 +       moveai          SRC_AN, #%hi(_data_protection_end)
16486 +       lea.4           SRC_AN, %lo(_data_protection_end)(SRC_AN)
16487 +       move.4          D_RANGE2_LO, SRC_AN
16488 +       move.4          D_RANGE2_HI, I_RANGE0_HI
16489 +
16490 +;; enable ranges
16491 +       ;; skip I_RANGE0_EN
16492 +       move.4          I_RANGE1_EN, #-1
16493 +       move.4          I_RANGE2_EN, #-1
16494 +       move.4          I_RANGE3_EN, #0
16495 +
16496 +       ;; skip D_RANGE0_EN or D_RANGE1_EN
16497 +       move.4          D_RANGE2_EN, #-1
16498 +       move.4          D_RANGE3_EN, #0
16499 +       move.4          D_RANGE4_EN, #0
16500 +#endif
16501 +
16502 +;
16503 +; If __ocm_free_begin is smaller than __ocm_free_end the
16504 +; setup OCM text and data ram banks properly
16505 +;
16506 +       moveai          DST_AN, #%hi(__ocm_free_begin)
16507 +       lea.4           TMP_DN, %lo(__ocm_free_begin)(DST_AN)
16508 +       moveai          DST_AN, #%hi(__ocm_free_end)
16509 +       lea.4           TMP2_DN, %lo(__ocm_free_end)(DST_AN)
16510 +       sub.4           #0, TMP2_DN, TMP_DN
16511 +       jmple.f         2f
16512 +       moveai          DST_AN, #%hi(__data_begin)
16513 +       lea.4           TMP_DN, %lo(__data_begin)(DST_AN)
16514 +       moveai          DST_AN, #%hi(OCMSTART)
16515 +       lea.4           TMP2_DN, %lo(OCMSTART)(DST_AN)
16516 +       sub.4           TMP_DN, TMP_DN, TMP2_DN
16517 +       lsr.4           TMP_DN, TMP_DN, #15
16518 +       lsl.4           TMP_DN, #1, TMP_DN
16519 +       moveai          DST_AN, #%hi(OCMC_BASE)
16520 +       add.4           OCMC_BANK_MASK(DST_AN), #-1, TMP_DN
16521 +       pipe_flush      0
16522 +2:
16523 +;
16524 +; Load .ocm_text
16525 +;
16526 +       moveai          DST_AN, #%hi(__ocm_text_run_end)
16527 +       lea.4           TMP_DN, %lo(__ocm_text_run_end)(DST_AN)
16528 +       moveai          DST_AN, #%hi(__ocm_text_run_begin)
16529 +       lea.4           DST_AN, %lo(__ocm_text_run_begin)(DST_AN)
16530 +       moveai          SRC_AN, #%hi(__ocm_text_load_begin)
16531 +       lea.4           SRC_AN, %lo(__ocm_text_load_begin)(SRC_AN)
16532 +       jmpt.t          2f
16533 +
16534 +1:      move.4          (DST_AN)4++, (SRC_AN)4++
16535 +
16536 +2:      sub.4           #0, DST_AN, TMP_DN
16537 +       jmpne.t         1b
16538 +
16539 +;
16540 +; Load .ocm_data
16541 +;
16542 +       moveai          DST_AN, #%hi(__ocm_data_run_end)
16543 +       lea.4           TMP_DN, %lo(__ocm_data_run_end)(DST_AN)
16544 +       moveai          DST_AN, #%hi(__ocm_data_run_begin)
16545 +       lea.4           DST_AN, %lo(__ocm_data_run_begin)(DST_AN)
16546 +       moveai          SRC_AN, #%hi(__ocm_data_load_begin)
16547 +       lea.4           SRC_AN, %lo(__ocm_data_load_begin)(SRC_AN)
16548 +       jmpt.t          2f
16549 +
16550 +1:      move.4          (DST_AN)4++, (SRC_AN)4++
16551 +
16552 +2:      sub.4           #0, DST_AN, TMP_DN
16553 +       jmpne.t         1b
16554 +
16555 +; Clear .bss
16556 +;
16557 +       moveai          SRC_AN, #%hi(_ebss)
16558 +       lea.4           TMP_DN, %lo(_ebss)(SRC_AN)
16559 +       moveai          DST_AN, #%hi(_sbss)
16560 +       lea.4           DST_AN, %lo(_sbss)(DST_AN)
16561 +       jmpt.t          2f
16562 +
16563 +1:     move.4          (DST_AN)4++, #0
16564 +
16565 +2:     sub.4           #0, DST_AN, TMP_DN
16566 +       jmpne.t         1b
16567 +
16568 +; save our parameter to devtree (after clearing .bss)
16569 +       moveai          DST_AN, #%hi(devtree)
16570 +       lea.4           DST_AN, %lo(devtree)(DST_AN)
16571 +       move.4          (DST_AN), PARAM_DN
16572 +
16573 +       moveai          sp, #%hi(init_thread_union)
16574 +       lea.4           sp, %lo(init_thread_union)(sp)
16575 +       movei           TMP_DN, #ASM_THREAD_SIZE
16576 +       add.4           sp, sp, TMP_DN
16577 +       move.4          -4(sp)++, #0 ; nesting level = 0
16578 +       move.4          -4(sp)++, #1 ; KERNEL_THREAD
16579 +
16580 +;; ip3k-elf-gdb backend now sets scratchpad3 to 1 when either continue
16581 +;; or single step commands are issued. scratchpad3 is set to 0 when the
16582 +;; debugger detaches from the board.
16583 +       move.4          TMP_DN, scratchpad3
16584 +       lsl.4           TMP_DN, TMP_DN, #0x0
16585 +       jmpeq.f         _jump_to_start_kernel
16586 +_ok_to_set_break_points_in_linux:
16587 +;; THREAD_STALL
16588 +       move.4          mt_dbg_active_clr,#-1
16589 +;; stalling the threads isn't instantaneous.. need to flush the pipe.
16590 +       pipe_flush      0
16591 +       pipe_flush      0
16592 +
16593 +_jump_to_start_kernel:
16594 +       moveai          SRC_AN, #%hi(start_kernel)
16595 +       lea.4           SRC_AN, %lo(start_kernel)(SRC_AN)
16596 +       ret             SRC_AN
16597 --- /dev/null
16598 +++ b/arch/ubicom32/kernel/init_task.c
16599 @@ -0,0 +1,62 @@
16600 +/*
16601 + * arch/ubicom32/kernel/init_task.c
16602 + *   Ubicom32 architecture task initialization implementation.
16603 + *
16604 + * (C) Copyright 2009, Ubicom, Inc.
16605 + *
16606 + * This file is part of the Ubicom32 Linux Kernel Port.
16607 + *
16608 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16609 + * it and/or modify it under the terms of the GNU General Public License
16610 + * as published by the Free Software Foundation, either version 2 of the
16611 + * License, or (at your option) any later version.
16612 + *
16613 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16614 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16615 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16616 + * the GNU General Public License for more details.
16617 + *
16618 + * You should have received a copy of the GNU General Public License
16619 + * along with the Ubicom32 Linux Kernel Port.  If not,
16620 + * see <http://www.gnu.org/licenses/>.
16621 + *
16622 + * Ubicom32 implementation derived from (with many thanks):
16623 + *   arch/m68knommu
16624 + *   arch/blackfin
16625 + *   arch/parisc
16626 + */
16627 +#include <linux/mm.h>
16628 +#include <linux/module.h>
16629 +#include <linux/sched.h>
16630 +#include <linux/init.h>
16631 +#include <linux/init_task.h>
16632 +#include <linux/fs.h>
16633 +#include <linux/mqueue.h>
16634 +#include <linux/uaccess.h>
16635 +#include <asm/pgtable.h>
16636 +
16637 +static struct fs_struct init_fs = INIT_FS;
16638 +static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
16639 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
16640 +struct mm_struct init_mm = INIT_MM(init_mm);
16641 +EXPORT_SYMBOL(init_mm);
16642 +
16643 +/*
16644 + * Initial task structure.
16645 + *
16646 + * All other task structs will be allocated on slabs in fork.c
16647 + */
16648 +struct task_struct init_task = INIT_TASK(init_task);
16649 +
16650 +EXPORT_SYMBOL(init_task);
16651 +
16652 +/*
16653 + * Initial thread structure.
16654 + *
16655 + * We need to make sure that this is 8192-byte aligned due to the
16656 + * way process stacks are handled. This is done by having a special
16657 + * "init_task" linker map entry..
16658 + */
16659 +union thread_union init_thread_union
16660 +       __attribute__((__section__(".data.init_task"))) =
16661 +               { INIT_THREAD_INFO(init_task) };
16662 --- /dev/null
16663 +++ b/arch/ubicom32/kernel/irq.c
16664 @@ -0,0 +1,596 @@
16665 +/*
16666 + * arch/ubicom32/kernel/irq.c
16667 + *   Ubicom32 architecture IRQ support.
16668 + *
16669 + * (C) Copyright 2009, Ubicom, Inc.
16670 + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
16671 + *
16672 + * This file is part of the Ubicom32 Linux Kernel Port.
16673 + *
16674 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16675 + * it and/or modify it under the terms of the GNU General Public License
16676 + * as published by the Free Software Foundation, either version 2 of the
16677 + * License, or (at your option) any later version.
16678 + *
16679 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16680 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16681 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16682 + * the GNU General Public License for more details.
16683 + *
16684 + * You should have received a copy of the GNU General Public License
16685 + * along with the Ubicom32 Linux Kernel Port.  If not,
16686 + * see <http://www.gnu.org/licenses/>.
16687 + *
16688 + * Ubicom32 implementation derived from (with many thanks):
16689 + *   arch/m68knommu
16690 + *   arch/blackfin
16691 + *   arch/parisc
16692 + */
16693 +
16694 +#include <linux/types.h>
16695 +#include <linux/irq.h>
16696 +#include <linux/init.h>
16697 +#include <linux/kernel.h>
16698 +#include <linux/kernel_stat.h>
16699 +#include <linux/module.h>
16700 +#include <linux/seq_file.h>
16701 +#include <linux/proc_fs.h>
16702 +#include <asm/system.h>
16703 +#include <asm/traps.h>
16704 +#include <asm/ldsr.h>
16705 +#include <asm/ip5000.h>
16706 +#include <asm/machdep.h>
16707 +#include <asm/asm-offsets.h>
16708 +#include <asm/thread.h>
16709 +#include <asm/devtree.h>
16710 +
16711 +unsigned int irq_soft_avail;
16712 +static struct irqaction ubicom32_reserve_action[NR_IRQS];
16713 +
16714 +#if !defined(CONFIG_DEBUG_IRQMEASURE)
16715 +#define IRQ_DECLARE_MEASUREMENT
16716 +#define IRQ_MEASUREMENT_START()
16717 +#define IRQ_MEASUREMENT_END(irq)
16718 +#else
16719 +#define IRQ_DECLARE_MEASUREMENT \
16720 +       int __diff;             \
16721 +       unsigned int __tstart;
16722 +
16723 +#define IRQ_MEASUREMENT_START() \
16724 +       __tstart = UBICOM32_IO_TIMER->sysval;
16725 +
16726 +#define IRQ_MEASUREMENT_END(irq) \
16727 +       __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
16728 +       irq_measurement_update((irq), __diff);
16729 +
16730 +/*
16731 + * We keep track of the time spent in both irq_enter()
16732 + * and irq_exit().
16733 + */
16734 +#define IRQ_WEIGHT 32
16735 +
16736 +struct irq_measurement {
16737 +       volatile unsigned int min;
16738 +       volatile unsigned int avg;
16739 +       volatile unsigned int max;
16740 +};
16741 +
16742 +static DEFINE_SPINLOCK(irq_measurement_lock);
16743 +
16744 +/*
16745 + *  Add 1 in for softirq (irq_exit());
16746 + */
16747 +static struct irq_measurement irq_measurements[NR_IRQS + 1];
16748 +
16749 +/*
16750 + * irq_measurement_update()
16751 + *     Update an entry in the measurement array for this irq.
16752 + */
16753 +static void irq_measurement_update(int irq, int sample)
16754 +{
16755 +       struct irq_measurement *im = &irq_measurements[irq];
16756 +       spin_lock(&irq_measurement_lock);
16757 +       if ((im->min == 0) || (im->min > sample)) {
16758 +               im->min = sample;
16759 +       }
16760 +       if (im->max < sample) {
16761 +               im->max = sample;
16762 +       }
16763 +       im->avg = ((im->avg * (IRQ_WEIGHT - 1)) + sample) / IRQ_WEIGHT;
16764 +       spin_unlock(&irq_measurement_lock);
16765 +}
16766 +#endif
16767 +
16768 +/*
16769 + * irq_kernel_stack_check()
16770 + *     See if the kernel stack is within STACK_WARN of the end.
16771 + */
16772 +static void irq_kernel_stack_check(int irq, struct pt_regs *regs)
16773 +{
16774 +#ifdef CONFIG_DEBUG_STACKOVERFLOW
16775 +       unsigned long sp;
16776 +
16777 +       /*
16778 +        * Make sure that we are not close to the top of the stack and thus
16779 +        * can not really service this interrupt.
16780 +        */
16781 +       asm volatile (
16782 +               "and.4          %0, SP, %1 \n\t"
16783 +               : "=d" (sp)
16784 +               : "d" (THREAD_SIZE - 1)
16785 +               : "cc"
16786 +       );
16787 +
16788 +       if (sp < (sizeof(struct thread_info) + STACK_WARN)) {
16789 +               printk(KERN_WARNING
16790 +                       "cpu[%d]: possible overflow detected sp remain: %p, "
16791 +                      "irq: %d, regs: %p\n",
16792 +                       thread_get_self(), (void *)sp, irq, regs);
16793 +               dump_stack();
16794 +       }
16795 +
16796 +       if (sp < (sizeof(struct thread_info) + 16)) {
16797 +               THREAD_STALL;
16798 +       }
16799 +#endif
16800 +}
16801 +
16802 +/*
16803 + * irq_get_lsb()
16804 + *     Get the LSB set in value
16805 + */
16806 +static int irq_get_lsb(unsigned int value)
16807 +{
16808 +       static unsigned char irq_bits[8] = {
16809 +               3, 0, 1, 0, 2, 0, 1, 0
16810 +       };
16811 +       u32_t nextbit = 0;
16812 +
16813 +       value = (value >> nextbit) | (value << ((sizeof(value) * 8) - nextbit));
16814 +
16815 +       /*
16816 +        * It's unlikely that we find that we execute the body of this while
16817 +        * loop.  50% of the time we won't take this at all and then of the
16818 +        * cases where we do about 50% of those we only execute once.
16819 +        */
16820 +       if (!(value & 0xffff)) {
16821 +               nextbit += 0x10;
16822 +               value >>= 16;
16823 +       }
16824 +
16825 +       if (!(value & 0xff)) {
16826 +               nextbit += 0x08;
16827 +               value >>= 8;
16828 +       }
16829 +
16830 +       if (!(value & 0xf)) {
16831 +               nextbit += 0x04;
16832 +               value >>= 4;
16833 +       }
16834 +
16835 +       nextbit += irq_bits[value & 0x7];
16836 +       if (nextbit > 63) {
16837 +               panic("nextbit out of range: %d\n", nextbit);
16838 +       }
16839 +       return nextbit;
16840 +}
16841 +
16842 +/*
16843 + * ubicom32_reserve_handler()
16844 + *     Bogus handler associated with pre-reserved IRQ(s).
16845 + */
16846 +static irqreturn_t ubicom32_reserve_handler(int irq, void *dev_id)
16847 +{
16848 +       BUG();
16849 +       return IRQ_HANDLED;
16850 +}
16851 +
16852 +/*
16853 + * __irq_disable_vector()
16854 + *     Disable the interrupt by clearing the appropriate bit in the
16855 + *     LDSR Mask Register.
16856 + */
16857 +static void __irq_disable_vector(unsigned int irq)
16858 +{
16859 +       ldsr_disable_vector(irq);
16860 +}
16861 +
16862 +/*
16863 + * __irq_ack_vector()
16864 + *     Acknowledge the specific interrupt by clearing the associate bit in
16865 + *     hardware
16866 + */
16867 +static void __irq_ack_vector(unsigned int irq)
16868 +{
16869 +       if (irq < 32) {
16870 +               asm volatile ("move.4 INT_CLR0, %0" : : "d" (1 << irq));
16871 +       } else {
16872 +               asm volatile ("move.4 INT_CLR1, %0" : : "d" (1 << (irq - 32)));
16873 +       }
16874 +}
16875 +
16876 +/*
16877 + * __irq_enable_vector()
16878 + *     Clean and then enable the interrupt by setting the appropriate bit in
16879 + *     the LDSR Mask Register.
16880 + */
16881 +static void __irq_enable_vector(unsigned int irq)
16882 +{
16883 +       /*
16884 +        * Acknowledge, really clear the vector.
16885 +        */
16886 +       __irq_ack_vector(irq);
16887 +       ldsr_enable_vector(irq);
16888 +}
16889 +
16890 +/*
16891 + * __irq_mask_vector()
16892 + */
16893 +static void __irq_mask_vector(unsigned int irq)
16894 +{
16895 +       ldsr_mask_vector(irq);
16896 +}
16897 +
16898 +/*
16899 + * __irq_unmask_vector()
16900 + */
16901 +static void __irq_unmask_vector(unsigned int irq)
16902 +{
16903 +       ldsr_unmask_vector(irq);
16904 +}
16905 +
16906 +/*
16907 + * __irq_end_vector()
16908 + *     Called once an interrupt is completed (reset the LDSR mask).
16909 + */
16910 +static void __irq_end_vector(unsigned int irq)
16911 +{
16912 +       ldsr_unmask_vector(irq);
16913 +}
16914 +
16915 +#if defined(CONFIG_SMP)
16916 +/*
16917 + * __irq_set_affinity()
16918 + *     Set the cpu affinity for this interrupt.
16919 + */
16920 +static void __irq_set_affinity(unsigned int irq, cpumask_t dest)
16921 +{
16922 +       smp_set_affinity(irq, dest);
16923 +       irq_desc[irq].affinity = dest;
16924 +}
16925 +#endif
16926 +
16927 +/*
16928 + * On-Chip Generic Interrupt function handling.
16929 + */
16930 +static struct irq_chip ubicom32_irq_chip = {
16931 +       .name           = "Ubicom32",
16932 +       .startup        = NULL,
16933 +       .shutdown       = NULL,
16934 +       .enable         = __irq_enable_vector,
16935 +       .disable        = __irq_disable_vector,
16936 +       .ack            = __irq_ack_vector,
16937 +       .mask           = __irq_mask_vector,
16938 +       .unmask         = __irq_unmask_vector,
16939 +       .end            = __irq_end_vector,
16940 +#if defined(CONFIG_SMP)
16941 +       .set_affinity   = __irq_set_affinity,
16942 +#endif
16943 +};
16944 +
16945 +/*
16946 + * do_IRQ()
16947 + *     Primary interface for handling IRQ() requests.
16948 + */
16949 +asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
16950 +{
16951 +       struct pt_regs *oldregs;
16952 +       struct thread_info *ti;
16953 +       unsigned long sp;
16954 +
16955 +       IRQ_DECLARE_MEASUREMENT;
16956 +
16957 +       oldregs = set_irq_regs(regs);
16958 +
16959 +       /*
16960 +        * Before we call the handler and potentially enable
16961 +        * interrupts, track the nesting level.
16962 +        */
16963 +       asm volatile (
16964 +               "and.4          %0, SP, %1 \n\t"
16965 +               : "=d" (sp)
16966 +               : "d" (~(THREAD_SIZE - 1))
16967 +               : "cc"
16968 +       );
16969 +       ti = (struct thread_info *)sp;
16970 +       ti->interrupt_nesting++;
16971 +
16972 +       /*
16973 +        * Check for possible stack overflow on the kernel stack.
16974 +        */
16975 +       irq_kernel_stack_check(irq, regs);
16976 +
16977 +       /*
16978 +        * Execute the IRQ handler and any pending SoftIRQ requests.
16979 +        */
16980 +       BUG_ON(!irqs_disabled());
16981 +       irq_enter();
16982 +
16983 +       BUG_ON(!irqs_disabled());
16984 +       IRQ_MEASUREMENT_START();
16985 +       __do_IRQ(irq);
16986 +       IRQ_MEASUREMENT_END(irq);
16987 +       BUG_ON(!irqs_disabled());
16988 +
16989 +       IRQ_MEASUREMENT_START();
16990 +       irq_exit();
16991 +       IRQ_MEASUREMENT_END(NR_IRQS);
16992 +       BUG_ON(!irqs_disabled());
16993 +
16994 +       set_irq_regs(oldregs);
16995 +       ti->interrupt_nesting--;
16996 +}
16997 +
16998 +/*
16999 + * irq_soft_alloc()
17000 + *     Allocate a soft IRQ.
17001 + */
17002 +int irq_soft_alloc(unsigned int *soft)
17003 +{
17004 +       if (irq_soft_avail == 0) {
17005 +               printk(KERN_NOTICE "no soft irqs to allocate\n");
17006 +               return -EFAULT;
17007 +       }
17008 +
17009 +       *soft = irq_get_lsb(irq_soft_avail);
17010 +       irq_soft_avail &= ~(1 << *soft);
17011 +       return 0;
17012 +}
17013 +
17014 +/*
17015 + * ack_bad_irq()
17016 + *     Called to handle an bad irq request.
17017 + */
17018 +void ack_bad_irq(unsigned int irq)
17019 +{
17020 +       printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
17021 +       __irq_end_vector(irq);
17022 +}
17023 +
17024 +/*
17025 + * show_interrupts()
17026 + *     Return a string that displays the state of each of the interrupts.
17027 + */
17028 +int show_interrupts(struct seq_file *p, void *v)
17029 +{
17030 +       struct irqaction *ap;
17031 +       int irq = *((loff_t *) v);
17032 +       int j;
17033 +
17034 +       if (irq >= NR_IRQS) {
17035 +               return 0;
17036 +       }
17037 +
17038 +       if (irq == 0) {
17039 +               seq_puts(p, "           ");
17040 +               for_each_online_cpu(j) {
17041 +                       seq_printf(p, "CPU%d       ", j);
17042 +               }
17043 +               seq_putc(p, '\n');
17044 +       }
17045 +
17046 +       ap = irq_desc[irq].action;
17047 +       if (ap) {
17048 +               seq_printf(p, "%3d: ", irq);
17049 +               for_each_online_cpu(j) {
17050 +                       seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
17051 +               }
17052 +               seq_printf(p, "%14s  ", irq_desc[irq].chip->name);
17053 +               seq_printf(p, "%s", ap->name);
17054 +               for (ap = ap->next; ap; ap = ap->next) {
17055 +                       seq_printf(p, ", %s", ap->name);
17056 +               }
17057 +               seq_putc(p, '\n');
17058 +       }
17059 +       return 0;
17060 +}
17061 +
17062 +#if defined(CONFIG_DEBUG_IRQMEASURE)
17063 +static unsigned int irq_cycles_to_micro(unsigned int cycles, unsigned int frequency)
17064 +{
17065 +       unsigned int micro = (cycles / (frequency / 1000000));
17066 +       return micro;
17067 +}
17068 +
17069 +/*
17070 + * irq_measurement_show()
17071 + *     Print out the min, avg, max values for each IRQ
17072 + *
17073 + * By request, the max value is reset after each dump.
17074 + */
17075 +static int irq_measurement_show(struct seq_file *p, void *v)
17076 +{
17077 +       struct irqaction *ap;
17078 +       unsigned int freq = processor_frequency();
17079 +       int irq = *((loff_t *) v);
17080 +
17081 +
17082 +       if (irq == 0) {
17083 +               seq_puts(p, "\tmin\tavg\tmax\t(micro-seconds)\n");
17084 +       }
17085 +
17086 +       if (irq > NR_IRQS) {
17087 +               return 0;
17088 +       }
17089 +
17090 +       if (irq == NR_IRQS) {
17091 +               unsigned int min, avg, max;
17092 +               spin_lock(&irq_measurement_lock);
17093 +               min = irq_cycles_to_micro(irq_measurements[irq].min, freq);
17094 +               avg = irq_cycles_to_micro(irq_measurements[irq].avg, freq);
17095 +               max = irq_cycles_to_micro(irq_measurements[irq].max, freq);
17096 +               irq_measurements[irq].max = 0;
17097 +               spin_unlock(&irq_measurement_lock);
17098 +               seq_printf(p, "   \t%u\t%u\t%u\tsoftirq\n", min, avg, max);
17099 +               return 0;
17100 +       }
17101 +
17102 +       ap = irq_desc[irq].action;
17103 +       if (ap) {
17104 +               unsigned int min, avg, max;
17105 +               spin_lock(&irq_measurement_lock);
17106 +               min = irq_cycles_to_micro(irq_measurements[irq].min, freq);
17107 +               avg = irq_cycles_to_micro(irq_measurements[irq].avg, freq);
17108 +               max = irq_cycles_to_micro(irq_measurements[irq].max, freq);
17109 +               irq_measurements[irq].max = 0;
17110 +               spin_unlock(&irq_measurement_lock);
17111 +               seq_printf(p, "%2u:\t%u\t%u\t%u\t%s\n", irq, min, avg, max, ap->name);
17112 +       }
17113 +       return 0;
17114 +}
17115 +
17116 +static void *irq_measurement_start(struct seq_file *f, loff_t *pos)
17117 +{
17118 +       return (*pos <= NR_IRQS) ? pos : NULL;
17119 +}
17120 +
17121 +static void *irq_measurement_next(struct seq_file *f, void *v, loff_t *pos)
17122 +{
17123 +       (*pos)++;
17124 +       if (*pos > NR_IRQS)
17125 +               return NULL;
17126 +       return pos;
17127 +}
17128 +
17129 +static void irq_measurement_stop(struct seq_file *f, void *v)
17130 +{
17131 +       /* Nothing to do */
17132 +}
17133 +
17134 +static const struct seq_operations irq_measurement_seq_ops = {
17135 +       .start = irq_measurement_start,
17136 +       .next  = irq_measurement_next,
17137 +       .stop  = irq_measurement_stop,
17138 +       .show  = irq_measurement_show,
17139 +};
17140 +
17141 +static int irq_measurement_open(struct inode *inode, struct file *filp)
17142 +{
17143 +       return seq_open(filp, &irq_measurement_seq_ops);
17144 +}
17145 +
17146 +static const struct file_operations irq_measurement_fops = {
17147 +       .open           = irq_measurement_open,
17148 +       .read           = seq_read,
17149 +       .llseek         = seq_lseek,
17150 +       .release        = seq_release,
17151 +};
17152 +
17153 +static int __init irq_measurement_init(void)
17154 +{
17155 +       proc_create("irq_measurements", 0, NULL, &irq_measurement_fops);
17156 +       return 0;
17157 +}
17158 +module_init(irq_measurement_init);
17159 +#endif
17160 +
17161 +/*
17162 + * init_IRQ(void)
17163 + *     Initialize the on-chip IRQ subsystem.
17164 + */
17165 +void __init init_IRQ(void)
17166 +{
17167 +       int irq;
17168 +       struct devtree_node *p = NULL;
17169 +       struct devtree_node *iter = NULL;
17170 +       unsigned int mask = 0;
17171 +       unsigned int reserved = 0;
17172 +
17173 +       /*
17174 +        * Pull out the list of software interrupts that are avialable to
17175 +        * Linux and provide an allocation function for them.  The first
17176 +        * 24 interrupts of INT0 are software interrupts.
17177 +        */
17178 +       irq_soft_avail = 0;
17179 +       if (processor_interrupts(&irq_soft_avail, NULL) < 0) {
17180 +               printk(KERN_WARNING "No Soft IRQ(s) available\n");
17181 +       }
17182 +       irq_soft_avail &= ((1 << 24) - 1);
17183 +
17184 +       /*
17185 +        * Initialize all of the on-chip interrupt handling
17186 +        * to use a common set of interrupt functions.
17187 +        */
17188 +       for (irq = 0; irq < NR_IRQS; irq++) {
17189 +               irq_desc[irq].status = IRQ_DISABLED;
17190 +               irq_desc[irq].action = NULL;
17191 +               irq_desc[irq].depth = 1;
17192 +               set_irq_chip(irq, &ubicom32_irq_chip);
17193 +       }
17194 +
17195 +       /*
17196 +        * The sendirq of a devnode is not registered within Linux but instead
17197 +        * is used by the software I/O thread.  These interrupts are reserved.
17198 +        * The recvirq is used by Linux and registered by a device driver, these
17199 +        * are not reserved.
17200 +        *
17201 +        * recvirq(s) that are in the software interrupt range are not supposed
17202 +        * to be marked as reserved.  We track this while we scan the device
17203 +        * nodes.
17204 +        */
17205 +       p = devtree_find_next(&iter);
17206 +       while (p) {
17207 +               unsigned char sendirq, recvirq;
17208 +               devtree_irq(p, &sendirq, &recvirq);
17209 +
17210 +               /*
17211 +                * If the sendirq is valid, mark that irq as taken by the
17212 +                * devtree node.
17213 +                */
17214 +               if (sendirq < NR_IRQS) {
17215 +                       ubicom32_reserve_action[sendirq].handler =
17216 +                               ubicom32_reserve_handler;
17217 +                       ubicom32_reserve_action[sendirq].name = p->name;
17218 +                       irq_desc[sendirq].action =
17219 +                               &ubicom32_reserve_action[sendirq];
17220 +                       mask |= (1 << sendirq);
17221 +               }
17222 +
17223 +               /*
17224 +                * Track the relevant recieve IRQ(s)
17225 +                */
17226 +               if (recvirq < 24) {
17227 +                       mask |= (1 << recvirq);
17228 +               }
17229 +
17230 +               /*
17231 +                * Move to the next node.
17232 +                */
17233 +               p = devtree_find_next(&iter);
17234 +       }
17235 +
17236 +       /*
17237 +        * Remove these bits from the irq_soft_avail list and then use the
17238 +        * result as the list of pre-reserved IRQ(s).
17239 +        */
17240 +       reserved = ~irq_soft_avail & ~mask;
17241 +       for (irq = 0; irq < 24; irq++) {
17242 +               if ((reserved & (1 << irq))) {
17243 +                       ubicom32_reserve_action[irq].handler =
17244 +                               ubicom32_reserve_handler;
17245 +                       ubicom32_reserve_action[irq].name = "reserved";
17246 +                       irq_desc[irq].action = &ubicom32_reserve_action[irq];
17247 +               }
17248 +       }
17249 +
17250 +       /*
17251 +        * Initialize the LDSR which is the Ubicom32 programmable
17252 +        * interrupt controller.
17253 +        */
17254 +       ldsr_init();
17255 +
17256 +       /*
17257 +        * The Ubicom trap code needs a 2nd init after IRQ(s) are setup.
17258 +        */
17259 +       trap_init_interrupt();
17260 +}
17261 --- /dev/null
17262 +++ b/arch/ubicom32/kernel/ldsr.c
17263 @@ -0,0 +1,1176 @@
17264 +/*
17265 + * arch/ubicom32/kernel/ldsr.c
17266 + *   Ubicom32 architecture Linux Device Services Driver Interface
17267 + *
17268 + * (C) Copyright 2009, Ubicom, Inc.
17269 + *
17270 + * This file is part of the Ubicom32 Linux Kernel Port.
17271 + *
17272 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
17273 + * it and/or modify it under the terms of the GNU General Public License
17274 + * as published by the Free Software Foundation, either version 2 of the
17275 + * License, or (at your option) any later version.
17276 + *
17277 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
17278 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
17279 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17280 + * the GNU General Public License for more details.
17281 + *
17282 + * You should have received a copy of the GNU General Public License
17283 + * along with the Ubicom32 Linux Kernel Port.  If not,
17284 + * see <http://www.gnu.org/licenses/>.
17285 + *
17286 + * Ubicom32 implementation derived from (with many thanks):
17287 + *   arch/m68knommu
17288 + *   arch/blackfin
17289 + *   arch/parisc
17290 + *
17291 + * NOTES:
17292 + *
17293 + * The LDSR is a programmable interrupt controller that is written in software.
17294 + * It emulates the behavior of an pic by fielding the interrupts, choosing a
17295 + * victim thread to take the interrupt and forcing that thread to take a context
17296 + * switch to the appropriate interrupt handler.
17297 + *
17298 + * Because traps are treated as just a special class of interrupts, the LDSR
17299 + * also handles the processing of traps.
17300 + *
17301 + * Because we compile Linux both UP and SMP, we need the LDSR to use
17302 + * architectural locking that is not "compiled out" when compiling UP.  For now,
17303 + * we use the single atomic bit lock.
17304 + */
17305 +#include <linux/kernel.h>
17306 +#include <linux/init.h>
17307 +#include <linux/sched.h>
17308 +#include <linux/interrupt.h>
17309 +#include <linux/irq.h>
17310 +#include <linux/profile.h>
17311 +#include <linux/clocksource.h>
17312 +#include <linux/types.h>
17313 +#include <linux/module.h>
17314 +#include <linux/cpumask.h>
17315 +#include <linux/bug.h>
17316 +#include <linux/delay.h>
17317 +#include <asm/ip5000.h>
17318 +#include <asm/atomic.h>
17319 +#include <asm/machdep.h>
17320 +#include <asm/asm-offsets.h>
17321 +#include <asm/traps.h>
17322 +#include <asm/thread.h>
17323 +#include <asm/range-protect.h>
17324 +
17325 +/*
17326 + * One can not print from the LDSR so the best we can do is
17327 + * check a condition and stall all of the threads.
17328 + */
17329 +
17330 +// #define DEBUG_LDSR 1
17331 +#if defined(DEBUG_LDSR)
17332 +#define DEBUG_ASSERT(cond) \
17333 +       if (!(cond)) { \
17334 +               THREAD_STALL; \
17335 +       }
17336 +#else
17337 +#define DEBUG_ASSERT(cond)
17338 +#endif
17339 +
17340 +/*
17341 + * Make global so that we can use it in the RFI code in assembly.
17342 + */
17343 +unsigned int ldsr_soft_irq_mask;
17344 +EXPORT_SYMBOL(ldsr_soft_irq_mask);
17345 +
17346 +static unsigned int ldsr_suspend_mask;
17347 +static unsigned int ldsr_soft_irq;
17348 +static unsigned int ldsr_stack_space[1024];
17349 +
17350 +static struct ldsr_register_bank {
17351 +       volatile unsigned int enabled0;
17352 +       volatile unsigned int enabled1;
17353 +       volatile unsigned int mask0;
17354 +       volatile unsigned int mask1;
17355 +       unsigned int total;
17356 +       unsigned int retry;
17357 +       unsigned int backout;
17358 +} ldsr_interrupt;
17359 +
17360 +/*
17361 + * Which thread/cpu are we?
17362 + */
17363 +static int ldsr_tid = -1;
17364 +
17365 +#if defined(CONFIG_IRQSTACKS)
17366 +/*
17367 + * per-CPU IRQ stacks (thread information and stack)
17368 + *
17369 + * NOTE: Do not use DEFINE_PER_CPU() as it makes it harder
17370 + * to find the location of ctx from assembly language.
17371 + */
17372 +union irq_ctx {
17373 +       struct thread_info      tinfo;
17374 +       u32                     stack[THREAD_SIZE/sizeof(u32)];
17375 +};
17376 +static union irq_ctx *percpu_irq_ctxs[NR_CPUS];
17377 +
17378 +/*
17379 + *  Storage for the interrupt stack.
17380 + */
17381 +#if !defined(CONFIG_IRQSTACKS_USEOCM)
17382 +static char percpu_irq_stacks[(NR_CPUS * THREAD_SIZE) + (THREAD_SIZE - 1)];
17383 +#else
17384 +/*
17385 + *  For OCM, the linker will ensure that space is allocated for the stack
17386 + *  see (vmlinux.lds.S)
17387 + */
17388 +static char percpu_irq_stacks[];
17389 +#endif
17390 +
17391 +#endif
17392 +
17393 +/*
17394 + * Save trap IRQ because we need to un-suspend if it gets set.
17395 + */
17396 +static unsigned int ldsr_trap_irq_mask;
17397 +static unsigned int ldsr_trap_irq;
17398 +
17399 +/*
17400 + * ret_from_interrupt_to_kernel
17401 + *     Just restore the context and do nothing else.
17402 + */
17403 +asmlinkage void ret_from_interrupt_to_kernel(void)__attribute__((naked));
17404 +
17405 +/*
17406 + * ret_from_interrupt_to_user
17407 + *     Call scheduler if needed. Just restore the context.
17408 + */
17409 +asmlinkage void ret_from_interrupt_to_user(void)__attribute__((naked));
17410 +
17411 +#ifdef DEBUG_LDSR
17412 +u32_t old_sp, old_pc, old_a0, old_a5, old_a3;
17413 +struct pt_regs copy_regs, *copy_save_area;
17414 +#endif
17415 +
17416 +int __user_mode(unsigned long sp)
17417 +{
17418 +
17419 +       u32_t saved_stack_base = sp & ~(ASM_THREAD_SIZE - 1);
17420 +#if defined(CONFIG_IRQSTACKS_USEOCM)
17421 +       if ((union irq_ctx *)saved_stack_base == percpu_irq_ctxs[smp_processor_id()]) {
17422 +               /*
17423 +                *  On the interrupt stack.
17424 +                */
17425 +               return 0;
17426 +       }
17427 +#endif
17428 +
17429 +       if (!(u32_t)current) {
17430 +               return 0;
17431 +       }
17432 +       return saved_stack_base != ((u32_t)current->stack);
17433 +}
17434 +
17435 +/*
17436 + * ldsr_lock_release()
17437 + *     Release the LDSR lock.
17438 + */
17439 +static void ldsr_lock_release(void)
17440 +{
17441 +       UBICOM32_UNLOCK(LDSR_LOCK_BIT);
17442 +}
17443 +
17444 +/*
17445 + * ldsr_lock_acquire()
17446 + *     Acquire the LDSR lock, spin if not available.
17447 + */
17448 +static void ldsr_lock_acquire(void)
17449 +{
17450 +       UBICOM32_LOCK(LDSR_LOCK_BIT);
17451 +}
17452 +
17453 +/*
17454 + * ldsr_thread_irq_disable()
17455 + *     Disable interrupts for the specified thread.
17456 + */
17457 +static void ldsr_thread_irq_disable(unsigned int tid)
17458 +{
17459 +       unsigned int mask = (1 << tid);
17460 +
17461 +       asm volatile (
17462 +       "       or.4    scratchpad1, scratchpad1, %0    \n\t"
17463 +               :
17464 +               : "d"(mask)
17465 +               : "cc"
17466 +       );
17467 +}
17468 +
17469 +/*
17470 + * ldsr_thread_get_interrupts()
17471 + *     Get the interrupt state for all threads.
17472 + */
17473 +static unsigned long ldsr_thread_get_interrupts(void)
17474 +{
17475 +       unsigned long ret = 0;
17476 +       asm volatile (
17477 +       "       move.4  %0, scratchpad1 \n\t"
17478 +               : "=r" (ret)
17479 +               :
17480 +       );
17481 +       return ret;
17482 +}
17483 +
17484 +/*
17485 + * ldsr_emulate_and_run()
17486 + *     Emulate the instruction and then set the thread to run.
17487 + */
17488 +static void ldsr_emulate_and_run(unsigned int tid)
17489 +{
17490 +       unsigned int thread_mask = (1 << tid);
17491 +       u32_t write_csr = (tid << 15) | (1 << 14);
17492 +
17493 +       /*
17494 +        * Emulate the unaligned access.
17495 +        */
17496 +       unaligned_emulate(tid);
17497 +
17498 +       /*
17499 +        * Get the thread back in a running state.
17500 +        */
17501 +       asm volatile (
17502 +       "       setcsr  %0                      \n\t"
17503 +       "       setcsr_flush 0                  \n\t"
17504 +       "       move.4  trap_cause, #0          \n\t" /* Clear the trap cause
17505 +                                                      * register */
17506 +       "       setcsr  #0                      \n\t"
17507 +       "       setcsr_flush 0                  \n\t"
17508 +       "       move.4  mt_dbg_active_set, %1   \n\t" /* Activate thread even if
17509 +                                                      * in dbg/fault state */
17510 +       "       move.4  mt_active_set, %1       \n\t" /* Restart target
17511 +                                                      * thread. */
17512 +               :
17513 +               : "r" (write_csr), "d" (thread_mask)
17514 +               : "cc"
17515 +       );
17516 +       thread_enable_mask(thread_mask);
17517 +}
17518 +
17519 +/*
17520 + * ldsr_preemptive_context_save()
17521 + *     save thread context from another hardware thread.  The other thread must
17522 + *     be stalled.
17523 + */
17524 +static inline void ldsr_preemptive_context_save(u32_t thread,
17525 +                                               struct pt_regs *regs)
17526 +{
17527 +       /*
17528 +        * Save the current state of the specified thread
17529 +        */
17530 +       asm volatile (
17531 +       "       move.4  a3, %0                                  \n\t"
17532 +
17533 +               /* set src1 from the target thread */
17534 +       "       move.4  csr, %1                                 \n\t"
17535 +       "       setcsr_flush 0                                  \n\t"
17536 +       "       setcsr_flush 0                                  \n\t"
17537 +
17538 +               /* copy state from the other thread */
17539 +       "       move.4  "D(PT_D0)"(a3), d0                      \n\t"
17540 +       "       move.4  "D(PT_D1)"(a3), d1                      \n\t"
17541 +       "       move.4  "D(PT_D2)"(a3), d2                      \n\t"
17542 +       "       move.4  "D(PT_D3)"(a3), d3                      \n\t"
17543 +       "       move.4  "D(PT_D4)"(a3), d4                      \n\t"
17544 +       "       move.4  "D(PT_D5)"(a3), d5                      \n\t"
17545 +       "       move.4  "D(PT_D6)"(a3), d6                      \n\t"
17546 +       "       move.4  "D(PT_D7)"(a3), d7                      \n\t"
17547 +       "       move.4  "D(PT_D8)"(a3), d8                      \n\t"
17548 +       "       move.4  "D(PT_D9)"(a3), d9                      \n\t"
17549 +       "       move.4  "D(PT_D10)"(a3), d10                    \n\t"
17550 +       "       move.4  "D(PT_D11)"(a3), d11                    \n\t"
17551 +       "       move.4  "D(PT_D12)"(a3), d12                    \n\t"
17552 +       "       move.4  "D(PT_D13)"(a3), d13                    \n\t"
17553 +       "       move.4  "D(PT_D14)"(a3), d14                    \n\t"
17554 +       "       move.4  "D(PT_D15)"(a3), d15                    \n\t"
17555 +       "       move.4  "D(PT_A0)"(a3), a0                      \n\t"
17556 +       "       move.4  "D(PT_A1)"(a3), a1                      \n\t"
17557 +       "       move.4  "D(PT_A2)"(a3), a2                      \n\t"
17558 +       "       move.4  "D(PT_A3)"(a3), a3                      \n\t"
17559 +       "       move.4  "D(PT_A4)"(a3), a4                      \n\t"
17560 +       "       move.4  "D(PT_A5)"(a3), a5                      \n\t"
17561 +       "       move.4  "D(PT_A6)"(a3), a6                      \n\t"
17562 +       "       move.4  "D(PT_SP)"(a3), a7                      \n\t"
17563 +       "       move.4  "D(PT_ACC0HI)"(a3), acc0_hi             \n\t"
17564 +       "       move.4  "D(PT_ACC0LO)"(a3), acc0_lo             \n\t"
17565 +       "       move.4  "D(PT_MAC_RC16)"(a3), mac_rc16          \n\t"
17566 +       "       move.4  "D(PT_ACC1HI)"(a3), acc1_hi             \n\t"
17567 +       "       move.4  "D(PT_ACC1LO)"(a3), acc1_lo             \n\t"
17568 +       "       move.4  "D(PT_SOURCE3)"(a3), source3            \n\t"
17569 +       "       move.4  "D(PT_INST_CNT)"(a3), inst_cnt          \n\t"
17570 +       "       move.4  "D(PT_CSR)"(a3), csr                    \n\t"
17571 +       "       move.4  "D(PT_DUMMY_UNUSED)"(a3), #0            \n\t"
17572 +       "       move.4  "D(PT_INT_MASK0)"(a3), int_mask0        \n\t"
17573 +       "       move.4  "D(PT_INT_MASK1)"(a3), int_mask1        \n\t"
17574 +       "       move.4  "D(PT_TRAP_CAUSE)"(a3), trap_cause      \n\t"
17575 +       "       move.4  "D(PT_PC)"(a3), pc                      \n\t"
17576 +       "       move.4  "D(PT_PREVIOUS_PC)"(a3), previous_pc    \n\t"
17577 +               /* disable csr thread select */
17578 +       "       movei   csr, #0                                 \n\t"
17579 +       "       setcsr_flush 0                                  \n\t"
17580 +       :
17581 +       : "r" (regs->dn), "d" ((thread << 9) | (1 << 8))
17582 +       : "a3"
17583 +       );
17584 +}
17585 +
17586 +/*
17587 + * ldsr_rotate_threads()
17588 + *     Simple round robin algorithm for choosing the next cpu
17589 + */
17590 +static int ldsr_rotate_threads(unsigned long cpus)
17591 +{
17592 +       static unsigned char ldsr_bits[8] = {
17593 +               3, 0, 1, 0, 2, 0, 1, 0
17594 +       };
17595 +
17596 +       static int nextbit;
17597 +       int thisbit;
17598 +
17599 +       /*
17600 +        * Move the interrupts down so that we consider interrupts from where
17601 +        * we left off, then take the interrupts we would lose and move them
17602 +        * to the top half of the interrupts value.
17603 +        */
17604 +       cpus = (cpus >> nextbit) | (cpus << ((sizeof(cpus) * 8) - nextbit));
17605 +
17606 +       /*
17607 +        * 50% of the time we won't take this at all and then of the cases where
17608 +        * we do about 50% of those we only execute once.
17609 +        */
17610 +       if (!(cpus & 0xffff)) {
17611 +               nextbit += 16;
17612 +               cpus >>= 16;
17613 +       }
17614 +
17615 +       if (!(cpus & 0xff)) {
17616 +               nextbit += 8;
17617 +               cpus >>= 8;
17618 +       }
17619 +
17620 +       if (!(cpus & 0xf)) {
17621 +               nextbit += 4;
17622 +               cpus >>= 4;
17623 +       }
17624 +
17625 +       nextbit += ldsr_bits[cpus & 0x7];
17626 +       thisbit = (nextbit & ((sizeof(cpus) * 8) - 1));
17627 +       nextbit = (thisbit + 1) & ((sizeof(cpus) * 8) - 1);
17628 +       DEBUG_ASSERT(thisbit < THREAD_ARCHITECTURAL_MAX);
17629 +       return thisbit;
17630 +}
17631 +
17632 +/*
17633 + * ldsr_rotate_interrupts()
17634 + *     Get rotating next set bit value.
17635 + */
17636 +static int ldsr_rotate_interrupts(unsigned long long interrupts)
17637 +{
17638 +       static unsigned char ldsr_bits[8] = {
17639 +               3, 0, 1, 0, 2, 0, 1, 0
17640 +       };
17641 +
17642 +       static int nextbit;
17643 +       int thisbit;
17644 +
17645 +       /*
17646 +        * Move the interrupts down so that we consider interrupts from where
17647 +        * we left off, then take the interrupts we would lose and move them
17648 +        * to the top half of the interrupts value.
17649 +        */
17650 +       interrupts = (interrupts >> nextbit) |
17651 +               (interrupts << ((sizeof(interrupts) * 8) - nextbit));
17652 +
17653 +       /*
17654 +        * 50% of the time we won't take this at all and then of the cases where
17655 +        * we do about 50% of those we only execute once.
17656 +        */
17657 +       if (!(interrupts & 0xffffffff)) {
17658 +               nextbit += 32;
17659 +               interrupts >>= 32;
17660 +       }
17661 +
17662 +       if (!(interrupts & 0xffff)) {
17663 +               nextbit += 16;
17664 +               interrupts >>= 16;
17665 +       }
17666 +
17667 +       if (!(interrupts & 0xff)) {
17668 +               nextbit += 8;
17669 +               interrupts >>= 8;
17670 +       }
17671 +
17672 +       if (!(interrupts & 0xf)) {
17673 +               nextbit += 4;
17674 +               interrupts >>= 4;
17675 +       }
17676 +
17677 +       nextbit += ldsr_bits[interrupts & 0x7];
17678 +       thisbit = (nextbit & ((sizeof(interrupts) * 8) - 1));
17679 +       nextbit = (thisbit + 1) & ((sizeof(interrupts) * 8) - 1);
17680 +
17681 +       DEBUG_ASSERT(thisbit < (sizeof(interrupts) * 8));
17682 +       return thisbit;
17683 +}
17684 +
17685 +/*
17686 + * ldsr_backout_or_irq()
17687 + *
17688 + * One way or the other this interrupt is not being
17689 + * processed, make sure that it is reset.  We are
17690 + * not going to call irq_end_vector() so unmask the
17691 + * interrupt.
17692 + */
17693 +static void ldsr_backout_of_irq(int vector, unsigned long tid_mask)
17694 +{
17695 +#if defined(CONFIG_SMP)
17696 +       if (unlikely(vector == smp_ipi_irq)) {
17697 +               smp_reset_ipi(tid_mask);
17698 +       }
17699 +#endif
17700 +       ldsr_unmask_vector(vector);
17701 +       ldsr_interrupt.backout++;
17702 +}
17703 +
17704 +#if defined(CONFIG_IRQSTACKS)
17705 +/*
17706 + * ldsr_choose_savearea_and_returnvec()
17707 + *     Test our current state (user, kernel, interrupt) and set things up.
17708 + *
17709 + * This version of the function uses 3 stacks and nests interrupts
17710 + * on the interrupt stack.
17711 + */
17712 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
17713 +{
17714 +       struct pt_regs *save_area;
17715 +       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
17716 +       struct thread_info * ti= (struct thread_info *)sw_ksp[tid];
17717 +
17718 +#if defined(CONFIG_SMP)
17719 +       union irq_ctx *icp = percpu_irq_ctxs[tid];
17720 +#else
17721 +       union irq_ctx *icp = percpu_irq_ctxs[0];
17722 +#endif
17723 +
17724 +       if (masked_linux_sp == (u32_t)icp) {
17725 +               /*
17726 +                * Fault/Interrupt occurred while on the interrupt stack.
17727 +                */
17728 +               save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17729 +               *pvec = (u32_t)(&ret_from_interrupt_to_kernel);
17730 +       } else {
17731 +               /*
17732 +                *  Fault/Interrupt occurred while on user/kernel stack.  This is a new
17733 +                *  first use of the interrupt stack.
17734 +                */
17735 +               save_area = (struct pt_regs *) ((char *)icp + sizeof(icp->stack) - sizeof(struct pt_regs) - 8);
17736 +               if (masked_linux_sp == (u32_t)ti) {
17737 +                       *pvec  = (u32_t)(&ret_from_interrupt_to_kernel);
17738 +               } else {
17739 +                       *pvec  = (u32_t)(&ret_from_interrupt_to_user);
17740 +               }
17741 +
17742 +               /*
17743 +                * Because the softirq code will execute on the "interrupt" stack, we
17744 +                * need to maintain the knowledge of what "task" was executing on the
17745 +                * cpu.  This is done by copying the thread_info->task from the cpu
17746 +                * we are about to context switch into the interrupt contexts thread_info
17747 +                * structure.
17748 +                */
17749 +               icp->tinfo.task = ti->task;
17750 +               icp->tinfo.preempt_count =
17751 +                               (icp->tinfo.preempt_count & ~SOFTIRQ_MASK) |
17752 +                               (ti->preempt_count & SOFTIRQ_MASK);
17753 +               icp->tinfo.interrupt_nesting = 0;
17754 +       }
17755 +       save_area->nesting_level = icp->tinfo.interrupt_nesting;
17756 +       return save_area;
17757 +}
17758 +
17759 +#else
17760 +/*
17761 + * ldsr_choose_savearea_and_returnvec()
17762 + *     Test our current state (user, kernel, interrupt) and set things up.
17763 + *
17764 + * The version of the function uses just the user & kernel stack and
17765 + * nests interrupts on the existing kernel stack.
17766 + */
17767 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
17768 +{
17769 +       struct pt_regs *save_area;
17770 +       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
17771 +       struct thread_info *ti = (struct thread_info *)sw_ksp[tid];
17772 +
17773 +       if (masked_linux_sp == (u32_t)ti) {
17774 +               /*
17775 +                * Fault/Interrupt occurred while on the kernel stack.
17776 +                */
17777 +               save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17778 +               *pvec = (u32_t) (&ret_from_interrupt_to_kernel);
17779 +       } else {
17780 +               /*
17781 +                *  Fault/Interrupt occurred while on user stack.
17782 +                */
17783 +               ti->interrupt_nesting = 0;
17784 +               save_area = (struct pt_regs *)((u32_t)ti + THREAD_SIZE - sizeof(struct pt_regs) - 8);
17785 +               *pvec  = (u32_t) (&ret_from_interrupt_to_user);
17786 +       }
17787 +       save_area->nesting_level = ti->interrupt_nesting;
17788 +       return save_area;
17789 +}
17790 +#endif
17791 +
17792 +/*
17793 + * ldsr_ctxsw_thread()
17794 + *     Context switch a mainline thread to execute do_IRQ() for the specified
17795 + *     vector.
17796 + */
17797 +static void ldsr_ctxsw_thread(int vector, thread_t tid)
17798 +{
17799 +       u32_t linux_sp;
17800 +       u32_t return_vector;
17801 +       struct pt_regs *save_area, *regs;
17802 +       u32_t thread_mask = (1 << tid);
17803 +       u32_t read_csr = ((tid << 9) | (1 << 8));
17804 +       u32_t write_csr = (tid << 15) | (1 << 14);
17805 +       u32_t interrupt_vector = (u32_t)(&do_IRQ);
17806 +
17807 +       unsigned int frame_type = UBICOM32_FRAME_TYPE_INTERRUPT;
17808 +
17809 +
17810 +       DEBUG_ASSERT(!thread_is_enabled(tid));
17811 +
17812 +       /*
17813 +        * Acquire the necessary global and per thread locks for tid.
17814 +        * As a side effect, we ensure that the thread has not trapped
17815 +        * and return true if it has.
17816 +        */
17817 +       if (unlikely(thread_is_trapped(tid))) {
17818 +               /*
17819 +                * Read the trap cause, the sp and clear the MT_TRAP bits.
17820 +                */
17821 +               unsigned int cause;
17822 +               asm volatile (
17823 +               "       setcsr  %3              \n\t"
17824 +               "       setcsr_flush 0          \n\t"
17825 +               "       setcsr_flush 0          \n\t"
17826 +               "       move.4  %0, TRAP_CAUSE  \n\t"
17827 +               "       move.4  %1, SP          \n\t"
17828 +               "       setcsr  #0              \n\t"
17829 +               "       setcsr_flush 0          \n\t"
17830 +               "       move.4  MT_BREAK_CLR, %2\n\t"
17831 +               "       move.4  MT_TRAP_CLR, %2 \n\t"
17832 +                       : "=&r" (cause), "=&r" (linux_sp)
17833 +                       : "r" (thread_mask), "m" (read_csr)
17834 +               );
17835 +
17836 +               ldsr_backout_of_irq(vector, (1 << tid));
17837 +
17838 +#if !defined(CONFIG_UNALIGNED_ACCESS_DISABLED)
17839 +               /*
17840 +                * See if the unaligned trap handler can deal with this.
17841 +                * If so, emulate the instruction and then just restart
17842 +                * the thread.
17843 +                */
17844 +               if (unaligned_only(cause)) {
17845 +#if defined(CONFIG_UNALIGNED_ACCESS_USERSPACE_ONLY)
17846 +                       /*
17847 +                        * Check if this is a kernel stack if so we will not
17848 +                        * handle the trap
17849 +                        */
17850 +                       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
17851 +                       if ((masked_linux_sp != (u32_t)sw_ksp[tid]) &&
17852 +                           unaligned_only(cause)) {
17853 +                               ldsr_emulate_and_run(tid);
17854 +                               return;
17855 +                       }
17856 +#else
17857 +                       ldsr_emulate_and_run(tid);
17858 +                       return;
17859 +#endif
17860 +
17861 +               }
17862 +#endif
17863 +
17864 +               interrupt_vector = (u32_t)(&trap_handler);
17865 +               frame_type = UBICOM32_FRAME_TYPE_TRAP;
17866 +       } else {
17867 +               /*
17868 +                * Read the target thread's SP
17869 +                */
17870 +               asm volatile (
17871 +               "       setcsr  %1              \n\t"
17872 +               "       setcsr_flush 0          \n\t"
17873 +               "       setcsr_flush 0          \n\t"
17874 +               "       move.4  %0, SP          \n\t"
17875 +               "       setcsr  #0              \n\t"
17876 +               "       setcsr_flush 0          \n\t"
17877 +                       : "=m" (linux_sp)
17878 +                       : "m" (read_csr)
17879 +               );
17880 +       }
17881 +
17882 +       /*
17883 +        * We are delivering an interrupt, count it.
17884 +        */
17885 +       ldsr_interrupt.total++;
17886 +
17887 +       /*
17888 +        * At this point, we will definitely force this thread to
17889 +        * a new context, show its interrupts as disabled.
17890 +        */
17891 +       ldsr_thread_irq_disable(tid);
17892 +
17893 +       /*
17894 +        * Test our current state (user, kernel, interrupt).  Save the
17895 +        * appropriate data and setup for the return.
17896 +        */
17897 +       save_area = ldsr_choose_savearea_and_returnvec(tid, linux_sp, &return_vector);
17898 +
17899 +       /*
17900 +        *  The pt_regs (save_area) contains the type of thread that we are dealing
17901 +        *  with (KERNEL/NORMAL) and is copied into each pt_regs area.  We get this
17902 +        *  from the current tasks kernel pt_regs area that always exists at the
17903 +        *  top of the kernel stack.
17904 +        */
17905 +       regs = (struct pt_regs *)((u32_t)sw_ksp[tid] + THREAD_SIZE - sizeof(struct pt_regs) - 8);
17906 +       save_area->thread_type = regs->thread_type;
17907 +
17908 +       /*
17909 +        * Preserve the context of the Linux thread.
17910 +        */
17911 +       ldsr_preemptive_context_save(tid, save_area);
17912 +
17913 +       /*
17914 +        * Load the fram_type into the save_area.
17915 +        */
17916 +       save_area->frame_type = frame_type;
17917 +
17918 +#ifdef CONFIG_STOP_ON_TRAP
17919 +       /*
17920 +        * Before we get backtrace and showing stacks working well, it sometimes
17921 +        * helps to enter the debugger when a trap occurs before we change the
17922 +        * thread to handle the fault.  This optional code causes all threads to
17923 +        * stop on every trap frame.  One assumes that GDB connected via the
17924 +        * mailbox interface will be used to recover from this state.
17925 +        */
17926 +       if (frame_type == UBICOM32_FRAME_TYPE_TRAP) {
17927 +               THREAD_STALL;
17928 +       }
17929 +#endif
17930 +
17931 +#ifdef DEBUG_LDSR
17932 +       copy_regs = *save_area;
17933 +       copy_save_area = save_area;
17934 +
17935 +       old_a0 = save_area->an[0];
17936 +       old_a3 = save_area->an[3];
17937 +       old_sp = save_area->an[7];
17938 +       old_a5 = save_area->an[5];
17939 +       old_pc = save_area->pc;
17940 +#endif
17941 +
17942 +       /*
17943 +        * Now we have to switch the kernel thread to run do_IRQ function.
17944 +        *      Set pc to do_IRQ
17945 +        *      Set d0 to vector
17946 +        *      Set d1 to save_area.
17947 +        *      Set a5 to the proper return vector.
17948 +        */
17949 +       asm volatile (
17950 +       "       setcsr  %0                      \n\t"
17951 +       "       setcsr_flush 0                  \n\t"
17952 +       "       move.4  d0, %5                  \n\t" /* d0 = 0 vector # */
17953 +       "       move.4  d1, %1                  \n\t" /* d1 = save_area */
17954 +       "       move.4  sp, %1                  \n\t" /* sp = save_area */
17955 +       "       move.4  a5, %2                  \n\t" /* a5 = return_vector */
17956 +       "       move.4  pc, %3                  \n\t" /* pc = do_IRQ routine. */
17957 +       "       move.4  trap_cause, #0          \n\t" /* Clear the trap cause
17958 +                                                      * register */
17959 +       "       setcsr  #0                      \n\t"
17960 +       "       setcsr_flush 0                  \n\t"
17961 +       "       enable_kernel_ranges %4         \n\t"
17962 +       "       move.4  mt_dbg_active_set, %4   \n\t" /* Activate thread even if
17963 +                                                      * in dbg/fault state */
17964 +       "       move.4  mt_active_set, %4       \n\t" /* Restart target
17965 +                                                      * thread. */
17966 +               :
17967 +               : "r" (write_csr), "r" (save_area),
17968 +                 "r" (return_vector), "r" (interrupt_vector),
17969 +                 "d" (thread_mask), "r" (vector)
17970 +               : "cc"
17971 +       );
17972 +       thread_enable_mask(thread_mask);
17973 +}
17974 +
17975 +/*
17976 + * ldsr_deliver_interrupt()
17977 + *     Deliver the interrupt to one of the threads or all of the threads.
17978 + */
17979 +static void ldsr_deliver_interrupt(int vector,
17980 +                                  unsigned long deliver_to,
17981 +                                  int all)
17982 +{
17983 +       unsigned long disabled_threads;
17984 +       unsigned long possible_threads;
17985 +       unsigned long trapped_threads;
17986 +       unsigned long global_locks;
17987 +
17988 +       /*
17989 +        * Disable all of the threads that we might want to send
17990 +        * this interrupt to.
17991 +        */
17992 +retry:
17993 +       DEBUG_ASSERT(deliver_to);
17994 +       thread_disable_mask(deliver_to);
17995 +
17996 +       /*
17997 +        * If any threads are in the trap state, we have to service the
17998 +        * trap for those threads first.
17999 +        */
18000 +       asm volatile (
18001 +               "move.4 %0, MT_TRAP             \n\t"
18002 +               : "=r" (trapped_threads)
18003 +               :
18004 +       );
18005 +
18006 +       trapped_threads &= deliver_to;
18007 +       if (unlikely(trapped_threads)) {
18008 +               /*
18009 +                * all traps will be handled, so clear the trap bit before restarting any threads
18010 +                */
18011 +               ubicom32_clear_interrupt(ldsr_trap_irq);
18012 +
18013 +               /*
18014 +                * Let the remaining untrapped threads, continue.
18015 +                */
18016 +               deliver_to &= ~trapped_threads;
18017 +               if (deliver_to) {
18018 +                       thread_enable_mask(deliver_to);
18019 +               }
18020 +
18021 +               /*
18022 +                * For the trapped threads force them to handle
18023 +                * a trap.
18024 +                */
18025 +               while (trapped_threads) {
18026 +                       unsigned long which = ffz(~trapped_threads);
18027 +                       trapped_threads &= ~(1 << which);
18028 +                       ldsr_ctxsw_thread(vector, which);
18029 +               }
18030 +               return;
18031 +       }
18032 +
18033 +       /*
18034 +        * Can we deliver an interrupt to any of the threads?
18035 +        */
18036 +       disabled_threads = ldsr_thread_get_interrupts();
18037 +       possible_threads = deliver_to & ~disabled_threads;
18038 +       if (unlikely(!possible_threads)) {
18039 +#if defined(CONFIG_SMP)
18040 +               /*
18041 +                * In the SMP case, we can not wait because 1 cpu might be
18042 +                * sending an IPI to another cpu which is currently blocked.
18043 +                * The only way to ensure IPI delivery is to backout and
18044 +                * keep trying.  For SMP, we don't sleep until the interrupts
18045 +                * are delivered.
18046 +                */
18047 +               thread_enable_mask(deliver_to);
18048 +               ldsr_backout_of_irq(vector, deliver_to);
18049 +               return;
18050 +#else
18051 +               /*
18052 +                * In the UP case, we have nothing to do so we should wait.
18053 +                *
18054 +                * Since the INT_MASK0 and INT_MASK1 are "re-loaded" before we
18055 +                * suspend in the outer loop, we do not need to save them here.
18056 +                *
18057 +                * We test that we were awakened for our specific interrupts
18058 +                * because the ldsr mask/unmask operations will force the ldsr
18059 +                * awake even if the interrupt on the mainline thread is not
18060 +                * completed.
18061 +                */
18062 +               unsigned int scratch = 0;
18063 +               thread_enable_mask(deliver_to);
18064 +               asm volatile (
18065 +               "       move.4  INT_MASK0, %1           \n\t"
18066 +               "       move.4  INT_MASK1, #0           \n\t"
18067 +
18068 +               "1:     suspend                         \n\t"
18069 +               "       move.4  %0, INT_STAT0           \n\t"
18070 +               "       and.4   %0, %0, %1              \n\t"
18071 +               "       jmpeq.f 1b                      \n\t"
18072 +
18073 +               "       move.4  INT_CLR0, %2            \n\t"
18074 +                       : "+r" (scratch)
18075 +                       : "d" (ldsr_suspend_mask), "r" (ldsr_soft_irq_mask)
18076 +                       : "cc"
18077 +               );
18078 +
18079 +               /*
18080 +                * This delay is sized to coincide with the time it takes a
18081 +                * thread to complete the exit (see return_from_interrupt).
18082 +                */
18083 +               ldsr_interrupt.retry++;
18084 +               __delay(10);
18085 +               goto retry;
18086 +#endif
18087 +       }
18088 +
18089 +       /*
18090 +        * If any of the global locks are held, we can not deliver any
18091 +        * interrupts, we spin delay(10) and then try again.  If our
18092 +        * spinning becomes a bottle neck, we will need to suspend but for
18093 +        * now lets just spin.
18094 +        */
18095 +       asm volatile (
18096 +               "move.4 %0, scratchpad1         \n\t"
18097 +               : "=r" (global_locks)
18098 +               :
18099 +       );
18100 +       if (unlikely(global_locks & 0xffff0000)) {
18101 +               thread_enable_mask(deliver_to);
18102 +
18103 +               /*
18104 +                * This delay is sized to coincide with the average time it
18105 +                * takes a thread to release a global lock.
18106 +                */
18107 +               ldsr_interrupt.retry++;
18108 +               __delay(10);
18109 +               goto retry;
18110 +       }
18111 +
18112 +       /*
18113 +        * Deliver to one cpu.
18114 +        */
18115 +       if (!all) {
18116 +               /*
18117 +                * Find our victim and then enable everyone else.
18118 +                */
18119 +               unsigned long victim = ldsr_rotate_threads(possible_threads);
18120 +               DEBUG_ASSERT((deliver_to & (1 << victim)));
18121 +               DEBUG_ASSERT((possible_threads & (1 << victim)));
18122 +
18123 +               deliver_to &= ~(1 << victim);
18124 +               if (deliver_to) {
18125 +                       thread_enable_mask(deliver_to);
18126 +               }
18127 +               ldsr_ctxsw_thread(vector, victim);
18128 +               return;
18129 +       }
18130 +
18131 +       /*
18132 +        * If we can't deliver to some threads, wake them
18133 +        * back up and reset things to deliver to them.
18134 +        */
18135 +       deliver_to &= ~possible_threads;
18136 +       if (unlikely(deliver_to)) {
18137 +               thread_enable_mask(deliver_to);
18138 +               ldsr_backout_of_irq(vector, deliver_to);
18139 +       }
18140 +
18141 +       /*
18142 +        * Deliver to all possible threads(s).
18143 +        */
18144 +       while (possible_threads) {
18145 +               unsigned long victim = ffz(~possible_threads);
18146 +               possible_threads &= ~(1 << victim);
18147 +               ldsr_ctxsw_thread(vector, victim);
18148 +       }
18149 +}
18150 +
18151 +/*
18152 + * ldsr_thread()
18153 + *     This thread acts as the interrupt controller for Linux.
18154 + */
18155 +static void ldsr_thread(void *arg)
18156 +{
18157 +       int stat0;
18158 +       int stat1;
18159 +       int interrupt0;
18160 +       int interrupt1;
18161 +       long long interrupts;
18162 +       unsigned long cpus;
18163 +
18164 +#if !defined(CONFIG_SMP)
18165 +       /*
18166 +        * In a non-smp configuration, we can not use the cpu(s) arrays because
18167 +        * there is not a 1-1 correspondence between cpus(s) and our threads.
18168 +        * Thus we must get a local idea of the mainline threads and use the
18169 +        * one and only 1 set as the victim.  We do this once before the ldsr
18170 +        * loop.
18171 +        *
18172 +        * In the SMP case, we will use the cpu(s) map to determine which cpu(s)
18173 +        * are valid to send interrupts to.
18174 +        */
18175 +       int victim = 0;
18176 +       unsigned int mainline = thread_get_mainline();
18177 +       if (mainline == 0) {
18178 +               panic("no mainline Linux threads to interrupt");
18179 +               return;
18180 +       }
18181 +       victim = ffz(~mainline);
18182 +       cpus = (1 << victim);
18183 +#endif
18184 +
18185 +       while (1) {
18186 +               /*
18187 +                * If one changes this code not to reload the INT_MASK(s), you
18188 +                * need to know that code in the lock waiting above does not
18189 +                * reset the MASK registers back; so that code will need to be
18190 +                * changed.
18191 +                */
18192 +               ldsr_lock_acquire();
18193 +               asm volatile (
18194 +               "       move.4 INT_MASK0, %0    \n\t"
18195 +               "       move.4 INT_MASK1, %1    \n\t"
18196 +                       :
18197 +                       : "U4" (ldsr_interrupt.mask0), "U4" (ldsr_interrupt.mask1)
18198 +               );
18199 +               ldsr_lock_release();
18200 +               thread_suspend();
18201 +
18202 +               /*
18203 +                * Read the interrupt status registers
18204 +                */
18205 +               asm volatile (
18206 +                       "move.4 %0, INT_STAT0   \n\t"
18207 +                       "move.4 %1, INT_STAT1   \n\t"
18208 +                       : "=r" (stat0), "=r" (stat1)
18209 +                       :
18210 +               );
18211 +
18212 +               /*
18213 +                * We only care about interrupts that we have been told to care
18214 +                * about.  The interrupt must be enabled, unmasked, and have
18215 +                * occurred in the hardware.
18216 +                */
18217 +               ldsr_lock_acquire();
18218 +               interrupt0 = ldsr_interrupt.enabled0 &
18219 +                       ldsr_interrupt.mask0 & stat0;
18220 +               interrupt1 = ldsr_interrupt.enabled1 &
18221 +                       ldsr_interrupt.mask1 & stat1;
18222 +               ldsr_lock_release();
18223 +
18224 +               /*
18225 +                * For each interrupt in the "snapshot" we will mask the
18226 +                * interrupt handle the interrupt (typically calling do_IRQ()).
18227 +                *
18228 +                * The interrupt is unmasked by desc->chip->end() function in
18229 +                * the per chip generic interrupt handling code
18230 +                * (arch/ubicom32/kernel/irq.c).8
18231 +                */
18232 +               interrupts = ((unsigned long long)interrupt1 << 32) |
18233 +                       interrupt0;
18234 +               while (interrupts) {
18235 +                       int all = 0;
18236 +                       int vector = ldsr_rotate_interrupts(interrupts);
18237 +                       interrupts &= ~((unsigned long long)1 << vector);
18238 +
18239 +                       /*
18240 +                        * Now mask off this vector so that the LDSR ignores
18241 +                        * it until it is acknowledged.
18242 +                        */
18243 +                       ldsr_mask_vector(vector);
18244 +#if !defined(CONFIG_SMP)
18245 +                       ldsr_deliver_interrupt(vector, cpus, all);
18246 +#else
18247 +                       cpus = smp_get_affinity(vector, &all);
18248 +                       if (cpus) {
18249 +                               ldsr_deliver_interrupt(vector, cpus, all);
18250 +                       }
18251 +#endif
18252 +               }
18253 +       }
18254 +
18255 +       /* NOTREACHED */
18256 +}
18257 +
18258 +/*
18259 + * ldsr_mask_vector()
18260 + *     Temporarily mask the interrupt vector, turn off the bit in the mask
18261 + *     register.
18262 + */
18263 +void ldsr_mask_vector(unsigned int vector)
18264 +{
18265 +       unsigned int mask;
18266 +       if (vector < 32) {
18267 +               mask = ~(1 << vector);
18268 +               ldsr_lock_acquire();
18269 +               ldsr_interrupt.mask0 &= mask;
18270 +               ldsr_lock_release();
18271 +               thread_resume(ldsr_tid);
18272 +               return;
18273 +       }
18274 +
18275 +       mask = ~(1 << (vector - 32));
18276 +       ldsr_lock_acquire();
18277 +       ldsr_interrupt.mask1 &= mask;
18278 +       ldsr_lock_release();
18279 +       thread_resume(ldsr_tid);
18280 +}
18281 +
18282 +/*
18283 + * ldsr_unmask_vector()
18284 + *     Unmask the interrupt vector so that it can be used, turn on the bit in
18285 + *     the mask register.
18286 + *
18287 + * Because it is legal for the interrupt path to disable an interrupt,
18288 + * the unmasking code must ensure that disabled interrupts are not
18289 + * unmasked.
18290 + */
18291 +void ldsr_unmask_vector(unsigned int vector)
18292 +{
18293 +       unsigned int mask;
18294 +       if (vector < 32) {
18295 +               mask = (1 << vector);
18296 +               ldsr_lock_acquire();
18297 +               ldsr_interrupt.mask0 |= (mask & ldsr_interrupt.enabled0);
18298 +               ldsr_lock_release();
18299 +               thread_resume(ldsr_tid);
18300 +               return;
18301 +       }
18302 +
18303 +       mask = (1 << (vector - 32));
18304 +       ldsr_lock_acquire();
18305 +       ldsr_interrupt.mask1 |= (mask & ldsr_interrupt.enabled1);
18306 +       ldsr_lock_release();
18307 +       thread_resume(ldsr_tid);
18308 +}
18309 +
18310 +/*
18311 + * ldsr_enable_vector()
18312 + *     The LDSR implements an interrupt controller and has a local (to the
18313 + *     LDSR) copy of its interrupt mask.
18314 + */
18315 +void ldsr_enable_vector(unsigned int vector)
18316 +{
18317 +       unsigned int mask;
18318 +       if (vector < 32) {
18319 +               mask = (1 << vector);
18320 +               ldsr_lock_acquire();
18321 +               ldsr_interrupt.enabled0 |= mask;
18322 +               ldsr_interrupt.mask0 |= mask;
18323 +               ldsr_lock_release();
18324 +               thread_resume(ldsr_tid);
18325 +               return;
18326 +       }
18327 +
18328 +       mask = (1 << (vector - 32));
18329 +       ldsr_lock_acquire();
18330 +       ldsr_interrupt.enabled1 |= mask;
18331 +       ldsr_interrupt.mask1 |= mask;
18332 +       ldsr_lock_release();
18333 +       thread_resume(ldsr_tid);
18334 +}
18335 +
18336 +/*
18337 + * ldsr_disable_vector()
18338 + *     The LDSR implements an interrupt controller and has a local (to the
18339 + *     LDSR) copy of its interrupt mask.
18340 + */
18341 +void ldsr_disable_vector(unsigned int vector)
18342 +{
18343 +       unsigned int mask;
18344 +
18345 +       if (vector < 32) {
18346 +               mask = ~(1 << vector);
18347 +               ldsr_lock_acquire();
18348 +               ldsr_interrupt.enabled0 &= mask;
18349 +               ldsr_interrupt.mask0 &= mask;
18350 +               ldsr_lock_release();
18351 +               thread_resume(ldsr_tid);
18352 +               return;
18353 +       }
18354 +
18355 +       mask = ~(1 << (vector - 32));
18356 +       ldsr_lock_acquire();
18357 +       ldsr_interrupt.enabled1 &= mask;
18358 +       ldsr_interrupt.mask1 &= mask;
18359 +       ldsr_lock_release();
18360 +       thread_resume(ldsr_tid);
18361 +}
18362 +
18363 +/*
18364 + * ldsr_get_threadid()
18365 + *     Return the threadid of the LDSR thread.
18366 + */
18367 +thread_t ldsr_get_threadid(void)
18368 +{
18369 +       return ldsr_tid;
18370 +}
18371 +
18372 +/*
18373 + * ldsr_set_trap_irq()
18374 + *     Save away the trap Soft IRQ
18375 + *
18376 + * See the per thread lock suspend code above for an explination.
18377 + */
18378 +void ldsr_set_trap_irq(unsigned int irq)
18379 +{
18380 +       ldsr_trap_irq = irq;
18381 +       ldsr_trap_irq_mask = (1 << irq);
18382 +       ldsr_suspend_mask |= ldsr_trap_irq_mask;
18383 +}
18384 +
18385 +/*
18386 + * ldsr_init()
18387 + *     Initialize the LDSR (Interrupt Controller)
18388 + */
18389 +void ldsr_init(void)
18390 +{
18391 +#if defined(CONFIG_IRQSTACKS)
18392 +       int i;
18393 +       union irq_ctx *icp;
18394 +#endif
18395 +
18396 +       void *stack_high = (void *)ldsr_stack_space;
18397 +       stack_high += sizeof(ldsr_stack_space);
18398 +       stack_high -= 8;
18399 +
18400 +
18401 +       /*
18402 +        * Obtain a soft IRQ to use
18403 +        */
18404 +       if (irq_soft_alloc(&ldsr_soft_irq) < 0) {
18405 +               panic("no software IRQ is available\n");
18406 +               return;
18407 +       }
18408 +       ldsr_soft_irq_mask |= (1 << ldsr_soft_irq);
18409 +       ldsr_suspend_mask |= ldsr_soft_irq_mask;
18410 +
18411 +       /*
18412 +        * Now allocate and start the LDSR thread.
18413 +        */
18414 +       ldsr_tid = thread_alloc();
18415 +       if (ldsr_tid < 0) {
18416 +               panic("no thread available to run LDSR");
18417 +               return;
18418 +       }
18419 +
18420 +#if defined(CONFIG_IRQSTACKS)
18421 +       /*
18422 +        * Initialize the per-cpu irq thread_info structure that
18423 +        * is at the top of each per-cpu irq stack.
18424 +        */
18425 +       icp = (union irq_ctx *)
18426 +               (((unsigned long)percpu_irq_stacks + (THREAD_SIZE - 1)) & ~(THREAD_SIZE - 1));
18427 +       for (i = 0; i < NR_CPUS; i++) {
18428 +               struct thread_info *ti = &(icp->tinfo);
18429 +               ti->task = NULL;
18430 +               ti->exec_domain = NULL;
18431 +               ti->cpu = i;
18432 +               ti->preempt_count = 0;
18433 +               ti->interrupt_nesting = 0;
18434 +               percpu_irq_ctxs[i] = icp++;
18435 +       }
18436 +#endif
18437 +       thread_start(ldsr_tid, ldsr_thread, NULL,
18438 +                    stack_high, THREAD_TYPE_NORMAL);
18439 +}
18440 --- /dev/null
18441 +++ b/arch/ubicom32/kernel/Makefile
18442 @@ -0,0 +1,64 @@
18443 +#
18444 +# arch/ubicom32/kernel/Makefile
18445 +#      Main Makefile for the Ubicom32 arch directory.
18446 +#
18447 +# (C) Copyright 2009, Ubicom, Inc.
18448 +#
18449 +# This file is part of the Ubicom32 Linux Kernel Port.
18450 +#
18451 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
18452 +# it and/or modify it under the terms of the GNU General Public License
18453 +# as published by the Free Software Foundation, either version 2 of the
18454 +# License, or (at your option) any later version.
18455 +#
18456 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
18457 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
18458 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18459 +# the GNU General Public License for more details.
18460 +#
18461 +# You should have received a copy of the GNU General Public License
18462 +# along with the Ubicom32 Linux Kernel Port.  If not, 
18463 +# see <http://www.gnu.org/licenses/>.
18464 +#
18465 +# Ubicom32 implementation derived from (with many thanks):
18466 +#   arch/m68knommu
18467 +#   arch/blackfin
18468 +#   arch/parisc
18469 +#
18470 +
18471 +extra-y := head.o vmlinux.lds
18472 +
18473 +obj-y += \
18474 +       devtree.o \
18475 +       dma.o \
18476 +       flat.o \
18477 +       init_task.o \
18478 +       irq.o \
18479 +       ldsr.o \
18480 +       os_node.o \
18481 +       process.o \
18482 +       processor.o \
18483 +       ptrace.o \
18484 +       setup.o \
18485 +       signal.o \
18486 +       stacktrace.o \
18487 +       sys_ubicom32.o \
18488 +       syscalltable.o \
18489 +       thread.o \
18490 +       time.o \
18491 +       traps.o \
18492 +       ubicom32_context_switch.o \
18493 +       ubicom32_ksyms.o \
18494 +       ubicom32_syscall.o \
18495 +       unaligned_trap.o
18496 +
18497 +obj-$(CONFIG_MODULES)                          += module.o
18498 +obj-$(CONFIG_COMEMPCI)                         += comempci.o
18499 +obj-$(CONFIG_SMP)                              += smp.o topology.o
18500 +obj-$(CONFIG_ACCESS_OK_CHECKS_ENABLED)         += uaccess.o
18501 +obj-$(CONFIG_GENERIC_CLOCKEVENTS)              += timer_device.o
18502 +obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)    += timer_broadcast.o
18503 +
18504 +ifndef CONFIG_GENERIC_CLOCKEVENTS
18505 +obj-y                  += timer_tick.o
18506 +endif
18507 --- /dev/null
18508 +++ b/arch/ubicom32/kernel/module.c
18509 @@ -0,0 +1,463 @@
18510 +/*
18511 + * arch/ubicom32/kernel/module.c
18512 + *   Ubicom32 architecture loadable module support.
18513 + *
18514 + * (C) Copyright 2009, Ubicom, Inc.
18515 + *
18516 + * This file is part of the Ubicom32 Linux Kernel Port.
18517 + *
18518 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
18519 + * it and/or modify it under the terms of the GNU General Public License
18520 + * as published by the Free Software Foundation, either version 2 of the
18521 + * License, or (at your option) any later version.
18522 + *
18523 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
18524 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18525 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18526 + * the GNU General Public License for more details.
18527 + *
18528 + * You should have received a copy of the GNU General Public License
18529 + * along with the Ubicom32 Linux Kernel Port.  If not,
18530 + * see <http://www.gnu.org/licenses/>.
18531 + *
18532 + * Ubicom32 implementation derived from (with many thanks):
18533 + *   arch/m68knommu
18534 + *   arch/blackfin
18535 + *   arch/parisc
18536 + */
18537 +#include <linux/moduleloader.h>
18538 +#include <linux/bug.h>
18539 +#include <linux/elf.h>
18540 +#include <linux/vmalloc.h>
18541 +#include <linux/fs.h>
18542 +#include <linux/string.h>
18543 +#include <linux/kernel.h>
18544 +#include <asm/ocm-alloc.h>
18545 +
18546 +#if 0
18547 +#define DEBUGP printk
18548 +#else
18549 +#define DEBUGP(fmt...)
18550 +#endif
18551 +
18552 +static void _module_free_ocm(struct module *mod)
18553 +{
18554 +       printk(KERN_INFO "module arch cleanup %s: OCM instruction memory free "
18555 +              " of %d @%p\n", mod->name, mod->arch.ocm_inst_size,
18556 +              mod->arch.ocm_inst);
18557 +
18558 +       if (mod->arch.ocm_inst) {
18559 +               ocm_inst_free(mod->arch.ocm_inst);
18560 +               mod->arch.ocm_inst = 0;
18561 +               mod->arch.ocm_inst_size = 0;
18562 +       }
18563 +}
18564 +
18565 +void *module_alloc(unsigned long size)
18566 +{
18567 +       if (size == 0)
18568 +               return NULL;
18569 +       return vmalloc(size);
18570 +}
18571 +
18572 +
18573 +/* Free memory returned from module_alloc */
18574 +void module_free(struct module *mod, void *module_region)
18575 +{
18576 +       vfree(module_region);
18577 +       /* FIXME: If module_region == mod->init_region, trim exception
18578 +          table entries. */
18579 +
18580 +       /*
18581 +        * This is expected to be final module free, use this to prune the
18582 +        * ocm
18583 +        */
18584 +       if (module_region && module_region == mod->module_core)
18585 +               _module_free_ocm(mod);
18586 +
18587 +}
18588 +
18589 +/*
18590 + * module_frob_arch_sections()
18591 + *     Called from kernel/module.c allowing arch specific handling of
18592 + *     sections/headers.
18593 + */
18594 +int module_frob_arch_sections(Elf_Ehdr *hdr,
18595 +                             Elf_Shdr *sechdrs,
18596 +                             char *secstrings,
18597 +                             struct module *mod)
18598 +{
18599 +       Elf_Shdr *s, *sechdrs_end;
18600 +       void *ocm_inst = NULL;
18601 +       int ocm_inst_size = 0;
18602 +
18603 +       /*
18604 +        * Ubicom32 v3 and v4 are almost binary compatible but not completely.
18605 +        * To be safe check that the module was compiled with the correct -march
18606 +        * which is flags.
18607 +        */
18608 +#ifdef CONFIG_UBICOM32_V4
18609 +       if ((hdr->e_flags & 0xFFFF) != EF_UBICOM32_V4) {
18610 +               printk(KERN_WARNING "Module %s was not compiled for "
18611 +                      "ubicom32v4, elf_flags:%x,\n",
18612 +                      mod->name, hdr->e_flags);
18613 +               return -ENOEXEC;
18614 +       }
18615 +#elif defined CONFIG_UBICOM32_V3
18616 +       if ((hdr->e_flags & 0xFFFF) != EF_UBICOM32_V3) {
18617 +               printk(KERN_WARNING "Module %s was not compiled for "
18618 +                      "ubicom32v3, elf_flags:%x\n",
18619 +                      mod->name, hdr->e_flags);
18620 +               return -ENOEXEC;
18621 +       }
18622 +#else
18623 +#error Unknown/Unsupported ubicom32 architecture.
18624 +#endif
18625 +
18626 +       /*
18627 +        * XXX: sechdrs are vmalloced in kernel/module.c
18628 +        * and would be vfreed just after module is loaded,
18629 +        * so we hack to keep the only information we needed
18630 +        * in mod->arch to correctly free L1 I/D sram later.
18631 +        * NOTE: this breaks the semantic of mod->arch structure.
18632 +        */
18633 +       sechdrs_end = sechdrs + hdr->e_shnum;
18634 +       for (s = sechdrs; s < sechdrs_end; ++s) {
18635 +               if (strncmp(".ocm_text", secstrings + s->sh_name, 9) == 0)
18636 +                       ocm_inst_size += s->sh_size;
18637 +       }
18638 +
18639 +       if (!ocm_inst_size)
18640 +               return 0;
18641 +
18642 +       ocm_inst = ocm_inst_alloc(ocm_inst_size, 0 /* internal */);
18643 +       if (ocm_inst == NULL) {
18644 +#ifdef CONFIG_OCM_MODULES_FALLBACK_TO_DDR
18645 +               printk(KERN_WARNING
18646 +                      "module %s: OCM instruction memory allocation of %d"
18647 +                      "failed, fallback to DDR\n", mod->name, ocm_inst_size);
18648 +               return 0;
18649 +#else
18650 +               printk(KERN_ERR
18651 +                      "module %s: OCM instruction memory allocation of %d"
18652 +                      "failed.\n", mod->name, ocm_inst_size);
18653 +               return -ENOMEM;
18654 +#endif
18655 +       }
18656 +
18657 +       mod->arch.ocm_inst = ocm_inst;
18658 +       mod->arch.ocm_inst_size = ocm_inst_size;
18659 +
18660 +       printk(KERN_INFO
18661 +              "module %s: OCM instruction memory allocation of %d @%p\n",
18662 +              mod->name, mod->arch.ocm_inst_size, mod->arch.ocm_inst);
18663 +
18664 +       for (s = sechdrs; s < sechdrs_end; ++s) {
18665 +               if (strncmp(".ocm_text", secstrings + s->sh_name, 9) == 0) {
18666 +                       memcpy(ocm_inst, (void *)s->sh_addr, s->sh_size);
18667 +                       s->sh_flags &= ~SHF_ALLOC;
18668 +                       s->sh_addr = (unsigned long)ocm_inst;
18669 +                       ocm_inst += s->sh_size;
18670 +               }
18671 +       }
18672 +
18673 +       return 0;
18674 +}
18675 +
18676 +int apply_relocate(Elf32_Shdr *sechdrs,
18677 +                  const char *strtab,
18678 +                  unsigned int symindex,
18679 +                  unsigned int relsec,
18680 +                  struct module *me)
18681 +{
18682 +       DEBUGP("Invalid Applying relocate section %u to %u\n", relsec,
18683 +              sechdrs[relsec].sh_info);
18684 +       return -EINVAL;
18685 +}
18686 +
18687 +int apply_relocate_add(Elf32_Shdr *sechdrs,
18688 +                      const char *strtab,
18689 +                      unsigned int symindex,
18690 +                      unsigned int relsec,
18691 +                      struct module *me)
18692 +{
18693 +       unsigned int i;
18694 +       Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
18695 +       Elf32_Sym *sym;
18696 +       uint32_t *location;
18697 +       uint32_t insn;
18698 +
18699 +       DEBUGP("Applying relocate_add section %u to %u\n", relsec,
18700 +              sechdrs[relsec].sh_info);
18701 +       for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
18702 +               uint32_t v;
18703 +               const int elf32_rtype = ELF32_R_TYPE(rel[i].r_info);
18704 +
18705 +               /* This is where to make the change */
18706 +               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
18707 +                       + rel[i].r_offset;
18708 +               /* This is the symbol it is referring to.  Note that all
18709 +                  undefined symbols have been resolved.  */
18710 +               sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
18711 +                       + ELF32_R_SYM(rel[i].r_info);
18712 +
18713 +               v = rel[i].r_addend + sym->st_value;
18714 +
18715 +
18716 +               switch (elf32_rtype) {
18717 +               case R_UBICOM32_32:
18718 +               {
18719 +                       /*
18720 +                        * Store the 32 bit relocation as is.
18721 +                        */
18722 +                       *location = v;
18723 +                       break;
18724 +               }
18725 +               case R_UBICOM32_HI24:
18726 +               {
18727 +                       /*
18728 +                        * 24 bit relocation that is part of the MOVEAI
18729 +                        * instruction. The 24 bits come from bits 7 - 30 of the
18730 +                        * relocation. Theses bits eventually get split into 2
18731 +                        * fields in the instruction encoding.
18732 +                        *
18733 +                        * - Bits 7 - 27 of the relocation are encoded into bits
18734 +                        * 0 - 20 of the instruction.
18735 +                        *
18736 +                        *  - Bits 28 - 30 of the relocation are encoded into
18737 +                        *  bit 24 - 26 of the instruction.
18738 +                        */
18739 +                       uint32_t valid24 = (v >> 7) & 0xffffff;
18740 +                       insn = *location;
18741 +
18742 +                       insn &= ~(0x1fffff | (0x7 << 24));
18743 +                       insn |= (valid24 & 0x1fffff);
18744 +                       insn |= ((valid24 & 0xe00000) << 3);
18745 +                       *location = insn;
18746 +               }
18747 +               break;
18748 +               case R_UBICOM32_LO7_S:
18749 +               case R_UBICOM32_LO7_2_S:
18750 +               case R_UBICOM32_LO7_4_S:
18751 +               {
18752 +                       /*
18753 +                        * Bits 0 - 6 of the relocation are encoded into the
18754 +                        * 7bit unsigned immediate fields of the SOURCE-1 field
18755 +                        * of the instruction.  The immediate value is left
18756 +                        * shifted by (0, 1, 2) based on the operand size.
18757 +                        */
18758 +                       uint32_t valid7 = v & 0x7f;
18759 +                       insn = *location;
18760 +
18761 +                       if (elf32_rtype == R_UBICOM32_LO7_2_S) {
18762 +                               valid7 >>= 1;
18763 +                       } else if (elf32_rtype == R_UBICOM32_LO7_4_S) {
18764 +                               valid7 >>= 2;
18765 +                       }
18766 +
18767 +                       insn &= ~(0x1f | (0x3 << 8));
18768 +                       insn |= (valid7 & 0x1f);
18769 +                       insn |= ((valid7 & 0x60) << 3);
18770 +                       *location = insn;
18771 +               }
18772 +               break;
18773 +               case R_UBICOM32_LO7_D:
18774 +               case R_UBICOM32_LO7_2_D:
18775 +               case R_UBICOM32_LO7_4_D:
18776 +               {
18777 +                       /*
18778 +                        * Bits 0 - 6 of the relocation are encoded into the
18779 +                        * 7bit unsigned immediate fields of the DESTINATION
18780 +                        * field of the instruction.  The immediate value is
18781 +                        * left shifted by (0, 1, 2) based on the operand size.
18782 +                        */
18783 +                       uint32_t valid7 = v & 0x7f;
18784 +                       insn = *location;
18785 +
18786 +                       if (elf32_rtype == R_UBICOM32_LO7_2_D) {
18787 +                               valid7 >>= 1;
18788 +                       } else if (elf32_rtype == R_UBICOM32_LO7_4_D) {
18789 +                               valid7 >>= 2;
18790 +                       }
18791 +
18792 +                       insn &= ~((0x1f | (0x3 << 8)) << 16);
18793 +                       insn |= ((valid7 & 0x1f) << 16);
18794 +                       insn |= ((valid7 & 0x60) << 19);
18795 +                       *location = insn;
18796 +               }
18797 +               break;
18798 +               case R_UBICOM32_LO7_CALLI:
18799 +               case R_UBICOM32_LO16_CALLI:
18800 +               {
18801 +                       /*
18802 +                        * Extract the offset for a CALLI instruction. The
18803 +                        * offsets can be either 7 bits or 18 bits. Since all
18804 +                        * instructions in ubicom32 architecture are at work
18805 +                        * aligned addresses the truncated offset is right
18806 +                        * shifted by 2 before being encoded in the instruction.
18807 +                        */
18808 +                       uint32_t val;
18809 +                       if (elf32_rtype == R_UBICOM32_LO7_CALLI) {
18810 +                               val  = v & 0x7f;
18811 +                       } else {
18812 +                               val  = v & 0x3ffff;
18813 +                       }
18814 +
18815 +                       val >>= 2;
18816 +
18817 +                       insn = *location;
18818 +
18819 +                       insn &= ~0x071f071f;
18820 +                       insn |= (val & 0x1f) << 0;
18821 +                       val >>= 5;
18822 +                       insn |= (val & 0x07) << 8;
18823 +                       val >>= 3;
18824 +                       insn |= (val & 0x1f) << 16;
18825 +                       val >>= 5;
18826 +                       insn |= (val & 0x07) << 24;
18827 +                       *location = insn;
18828 +               }
18829 +               break;
18830 +               case R_UBICOM32_24_PCREL:
18831 +               {
18832 +                       /*
18833 +                        * Extract 26 bit signed PC relative offset for CALL
18834 +                        * instructions. Since instruction addresses are word
18835 +                        * aligned the offset is right shited by 2 before
18836 +                        * encoding into instruction.
18837 +                        */
18838 +                       int32_t val = v - (int32_t)location;
18839 +
18840 +                       /*
18841 +                        * Check that the top 7 bits are all equal to the sign
18842 +                        * bit (26), i.e all 0's or all 1's.  If they are not then
18843 +                        * the absolute difference is greater than 25 bits.
18844 +                        */
18845 +                       if (((uint32_t)val & 0xFE000000) != 0xFE000000 &&
18846 +                               ((uint32_t)val & 0xFE000000) != 0x0) {
18847 +                               /*
18848 +                                * The relocation is beyond our addressable
18849 +                                * range with a 26 bit call.
18850 +                                */
18851 +                               printk(KERN_ERR "module %s: PC Relative "
18852 +                                       "relocation out of range: "
18853 +                                       "%u (%x->%x, %x)\n",
18854 +                                       me->name, elf32_rtype,
18855 +                                       v, (uint32_t) location, val);
18856 +                               return -ENOEXEC;
18857 +                       }
18858 +
18859 +                       val = (val & 0x3ffffff) >> 2;
18860 +                       insn = *location;
18861 +                       insn = insn & 0xf8e00000;
18862 +
18863 +                       insn |= (val >> 21) << 24;
18864 +                       insn |= (val & 0x1fffff);
18865 +                       *location = insn;
18866 +               }
18867 +               break;
18868 +               case R_UBICOM32_LO16:
18869 +               case R_UBICOM32_HI16:
18870 +               {
18871 +                       /*
18872 +                        * 16 bit immediate value that is encoded into bit 0 -
18873 +                        * 15 of the instruction.
18874 +                        */
18875 +                       uint32_t val;
18876 +
18877 +                       if (elf32_rtype == R_UBICOM32_LO16) {
18878 +                               val  = v & 0xffff;
18879 +                       } else {
18880 +                               val  = (v >> 16) & 0xffff;
18881 +                       }
18882 +
18883 +                       insn = *location;
18884 +                       insn &= 0xffff0000;
18885 +
18886 +                       insn |= val;
18887 +                       *location = insn;
18888 +               }
18889 +               break;
18890 +               case R_UBICOM32_21_PCREL:
18891 +               {
18892 +                       /*
18893 +                        * Extract 23 bit signed PC relative offset for JMP<cc>
18894 +                        * instructions. Since instruction addresses are word
18895 +                        * aligned the offset is right shited by 2 before
18896 +                        * encoding into instruction.
18897 +                        */
18898 +                       int32_t val = v - (int32_t)location;
18899 +
18900 +                       val = (val & 0x7fffff) >> 2;
18901 +                       insn = *location;
18902 +                       insn = insn & 0xffe00000;
18903 +
18904 +                       insn |= (val >> 21) << 24;
18905 +                       insn |= val;
18906 +                       *location = insn;
18907 +               }
18908 +               break;
18909 +               default:
18910 +                       BUG();
18911 +                       printk(KERN_ERR "module %s: Unknown relocation: %u\n",
18912 +                              me->name, elf32_rtype);
18913 +                       return -ENOEXEC;
18914 +               }
18915 +       }
18916 +       return 0;
18917 +}
18918 +
18919 +int module_finalize(const Elf_Ehdr *hdr,
18920 +                   const Elf_Shdr *sechdrs,
18921 +                   struct module *mod)
18922 +{
18923 +       unsigned int i, strindex = 0, symindex = 0;
18924 +       char *secstrings;
18925 +       int err;
18926 +
18927 +       err = module_bug_finalize(hdr, sechdrs, mod);
18928 +       if (err)
18929 +               return err;
18930 +
18931 +       if (!mod->arch.ocm_inst) {
18932 +               /*
18933 +                * No OCM code, so nothing more to do.
18934 +                */
18935 +               return 0;
18936 +       }
18937 +
18938 +       secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
18939 +
18940 +       for (i = 1; i < hdr->e_shnum; i++) {
18941 +               /* Internal symbols and strings. */
18942 +               if (sechdrs[i].sh_type == SHT_SYMTAB) {
18943 +                       symindex = i;
18944 +                       strindex = sechdrs[i].sh_link;
18945 +               }
18946 +       }
18947 +
18948 +       for (i = 1; i < hdr->e_shnum; i++) {
18949 +               const char *strtab = (char *)sechdrs[strindex].sh_addr;
18950 +               unsigned int info = sechdrs[i].sh_info;
18951 +
18952 +               /* Not a valid relocation section? */
18953 +               if (info >= hdr->e_shnum)
18954 +                       continue;
18955 +
18956 +               if ((sechdrs[i].sh_type == SHT_RELA) &&
18957 +                   (strncmp(".rela.ocm_text",
18958 +                            secstrings + sechdrs[i].sh_name, 5 + 9) == 0)) {
18959 +                       err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
18960 +                                                symindex, i, mod);
18961 +                       if (err)
18962 +                               return err;
18963 +               }
18964 +       }
18965 +
18966 +       return 0;
18967 +}
18968 +
18969 +void module_arch_cleanup(struct module *mod)
18970 +{
18971 +       module_bug_cleanup(mod);
18972 +}
18973 --- /dev/null
18974 +++ b/arch/ubicom32/kernel/os_node.c
18975 @@ -0,0 +1,80 @@
18976 +/*
18977 + * arch/ubicom32/kernel/os_node.c
18978 + *   <TODO: Replace with short file description>
18979 + *
18980 + * (C) Copyright 2009, Ubicom, Inc.
18981 + *
18982 + * This file is part of the Ubicom32 Linux Kernel Port.
18983 + *
18984 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
18985 + * it and/or modify it under the terms of the GNU General Public License
18986 + * as published by the Free Software Foundation, either version 2 of the
18987 + * License, or (at your option) any later version.
18988 + *
18989 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
18990 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18991 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18992 + * the GNU General Public License for more details.
18993 + *
18994 + * You should have received a copy of the GNU General Public License
18995 + * along with the Ubicom32 Linux Kernel Port.  If not,
18996 + * see <http://www.gnu.org/licenses/>.
18997 + *
18998 + */
18999 +#include "linux/types.h"
19000 +#include "linux/linkage.h"
19001 +#include "linux/uts.h"
19002 +#include "linux/utsrelease.h"
19003 +#include "linux/version.h"
19004 +#include <asm/ocm_size.h>
19005 +#include <asm/devtree.h>
19006 +#include <asm/ip5000.h>
19007 +
19008 +extern asmlinkage void *_start;
19009 +
19010 +/*
19011 + * This file provides static information to the boot code allowing it to decide
19012 + * if the os is compatible. Thus hopefully enabling the boot code to prevent
19013 + * accidentally booting a kernel that has no hope of running.
19014 + */
19015 +struct os_node {
19016 +       struct devtree_node node;
19017 +       unsigned long version; /* Always 1 */
19018 +       unsigned long entry_point;
19019 +       const char    os_name[32]; /* For diagnostic purposes only */
19020 +       const char    os_version_str[32];
19021 +       unsigned long os_version_num;
19022 +       unsigned long expected_ocm_code_start;/* OS Code */
19023 +       unsigned long expected_ocm_data_end;  /* OS Data */
19024 +       unsigned long expected_ram_start;
19025 +       unsigned long expected_ram_end;
19026 +       unsigned long arch_version;
19027 +};
19028 +
19029 +
19030 +/*
19031 + * The os_node is only referenced by head.S and should never be modified at
19032 + * run-time.
19033 + */
19034 +asmlinkage const struct os_node _os_node = {
19035 +       .node = {
19036 +               .next = NULL,
19037 +               .name = { "OS" },
19038 +               .magic = 0x10203040,
19039 +       },
19040 +       .version = 0x10001,
19041 +       .entry_point = (unsigned long)&_start,
19042 +#if APP_OCM_CODE_SIZE || APP_OCM_DATA_SIZE
19043 +       .expected_ocm_code_start = OCMSTART + APP_OCM_CODE_SIZE,
19044 +       .expected_ocm_data_end   = OCMEND   - APP_OCM_DATA_SIZE,
19045 +#else
19046 +       .expected_ocm_code_start = OCMEND,
19047 +       .expected_ocm_data_end   = OCMEND,
19048 +#endif
19049 +       .os_name = { UTS_SYSNAME },
19050 +       .os_version_str = { UTS_RELEASE },
19051 +       .os_version_num = LINUX_VERSION_CODE,
19052 +       .expected_ram_start = CONFIG_KERNELBASE,
19053 +       .expected_ram_end = CONFIG_RAMBASE + CONFIG_RAMSIZE,
19054 +       .arch_version = UBICOM32_ARCH_VERSION
19055 +};
19056 --- /dev/null
19057 +++ b/arch/ubicom32/kernel/process.c
19058 @@ -0,0 +1,494 @@
19059 +/*
19060 + * arch/ubicom32/kernel/process.c
19061 + *   Ubicom32 architecture-dependent process handling.
19062 + *
19063 + * (C) Copyright 2009, Ubicom, Inc.
19064 + * Copyright (C) 1995  Hamish Macdonald
19065 + *
19066 + * 68060 fixes by Jesper Skov
19067 + *
19068 + * uClinux changes
19069 + * Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
19070 + *
19071 + * This file is part of the Ubicom32 Linux Kernel Port.
19072 + *
19073 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19074 + * it and/or modify it under the terms of the GNU General Public License
19075 + * as published by the Free Software Foundation, either version 2 of the
19076 + * License, or (at your option) any later version.
19077 + *
19078 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19079 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19080 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19081 + * the GNU General Public License for more details.
19082 + *
19083 + * You should have received a copy of the GNU General Public License
19084 + * along with the Ubicom32 Linux Kernel Port.  If not,
19085 + * see <http://www.gnu.org/licenses/>.
19086 + *
19087 + * Ubicom32 implementation derived from (with many thanks):
19088 + *   arch/m68knommu
19089 + *   arch/blackfin
19090 + *   arch/parisc
19091 + */
19092 +
19093 +/*
19094 + * This file handles the architecture-dependent parts of process handling..
19095 + */
19096 +
19097 +#include <linux/module.h>
19098 +#include <linux/errno.h>
19099 +#include <linux/sched.h>
19100 +#include <linux/kernel.h>
19101 +#include <linux/mm.h>
19102 +#include <linux/smp.h>
19103 +#include <linux/smp_lock.h>
19104 +#include <linux/stddef.h>
19105 +#include <linux/unistd.h>
19106 +#include <linux/ptrace.h>
19107 +#include <linux/slab.h>
19108 +#include <linux/user.h>
19109 +#include <linux/a.out.h>
19110 +#include <linux/interrupt.h>
19111 +#include <linux/reboot.h>
19112 +#include <linux/fs.h>
19113 +#include <linux/pm.h>
19114 +
19115 +#include <linux/uaccess.h>
19116 +#include <asm/system.h>
19117 +#include <asm/traps.h>
19118 +#include <asm/machdep.h>
19119 +#include <asm/setup.h>
19120 +#include <asm/pgtable.h>
19121 +#include <asm/ip5000.h>
19122 +#include <asm/range-protect.h>
19123 +
19124 +asmlinkage void ret_from_fork(void);
19125 +
19126 +void (*pm_power_off)(void) = machine_power_off;
19127 +EXPORT_SYMBOL(pm_power_off);
19128 +
19129 +/* machine-dependent / hardware-specific power functions */
19130 +void (*mach_reset)(void);
19131 +void (*mach_halt)(void);
19132 +void (*mach_power_off)(void);
19133 +
19134 +/*
19135 + * cpu_idle()
19136 + *     The idle thread.
19137 + *
19138 + * Our idle loop suspends and is woken up by a timer interrupt.
19139 + */
19140 +void cpu_idle(void)
19141 +{
19142 +       while (1) {
19143 +               local_irq_disable();
19144 +               while (!need_resched()) {
19145 +                       local_irq_enable();
19146 +                       thread_suspend();
19147 +                       local_irq_disable();
19148 +               }
19149 +               local_irq_enable();
19150 +               preempt_enable_no_resched();
19151 +               schedule();
19152 +               preempt_disable();
19153 +       }
19154 +}
19155 +
19156 +/*
19157 + * dump_fpu()
19158 + *
19159 + *     Fill in the fpu structure for a core dump. (just a stub as we don't have
19160 + *     an fpu)
19161 + */
19162 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
19163 +{
19164 +       return 1;
19165 +}
19166 +
19167 +/*
19168 + * machine_restart()
19169 + *     Resets the system.
19170 + */
19171 +void machine_restart(char *__unused)
19172 +{
19173 +       /*
19174 +        * Disable all threads except myself. We can do this
19175 +        * directly without needing to call smp_send_stop
19176 +        * because we have a unique architecture where
19177 +        * one thread can disable one or more other threads.
19178 +        */
19179 +       thread_disable_others();
19180 +
19181 +       /*
19182 +        * Call the hardware-specific machine reset function.
19183 +        */
19184 +       if (mach_reset) {
19185 +               mach_reset();
19186 +       }
19187 +
19188 +       printk(KERN_EMERG "System Restarting\n");
19189 +
19190 +       /*
19191 +        * Set watchdog to trigger (after 1ms delay) (12 Mhz is the fixed OSC)
19192 +        */
19193 +       UBICOM32_IO_TIMER->tkey = TIMER_TKEYVAL;
19194 +       UBICOM32_IO_TIMER->wdcom = UBICOM32_IO_TIMER->mptval +
19195 +               (12000000 / 1000);
19196 +       UBICOM32_IO_TIMER->wdcfg = 0;
19197 +       UBICOM32_IO_TIMER->tkey = 0;
19198 +
19199 +       /*
19200 +        * Wait for watchdog
19201 +        */
19202 +       asm volatile (
19203 +               "       move.4          MT_EN, #0               \n\t"
19204 +               "       pipe_flush      0                       \n\t"
19205 +       );
19206 +
19207 +       local_irq_disable();
19208 +       for (;;) {
19209 +               thread_suspend();
19210 +       }
19211 +}
19212 +
19213 +/*
19214 + * machine_halt()
19215 + *     Halt the machine.
19216 + *
19217 + * Similar to machine_power_off, but don't shut off power.  Add code
19218 + * here to freeze the system for e.g. post-mortem debug purpose when
19219 + * possible.  This halt has nothing to do with the idle halt.
19220 + */
19221 +void machine_halt(void)
19222 +{
19223 +       /*
19224 +        * Disable all threads except myself. We can do this
19225 +        * directly without needing to call smp_send_stop
19226 +        * because we have a unique architecture where
19227 +        * one thread can disable one or more other threads.
19228 +        */
19229 +       thread_disable_others();
19230 +
19231 +       /*
19232 +        * Call the hardware-specific machine halt function.
19233 +        */
19234 +       if (mach_halt) {
19235 +               mach_halt();
19236 +       }
19237 +
19238 +       printk(KERN_EMERG "System Halted, OK to turn off power\n");
19239 +       local_irq_disable();
19240 +       for (;;) {
19241 +               thread_suspend();
19242 +       }
19243 +}
19244 +
19245 +/*
19246 + * machine_power_off()
19247 + *     Turn the power off, if a power off handler is defined, otherwise, spin
19248 + *     endlessly.
19249 + */
19250 +void machine_power_off(void)
19251 +{
19252 +       /*
19253 +        * Disable all threads except myself. We can do this
19254 +        * directly without needing to call smp_send_stop
19255 +        * because we have a unique architecture where
19256 +        * one thread can disable one or more other threads.
19257 +        */
19258 +       thread_disable_others();
19259 +
19260 +       /*
19261 +        * Call the hardware-specific machine power off function.
19262 +        */
19263 +       if (mach_power_off) {
19264 +               mach_power_off();
19265 +       }
19266 +
19267 +       printk(KERN_EMERG "System Halted, OK to turn off power\n");
19268 +       local_irq_disable();
19269 +       for (;;) {
19270 +               thread_suspend();
19271 +       }
19272 +}
19273 +
19274 +/*
19275 + * show_regs()
19276 + *     Print out all of the registers.
19277 + */
19278 +void show_regs(struct pt_regs *regs)
19279 +{
19280 +       unsigned int i;
19281 +
19282 +       printk(KERN_NOTICE "regs: %p, tid: %d\n",
19283 +               (void *)regs,
19284 +               thread_get_self());
19285 +
19286 +       printk(KERN_NOTICE "pc: %08x, previous_pc: %08x\n\n",
19287 +               (unsigned int)regs->pc,
19288 +               (unsigned int)regs->previous_pc);
19289 +
19290 +       printk(KERN_NOTICE "Data registers\n");
19291 +       for (i = 0; i < 16; i++) {
19292 +               printk("D%02d: %08x, ", i, (unsigned int)regs->dn[i]);
19293 +               if ((i % 4) == 3) {
19294 +                       printk("\n");
19295 +               }
19296 +       }
19297 +       printk("\n");
19298 +
19299 +       printk(KERN_NOTICE "Address registers\n");
19300 +       for (i = 0; i < 8; i++) {
19301 +               printk("A%02d: %08x, ", i, (unsigned int)regs->an[i]);
19302 +               if ((i % 4) == 3) {
19303 +                       printk("\n");
19304 +               }
19305 +       }
19306 +       printk("\n");
19307 +
19308 +       printk(KERN_NOTICE "acc0: %08x-%08x, acc1: %08x-%08x\n",
19309 +               (unsigned int)regs->acc0[1],
19310 +               (unsigned int)regs->acc0[0],
19311 +               (unsigned int)regs->acc1[1],
19312 +               (unsigned int)regs->acc1[0]);
19313 +
19314 +       printk(KERN_NOTICE "mac_rc16: %08x, source3: %08x\n",
19315 +               (unsigned int)regs->mac_rc16,
19316 +               (unsigned int)regs->source3);
19317 +
19318 +       printk(KERN_NOTICE "inst_cnt: %08x, csr: %08x\n",
19319 +               (unsigned int)regs->inst_cnt,
19320 +               (unsigned int)regs->csr);
19321 +
19322 +       printk(KERN_NOTICE "int_mask0: %08x, int_mask1: %08x\n",
19323 +               (unsigned int)regs->int_mask0,
19324 +               (unsigned int)regs->int_mask1);
19325 +
19326 +       printk(KERN_NOTICE "frame_type: %d, nesting_level: %d, thread_type %d\n\n",
19327 +               (int)regs->frame_type,
19328 +               (int)regs->nesting_level,
19329 +               (int)regs->thread_type);
19330 +}
19331 +
19332 +/*
19333 + * kernel_thread_helper()
19334 + *     On execution d0 will be 0, d1 will be the argument to be passed to the
19335 + *     kernel function.  d2 contains the kernel function that needs to get
19336 + *     called. d3 will contain address to do_exit which need to get moved
19337 + *     into a5. On return from fork the child thread d0 will be 0. We call
19338 + *     this dummy function which in turn loads the argument
19339 + */
19340 +asmlinkage void kernel_thread_helper(void);
19341 +
19342 +/*
19343 + * kernel_thread()
19344 + *     Create a kernel thread
19345 + */
19346 +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
19347 +{
19348 +       struct pt_regs regs;
19349 +
19350 +       memset(&regs, 0, sizeof(regs));
19351 +
19352 +       regs.dn[1] = (unsigned long)arg;
19353 +       regs.dn[2] = (unsigned long)fn;
19354 +       regs.dn[3] = (unsigned long)do_exit;
19355 +       regs.an[5] = (unsigned long)kernel_thread_helper;
19356 +       regs.pc = (unsigned long)kernel_thread_helper;
19357 +       regs.nesting_level = 0;
19358 +       regs.thread_type = KERNEL_THREAD;
19359 +
19360 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
19361 +                      0, &regs, 0, NULL, NULL);
19362 +}
19363 +EXPORT_SYMBOL(kernel_thread);
19364 +
19365 +/*
19366 + * flush_thread()
19367 + *     XXX todo
19368 + */
19369 +void flush_thread(void)
19370 +{
19371 +       /* XXX todo */
19372 +}
19373 +
19374 +/*
19375 + * sys_fork()
19376 + *     Not implemented on no-mmu.
19377 + */
19378 +asmlinkage int sys_fork(struct pt_regs *regs)
19379 +{
19380 +       /* fork almost works, enough to trick you into looking elsewhere :-( */
19381 +       return -EINVAL;
19382 +}
19383 +
19384 +/*
19385 + * sys_vfork()
19386 + *     By the time we get here, the non-volatile registers have also been saved
19387 + *     on the stack. We do some ugly pointer stuff here.. (see also copy_thread
19388 + *     which does context copy).
19389 + */
19390 +asmlinkage int sys_vfork(struct pt_regs *regs)
19391 +{
19392 +       unsigned long old_sp = regs->an[7];
19393 +       unsigned long old_a5 = regs->an[5];
19394 +       unsigned long old_return_address;
19395 +       long do_fork_return;
19396 +
19397 +       /*
19398 +        * Read the old retrun address from the stack.
19399 +        */
19400 +       if (copy_from_user(&old_return_address,
19401 +                          (void *)old_sp, sizeof(unsigned long))) {
19402 +               force_sig(SIGSEGV, current);
19403 +               return 0;
19404 +       }
19405 +
19406 +       /*
19407 +        * Pop the vfork call frame by setting a5 and pc to the old_return
19408 +        * address and incrementing the stack pointer by 4.
19409 +        */
19410 +       regs->an[5] = old_return_address;
19411 +       regs->pc = old_return_address;
19412 +       regs->an[7] += 4;
19413 +
19414 +       do_fork_return = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
19415 +                                regs->an[7], regs, 0, NULL, NULL);
19416 +
19417 +       /*
19418 +        * Now we have to test if the return code is an error. If it is an error
19419 +        * then restore the frame and we will execute error processing in user
19420 +        * space. Other wise the child and the parent will return to the correct
19421 +        * places.
19422 +        */
19423 +       if ((unsigned long)(do_fork_return) >= (unsigned long)(-125)) {
19424 +               /*
19425 +                * Error case. We need to restore the frame.
19426 +                */
19427 +               regs->an[5] = old_a5;
19428 +               regs->pc = old_a5;
19429 +               regs->an[7] = old_sp;
19430 +       }
19431 +
19432 +       return do_fork_return;
19433 +}
19434 +
19435 +/*
19436 + * sys_clone()
19437 + *     creates a child thread.
19438 + */
19439 +asmlinkage int sys_clone(unsigned long clone_flags,
19440 +                        unsigned long newsp,
19441 +                        struct pt_regs *regs)
19442 +{
19443 +       if (!newsp)
19444 +               newsp = regs->an[7];
19445 +       return do_fork(clone_flags, newsp, regs, 0,
19446 +                      NULL, NULL);
19447 +}
19448 +
19449 +/*
19450 + * copy_thread()
19451 + *     low level thread copy, only used by do_fork in kernel/fork.c
19452 + */
19453 +int copy_thread(int nr, unsigned long clone_flags,
19454 +               unsigned long usp, unsigned long topstk,
19455 +               struct task_struct *p, struct pt_regs *regs)
19456 +{
19457 +       struct pt_regs *childregs;
19458 +
19459 +       childregs = (struct pt_regs *)
19460 +               (task_stack_page(p) + THREAD_SIZE - 8) - 1;
19461 +
19462 +       *childregs = *regs;
19463 +
19464 +       /*
19465 +        * Set return value for child to be 0.
19466 +        */
19467 +       childregs->dn[0] = 0;
19468 +
19469 +       if (usp)
19470 +               childregs->an[7] = usp;
19471 +       else
19472 +               childregs->an[7] = (unsigned long)task_stack_page(p) +
19473 +                       THREAD_SIZE - 8;
19474 +
19475 +       /*
19476 +        * Set up the switch_to frame to return to "ret_from_fork"
19477 +        */
19478 +       p->thread.a5 = (unsigned long)ret_from_fork;
19479 +       p->thread.sp = (unsigned long)childregs;
19480 +
19481 +       return 0;
19482 +}
19483 +
19484 +/*
19485 + * sys_execve()
19486 + *     executes a new program.
19487 + */
19488 +asmlinkage int sys_execve(char *name, char **argv,
19489 +                         char **envp, struct pt_regs *regs)
19490 +{
19491 +       int error;
19492 +       char *filename;
19493 +
19494 +       lock_kernel();
19495 +       filename = getname(name);
19496 +       error = PTR_ERR(filename);
19497 +       if (IS_ERR(filename))
19498 +               goto out;
19499 +       error = do_execve(filename, argv, envp, regs);
19500 +       putname(filename);
19501 +       asm ("       .global sys_execve_complete\n"
19502 +            "       sys_execve_complete:");
19503 +out:
19504 +       unlock_kernel();
19505 +       return error;
19506 +}
19507 +
19508 +/*
19509 + * Return saved PC of a blocked thread.
19510 + */
19511 +unsigned long thread_saved_pc(struct task_struct *tsk)
19512 +{
19513 +       return tsk->thread.a5;
19514 +}
19515 +
19516 +
19517 +unsigned long get_wchan(struct task_struct *p)
19518 +{
19519 +       unsigned long pc;
19520 +
19521 +       /*
19522 +        * If we don't have a process, or it is not the current
19523 +        * one or not RUNNING, it makes no sense to ask for a
19524 +        * wchan.
19525 +        */
19526 +       if (!p || p == current || p->state == TASK_RUNNING)
19527 +               return 0;
19528 +
19529 +       /*
19530 +        * TODO: If the process is in the middle of schedule, we
19531 +        * are supposed to do something different but for now we
19532 +        * will return the same thing in both situations.
19533 +        */
19534 +       pc = thread_saved_pc(p);
19535 +       if (in_sched_functions(pc))
19536 +               return pc;
19537 +       return pc;
19538 +}
19539 +
19540 +/*
19541 + * __switch_to is the function that implements the contex save and
19542 + * switch within the kernel. Since this is a function call very few
19543 + * registers have to be saved to pull this off. d0 holds prev and we
19544 + * want to preserve it. prev_switch is a pointer to task->thread
19545 + * structure. This is where we will save the register state. next_switch
19546 + * is pointer to the next task's thread structure that holds the
19547 + * registers.
19548 + */
19549 +asmlinkage void *__switch_to(struct task_struct *prev,
19550 +                            struct thread_struct *prev_switch,
19551 +                            struct thread_struct *next_switch)
19552 +       __attribute__((naked));
19553 --- /dev/null
19554 +++ b/arch/ubicom32/kernel/processor.c
19555 @@ -0,0 +1,258 @@
19556 +/*
19557 + * arch/ubicom32/kernel/processor.c
19558 + *   Ubicom32 architecture processor info implementation.
19559 + *
19560 + * (C) Copyright 2009, Ubicom, Inc.
19561 + *
19562 + * This file is part of the Ubicom32 Linux Kernel Port.
19563 + *
19564 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19565 + * it and/or modify it under the terms of the GNU General Public License
19566 + * as published by the Free Software Foundation, either version 2 of the
19567 + * License, or (at your option) any later version.
19568 + *
19569 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19570 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19571 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19572 + * the GNU General Public License for more details.
19573 + *
19574 + * You should have received a copy of the GNU General Public License
19575 + * along with the Ubicom32 Linux Kernel Port.  If not,
19576 + * see <http://www.gnu.org/licenses/>.
19577 + *
19578 + * Ubicom32 implementation derived from (with many thanks):
19579 + *   arch/m68knommu
19580 + *   arch/blackfin
19581 + *   arch/parisc
19582 + */
19583 +#include <linux/module.h>
19584 +#include <linux/kernel.h>
19585 +#include <linux/init.h>
19586 +#include <linux/sched.h>
19587 +#include <linux/interrupt.h>
19588 +#include <linux/irq.h>
19589 +#include <linux/profile.h>
19590 +#include <linux/clocksource.h>
19591 +#include <linux/types.h>
19592 +#include <linux/seq_file.h>
19593 +#include <linux/delay.h>
19594 +#include <linux/cpu.h>
19595 +#include <asm/devtree.h>
19596 +#include <asm/processor.h>
19597 +#include <asm/cpu.h>
19598 +
19599 +struct procnode {
19600 +       struct devtree_node dn;
19601 +       unsigned int threads;
19602 +       unsigned int timers;
19603 +       unsigned int frequency;
19604 +       unsigned int interrupt0;
19605 +       unsigned int interrupt1;
19606 +       void *socm;
19607 +       void *eocm;
19608 +       void *sdram;
19609 +       void *edram;
19610 +};
19611 +
19612 +struct procnode *pn;
19613 +
19614 +/*
19615 + * show_processorinfo()
19616 + *     Print the actual processor information.
19617 + */
19618 +static void show_processorinfo(struct seq_file *m)
19619 +{
19620 +       char *cpu, *mmu, *fpu;
19621 +       unsigned int clockfreq;
19622 +       unsigned int chipid;
19623 +
19624 +       cpu = CPU;
19625 +       mmu = "none";
19626 +       fpu = "none";
19627 +
19628 +       asm volatile (
19629 +       "move.4         %0, CHIP_ID     \n\t"
19630 +       : "=r" (chipid)
19631 +       );
19632 +
19633 +       /*
19634 +        * General Processor Information.
19635 +        */
19636 +       seq_printf(m, "Vendor:\t\t%s\n", "Ubicom");
19637 +       seq_printf(m, "CPU:\t\t%s\n", cpu);
19638 +       seq_printf(m, "MMU:\t\t%s\n", mmu);
19639 +       seq_printf(m, "FPU:\t\t%s\n", fpu);
19640 +       seq_printf(m, "Arch:\t\t%hx\n", chipid >> 16);
19641 +       seq_printf(m, "Rev:\t\t%hx\n", (chipid & 0xffff));
19642 +
19643 +       /*
19644 +        * Now compute the clock frequency in Mhz.
19645 +        */
19646 +       clockfreq = processor_frequency();
19647 +       seq_printf(m, "Clock Freq:\t%u.%1u MHz\n",
19648 +                  clockfreq / 1000000,
19649 +                  (clockfreq / 100000) % 10);
19650 +       seq_printf(m, "BogoMips:\t%lu.%02lu\n",
19651 +                  (loops_per_jiffy * HZ) / 500000,
19652 +                  ((loops_per_jiffy * HZ) / 5000) % 100);
19653 +       seq_printf(m, "Calibration:\t%lu loops\n", (loops_per_jiffy * HZ));
19654 +}
19655 +
19656 +/*
19657 + * show_cpuinfo()
19658 + *     Get CPU information for use by the procfs.
19659 + */
19660 +static int show_cpuinfo(struct seq_file *m, void *v)
19661 +{
19662 +       unsigned long n = (unsigned long)v - 1;
19663 +
19664 +#if defined(CONFIG_SMP)
19665 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, n);
19666 +#endif
19667 +
19668 +       /*
19669 +        * Print the general processor information on the first
19670 +        * call.
19671 +        */
19672 +       if (n == 0) {
19673 +               show_processorinfo(m);
19674 +       }
19675 +
19676 +#if defined(CONFIG_SMP)
19677 +       /*
19678 +        * For each hwthread, print if this hwthread is running Linux
19679 +        * or is an I/O thread.
19680 +        */
19681 +       if (cpu_isset(n, cpu_online_map)) {
19682 +               seq_printf(m, "cpu[%02lu]:\tthread id - %lu\n", n, p->tid);
19683 +       } else {
19684 +               seq_printf(m, "cpu[%02lu]:\toff-line\n", n);
19685 +       }
19686 +#endif
19687 +       return 0;
19688 +
19689 +}
19690 +
19691 +static void *c_start(struct seq_file *m, loff_t *pos)
19692 +{
19693 +       unsigned long i = *pos;
19694 +
19695 +       return i < NR_CPUS ? (void *)(i + 1) : NULL;
19696 +}
19697 +
19698 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
19699 +{
19700 +       ++*pos;
19701 +       return c_start(m, pos);
19702 +}
19703 +
19704 +static void c_stop(struct seq_file *m, void *v)
19705 +{
19706 +}
19707 +
19708 +const struct seq_operations cpuinfo_op = {
19709 +       .start  = c_start,
19710 +       .next   = c_next,
19711 +       .stop   = c_stop,
19712 +       .show   = show_cpuinfo,
19713 +};
19714 +
19715 +/*
19716 + * processor_timers()
19717 + *     Returns the timers available to Linux.
19718 + */
19719 +unsigned int processor_timers(void)
19720 +{
19721 +       if (!pn) {
19722 +               return 0;
19723 +       }
19724 +       return pn->timers;
19725 +}
19726 +
19727 +/*
19728 + * processor_threads()
19729 + *     Returns the threads available to Linux.
19730 + */
19731 +unsigned int processor_threads(void)
19732 +{
19733 +       if (!pn) {
19734 +               return 0;
19735 +       }
19736 +       return pn->threads;
19737 +}
19738 +
19739 +/*
19740 + * processor_frequency()
19741 + *     Returns the frequency of the system clock.
19742 + */
19743 +unsigned int processor_frequency(void)
19744 +{
19745 +       if (!pn) {
19746 +               return 0;
19747 +       }
19748 +       return pn->frequency;
19749 +}
19750 +EXPORT_SYMBOL(processor_frequency);
19751 +
19752 +/*
19753 + * processor_interrupts()
19754 + *     Return the interrupts that are setup at boot time.
19755 + */
19756 +int processor_interrupts(unsigned int *int0, unsigned int *int1)
19757 +{
19758 +       if (!pn) {
19759 +               return -EFAULT;
19760 +       }
19761 +
19762 +       if (int0) {
19763 +               *int0 = pn->interrupt0;
19764 +       }
19765 +
19766 +       if (int1) {
19767 +               *int1 = pn->interrupt1;
19768 +       }
19769 +       return 0;
19770 +}
19771 +
19772 +/*
19773 + * processor_ocm()
19774 + *     Returns the OCM available to Linux.
19775 + */
19776 +int processor_ocm(void **socm, void **eocm)
19777 +{
19778 +       if (!pn) {
19779 +               return -ENOSYS;
19780 +       }
19781 +
19782 +       *socm = pn->socm;
19783 +       *eocm = pn->eocm;
19784 +       return 0;
19785 +}
19786 +
19787 +/*
19788 + * processor_dram()
19789 + *     Returns the dram available to Linux.
19790 + */
19791 +int processor_dram(void **sdram, void **edram)
19792 +{
19793 +       if (!pn) {
19794 +               return -ENOSYS;
19795 +       }
19796 +
19797 +       *sdram = pn->sdram;
19798 +       *edram = pn->edram;
19799 +       return 0;
19800 +}
19801 +
19802 +void __init processor_init(void)
19803 +{
19804 +       /*
19805 +        * If we do not have a trap node in the device tree, we leave the fault
19806 +        * handling to the underlying hardware.
19807 +        */
19808 +       pn = (struct procnode *)devtree_find_node("processor");
19809 +       if (!pn) {
19810 +               printk(KERN_WARNING "processor node not found\n");
19811 +               return;
19812 +       }
19813 +}
19814 --- /dev/null
19815 +++ b/arch/ubicom32/kernel/ptrace.c
19816 @@ -0,0 +1,275 @@
19817 +/*
19818 + * arch/ubicom32/kernel/ptrace.c
19819 + *   Ubicom32 architecture ptrace implementation.
19820 + *
19821 + * (C) Copyright 2009, Ubicom, Inc.
19822 + * (C) 1994 by Hamish Macdonald
19823 + * Taken from linux/kernel/ptrace.c and modified for M680x0.
19824 + * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
19825 + *
19826 + * This file is part of the Ubicom32 Linux Kernel Port.
19827 + *
19828 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19829 + * it and/or modify it under the terms of the GNU General Public License
19830 + * as published by the Free Software Foundation, either version 2 of the
19831 + * License, or (at your option) any later version.
19832 + *
19833 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19834 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19835 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19836 + * the GNU General Public License for more details.
19837 + *
19838 + * You should have received a copy of the GNU General Public License
19839 + * along with the Ubicom32 Linux Kernel Port.  If not,
19840 + * see <http://www.gnu.org/licenses/>.
19841 + *
19842 + * Ubicom32 implementation derived from (with many thanks):
19843 + *   arch/m68knommu
19844 + *   arch/blackfin
19845 + *   arch/parisc
19846 + */
19847 +
19848 +#include <linux/module.h>
19849 +#include <linux/kernel.h>
19850 +#include <linux/sched.h>
19851 +#include <linux/mm.h>
19852 +#include <linux/smp.h>
19853 +#include <linux/errno.h>
19854 +#include <linux/ptrace.h>
19855 +#include <linux/user.h>
19856 +#include <linux/signal.h>
19857 +#include <linux/uaccess.h>
19858 +
19859 +#include <asm/page.h>
19860 +#include <asm/pgtable.h>
19861 +#include <asm/system.h>
19862 +#include <asm/cacheflush.h>
19863 +#include <asm/processor.h>
19864 +
19865 +/*
19866 + * ptrace_getregs()
19867 + *
19868 + *     Get all user integer registers.
19869 + */
19870 +static inline int ptrace_getregs(struct task_struct *task, void __user *uregs)
19871 +{
19872 +       struct pt_regs *regs = task_pt_regs(task);
19873 +       return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
19874 +}
19875 +
19876 +/*
19877 + * ptrace_get_reg()
19878 + *
19879 + *     Get contents of register REGNO in task TASK.
19880 + */
19881 +static unsigned long ptrace_get_reg(struct task_struct *task, int regno)
19882 +{
19883 +       if (regno < sizeof(struct pt_regs)) {
19884 +               struct pt_regs *pt_regs = task_pt_regs(task);
19885 +               return *(unsigned long *)((long) pt_regs + regno);
19886 +       }
19887 +
19888 +       return -EIO;
19889 +}
19890 +
19891 +/*
19892 + * ptrace_put_reg()
19893 + *     Write contents of register REGNO in task TASK.
19894 + */
19895 +static int ptrace_put_reg(struct task_struct *task, int regno,
19896 +                         unsigned long data)
19897 +{
19898 +       if (regno <= sizeof(struct pt_regs) && regno != PT_FRAME_TYPE) {
19899 +               struct pt_regs *pt_regs = task_pt_regs(task);
19900 +               *(unsigned long *)((long) pt_regs + regno) = data;
19901 +               return 0;
19902 +       }
19903 +       return -EIO;
19904 +}
19905 +
19906 +/*
19907 + * ptrace_disable_single_step()
19908 + *     Disable Single Step
19909 + */
19910 +static int ptrace_disable_single_step(struct task_struct *task)
19911 +{
19912 +       /*
19913 +        * Single Step not yet implemented, so must always be disabled
19914 +        */
19915 +       return 0;
19916 +}
19917 +
19918 +/*
19919 + * ptrace_disable()
19920 + *     Make sure the single step bit is not set.
19921 + * Called by kernel/ptrace.c when detaching..
19922 + */
19923 +void ptrace_disable(struct task_struct *child)
19924 +{
19925 +       ptrace_disable_single_step(child);
19926 +}
19927 +
19928 +/*
19929 + * arch_ptrace()
19930 + *     architecture specific ptrace routine.
19931 + */
19932 +long arch_ptrace(struct task_struct *child, long request, long addr, long data)
19933 +{
19934 +       int ret;
19935 +       switch (request) {
19936 +       /* when I and D space are separate, these will need to be fixed. */
19937 +       case PTRACE_PEEKTEXT: /* read word at location addr. */
19938 +       case PTRACE_PEEKDATA:
19939 +               ret = generic_ptrace_peekdata(child, addr, data);
19940 +               break;
19941 +
19942 +       /* read the word at location addr in the USER area. */
19943 +       case PTRACE_PEEKUSR: {
19944 +               unsigned long tmp;
19945 +
19946 +               ret = -EIO;
19947 +               if (((unsigned long) addr > PT_INTERP_FDPIC_LOADMAP)
19948 +                   || (addr & 3))
19949 +                       break;
19950 +
19951 +               tmp = 0;  /* Default return condition */
19952 +
19953 +               ret = -EIO;
19954 +               if (addr < sizeof(struct pt_regs)) {
19955 +                       tmp = ptrace_get_reg(child, addr);
19956 +               } else if (addr == PT_TEXT_ADDR) {
19957 +                       tmp = child->mm->start_code;
19958 +               } else if (addr == PT_TEXT_END_ADDR) {
19959 +                       tmp = child->mm->end_code;
19960 +               } else if (addr == PT_DATA_ADDR) {
19961 +                       tmp = child->mm->start_data;
19962 +               } else if (addr == PT_EXEC_FDPIC_LOADMAP) {
19963 +#ifdef CONFIG_BINFMT_ELF_FDPIC
19964 +                       tmp = child->mm->context.exec_fdpic_loadmap;
19965 +#endif
19966 +               } else if (addr == PT_INTERP_FDPIC_LOADMAP) {
19967 +#ifdef CONFIG_BINFMT_ELF_FDPIC
19968 +                       tmp = child->mm->context.interp_fdpic_loadmap;
19969 +#endif
19970 +               } else {
19971 +                       break;
19972 +               }
19973 +
19974 +               ret = put_user(tmp, (unsigned long *)data);
19975 +               break;
19976 +       }
19977 +
19978 +       case PTRACE_POKETEXT: /* write the word at location addr. */
19979 +       case PTRACE_POKEDATA:
19980 +               ret = generic_ptrace_pokedata(child, addr, data);
19981 +
19982 +               /*
19983 +                * If we just changed some code so we need to
19984 +                * correct the caches
19985 +                */
19986 +               if (request == PTRACE_POKETEXT && ret == 0) {
19987 +                       flush_icache_range(addr, addr + 4);
19988 +               }
19989 +               break;
19990 +
19991 +       case PTRACE_POKEUSR: /* write the word at location addr
19992 +                             * in the USER area */
19993 +               ret = -EIO;
19994 +
19995 +               if (((unsigned long) addr > PT_DATA_ADDR) || (addr & 3))
19996 +                       break;
19997 +
19998 +               if (addr < sizeof(struct pt_regs)) {
19999 +                       ret = ptrace_put_reg(child, addr, data);
20000 +               }
20001 +               break;
20002 +
20003 +       case PTRACE_SYSCALL: /* continue and stop at next (return from)
20004 +                             * syscall */
20005 +       case PTRACE_CONT: { /* restart after signal. */
20006 +
20007 +               ret = -EIO;
20008 +               if (!valid_signal(data))
20009 +                       break;
20010 +               if (request == PTRACE_SYSCALL)
20011 +                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
20012 +               else
20013 +                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
20014 +               child->exit_code = data;
20015 +               /* make sure the single step bit is not set. */
20016 +               ptrace_disable_single_step(child);
20017 +               wake_up_process(child);
20018 +               ret = 0;
20019 +               break;
20020 +       }
20021 +
20022 +       /*
20023 +        * make the child exit.  Best I can do is send it a sigkill.
20024 +        * perhaps it should be put in the status that it wants to exit.
20025 +        */
20026 +       case PTRACE_KILL: {
20027 +               ret = 0;
20028 +               if (child->exit_state == EXIT_ZOMBIE) /* already dead */
20029 +                       break;
20030 +               child->exit_code = SIGKILL;
20031 +               /* make sure the single step bit is not set. */
20032 +               ptrace_disable_single_step(child);
20033 +               wake_up_process(child);
20034 +               break;
20035 +       }
20036 +
20037 +       case PTRACE_DETACH:     /* detach a process that was attached. */
20038 +               ret = ptrace_detach(child, data);
20039 +               break;
20040 +
20041 +       case PTRACE_GETREGS:    /* Get all gp regs from the child. */
20042 +               ptrace_getregs(child, (unsigned long *)data);
20043 +               ret = 0;
20044 +               break;
20045 +
20046 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
20047 +               int i;
20048 +               unsigned long tmp;
20049 +               int count = sizeof(struct pt_regs) / sizeof(unsigned long);
20050 +               for (i = 0; i < count; i++) {
20051 +                       if (get_user(tmp, (unsigned long *) data)) {
20052 +                               ret = -EFAULT;
20053 +                               break;
20054 +                       }
20055 +                       ptrace_put_reg(child, sizeof(unsigned long) * i, tmp);
20056 +                       data += sizeof(long);
20057 +               }
20058 +               ret = 0;
20059 +               break;
20060 +       }
20061 +
20062 +       default:
20063 +               return ptrace_request(child, request, addr, data);
20064 +               break;
20065 +       }
20066 +       return ret;
20067 +}
20068 +/*
20069 + * syscall_trace
20070 + *
20071 + * called by syscall enter/exit when the TIF_SYSCALL_TRACE bit is set.
20072 + */
20073 +asmlinkage void syscall_trace(void)
20074 +{
20075 +       struct task_struct *cur = current;
20076 +       if (!test_thread_flag(TIF_SYSCALL_TRACE))
20077 +               return;
20078 +       if (!(cur->ptrace & PT_PTRACED))
20079 +               return;
20080 +       ptrace_notify(SIGTRAP | ((cur->ptrace & PT_TRACESYSGOOD)
20081 +                                ? 0x80 : 0));
20082 +       /*
20083 +        * this isn't the same as continuing with a signal, but it will do
20084 +        * for normal use.  strace only continues with a signal if the
20085 +        * stopping signal is not SIGTRAP.  -brl
20086 +        */
20087 +       if (cur->exit_code) {
20088 +               send_sig(cur->exit_code, current, 1);
20089 +               current->exit_code = 0;
20090 +       }
20091 +}
20092 --- /dev/null
20093 +++ b/arch/ubicom32/kernel/semaphore.c
20094 @@ -0,0 +1,159 @@
20095 +/*
20096 + * arch/ubicom32/kernel/semaphore.c
20097 + *   Ubicom32 architecture semaphore implementation.
20098 + *
20099 + * (C) Copyright 2009, Ubicom, Inc.
20100 + *
20101 + * This file is part of the Ubicom32 Linux Kernel Port.
20102 + *
20103 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20104 + * it and/or modify it under the terms of the GNU General Public License
20105 + * as published by the Free Software Foundation, either version 2 of the
20106 + * License, or (at your option) any later version.
20107 + *
20108 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20109 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20110 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20111 + * the GNU General Public License for more details.
20112 + *
20113 + * You should have received a copy of the GNU General Public License
20114 + * along with the Ubicom32 Linux Kernel Port.  If not,
20115 + * see <http://www.gnu.org/licenses/>.
20116 + *
20117 + * Ubicom32 implementation derived from (with many thanks):
20118 + *   arch/m68knommu
20119 + *   arch/blackfin
20120 + *   arch/parisc
20121 + */
20122 +/*
20123 + *  Generic semaphore code. Buyer beware. Do your own
20124 + * specific changes in <asm/semaphore-helper.h>
20125 + */
20126 +
20127 +#include <linux/sched.h>
20128 +#include <linux/err.h>
20129 +#include <linux/init.h>
20130 +#include <asm/semaphore-helper.h>
20131 +
20132 +#ifndef CONFIG_RMW_INSNS
20133 +spinlock_t semaphore_wake_lock;
20134 +#endif
20135 +
20136 +/*
20137 + * Semaphores are implemented using a two-way counter:
20138 + * The "count" variable is decremented for each process
20139 + * that tries to sleep, while the "waking" variable is
20140 + * incremented when the "up()" code goes to wake up waiting
20141 + * processes.
20142 + *
20143 + * Notably, the inline "up()" and "down()" functions can
20144 + * efficiently test if they need to do any extra work (up
20145 + * needs to do something only if count was negative before
20146 + * the increment operation.
20147 + *
20148 + * waking_non_zero() (from asm/semaphore.h) must execute
20149 + * atomically.
20150 + *
20151 + * When __up() is called, the count was negative before
20152 + * incrementing it, and we need to wake up somebody.
20153 + *
20154 + * This routine adds one to the count of processes that need to
20155 + * wake up and exit.  ALL waiting processes actually wake up but
20156 + * only the one that gets to the "waking" field first will gate
20157 + * through and acquire the semaphore.  The others will go back
20158 + * to sleep.
20159 + *
20160 + * Note that these functions are only called when there is
20161 + * contention on the lock, and as such all this is the
20162 + * "non-critical" part of the whole semaphore business. The
20163 + * critical part is the inline stuff in <asm/semaphore.h>
20164 + * where we want to avoid any extra jumps and calls.
20165 + */
20166 +void __up(struct semaphore *sem)
20167 +{
20168 +       wake_one_more(sem);
20169 +       wake_up(&sem->wait);
20170 +}
20171 +
20172 +/*
20173 + * Perform the "down" function.  Return zero for semaphore acquired,
20174 + * return negative for signalled out of the function.
20175 + *
20176 + * If called from __down, the return is ignored and the wait loop is
20177 + * not interruptible.  This means that a task waiting on a semaphore
20178 + * using "down()" cannot be killed until someone does an "up()" on
20179 + * the semaphore.
20180 + *
20181 + * If called from __down_interruptible, the return value gets checked
20182 + * upon return.  If the return value is negative then the task continues
20183 + * with the negative value in the return register (it can be tested by
20184 + * the caller).
20185 + *
20186 + * Either form may be used in conjunction with "up()".
20187 + *
20188 + */
20189 +
20190 +
20191 +#define DOWN_HEAD(task_state)                                          \
20192 +                                                                       \
20193 +                                                                       \
20194 +       current->state = (task_state);                                  \
20195 +       add_wait_queue(&sem->wait, &wait);                              \
20196 +                                                                       \
20197 +       /*                                                              \
20198 +        * Ok, we're set up.  sem->count is known to be less than zero  \
20199 +        * so we must wait.                                             \
20200 +        *                                                              \
20201 +        * We can let go the lock for purposes of waiting.              \
20202 +        * We re-acquire it after awaking so as to protect              \
20203 +        * all semaphore operations.                                    \
20204 +        *                                                              \
20205 +        * If "up()" is called before we call waking_non_zero() then    \
20206 +        * we will catch it right away.  If it is called later then     \
20207 +        * we will have to go through a wakeup cycle to catch it.       \
20208 +        *                                                              \
20209 +        * Multiple waiters contend for the semaphore lock to see       \
20210 +        * who gets to gate through and who has to wait some more.      \
20211 +        */                                                             \
20212 +       for (;;) {
20213 +
20214 +#define DOWN_TAIL(task_state)                  \
20215 +               current->state = (task_state);  \
20216 +       }                                       \
20217 +       current->state = TASK_RUNNING;          \
20218 +       remove_wait_queue(&sem->wait, &wait);
20219 +
20220 +void __sched __down(struct semaphore *sem)
20221 +{
20222 +       DECLARE_WAITQUEUE(wait, current);
20223 +
20224 +       DOWN_HEAD(TASK_UNINTERRUPTIBLE)
20225 +       if (waking_non_zero(sem))
20226 +               break;
20227 +       schedule();
20228 +       DOWN_TAIL(TASK_UNINTERRUPTIBLE)
20229 +}
20230 +
20231 +int __sched __down_interruptible(struct semaphore *sem)
20232 +{
20233 +       DECLARE_WAITQUEUE(wait, current);
20234 +       int ret = 0;
20235 +
20236 +       DOWN_HEAD(TASK_INTERRUPTIBLE)
20237 +
20238 +       ret = waking_non_zero_interruptible(sem, current);
20239 +       if (ret) {
20240 +               if (ret == 1)
20241 +                       /* ret != 0 only if we get interrupted -arca */
20242 +                       ret = 0;
20243 +               break;
20244 +       }
20245 +       schedule();
20246 +       DOWN_TAIL(TASK_INTERRUPTIBLE)
20247 +       return ret;
20248 +}
20249 +
20250 +int __down_trylock(struct semaphore *sem)
20251 +{
20252 +       return waking_non_zero_trylock(sem);
20253 +}
20254 --- /dev/null
20255 +++ b/arch/ubicom32/kernel/setup.c
20256 @@ -0,0 +1,189 @@
20257 +/*
20258 + * arch/ubicom32/kernel/setup.c
20259 + *   Ubicom32 architecture-dependent parts of system setup.
20260 + *
20261 + * (C) Copyright 2009, Ubicom, Inc.
20262 + * Copyright (C) 1999-2007  Greg Ungerer (gerg@snapgear.com)
20263 + * Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
20264 + * Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
20265 + * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
20266 + * Copyright (C) 1995       Hamish Macdonald
20267 + * Copyright (C) 2000       Lineo Inc. (www.lineo.com)
20268 + * Copyright (C) 2001      Lineo, Inc. <www.lineo.com>
20269 + * 68VZ328 Fixes/support    Evan Stawnyczy <e@lineo.ca>
20270 + *
20271 + * This file is part of the Ubicom32 Linux Kernel Port.
20272 + *
20273 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20274 + * it and/or modify it under the terms of the GNU General Public License
20275 + * as published by the Free Software Foundation, either version 2 of the
20276 + * License, or (at your option) any later version.
20277 + *
20278 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20279 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20280 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20281 + * the GNU General Public License for more details.
20282 + *
20283 + * You should have received a copy of the GNU General Public License
20284 + * along with the Ubicom32 Linux Kernel Port.  If not,
20285 + * see <http://www.gnu.org/licenses/>.
20286 + *
20287 + * Ubicom32 implementation derived from (with many thanks):
20288 + *   arch/m68knommu
20289 + *   arch/blackfin
20290 + *   arch/parisc
20291 + */
20292 +
20293 +#include <linux/kernel.h>
20294 +#include <linux/sched.h>
20295 +#include <linux/delay.h>
20296 +#include <linux/interrupt.h>
20297 +#include <linux/fb.h>
20298 +#include <linux/module.h>
20299 +#include <linux/console.h>
20300 +#include <linux/errno.h>
20301 +#include <linux/string.h>
20302 +#include <linux/bootmem.h>
20303 +#include <linux/seq_file.h>
20304 +#include <linux/init.h>
20305 +
20306 +#include <asm/devtree.h>
20307 +#include <asm/setup.h>
20308 +#include <asm/irq.h>
20309 +#include <asm/machdep.h>
20310 +#include <asm/pgtable.h>
20311 +#include <asm/pgalloc.h>
20312 +#include <asm/ubicom32-common.h>
20313 +#include <asm/processor.h>
20314 +#include <asm/bootargs.h>
20315 +#include <asm/thread.h>
20316 +
20317 +unsigned long memory_start;
20318 +EXPORT_SYMBOL(memory_start);
20319 +
20320 +unsigned long memory_end;
20321 +EXPORT_SYMBOL(memory_end);
20322 +
20323 +static char __initdata command_line[COMMAND_LINE_SIZE];
20324 +#ifdef CONFIG_CMDLINE_BOOL
20325 +static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
20326 +#endif
20327 +
20328 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
20329 +
20330 +/*
20331 + * setup_arch()
20332 + *     Setup the architecture dependent portions of the system.
20333 + */
20334 +void __init setup_arch(char **cmdline_p)
20335 +{
20336 +       int bootmap_size;
20337 +
20338 +       processor_init();
20339 +       bootargs_init();
20340 +
20341 +       /*
20342 +        * TODO: The memory regions should really come from the
20343 +        * processor node.
20344 +        */
20345 +       memory_start = PAGE_ALIGN(((unsigned long)&_end));
20346 +       memory_end = CONFIG_RAMBASE+CONFIG_RAMSIZE;
20347 +
20348 +       init_mm.start_code = (unsigned long) &_stext;
20349 +       init_mm.end_code = (unsigned long) &_etext;
20350 +       init_mm.end_data = (unsigned long) &_edata;
20351 +       init_mm.brk = (unsigned long) 0;
20352 +
20353 +       strlcpy(boot_command_line, bootargs_get_cmdline(), COMMAND_LINE_SIZE);
20354 +
20355 +#ifdef CONFIG_CMDLINE_BOOL
20356 +#ifdef CONFIG_CMDLINE_OVERRIDE
20357 +       strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
20358 +#else
20359 +       if (builtin_cmdline[0]) {
20360 +               /* append boot loader cmdline to builtin */
20361 +               strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
20362 +               strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
20363 +               strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
20364 +       }
20365 +#endif
20366 +#endif
20367 +
20368 +       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
20369 +       *cmdline_p = command_line;
20370 +
20371 +       parse_early_param();
20372 +
20373 +       printk(KERN_INFO "%s Processor, Ubicom, Inc. <www.ubicom.com>\n", CPU);
20374 +
20375 +#if defined(DEBUG)
20376 +       printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
20377 +               "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
20378 +               (int) &_sdata, (int) &_edata,
20379 +               (int) &_sbss, (int) &_ebss);
20380 +       printk(KERN_DEBUG "MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
20381 +               (int) &_ebss, (int) memory_start,
20382 +               (int) memory_start, (int) memory_end);
20383 +#endif
20384 +
20385 +       /* Keep a copy of command line */
20386 +       *cmdline_p = &command_line[0];
20387 +       memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
20388 +       boot_command_line[COMMAND_LINE_SIZE-1] = 0;
20389 +
20390 +#ifdef DEBUG
20391 +       if (strlen(*cmdline_p))
20392 +               printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
20393 +#endif
20394 +
20395 +#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
20396 +       conswitchp = &dummy_con;
20397 +#endif
20398 +
20399 +       /*
20400 +        * If we have a device tree, see if we have the nodes we need.
20401 +        */
20402 +       if (devtree) {
20403 +               devtree_print();
20404 +       }
20405 +
20406 +       /*
20407 +        * From the arm initialization comment:
20408 +        *
20409 +        * This doesn't seem to be used by the Linux memory manager any
20410 +        * more, but is used by ll_rw_block.  If we can get rid of it, we
20411 +        * also get rid of some of the stuff above as well.
20412 +        *
20413 +        * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
20414 +        * the system, not the maximum PFN.
20415 +        */
20416 +       max_pfn = max_low_pfn = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
20417 +
20418 +       /*
20419 +        * Give all the memory to the bootmap allocator, tell it to put the
20420 +        * boot mem_map at the start of memory.
20421 +        */
20422 +       bootmap_size = init_bootmem_node(
20423 +                       NODE_DATA(0),
20424 +                       memory_start >> PAGE_SHIFT,     /* map goes here */
20425 +                       PAGE_OFFSET >> PAGE_SHIFT,      /* 0 on coldfire */
20426 +                       memory_end >> PAGE_SHIFT);
20427 +       /*
20428 +        * Free the usable memory, we have to make sure we do not free
20429 +        * the bootmem bitmap so we then reserve it after freeing it :-)
20430 +        */
20431 +       free_bootmem(memory_start, memory_end - memory_start);
20432 +       reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
20433 +
20434 +       /*
20435 +        * Get kmalloc into gear.
20436 +        */
20437 +       paging_init();
20438 +
20439 +       /*
20440 +        * Fix up the thread_info structure, indicate this is a mainline Linux
20441 +        * thread and setup the sw_ksp().
20442 +        */
20443 +       sw_ksp[thread_get_self()] = (unsigned int) current_thread_info();
20444 +       thread_set_mainline(thread_get_self());
20445 +}
20446 --- /dev/null
20447 +++ b/arch/ubicom32/kernel/signal.c
20448 @@ -0,0 +1,458 @@
20449 +/*
20450 + * arch/ubicom32/kernel/signal.c
20451 + *   Ubicom32 architecture signal handling implementation.
20452 + *
20453 + * (C) Copyright 2009, Ubicom, Inc.
20454 + * Copyright (C) 1991, 1992  Linus Torvalds
20455 + * Linux/m68k support by Hamish Macdonald
20456 + * 68060 fixes by Jesper Skov
20457 + * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
20458 + * mathemu support by Roman Zippel
20459 + * ++roman (07/09/96): implemented signal stacks
20460 + *
20461 + * This file is part of the Ubicom32 Linux Kernel Port.
20462 + *
20463 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20464 + * it and/or modify it under the terms of the GNU General Public License
20465 + * as published by the Free Software Foundation, either version 2 of the
20466 + * License, or (at your option) any later version.
20467 + *
20468 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20469 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20470 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20471 + * the GNU General Public License for more details.
20472 + *
20473 + * You should have received a copy of the GNU General Public License
20474 + * along with the Ubicom32 Linux Kernel Port.  If not,
20475 + * see <http://www.gnu.org/licenses/>.
20476 + *
20477 + * Ubicom32 implementation derived from (with many thanks):
20478 + *   arch/m68knommu
20479 + *   arch/blackfin
20480 + *   arch/parisc
20481 + *
20482 + * mathemu support by Roman Zippel
20483 + *  (Note: fpstate in the signal context is completely ignored for the emulator
20484 + *         and the internal floating point format is put on stack)
20485 + *
20486 + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
20487 + * Atari :-) Current limitation: Only one sigstack can be active at one time.
20488 + * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
20489 + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
20490 + * signal handlers!
20491 + */
20492 +
20493 +#include <linux/module.h>
20494 +#include <linux/sched.h>
20495 +#include <linux/mm.h>
20496 +#include <linux/kernel.h>
20497 +#include <linux/signal.h>
20498 +#include <linux/syscalls.h>
20499 +#include <linux/errno.h>
20500 +#include <linux/wait.h>
20501 +#include <linux/ptrace.h>
20502 +#include <linux/unistd.h>
20503 +#include <linux/stddef.h>
20504 +#include <linux/highuid.h>
20505 +#include <linux/tty.h>
20506 +#include <linux/personality.h>
20507 +#include <linux/binfmts.h>
20508 +
20509 +#include <asm/setup.h>
20510 +#include <asm/uaccess.h>
20511 +#include <asm/pgtable.h>
20512 +#include <asm/traps.h>
20513 +#include <asm/ucontext.h>
20514 +
20515 +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
20516 +
20517 +/*
20518 + * asm signal return handlers.
20519 + */
20520 +void ret_from_user_signal(void);
20521 +void ret_from_user_rt_signal(void);
20522 +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
20523 +
20524 +/*
20525 + * Common signal suspend implementation
20526 + */
20527 +static int signal_suspend(sigset_t *saveset, struct pt_regs *regs)
20528 +{
20529 +       regs->dn[0] = -EINTR;
20530 +       while (1) {
20531 +               current->state = TASK_INTERRUPTIBLE;
20532 +               schedule();
20533 +               if (!do_signal(saveset, regs)) {
20534 +                       continue;
20535 +               }
20536 +               /*
20537 +                * If the current frame type is a signal trampoline we are
20538 +                * actually going to call the signal handler so we return the
20539 +                * desired d0 as the return value.
20540 +                */
20541 +               if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) {
20542 +                       return regs->dn[0];
20543 +               }
20544 +               return -EINTR;
20545 +       }
20546 +       /*
20547 +        * Should never get here
20548 +        */
20549 +       BUG();
20550 +       return 0;
20551 +}
20552 +
20553 +/*
20554 + * Atomically swap in the new signal mask, and wait for a signal.
20555 + */
20556 +asmlinkage int do_sigsuspend(struct pt_regs *regs)
20557 +{
20558 +       old_sigset_t mask = regs->dn[0];
20559 +       sigset_t saveset;
20560 +
20561 +       mask &= _BLOCKABLE;
20562 +       spin_lock_irq(&current->sighand->siglock);
20563 +       saveset = current->blocked;
20564 +       siginitset(&current->blocked, mask);
20565 +       recalc_sigpending();
20566 +       spin_unlock_irq(&current->sighand->siglock);
20567 +
20568 +       /*
20569 +        * Call common handler
20570 +        */
20571 +       return signal_suspend(&saveset, regs);
20572 +}
20573 +
20574 +asmlinkage int
20575 +do_rt_sigsuspend(struct pt_regs *regs)
20576 +{
20577 +       sigset_t *unewset = (sigset_t *)regs->dn[0];
20578 +       size_t sigsetsize = (size_t)regs->dn[1];
20579 +       sigset_t saveset, newset;
20580 +
20581 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
20582 +       if (sigsetsize != sizeof(sigset_t))
20583 +               return -EINVAL;
20584 +
20585 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
20586 +               return -EFAULT;
20587 +       sigdelsetmask(&newset, ~_BLOCKABLE);
20588 +
20589 +       spin_lock_irq(&current->sighand->siglock);
20590 +       saveset = current->blocked;
20591 +       current->blocked = newset;
20592 +       recalc_sigpending();
20593 +       spin_unlock_irq(&current->sighand->siglock);
20594 +
20595 +       /*
20596 +        * Call common handler
20597 +        */
20598 +       return signal_suspend(&saveset, regs);
20599 +}
20600 +
20601 +asmlinkage int
20602 +sys_sigaction(int sig, const struct old_sigaction *act,
20603 +             struct old_sigaction *oact)
20604 +{
20605 +       struct k_sigaction new_ka, old_ka;
20606 +       int ret;
20607 +
20608 +       if (act) {
20609 +               old_sigset_t mask;
20610 +               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
20611 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
20612 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
20613 +                       return -EFAULT;
20614 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
20615 +               __get_user(mask, &act->sa_mask);
20616 +               siginitset(&new_ka.sa.sa_mask, mask);
20617 +       }
20618 +
20619 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
20620 +
20621 +       if (!ret && oact) {
20622 +               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
20623 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
20624 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
20625 +                       return -EFAULT;
20626 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
20627 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
20628 +       }
20629 +
20630 +       return ret;
20631 +}
20632 +
20633 +asmlinkage int
20634 +do_sys_sigaltstack(struct pt_regs *regs)
20635 +{
20636 +       const stack_t *uss = (stack_t *) regs->dn[0];
20637 +       stack_t *uoss = (stack_t *)regs->dn[1];
20638 +       return do_sigaltstack(uss, uoss, regs->an[7]);
20639 +}
20640 +
20641 +/*
20642 + * fdpic_func_descriptor describes sa_handler when the application is FDPIC
20643 + */
20644 +struct fdpic_func_descriptor {
20645 +       unsigned long   text;
20646 +       unsigned long   GOT;
20647 +};
20648 +
20649 +/*
20650 + * rt_sigframe is stored on the user stack immediately before (above)
20651 + * the signal handlers stack.
20652 + */
20653 +struct rt_sigframe
20654 +{
20655 +       unsigned long syscall_number;   /* This holds __NR_rt_sigreturn. */
20656 +       unsigned long restore_all_regs; /* This field gets set to 1 if the frame
20657 +                                        * type is TRAP or INTERRUPT. */
20658 +       siginfo_t *info;
20659 +       struct ucontext uc;
20660 +       int sig;
20661 +       void *pretcode;
20662 +};
20663 +
20664 +/*
20665 + * Do a signal return; undo the signal stack.
20666 + */
20667 +asmlinkage int do_sigreturn(unsigned long __unused)
20668 +{
20669 +       BUG();
20670 +       return 0;
20671 +}
20672 +
20673 +asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
20674 +{
20675 +       unsigned long usp = regs->an[7];
20676 +       struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
20677 +       sigset_t set;
20678 +
20679 +       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
20680 +               goto badframe;
20681 +       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
20682 +               goto badframe;
20683 +
20684 +       sigdelsetmask(&set, ~_BLOCKABLE);
20685 +       spin_lock_irq(&current->sighand->siglock);
20686 +       current->blocked = set;
20687 +       recalc_sigpending();
20688 +       spin_unlock_irq(&current->sighand->siglock);
20689 +
20690 +       if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs)))
20691 +               goto badframe;
20692 +       return regs->dn[0];
20693 +
20694 +badframe:
20695 +       force_sig(SIGSEGV, current);
20696 +       return 0;
20697 +}
20698 +
20699 +static inline void *
20700 +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
20701 +{
20702 +       unsigned long usp;
20703 +
20704 +       /* Default to using normal stack.  */
20705 +       usp = regs->an[7];
20706 +
20707 +       /* This is the X/Open sanctioned signal stack switching.  */
20708 +       if (ka->sa.sa_flags & SA_ONSTACK) {
20709 +               if (!sas_ss_flags(usp))
20710 +                       usp = current->sas_ss_sp + current->sas_ss_size;
20711 +       }
20712 +       return (void *)((usp - frame_size) & ~0x3);
20713 +}
20714 +
20715 +/*
20716 + * signal_trampoline:  Defined in ubicom32_syscall.S
20717 + */
20718 +asmlinkage void signal_trampoline(void)__attribute__((naked));
20719 +
20720 +static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
20721 +                           sigset_t *set, struct pt_regs *regs)
20722 +{
20723 +       struct rt_sigframe *frame;
20724 +       int err = 0;
20725 +
20726 +       frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame));
20727 +
20728 +       /*
20729 +        * The 'err |=' have been may criticized as bad code style, but I
20730 +        * strongly suspect that we want this code to be fast.  So for
20731 +        * now it stays as is.
20732 +        */
20733 +       err |= __put_user( (  (current_thread_info()->exec_domain)
20734 +                          && (current_thread_info()->exec_domain->signal_invmap)
20735 +                          && (sig < 32) )
20736 +                          ? current_thread_info()->exec_domain->signal_invmap[sig]
20737 +                          : sig, &frame->sig);
20738 +       err |= __put_user(info, &frame->info);
20739 +
20740 +       /* Create the ucontext.  */
20741 +       err |= __put_user(0, &frame->uc.uc_flags);
20742 +       err |= __put_user(0, &frame->uc.uc_link);
20743 +       err |= __put_user((void *)current->sas_ss_sp,
20744 +                         &frame->uc.uc_stack.ss_sp);
20745 +       err |= __put_user(sas_ss_flags(regs->an[7]),
20746 +                         &frame->uc.uc_stack.ss_flags);
20747 +       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
20748 +       err |= __put_user(__NR_rt_sigreturn, &frame->syscall_number);
20749 +       if ((regs->frame_type == UBICOM32_FRAME_TYPE_TRAP) ||
20750 +           (regs->frame_type == UBICOM32_FRAME_TYPE_INTERRUPT)) {
20751 +               err |= __put_user(1, &frame->restore_all_regs);
20752 +       } else {
20753 +               err |= __put_user(0, &frame->restore_all_regs);
20754 +       }
20755 +       err |= copy_to_user (&frame->uc.uc_mcontext.sc_regs, regs, sizeof(struct pt_regs));
20756 +       err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
20757 +
20758 +       if (err)
20759 +               goto give_sigsegv;
20760 +
20761 +       /*
20762 +        * Set up registers for signal handler NOTE: Do not modify dn[14], it
20763 +        * contains the userspace tls pointer, so it important that it carries
20764 +        * over to the signal handler.
20765 +        */
20766 +       regs->an[7] = (unsigned long)frame;
20767 +       regs->pc = (unsigned long) signal_trampoline;
20768 +       regs->an[5] = (unsigned long) signal_trampoline;
20769 +       regs->dn[0] = sig;
20770 +       regs->dn[1] = (unsigned long) frame->info;
20771 +       regs->dn[2] = (unsigned int) &frame->uc;
20772 +
20773 +       /*
20774 +        * If this is FDPIC then the signal handler is actually a function
20775 +        * descriptor.
20776 +        */
20777 +       if (current->personality & FDPIC_FUNCPTRS) {
20778 +               struct fdpic_func_descriptor __user *funcptr =
20779 +                       (struct fdpic_func_descriptor *) ka->sa.sa_handler;
20780 +               err |= __get_user(regs->dn[3], &funcptr->text);
20781 +               err |= __get_user(regs->an[0], &funcptr->GOT);
20782 +               if (err)
20783 +                       goto give_sigsegv;
20784 +
20785 +               /*
20786 +                * The funcdesc must be in a3 as this is required for the lazy
20787 +                * resolver in ld.so, if the application is not FDPIC a3 is not
20788 +                * used.
20789 +                */
20790 +               regs->an[3] = (unsigned long) funcptr;
20791 +
20792 +       } else {
20793 +               regs->dn[3] = (unsigned long)ka->sa.sa_handler;
20794 +               regs->an[0] = 0;
20795 +       }
20796 +
20797 +       regs->frame_type =  UBICOM32_FRAME_TYPE_SIGTRAMP;
20798 +
20799 +       return;
20800 +
20801 +give_sigsegv:
20802 +       /* user space exception */
20803 +       force_sigsegv(sig, current);
20804 +}
20805 +
20806 +static inline void
20807 +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
20808 +{
20809 +       switch (regs->dn[0]) {
20810 +       case -ERESTARTNOHAND:
20811 +               if (!has_handler)
20812 +                       goto do_restart;
20813 +               regs->dn[0] = -EINTR;
20814 +               break;
20815 +
20816 +       case -ERESTARTSYS:
20817 +               if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
20818 +                       regs->dn[0] = -EINTR;
20819 +                       break;
20820 +               }
20821 +       /* fallthrough */
20822 +       case -ERESTARTNOINTR:
20823 +       do_restart:
20824 +               regs->dn[0] = regs->original_dn_0;
20825 +               regs->pc -= 8;
20826 +               regs->an[5] -= 8;
20827 +               break;
20828 +       }
20829 +}
20830 +
20831 +/*
20832 + * OK, we're invoking a handler
20833 + */
20834 +static void
20835 +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
20836 +             sigset_t *oldset, struct pt_regs *regs)
20837 +{
20838 +       /* are we from a system call? */
20839 +       if (regs->frame_type == -1)
20840 +               /* If so, check system call restarting.. */
20841 +               handle_restart(regs, ka, 1);
20842 +
20843 +       /* set up the stack frame */
20844 +       setup_rt_frame(sig, ka, info, oldset, regs);
20845 +
20846 +       if (ka->sa.sa_flags & SA_ONESHOT)
20847 +               ka->sa.sa_handler = SIG_DFL;
20848 +
20849 +       spin_lock_irq(&current->sighand->siglock);
20850 +       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
20851 +       if (!(ka->sa.sa_flags & SA_NODEFER))
20852 +               sigaddset(&current->blocked,sig);
20853 +       recalc_sigpending();
20854 +       spin_unlock_irq(&current->sighand->siglock);
20855 +}
20856 +
20857 +/*
20858 + * Note that 'init' is a special process: it doesn't get signals it doesn't
20859 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
20860 + * mistake.
20861 + */
20862 +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
20863 +{
20864 +       struct k_sigaction ka;
20865 +       siginfo_t info;
20866 +       int signr;
20867 +
20868 +       /*
20869 +        * We want the common case to go fast, which
20870 +        * is why we may in certain cases get here from
20871 +        * kernel mode. Just return without doing anything
20872 +        * if so.
20873 +        */
20874 +       if (!user_mode(regs))
20875 +               return 1;
20876 +
20877 +       if (!oldset)
20878 +               oldset = &current->blocked;
20879 +
20880 +       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
20881 +       if (signr > 0) {
20882 +               /* Whee!  Actually deliver the signal.  */
20883 +               handle_signal(signr, &ka, &info, oldset, regs);
20884 +               return 1;
20885 +       }
20886 +
20887 +       /* Did we come from a system call? */
20888 +       if (regs->frame_type == -1) {
20889 +               /* Restart the system call - no handlers present */
20890 +               handle_restart(regs, NULL, 0);
20891 +       }
20892 +
20893 +       return 0;
20894 +}
20895 +
20896 +/*
20897 + * sys_sigreturn()
20898 + *     Return handler for signal clean-up.
20899 + *
20900 + * NOTE: Ubicom32 does not use this syscall.  Instead we rely
20901 + * on do_rt_sigreturn().
20902 + */
20903 +asmlinkage long sys_sigreturn(void)
20904 +{
20905 +       return -ENOSYS;
20906 +}
20907 --- /dev/null
20908 +++ b/arch/ubicom32/kernel/smp.c
20909 @@ -0,0 +1,808 @@
20910 +/*
20911 + * arch/ubicom32/kernel/smp.c
20912 + *   SMP implementation for Ubicom32 processors.
20913 + *
20914 + * (C) Copyright 2009, Ubicom, Inc.
20915 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
20916 + * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
20917 + * Copyright (C) 2001,2004 Grant Grundler <grundler@parisc-linux.org>
20918 + *
20919 + * This file is part of the Ubicom32 Linux Kernel Port.
20920 + *
20921 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20922 + * it and/or modify it under the terms of the GNU General Public License
20923 + * as published by the Free Software Foundation, either version 2 of the
20924 + * License, or (at your option) any later version.
20925 + *
20926 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20927 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20928 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20929 + * the GNU General Public License for more details.
20930 + *
20931 + * You should have received a copy of the GNU General Public License
20932 + * along with the Ubicom32 Linux Kernel Port.  If not,
20933 + * see <http://www.gnu.org/licenses/>.
20934 + *
20935 + * Ubicom32 implementation derived from (with many thanks):
20936 + *   arch/m68knommu
20937 + *   arch/blackfin
20938 + *   arch/parisc
20939 + */
20940 +
20941 +#include <linux/types.h>
20942 +#include <linux/spinlock.h>
20943 +#include <linux/slab.h>
20944 +
20945 +#include <linux/kernel.h>
20946 +#include <linux/bootmem.h>
20947 +#include <linux/module.h>
20948 +#include <linux/sched.h>
20949 +#include <linux/init.h>
20950 +#include <linux/interrupt.h>
20951 +#include <linux/smp.h>
20952 +#include <linux/kernel_stat.h>
20953 +#include <linux/mm.h>
20954 +#include <linux/err.h>
20955 +#include <linux/delay.h>
20956 +#include <linux/bitops.h>
20957 +#include <linux/cpu.h>
20958 +#include <linux/profile.h>
20959 +#include <linux/delay.h>
20960 +#include <linux/io.h>
20961 +#include <linux/ptrace.h>
20962 +#include <linux/unistd.h>
20963 +#include <linux/irq.h>
20964 +
20965 +#include <asm/system.h>
20966 +#include <asm/atomic.h>
20967 +#include <asm/current.h>
20968 +#include <asm/tlbflush.h>
20969 +#include <asm/timex.h>
20970 +#include <asm/cpu.h>
20971 +#include <asm/irq.h>
20972 +#include <asm/processor.h>
20973 +#include <asm/thread.h>
20974 +#include <asm/sections.h>
20975 +#include <asm/ip5000.h>
20976 +
20977 +/*
20978 + * Mask the debug printout for IPI because they are too verbose
20979 + * for regular debugging.
20980 + */
20981 +
20982 +// #define DEBUG_SMP 1
20983 +#if !defined(DEBUG_SMP)
20984 +#define smp_debug(lvl, ...)
20985 +#else
20986 +static unsigned int smp_debug_lvl = 50;
20987 +#define smp_debug(lvl, printargs...)           \
20988 +       if (lvl >= smp_debug_lvl) {             \
20989 +                       printk(printargs);      \
20990 +       }
20991 +#endif
20992 +
20993 +#if !defined(DEBUG_SMP)
20994 +#define DEBUG_ASSERT(cond)
20995 +#else
20996 +#define DEBUG_ASSERT(cond) \
20997 +       if (!(cond)) { \
20998 +               THREAD_STALL; \
20999 +       }
21000 +#endif
21001 +
21002 +/*
21003 + * List of IPI Commands (more than one can be set at a time).
21004 + */
21005 +enum ipi_message_type {
21006 +       IPI_NOP,
21007 +       IPI_RESCHEDULE,
21008 +       IPI_CALL_FUNC,
21009 +       IPI_CALL_FUNC_SINGLE,
21010 +       IPI_CPU_STOP,
21011 +       IPI_CPU_TIMER,
21012 +};
21013 +
21014 +/*
21015 + * These values are properly adjusted by smp_prepare_cpus() below.  They are
21016 + * required to be declared in the arch directory if CONFIG_SMP is set.
21017 + */
21018 +cpumask_t cpu_online_map = CPU_MASK_NONE;  /* Bitmap of online CPUs */
21019 +EXPORT_SYMBOL(cpu_online_map);
21020 +
21021 +cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */
21022 +EXPORT_SYMBOL(cpu_possible_map);
21023 +
21024 +/*
21025 + * We maintain a hardware thread oriented view of online threads
21026 + * and those involved or needing IPI.
21027 + */
21028 +static unsigned long smp_online_threads = 0;
21029 +static unsigned long smp_needs_ipi = 0;
21030 +static unsigned long smp_inside_ipi = 0;
21031 +static unsigned long smp_irq_affinity[NR_IRQS];
21032 +
21033 +/*
21034 + * What do we need to track on a per cpu/thread basis?
21035 + */
21036 +DEFINE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
21037 +
21038 +/*
21039 + * Each thread cpuinfo IPI information is guarded by a lock
21040 + * that is kept local to this file.
21041 + */
21042 +DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
21043 +
21044 +/*
21045 + * The IPI(s) are based on a software IRQ through the LDSR.
21046 + */
21047 +unsigned int smp_ipi_irq;
21048 +
21049 +/*
21050 + * Define a spinlock so that only one cpu is able to modify the
21051 + * smp_needs_ipi and to set/clear the IRQ at a time.
21052 + */
21053 +DEFINE_SPINLOCK(smp_ipi_lock);
21054 +
21055 +/*
21056 + * smp_halt_processor()
21057 + *     Halt this hardware thread.
21058 + */
21059 +static void smp_halt_processor(void)
21060 +{
21061 +       int cpuid = thread_get_self();
21062 +       cpu_clear(smp_processor_id(), cpu_online_map);
21063 +       local_irq_disable();
21064 +       printk(KERN_EMERG "cpu[%d] has halted. It is not OK to turn off power \
21065 +               until all cpu's are off.\n", cpuid);
21066 +       for (;;) {
21067 +               thread_suspend();
21068 +       }
21069 +}
21070 +
21071 +/*
21072 + * ipi_interrupt()
21073 + *     Handle an Interprocessor Interrupt.
21074 + */
21075 +static irqreturn_t ipi_interrupt(int irq, void *dev_id)
21076 +{
21077 +       int cpuid = smp_processor_id();
21078 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21079 +       unsigned long ops;
21080 +
21081 +       /*
21082 +        * Count this now; we may make a call that never returns.
21083 +        */
21084 +       p->ipi_count++;
21085 +
21086 +       /*
21087 +        * We are about to process all ops.  If another cpu has stated
21088 +        * that we need an IPI, we will have already processed it.  By
21089 +        * clearing our smp_needs_ipi, and processing all ops,
21090 +        * we reduce the number of IPI interrupts.  However, this introduces
21091 +        * the possibility that smp_needs_ipi will be clear and the soft irq
21092 +        * will have gone off; so we need to make the get_affinity() path
21093 +        * tolerant of spurious interrupts.
21094 +        */
21095 +       spin_lock(&smp_ipi_lock);
21096 +       smp_needs_ipi &= ~p->tid;
21097 +       spin_unlock(&smp_ipi_lock);
21098 +
21099 +       for (;;) {
21100 +               /*
21101 +                * Read the set of IPI commands we should handle.
21102 +                */
21103 +               spinlock_t *lock = &per_cpu(ipi_lock, cpuid);
21104 +               spin_lock(lock);
21105 +               ops = p->ipi_pending;
21106 +               p->ipi_pending = 0;
21107 +               spin_unlock(lock);
21108 +
21109 +               /*
21110 +                * If we have no IPI commands to execute, break out.
21111 +                */
21112 +               if (!ops) {
21113 +                       break;
21114 +               }
21115 +
21116 +               /*
21117 +                * Execute the set of commands in the ops word, one command
21118 +                * at a time in no particular order.  Strip of each command
21119 +                * as we execute it.
21120 +                */
21121 +               while (ops) {
21122 +                       unsigned long which = ffz(~ops);
21123 +                       ops &= ~(1 << which);
21124 +
21125 +                       BUG_ON(!irqs_disabled());
21126 +                       switch (which) {
21127 +                       case IPI_NOP:
21128 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21129 +                                         "IPI_NOP\n", cpuid);
21130 +                               break;
21131 +
21132 +                       case IPI_RESCHEDULE:
21133 +                               /*
21134 +                                * Reschedule callback.  Everything to be
21135 +                                * done is done by the interrupt return path.
21136 +                                */
21137 +                               smp_debug(200, KERN_INFO "cpu[%d]: "
21138 +                                         "IPI_RESCHEDULE\n", cpuid);
21139 +                               break;
21140 +
21141 +                       case IPI_CALL_FUNC:
21142 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21143 +                                         "IPI_CALL_FUNC\n", cpuid);
21144 +                               generic_smp_call_function_interrupt();
21145 +                               break;
21146 +
21147 +                       case IPI_CALL_FUNC_SINGLE:
21148 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21149 +                                         "IPI_CALL_FUNC_SINGLE\n", cpuid);
21150 +                               generic_smp_call_function_single_interrupt();
21151 +                               break;
21152 +
21153 +                       case IPI_CPU_STOP:
21154 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21155 +                                         "IPI_CPU_STOP\n", cpuid);
21156 +                               smp_halt_processor();
21157 +                               break;
21158 +
21159 +#if !defined(CONFIG_LOCAL_TIMERS)
21160 +                       case IPI_CPU_TIMER:
21161 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21162 +                                         "IPI_CPU_TIMER\n", cpuid);
21163 +#if defined(CONFIG_GENERIC_CLOCKEVENTS)
21164 +                               local_timer_interrupt();
21165 +#else
21166 +                               update_process_times(user_mode(get_irq_regs()));
21167 +                               profile_tick(CPU_PROFILING);
21168 +#endif
21169 +#endif
21170 +                               break;
21171 +
21172 +                       default:
21173 +                               printk(KERN_CRIT "cpu[%d]: "
21174 +                                         "Unknown IPI: %lu\n", cpuid, which);
21175 +
21176 +                               return IRQ_NONE;
21177 +                       }
21178 +
21179 +                       /*
21180 +                        * Let in any pending interrupts
21181 +                        */
21182 +                       BUG_ON(!irqs_disabled());
21183 +                       local_irq_enable();
21184 +                       local_irq_disable();
21185 +               }
21186 +       }
21187 +       return IRQ_HANDLED;
21188 +}
21189 +
21190 +/*
21191 + * ipi_send()
21192 + *     Send an Interprocessor Interrupt.
21193 + */
21194 +static void ipi_send(int cpu, enum ipi_message_type op)
21195 +{
21196 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21197 +       spinlock_t *lock = &per_cpu(ipi_lock, cpu);
21198 +       unsigned long flags;
21199 +
21200 +       /*
21201 +        * We protect the setting of the ipi_pending field and ensure
21202 +        * that the ipi delivery mechanism and interrupt are atomically
21203 +        * handled.
21204 +        */
21205 +       spin_lock_irqsave(lock, flags);
21206 +       p->ipi_pending |= 1 << op;
21207 +       spin_unlock_irqrestore(lock, flags);
21208 +
21209 +       spin_lock_irqsave(&smp_ipi_lock, flags);
21210 +       smp_needs_ipi |= (1 << p->tid);
21211 +       ubicom32_set_interrupt(smp_ipi_irq);
21212 +       spin_unlock_irqrestore(&smp_ipi_lock, flags);
21213 +}
21214 +
21215 +/*
21216 + * ipi_send_mask
21217 + *     Send an IPI to each cpu in mask.
21218 + */
21219 +static inline void ipi_send_mask(unsigned int op, cpumask_t mask)
21220 +{
21221 +       int cpu;
21222 +       for_each_cpu_mask(cpu, mask) {
21223 +               ipi_send(cpu, op);
21224 +       }
21225 +}
21226 +
21227 +/*
21228 + * ipi_send_allbutself()
21229 + *     Send an IPI to all threads but ourselves.
21230 + */
21231 +static inline void ipi_send_allbutself(unsigned int op)
21232 +{
21233 +       int self = smp_processor_id();
21234 +       cpumask_t result = cpu_online_map;
21235 +       cpu_clear(self, result);
21236 +       ipi_send_mask(op, result);
21237 +}
21238 +
21239 +/*
21240 + * smp_enable_vector()
21241 + */
21242 +static void smp_enable_vector(unsigned int irq)
21243 +{
21244 +       ubicom32_clear_interrupt(smp_ipi_irq);
21245 +       ldsr_enable_vector(irq);
21246 +}
21247 +
21248 +/*
21249 + * smp_disable_vector()
21250 + *     Disable the interrupt by clearing the appropriate bit in the
21251 + *     LDSR Mask Register.
21252 + */
21253 +static void smp_disable_vector(unsigned int irq)
21254 +{
21255 +       ldsr_disable_vector(irq);
21256 +}
21257 +
21258 +/*
21259 + * smp_mask_vector()
21260 + */
21261 +static void smp_mask_vector(unsigned int irq)
21262 +{
21263 +       ldsr_mask_vector(irq);
21264 +}
21265 +
21266 +/*
21267 + * smp_unmask_vector()
21268 + */
21269 +static void smp_unmask_vector(unsigned int irq)
21270 +{
21271 +       ldsr_unmask_vector(irq);
21272 +}
21273 +
21274 +/*
21275 + * smp_end_vector()
21276 + *     Called once an interrupt is completed (reset the LDSR mask).
21277 + */
21278 +static void smp_end_vector(unsigned int irq)
21279 +{
21280 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, smp_processor_id());
21281 +       spin_lock(&smp_ipi_lock);
21282 +       smp_inside_ipi &= ~(1 << p->tid);
21283 +       if (smp_inside_ipi) {
21284 +               spin_unlock(&smp_ipi_lock);
21285 +               return;
21286 +       }
21287 +       spin_unlock(&smp_ipi_lock);
21288 +       ldsr_unmask_vector(irq);
21289 +}
21290 +
21291 +/*
21292 + * Special hanlder functions for SMP.
21293 + */
21294 +static struct irq_chip ubicom32_smp_chip = {
21295 +       .name           = "UbicoIPI",
21296 +       .startup        = NULL,
21297 +       .shutdown       = NULL,
21298 +       .enable         = smp_enable_vector,
21299 +       .disable        = smp_disable_vector,
21300 +       .ack            = NULL,
21301 +       .mask           = smp_mask_vector,
21302 +       .unmask         = smp_unmask_vector,
21303 +       .end            = smp_end_vector,
21304 +};
21305 +
21306 +/*
21307 + * smp_reset_ipi()
21308 + *     None of these cpu(s) got their IPI, turn it back on.
21309 + *
21310 + * Note: This is called by the LDSR which is not a full
21311 + * Linux cpu.  Thus you must use the raw form of locks
21312 + * because lock debugging will not work on the partial
21313 + * cpu nature of the LDSR.
21314 + */
21315 +void smp_reset_ipi(unsigned long mask)
21316 +{
21317 +       __raw_spin_lock(&smp_ipi_lock.raw_lock);
21318 +       smp_needs_ipi |= mask;
21319 +       smp_inside_ipi &= ~mask;
21320 +       ubicom32_set_interrupt(smp_ipi_irq);
21321 +       __raw_spin_unlock(&smp_ipi_lock.raw_lock);
21322 +}
21323 +
21324 +/*
21325 + * smp_get_affinity()
21326 + *     Choose the thread affinity for this interrupt.
21327 + *
21328 + * Note: This is called by the LDSR which is not a full
21329 + * Linux cpu.  Thus you must use the raw form of locks
21330 + * because lock debugging will not work on the partial
21331 + * cpu nature of the LDSR.
21332 + */
21333 +unsigned long smp_get_affinity(unsigned int irq, int *all)
21334 +{
21335 +       unsigned long mask = 0;
21336 +
21337 +       /*
21338 +        * Most IRQ(s) are delivered in a round robin fashion.
21339 +        */
21340 +       if (irq != smp_ipi_irq) {
21341 +               unsigned long result = smp_irq_affinity[irq] & smp_online_threads;
21342 +               DEBUG_ASSERT(result);
21343 +               *all = 0;
21344 +               return result;
21345 +       }
21346 +
21347 +       /*
21348 +        * This is an IPI request.  Return all cpu(s) scheduled for an IPI.
21349 +        * We also track those cpu(s) that are going to be "receiving" IPI this
21350 +        * round.  When all CPU(s) have called smp_end_vector(),
21351 +        * we will unmask the IPI interrupt.
21352 +        */
21353 +       __raw_spin_lock(&smp_ipi_lock.raw_lock);
21354 +       ubicom32_clear_interrupt(smp_ipi_irq);
21355 +       if (smp_needs_ipi) {
21356 +               mask = smp_needs_ipi;
21357 +               smp_inside_ipi |= smp_needs_ipi;
21358 +               smp_needs_ipi = 0;
21359 +       }
21360 +       __raw_spin_unlock(&smp_ipi_lock.raw_lock);
21361 +       *all = 1;
21362 +       return mask;
21363 +}
21364 +
21365 +/*
21366 + *  smp_set_affinity()
21367 + *     Set the affinity for this irq but store the value in tid(s).
21368 + */
21369 +void smp_set_affinity(unsigned int irq, cpumask_t dest)
21370 +{
21371 +       int cpuid;
21372 +       unsigned long *paffinity = &smp_irq_affinity[irq];
21373 +
21374 +       /*
21375 +        *  If none specified, all cpus are allowed.
21376 +        */
21377 +       if (cpus_empty(dest)) {
21378 +               *paffinity = 0xffffffff;
21379 +               return;
21380 +       }
21381 +
21382 +       /*
21383 +        * Make sure to clear the old value before setting up the
21384 +        * list.
21385 +        */
21386 +       *paffinity = 0;
21387 +       for_each_cpu_mask(cpuid, dest) {
21388 +               struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21389 +               *paffinity |= (1 << p->tid);
21390 +       }
21391 +}
21392 +
21393 +/*
21394 + * smp_send_stop()
21395 + *     Send a stop request to all CPU but this one.
21396 + */
21397 +void smp_send_stop(void)
21398 +{
21399 +       ipi_send_allbutself(IPI_CPU_STOP);
21400 +}
21401 +
21402 +/*
21403 + * smp_send_timer_all()
21404 + *     Send all cpu(s) but this one, a request to update times.
21405 + */
21406 +void smp_send_timer_all(void)
21407 +{
21408 +       ipi_send_allbutself(IPI_CPU_TIMER);
21409 +}
21410 +
21411 +/*
21412 + * smp_timer_broadcast()
21413 + *     Use an IPI to broadcast a timer message
21414 + */
21415 +void smp_timer_broadcast(cpumask_t mask)
21416 +{
21417 +       ipi_send_mask(IPI_CPU_TIMER, mask);
21418 +}
21419 +
21420 +/*
21421 + * smp_send_reschedule()
21422 + *     Send a reschedule request to the specified cpu.
21423 + */
21424 +void smp_send_reschedule(int cpu)
21425 +{
21426 +       ipi_send(cpu, IPI_RESCHEDULE);
21427 +}
21428 +
21429 +/*
21430 + * arch_send_call_function_ipi()
21431 + *     Cause each cpu in the mask to call the generic function handler.
21432 + */
21433 +void arch_send_call_function_ipi(cpumask_t mask)
21434 +{
21435 +       int cpu;
21436 +       for_each_cpu_mask(cpu, mask) {
21437 +               ipi_send(cpu, IPI_CALL_FUNC);
21438 +       }
21439 +}
21440 +
21441 +/*
21442 + * arch_send_call_function_single_ipi()
21443 + *     Cause the specified cpu to call the generic function handler.
21444 + */
21445 +void arch_send_call_function_single_ipi(int cpu)
21446 +{
21447 +       ipi_send(cpu, IPI_CALL_FUNC_SINGLE);
21448 +}
21449 +
21450 +/*
21451 + * smp_mainline_start()
21452 + *     Start a slave thread executing a mainline Linux context.
21453 + */
21454 +static void __init smp_mainline_start(void *arg)
21455 +{
21456 +       int cpuid = smp_processor_id();
21457 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21458 +
21459 +       BUG_ON(p->tid != thread_get_self());
21460 +
21461 +       /*
21462 +        * Well, support 2.4 linux scheme as well.
21463 +        */
21464 +       if (cpu_test_and_set(cpuid, cpu_online_map)) {
21465 +               printk(KERN_CRIT "cpu[%d]: already initialized!\n", cpuid);
21466 +               smp_halt_processor();
21467 +               return;
21468 +       }
21469 +
21470 +       /*
21471 +        * Initialise the idle task for this CPU
21472 +        */
21473 +       atomic_inc(&init_mm.mm_count);
21474 +       current->active_mm = &init_mm;
21475 +       if (current->mm) {
21476 +               printk(KERN_CRIT "cpu[%d]: idle task already has memory "
21477 +                      "management\n", cpuid);
21478 +               smp_halt_processor();
21479 +               return;
21480 +       }
21481 +
21482 +       /*
21483 +        * TODO: X86 does this prior to calling notify, try to understand why?
21484 +        */
21485 +       preempt_disable();
21486 +
21487 +#if defined(CONFIG_GENERIC_CLOCKEVENTS)
21488 +       /*
21489 +        * Setup a local timer event so that this cpu will get timer interrupts
21490 +        */
21491 +       if (local_timer_setup(cpuid) == -1) {
21492 +               printk(KERN_CRIT "cpu[%d]: timer alloc failed\n", cpuid);
21493 +               smp_halt_processor();
21494 +               return;
21495 +       }
21496 +#endif
21497 +
21498 +       /*
21499 +        * Notify those interested that we are up and alive.  This must
21500 +        * be done before interrupts are enabled.  It must also be completed
21501 +        * before the bootstrap cpu returns from __cpu_up() (see comment
21502 +        * above cpu_set() of the cpu_online_map).
21503 +        */
21504 +       notify_cpu_starting(cpuid);
21505 +
21506 +       /*
21507 +        * Indicate that this thread is now online and present.   Setting
21508 +        * cpu_online_map has the side effect of allowing the bootstrap
21509 +        * cpu to continue along; so anything that MUST be done prior to the
21510 +        * bootstrap cpu returning from __cpu_up() needs to go above here.
21511 +        */
21512 +       cpu_set(cpuid, cpu_online_map);
21513 +       cpu_set(cpuid, cpu_present_map);
21514 +
21515 +       /*
21516 +        * Maintain a thread mapping in addition to the cpu mapping.
21517 +        */
21518 +       smp_online_threads |= (1 << p->tid);
21519 +
21520 +       /*
21521 +        * Enable interrupts for this thread.
21522 +        */
21523 +       local_irq_enable();
21524 +
21525 +       /*
21526 +        * Enter the idle loop and wait for a timer to schedule some work.
21527 +        */
21528 +       printk(KERN_INFO "cpu[%d]: entering cpu_idle()\n", cpuid);
21529 +       cpu_idle();
21530 +
21531 +       /* Not Reached */
21532 +}
21533 +
21534 +/*
21535 + * smp_cpus_done()
21536 + *     Called once the kernel_init() has brought up all cpu(s).
21537 + */
21538 +void smp_cpus_done(unsigned int cpu_max)
21539 +{
21540 +       /* Do Nothing */
21541 +}
21542 +
21543 +/*
21544 + * __cpu_up()
21545 + *     Called to startup a sepcific cpu.
21546 + */
21547 +int __cpuinit __cpu_up(unsigned int cpu)
21548 +{
21549 +       struct task_struct *idle;
21550 +       unsigned int *stack;
21551 +       long timeout;
21552 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21553 +
21554 +       /*
21555 +        * Create an idle task for this CPU.
21556 +        */
21557 +       idle = fork_idle(cpu);
21558 +       if (IS_ERR(idle)) {
21559 +               panic("cpu[%d]: fork failed\n", cpu);
21560 +               return -ENOSYS;
21561 +       }
21562 +       task_thread_info(idle)->cpu = cpu;
21563 +
21564 +       /*
21565 +        * Setup the sw_ksp[] to point to this new task.
21566 +        */
21567 +       sw_ksp[p->tid] = (unsigned int)idle->stack;
21568 +       stack = (unsigned int *)(sw_ksp[p->tid] + PAGE_SIZE - 8);
21569 +
21570 +       /*
21571 +        * Cause the specified thread to execute our smp_mainline_start
21572 +        * function as a TYPE_NORMAL thread.
21573 +        */
21574 +       printk(KERN_INFO "cpu[%d]: launching mainline Linux thread\n", cpu);
21575 +       if (thread_start(p->tid, smp_mainline_start, (void *)NULL, stack,
21576 +                        THREAD_TYPE_NORMAL) == -1) {
21577 +               printk(KERN_WARNING "cpu[%d]: failed thread_start\n", cpu);
21578 +               return -ENOSYS;
21579 +       }
21580 +
21581 +       /*
21582 +        * Wait for the thread to start up.  The thread will set
21583 +        * the online bit when it is running.  Our caller execpts the
21584 +        * cpu to be online if we return 0.
21585 +        */
21586 +       for (timeout = 0; timeout < 10000; timeout++) {
21587 +               if (cpu_online(cpu)) {
21588 +                       break;
21589 +               }
21590 +
21591 +               udelay(100);
21592 +               barrier();
21593 +               continue;
21594 +       }
21595 +
21596 +       if (!cpu_online(cpu)) {
21597 +               printk(KERN_CRIT "cpu[%d]: failed to live after %ld us\n",
21598 +                      cpu, timeout * 100);
21599 +               return -ENOSYS;
21600 +       }
21601 +
21602 +       printk(KERN_INFO "cpu[%d]: came alive after %ld us\n",
21603 +              cpu, timeout * 100);
21604 +       return 0;
21605 +}
21606 +
21607 +/*
21608 + * Data used by setup_irq for the IPI.
21609 + */
21610 +static struct irqaction ipi_irq = {
21611 +       .name    = "ipi",
21612 +       .flags   = IRQF_DISABLED | IRQF_PERCPU,
21613 +       .handler = ipi_interrupt,
21614 +};
21615 +
21616 +/*
21617 + * smp_prepare_cpus()
21618 + *     Mark threads that are available to Linux as possible cpus(s).
21619 + */
21620 +void __init smp_prepare_cpus(unsigned int max_cpus)
21621 +{
21622 +       int i;
21623 +
21624 +       /*
21625 +        * We will need a software IRQ to send IPI(s).  We will use
21626 +        * a single software IRQ for all IPI(s).
21627 +        */
21628 +       if (irq_soft_alloc(&smp_ipi_irq) < 0) {
21629 +               panic("no software IRQ is available\n");
21630 +               return;
21631 +       }
21632 +
21633 +       /*
21634 +        * For the IPI interrupt, we want to use our own chip definition.
21635 +        * This allows us to define what happens in SMP IPI without affecting
21636 +        * the performance of the other interrupts.
21637 +        *
21638 +        * Next, Register the IPI interrupt function against the soft IRQ.
21639 +        */
21640 +       set_irq_chip(smp_ipi_irq, &ubicom32_smp_chip);
21641 +       setup_irq(smp_ipi_irq, &ipi_irq);
21642 +
21643 +       /*
21644 +        * We use the device tree node to determine how many
21645 +        * free cpus we will have (up to NR_CPUS) and we indicate
21646 +        * that those cpus are present.
21647 +        *
21648 +        * We need to do this very early in the SMP case
21649 +        * because the Linux init code uses the cpu_present_map.
21650 +        */
21651 +       for_each_possible_cpu(i) {
21652 +               thread_t tid;
21653 +               struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, i);
21654 +
21655 +               /*
21656 +                *  Skip the bootstrap cpu
21657 +                */
21658 +               if (i == 0) {
21659 +                       continue;
21660 +               }
21661 +
21662 +               /*
21663 +                * If we have a free thread left in the mask,
21664 +                * indicate that the cpu is present.
21665 +                */
21666 +               tid = thread_alloc();
21667 +               if (tid == (thread_t)-1) {
21668 +                       break;
21669 +               }
21670 +
21671 +               /*
21672 +                * Save the hardware thread id for this cpu.
21673 +                */
21674 +               p->tid = tid;
21675 +               cpu_set(i, cpu_present_map);
21676 +               printk(KERN_INFO "cpu[%d]: added to cpu_present_map - tid: %d\n", i, tid);
21677 +       }
21678 +}
21679 +
21680 +/*
21681 + * smp_prepare_boot_cpu()
21682 + *     Copy the per_cpu data into the appropriate spot for the bootstrap cpu.
21683 + *
21684 + * The code in boot_cpu_init() has already set the boot cpu's
21685 + * state in the possible, present, and online maps.
21686 + */
21687 +void __devinit smp_prepare_boot_cpu(void)
21688 +{
21689 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
21690 +
21691 +       smp_online_threads |= (1 << p->tid);
21692 +       printk(KERN_INFO "cpu[%d]: bootstrap CPU online - tid: %ld\n",
21693 +                       current_thread_info()->cpu, p->tid);
21694 +}
21695 +
21696 +/*
21697 + * smp_setup_processor_id()
21698 + *     Set the current_thread_info() structure cpu value.
21699 + *
21700 + * We set the value to the true hardware thread value that we are running on.
21701 + * NOTE: this function overrides the weak alias function in main.c
21702 + */
21703 +void __init smp_setup_processor_id(void)
21704 +{
21705 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
21706 +       current_thread_info()->cpu = 0;
21707 +       p->tid = thread_get_self();
21708 +}
21709 +
21710 +/*
21711 + * setup_profiling_timer()
21712 + *     Dummy function created to keep Oprofile happy in the SMP case.
21713 + */
21714 +int setup_profiling_timer(unsigned int multiplier)
21715 +{
21716 +       return 0;
21717 +}
21718 --- /dev/null
21719 +++ b/arch/ubicom32/kernel/stacktrace.c
21720 @@ -0,0 +1,243 @@
21721 +/*
21722 + * arch/ubicom32/kernel/stacktrace.c
21723 + *   Ubicom32 architecture stack back trace implementation.
21724 + *
21725 + * (C) Copyright 2009, Ubicom, Inc.
21726 + *
21727 + * This file is part of the Ubicom32 Linux Kernel Port.
21728 + *
21729 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
21730 + * it and/or modify it under the terms of the GNU General Public License
21731 + * as published by the Free Software Foundation, either version 2 of the
21732 + * License, or (at your option) any later version.
21733 + *
21734 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21735 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
21736 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
21737 + * the GNU General Public License for more details.
21738 + *
21739 + * You should have received a copy of the GNU General Public License
21740 + * along with the Ubicom32 Linux Kernel Port.  If not,
21741 + * see <http://www.gnu.org/licenses/>.
21742 + *
21743 + * Ubicom32 implementation derived from (with many thanks):
21744 + *   arch/m68knommu
21745 + *   arch/blackfin
21746 + *   arch/parisc
21747 + */
21748 +#include <linux/sched.h>
21749 +#include <linux/stacktrace.h>
21750 +#include <linux/module.h>
21751 +#include <asm/stacktrace.h>
21752 +#include <asm/thread.h>
21753 +
21754 +/*
21755 + * These symbols are filled in by the linker.
21756 + */
21757 +extern unsigned long _stext;
21758 +extern unsigned long _etext;
21759 +
21760 +extern unsigned long __ocm_text_run_begin;
21761 +extern unsigned long __data_begin;
21762 +
21763 +/*
21764 + * stacktrace_iterate()
21765 + *     Walk the stack looking for call and calli instructions on an aligned
21766 + *     boundary.
21767 + *
21768 + * Trace must point to the top of the current stack frame.
21769 + */
21770 +unsigned long stacktrace_iterate(unsigned long **trace,
21771 +                                unsigned long stext,
21772 +                                unsigned long etext,
21773 +                                unsigned long ocm_stext,
21774 +                                unsigned long ocm_etext,
21775 +                                unsigned long sstack,
21776 +                                unsigned long estack)
21777 +{
21778 +       unsigned int thread_trap_en, instruction;
21779 +       unsigned long address;
21780 +       unsigned int limit = 0;
21781 +       unsigned long result = 0;
21782 +       unsigned long *sp = *trace;
21783 +
21784 +       /*
21785 +        * Exclude the current thread from being monitored for traps.
21786 +        */
21787 +       asm volatile(
21788 +               "       thread_get_self_mask d15                \n\t"
21789 +                       /* save current trap status */
21790 +               "       and.4   %0, MT_TRAP_EN, d15             \n\t"
21791 +               "       not.4   d15, d15                        \n\t"
21792 +                       /* disable trap */
21793 +               "       and.4   MT_TRAP_EN, MT_TRAP_EN, d15     \n\t"
21794 +               "       pipe_flush 0                            \n\t"
21795 +               : "=r" (thread_trap_en)
21796 +               :
21797 +               : "d15", "cc"
21798 +       );
21799 +
21800 +       while (limit++ < 256) {
21801 +               /*
21802 +                * See if we have a valid stack.
21803 +                */
21804 +               if (!between((unsigned long)sp, sstack, estack)) {
21805 +#ifdef TRAP_DEBUG_STACK_TRACE
21806 +                       printk(KERN_EMERG "stack address is out of range - "
21807 +                              "sp: %x, sstack: %x, estack: %x\n",
21808 +                              (unsigned int)sp, (unsigned int)sstack,
21809 +                              (unsigned int)estack);
21810 +#endif
21811 +                       result = 0;
21812 +                       *trace = 0;
21813 +                       break;
21814 +               }
21815 +
21816 +               /*
21817 +                * Get the value off the stack and back up 4 bytes to what
21818 +                * should be the address of a call or calli.
21819 +                */
21820 +               address = (*sp++) - 4;
21821 +
21822 +               /*
21823 +                * If the address is not within the text segment, skip this
21824 +                * value.
21825 +                */
21826 +               if (!between(address, stext, etext) &&
21827 +                   !between(address, ocm_stext, ocm_etext)) {
21828 +#ifdef TRAP_DEBUG_STACK_TRACE
21829 +                       printk(KERN_EMERG "not a text address - "
21830 +                              "address: %08x, stext: %08x, etext: %08x\n"
21831 +                              "ocm_stext: %08x, ocm_etext: %08x\n",
21832 +                              (unsigned int)address,
21833 +                              (unsigned int)stext,
21834 +                              (unsigned int)etext,
21835 +                              (unsigned int)ocm_stext,
21836 +                              (unsigned int)ocm_etext);
21837 +#endif
21838 +                       continue;
21839 +
21840 +               }
21841 +
21842 +               /*
21843 +                * If the address is not on an aligned boundary it can not be a
21844 +                * return address.
21845 +                */
21846 +               if (address & 0x3) {
21847 +                       continue;
21848 +               }
21849 +
21850 +               /*
21851 +                * Read the probable instruction.
21852 +                */
21853 +               instruction = *(unsigned int *)address;
21854 +
21855 +               /*
21856 +                * Is this a call instruction?
21857 +                */
21858 +               if ((instruction & 0xF8000000) == (u32_t)(0x1B << 27)) {
21859 +#ifdef TRAP_DEBUG_STACK_TRACE
21860 +                       printk(KERN_EMERG "call inst. result: %x, "
21861 +                              "test: %x\n", (unsigned int)address,
21862 +                              (unsigned int)instruction);
21863 +#endif
21864 +                       *trace = sp;
21865 +                       result = address;
21866 +                       break;
21867 +               }
21868 +
21869 +               /*
21870 +                * Is this a calli instruction?
21871 +                */
21872 +               if ((instruction & 0xF8000000) == (u32_t)(0x1E << 27)) {
21873 +#ifdef TRAP_DEBUG_STACK_TRACE
21874 +                       printk(KERN_EMERG "calli inst. result: %x, "
21875 +                              "test: %x\n", (unsigned int)address,
21876 +                              (unsigned int)instruction);
21877 +#endif
21878 +                       *trace = sp;
21879 +                       result = address;
21880 +                       break;
21881 +               }
21882 +       }
21883 +
21884 +       /*
21885 +        * Restore the current thread to be monitored for traps.
21886 +        */
21887 +       if (thread_trap_en) {
21888 +               asm volatile(
21889 +               "       thread_get_self_mask d15                \n\t"
21890 +               "       or.4    MT_TRAP_EN, MT_TRAP_EN, d15     \n\t"
21891 +                       :
21892 +                       :
21893 +                       : "d15", "cc"
21894 +               );
21895 +       }
21896 +       return result;
21897 +}
21898 +
21899 +#ifdef CONFIG_STACKTRACE
21900 +/*
21901 + * stacktrace_save_entries()
21902 + *     Save stack back trace information into the provided trace structure.
21903 + */
21904 +void stacktrace_save_entries(struct task_struct *tsk,
21905 +                            struct stack_trace *trace,
21906 +                            unsigned long sp)
21907 +{
21908 +       unsigned long code_start = (unsigned long)&_stext;
21909 +       unsigned long code_end = (unsigned long)&_etext;
21910 +       unsigned long ocm_code_start = (unsigned long)&__ocm_text_run_begin;
21911 +       unsigned long ocm_code_end = (unsigned long)&__data_begin;
21912 +       unsigned long stack_end = (unsigned long)(tsk->stack + THREAD_SIZE - 8);
21913 +       unsigned long stack = (unsigned long)sp;
21914 +       unsigned int idx = 0;
21915 +       unsigned long *handle;
21916 +       int skip = trace->skip;
21917 +
21918 +       handle = (unsigned long *)stack;
21919 +       while (idx < trace->max_entries) {
21920 +               if (skip) {
21921 +                       skip--;
21922 +                       continue;
21923 +               }
21924 +               trace->entries[idx] = stacktrace_iterate(&handle,
21925 +                                       code_start, code_end,
21926 +                                       ocm_code_start, ocm_code_end,
21927 +                                       (unsigned long)stack, stack_end);
21928 +               if (trace->entries[idx] == 0) {
21929 +                       break;
21930 +               }
21931 +               idx++;
21932 +       }
21933 +}
21934 +
21935 +/*
21936 + * save_stack_trace()
21937 + *     Save the specified amount of the kernel stack trace information
21938 + *     for the current task.
21939 + */
21940 +void save_stack_trace(struct stack_trace *trace)
21941 +{
21942 +       unsigned long sp = 0;
21943 +       asm volatile (
21944 +       "       move.4  %0, SP          \n\t"
21945 +               : "=r" (sp)
21946 +       );
21947 +       stacktrace_save_entries(current, trace, sp);
21948 +}
21949 +EXPORT_SYMBOL_GPL(save_stack_trace);
21950 +
21951 +/*
21952 + * save_stack_trace_tsk()
21953 + *     Save the specified amount of the kernel stack trace information
21954 + *     for the specified task.
21955 + *
21956 + * Note: We assume the specified task is not currently running.
21957 + */
21958 +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
21959 +{
21960 +       stacktrace_save_entries(tsk, trace, tsk->thread.sp);
21961 +}
21962 +EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
21963 +#endif /* CONFIG_STACKTRACE */
21964 --- /dev/null
21965 +++ b/arch/ubicom32/kernel/syscalltable.S
21966 @@ -0,0 +1,377 @@
21967 +/*
21968 + * arch/ubicom32/kernel/syscalltable.S
21969 + *     <TODO: Replace with short file description>
21970 + *
21971 + * (C) Copyright 2009, Ubicom, Inc.
21972 + *
21973 + * This file is part of the Ubicom32 Linux Kernel Port.
21974 + *
21975 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
21976 + * it and/or modify it under the terms of the GNU General Public License
21977 + * as published by the Free Software Foundation, either version 2 of the
21978 + * License, or (at your option) any later version.
21979 + *
21980 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21981 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
21982 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
21983 + * the GNU General Public License for more details.
21984 + *
21985 + * You should have received a copy of the GNU General Public License
21986 + * along with the Ubicom32 Linux Kernel Port.  If not, 
21987 + * see <http://www.gnu.org/licenses/>.
21988 + *
21989 + * Ubicom32 implementation derived from (with many thanks):
21990 + *   arch/m68knommu
21991 + *   arch/blackfin
21992 + *   arch/parisc
21993 + */
21994 +/*
21995 + *
21996 + *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
21997 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>, Kenneth Albanowski <kjahds@kjahds.com>,
21998 + *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
21999 + *  Copyright (C) 1991, 1992  Linus Torvalds
22000 + */
22001 +
22002 +#include <linux/sys.h>
22003 +#include <linux/linkage.h>
22004 +#include <asm/unistd.h>
22005 +
22006 +.text
22007 +ALIGN
22008 +       .global sys_call_table
22009 +sys_call_table:        
22010 +       .long sys_ni_syscall    /* 0  -  old "setup()" system call*/
22011 +       .long sys_exit
22012 +       .long sys_fork
22013 +       .long sys_read
22014 +       .long sys_write
22015 +       .long sys_open          /* 5 */
22016 +       .long sys_close
22017 +       .long sys_waitpid
22018 +       .long sys_creat
22019 +       .long sys_link
22020 +       .long sys_unlink        /* 10 */
22021 +       .long execve_intercept
22022 +       .long sys_chdir
22023 +       .long sys_time
22024 +       .long sys_mknod
22025 +       .long sys_chmod         /* 15 */
22026 +       .long sys_chown16
22027 +       .long sys_ni_syscall    /* old break syscall holder */
22028 +       .long sys_stat
22029 +       .long sys_lseek
22030 +       .long sys_getpid        /* 20 */
22031 +       .long sys_mount
22032 +       .long sys_oldumount
22033 +       .long sys_setuid16
22034 +       .long sys_getuid16
22035 +       .long sys_stime         /* 25 */
22036 +       .long sys_ptrace
22037 +       .long sys_alarm
22038 +       .long sys_fstat
22039 +       .long sys_pause
22040 +       .long sys_utime         /* 30 */
22041 +       .long sys_ni_syscall    /* old stty syscall holder */
22042 +       .long sys_ni_syscall    /* old gtty syscall holder */
22043 +       .long sys_access
22044 +       .long sys_nice
22045 +       .long sys_ni_syscall    /* 35 */ /* old ftime syscall holder */
22046 +       .long sys_sync
22047 +       .long sys_kill
22048 +       .long sys_rename
22049 +       .long sys_mkdir
22050 +       .long sys_rmdir         /* 40 */
22051 +       .long sys_dup
22052 +       .long sys_pipe
22053 +       .long sys_times
22054 +       .long sys_ni_syscall    /* old prof syscall holder */
22055 +       .long sys_brk           /* 45 */
22056 +       .long sys_setgid16
22057 +       .long sys_getgid16
22058 +       .long sys_signal
22059 +       .long sys_geteuid16
22060 +       .long sys_getegid16     /* 50 */
22061 +       .long sys_acct
22062 +       .long sys_umount        /* recycled never used phys() */
22063 +       .long sys_ni_syscall    /* old lock syscall holder */
22064 +       .long sys_ioctl
22065 +       .long sys_fcntl         /* 55 */
22066 +       .long sys_ni_syscall    /* old mpx syscall holder */
22067 +       .long sys_setpgid
22068 +       .long sys_ni_syscall    /* old ulimit syscall holder */
22069 +       .long sys_ni_syscall
22070 +       .long sys_umask         /* 60 */
22071 +       .long sys_chroot
22072 +       .long sys_ustat
22073 +       .long sys_dup2
22074 +       .long sys_getppid
22075 +       .long sys_getpgrp       /* 65 */
22076 +       .long sys_setsid
22077 +       .long sys_sigaction
22078 +       .long sys_sgetmask
22079 +       .long sys_ssetmask
22080 +       .long sys_setreuid16    /* 70 */
22081 +       .long sys_setregid16
22082 +       .long sys_sigsuspend
22083 +       .long sys_sigpending
22084 +       .long sys_sethostname
22085 +       .long sys_setrlimit     /* 75 */
22086 +       .long sys_old_getrlimit
22087 +       .long sys_getrusage
22088 +       .long sys_gettimeofday
22089 +       .long sys_settimeofday
22090 +       .long sys_getgroups16   /* 80 */
22091 +       .long sys_setgroups16
22092 +       .long old_select
22093 +       .long sys_symlink
22094 +       .long sys_lstat
22095 +       .long sys_readlink      /* 85 */
22096 +       .long sys_uselib
22097 +       .long sys_ni_syscall    /* _sys_swapon */
22098 +       .long sys_reboot
22099 +       .long sys_old_readdir
22100 +       .long old_mmap          /* 90 */
22101 +       .long sys_munmap
22102 +       .long sys_truncate
22103 +       .long sys_ftruncate
22104 +       .long sys_fchmod
22105 +       .long sys_fchown16      /* 95 */
22106 +       .long sys_getpriority
22107 +       .long sys_setpriority
22108 +       .long sys_ni_syscall    /* old profil syscall holder */
22109 +       .long sys_statfs
22110 +       .long sys_fstatfs       /* 100 */
22111 +       .long sys_ni_syscall    /* ioperm for i386 */
22112 +       .long sys_socketcall
22113 +       .long sys_syslog
22114 +       .long sys_setitimer
22115 +       .long sys_getitimer     /* 105 */
22116 +       .long sys_newstat
22117 +       .long sys_newlstat
22118 +       .long sys_newfstat
22119 +       .long sys_ni_syscall
22120 +       .long sys_ni_syscall    /* iopl for i386 */ /* 110 */
22121 +       .long sys_vhangup
22122 +       .long sys_ni_syscall    /* obsolete idle() syscall */
22123 +       .long sys_ni_syscall    /* vm86old for i386 */
22124 +       .long sys_wait4
22125 +       .long sys_ni_syscall    /* 115 */ /* _sys_swapoff */
22126 +       .long sys_sysinfo
22127 +       .long sys_ipc
22128 +       .long sys_fsync
22129 +       .long sys_sigreturn
22130 +       .long clone_intercept   /* 120 */
22131 +       .long sys_setdomainname
22132 +       .long sys_newuname
22133 +       .long sys_cacheflush    /* modify_ldt for i386 */
22134 +       .long sys_adjtimex
22135 +       .long sys_ni_syscall    /* 125 */ /* _sys_mprotect */
22136 +       .long sys_sigprocmask
22137 +       .long sys_ni_syscall    /* old "creat_module" */
22138 +       .long sys_init_module
22139 +       .long sys_delete_module
22140 +       .long sys_ni_syscall    /* 130: old "get_kernel_syms" */
22141 +       .long sys_quotactl
22142 +       .long sys_getpgid
22143 +       .long sys_fchdir
22144 +       .long sys_bdflush
22145 +       .long sys_sysfs         /* 135 */
22146 +       .long sys_personality
22147 +       .long sys_ni_syscall    /* for afs_syscall */
22148 +       .long sys_setfsuid16
22149 +       .long sys_setfsgid16
22150 +       .long sys_llseek        /* 140 */
22151 +       .long sys_getdents
22152 +       .long sys_select
22153 +       .long sys_flock
22154 +       .long sys_ni_syscall    /* _sys_msync */
22155 +       .long sys_readv         /* 145 */
22156 +       .long sys_writev
22157 +       .long sys_getsid
22158 +       .long sys_fdatasync
22159 +       .long sys_sysctl
22160 +       .long sys_ni_syscall    /* 150 */ /* _sys_mlock */
22161 +       .long sys_ni_syscall    /* _sys_munlock */
22162 +       .long sys_ni_syscall    /* _sys_mlockall */
22163 +       .long sys_ni_syscall    /* _sys_munlockall */
22164 +       .long sys_sched_setparam
22165 +       .long sys_sched_getparam /* 155 */
22166 +       .long sys_sched_setscheduler
22167 +       .long sys_sched_getscheduler
22168 +       .long sys_sched_yield
22169 +       .long sys_sched_get_priority_max
22170 +       .long sys_sched_get_priority_min  /* 160 */
22171 +       .long sys_sched_rr_get_interval
22172 +       .long sys_nanosleep
22173 +       .long sys_ni_syscall    /* _sys_mremap */
22174 +       .long sys_setresuid16
22175 +       .long sys_getresuid16   /* 165 */
22176 +       .long sys_getpagesize   /* _sys_getpagesize */
22177 +       .long sys_ni_syscall    /* old "query_module" */
22178 +       .long sys_poll
22179 +       .long sys_ni_syscall    /* _sys_nfsservctl */
22180 +       .long sys_setresgid16   /* 170 */
22181 +       .long sys_getresgid16
22182 +       .long sys_prctl
22183 +       .long sys_rt_sigreturn
22184 +       .long sys_rt_sigaction
22185 +       .long sys_rt_sigprocmask /* 175 */
22186 +       .long sys_rt_sigpending
22187 +       .long sys_rt_sigtimedwait
22188 +       .long sys_rt_sigqueueinfo
22189 +       .long sys_rt_sigsuspend
22190 +       .long sys_pread64       /* 180 */
22191 +       .long sys_pwrite64
22192 +       .long sys_lchown16
22193 +       .long sys_getcwd
22194 +       .long sys_capget
22195 +       .long sys_capset        /* 185 */
22196 +       .long sys_sigaltstack
22197 +       .long sys_sendfile
22198 +       .long sys_ni_syscall    /* streams1 */
22199 +       .long sys_ni_syscall    /* streams2 */
22200 +       .long vfork_intercept           /* 190 */
22201 +       .long sys_getrlimit
22202 +       .long sys_mmap2
22203 +       .long sys_truncate64
22204 +       .long sys_ftruncate64
22205 +       .long sys_stat64        /* 195 */
22206 +       .long sys_lstat64
22207 +       .long sys_fstat64
22208 +       .long sys_chown
22209 +       .long sys_getuid
22210 +       .long sys_getgid        /* 200 */
22211 +       .long sys_geteuid
22212 +       .long sys_getegid
22213 +       .long sys_setreuid
22214 +       .long sys_setregid
22215 +       .long sys_getgroups     /* 205 */
22216 +       .long sys_setgroups
22217 +       .long sys_fchown
22218 +       .long sys_setresuid
22219 +       .long sys_getresuid
22220 +       .long sys_setresgid     /* 210 */
22221 +       .long sys_getresgid
22222 +       .long sys_lchown
22223 +       .long sys_setuid
22224 +       .long sys_setgid
22225 +       .long sys_setfsuid      /* 215 */
22226 +       .long sys_setfsgid
22227 +       .long sys_pivot_root
22228 +       .long sys_ni_syscall
22229 +       .long sys_ni_syscall
22230 +       .long sys_getdents64    /* 220 */
22231 +       .long sys_gettid
22232 +       .long sys_tkill
22233 +       .long sys_setxattr
22234 +       .long sys_lsetxattr
22235 +       .long sys_fsetxattr     /* 225 */
22236 +       .long sys_getxattr
22237 +       .long sys_lgetxattr
22238 +       .long sys_fgetxattr
22239 +       .long sys_listxattr
22240 +       .long sys_llistxattr    /* 230 */
22241 +       .long sys_flistxattr
22242 +       .long sys_removexattr
22243 +       .long sys_lremovexattr
22244 +       .long sys_fremovexattr
22245 +       .long sys_futex         /* 235 */
22246 +       .long sys_sendfile64
22247 +       .long sys_ni_syscall    /* _sys_mincore */
22248 +       .long sys_ni_syscall    /* _sys_madvise */
22249 +       .long sys_fcntl64
22250 +       .long sys_readahead     /* 240 */
22251 +       .long sys_io_setup
22252 +       .long sys_io_destroy
22253 +       .long sys_io_getevents
22254 +       .long sys_io_submit
22255 +       .long sys_io_cancel     /* 245 */
22256 +       .long sys_fadvise64
22257 +       .long sys_exit_group
22258 +       .long sys_lookup_dcookie
22259 +       .long sys_epoll_create
22260 +       .long sys_epoll_ctl     /* 250 */
22261 +       .long sys_epoll_wait
22262 +       .long sys_ni_syscall    /* _sys_remap_file_pages */
22263 +       .long sys_set_tid_address
22264 +       .long sys_timer_create
22265 +       .long sys_timer_settime /* 255 */
22266 +       .long sys_timer_gettime
22267 +       .long sys_timer_getoverrun
22268 +       .long sys_timer_delete
22269 +       .long sys_clock_settime
22270 +       .long sys_clock_gettime /* 260 */
22271 +       .long sys_clock_getres
22272 +       .long sys_clock_nanosleep
22273 +       .long sys_statfs64
22274 +       .long sys_fstatfs64
22275 +       .long sys_tgkill        /* 265 */
22276 +       .long sys_utimes
22277 +       .long sys_fadvise64_64
22278 +       .long sys_mbind 
22279 +       .long sys_get_mempolicy
22280 +       .long sys_set_mempolicy /* 270 */
22281 +       .long sys_mq_open
22282 +       .long sys_mq_unlink
22283 +       .long sys_mq_timedsend
22284 +       .long sys_mq_timedreceive
22285 +       .long sys_mq_notify     /* 275 */
22286 +       .long sys_mq_getsetattr
22287 +       .long sys_waitid
22288 +       .long sys_ni_syscall    /* for _sys_vserver */
22289 +       .long sys_add_key
22290 +       .long sys_request_key   /* 280 */
22291 +       .long sys_keyctl
22292 +       .long sys_ioprio_set
22293 +       .long sys_ioprio_get
22294 +       .long sys_inotify_init
22295 +       .long sys_inotify_add_watch     /* 285 */
22296 +       .long sys_inotify_rm_watch
22297 +       .long sys_migrate_pages
22298 +       .long sys_openat
22299 +       .long sys_mkdirat
22300 +       .long sys_mknodat               /* 290 */
22301 +       .long sys_fchownat
22302 +       .long sys_futimesat
22303 +       .long sys_fstatat64
22304 +       .long sys_unlinkat
22305 +       .long sys_renameat              /* 295 */
22306 +       .long sys_linkat
22307 +       .long sys_symlinkat
22308 +       .long sys_readlinkat
22309 +       .long sys_fchmodat
22310 +       .long sys_faccessat             /* 300 */
22311 +       .long sys_ni_syscall            /* Reserved for pselect6 */
22312 +       .long sys_ni_syscall            /* Reserved for ppoll */
22313 +       .long sys_unshare
22314 +       .long sys_set_robust_list
22315 +       .long sys_get_robust_list       /* 305 */
22316 +       .long sys_splice
22317 +       .long sys_sync_file_range
22318 +       .long sys_tee
22319 +       .long sys_vmsplice
22320 +       .long sys_move_pages            /* 310 */
22321 +       .long sys_sched_setaffinity
22322 +       .long sys_sched_getaffinity
22323 +       .long sys_kexec_load
22324 +       .long sys_getcpu
22325 +       .long sys_epoll_pwait           /* 315 */
22326 +       .long sys_utimensat
22327 +       .long sys_signalfd
22328 +       .long sys_timerfd_create
22329 +       .long sys_eventfd
22330 +       .long sys_fallocate             /* 320 */
22331 +       .long sys_timerfd_settime
22332 +       .long sys_timerfd_gettime
22333 +       .long sys_ni_syscall            /* sys_signalfd4 */
22334 +       .long sys_ni_syscall            /* sys_eventfd2 */
22335 +       .long sys_ni_syscall            /* sys_epoll_create1 */
22336 +                                       /* 325 */
22337 +       .long sys_ni_syscall            /* sys_dup3 */
22338 +       .long sys_ni_syscall            /* sys_pipe2 */
22339 +       .long sys_ni_syscall            /* sys_inotify_init1 */
22340 +       .rept NR_syscalls-(.-sys_call_table)/4
22341 +               .long sys_ni_syscall
22342 +       .endr
22343 +
22344 --- /dev/null
22345 +++ b/arch/ubicom32/kernel/sys_ubicom32.c
22346 @@ -0,0 +1,237 @@
22347 +/*
22348 + * arch/ubicom32/kernel/sys_ubicom32.c
22349 + *   Ubicom32 architecture system call support implementation.
22350 + *
22351 + * (C) Copyright 2009, Ubicom, Inc.
22352 + *
22353 + * This file is part of the Ubicom32 Linux Kernel Port.
22354 + *
22355 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22356 + * it and/or modify it under the terms of the GNU General Public License
22357 + * as published by the Free Software Foundation, either version 2 of the
22358 + * License, or (at your option) any later version.
22359 + *
22360 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22361 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22362 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22363 + * the GNU General Public License for more details.
22364 + *
22365 + * You should have received a copy of the GNU General Public License
22366 + * along with the Ubicom32 Linux Kernel Port.  If not,
22367 + * see <http://www.gnu.org/licenses/>.
22368 + *
22369 + * Ubicom32 implementation derived from (with many thanks):
22370 + *   arch/m68knommu
22371 + *   arch/blackfin
22372 + *   arch/parisc
22373 + *
22374 + * This file contains various random system calls that
22375 + * have a non-standard calling sequence on the Linux/ubicom32
22376 + * platform.
22377 + */
22378 +
22379 +#include <linux/module.h>
22380 +#include <linux/errno.h>
22381 +#include <linux/sched.h>
22382 +#include <linux/mm.h>
22383 +#include <linux/smp.h>
22384 +#include <linux/sem.h>
22385 +#include <linux/msg.h>
22386 +#include <linux/shm.h>
22387 +#include <linux/stat.h>
22388 +#include <linux/syscalls.h>
22389 +#include <linux/mman.h>
22390 +#include <linux/file.h>
22391 +#include <linux/utsname.h>
22392 +#include <linux/ipc.h>
22393 +#include <linux/fs.h>
22394 +#include <linux/uaccess.h>
22395 +#include <linux/unistd.h>
22396 +
22397 +#include <asm/setup.h>
22398 +#include <asm/traps.h>
22399 +#include <asm/cacheflush.h>
22400 +
22401 +/* common code for old and new mmaps */
22402 +static inline long do_mmap2(
22403 +       unsigned long addr, unsigned long len,
22404 +       unsigned long prot, unsigned long flags,
22405 +       unsigned long fd, unsigned long pgoff)
22406 +{
22407 +       int error = -EBADF;
22408 +       struct file *file = NULL;
22409 +
22410 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22411 +       if (!(flags & MAP_ANONYMOUS)) {
22412 +               file = fget(fd);
22413 +               if (!file)
22414 +                       goto out;
22415 +       }
22416 +
22417 +       down_write(&current->mm->mmap_sem);
22418 +       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
22419 +       up_write(&current->mm->mmap_sem);
22420 +
22421 +       if (file)
22422 +               fput(file);
22423 +out:
22424 +       return error;
22425 +}
22426 +
22427 +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
22428 +       unsigned long prot, unsigned long flags,
22429 +       unsigned long fd, unsigned long pgoff)
22430 +{
22431 +       return do_mmap2(addr, len, prot, flags, fd, pgoff);
22432 +}
22433 +
22434 +/*
22435 + * Perform the select(nd, in, out, ex, tv) and mmap() system
22436 + * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
22437 + * handle more than 4 system call parameters, so these system calls
22438 + * used a memory block for parameter passing..
22439 + */
22440 +
22441 +struct mmap_arg_struct {
22442 +       unsigned long addr;
22443 +       unsigned long len;
22444 +       unsigned long prot;
22445 +       unsigned long flags;
22446 +       unsigned long fd;
22447 +       unsigned long offset;
22448 +};
22449 +
22450 +asmlinkage int old_mmap(struct mmap_arg_struct *arg)
22451 +{
22452 +       struct mmap_arg_struct a;
22453 +       int error = -EFAULT;
22454 +
22455 +       if (copy_from_user(&a, arg, sizeof(a)))
22456 +               goto out;
22457 +
22458 +       error = -EINVAL;
22459 +       if (a.offset & ~PAGE_MASK)
22460 +               goto out;
22461 +
22462 +       a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22463 +
22464 +       error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd,
22465 +                        a.offset >> PAGE_SHIFT);
22466 +out:
22467 +       return error;
22468 +}
22469 +
22470 +struct sel_arg_struct {
22471 +       unsigned long n;
22472 +       fd_set *inp, *outp, *exp;
22473 +       struct timeval *tvp;
22474 +};
22475 +
22476 +asmlinkage int old_select(struct sel_arg_struct *arg)
22477 +{
22478 +       struct sel_arg_struct a;
22479 +
22480 +       if (copy_from_user(&a, arg, sizeof(a)))
22481 +               return -EFAULT;
22482 +       /* sys_select() does the appropriate kernel locking */
22483 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
22484 +}
22485 +
22486 +/*
22487 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
22488 + *
22489 + * This is really horribly ugly.
22490 + */
22491 +asmlinkage int sys_ipc(uint call, int first, int second,
22492 +                       int third, void *ptr, long fifth)
22493 +{
22494 +       int version, ret;
22495 +
22496 +       version = call >> 16; /* hack for backward compatibility */
22497 +       call &= 0xffff;
22498 +
22499 +       if (call <= SEMCTL)
22500 +               switch (call) {
22501 +               case SEMOP:
22502 +                       return sys_semop(first, (struct sembuf *)ptr, second);
22503 +               case SEMGET:
22504 +                       return sys_semget(first, second, third);
22505 +               case SEMCTL: {
22506 +                       union semun fourth;
22507 +                       if (!ptr)
22508 +                               return -EINVAL;
22509 +                       if (get_user(fourth.__pad, (void **) ptr))
22510 +                               return -EFAULT;
22511 +                       return sys_semctl(first, second, third, fourth);
22512 +                       }
22513 +               default:
22514 +                       return -EINVAL;
22515 +               }
22516 +       if (call <= MSGCTL)
22517 +               switch (call) {
22518 +               case MSGSND:
22519 +                       return sys_msgsnd(first, (struct msgbuf *) ptr,
22520 +                                         second, third);
22521 +               case MSGRCV:
22522 +                       switch (version) {
22523 +                       case 0: {
22524 +                               struct ipc_kludge tmp;
22525 +                               if (!ptr)
22526 +                                       return -EINVAL;
22527 +                               if (copy_from_user(&tmp,
22528 +                                                  (struct ipc_kludge *)ptr,
22529 +                                                  sizeof(tmp)))
22530 +                                       return -EFAULT;
22531 +                               return sys_msgrcv(first, tmp.msgp, second,
22532 +                                                  tmp.msgtyp, third);
22533 +                               }
22534 +                       default:
22535 +                               return sys_msgrcv(first,
22536 +                                                 (struct msgbuf *) ptr,
22537 +                                                 second, fifth, third);
22538 +                       }
22539 +               case MSGGET:
22540 +                       return sys_msgget((key_t) first, second);
22541 +               case MSGCTL:
22542 +                       return sys_msgctl(first, second,
22543 +                                          (struct msqid_ds *) ptr);
22544 +               default:
22545 +                       return -EINVAL;
22546 +               }
22547 +       if (call <= SHMCTL)
22548 +               switch (call) {
22549 +               case SHMAT:
22550 +                       switch (version) {
22551 +                       default: {
22552 +                               ulong raddr;
22553 +                               ret = do_shmat(first, ptr, second, &raddr);
22554 +                               if (ret)
22555 +                                       return ret;
22556 +                               return put_user(raddr, (ulong __user *) third);
22557 +                       }
22558 +                       }
22559 +               case SHMDT:
22560 +                       return sys_shmdt(ptr);
22561 +               case SHMGET:
22562 +                       return sys_shmget(first, second, third);
22563 +               case SHMCTL:
22564 +                       return sys_shmctl(first, second, ptr);
22565 +               default:
22566 +                       return -ENOSYS;
22567 +               }
22568 +
22569 +       return -EINVAL;
22570 +}
22571 +
22572 +/* sys_cacheflush -- flush (part of) the processor cache.  */
22573 +asmlinkage int
22574 +sys_cacheflush(unsigned long addr, int scope, int cache, unsigned long len)
22575 +{
22576 +       flush_cache_all();
22577 +       return 0;
22578 +}
22579 +
22580 +asmlinkage int sys_getpagesize(void)
22581 +{
22582 +       return PAGE_SIZE;
22583 +}
22584 --- /dev/null
22585 +++ b/arch/ubicom32/kernel/thread.c
22586 @@ -0,0 +1,228 @@
22587 +/*
22588 + * arch/ubicom32/kernel/thread.c
22589 + *   Ubicom32 architecture hardware thread support.
22590 + *
22591 + * (C) Copyright 2009, Ubicom, Inc.
22592 + *
22593 + * This file is part of the Ubicom32 Linux Kernel Port.
22594 + *
22595 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22596 + * it and/or modify it under the terms of the GNU General Public License
22597 + * as published by the Free Software Foundation, either version 2 of the
22598 + * License, or (at your option) any later version.
22599 + *
22600 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22601 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22602 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22603 + * the GNU General Public License for more details.
22604 + *
22605 + * You should have received a copy of the GNU General Public License
22606 + * along with the Ubicom32 Linux Kernel Port.  If not,
22607 + * see <http://www.gnu.org/licenses/>.
22608 + *
22609 + * Ubicom32 implementation derived from (with many thanks):
22610 + *   arch/m68knommu
22611 + *   arch/blackfin
22612 + *   arch/parisc
22613 + */
22614 +
22615 +#include <linux/module.h>
22616 +#include <linux/kernel.h>
22617 +#include <linux/init.h>
22618 +#include <linux/sched.h>
22619 +#include <linux/interrupt.h>
22620 +#include <linux/irq.h>
22621 +#include <linux/profile.h>
22622 +#include <linux/clocksource.h>
22623 +#include <linux/types.h>
22624 +#include <asm/ip5000.h>
22625 +#include <asm/machdep.h>
22626 +#include <asm/asm-offsets.h>
22627 +#include <asm/thread.h>
22628 +
22629 +/*
22630 + * TODO: At some point change the name here to be thread_ksp
22631 + */
22632 +unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
22633 +
22634 +static unsigned int thread_mask = -1;
22635 +static unsigned int thread_mainline_mask;
22636 +
22637 +/*
22638 + * thread_entry()
22639 + *     Returning from the called function will disable the thread.
22640 + *
22641 + * This could be a naked call to allow for hwthreads that do not have stacks.
22642 + * However, with -O0, the code still writes to thex stack, and this was
22643 + * corrupting memory just after the callers stack.
22644 + */
22645 +static void thread_entry(void *arg, thread_exec_fn_t exec)
22646 +{
22647 +       /*
22648 +        * Call thread function
22649 +        */
22650 +       exec(arg);
22651 +
22652 +       /*
22653 +        * Complete => Disable self
22654 +        */
22655 +       thread_disable(thread_get_self());
22656 +}
22657 +
22658 +/*
22659 + * thread_start()
22660 + *     Start the specified function on the specified hardware thread.
22661 + */
22662 +thread_t thread_start(thread_t thread,
22663 +                     thread_exec_fn_t exec,
22664 +                     void *arg,
22665 +                     unsigned int *sp_high,
22666 +                     thread_type_t type)
22667 +{
22668 +       /*
22669 +        * Sanity check
22670 +        */
22671 +       unsigned int enabled, mask, csr;
22672 +       asm volatile (
22673 +               "move.4         %0, MT_EN\n\t"
22674 +               : "=m" (enabled)
22675 +       );
22676 +
22677 +       mask = 1 << thread;
22678 +       if (enabled & mask) {
22679 +               printk(KERN_WARNING "request to enable a previously enabled thread\n");
22680 +               return (thread_t)-1;
22681 +       }
22682 +
22683 +       /*
22684 +        * Update thread state
22685 +        */
22686 +       csr = (thread << 15) | (1 << 14);
22687 +       asm volatile (
22688 +               "setcsr         %0              \n\t"
22689 +               "setcsr_flush   0               \n\t"
22690 +
22691 +               "move.4         A0, #0          \n\t"
22692 +               "move.4         A1, #0          \n\t"
22693 +               "move.4         A2, #0          \n\t"
22694 +               "move.4         A3, #0          \n\t"
22695 +               "move.4         A4, #0          \n\t"
22696 +               "move.4         A5, #0          \n\t"
22697 +               "move.4         A6, #0          \n\t"
22698 +               "move.4         SP, %4          \n\t"   /* A7 is SP */
22699 +
22700 +               "move.4         D0, %3          \n\t"
22701 +               "move.4         D1, %2          \n\t"
22702 +               "move.4         D2, #0          \n\t"
22703 +               "move.4         D3, #0          \n\t"
22704 +               "move.4         D4, #0          \n\t"
22705 +               "move.4         D5, #0          \n\t"
22706 +               "move.4         D6, #0          \n\t"
22707 +               "move.4         D7, #0          \n\t"
22708 +               "move.4         D8, #0          \n\t"
22709 +               "move.4         D9, #0          \n\t"
22710 +               "move.4         D10, #0         \n\t"
22711 +               "move.4         D11, #0         \n\t"
22712 +               "move.4         D12, #0         \n\t"
22713 +               "move.4         D13, #0         \n\t"
22714 +               "move.4         D14, #0         \n\t"
22715 +               "move.4         D15, #0         \n\t"
22716 +
22717 +               "move.4         INT_MASK0, #0   \n\t"
22718 +               "move.4         INT_MASK1, #0   \n\t"
22719 +               "move.4         PC, %1          \n\t"
22720 +               "setcsr         #0              \n\t"
22721 +               "setcsr_flush   0               \n\t"
22722 +               :
22723 +               : "r" (csr), "r" (thread_entry), "r" (exec),
22724 +                 "r" (arg), "r" (sp_high)
22725 +       );
22726 +
22727 +       /*
22728 +        * Apply HRT state
22729 +        */
22730 +       if (type & THREAD_TYPE_HRT) {
22731 +               asm volatile (
22732 +                       "or.4           MT_HRT, MT_HRT, %0\n\t"
22733 +                       :
22734 +                       : "d" (mask)
22735 +                       : "cc"
22736 +               );
22737 +       } else {
22738 +               asm volatile (
22739 +                       "and.4          MT_HRT, MT_HRT, %0\n\t"
22740 +                       :
22741 +                       : "d" (~mask)
22742 +                       : "cc"
22743 +               );
22744 +       }
22745 +
22746 +       /*
22747 +        * Set priority
22748 +        */
22749 +       asm volatile (
22750 +               "or.4           MT_HPRI, MT_HPRI, %0\n\t"
22751 +               :
22752 +               : "d" (mask)
22753 +               : "cc"
22754 +       );
22755 +
22756 +       /*
22757 +        * Enable thread
22758 +        */
22759 +       asm volatile (
22760 +               "move.4         MT_ACTIVE_SET, %0       \n\t"
22761 +               :
22762 +               : "d" (mask)
22763 +       );
22764 +       thread_enable_mask(mask);
22765 +       return thread;
22766 +}
22767 +
22768 +/*
22769 + * thread_get_mainline()
22770 + *     Return a mask of those threads that are Linux mainline threads.
22771 + */
22772 +unsigned int thread_get_mainline(void)
22773 +{
22774 +       return thread_mainline_mask;
22775 +}
22776 +
22777 +/*
22778 + * thread_set_mainline()
22779 + *     Indicate that the specified thread is a Linux mainline thread.
22780 + */
22781 +void thread_set_mainline(thread_t tid)
22782 +{
22783 +       thread_mainline_mask |= (1 << tid);
22784 +}
22785 +
22786 +/*
22787 + * thread_alloc()
22788 + *     Allocate an unused hardware thread.
22789 + */
22790 +thread_t thread_alloc(void)
22791 +{
22792 +       thread_t tid;
22793 +
22794 +       /*
22795 +        * If this is the first time we are here get the list of unused
22796 +        * threads from the processor device tree node.
22797 +        */
22798 +       if (thread_mask == -1) {
22799 +               thread_mask = processor_threads();
22800 +       }
22801 +
22802 +       if (!thread_mask) {
22803 +               return (thread_t)-1;
22804 +       }
22805 +
22806 +       tid = ffs(thread_mask);
22807 +       if (tid != 0) {
22808 +               tid--;
22809 +               thread_mask &= ~(1 << tid);
22810 +               return tid;
22811 +       }
22812 +
22813 +       return (thread_t)-1;
22814 +}
22815 --- /dev/null
22816 +++ b/arch/ubicom32/kernel/time.c
22817 @@ -0,0 +1,212 @@
22818 +/*
22819 + * arch/ubicom32/kernel/time.c
22820 + *     Initialize the timer list and start the appropriate timers.
22821 + *
22822 + * (C) Copyright 2009, Ubicom, Inc.
22823 + * Copyright (C) 1991, 1992, 1995  Linus Torvalds
22824 + *
22825 + * This file is part of the Ubicom32 Linux Kernel Port.
22826 + *
22827 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22828 + * it and/or modify it under the terms of the GNU General Public License
22829 + * as published by the Free Software Foundation, either version 2 of the
22830 + * License, or (at your option) any later version.
22831 + *
22832 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22833 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22834 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22835 + * the GNU General Public License for more details.
22836 + *
22837 + * You should have received a copy of the GNU General Public License
22838 + * along with the Ubicom32 Linux Kernel Port.  If not,
22839 + * see <http://www.gnu.org/licenses/>.
22840 + *
22841 + * Ubicom32 implementation derived from (with many thanks):
22842 + *   arch/m68knommu
22843 + *   arch/blackfin
22844 + *   arch/parisc
22845 + */
22846 +
22847 +#include <linux/profile.h>
22848 +#include <linux/smp.h>
22849 +#include <asm/ip5000.h>
22850 +#include <asm/machdep.h>
22851 +
22852 +/*
22853 + * A bitmap of the timers on the processor indicates
22854 + * that the timer is free or in-use.
22855 + */
22856 +static unsigned int timers;
22857 +
22858 +/*
22859 + * timer_set()
22860 + *     Init the specified compare register to go off <n> cycles from now.
22861 + */
22862 +void timer_set(int timervector, unsigned int cycles)
22863 +{
22864 +       int idx = UBICOM32_VECTOR_TO_TIMER_INDEX(timervector);
22865 +       UBICOM32_IO_TIMER->syscom[idx] =
22866 +                       UBICOM32_IO_TIMER->sysval + cycles;
22867 +       ldsr_enable_vector(timervector);
22868 +}
22869 +
22870 +/*
22871 + * timer_reset()
22872 + *     Set/reset the timer to go off again.
22873 + *
22874 + * Because sysval is a continuous timer, this function is able
22875 + * to ensure that we do not have clock sku by using the previous
22876 + * value in syscom to set the next value for syscom.
22877 + *
22878 + * Returns the number of ticks that transpired since the last event.
22879 + */
22880 +int timer_reset(int timervector, unsigned int cycles)
22881 +{
22882 +       /*
22883 +        * Reset the timer in the LDSR thread to go off appropriately.
22884 +        *
22885 +        * Use the previous value of the timer to calculate the new stop
22886 +        * time.  This allows us to account for it taking an
22887 +        * indeterminate amount of time to get here.
22888 +        */
22889 +       const int timer_index = UBICOM32_VECTOR_TO_TIMER_INDEX(timervector);
22890 +       unsigned int prev = UBICOM32_IO_TIMER->syscom[timer_index];
22891 +       unsigned int next = prev + cycles;
22892 +       int scratchpad3;
22893 +       int diff;
22894 +       int ticks = 1;
22895 +
22896 +       /*
22897 +        * If the difference is negative, we have missed at least one
22898 +        * timer tick.
22899 +        *
22900 +        * TODO: Decide if we want to "ignore" time (as done below) or
22901 +        * if we want to process time (unevenly) by calling timer_tick()
22902 +        * lost_ticks times.
22903 +        */
22904 +       while (1) {
22905 +               /*
22906 +                * Set our future time first.
22907 +                */
22908 +               UBICOM32_IO_TIMER->syscom[timer_index] = next;
22909 +
22910 +               /*
22911 +                * Then check if we are really set time in the futrue.
22912 +                */
22913 +               diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
22914 +               if (diff >= 0) {
22915 +                       break;
22916 +               }
22917 +
22918 +               /*
22919 +                * Oops, we are too slow. Playing catch up.
22920 +                *
22921 +                * If the debugger is connected the there is a good
22922 +                * chance that we lost time because we were in a
22923 +                * break-point, so in this case we do not print out
22924 +                * diagnostics.
22925 +                */
22926 +               asm volatile ("move.4 %0, scratchpad3"
22927 +                             : "=r" (scratchpad3));
22928 +               if ((scratchpad3 & 0x1) == 0) {
22929 +                       /*
22930 +                        * No debugger attached, print to the console
22931 +                        */
22932 +                       printk(KERN_EMERG "diff: %d, timer has lost %u "
22933 +                              "ticks [rounded up]\n",
22934 +                              -diff,
22935 +                              (unsigned int)((-diff + cycles - 1) / cycles));
22936 +               }
22937 +
22938 +               do {
22939 +                       next += cycles;
22940 +                       diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
22941 +                       ticks++;
22942 +               } while (diff < 0);
22943 +       }
22944 +       return ticks;
22945 +}
22946 +
22947 +/*
22948 + * sched_clock()
22949 + *     Returns current time in nano-second units.
22950 + *
22951 + * Notes:
22952 + * 1) This is an override for the weak alias in
22953 + * kernel/sched_clock.c.
22954 + * 2) Do not use xtime_lock as this function is
22955 + * sometimes called with xtime_lock held.
22956 + * 3) We use a retry algorithm to ensure that
22957 + * we get a consistent value.
22958 + * 4) sched_clock must be overwritten if IRQ tracing
22959 + * is enabled because the default implementation uses
22960 + * the xtime_lock sequence while holding xtime_lock.
22961 + */
22962 +unsigned long long sched_clock(void)
22963 +{
22964 +       unsigned long long my_jiffies;
22965 +       unsigned long jiffies_top;
22966 +       unsigned long jiffies_bottom;
22967 +
22968 +       do {
22969 +               jiffies_top = jiffies_64 >> 32;
22970 +               jiffies_bottom = jiffies_64 & 0xffffffff;
22971 +       } while (unlikely(jiffies_top != (unsigned long)(jiffies_64 >> 32)));
22972 +
22973 +       my_jiffies = ((unsigned long long)jiffies_top << 32) | (jiffies_bottom);
22974 +       return (my_jiffies - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
22975 +}
22976 +
22977 +/*
22978 + * timer_free()
22979 + *     Free a hardware timer.
22980 + */
22981 +void timer_free(int interrupt)
22982 +{
22983 +       unsigned int bit = interrupt - TIMER_INT(0);
22984 +
22985 +       /*
22986 +        * The timer had not been allocated.
22987 +        */
22988 +       BUG_ON(timers & (1 << bit));
22989 +       timers |= (1 << bit);
22990 +}
22991 +
22992 +/*
22993 + * timer_alloc()
22994 + *     Allocate a hardware timer.
22995 + */
22996 +int timer_alloc(void)
22997 +{
22998 +       unsigned int bit = find_first_bit((unsigned long *)&timers, 32);
22999 +       if (!bit) {
23000 +               printk(KERN_WARNING "no more free timers\n");
23001 +               return -1;
23002 +       }
23003 +
23004 +       timers &= ~(1 << bit);
23005 +       return bit + TIMER_INT(0);
23006 +}
23007 +
23008 +/*
23009 + * time_init()
23010 + *     Time init function.
23011 + */
23012 +void time_init(void)
23013 +{
23014 +       /*
23015 +        * Find the processor node and determine what timers are
23016 +        * available for us.
23017 +        */
23018 +       timers = processor_timers();
23019 +       if (timers == 0) {
23020 +               printk(KERN_WARNING "no timers are available for Linux\n");
23021 +               return;
23022 +       }
23023 +
23024 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
23025 +       timer_device_init();
23026 +#else
23027 +       timer_tick_init();
23028 +#endif
23029 +}
23030 --- /dev/null
23031 +++ b/arch/ubicom32/kernel/timer_broadcast.c
23032 @@ -0,0 +1,102 @@
23033 +/*
23034 + * arch/ubicom32/kernel/timer_broadcast.c
23035 + *   Implements a dummy clock event for each cpu.
23036 + *
23037 + * Copyright (C) 2008  Paul Mundt
23038 + * (C) Copyright 2009, Ubicom, Inc.
23039 + *
23040 + * This file is part of the Ubicom32 Linux Kernel Port.
23041 + *
23042 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23043 + * it and/or modify it under the terms of the GNU General Public License
23044 + * as published by the Free Software Foundation, either version 2 of the
23045 + * License, or (at your option) any later version.
23046 + *
23047 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23048 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23049 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23050 + * the GNU General Public License for more details.
23051 + *
23052 + * You should have received a copy of the GNU General Public License
23053 + * along with the Ubicom32 Linux Kernel Port.  If not,
23054 + * see <http://www.gnu.org/licenses/>.
23055 + *
23056 + * Ubicom32 implementation derived from (with many thanks):
23057 + *   arch/m68knommu
23058 + *   arch/blackfin
23059 + *   arch/parisc
23060 + *   arch/arm
23061 + *   arch/sh
23062 + */
23063 +#include <linux/init.h>
23064 +#include <linux/kernel.h>
23065 +#include <linux/delay.h>
23066 +#include <linux/device.h>
23067 +#include <linux/smp.h>
23068 +#include <linux/jiffies.h>
23069 +#include <linux/percpu.h>
23070 +#include <linux/clockchips.h>
23071 +#include <linux/irq.h>
23072 +
23073 +static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
23074 +
23075 +/*
23076 + *  The broadcast trick only works when the timer will be used in a periodic mode.
23077 + *  If the user has configured either NO_HZ or HIGH_RES_TIMERS they must have
23078 + *  a per cpu timer.
23079 + */
23080 +#if defined(CONFIG_NO_HZ) || defined(CONFIG_HIGH_RES_TIMERS)
23081 +#error "Tickless and High Resolution Timers require per-CPU local timers: CONFIG_LOCAL_TIMERS"
23082 +#endif
23083 +
23084 +/*
23085 + * local_timer_interrupt()
23086 + *     Used on SMP for local timer interrupt sent via an IPI.
23087 + */
23088 +void local_timer_interrupt(void)
23089 +{
23090 +       struct clock_event_device *dev = &__get_cpu_var(local_clockevent);
23091 +
23092 +       dev->event_handler(dev);
23093 +}
23094 +
23095 +/*
23096 + * dummy_timer_set_next_event()
23097 + *     Cause the timer to go off "cycles" from now.
23098 + */
23099 +static int dummy_timer_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23100 +{
23101 +       return 0;
23102 +}
23103 +
23104 +/*
23105 + * dummy_timer_set_mode()
23106 + *     Do Nothing.
23107 + */
23108 +static void dummy_timer_set_mode(enum clock_event_mode mode,
23109 +                                struct clock_event_device *clk)
23110 +{
23111 +}
23112 +
23113 +/*
23114 + * local_timer_setup()
23115 + *     Adds a clock event for the specified cpu.
23116 + */
23117 +int __cpuinit local_timer_setup(unsigned int cpu)
23118 +{
23119 +       struct clock_event_device *dev = &per_cpu(local_clockevent, cpu);
23120 +
23121 +       dev->name               = "timer-dummy";
23122 +       dev->features           = CLOCK_EVT_FEAT_DUMMY;
23123 +       dev->rating             = 200;
23124 +       dev->mult               = 1;
23125 +       dev->set_mode           = dummy_timer_set_mode;
23126 +       dev->set_next_event     = dummy_timer_set_next_event;
23127 +       dev->broadcast          = smp_timer_broadcast;
23128 +       dev->cpumask            = cpumask_of_cpu(cpu);
23129 +       dev->irq                = -1;
23130 +       printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
23131 +
23132 +       clockevents_register_device(dev);
23133 +       return 0;
23134 +}
23135 --- /dev/null
23136 +++ b/arch/ubicom32/kernel/timer_device.c
23137 @@ -0,0 +1,302 @@
23138 +/*
23139 + * arch/ubicom32/kernel/timer_device.c
23140 + *   Implements a Ubicom32 clock device and event devices.
23141 + *
23142 + * (C) Copyright 2009, Ubicom, Inc.
23143 + *
23144 + * This file is part of the Ubicom32 Linux Kernel Port.
23145 + *
23146 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23147 + * it and/or modify it under the terms of the GNU General Public License
23148 + * as published by the Free Software Foundation, either version 2 of the
23149 + * License, or (at your option) any later version.
23150 + *
23151 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23152 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23153 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23154 + * the GNU General Public License for more details.
23155 + *
23156 + * You should have received a copy of the GNU General Public License
23157 + * along with the Ubicom32 Linux Kernel Port.  If not,
23158 + * see <http://www.gnu.org/licenses/>.
23159 + *
23160 + * Ubicom32 implementation derived from (with many thanks):
23161 + *   arch/m68knommu
23162 + *   arch/blackfin
23163 + *   arch/parisc
23164 + */
23165 +#include <linux/types.h>
23166 +#include <linux/clockchips.h>
23167 +#include <linux/clocksource.h>
23168 +#include <linux/spinlock.h>
23169 +#include <asm/ip5000.h>
23170 +#include <asm/machdep.h>
23171 +
23172 +#if defined(CONFIG_SMP)
23173 +#include <asm/smp.h>
23174 +#endif
23175 +
23176 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23177 +#define MAX_TIMERS (2 + CONFIG_TIMER_EXTRA_ALLOC)
23178 +#else
23179 +#define MAX_TIMERS (NR_CPUS + CONFIG_TIMER_EXTRA_ALLOC)
23180 +#endif
23181 +
23182 +#if (MAX_TIMERS > 10)
23183 +#error "Ubicom32 only has 10 timers"
23184 +#endif
23185 +
23186 +static unsigned int frequency;
23187 +static struct clock_event_device timer_device_devs[MAX_TIMERS];
23188 +static struct irqaction timer_device_irqs[MAX_TIMERS];
23189 +static int timer_device_next_timer = 0;
23190 +
23191 +DEFINE_SPINLOCK(timer_device_lock);
23192 +
23193 +/*
23194 + * timer_device_set_next_event()
23195 + *     Cause the timer to go off "cycles" from now.
23196 + */
23197 +static int timer_device_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23198 +{
23199 +       timer_set(dev->irq, cycles);
23200 +       return 0;
23201 +}
23202 +
23203 +/*
23204 + * timer_device_set_mode()
23205 + *     Handle the mode switch for a clock event device.
23206 + */
23207 +static void timer_device_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
23208 +{
23209 +       switch (mode) {
23210 +       case CLOCK_EVT_MODE_SHUTDOWN:
23211 +               /*
23212 +                * Make sure the vector is disabled
23213 +                * until the next event is set.
23214 +                */
23215 +               printk(KERN_NOTICE "timer[%d]: shutdown\n", dev->irq);
23216 +               ldsr_disable_vector(dev->irq);
23217 +               break;
23218 +
23219 +       case CLOCK_EVT_MODE_ONESHOT:
23220 +               /*
23221 +                * Make sure the vector is disabled
23222 +                * until the next event is set.
23223 +                */
23224 +               printk(KERN_NOTICE "timer[%d]: oneshot\n", dev->irq);
23225 +               ldsr_disable_vector(dev->irq);
23226 +               break;
23227 +
23228 +       case CLOCK_EVT_MODE_PERIODIC:
23229 +               /*
23230 +                * The periodic request is 1 per jiffies
23231 +                */
23232 +               printk(KERN_NOTICE "timer[%d]: periodic: %d cycles\n",
23233 +                       dev->irq, frequency / CONFIG_HZ);
23234 +               timer_set(dev->irq, frequency / CONFIG_HZ);
23235 +               break;
23236 +
23237 +       case CLOCK_EVT_MODE_UNUSED:
23238 +       case CLOCK_EVT_MODE_RESUME:
23239 +               printk(KERN_WARNING "timer[%d]: unimplemented mode: %d\n",
23240 +                       dev->irq, mode);
23241 +               break;
23242 +       };
23243 +}
23244 +
23245 +/*
23246 + * timer_device_event()
23247 + *     Call the device's event handler.
23248 + *
23249 + * The pointer is initialized by the generic Linux code
23250 + * to the function to be called.
23251 + */
23252 +static irqreturn_t timer_device_event(int irq, void *dev_id)
23253 +{
23254 +       struct clock_event_device *dev = (struct clock_event_device *)dev_id;
23255 +
23256 +       if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
23257 +               /*
23258 +                * The periodic request is 1 per jiffies
23259 +                */
23260 +               timer_reset(dev->irq, frequency / CONFIG_HZ);
23261 +       } else {
23262 +               /*
23263 +                * The timer will go off again at the rollover
23264 +                * point.  We must disable the IRQ to prevent
23265 +                * getting a spurious interrupt.
23266 +                */
23267 +               ldsr_disable_vector(dev->irq);
23268 +       }
23269 +
23270 +       if (!dev->event_handler) {
23271 +               printk(KERN_CRIT "no registered event handler\n");
23272 +               return IRQ_HANDLED;
23273 +       }
23274 +
23275 +       dev->event_handler(dev);
23276 +       return IRQ_HANDLED;
23277 +}
23278 +
23279 +/*
23280 + * timer_device_clockbase_read()
23281 + *     Provide a primary clocksource around the sysval timer.
23282 + */
23283 +static cycle_t timer_device_clockbase_read(void)
23284 +{
23285 +       return (cycle_t)UBICOM32_IO_TIMER->sysval;
23286 +}
23287 +
23288 +/*
23289 + * Primary Clock Source Description
23290 + *
23291 + * We use 24 for the shift factor because we want
23292 + * to ensure there are less than 2^24 clocks
23293 + * in a jiffie of 10 ms.
23294 + */
23295 +static struct clocksource timer_device_clockbase = {
23296 +       .name   = "sysval",
23297 +       .rating = 400,
23298 +       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
23299 +       .mask   = CLOCKSOURCE_MASK(32),
23300 +       .shift  = 24,
23301 +       .mult   = 0,
23302 +       .read   = timer_device_clockbase_read,
23303 +};
23304 +
23305 +/*
23306 + * timer_device_alloc_event()
23307 + *     Allocate a timer device event.
23308 + */
23309 +static int timer_device_alloc_event(const char *name, int cpuid, cpumask_t mask)
23310 +{
23311 +       struct clock_event_device *dev;
23312 +       struct irqaction *action;
23313 +
23314 +       /*
23315 +        * Are we out of configured timers?
23316 +        */
23317 +       spin_lock(&timer_device_lock);
23318 +       if (timer_device_next_timer >= MAX_TIMERS) {
23319 +               spin_unlock(&timer_device_lock);
23320 +               printk(KERN_WARNING "out of timer event entries\n");
23321 +               return -1;
23322 +       }
23323 +       dev = &timer_device_devs[timer_device_next_timer];
23324 +       action = &timer_device_irqs[timer_device_next_timer];
23325 +       timer_device_next_timer++;
23326 +       spin_unlock(&timer_device_lock);
23327 +
23328 +       /*
23329 +        * Now allocate a timer to ourselves.
23330 +        */
23331 +       dev->irq = timer_alloc();
23332 +       if (dev->irq == -1) {
23333 +               spin_lock(&timer_device_lock);
23334 +               timer_device_next_timer--;
23335 +               spin_unlock(&timer_device_lock);
23336 +               printk(KERN_WARNING "out of hardware timers\n");
23337 +               return -1;
23338 +       }
23339 +
23340 +       /*
23341 +        * Init the IRQ action structure.  Make sure
23342 +        * this in place before you register the clock
23343 +        * event device.
23344 +        */
23345 +       action->name = name;
23346 +       action->flags = IRQF_DISABLED | IRQF_TIMER;
23347 +       action->handler = timer_device_event;
23348 +       action->mask = mask;
23349 +       action->dev_id = dev;
23350 +       setup_irq(dev->irq, action);
23351 +       irq_set_affinity(dev->irq, mask);
23352 +       ldsr_disable_vector(dev->irq);
23353 +
23354 +       /*
23355 +        * init clock dev structure.
23356 +        *
23357 +        * The min_delta_ns is chosen to ensure that setting next
23358 +        * event will never be requested with too small of value.
23359 +        */
23360 +       dev->name = name;
23361 +       dev->rating = timer_device_clockbase.rating;
23362 +       dev->shift = timer_device_clockbase.shift;
23363 +       dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
23364 +       dev->set_mode = timer_device_set_mode;
23365 +       dev->set_next_event = timer_device_set_next_event;
23366 +       dev->mult = div_sc(frequency, NSEC_PER_SEC, dev->shift);
23367 +       dev->max_delta_ns = clockevent_delta2ns(0xffffffff, dev);
23368 +       dev->min_delta_ns = clockevent_delta2ns(100, dev);
23369 +       dev->cpumask = mask;
23370 +       printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
23371 +
23372 +       /*
23373 +        * Now register the device.
23374 +        */
23375 +       clockevents_register_device(dev);
23376 +       return dev->irq;
23377 +}
23378 +
23379 +#if defined(CONFIG_LOCAL_TIMERS)
23380 +/*
23381 + * local_timer_setup()
23382 + *     Allocation function for creating a per cpu local timer.
23383 + */
23384 +int __cpuinit local_timer_setup(unsigned int cpu)
23385 +{
23386 +       return timer_device_alloc_event("timer-cpu", cpu, cpumask_of_cpu(cpu));
23387 +}
23388 +#endif
23389 +
23390 +/*
23391 + * timer_device_init()
23392 + *     Create and init a generic clock driver for Ubicom32.
23393 + */
23394 +void timer_device_init(void)
23395 +{
23396 +       int i;
23397 +
23398 +       /*
23399 +        * Get the frequency from the processor device tree node or use
23400 +        * the default if not available. We will store this as the frequency
23401 +        * of the timer to avoid future calculations.
23402 +        */
23403 +       frequency = processor_frequency();
23404 +       if (frequency == 0) {
23405 +               frequency = CLOCK_TICK_RATE;
23406 +       }
23407 +
23408 +       /*
23409 +        * Setup the primary clock source around sysval.  Linux does not
23410 +        * supply a Mhz multiplier so convert down to khz.
23411 +        */
23412 +       timer_device_clockbase.mult =
23413 +               clocksource_khz2mult(frequency / 1000,
23414 +                       timer_device_clockbase.shift);
23415 +       if (clocksource_register(&timer_device_clockbase)) {
23416 +               printk(KERN_ERR "timer: clocksource failed to register\n");
23417 +               return;
23418 +       }
23419 +
23420 +       /*
23421 +        * Always allocate a primary timer.
23422 +        */
23423 +       timer_device_alloc_event("timer-primary", -1, CPU_MASK_ALL);
23424 +
23425 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23426 +       /*
23427 +        * If BROADCAST is selected we need to add a broadcast timer.
23428 +        */
23429 +       timer_device_alloc_event("timer-broadcast", -1, CPU_MASK_ALL);
23430 +#endif
23431 +
23432 +       /*
23433 +        * Allocate extra timers that are requested.
23434 +        */
23435 +       for (i = 0; i < CONFIG_TIMER_EXTRA_ALLOC; i++) {
23436 +               timer_device_alloc_event("timer-extra", -1, CPU_MASK_ALL);
23437 +       }
23438 +}
23439 +
23440 --- /dev/null
23441 +++ b/arch/ubicom32/kernel/timer_tick.c
23442 @@ -0,0 +1,109 @@
23443 +/*
23444 + * arch/ubicom32/kernel/timer_tick.c
23445 + *     Impelemets a perodic timer.
23446 + *
23447 + * (C) Copyright 2009, Ubicom, Inc.
23448 + * Copyright (C) 1991, 1992, 1995  Linus Torvalds
23449 + *
23450 + * This file is part of the Ubicom32 Linux Kernel Port.
23451 + *
23452 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23453 + * it and/or modify it under the terms of the GNU General Public License
23454 + * as published by the Free Software Foundation, either version 2 of the
23455 + * License, or (at your option) any later version.
23456 + *
23457 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23458 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23459 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23460 + * the GNU General Public License for more details.
23461 + *
23462 + * You should have received a copy of the GNU General Public License
23463 + * along with the Ubicom32 Linux Kernel Port.  If not, 
23464 + * see <http://www.gnu.org/licenses/>.
23465 + *
23466 + * Ubicom32 implementation derived from (with many thanks):
23467 + *   arch/m68knommu
23468 + *   arch/blackfin
23469 + *   arch/parisc
23470 + */
23471 +
23472 +#include <linux/profile.h>
23473 +
23474 +#include <asm/ip5000.h>
23475 +#include <asm/machdep.h>
23476 +#if defined(CONFIG_SMP)
23477 +#include <asm/smp.h>
23478 +#endif
23479 +
23480 +static unsigned int timervector;
23481 +static unsigned int frequency;
23482 +
23483 +/*
23484 + * timer_tick()
23485 + *     Kernel system timer support. Needs to keep up the real-time clock, 
23486 + *     as well as call the "do_timer()" routine every clocktick.
23487 + */
23488 +static irqreturn_t timer_tick(int irq, void *dummy)
23489 +{
23490 +       int ticks;
23491 +
23492 +       BUG_ON(!irqs_disabled());
23493 +       ticks = timer_reset(timervector, frequency);
23494 +
23495 +       write_seqlock(&xtime_lock);
23496 +       do_timer(ticks);
23497 +       write_sequnlock(&xtime_lock);
23498 +
23499 +       update_process_times(user_mode(get_irq_regs()));
23500 +       profile_tick(CPU_PROFILING);
23501 +
23502 +#if defined(CONFIG_SMP)
23503 +       smp_send_timer_all();
23504 +#endif
23505 +       return(IRQ_HANDLED);
23506 +}
23507 +
23508 +/*
23509 + * Data used by setup_irq for the timer.
23510 + */
23511 +static struct irqaction timer_irq = {
23512 +       .name    = "timer",
23513 +       .flags   = IRQF_DISABLED | IRQF_TIMER,
23514 +       .handler = timer_tick,
23515 +};
23516 +
23517 +/*
23518 + * timer_tick_init()
23519 + *     Implements a periodic timer
23520 + *
23521 + * This implementation directly calls the timer_tick() and move
23522 + * the Linux kernel forward.  This is used when the user has not
23523 + * selected GENERIC_CLOCKEVENTS.
23524 + */
23525 +void timer_tick_init(void)
23526 +{
23527 +       /*
23528 +        * Now allocate a timer to ourselves.
23529 +        */
23530 +       timervector = timer_alloc();
23531 +       if (timervector == -1) {
23532 +               printk(KERN_WARNING "where did the timer go?\n");
23533 +               return;
23534 +       }
23535 +
23536 +       setup_irq(timervector, &timer_irq);
23537 +
23538 +       /*
23539 +        * Get the frequency from the processor device tree node or use
23540 +        * the default if not available. We will store this as the frequency
23541 +        * of the timer to avoid future calculations.
23542 +        */
23543 +       frequency = processor_frequency();
23544 +       if (frequency == 0) {
23545 +               frequency = CLOCK_TICK_RATE;
23546 +       }
23547 +       frequency /= CONFIG_HZ;
23548 +
23549 +       printk(KERN_NOTICE "timer will interrupt every: %d cycles\n", frequency);
23550 +       timer_set(timervector, frequency);
23551 +}
23552 --- /dev/null
23553 +++ b/arch/ubicom32/kernel/topology.c
23554 @@ -0,0 +1,47 @@
23555 +/*
23556 + * arch/ubicom32/kernel/topology.c
23557 + *   Ubicom32 architecture sysfs topology information.
23558 + *
23559 + * (C) Copyright 2009, Ubicom, Inc.
23560 + *
23561 + * This file is part of the Ubicom32 Linux Kernel Port.
23562 + *
23563 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23564 + * it and/or modify it under the terms of the GNU General Public License
23565 + * as published by the Free Software Foundation, either version 2 of the
23566 + * License, or (at your option) any later version.
23567 + *
23568 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23569 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23570 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23571 + * the GNU General Public License for more details.
23572 + *
23573 + * You should have received a copy of the GNU General Public License
23574 + * along with the Ubicom32 Linux Kernel Port.  If not, 
23575 + * see <http://www.gnu.org/licenses/>.
23576 + *
23577 + * Ubicom32 implementation derived from (with many thanks):
23578 + *   arch/m68knommu
23579 + *   arch/blackfin
23580 + *   arch/parisc
23581 + */
23582 +
23583 +#include <linux/init.h>
23584 +#include <linux/smp.h>
23585 +#include <linux/cpu.h>
23586 +#include <linux/cache.h>
23587 +
23588 +static struct cpu cpu_devices[NR_CPUS] __read_mostly;
23589 +
23590 +static int __init topology_init(void)
23591 +{
23592 +       int num;
23593 +
23594 +       for_each_present_cpu(num) {
23595 +               cpu_devices[num].hotpluggable = 0;
23596 +               register_cpu(&cpu_devices[num], num);
23597 +       }
23598 +       return 0;
23599 +}
23600 +
23601 +subsys_initcall(topology_init);
23602 --- /dev/null
23603 +++ b/arch/ubicom32/kernel/traps.c
23604 @@ -0,0 +1,510 @@
23605 +/*
23606 + * arch/ubicom32/kernel/traps.c
23607 + *   Ubicom32 architecture trap handling support.
23608 + *
23609 + * (C) Copyright 2009, Ubicom, Inc.
23610 + *
23611 + * This file is part of the Ubicom32 Linux Kernel Port.
23612 + *
23613 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23614 + * it and/or modify it under the terms of the GNU General Public License
23615 + * as published by the Free Software Foundation, either version 2 of the
23616 + * License, or (at your option) any later version.
23617 + *
23618 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23619 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23620 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23621 + * the GNU General Public License for more details.
23622 + *
23623 + * You should have received a copy of the GNU General Public License
23624 + * along with the Ubicom32 Linux Kernel Port.  If not,
23625 + * see <http://www.gnu.org/licenses/>.
23626 + *
23627 + * Ubicom32 implementation derived from (with many thanks):
23628 + *   arch/m68knommu
23629 + *   arch/blackfin
23630 + *   arch/parisc
23631 + */
23632 +
23633 +/*
23634 + * Sets up all exception vectors
23635 + */
23636 +#include <linux/sched.h>
23637 +#include <linux/signal.h>
23638 +#include <linux/kernel.h>
23639 +#include <linux/mm.h>
23640 +#include <linux/module.h>
23641 +#include <linux/types.h>
23642 +#include <linux/a.out.h>
23643 +#include <linux/user.h>
23644 +#include <linux/string.h>
23645 +#include <linux/linkage.h>
23646 +#include <linux/init.h>
23647 +#include <linux/ptrace.h>
23648 +#include <linux/kallsyms.h>
23649 +#include <linux/compiler.h>
23650 +#include <linux/stacktrace.h>
23651 +#include <linux/personality.h>
23652 +
23653 +#include <asm/uaccess.h>
23654 +#include <asm/stacktrace.h>
23655 +#include <asm/devtree.h>
23656 +#include <asm/setup.h>
23657 +#include <asm/fpu.h>
23658 +#include <asm/system.h>
23659 +#include <asm/traps.h>
23660 +#include <asm/pgtable.h>
23661 +#include <asm/machdep.h>
23662 +#include <asm/siginfo.h>
23663 +#include <asm/ip5000.h>
23664 +#include <asm/thread.h>
23665 +
23666 +#define TRAP_MAX_STACK_DEPTH 20
23667 +
23668 +/*
23669 + * These symbols are filled in by the linker.
23670 + */
23671 +extern unsigned long _stext;
23672 +extern unsigned long _etext;
23673 +
23674 +extern unsigned long __ocm_text_run_begin;
23675 +extern unsigned long __data_begin;
23676 +
23677 +const char *trap_cause_strings[] = {
23678 +       /*0*/   "inst address decode error",
23679 +       /*1*/   "inst sync error",
23680 +       /*2*/   "inst illegal",
23681 +       /*3*/   "src1 address decode error",
23682 +       /*4*/   "dst address decode error",
23683 +       /*5*/   "src1 alignment error",
23684 +       /*6*/   "dst alignment error",
23685 +       /*7*/   "src1 sync error",
23686 +       /*8*/   "dst sync error",
23687 +       /*9*/   "DCAPT error",
23688 +       /*10*/  "inst range error",
23689 +       /*11*/  "src1 range error",
23690 +       /*12*/  "dst range error",
23691 +};
23692 +
23693 +/*
23694 + * The device tree trap node definition.
23695 + */
23696 +struct trapnode {
23697 +       struct devtree_node dn;
23698 +       unsigned int intthread;
23699 +};
23700 +
23701 +static struct trapnode *tn;;
23702 +
23703 +/*
23704 + * trap_interrupt_handler()
23705 + *     Software Interrupt to ensure that a trap is serviced.
23706 + */
23707 +static irqreturn_t trap_interrupt_handler(int irq, void *dummy)
23708 +{
23709 +       /* Do Nothing */
23710 +       return IRQ_HANDLED;
23711 +}
23712 +
23713 +/*
23714 + * Data used by setup_irq for the timer.
23715 + */
23716 +static struct irqaction trap_irq = {
23717 +       .name    = "trap",
23718 +       .flags   = IRQF_DISABLED,
23719 +       .handler = trap_interrupt_handler,
23720 +};
23721 +
23722 +/*
23723 + * trap_cause_to_str()
23724 + *     Convert a trap_cause into a series of printk
23725 + */
23726 +static void trap_cause_to_str(long status)
23727 +{
23728 +       int bit;
23729 +
23730 +       if ((status & ((1 << TRAP_CAUSE_TOTAL) - 1)) == 0) {
23731 +               printk(KERN_NOTICE "decode: UNKNOWN CAUSES\n");
23732 +               return;
23733 +       }
23734 +
23735 +       for (bit = 0; bit < TRAP_CAUSE_TOTAL; bit++) {
23736 +               if (status & (1 << bit)) {
23737 +                       printk(KERN_NOTICE "\tdecode: %08x %s\n",
23738 +                              1 << bit, trap_cause_strings[bit]);
23739 +               }
23740 +       }
23741 +}
23742 +
23743 +/*
23744 + * trap_print_information()
23745 + *     Print the cause of the trap and additional info.
23746 + */
23747 +static void trap_print_information(const char *str, struct pt_regs *regs)
23748 +{
23749 +       printk(KERN_WARNING "\n");
23750 +
23751 +       if (current) {
23752 +               printk(KERN_WARNING "Process %s (pid: %d)\n",
23753 +                       current->comm, current->pid);
23754 +       }
23755 +
23756 +       if (current && current->mm) {
23757 +               printk(KERN_NOTICE "text = 0x%p-0x%p  data = 0x%p-0x%p\n"
23758 +                       KERN_NOTICE "bss = 0x%p-0x%p   user-stack = 0x%p\n"
23759 +                       KERN_NOTICE "\n",
23760 +                       (void *)current->mm->start_code,
23761 +                       (void *)current->mm->end_code,
23762 +                       (void *)current->mm->start_data,
23763 +                       (void *)current->mm->end_data,
23764 +                       (void *)current->mm->end_data,
23765 +                       (void *)current->mm->brk,
23766 +                       (void *)current->mm->start_stack);
23767 +       }
23768 +
23769 +       printk(KERN_WARNING "%s: Causes: 0x%08x\n", str,
23770 +                       (unsigned int)regs->trap_cause);
23771 +       trap_cause_to_str(regs->trap_cause);
23772 +       show_regs(regs);
23773 +       show_stack(NULL, (unsigned long *)regs->an[7]);
23774 +       printk(KERN_NOTICE "--- End Trap --- \n");
23775 +}
23776 +
23777 +/*
23778 + * dump_stack()
23779 + *     Dump the stack of the current task.
23780 + */
23781 +void dump_stack(void)
23782 +{
23783 +       show_stack(NULL, NULL);
23784 +}
23785 +EXPORT_SYMBOL(dump_stack);
23786 +
23787 +/*
23788 + * show_stack()
23789 + *     Print out information from the current stack.
23790 + */
23791 +void show_stack(struct task_struct *task, unsigned long *sp)
23792 +{
23793 +       /*
23794 +        *  Allocate just enough entries on the stack.
23795 +        */
23796 +       unsigned int calls[TRAP_MAX_STACK_DEPTH];
23797 +       unsigned long code_start = (unsigned long)CONFIG_RAMBASE;
23798 +       unsigned long code_end = (unsigned long)CONFIG_RAMBASE+CONFIG_RAMSIZE;
23799 +       unsigned long ocm_code_start = (unsigned long)&__ocm_text_run_begin;
23800 +       unsigned long ocm_code_end = (unsigned long)&__data_begin;
23801 +       unsigned long stack_end = (unsigned long)(current->stack + THREAD_SIZE - 8);
23802 +       unsigned long stack = (unsigned long)sp;
23803 +       int kernel_stack = 1;
23804 +
23805 +       /*
23806 +        * Which task are we talking about.
23807 +        */
23808 +       if (!task) {
23809 +               task = current;
23810 +       }
23811 +
23812 +       /*
23813 +        * Find the stack for the task if one was not specified.  Otherwise
23814 +        * use the specified stack.
23815 +        */
23816 +       if (!stack) {
23817 +               if (task != current) {
23818 +                       stack = task->thread.sp;
23819 +                       stack_end = (unsigned long)task->stack + THREAD_SIZE - 8;
23820 +               } else {
23821 +                       asm volatile (
23822 +                               "move.4         %0, SP          \n\t"
23823 +                               : "=r" (stack)
23824 +                       );
23825 +               }
23826 +       }
23827 +
23828 +       printk(KERN_NOTICE "Starting backtrace: PID %d '%s'\n",
23829 +                       task->pid, task->comm);
23830 +
23831 +       /*
23832 +        * We do 2 passes the first pass is Kernel stack is the second
23833 +        * User stack.
23834 +        */
23835 +       while (kernel_stack) {
23836 +               unsigned long *handle;
23837 +               unsigned int i, idx = 0;
23838 +               struct pt_regs *pt = task_pt_regs(task);
23839 +
23840 +               /*
23841 +                * If the task is in user mode, reset the start
23842 +                * and end values for text.
23843 +                */
23844 +               if (__user_mode(stack)) {
23845 +                       if (!(task->personality & FDPIC_FUNCPTRS)) {
23846 +                               printk(KERN_NOTICE "  User Stack:\n");
23847 +                               code_start = task->mm->start_code;
23848 +                               code_end = task->mm->end_code;
23849 +                       } else {
23850 +                               printk(KERN_NOTICE "  User Stack (fdpic):\n");
23851 +
23852 +                       }
23853 +                       stack_end = task->mm->start_stack;
23854 +                       ocm_code_end = ocm_code_start = 0;
23855 +                       kernel_stack = 0;
23856 +               } else {
23857 +                       printk(KERN_NOTICE "  Kernel Stack:\n");
23858 +               }
23859 +
23860 +               /*
23861 +                * Collect the stack back trace information.
23862 +                */
23863 +               printk("    code[0x%lx-0x%lx]", code_start, code_end);
23864 +               if (ocm_code_start) {
23865 +                       printk(" ocm_code[0x%lx-0x%lx]",
23866 +                              ocm_code_start, ocm_code_end);
23867 +               }
23868 +               printk("\n    stack[0x%lx-0x%lx]\n", stack, stack_end);
23869 +
23870 +               handle = (unsigned long*)stack;
23871 +               while (idx < TRAP_MAX_STACK_DEPTH) {
23872 +                       calls[idx] = stacktrace_iterate(&handle,
23873 +                                       code_start, code_end,
23874 +                                       ocm_code_start, ocm_code_end,
23875 +                                       (unsigned long)stack, stack_end);
23876 +                       if (calls[idx] == 0) {
23877 +                               break;
23878 +                       }
23879 +                       idx++;
23880 +               }
23881 +
23882 +               /*
23883 +                * Now print out the data.
23884 +                */
23885 +               printk(KERN_NOTICE "  CALL && CALLI on stack:");
23886 +               for (i = 0; i < idx; i++) {
23887 +                       printk("%s0x%x, ", (i & 0x3) == 0 ?  "\n    " : "",
23888 +                                       calls[i]);
23889 +               }
23890 +               printk(idx == TRAP_MAX_STACK_DEPTH ? "...\n" : "\n");
23891 +
23892 +               /*
23893 +                * If we are doing user stack we are done
23894 +                */
23895 +               if (!kernel_stack) {
23896 +                       break;
23897 +               }
23898 +
23899 +               /*
23900 +                * Does this kernel stack have a mm (i.e. is it user)
23901 +                */
23902 +               if (!task->mm) {
23903 +                       printk("No mm for userspace stack.\n");
23904 +                       break;
23905 +               }
23906 +               /*
23907 +                * Get the user-mode stack (if any)
23908 +                */
23909 +               stack = pt->an[7];
23910 +               printk(KERN_NOTICE "Userspace stack at 0x%lx frame type %d\n",
23911 +                               stack, (int)pt->frame_type);
23912 +               if (!__user_mode(stack)) {
23913 +                       break;
23914 +               }
23915 +       }
23916 +}
23917 +
23918 +/*
23919 + * die_if_kernel()
23920 + *     Determine if we are in kernel mode and if so print stuff out and die.
23921 + */
23922 +void die_if_kernel(char *str, struct pt_regs *regs, long trap_cause)
23923 +{
23924 +       unsigned int s3value;
23925 +
23926 +       if (user_mode(regs)) {
23927 +               return;
23928 +       }
23929 +
23930 +       console_verbose();
23931 +       trap_print_information(str, regs);
23932 +
23933 +       /*
23934 +        * If the debugger is attached via the hardware mailbox protocol,
23935 +        * go into an infinite loop and the debugger will figure things out.
23936 +        */
23937 +       asm volatile (
23938 +             "move.4 %0, scratchpad3"
23939 +             : "=r" (s3value)
23940 +       );
23941 +       if (s3value) {
23942 +               asm volatile("1:        jmpt.t 1b");
23943 +       }
23944 +
23945 +       /*
23946 +        * Set the debug taint value.
23947 +        */
23948 +       add_taint(TAINT_DIE);
23949 +       do_exit(SIGSEGV);
23950 +}
23951 +
23952 +/*
23953 + * trap_handler()
23954 + *     Handle traps.
23955 + *
23956 + * Traps are treated as interrupts and registered with the LDSR.  When
23957 + * the LDSR takes the interrupt, it will determine if a trap has occurred
23958 + * and service the trap prior to servicing the interrupt.
23959 + *
23960 + * This function is directly called by the LDSR.
23961 + */
23962 +void trap_handler(int irq, struct pt_regs *regs)
23963 +{
23964 +       int sig = SIGSEGV;
23965 +       siginfo_t info;
23966 +       unsigned int trap_cause = regs->trap_cause;
23967 +
23968 +       BUG_ON(!irqs_disabled());
23969 +
23970 +       /*
23971 +        * test if in kernel and die.
23972 +        */
23973 +       die_if_kernel("Kernel Trap", regs, trap_cause);
23974 +
23975 +       /*
23976 +        * User process problem, setup a signal for this process
23977 +        */
23978 +       if ((trap_cause & (1 << TRAP_CAUSE_DST_RANGE_ERR)) ||
23979 +           (trap_cause & (1 << TRAP_CAUSE_SRC1_RANGE_ERR)) ||
23980 +           (trap_cause & (1 << TRAP_CAUSE_I_RANGE_ERR))) {
23981 +               sig = SIGSEGV;
23982 +               info.si_code = SEGV_MAPERR;
23983 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DST_MISALIGNED)) ||
23984 +                  (trap_cause & (1 << TRAP_CAUSE_SRC1_MISALIGNED))) {
23985 +               sig = SIGBUS;
23986 +               info.si_code = BUS_ADRALN;
23987 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DST_DECODE_ERR)) ||
23988 +                  (trap_cause & (1 << TRAP_CAUSE_SRC1_DECODE_ERR))) {
23989 +               sig = SIGILL;
23990 +               info.si_code = ILL_ILLOPN;
23991 +       } else if ((trap_cause & (1 << TRAP_CAUSE_ILLEGAL_INST))) {
23992 +               /*
23993 +                * Check for software break point and if found signal trap
23994 +                * not illegal instruction.
23995 +                */
23996 +               unsigned long instruction;
23997 +               if (between(regs->pc, CONFIG_RAMBASE,
23998 +                           CONFIG_RAMBASE + CONFIG_RAMSIZE) &&
23999 +                       (regs->pc & 3) == 0 &&
24000 +                       get_user(instruction, (unsigned long *)regs->pc) == 0) {
24001 +
24002 +                       /*
24003 +                        * This used to be 0xaabbccdd but it turns out
24004 +                        * that is now valid in ubicom32v4 isa so we
24005 +                        * have switched to 0xfabbccdd
24006 +                        */
24007 +                       if ((instruction == 0xfabbccdd) ||
24008 +                           (instruction == 0xaabbccdd)) {
24009 +                               sig = SIGTRAP;
24010 +                               info.si_code = TRAP_BRKPT;
24011 +                               goto send_signal;
24012 +                       }
24013 +               }
24014 +               sig = SIGILL;
24015 +               info.si_code = ILL_ILLOPC;
24016 +       } else if ((trap_cause & (1 << TRAP_CAUSE_I_DECODE_ERR))) {
24017 +               sig = SIGILL;
24018 +               info.si_code = ILL_ILLOPC;
24019 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DCAPT))) {
24020 +               sig = SIGTRAP;
24021 +               info.si_code = TRAP_TRACE;
24022 +       }
24023 +
24024 +       /*
24025 +        * Print a trap information block to the console, do not
24026 +        * print this above the case because we don't want it
24027 +        * printed for software break points.
24028 +        */
24029 +       trap_print_information("User Trap", regs);
24030 +
24031 +send_signal:
24032 +
24033 +       force_sig_info(sig, &info, current);
24034 +
24035 +       /*
24036 +        * Interrupts are disabled, re-enable them now.
24037 +        */
24038 +       if (!irqs_disabled()) {
24039 +               printk(KERN_EMERG "interrupts enabled on exit, irq=%d, regs=%p",
24040 +                               irq, regs);
24041 +               BUG();
24042 +       }
24043 +}
24044 +
24045 +/*
24046 + * trap_init_interrupt()
24047 + *     We need a 2nd trap handling init that will occur after init_IRQ().
24048 + */
24049 +void __init trap_init_interrupt(void)
24050 +{
24051 +       int err;
24052 +       unsigned char tirq;
24053 +       struct devtree_node *dn = (struct devtree_node *)tn;
24054 +
24055 +       /*
24056 +        * Now setup the Software IRQ so that if a trap occurs the LDSR
24057 +        * is started.  The irq is there just to "force" the LDSR to run.
24058 +        */
24059 +       if (!tn) {
24060 +               printk(KERN_WARNING "trap_init_interrupt skipped.\n");
24061 +               return;
24062 +       }
24063 +
24064 +       err = devtree_irq(dn, NULL, &tirq);
24065 +       if (err) {
24066 +               printk(KERN_WARNING "error obtaining trap irq value: %d\n",
24067 +                       err);
24068 +               return;
24069 +       }
24070 +
24071 +       if (tirq == DEVTREE_IRQ_NONE) {
24072 +               printk(KERN_WARNING "trap irq not available: %d\n", tirq);
24073 +               return;
24074 +       }
24075 +
24076 +       err = setup_irq(tirq, &trap_irq);
24077 +       if (err) {
24078 +               printk(KERN_WARNING "trap irq setup failed: %d\n", err);
24079 +               return;
24080 +       }
24081 +
24082 +       /*
24083 +        * Let ultra know which thread is handling the traps and
24084 +        * what the interrupt to use is.
24085 +        */
24086 +       tn->intthread = ldsr_get_threadid();
24087 +
24088 +       /*
24089 +        * Tell the LDSR about our IRQ so that it will unsuspend
24090 +        * if one occurs while waiting for the per thread lock.
24091 +        */
24092 +       ldsr_set_trap_irq(tirq);
24093 +}
24094 +
24095 +/*
24096 + * trap_init()
24097 + *     init trap handling
24098 + *
24099 + * Trap handling is done through the ldsr.  Every time an interrupt
24100 + * occurs, the LDSR looks for threads that are listed in the TRAP
24101 + * register and forces a call to the trap handler.
24102 + */
24103 +void __init trap_init(void)
24104 +{
24105 +       /*
24106 +        * If we do not have a trap node in the device tree, we leave the fault
24107 +        * handling to the underlying hardware.
24108 +        */
24109 +       tn = (struct trapnode *)devtree_find_node("traps");
24110 +       if (!tn) {
24111 +               printk(KERN_WARNING "traps are not handled by linux\n");
24112 +               return;
24113 +       }
24114 +}
24115 --- /dev/null
24116 +++ b/arch/ubicom32/kernel/uaccess.c
24117 @@ -0,0 +1,109 @@
24118 +/*
24119 + * arch/ubicom32/include/asm/uaccess.c
24120 + *   User space memory access functions for Ubicom32 architecture.
24121 + *
24122 + * (C) Copyright 2009, Ubicom, Inc.
24123 + *
24124 + * This file is part of the Ubicom32 Linux Kernel Port.
24125 + *
24126 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24127 + * it and/or modify it under the terms of the GNU General Public License
24128 + * as published by the Free Software Foundation, either version 2 of the
24129 + * License, or (at your option) any later version.
24130 + *
24131 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24132 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24133 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24134 + * the GNU General Public License for more details.
24135 + *
24136 + * You should have received a copy of the GNU General Public License
24137 + * along with the Ubicom32 Linux Kernel Port.  If not,
24138 + * see <http://www.gnu.org/licenses/>.
24139 + *
24140 + * Ubicom32 implementation derived from (with many thanks):
24141 + *   arch/m68knommu
24142 + *   arch/blackfin
24143 + *   arch/parisc
24144 + */
24145 +
24146 +#include <linux/sched.h>
24147 +#include <linux/mm.h>
24148 +#include <linux/string.h>
24149 +#include <linux/module.h>
24150 +
24151 +#include <asm/segment.h>
24152 +#include <asm/uaccess.h>
24153 +
24154 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
24155 +
24156 +/*
24157 + * __access_ok()
24158 + *     Check that the address is in the current processes.
24159 + * 
24160 + * NOTE: The kernel uses "pretend" user addresses that wind
24161 + * up calling access_ok() so this approach has only marginal
24162 + * value because you wind up with lots of false positives.
24163 + */
24164 +int __access_ok(unsigned long addr, unsigned long size)
24165 +{
24166 +       // struct vm_area_struct *vma;
24167 +
24168 +       /*
24169 +        * Don't do anything if we are not a running system yet.
24170 +        */
24171 +       if (system_state != SYSTEM_RUNNING) {
24172 +               return 1;
24173 +       }
24174 +
24175 +       /*
24176 +        * It appears that Linux will call this function even when we are not
24177 +        * in the context of a user space application that has a VM address 
24178 +        * space.  So we must check that current and mm are valid before
24179 +        * performing the check.
24180 +        */
24181 +       if ((!current) || (!current->mm)) {
24182 +               return 1;
24183 +       }
24184 +
24185 +       /*
24186 +        * We perform some basic checks on the address to ensure that it
24187 +        * is at least within the range of DRAM.
24188 +        */
24189 +       if ((addr < (int)&_etext) || (addr > memory_end)) {
24190 +               printk(KERN_WARNING "pid=%d[%s]: range [%lx - %lx] not in memory area: [%lx - %lx]\n",
24191 +                       current->pid, current->comm, 
24192 +                       addr, addr + size,
24193 +                       memory_start, memory_end);
24194 +               return 0;
24195 +       }
24196 +
24197 +       /*
24198 +        * For nommu Linux we can check this by looking at the allowed
24199 +        * memory map for the process.
24200 +        *
24201 +        * TODO: Since the kernel passes addresses in it's own space as though
24202 +        * they were user address, we can not validate the addresses this way.
24203 +        */
24204 +#if 0
24205 +       if (!down_read_trylock(&current->mm->mmap_sem)) {
24206 +               return 1;
24207 +       }
24208 +       vma = find_vma(current->mm, addr);
24209 +       if (!vma) {
24210 +               up_read(&current->mm->mmap_sem);
24211 +               printk(KERN_WARNING "pid=%d[%s]: possible invalid acesss on range: [%lx - %lx]\n",
24212 +                               current->pid, current->comm, addr, addr + size);
24213 +               return 1;
24214 +       }
24215 +       if ((addr + size) > vma->vm_end) {
24216 +               up_read(&current->mm->mmap_sem);
24217 +               printk(KERN_WARNING "pid=%d[%s]: possible invalid length on range: [%lx - %lx]\n",
24218 +                               current->pid, current->comm, addr, addr + size);
24219 +               return 1;
24220 +       }
24221 +       up_read(&current->mm->mmap_sem);
24222 +#endif
24223 +       return 1;
24224 +}
24225 +
24226 +EXPORT_SYMBOL(__access_ok);
24227 --- /dev/null
24228 +++ b/arch/ubicom32/kernel/ubicom32_context_switch.S
24229 @@ -0,0 +1,325 @@
24230 +/*
24231 + * arch/ubicom32/kernel/ubicom32_context_switch.S
24232 + *     Implements context switch and return functions.
24233 + *
24234 + * (C) Copyright 2009, Ubicom, Inc.
24235 + *
24236 + * This file is part of the Ubicom32 Linux Kernel Port.
24237 + *
24238 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24239 + * it and/or modify it under the terms of the GNU General Public License
24240 + * as published by the Free Software Foundation, either version 2 of the
24241 + * License, or (at your option) any later version.
24242 + *
24243 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24244 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24245 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24246 + * the GNU General Public License for more details.
24247 + *
24248 + * You should have received a copy of the GNU General Public License
24249 + * along with the Ubicom32 Linux Kernel Port.  If not,
24250 + * see <http://www.gnu.org/licenses/>.
24251 + *
24252 + * Ubicom32 implementation derived from (with many thanks):
24253 + *   arch/m68knommu
24254 + *   arch/blackfin
24255 + *   arch/parisc
24256 + */
24257 +#include <linux/sys.h>
24258 +#include <linux/linkage.h>
24259 +#include <asm/asm-offsets.h>
24260 +#include <asm/ubicom32-common.h>
24261 +#include <asm/ip5000.h>
24262 +#include <asm/range-protect.h>
24263 +
24264 +/*
24265 + * restore_context()
24266 + *     Restore the full context from sp (struct pt_reg *)
24267 + *
24268 + * Note: Recovered PC and CSR are saved on the stack and are to be popped off
24269 + * before returning.
24270 + */
24271 +.macro restore_context
24272 +       move.4  a0, sp                  ; Set up a0 as base address for register recovery
24273 +       move.4  sp, PT_SP(a0)           ; Recover Stack pointer from save area
24274 +       move.4  -4(sp)++, PT_PC(a0)     ; Recover saved PC and save to stack
24275 +       move.4  -4(sp)++, PT_CSR(a0)    ; Recover saved csr and save to stack
24276 +       move.4  d0, PT_D0(a0)
24277 +       move.4  d1, PT_D1(a0)
24278 +       move.4  d2, PT_D2(a0)
24279 +       move.4  d3, PT_D3(a0)
24280 +       move.4  d4, PT_D4(a0)
24281 +       move.4  d5, PT_D5(a0)
24282 +       move.4  d6, PT_D6(a0)
24283 +       move.4  d7, PT_D7(a0)
24284 +       move.4  d8, PT_D8(a0)
24285 +       move.4  d9, PT_D9(a0)
24286 +       move.4  d10, PT_D10(a0)
24287 +       move.4  d11, PT_D11(a0)
24288 +       move.4  d12, PT_D12(a0)
24289 +       move.4  d13, PT_D13(a0)
24290 +       move.4  d14, PT_D14(a0)
24291 +       move.4  d15, PT_D15(a0)
24292 +       move.4  a1, PT_A1(a0)
24293 +       move.4  a2, PT_A2(a0)
24294 +       move.4  a3, PT_A3(a0)
24295 +       move.4  a4, PT_A4(a0)
24296 +       move.4  a5, PT_A5(a0)
24297 +       move.4  a6, PT_A6(a0)
24298 +       move.4  acc0_hi, PT_ACC0HI(a0)
24299 +       move.4  acc0_lo, PT_ACC0LO(a0)
24300 +       move.4  mac_rc16, PT_MAC_RC16(a0)
24301 +       move.4  acc1_hi, PT_ACC1HI(a0)
24302 +       move.4  acc1_lo, PT_ACC1LO(a0)
24303 +       move.4  source3, PT_SOURCE3(a0)
24304 +       move.4  int_mask0, PT_INT_MASK0(a0)
24305 +       move.4  int_mask1, PT_INT_MASK1(a0)
24306 +       move.4  a0, PT_A0(a0)
24307 +.endm
24308 +
24309 +/*
24310 + * ldsr_thread_enable_interrupts()
24311 + *     An assembly version of the enable interrupts function.
24312 + *
24313 + * The stack is fair game but all registers MUST be preserved.
24314 + *
24315 + */
24316 +.macro ldsr_thread_enable_interrupts
24317 +       move.4  -4(sp)++, d3    ; Push d3
24318 +       move.4  -4(sp)++, a3    ; Push a3
24319 +
24320 +       /*
24321 +        * Read the ROSR and obtain ~(1 << tid)
24322 +        */
24323 +       lsr.4   d3, rosr, #0x2  ; Move the thread portion of ROSR into d3
24324 +       lsl.4   d3, #1, d3      ; perform a (1 << tid)
24325 +       not.4   d3, d3          ; Negate the value of d3 == ~(1 << threadid)
24326 +
24327 +       /*
24328 +        * Get the value of the ldsr_soft_irq_mask
24329 +        */
24330 +       moveai  a3, #%hi(ldsr_soft_irq_mask)
24331 +       move.4  a3, %lo(ldsr_soft_irq_mask)(a3)
24332 +
24333 +       /*
24334 +        * Now re-enable interrupts for this thread and then
24335 +        * wakeup the LDSR.
24336 +        */
24337 +       and.4   scratchpad1, scratchpad1, d3
24338 +       move.4  int_set0, a3
24339 +
24340 +       /*
24341 +        * Restore the registers.
24342 +        */
24343 +       move.4  a3, (sp)4++
24344 +       move.4  d3, (sp)4++
24345 +.endm
24346 +
24347 +/*
24348 + * ret_from_interrupt_to_kernel()
24349 + *     RFI function that is where do_IRQ() returns to if the thread was in kernel space.
24350 + */
24351 +       .section .text.ret_from_interrupt_to_kernel
24352 +       .global ret_from_interrupt_to_kernel
24353 +ret_from_interrupt_to_kernel:
24354 +       atomic_lock_acquire             ; Enter critical section
24355 +       restore_context                 ; Restore the thread context
24356 +       atomic_lock_release             ; Leave critical section
24357 +       ldsr_thread_enable_interrupts   ; enable the threads interrupts
24358 +       move.4  csr, (sp)4++            ; Restore csr from the stack
24359 +       ret     (sp)4++
24360 +
24361 +/*
24362 + * ret_from_interrupt_to_user()
24363 + *     RFI function that is where do_IRQ() returns to if the thread was in user space.
24364 + *
24365 + * TODO: Do we really need the ciritical section handling in this code?
24366 + *
24367 + */
24368 +       .section .ret_from_interrupt_to_user.text
24369 +       .global ret_from_interrupt_to_user
24370 +ret_from_interrupt_to_user:
24371 +       ldsr_thread_enable_interrupts                   ; enable the threads interrupts
24372 +       movei   d0, #(~(ASM_THREAD_SIZE-1))
24373 +       and.4   a3, sp, d0                              ; a3 now has the thread info pointer
24374 +
24375 +       /*
24376 +        * Test if the scheduler needs to be called.
24377 +        */
24378 +       btst    TI_FLAGS(a3), #ASM_TIF_NEED_RESCHED
24379 +       jmpeq.t 2f
24380 +       moveai  a5, #%hi(schedule)
24381 +       calli   a5, %lo(schedule)(a5)                   ; Call the scheduler. I will come back here.
24382 +
24383 +       /*
24384 +        * See if we have pending signals and call do_signal
24385 +        * if needed.
24386 +        */
24387 +2:     atomic_lock_acquire                             ; Enter critical section
24388 +       move.4  -4(sp)++, a1                            ; Save A1 on the stack. We are going to use a1 it.
24389 +       movei   d0, #(~(ASM_THREAD_SIZE-1))
24390 +       and.4   a1, sp, d0                              ; a1 now has the thread info pointer
24391 +       btst    TI_FLAGS(a1), #ASM_TIF_SIGPENDING       ; Any signals needed?
24392 +       jmpeq.t 1f
24393 +
24394 +
24395 +       /*
24396 +        * Now call do_signal()
24397 +        */
24398 +       atomic_lock_release                             ; Leave critical section
24399 +       move.4  d0, #0                                  ; oldset pointer is NULL
24400 +       lea.1   d1, 4(sp)                               ; d1 is the regs pointer
24401 +       moveai  a5, #%hi(do_signal)
24402 +       calli   a5, %lo(do_signal)(a5)                  ; Call do_signal()
24403 +
24404 +       /*
24405 +        * Back from do_signal(), re-enter critical section.
24406 +        */
24407 +       atomic_lock_acquire                             ; Enter critical section
24408 +
24409 +1:     move.4  a1, (sp)4++                             ; pop A1 off the stack
24410 +
24411 +       disable_kernel_ranges_for_current d15           ; disable kernel ranges
24412 +
24413 +       restore_context                                 ; restore the previous context
24414 +       atomic_lock_release                             ; Leave critical section
24415 +       move.4  csr, (sp)4++                            ; Restore csr from the stack
24416 +       ret     (sp)4++
24417 +
24418 +/*
24419 + * restore_all_registers()
24420 + *
24421 + * restore_all_registers will be the alternate exit route for
24422 + * preempted processes that have called a signal handler
24423 + * and are returning back to user space.
24424 + */
24425 +       .global restore_all_registers
24426 +restore_all_registers:
24427 +       atomic_lock_acquire                     ; Enter critical section
24428 +       disable_kernel_ranges_for_current d15   ; disable kernel ranges
24429 +       atomic_lock_release                     ; Leave critical section
24430 +       restore_context                         ; restore previous context
24431 +       move.4  csr, (sp)4++                    ; Restore csr from the stack
24432 +       ret     (sp)4++
24433 +
24434 +/*
24435 + * ret_from_fork()
24436 + *     Called on the child's return from fork system call.
24437 + */
24438 +       .section .ret_from_fork.text
24439 +       .global ret_from_fork
24440 +ret_from_fork:
24441 +       ;;;  d0 contains the arg for schedule_tail
24442 +       ;;;  the others we don't care about as they are in PT_REGS (sp)
24443 +       moveai  a5, #%hi(schedule_tail)
24444 +       calli   a5, %lo(schedule_tail)(a5)
24445 +
24446 +       atomic_lock_acquire             ; Enter critical section
24447 +
24448 +       move.4  a3, sp
24449 +       move.4  d0, PT_D0(a3)           ; Restore D0
24450 +       move.4  d1, PT_D1(a3)           ; Restore D1
24451 +       move.4  d2, PT_D2(a3)           ; Restore D2
24452 +       move.4  d3, PT_D3(a3)           ; Restore D3
24453 +       move.4  d10, PT_D10(a3)         ; Restore D10
24454 +       move.4  d11, PT_D11(a3)         ; Restore D11
24455 +       move.4  d12, PT_D12(a3)         ; Restore D12
24456 +       move.4  d13, PT_D13(a3)         ; Restore D13
24457 +       move.4  a1, PT_A1(a3)           ; Restore A1
24458 +       move.4  a2, PT_A2(a3)           ; Restore A2
24459 +       move.4  a5, PT_A5(a3)           ; Restore A5
24460 +       move.4  a6, PT_A6(a3)           ; Restore A6
24461 +       move.4  sp, PT_SP(a3)           ; Restore sp
24462 +       move.4  a4, PT_PC(a3)           ; Restore pc in register a4
24463 +       move.4  PT_FRAME_TYPE(a3), #0   ; Clear frame_type to indicate it is invalid.
24464 +
24465 +       disable_kernel_ranges_for_current d15
24466 +       atomic_lock_release             ; Leave critical section
24467 +       calli   a4, 0(a4)               ; Return.
24468 +
24469 +/*
24470 + * __switch_to()
24471 + *
24472 + * Call with:
24473 + *     void *__switch_to(struct task_struct *prev, struct thread_struct *prev_switch,
24474 + *                             struct thread_struct *next_switch)
24475 + */
24476 +       .global __switch_to
24477 +__switch_to:
24478 +
24479 +       /*
24480 +        * Set up register a3 to point to save area.
24481 +        */
24482 +       movea   a3, d1                  ; a3 now holds prev_switch
24483 +       move.4  (a3)4++, d10
24484 +       move.4  (a3)4++, d11
24485 +       move.4  (a3)4++, d12
24486 +       move.4  (a3)4++, d13
24487 +       move.4  (a3)4++, a1
24488 +       move.4  (a3)4++, a2
24489 +       move.4  (a3)4++, a5
24490 +       move.4  (a3)4++, a6
24491 +       move.4  (a3)4++, a7
24492 +
24493 +       /*
24494 +        * Set up register a3 to point to restore area.
24495 +        */
24496 +       movea   a3, d2                  ; a3 now holds next_switch
24497 +       move.4  d10 , (a3)4++
24498 +       move.4  d11 , (a3)4++
24499 +       move.4  d12 , (a3)4++
24500 +       move.4  d13 , (a3)4++
24501 +       move.4  a1 , (a3)4++
24502 +       move.4  a2 , (a3)4++
24503 +       move.4  a5 , (a3)4++
24504 +       move.4  a6 , (a3)4++
24505 +       move.4  a7 , (a3)4++
24506 +
24507 +       /*
24508 +        * Load the sw_ksp with the proper thread_info pointer.
24509 +        */
24510 +       movei   d15, #(~(ASM_THREAD_SIZE-1))
24511 +       and.4   a3, sp, d15             ; a3 now has the thread info pointer
24512 +       moveai  a4, #%hi(sw_ksp)
24513 +       lea.1   a4, %lo(sw_ksp)(a4)     ; a4 now has the base address of sw_ksp array
24514 +       lsr.4   d15, ROSR, #2           ; Thread number + garbage
24515 +       and.4   d15, #31, D15           ; Mask to get thread number into register D15
24516 +       move.4  (a4, d15), a3           ; Load the thread info pointer into the hw_ksp array..
24517 +
24518 +       /*
24519 +        * We are done with context switch. Time to return..
24520 +        */
24521 +       ret     a5
24522 +
24523 +
24524 +/*
24525 + * ubicom32_emulate_insn()
24526 + *     Emulates the instruction.
24527 + *
24528 + * Call with:
24529 + *     unsigned int ubicom32_emulate_insn(int source1, int source2, int source3, int *save_acc, int *save_csr);
24530 + */
24531 +       .global ubicom32_emulate_insn
24532 +       .global trap_emulate
24533 +ubicom32_emulate_insn:
24534 +       movea   a3, d3          ; a3 holds save_acc pointer
24535 +       movea   a4, d4          ; a4 hods save_csr pointer
24536 +       move.4  source3, d2
24537 +       move.4  acc0_lo, (a3)
24538 +       move.4  acc0_hi, 4(a3)
24539 +       move.4  acc1_lo, 8(a3)
24540 +       move.4  acc1_hi, 12(a3)
24541 +       move.4  mac_rc16, 16(a3)
24542 +       move.4  CSR, (a4)
24543 +       setcsr_flush 0
24544 +
24545 +trap_emulate:
24546 +       move.4  d0, d1
24547 +       setcsr_flush 0
24548 +       move.4  (a4), CSR       ; Save csr
24549 +       move.4  (a3), acc0_lo
24550 +       move.4  4(a3), acc0_hi
24551 +       move.4  8(a3), acc1_lo
24552 +       move.4  12(a3), acc1_hi
24553 +       move.4  16(a3), mac_rc16
24554 +       ret     a5
24555 --- /dev/null
24556 +++ b/arch/ubicom32/kernel/ubicom32_ksyms.c
24557 @@ -0,0 +1,95 @@
24558 +/*
24559 + * arch/ubicom32/kernel/ubicom32_ksyms.c
24560 + *   Ubicom32 architecture compiler support and misc symbols.
24561 + *
24562 + * (C) Copyright 2009, Ubicom, Inc.
24563 + *
24564 + * This file is part of the Ubicom32 Linux Kernel Port.
24565 + *
24566 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24567 + * it and/or modify it under the terms of the GNU General Public License
24568 + * as published by the Free Software Foundation, either version 2 of the
24569 + * License, or (at your option) any later version.
24570 + *
24571 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24572 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24573 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24574 + * the GNU General Public License for more details.
24575 + *
24576 + * You should have received a copy of the GNU General Public License
24577 + * along with the Ubicom32 Linux Kernel Port.  If not,
24578 + * see <http://www.gnu.org/licenses/>.
24579 + *
24580 + * Ubicom32 implementation derived from (with many thanks):
24581 + *   arch/m68knommu
24582 + *   arch/blackfin
24583 + *   arch/parisc
24584 + */
24585 +#include <linux/module.h>
24586 +#include <linux/linkage.h>
24587 +#include <linux/sched.h>
24588 +#include <linux/string.h>
24589 +#include <linux/mm.h>
24590 +#include <linux/user.h>
24591 +#include <linux/elfcore.h>
24592 +#include <linux/in6.h>
24593 +#include <linux/interrupt.h>
24594 +#include <linux/io.h>
24595 +#include <linux/semaphore.h>
24596 +
24597 +#include <asm/setup.h>
24598 +#include <asm/machdep.h>
24599 +#include <asm/pgalloc.h>
24600 +#include <asm/irq.h>
24601 +#include <asm/checksum.h>
24602 +#include <asm/current.h>
24603 +
24604 +/* platform dependent support */
24605 +
24606 +EXPORT_SYMBOL(__ioremap);
24607 +EXPORT_SYMBOL(iounmap);
24608 +
24609 +EXPORT_SYMBOL(ip_fast_csum);
24610 +
24611 +
24612 +/* Networking helper routines. */
24613 +EXPORT_SYMBOL(csum_partial_copy_nocheck);
24614 +
24615 +/* The following are special because they're not called
24616 +   explicitly (the C compiler generates them).  Fortunately,
24617 +   their interface isn't gonna change any time soon now, so
24618 +   it's OK to leave it out of version control.  */
24619 +EXPORT_SYMBOL(memcpy);
24620 +EXPORT_SYMBOL(memset);
24621 +
24622 +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4
24623 +/*
24624 + * libgcc functions - functions that are used internally by the
24625 + * compiler...  (prototypes are not correct though, but that
24626 + * doesn't really matter since they're not versioned).
24627 + */
24628 +extern void __ashldi3(void);
24629 +extern void __ashrdi3(void);
24630 +extern void __divsi3(void);
24631 +extern void __lshrdi3(void);
24632 +extern void __modsi3(void);
24633 +extern void __muldi3(void);
24634 +extern void __udivsi3(void);
24635 +extern void __umodsi3(void);
24636 +
24637 +/* gcc lib functions */
24638 +EXPORT_SYMBOL(__ashldi3);
24639 +EXPORT_SYMBOL(__ashrdi3);
24640 +EXPORT_SYMBOL(__divsi3);
24641 +EXPORT_SYMBOL(__lshrdi3);
24642 +EXPORT_SYMBOL(__modsi3);
24643 +EXPORT_SYMBOL(__muldi3);
24644 +EXPORT_SYMBOL(__udivsi3);
24645 +EXPORT_SYMBOL(__umodsi3);
24646 +#else
24647 +extern void __libgcc_udivmodsi(void);
24648 +extern void __libgcc_divmodsi(void);
24649 +
24650 +EXPORT_SYMBOL(__libgcc_udivmodsi);
24651 +EXPORT_SYMBOL(__libgcc_divmodsi);
24652 +#endif
24653 --- /dev/null
24654 +++ b/arch/ubicom32/kernel/ubicom32_syscall.S
24655 @@ -0,0 +1,643 @@
24656 +/*
24657 + * arch/ubicom32/kernel/ubicom32_syscall.S
24658 + *     <TODO: Replace with short file description>
24659 + *
24660 + * (C) Copyright 2009, Ubicom, Inc.
24661 + *
24662 + * This file is part of the Ubicom32 Linux Kernel Port.
24663 + *
24664 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24665 + * it and/or modify it under the terms of the GNU General Public License
24666 + * as published by the Free Software Foundation, either version 2 of the
24667 + * License, or (at your option) any later version.
24668 + *
24669 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24670 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24671 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24672 + * the GNU General Public License for more details.
24673 + *
24674 + * You should have received a copy of the GNU General Public License
24675 + * along with the Ubicom32 Linux Kernel Port.  If not,
24676 + * see <http://www.gnu.org/licenses/>.
24677 + *
24678 + * Ubicom32 implementation derived from (with many thanks):
24679 + *   arch/m68knommu
24680 + *   arch/blackfin
24681 + *   arch/parisc
24682 + */
24683 +#include <linux/sys.h>
24684 +#include <linux/linkage.h>
24685 +#include <linux/unistd.h>
24686 +
24687 +#include <asm/ubicom32-common.h>
24688 +#include <asm/thread_info.h>
24689 +#include <asm/asm-offsets.h>
24690 +#include <asm/range-protect.h>
24691 +
24692 +/*
24693 + * system_call()
24694 + */
24695 +       .section .syscall_entry.text
24696 +       .global system_call
24697 +system_call:
24698 +       /*
24699 +        * Regular ABI rules for function calls apply for syscall.  d8 holds
24700 +        * the syscall number. We will use that to index into the syscall table.
24701 +        * d0 - d5 hold the parameters.
24702 +        *
24703 +        * First we get the current thread_info and swap to the kernel stack.
24704 +        * This is done by reading the current thread and looking up the ksp
24705 +        * from the sw_ksp array and storing it in a3.
24706 +        *
24707 +        * Then we reserve space for the syscall context a struct pt_regs and
24708 +        * save it using a4 initially and later as sp.
24709 +        * Once sp is set to the kernel sp we can leave the critical section.
24710 +        *
24711 +        * For the user case the kernel stack will have the following layout.
24712 +        *
24713 +        *  a3           ksp[0] +-----------------------+
24714 +        *                      | Thread info area      |
24715 +        *                      | struct thread_info    |
24716 +        *                      +-----------------------+
24717 +        *                      :                       :
24718 +        *                      |   Kernel Stack Area   |
24719 +        *                      |                       |
24720 +        *  a4 / sp >>>         +-----------------------+
24721 +        *                      | Context save area     |
24722 +        *                      | struct pt_reg         |
24723 +        *  ksp[THREAD_SIZE-8]  +-----------------------+
24724 +        *                      | 8 Byte Buffer Zone    |
24725 +        *  ksp[THREAD_SIZE]    +-----------------------+
24726 +
24727 +        *
24728 +        * For kernel syscalls the layout is as follows.
24729 +        *
24730 +        *  a3           ksp[0] +-----------------------+
24731 +        *                      | Thread info area      |
24732 +        *                      | struct thread_info    |
24733 +        *                      +-----------------------+
24734 +        *                      :                       :
24735 +        *                      |   Kernel Stack Area   |
24736 +        *                      |                       |
24737 +        *  a4 / sp >>>         +-----------------------+
24738 +        *                      | Context save area     |
24739 +        *                      | struct pt_reg         |
24740 +        * sp at syscall entry  +-----------------------+
24741 +        *                      | Callers Kernel Stack  |
24742 +        *                      :                       :
24743 +        *
24744 +        * Once the context is saved we optionally call syscall_trace and setup
24745 +        * the exit routine and jump to the syscall.
24746 +        */
24747 +
24748 +       /*
24749 +        * load the base address for sw_ksp into a3
24750 +        * Note.. we cannot access it just yet as protection is still on.
24751 +        */
24752 +       moveai  a3, #%hi(sw_ksp)
24753 +       lea.1   a3, %lo(sw_ksp)(a3)
24754 +
24755 +       /*
24756 +        * Enter critical section .
24757 +        *
24758 +        * The 'critical' aspects here are the switching the to the ksp and
24759 +        * changing the protection registers, these both use per thread
24760 +        * information so we need to protect from a context switch. For now this
24761 +        * is done using the global atomic lock.
24762 +        */
24763 +       atomic_lock_acquire
24764 +
24765 +       thread_get_self d15                     ; Load current thread number
24766 +#ifdef CONFIG_PROTECT_KERNEL
24767 +       lsl.4   d9, #1, d15                     ; Convert to thread bit
24768 +       enable_kernel_ranges d9
24769 +#endif
24770 +       /*
24771 +        * We need to Determine if this is a kernel syscall or user syscall.
24772 +        * Start by loading the pointer for the thread_info structure for the
24773 +        * current process in to a3.
24774 +        */
24775 +       move.4  a3, (a3, d15)                   ; a3 = sw_ksp[d15]
24776 +
24777 +       /*
24778 +        * Now if this is a kernel thread the same value can be a acheived by
24779 +        * masking off the lower bits on the current stack pointer.
24780 +        */
24781 +       movei   d9, #(~(ASM_THREAD_SIZE-1))     ; load mask
24782 +       and.4   d9, sp, d9                      ; apply mask
24783 +
24784 +       /*
24785 +        * d9 now has the masked version of the sp. If this is identical to
24786 +        * what is in a3 then don't switch to ksp as we are already in the
24787 +        * kernel.
24788 +        */
24789 +       sub.4   #0, a3, d9
24790 +
24791 +       /*
24792 +        * if d9 and a3 are not equal. We are usespace and have to shift to
24793 +        * ksp.
24794 +        */
24795 +       jmpne.t 1f
24796 +
24797 +       /*
24798 +        * Kernel Syscall.
24799 +        *
24800 +        * The kernel has called this routine. We have to pdec space for pt_regs
24801 +        * from sp.
24802 +        */
24803 +       pdec    a4, PT_SIZE(sp)                 ; a4 = ksp - PT_SIZE
24804 +       jmpt.t  2f
24805 +
24806 +       /*
24807 +        * Userspace Syscall.
24808 +        *
24809 +        * Add THREAD_SIZE and subtract PT_SIZE to create the proper ksp
24810 +        */
24811 +1:     movei   d15, #(ASM_THREAD_SIZE - 8 - PT_SIZE)
24812 +       lea.1   a4, (a3, d15)                   ; a4 = ksp + d15
24813 +
24814 +       /*
24815 +        * Replace user stack pointer with kernel stack pointer (a4)
24816 +        * Load -1 into frame_type in save area to indicate this is system call
24817 +        * frame.
24818 +        */
24819 +2:     move.4  PT_A7(a4), a7                   ; Save old sp/A7 on kernel stack
24820 +       move.4  PT_FRAME_TYPE(a4), #-1          ; Set the frame type.
24821 +       move.4  sp, a4                          ; Change to ksp.
24822 +       /*
24823 +        * We are now officially back in the kernel!
24824 +        */
24825 +
24826 +       /*
24827 +        * Now that we are on the ksp we can leave the critical section
24828 +        */
24829 +       atomic_lock_release
24830 +
24831 +       /*
24832 +        * We need to save a0 because we need to be able to restore it in
24833 +        * the event that we need to handle a signal.  It's not generally
24834 +        * a callee-saved register but is the GOT pointer.
24835 +        */
24836 +       move.4  PT_A0(sp), a0                   ; Save A0 on kernel stack
24837 +
24838 +       /*
24839 +        * We still need to save d10-d13, a1, a2, a5, a6 in the kernel frame
24840 +        * for this process, we also save the system call params in the case of
24841 +        * syscall restart. (note a7 was saved above)
24842 +        */
24843 +       move.4  PT_A1(sp), a1                   ; Save A1 on kernel stack
24844 +       move.4  PT_A2(sp), a2                   ; Save A2 on kernel stack
24845 +       move.4  PT_A5(sp), a5                   ; Save A5 on kernel stack
24846 +       move.4  PT_A6(sp), a6                   ; Save A6 on kernel stack
24847 +       move.4  PT_PC(sp), a5                   ; Save A5 at the PC location
24848 +       move.4  PT_D10(sp), d10                 ; Save D10 on kernel stack
24849 +       move.4  PT_D11(sp), d11                 ; Save D11 on kernel stack
24850 +       move.4  PT_D12(sp), d12                 ; Save D12 on kernel stack
24851 +       move.4  PT_D13(sp), d13                 ; Save D13 on kernel stack
24852 +
24853 +       /*
24854 +        * Now save the syscall parameters
24855 +        */
24856 +       move.4  PT_D0(sp), d0                   ; Save d0 on kernel stack
24857 +       move.4  PT_ORIGINAL_D0(sp), d0          ; Save d0 on kernel stack
24858 +       move.4  PT_D1(sp), d1                   ; Save d1 on kernel stack
24859 +       move.4  PT_D2(sp), d2                   ; Save d2 on kernel stack
24860 +       move.4  PT_D3(sp), d3                   ; Save d3 on kernel stack
24861 +       move.4  PT_D4(sp), d4                   ; Save d4 on kernel stack
24862 +       move.4  PT_D5(sp), d5                   ; Save d5 on kernel stack
24863 +       /* add this back if we ever have a syscall with 7 args */
24864 +       move.4  PT_D8(sp), d8                   ; Save d8 on kernel stack
24865 +
24866 +       /*
24867 +        * Test if syscalls are being traced and if they are jump to syscall
24868 +        * trace (it will comeback here)
24869 +        */
24870 +       btst    TI_FLAGS(a3), #ASM_TIF_SYSCALL_TRACE
24871 +       jmpne.f .Lsystem_call__trace
24872 +.Lsystem_call__trace_complete:
24873 +       /*
24874 +        * Check for a valid call number [ 0 <= syscall_number < NR_syscalls ]
24875 +        */
24876 +       cmpi    d8, #0
24877 +       jmplt.f 3f
24878 +       cmpi    d8, #NR_syscalls
24879 +       jmplt.t 4f
24880 +
24881 +       /*
24882 +        * They have passed an invalid number. Call sys_ni_syscall staring by
24883 +        * load a4 with the base address of sys_ni_syscall
24884 +        */
24885 +3:     moveai  a4, #%hi(sys_ni_syscall)
24886 +       lea.1   a4, %lo(sys_ni_syscall)(a4)
24887 +       jmpt.t  5f                              ; Jump to regular processing
24888 +
24889 +       /*
24890 +        * Validated syscall, load the syscall table base address into a3 and
24891 +        * read the syscall ptr out.
24892 +        */
24893 +4:     moveai  a3, #%hi(sys_call_table)
24894 +       lea.1   a3, %lo(sys_call_table)(a3)     ; a3 = sys_call_table
24895 +       move.4  a4, (a3, d8)                    ; a4 = sys_call_table[d8]
24896 +
24897 +       /*
24898 +        * Before calling the syscall, setup a5 so that syscall_exit is called
24899 +        * on return from syscall
24900 +        */
24901 +5:     moveai  a5, #%hi(syscall_exit)          ; Setup return address
24902 +       lea.1   a5, %lo(syscall_exit)(a5)       ; from system call
24903 +
24904 +       /*
24905 +        * If the syscall is __NR_rt_rigreturn then we have to test d1 to
24906 +        * figure out if we have to change change the return routine to restore
24907 +        * all registers.
24908 +        */
24909 +       cmpi    d8, #__NR_rt_sigreturn
24910 +       jmpeq.f 6f
24911 +
24912 +       /*
24913 +        * Launch system call (it will return through a5 - syscall_exit)
24914 +        */
24915 +       calli   a3, 0(a4)
24916 +
24917 +       /*
24918 +        * System call is rt_sigreturn. Test d1. If it is 1 we have to
24919 +        * change the return address to restore_all_registers
24920 +        */
24921 +6:     cmpi    d1, #1
24922 +       jmpne.t 7f
24923 +
24924 +       moveai  a5, #%hi(restore_all_registers)  ; Setup return address
24925 +       lea.1   a5, %lo(restore_all_registers)(a5) ; to restore_all_registers.
24926 +
24927 +       /*
24928 +        * Launch system call  (it will return through a5)
24929 +        */
24930 +7:     calli   a3, 0(a4)                        ; Launch system call
24931 +
24932 +.Lsystem_call__trace:
24933 +       /*
24934 +        * Syscalls are being traced.
24935 +        * Call syscall_trace, (return here)
24936 +        */
24937 +       moveai  a4, #%hi(syscall_trace)
24938 +       calli   a5, %lo(syscall_trace)(a4)
24939 +
24940 +       /*
24941 +        * Restore syscall state (it would have been discarded during the
24942 +        * syscall trace)
24943 +        */
24944 +       move.4  d0, PT_D0(sp)                   ; Restore d0 from kernel stack
24945 +       move.4  d1, PT_D1(sp)                   ; Restore d1 from kernel stack
24946 +       move.4  d2, PT_D2(sp)                   ; Restore d2 from kernel stack
24947 +       move.4  d3, PT_D3(sp)                   ; Restore d3 from kernel stack
24948 +       move.4  d4, PT_D4(sp)                   ; Restore d4 from kernel stack
24949 +       move.4  d5, PT_D5(sp)                   ; Restore d5 from kernel stack
24950 +       /* add this back if we ever have a syscall with 7 args */
24951 +       move.4  d8, PT_D8(sp)                   ; Restore d8 from kernel stack
24952 +
24953 +       /*
24954 +        * return to syscall
24955 +        */
24956 +       jmpt.t .Lsystem_call__trace_complete
24957 +       .size system_call, . - system_call
24958 +
24959 +/*
24960 + * syscall_exit()
24961 + */
24962 +       .section .syscall_exit.text
24963 +       .global syscall_exit
24964 +syscall_exit:
24965 +       /*
24966 +        * d0 contains the return value. We should move that into the kernel
24967 +        * stack d0 location.  We will be transitioning from kernel to user
24968 +        * mode. Test the flags and see if we have to call schedule. If we are
24969 +        * going to truly exit then all that has to be done is that from the
24970 +        * kernel stack we have to restore d0, a0, a1, a2, a5, a6 and sp (a7)bb
24971 +        * and then return via a5.
24972 +        */
24973 +
24974 +       /*
24975 +        * Save d0 to pt_regs
24976 +        */
24977 +       move.4  PT_D0(sp), d0                   ; Save d0 into the kernel stack
24978 +
24979 +       /*
24980 +        * load the thread_info structure by masking off the THREAD_SIZE
24981 +        * bits.
24982 +        *
24983 +        * Note: we used to push a1, but now we don't as we are going
24984 +        * to eventually restore it to the userspace a1.
24985 +        */
24986 +       movei   d9, #(~(ASM_THREAD_SIZE-1))
24987 +       and.4   a1, sp, d9
24988 +
24989 +       /*
24990 +        * Are any interesting bits set on TI flags, if there are jump
24991 +        * aside to post_processing.
24992 +        */
24993 +       move.4  d9, #(_TIF_SYSCALL_TRACE | _TIF_NEED_RESCHED | _TIF_SIGPENDING)
24994 +       and.4   #0, TI_FLAGS(a1), d9
24995 +       jmpne.f .Lsyscall_exit__post_processing ; jump to handler
24996 +.Lsyscall_exit__post_processing_complete:
24997 +
24998 +       move.4  d0, PT_D0(sp)                   ; Restore D0 from kernel stack
24999 +       move.4  d1, PT_D1(sp)                   ; Restore d1 from kernel stack
25000 +       move.4  d2, PT_D2(sp)                   ; Restore d2 from kernel stack
25001 +       move.4  d3, PT_D3(sp)                   ; Restore d3 from kernel stack
25002 +       move.4  d4, PT_D4(sp)                   ; Restore d4 from kernel stack
25003 +       move.4  d5, PT_D5(sp)                   ; Restore d5 from kernel stack
25004 +       move.4  d8, PT_D8(sp)                   ; Restore d8 from kernel stack
25005 +       move.4  d10, PT_D10(sp)                 ; Restore d10 from kernel stack
25006 +       move.4  d11, PT_D11(sp)                 ; Restore d11 from kernel stack
25007 +       move.4  d12, PT_D12(sp)                 ; Restore d12 from kernel stack
25008 +       move.4  d13, PT_D13(sp)                 ; Restore d13 from kernel stack
25009 +       move.4  a1, PT_A1(sp)                   ; Restore A1 from kernel stack
25010 +       move.4  a2, PT_A2(sp)                   ; Restore A2 from kernel stack
25011 +       move.4  a5, PT_A5(sp)                   ; Restore A5 from kernel stack
25012 +       move.4  a6, PT_A6(sp)                   ; Restore A6 from kernel stack
25013 +       move.4  a0, PT_A0(sp)                   ; Restore A6 from kernel stack
25014 +
25015 +       /*
25016 +        * this is only for debug, and could be removed for production builds
25017 +        */
25018 +       move.4  PT_FRAME_TYPE(sp), #0           ; invalidate frame_type
25019 +
25020 +#ifdef CONFIG_PROTECT_KERNEL
25021 +       /*
25022 +        * Enter critical section
25023 +        */
25024 +       atomic_lock_acquire
25025 +       disable_kernel_ranges_for_current d15
25026 +#endif
25027 +       /*
25028 +        * Lastly restore userspace stack ptr
25029 +        *
25030 +        * Note: that when protection is on we need to hold the lock around the
25031 +        * stack swap as well because otherwise the protection could get
25032 +        * inadvertently disabled again at the end of a context switch.
25033 +        */
25034 +       move.4  a7, PT_A7(sp)                   ; Restore A7 from kernel stack
25035 +
25036 +       /*
25037 +        * We are now officially back in userspace!
25038 +        */
25039 +
25040 +#ifdef CONFIG_PROTECT_KERNEL
25041 +       /*
25042 +        * Leave critical section and return to user space.
25043 +        */
25044 +       atomic_lock_release
25045 +#endif
25046 +       calli   a5, 0(a5)                       ; Back to userspace code.
25047 +
25048 +       bkpt #-1                                ; we will never get here
25049 +
25050 +       /*
25051 +        * Post syscall processing. (unlikely part of syscall_exit)
25052 +        *
25053 +        * Are we tracing syscalls. If TIF_SYSCALL_TRACE is set, call
25054 +        * syscall_trace routine and return here.
25055 +        */
25056 +.Lsyscall_exit__post_processing:
25057 +       btst    TI_FLAGS(a1), #ASM_TIF_SYSCALL_TRACE
25058 +       jmpeq.t 1f
25059 +       moveai  a5, #%hi(syscall_trace)
25060 +       calli   a5, %lo(syscall_trace)(a5)
25061 +
25062 +       /*
25063 +        * Do we need to resched ie call schedule. If TIF_NEED_RESCHED is set,
25064 +        * call the scheduler, it will come back here.
25065 +        */
25066 +1:     btst    TI_FLAGS(a1), #ASM_TIF_NEED_RESCHED
25067 +       jmpeq.t 2f
25068 +       moveai  a5, #%hi(schedule)
25069 +       calli   a5, %lo(schedule)(a5)
25070 +
25071 +       /*
25072 +        * Do we need to post a signal, if TIF_SIGPENDING is set call the
25073 +        * do_signal.
25074 +        */
25075 +2:     btst    TI_FLAGS(a1), #ASM_TIF_SIGPENDING
25076 +       jmpeq.t .Lsyscall_exit__post_processing_complete
25077 +
25078 +       /*
25079 +        * setup the do signal call
25080 +        */
25081 +       move.4  d0, #0                          ; oldset pointer is NULL
25082 +       lea.1   d1, (sp)                        ; d1 is the regs pointer.
25083 +       moveai  a5, #%hi(do_signal)             ; Have to call do_signal
25084 +       calli   a5, %lo(do_signal)(a5)
25085 +
25086 +       jmpt.t  .Lsyscall_exit__post_processing_complete
25087 +
25088 +       .size syscall_exit, . - syscall_exit
25089 +
25090 +/*
25091 + * kernel_execve()
25092 + *     kernel_execv is called when we the kernel is starting a
25093 + *     userspace application.
25094 + */
25095 +       .section .kernel_unprotected
25096 +       .global kernel_execve
25097 +kernel_execve:
25098 +       move.4  -4(sp)++, a5                    ; Save return address
25099 +       /*
25100 +        * Call execve
25101 +        */
25102 +       movei   d8, #__NR_execve                ; call execve
25103 +       moveai  a3, #%hi(system_call)
25104 +       calli   a5, %lo(system_call)(a3)
25105 +       move.4  a5, (sp)4++
25106 +
25107 +       /*
25108 +        * protection was enabled again at syscall exit, but we want
25109 +        * to return to kernel so we enable it again.
25110 +        */
25111 +#ifdef CONFIG_PROTECT_KERNEL
25112 +       /*
25113 +        * We are entering the kernel so we need to disable the protection.
25114 +        * Enter critical section, disable ranges and leave critical section.
25115 +        */
25116 +       atomic_lock_acquire                     ; Enter critical section
25117 +       enable_kernel_ranges_for_current d15
25118 +       atomic_lock_release                     ; Leave critical section
25119 +#endif
25120 +       ret a5                                  ; jump back to the kernel
25121 +
25122 +       .size kernel_execve, . - kernel_execve
25123 +
25124 +/*
25125 + * signal_trampoline()
25126 + *
25127 + *     Deals with transitioning from to userspace signal handlers and returning
25128 + *     to userspace, only called from the kernel.
25129 + *
25130 + */
25131 +       .section .kernel_unprotected
25132 +       .global signal_trampoline
25133 +signal_trampoline:
25134 +       /*
25135 +        * signal_trampoline is called when we are jumping from the kernel to
25136 +        * the userspace signal handler.
25137 +        *
25138 +        * The following registers are relevant. (set setup_rt_frame)
25139 +        *   sp is the user space stack not the kernel stack
25140 +        *  d0 = signal number
25141 +        *  d1 = siginfo_t *
25142 +        *  d2 = ucontext *
25143 +        *  d3 = the user space signal handler
25144 +        *  a0 is set to the GOT if userspace application is FDPIC, otherwise 0
25145 +        *  a3 is set to the FD for the signal if userspace application is FDPIC
25146 +        */
25147 +#ifdef CONFIG_PROTECT_KERNEL
25148 +       /*
25149 +        * We are leaving the kernel so we need to enable the protection.
25150 +        * Enter critical section, disable ranges and leave critical section.
25151 +        */
25152 +       atomic_lock_acquire                     ; Enter critical section
25153 +       disable_kernel_ranges_for_current d15   ; disable kernel ranges
25154 +       atomic_lock_release                     ; Leave critical section
25155 +#endif
25156 +       /*
25157 +        * The signal handler pointer is in register d3 so tranfer it to a4 and
25158 +        * call it
25159 +        */
25160 +       movea   a4, d3                          ; signal handler
25161 +       calli   a5, 0(a4)
25162 +
25163 +       /*
25164 +        * Return to userspace through rt_syscall which is stored on top of the
25165 +        * stack d1 contains ret_via_interrupt status.
25166 +        */
25167 +       move.4  d8, (sp)                        ; d8 (syscall #) = rt_syscall
25168 +       move.4  d1, 4(sp)                       ; d1 = ret_via_interrupt
25169 +       moveai  a3, #%hi(system_call)           ; call system_call
25170 +       calli   a5, %lo(system_call)(a3)
25171 +
25172 +       bkpt -1                                 ; will never get here.
25173 +       .size signal_trampoline, . - signal_trampoline
25174 +
25175 +/*
25176 + * kernel_thread_helper()
25177 + *
25178 + *     Entry point for kernel threads (only referenced by kernel_thread()).
25179 + *
25180 + *     On execution d0 will be 0, d1 will be the argument to be passed to the
25181 + *     kernel function.
25182 + *     d2 contains the kernel function that needs to get called.
25183 + *     d3 will contain address to do_exit which needs to get moved into a5.
25184 + *
25185 + *     On return from fork the child thread d0 will be 0. We call this dummy
25186 + *     function which in turn loads the argument
25187 + */
25188 +       .section .kernel_unprotected
25189 +       .global kernel_thread_helper
25190 +kernel_thread_helper:
25191 +       /*
25192 +        * Create a kernel thread. This is called from ret_from_vfork (a
25193 +        * userspace return routine) so we need to put it in an unprotected
25194 +        * section and re-enable protection before calling the vector in d2.
25195 +        */
25196 +
25197 +#ifdef CONFIG_PROTECT_KERNEL
25198 +       /*
25199 +        * We are entering the kernel so we need to disable the protection.
25200 +        * Enter critical section, disable ranges and leave critical section.
25201 +        */
25202 +       atomic_lock_acquire                     ; Enter critical section
25203 +       enable_kernel_ranges_for_current d0
25204 +       atomic_lock_release                     ; Leave critical section
25205 +#endif
25206 +       /*
25207 +        * Move argument for kernel function into d0, and set a5 return address
25208 +        * (a5) to do_exit and return through a2
25209 +        */
25210 +       move.4  d0, d1                          ; d0 = arg
25211 +       move.4  a5, d3                          ; a5 = do_exit
25212 +       ret     d2                              ; call function ptr in d2
25213 +
25214 +       .size kernel_thread_helper, . - kernel_thread_helper
25215 +
25216 +/*
25217 + * execve_intercept()
25218 + */
25219 +       .section .text
25220 +       .global execve_intercept
25221 +execve_intercept:
25222 +       move.4  d3, sp  ; Save retrun address
25223 +       moveai  a3, #%hi(sys_execve)
25224 +       calli   a3, %lo(sys_execve)(a3)
25225 +
25226 +       .size execve_intercept, . - execve_intercept
25227 +
25228 +/*
25229 + * vfork_intercept()
25230 + */
25231 +       .section .text
25232 +       .global vfork_intercept
25233 +vfork_intercept:
25234 +       move.4  d0, sp  ; Save pt_regs address
25235 +       moveai  a3, #%hi(sys_vfork)
25236 +       calli   a3, %lo(sys_vfork)(a3)
25237 +
25238 +       .size vfork_intercept, . - vfork_intercept
25239 +
25240 +/*
25241 + * clone_intercept()
25242 + */
25243 +       .section .text
25244 +       .global clone_intercept
25245 +clone_intercept:
25246 +       move.4  d2, sp  ; Save pt_regs address
25247 +       moveai  a3, #%hi(sys_clone)
25248 +       calli   a3, %lo(sys_clone)(a3)
25249 +
25250 +       .size clone_intercept, . - clone_intercept
25251 +
25252 +/*
25253 + * sys_sigsuspend()
25254 + */
25255 +       .section .text
25256 +       .global sys_sigsuspend
25257 +sys_sigsuspend:
25258 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25259 +       moveai  a3, #%hi(do_sigsuspend)
25260 +       calli   a3, %lo(do_sigsuspend)(a3)
25261 +
25262 +       .size sys_sigsuspend, . - sys_sigsuspend
25263 +
25264 +/*
25265 + * sys_rt_sigsuspend()
25266 + */
25267 +       .section .text
25268 +       .global sys_rt_sigsuspend
25269 +sys_rt_sigsuspend:
25270 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25271 +       moveai  a3, #%hi(do_rt_sigsuspend)
25272 +       calli   a3, %lo(do_rt_sigsuspend)(a3)
25273 +
25274 +       .size sys_rt_sigsuspend, . - sys_rt_sigsuspend
25275 +
25276 +/*
25277 + * sys_rt_sigreturn()
25278 + */
25279 +       .section .text
25280 +       .global sys_rt_sigreturn
25281 +sys_rt_sigreturn:
25282 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25283 +       moveai  a3, #%hi(do_rt_sigreturn)
25284 +       calli   a3, %lo(do_rt_sigreturn)(a3)
25285 +
25286 +       .size sys_rt_sigreturn, . - sys_rt_sigreturn
25287 +
25288 +/*
25289 + * sys_sigaltstack()
25290 + */
25291 +       .section .text
25292 +       .global sys_sigaltstack
25293 +sys_sigaltstack:
25294 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25295 +       moveai  a3, #%hi(do_sys_sigaltstack)
25296 +       calli   a3, %lo(do_sys_sigaltstack)(a3)
25297 +
25298 +       .size sys_sigaltstack, . - sys_sigaltstack
25299 --- /dev/null
25300 +++ b/arch/ubicom32/kernel/unaligned_trap.c
25301 @@ -0,0 +1,698 @@
25302 +/*
25303 + * arch/ubicom32/kernel/unaligned_trap.c
25304 + *   Handle unaligned traps in both user or kernel space.
25305 + *
25306 + * (C) Copyright 2009, Ubicom, Inc.
25307 + *
25308 + * This file is part of the Ubicom32 Linux Kernel Port.
25309 + *
25310 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
25311 + * it and/or modify it under the terms of the GNU General Public License
25312 + * as published by the Free Software Foundation, either version 2 of the
25313 + * License, or (at your option) any later version.
25314 + *
25315 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
25316 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
25317 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
25318 + * the GNU General Public License for more details.
25319 + *
25320 + * You should have received a copy of the GNU General Public License
25321 + * along with the Ubicom32 Linux Kernel Port.  If not,
25322 + * see <http://www.gnu.org/licenses/>.
25323 + *
25324 + * Ubicom32 implementation derived from (with many thanks):
25325 + *   arch/m68knommu
25326 + *   arch/blackfin
25327 + *   arch/parisc
25328 + */
25329 +
25330 +#include <linux/types.h>
25331 +#include <linux/kernel.h>
25332 +#include <asm/cacheflush.h>
25333 +#include <asm/traps.h>
25334 +
25335 +#define FALSE 0
25336 +#define TRUE 1
25337 +
25338 +/* no possible trap */
25339 +#define UNUSED 0
25340 +/* possible source operand trap */
25341 +#define SRC 1
25342 +#define SRC_2 2
25343 +/* possible destination operand trap */
25344 +#define DEST 3
25345 +#define DEST_2 4
25346 +/* can be either source or destination or both */
25347 +#define TWO_OP 5
25348 +#define TWO_OP_2 6
25349 +
25350 +/* TODO: What is the real value here, put something in to make it compile for
25351 + * now */
25352 +#define MOVE_2 0x0d
25353 +#define LSL_2  0x11
25354 +#define LSR_2  0x13
25355 +#define MOVEI  0x19
25356 +#define CMPI   0x18
25357 +
25358 +static int op_format[32] =
25359 +{
25360 +       TWO_OP,         /* 0x00 */
25361 +       UNUSED,
25362 +       SRC,
25363 +       UNUSED,
25364 +       TWO_OP,         /* 0x04 */
25365 +       TWO_OP,
25366 +       SRC,
25367 +       UNUSED,
25368 +       TWO_OP_2,       /* 0x08 */
25369 +       TWO_OP,
25370 +       TWO_OP_2,
25371 +       TWO_OP,
25372 +       TWO_OP_2,       /* 0x0C */
25373 +       TWO_OP,
25374 +       TWO_OP_2,
25375 +       TWO_OP,
25376 +       TWO_OP,         /* 0x10 */
25377 +       TWO_OP_2,
25378 +       TWO_OP,
25379 +       TWO_OP,
25380 +       UNUSED,         /* 0x14 */
25381 +       UNUSED,
25382 +       UNUSED,
25383 +       UNUSED,
25384 +       SRC_2,          /* 0x18 */
25385 +       DEST_2,
25386 +       UNUSED,
25387 +       UNUSED,
25388 +       UNUSED,         /* 0x1C */
25389 +       UNUSED,
25390 +       UNUSED,         /* unaligned CALLI will not be fixed. */
25391 +       UNUSED
25392 +};
25393 +
25394 +static int op_0_format[32] =
25395 +{
25396 +       UNUSED,         /* 0x00 */
25397 +       UNUSED,
25398 +       UNUSED,
25399 +       UNUSED,
25400 +       UNUSED,         /* 0x04 - ret don't fix - bad ret is always wrong */
25401 +       UNUSED,
25402 +       UNUSED,
25403 +       UNUSED,
25404 +       UNUSED,         /* 0x08 */
25405 +       UNUSED,
25406 +       TWO_OP,
25407 +       TWO_OP_2,
25408 +       TWO_OP,         /* 0x0c */
25409 +       TWO_OP_2,
25410 +       TWO_OP,
25411 +       UNUSED,         /* .1 can't trap */
25412 +       UNUSED,         /* 0x10 */
25413 +       UNUSED,
25414 +       SRC,
25415 +       UNUSED,
25416 +       UNUSED,         /* 0x14 */
25417 +       TWO_OP_2,
25418 +       UNUSED,
25419 +       UNUSED,
25420 +       UNUSED,         /* 0x18 */
25421 +       UNUSED,
25422 +       UNUSED,
25423 +       UNUSED,
25424 +       DEST,           /* 0x1c */
25425 +       DEST,
25426 +       DEST,
25427 +       DEST,           /* all lea have 32-bit destination */
25428 +};
25429 +
25430 +static int op_2_format[32] =
25431 +{
25432 +       UNUSED,         /* 0x00 */
25433 +       UNUSED,
25434 +       UNUSED,
25435 +       UNUSED,
25436 +       UNUSED,         /* 0x04 */
25437 +       UNUSED,
25438 +       SRC,
25439 +       UNUSED,
25440 +       UNUSED,         /* 0x08 crcgen is .1 */
25441 +       UNUSED,
25442 +       UNUSED,
25443 +       UNUSED,
25444 +       UNUSED,         /* 0x0c */
25445 +       UNUSED,
25446 +       UNUSED,
25447 +       UNUSED,
25448 +       SRC,            /* 0x10 */
25449 +       SRC_2,
25450 +       SRC,
25451 +       SRC_2,
25452 +       SRC,            /* 0x14 */
25453 +       SRC_2,
25454 +       SRC,
25455 +       UNUSED,
25456 +       UNUSED,         /* 0x18 */
25457 +       UNUSED,
25458 +       SRC,
25459 +       UNUSED,
25460 +       SRC,            /* 0x1c */
25461 +       UNUSED,
25462 +       SRC_2,
25463 +       UNUSED,
25464 +};
25465 +
25466 +static int op_6_format[32] =
25467 +{
25468 +       SRC_2,          /* 0x00 */
25469 +       SRC_2,
25470 +       SRC_2,
25471 +       SRC_2,
25472 +       SRC_2,          /* 0x04 */
25473 +       SRC_2,
25474 +       UNUSED,
25475 +       SRC_2,
25476 +       SRC,            /* 0x08 MULS.4 */
25477 +       SRC_2,
25478 +       SRC,
25479 +       UNUSED,
25480 +       UNUSED,         /* 0x0c */
25481 +       UNUSED,
25482 +       UNUSED,
25483 +       UNUSED,
25484 +       SRC,            /* 0x10 */
25485 +       SRC_2,
25486 +       SRC,
25487 +       SRC_2,
25488 +       UNUSED,         /* 0x14 */
25489 +       UNUSED,
25490 +       UNUSED,
25491 +       UNUSED,
25492 +       UNUSED,         /* 0x18 */
25493 +       UNUSED,
25494 +       UNUSED,
25495 +       UNUSED,
25496 +       UNUSED,         /* 0x1c */
25497 +       UNUSED,
25498 +       UNUSED,
25499 +       UNUSED,
25500 +};
25501 +
25502 +/*
25503 + * unaligned_get_address()
25504 + *     get an address using save_an and save_dn registers, and updates save_an
25505 + *     with side effects
25506 + */
25507 +unsigned char *unaligned_get_address(int thread, int specifier, int four_byte,
25508 +                                    unsigned int save_an[],
25509 +                                    unsigned int save_dn[], int *write_back_an)
25510 +{
25511 +       unsigned char *address;
25512 +
25513 +       int areg = (specifier >> 5) & 7;
25514 +       if ((specifier >> 8) == 2) {
25515 +               int offset = specifier & 0xf;
25516 +               offset = ((offset << 28) >> 28);
25517 +               if (likely(four_byte)) {
25518 +                       offset <<= 2;
25519 +               } else {
25520 +                       offset <<= 1;
25521 +               }
25522 +               if (specifier & 0x10) {
25523 +                       address = (unsigned char *)(save_an[areg] + offset);
25524 +               } else {
25525 +                       address = (unsigned char *)save_an[areg];
25526 +               }
25527 +               save_an[areg] = save_an[areg] + offset;
25528 +
25529 +               /*
25530 +                * Let caller know An registers have been modified.
25531 +                */
25532 +               *write_back_an = 1;
25533 +       } else if ((specifier >> 8) == 3) {
25534 +               int dreg = specifier & 0xf;
25535 +               if (likely(four_byte)) {
25536 +                       address = (unsigned char *)(save_an[areg] +
25537 +                                                   (save_dn[dreg] << 2));
25538 +               } else {
25539 +                       address = (unsigned char *)(save_an[areg] +
25540 +                                                   (save_dn[dreg] << 1));
25541 +               }
25542 +       } else {
25543 +               int offset = ((specifier >> 3) & 0x60) | (specifier & 0x1f);
25544 +               if (likely(four_byte)) {
25545 +                       address = (unsigned char *)(save_an[areg] +
25546 +                                                   (offset << 2));
25547 +               } else {
25548 +                       address = (unsigned char *)(save_an[areg] +
25549 +                                                   (offset << 1));
25550 +               }
25551 +       }
25552 +
25553 +       return address;
25554 +}
25555 +
25556 +static int save_dn[16];
25557 +static int save_an[8];
25558 +static int save_acc[5];
25559 +
25560 +/*
25561 + * unaligned_emulate()
25562 + *     emulate the instruction at thread's pc that has taken an unaligned data
25563 + *     trap.
25564 + *
25565 + * source or destination or both might be unaligned
25566 + * the instruction must have a memory source or destination or both
25567 + * the emulated instruction is copied and executed in this thread
25568 + *
25569 + *     TODO: Protection is handled outside of this function
25570 + *     TODO: handling simultaneous unaligned and memory protection traps
25571 + *
25572 + *     Get thread state
25573 + *             the PC and instruction (and local copy, emulate_inst), and An
25574 + *             and Dn registers
25575 + *             All implicit soruce state (source3, CSR, accumulators)
25576 +
25577 + *     if the instruction has a memory source
25578 + *             Use the instruction, An and Dn registers to form src_address
25579 + *             get unaligned source data from src_address (usually sign
25580 + *             extended)
25581 + *                     (2 bytes, with or without sign extension, or 4 bytes)
25582 + *             modify emulate_inst to use d0 as source
25583 + *     else
25584 + *             get the soure operand from one of thread's registers
25585 + *     if instruction has a memory destination
25586 + *             Use the instruction, An and Dn registers to form dest_address
25587 + *             modify emulate_inst to use d0 as destination
25588 + *     if there was a memory source
25589 + *             put the source data in thread's d0
25590 + *     get the source-2 Dn operand and source 3 operand from thread
25591 + *     execute modified inst
25592 + *             (save it, flush caches, set up local values for implicit
25593 + *             sources, execute, save explicit and implicit results)
25594 + *     if inst has destination address
25595 + *             copy result to dest_address, possibly unaligned, 1, 2, or 4
25596 + *             bytes
25597 + *     restore thread's implicit results (modified address registers, CSR,
25598 + *     accumulators) add 4 to thread's pc
25599 + */
25600 +void unaligned_emulate(unsigned int thread)
25601 +{
25602 +       unsigned int pc;
25603 +       unsigned int inst;
25604 +       unsigned int op;
25605 +       unsigned int subop;
25606 +       int format;
25607 +       unsigned int emulate_inst;
25608 +       int four_byte;
25609 +       int src_operand, dest_operand;
25610 +       int save_csr;
25611 +       int source3;
25612 +       unsigned int source1;
25613 +       unsigned int source_data;
25614 +       unsigned char *dest_address = NULL;
25615 +       int source2 = 0;
25616 +       unsigned int result;
25617 +       unsigned int write_back_an = 0;
25618 +       unsigned int chip_id_copy;
25619 +
25620 +       extern unsigned int trap_emulate;
25621 +       extern unsigned int ubicom32_emulate_insn(int source1, int source2,
25622 +                                                 int source3, int *save_acc,
25623 +                                                 int *save_csr);
25624 +
25625 +       /*
25626 +        * get the chip_id
25627 +        */
25628 +       asm volatile (
25629 +       "       move.4          %0, chip_id             \n\t" /* get chip_id. */
25630 +               : "=r"(chip_id_copy)
25631 +               :
25632 +       );
25633 +
25634 +       /*
25635 +        * get the pc
25636 +        */
25637 +       asm volatile (
25638 +       "       move.4          CSR, %1         \n\t" /* set source thread in
25639 +                                                      * CSR */
25640 +       "       setcsr_flush    0               \n\t"
25641 +       "       move.4          %0, pc          \n\t"
25642 +       "       move.4          CSR, #0         \n\t" /* restore CSR */
25643 +       "       setcsr_flush    0               \n\t"
25644 +               : "=a"(pc)
25645 +               : "d" ((1 << 8) | (thread << 9))
25646 +               : "cc"
25647 +       );
25648 +
25649 +       inst = *((unsigned int *)pc);
25650 +       op = inst >> 27;
25651 +       if (unlikely(op == 2 || op == 6)) {
25652 +               subop = (inst >> 21) & 0x1f;
25653 +       } else {
25654 +               subop = (inst >> 11) & 0x1f;
25655 +       }
25656 +       format = op_format[op];
25657 +       emulate_inst = inst;
25658 +
25659 +       if (op == 0) {
25660 +               format = op_0_format[subop];
25661 +       } else if (op == 2) {
25662 +               format = op_2_format[subop];
25663 +       } else if (op == 6) {
25664 +               format = op_6_format[subop];
25665 +       }
25666 +
25667 +       if (unlikely(format == UNUSED)) {
25668 +               /*
25669 +                * We are not going to emulate this. Bump PC by 4 and move on.
25670 +                */
25671 +               asm volatile (
25672 +               "       move.4          CSR, %0                 \n\t"
25673 +               "       setcsr_flush    0                       \n\t"
25674 +               "       move.4          pc, %1                  \n\t"
25675 +               "       setcsr          #0                      \n\t"
25676 +               "       setcsr_flush    0                       \n\t"
25677 +                       :
25678 +                       : "d"((1 << 14) | (thread << 15)), "d"(pc + 4)
25679 +                       : "cc"
25680 +               );
25681 +               return;
25682 +       }
25683 +
25684 +       four_byte = (format == TWO_OP || format == DEST || format == SRC);
25685 +
25686 +       /*
25687 +        * source or destination memory operand needs emulation
25688 +        */
25689 +       src_operand = (format == SRC ||
25690 +                      format == SRC_2 ||
25691 +                      format == TWO_OP ||
25692 +                      format == TWO_OP_2) &&
25693 +               ((inst >> 8) & 7) > 1;
25694 +
25695 +       dest_operand = (format == DEST ||
25696 +                       format == DEST_2 ||
25697 +                       format == TWO_OP ||
25698 +                       format == TWO_OP_2) &&
25699 +               ((inst >> 24) & 7) > 1;
25700 +
25701 +       /*
25702 +        * get thread's implicit sources (not covered by source context select).
25703 +        * data and address registers and CSR (for flag bits) and src3 and
25704 +        * accumulators
25705 +        */
25706 +       asm volatile (
25707 +       "       move.4          CSR, %2         \n\t"   /* set source thread in
25708 +                                                        * CSR */
25709 +       "       setcsr_flush    0               \n\t"
25710 +       "       move.4          (%3), d0        \n\t"   /* get dn registers */
25711 +       "       move.4          4(%3), d1       \n\t"
25712 +       "       move.4          8(%3), d2       \n\t"
25713 +       "       move.4          12(%3), d3      \n\t"
25714 +       "       move.4          16(%3), d4      \n\t"
25715 +       "       move.4          20(%3), d5      \n\t"
25716 +       "       move.4          24(%3), d6      \n\t"
25717 +       "       move.4          28(%3), d7      \n\t"
25718 +       "       move.4          32(%3), d8      \n\t"
25719 +       "       move.4          36(%3), d9      \n\t"
25720 +       "       move.4          40(%3), d10     \n\t"
25721 +       "       move.4          44(%3), d11     \n\t"
25722 +       "       move.4          48(%3), d12     \n\t"
25723 +       "       move.4          52(%3), d13     \n\t"
25724 +       "       move.4          56(%3), d14     \n\t"
25725 +       "       move.4          60(%3), d15     \n\t"
25726 +       "       move.4          (%4), a0        \n\t"   /* get an registers */
25727 +       "       move.4          4(%4), a1       \n\t"
25728 +       "       move.4          8(%4), a2       \n\t"
25729 +       "       move.4          12(%4), a3      \n\t"
25730 +       "       move.4          16(%4), a4      \n\t"
25731 +       "       move.4          20(%4), a5      \n\t"
25732 +       "       move.4          24(%4), a6      \n\t"
25733 +       "       move.4          28(%4), a7      \n\t"
25734 +       "       move.4          %0, CSR         \n\t"   /* get csr and source3
25735 +                                                        * implicit operands */
25736 +       "       move.4          %1, source3     \n\t"
25737 +       "       move.4          (%5), acc0_lo   \n\t"   /* get accumulators */
25738 +       "       move.4          4(%5), acc0_hi  \n\t"
25739 +       "       move.4          8(%5), acc1_lo  \n\t"
25740 +       "       move.4          12(%5), acc1_hi \n\t"
25741 +       "       move.4          16(%5), mac_rc16        \n\t"
25742 +       "       move.4          CSR, #0         \n\t"   /* restore CSR */
25743 +       "       setcsr_flush    0               \n\t"
25744 +               : "=m"(save_csr), "=m"(source3)
25745 +               : "d"((1 << 8) | (thread << 9)),
25746 +                 "a"(save_dn), "a"(save_an), "a"(save_acc)
25747 +               : "cc"
25748 +       );
25749 +
25750 +       /*
25751 +        * turn off thread select bits if they were on
25752 +        */
25753 +       BUG_ON((save_csr & 0x04100) != 0);
25754 +       if (unlikely(save_csr & 0x04100)) {
25755 +               /*
25756 +                * Things are in funny state as thread select bits are on in
25757 +                * csr. PANIC.
25758 +                */
25759 +               panic("In unaligned trap handler. Trap thread CSR has thread "
25760 +                     "select bits on.\n");
25761 +       }
25762 +
25763 +       save_csr = save_csr & 0x1000ff;
25764 +
25765 +       /*
25766 +        * get the source1 operand
25767 +        */
25768 +       source1 = 0;
25769 +       if (src_operand) {
25770 +               unsigned char *src_address;
25771 +
25772 +               /*
25773 +                * source1 comes from memory
25774 +                */
25775 +               BUG_ON(!(format == TWO_OP || format == TWO_OP_2 ||
25776 +                        format == SRC || format == SRC_2));
25777 +               src_address = unaligned_get_address(thread, inst & 0x7ff,
25778 +                                                   four_byte, save_an,
25779 +                                                   save_dn, &write_back_an);
25780 +
25781 +               /*
25782 +                * get data (possibly unaligned)
25783 +                */
25784 +               if (likely(four_byte)) {
25785 +                       source_data = (*src_address << 24) |
25786 +                               (*(src_address + 1) << 16) |
25787 +                               (*(src_address + 2) << 8) |
25788 +                               *(src_address + 3);
25789 +                       source1 = source_data;
25790 +               } else {
25791 +                       source1 = *src_address << 8 |
25792 +                               *(src_address + 1);
25793 +
25794 +                       /*
25795 +                        * Source is not extended if the instrution is MOVE.2 or
25796 +                        * if the cpu CHIP_ID >= 0x30000 and the instruction is
25797 +                        * either LSL.2 or LSR.2.  All other cases have to be
25798 +                        * sign extended.
25799 +                        */
25800 +                       if ((!(op == 2 && subop == MOVE_2)) &&
25801 +                           (!((chip_id_copy >= 0x30000) &&
25802 +                              (subop == LSL_2 || subop == LSR_2)))) {
25803 +                               /*
25804 +                                * Have to sign extend the .2 entry.
25805 +                                */
25806 +                               source1 = ((unsigned int)
25807 +                                          ((signed int)
25808 +                                           ((signed short) source1)));
25809 +                       }
25810 +               }
25811 +       } else if (likely(op != MOVEI)) {
25812 +               /*
25813 +                * source1 comes from a register, using move.4 d0, src1
25814 +                * unaligned_emulate_get_source is pointer to code to insert remulated instruction
25815 +                */
25816 +               extern unsigned int unaligned_emulate_get_src;
25817 +               *((int *)&unaligned_emulate_get_src) &= ~(0x7ff);
25818 +               *((int *)&unaligned_emulate_get_src) |= (inst & 0x7ff);
25819 +               flush_dcache_range((unsigned long)(&unaligned_emulate_get_src),
25820 +                                  (unsigned long)(&unaligned_emulate_get_src) + 4);
25821 +
25822 +               asm volatile (
25823 +                       /* source1 uses thread's registers */
25824 +               "       move.4          CSR, %1                 \n\t"
25825 +               "       setcsr_flush 0                          \n\t"
25826 +               "unaligned_emulate_get_src:                     \n\t"
25827 +               "       move.4  %0, #0                          \n\t"
25828 +               "       setcsr          #0                      \n\t"
25829 +               "       setcsr_flush    0                       \n\t"
25830 +                       : "=d" (source1)
25831 +                       : "d" ((1 << 8) | (thread << 9))
25832 +                       : "cc"
25833 +               );
25834 +       }
25835 +
25836 +       /*
25837 +        * get the destination address
25838 +        */
25839 +       if (dest_operand) {
25840 +               BUG_ON(!(format == TWO_OP || format == TWO_OP_2 ||
25841 +                        format == DEST || format == DEST_2));
25842 +               dest_address = unaligned_get_address(thread,
25843 +                                                    ((inst >> 16) & 0x7ff),
25844 +                                                    four_byte, save_an,
25845 +                                                    save_dn, &write_back_an);
25846 +       }
25847 +
25848 +       if (write_back_an) {
25849 +               /*
25850 +                * restore any modified An registers
25851 +                */
25852 +               asm volatile (
25853 +               "       move.4          CSR, %0                 \n\t"
25854 +               "       setcsr_flush    0                       \n\t"
25855 +               "       move.4          a0, (%1)                \n\t"
25856 +               "       move.4          a1, 4(%1)               \n\t"
25857 +               "       move.4          a2, 8(%1)               \n\t"
25858 +               "       move.4          a3, 12(%1)              \n\t"
25859 +               "       move.4          a4, 16(%1)              \n\t"
25860 +               "       move.4          a5, 20(%1)              \n\t"
25861 +               "       move.4          a6, 24(%1)              \n\t"
25862 +               "       move.4          a7, 28(%1)              \n\t"
25863 +               "       setcsr          #0                      \n\t"
25864 +               "       setcsr_flush    0                       \n\t"
25865 +                       :
25866 +                       : "d" ((1 << 14) | (thread << 15)), "a" (save_an)
25867 +                       : "cc"
25868 +               );
25869 +       }
25870 +
25871 +       /*
25872 +        * get source 2 register if needed, and modify inst to use d1 for
25873 +        * source-2 source-2 will come from this thread, not the trapping thread
25874 +        */
25875 +       source2 = 0;
25876 +       if ((op >= 8 && op <= 0x17) ||
25877 +           ((op == 2 || op == 6) && (inst & 0x4000000))) {
25878 +               int src_dn = (inst >> 11) & 0xf;
25879 +               source2 = save_dn[src_dn];
25880 +               /*
25881 +                * force the emulated instruction to use d1 for source2 operand
25882 +                */
25883 +               emulate_inst = (emulate_inst & 0xffff07ff) | 0x800;
25884 +       }
25885 +
25886 +       if (likely(op != MOVEI)) {
25887 +               /*
25888 +                * change emulated instruction source1 to d0
25889 +                */
25890 +               emulate_inst &= ~0x7ff;
25891 +               emulate_inst |= 1 << 8;
25892 +       }
25893 +
25894 +       if (unlikely(op == 6 || op == 2)) {
25895 +               /*
25896 +                * Set destination to d0
25897 +                */
25898 +               emulate_inst &= ~(0xf << 16);
25899 +       } else if (likely(op != CMPI)) {
25900 +               /*
25901 +                * Set general destination field to d0.
25902 +                */
25903 +               emulate_inst &= ~(0x7ff << 16);
25904 +               emulate_inst |= 1 << 24;
25905 +       }
25906 +
25907 +       /*
25908 +        * execute emulated instruction d0, to d0, no memory access
25909 +        * source2 if needed will be in d1
25910 +        * source3, CSR, and accumulators are set up before execution
25911 +        */
25912 +       *((unsigned int *)&trap_emulate) = emulate_inst;
25913 +       flush_dcache_range((unsigned long)(&trap_emulate),
25914 +                          (unsigned long)(&trap_emulate) + 4);
25915 +
25916 +       result = ubicom32_emulate_insn(source1, source2, source3,
25917 +                                      save_acc, &save_csr);
25918 +
25919 +       /*
25920 +        * set the result value
25921 +        */
25922 +       if (dest_operand) {
25923 +               /*
25924 +                * copy result to memory
25925 +                */
25926 +               if (four_byte) {
25927 +                       *dest_address++ =
25928 +                               (unsigned char)((result >> 24) & 0xff);
25929 +                       *dest_address++ =
25930 +                               (unsigned char)((result >> 16) & 0xff);
25931 +               }
25932 +               *dest_address++ = (unsigned char)((result >> 8) & 0xff);
25933 +               *dest_address = (unsigned char)(result & 0xff);
25934 +       } else if (likely(op != CMPI)) {
25935 +               /*
25936 +                * copy result to a register, using move.4 dest, result
25937 +                */
25938 +               extern unsigned int unaligned_trap_set_result;
25939 +               *((unsigned int *)&unaligned_trap_set_result) &= ~0x7ff0000;
25940 +
25941 +               if (op == 2 || op == 6) {
25942 +                       *((unsigned int *)&unaligned_trap_set_result) |=
25943 +                               ((inst & 0x000f0000) | 0x01000000);
25944 +               } else {
25945 +                       *((unsigned int *)&unaligned_trap_set_result) |=
25946 +                               (inst & 0x7ff0000);
25947 +               }
25948 +               flush_dcache_range((unsigned long)&unaligned_trap_set_result,
25949 +                                  ((unsigned long)(&unaligned_trap_set_result) + 4));
25950 +
25951 +               asm volatile (
25952 +                       /* result uses thread's registers */
25953 +               "       move.4          CSR, %1                 \n\t"
25954 +               "       setcsr_flush 0                          \n\t"
25955 +               "unaligned_trap_set_result:                     \n\t"
25956 +               "       move.4 #0, %0                           \n\t"
25957 +               "       setcsr          #0                      \n\t"
25958 +               "       setcsr_flush    0                       \n\t"
25959 +                       :
25960 +                       : "d"(result), "d" ((1 << 14) | (thread << 15))
25961 +                       : "cc"
25962 +               );
25963 +       }
25964 +
25965 +       /*
25966 +        * bump PC in thread and restore implicit register changes
25967 +        */
25968 +       asm volatile (
25969 +       "       move.4          CSR, %0                 \n\t"
25970 +       "       setcsr_flush    0                       \n\t"
25971 +       "       move.4          pc, %1                  \n\t"
25972 +       "       move.4          acc0_lo, (%3)           \n\t"
25973 +       "       move.4          acc0_hi, 4(%3)          \n\t"
25974 +       "       move.4          acc1_lo, 8(%3)          \n\t"
25975 +       "       move.4          acc1_hi, 12(%3)         \n\t"
25976 +       "       move.4          mac_rc16, 16(%3)        \n\t"
25977 +       "       move.4          CSR, %2                 \n\t"
25978 +       "       setcsr          #0                      \n\t"
25979 +       "       setcsr_flush    0                       \n\t"
25980 +               :
25981 +               : "d"((1 << 14) | (thread << 15)),
25982 +                 "d"(pc + 4), "d"(save_csr), "a"(save_acc)
25983 +               : "cc"
25984 +       );
25985 +}
25986 +
25987 +/*
25988 + * unaligned_only()
25989 + *     Return true if either of the unaligned causes are set (and no others).
25990 + */
25991 +int unaligned_only(unsigned int cause)
25992 +{
25993 +       unsigned int unaligned_cause_mask =
25994 +               (1 << TRAP_CAUSE_DST_MISALIGNED) |
25995 +               (1 << TRAP_CAUSE_SRC1_MISALIGNED);
25996 +
25997 +       BUG_ON(cause == 0);
25998 +       return (cause & unaligned_cause_mask) == cause;
25999 +}
26000 --- /dev/null
26001 +++ b/arch/ubicom32/kernel/vmlinux.lds.S
26002 @@ -0,0 +1,303 @@
26003 +/*
26004 + * arch/ubicom32/kernel/vmlinux.lds.S
26005 + *     vmlinux primary linker script
26006 + *
26007 + * (C) Copyright 2009, Ubicom, Inc.
26008 + *
26009 + * This file is part of the Ubicom32 Linux Kernel Port.
26010 + *
26011 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26012 + * it and/or modify it under the terms of the GNU General Public License
26013 + * as published by the Free Software Foundation, either version 2 of the
26014 + * License, or (at your option) any later version.
26015 + *
26016 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26017 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26018 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26019 + * the GNU General Public License for more details.
26020 + *
26021 + * You should have received a copy of the GNU General Public License
26022 + * along with the Ubicom32 Linux Kernel Port.  If not,
26023 + * see <http://www.gnu.org/licenses/>.
26024 + *
26025 + * Ubicom32 implementation derived from (with many thanks):
26026 + *   arch/m68knommu
26027 + *   arch/blackfin
26028 + *   arch/parisc
26029 + */
26030 +#include <asm-generic/vmlinux.lds.h>
26031 +#include <asm/ocm_size.h>
26032 +#include <asm/thread_info.h>
26033 +#include <linux/threads.h>
26034 +
26035 +/*
26036 + * Sanity checks to prevent errors later on that are much harder to understand
26037 + */
26038 +#if !defined APP_OCM_CODE_SIZE
26039 +#error APP_OCM_CODE_SIZE has not been defined in ocm_size.h
26040 +#endif
26041 +
26042 +#if !defined APP_OCM_DATA_SIZE
26043 +#error APP_OCM_DATA_SIZE has not been defined in ocm_size.h
26044 +#endif
26045 +
26046 +/*
26047 + * XXX Should get these from a common header file, but <asm/ip5000.h> is a mess
26048 + * and can't be included by anything other than C code at the moment.
26049 + */
26050 +/*
26051 + * Memory Size
26052 + */
26053 +#define OCM_SECTOR_SIZE 0x00008000              /* 32K */
26054 +
26055 +#if defined(CONFIG_UBICOM32_V3)
26056 +#define OCMSIZE         0x00030000              /* 192K on-chip RAM for both program and data */
26057 +#elif defined(CONFIG_UBICOM32_V4)
26058 +#define OCMSIZE         0x0003C000              /* 240K on-chip RAM for both program and data */
26059 +#else
26060 +#error "Unknown IP5K silicon"
26061 +#endif
26062 +
26063 +#define OCMSTART        0x3ffc0000              /* alias from 0x03000000 for easy jump to/from SDRAM */
26064 +#define OCMEND          (OCMSTART + OCMSIZE)
26065 +
26066 +/*
26067 + * The `free' ocm area that ultra does not use.
26068 + */
26069 +#if APP_OCM_CODE_SIZE || APP_OCM_DATA_SIZE
26070 +#define OCM_FREE_START (OCMSTART + APP_OCM_CODE_SIZE)
26071 +#define OCM_FREE_LENGTH        (OCMSIZE - APP_OCM_CODE_SIZE - APP_OCM_DATA_SIZE)
26072 +#else
26073 +#define OCM_FREE_START OCMEND
26074 +#define OCM_FREE_LENGTH 0
26075 +#endif
26076 +/*
26077 + * If you want to limit OCM use for text/data or completely disable it you can change these values.
26078 + */
26079 +#define OCM_TEXT_LENGTH        OCM_FREE_LENGTH
26080 +#define OCM_DATA_LENGTH        OCM_FREE_LENGTH
26081 +
26082 +#define        RAM_START       CONFIG_KERNELBASE
26083 +#define        RAM_LENGTH      (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
26084 +#define        TEXT            ram
26085 +#define        DATA            ram
26086 +#define        INIT            ram
26087 +#define        BSS             ram
26088 +
26089 +#ifndef DATA_ADDR
26090 +#define        DATA_ADDR
26091 +#endif
26092 +
26093 +OUTPUT_ARCH(ubicom32)
26094 +ENTRY(_start)
26095 +
26096 +MEMORY {
26097 +       ram             : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
26098 +       ocm             : ORIGIN = OCM_FREE_START, LENGTH = OCM_FREE_LENGTH
26099 +}
26100 +
26101 +jiffies = jiffies_64 + 4;
26102 +
26103 +/*
26104 + * Fixed locations required by gdb coredumps.
26105 + *
26106 + * Note that the names are what gdb is expecting so renaming will break
26107 + * the toolchain.
26108 + */
26109 +__ocm_begin            = OCMSTART;
26110 +__ocm_limit            = __ocm_begin + OCMSIZE;
26111 +__sdram_begin          = CONFIG_RAMBASE;
26112 +__sdram_limit          = __sdram_begin + CONFIG_RAMSIZE;
26113 +__filemedia_begin_addr = 0x60000000;
26114 +__filemedia_end_addr   = __filemedia_begin_addr + 0x00800000;
26115 +
26116 +SECTIONS {
26117 +
26118 +       .fixed_text : {
26119 +               _begin = .;
26120 +               *(.skip_syscall)
26121 +               *(.syscall_entry.text)
26122 +               *(.syscall_exit.text)
26123 +               *(.ret_from_interrupt_to_user.text)
26124 +               *(.ret_from_fork.text)
26125 +               *(.kernel_unprotected)
26126 +               __fixed_text_end = .;
26127 +       } > TEXT
26128 +       . = _begin + SIZEOF(.fixed_text) ;
26129 +
26130 +       __ocm_text_load_begin = .;
26131 +       __ocm_text_run_begin = OCM_FREE_START ;
26132 +       .ocm_text __ocm_text_run_begin : AT(__ocm_text_load_begin) {
26133 +#if OCM_TEXT_LENGTH
26134 +               *(.ocm_text)
26135 +               *(.sched.text)
26136 +               *(.spinlock.text)
26137 +#include <asm/ocm_text.lds.inc>
26138 +               . = ALIGN(4);
26139 +#endif
26140 +               __ocm_text_run_end = .;
26141 +               __data_begin = ALIGN(OCM_SECTOR_SIZE);
26142 +       } > ocm /* .ocm_text */
26143 +
26144 +       .ocm_module_text __ocm_text_run_end (NOLOAD) : AT(__ocm_text_run_end) {
26145 +               __ocm_inst_heap_begin = .;
26146 +               /* Reserve the min requested */
26147 +               . += (CONFIG_OCM_MODULES_RESERVATION) * 1024;
26148 +#ifdef CONFIG_OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
26149 +               /* Round up to OCM sector size (we cannot use it for data) */
26150 +               . = ALIGN(OCM_SECTOR_SIZE);
26151 +#endif
26152 +               __ocm_inst_heap_end = .;
26153 +               /* update __data_begin */
26154 +               __data_begin = ALIGN(OCM_SECTOR_SIZE);
26155 +       } > ocm  /* .ocm_module_text */
26156 +
26157 +       . = __ocm_text_load_begin + __ocm_text_run_end - __ocm_text_run_begin ;
26158 +       __ocm_text_load_end = .;
26159 +
26160 +       __ocm_data_load_begin = .;
26161 +       __ocm_data_run_begin = __data_begin ;
26162 +#if OCM_DATA_LENGTH
26163 +       .ocm_data __ocm_data_run_begin : AT(__ocm_data_load_begin) {
26164 +#if defined(CONFIG_IRQSTACKS_USEOCM)
26165 +               percpu_irq_stacks = .;
26166 +               . += NR_CPUS * THREAD_SIZE;
26167 +#endif
26168 +               *(.ocm_data)
26169 +               . = ALIGN(4) ;
26170 +               __ocm_data_run_end = .;
26171 +       } > ocm
26172 +       . = __ocm_data_load_begin + __ocm_data_run_end - __ocm_data_run_begin ;
26173 +#else
26174 +       __ocm_data_run_end = __ocm_data_run_begin;
26175 +#endif
26176 +       __ocm_data_load_end = .;
26177 +
26178 +       __ocm_free_begin = __ocm_data_run_end;
26179 +       __ocm_free_end = OCM_FREE_START + OCM_FREE_LENGTH;
26180 +
26181 +       .text __ocm_data_load_end : AT(__ocm_data_load_end) {
26182 +               . = ALIGN(4);
26183 +               _stext = .;
26184 +               _text = .;
26185 +               TEXT_TEXT
26186 +               SCHED_TEXT
26187 +               LOCK_TEXT
26188 +               *(.text.lock)
26189 +               *(.text.__libgcc_udivmodsi)
26190 +               *(.text.__libgcc_divmodsi)
26191 +               *(.text.__libgcc_muldi3)
26192 +               *(.text.__libgcc_udivmoddi)
26193 +               *(.text.__libgcc_divmoddi)
26194 +               *(.text.*)
26195 +#if OCM_TEXT_LENGTH == 0
26196 +               *(.ocm_text)
26197 +               *(.sched.text)
26198 +               *(.spinlock.text)
26199 +#endif
26200 +               . = ALIGN(16);          /* Exception table              */
26201 +               __start___ex_table = .;
26202 +               *(__ex_table)
26203 +               __stop___ex_table = .;
26204 +
26205 +       } > TEXT
26206 +
26207 +       RO_DATA(16)
26208 +
26209 +       .rodata : {} > TEXT
26210 +       .rodata1 : {} > TEXT
26211 +       .pci_fixup : {} > TEXT
26212 +       .builtin_fw : {} > TEXT
26213 +       .rio_route : {} > TEXT
26214 +       .tracedata : {} > TEXT
26215 +       __ksymtab : {} > TEXT
26216 +       __ksymtab_gpl : {} > TEXT
26217 +       __ksymtab_gpl_future : {} > TEXT
26218 +       __kcrctab_gpl : {} > TEXT
26219 +       __kcrctab_unused : {} > TEXT
26220 +       __kcrctab_unused_gpl : {} > TEXT
26221 +       __kcrctab_gpl_future : {} > TEXT
26222 +       __ksymtab_strings : {} > TEXT
26223 +       __init_rodata : {} > TEXT
26224 +       __param : {} > TEXT
26225 +
26226 +       _etext = .;
26227 +
26228 +       .data DATA_ADDR : {
26229 +               . = ALIGN(4);
26230 +               _sdata = . ;
26231 +               DATA_DATA
26232 +#if OCM_DATA_LENGTH == 0
26233 +               *(.ocm_data)
26234 +#endif
26235 +               . = ALIGN(8192) ;
26236 +               _data_protection_end = .;
26237 +               *(.data.init_task)
26238 +               . = ALIGN(4);
26239 +               _edata = . ;
26240 +       } > DATA
26241 +
26242 +       .init : {
26243 +               . = ALIGN(4096);
26244 +               __init_begin = .;
26245 +               _sinittext = .;
26246 +               INIT_TEXT
26247 +               _einittext = .;
26248 +               *(.init.rodata)
26249 +               INIT_DATA
26250 +               . = ALIGN(16);
26251 +               __setup_start = .;
26252 +               *(.init.setup)
26253 +               __setup_end = .;
26254 +               __initcall_start = .;
26255 +               INITCALLS
26256 +               __initcall_end = .;
26257 +               __con_initcall_start = .;
26258 +               *(.con_initcall.init)
26259 +               __con_initcall_end = .;
26260 +               ___security_initcall_start = .;
26261 +               *(.security_initcall.init)
26262 +               ___security_initcall_end = .;
26263 +#ifdef CONFIG_BLK_DEV_INITRD
26264 +               . = ALIGN(4);
26265 +               __initramfs_start = .;
26266 +               *(.init.ramfs)
26267 +               __initramfs_end = .;
26268 +#endif
26269 +               . = ALIGN(4096);
26270 +               __per_cpu_start = .;
26271 +                       *(.data.percpu)
26272 +                       *(.data.percpu.shared_aligned)
26273 +               __per_cpu_end = .;
26274 +
26275 +               . = ALIGN(4096);
26276 +               __init_end = .;
26277 +       } > INIT
26278 +
26279 +         .eh_frame   :
26280 +         {
26281 +           PROVIDE (___eh_frame_begin = .);
26282 +           *(.eh_frame)
26283 +           LONG (0);
26284 +           PROVIDE (___eh_frame_end = .);
26285 +         } > INIT
26286 +
26287 +       .bss : {
26288 +               . = ALIGN(4);
26289 +               _sbss = . ;
26290 +               *(.bss)
26291 +               *(COMMON)
26292 +               . = ALIGN(4) ;
26293 +               _ebss = . ;
26294 +               _end = . ;
26295 +       } > BSS
26296 +
26297 +       /DISCARD/ : {
26298 +               EXIT_TEXT
26299 +               EXIT_DATA
26300 +               *(.exitcall.exit)
26301 +       }
26302 +
26303 +       NOTES > BSS
26304 +
26305 +}
26306 --- /dev/null
26307 +++ b/arch/ubicom32/lib/checksum.c
26308 @@ -0,0 +1,250 @@
26309 +/*
26310 + * arch/ubicom32/lib/checksum.c
26311 + *   Optimized checksum utilities for IP.
26312 + *
26313 + * (C) Copyright 2009, Ubicom, Inc.
26314 + *
26315 + * This file is part of the Ubicom32 Linux Kernel Port.
26316 + *
26317 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26318 + * it and/or modify it under the terms of the GNU General Public License
26319 + * as published by the Free Software Foundation, either version 2 of the
26320 + * License, or (at your option) any later version.
26321 + *
26322 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26323 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26324 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26325 + * the GNU General Public License for more details.
26326 + *
26327 + * You should have received a copy of the GNU General Public License
26328 + * along with the Ubicom32 Linux Kernel Port.  If not, 
26329 + * see <http://www.gnu.org/licenses/>.
26330 + *
26331 + * Ubicom32 implementation derived from (with many thanks):
26332 + *   arch/m68knommu
26333 + *   arch/blackfin
26334 + *   arch/parisc
26335 + */
26336 +/*
26337 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
26338 + *             operating system.  INET is implemented using the  BSD Socket
26339 + *             interface as the means of communication with the user level.
26340 + *
26341 + *             IP/TCP/UDP checksumming routines
26342 + *
26343 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
26344 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
26345 + *             Tom May, <ftom@netcom.com>
26346 + *             Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
26347 + *             Lots of code moved from tcp.c and ip.c; see those files
26348 + *             for more names.
26349 + *
26350 + * 03/02/96    Jes Sorensen, Andreas Schwab, Roman Hodek:
26351 + *             Fixed some nasty bugs, causing some horrible crashes.
26352 + *             A: At some points, the sum (%0) was used as
26353 + *             length-counter instead of the length counter
26354 + *             (%1). Thanks to Roman Hodek for pointing this out.
26355 + *             B: GCC seems to mess up if one uses too many
26356 + *             data-registers to hold input values and one tries to
26357 + *             specify d0 and d1 as scratch registers. Letting gcc choose these
26358 + *             registers itself solves the problem.
26359 + *
26360 + *             This program is free software; you can redistribute it and/or
26361 + *             modify it under the terms of the GNU General Public License
26362 + *             as published by the Free Software Foundation; either version
26363 + *             2 of the License, or (at your option) any later version.
26364 + */
26365 +
26366 +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
26367 +   of the assembly has to go. */
26368 +
26369 +#include <linux/module.h>
26370 +#include <net/checksum.h>
26371 +
26372 +static unsigned long do_csum(const unsigned char * buff, int len)
26373 +{
26374 +       int count;
26375 +       unsigned long result = 0;
26376 +
26377 +       /*
26378 +        * The following optimized assembly code cannot handle data length less than 7 bytes!
26379 +        */
26380 +       if (likely(len >= 7)) {
26381 +               len -= (4 - (int)buff) & 3;
26382 +               count = len >> 2;
26383 +               asm (
26384 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26385 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26386 +
26387 +               "       bfextu          d14, %0, #2             \n\t"   // test 2 LSB of buff
26388 +               "       jmpne.w.f       100f                    \n\t"
26389 +               "       add.4           %1, #0, %1              \n\t"   // clear C
26390 +               "       moveai          a3, #%%hi(1f)           \n\t"   // table jump
26391 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26392 +               "       lea.4           a3, (a3,d15)            \n\t"
26393 +               "       calli           a3, 0(a3)               \n\t"
26394 +
26395 +               "100:   sub.4           %0, %0, d14             \n\t"
26396 +               "       sub.4           d14, #4, d14            \n\t"
26397 +               "       lsl.4           d14, d14, #3            \n\t"
26398 +               "       add.4           %1, #0, %1              \n\t"   // clear C
26399 +               "       moveai          a3, #%%hi(1f)           \n\t"   // table jump
26400 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26401 +               "       lea.4           a3, (a3,d15)            \n\t"
26402 +               "       bfextu          %1, (%0)4++, d14        \n\t"   // read first partial word
26403 +               "       calli           a3, 0(a3)               \n\t"
26404 +#if 1
26405 +               "200:   lsl.4           %3, %3, #3              \n\t"
26406 +               "       bfrvrs          d15, (%0), #0           \n\t"   // read last word (partial)
26407 +               "       bfextu          d15, d15, %3            \n\t"
26408 +               "       bfrvrs          d15, d15, #0            \n\t"
26409 +               "       add.4           %1, d15, %1             \n\t"
26410 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26411 +               "       jmpt.w.t        2f                      \n\t"
26412 +#else
26413 +               "200:   move.1          d15, 0(%0)              \n\t"
26414 +               "       lsl.4           d15, d15, #8            \n\t"
26415 +               "       add.4           %1, d15, %1             \n\t"
26416 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26417 +               "       add.4           %3, #-1, %3             \n\t"
26418 +               "       jmpeq.w.t       2f                      \n\t"
26419 +
26420 +               "       move.1          d15, 1(%0)              \n\t"
26421 +               "       add.4           %1, d15, %1             \n\t"
26422 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26423 +               "       add.4           %3, #-1, %3             \n\t"
26424 +               "       jmpeq.w.t       2f                      \n\t"
26425 +
26426 +               "       move.1          d15, 2(%0)              \n\t"
26427 +               "       lsl.4           d15, d15, #8            \n\t"
26428 +               "       add.4           %1, d15, %1             \n\t"
26429 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26430 +               "       jmpt.w.t        2f                      \n\t"
26431 +#endif
26432 +#if defined(IP7000) || defined(IP7000_REV2)
26433 +               "300:   swapb.2         %1, %1                  \n\t"
26434 +#else
26435 +               "300:   shmrg.2         %1, %1, %1              \n\t"
26436 +               "       lsr.4           %1, %1, #8              \n\t"
26437 +               "       bfextu          %1, %1, #16             \n\t"
26438 +#endif
26439 +               "       jmpt.w.t        3f                      \n\t"
26440 +
26441 +               "1:     add.4           %1, (%0)4++, %1         \n\t"   // first add without C
26442 +               "       .rept           31                      \n\t"
26443 +               "       addc            %1, (%0)4++, %1         \n\t"
26444 +               "       .endr                                   \n\t"
26445 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26446 +               "       add.4           %2, #-32, %2            \n\t"
26447 +               "       jmpgt.w.t       1b                      \n\t"
26448 +
26449 +               "       and.4           %3, #3, %3              \n\t"   // check n
26450 +               "       jmpne.w.f       200b                    \n\t"
26451 +
26452 +               "2:     .rept           2                       \n\t"
26453 +               "       lsr.4           d15, %1, #16            \n\t"
26454 +               "       bfextu          %1, %1, #16             \n\t"
26455 +               "       add.4           %1, d15, %1             \n\t"
26456 +               "       .endr                                   \n\t"
26457 +               "       btst            d14, #3                 \n\t"   // start from odd address (<< 3)?
26458 +               "       jmpne.w.f       300b                    \n\t"
26459 +               "3:                                             \n\t"
26460 +
26461 +                       : "+a"(buff), "+d"(result), "+d"(count), "+d"(len)
26462 +                       :
26463 +                       : "d15", "d14", "a3", "cc"
26464 +               );
26465 +
26466 +               return result;
26467 +       }
26468 +
26469 +       /*
26470 +        * handle a few bytes and fold result into 16-bit
26471 +        */
26472 +       while (len-- > 0) {
26473 +               result += (*buff++ << 8);
26474 +               if (len) {
26475 +                       result += *buff++;
26476 +                       len--;
26477 +               }
26478 +       }
26479 +       asm (
26480 +       "       .rept           2                       \n\t"
26481 +       "       lsr.4           d15, %0, #16            \n\t"
26482 +       "       bfextu          %0, %0, #16             \n\t"
26483 +       "       add.4           %0, d15, %0             \n\t"
26484 +       "       .endr                                   \n\t"
26485 +               : "+d" (result)
26486 +               :
26487 +               : "d15", "cc"
26488 +       );
26489 +
26490 +       return result;
26491 +}
26492 +
26493 +/*
26494 + *     This is a version of ip_compute_csum() optimized for IP headers,
26495 + *     which always checksum on 4 octet boundaries.
26496 + */
26497 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
26498 +{
26499 +       return (__force __sum16)~do_csum(iph,ihl*4);
26500 +}
26501 +
26502 +/*
26503 + * computes the checksum of a memory block at buff, length len,
26504 + * and adds in "sum" (32-bit)
26505 + *
26506 + * returns a 32-bit number suitable for feeding into itself
26507 + * or csum_tcpudp_magic
26508 + *
26509 + * this function must be called with even lengths, except
26510 + * for the last fragment, which may be odd
26511 + *
26512 + * it's best to have buff aligned on a 32-bit boundary
26513 + */
26514 +__wsum csum_partial(const void *buff, int len, __wsum sum)
26515 +{
26516 +       unsigned int result = do_csum(buff, len);
26517 +
26518 +       /* add in old sum, and carry.. */
26519 +       result += (__force u32)sum;
26520 +       if ((__force u32)sum > result)
26521 +               result += 1;
26522 +       return (__force __wsum)result;
26523 +}
26524 +
26525 +EXPORT_SYMBOL(csum_partial);
26526 +
26527 +/*
26528 + * this routine is used for miscellaneous IP-like checksums, mainly
26529 + * in icmp.c
26530 + */
26531 +__sum16 ip_compute_csum(const void *buff, int len)
26532 +{
26533 +       return (__force __sum16)~do_csum(buff,len);
26534 +}
26535 +
26536 +/*
26537 + * copy from fs while checksumming, otherwise like csum_partial
26538 + */
26539 +
26540 +__wsum
26541 +csum_partial_copy_from_user(const void __user *src, void *dst,
26542 +                           int len, __wsum sum, int *csum_err)
26543 +{
26544 +       if (csum_err) *csum_err = 0;
26545 +       memcpy(dst, (__force const void *)src, len);
26546 +       return csum_partial(dst, len, sum);
26547 +}
26548 +
26549 +/*
26550 + * copy from ds while checksumming, otherwise like csum_partial
26551 + */
26552 +
26553 +__wsum
26554 +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
26555 +{
26556 +       memcpy(dst, src, len);
26557 +       return csum_partial(dst, len, sum);
26558 +}
26559 --- /dev/null
26560 +++ b/arch/ubicom32/lib/delay.c
26561 @@ -0,0 +1,49 @@
26562 +/*
26563 + * arch/ubicom32/lib/delay.c
26564 + *   Ubicom32 implementation of udelay()
26565 + *
26566 + * (C) Copyright 2009, Ubicom, Inc.
26567 + *
26568 + * This file is part of the Ubicom32 Linux Kernel Port.
26569 + *
26570 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26571 + * it and/or modify it under the terms of the GNU General Public License
26572 + * as published by the Free Software Foundation, either version 2 of the
26573 + * License, or (at your option) any later version.
26574 + *
26575 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26576 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26577 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26578 + * the GNU General Public License for more details.
26579 + *
26580 + * You should have received a copy of the GNU General Public License
26581 + * along with the Ubicom32 Linux Kernel Port.  If not, 
26582 + * see <http://www.gnu.org/licenses/>.
26583 + *
26584 + * Ubicom32 implementation derived from (with many thanks):
26585 + *   arch/m68knommu
26586 + *   arch/blackfin
26587 + *   arch/parisc
26588 + */
26589 +
26590 +#include <linux/module.h>
26591 +#include <asm/param.h>
26592 +#include <asm/delay.h>
26593 +#include <asm/ip5000.h>
26594 +
26595 +/*
26596 + * read_current_timer()
26597 + *     Return the current value of sysval.
26598 + */
26599 +int __devinit read_current_timer(unsigned long *timer_val)
26600 +{
26601 +       *timer_val = (long)(UBICOM32_IO_TIMER->sysval);
26602 +       return 0;
26603 +}
26604 +
26605 +
26606 +void udelay(unsigned long usecs)
26607 +{
26608 +       _udelay(usecs);
26609 +}
26610 +EXPORT_SYMBOL(udelay);
26611 --- /dev/null
26612 +++ b/arch/ubicom32/lib/Makefile
26613 @@ -0,0 +1,32 @@
26614 +#
26615 +# arch/ubicom32/lib/Makefile
26616 +#      <TODO: Replace with short file description>
26617 +#
26618 +# (C) Copyright 2009, Ubicom, Inc.
26619 +#
26620 +# This file is part of the Ubicom32 Linux Kernel Port.
26621 +#
26622 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
26623 +# it and/or modify it under the terms of the GNU General Public License
26624 +# as published by the Free Software Foundation, either version 2 of the
26625 +# License, or (at your option) any later version.
26626 +#
26627 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
26628 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
26629 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26630 +# the GNU General Public License for more details.
26631 +#
26632 +# You should have received a copy of the GNU General Public License
26633 +# along with the Ubicom32 Linux Kernel Port.  If not, 
26634 +# see <http://www.gnu.org/licenses/>.
26635 +#
26636 +# Ubicom32 implementation derived from (with many thanks):
26637 +#   arch/m68knommu
26638 +#   arch/blackfin
26639 +#   arch/parisc
26640 +#
26641 +#
26642 +# Makefile for m68knommu specific library files..
26643 +#
26644 +
26645 +lib-y  := checksum.o delay.o mem_ubicom32.o muldi3.o lshrdi3.o ashldi3.o ashrdi3.o divmod.o
26646 --- /dev/null
26647 +++ b/arch/ubicom32/lib/mem_ubicom32.c
26648 @@ -0,0 +1,242 @@
26649 +/*
26650 + * arch/ubicom32/lib/mem_ubicom32.c
26651 + *   String functions.
26652 + *
26653 + * (C) Copyright 2009, Ubicom, Inc.
26654 + *
26655 + * This file is part of the Ubicom32 Linux Kernel Port.
26656 + *
26657 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26658 + * it and/or modify it under the terms of the GNU General Public License
26659 + * as published by the Free Software Foundation, either version 2 of the
26660 + * License, or (at your option) any later version.
26661 + *
26662 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26663 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26664 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26665 + * the GNU General Public License for more details.
26666 + *
26667 + * You should have received a copy of the GNU General Public License
26668 + * along with the Ubicom32 Linux Kernel Port.  If not,
26669 + * see <http://www.gnu.org/licenses/>.
26670 + *
26671 + * Ubicom32 implementation derived from (with many thanks):
26672 + *   arch/m68knommu
26673 + *   arch/blackfin
26674 + *   arch/parisc
26675 + */
26676 +
26677 +#include <linux/module.h>
26678 +#include <linux/types.h>
26679 +#include <linux/compiler.h>
26680 +
26681 +#define LIKELY likely
26682 +#define UNLIKELY unlikely
26683 +
26684 +typedef u32_t addr_t;
26685 +
26686 +/*
26687 + * memcpy()
26688 + */
26689 +void *memcpy(void *dest, const void *src, size_t n)
26690 +{
26691 +       void *dest_ret = dest;
26692 +
26693 +       if (LIKELY((((addr_t)dest ^ (addr_t)src) & 3) == 0) && LIKELY(n > 6)) {
26694 +               size_t m;
26695 +               n -= (4 - (addr_t)dest) & 0x03;
26696 +               m = n >> 2;
26697 +               asm volatile (
26698 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26699 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26700 +               "       moveai          a3, #%%hi(1f)           \n\t"
26701 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26702 +               "       lea.4           a3, (a3,d15)            \n\t"
26703 +
26704 +               "       bfextu          d15, %0, #2             \n\t"   // d15 = (dest & 3)
26705 +               "       jmpne.w.f       100f                    \n\t"
26706 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
26707 +
26708 +               "100:   cmpi            d15, #2                 \n\t"
26709 +               "       jmpne.s.f       101f                    \n\t"
26710 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26711 +               "       calli           a3, 0(a3)               \n\t"   // 2-byte alignment
26712 +
26713 +               "101:   move.1          (%0)1++, (%1)1++        \n\t"
26714 +               "       jmpgt.s.f       102f                    \n\t"   // 3-byte alignment
26715 +               "       move.2          (%0)2++, (%1)2++        \n\t"   // 1-byte alignment
26716 +               "102:   calli           a3, 0(a3)               \n\t"
26717 +
26718 +               "200:   cmpi            %3, #2                  \n\t"
26719 +               "       jmplt.s.f       201f                    \n\t"
26720 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26721 +               "       jmpeq.s.t       2f                      \n\t"
26722 +               "201:   move.1          (%0)1++, (%1)1++        \n\t"
26723 +               "       jmpt.w.t        2f                      \n\t"
26724 +
26725 +               "1:     .rept           25                      \n\t"
26726 +               "       movea           (%0)4++, (%1)4++        \n\t"
26727 +               "       .endr                                   \n\t"
26728 +               "       .rept           7                       \n\t"
26729 +               "       move.4          (%0)4++, (%1)4++        \n\t"
26730 +               "       .endr                                   \n\t"
26731 +               "       add.4           %2, #-32, %2            \n\t"
26732 +               "       jmpgt.w.f       1b                      \n\t"
26733 +
26734 +               "       and.4           %3, #3, %3              \n\t"   // check n
26735 +               "       jmpne.w.f       200b                    \n\t"
26736 +               "2:                                             \n\t"
26737 +                       : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26738 +                       :
26739 +                       : "d15", "a3", "memory", "cc"
26740 +               );
26741 +
26742 +               return dest_ret;
26743 +       }
26744 +
26745 +       if (LIKELY((((addr_t)dest ^ (addr_t)src) & 1) == 0) && LIKELY(n > 2)) {
26746 +               size_t m;
26747 +               n -= (addr_t)dest & 0x01;
26748 +               m = n >> 1;
26749 +               asm volatile (
26750 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26751 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26752 +               "       moveai          a3, #%%hi(1f)           \n\t"
26753 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26754 +               "       lea.4           a3, (a3,d15)            \n\t"
26755 +
26756 +               "       btst            %0, #0                  \n\t"   // check bit 0
26757 +               "       jmpne.w.f       100f                    \n\t"
26758 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
26759 +
26760 +               "100:   move.1          (%0)1++, (%1)1++        \n\t"
26761 +               "       calli           a3, 0(a3)               \n\t"
26762 +
26763 +               "200:   move.1          (%0)1++, (%1)1++        \n\t"
26764 +               "       jmpt.w.t        2f                      \n\t"
26765 +
26766 +               "1:     .rept           32                      \n\t"
26767 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26768 +               "       .endr                                   \n\t"
26769 +               "       add.4           %2, #-32, %2            \n\t"
26770 +               "       jmpgt.w.f       1b                      \n\t"
26771 +
26772 +               "       and.4           %3, #1, %3              \n\t"   // check n
26773 +               "       jmpne.w.f       200b                    \n\t"
26774 +               "2:                                             \n\t"
26775 +
26776 +                       : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26777 +                       :
26778 +                       : "d15", "a3", "memory", "cc"
26779 +               );
26780 +
26781 +               return dest_ret;
26782 +       }
26783 +
26784 +       asm volatile (
26785 +       "       sub.4           d15, #0, %2             \n\t"
26786 +       "       jmpeq.w.f       2f                      \n\t"
26787 +       "       and.4           d15, #(16-1), d15       \n\t"   // d15 = (-n) & (16 - 1)
26788 +       "       moveai          a3, #%%hi(1f)           \n\t"
26789 +       "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26790 +       "       lea.4           a3, (a3,d15)            \n\t"
26791 +       "       calli           a3, 0(a3)               \n\t"
26792 +
26793 +       "1:     .rept           16                      \n\t"
26794 +       "       move.1          (%0)1++, (%1)1++        \n\t"
26795 +       "       .endr                                   \n\t"
26796 +       "       add.4           %2, #-16, %2            \n\t"
26797 +       "       jmpgt.w.f       1b                      \n\t"
26798 +       "2:                                             \n\t"
26799 +
26800 +               : "+a" (dest), "+a" (src), "+d" (n)
26801 +               :
26802 +               : "d15", "a3", "memory", "cc"
26803 +       );
26804 +
26805 +       return dest_ret;
26806 +}
26807 +
26808 +/*
26809 + * memset()
26810 + */
26811 +void *memset(void *s, int c, size_t n)
26812 +{
26813 +       void *s_ret = s;
26814 +
26815 +       if (LIKELY(n > 6)) {
26816 +               size_t m;
26817 +               n -= (4 - (addr_t)s) & 0x03;
26818 +               m = n >> 2;
26819 +               asm volatile (
26820 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26821 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26822 +               "       shmrg.1         %1, %1, %1              \n\t"
26823 +               "       shmrg.2         %1, %1, %1              \n\t"   // %1 = (c<<24)|(c<<16)|(c<<8)|c
26824 +               "       moveai          a3, #%%hi(1f)           \n\t"
26825 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26826 +               "       lea.4           a3, (a3,d15)            \n\t"
26827 +
26828 +               "       bfextu          d15, %0, #2             \n\t"   // d15 = (s & 3)
26829 +               "       jmpne.w.f       100f                    \n\t"
26830 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
26831 +
26832 +               "100:   cmpi            d15, #2                 \n\t"
26833 +               "       jmpne.s.f       101f                    \n\t"
26834 +               "       move.2          (%0)2++, %1             \n\t"
26835 +               "       calli           a3, 0(a3)               \n\t"   // 2-byte alignment
26836 +
26837 +               "101:   move.1          (%0)1++, %1             \n\t"
26838 +               "       jmpgt.s.f       102f                    \n\t"   // 3-byte alignment
26839 +               "       move.2          (%0)2++, %1             \n\t"   // 1-byte alignment
26840 +               "102:   calli           a3, 0(a3)               \n\t"
26841 +
26842 +               "200:   cmpi            %3, #2                  \n\t"
26843 +               "       jmplt.s.f       201f                    \n\t"
26844 +               "       move.2          (%0)2++, %1             \n\t"
26845 +               "       jmpeq.s.t       2f                      \n\t"
26846 +               "201:   move.1          (%0)1++, %1             \n\t"
26847 +               "       jmpt.w.t        2f                      \n\t"
26848 +
26849 +               "1:     .rept           25                      \n\t"
26850 +               "       movea           (%0)4++, %1             \n\t"
26851 +               "       .endr                                   \n\t"
26852 +               "       .rept           7                       \n\t"
26853 +               "       move.4          (%0)4++, %1             \n\t"
26854 +               "       .endr                                   \n\t"
26855 +               "       add.4           %2, #-32, %2            \n\t"
26856 +               "       jmpgt.w.f       1b                      \n\t"
26857 +
26858 +               "       and.4           %3, #3, %3              \n\t"   // test bit 1 of n
26859 +               "       jmpne.w.f       200b                    \n\t"
26860 +               "2:                                             \n\t"
26861 +
26862 +                       : "+a" (s), "+d" (c), "+d" (m), "+d" (n)
26863 +                       :
26864 +                       : "d15", "a3", "memory", "cc"
26865 +               );
26866 +
26867 +               return s_ret;
26868 +       }
26869 +
26870 +       asm volatile (
26871 +       "       sub.4           d15, #0, %2             \n\t"
26872 +       "       jmpeq.w.f       2f                      \n\t"
26873 +       "       and.4           d15, #(8-1), d15        \n\t"   // d15 = (-%2) & (16 - 1)
26874 +       "       moveai          a3, #%%hi(1f)           \n\t"
26875 +       "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26876 +       "       lea.4           a3, (a3,d15)            \n\t"
26877 +       "       calli           a3, 0(a3)               \n\t"
26878 +
26879 +       "1:     .rept           8                       \n\t"
26880 +       "       move.1          (%0)1++, %1             \n\t"
26881 +       "       .endr                                   \n\t"
26882 +       "2:                                             \n\t"
26883 +
26884 +               : "+a" (s), "+d" (c), "+d" (n)
26885 +               :
26886 +               : "d15", "a3", "memory", "cc"
26887 +       );
26888 +
26889 +       return s_ret;
26890 +}
26891 --- /dev/null
26892 +++ b/arch/ubicom32/mach-common/audio_tio.c
26893 @@ -0,0 +1,115 @@
26894 +/*
26895 + * arch/ubicom32/mach-common/audio_tio.c
26896 + *   Generic initialization for Ubicom32 Audio
26897 + *
26898 + * (C) Copyright 2009, Ubicom, Inc.
26899 + *
26900 + * This file is part of the Ubicom32 Linux Kernel Port.
26901 + *
26902 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26903 + * it and/or modify it under the terms of the GNU General Public License
26904 + * as published by the Free Software Foundation, either version 2 of the
26905 + * License, or (at your option) any later version.
26906 + *
26907 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26908 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26909 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26910 + * the GNU General Public License for more details.
26911 + *
26912 + * You should have received a copy of the GNU General Public License
26913 + * along with the Ubicom32 Linux Kernel Port.  If not,
26914 + * see <http://www.gnu.org/licenses/>.
26915 + */
26916 +
26917 +#include <linux/platform_device.h>
26918 +#include <linux/types.h>
26919 +
26920 +#include <asm/devtree.h>
26921 +#include <asm/audio_tio.h>
26922 +#include <asm/ubi32-pcm.h>
26923 +
26924 +/*
26925 + * The number of audio_tio's currently allocated, used for .id
26926 + */
26927 +static int __initdata audio_tio_count;
26928 +
26929 +/*
26930 + * The maximum number of resources that the audio_tio will have.
26931 + * Currently 3, a register space, and up to 2 interrupts.
26932 + */
26933 +#define AUDIO_TIO_MAX_RESOURCES        3
26934 +
26935 +/*
26936 + * audio_tio_alloc
26937 + *     Checks the device tree and allocates a platform_device if found
26938 + */
26939 +struct platform_device * __init audio_tio_alloc(const char *driver_name, 
26940 +               const char *node_name, int priv_bytes)
26941 +{
26942 +       struct platform_device *pdev;
26943 +       struct resource *res;
26944 +       struct audiotionode *audio_node;
26945 +       struct ubi32pcm_platform_data *pdata;
26946 +
26947 +       /*
26948 +        * Check the device tree for the audio_tio
26949 +        */
26950 +       audio_node = (struct audiotionode *)devtree_find_node(node_name);
26951 +       if (!audio_node) {
26952 +               printk(KERN_WARNING "audio TIO '%s' found\n", node_name);
26953 +               return NULL;
26954 +       }
26955 +
26956 +       if (audio_node->version != AUDIOTIONODE_VERSION) {
26957 +               printk(KERN_WARNING "audio_tio not compatible\n");
26958 +               return NULL;
26959 +       }
26960 +
26961 +       /*
26962 +        * Dynamically create the platform_device structure and resources
26963 +        */
26964 +       pdev = kzalloc(sizeof(struct platform_device) + 
26965 +                      sizeof(struct ubi32pcm_platform_data) + 
26966 +                      priv_bytes , GFP_KERNEL);
26967 +       if (!pdev) {
26968 +               printk(KERN_WARNING "audio_tio could not alloc pdev\n");
26969 +               return NULL;
26970 +       }
26971 +
26972 +       res = kzalloc(sizeof(struct resource) * AUDIO_TIO_MAX_RESOURCES,
26973 +                       GFP_KERNEL);
26974 +       if (!res) {
26975 +               kfree(pdev);
26976 +               printk(KERN_WARNING "audio_tio could not alloc res\n");
26977 +               return NULL;
26978 +       }
26979 +
26980 +       pdev->name = driver_name;
26981 +       pdev->id = audio_tio_count++;
26982 +       pdev->resource = res;
26983 +
26984 +       /*
26985 +        * Fill in the resources and platform data from devtree information
26986 +        */
26987 +       res[0].start = (u32_t)(audio_node->regs);
26988 +       res[0].end = (u32_t)(audio_node->regs);
26989 +       res[0].flags = IORESOURCE_MEM;
26990 +       res[1 + AUDIOTIO_TX_IRQ_RESOURCE].start = audio_node->dn.sendirq;
26991 +       res[1 + AUDIOTIO_TX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
26992 +       res[1 + AUDIOTIO_RX_IRQ_RESOURCE].start = audio_node->dn.recvirq;
26993 +       res[1 + AUDIOTIO_RX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
26994 +       pdev->num_resources = 3;
26995 +
26996 +       printk(KERN_INFO "AudioTIO.%d '%s' found irq=%d/%d regs=%p pdev=%p/%p\n",
26997 +               audio_tio_count - 1, node_name, audio_node->dn.sendirq,
26998 +               audio_node->dn.recvirq, audio_node->regs, pdev, res);
26999 +       pdata = (struct ubi32pcm_platform_data *)(pdev + 1);
27000 +       pdev->dev.platform_data = pdata;
27001 +       pdata->node_name = node_name;
27002 +       if (priv_bytes) {
27003 +               pdata->priv_data = pdata + 1;
27004 +       }
27005 +
27006 +       return pdev;
27007 +}
27008 +
27009 --- /dev/null
27010 +++ b/arch/ubicom32/mach-common/board.c
27011 @@ -0,0 +1,63 @@
27012 +/*
27013 + * arch/ubicom32/mach-common/board.c
27014 + *   Board init and support code.
27015 + *
27016 + * (C) Copyright 2009, Ubicom, Inc.
27017 + *
27018 + * This file is part of the Ubicom32 Linux Kernel Port.
27019 + *
27020 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27021 + * it and/or modify it under the terms of the GNU General Public License
27022 + * as published by the Free Software Foundation, either version 2 of the
27023 + * License, or (at your option) any later version.
27024 + *
27025 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27026 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27027 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27028 + * the GNU General Public License for more details.
27029 + *
27030 + * You should have received a copy of the GNU General Public License
27031 + * along with the Ubicom32 Linux Kernel Port.  If not,
27032 + * see <http://www.gnu.org/licenses/>.
27033 + *
27034 + * Ubicom32 implementation derived from (with many thanks):
27035 + *   arch/m68knommu
27036 + *   arch/blackfin
27037 + *   arch/parisc
27038 + */
27039 +#include <linux/module.h>
27040 +#include <linux/types.h>
27041 +#include <linux/cpu.h>
27042 +#include <asm/devtree.h>
27043 +
27044 +struct boardnode {
27045 +       struct devtree_node dn;
27046 +       const char *revision;
27047 +};
27048 +
27049 +static const struct boardnode *bn;
27050 +
27051 +/*
27052 + * board_get_revision()
27053 + *     Returns revision string of the board.
27054 + */
27055 +const char *board_get_revision(void)
27056 +{
27057 +       if (!bn) {
27058 +               return "NULL";
27059 +       }
27060 +
27061 +       return bn->revision;
27062 +}
27063 +
27064 +/*
27065 + * board_init
27066 + */
27067 +void __init board_init(void)
27068 +{
27069 +       bn = (struct boardnode *)devtree_find_node("board");
27070 +       if (!bn) {
27071 +               printk(KERN_WARNING "board node not found\n");
27072 +               return;
27073 +       }
27074 +}
27075 --- /dev/null
27076 +++ b/arch/ubicom32/mach-common/bootargs.c
27077 @@ -0,0 +1,63 @@
27078 +/*
27079 + * arch/ubicom32/mach-common/bootargs.c
27080 + *   Board init and support code.
27081 + *
27082 + * (C) Copyright 2009, Ubicom, Inc.
27083 + *
27084 + * This file is part of the Ubicom32 Linux Kernel Port.
27085 + *
27086 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27087 + * it and/or modify it under the terms of the GNU General Public License
27088 + * as published by the Free Software Foundation, either version 2 of the
27089 + * License, or (at your option) any later version.
27090 + *
27091 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27092 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27093 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27094 + * the GNU General Public License for more details.
27095 + *
27096 + * You should have received a copy of the GNU General Public License
27097 + * along with the Ubicom32 Linux Kernel Port.  If not,
27098 + * see <http://www.gnu.org/licenses/>.
27099 + *
27100 + * Ubicom32 implementation derived from (with many thanks):
27101 + *   arch/m68knommu
27102 + *   arch/blackfin
27103 + *   arch/parisc
27104 + */
27105 +#include <linux/module.h>
27106 +#include <linux/types.h>
27107 +#include <linux/cpu.h>
27108 +#include <asm/devtree.h>
27109 +
27110 +struct bootargsnode {
27111 +       struct devtree_node dn;
27112 +       const char cmdline[512];
27113 +};
27114 +
27115 +static const struct bootargsnode *ban;
27116 +
27117 +/*
27118 + * bootargs_get_cmdline()
27119 + *     Returns kernel boot arguments set by the bootloader.
27120 + */
27121 +const char *bootargs_get_cmdline(void)
27122 +{
27123 +       if (!ban) {
27124 +               return "";
27125 +       }
27126 +
27127 +       return ban->cmdline;
27128 +}
27129 +
27130 +/*
27131 + * bootargs_init
27132 + */
27133 +void __init bootargs_init(void)
27134 +{
27135 +       ban = (struct bootargsnode *)devtree_find_node("bootargs");
27136 +       if (!ban) {
27137 +               printk(KERN_WARNING "bootargs node not found\n");
27138 +               return;
27139 +       }
27140 +}
27141 --- /dev/null
27142 +++ b/arch/ubicom32/mach-common/cachectl.c
27143 @@ -0,0 +1,125 @@
27144 +/*
27145 + * arch/ubicom32/mach-common/cachectl.c
27146 + *   Architecture cache control support
27147 + *
27148 + * (C) Copyright 2009, Ubicom, Inc.
27149 + *
27150 + * This file is part of the Ubicom32 Linux Kernel Port.
27151 + *
27152 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27153 + * it and/or modify it under the terms of the GNU General Public License
27154 + * as published by the Free Software Foundation, either version 2 of the
27155 + * License, or (at your option) any later version.
27156 + *
27157 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27158 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27159 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27160 + * the GNU General Public License for more details.
27161 + *
27162 + * You should have received a copy of the GNU General Public License
27163 + * along with the Ubicom32 Linux Kernel Port.  If not,
27164 + * see <http://www.gnu.org/licenses/>.
27165 + *
27166 + * Ubicom32 implementation derived from (with many thanks):
27167 + *   arch/m68knommu
27168 + *   arch/blackfin
27169 + *   arch/parisc
27170 + */
27171 +
27172 +#include <linux/types.h>
27173 +#include <linux/module.h>
27174 +#include <asm/cachectl.h>
27175 +
27176 +/*
27177 + * The write queue flush procedure in mem_cache_control needs to make
27178 + * DCACHE_WRITE_QUEUE_LENGTH writes to DDR (not OCM). Here we reserve some
27179 + * memory for this operation.
27180 + * Allocate array of cache lines of least DCACHE_WRITE_QUEUE_LENGTH + 1 words in
27181 + * length rounded up to the nearest cache line.
27182 + */
27183 +#define CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE \
27184 +       ALIGN(sizeof(int) * (DCACHE_WRITE_QUEUE_LENGTH + 1), CACHE_LINE_SIZE)
27185 +
27186 +static char cache_write_queue_flush_area[CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE]
27187 +       __attribute__((aligned(CACHE_LINE_SIZE)));
27188 +
27189 +/*
27190 + * ONE_CCR_ADDR_OP is a helper macro that executes a single CCR operation.
27191 + */
27192 +#define ONE_CCR_ADDR_OP(cc, op_addr, op)                               \
27193 +       do {                                                            \
27194 +               asm volatile (                                          \
27195 +               "       btst    "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_VALID)"                         \n\t" \
27196 +               "       jmpne.f .-4                                                             \n\t" \
27197 +               "       move.4  "D(CCR_ADDR)"(%0), %1                                           \n\t" \
27198 +               "       move.1  "D(CCR_CTRL+3)"(%0), %2                                         \n\t" \
27199 +               "       bset    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_VALID)"      \n\t" \
27200 +               "       cycles  2                                                               \n\t" \
27201 +               "       btst    "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_DONE)"                          \n\t" \
27202 +               "       jmpeq.f .-4                                                             \n\t" \
27203 +                       :                                               \
27204 +                       : "a"(cc), "r"(op_addr), "r"(op & 0xff)         \
27205 +                       : "cc"                                          \
27206 +               );                                                      \
27207 +       } while (0)
27208 +
27209 +/*
27210 + * mem_cache_control()
27211 + *     Special cache control operation
27212 + */
27213 +void mem_cache_control(unsigned long cc, unsigned long begin_addr,
27214 +                      unsigned long end_addr, unsigned long op)
27215 +{
27216 +       unsigned long op_addr;
27217 +
27218 +       if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
27219 +               /*
27220 +                * We ensure all previous writes have left the data cache write
27221 +                * queue by sending DCACHE_WRITE_QUEUE_LENGTH writes (to
27222 +                * different words) down the queue.  If this is not done it's
27223 +                * possible that the data we are trying to flush hasn't even
27224 +                * entered the data cache.
27225 +                * The +1 ensure that the final 'flush' is actually a flush.
27226 +                */
27227 +               int *flush_area = (int *)cache_write_queue_flush_area;
27228 +               asm volatile(
27229 +                       "       .rept "D(DCACHE_WRITE_QUEUE_LENGTH + 1)"        \n\t"
27230 +                       "       move.4 (%0)4++, d0                              \n\t"
27231 +                       "       .endr                                           \n\t"
27232 +                       : "+a"(flush_area)
27233 +                       );
27234 +       }
27235 +
27236 +       /*
27237 +        * Calculate the cache lines we need to operate on that include
27238 +        * begin_addr though end_addr.
27239 +        */
27240 +       begin_addr = begin_addr & ~(CACHE_LINE_SIZE - 1);
27241 +       end_addr = (end_addr + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
27242 +       op_addr = begin_addr;
27243 +
27244 +       do {
27245 +               ONE_CCR_ADDR_OP(cc, op_addr, op);
27246 +               op_addr += CACHE_LINE_SIZE;
27247 +       } while (likely(op_addr < end_addr));
27248 +
27249 +       if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
27250 +               /*
27251 +                * It turns out that when flushing the data cache the last flush
27252 +                * isn't actually complete at this point. This is because there
27253 +                * is another write buffer on the DDR side of the cache that is
27254 +                * arbitrated with the I-Cache.
27255 +                *
27256 +                * The only foolproof method that ensures that the last data
27257 +                * cache flush *actually* completed is to do another flush on a
27258 +                * dirty cache line. This flush will block until the DDR write
27259 +                * buffer is empty.
27260 +                *
27261 +                * Rather than creating a another dirty cache line, we use the
27262 +                * flush_area above as we know that it is dirty from previous
27263 +                * writes.
27264 +                */
27265 +               ONE_CCR_ADDR_OP(cc, cache_write_queue_flush_area, op);
27266 +       }
27267 +}
27268 +EXPORT_SYMBOL(mem_cache_control);
27269 --- /dev/null
27270 +++ b/arch/ubicom32/mach-common/common.c
27271 @@ -0,0 +1,64 @@
27272 +/*
27273 + * arch/ubicom32/mach-common/common.c
27274 + *   Common platform support.
27275 + *
27276 + * (C) Copyright 2009, Ubicom, Inc.
27277 + *
27278 + * This file is part of the Ubicom32 Linux Kernel Port.
27279 + *
27280 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27281 + * it and/or modify it under the terms of the GNU General Public License
27282 + * as published by the Free Software Foundation, either version 2 of the
27283 + * License, or (at your option) any later version.
27284 + *
27285 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27286 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27287 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27288 + * the GNU General Public License for more details.
27289 + *
27290 + * You should have received a copy of the GNU General Public License
27291 + * along with the Ubicom32 Linux Kernel Port.  If not,
27292 + * see <http://www.gnu.org/licenses/>.
27293 + *
27294 + * Ubicom32 implementation derived from (with many thanks):
27295 + *   arch/m68knommu
27296 + *   arch/blackfin
27297 + *   arch/parisc
27298 + */
27299 +#include <linux/version.h>
27300 +#include <linux/kernel.h>
27301 +#include <linux/init.h>
27302 +#include <linux/module.h>
27303 +#include <linux/list.h>
27304 +#include <linux/errno.h>
27305 +#include <linux/err.h>
27306 +#include <linux/string.h>
27307 +#include <linux/clk.h>
27308 +#include <linux/mutex.h>
27309 +#include <linux/platform_device.h>
27310 +
27311 +
27312 +/* Minimum CLK support */
27313 +
27314 +struct clk *clk_get(struct device *dev, const char *id)
27315 +{
27316 +       return ERR_PTR(-ENOENT);
27317 +}
27318 +EXPORT_SYMBOL(clk_get);
27319 +
27320 +void clk_put(struct clk *clk)
27321 +{
27322 +}
27323 +EXPORT_SYMBOL(clk_put);
27324 +
27325 +int clk_enable(struct clk *clk)
27326 +{
27327 +       return 0;
27328 +}
27329 +EXPORT_SYMBOL(clk_enable);
27330 +
27331 +
27332 +void clk_disable(struct clk *clk)
27333 +{
27334 +}
27335 +EXPORT_SYMBOL(clk_disable);
27336 --- /dev/null
27337 +++ b/arch/ubicom32/mach-common/io.c
27338 @@ -0,0 +1,250 @@
27339 +/*
27340 + * arch/ubicom32/mach-common/io.c
27341 + *   PCI I/O memory read/write support functions.
27342 + *
27343 + * (C) Copyright 2009, Ubicom, Inc.
27344 + *
27345 + * This file is part of the Ubicom32 Linux Kernel Port.
27346 + *
27347 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27348 + * it and/or modify it under the terms of the GNU General Public License
27349 + * as published by the Free Software Foundation, either version 2 of the
27350 + * License, or (at your option) any later version.
27351 + *
27352 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27353 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27354 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27355 + * the GNU General Public License for more details.
27356 + *
27357 + * You should have received a copy of the GNU General Public License
27358 + * along with the Ubicom32 Linux Kernel Port.  If not,
27359 + * see <http://www.gnu.org/licenses/>.
27360 + *
27361 + * Ubicom32 implementation derived from (with many thanks):
27362 + *   arch/m68knommu
27363 + *   arch/blackfin
27364 + *   arch/parisc
27365 + */
27366 +#include <linux/module.h>
27367 +#include <linux/kernel.h>
27368 +#include <linux/io.h>
27369 +
27370 +#ifdef CONFIG_PCI
27371 +unsigned char  ioread8(void __iomem *addr)
27372 +{
27373 +       if (IS_PCI_ADDRESS(addr))
27374 +               return ubi32_pci_read_u8(addr);
27375 +       else
27376 +               return (unsigned char)(*(volatile unsigned char *)addr);
27377 +}
27378 +EXPORT_SYMBOL(ioread8);
27379 +
27380 +unsigned short  ioread16(void __iomem *addr)
27381 +{
27382 +       if (IS_PCI_ADDRESS(addr))
27383 +               return ubi32_pci_read_u16(addr);
27384 +       else
27385 +               return (unsigned short)(*(volatile unsigned short *)addr);
27386 +}
27387 +EXPORT_SYMBOL(ioread16);
27388 +
27389 +unsigned int  ioread32(void __iomem *addr)
27390 +{
27391 +       if (IS_PCI_ADDRESS(addr))
27392 +               return ubi32_pci_read_u32(addr);
27393 +       else
27394 +               return (unsigned int)(*(volatile unsigned int *)addr);
27395 +}
27396 +EXPORT_SYMBOL(ioread32);
27397 +
27398 +void iowrite32(unsigned int val, void __iomem *addr)
27399 +{
27400 +       if (IS_PCI_ADDRESS(addr))
27401 +               ubi32_pci_write_u32(val, addr);
27402 +       else
27403 +               *(volatile unsigned int *)addr = val;
27404 +}
27405 +EXPORT_SYMBOL(iowrite32);
27406 +
27407 +void iowrite16(unsigned short val, void __iomem *addr)
27408 +{
27409 +       if (IS_PCI_ADDRESS(addr))
27410 +               ubi32_pci_write_u16(val, addr);
27411 +       else
27412 +               *(volatile unsigned short *)addr = val;
27413 +}
27414 +EXPORT_SYMBOL(iowrite16);
27415 +
27416 +void iowrite8(unsigned char val, void __iomem *addr)
27417 +{
27418 +       if (IS_PCI_ADDRESS(addr))
27419 +               ubi32_pci_write_u8(val, addr);
27420 +       else
27421 +               *(volatile unsigned char *)addr = val;
27422 +}
27423 +EXPORT_SYMBOL(iowrite8);
27424 +
27425 +void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
27426 +{
27427 +       if (IS_PCI_ADDRESS(from)) {
27428 +               if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
27429 +                       while ((int)len >= 4) {
27430 +                               *(u32_t *)to = ubi32_pci_read_u32(from);
27431 +                               to += 4;
27432 +                               from += 4;
27433 +                               len -= 4;
27434 +                       }
27435 +               } else if ((((u32_t)from & 0x1) == 0) &&
27436 +                          (((u32_t)to & 0x1) == 0)) {
27437 +                       while ((int)len >= 2) {
27438 +                                *(u16_t *)to = ubi32_pci_read_u16(from);
27439 +                                to += 2;
27440 +                                from += 2;
27441 +                                len -= 2;
27442 +                       }
27443 +               }
27444 +
27445 +               while (len) {
27446 +                       *(u8_t *)to = ubi32_pci_read_u8(from);
27447 +                       to++;
27448 +                       from++;
27449 +                       len--;
27450 +               }
27451 +       } else
27452 +               memcpy(to, (void *)from, len);
27453 +}
27454 +EXPORT_SYMBOL(memcpy_fromio);
27455 +
27456 +void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
27457 +{
27458 +       if (IS_PCI_ADDRESS(to)) {
27459 +               if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
27460 +                       while ((int)len >= 4) {
27461 +                               ubi32_pci_write_u32(*(u32_t *)from, to);
27462 +                               to += 4;
27463 +                               from += 4;
27464 +                               len -= 4;
27465 +                       }
27466 +               } else if ((((u32_t)from & 0x1) == 0) &&
27467 +                          (((u32_t)to & 0x1) == 0)) {
27468 +                       while ((int)len >= 2) {
27469 +                               ubi32_pci_write_u16(*(u16_t *)from, to);
27470 +                               to += 2;
27471 +                               from += 2;
27472 +                               len -= 2;
27473 +                       }
27474 +               }
27475 +
27476 +               while (len) {
27477 +                       ubi32_pci_write_u8(*(u8_t *)from, to);
27478 +                       from++;
27479 +                       to++;
27480 +                       len--;
27481 +               }
27482 +       } else
27483 +               memcpy((void *)to, from, len);
27484 +
27485 +}
27486 +EXPORT_SYMBOL(memcpy_toio);
27487 +
27488 +void memset_io(volatile void __iomem *addr, int val, size_t len)
27489 +{
27490 +       if (IS_PCI_ADDRESS(addr)) {
27491 +               while (len) {
27492 +                       ubi32_pci_write_u8((unsigned char)val, addr);
27493 +                       addr++;
27494 +                       len--;
27495 +               }
27496 +       } else
27497 +               memset((void *)addr, val, len);
27498 +
27499 +}
27500 +EXPORT_SYMBOL(memset_io);
27501 +
27502 +void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
27503 +{
27504 +       if (IS_PCI_ADDRESS(port)) {
27505 +               while (count) {
27506 +                       *(u8_t *)buf = ioread8(port);
27507 +                       buf++;
27508 +                       count--;
27509 +               }
27510 +       } else {
27511 +               insb((unsigned int)port, buf, count);
27512 +       }
27513 +
27514 +}
27515 +EXPORT_SYMBOL(ioread8_rep);
27516 +
27517 +void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
27518 +{
27519 +       if (IS_PCI_ADDRESS(port)) {
27520 +               while (count) {
27521 +                       *(u16_t *)buf = ioread16(port);
27522 +                       buf += 2;
27523 +                       count--;
27524 +               }
27525 +       } else {
27526 +               insw((unsigned int)port, buf, count);
27527 +       }
27528 +}
27529 +EXPORT_SYMBOL(ioread16_rep);
27530 +
27531 +void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
27532 +{
27533 +        if (IS_PCI_ADDRESS(port)) {
27534 +               while (count) {
27535 +                       *(u32_t *)buf = ioread32(port);
27536 +                       buf += 4;
27537 +                       count--;
27538 +               }
27539 +       } else {
27540 +               insl((unsigned int)port, buf, count);
27541 +       }
27542 +}
27543 +EXPORT_SYMBOL(ioread32_rep);
27544 +
27545 +void  iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
27546 +{
27547 +         if (IS_PCI_ADDRESS(port)) {
27548 +               while (count) {
27549 +                       iowrite8(*(u8_t *)buf, port);
27550 +                       buf++;
27551 +                       count--;
27552 +               }
27553 +       } else {
27554 +               outsb((unsigned int)port, buf, count);
27555 +       }
27556 +
27557 +}
27558 +EXPORT_SYMBOL(iowrite8_rep);
27559 +
27560 +void  iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
27561 +{
27562 +       if (IS_PCI_ADDRESS(port)) {
27563 +               while (count) {
27564 +                       iowrite16(*(u16_t *)buf, port);
27565 +                       buf += 2;
27566 +                       count--;
27567 +               }
27568 +       } else {
27569 +               outsw((unsigned int)port, buf, count);
27570 +       }
27571 +}
27572 +EXPORT_SYMBOL(iowrite16_rep);
27573 +
27574 +void  iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
27575 +{
27576 +       if (IS_PCI_ADDRESS(port)) {
27577 +               while (count) {
27578 +                       iowrite32(*(u32_t *)buf, port);
27579 +                       buf += 4;
27580 +                       count--;
27581 +               }
27582 +       } else {
27583 +               outsl((unsigned int)port, buf, count);
27584 +       }
27585 +}
27586 +EXPORT_SYMBOL(iowrite32_rep);
27587 +
27588 +#endif /* CONFIG_PCI */
27589 --- /dev/null
27590 +++ b/arch/ubicom32/mach-common/Makefile
27591 @@ -0,0 +1,38 @@
27592 +#
27593 +# arch/ubicom32/mach-common/Makefile
27594 +#      Makefile for Ubicom32 generic drivers/code.
27595 +#
27596 +# (C) Copyright 2009, Ubicom, Inc.
27597 +#
27598 +# This file is part of the Ubicom32 Linux Kernel Port.
27599 +#
27600 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
27601 +# it and/or modify it under the terms of the GNU General Public License
27602 +# as published by the Free Software Foundation, either version 2 of the
27603 +# License, or (at your option) any later version.
27604 +#
27605 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
27606 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
27607 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27608 +# the GNU General Public License for more details.
27609 +#
27610 +# You should have received a copy of the GNU General Public License
27611 +# along with the Ubicom32 Linux Kernel Port.  If not, 
27612 +# see <http://www.gnu.org/licenses/>.
27613 +#
27614 +# Ubicom32 implementation derived from (with many thanks):
27615 +#   arch/m68knommu
27616 +#   arch/blackfin
27617 +#   arch/parisc
27618 +#
27619 +
27620 +obj-y += cachectl.o common.o usb_tio.o usb.o ubi32-gpio.o board.o bootargs.o
27621 +obj-$(CONFIG_PCI) += pci.o io.o
27622 +
27623 +obj-$(CONFIG_FB_UBICOM32) += vdc_tio.o
27624 +obj-$(CONFIG_UBICOM_HID) += ubicom32hid.o
27625 +obj-$(CONFIG_UBICOM_INPUT) += ubicom32input.o
27626 +obj-$(CONFIG_UBICOM_INPUT_I2C) += ubicom32input_i2c.o
27627 +obj-$(CONFIG_UIO_UBICOM32RING) += ring_tio.o
27628 +obj-$(CONFIG_SND_UBI32) += audio_tio.o
27629 +
27630 --- /dev/null
27631 +++ b/arch/ubicom32/mach-common/pci.c
27632 @@ -0,0 +1,1157 @@
27633 +/*
27634 + * arch/ubicom32/mach-common/pci.c
27635 + *     PCI interface management.
27636 + *
27637 + * (C) Copyright 2009, Ubicom, Inc.
27638 + *
27639 + * This file is part of the Ubicom32 Linux Kernel Port.
27640 + *
27641 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27642 + * it and/or modify it under the terms of the GNU General Public License
27643 + * as published by the Free Software Foundation, either version 2 of the
27644 + * License, or (at your option) any later version.
27645 + *
27646 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27647 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27648 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27649 + * the GNU General Public License for more details.
27650 + *
27651 + * You should have received a copy of the GNU General Public License
27652 + * along with the Ubicom32 Linux Kernel Port.  If not,
27653 + * see <http://www.gnu.org/licenses/>.
27654 + *
27655 + * Ubicom32 implementation derived from (with many thanks):
27656 + *   arch/m68knommu
27657 + *   arch/blackfin
27658 + *   arch/parisc
27659 + */
27660 +
27661 +#include <linux/module.h>
27662 +#include <linux/kernel.h>
27663 +#include <linux/pci.h>
27664 +#include <linux/slab.h>
27665 +#include <linux/init.h>
27666 +#include <linux/io.h>
27667 +#include <linux/seq_file.h>
27668 +#include <linux/proc_fs.h>
27669 +
27670 +#include <asm/devtree.h>
27671 +#include <asm/ip5000.h>
27672 +#include <asm/ubicom32-common.h>
27673 +
27674 +static int debug_pci = 1 ;
27675 +
27676 +/* #define PCI_USE_INTERNAL_LOCK 1 */
27677 +
27678 +#ifdef PCI_USE_INTERNAL_LOCK
27679 +#define PCI_LOCK(lock, irqflag)        pci_lock_acquire(irqflag)
27680 +#define PCI_UNLOCK(lock, irqflag) pci_lock_release(irqflag)
27681 +#elif defined(CONFIG_SMP)
27682 +static DEFINE_SPINLOCK(pci_master_lock);
27683 +#define PCI_LOCK(lock, irqflag)        spin_lock_irqsave(lock, irqflag)
27684 +#define PCI_UNLOCK(lock, irqflag) spin_unlock_irqrestore(lock, irqflag)
27685 +#else
27686 +#define PCI_LOCK(lock, irqflag)                local_irq_save(irqflag)
27687 +#define PCI_UNLOCK(lock, irqflag)      local_irq_restore(irqflag)
27688 +#endif
27689 +
27690 +#define PCI_DEV0_IDSEL CONFIG_PCI_DEV0_IDSEL
27691 +#define PCI_DEV1_IDSEL CONFIG_PCI_DEV1_IDSEL
27692 +
27693 +/*
27694 + * PCI commands
27695 + */
27696 +#define PCI_CMD_INT_ACK                0x00    /* not supported */
27697 +#define PCI_CMD_SPECIAL                0x01    /* not supported */
27698 +#define PCI_CMD_IO_READ                0x02
27699 +#define PCI_CMD_IO_WRITE       0x03
27700 +#define PCI_CMD_MEM_READ       0x06
27701 +#define PCI_CMD_MEM_WRITE      0x07
27702 +#define PCI_CMD_CFG_READ       0x0a
27703 +#define PCI_CMD_CFG_WRITE      0x0b
27704 +#define PCI_CMD_MEM_READ_MULT  0x0c    /* not supported */
27705 +#define PCI_CMD_DUAL_ADDR      0x0d    /* not supported */
27706 +#define PCI_CMD_MEM_READ_LINE  0x0e    /* not supported */
27707 +#define PCI_CMD_MEM_WRITE_INVAL        0x0f    /* not supported */
27708 +/*
27709 + * Status codes, returned by pci_read_u32() and pci_write_u32()
27710 + */
27711 +#define PCI_RESP_IN_PROGRESS   0xff  /* request still in queue */
27712 +#define PCI_RESP_OK            0
27713 +/*
27714 + * The following codes indicate that the request has completed
27715 + */
27716 +#define PCI_RESP_NO_DEVSEL             1  /* timeout before target asserted
27717 +                                           * DEVSEL! */
27718 +#define PCI_RESP_LOST_DEVSEL           2  /* had DEVSEL, but went away before
27719 +                                           * transfer completed! */
27720 +#define PCI_RESP_BAD_TRDY              3  /* target asserted TRDY without
27721 +                                           * DEVSEL! */
27722 +#define PCI_RESP_NO_TRDY               4  /* timeout before target asserted
27723 +                                           * TRDY! */
27724 +#define PCI_RESP_BAD_STOP              5  /* target asserted STOP and TRDY
27725 +                                           * without DEVSEL! */
27726 +#define PCI_RESP_TARGET_ABORT          6
27727 +#define PCI_RESP_TARGET_RETRY          7
27728 +#define        PCI_RESP_TARGET_DISCONNECT      8
27729 +#define PCI_RESP_MISMATCH              9  /* data read back doesn't match data
27730 +                                           * written - debug only, the core PCI
27731 +                                           * routines never return this */
27732 +#define PCI_RESP_DET_SERR              10
27733 +#define PCI_RESP_DET_PERR              11
27734 +#define PCI_RESP_MALFORMED_REQ         12 /* Could be due to misaligned
27735 +                                           * requests or invalid address */
27736 +#define PCI_RESP_NO_RESOURCE           13 /* Could be memory or other resourse
27737 +                                           * like queue space */
27738 +#define PCI_RESP_ERROR                 14 /* All emcompassing error */
27739 +
27740 +/* registers in PCI config space */
27741 +#define PCI_DEVICE_VENDOR_ID_REG       0x00
27742 +#define PCI_STATUS_COMMAND_REG         0x04
27743 +#define PCI_CLASS_REVISION_REG         0x08
27744 +#define PCI_BHLC_REG                   0x0c  /* BIST, Header type, Latency
27745 +                                              * timer, Cache line size */
27746 +#define PCI_BASE_ADDR_REG              0x10
27747 +#define PCI_BASE_REG_COUNT             6
27748 +#define CARDBUS_CIS_PTR_REG            0x28
27749 +#define PCI_SUB_SYSTEM_ID_REG          0x2c
27750 +#define PCI_EXP_ROM_ADDR_REG           0x30
27751 +#define PCI_CAP_PTR_REG                        0x34
27752 +#define PCI_LGPL_REG                   0x3C  /* max Latency, min Gnt, interrupt
27753 +                                              * Pin, interrupt Line */
27754 +
27755 +struct pci_master_request {
27756 +       volatile u32_t pci_address;     /* must be 4-byte aligned */
27757 +       volatile u32_t data;            /* must be 4-byte aligned */
27758 +       volatile u8_t cmd;
27759 +       volatile u8_t byte_valid;
27760 +       volatile u8_t status;
27761 +};
27762 +
27763 +struct pci_devnode {
27764 +       struct devtree_node dn;
27765 +       u32_t pci_idsel_0;
27766 +       u32_t pci_idsel_1;
27767 +       u32_t pci_cpu_address;
27768 +       struct pci_master_request volatile *volatile req;
27769 +};
27770 +
27771 +static struct pci_master_request req;  /* globally used for faster master write
27772 +                                        * (discarding result when possible) */
27773 +static struct pci_devnode *pci_node;
27774 +
27775 +#if !defined(CONFIG_DEBUG_PCIMEASURE)
27776 +#define PCI_DECLARE_MEASUREMENT
27777 +#define PCI_MEASUREMENT_START()
27778 +#define PCI_MEASUREMENT_END(idx)
27779 +#else
27780 +#define PCI_DECLARE_MEASUREMENT \
27781 +       int __diff;             \
27782 +       unsigned int __tstart;
27783 +
27784 +#define PCI_MEASUREMENT_START() \
27785 +       __tstart = UBICOM32_IO_TIMER->sysval;
27786 +
27787 +#define PCI_MEASUREMENT_END(idx) \
27788 +       __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
27789 +       pci_measurement_update((idx), __diff);
27790 +
27791 +#define PCI_WEIGHT 32
27792 +
27793 +struct pci_measurement {
27794 +       volatile unsigned int min;
27795 +       volatile unsigned int avg;
27796 +       volatile unsigned int max;
27797 +};
27798 +
27799 +enum pci_measurement_list {
27800 +       PCI_MEASUREMENT_READ32,
27801 +       PCI_MEASUREMENT_WRITE32,
27802 +       PCI_MEASUREMENT_READ16,
27803 +       PCI_MEASUREMENT_WRITE16,
27804 +       PCI_MEASUREMENT_READ8,
27805 +       PCI_MEASUREMENT_WRITE8,
27806 +       PCI_MEASUREMENT_LAST,
27807 +};
27808 +
27809 +static const char *pci_measurement_name_list[PCI_MEASUREMENT_LAST] = {
27810 +       "READ32",
27811 +       "WRITE32",
27812 +       "READ16",
27813 +       "WRITE16",
27814 +       "READ8",
27815 +       "WRITE8"
27816 +};
27817 +static struct pci_measurement pci_measurements[PCI_MEASUREMENT_LAST];
27818 +
27819 +/*
27820 + * pci_measurement_update()
27821 + *     Update an entry in the measurement array for this idx.
27822 + */
27823 +static void pci_measurement_update(int idx, int sample)
27824 +{
27825 +       struct pci_measurement *pm = &pci_measurements[idx];
27826 +       if ((pm->min == 0) || (pm->min > sample)) {
27827 +               pm->min = sample;
27828 +       }
27829 +       if (pm->max < sample) {
27830 +               pm->max = sample;
27831 +       }
27832 +       pm->avg = ((pm->avg * (PCI_WEIGHT - 1)) + sample) / PCI_WEIGHT;
27833 +}
27834 +#endif
27835 +
27836 +#if defined(PCI_USE_INTERNAL_LOCK)
27837 +/*
27838 + * pci_lock_release()
27839 + *     Release the PCI lock.
27840 + */
27841 +static void pci_lock_release(unsigned long irqflag)
27842 +{
27843 +       UBICOM32_UNLOCK(PCI_LOCK_BIT);
27844 +}
27845 +
27846 +/*
27847 + * pci_lock_acquire()
27848 + *     Acquire the PCI lock, spin if not available.
27849 + */
27850 +static void pci_lock_acquire(unsigned long irqflag)
27851 +{
27852 +       UBICOM32_LOCK(PCI_LOCK_BIT);
27853 +}
27854 +#endif
27855 +
27856 +/*
27857 + * pci_set_hrt_interrupt()
27858 + */
27859 +static inline void pci_set_hrt_interrupt(struct pci_devnode *pci_node)
27860 +{
27861 +       ubicom32_set_interrupt(pci_node->dn.sendirq);
27862 +}
27863 +
27864 +/*
27865 + * pci_read_u32()
27866 + *     Synchronously read 32 bits from PCI space.
27867 + */
27868 +u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data)
27869 +{
27870 +       u8 status;
27871 +       unsigned long irqflag;
27872 +
27873 +
27874 +       /*
27875 +        * Fill in the request.
27876 +        */
27877 +       volatile struct pci_master_request lreq;
27878 +       PCI_DECLARE_MEASUREMENT;
27879 +
27880 +       lreq.pci_address = address;
27881 +       lreq.cmd = pci_cmd;
27882 +       lreq.byte_valid = 0xf;          /* enable all bytes */
27883 +
27884 +       /*
27885 +        * Wait for any previous request to complete and then make this request.
27886 +        */
27887 +       PCI_MEASUREMENT_START();
27888 +       PCI_LOCK(&pci_master_lock, irqflag);
27889 +       while (unlikely(pci_node->req == &req))
27890 +               ;
27891 +       pci_node->req = &lreq;
27892 +       pci_set_hrt_interrupt(pci_node);
27893 +       PCI_UNLOCK(&pci_master_lock, irqflag);
27894 +
27895 +       /*
27896 +        * Wait for the result to show up.
27897 +        */
27898 +       while (unlikely(pci_node->req == &lreq))
27899 +               ;
27900 +       status = lreq.status;
27901 +       if (likely(status == PCI_RESP_OK))
27902 +               *data = le32_to_cpu(lreq.data);
27903 +       else
27904 +               *data = 0;
27905 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ32);
27906 +       return status;
27907 +}
27908 +
27909 +/*
27910 + * pci_write_u32()
27911 + *     Asyncrhnously or synchronously write 32 bits to PCI master space.
27912 + */
27913 +u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data)
27914 +{
27915 +       unsigned long irqflag;
27916 +       PCI_DECLARE_MEASUREMENT;
27917 +
27918 +       /*
27919 +        * Wait for any previous write or pending read to complete.
27920 +        *
27921 +        * We use a global data block because once we write the request
27922 +        * we do not wait for it to complete before exiting.
27923 +        */
27924 +       PCI_MEASUREMENT_START();
27925 +       PCI_LOCK(&pci_master_lock, irqflag);
27926 +       while (unlikely(pci_node->req == &req))
27927 +               ;
27928 +       req.pci_address = address;
27929 +       req.data = cpu_to_le32(data);
27930 +       req.cmd = pci_cmd;
27931 +       req.byte_valid = 0xf;           /* enable all bytes */
27932 +       pci_node->req = &req;
27933 +       pci_set_hrt_interrupt(pci_node);
27934 +       PCI_UNLOCK(&pci_master_lock, irqflag);
27935 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE32);
27936 +       return PCI_RESP_OK;
27937 +}
27938 +
27939 +/*
27940 + * pci_read_u16()
27941 + *     Synchronously read 16 bits from PCI space.
27942 + */
27943 +u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data)
27944 +{
27945 +       u8 status;
27946 +       unsigned long irqflag;
27947 +
27948 +       /*
27949 +        * Fill in the request.
27950 +        */
27951 +       volatile struct pci_master_request lreq;
27952 +       PCI_DECLARE_MEASUREMENT;
27953 +
27954 +       lreq.pci_address = address & ~2;
27955 +       lreq.cmd = pci_cmd;
27956 +       lreq.byte_valid = (address & 2) ? 0xc : 0x3;
27957 +
27958 +       /*
27959 +        * Wait for any previous request to complete and then make this request.
27960 +        */
27961 +       PCI_MEASUREMENT_START();
27962 +       PCI_LOCK(&pci_master_lock, irqflag);
27963 +       while (unlikely(pci_node->req == &req))
27964 +               ;
27965 +       pci_node->req = &lreq;
27966 +       pci_set_hrt_interrupt(pci_node);
27967 +       PCI_UNLOCK(&pci_master_lock, irqflag);
27968 +
27969 +       /*
27970 +        * Wait for the result to show up.
27971 +        */
27972 +       while (unlikely(pci_node->req == &lreq))
27973 +               ;
27974 +       status = lreq.status;
27975 +       if (likely(status == PCI_RESP_OK)) {
27976 +               lreq.data = le32_to_cpu(lreq.data);
27977 +               *data = (u16)((address & 2) ? (lreq.data >> 16) : lreq.data);
27978 +       } else
27979 +               *data = 0;
27980 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ16);
27981 +       return status;
27982 +}
27983 +
27984 +/*
27985 + * pci_write_u16()
27986 + *     Asyncrhnously or synchronously write 16 bits to PCI master space.
27987 + */
27988 +u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data)
27989 +{
27990 +       unsigned long irqflag;
27991 +       PCI_DECLARE_MEASUREMENT;
27992 +
27993 +       /*
27994 +        * Wait for any previous write or pending read to complete.
27995 +        *
27996 +        * We use a global data block because once we write the request
27997 +        * we do not wait for it to complete before exiting.
27998 +        */
27999 +       PCI_MEASUREMENT_START();
28000 +       PCI_LOCK(&pci_master_lock, irqflag);
28001 +       while (unlikely(pci_node->req == &req))
28002 +               ;
28003 +       req.pci_address = address & ~2;
28004 +       req.data = (u32)data;
28005 +       req.data = cpu_to_le32((address & 2) ? (req.data << 16) : req.data);
28006 +       req.cmd = pci_cmd;
28007 +       req.byte_valid = (address & 2) ? 0xc : 0x3;
28008 +       pci_node->req = &req;
28009 +       pci_set_hrt_interrupt(pci_node);
28010 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28011 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE16);
28012 +       return PCI_RESP_OK;
28013 +}
28014 +
28015 +/*
28016 + * pci_read_u8()
28017 + *     Synchronously read 8 bits from PCI space.
28018 + */
28019 +u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data)
28020 +{
28021 +       u8 status;
28022 +       unsigned long irqflag;
28023 +
28024 +       /*
28025 +        * Fill in the request.
28026 +        */
28027 +       volatile struct pci_master_request lreq;
28028 +       PCI_DECLARE_MEASUREMENT;
28029 +
28030 +       lreq.pci_address = address & ~3;
28031 +       lreq.cmd = pci_cmd;
28032 +       lreq.byte_valid = 1 << (address & 0x3);
28033 +
28034 +       /*
28035 +        * Wait for any previous request to complete and then make this request.
28036 +        */
28037 +       PCI_MEASUREMENT_START();
28038 +       PCI_LOCK(&pci_master_lock, irqflag);
28039 +       while (unlikely(pci_node->req == &req))
28040 +               ;
28041 +       pci_node->req = &lreq;
28042 +       pci_set_hrt_interrupt(pci_node);
28043 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28044 +
28045 +       /*
28046 +        * Wait for the result to show up.
28047 +        */
28048 +       while (unlikely(pci_node->req == &lreq))
28049 +               ;
28050 +       status = lreq.status;
28051 +       if (likely(status == PCI_RESP_OK)) {
28052 +               *data = (u8)(lreq.data >> (24 - ((address & 0x3) << 3)));
28053 +       } else
28054 +               *data = 0;
28055 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ8);
28056 +       return status;
28057 +}
28058 +
28059 +/*
28060 + * pci_write_u8()
28061 + *     Asyncrhnously or synchronously write 8 bits to PCI master space.
28062 + */
28063 +u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data)
28064 +{
28065 +       unsigned long irqflag;
28066 +       PCI_DECLARE_MEASUREMENT;
28067 +
28068 +       /*
28069 +        * Wait for any previous write or pending read to complete.
28070 +        *
28071 +        * We use a global data block because once we write the request
28072 +        * we do not wait for it to complete before exiting.
28073 +        */
28074 +       PCI_MEASUREMENT_START();
28075 +       PCI_LOCK(&pci_master_lock, irqflag);
28076 +       while (unlikely(pci_node->req == &req))
28077 +               ;
28078 +       req.pci_address = address & ~3;
28079 +       req.data = ((u32)data << (24 - ((address & 0x3) << 3)));
28080 +       req.cmd = pci_cmd;
28081 +       req.byte_valid = 1 << (address & 0x3);
28082 +       pci_node->req = &req;
28083 +       pci_set_hrt_interrupt(pci_node);
28084 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28085 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE8);
28086 +       return PCI_RESP_OK;
28087 +}
28088 +
28089 +unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr)
28090 +{
28091 +       unsigned int data;
28092 +       pci_read_u32(PCI_CMD_MEM_READ, (u32)addr, &data);
28093 +       return data;
28094 +}
28095 +EXPORT_SYMBOL(ubi32_pci_read_u32);
28096 +
28097 +unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr)
28098 +{
28099 +       unsigned short data;
28100 +       pci_read_u16(PCI_CMD_MEM_READ, (u32)addr, &data);
28101 +       return data;
28102 +}
28103 +EXPORT_SYMBOL(ubi32_pci_read_u16);
28104 +
28105 +unsigned char  ubi32_pci_read_u8(const volatile void __iomem *addr)
28106 +{
28107 +       unsigned char  data;
28108 +       pci_read_u8(PCI_CMD_MEM_READ, (u32)addr, &data);
28109 +       return data;
28110 +}
28111 +EXPORT_SYMBOL(ubi32_pci_read_u8);
28112 +
28113 +void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr)
28114 +{
28115 +       pci_write_u32(PCI_CMD_MEM_WRITE, (u32)addr, val);
28116 +}
28117 +EXPORT_SYMBOL(ubi32_pci_write_u32);
28118 +
28119 +void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr)
28120 +{
28121 +       pci_write_u16(PCI_CMD_MEM_WRITE, (u32)addr, val);
28122 +}
28123 +EXPORT_SYMBOL(ubi32_pci_write_u16);
28124 +
28125 +void ubi32_pci_write_u8(unsigned char val, const void volatile __iomem *addr)
28126 +{
28127 +       pci_write_u8(PCI_CMD_MEM_WRITE, (u32)addr, val);
28128 +}
28129 +EXPORT_SYMBOL(ubi32_pci_write_u8);
28130 +
28131 +#if defined(CONFIG_DEBUG_PCIMEASURE)
28132 +static unsigned int pci_cycles_to_nano(unsigned int cycles, unsigned int frequency)
28133 +{
28134 +       unsigned int nano = ((cycles * 1000) / (frequency / 1000000));
28135 +       return nano;
28136 +}
28137 +
28138 +/*
28139 + * pci_measurement_show()
28140 + *     Print out the min, avg, max values for each PCI transaction type.
28141 + *
28142 + * By request, the max value is reset after each dump.
28143 + */
28144 +static int pci_measurement_show(struct seq_file *p, void *v)
28145 +{
28146 +       unsigned int min, avg, max;
28147 +       unsigned int freq = processor_frequency();
28148 +       int trans = *((loff_t *) v);
28149 +
28150 +       if (trans == 0) {
28151 +               seq_puts(p, "min\tavg\tmax\t(nano-seconds)\n");
28152 +       }
28153 +
28154 +       if (trans >= PCI_MEASUREMENT_LAST) {
28155 +               return 0;
28156 +       }
28157 +
28158 +       min = pci_cycles_to_nano(pci_measurements[trans].min, freq);
28159 +       avg = pci_cycles_to_nano(pci_measurements[trans].avg, freq);
28160 +       max = pci_cycles_to_nano(pci_measurements[trans].max, freq);
28161 +       pci_measurements[trans].max = 0;
28162 +       seq_printf(p, "%u\t%u\t%u\t%s\n", min, avg, max, pci_measurement_name_list[trans]);
28163 +       return 0;
28164 +}
28165 +
28166 +static void *pci_measurement_start(struct seq_file *f, loff_t *pos)
28167 +{
28168 +       return (*pos < PCI_MEASUREMENT_LAST) ? pos : NULL;
28169 +}
28170 +
28171 +static void *pci_measurement_next(struct seq_file *f, void *v, loff_t *pos)
28172 +{
28173 +       (*pos)++;
28174 +       if (*pos >= PCI_MEASUREMENT_LAST)
28175 +               return NULL;
28176 +       return pos;
28177 +}
28178 +
28179 +static void pci_measurement_stop(struct seq_file *f, void *v)
28180 +{
28181 +       /* Nothing to do */
28182 +}
28183 +
28184 +static const struct seq_operations pci_measurement_seq_ops = {
28185 +       .start = pci_measurement_start,
28186 +       .next  = pci_measurement_next,
28187 +       .stop  = pci_measurement_stop,
28188 +       .show  = pci_measurement_show,
28189 +};
28190 +
28191 +static int pci_measurement_open(struct inode *inode, struct file *filp)
28192 +{
28193 +       return seq_open(filp, &pci_measurement_seq_ops);
28194 +}
28195 +
28196 +static const struct file_operations pci_measurement_fops = {
28197 +       .open           = pci_measurement_open,
28198 +       .read           = seq_read,
28199 +       .llseek         = seq_lseek,
28200 +       .release        = seq_release,
28201 +};
28202 +
28203 +static int __init pci_measurement_init(void)
28204 +{
28205 +       proc_create("pci_measurements", 0, NULL, &pci_measurement_fops);
28206 +       return 0;
28207 +}
28208 +module_init(pci_measurement_init);
28209 +#endif
28210 +
28211 +static int ubi32_pci_read_config(struct pci_bus *bus, unsigned int devfn,
28212 +                                int where, int size, u32 *value)
28213 +{
28214 +       u8 cmd;
28215 +       u32 addr;
28216 +       u8  data8;
28217 +       u16 data16;
28218 +
28219 +       u8 slot = PCI_SLOT(devfn);
28220 +       u8 fn = PCI_FUNC(devfn);
28221 +
28222 +       if (slot > 1) {
28223 +               return PCIBIOS_DEVICE_NOT_FOUND;
28224 +       } else if (slot == 0) {
28225 +               addr = PCI_DEV0_IDSEL + where;
28226 +       } else {
28227 +               addr = PCI_DEV1_IDSEL + where;
28228 +       }
28229 +
28230 +       addr += (fn << 8);
28231 +
28232 +       cmd = PCI_CMD_CFG_READ;
28233 +       if (size == 1) {
28234 +               pci_read_u8(cmd, addr, &data8);
28235 +               *value = (u32)data8;
28236 +       } else if (size == 2) {
28237 +               pci_read_u16(cmd, addr, &data16);
28238 +               *value = (u32)data16;
28239 +       } else {
28240 +               pci_read_u32(cmd, addr, value);
28241 +       }
28242 +
28243 +       return PCIBIOS_SUCCESSFUL;
28244 +}
28245 +
28246 +static int ubi32_pci_write_config(struct pci_bus *bus, unsigned int devfn,
28247 +                                 int where, int size, u32 value)
28248 +{
28249 +       u8 cmd;
28250 +       u32 addr;
28251 +       u8 slot = PCI_SLOT(devfn);
28252 +       u8 fn = PCI_FUNC(devfn);
28253 +
28254 +       if (slot > 1) {
28255 +               return PCIBIOS_DEVICE_NOT_FOUND;
28256 +       } else if (slot == 0) {
28257 +               addr = PCI_DEV0_IDSEL + where;
28258 +       } else {
28259 +               addr = PCI_DEV1_IDSEL + where;
28260 +       }
28261 +
28262 +       addr += (fn << 8);
28263 +
28264 +       cmd = PCI_CMD_CFG_WRITE;
28265 +       if (size == 1) {
28266 +               pci_write_u8(cmd, addr, (u8)value);
28267 +       } else if (size == 2) {
28268 +               pci_write_u16(cmd, addr, (u16)value);
28269 +       } else {
28270 +               pci_write_u32(cmd, addr, value);
28271 +       }
28272 +
28273 +       return PCIBIOS_SUCCESSFUL;
28274 +}
28275 +
28276 +int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
28277 +{
28278 +       return -EIO;
28279 +}
28280 +EXPORT_SYMBOL(pci_set_dma_max_seg_size);
28281 +
28282 +int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
28283 +{
28284 +       return -EIO;
28285 +}
28286 +EXPORT_SYMBOL(pci_set_dma_seg_boundary);
28287 +
28288 +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
28289 +{
28290 +       resource_size_t start = pci_resource_start(dev, bar);
28291 +       resource_size_t len   = pci_resource_len(dev, bar);
28292 +       unsigned long flags = pci_resource_flags(dev, bar);
28293 +
28294 +       if (!len || !start) {
28295 +               return NULL;
28296 +       }
28297 +
28298 +       if (maxlen && len > maxlen) {
28299 +               len = maxlen;
28300 +       }
28301 +
28302 +       if (flags & IORESOURCE_IO) {
28303 +               return ioport_map(start, len);
28304 +       }
28305 +
28306 +       if (flags & IORESOURCE_MEM) {
28307 +               if (flags & IORESOURCE_CACHEABLE) {
28308 +                       return ioremap(start, len);
28309 +               }
28310 +               return ioremap_nocache(start, len);
28311 +       }
28312 +       return NULL;
28313 +}
28314 +EXPORT_SYMBOL(pci_iomap);
28315 +
28316 +void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
28317 +{
28318 +       if ((unsigned long)addr >= VMALLOC_START &&
28319 +           (unsigned long)addr < VMALLOC_END) {
28320 +               iounmap(addr);
28321 +       }
28322 +}
28323 +EXPORT_SYMBOL(pci_iounmap);
28324 +
28325 +/*
28326 + *  From arch/arm/kernel/bios32.c
28327 + *
28328 + *  PCI bios-type initialisation for PCI machines
28329 + *
28330 + *  Bits taken from various places.
28331 + */
28332 +static void __init pcibios_init_hw(struct hw_pci *hw)
28333 +{
28334 +       struct pci_sys_data *sys = NULL;
28335 +       int ret;
28336 +       int nr, busnr;
28337 +
28338 +       for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
28339 +               sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
28340 +               if (!sys)
28341 +                       panic("PCI: unable to allocate sys data!");
28342 +
28343 +               sys->hw      = hw;
28344 +               sys->busnr   = busnr;
28345 +               sys->map_irq = hw->map_irq;
28346 +               sys->resource[0] = &ioport_resource;
28347 +               sys->resource[1] = &iomem_resource;
28348 +
28349 +               ret = hw->setup(nr, sys);
28350 +
28351 +               if (ret > 0) {
28352 +                       sys->bus = hw->scan(nr, sys);
28353 +
28354 +                       if (!sys->bus)
28355 +                               panic("PCI: unable to scan bus!");
28356 +
28357 +                       busnr = sys->bus->subordinate + 1;
28358 +
28359 +                       list_add(&sys->node, &hw->buses);
28360 +               } else {
28361 +                       kfree(sys);
28362 +                       if (ret < 0)
28363 +                               break;
28364 +               }
28365 +       }
28366 +}
28367 +
28368 +/*
28369 + * Swizzle the device pin each time we cross a bridge.
28370 + * This might update pin and returns the slot number.
28371 + */
28372 +static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin)
28373 +{
28374 +       struct pci_sys_data *sys = dev->sysdata;
28375 +       int slot = 0, oldpin = *pin;
28376 +
28377 +       if (sys->swizzle)
28378 +               slot = sys->swizzle(dev, pin);
28379 +
28380 +       if (debug_pci)
28381 +               printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
28382 +                       pci_name(dev), oldpin, *pin, slot);
28383 +       return slot;
28384 +}
28385 +
28386 +/*
28387 + * Map a slot/pin to an IRQ.
28388 + */
28389 +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28390 +{
28391 +       struct pci_sys_data *sys = dev->sysdata;
28392 +       int irq = -1;
28393 +
28394 +       if (sys->map_irq)
28395 +               irq = sys->map_irq(dev, slot, pin);
28396 +
28397 +       if (debug_pci)
28398 +               printk("PCI: %s mapping slot %d pin %d => irq %d\n",
28399 +                       pci_name(dev), slot, pin, irq);
28400 +
28401 +       return irq;
28402 +}
28403 +
28404 +void __init pci_common_init(struct hw_pci *hw)
28405 +{
28406 +       struct pci_sys_data *sys;
28407 +
28408 +       INIT_LIST_HEAD(&hw->buses);
28409 +
28410 +       if (hw->preinit)
28411 +               hw->preinit();
28412 +       pcibios_init_hw(hw);
28413 +       if (hw->postinit)
28414 +               hw->postinit();
28415 +
28416 +       pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
28417 +       list_for_each_entry(sys, &hw->buses, node) {
28418 +               struct pci_bus *bus = sys->bus;
28419 +               /*
28420 +                * Size the bridge windows.
28421 +                */
28422 +               pci_bus_size_bridges(bus);
28423 +               /*
28424 +                * Assign resources.
28425 +                */
28426 +               pci_bus_assign_resources(bus);
28427 +
28428 +               /*
28429 +                * Tell drivers about devices found.
28430 +                */
28431 +               pci_bus_add_devices(bus);
28432 +       }
28433 +}
28434 +
28435 +char * __init pcibios_setup(char *str)
28436 +{
28437 +       if (!strcmp(str, "debug")) {
28438 +               debug_pci = 1;
28439 +               return NULL;
28440 +       }
28441 +       return str;
28442 +}
28443 +
28444 +/*
28445 + * From arch/i386/kernel/pci-i386.c:
28446 + *
28447 + * We need to avoid collisions with `mirrored' VGA ports
28448 + * and other strange ISA hardware, so we always want the
28449 + * addresses to be allocated in the 0x000-0x0ff region
28450 + * modulo 0x400.
28451 + *
28452 + * Why? Because some silly external IO cards only decode
28453 + * the low 10 bits of the IO address. The 0x00-0xff region
28454 + * is reserved for motherboard devices that decode all 16
28455 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
28456 + * but we want to try to avoid allocating at 0x2900-0x2bff
28457 + * which might be mirrored at 0x0100-0x03ff..
28458 + */
28459 +void pcibios_align_resource(void *data, struct resource *res,
28460 +                           resource_size_t size, resource_size_t align)
28461 +{
28462 +       resource_size_t start = res->start;
28463 +
28464 +       if (res->flags & IORESOURCE_IO && start & 0x300)
28465 +               start = (start + 0x3ff) & ~0x3ff;
28466 +
28467 +       res->start = (start + align - 1) & ~(align - 1);
28468 +}
28469 +
28470 +
28471 +void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
28472 +{
28473 +       if (debug_pci)
28474 +               printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
28475 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
28476 +}
28477 +
28478 +/*
28479 + * If the bus contains any of these devices, then we must not turn on
28480 + * parity checking of any kind.  Currently this is CyberPro 20x0 only.
28481 + */
28482 +static inline int pdev_bad_for_parity(struct pci_dev *dev)
28483 +{
28484 +       return (dev->vendor == PCI_VENDOR_ID_INTERG &&
28485 +               (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
28486 +                dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
28487 +               (dev->vendor == PCI_VENDOR_ID_ITE &&
28488 +                dev->device == PCI_DEVICE_ID_ITE_8152);
28489 +
28490 +}
28491 +
28492 +/*
28493 + * Adjust the device resources from bus-centric to Linux-centric.
28494 + */
28495 +static void __devinit
28496 +pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
28497 +{
28498 +       resource_size_t offset;
28499 +       int i;
28500 +
28501 +       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
28502 +               if (dev->resource[i].start == 0)
28503 +                       continue;
28504 +               if (dev->resource[i].flags & IORESOURCE_MEM)
28505 +                       offset = root->mem_offset;
28506 +               else
28507 +                       offset = root->io_offset;
28508 +
28509 +               dev->resource[i].start += offset;
28510 +               dev->resource[i].end   += offset;
28511 +       }
28512 +}
28513 +
28514 +static void __devinit
28515 +pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
28516 +{
28517 +       struct pci_dev *dev = bus->self;
28518 +       int i;
28519 +
28520 +       if (!dev) {
28521 +               /*
28522 +                * Assign root bus resources.
28523 +                */
28524 +               for (i = 0; i < 3; i++)
28525 +                       bus->resource[i] = root->resource[i];
28526 +       }
28527 +}
28528 +
28529 +/*
28530 + * pcibios_fixup_bus - Called after each bus is probed,
28531 + * but before its children are examined.
28532 + */
28533 +void pcibios_fixup_bus(struct pci_bus *bus)
28534 +{
28535 +       struct pci_sys_data *root = bus->sysdata;
28536 +       struct pci_dev *dev;
28537 +       u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
28538 +               PCI_COMMAND_FAST_BACK;
28539 +
28540 +       pbus_assign_bus_resources(bus, root);
28541 +
28542 +       /*
28543 +        * Walk the devices on this bus, working out what we can
28544 +        * and can't support.
28545 +        */
28546 +       list_for_each_entry(dev, &bus->devices, bus_list) {
28547 +               u16 status;
28548 +
28549 +               pdev_fixup_device_resources(root, dev);
28550 +
28551 +               pci_read_config_word(dev, PCI_STATUS, &status);
28552 +
28553 +               /*
28554 +                * If any device on this bus does not support fast back
28555 +                * to back transfers, then the bus as a whole is not able
28556 +                * to support them.  Having fast back to back transfers
28557 +                * on saves us one PCI cycle per transaction.
28558 +                */
28559 +               if (!(status & PCI_STATUS_FAST_BACK))
28560 +                       features &= ~PCI_COMMAND_FAST_BACK;
28561 +
28562 +               if (pdev_bad_for_parity(dev))
28563 +                       features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
28564 +
28565 +               switch (dev->class >> 8) {
28566 +               case PCI_CLASS_BRIDGE_PCI:
28567 +                       pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status);
28568 +                       status |= PCI_BRIDGE_CTL_PARITY |
28569 +                               PCI_BRIDGE_CTL_MASTER_ABORT;
28570 +                       status &= ~(PCI_BRIDGE_CTL_BUS_RESET |
28571 +                                   PCI_BRIDGE_CTL_FAST_BACK);
28572 +                       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status);
28573 +                       break;
28574 +
28575 +               case PCI_CLASS_BRIDGE_CARDBUS:
28576 +                       pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28577 +                                            &status);
28578 +                       status |= PCI_CB_BRIDGE_CTL_PARITY |
28579 +                               PCI_CB_BRIDGE_CTL_MASTER_ABORT;
28580 +                       pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28581 +                                             status);
28582 +                       break;
28583 +               }
28584 +       }
28585 +
28586 +       /*
28587 +        * Now walk the devices again, this time setting them up.
28588 +        */
28589 +       list_for_each_entry(dev, &bus->devices, bus_list) {
28590 +               u16 cmd;
28591 +
28592 +               pci_read_config_word(dev, PCI_COMMAND, &cmd);
28593 +               cmd |= features;
28594 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
28595 +
28596 +               pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
28597 +                                     L1_CACHE_BYTES >> 2);
28598 +       }
28599 +
28600 +       /*
28601 +        * Propagate the flags to the PCI bridge.
28602 +        */
28603 +       if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
28604 +               if (features & PCI_COMMAND_FAST_BACK)
28605 +                       bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK;
28606 +               if (features & PCI_COMMAND_PARITY)
28607 +                       bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY;
28608 +       }
28609 +
28610 +       /*
28611 +        * Report what we did for this bus
28612 +        */
28613 +       printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
28614 +               bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
28615 +}
28616 +/*
28617 + * Convert from Linux-centric to bus-centric addresses for bridge devices.
28618 + */
28619 +void
28620 +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
28621 +                        struct resource *res)
28622 +{
28623 +       struct pci_sys_data *root = dev->sysdata;
28624 +       unsigned long offset = 0;
28625 +
28626 +       if (res->flags & IORESOURCE_IO)
28627 +               offset = root->io_offset;
28628 +       if (res->flags & IORESOURCE_MEM)
28629 +               offset = root->mem_offset;
28630 +
28631 +       region->start = res->start - offset;
28632 +       region->end   = res->end - offset;
28633 +}
28634 +
28635 +void __devinit
28636 +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
28637 +                       struct pci_bus_region *region)
28638 +{
28639 +       struct pci_sys_data *root = dev->sysdata;
28640 +       unsigned long offset = 0;
28641 +
28642 +       if (res->flags & IORESOURCE_IO)
28643 +               offset = root->io_offset;
28644 +       if (res->flags & IORESOURCE_MEM)
28645 +               offset = root->mem_offset;
28646 +
28647 +       res->start = region->start + offset;
28648 +       res->end   = region->end + offset;
28649 +}
28650 +
28651 +#ifdef CONFIG_HOTPLUG
28652 +EXPORT_SYMBOL(pcibios_fixup_bus);
28653 +EXPORT_SYMBOL(pcibios_resource_to_bus);
28654 +EXPORT_SYMBOL(pcibios_bus_to_resource);
28655 +#endif
28656 +
28657 +/**
28658 + * pcibios_enable_device - Enable I/O and memory.
28659 + * @dev: PCI device to be enabled
28660 + */
28661 +int pcibios_enable_device(struct pci_dev *dev, int mask)
28662 +{
28663 +       u16 cmd, old_cmd;
28664 +       int idx;
28665 +       struct resource *r;
28666 +
28667 +       pci_read_config_word(dev, PCI_COMMAND, &cmd);
28668 +       old_cmd = cmd;
28669 +       for (idx = 0; idx < 6; idx++) {
28670 +               /* Only set up the requested stuff */
28671 +               if (!(mask & (1 << idx)))
28672 +                       continue;
28673 +
28674 +               r = dev->resource + idx;
28675 +               if (!r->start && r->end) {
28676 +                       printk(KERN_ERR "PCI: Device %s not available because"
28677 +                              " of resource collisions\n", pci_name(dev));
28678 +                       return -EINVAL;
28679 +               }
28680 +               if (r->flags & IORESOURCE_IO)
28681 +                       cmd |= PCI_COMMAND_IO;
28682 +               if (r->flags & IORESOURCE_MEM)
28683 +                       cmd |= PCI_COMMAND_MEMORY;
28684 +       }
28685 +
28686 +       /*
28687 +        * Bridges (eg, cardbus bridges) need to be fully enabled
28688 +        */
28689 +       if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
28690 +               cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
28691 +
28692 +       if (cmd != old_cmd) {
28693 +               printk("PCI: enabling device %s (%04x -> %04x)\n",
28694 +                      pci_name(dev), old_cmd, cmd);
28695 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
28696 +       }
28697 +       return 0;
28698 +}
28699 +
28700 +
28701 +struct pci_ops ubi32_pci_ops = {
28702 +       .read   = ubi32_pci_read_config,
28703 +       .write  = ubi32_pci_write_config,
28704 +};
28705 +
28706 +static struct pci_bus *ubi32_pci_scan_bus(int nr, struct pci_sys_data *sys)
28707 +{
28708 +       return pci_scan_bus(sys->busnr, &ubi32_pci_ops, sys);
28709 +}
28710 +
28711 +#define UBI32_PCI_MEM_BASE PCI_DEV_REG_BASE
28712 +#define UBI32_PCI_MEM_LEN  0x80000000
28713 +
28714 +#define UBI32_PCI_IO_BASE 0x0
28715 +#define UBI32_PCI_IO_END  0x0
28716 +
28717 +static struct resource ubi32_pci_mem = {
28718 +       .name   = "PCI memory space",
28719 +       .start  = UBI32_PCI_MEM_BASE,
28720 +       .end    = UBI32_PCI_MEM_BASE + UBI32_PCI_MEM_LEN - 1,
28721 +       .flags  = IORESOURCE_MEM,
28722 +};
28723 +
28724 +static struct resource ubi32_pci_io = {
28725 +       .name   = "PCI IO space",
28726 +       .start  = UBI32_PCI_IO_BASE,
28727 +       .end    = UBI32_PCI_IO_END,
28728 +       .flags  = IORESOURCE_IO,
28729 +};
28730 +
28731 +static int __init ubi32_pci_setup(int nr, struct pci_sys_data *sys)
28732 +{
28733 +       if (nr > 0)
28734 +               return 0;
28735 +
28736 +       request_resource(&iomem_resource, &ubi32_pci_mem);
28737 +       request_resource(&ioport_resource, &ubi32_pci_io);
28738 +
28739 +       sys->resource[0] = &ubi32_pci_io;
28740 +       sys->resource[1] = &ubi32_pci_mem;
28741 +       sys->resource[2] = NULL;
28742 +
28743 +       return 1;
28744 +}
28745 +
28746 +static void __init ubi32_pci_preinit(void)
28747 +{
28748 +}
28749 +
28750 +static int __init ubi32_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28751 +{
28752 +       return pci_node->dn.recvirq;
28753 +}
28754 +
28755 +struct hw_pci ubi32_pci __initdata = {
28756 +       .nr_controllers = 1,
28757 +       .preinit        = ubi32_pci_preinit,
28758 +       .setup          = ubi32_pci_setup,
28759 +       .scan           = ubi32_pci_scan_bus,
28760 +       .map_irq        = ubi32_pci_map_irq,
28761 +};
28762 +
28763 +static int __init ubi32_pci_init(void)
28764 +{
28765 +       pci_node = (struct pci_devnode *)devtree_find_node("pci");
28766 +       if (pci_node == NULL) {
28767 +               printk(KERN_WARNING "PCI init failed\n");
28768 +               return -ENOSYS;
28769 +       }
28770 +       pci_common_init(&ubi32_pci);
28771 +       return 0;
28772 +}
28773 +
28774 +subsys_initcall(ubi32_pci_init);
28775 +
28776 +/*
28777 + * workaround for dual PCI card interrupt
28778 + */
28779 +#define PCI_COMMON_INT_BIT (1 << 19)
28780 +void ubi32_pci_int_wr(void)
28781 +{
28782 +       volatile unsigned int pci_int_line;
28783 +       pci_int_line = UBICOM32_IO_PORT(RB)->gpio_in;
28784 +       if (!(pci_int_line & PCI_COMMON_INT_BIT))
28785 +       {
28786 +               ubicom32_set_interrupt(pci_node->dn.recvirq);
28787 +       }
28788 +}
28789 +EXPORT_SYMBOL(ubi32_pci_int_wr);
28790 --- /dev/null
28791 +++ b/arch/ubicom32/mach-common/ring_tio.c
28792 @@ -0,0 +1,123 @@
28793 +/*
28794 + * arch/ubicom32/mach-common/ring_tio.c
28795 + *   Generic initialization for UIO Ubicom32 Ring
28796 + *
28797 + * (C) Copyright 2009, Ubicom, Inc.
28798 + *
28799 + * This file is part of the Ubicom32 Linux Kernel Port.
28800 + *
28801 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
28802 + * it and/or modify it under the terms of the GNU General Public License
28803 + * as published by the Free Software Foundation, either version 2 of the
28804 + * License, or (at your option) any later version.
28805 + *
28806 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
28807 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
28808 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
28809 + * the GNU General Public License for more details.
28810 + *
28811 + * You should have received a copy of the GNU General Public License
28812 + * along with the Ubicom32 Linux Kernel Port.  If not,
28813 + * see <http://www.gnu.org/licenses/>.
28814 + */
28815 +
28816 +#include <linux/platform_device.h>
28817 +#include <linux/types.h>
28818 +
28819 +#include <asm/devtree.h>
28820 +#include <asm/ring_tio.h>
28821 +
28822 +static const char *ring_tio_driver_name = "uio_ubicom32ring";
28823 +
28824 +/*
28825 + * The number of ring_tio's currently allocated, used for .id
28826 + */
28827 +static int __initdata ring_tio_count;
28828 +
28829 +/*
28830 + * The maximum number of resources that the ring_tio will have.
28831 + * Currently 3, a register space, and up to 2 interrupts.
28832 + */
28833 +#define RING_TIO_MAX_RESOURCES 3
28834 +
28835 +/*
28836 + * ring_tio_init
28837 + *     Checks the device tree and instantiates the driver if found
28838 + */
28839 +void __init ring_tio_init(const char *node_name)
28840 +{
28841 +       struct platform_device *pdev;
28842 +       struct resource *res;
28843 +       int resource_idx = 0;
28844 +       struct ring_tio_node *ring_node;
28845 +
28846 +       /*
28847 +        * Check the device tree for the ring_tio
28848 +        */
28849 +       ring_node = (struct ring_tio_node *)devtree_find_node(node_name);
28850 +       if (!ring_node) {
28851 +               printk(KERN_WARNING "Ring TIO '%s' not found\n", node_name);
28852 +               return;
28853 +       }
28854 +
28855 +       if (ring_node->version != RING_TIO_NODE_VERSION) {
28856 +               printk(KERN_WARNING "ring_tio not compatible\n");
28857 +               return;
28858 +       }
28859 +
28860 +       /*
28861 +        * Dynamically create the platform_device structure and resources
28862 +        */
28863 +       pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
28864 +       if (!pdev) {
28865 +               printk(KERN_WARNING "ring_tio could not alloc pdev\n");
28866 +               return;
28867 +       }
28868 +
28869 +       res = kzalloc(sizeof(struct resource) * RING_TIO_MAX_RESOURCES,
28870 +                       GFP_KERNEL);
28871 +       if (!res) {
28872 +               kfree(pdev);
28873 +               printk(KERN_WARNING "ring_tio could not alloc res\n");
28874 +               return;
28875 +       }
28876 +
28877 +       pdev->name = ring_tio_driver_name;
28878 +       pdev->id = ring_tio_count++;
28879 +       pdev->resource = res;
28880 +
28881 +       /*
28882 +        * Fill in the resources and platform data from devtree information
28883 +        */
28884 +       res[resource_idx].start = (u32_t)(ring_node->regs);
28885 +       res[resource_idx].end = (u32_t)(ring_node->regs);
28886 +       res[resource_idx].flags = IORESOURCE_MEM;
28887 +       resource_idx++;
28888 +
28889 +       if (ring_node->dn.sendirq != 0xFF) {
28890 +               res[resource_idx].start = ring_node->dn.sendirq;
28891 +               res[resource_idx].flags = IORESOURCE_IRQ;
28892 +               resource_idx++;
28893 +       }
28894 +
28895 +       if (ring_node->dn.recvirq != 0xFF) {
28896 +               res[resource_idx].start = ring_node->dn.recvirq;
28897 +               res[resource_idx].flags = IORESOURCE_IRQ;
28898 +               resource_idx++;
28899 +       }
28900 +       pdev->num_resources = resource_idx;
28901 +
28902 +       printk(KERN_INFO "RingTIO.%d '%s' found irq=%d/%d regs=%p pdev=%p/%p\n",
28903 +               ring_tio_count - 1, node_name, ring_node->dn.sendirq,
28904 +               ring_node->dn.recvirq, ring_node->regs, pdev, res);
28905 +
28906 +       /*
28907 +        * Try to get the device registered
28908 +        */
28909 +       pdev->dev.platform_data = (void *)node_name;
28910 +       if (platform_device_register(pdev) < 0) {
28911 +               printk(KERN_WARNING "Ring failed to register\n");
28912 +               kfree(pdev);
28913 +               kfree(res);
28914 +       }
28915 +}
28916 --- /dev/null
28917 +++ b/arch/ubicom32/mach-common/ubi32-gpio.c
28918 @@ -0,0 +1,411 @@
28919 +/*
28920 + * arch/ubicom32/mach-common/ubi32-gpio.c
28921 + *   Ubicom gpio driver
28922 + *
28923 + * (C) Copyright 2009, Ubicom, Inc.
28924 + *
28925 + * This file is part of the Ubicom32 Linux Kernel Port.
28926 + *
28927 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
28928 + * it and/or modify it under the terms of the GNU General Public License
28929 + * as published by the Free Software Foundation, either version 2 of the
28930 + * License, or (at your option) any later version.
28931 + *
28932 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
28933 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
28934 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
28935 + * the GNU General Public License for more details.
28936 + *
28937 + * You should have received a copy of the GNU General Public License
28938 + * along with the Ubicom32 Linux Kernel Port.  If not,
28939 + * see <http://www.gnu.org/licenses/>.
28940 + *
28941 + * Ubicom32 implementation derived from (with many thanks):
28942 + *   arch/m68knommu
28943 + *   arch/blackfin
28944 + *   arch/parisc
28945 + */
28946 +
28947 +#include <linux/module.h>
28948 +#include <linux/init.h>
28949 +#include <linux/errno.h>
28950 +#include <linux/kernel.h>
28951 +#include <linux/io.h>
28952 +#include <linux/gpio.h>
28953 +#include <linux/irq.h>
28954 +#include <linux/version.h>
28955 +
28956 +#if defined(CONFIG_PROC_FS)
28957 +#include <linux/proc_fs.h>
28958 +#endif
28959 +
28960 +#include <linux/io.h>
28961 +#include <asm/ip5000.h>
28962 +#include <linux/gpio.h>
28963 +
28964 +#define UBI_GPIO_CHECK_RANGE     0  /* !0 enables range checking */
28965 +
28966 +
28967 +/*
28968 + * Each I/O port can be configured to operate in one of several
28969 + * functional modes. One of these modes is GPIO, which causes the
28970 + * entire port to function as a GPIO port.  Since the various port
28971 + * registers serve the system with other important functions, such as
28972 + * ethernet, serial, USB, etc., it isn't advantageous to set any of
28973 + * the ports to be entirely dedicated for GPIO use.  The processor
28974 + * alternatively allows individual bits of a port to be assigned to be
28975 + * used as GPIO independently from the overall port function.  This
28976 + * bit-by-bit assignment is selected by setting the corresponding bit
28977 + * in the port's gpio_mask register.  When set, the selected bit is
28978 + * then enabled as a GPIO.  If the corresponding bit is set in the
28979 + * gpio_ctl register of the port, the bit is configured as a GPIO
28980 + * output.  Otherwise, it is an input.
28981 + *
28982 + * NOTE: This driver uses the bit-by-bit GPIO function assignment
28983 + * exclusively and *never* sets the port function registers to the
28984 + * GPIO function.
28985 + *
28986 + * GPIO is not the main function of any of the I/O ports.  The port
28987 + * bit widths are variable from one port to the next, determined by
28988 + * the more common I/O functions of the ports.  For simplicity, this
28989 + * driver assumes all the ports are 32 bits wide regardless of the
28990 + * real bit width of the port.  GPIO bits are numbered from zero to
28991 + * MAX_UBICOM_GPIOS.  Within a port, the least significant bit is
28992 + * numbered bit zero, the most significant is bit 31.  Since the ports
28993 + * are considered logically contiguous, GPIO #32 is the zeroth bit in
28994 + * port #1, and so on.  Due to the hardware definition, there are
28995 + * large gaps in the GPIO numbers representing real pins.
28996 + *
28997 + * NOTE: It is up to the programmer to refer to the processor data
28998 + * sheet to determine which bits in which ports can be accessed and
28999 + * used for GPIO.
29000 + *
29001 + */
29002 +
29003 +
29004 +/* There are 9 ports, A through I. Not all 32 bits in each
29005 + * port can be a GPIO, but we pretend they are.  Its up to the
29006 + * programmer to refer to the processor data sheet.
29007 + */
29008 +#define MAX_UBICOM_GPIOS   (9 * 32) /* ARCH_NR_GPIOS */
29009 +#define NUM_GPIO_PORTS     (gpio_bank(MAX_UBICOM_GPIOS))
29010 +
29011 +
29012 +/* GPIO reservation bit map array */
29013 +static int reserved_gpio_map[NUM_GPIO_PORTS];
29014 +
29015 +
29016 +/* Array of hardware io_port addresses */
29017 +static struct ubicom32_io_port *gpio_bank_addr[NUM_GPIO_PORTS] =
29018 +{
29019 +       UBICOM32_IO_PORT(RA),
29020 +       UBICOM32_IO_PORT(RB),
29021 +       UBICOM32_IO_PORT(RC),
29022 +       UBICOM32_IO_PORT(RD),
29023 +       UBICOM32_IO_PORT(RE),
29024 +       UBICOM32_IO_PORT(RF),
29025 +       UBICOM32_IO_PORT(RG),
29026 +       UBICOM32_IO_PORT(RH),
29027 +       UBICOM32_IO_PORT(RI)
29028 +};
29029 +
29030 +
29031 +struct ubi_gpio_chip {
29032 +       /*
29033 +        * Right now, nothing else lives here.
29034 +        */
29035 +       struct gpio_chip gpio_chip;
29036 +};
29037 +
29038 +
29039 +#if UBI_GPIO_CHECK_RANGE
29040 +inline int check_gpio(unsigned gpio)
29041 +{
29042 +       if (gpio >= MAX_UBICOM_GPIOS)
29043 +               return -EINVAL;
29044 +       return 0;
29045 +}
29046 +#else
29047 +#define check_gpio(n)   (0)
29048 +#endif
29049 +
29050 +/*
29051 + * ubi_gpio_get_port
29052 + *     Get the IO port associated with a certain gpio
29053 + */
29054 +struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio)
29055 +{
29056 +       if (gpio_bank(gpio) > NUM_GPIO_PORTS) {
29057 +               return NULL;
29058 +       }
29059 +       return gpio_bank_addr[gpio_bank(gpio)];
29060 +}
29061 +
29062 +/*
29063 + * ubi_gpio_error()
29064 + */
29065 +static void ubi_gpio_error(unsigned gpio)
29066 +{
29067 +       printk(KERN_ERR "ubicom-gpio: GPIO %d wasn't requested!\n", gpio);
29068 +}
29069 +
29070 +/*
29071 + * ubi_port_setup()
29072 + */
29073 +static void ubi_port_setup(unsigned gpio, unsigned short usage)
29074 +{
29075 +       if (!check_gpio(gpio)) {
29076 +               if (usage) {
29077 +                       UBICOM32_GPIO_ENABLE(gpio);
29078 +               } else {
29079 +                       UBICOM32_GPIO_DISABLE(gpio);
29080 +               }
29081 +       }
29082 +}
29083 +
29084 +/*
29085 + * ubi_gpio_request()
29086 + */
29087 +static int ubi_gpio_request(struct gpio_chip *chip, unsigned gpio)
29088 +{
29089 +       unsigned long flags;
29090 +
29091 +       if (check_gpio(gpio) < 0)
29092 +               return -EINVAL;
29093 +
29094 +       local_irq_save(flags);
29095 +
29096 +       if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29097 +               printk(KERN_ERR "ubi-gpio: GPIO %d is already reserved!\n",
29098 +                      gpio);
29099 +               local_irq_restore(flags);
29100 +               return -EBUSY;
29101 +       }
29102 +
29103 +       reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
29104 +
29105 +       ubi_port_setup(gpio, 1);
29106 +
29107 +       local_irq_restore(flags);
29108 +
29109 +       return 0;
29110 +}
29111 +
29112 +/*
29113 + * ubi_gpio_free()
29114 + */
29115 +static void ubi_gpio_free(struct gpio_chip *chip, unsigned gpio)
29116 +{
29117 +       unsigned long flags;
29118 +
29119 +       if (check_gpio(gpio) < 0)
29120 +               return;
29121 +
29122 +       local_irq_save(flags);
29123 +
29124 +       if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
29125 +               ubi_gpio_error(gpio);
29126 +               local_irq_restore(flags);
29127 +               return;
29128 +       }
29129 +
29130 +       /* Assert the pin is no longer claimed */
29131 +       reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
29132 +
29133 +       /* Revert port bit to use specified by port->function */
29134 +       ubi_port_setup(gpio, 0);
29135 +
29136 +       local_irq_restore(flags);
29137 +}
29138 +
29139 +/*
29140 + * ubi_gpio_direction_input()
29141 + */
29142 +static int ubi_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
29143 +{
29144 +       unsigned long flags;
29145 +
29146 +       if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29147 +               ubi_gpio_error(gpio);
29148 +               return -EINVAL;
29149 +       }
29150 +
29151 +       local_irq_save(flags);
29152 +
29153 +       /* Configure pin as gpio */
29154 +       ubi_port_setup(gpio, 1);
29155 +
29156 +       /* Assert pin is an input */
29157 +       UBICOM32_GPIO_SET_PIN_INPUT(gpio);
29158 +
29159 +       local_irq_restore(flags);
29160 +
29161 +       return 0;
29162 +}
29163 +
29164 +
29165 +/*
29166 + * ubi_gpio_direction_output()
29167 + */
29168 +static int ubi_gpio_direction_output(struct gpio_chip *chip,
29169 +                                    unsigned gpio, int value)
29170 +{
29171 +       unsigned long flags;
29172 +
29173 +       if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29174 +               ubi_gpio_error(gpio);
29175 +               return -EINVAL;
29176 +       }
29177 +
29178 +       local_irq_save(flags);
29179 +
29180 +       /* Configure pin as gpio and set initial value in gpio_out register
29181 +        * so that when we enable it as an output, it will have the correct
29182 +        * initial value.
29183 +        */
29184 +       ubi_port_setup(gpio, 1);
29185 +       if (value) {
29186 +               UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29187 +       } else {
29188 +               UBICOM32_GPIO_SET_PIN_LOW(gpio);
29189 +       }
29190 +
29191 +       /* Enable the pin as an output */
29192 +       UBICOM32_GPIO_SET_PIN_OUTPUT(gpio);
29193 +
29194 +       local_irq_restore(flags);
29195 +
29196 +       return 0;
29197 +}
29198 +
29199 +
29200 +/*
29201 + * ubi_gpio_get_value()
29202 + */
29203 +static int ubi_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
29204 +{
29205 +       return 0 != (gpio_bank_addr[gpio_bank(gpio)]->gpio_in & gpio_bit(gpio));
29206 +}
29207 +
29208 +
29209 +/*
29210 + * ubi_gpio_set_value()
29211 + */
29212 +static void ubi_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
29213 +                              int arg)
29214 +{
29215 +       unsigned long flags;
29216 +       local_irq_save(flags);
29217 +
29218 +       if (arg) {
29219 +               UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29220 +       } else {
29221 +               UBICOM32_GPIO_SET_PIN_LOW(gpio);
29222 +       }
29223 +
29224 +       local_irq_restore(flags);
29225 +}
29226 +
29227 +
29228 +/*
29229 + * ubi_gpio_to_irq()
29230 + */
29231 +static int ubi_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
29232 +{
29233 +       return gpio_to_irq(gpio);
29234 +}
29235 +
29236 +
29237 +/*
29238 + * ubi_gpio_init()
29239 + */
29240 +int __init ubi_gpio_init(void)
29241 +{
29242 +       int k;
29243 +       int status;
29244 +       struct ubi_gpio_chip *chip;
29245 +       struct gpio_chip *gc;
29246 +
29247 +       printk(KERN_INFO "Ubicom GPIO Controller\n");
29248 +
29249 +       chip = kzalloc(sizeof(struct ubi_gpio_chip), GFP_KERNEL);
29250 +       if (chip == NULL)
29251 +               return -ENOMEM;
29252 +
29253 +       gc = &chip->gpio_chip;
29254 +       gc->request          = ubi_gpio_request;
29255 +       gc->free             = ubi_gpio_free;
29256 +       gc->to_irq           = ubi_gpio_to_irq;
29257 +       gc->direction_input  = ubi_gpio_direction_input;
29258 +       gc->direction_output = ubi_gpio_direction_output;
29259 +       gc->get              = ubi_gpio_get_value;
29260 +       gc->set              = ubi_gpio_set_value;
29261 +       gc->can_sleep        = 0;
29262 +       gc->base             = 0;
29263 +       gc->ngpio            = MAX_UBICOM_GPIOS; /* ARCH_NR_GPIOS - 1 */
29264 +       gc->label            = "ubi_gpio";
29265 +
29266 +       status = gpiochip_add(gc);
29267 +       if (status != 0) {
29268 +               kfree(chip);
29269 +               return status;
29270 +       }
29271 +
29272 +       /* Assert all pins are free */
29273 +       for (k = 0; k < NUM_GPIO_PORTS; k++) {
29274 +               reserved_gpio_map[k] = 0;
29275 +       }
29276 +
29277 +       return 0;
29278 +}
29279 +
29280 +#if defined(CONFIG_PROC_FS)
29281 +/*
29282 + * ubi_get_gpio_dir()
29283 + */
29284 +static int ubi_get_gpio_dir(unsigned gpio)
29285 +{
29286 +       if (gpio_bank_addr[gpio_bank(gpio)]->gpio_ctl & gpio_bit(gpio))
29287 +               return 1;
29288 +       else
29289 +               return 0;
29290 +}
29291 +
29292 +/*
29293 + * gpio_proc_read()
29294 + */
29295 +static int ubi_gpio_proc_read(char *buf, char **start, off_t offset,
29296 +                         int len, int *unused_i, void *unused_v)
29297 +{
29298 +       int c, outlen = 0;
29299 +
29300 +       for (c = 0; c < MAX_UBICOM_GPIOS; c++) {
29301 +               if (!check_gpio(c) &&
29302 +                   (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) {
29303 +                       len = sprintf(buf, "GPIO_%d:\t\tGPIO %s\n", c,
29304 +                                     ubi_get_gpio_dir(c) ? "OUTPUT" : "INPUT");
29305 +               } else {
29306 +                       continue;
29307 +               }
29308 +
29309 +               buf += len;
29310 +               outlen += len;
29311 +       }
29312 +       return outlen;
29313 +}
29314 +
29315 +/*
29316 + * ubi_gpio_register_proc()
29317 + */
29318 +static __init int ubi_gpio_register_proc(void)
29319 +{
29320 +       struct proc_dir_entry *proc_gpio;
29321 +
29322 +       proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
29323 +       if (proc_gpio)
29324 +               proc_gpio->read_proc = ubi_gpio_proc_read;
29325 +
29326 +       return proc_gpio != NULL;
29327 +}
29328 +device_initcall(ubi_gpio_register_proc);
29329 +#endif
29330 --- /dev/null
29331 +++ b/arch/ubicom32/mach-common/ubicom32hid.c
29332 @@ -0,0 +1,557 @@
29333 +/*
29334 + * arch/ubicom32/mach-common/ubicom32hid.c
29335 + *   I2C driver for HID coprocessor found on some DPF implementations.
29336 + *
29337 + * (C) Copyright 2009, Ubicom, Inc.
29338 + *
29339 + * This file is part of the Ubicom32 Linux Kernel Port.
29340 + *
29341 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
29342 + * it and/or modify it under the terms of the GNU General Public License
29343 + * as published by the Free Software Foundation, either version 2 of the
29344 + * License, or (at your option) any later version.
29345 + *
29346 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
29347 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
29348 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
29349 + * the GNU General Public License for more details.
29350 + *
29351 + * You should have received a copy of the GNU General Public License
29352 + * along with the Ubicom32 Linux Kernel Port.  If not,
29353 + * see <http://www.gnu.org/licenses/>.
29354 + *
29355 + * Ubicom32 implementation derived from (with many thanks):
29356 + *   arch/m68knommu
29357 + *   arch/blackfin
29358 + *   arch/parisc
29359 + */
29360 +
29361 +#include <linux/module.h>
29362 +#include <linux/init.h>
29363 +#include <linux/gpio.h>
29364 +#include <linux/delay.h>
29365 +#include <linux/platform_device.h>
29366 +#include <linux/i2c.h>
29367 +#include <linux/backlight.h>
29368 +#include <linux/fb.h>
29369 +#include <linux/input.h>
29370 +#include <linux/input-polldev.h>
29371 +
29372 +#include <asm/ubicom32hid.h>
29373 +
29374 +#define DRIVER_NAME "ubicom32hid"
29375 +
29376 +#ifdef DEBUG
29377 +static int ubicom32hid_debug;
29378 +#endif
29379 +
29380 +static const struct i2c_device_id ubicom32hid_id[] = {
29381 +       { DRIVER_NAME, },
29382 +       { }
29383 +};
29384 +MODULE_DEVICE_TABLE(i2c, ubicom32hid_id);
29385 +
29386 +/*
29387 + * Define this to make IR checking strict, in general, it's not needed
29388 + */
29389 +#undef UBICOM32HID_STRICT_IR_CHECK
29390 +
29391 +#define UBICOM32HID_CMD_SET_PWM                0x01
29392 +#define UBICOM32HID_CMD_SET_BL_EN      0x02
29393 +#define UBICOM32HID_BL_EN_LOW          0x00
29394 +#define UBICOM32HID_BL_EN_HIZ          0x01
29395 +#define UBICOM32HID_BL_EN_HI           0x02
29396 +#define UBICOM32HID_CMD_FLUSH          0x99
29397 +#define UBICOM32HID_CMD_RESET          0x99
29398 +#define UBICOM32HID_CMD_GET_IR_SWITCH  0xC0
29399 +#define UBICOM32HID_CMD_GET_REVISION   0xfd
29400 +#define UBICOM32HID_CMD_GET_DEVICE_ID  0xfe
29401 +#define UBICOM32HID_CMD_GET_VERSION    0xff
29402 +#define UBICOM32HID_DEVICE_ID          0x49
29403 +
29404 +#define UBICOM32HID_MAX_BRIGHTNESS_PWM 255
29405 +
29406 +/*
29407 + * Data structure returned by the HID device
29408 + */
29409 +struct ubicom32hid_input_data {
29410 +       uint32_t        ircmd;
29411 +       uint8_t         sw_state;
29412 +       uint8_t         sw_changed;
29413 +};
29414 +
29415 +/*
29416 + * Our private data
29417 + */
29418 +struct ubicom32hid_data {
29419 +       /*
29420 +        * Pointer to the platform data structure, we need the settings.
29421 +        */
29422 +       const struct ubicom32hid_platform_data  *pdata;
29423 +
29424 +       /*
29425 +        * Backlight device
29426 +        */
29427 +       struct backlight_device                 *bldev;
29428 +
29429 +       /*
29430 +        * I2C client, for sending messages to the HID device
29431 +        */
29432 +       struct i2c_client                       *client;
29433 +
29434 +       /*
29435 +        * Current intensity, used for get_intensity.
29436 +        */
29437 +       int                                     cur_intensity;
29438 +
29439 +       /*
29440 +        * Input subsystem
29441 +        *      We won't register an input subsystem if there are no mappings.
29442 +        */
29443 +       struct input_polled_dev                 *poll_dev;
29444 +};
29445 +
29446 +
29447 +/*
29448 + * ubicom32hid_set_intensity
29449 + */
29450 +static int ubicom32hid_set_intensity(struct backlight_device *bd)
29451 +{
29452 +       struct ubicom32hid_data *ud =
29453 +               (struct ubicom32hid_data *)bl_get_data(bd);
29454 +       int intensity = bd->props.brightness;
29455 +       int reg;
29456 +       u8_t val;
29457 +       int ret;
29458 +
29459 +       /*
29460 +        * If we're blanked the the intensity doesn't matter.
29461 +        */
29462 +       if ((bd->props.power != FB_BLANK_UNBLANK) ||
29463 +           (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
29464 +               intensity = 0;
29465 +       }
29466 +
29467 +       /*
29468 +        * Set the brightness based on the type of backlight
29469 +        */
29470 +       if (ud->pdata->type == UBICOM32HID_BL_TYPE_BINARY) {
29471 +               reg = UBICOM32HID_CMD_SET_BL_EN;
29472 +               if (intensity) {
29473 +                       val = ud->pdata->invert
29474 +                               ? UBICOM32HID_BL_EN_LOW : UBICOM32HID_BL_EN_HI;
29475 +               } else {
29476 +                       val = ud->pdata->invert
29477 +                               ? UBICOM32HID_BL_EN_HI : UBICOM32HID_BL_EN_LOW;
29478 +               }
29479 +       } else {
29480 +               reg = UBICOM32HID_CMD_SET_PWM;
29481 +               val = ud->pdata->invert
29482 +                       ? (UBICOM32HID_MAX_BRIGHTNESS_PWM - intensity) :
29483 +                       intensity;
29484 +       }
29485 +
29486 +       /*
29487 +        * Send the command
29488 +        */
29489 +       ret = i2c_smbus_write_byte_data(ud->client, reg, val);
29490 +       if (ret < 0) {
29491 +               dev_warn(&ud->client->dev, "Unable to write backlight err=%d\n",
29492 +                        ret);
29493 +               return ret;
29494 +       }
29495 +
29496 +       ud->cur_intensity = intensity;
29497 +
29498 +       return 0;
29499 +}
29500 +
29501 +/*
29502 + * ubicom32hid_get_intensity
29503 + *     Return the current intensity of the backlight.
29504 + */
29505 +static int ubicom32hid_get_intensity(struct backlight_device *bd)
29506 +{
29507 +       struct ubicom32hid_data *ud =
29508 +               (struct ubicom32hid_data *)bl_get_data(bd);
29509 +
29510 +       return ud->cur_intensity;
29511 +}
29512 +
29513 +/*
29514 + * ubicom32hid_verify_data
29515 + *     Verify the data to see if there is any action to be taken
29516 + *
29517 + * Returns 0 if no action is to be taken, non-zero otherwise
29518 + */
29519 +static int ubicom32hid_verify_data(struct ubicom32hid_data *ud,
29520 +                                  struct ubicom32hid_input_data *data)
29521 +{
29522 +       uint8_t *ircmd = (uint8_t *)&(data->ircmd);
29523 +
29524 +       /*
29525 +        * ircmd == DEADBEEF means ir queue is empty.  Since this is a
29526 +        * meaningful code, that means the rest of the message is most likely
29527 +        * correct, so only process the data if the switch state has changed.
29528 +        */
29529 +       if (data->ircmd == 0xDEADBEEF) {
29530 +               return data->sw_changed != 0;
29531 +       }
29532 +
29533 +       /*
29534 +        * We have an ircmd which is not empty:
29535 +        *      Data[1] should be the complement of Data[0]
29536 +        */
29537 +       if (ircmd[0] != (u8_t)~ircmd[1]) {
29538 +               return 0;
29539 +       }
29540 +
29541 +#ifdef UBICOM32HID_STRICT_IR_CHECK
29542 +       /*
29543 +        * It seems that some remote controls don't follow the NEC protocol
29544 +        * properly, so only do this check if the remote does indeed follow the
29545 +        * spec.  Data[3] should be the complement of Data[2]
29546 +        */
29547 +       if (ircmd[2] == (u8_t)~ircmd[3]) {
29548 +               return 1;
29549 +       }
29550 +
29551 +       /*
29552 +        * For non-compliant remotes, check the system code according to what
29553 +        * they send.
29554 +        */
29555 +       if ((ircmd[2] != UBICOM32HID_IR_SYSTEM_CODE_CHECK) ||
29556 +           (ircmd[3] != UBICOM32HID_IR_SYSTEM_CODE)) {
29557 +               return 0;
29558 +       }
29559 +#endif
29560 +
29561 +       /*
29562 +        * Data checks out, process
29563 +        */
29564 +       return 1;
29565 +}
29566 +
29567 +/*
29568 + * ubicom32hid_poll_input
29569 + *     Poll the input from the HID device.
29570 + */
29571 +static void ubicom32hid_poll_input(struct input_polled_dev *dev)
29572 +{
29573 +       struct ubicom32hid_data *ud = (struct ubicom32hid_data *)dev->private;
29574 +       const struct ubicom32hid_platform_data *pdata = ud->pdata;
29575 +       struct ubicom32hid_input_data data;
29576 +       struct input_dev *id = dev->input;
29577 +       int i;
29578 +       int sync_needed = 0;
29579 +       uint8_t cmd;
29580 +       int ret;
29581 +
29582 +       /*
29583 +        * Flush the queue
29584 +        */
29585 +       cmd = UBICOM32HID_CMD_FLUSH;
29586 +       ret = i2c_master_send(ud->client, &cmd, 1);
29587 +       if (ret < 0) {
29588 +               return;
29589 +       }
29590 +
29591 +       ret = i2c_smbus_read_i2c_block_data(
29592 +               ud->client, UBICOM32HID_CMD_GET_IR_SWITCH, 6, (void *)&data);
29593 +       if (ret < 0) {
29594 +               return;
29595 +       }
29596 +
29597 +       /*
29598 +        * Verify the data to see if there is any action to be taken
29599 +        */
29600 +       if (!ubicom32hid_verify_data(ud, &data)) {
29601 +               return;
29602 +       }
29603 +
29604 +#ifdef DEBUG
29605 +       if (ubicom32hid_debug) {
29606 +               printk("Polled ircmd=%8x swstate=%2x swchanged=%2x\n",
29607 +                      data.ircmd, data.sw_state, data.sw_changed);
29608 +       }
29609 +#endif
29610 +
29611 +       /*
29612 +        * Process changed switches
29613 +        */
29614 +       if (data.sw_changed) {
29615 +               const struct ubicom32hid_button *ub = pdata->buttons;
29616 +               for (i = 0; i < pdata->nbuttons; i++, ub++) {
29617 +                       uint8_t mask = (1 << ub->bit);
29618 +                       if (!(data.sw_changed & mask)) {
29619 +                               continue;
29620 +                       }
29621 +
29622 +                       sync_needed = 1;
29623 +                       input_event(id, ub->type, ub->code,
29624 +                                   (data.sw_state & mask) ? 1 : 0);
29625 +               }
29626 +       }
29627 +       if (sync_needed) {
29628 +               input_sync(id);
29629 +       }
29630 +
29631 +       /*
29632 +        * Process ir codes
29633 +        */
29634 +       if (data.ircmd != 0xDEADBEEF) {
29635 +               const struct ubicom32hid_ir *ui = pdata->ircodes;
29636 +               for (i = 0; i < pdata->nircodes; i++, ui++) {
29637 +                       if (ui->ir_code == data.ircmd) {
29638 +                               /*
29639 +                                * Simulate a up/down event
29640 +                                */
29641 +                               input_event(id, ui->type, ui->code, 1);
29642 +                               input_sync(id);
29643 +                               input_event(id, ui->type, ui->code, 0);
29644 +                               input_sync(id);
29645 +                       }
29646 +               }
29647 +       }
29648 +}
29649 +
29650 +
29651 +/*
29652 + * Backlight ops
29653 + */
29654 +static struct backlight_ops ubicom32hid_blops = {
29655 +       .get_brightness = ubicom32hid_get_intensity,
29656 +       .update_status  = ubicom32hid_set_intensity,
29657 +};
29658 +
29659 +/*
29660 + * ubicom32hid_probe
29661 + */
29662 +static int ubicom32hid_probe(struct i2c_client *client,
29663 +                            const struct i2c_device_id *id)
29664 +{
29665 +       struct ubicom32hid_platform_data *pdata;
29666 +       struct ubicom32hid_data *ud;
29667 +       int ret;
29668 +       int i;
29669 +       u8 version[2];
29670 +       char buf[1];
29671 +
29672 +       pdata = client->dev.platform_data;
29673 +       if (pdata == NULL) {
29674 +               return -ENODEV;
29675 +       }
29676 +
29677 +       /*
29678 +        * See if we even have a device available before allocating memory.
29679 +        *
29680 +        * Hard reset the device
29681 +        */
29682 +       ret = gpio_request(pdata->gpio_reset, "ubicom32hid-reset");
29683 +       if (ret < 0) {
29684 +               return ret;
29685 +       }
29686 +       gpio_direction_output(pdata->gpio_reset, pdata->gpio_reset_polarity);
29687 +       udelay(100);
29688 +       gpio_set_value(pdata->gpio_reset, !pdata->gpio_reset_polarity);
29689 +       udelay(100);
29690 +
29691 +       /*
29692 +        * soft reset the device.  It sometimes takes a while to do this.
29693 +        */
29694 +       for (i = 0; i < 50; i++) {
29695 +               buf[0] = UBICOM32HID_CMD_RESET;
29696 +               ret = i2c_master_send(client, buf, 1);
29697 +               if (ret > 0) {
29698 +                       break;
29699 +               }
29700 +               udelay(10000);
29701 +       }
29702 +       if (i == 50) {
29703 +               dev_warn(&client->dev, "Unable to reset device\n");
29704 +               goto fail;
29705 +       }
29706 +
29707 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_DEVICE_ID);
29708 +       if (ret != UBICOM32HID_DEVICE_ID) {
29709 +               dev_warn(&client->dev, "Incorrect device id %02x\n", buf[0]);
29710 +               ret = -ENODEV;
29711 +               goto fail;
29712 +       }
29713 +
29714 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_VERSION);
29715 +       if (ret < 0) {
29716 +               dev_warn(&client->dev, "Unable to get version\n");
29717 +               goto fail;
29718 +       }
29719 +       version[0] = ret;
29720 +
29721 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_REVISION);
29722 +       if (ret < 0) {
29723 +               dev_warn(&client->dev, "Unable to get revision\n");
29724 +               goto fail;
29725 +       }
29726 +       version[1] = ret;
29727 +
29728 +       /*
29729 +        * Allocate our private data
29730 +        */
29731 +       ud = kzalloc(sizeof(struct ubicom32hid_data), GFP_KERNEL);
29732 +       if (!ud) {
29733 +               ret = -ENOMEM;
29734 +               goto fail;
29735 +       }
29736 +       ud->pdata = pdata;
29737 +       ud->client = client;
29738 +
29739 +       /*
29740 +        * Register our backlight device
29741 +        */
29742 +       ud->bldev = backlight_device_register(DRIVER_NAME, &client->dev,
29743 +                                             ud, &ubicom32hid_blops);
29744 +       if (IS_ERR(ud->bldev)) {
29745 +               ret = PTR_ERR(ud->bldev);
29746 +               goto fail2;
29747 +       }
29748 +       platform_set_drvdata(client, ud);
29749 +
29750 +       /*
29751 +        * Start up the backlight with the requested intensity
29752 +        */
29753 +       ud->bldev->props.power = FB_BLANK_UNBLANK;
29754 +       ud->bldev->props.max_brightness =
29755 +               (pdata->type == UBICOM32HID_BL_TYPE_PWM) ?
29756 +               UBICOM32HID_MAX_BRIGHTNESS_PWM : 1;
29757 +       if (pdata->default_intensity < ud->bldev->props.max_brightness) {
29758 +               ud->bldev->props.brightness = pdata->default_intensity;
29759 +       } else {
29760 +               dev_warn(&client->dev, "Default brightness out of range, "
29761 +                        "setting to max\n");
29762 +               ud->bldev->props.brightness = ud->bldev->props.max_brightness;
29763 +       }
29764 +
29765 +       ubicom32hid_set_intensity(ud->bldev);
29766 +
29767 +       /*
29768 +        * Check to see if we have any inputs
29769 +        */
29770 +       if (!pdata->nbuttons && !pdata->nircodes) {
29771 +               goto done;
29772 +       }
29773 +
29774 +       /*
29775 +        * We have buttons or codes, we must register an input device
29776 +        */
29777 +       ud->poll_dev = input_allocate_polled_device();
29778 +       if (!ud->poll_dev) {
29779 +               ret = -ENOMEM;
29780 +               goto fail3;
29781 +       }
29782 +
29783 +       /*
29784 +        * Setup the polling to default to 100ms
29785 +        */
29786 +       ud->poll_dev->poll = ubicom32hid_poll_input;
29787 +       ud->poll_dev->poll_interval =
29788 +               pdata->poll_interval ? pdata->poll_interval : 100;
29789 +       ud->poll_dev->private = ud;
29790 +
29791 +       ud->poll_dev->input->name =
29792 +               pdata->input_name ? pdata->input_name : "Ubicom32HID";
29793 +       ud->poll_dev->input->phys = "ubicom32hid/input0";
29794 +       ud->poll_dev->input->dev.parent = &client->dev;
29795 +       ud->poll_dev->input->id.bustype = BUS_I2C;
29796 +
29797 +       /*
29798 +        * Set the capabilities by running through the buttons and ir codes
29799 +        */
29800 +       for (i = 0; i < pdata->nbuttons; i++) {
29801 +               const struct ubicom32hid_button *ub = &pdata->buttons[i];
29802 +
29803 +               input_set_capability(ud->poll_dev->input,
29804 +                                    ub->type ? ub->type : EV_KEY, ub->code);
29805 +       }
29806 +
29807 +       for (i = 0; i < pdata->nircodes; i++) {
29808 +               const struct ubicom32hid_ir *ui = &pdata->ircodes[i];
29809 +
29810 +               input_set_capability(ud->poll_dev->input,
29811 +                                    ui->type ? ui->type : EV_KEY, ui->code);
29812 +       }
29813 +
29814 +       ret = input_register_polled_device(ud->poll_dev);
29815 +       if (ret) {
29816 +               goto fail3;
29817 +       }
29818 +
29819 +done:
29820 +       printk(KERN_INFO DRIVER_NAME ": enabled, version=%02x.%02x\n",
29821 +              version[0], version[1]);
29822 +
29823 +       return 0;
29824 +
29825 +fail3:
29826 +       gpio_free(ud->pdata->gpio_reset);
29827 +       backlight_device_unregister(ud->bldev);
29828 +fail2:
29829 +       kfree(ud);
29830 +fail:
29831 +       gpio_free(pdata->gpio_reset);
29832 +       return ret;
29833 +}
29834 +
29835 +/*
29836 + * ubicom32hid_remove
29837 + */
29838 +static int ubicom32hid_remove(struct i2c_client *client)
29839 +{
29840 +       struct ubicom32hid_data *ud =
29841 +               (struct ubicom32hid_data *)platform_get_drvdata(client);
29842 +
29843 +       gpio_free(ud->pdata->gpio_reset);
29844 +
29845 +       backlight_device_unregister(ud->bldev);
29846 +
29847 +       if (ud->poll_dev) {
29848 +               input_unregister_polled_device(ud->poll_dev);
29849 +               input_free_polled_device(ud->poll_dev);
29850 +       }
29851 +
29852 +       platform_set_drvdata(client, NULL);
29853 +
29854 +       kfree(ud);
29855 +
29856 +       return 0;
29857 +}
29858 +
29859 +static struct i2c_driver ubicom32hid_driver = {
29860 +       .driver = {
29861 +               .name   = DRIVER_NAME,
29862 +               .owner  = THIS_MODULE,
29863 +       },
29864 +       .probe          = ubicom32hid_probe,
29865 +       .remove         = __exit_p(ubicom32hid_remove),
29866 +       .id_table       = ubicom32hid_id,
29867 +};
29868 +
29869 +/*
29870 + * ubicom32hid_init
29871 + */
29872 +static int __init ubicom32hid_init(void)
29873 +{
29874 +       return i2c_add_driver(&ubicom32hid_driver);
29875 +}
29876 +module_init(ubicom32hid_init);
29877 +
29878 +/*
29879 + * ubicom32hid_exit
29880 + */
29881 +static void __exit ubicom32hid_exit(void)
29882 +{
29883 +       i2c_del_driver(&ubicom32hid_driver);
29884 +}
29885 +module_exit(ubicom32hid_exit);
29886 +
29887 +MODULE_AUTHOR("Pat Tjin <@ubicom.com>")
29888 +MODULE_DESCRIPTION("Ubicom HID driver");
29889 +MODULE_LICENSE("GPL");
29890 --- /dev/null
29891 +++ b/arch/ubicom32/mach-common/ubicom32input.c
29892 @@ -0,0 +1,265 @@
29893 +/*
29894 + * arch/ubicom32/mach-common/ubicom32input.c
29895 + *   Ubicom32 Input driver
29896 + *
29897 + *   based on gpio-keys
29898 + *
29899 + * (C) Copyright 2009, Ubicom, Inc.
29900 + *
29901 + * This file is part of the Ubicom32 Linux Kernel Port.
29902 + *
29903 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
29904 + * it and/or modify it under the terms of the GNU General Public License
29905 + * as published by the Free Software Foundation, either version 2 of the
29906 + * License, or (at your option) any later version.
29907 + *
29908 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
29909 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
29910 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
29911 + * the GNU General Public License for more details.
29912 + *
29913 + * You should have received a copy of the GNU General Public License
29914 + * along with the Ubicom32 Linux Kernel Port.  If not,
29915 + * see <http://www.gnu.org/licenses/>.
29916 + *
29917 + * Ubicom32 implementation derived from (with many thanks):
29918 + *   arch/m68knommu
29919 + *   arch/blackfin
29920 + *   arch/parisc
29921 + *
29922 + *
29923 + * TODO: add groups for inputs which can be sampled together (i.e. I2C)
29924 + */
29925 +
29926 +#include <linux/kernel.h>
29927 +#include <linux/module.h>
29928 +#include <linux/platform_device.h>
29929 +#include <linux/input.h>
29930 +#include <linux/input-polldev.h>
29931 +#include <linux/delay.h>
29932 +#include <linux/gpio.h>
29933 +
29934 +#include <asm/ubicom32input.h>
29935 +
29936 +struct ubicom32input_data {
29937 +       struct ubicom32input_platform_data      *pdata;
29938 +
29939 +       struct input_polled_dev                 *poll_dev;
29940 +
29941 +       /*
29942 +        * collection of previous states for buttons
29943 +        */
29944 +       u8                                      prev_state[0];
29945 +};
29946 +
29947 +/*
29948 + * ubicom32input_poll
29949 + */
29950 +static void ubicom32input_poll(struct input_polled_dev *dev)
29951 +{
29952 +       struct ubicom32input_data *ud =
29953 +               (struct ubicom32input_data *)dev->private;
29954 +       struct ubicom32input_platform_data *pdata = ud->pdata;
29955 +       struct input_dev *id = dev->input;
29956 +       int i;
29957 +       int sync_needed = 0;
29958 +
29959 +       for (i = 0; i < pdata->nbuttons; i++) {
29960 +               const struct ubicom32input_button *ub = &pdata->buttons[i];
29961 +               int state = 0;
29962 +
29963 +               int val = gpio_get_value(ub->gpio);
29964 +
29965 +               /*
29966 +                * Check to see if the state changed from the last time we
29967 +                * looked
29968 +                */
29969 +               if (val == ud->prev_state[i]) {
29970 +                       continue;
29971 +               }
29972 +
29973 +               /*
29974 +                * The state has changed, determine if we are "up" or "down"
29975 +                */
29976 +               ud->prev_state[i] = val;
29977 +
29978 +               if ((!val && ub->active_low) || (val && !ub->active_low)) {
29979 +                       state = 1;
29980 +               }
29981 +
29982 +               input_event(id, ub->type, ub->code, state);
29983 +               sync_needed = 1;
29984 +       }
29985 +
29986 +       if (sync_needed) {
29987 +               input_sync(id);
29988 +       }
29989 +}
29990 +
29991 +/*
29992 + * ubicom32input_probe
29993 + */
29994 +static int __devinit ubicom32input_probe(struct platform_device *pdev)
29995 +{
29996 +       int i;
29997 +       struct ubicom32input_data *ud;
29998 +       struct input_polled_dev *poll_dev;
29999 +       struct input_dev *input_dev;
30000 +       struct ubicom32input_platform_data *pdata;
30001 +       int ret;
30002 +
30003 +       pdata = pdev->dev.platform_data;
30004 +       if (!pdata) {
30005 +               return -EINVAL;
30006 +       }
30007 +
30008 +       ud = kzalloc(sizeof(struct ubicom32input_data) +
30009 +                    pdata->nbuttons, GFP_KERNEL);
30010 +       if (!ud) {
30011 +               return -ENOMEM;
30012 +       }
30013 +       ud->pdata = pdata;
30014 +
30015 +       poll_dev = input_allocate_polled_device();
30016 +       if (!poll_dev) {
30017 +               ret = -ENOMEM;
30018 +               goto fail;
30019 +       }
30020 +
30021 +       platform_set_drvdata(pdev, ud);
30022 +
30023 +       ud->poll_dev = poll_dev;
30024 +       poll_dev->private = ud;
30025 +       poll_dev->poll = ubicom32input_poll;
30026 +
30027 +       /*
30028 +        * Set the poll interval requested, default to 50 msec
30029 +        */
30030 +       if (pdata->poll_interval) {
30031 +               poll_dev->poll_interval = pdata->poll_interval;
30032 +       } else {
30033 +               poll_dev->poll_interval = 50;
30034 +       }
30035 +
30036 +       /*
30037 +        * Setup the input device
30038 +        */
30039 +       input_dev = poll_dev->input;
30040 +       input_dev->name = pdata->name ? pdata->name : "Ubicom32 Input";
30041 +       input_dev->phys = "ubicom32input/input0";
30042 +       input_dev->dev.parent = &pdev->dev;
30043 +       input_dev->id.bustype = BUS_HOST;
30044 +
30045 +       /*
30046 +        * Reserve the GPIOs
30047 +        */
30048 +       for (i = 0; i < pdata->nbuttons; i++) {
30049 +               const struct ubicom32input_button *ub = &pdata->buttons[i];
30050 +
30051 +               ret = gpio_request(ub->gpio,
30052 +                                  ub->desc ? ub->desc : "ubicom32input");
30053 +               if (ret < 0) {
30054 +                       pr_err("ubicom32input: failed to request "
30055 +                              "GPIO %d ret=%d\n", ub->gpio, ret);
30056 +                       goto fail2;
30057 +               }
30058 +
30059 +               ret = gpio_direction_input(ub->gpio);
30060 +               if (ret < 0) {
30061 +                       pr_err("ubicom32input: failed to set "
30062 +                              "GPIO %d to input ret=%d\n", ub->gpio, ret);
30063 +                       goto fail2;
30064 +               }
30065 +
30066 +               /*
30067 +                * Set the previous state to the non-active stae
30068 +                */
30069 +               ud->prev_state[i] = ub->active_low;
30070 +
30071 +               input_set_capability(input_dev,
30072 +                                    ub->type ? ub->type : EV_KEY, ub->code);
30073 +       }
30074 +
30075 +       /*
30076 +        * Register
30077 +        */
30078 +       ret = input_register_polled_device(ud->poll_dev);
30079 +       if (ret) {
30080 +               goto fail2;
30081 +       }
30082 +
30083 +       return 0;
30084 +
30085 +fail2:
30086 +       /*
30087 +        * release the GPIOs we have already requested.
30088 +        */
30089 +       while (--i >= 0) {
30090 +               gpio_free(pdata->buttons[i].gpio);
30091 +       }
30092 +
30093 +fail:
30094 +       printk(KERN_ERR "Ubicom32Input: Failed to register driver %d", ret);
30095 +       platform_set_drvdata(pdev, NULL);
30096 +       input_free_polled_device(poll_dev);
30097 +       kfree(ud);
30098 +       return ret;
30099 +}
30100 +
30101 +/*
30102 + * ubicom32input_remove
30103 + */
30104 +static int __devexit ubicom32input_remove(struct platform_device *dev)
30105 +{
30106 +       struct ubicom32input_data *ud =
30107 +               (struct ubicom32input_data *)platform_get_drvdata(dev);
30108 +       int i;
30109 +
30110 +       /*
30111 +        * Free the GPIOs
30112 +        */
30113 +       for (i = 0; i < ud->pdata->nbuttons; i++) {
30114 +               gpio_free(ud->pdata->buttons[i].gpio);
30115 +       }
30116 +
30117 +       platform_set_drvdata(dev, NULL);
30118 +       input_unregister_polled_device(ud->poll_dev);
30119 +       input_free_polled_device(ud->poll_dev);
30120 +
30121 +       kfree(ud);
30122 +
30123 +       return 0;
30124 +}
30125 +
30126 +static struct platform_driver ubicom32input_driver = {
30127 +       .driver         = {
30128 +               .name   = "ubicom32input",
30129 +               .owner  = THIS_MODULE,
30130 +       },
30131 +       .probe          = ubicom32input_probe,
30132 +       .remove         = __devexit_p(ubicom32input_remove),
30133 +};
30134 +
30135 +/*
30136 + * ubicom32input_init
30137 + */
30138 +static int __devinit ubicom32input_init(void)
30139 +{
30140 +       return platform_driver_register(&ubicom32input_driver);
30141 +}
30142 +
30143 +/*
30144 + * ubicom32input_exit
30145 + */
30146 +static void __exit ubicom32input_exit(void)
30147 +{
30148 +       platform_driver_unregister(&ubicom32input_driver);
30149 +}
30150 +
30151 +module_init(ubicom32input_init);
30152 +module_exit(ubicom32input_exit);
30153 +
30154 +MODULE_AUTHOR("Pat Tjin <pattjin@ubicom.com>");
30155 +MODULE_DESCRIPTION("Ubicom32 Input Driver");
30156 +MODULE_LICENSE("GPL");
30157 +MODULE_ALIAS("platform:ubicom32-input");
30158 --- /dev/null
30159 +++ b/arch/ubicom32/mach-common/ubicom32input_i2c.c
30160 @@ -0,0 +1,325 @@
30161 +/*
30162 + * arch/ubicom32/mach-common/ubicom32input_i2c.c
30163 + *   Ubicom32 Input driver for I2C
30164 + *       Supports PCA953x and family
30165 + *
30166 + *   We hog the I2C device, turning it all to input.
30167 + *
30168 + *   Based on gpio-keys, pca953x
30169 + *
30170 + * (C) Copyright 2009, Ubicom, Inc.
30171 + *
30172 + * This file is part of the Ubicom32 Linux Kernel Port.
30173 + *
30174 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30175 + * it and/or modify it under the terms of the GNU General Public License
30176 + * as published by the Free Software Foundation, either version 2 of the
30177 + * License, or (at your option) any later version.
30178 + *
30179 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30180 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30181 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
30182 + * the GNU General Public License for more details.
30183 + *
30184 + * You should have received a copy of the GNU General Public License
30185 + * along with the Ubicom32 Linux Kernel Port.  If not,
30186 + * see <http://www.gnu.org/licenses/>.
30187 + *
30188 + * Ubicom32 implementation derived from (with many thanks):
30189 + *   arch/m68knommu
30190 + *   arch/blackfin
30191 + *   arch/parisc
30192 + */
30193 +#include <linux/kernel.h>
30194 +#include <linux/module.h>
30195 +#include <linux/platform_device.h>
30196 +#include <linux/input.h>
30197 +#include <linux/input-polldev.h>
30198 +#include <linux/i2c.h>
30199 +
30200 +#include <asm/ubicom32input_i2c.h>
30201 +
30202 +#define UBICOM32INPUT_I2C_REG_INPUT    0
30203 +#define UBICOM32INPUT_I2C_REG_OUTPUT   1
30204 +#define UBICOM32INPUT_I2C_REG_INVERT   2
30205 +#define UBICOM32INPUT_I2C_REG_DIRECTION        3
30206 +
30207 +static const struct i2c_device_id ubicom32input_i2c_id[] = {
30208 +       { "ubicom32in_pca9534", 8, },
30209 +       { "ubicom32in_pca9535", 16, },
30210 +       { "ubicom32in_pca9536", 4, },
30211 +       { "ubicom32in_pca9537", 4, },
30212 +       { "ubicom32in_pca9538", 8, },
30213 +       { "ubicom32in_pca9539", 16, },
30214 +       { "ubicom32in_pca9554", 8, },
30215 +       { "ubicom32in_pca9555", 16, },
30216 +       { "ubicom32in_pca9557", 8, },
30217 +       { "ubicom32in_max7310", 8, },
30218 +       { }
30219 +};
30220 +MODULE_DEVICE_TABLE(i2c, ubicom32input_i2c_id);
30221 +
30222 +struct ubicom32input_i2c_data {
30223 +       struct ubicom32input_i2c_platform_data  *pdata;
30224 +
30225 +       struct i2c_client                       *client;
30226 +
30227 +       struct input_polled_dev                 *poll_dev;
30228 +
30229 +       /*
30230 +        * collection of previous states for buttons
30231 +        */
30232 +       uint16_t                                prev_state;
30233 +
30234 +       uint8_t                                 ngpios;
30235 +};
30236 +
30237 +/*
30238 + * ubicom32input_i2c_write_reg
30239 + *     writes a register to the I2C device.
30240 + */
30241 +static int ubicom32input_i2c_write_reg(struct ubicom32input_i2c_data *ud,
30242 +                                      int reg, uint16_t val)
30243 +{
30244 +       int ret;
30245 +
30246 +       if (ud->ngpios <= 8) {
30247 +               ret = i2c_smbus_write_byte_data(ud->client, reg, val);
30248 +       } else {
30249 +               ret = i2c_smbus_write_word_data(ud->client, reg << 1, val);
30250 +       }
30251 +
30252 +       if (ret < 0) {
30253 +               return ret;
30254 +       }
30255 +
30256 +       return 0;
30257 +}
30258 +
30259 +/*
30260 + * ubicom32input_i2c_read_reg
30261 + *     reads a register from the I2C device.
30262 + */
30263 +static int ubicom32input_i2c_read_reg(struct ubicom32input_i2c_data *ud,
30264 +                                     int reg, uint16_t *val)
30265 +{
30266 +       int ret;
30267 +
30268 +       if (ud->ngpios <= 8) {
30269 +               ret = i2c_smbus_read_byte_data(ud->client, reg);
30270 +       } else {
30271 +               ret = i2c_smbus_read_word_data(ud->client, reg);
30272 +       }
30273 +
30274 +       if (ret < 0) {
30275 +               return ret;
30276 +       }
30277 +
30278 +       *val = (uint16_t)ret;
30279 +
30280 +       return 0;
30281 +}
30282 +
30283 +/*
30284 + * ubicom32input_i2c_poll
30285 + */
30286 +static void ubicom32input_i2c_poll(struct input_polled_dev *dev)
30287 +{
30288 +       struct ubicom32input_i2c_data *ud =
30289 +               (struct ubicom32input_i2c_data *)dev->private;
30290 +       struct ubicom32input_i2c_platform_data *pdata = ud->pdata;
30291 +       struct input_dev *id = dev->input;
30292 +       int i;
30293 +       int sync_needed = 0;
30294 +       uint16_t val;
30295 +       uint16_t change_mask;
30296 +
30297 +       /*
30298 +        * Try to get the input status, if we fail, bail out, maybe we can do it
30299 +        * next time.
30300 +        */
30301 +       if (ubicom32input_i2c_read_reg(ud, UBICOM32INPUT_I2C_REG_INPUT, &val)) {
30302 +               return;
30303 +       }
30304 +
30305 +       /*
30306 +        * see if anything changed by using XOR
30307 +        */
30308 +       change_mask = ud->prev_state ^ val;
30309 +       ud->prev_state = val;
30310 +
30311 +       for (i = 0; i < pdata->nbuttons; i++) {
30312 +               const struct ubicom32input_i2c_button *ub = &pdata->buttons[i];
30313 +               uint16_t mask = 1 << ub->bit;
30314 +               int state = val & mask;
30315 +
30316 +               /*
30317 +                * Check to see if the state changed from the last time we
30318 +                * looked
30319 +                */
30320 +               if (!(change_mask & mask)) {
30321 +                       continue;
30322 +               }
30323 +               input_event(id, ub->type, ub->code, state);
30324 +               sync_needed = 1;
30325 +       }
30326 +
30327 +       if (sync_needed) {
30328 +               input_sync(id);
30329 +       }
30330 +}
30331 +
30332 +/*
30333 + * ubicom32input_i2c_probe
30334 + */
30335 +static int __devinit ubicom32input_i2c_probe(struct i2c_client *client,
30336 +                                            const struct i2c_device_id *id)
30337 +{
30338 +       int i;
30339 +       struct ubicom32input_i2c_data *ud;
30340 +       struct input_polled_dev *poll_dev;
30341 +       struct input_dev *input_dev;
30342 +       struct ubicom32input_i2c_platform_data *pdata;
30343 +       int ret;
30344 +       uint16_t invert_mask = 0;
30345 +
30346 +       pdata = client->dev.platform_data;
30347 +       if (!pdata) {
30348 +               return -EINVAL;
30349 +       }
30350 +
30351 +       ud = kzalloc(sizeof(struct ubicom32input_i2c_data), GFP_KERNEL);
30352 +       if (!ud) {
30353 +               return -ENOMEM;
30354 +       }
30355 +       ud->pdata = pdata;
30356 +       ud->client = client;
30357 +       ud->ngpios = id->driver_data;
30358 +
30359 +       poll_dev = input_allocate_polled_device();
30360 +       if (!poll_dev) {
30361 +               ret = -ENOMEM;
30362 +               goto fail;
30363 +       }
30364 +
30365 +       ud->poll_dev = poll_dev;
30366 +       poll_dev->private = ud;
30367 +       poll_dev->poll = ubicom32input_i2c_poll;
30368 +
30369 +       /*
30370 +        * Set the poll interval requested, default to 100 msec
30371 +        */
30372 +       if (pdata->poll_interval) {
30373 +               poll_dev->poll_interval = pdata->poll_interval;
30374 +       } else {
30375 +               poll_dev->poll_interval = 100;
30376 +       }
30377 +
30378 +       /*
30379 +        * Setup the input device
30380 +        */
30381 +       input_dev = poll_dev->input;
30382 +       input_dev->name = pdata->name ? pdata->name : "Ubicom32 Input I2C";
30383 +       input_dev->phys = "ubicom32input_i2c/input0";
30384 +       input_dev->dev.parent = &client->dev;
30385 +       input_dev->id.bustype = BUS_I2C;
30386 +
30387 +       /*
30388 +        * Set the capabilities
30389 +        */
30390 +       for (i = 0; i < pdata->nbuttons; i++) {
30391 +               const struct ubicom32input_i2c_button *ub = &pdata->buttons[i];
30392 +
30393 +               if (ub->active_low) {
30394 +                       invert_mask |= (1 << ub->bit);
30395 +               }
30396 +
30397 +               input_set_capability(input_dev,
30398 +                                    ub->type ? ub->type : EV_KEY, ub->code);
30399 +       }
30400 +
30401 +       /*
30402 +        * Setup the device (all inputs)
30403 +        */
30404 +       ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_DIRECTION,
30405 +                                         0xFFFF);
30406 +       if (ret < 0) {
30407 +               goto fail;
30408 +       }
30409 +
30410 +       ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_INVERT,
30411 +                                         invert_mask);
30412 +       if (ret < 0) {
30413 +               goto fail;
30414 +       }
30415 +
30416 +       /*
30417 +        * Register
30418 +        */
30419 +       ret = input_register_polled_device(ud->poll_dev);
30420 +       if (ret) {
30421 +               goto fail;
30422 +       }
30423 +
30424 +       i2c_set_clientdata(client, ud);
30425 +
30426 +       return 0;
30427 +
30428 +fail:
30429 +       printk(KERN_ERR "ubicom32input_i2c: Failed to register driver %d\n",
30430 +              ret);
30431 +       input_free_polled_device(poll_dev);
30432 +       kfree(ud);
30433 +       return ret;
30434 +}
30435 +
30436 +/*
30437 + * ubicom32input_i2c_remove
30438 + */
30439 +static int __devexit ubicom32input_i2c_remove(struct i2c_client *client)
30440 +{
30441 +       struct ubicom32input_i2c_data *ud =
30442 +               (struct ubicom32input_i2c_data *)i2c_get_clientdata(client);
30443 +
30444 +       i2c_set_clientdata(client, NULL);
30445 +       input_unregister_polled_device(ud->poll_dev);
30446 +       input_free_polled_device(ud->poll_dev);
30447 +
30448 +       kfree(ud);
30449 +
30450 +       return 0;
30451 +}
30452 +
30453 +static struct i2c_driver ubicom32input_i2c_driver = {
30454 +       .driver         = {
30455 +               .name   = "ubicom32input_i2c",
30456 +               .owner  = THIS_MODULE,
30457 +       },
30458 +       .remove         = __devexit_p(ubicom32input_i2c_remove),
30459 +       .id_table       = ubicom32input_i2c_id,
30460 +       .probe          = ubicom32input_i2c_probe,
30461 +};
30462 +
30463 +/*
30464 + * ubicom32input_i2c_init
30465 + */
30466 +static int __devinit ubicom32input_i2c_init(void)
30467 +{
30468 +       return i2c_add_driver(&ubicom32input_i2c_driver);
30469 +}
30470 +
30471 +/*
30472 + * ubicom32input_i2c_exit
30473 + */
30474 +static void __exit ubicom32input_i2c_exit(void)
30475 +{
30476 +       i2c_del_driver(&ubicom32input_i2c_driver);
30477 +}
30478 +
30479 +module_init(ubicom32input_i2c_init);
30480 +module_exit(ubicom32input_i2c_exit);
30481 +
30482 +MODULE_AUTHOR("Pat Tjin <pattjin@ubicom.com>");
30483 +MODULE_DESCRIPTION("Ubicom32 Input Driver I2C");
30484 +MODULE_LICENSE("GPL");
30485 +MODULE_ALIAS("platform:ubicom32-input");
30486 --- /dev/null
30487 +++ b/arch/ubicom32/mach-common/usb.c
30488 @@ -0,0 +1,133 @@
30489 +/*
30490 + * arch/ubicom32/mach-common/ip5k_usb.c
30491 + *   Ubicom32 architecture usb support.
30492 + *
30493 + * (C) Copyright 2009, Ubicom, Inc.
30494 + * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
30495 + * Author: Kevin Hilman
30496 + *
30497 + * This file is part of the Ubicom32 Linux Kernel Port.
30498 + *
30499 + * The Ubicom32 Linux Kernel Port is free software: you can
30500 + * redistribute it and/or modify it under the terms of the GNU General
30501 + * Public License as published by the Free Software Foundation, either
30502 + * version 2 of the License, or (at your option) any later version.
30503 + *
30504 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30505 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30506 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30507 + * See the GNU General Public License for more details.
30508 + *
30509 + * You should have received a copy of the GNU General Public License
30510 + * along with the Ubicom32 Linux Kernel Port.  If not, 
30511 + * see <http://www.gnu.org/licenses/>.
30512 + *
30513 + * Ubicom32 implementation derived from (with many thanks):
30514 + *   arch/m68knommu
30515 + *   arch/blackfin
30516 + *   arch/parisc
30517 + */
30518 +
30519 +#include <linux/types.h>
30520 +#include <linux/errno.h>
30521 +#include <linux/delay.h>
30522 +#include <linux/platform_device.h>
30523 +#include <linux/dma-mapping.h>
30524 +#include <linux/usb/musb.h>
30525 +#include <asm/devtree.h>
30526 +#include <asm/ip5000.h>
30527 +#include "usb_tio.h"
30528 +
30529 +struct usbtionode *unode = NULL;
30530 +
30531 +static struct resource usb_resources[] = {
30532 +       [0] = {
30533 +               .start  = RJ + 0x800,
30534 +               .end    = RJ + 0x1000,
30535 +               .flags  = IORESOURCE_MEM,
30536 +       },
30537 +       [1] = { /* general IRQ */
30538 +               .start  = 1, /* this is a dummy value, the real irq number is passed from kernel_setup_param */
30539 +               .flags  = IORESOURCE_IRQ,
30540 +       },
30541 +};
30542 +
30543 +
30544 +static struct musb_hdrc_eps_bits musb_eps[] = {
30545 +       { "ep1_tx", 4, },
30546 +       { "ep1_rx", 4, },
30547 +       { "ep2_tx", 10, },
30548 +       { "ep2_rx", 10, },
30549 +       { "ep3_tx", 9, },
30550 +       { "ep3_rx", 9, },
30551 +       { "ep4_tx", 9, },
30552 +       { "ep4_rx", 9, },
30553 +       { "ep5_tx", 6, },
30554 +       { "ep5_rx", 6, },
30555 +};
30556 +
30557 +static struct musb_hdrc_config musb_config = {
30558 +       .multipoint     = true,
30559 +       .dyn_fifo       = false,
30560 +       .soft_con       = true,
30561 +       .dma            = false,
30562 +
30563 +       .num_eps        = 6,
30564 +       .dma_channels   = 0,
30565 +       .ram_bits       = 0,
30566 +       .eps_bits       = musb_eps,
30567 +};
30568 +
30569 +static struct musb_hdrc_platform_data usb_data = {
30570 +#ifdef CONFIG_USB_MUSB_OTG
30571 +       .mode           = MUSB_OTG,
30572 +#else
30573 +#ifdef CONFIG_USB_MUSB_HDRC_HCD
30574 +       .mode           = MUSB_HOST,
30575 +#else
30576 +#ifdef CONFIG_USB_GADGET_MUSB_HDRC
30577 +       .mode           = MUSB_PERIPHERAL,
30578 +#endif
30579 +#endif
30580 +#endif
30581 +       .clock          = NULL,
30582 +       .set_clock      = NULL,
30583 +       .config         = &musb_config,
30584 +};
30585 +
30586 +static struct platform_device musb_device = {
30587 +       .name           = "musb_hdrc",
30588 +       .id             = 0,
30589 +       .dev = {
30590 +               .platform_data          = &usb_data,
30591 +               .dma_mask               = NULL,
30592 +               .coherent_dma_mask      = 0,
30593 +       },
30594 +       .resource       = usb_resources,
30595 +       .num_resources  = ARRAY_SIZE(usb_resources),
30596 +};
30597 +
30598 +struct usbtio_node *usb_node = NULL;
30599 +void ubi32_usb_init(void)
30600 +{
30601 +       /*
30602 +        * See if the usbtio is in the device tree.
30603 +        */
30604 +       usb_node = (struct usbtio_node *)devtree_find_node("usbtio");
30605 +       if (!usb_node) {
30606 +               printk(KERN_WARNING "usb init failed\n");
30607 +               return;
30608 +       }
30609 +
30610 +       usb_resources[1].start = usb_node->dn.recvirq;
30611 +       if (platform_device_register(&musb_device) < 0) {
30612 +               printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
30613 +               return;
30614 +       }
30615 +}
30616 +
30617 +void ubi32_usb_int_clr(void)
30618 +{
30619 +        UBICOM32_IO_PORT(RJ)->int_clr = (1 << 3);
30620 +}
30621 +
30622 --- /dev/null
30623 +++ b/arch/ubicom32/mach-common/usb_tio.c
30624 @@ -0,0 +1,356 @@
30625 +/*
30626 + * arch/ubicom32/mach-common/usb_tio.c
30627 + *  Linux side Ubicom USB TIO driver
30628 + *
30629 + * (C) Copyright 2009, Ubicom, Inc.
30630 + *
30631 + * This file is part of the Ubicom32 Linux Kernel Port.
30632 + *
30633 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30634 + * it and/or modify it under the terms of the GNU General Public License
30635 + * as published by the Free Software Foundation, either version 2 of the
30636 + * License, or (at your option) any later version.
30637 + *
30638 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30639 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30640 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
30641 + * the GNU General Public License for more details.
30642 + *
30643 + * You should have received a copy of the GNU General Public License
30644 + * along with the Ubicom32 Linux Kernel Port.  If not, 
30645 + * see <http://www.gnu.org/licenses/>.
30646 + *
30647 + * Ubicom32 implementation derived from (with many thanks):
30648 + *   arch/m68knommu
30649 + *   arch/blackfin
30650 + *   arch/parisc
30651 + */
30652 +#include <linux/module.h>
30653 +#include <linux/spinlock.h>
30654 +#include <linux/slab.h>
30655 +#include <asm/devtree.h>
30656 +#include "usb_tio.h"
30657 +
30658 +#ifdef CONFIG_SMP
30659 +static DEFINE_SPINLOCK(tio_lock);
30660 +#define USB_TIO_LOCK(lock, flag) spin_lock_irqsave(lock, flag)
30661 +#define USB_TIO_UNLOCK(lock, flag) spin_unlock_irqrestore(lock, flag)
30662 +#define USB_TIO_LOCK_ISLOCKED(lock) spin_try_lock(lock)
30663 +#else
30664 +#define USB_TIO_LOCK(lock, flag) local_irq_save(flag)
30665 +#define USB_TIO_UNLOCK(lock, flag) local_irq_restore(flag)
30666 +#endif
30667 +
30668 +spinlock_t usb_tio_lock;
30669 +
30670 +/*
30671 + * usb_tio_set_hrt_interrupt()
30672 + */
30673 +static inline void usb_tio_set_hrt_interrupt(void)
30674 +{
30675 +       ubicom32_set_interrupt(usb_node->dn.sendirq);
30676 +}
30677 +
30678 +static inline void usb_tio_wait_hrt(void)
30679 +{
30680 +       while (unlikely(usb_node->pdesc));
30681 +}
30682 +
30683 +#if defined(USB_TIO_DEBUG)
30684 +static void usb_tio_request_verify_magic(volatile struct usb_tio_request *req)
30685 +{
30686 +       BUG_ON(req->magic != USB_TIO_REQUEST_MAGIC2);
30687 +}
30688 +
30689 +static void usb_tio_request_clear_magic(volatile struct usb_tio_request *req)
30690 +{
30691 +       req->magic = 0;
30692 +}
30693 +#endif
30694 +
30695 +static void usb_tio_request_set_magic(volatile struct usb_tio_request *req)
30696 +{
30697 +       req->magic = USB_TIO_REQUEST_MAGIC1;
30698 +}
30699 +
30700 +/*
30701 + * usb_tio_commit_request()
30702 + */
30703 +static inline void usb_tio_commit_request(volatile struct usb_tio_request *request)
30704 +{
30705 +       wmb();
30706 +       usb_node->pdesc = request;
30707 +
30708 +       /*
30709 +        * next thing to do is alway checking if (usb_node->pdesc == NULL) 
30710 +        * to see if the request is done, so add a mb() here
30711 +        */
30712 +       mb();
30713 +       usb_tio_set_hrt_interrupt();
30714 +}
30715 +
30716 +/*
30717 + * usb_tio_read_u16()
30718 + *     Synchronously read 16 bits.
30719 + */
30720 +u8_t usb_tio_read_u16(u32_t address, u16_t *data)
30721 +{
30722 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30723 +       unsigned long flag;
30724 +
30725 +       /*
30726 +        * Wait for any previous request to complete and then make this request.
30727 +        */
30728 +       USB_TIO_LOCK(&tio_lock, flag);
30729 +       usb_tio_wait_hrt();
30730 +
30731 +       /*
30732 +        * Fill in the request.
30733 +        */
30734 +       tio_req->address = address;
30735 +       tio_req->cmd = USB_TIO_READ16_SYNC;
30736 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30737 +       usb_tio_commit_request(tio_req);
30738 +
30739 +       /*
30740 +        * Wait for the result to show up.
30741 +        */
30742 +       usb_tio_wait_hrt();
30743 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30744 +       *data = (u16_t)tio_req->data;
30745 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30746 +       USB_TIO_UNLOCK(&tio_lock, flag);
30747 +       return USB_TIO_OK;
30748 +}
30749 +
30750 +/*
30751 + * usb_tio_read_u8()
30752 + *     Synchronously read 16 bits.
30753 + */
30754 +u8_t usb_tio_read_u8(u32_t address, u8_t *data)
30755 +{
30756 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30757 +       unsigned long flag;
30758 +
30759 +       /*
30760 +        * Wait for any previous request to complete and then make this request.
30761 +        */
30762 +       USB_TIO_LOCK(&tio_lock, flag);
30763 +       usb_tio_wait_hrt();
30764 +
30765 +       /*
30766 +        * Fill in the request.
30767 +        */
30768 +       tio_req->address = address;
30769 +       tio_req->cmd = USB_TIO_READ8_SYNC;
30770 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30771 +
30772 +       /*
30773 +        * commit the request
30774 +        */
30775 +       usb_tio_commit_request(tio_req);
30776 +
30777 +       /*
30778 +        * Wait for the result to show up.
30779 +        */
30780 +       usb_tio_wait_hrt();
30781 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30782 +       *data = (u8_t)tio_req->data;
30783 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30784 +       USB_TIO_UNLOCK(&tio_lock, flag);
30785 +       return USB_TIO_OK;
30786 +}
30787 +
30788 +/*
30789 + * usb_tio_write_u16()
30790 + *     Asynchronously  write 16 bits.
30791 + */
30792 +u8_t usb_tio_write_u16(u32_t address, u16_t data)
30793 +{
30794 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30795 +       unsigned long flag;
30796 +
30797 +       /*
30798 +        * Wait for any previous write or pending read to complete.
30799 +        */
30800 +       USB_TIO_LOCK(&tio_lock, flag);
30801 +       usb_tio_wait_hrt();
30802 +
30803 +       tio_req->address = address;
30804 +       tio_req->data = data;
30805 +       tio_req->cmd = USB_TIO_WRITE16_ASYNC;
30806 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30807 +
30808 +       /*
30809 +        * commit the request
30810 +        */
30811 +       usb_tio_commit_request(tio_req);
30812 +       USB_TIO_UNLOCK(&tio_lock, flag);
30813 +       return USB_TIO_OK;
30814 +}
30815 +
30816 +/*
30817 + * usb_tio_write_u8()
30818 + *     Asynchronously  write 8 bits.
30819 + */
30820 +u8_t usb_tio_write_u8(u32_t address, u8_t data)
30821 +{
30822 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30823 +       unsigned long flag;
30824 +
30825 +       /*
30826 +        * Wait for any previous write or pending read to complete.
30827 +        */
30828 +       USB_TIO_LOCK(&tio_lock, flag);
30829 +       usb_tio_wait_hrt();
30830 +
30831 +       tio_req->address = address;
30832 +       tio_req->data = data;
30833 +       tio_req->cmd = USB_TIO_WRITE8_ASYNC;
30834 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30835 +
30836 +       /*
30837 +        * commit the request
30838 +        */
30839 +       usb_tio_commit_request(tio_req);
30840 +       USB_TIO_UNLOCK(&tio_lock, flag);
30841 +       return USB_TIO_OK;
30842 +}
30843 +
30844 +/*
30845 + * usb_tio_read_fifo()
30846 + *     Synchronously read FIFO.
30847 + */
30848 +u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes)
30849 +{
30850 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30851 +       unsigned long flag;
30852 +
30853 +       /*
30854 +        * Wait for any previous request to complete and then make this request.
30855 +        */
30856 +       USB_TIO_LOCK(&tio_lock, flag);
30857 +       usb_tio_wait_hrt();
30858 +
30859 +       /*
30860 +        * Fill in the request.
30861 +        */
30862 +       tio_req->address = address;
30863 +       tio_req->cmd = USB_TIO_READ_FIFO_SYNC;
30864 +       tio_req->buffer = buffer;
30865 +       tio_req->transfer_length = bytes;
30866 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30867 +
30868 +       /*
30869 +        * commit the request
30870 +        */
30871 +       usb_tio_commit_request(tio_req);
30872 +
30873 +        /*
30874 +        * Wait for the result to show up.
30875 +        */
30876 +       usb_tio_wait_hrt();
30877 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30878 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30879 +       USB_TIO_UNLOCK(&tio_lock, flag);
30880 +       return USB_TIO_OK;
30881 +}
30882 +
30883 +/*
30884 + * usb_tio_write_fifo()
30885 + *     Synchronously  write 32 bits.
30886 + */
30887 +u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes)
30888 +{
30889 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30890 +       unsigned long flag;
30891 +
30892 +       USB_TIO_LOCK(&tio_lock, flag);
30893 +       usb_tio_wait_hrt();
30894 +
30895 +       tio_req->address = address;
30896 +       tio_req->buffer = buffer;
30897 +       tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
30898 +       tio_req->transfer_length = bytes;
30899 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30900 +       /*
30901 +        * commit the request
30902 +        */
30903 +       usb_tio_commit_request(tio_req);
30904 +       
30905 +       /*
30906 +        * Wait for the result to show up.
30907 +        */
30908 +       usb_tio_wait_hrt();
30909 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30910 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30911 +       USB_TIO_UNLOCK(&tio_lock, flag);
30912 +       return USB_TIO_OK;
30913 +}
30914 +
30915 +/*
30916 + * usb_tio_write_fifo_async()
30917 + *     Asynchronously write 32 bits.
30918 + */
30919 +u8_t usb_tio_write_fifo_async(u32_t address, u32_t buffer, u32_t bytes)
30920 +{
30921 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30922 +       unsigned long flag;
30923 +
30924 +       USB_TIO_LOCK(&tio_lock, flag);
30925 +       usb_tio_wait_hrt();
30926 +
30927 +       tio_req->address = address;
30928 +       
30929 +       /*
30930 +        * Is it necessary to make a local copy of the buffer? Any chance the URB is aborted before TIO finished the FIFO write?
30931 +        */
30932 +       tio_req->buffer = buffer;
30933 +       tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
30934 +       tio_req->transfer_length = bytes;
30935 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30936 +       /*
30937 +        * commit the request
30938 +        */
30939 +       usb_tio_commit_request(tio_req);
30940 +       USB_TIO_UNLOCK(&tio_lock, flag);
30941 +       return USB_TIO_OK;
30942 +}
30943 +
30944 +/*
30945 + * usb_tio_read_int_status()
30946 + *     read and clear the interrupt status registers
30947 + */
30948 +void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
30949 +{
30950 +
30951 +       /*
30952 +        * clear the interrupt must be syncronized with the TIO thread to prevent the racing condiiton 
30953 +        * that TIO thread try to set it at same time
30954 +        */
30955 +       asm volatile (
30956 +       "1:     bset (%0), (%0), #0     \n\t" \
30957 +       "       jmpne.f 1b              \n\t" \
30958 +               :
30959 +               : "a" (&usb_node->usb_vp_control)
30960 +               : "memory", "cc"
30961 +       );
30962 +
30963 +       *int_usb = usb_node->usb_vp_hw_int_usb;
30964 +       *int_tx  = cpu_to_le16(usb_node->usb_vp_hw_int_tx);
30965 +       *int_rx  = cpu_to_le16(usb_node->usb_vp_hw_int_rx);
30966 +
30967 +       //printk(KERN_INFO "int read %x, %x, %x\n", *int_usb, *int_tx, *int_rx);
30968 +       
30969 +       /* 
30970 +        * The interrupt status register is read-clean, so clear it now
30971 +        */
30972 +       usb_node->usb_vp_hw_int_usb = 0;
30973 +       usb_node->usb_vp_hw_int_tx = 0;
30974 +       usb_node->usb_vp_hw_int_rx = 0;
30975 +
30976 +       /*
30977 +        * release the lock bit
30978 +        */
30979 +       usb_node->usb_vp_control &= 0xfffe;
30980 +}
30981 --- /dev/null
30982 +++ b/arch/ubicom32/mach-common/usb_tio.h
30983 @@ -0,0 +1,111 @@
30984 +/*
30985 + * arch/ubicom32/mach-common/usb_tio.h
30986 + *   Definitions for usb_tio.c
30987 + *
30988 + * (C) Copyright 2009, Ubicom, Inc.
30989 + *
30990 + * This file is part of the Ubicom32 Linux Kernel Port.
30991 + *
30992 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30993 + * it and/or modify it under the terms of the GNU General Public License
30994 + * as published by the Free Software Foundation, either version 2 of the
30995 + * License, or (at your option) any later version.
30996 + *
30997 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30998 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30999 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31000 + * the GNU General Public License for more details.
31001 + *
31002 + * You should have received a copy of the GNU General Public License
31003 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31004 + * see <http://www.gnu.org/licenses/>.
31005 + *
31006 + * Ubicom32 implementation derived from (with many thanks):
31007 + *   arch/m68knommu
31008 + *   arch/blackfin
31009 + *   arch/parisc
31010 + */
31011 +
31012 +#include <linux/version.h>
31013 +#include <linux/kernel.h>
31014 +#include <linux/types.h>
31015 +#include <linux/errno.h>
31016 +#include <linux/err.h>
31017 +#include <asm/devtree.h>
31018 +#include <asm/ip5000.h>
31019 +
31020 +#ifndef _USB_TIO_H
31021 +#define _USB_TIO_H
31022 +
31023 +#undef  USB_TIO_DEBUG
31024 +
31025 +#define USB_TIO_REQUEST_MAGIC1 0x2307
31026 +#define USB_TIO_REQUEST_MAGIC2 0x0789
31027 +#if defined(USB_TIO_DEBUG)
31028 +#define USB_TIO_REQUEST_VERIFY_MAGIC(req)      usb_tio_request_verify_magic(req)
31029 +#define USB_TIO_REQUEST_SET_MAGIC(req)          usb_tio_request_set_magic(req)
31030 +#define USB_TIO_REQUEST_CLEAR_MAGIC(req)       usb_tio_request_clear_magic(req)
31031 +#else
31032 +#define USB_TIO_REQUEST_VERIFY_MAGIC(req)
31033 +#define USB_TIO_REQUEST_SET_MAGIC(req)          usb_tio_request_set_magic(req)
31034 +#define USB_TIO_REQUEST_CLEAR_MAGIC(req)
31035 +#endif
31036 +
31037 +enum USB_TIO_status {
31038 +       USB_TIO_OK,
31039 +       USB_TIO_ERROR,
31040 +       USB_TIO_ERROR_COMMIT,
31041 +};
31042 +
31043 +enum USB_TIO_cmds {
31044 +       USB_TIO_READ16_SYNC,
31045 +       USB_TIO_READ8_SYNC,
31046 +       USB_TIO_READ_FIFO_SYNC,
31047 +
31048 +       USB_TIO_WRITE16_ASYNC,
31049 +       USB_TIO_WRITE8_ASYNC,
31050 +       USB_TIO_WRITE_FIFO_ASYNC,
31051 +
31052 +       USB_TIO_WRITE16_SYNC,
31053 +       USB_TIO_WRITE8_SYNC,
31054 +       USB_TIO_WRITE_FIFO_SYNC,
31055 +
31056 +};
31057 +
31058 +enum USB_TIO_state {
31059 +       USB_TIO_NORMAL,
31060 +       USB_TIO_DMA_SETUP,
31061 +};
31062 +
31063 +struct usb_tio_request {
31064 +       volatile u32_t address;
31065 +       union {
31066 +               volatile u32_t data;
31067 +               volatile u32_t buffer;
31068 +       };
31069 +       volatile u16_t cmd;
31070 +       const volatile u16_t status;
31071 +       volatile u32_t transfer_length;
31072 +       volatile u32_t thread_mask;
31073 +       volatile u16_t magic;
31074 +};
31075 +
31076 +struct usbtio_node {
31077 +       struct devtree_node dn;
31078 +       volatile struct usb_tio_request * volatile pdesc;
31079 +       struct usb_tio_request  request;
31080 +       volatile u32_t usb_vp_config;
31081 +       volatile u32_t usb_vp_control;
31082 +       const volatile u32_t usb_vp_status;
31083 +       volatile u16_t usb_vp_hw_int_tx;
31084 +       volatile u16_t usb_vp_hw_int_rx;
31085 +       volatile u8_t  usb_vp_hw_int_usb;
31086 +       volatile u8_t usb_vp_hw_int_mask_usb;
31087 +        volatile u16_t usb_vp_hw_int_mask_tx;
31088 +        volatile u16_t usb_vp_hw_int_mask_rx;
31089 +
31090 +};
31091 +
31092 +extern struct usbtio_node *usb_node;
31093 +extern void ubi32_usb_init(void);
31094 +#endif
31095 --- /dev/null
31096 +++ b/arch/ubicom32/mach-common/vdc_tio.c
31097 @@ -0,0 +1,111 @@
31098 +/*
31099 + * arch/ubicom32/mach-common/vdc_tio.c
31100 + *   Generic initialization for VDC
31101 + *
31102 + * (C) Copyright 2009, Ubicom, Inc.
31103 + *
31104 + * This file is part of the Ubicom32 Linux Kernel Port.
31105 + *
31106 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31107 + * it and/or modify it under the terms of the GNU General Public License
31108 + * as published by the Free Software Foundation, either version 2 of the
31109 + * License, or (at your option) any later version.
31110 + *
31111 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31112 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31113 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31114 + * the GNU General Public License for more details.
31115 + *
31116 + * You should have received a copy of the GNU General Public License
31117 + * along with the Ubicom32 Linux Kernel Port.  If not,
31118 + * see <http://www.gnu.org/licenses/>.
31119 + *
31120 + * Ubicom32 implementation derived from (with many thanks):
31121 + *   arch/m68knommu
31122 + *   arch/blackfin
31123 + *   arch/parisc
31124 + */
31125 +
31126 +#include <linux/platform_device.h>
31127 +#include <linux/types.h>
31128 +
31129 +#include <asm/devtree.h>
31130 +#include <asm/vdc_tio.h>
31131 +
31132 +/*
31133 + * Resources that this driver uses
31134 + */
31135 +static struct resource vdc_tio_resources[] = {
31136 +       /*
31137 +        * Send IRQ
31138 +        */
31139 +       [0] = {
31140 +               /*
31141 +                * The init routine will query the devtree and fill this in
31142 +                */
31143 +               .flags  = IORESOURCE_IRQ,
31144 +       },
31145 +
31146 +       /*
31147 +        * Receive IRQ (optional)
31148 +        */
31149 +       [1] = {
31150 +               /*
31151 +                * The init routine will query the devtree and fill this in
31152 +                */
31153 +               .flags  = IORESOURCE_IRQ,
31154 +       },
31155 +
31156 +       /*
31157 +        * Memory Mapped Registers
31158 +        */
31159 +       [2] = {
31160 +               /*
31161 +                * The init routine will query the devtree and fill this in
31162 +                */
31163 +               .flags  = IORESOURCE_MEM,
31164 +       },
31165 +};
31166 +
31167 +/*
31168 + * The platform_device structure which is passed to the driver
31169 + */
31170 +static struct platform_device vdc_tio_platform_device = {
31171 +       .name           = "ubicom32fb",
31172 +       .id             = -1,
31173 +       .resource       = vdc_tio_resources,
31174 +       .num_resources  = ARRAY_SIZE(vdc_tio_resources),
31175 +};
31176 +
31177 +/*
31178 + * vdc_tio_init
31179 + *     Checks the device tree and instantiates the driver if found
31180 + */
31181 +void __init vdc_tio_init(void)
31182 +{
31183 +       /*
31184 +        * Check the device tree for the vdc_tio
31185 +        */
31186 +       struct vdc_tio_node *vdc_node =
31187 +               (struct vdc_tio_node *)devtree_find_node("vdctio");
31188 +       if (!vdc_node) {
31189 +               printk(KERN_WARNING "No vdc_tio found\n");
31190 +               return;
31191 +       }
31192 +
31193 +       /*
31194 +        * Fill in the resources and platform data from devtree information
31195 +        */
31196 +       vdc_tio_resources[0].start = vdc_node->dn.sendirq;
31197 +       vdc_tio_resources[1].start = vdc_node->dn.recvirq;
31198 +       vdc_tio_resources[2].start = (u32_t)vdc_node->regs;
31199 +       vdc_tio_resources[2].end = (u32_t)vdc_node->regs +
31200 +               sizeof(struct vdc_tio_vp_regs);
31201 +
31202 +       /*
31203 +        * Try to get the device registered
31204 +        */
31205 +       if (platform_device_register(&vdc_tio_platform_device) < 0) {
31206 +               printk(KERN_WARNING "VDC failed to register\n");
31207 +       }
31208 +}
31209 --- /dev/null
31210 +++ b/arch/ubicom32/mach-ip5k/board-ip5160dev.c
31211 @@ -0,0 +1,110 @@
31212 +/*
31213 + * arch/ubicom32/mach-ip5k/board-ip5160dev.c
31214 + *   Platform initialization for ip5160dev board.
31215 + *
31216 + * (C) Copyright 2009, Ubicom, Inc.
31217 + *
31218 + * This file is part of the Ubicom32 Linux Kernel Port.
31219 + *
31220 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31221 + * it and/or modify it under the terms of the GNU General Public License
31222 + * as published by the Free Software Foundation, either version 2 of the
31223 + * License, or (at your option) any later version.
31224 + *
31225 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31226 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31227 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31228 + * the GNU General Public License for more details.
31229 + *
31230 + * You should have received a copy of the GNU General Public License
31231 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31232 + * see <http://www.gnu.org/licenses/>.
31233 + *
31234 + * Ubicom32 implementation derived from (with many thanks):
31235 + *   arch/m68knommu
31236 + *   arch/blackfin
31237 + *   arch/parisc
31238 + */
31239 +#include <linux/device.h>
31240 +#include <linux/platform_device.h>
31241 +#include <linux/gpio.h>
31242 +
31243 +#include <asm/board.h>
31244 +#include <asm/machdep.h>
31245 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31246 +#include <asm/ubicom32suart.h>
31247 +#endif
31248 +
31249 +/*
31250 + * Factory Default Button on the board at PXn
31251 + * TODO: This is just a placeholder and it needs to include proper header files
31252 + */
31253 +struct ubicom32fdb_platform_data {
31254 +       int             fdb_gpio;
31255 +       bool            fdb_polarity;
31256 +};
31257 +
31258 +static struct ubicom32fdb_platform_data ip5160dev_fdb_data = {
31259 +       .fdb_gpio               = 0,
31260 +       .fdb_polarity           = true,
31261 +};
31262 +
31263 +static struct platform_device ip5160dev_fdb_device = {
31264 +       .name   = "ubicom32fdb",
31265 +       .id     = -1,
31266 +       .dev    = {
31267 +               .platform_data = &ip5160dev_fdb_data,
31268 +       },
31269 +};
31270 +
31271 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31272 +static struct resource ip5160dev_ubicom32_suart_resources[] = {
31273 +        {
31274 +               .start  = RD,
31275 +               .end    = RD,
31276 +               .flags  = IORESOURCE_MEM,
31277 +        },
31278 +        {
31279 +               .start  = PORT_OTHER_INT(RD),
31280 +               .end    = PORT_OTHER_INT(RD),
31281 +               .flags  = IORESOURCE_IRQ,
31282 +        },
31283 +        {
31284 +               .start  = 240000000,
31285 +               .end    = 240000000,
31286 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
31287 +        },
31288 +};
31289 +
31290 +static struct platform_device ip5160dev_ubicom32_suart_device = {
31291 +       .name           = "ubicom32suart",
31292 +       .id             = -1,
31293 +        .num_resources  = ARRAY_SIZE(ip5160dev_ubicom32_suart_resources),
31294 +        .resource       = ip5160dev_ubicom32_suart_resources,
31295 +};
31296 +#endif
31297 +
31298 +/*
31299 + * List of all devices in our system
31300 + */
31301 +static struct platform_device *ip5160dev_devices[] __initdata = {
31302 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31303 +       &ip5160dev_ubicom32_suart_device,
31304 +#endif
31305 +       &ip5160dev_fdb_device,
31306 +};
31307 +
31308 +/*
31309 + * ip5160dev_init
31310 + *     Called to add the devices which we have on this board
31311 + */
31312 +static int __init ip5160dev_init(void)
31313 +{
31314 +       ubi_gpio_init();
31315 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31316 +       platform_add_devices(ip5160dev_devices, ARRAY_SIZE(ip5160dev_devices));
31317 +       return 0;
31318 +}
31319 +
31320 +arch_initcall(ip5160dev_init);
31321 +
31322 --- /dev/null
31323 +++ b/arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31324 @@ -0,0 +1,76 @@
31325 +/*
31326 + * arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31327 + *   Platform initialization for ip5160rgw board.
31328 + *
31329 + * (C) Copyright 2009, Ubicom, Inc.
31330 + *
31331 + * This file is part of the Ubicom32 Linux Kernel Port.
31332 + *
31333 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31334 + * it and/or modify it under the terms of the GNU General Public License
31335 + * as published by the Free Software Foundation, either version 2 of the
31336 + * License, or (at your option) any later version.
31337 + *
31338 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31339 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31340 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31341 + * the GNU General Public License for more details.
31342 + *
31343 + * You should have received a copy of the GNU General Public License
31344 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31345 + * see <http://www.gnu.org/licenses/>.
31346 + *
31347 + * Ubicom32 implementation derived from (with many thanks):
31348 + *   arch/m68knommu
31349 + *   arch/blackfin
31350 + *   arch/parisc
31351 + */
31352 +#include <linux/device.h>
31353 +#include <linux/platform_device.h>
31354 +#include <linux/gpio.h>
31355 +#include <asm/board.h>
31356 +#include <asm/machdep.h>
31357 +
31358 +/*
31359 + * Factory Default Button on the board at PXn
31360 + * TODO: This is just a placeholder and it needs to include proper header files
31361 + */
31362 +struct ubicom32fdb_platform_data {
31363 +       int             fdb_gpio;
31364 +       bool            fdb_polarity;
31365 +};
31366 +
31367 +static struct ubicom32fdb_platform_data ip5160rgw_fdb_data = {
31368 +       .fdb_gpio               = 0,
31369 +       .fdb_polarity           = true,
31370 +};
31371 +
31372 +static struct platform_device ip5160rgw_fdb_device = {
31373 +       .name   = "ubicom32fdb",
31374 +       .id     = -1,
31375 +       .dev    = {
31376 +               .platform_data = &ip5160rgw_fdb_data,
31377 +       },
31378 +};
31379 +
31380 +/*
31381 + * List of all devices in our system
31382 + */
31383 +static struct platform_device *ip5160rgw_devices[] __initdata = {
31384 +       &ip5160rgw_fdb_device,
31385 +};
31386 +
31387 +/*
31388 + * ip5160rgw_init
31389 + *     Called to add the devices which we have on this board
31390 + */
31391 +static int __init ip5160rgw_init(void)
31392 +{
31393 +       ubi_gpio_init();
31394 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31395 +       platform_add_devices(ip5160rgw_devices, ARRAY_SIZE(ip5160rgw_devices));
31396 +       return 0;
31397 +}
31398 +
31399 +arch_initcall(ip5160rgw_init);
31400 +
31401 --- /dev/null
31402 +++ b/arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31403 @@ -0,0 +1,280 @@
31404 +/*
31405 + * arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31406 + *   Platform initialization for ip5160dpf board.
31407 + *
31408 + * (C) Copyright 2009, Ubicom, Inc.
31409 + *
31410 + * This file is part of the Ubicom32 Linux Kernel Port.
31411 + *
31412 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31413 + * it and/or modify it under the terms of the GNU General Public License
31414 + * as published by the Free Software Foundation, either version 2 of the
31415 + * License, or (at your option) any later version.
31416 + *
31417 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31418 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31419 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31420 + * the GNU General Public License for more details.
31421 + *
31422 + * You should have received a copy of the GNU General Public License
31423 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31424 + * see <http://www.gnu.org/licenses/>.
31425 + *
31426 + * Ubicom32 implementation derived from (with many thanks):
31427 + *   arch/m68knommu
31428 + *   arch/blackfin
31429 + *   arch/parisc
31430 + */
31431 +#include <linux/device.h>
31432 +#include <linux/platform_device.h>
31433 +#include <linux/gpio.h>
31434 +#include <linux/leds.h>
31435 +
31436 +#include <linux/i2c.h>
31437 +#include <linux/i2c-gpio.h>
31438 +
31439 +#include <linux/input.h>
31440 +#include <asm/board.h>
31441 +#include <asm/machdep.h>
31442 +#include <asm/ubicom32hid.h>
31443 +#include <asm/vdc_tio.h>
31444 +
31445 +/*
31446 + * LEDs
31447 + *
31448 + * WLAN                        PD9     (Note this is shared with MISO, but we don't use it)
31449 + * WPS                 PD8
31450 + *
31451 + * TODO: check triggers, are they generic?
31452 + */
31453 +static struct gpio_led ip5170dpf_gpio_leds[] = {
31454 +       {
31455 +               .name                   = "d31:green:WLAN1",
31456 +               .default_trigger        = "WLAN1",
31457 +               .gpio                   = GPIO_RD_9,
31458 +               .active_low             = 1,
31459 +       },
31460 +       {
31461 +               .name                   = "d30:green:WPS",
31462 +               .default_trigger        = "WPS",
31463 +               .gpio                   = GPIO_RD_8,
31464 +               .active_low             = 1,
31465 +       },
31466 +};
31467 +
31468 +static struct gpio_led_platform_data ip5170dpf_gpio_led_platform_data = {
31469 +       .num_leds       = 2,
31470 +       .leds           = ip5170dpf_gpio_leds,
31471 +};
31472 +
31473 +static struct platform_device ip5170dpf_gpio_leds_device = {
31474 +       .name           = "leds-gpio",
31475 +       .id             = -1,
31476 +       .dev = {
31477 +               .platform_data = &ip5170dpf_gpio_led_platform_data,
31478 +       },
31479 +};
31480 +
31481 +/*
31482 + * Backlight on the board PD0, hardware PWM
31483 + */
31484 +static const struct ubicom32hid_button ip5170dpf_ubicom32hid_buttons[] = {
31485 +       {
31486 +               .type   = EV_KEY,
31487 +               .code   = KEY_UP,
31488 +               .bit    = 0,
31489 +       },
31490 +       {
31491 +               .type   = EV_KEY,
31492 +               .code   = KEY_LEFT,
31493 +               .bit    = 1,
31494 +       },
31495 +       {
31496 +               .type   = EV_KEY,
31497 +               .code   = KEY_RIGHT,
31498 +               .bit    = 2,
31499 +       },
31500 +       {
31501 +               .type   = EV_KEY,
31502 +               .code   = KEY_DOWN,
31503 +               .bit    = 3,
31504 +       },
31505 +       {
31506 +               .type   = EV_KEY,
31507 +               .code   = KEY_ENTER,
31508 +               .bit    = 4,
31509 +       },
31510 +       {
31511 +               .type   = EV_KEY,
31512 +               .code   = KEY_MENU,
31513 +               .bit    = 5,
31514 +       },
31515 +       {
31516 +               .type   = EV_KEY,
31517 +               .code   = KEY_ESC,
31518 +               .bit    = 7,
31519 +       },
31520 +};
31521 +
31522 +static const struct ubicom32hid_ir ip5170dpf_ubicom32hid_ircodes[] = {
31523 +       {
31524 +               .type           = EV_KEY,
31525 +               .code           = KEY_UP,
31526 +               .ir_code        = 0xF807916E
31527 +       },
31528 +       {
31529 +               .type           = EV_KEY,
31530 +               .code           = KEY_DOWN,
31531 +               .ir_code        = 0xF20D916E
31532 +       },
31533 +       {
31534 +               .type           = EV_KEY,
31535 +               .code           = KEY_LEFT,
31536 +               .ir_code        = 0xF609916E
31537 +       },
31538 +       {
31539 +               .type           = EV_KEY,
31540 +               .code           = KEY_RIGHT,
31541 +               .ir_code        = 0xF40B916E
31542 +       },
31543 +       {
31544 +               .type           = EV_KEY,
31545 +               .code           = KEY_ENTER,
31546 +               .ir_code        = 0xF50A916E
31547 +       },
31548 +       {       /* rotate */
31549 +               .type           = EV_KEY,
31550 +               .code           = KEY_FN_F1,
31551 +               .ir_code        = 0xF906916E
31552 +       },
31553 +       {
31554 +               .type           = EV_KEY,
31555 +               .code           = KEY_MENU,
31556 +               .ir_code        = 0xF708916E
31557 +       },
31558 +       {       /* font size */
31559 +               .type           = EV_KEY,
31560 +               .code           = KEY_FN_F2,
31561 +               .ir_code        = 0xF30C916E
31562 +       },
31563 +       {       
31564 +               .type           = EV_KEY,
31565 +               .code           = KEY_ESC,
31566 +               .ir_code        = 0xF10E916E
31567 +       },
31568 +       {
31569 +               .type           = EV_KEY,
31570 +               .code           = KEY_VOLUMEUP,
31571 +               .ir_code        = 0xF00F916E
31572 +       },
31573 +       {
31574 +               .type           = EV_KEY,
31575 +               .code           = KEY_VOLUMEDOWN,
31576 +               .ir_code        = 0xED12916E
31577 +       },
31578 +       {
31579 +               .type           = EV_KEY,
31580 +               .code           = KEY_MUTE,
31581 +               .ir_code        = 0xEA15916E
31582 +       },
31583 +       {
31584 +               .type           = EV_KEY,
31585 +               .code           = KEY_INFO,
31586 +               .ir_code        = 0xEF10916E
31587 +       },
31588 +       {       /* Like */
31589 +               .type           = EV_KEY,
31590 +               .code           = KEY_FN_F3,
31591 +               .ir_code        = 0xEE11916E
31592 +       },
31593 +       {       /* Dislike */
31594 +               .type           = EV_KEY,
31595 +               .code           = KEY_FN_F4,
31596 +               .ir_code        = 0xEB14916E
31597 +       },
31598 +       {
31599 +               .type           = EV_KEY,
31600 +               .code           = KEY_POWER,
31601 +               .ir_code        = 0xFD02916E
31602 +       },
31603 +};
31604 +
31605 +static struct ubicom32hid_platform_data ip5170dpf_ubicom32hid_platform_data = {
31606 +       .gpio_reset             = GPIO_RA_4,
31607 +       .gpio_reset_polarity    = 0,
31608 +       .type                   = UBICOM32HID_BL_TYPE_BINARY,
31609 +       .invert                 = 0,
31610 +       .default_intensity      = 1,
31611 +       .buttons                = ip5170dpf_ubicom32hid_buttons,
31612 +       .nbuttons               = ARRAY_SIZE(ip5170dpf_ubicom32hid_buttons),
31613 +       .ircodes                = ip5170dpf_ubicom32hid_ircodes,
31614 +       .nircodes               = ARRAY_SIZE(ip5170dpf_ubicom32hid_ircodes),
31615 +};
31616 +
31617 +/*
31618 + * Devices on the I2C bus
31619 + */
31620 +static struct i2c_board_info __initdata ip5170dpf_i2c_board_info[] = {
31621 +       /*
31622 +        * U24, ubicom32hid
31623 +        */
31624 +       {
31625 +               .type           = "ubicom32hid",
31626 +               .addr           = 0x08,
31627 +               .platform_data  = &ip5170dpf_ubicom32hid_platform_data,
31628 +       },
31629 +
31630 +       /*
31631 +        * U14, CS4350 DAC, address 0x4B
31632 +        */
31633 +};
31634 +
31635 +/*
31636 + * I2C bus on the board, SDA PF13, SCL PF14
31637 + */
31638 +static struct i2c_gpio_platform_data ip5170dpf_i2c_data = {
31639 +       .sda_pin                = GPIO_RF_13,
31640 +       .scl_pin                = GPIO_RF_14,
31641 +       .sda_is_open_drain      = 0,
31642 +       .scl_is_open_drain      = 0,
31643 +       .scl_is_output_only     = 1,
31644 +       .udelay                 = 5,
31645 +};
31646 +
31647 +static struct platform_device ip5170dpf_i2c_device = {
31648 +       .name   = "i2c-gpio",
31649 +       .id     = 0,
31650 +       .dev    = {
31651 +               .platform_data = &ip5170dpf_i2c_data,
31652 +       },
31653 +};
31654 +
31655 +/*
31656 + * List of all devices in our system
31657 + */
31658 +static struct platform_device *ip5170dpf_devices[] __initdata = {
31659 +       &ip5170dpf_i2c_device,
31660 +       &ip5170dpf_gpio_leds_device,
31661 +};
31662 +
31663 +/*
31664 + * ip5170dpf_init
31665 + *     Called to add the devices which we have on this board
31666 + */
31667 +static int __init ip5170dpf_init(void)
31668 +{
31669 +       ubi_gpio_init();
31670 +
31671 +       vdc_tio_init();
31672 +
31673 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31674 +       platform_add_devices(ip5170dpf_devices, ARRAY_SIZE(ip5170dpf_devices));
31675 +
31676 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
31677 +       i2c_register_board_info(0, ip5170dpf_i2c_board_info, ARRAY_SIZE(ip5170dpf_i2c_board_info));
31678 +
31679 +       return 0;
31680 +}
31681 +
31682 +arch_initcall(ip5170dpf_init);
31683 +
31684 --- /dev/null
31685 +++ b/arch/ubicom32/mach-ip5k/Kconfig
31686 @@ -0,0 +1,32 @@
31687 +
31688 +config IP5170DPF
31689 +       bool "IP5170DPF"
31690 +       select UBICOM32_V3
31691 +       select I2C
31692 +       select I2C_GPIO
31693 +       select FB
31694 +       select FB_UBICOM32
31695 +       select BACKLIGHT_LCD_SUPPORT
31696 +       select BACKLIGHT_CLASS_DEVICE
31697 +       select UBICOM_HID
31698 +       select NEW_LEDS
31699 +       select LEDS_CLASS
31700 +       select LEDS_GPIO
31701 +       select BRD_64MB
31702 +       help
31703 +               IP5170 Digital Picture Frame board, 8005-1113, IP5K-BEV-0011-13 v1.3
31704 +
31705 +config IP5160DEV
31706 +       bool "IP5160Dev_Ver1Dot1"
31707 +       select UBICOM32_V3
31708 +       select BRD_64MB
31709 +       help
31710 +               Ubicom StreamEngine 5000 Development Board, IP5K-BDV-0004-11 v1.1
31711 +
31712 +config IP5160EVAL
31713 +       bool "IP5160RGWEval_Ver2Rev2"
31714 +       select UBICOM32_V3
31715 +       select BRD_32MB
31716 +       help
31717 +               Ubicom StreamEngine 5000 RGW Evaluation Board, IP5K-RGW-0004-11 v2.2
31718 +
31719 --- /dev/null
31720 +++ b/arch/ubicom32/mach-ip5k/Makefile
31721 @@ -0,0 +1,32 @@
31722 +#
31723 +# arch/ubicom32/mach-ip5k/Makefile
31724 +#      Makefile for boards which have an ip5k on them.
31725 +#
31726 +# (C) Copyright 2009, Ubicom, Inc.
31727 +#
31728 +# This file is part of the Ubicom32 Linux Kernel Port.
31729 +#
31730 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
31731 +# it and/or modify it under the terms of the GNU General Public License
31732 +# as published by the Free Software Foundation, either version 2 of the
31733 +# License, or (at your option) any later version.
31734 +#
31735 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
31736 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
31737 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31738 +# the GNU General Public License for more details.
31739 +#
31740 +# You should have received a copy of the GNU General Public License
31741 +# along with the Ubicom32 Linux Kernel Port.  If not, 
31742 +# see <http://www.gnu.org/licenses/>.
31743 +#
31744 +# Ubicom32 implementation derived from (with many thanks):
31745 +#   arch/m68knommu
31746 +#   arch/blackfin
31747 +#   arch/parisc
31748 +#
31749 +
31750 +obj-$(CONFIG_IP5170DPF)                += board-ip5170dpf.o
31751 +obj-$(CONFIG_IP5160DEV)                += board-ip5160dev.o
31752 +obj-$(CONFIG_IP5160EVAL)       += board-ip5160rgw.o
31753 +
31754 --- /dev/null
31755 +++ b/arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31756 @@ -0,0 +1,716 @@
31757 +/*
31758 + * arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31759 + *   Board file for IP7145DPF, rev 1.0, P/N 8007-0410
31760 + *
31761 + * (C) Copyright 2009, Ubicom, Inc.
31762 + *
31763 + * This file is part of the Ubicom32 Linux Kernel Port.
31764 + *
31765 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31766 + * it and/or modify it under the terms of the GNU General Public License
31767 + * as published by the Free Software Foundation, either version 2 of the
31768 + * License, or (at your option) any later version.
31769 + *
31770 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31771 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31772 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31773 + * the GNU General Public License for more details.
31774 + *
31775 + * You should have received a copy of the GNU General Public License
31776 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31777 + * see <http://www.gnu.org/licenses/>.
31778 + *
31779 + * Ubicom32 implementation derived from (with many thanks):
31780 + *   arch/m68knommu
31781 + *   arch/blackfin
31782 + *   arch/parisc
31783 + */
31784 +#include <linux/device.h>
31785 +#include <linux/platform_device.h>
31786 +#include <linux/gpio.h>
31787 +
31788 +#include <linux/input.h>
31789 +
31790 +#include <linux/i2c.h>
31791 +#include <linux/i2c-gpio.h>
31792 +#include <linux/i2c/pca953x.h>
31793 +
31794 +#include <asm/board.h>
31795 +#include <asm/machdep.h>
31796 +#include <asm/ubicom32input.h>
31797 +#include <asm/ubicom32input_i2c.h>
31798 +#include <asm/ubicom32bl.h>
31799 +#include <asm/ubicom32lcd.h>
31800 +#include <asm/vdc_tio.h>
31801 +
31802 +#include <asm/ubicom32sd.h>
31803 +#include <asm/sd_tio.h>
31804 +#include <asm/devtree.h>
31805 +#include <asm/audio_tio.h>
31806 +
31807 +#include <asm/ring_tio.h>
31808 +
31809 +/******************************************************************************
31810 + * SD/IO Port F (Slot 1) platform data
31811 + */
31812 +static struct resource ip7145dpf_portf_sd_resources[] = {
31813 +       /*
31814 +        * Send IRQ
31815 +        */
31816 +       [0] = {
31817 +               /* 
31818 +                * The init routine will query the devtree and fill this in
31819 +                */
31820 +               .flags  = IORESOURCE_IRQ,
31821 +       },
31822 +
31823 +       /*
31824 +        * Receive IRQ
31825 +        */
31826 +       [1] = {
31827 +               /* 
31828 +                * The init routine will query the devtree and fill this in
31829 +                */
31830 +               .flags  = IORESOURCE_IRQ,
31831 +       },
31832 +
31833 +       /*
31834 +        * Memory Mapped Registers
31835 +        */
31836 +       [2] = {
31837 +               /* 
31838 +                * The init routine will query the devtree and fill this in
31839 +                */
31840 +               .flags  = IORESOURCE_MEM,
31841 +       },
31842 +};
31843 +
31844 +static struct ubicom32sd_card ip7145dpf_portf_sd_cards[] = {
31845 +       [0] = {
31846 +               .pin_wp         = IP7145DPF_IOB0,
31847 +               .wp_polarity    = 1,
31848 +               .pin_pwr        = IP7145DPF_IOB4,
31849 +               .pin_cd         = GPIO_RA_4,
31850 +       },
31851 +       [1] = {
31852 +               .pin_wp         = IP7145DPF_IOB1,
31853 +               .wp_polarity    = 1,
31854 +               .pin_pwr        = IP7145DPF_IOB5,
31855 +               .pin_cd         = GPIO_RA_6,
31856 +       },
31857 +};
31858 +
31859 +static struct ubicom32sd_platform_data ip7145dpf_portf_sd_platform_data = {
31860 +       .ncards         = 2,
31861 +       .cards          = ip7145dpf_portf_sd_cards, 
31862 +};
31863 +
31864 +static struct platform_device ip7145dpf_portf_sd_device = {
31865 +       .name           = "ubicom32sd",
31866 +       .id             = 0,
31867 +       .resource       = ip7145dpf_portf_sd_resources,
31868 +       .num_resources  = ARRAY_SIZE(ip7145dpf_portf_sd_resources),
31869 +       .dev            = {
31870 +                       .platform_data = &ip7145dpf_portf_sd_platform_data,
31871 +       },
31872 +
31873 +};
31874 +
31875 +/*
31876 + * ip7145dpf_portf_sd_init
31877 + */
31878 +static void ip7145dpf_portf_sd_init(void)
31879 +{
31880 +       /*
31881 +        * Check the device tree for the sd_tio
31882 +        */
31883 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
31884 +       if (!sd_node) {
31885 +               printk(KERN_INFO "PortF SDTIO not found\n");
31886 +               return;
31887 +       }
31888 +
31889 +       /*
31890 +        * Fill in the resources and platform data from devtree information
31891 +        */
31892 +       ip7145dpf_portf_sd_resources[0].start = sd_node->dn.sendirq;
31893 +       ip7145dpf_portf_sd_resources[1].start = sd_node->dn.recvirq;
31894 +       ip7145dpf_portf_sd_resources[2].start = (u32_t)&(sd_node->regs);
31895 +       ip7145dpf_portf_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
31896 +
31897 +       platform_device_register(&ip7145dpf_portf_sd_device);
31898 +}
31899 +
31900 +/******************************************************************************
31901 + * SD/IO Port B (Slot 2) platform data
31902 + */
31903 +static struct resource ip7145dpf_portb_sd_resources[] = {
31904 +       /*
31905 +        * Send IRQ
31906 +        */
31907 +       [0] = {
31908 +               /* 
31909 +                * The init routine will query the devtree and fill this in
31910 +                */
31911 +               .flags  = IORESOURCE_IRQ,
31912 +       },
31913 +
31914 +       /*
31915 +        * Receive IRQ
31916 +        */
31917 +       [1] = {
31918 +               /* 
31919 +                * The init routine will query the devtree and fill this in
31920 +                */
31921 +               .flags  = IORESOURCE_IRQ,
31922 +       },
31923 +
31924 +       /*
31925 +        * Memory Mapped Registers
31926 +        */
31927 +       [2] = {
31928 +               /* 
31929 +                * The init routine will query the devtree and fill this in
31930 +                */
31931 +               .flags  = IORESOURCE_MEM,
31932 +       },
31933 +};
31934 +
31935 +static struct ubicom32sd_card ip7145dpf_portb_sd_cards[] = {
31936 +       [0] = {
31937 +               .pin_wp         = IP7145DPF_IOB2,
31938 +               .wp_polarity    = 1,
31939 +               .pin_pwr        = IP7145DPF_IOB6,
31940 +               .pin_cd         = IP7145DPF_IOB3,
31941 +       },
31942 +};
31943 +
31944 +static struct ubicom32sd_platform_data ip7145dpf_portb_sd_platform_data = {
31945 +       .ncards         = 1,
31946 +       .cards          = ip7145dpf_portb_sd_cards,
31947 +};
31948 +
31949 +static struct platform_device ip7145dpf_portb_sd_device = {
31950 +       .name           = "ubicom32sd",
31951 +       .id             = 1,
31952 +       .resource       = ip7145dpf_portb_sd_resources,
31953 +       .num_resources  = ARRAY_SIZE(ip7145dpf_portb_sd_resources),
31954 +       .dev            = {
31955 +                       .platform_data = &ip7145dpf_portb_sd_platform_data,
31956 +       },
31957 +
31958 +};
31959 +
31960 +/*
31961 + * ip7145dpf_portb_sd_init
31962 + */
31963 +static void ip7145dpf_portb_sd_init(void)
31964 +{
31965 +       /*
31966 +        * Check the device tree for the sd_tio
31967 +        */
31968 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
31969 +       if (!sd_node) {
31970 +               printk(KERN_INFO "PortB SDTIO not found\n");
31971 +               return;
31972 +       }
31973 +
31974 +       /*
31975 +        * Fill in the resources and platform data from devtree information
31976 +        */
31977 +       ip7145dpf_portb_sd_resources[0].start = sd_node->dn.sendirq;
31978 +       ip7145dpf_portb_sd_resources[1].start = sd_node->dn.recvirq;
31979 +       ip7145dpf_portb_sd_resources[2].start = (u32_t)&(sd_node->regs);
31980 +       ip7145dpf_portb_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
31981 +
31982 +       platform_device_register(&ip7145dpf_portb_sd_device);
31983 +}
31984 +
31985 +
31986 +#ifdef IP7145DPF_USE_MMC_SPI
31987 +/******************************************************************************
31988 + * SPI over GPIO (MMC_SPI)
31989 + */
31990 +#include <linux/spi/spi.h>
31991 +#include <linux/spi/mmc_spi.h>
31992 +#include <linux/mmc/host.h>
31993 +#include <asm/ubicom32-spi-gpio.h>
31994 +
31995 +#define MMC_CS GPIO_RF_5       // PF5 D3
31996 +#define MMC_CD GPIO_RA_4       // PA4 CD
31997 +#define MMC_WP IP7145DPF_IOB0  // IOB0 WP
31998 +#define MMC_PWR        IP7145DPF_IOB4  // IOB4 PWR
31999 +
32000 +/*
32001 + * SPI bus over GPIO (for SD card)
32002 + */
32003 +static struct ubicom32_spi_gpio_platform_data ip7145dpf_spi_gpio_data = {
32004 +       .pin_mosi       = GPIO_RF_0,    // PF0 CMD
32005 +       .pin_miso       = GPIO_RF_2,    // PF2 D0
32006 +       .pin_clk        = GPIO_RF_1,    // PF1 CLK
32007 +       .bus_num        = 0,            // We'll call this SPI bus 0
32008 +       .num_chipselect = 1,            // only one device on this SPI bus 
32009 +};
32010 +
32011 +static struct platform_device ip7145dpf_spi_gpio_device = {
32012 +       .name   = "ubicom32-spi-gpio",
32013 +       .id     = 0,
32014 +       .dev    = {
32015 +               .platform_data = &ip7145dpf_spi_gpio_data,
32016 +       },
32017 +};
32018 +
32019 +/*
32020 + * ip7145dpf_mmc_spi_setpower_slot_a
32021 + *     Set the power state for slot A
32022 + */
32023 +static void ip7145dpf_mmc_spi_setpower_slot_a(struct device *dev, unsigned int vdd)
32024 +{
32025 +       struct mmc_spi_platform_data *pd = dev->platform_data;
32026 +
32027 +       /*
32028 +        * Power is inverted, we could tell the IOB to do it, but it's cleaner this way.
32029 +        */
32030 +       if ((1 << vdd) & pd->ocr_mask) {
32031 +               gpio_set_value(MMC_PWR, 0);
32032 +               return;
32033 +       }
32034 +       gpio_set_value(MMC_PWR, 1);
32035 +}
32036 +
32037 +/*
32038 + * ip7145dpf_mmc_spi_get_cd_slot_a
32039 + *     Get the CD bit for slot A
32040 + */
32041 +static int ip7145dpf_mmc_spi_get_cd_slot_a(struct device *dev)
32042 +{
32043 +       /*
32044 +        * Note that the sense of the GPIO is inverted
32045 +        */
32046 +       return !gpio_get_value(MMC_CD);
32047 +}
32048 +
32049 +/*
32050 + * ip7145dpf_mmc_spi_get_ro_slot_a
32051 + *     Get the WP bit for slot A
32052 + */
32053 +static int ip7145dpf_mmc_spi_get_ro_slot_a(struct device *dev)
32054 +{
32055 +       /*
32056 +        * Note that the sense of the GPIO is inverted, we could tell the IOB to do it, but
32057 +        * it's clearer this way.
32058 +        */
32059 +       return !gpio_get_value(MMC_WP);
32060 +}
32061 +
32062 +/*
32063 + * ip7145dpf_mmc_spi_exit_slot_a
32064 + *     Free the appropriate GPIOs for slot A SD slot.
32065 + */
32066 +static void ip7145dpf_mmc_spi_exit_slot_a(struct device *dev, void *appdata)
32067 +{
32068 +       gpio_free(MMC_CD);
32069 +       gpio_free(MMC_CS);
32070 +       gpio_free(MMC_WP);
32071 +       gpio_free(MMC_PWR);
32072 +       platform_device_unregister(&ip7145dpf_spi_gpio_device);
32073 +}
32074 +
32075 +/*
32076 + * ip7145dpf_mmc_spi_init_slot_a
32077 + *     Allocate the appropriate GPIOs for slot A SD slot.
32078 + *     WP is on IOB0, CD is PA4, CS is on PF5
32079 + *     TODO: make CD an interrupt
32080 + */
32081 +static int ip7145dpf_mmc_spi_init_slot_a(void)
32082 +{
32083 +       int ret = gpio_request(MMC_CD, "mmc-a-cd");
32084 +       if (ret) {
32085 +               printk(KERN_ERR "%s: could not request mmc-a-cd pin\n", __FUNCTION__);
32086 +               return -ENOSYS;
32087 +       }
32088 +       gpio_direction_input(MMC_CD);
32089 +
32090 +       ret = gpio_request(MMC_CS, "mmc-a-cs");
32091 +       if (ret) {
32092 +               printk(KERN_ERR "%s: could not request mmc-a-cs pin\n", __FUNCTION__);
32093 +               goto no_cs;
32094 +       }
32095 +       gpio_direction_output(MMC_CS, 0);
32096 +
32097 +       ret = gpio_request(MMC_WP, "mmc-a-wp");
32098 +       if (ret) {
32099 +               printk(KERN_ERR "%s: could not request mmc-a-wp pin\n", __FUNCTION__);
32100 +               goto no_wp;
32101 +       }
32102 +       gpio_direction_input(MMC_WP);
32103 +
32104 +       /*
32105 +        * Start off with power off
32106 +        */
32107 +       ret = gpio_request(MMC_PWR, "mmc-a-pwr");
32108 +       if (ret) {
32109 +               printk(KERN_ERR "%s: could not request mmc-a-pwr pin\n", __FUNCTION__);
32110 +               goto no_pwr;
32111 +       }
32112 +       ret = gpio_direction_output(MMC_PWR, 1);
32113 +
32114 +       return 0;
32115 +
32116 +no_pwr:
32117 +       gpio_free(MMC_WP);
32118 +
32119 +no_wp:
32120 +       gpio_free(MMC_CS);
32121 +
32122 +no_cs:
32123 +       gpio_free(MMC_CD);
32124 +       return -ENOSYS;
32125 +}
32126 +
32127 +/*
32128 + * MMC_SPI driver (currently bitbang)
32129 + */
32130 +static struct mmc_spi_platform_data ip7145dpf_mmc_platform_data = {
32131 +       .ocr_mask       = MMC_VDD_33_34,
32132 +       .exit           = ip7145dpf_mmc_spi_exit_slot_a,
32133 +       .get_ro         = ip7145dpf_mmc_spi_get_ro_slot_a,
32134 +       .get_cd         = ip7145dpf_mmc_spi_get_cd_slot_a,
32135 +
32136 +       .setpower       = ip7145dpf_mmc_spi_setpower_slot_a,
32137 +       .powerup_msecs  = 500,
32138 +
32139 +       .detect_delay   = 100,
32140 +
32141 +       .caps           = MMC_CAP_NEEDS_POLL,
32142 +};
32143 +
32144 +static struct ubicom32_spi_gpio_controller_data ip7145dpf_mmc_controller_data = {
32145 +       .pin_cs =  MMC_CS,
32146 +};
32147 +
32148 +static struct spi_board_info ip7145dpf_spi_board_info[] = {
32149 +       {
32150 +               .modalias = "mmc_spi",
32151 +               .bus_num = 0,
32152 +               .chip_select = 0,
32153 +               .max_speed_hz = 2000000,
32154 +               .platform_data = &ip7145dpf_mmc_platform_data,
32155 +               .controller_data = &ip7145dpf_mmc_controller_data,
32156 +       }
32157 +};
32158 +#endif /* IP7145DPF_USE_MMC_SPI */
32159 +
32160 +/*
32161 + * ip7145dpf_u72_setup
32162 + *     Called by I2C to tell us that u72 is setup.
32163 + *
32164 + * This function is called by I2C to tell us that u72 has been setup.  All
32165 + * devices which rely on this chip being initialized (or even present) need to
32166 + * be initialized in this function otherwise they may get initialized too early.
32167 + *
32168 + * Currently the only device depending on u72 is the SPI
32169 + */
32170 +static int __init ip7145dpf_u72_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
32171 +{
32172 +#ifdef IP7145DPF_USE_MMC_SPI
32173 +       if (ip7145dpf_mmc_spi_init_slot_a()) {
32174 +               printk(KERN_ERR "%s: could not request mmc resources\n", __FUNCTION__);
32175 +       } else {
32176 +               printk(KERN_INFO "%s: registering SPI resources\n", __FUNCTION__);
32177 +               spi_register_board_info(ip7145dpf_spi_board_info, ARRAY_SIZE(ip7145dpf_spi_board_info));
32178 +               platform_device_register(&ip7145dpf_spi_gpio_device);
32179 +       }
32180 +#else
32181 +       /*
32182 +        * Initialize the Port F/Port B SD slots
32183 +        */
32184 +       ip7145dpf_portf_sd_init();
32185 +       ip7145dpf_portb_sd_init();
32186 +#endif
32187 +       return 0;
32188 +}
32189 +
32190 +/******************************************************************************
32191 + * LCD VGH on the board at PE6
32192 + */
32193 +static struct ubicom32lcd_platform_data ip7145dpf_lcd_data = {
32194 +       .vgh_gpio               = GPIO_RE_6,
32195 +       .vgh_polarity           = true,
32196 +};
32197 +
32198 +static struct platform_device ip7145dpf_lcd_device = {
32199 +       .name   = "ubicom32lcd",
32200 +       .id     = -1,
32201 +       .dev    = {
32202 +               .platform_data = &ip7145dpf_lcd_data,
32203 +       },
32204 +};
32205 +
32206 +/******************************************************************************
32207 + * Backlight on the board PD0, hardware PWM
32208 + */
32209 +static struct ubicom32bl_platform_data ip7145dpf_backlight_data = {
32210 +       .type                   = UBICOM32BL_TYPE_PWM,
32211 +       .pwm_channel            = 2,
32212 +       .pwm_prescale           = 15,
32213 +       .pwm_period             = 60,
32214 +       .default_intensity      = 0x80,
32215 +};
32216 +
32217 +static struct platform_device ip7145dpf_backlight_device = {
32218 +       .name   = "ubicom32bl",
32219 +       .id     = -1,
32220 +       .dev    = {
32221 +               .platform_data = &ip7145dpf_backlight_data,
32222 +       },
32223 +};
32224 +
32225 +/******************************************************************************
32226 + * Ubicom32Input on I2C, U48 MAX7310, address 0x18, 8 bits
32227 + */
32228 +static struct ubicom32input_i2c_button ip7145dpf_ubicom32input_i2c_u48_buttons[] = {
32229 +       {
32230 +               .type           = EV_KEY,
32231 +               .code           = KEY_UP,
32232 +               .bit            = 0,
32233 +               .active_low     = 1,
32234 +       },
32235 +       {
32236 +               .type           = EV_KEY,
32237 +               .code           = KEY_LEFT,
32238 +               .bit            = 1,
32239 +               .active_low     = 1,
32240 +       },
32241 +       {
32242 +               .type           = EV_KEY,
32243 +               .code           = KEY_RIGHT,
32244 +               .bit            = 2,
32245 +               .active_low     = 1,
32246 +       },
32247 +       {
32248 +               .type           = EV_KEY,
32249 +               .code           = KEY_DOWN,
32250 +               .bit            = 3,
32251 +               .active_low     = 1,
32252 +       },
32253 +       {
32254 +               .type           = EV_KEY,
32255 +               .code           = KEY_ENTER,
32256 +               .bit            = 4,
32257 +               .active_low     = 1,
32258 +       },
32259 +       {
32260 +               .type           = EV_KEY,
32261 +               .code           = KEY_MENU,
32262 +               .bit            = 5,
32263 +               .active_low     = 1,
32264 +       },
32265 +       {
32266 +               .type           = EV_KEY,
32267 +               .code           = KEY_ESC,
32268 +               .bit            = 6,
32269 +               .active_low     = 1,
32270 +       },
32271 +};
32272 +
32273 +static struct ubicom32input_i2c_platform_data ip7145dpf_ubicom32input_i2c_u48_platform_data = {
32274 +       .buttons        = ip7145dpf_ubicom32input_i2c_u48_buttons,
32275 +       .nbuttons       = ARRAY_SIZE(ip7145dpf_ubicom32input_i2c_u48_buttons),
32276 +       .name           = "Ubicom32 Input I2C U48",
32277 +};
32278 +
32279 +/******************************************************************************
32280 + * Additional GPIO chips
32281 + */
32282 +static struct pca953x_platform_data ip7145dpf_gpio_u72_platform_data = {
32283 +       .gpio_base = IP7145DPF_U72_BASE,
32284 +       .setup = ip7145dpf_u72_setup,
32285 +};
32286 +
32287 +/******************************************************************************
32288 + * Devices on the I2C bus
32289 + */
32290 +static struct i2c_board_info __initdata ip7145dpf_i2c_board_info[] = {
32291 +       /*
32292 +        * U51, S35390A RTC, address 0x30
32293 +        */
32294 +       {
32295 +               .type           = "s35390a",
32296 +               .addr           = 0x30,
32297 +       },
32298 +
32299 +       /*
32300 +        * U48, MAX7310 IO expander, 8 bits, address 0x18
32301 +        */
32302 +       {
32303 +               .type           = "ubicom32in_max7310",
32304 +               .addr           = 0x18,
32305 +               .platform_data  = &ip7145dpf_ubicom32input_i2c_u48_platform_data,
32306 +       },
32307 +
32308 +       /*
32309 +        * U72, MAX7310 IOB expander, 8 bits, address 0x19
32310 +        */
32311 +       {
32312 +               .type           = "max7310",
32313 +               .addr           = 0x19,
32314 +               .platform_data  = &ip7145dpf_gpio_u72_platform_data,
32315 +       },
32316 +};
32317 +
32318 +/*
32319 + * I2C bus on the board, SDA PE1, SCL PE2
32320 + */
32321 +static struct i2c_gpio_platform_data ip7145dpf_i2c_data = {
32322 +       .sda_pin                = GPIO_RE_1,
32323 +       .scl_pin                = GPIO_RE_2,
32324 +       .sda_is_open_drain      = 0,
32325 +       .scl_is_open_drain      = 0,
32326 +};
32327 +
32328 +static struct platform_device ip7145dpf_i2c_device = {
32329 +       .name   = "i2c-gpio",
32330 +       .id     = 0,
32331 +       .dev    = {
32332 +               .platform_data = &ip7145dpf_i2c_data,
32333 +       },
32334 +};
32335 +
32336 +/******************************************************************************
32337 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32338 + *
32339 + * WPS                 PF12
32340 + * FACT_DEFAULT                PF13
32341 + * POWER               PE4
32342 + *
32343 + * Not sutable for the keypad buttons since those run on I2C GPIO.  The polling
32344 + * of ubicom32input would seem to be excessive for this.
32345 + *
32346 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32347 + */
32348 +static struct ubicom32input_button ip7145dpf_ubicom32input_buttons[] = {
32349 +       {
32350 +               .type           = EV_KEY,
32351 +               .code           = KEY_FN_F1,
32352 +               .gpio           = GPIO_RF_12,
32353 +               .desc           = "WPS",
32354 +               .active_low     = 1,
32355 +       },
32356 +       {
32357 +               .type           = EV_KEY,
32358 +               .code           = KEY_FN_F2,
32359 +               .gpio           = GPIO_RF_13,
32360 +               .desc           = "Factory Default",
32361 +               .active_low     = 1,
32362 +       },
32363 +       {
32364 +               .type           = EV_KEY,
32365 +               .code           = KEY_POWER,
32366 +               .gpio           = GPIO_RE_4,
32367 +               .desc           = "Power",
32368 +               .active_low     = 1,
32369 +       },
32370 +};
32371 +
32372 +static struct ubicom32input_platform_data ip7145dpf_ubicom32input_data = {
32373 +       .buttons        = ip7145dpf_ubicom32input_buttons,
32374 +       .nbuttons       = ARRAY_SIZE(ip7145dpf_ubicom32input_buttons),
32375 +};
32376 +
32377 +static struct platform_device ip7145dpf_ubicom32input_device = {
32378 +       .name   = "ubicom32input",
32379 +       .id     = -1,
32380 +       .dev    = {
32381 +               .platform_data = &ip7145dpf_ubicom32input_data,
32382 +       },
32383 +};
32384 +
32385 +/*
32386 + * List of all devices in our system
32387 + */
32388 +static struct platform_device *ip7145dpf_devices[] __initdata = {
32389 +       &ip7145dpf_i2c_device,
32390 +       &ip7145dpf_lcd_device,
32391 +       &ip7145dpf_backlight_device,
32392 +       &ip7145dpf_ubicom32input_device,
32393 +};
32394 +
32395 +/*
32396 + * ip7145dpf_power_off
32397 + *     Called to turn the power off for this board
32398 + */
32399 +static void ip7145dpf_power_off(void)
32400 +{
32401 +       gpio_set_value(GPIO_RE_5, 0);
32402 +}
32403 +
32404 +/*
32405 + * ip7145dpf_init
32406 + *     Called to add the devices which we have on this board
32407 + */
32408 +static int __init ip7145dpf_init(void)
32409 +{
32410 +       int ret;
32411 +       struct platform_device *audio_dev;
32412 +
32413 +       ubi_gpio_init();
32414 +
32415 +#ifdef CONFIG_UIO_UBICOM32RING
32416 +       ring_tio_init("decoder_ring");
32417 +#endif
32418 +
32419 +       /*
32420 +        * Start up the video driver first
32421 +        */
32422 +       vdc_tio_init();
32423 +
32424 +       /*
32425 +        * Take over holding of the power from the system
32426 +        */
32427 +       ret = gpio_request(GPIO_RE_5, "power_hold");
32428 +       if (ret) {
32429 +               printk(KERN_ERR "%s: could not request power hold GPIO\n", __FUNCTION__);
32430 +       }
32431 +       gpio_direction_output(GPIO_RE_5, 1);
32432 +       mach_power_off = ip7145dpf_power_off;
32433 +
32434 +       /*
32435 +        * USB SEL_HOST_USB line
32436 +        */
32437 +       ret = gpio_request(GPIO_RF_11, "SEL_HOST_USB");
32438 +       if (ret) {
32439 +               printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
32440 +       }
32441 +       gpio_direction_output(GPIO_RF_11, 0);
32442 +
32443 +       /*
32444 +        * Setup audio
32445 +        */
32446 +       audio_dev = audio_tio_alloc("snd-ubi32-generic", "audiotio-i2sout", 0);
32447 +       if (audio_dev) {
32448 +               platform_device_register(audio_dev);
32449 +       }
32450 +
32451 +       /*
32452 +        * Register all of the devices we have on this board
32453 +        */
32454 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32455 +       platform_add_devices(ip7145dpf_devices, ARRAY_SIZE(ip7145dpf_devices));
32456 +
32457 +       /*
32458 +        * Register all of the devices which sit on the I2C bus
32459 +        */
32460 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
32461 +       i2c_register_board_info(0, ip7145dpf_i2c_board_info, ARRAY_SIZE(ip7145dpf_i2c_board_info));
32462 +
32463 +       /*
32464 +        * We have to initialize the SPI after the I2C IOB gets setup. SPI is initialized in 
32465 +        * ip7145dpf_u72_setup
32466 +        */
32467 +
32468 +       return 0;
32469 +}
32470 +
32471 +arch_initcall(ip7145dpf_init);
32472 +
32473 --- /dev/null
32474 +++ b/arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32475 @@ -0,0 +1,135 @@
32476 +/*
32477 + * arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32478 + *   Support for the IP7160 bringup board.
32479 + *
32480 + * (C) Copyright 2009, Ubicom, Inc.
32481 + *
32482 + * This file is part of the Ubicom32 Linux Kernel Port.
32483 + *
32484 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
32485 + * it and/or modify it under the terms of the GNU General Public License
32486 + * as published by the Free Software Foundation, either version 2 of the
32487 + * License, or (at your option) any later version.
32488 + *
32489 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
32490 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
32491 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
32492 + * the GNU General Public License for more details.
32493 + *
32494 + * You should have received a copy of the GNU General Public License
32495 + * along with the Ubicom32 Linux Kernel Port.  If not, 
32496 + * see <http://www.gnu.org/licenses/>.
32497 + *
32498 + * Ubicom32 implementation derived from (with many thanks):
32499 + *   arch/m68knommu
32500 + *   arch/blackfin
32501 + *   arch/parisc
32502 + */
32503 +#include <linux/device.h>
32504 +#include <linux/platform_device.h>
32505 +#include <linux/gpio.h>
32506 +#include <linux/leds.h>
32507 +#include <linux/delay.h>
32508 +#include <linux/input.h>
32509 +
32510 +#include <asm/board.h>
32511 +#include <asm/machdep.h>
32512 +#include <asm/ubicom32input.h>
32513 +
32514 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32515 +#include <asm/ubicom32suart.h>
32516 +#endif
32517 +
32518 +/*
32519 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32520 + *
32521 + * WPS                 PD5
32522 + * FACT_DEFAULT                PD6
32523 + *
32524 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32525 + */
32526 +static struct ubicom32input_button ip7160bringup_ubicom32input_buttons[] = {
32527 +       {
32528 +               .type           = EV_KEY,
32529 +               .code           = KEY_FN_F1,
32530 +               .gpio           = GPIO_RD_5,
32531 +               .desc           = "WPS",
32532 +               .active_low     = 1,
32533 +       },
32534 +       {
32535 +               .type           = EV_KEY,
32536 +               .code           = KEY_FN_F2,
32537 +               .gpio           = GPIO_RD_6,
32538 +               .desc           = "Factory Default",
32539 +               .active_low     = 1,
32540 +       },
32541 +};
32542 +
32543 +static struct ubicom32input_platform_data ip7160bringup_ubicom32input_data = {
32544 +       .buttons        = ip7160bringup_ubicom32input_buttons,
32545 +       .nbuttons       = ARRAY_SIZE(ip7160bringup_ubicom32input_buttons),
32546 +};
32547 +
32548 +static struct platform_device ip7160bringup_ubicom32input_device = {
32549 +       .name   = "ubicom32input",
32550 +       .id     = -1,
32551 +       .dev    = {
32552 +               .platform_data = &ip7160bringup_ubicom32input_data,
32553 +       },
32554 +};
32555 +
32556 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32557 +static struct resource ip7160bringup_ubicom32_suart_resources[] = {
32558 +       {
32559 +               .start  = RE,
32560 +               .end    = RE,
32561 +               .flags  = IORESOURCE_MEM,
32562 +       },
32563 +       {
32564 +               .start  = PORT_OTHER_INT(RE),
32565 +               .end    = PORT_OTHER_INT(RE),
32566 +               .flags  = IORESOURCE_IRQ,
32567 +       },
32568 +       {
32569 +               .start  = 250000000,
32570 +               .end    = 250000000,
32571 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
32572 +       },
32573 +};
32574 +
32575 +static struct platform_device ip7160bringup_ubicom32_suart_device = {
32576 +       .name           = "ubicom32suart",
32577 +       .id             = -1,
32578 +       .num_resources  = ARRAY_SIZE(ip7160bringup_ubicom32_suart_resources),
32579 +       .resource       = ip7160bringup_ubicom32_suart_resources,
32580 +};
32581 +#endif
32582 +
32583 +/*
32584 + * List of all devices in our system
32585 + */
32586 +static struct platform_device *ip7160bringup_devices[] __initdata = {
32587 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32588 +       &ip7160bringup_ubicom32_suart_device,
32589 +#endif
32590 +       &ip7160bringup_ubicom32input_device,
32591 +};
32592 +
32593 +/*
32594 + * ip7160bringup_init
32595 + *     Called to add the devices which we have on this board
32596 + */
32597 +static int __init ip7160bringup_init(void)
32598 +{
32599 +       board_init();
32600 +
32601 +       ubi_gpio_init();
32602 +
32603 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32604 +       platform_add_devices(ip7160bringup_devices, ARRAY_SIZE(ip7160bringup_devices));
32605 +
32606 +       return 0;
32607 +}
32608 +
32609 +arch_initcall(ip7160bringup_init);
32610 +
32611 --- /dev/null
32612 +++ b/arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32613 @@ -0,0 +1,327 @@
32614 +/*
32615 + * arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32616 + *   Platform initialization for ip7160dpf board.
32617 + *
32618 + * (C) Copyright 2009, Ubicom, Inc.
32619 + *
32620 + * This file is part of the Ubicom32 Linux Kernel Port.
32621 + *
32622 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
32623 + * it and/or modify it under the terms of the GNU General Public License
32624 + * as published by the Free Software Foundation, either version 2 of the
32625 + * License, or (at your option) any later version.
32626 + *
32627 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
32628 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
32629 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
32630 + * the GNU General Public License for more details.
32631 + *
32632 + * You should have received a copy of the GNU General Public License
32633 + * along with the Ubicom32 Linux Kernel Port.  If not, 
32634 + * see <http://www.gnu.org/licenses/>.
32635 + *
32636 + * Ubicom32 implementation derived from (with many thanks):
32637 + *   arch/m68knommu
32638 + *   arch/blackfin
32639 + *   arch/parisc
32640 + */
32641 +#include <linux/device.h>
32642 +#include <linux/platform_device.h>
32643 +#include <linux/delay.h>
32644 +#include <linux/gpio.h>
32645 +
32646 +#include <linux/i2c.h>
32647 +#include <linux/i2c-gpio.h>
32648 +
32649 +#include <linux/input.h>
32650 +
32651 +#include <asm/board.h>
32652 +#include <asm/machdep.h>
32653 +#include <asm/ubicom32hid.h>
32654 +#include <asm/vdc_tio.h>
32655 +#include <asm/audio_tio.h>
32656 +
32657 +/*
32658 + * Backlight on the board PD0, hardware PWM
32659 + */
32660 +static const struct ubicom32hid_button ip7160dpf_ubicom32hid_buttons[] = {
32661 +       {
32662 +               .type   = EV_KEY,
32663 +               .code   = KEY_UP,
32664 +               .bit    = 0,
32665 +       },
32666 +       {
32667 +               .type   = EV_KEY,
32668 +               .code   = KEY_LEFT,
32669 +               .bit    = 1,
32670 +       },
32671 +       {
32672 +               .type   = EV_KEY,
32673 +               .code   = KEY_RIGHT,
32674 +               .bit    = 2,
32675 +       },
32676 +       {
32677 +               .type   = EV_KEY,
32678 +               .code   = KEY_DOWN,
32679 +               .bit    = 3,
32680 +       },
32681 +       {
32682 +               .type   = EV_KEY,
32683 +               .code   = KEY_ENTER,
32684 +               .bit    = 4,
32685 +       },
32686 +       {
32687 +               .type   = EV_KEY,
32688 +               .code   = KEY_MENU,
32689 +               .bit    = 5,
32690 +       },
32691 +       {
32692 +               .type   = EV_KEY,
32693 +               .code   = KEY_ESC,
32694 +               .bit    = 7,
32695 +       },
32696 +};
32697 +
32698 +static const struct ubicom32hid_ir ip7160dpf_ubicom32hid_ircodes[] = {
32699 +       {
32700 +               .type           = EV_KEY,
32701 +               .code           = KEY_UP,
32702 +               .ir_code        = 0xF807916E
32703 +       },
32704 +       {
32705 +               .type           = EV_KEY,
32706 +               .code           = KEY_DOWN,
32707 +               .ir_code        = 0xF20D916E
32708 +       },
32709 +       {
32710 +               .type           = EV_KEY,
32711 +               .code           = KEY_LEFT,
32712 +               .ir_code        = 0xF609916E
32713 +       },
32714 +       {
32715 +               .type           = EV_KEY,
32716 +               .code           = KEY_RIGHT,
32717 +               .ir_code        = 0xF40B916E
32718 +       },
32719 +       {
32720 +               .type           = EV_KEY,
32721 +               .code           = KEY_ENTER,
32722 +               .ir_code        = 0xF50A916E
32723 +       },
32724 +       {       /* rotate */
32725 +               .type           = EV_KEY,
32726 +               .code           = KEY_FN_F1,
32727 +               .ir_code        = 0xF906916E
32728 +       },
32729 +       {
32730 +               .type           = EV_KEY,
32731 +               .code           = KEY_MENU,
32732 +               .ir_code        = 0xF708916E
32733 +       },
32734 +       {       /* font size */
32735 +               .type           = EV_KEY,
32736 +               .code           = KEY_FN_F2,
32737 +               .ir_code        = 0xF30C916E
32738 +       },
32739 +       {       
32740 +               .type           = EV_KEY,
32741 +               .code           = KEY_ESC,
32742 +               .ir_code        = 0xF10E916E
32743 +       },
32744 +       {
32745 +               .type           = EV_KEY,
32746 +               .code           = KEY_VOLUMEUP,
32747 +               .ir_code        = 0xF00F916E
32748 +       },
32749 +       {
32750 +               .type           = EV_KEY,
32751 +               .code           = KEY_VOLUMEDOWN,
32752 +               .ir_code        = 0xED12916E
32753 +       },
32754 +       {
32755 +               .type           = EV_KEY,
32756 +               .code           = KEY_MUTE,
32757 +               .ir_code        = 0xEA15916E
32758 +       },
32759 +       {
32760 +               .type           = EV_KEY,
32761 +               .code           = KEY_INFO,
32762 +               .ir_code        = 0xEF10916E
32763 +       },
32764 +       {       /* Like */
32765 +               .type           = EV_KEY,
32766 +               .code           = KEY_FN_F3,
32767 +               .ir_code        = 0xEE11916E
32768 +       },
32769 +       {       /* Dislike */
32770 +               .type           = EV_KEY,
32771 +               .code           = KEY_FN_F4,
32772 +               .ir_code        = 0xEB14916E
32773 +       },
32774 +       {
32775 +               .type           = EV_KEY,
32776 +               .code           = KEY_POWER,
32777 +               .ir_code        = 0xFD02916E
32778 +       },
32779 +};
32780 +
32781 +static struct ubicom32hid_platform_data ip7160dpf_ubicom32hid_platform_data = {
32782 +       .gpio_reset             = GPIO_RI_5,
32783 +       .gpio_reset_polarity    = 0,
32784 +       .type                   = UBICOM32HID_BL_TYPE_PWM,
32785 +       .invert                 = 0,
32786 +       .default_intensity      = 128,
32787 +       .buttons                = ip7160dpf_ubicom32hid_buttons,
32788 +       .nbuttons               = ARRAY_SIZE(ip7160dpf_ubicom32hid_buttons),
32789 +       .ircodes                = ip7160dpf_ubicom32hid_ircodes,
32790 +       .nircodes               = ARRAY_SIZE(ip7160dpf_ubicom32hid_ircodes),
32791 +};
32792 +
32793 +/*
32794 + * Devices on the I2C bus
32795 + *     This board has a "bus 2" which is isolated from the main bus by U47
32796 + *     and pin RI0.  It should be safe to always enable bus 2 by setting
32797 + *     RI0 to low, however, it should be noted that on all existing configurations
32798 + *     of this board, U49 and U51 are not populated.
32799 + */
32800 +static struct i2c_board_info __initdata ip7160dpf_i2c_board_info[] = {
32801 +       /*
32802 +        * U37, CS4350 DAC, address 0x4B, bus 2
32803 +        *      THIS ENTRY MUST BE FIRST
32804 +        */
32805 +       {
32806 +               .type           = "cs4350",
32807 +               .addr           = 0x4B,
32808 +       }
32809 +
32810 +       /*
32811 +        * U24, ubicom32hid
32812 +        */
32813 +       {
32814 +               .type           = "ubicom32hid",
32815 +               .addr           = 0x08,
32816 +               .platform_data  = &ip7160dpf_ubicom32hid_platform_data,
32817 +       },
32818 +
32819 +       /*
32820 +        * U49, ISL29001 Ambient Light Sensor, address 0x44, bus 2 (may not be stuffed)
32821 +        */
32822 +
32823 +       /*
32824 +        * U51, S35390A RTC, address 0x30, bus 2 (may not be stuffed)
32825 +        */
32826 +#ifdef CONFIG_RTC_DRV_S35390A
32827 +       {
32828 +               .type           = "s35390a",
32829 +               .addr           = 0x30,
32830 +       },
32831 +#endif
32832 +};
32833 +
32834 +/*
32835 + * I2C bus on the board, SDA PI1, SCL PI2
32836 + */
32837 +static struct i2c_gpio_platform_data ip7160dpf_i2c_data = {
32838 +       .sda_pin                = GPIO_RI_1,
32839 +       .scl_pin                = GPIO_RI_2,
32840 +       .sda_is_open_drain      = 0,
32841 +       .scl_is_open_drain      = 0,
32842 +       .scl_is_output_only     = 1,
32843 +       .udelay                 = 6,
32844 +};
32845 +
32846 +static struct platform_device ip7160dpf_i2c_device = {
32847 +       .name   = "i2c-gpio",
32848 +       .id     = 0,
32849 +       .dev    = {
32850 +               .platform_data = &ip7160dpf_i2c_data,
32851 +       },
32852 +};
32853 +
32854 +/*
32855 + * List of all devices in our system
32856 + */
32857 +static struct platform_device *ip7160dpf_devices[] __initdata = {
32858 +       &ip7160dpf_i2c_device,
32859 +};
32860 +
32861 +/*
32862 + * ip7160dpf_power_off
32863 + *     Called to turn the power off for this board
32864 + */
32865 +static void ip7160dpf_power_off(void)
32866 +{
32867 +       gpio_set_value(GPIO_RF_14, 0);
32868 +}
32869 +
32870 +/*
32871 + * ip7160dpf_init
32872 + *     Called to add the devices which we have on this board
32873 + */
32874 +static int __init ip7160dpf_init(void)
32875 +{
32876 +       int ret;
32877 +       struct platform_device *audio_dev;
32878 +
32879 +       ubi_gpio_init();
32880 +
32881 +       /*
32882 +        * Hold the POWER_HOLD line
32883 +        */
32884 +       ret = gpio_request(GPIO_RF_14, "POWER_HOLD");
32885 +       if (ret) {
32886 +               printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__);
32887 +       }
32888 +       gpio_direction_output(GPIO_RF_14, 0);
32889 +       mach_power_off = ip7160dpf_power_off;
32890 +
32891 +       /*
32892 +        * USB SEL_HOST_USB line
32893 +        */
32894 +       ret = gpio_request(GPIO_RI_13, "SEL_HOST_USB");
32895 +       if (ret) {
32896 +               printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
32897 +       }
32898 +       gpio_direction_output(GPIO_RI_13, 0);
32899 +
32900 +       /*
32901 +        * USB/DAC nRESET line
32902 +        */
32903 +       ret = gpio_request(GPIO_RI_3, "USB_DAC_nRESET");
32904 +       if (ret) {
32905 +               printk(KERN_ERR "%s: could not request USB_DAC_nRESET GPIO\n", __FUNCTION__);
32906 +       }
32907 +       gpio_direction_output(GPIO_RI_3, 0);
32908 +       udelay(1);
32909 +       gpio_direction_output(GPIO_RI_3, 1);
32910 +
32911 +       /*
32912 +        * I2C BUS2 Disable line
32913 +        */
32914 +       ret = gpio_request(GPIO_RI_0, "DISABLE_BUS2");
32915 +       if (ret) {
32916 +               printk(KERN_ERR "%s: could not request DISABLE_BUS2 GPIO\n", __FUNCTION__);
32917 +       }
32918 +       gpio_direction_output(GPIO_RI_0, 0);
32919 +
32920 +       vdc_tio_init();
32921 +
32922 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32923 +       platform_add_devices(ip7160dpf_devices, ARRAY_SIZE(ip7160dpf_devices));
32924 +
32925 +       /*
32926 +        * Allocate the audio driver if we can
32927 +        */
32928 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
32929 +       if (audio_dev) {
32930 +               ip7160dpf_i2c_board_info[0].platform_data = audio_dev;
32931 +       }
32932 +
32933 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
32934 +       i2c_register_board_info(0, ip7160dpf_i2c_board_info, ARRAY_SIZE(ip7160dpf_i2c_board_info));
32935 +
32936 +       return 0;
32937 +}
32938 +
32939 +arch_initcall(ip7160dpf_init);
32940 +
32941 --- /dev/null
32942 +++ b/arch/ubicom32/mach-ip7k/board-ip7160rgw.c
32943 @@ -0,0 +1,255 @@
32944 +/*
32945 + * arch/ubicom32/mach-ip7k/board-ip7160rgw.c
32946 + *   Platform initialization for ip7160rgw board.
32947 + *
32948 + * (C) Copyright 2009, Ubicom, Inc.
32949 + *
32950 + * This file is part of the Ubicom32 Linux Kernel Port.
32951 + *
32952 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
32953 + * it and/or modify it under the terms of the GNU General Public License
32954 + * as published by the Free Software Foundation, either version 2 of the
32955 + * License, or (at your option) any later version.
32956 + *
32957 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
32958 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
32959 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
32960 + * the GNU General Public License for more details.
32961 + *
32962 + * You should have received a copy of the GNU General Public License
32963 + * along with the Ubicom32 Linux Kernel Port.  If not, 
32964 + * see <http://www.gnu.org/licenses/>.
32965 + *
32966 + * Ubicom32 implementation derived from (with many thanks):
32967 + *   arch/m68knommu
32968 + *   arch/blackfin
32969 + *   arch/parisc
32970 + */
32971 +#include <linux/device.h>
32972 +#include <linux/platform_device.h>
32973 +#include <linux/gpio.h>
32974 +#include <linux/leds.h>
32975 +#include <linux/delay.h>
32976 +#include <linux/input.h>
32977 +#include <linux/spi/spi.h>
32978 +
32979 +#include <asm/board.h>
32980 +#include <asm/machdep.h>
32981 +#include <asm/ubicom32input.h>
32982 +
32983 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32984 +#include <asm/ubicom32suart.h>
32985 +#endif
32986 +
32987 +#include <asm/ubicom32-spi-gpio.h>
32988 +#include <asm/switch-bcm539x.h>
32989 +
32990 +/*
32991 + * SPI bus over GPIO for Gigabit Ethernet Switch
32992 + *     U58:
32993 + *             MOSI    PE0
32994 + *             MISO    PE1
32995 + *             CLK     PE3
32996 + *             CS      PE2
32997 + */
32998 +static struct ubicom32_spi_gpio_platform_data ip7160rgw_spi_gpio_data = {
32999 +       .pin_mosi       = GPIO_RE_0,
33000 +       .pin_miso       = GPIO_RE_1,
33001 +       .pin_clk        = GPIO_RE_3,
33002 +       .bus_num        = 0,            // We'll call this SPI bus 0
33003 +       .num_chipselect = 1,            // only one device on this SPI bus 
33004 +       .clk_default    = 1,
33005 +};
33006 +
33007 +static struct platform_device ip7160rgw_spi_gpio_device = {
33008 +       .name   = "ubicom32-spi-gpio",
33009 +       .id     = 0,
33010 +       .dev    = {
33011 +               .platform_data = &ip7160rgw_spi_gpio_data,
33012 +       },
33013 +};
33014 +
33015 +static struct ubicom32_spi_gpio_controller_data ip7160rgw_bcm539x_controller_data = {
33016 +       .pin_cs = GPIO_RE_2,
33017 +};
33018 +
33019 +static struct switch_bcm539x_platform_data ip7160rgw_bcm539x_platform_data = {
33020 +       .flags          = SWITCH_BCM539X_FLAG_HW_RESET,
33021 +       .pin_cs         = GPIO_RE_2,
33022 +       .pin_reset      = GPIO_RE_4,
33023 +       .name           = "bcm539x",
33024 +};
33025 +
33026 +static struct spi_board_info ip7160rgw_spi_board_info[] = {
33027 +       {
33028 +               .modalias               = "bcm539x-spi",
33029 +               .bus_num                = 0,
33030 +               .chip_select            = 0,
33031 +               .max_speed_hz           = 2000000,
33032 +               .platform_data          = &ip7160rgw_bcm539x_platform_data,
33033 +               .controller_data        = &ip7160rgw_bcm539x_controller_data,
33034 +               .mode                   = SPI_MODE_3,
33035 +       }
33036 +};
33037 +
33038 +/*
33039 + * LEDs
33040 + *
33041 + * WLAN1               PD0     (PWM capable)
33042 + * WLAN2               PD1
33043 + * USB2.0              PD2
33044 + * Status              PD3
33045 + * WPS                 PD4
33046 + *
33047 + * TODO: check triggers, are they generic?
33048 + */
33049 +static struct gpio_led ip7160rgw_gpio_leds[] = {
33050 +       {
33051 +               .name                   = "d53:green:WLAN1",
33052 +               .default_trigger        = "WLAN1",
33053 +               .gpio                   = GPIO_RD_0,
33054 +               .active_low             = 1,
33055 +       },
33056 +       {
33057 +               .name                   = "d54:green:WLAN2",
33058 +               .default_trigger        = "WLAN2",
33059 +               .gpio                   = GPIO_RD_1,
33060 +               .active_low             = 1,
33061 +       },
33062 +       {
33063 +               .name                   = "d55:green:USB",
33064 +               .default_trigger        = "USB",
33065 +               .gpio                   = GPIO_RD_2,
33066 +               .active_low             = 1,
33067 +       },
33068 +       {
33069 +               .name                   = "d56:green:Status",
33070 +               .default_trigger        = "Status",
33071 +               .gpio                   = GPIO_RD_3,
33072 +               .active_low             = 1,
33073 +       },
33074 +       {
33075 +               .name                   = "d57:green:WPS",
33076 +               .default_trigger        = "WPS",
33077 +               .gpio                   = GPIO_RD_4,
33078 +               .active_low             = 1,
33079 +       },
33080 +};
33081 +
33082 +static struct gpio_led_platform_data ip7160rgw_gpio_led_platform_data = {
33083 +       .num_leds       = 5,
33084 +       .leds           = ip7160rgw_gpio_leds,
33085 +};
33086 +
33087 +static struct platform_device ip7160rgw_gpio_leds_device = {
33088 +       .name           = "leds-gpio",
33089 +       .id             = -1,
33090 +       .dev = {
33091 +               .platform_data = &ip7160rgw_gpio_led_platform_data,
33092 +       },
33093 +};
33094 +
33095 +/*
33096 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
33097 + *
33098 + * WPS                 PD5
33099 + * FACT_DEFAULT                PD6
33100 + *
33101 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
33102 + */
33103 +static struct ubicom32input_button ip7160rgw_ubicom32input_buttons[] = {
33104 +       {
33105 +               .type           = EV_KEY,
33106 +               .code           = KEY_FN_F1,
33107 +               .gpio           = GPIO_RD_5,
33108 +               .desc           = "WPS",
33109 +               .active_low     = 1,
33110 +       },
33111 +       {
33112 +               .type           = EV_KEY,
33113 +               .code           = KEY_FN_F2,
33114 +               .gpio           = GPIO_RD_6,
33115 +               .desc           = "Factory Default",
33116 +               .active_low     = 1,
33117 +       },
33118 +};
33119 +
33120 +static struct ubicom32input_platform_data ip7160rgw_ubicom32input_data = {
33121 +       .buttons        = ip7160rgw_ubicom32input_buttons,
33122 +       .nbuttons       = ARRAY_SIZE(ip7160rgw_ubicom32input_buttons),
33123 +};
33124 +
33125 +static struct platform_device ip7160rgw_ubicom32input_device = {
33126 +       .name   = "ubicom32input",
33127 +       .id     = -1,
33128 +       .dev    = {
33129 +               .platform_data = &ip7160rgw_ubicom32input_data,
33130 +       },
33131 +};
33132 +
33133 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33134 +static struct resource ip7160rgw_ubicom32_suart_resources[] = {
33135 +       {
33136 +               .start  = RE,
33137 +               .end    = RE,
33138 +               .flags  = IORESOURCE_MEM,
33139 +       },
33140 +       {
33141 +               .start  = PORT_OTHER_INT(RE),
33142 +               .end    = PORT_OTHER_INT(RE),
33143 +               .flags  = IORESOURCE_IRQ,
33144 +       },
33145 +       {
33146 +               .start  = 250000000,
33147 +               .end    = 250000000,
33148 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
33149 +       },
33150 +};
33151 +
33152 +static struct platform_device ip7160rgw_ubicom32_suart_device = {
33153 +       .name           = "ubicom32suart",
33154 +       .id             = -1,
33155 +       .num_resources  = ARRAY_SIZE(ip7160rgw_ubicom32_suart_resources),
33156 +       .resource       = ip7160rgw_ubicom32_suart_resources,
33157 +};
33158 +#endif
33159 +
33160 +/*
33161 + * List of all devices in our system
33162 + */
33163 +static struct platform_device *ip7160rgw_devices[] __initdata = {
33164 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33165 +       &ip7160rgw_ubicom32_suart_device,
33166 +#endif
33167 +       &ip7160rgw_ubicom32input_device,
33168 +       &ip7160rgw_gpio_leds_device,
33169 +       &ip7160rgw_spi_gpio_device,
33170 +};
33171 +
33172 +/*
33173 + * ip7160rgw_init
33174 + *     Called to add the devices which we have on this board
33175 + */
33176 +static int __init ip7160rgw_init(void)
33177 +{
33178 +       board_init();
33179 +
33180 +       /*
33181 +        * Rev 1.2 boards have spi in a different place than 1.1/1.0
33182 +        */
33183 +       if (strcmp(board_get_revision(), "1.2") == 0) {
33184 +               ip7160rgw_spi_gpio_data.pin_mosi = GPIO_RD_7;
33185 +       }
33186 +
33187 +       ubi_gpio_init();
33188 +
33189 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33190 +       platform_add_devices(ip7160rgw_devices, ARRAY_SIZE(ip7160rgw_devices));
33191 +
33192 +       printk(KERN_INFO "%s: registering SPI resources\n", __FUNCTION__);
33193 +       spi_register_board_info(ip7160rgw_spi_board_info, ARRAY_SIZE(ip7160rgw_spi_board_info));
33194 +
33195 +       return 0;
33196 +}
33197 +
33198 +arch_initcall(ip7160rgw_init);
33199 --- /dev/null
33200 +++ b/arch/ubicom32/mach-ip7k/board-ip7500av.c
33201 @@ -0,0 +1,167 @@
33202 +/*
33203 + * arch/ubicom32/mach-ip7k/board-ip7500av.c
33204 + *   Support for IP7500 Audio Video Board + CPU module board.
33205 + *
33206 + * This file supports the IP7500 Audio Video Board:
33207 + *     8007-0810  Rev 1.0
33208 + * with one of the following CPU module boards:
33209 + *     8007-0510  Rev 1.0
33210 + *     8007-0510A Rev 1.0 (with ethernet)
33211 + *
33212 + * DIP Switch SW2 configuration: (*) default
33213 + *     POS 1: on(*) = PCI enabled, off = PCI disabled
33214 + *     POS 2: on(*) = TTYX => PA6, off = TTYX => PF12
33215 + *     POS 3: on(*) = TTYY => PA7, off = TTYY => PF15
33216 + *     POS 4: unused
33217 + *
33218 + * (C) Copyright 2009, Ubicom, Inc.
33219 + *
33220 + * This file is part of the Ubicom32 Linux Kernel Port.
33221 + *
33222 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33223 + * it and/or modify it under the terms of the GNU General Public License
33224 + * as published by the Free Software Foundation, either version 2 of the
33225 + * License, or (at your option) any later version.
33226 + *
33227 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33228 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33229 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33230 + * the GNU General Public License for more details.
33231 + *
33232 + * You should have received a copy of the GNU General Public License
33233 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33234 + * see <http://www.gnu.org/licenses/>.
33235 + */
33236 +
33237 +#include <linux/device.h>
33238 +#include <linux/platform_device.h>
33239 +#include <linux/gpio.h>
33240 +#include <linux/i2c.h>
33241 +#include <linux/i2c-gpio.h>
33242 +#include <asm/board.h>
33243 +#include <asm/machdep.h>
33244 +#include <asm/ring_tio.h>
33245 +#include <asm/vdc_tio.h>
33246 +#include <asm/audio_tio.h>
33247 +#include <asm/ubi32-cs4384.h>
33248 +
33249 +/******************************************************************************
33250 + * Devices on the I2C bus
33251 + *
33252 + * BEWARE of changing the order of things in this array as we depend on
33253 + * certain things to be in certain places.
33254 + */
33255 +static struct i2c_board_info __initdata ip7500av_i2c_board_info[] = {
33256 +       /*
33257 +        * U6, CS4384 DAC, address 0x19
33258 +        */
33259 +       {
33260 +               .type           = "cs4384",
33261 +               .addr           = 0x19,
33262 +       },
33263 +};
33264 +
33265 +/*
33266 + * I2C bus on the board, SDA PD1, SCL PD2
33267 + */
33268 +static struct i2c_gpio_platform_data ip7500av_i2c_data = {
33269 +       .sda_pin                = GPIO_RD_6,
33270 +       .scl_pin                = GPIO_RD_3,
33271 +       .sda_is_open_drain      = 0,
33272 +       .scl_is_open_drain      = 0,
33273 +       .udelay                 = 50,
33274 +};
33275 +
33276 +static struct platform_device ip7500av_i2c_device = {
33277 +       .name   = "i2c-gpio",
33278 +       .id     = 0,
33279 +       .dev    = {
33280 +               .platform_data = &ip7500av_i2c_data,
33281 +       },
33282 +};
33283 +
33284 +/*
33285 + * List of possible mclks we can generate.  This depends on the CPU frequency.
33286 + */
33287 +static struct ubi32_cs4384_mclk_entry ip7500av_cs4384_mclk_entries[] = {
33288 +       {
33289 +               .rate   =       12288000,
33290 +               .div    =       44,
33291 +       },
33292 +       {
33293 +               .rate   =       11289600,
33294 +               .div    =       48,
33295 +       },
33296 +};
33297 +
33298 +/*
33299 + * List of all devices in our system
33300 + */
33301 +static struct platform_device *ip7500av_devices[] __initdata = {
33302 +       &ip7500av_i2c_device,
33303 +};
33304 +
33305 +/*
33306 + * ip7500av_init
33307 + *     Called to add the devices which we have on this board
33308 + */
33309 +static int __init ip7500av_init(void)
33310 +{
33311 +       struct platform_device *audio_dev;
33312 +       struct platform_device *audio_dev2;
33313 +       struct ubi32_cs4384_platform_data *cs4384_pd;
33314 +
33315 +       board_init();
33316 +
33317 +       vdc_tio_init();
33318 +
33319 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33320 +       platform_add_devices(ip7500av_devices, ARRAY_SIZE(ip7500av_devices));
33321 +
33322 +       /*
33323 +        * CS4384 DAC
33324 +        */
33325 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4384", "audiotio-i2sout", 
33326 +                       sizeof(struct ubi32_cs4384_platform_data));
33327 +       if (audio_dev) {
33328 +               /*
33329 +                * Attempt to figure out a good divisor.  This will only work
33330 +                * assuming the core frequency is compatible.
33331 +                */
33332 +               int i;
33333 +               unsigned int freq = processor_frequency();
33334 +               for (i = 0; i < ARRAY_SIZE(ip7500av_cs4384_mclk_entries); i++) {
33335 +                       unsigned int div;
33336 +                       unsigned int rate = ip7500av_cs4384_mclk_entries[i].rate / 1000;
33337 +                       div = ((freq / rate) + 500) / 1000;
33338 +                       ip7500av_cs4384_mclk_entries[i].div = div;
33339 +                       printk("CS4384 mclk %d rate %u000Hz div %u act %u\n", i, rate, div, freq / div);
33340 +               }
33341 +
33342 +               cs4384_pd = audio_tio_priv(audio_dev);
33343 +               cs4384_pd->mclk_src = UBI32_CS4384_MCLK_PWM_0;
33344 +               cs4384_pd->n_mclk = ARRAY_SIZE(ip7500av_cs4384_mclk_entries);
33345 +               cs4384_pd->mclk_entries = ip7500av_cs4384_mclk_entries;
33346 +               ip7500av_i2c_board_info[0].platform_data = audio_dev;
33347 +       }
33348 +
33349 +       /*
33350 +        * SPDIF port
33351 +        */
33352 +       audio_dev2 = audio_tio_alloc("snd-ubi32-generic", "audiotio-spdifout", 0);
33353 +       if (audio_dev2) {
33354 +               platform_device_register(audio_dev2);
33355 +       }
33356 +
33357 +       /*
33358 +        * Register all of the devices which sit on the I2C bus
33359 +        */
33360 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
33361 +       i2c_register_board_info(0, ip7500av_i2c_board_info, ARRAY_SIZE(ip7500av_i2c_board_info));
33362 +
33363 +       ubi_gpio_init();
33364 +
33365 +       return 0;
33366 +}
33367 +arch_initcall(ip7500av_init);
33368 +
33369 --- /dev/null
33370 +++ b/arch/ubicom32/mach-ip7k/board-ip7500media.c
33371 @@ -0,0 +1,520 @@
33372 +/*
33373 + * arch/ubicom32/mach-ip7k/board-ip7500media.c
33374 + *   Board file for IP7500 media board.
33375 + *
33376 + * Supports the following configuration
33377 + *     CPU Module:
33378 + *             P/N 8007-0510 rev 1.0
33379 + *                     DIP Switch SW2 configuration: 
33380 + *                             POS 1: on  = PCI enabled
33381 + *                             POS 2: off = TTYX => PF12
33382 + *                             POS 3: off = TTYY => PF15
33383 + *                             POS 4: unused
33384 + *     Media Board:
33385 + *             P/N 8007-0610 rev 1.0
33386 + *
33387 + * (C) Copyright 2009, Ubicom, Inc.
33388 + *
33389 + * This file is part of the Ubicom32 Linux Kernel Port.
33390 + *
33391 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33392 + * it and/or modify it under the terms of the GNU General Public License
33393 + * as published by the Free Software Foundation, either version 2 of the
33394 + * License, or (at your option) any later version.
33395 + *
33396 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33397 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33398 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33399 + * the GNU General Public License for more details.
33400 + *
33401 + * You should have received a copy of the GNU General Public License
33402 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33403 + * see <http://www.gnu.org/licenses/>.
33404 + *
33405 + * Ubicom32 implementation derived from (with many thanks):
33406 + *   arch/m68knommu
33407 + *   arch/blackfin
33408 + *   arch/parisc
33409 + */
33410 +#include <linux/device.h>
33411 +#include <linux/platform_device.h>
33412 +#include <linux/gpio.h>
33413 +
33414 +#include <linux/input.h>
33415 +
33416 +#include <linux/i2c.h>
33417 +#include <linux/i2c-gpio.h>
33418 +#include <linux/i2c/pca953x.h>
33419 +
33420 +#include <asm/board.h>
33421 +#include <asm/machdep.h>
33422 +#include <asm/ubicom32input_i2c.h>
33423 +#include <asm/ubicom32bl.h>
33424 +#include <asm/ubicom32lcd.h>
33425 +#include <asm/vdc_tio.h>
33426 +
33427 +#include <asm/ubicom32sd.h>
33428 +#include <asm/sd_tio.h>
33429 +#include <asm/devtree.h>
33430 +#include <asm/audio_tio.h>
33431 +
33432 +#include <asm/ring_tio.h>
33433 +
33434 +/******************************************************************************
33435 + * SD/IO Port F (Slot 1) platform data
33436 + */
33437 +static struct resource ip7500media_portf_sd_resources[] = {
33438 +       /*
33439 +        * Send IRQ
33440 +        */
33441 +       [0] = {
33442 +               /* 
33443 +                * The init routine will query the devtree and fill this in
33444 +                */
33445 +               .flags  = IORESOURCE_IRQ,
33446 +       },
33447 +
33448 +       /*
33449 +        * Receive IRQ
33450 +        */
33451 +       [1] = {
33452 +               /* 
33453 +                * The init routine will query the devtree and fill this in
33454 +                */
33455 +               .flags  = IORESOURCE_IRQ,
33456 +       },
33457 +
33458 +       /*
33459 +        * Memory Mapped Registers
33460 +        */
33461 +       [2] = {
33462 +               /* 
33463 +                * The init routine will query the devtree and fill this in
33464 +                */
33465 +               .flags  = IORESOURCE_MEM,
33466 +       },
33467 +};
33468 +
33469 +static struct ubicom32sd_card ip7500media_portf_sd_cards[] = {
33470 +       [0] = {
33471 +               .pin_wp         = IP7500MEDIA_IO16,
33472 +               .wp_polarity    = 1,
33473 +               .pin_pwr        = IP7500MEDIA_IO20,
33474 +               .pin_cd         = IP7500MEDIA_IO23,
33475 +       },
33476 +       [1] = {
33477 +               .pin_wp         = IP7500MEDIA_IO17,
33478 +               .wp_polarity    = 1,
33479 +               .pin_pwr        = IP7500MEDIA_IO21,
33480 +               .pin_cd         = IP7500MEDIA_IO24,
33481 +       },
33482 +};
33483 +
33484 +static struct ubicom32sd_platform_data ip7500media_portf_sd_platform_data = {
33485 +       .ncards         = 2,
33486 +       .cards          = ip7500media_portf_sd_cards, 
33487 +};
33488 +
33489 +static struct platform_device ip7500media_portf_sd_device = {
33490 +       .name           = "ubicom32sd",
33491 +       .id             = 0,
33492 +       .resource       = ip7500media_portf_sd_resources,
33493 +       .num_resources  = ARRAY_SIZE(ip7500media_portf_sd_resources),
33494 +       .dev            = {
33495 +                       .platform_data = &ip7500media_portf_sd_platform_data,
33496 +       },
33497 +
33498 +};
33499 +
33500 +/*
33501 + * ip7500media_portf_sd_init
33502 + */
33503 +static void ip7500media_portf_sd_init(void)
33504 +{
33505 +       /*
33506 +        * Check the device tree for the sd_tio
33507 +        */
33508 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
33509 +       if (!sd_node) {
33510 +               printk(KERN_INFO "PortF SDTIO not found\n");
33511 +               return;
33512 +       }
33513 +
33514 +       /*
33515 +        * Fill in the resources and platform data from devtree information
33516 +        */
33517 +       ip7500media_portf_sd_resources[0].start = sd_node->dn.sendirq;
33518 +       ip7500media_portf_sd_resources[1].start = sd_node->dn.recvirq;
33519 +       ip7500media_portf_sd_resources[2].start = (u32_t)&(sd_node->regs);
33520 +       ip7500media_portf_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
33521 +
33522 +       platform_device_register(&ip7500media_portf_sd_device);
33523 +}
33524 +
33525 +/******************************************************************************
33526 + * SD/IO Port B (Slot 2) platform data
33527 + */
33528 +static struct resource ip7500media_portb_sd_resources[] = {
33529 +       /*
33530 +        * Send IRQ
33531 +        */
33532 +       [0] = {
33533 +               /* 
33534 +                * The init routine will query the devtree and fill this in
33535 +                */
33536 +               .flags  = IORESOURCE_IRQ,
33537 +       },
33538 +
33539 +       /*
33540 +        * Receive IRQ
33541 +        */
33542 +       [1] = {
33543 +               /* 
33544 +                * The init routine will query the devtree and fill this in
33545 +                */
33546 +               .flags  = IORESOURCE_IRQ,
33547 +       },
33548 +
33549 +       /*
33550 +        * Memory Mapped Registers
33551 +        */
33552 +       [2] = {
33553 +               /* 
33554 +                * The init routine will query the devtree and fill this in
33555 +                */
33556 +               .flags  = IORESOURCE_MEM,
33557 +       },
33558 +};
33559 +
33560 +static struct ubicom32sd_card ip7500media_portb_sd_cards[] = {
33561 +       [0] = {
33562 +               .pin_wp         = IP7500MEDIA_IO19,
33563 +               .wp_polarity    = 1,
33564 +               .pin_pwr        = IP7500MEDIA_IO22,
33565 +               .pin_cd         = IP7500MEDIA_IO18,
33566 +       },
33567 +};
33568 +
33569 +static struct ubicom32sd_platform_data ip7500media_portb_sd_platform_data = {
33570 +       .ncards         = 1,
33571 +       .cards          = ip7500media_portb_sd_cards,
33572 +};
33573 +
33574 +static struct platform_device ip7500media_portb_sd_device = {
33575 +       .name           = "ubicom32sd",
33576 +       .id             = 1,
33577 +       .resource       = ip7500media_portb_sd_resources,
33578 +       .num_resources  = ARRAY_SIZE(ip7500media_portb_sd_resources),
33579 +       .dev            = {
33580 +                       .platform_data = &ip7500media_portb_sd_platform_data,
33581 +       },
33582 +
33583 +};
33584 +
33585 +/*
33586 + * ip7500media_portb_sd_init
33587 + */
33588 +static void ip7500media_portb_sd_init(void)
33589 +{
33590 +       /*
33591 +        * Check the device tree for the sd_tio
33592 +        */
33593 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
33594 +       if (!sd_node) {
33595 +               printk(KERN_INFO "PortB SDTIO not found\n");
33596 +               return;
33597 +       }
33598 +
33599 +       /*
33600 +        * Fill in the resources and platform data from devtree information
33601 +        */
33602 +       ip7500media_portb_sd_resources[0].start = sd_node->dn.sendirq;
33603 +       ip7500media_portb_sd_resources[1].start = sd_node->dn.recvirq;
33604 +       ip7500media_portb_sd_resources[2].start = (u32_t)&(sd_node->regs);
33605 +       ip7500media_portb_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
33606 +
33607 +       platform_device_register(&ip7500media_portb_sd_device);
33608 +}
33609 +
33610 +/*
33611 + * ip7500media_u17_setup
33612 + *     Called by I2C to tell us that u17 is setup.
33613 + *
33614 + * This function is called by I2C to tell us that u17 has been setup.  All
33615 + * devices which rely on this chip being initialized (or even present) need to
33616 + * be initialized in this function otherwise they may get initialized too early.
33617 + *
33618 + * Currently the only device depending on u17 is the SDIO
33619 + */
33620 +static int __init ip7500media_u17_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
33621 +{
33622 +       /*
33623 +        * Initialize the Port F/Port B SD slots (only the enabled ports will init)
33624 +        */
33625 +       ip7500media_portf_sd_init();
33626 +       ip7500media_portb_sd_init();
33627 +
33628 +       return 0;
33629 +}
33630 +
33631 +/******************************************************************************
33632 + * LCD VGH on the board at PE6
33633 + */
33634 +static struct ubicom32lcd_platform_data ip7500media_lcd_data = {
33635 +       .vgh_gpio               = GPIO_RE_7,
33636 +       .vgh_polarity           = true,
33637 +};
33638 +
33639 +static struct platform_device ip7500media_lcd_device = {
33640 +       .name   = "ubicom32lcd",
33641 +       .id     = -1,
33642 +       .dev    = {
33643 +               .platform_data = &ip7500media_lcd_data,
33644 +       },
33645 +};
33646 +
33647 +/******************************************************************************
33648 + * Backlight on the board PD0, hardware PWM
33649 + */
33650 +static struct ubicom32bl_platform_data ip7500media_backlight_data = {
33651 +       .type                   = UBICOM32BL_TYPE_PWM,
33652 +       .pwm_channel            = 2,
33653 +       .pwm_prescale           = 15,
33654 +       .pwm_period             = 60,
33655 +       .default_intensity      = 0x80,
33656 +};
33657 +
33658 +static struct platform_device ip7500media_backlight_device = {
33659 +       .name   = "ubicom32bl",
33660 +       .id     = -1,
33661 +       .dev    = {
33662 +               .platform_data = &ip7500media_backlight_data,
33663 +       },
33664 +};
33665 +
33666 +/******************************************************************************
33667 + * Ubicom32Input on I2C, U15 MAX7310, address 0x18, 8 bits
33668 + */
33669 +static struct ubicom32input_i2c_button ip7500media_ubicom32input_i2c_u15_buttons[] = {
33670 +       {
33671 +               .type           = EV_KEY,
33672 +               .code           = KEY_LEFT,
33673 +               .bit            = 0,
33674 +               .active_low     = 1,
33675 +       },
33676 +       {
33677 +               .type           = EV_KEY,
33678 +               .code           = KEY_RIGHT,
33679 +               .bit            = 1,
33680 +               .active_low     = 1,
33681 +       },
33682 +       {
33683 +               .type           = EV_KEY,
33684 +               .code           = KEY_UP,
33685 +               .bit            = 2,
33686 +               .active_low     = 1,
33687 +       },
33688 +       {
33689 +               .type           = EV_KEY,
33690 +               .code           = KEY_DOWN,
33691 +               .bit            = 3,
33692 +               .active_low     = 1,
33693 +       },
33694 +       {
33695 +               .type           = EV_KEY,
33696 +               .code           = KEY_ENTER,
33697 +               .bit            = 4,
33698 +               .active_low     = 1,
33699 +       },
33700 +       {
33701 +               .type           = EV_KEY,
33702 +               .code           = KEY_MENU,
33703 +               .bit            = 5,
33704 +               .active_low     = 1,
33705 +       },
33706 +       {
33707 +               .type           = EV_KEY,
33708 +               .code           = KEY_ESC,
33709 +               .bit            = 6,
33710 +               .active_low     = 1,
33711 +       },
33712 +};
33713 +
33714 +static struct ubicom32input_i2c_platform_data ip7500media_ubicom32input_i2c_u15_platform_data = {
33715 +       .buttons        = ip7500media_ubicom32input_i2c_u15_buttons,
33716 +       .nbuttons       = ARRAY_SIZE(ip7500media_ubicom32input_i2c_u15_buttons),
33717 +       .name           = "Ubicom32 Input I2C U15",
33718 +};
33719 +
33720 +/******************************************************************************
33721 + * Additional GPIO chips
33722 + */
33723 +static struct pca953x_platform_data ip7500media_gpio_u16_platform_data = {
33724 +       .gpio_base = IP7500MEDIA_U16_BASE,
33725 +};
33726 +
33727 +static struct pca953x_platform_data ip7500media_gpio_u17_platform_data = {
33728 +       .gpio_base = IP7500MEDIA_U17_BASE,
33729 +       .setup = ip7500media_u17_setup,
33730 +};
33731 +
33732 +static struct pca953x_platform_data ip7500media_gpio_u18_platform_data = {
33733 +       .gpio_base = IP7500MEDIA_U18_BASE,
33734 +};
33735 +
33736 +/******************************************************************************
33737 + * Devices on the I2C bus
33738 + *
33739 + * BEWARE of changing the order of things in this array as we depend on
33740 + * certain things to be in certain places.
33741 + */
33742 +static struct i2c_board_info __initdata ip7500media_i2c_board_info[] = {
33743 +       /*
33744 +        * U6, CS4350 DAC, address 0x4B
33745 +        */
33746 +       {
33747 +               .type           = "cs4350",
33748 +               .addr           = 0x4B,
33749 +       },
33750 +
33751 +       /*
33752 +        * U14, S35390A RTC, address 0x30
33753 +        */
33754 +       {
33755 +               .type           = "s35390a",
33756 +               .addr           = 0x30,
33757 +       },
33758 +
33759 +       /*
33760 +        * U15, MAX7310 IO expander, 8 bits, address 0x18
33761 +        *      IO0: User I/O (J16-1) (Left)    IO4: User I/O (J16-5) (Enter)
33762 +        *      IO1: User I/O (J16-2) (Right)   IO5: User I/O (J16-6) (Menu)
33763 +        *      IO2: User I/O (J16-3) (Up)      IO6: User I/O (J16-7) (Back)
33764 +        *      IO3: User I/O (J16-4) (Down)    IO7: User I/O (J16-8)
33765 +        */
33766 +       {
33767 +               .type           = "ubicom32in_max7310",
33768 +               .addr           = 0x18,
33769 +               .platform_data  = &ip7500media_ubicom32input_i2c_u15_platform_data,
33770 +       },
33771 +
33772 +       /*
33773 +        * U16, MAX7310 IO expander, 8 bits, address 0x1C
33774 +        *      IO8 : User I/O (J16-9)          IO12: User I/O (J16-17)
33775 +        *      IO9 : User I/O (J16-10)         IO13: User I/O (J16-18)
33776 +        *      IO10: User I/O (J16-15)         IO14: User I/O (J16-19)
33777 +        *      IO11: User I/O (J16-16)         IO15: User I/O (J16-20)
33778 +        */
33779 +       {
33780 +               .type           = "max7310",
33781 +               .addr           = 0x1C,
33782 +               .platform_data  = &ip7500media_gpio_u16_platform_data,
33783 +       },
33784 +
33785 +       /*
33786 +        * U17, MAX7310 IO expander, 8 bits, address 0x1A
33787 +        *      IO16: SDIO1A_WP                 IO20: SD1A_PWREN
33788 +        *      IO17: SDIO1B_WP                 IO21: SD1B_PWREN
33789 +        *      IO18: SDIO2_CD                  IO22: SD2_PWREN
33790 +        *      IO19: SDIO2_WP                  IO23: SDIO1A_CD
33791 +        *      
33792 +        */
33793 +       {
33794 +               .type           = "max7310",
33795 +               .addr           = 0x1A,
33796 +               .platform_data  = &ip7500media_gpio_u17_platform_data,
33797 +       },
33798 +
33799 +       /*
33800 +        * U18, MAX7310 IOB expander, 8 bits, address 0x1E
33801 +        *      IO24: SDIO1B_CD                 IO28: User I/O TP6
33802 +        *      IO25: User I/O TP9              IO29: User I/O TP5
33803 +        *      IO26: User I/O TP8              IO30: User I/O TP4
33804 +        *      IO27: User I/O TP7              IO31: User I/O TP3
33805 +        */
33806 +       {
33807 +               .type           = "max7310",
33808 +               .addr           = 0x1E,
33809 +               .platform_data  = &ip7500media_gpio_u18_platform_data,
33810 +       },
33811 +};
33812 +
33813 +/*
33814 + * I2C bus on the board, SDA PE4, SCL PE5
33815 + */
33816 +static struct i2c_gpio_platform_data ip7500media_i2c_data = {
33817 +       .sda_pin                = GPIO_RE_4,
33818 +       .scl_pin                = GPIO_RE_5,
33819 +       .sda_is_open_drain      = 0,
33820 +       .scl_is_open_drain      = 0,
33821 +       .udelay                 = 50,
33822 +};
33823 +
33824 +static struct platform_device ip7500media_i2c_device = {
33825 +       .name   = "i2c-gpio",
33826 +       .id     = 0,
33827 +       .dev    = {
33828 +               .platform_data = &ip7500media_i2c_data,
33829 +       },
33830 +};
33831 +
33832 +/*
33833 + * List of all devices in our system
33834 + */
33835 +static struct platform_device *ip7500media_devices[] __initdata = {
33836 +       &ip7500media_i2c_device,
33837 +       &ip7500media_lcd_device,
33838 +       &ip7500media_backlight_device,
33839 +};
33840 +
33841 +/*
33842 + * ip7500media_init
33843 + *     Called to add the devices which we have on this board
33844 + */
33845 +static int __init ip7500media_init(void)
33846 +{
33847 +       struct platform_device *audio_dev;
33848 +
33849 +       board_init();
33850 +
33851 +       ubi_gpio_init();
33852 +
33853 +#ifdef CONFIG_UIO_UBICOM32RING
33854 +       ring_tio_init("decoder_ring");
33855 +#endif
33856 +
33857 +       /*
33858 +        * Start up the video driver first
33859 +        */
33860 +       vdc_tio_init();
33861 +
33862 +       /*
33863 +        * Register all of the devices we have on this board
33864 +        */
33865 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33866 +       platform_add_devices(ip7500media_devices, ARRAY_SIZE(ip7500media_devices));
33867 +
33868 +       /*
33869 +        * Allocate the audio driver if we can
33870 +        */
33871 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
33872 +       if (audio_dev) {
33873 +               ip7500media_i2c_board_info[0].platform_data = audio_dev;
33874 +       }
33875 +
33876 +       /*
33877 +        * Register all of the devices which sit on the I2C bus
33878 +        */
33879 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
33880 +       i2c_register_board_info(0, ip7500media_i2c_board_info, ARRAY_SIZE(ip7500media_i2c_board_info));
33881 +
33882 +       /*
33883 +        * We have to initialize the SDIO after the I2C IOB gets setup.  SDIO is initialized in 
33884 +        * ip7500media_u17_setup
33885 +        */
33886 +
33887 +       return 0;
33888 +}
33889 +
33890 +arch_initcall(ip7500media_init);
33891 +
33892 --- /dev/null
33893 +++ b/arch/ubicom32/mach-ip7k/board-ip7500module.c
33894 @@ -0,0 +1,60 @@
33895 +/*
33896 + * arch/ubicom32/mach-ip7k/board-ip7500module.c
33897 + *   Support for IP7500 CPU module board.
33898 + *
33899 + * This file supports the IP7500 CPU module board:
33900 + *     8007-0510  Rev 1.0
33901 + *     8007-0510A Rev 1.0 (with ethernet)
33902 + *
33903 + * DIP Switch SW2 configuration: (*) default
33904 + *     POS 1: on(*) = PCI enabled, off = PCI disabled
33905 + *     POS 2: on(*) = TTYX => PA6, off = TTYX => PF12
33906 + *     POS 3: on(*) = TTYY => PA7, off = TTYY => PF15
33907 + *     POS 4: unused
33908 + *
33909 + * (C) Copyright 2009, Ubicom, Inc.
33910 + *
33911 + * This file is part of the Ubicom32 Linux Kernel Port.
33912 + *
33913 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33914 + * it and/or modify it under the terms of the GNU General Public License
33915 + * as published by the Free Software Foundation, either version 2 of the
33916 + * License, or (at your option) any later version.
33917 + *
33918 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33919 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33920 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33921 + * the GNU General Public License for more details.
33922 + *
33923 + * You should have received a copy of the GNU General Public License
33924 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33925 + * see <http://www.gnu.org/licenses/>.
33926 + *
33927 + * Ubicom32 implementation derived from (with many thanks):
33928 + *   arch/m68knommu
33929 + *   arch/blackfin
33930 + *   arch/parisc
33931 + */
33932 +#include <linux/device.h>
33933 +#include <linux/platform_device.h>
33934 +#include <linux/gpio.h>
33935 +#include <asm/board.h>
33936 +#include <asm/machdep.h>
33937 +#include <asm/ring_tio.h>
33938 +#include <asm/vdc_tio.h>
33939 +
33940 +/*
33941 + * ip7500module_init
33942 + *     Called to add the devices which we have on this board
33943 + */
33944 +static int __init ip7500module_init(void)
33945 +{
33946 +       board_init();
33947 +
33948 +       ubi_gpio_init();
33949 +
33950 +       return 0;
33951 +}
33952 +
33953 +arch_initcall(ip7500module_init);
33954 +
33955 --- /dev/null
33956 +++ b/arch/ubicom32/mach-ip7k/Kconfig
33957 @@ -0,0 +1,132 @@
33958 +config IP7145DPF
33959 +       bool "IP7145DPF"
33960 +       select UBICOM32_V4
33961 +       select UBICOM_INPUT
33962 +       select UBICOM_INPUT_I2C
33963 +       select RTC_CLASS
33964 +       select RTC_DRV_S35390A
33965 +       select I2C
33966 +       select I2C_GPIO
33967 +       select GPIO_PCA953X
33968 +       select FB
33969 +       select FB_UBICOM32
33970 +       select BACKLIGHT_LCD_SUPPORT
33971 +       select LCD_CLASS_DEVICE
33972 +       select LCD_UBICOM32
33973 +       select BACKLIGHT_CLASS_DEVICE
33974 +       select BACKLIGHT_UBICOM32
33975 +       select SND_UBI32
33976 +       select MMC_UBICOM32
33977 +       select MMC
33978 +       select MMC_BLOCK
33979 +       select BRD_64MB
33980 +       help
33981 +               IP7145 Digital Picture Frame reference design, supports:
33982 +                       8007-0410 v1.0
33983 +
33984 +config IP7160RGW
33985 +       bool "IP7160RGW"
33986 +       select UBICOM32_V4
33987 +       select UBICOM_INPUT
33988 +       select NEW_LEDS
33989 +       select LEDS_CLASS
33990 +       select LEDS_GPIO
33991 +       select BRD_64MB
33992 +       select SPI
33993 +       select SPI_UBICOM32_GPIO
33994 +       select VLAN_8021Q
33995 +       select UBICOM_SWITCH
33996 +       select UBICOM_SWITCH_BCM539X
33997 +       help
33998 +               Ubicom IP7160 RGW Eval, supports:
33999 +                       8007-0110 v1.0
34000 +                       8007-0111 v1.1
34001 +                       8007-0112 v1.2
34002 +
34003 +config IP7160BRINGUP
34004 +       bool "IP7160BRINGUP"
34005 +       select UBICOM32_V4
34006 +       select NEW_LEDS
34007 +       select LEDS_CLASS
34008 +       select LEDS_GPIO
34009 +       select BRD_64MB
34010 +       help
34011 +               Ubicom IP7160 Bringup, supports:
34012 +                       8007-0010 v1.0
34013 +
34014 +config IP7160DPF
34015 +       bool "IP7160DPF"
34016 +       select UBICOM32_V4
34017 +       select I2C
34018 +       select I2C_GPIO
34019 +       select FB
34020 +       select FB_UBICOM32
34021 +       select BACKLIGHT_LCD_SUPPORT
34022 +       select BACKLIGHT_CLASS_DEVICE
34023 +       select SND_UBI32
34024 +       select SND_UBI32_AUDIO_CS4350
34025 +       select UBICOM_HID
34026 +       select BRD_64MB
34027 +       help
34028 +               IP7160 Digital Picture Frame board, supports:
34029 +                       8007-0211 Rev 1.1
34030 +
34031 +config IP7500MODULE
34032 +       bool "IP7500MODULE"
34033 +       select UBICOM32_V4
34034 +       select BRD_128MB
34035 +       help
34036 +               Ubicom IP7500 CPU Module board, supports:
34037 +                       8007-0510  v1.0
34038 +                       8007-0510A v1.0
34039 +
34040 +               Please see ip7500module.c for more details.
34041 +
34042 +config IP7500AV
34043 +       bool "IP7500AV"
34044 +       select UBICOM32_V4
34045 +       select BRD_128MB
34046 +       select I2C
34047 +       select I2C_GPIO
34048 +       select SND_UBI32
34049 +       select SND_UBI32_AUDIO_CS4384
34050 +       select FB
34051 +       select FB_UBICOM32
34052 +       help
34053 +               Ubicom IP7500 Audio Video board, supports:
34054 +                       8007-0810  v1.0
34055 +
34056 +               With Ubicom IP7500 CPU Module board:
34057 +                       8007-0510  v1.0 -or-
34058 +                       8007-0510A v1.0
34059 +
34060 +               Please see ip7500av.c for more details.
34061 +
34062 +config IP7500MEDIA
34063 +       bool "IP7500MEDIA"
34064 +       select UBICOM32_V4
34065 +       select UBICOM_INPUT_I2C
34066 +       select RTC_CLASS
34067 +       select RTC_DRV_S35390A
34068 +       select I2C
34069 +       select I2C_GPIO
34070 +       select GPIO_PCA953X
34071 +       select FB
34072 +       select FB_UBICOM32
34073 +       select BACKLIGHT_LCD_SUPPORT
34074 +       select LCD_CLASS_DEVICE
34075 +       select LCD_UBICOM32
34076 +       select BACKLIGHT_CLASS_DEVICE
34077 +       select BACKLIGHT_UBICOM32
34078 +       select SND_UBI32
34079 +       select SND_UBI32_AUDIO_CS4350
34080 +       select MMC_UBICOM32
34081 +       select MMC
34082 +       select MMC_BLOCK
34083 +       select BRD_128MB
34084 +       help
34085 +               IP7500 Media Board w/ IP7500 CPU Module board, supports:
34086 +                       8007-0610 v1.0 w/ 8007-0510 v1.0
34087 +
34088 +               Please see ip7500media.c for more details.
34089 +
34090 --- /dev/null
34091 +++ b/arch/ubicom32/mach-ip7k/Makefile
34092 @@ -0,0 +1,35 @@
34093 +#
34094 +# arch/ubicom32/mach-ip7k/Makefile
34095 +#      Makefile for ip7k based boards.
34096 +#
34097 +# (C) Copyright 2009, Ubicom, Inc.
34098 +#
34099 +# This file is part of the Ubicom32 Linux Kernel Port.
34100 +#
34101 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34102 +# it and/or modify it under the terms of the GNU General Public License
34103 +# as published by the Free Software Foundation, either version 2 of the
34104 +# License, or (at your option) any later version.
34105 +#
34106 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34107 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34108 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34109 +# the GNU General Public License for more details.
34110 +#
34111 +# You should have received a copy of the GNU General Public License
34112 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34113 +# see <http://www.gnu.org/licenses/>.
34114 +#
34115 +# Ubicom32 implementation derived from (with many thanks):
34116 +#   arch/m68knommu
34117 +#   arch/blackfin
34118 +#   arch/parisc
34119 +#
34120 +
34121 +obj-$(CONFIG_IP7145DPF)                += board-ip7145dpf.o
34122 +obj-$(CONFIG_IP7160RGW)                += board-ip7160rgw.o
34123 +obj-$(CONFIG_IP7160BRINGUP)    += board-ip7160bringup.o
34124 +obj-$(CONFIG_IP7160DPF)                += board-ip7160dpf.o
34125 +obj-$(CONFIG_IP7500MODULE)     += board-ip7500module.o
34126 +obj-$(CONFIG_IP7500MEDIA)      += board-ip7500media.o
34127 +obj-$(CONFIG_IP7500AV)         += board-ip7500av.o
34128 --- /dev/null
34129 +++ b/arch/ubicom32/Makefile
34130 @@ -0,0 +1,103 @@
34131 +#
34132 +# arch/ubicom32/Makefile
34133 +#      <TODO: Replace with short file description>
34134 +#
34135 +# (C) Copyright 2009, Ubicom, Inc.
34136 +#
34137 +# This file is part of the Ubicom32 Linux Kernel Port.
34138 +#
34139 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34140 +# it and/or modify it under the terms of the GNU General Public License
34141 +# as published by the Free Software Foundation, either version 2 of the
34142 +# License, or (at your option) any later version.
34143 +#
34144 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34145 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34146 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34147 +# the GNU General Public License for more details.
34148 +#
34149 +# You should have received a copy of the GNU General Public License
34150 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34151 +# see <http://www.gnu.org/licenses/>.
34152 +#
34153 +# Ubicom32 implementation derived from (with many thanks):
34154 +#   arch/m68knommu
34155 +#   arch/blackfin
34156 +#   arch/parisc
34157 +#
34158 +
34159 +KBUILD_DEFCONFIG := 
34160 +
34161 +# setup the machine name and machine dependent settings
34162 +machine-$(CONFIG_UBICOM32_V3)  := ip5k
34163 +machine-$(CONFIG_UBICOM32_V4)  := ip7k
34164 +MACHINE := $(machine-y)
34165 +export MACHINE
34166 +
34167 +model-$(CONFIG_RAMKERNEL)      := ram
34168 +model-$(CONFIG_ROMKERNEL)      := rom
34169 +MODEL := $(model-y)
34170 +export MODEL
34171 +
34172 +CPUCLASS := $(cpuclass-y)
34173 +
34174 +export CPUCLASS
34175 +
34176 +#
34177 +# We want the core kernel built using the fastcall ABI but modules need
34178 +# to be built using the slower calling convention because they could be
34179 +# loaded out of range for fast calls.
34180 +#
34181 +CFLAGS_KERNEL    += -mfastcall
34182 +CFLAGS_MODULE    += -mno-fastcall
34183 +
34184 +#
34185 +# Some CFLAG additions based on specific CPU type.
34186 +#
34187 +cflags-$(CONFIG_UBICOM32_V3)           := -march=ubicom32v3 -mno-fdpic -DIP5000
34188 +cflags-$(CONFIG_UBICOM32_V4)           := -march=ubicom32v4 -mno-fdpic -DIP7000
34189 +
34190 +ldflags-$(CONFIG_LINKER_RELAXATION)    := --relax
34191 +LDFLAGS_vmlinux := $(ldflags-y)
34192 +
34193 +GCCLIBDIR := $(dir $(shell $(CC) $(cflags-y) -print-libgcc-file-name))
34194 +
34195 +KBUILD_CFLAGS += $(cflags-y) -ffunction-sections
34196 +KBUILD_AFLAGS += $(cflags-y)
34197 +
34198 +KBUILD_CFLAGS += -D__linux__ -Dlinux
34199 +KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
34200 +
34201 +# include any machine specific directory
34202 +ifneq ($(machine-y),)
34203 +core-y += arch/$(ARCH)/mach-$(MACHINE)/
34204 +endif
34205 +
34206 +head-y := arch/$(ARCH)/kernel/head.o
34207 +
34208 +core-y += arch/$(ARCH)/kernel/ \
34209 +          arch/$(ARCH)/mm/ \
34210 +          arch/$(ARCH)/crypto/ \
34211 +          arch/$(ARCH)/mach-common/
34212 +
34213 +drivers-$(CONFIG_OPROFILE)     += arch/ubicom32/oprofile/
34214 +
34215 +libs-y += arch/$(ARCH)/lib/
34216 +
34217 +archclean:
34218 +
34219 +# make sure developer has selected a valid board
34220 +ifeq ($(CONFIG_NOBOARD),y)
34221 +# $(error have to select a valid board file $(CONFIG_NOBOARD), please run kernel config again)
34222 +_all: config_board_error
34223 +endif
34224 +
34225 +config_board_error:
34226 +       @echo "*************************************************"
34227 +       @echo "You have not selected a proper board."
34228 +       @echo "Please run menuconfig (or config) against your"
34229 +       @echo "kernel and choose your board under Processor"
34230 +       @echo "options"
34231 +       @echo "*************************************************"
34232 +       @exit 1
34233 +
34234 --- /dev/null
34235 +++ b/arch/ubicom32/mm/fault.c
34236 @@ -0,0 +1,81 @@
34237 +/*
34238 + * arch/ubicom32/mm/fault.c
34239 + *   Ubicom32 architecture page fault implementation.
34240 + *
34241 + * (C) Copyright 2009, Ubicom, Inc.
34242 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
34243 + *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
34244 + *
34245 + *  Based on:
34246 + *
34247 + *  linux/arch/m68k/mm/fault.c
34248 + *
34249 + *  Copyright (C) 1995  Hamish Macdonald
34250 + *
34251 + * This file is part of the Ubicom32 Linux Kernel Port.
34252 + *
34253 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34254 + * it and/or modify it under the terms of the GNU General Public License
34255 + * as published by the Free Software Foundation, either version 2 of the
34256 + * License, or (at your option) any later version.
34257 + *
34258 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34259 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34260 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34261 + * the GNU General Public License for more details.
34262 + *
34263 + * You should have received a copy of the GNU General Public License
34264 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34265 + * see <http://www.gnu.org/licenses/>.
34266 + *
34267 + * Ubicom32 implementation derived from (with many thanks):
34268 + *   arch/m68knommu
34269 + *   arch/blackfin
34270 + *   arch/parisc
34271 + */
34272 +
34273 +#include <linux/module.h>
34274 +#include <linux/mman.h>
34275 +#include <linux/mm.h>
34276 +#include <linux/kernel.h>
34277 +#include <linux/ptrace.h>
34278 +
34279 +#include <asm/system.h>
34280 +#include <asm/pgtable.h>
34281 +
34282 +extern void die_if_kernel(char *, struct pt_regs *, long);
34283 +
34284 +/*
34285 + * This routine handles page faults.  It determines the problem, and
34286 + * then passes it off to one of the appropriate routines.
34287 + *
34288 + * error_code:
34289 + *     bit 0 == 0 means no page found, 1 means protection fault
34290 + *     bit 1 == 0 means read, 1 means write
34291 + *
34292 + * If this routine detects a bad access, it returns 1, otherwise it
34293 + * returns 0.
34294 + */
34295 +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
34296 +                             unsigned long error_code)
34297 +{
34298 +#ifdef DEBUG
34299 +       printk (KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
34300 +               regs->sr, regs->pc, address, error_code);
34301 +#endif
34302 +
34303 +       /*
34304 +        * Oops. The kernel tried to access some bad page. We'll have to
34305 +        * terminate things with extreme prejudice.
34306 +        */
34307 +       if ((unsigned long) address < PAGE_SIZE) {
34308 +               printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
34309 +       } else
34310 +               printk(KERN_ALERT "Unable to handle kernel access");
34311 +       printk(KERN_ALERT " at virtual address %08lx\n",address);
34312 +       die_if_kernel("Oops", regs, error_code);
34313 +       do_exit(SIGKILL);
34314 +
34315 +       return 1;
34316 +}
34317 +
34318 --- /dev/null
34319 +++ b/arch/ubicom32/mm/init.c
34320 @@ -0,0 +1,261 @@
34321 +/*
34322 + * arch/ubicom32/mm/init.c
34323 + *   Ubicom32 architecture virtual memory initialization.
34324 + *
34325 + * (C) Copyright 2009, Ubicom, Inc.
34326 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
34327 + *                      Kenneth Albanowski <kjahds@kjahds.com>,
34328 + *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
34329 + *
34330 + *  Based on:
34331 + *
34332 + *  linux/arch/m68k/mm/init.c
34333 + *
34334 + *  Copyright (C) 1995  Hamish Macdonald
34335 + *
34336 + *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
34337 + *  DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
34338 + *
34339 + * This file is part of the Ubicom32 Linux Kernel Port.
34340 + *
34341 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34342 + * it and/or modify it under the terms of the GNU General Public License
34343 + * as published by the Free Software Foundation, either version 2 of the
34344 + * License, or (at your option) any later version.
34345 + *
34346 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34347 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34348 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34349 + * the GNU General Public License for more details.
34350 + *
34351 + * You should have received a copy of the GNU General Public License
34352 + * along with the Ubicom32 Linux Kernel Port.  If not,
34353 + * see <http://www.gnu.org/licenses/>.
34354 + *
34355 + * Ubicom32 implementation derived from (with many thanks):
34356 + *   arch/m68knommu
34357 + *   arch/blackfin
34358 + *   arch/parisc
34359 + */
34360 +
34361 +#include <linux/signal.h>
34362 +#include <linux/sched.h>
34363 +#include <linux/kernel.h>
34364 +#include <linux/errno.h>
34365 +#include <linux/string.h>
34366 +#include <linux/types.h>
34367 +#include <linux/ptrace.h>
34368 +#include <linux/mman.h>
34369 +#include <linux/mm.h>
34370 +#include <linux/swap.h>
34371 +#include <linux/init.h>
34372 +#include <linux/highmem.h>
34373 +#include <linux/pagemap.h>
34374 +#include <linux/bootmem.h>
34375 +#include <linux/slab.h>
34376 +
34377 +#include <asm/setup.h>
34378 +#include <asm/segment.h>
34379 +#include <asm/page.h>
34380 +#include <asm/pgtable.h>
34381 +#include <asm/system.h>
34382 +#include <asm/machdep.h>
34383 +#include <asm/ocm-alloc.h>
34384 +
34385 +#undef DEBUG
34386 +
34387 +extern void die_if_kernel(char *,struct pt_regs *,long);
34388 +extern void free_initmem(void);
34389 +
34390 +/*
34391 + * BAD_PAGE is the page that is used for page faults when linux
34392 + * is out-of-memory. Older versions of linux just did a
34393 + * do_exit(), but using this instead means there is less risk
34394 + * for a process dying in kernel mode, possibly leaving a inode
34395 + * unused etc..
34396 + *
34397 + * BAD_PAGETABLE is the accompanying page-table: it is initialized
34398 + * to point to BAD_PAGE entries.
34399 + *
34400 + * ZERO_PAGE is a special page that is used for zero-initialized
34401 + * data and COW.
34402 + */
34403 +static unsigned long empty_bad_page_table;
34404 +
34405 +static unsigned long empty_bad_page;
34406 +
34407 +unsigned long empty_zero_page;
34408 +
34409 +void show_mem(void)
34410 +{
34411 +    unsigned long i;
34412 +    int free = 0, total = 0, reserved = 0, shared = 0;
34413 +    int cached = 0;
34414 +
34415 +    printk(KERN_INFO "\nMem-info:\n");
34416 +    show_free_areas();
34417 +    i = max_mapnr;
34418 +    while (i-- > 0) {
34419 +       total++;
34420 +       if (PageReserved(mem_map+i))
34421 +           reserved++;
34422 +       else if (PageSwapCache(mem_map+i))
34423 +           cached++;
34424 +       else if (!page_count(mem_map+i))
34425 +           free++;
34426 +       else
34427 +           shared += page_count(mem_map+i) - 1;
34428 +    }
34429 +    printk(KERN_INFO "%d pages of RAM\n",total);
34430 +    printk(KERN_INFO "%d free pages\n",free);
34431 +    printk(KERN_INFO "%d reserved pages\n",reserved);
34432 +    printk(KERN_INFO "%d pages shared\n",shared);
34433 +    printk(KERN_INFO "%d pages swap cached\n",cached);
34434 +}
34435 +
34436 +extern unsigned long memory_start;
34437 +extern unsigned long memory_end;
34438 +extern char __ocm_free_begin;
34439 +extern char __ocm_free_end;
34440 +
34441 +/*
34442 + * paging_init() continues the virtual memory environment setup which
34443 + * was begun by the code in arch/head.S.
34444 + * The parameters are pointers to where to stick the starting and ending
34445 + * addresses of available kernel virtual memory.
34446 + */
34447 +void __init paging_init(void)
34448 +{
34449 +       /*
34450 +        * Make sure start_mem is page aligned, otherwise bootmem and
34451 +        * page_alloc get different views of the world.
34452 +        */
34453 +#ifdef DEBUG
34454 +       unsigned long start_mem = PAGE_ALIGN(memory_start);
34455 +#endif
34456 +       unsigned long end_mem   = memory_end & PAGE_MASK;
34457 +
34458 +#ifdef DEBUG
34459 +       printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
34460 +               start_mem, end_mem);
34461 +#endif
34462 +
34463 +       /*
34464 +        * Initialize the bad page table and bad page to point
34465 +        * to a couple of allocated pages.
34466 +        */
34467 +       empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34468 +       empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34469 +       empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34470 +       memset((void *)empty_zero_page, 0, PAGE_SIZE);
34471 +
34472 +       /*
34473 +        * TODO: enable setting up for user memory management interface.
34474 +        */
34475 +
34476 +#ifdef DEBUG
34477 +       printk (KERN_DEBUG "before free_area_init\n");
34478 +
34479 +       printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
34480 +               start_mem, end_mem);
34481 +#endif
34482 +
34483 +       {
34484 +               unsigned long zones_size[MAX_NR_ZONES] = {0, };
34485 +#ifdef CONFIG_ZONE_DMA
34486 +               zones_size[ZONE_DMA] = OCMSIZE >> PAGE_SHIFT;
34487 +#endif
34488 +               zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
34489 +#ifdef CONFIG_HIGHMEM
34490 +               zones_size[ZONE_HIGHMEM] = 0;
34491 +#endif
34492 +               free_area_init(zones_size);
34493 +       }
34494 +}
34495 +
34496 +void __init mem_init(void)
34497 +{
34498 +       int codek = 0, datak = 0, initk = 0;
34499 +       unsigned long tmp;
34500 +       extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
34501 +       unsigned long len = CONFIG_RAMSIZE + OCMSIZE;
34502 +       unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
34503 +       unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
34504 +
34505 +#ifdef DEBUG
34506 +       printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
34507 +#endif
34508 +
34509 +       end_mem &= PAGE_MASK;
34510 +       high_memory = (void *) end_mem;
34511 +
34512 +       start_mem = PAGE_ALIGN(start_mem);
34513 +       max_mapnr = num_physpages = (((unsigned long) high_memory) - PAGE_OFFSET) >> PAGE_SHIFT;
34514 +
34515 +       /* this will put all memory onto the freelists */
34516 +#ifdef CONFIG_ZONE_DMA
34517 +       {
34518 +               unsigned long ocm_free_begin = (unsigned long)&__ocm_free_begin;
34519 +               unsigned long ocm_free_end = (unsigned long)&__ocm_free_end;
34520 +               unsigned long zone_dma_begin = (ocm_free_begin + PAGE_SIZE - 1) & PAGE_MASK;
34521 +               unsigned long zone_dma_end = ocm_free_end & PAGE_MASK;
34522 +               if (zone_dma_end > zone_dma_begin)
34523 +                       free_bootmem(zone_dma_begin, zone_dma_end-zone_dma_begin);
34524 +       }
34525 +#endif
34526 +       totalram_pages = free_all_bootmem();
34527 +
34528 +       codek = (&_etext - &_stext) >> 10;
34529 +       datak = (&_ebss - &_sdata) >> 10;
34530 +       initk = (&__init_begin - &__init_end) >> 10;
34531 +
34532 +       tmp = nr_free_pages() << PAGE_SHIFT;
34533 +       printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n",
34534 +              tmp >> 10,
34535 +              len >> 10,
34536 +              codek,
34537 +              datak
34538 +              );
34539 +
34540 +}
34541 +
34542 +#ifdef CONFIG_BLK_DEV_INITRD
34543 +void free_initrd_mem(unsigned long start, unsigned long end)
34544 +{
34545 +       int pages = 0;
34546 +       for (; start < end; start += PAGE_SIZE) {
34547 +               ClearPageReserved(virt_to_page(start));
34548 +               init_page_count(virt_to_page(start));
34549 +               free_page(start);
34550 +               totalram_pages++;
34551 +               pages++;
34552 +       }
34553 +       printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
34554 +}
34555 +#endif
34556 +
34557 +void
34558 +free_initmem()
34559 +{
34560 +#ifdef CONFIG_RAMKERNEL
34561 +       unsigned long addr;
34562 +       extern char __init_begin, __init_end;
34563 +       /*
34564 +        * The following code should be cool even if these sections
34565 +        * are not page aligned.
34566 +        */
34567 +       addr = PAGE_ALIGN((unsigned long)(&__init_begin));
34568 +       /* next to check that the page we free is not a partial page */
34569 +       for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
34570 +               ClearPageReserved(virt_to_page(addr));
34571 +               init_page_count(virt_to_page(addr));
34572 +               free_page(addr);
34573 +               totalram_pages++;
34574 +       }
34575 +       printk(KERN_NOTICE "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
34576 +                       (addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
34577 +                       (int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
34578 +                       (int)(addr - PAGE_SIZE));
34579 +#endif
34580 +}
34581 +
34582 --- /dev/null
34583 +++ b/arch/ubicom32/mm/kmap.c
34584 @@ -0,0 +1,79 @@
34585 +/*
34586 + * arch/ubicom32/mm/kmap.c
34587 + *   Ubicom32 architecture non-mmu ioremap and friends implementation.
34588 + *
34589 + * (C) Copyright 2009, Ubicom, Inc.
34590 + * Copyright (C) 2000 Lineo, <davidm@snapgear.com>
34591 + * Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
34592 + *
34593 + * This file is part of the Ubicom32 Linux Kernel Port.
34594 + *
34595 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34596 + * it and/or modify it under the terms of the GNU General Public License
34597 + * as published by the Free Software Foundation, either version 2 of the
34598 + * License, or (at your option) any later version.
34599 + *
34600 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34601 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34602 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34603 + * the GNU General Public License for more details.
34604 + *
34605 + * You should have received a copy of the GNU General Public License
34606 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34607 + * see <http://www.gnu.org/licenses/>.
34608 + *
34609 + * Ubicom32 implementation derived from (with many thanks):
34610 + *   arch/m68knommu
34611 + *   arch/blackfin
34612 + *   arch/parisc
34613 + */
34614 +
34615 +#include <linux/module.h>
34616 +#include <linux/mm.h>
34617 +#include <linux/kernel.h>
34618 +#include <linux/string.h>
34619 +#include <linux/types.h>
34620 +#include <linux/slab.h>
34621 +#include <linux/vmalloc.h>
34622 +
34623 +#include <asm/setup.h>
34624 +#include <asm/segment.h>
34625 +#include <asm/page.h>
34626 +#include <asm/pgalloc.h>
34627 +#include <asm/io.h>
34628 +#include <asm/system.h>
34629 +
34630 +#undef DEBUG
34631 +
34632 +/*
34633 + * Map some physical address range into the kernel address space.
34634 + */
34635 +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
34636 +{
34637 +       return (void *)physaddr;
34638 +}
34639 +
34640 +/*
34641 + * Unmap a ioremap()ed region again.
34642 + */
34643 +void iounmap(void *addr)
34644 +{
34645 +}
34646 +
34647 +/*
34648 + * __iounmap unmaps nearly everything, so be careful
34649 + * it doesn't free currently pointer/page tables anymore but it
34650 + * wans't used anyway and might be added later.
34651 + */
34652 +void __iounmap(void *addr, unsigned long size)
34653 +{
34654 +}
34655 +
34656 +/*
34657 + * Set new cache mode for some kernel address space.
34658 + * The caller must push data for that range itself, if such data may already
34659 + * be in the cache.
34660 + */
34661 +void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
34662 +{
34663 +}
34664 --- /dev/null
34665 +++ b/arch/ubicom32/mm/Makefile
34666 @@ -0,0 +1,32 @@
34667 +#
34668 +# arch/ubicom32/mm/Makefile
34669 +#      <TODO: Replace with short file description>
34670 +#
34671 +# (C) Copyright 2009, Ubicom, Inc.
34672 +#
34673 +# This file is part of the Ubicom32 Linux Kernel Port.
34674 +#
34675 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34676 +# it and/or modify it under the terms of the GNU General Public License
34677 +# as published by the Free Software Foundation, either version 2 of the
34678 +# License, or (at your option) any later version.
34679 +#
34680 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34681 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34682 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34683 +# the GNU General Public License for more details.
34684 +#
34685 +# You should have received a copy of the GNU General Public License
34686 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34687 +# see <http://www.gnu.org/licenses/>.
34688 +#
34689 +# Ubicom32 implementation derived from (with many thanks):
34690 +#   arch/m68knommu
34691 +#   arch/blackfin
34692 +#   arch/parisc
34693 +#
34694 +#
34695 +# Makefile for the linux m68knommu specific parts of the memory manager.
34696 +#
34697 +
34698 +obj-y += init.o fault.o memory.o kmap.o ocm-alloc.o
34699 --- /dev/null
34700 +++ b/arch/ubicom32/mm/memory.c
34701 @@ -0,0 +1,59 @@
34702 +/*
34703 + * arch/ubicom32/mm/memory.c
34704 + *   Ubicom32 architecture kernel_map() implementation.
34705 + *
34706 + * (C) Copyright 2009, Ubicom, Inc.
34707 + *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
34708 + *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
34709 + *
34710 + *  Based on:
34711 + *
34712 + *  linux/arch/m68k/mm/memory.c
34713 + *
34714 + *  Copyright (C) 1995  Hamish Macdonald
34715 + *
34716 + * This file is part of the Ubicom32 Linux Kernel Port.
34717 + *
34718 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34719 + * it and/or modify it under the terms of the GNU General Public License
34720 + * as published by the Free Software Foundation, either version 2 of the
34721 + * License, or (at your option) any later version.
34722 + *
34723 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34724 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34725 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34726 + * the GNU General Public License for more details.
34727 + *
34728 + * You should have received a copy of the GNU General Public License
34729 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34730 + * see <http://www.gnu.org/licenses/>.
34731 + *
34732 + * Ubicom32 implementation derived from (with many thanks):
34733 + *   arch/m68knommu
34734 + *   arch/blackfin
34735 + *   arch/parisc
34736 + */
34737 +
34738 +#include <linux/module.h>
34739 +#include <linux/mm.h>
34740 +#include <linux/kernel.h>
34741 +#include <linux/string.h>
34742 +#include <linux/types.h>
34743 +#include <linux/slab.h>
34744 +
34745 +#include <asm/segment.h>
34746 +#include <asm/page.h>
34747 +#include <asm/pgtable.h>
34748 +#include <asm/system.h>
34749 +
34750 +/*
34751 + * Map some physical address range into the kernel address space.
34752 + * The code is copied and adapted from map_chunk().
34753 + */
34754 +
34755 +unsigned long kernel_map(unsigned long paddr, unsigned long size,
34756 +                        int nocacheflag, unsigned long *memavailp )
34757 +{
34758 +       return paddr;
34759 +}
34760 +
34761 --- /dev/null
34762 +++ b/arch/ubicom32/mm/ocm-alloc.c
34763 @@ -0,0 +1,439 @@
34764 +/*
34765 + * arch/ubicom32/mm/ocm-alloc.c
34766 + *     OCM allocator for Uibcom32 On-Chip memory
34767 + *
34768 + * (C) Copyright 2009, Ubicom, Inc.
34769 + *  Copyright 2004-2008 Analog Devices Inc.
34770 + *
34771 + *  Based on:
34772 + *
34773 + *  arch/blackfin/mm/sram-alloc.c
34774 + *
34775 + *
34776 + * This file is part of the Ubicom32 Linux Kernel Port.
34777 + *
34778 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34779 + * it and/or modify it under the terms of the GNU General Public License
34780 + * as published by the Free Software Foundation, either version 2 of the
34781 + * License, or (at your option) any later version.
34782 + *
34783 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34784 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34785 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34786 + * the GNU General Public License for more details.
34787 + *
34788 + * You should have received a copy of the GNU General Public License
34789 + * along with the Ubicom32 Linux Kernel Port.  If not,
34790 + * see <http://www.gnu.org/licenses/>.
34791 + *
34792 + * Ubicom32 implementation derived from (with many thanks):
34793 + *   arch/m68knommu
34794 + *   arch/blackfin
34795 + *   arch/parisc
34796 + */
34797 +
34798 +#include <linux/module.h>
34799 +#include <linux/kernel.h>
34800 +#include <linux/types.h>
34801 +#include <linux/miscdevice.h>
34802 +#include <linux/ioport.h>
34803 +#include <linux/fcntl.h>
34804 +#include <linux/init.h>
34805 +#include <linux/poll.h>
34806 +#include <linux/proc_fs.h>
34807 +#include <linux/mutex.h>
34808 +#include <linux/rtc.h>
34809 +#include <asm/ocm-alloc.h>
34810 +
34811 +#if 0
34812 +#define DEBUGP printk
34813 +#else
34814 +#define DEBUGP(fmt, a...)
34815 +#endif
34816 +/*
34817 + * the data structure for OCM heap pieces
34818 + */
34819 +struct ocm_piece {
34820 +       void *paddr;
34821 +       int size;
34822 +       pid_t pid;
34823 +       struct ocm_piece *next;
34824 +};
34825 +
34826 +/*
34827 + * struct ocm_heap
34828 + */
34829 +struct ocm_heap {
34830 +       struct ocm_piece free_head;
34831 +       struct ocm_piece used_head;
34832 +       struct mutex lock;
34833 +};
34834 +
34835 +static struct ocm_heap ocm_inst_heap;
34836 +
34837 +/*
34838 + * OCM area for storing code
34839 + */
34840 +extern asmlinkage void *__ocm_inst_heap_begin;
34841 +extern asmlinkage void *__ocm_inst_heap_end;
34842 +#define OCM_INST_HEAP_BEGIN ((unsigned int)&__ocm_inst_heap_begin)
34843 +#define OCM_INST_HEAP_END ((unsigned int)&__ocm_inst_heap_end)
34844 +#define OCM_INST_HEAP_LENGTH (OCM_INST_HEAP_END - OCM_INST_HEAP_BEGIN)
34845 +
34846 +static struct kmem_cache *ocm_piece_cache;
34847 +
34848 +/*
34849 + * _ocm_heap_init()
34850 + */
34851 +static int __init _ocm_heap_init(struct ocm_heap *ocmh,
34852 +                                 unsigned int start,
34853 +                                 unsigned int size)
34854 +{
34855 +       ocmh->free_head.next = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
34856 +
34857 +       if (!ocmh->free_head.next)
34858 +               return -1;
34859 +
34860 +       ocmh->free_head.next->paddr = (void *)start;
34861 +       ocmh->free_head.next->size = size;
34862 +       ocmh->free_head.next->pid = 0;
34863 +       ocmh->free_head.next->next = 0;
34864 +
34865 +       ocmh->used_head.next = NULL;
34866 +
34867 +       /* mutex initialize */
34868 +       mutex_init(&ocmh->lock);
34869 +
34870 +       return 0;
34871 +}
34872 +
34873 +/*
34874 + * _ocm_alloc_init()
34875 + *
34876 + * starts the ocm heap(s)
34877 + */
34878 +static int __init _ocm_alloc_init(void)
34879 +{
34880 +       if (OCM_INST_HEAP_LENGTH) {
34881 +               ocm_piece_cache = kmem_cache_create("ocm_piece_cache",
34882 +                                                   sizeof(struct ocm_piece),
34883 +                                                   0, SLAB_PANIC, NULL);
34884 +
34885 +               if (_ocm_heap_init(&ocm_inst_heap,
34886 +                                  OCM_INST_HEAP_BEGIN,
34887 +                                  OCM_INST_HEAP_LENGTH) == 0)
34888 +                       printk(KERN_INFO "OCM Instruction Heap %d KB\n",
34889 +                              OCM_INST_HEAP_LENGTH >> 10);
34890 +               else
34891 +                       printk(KERN_INFO "Failed to initialize OCM "
34892 +                              "Instruction Heap\n");
34893 +
34894 +       } else
34895 +               printk(KERN_INFO "No space available for OCM "
34896 +                      "Instruction Heap\n");
34897 +
34898 +       return 0;
34899 +}
34900 +pure_initcall(_ocm_alloc_init);
34901 +
34902 +/*
34903 + * _ocm_alloc()
34904 + *     generic alloc a block in the ocm heap, if successful
34905 + *     returns the pointer.
34906 + */
34907 +static void *_ocm_alloc(size_t size, pid_t pid, struct ocm_heap *ocmheap)
34908 +{
34909 +       struct ocm_piece *pslot, *plast, *pavail;
34910 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
34911 +       struct ocm_piece *pused_head = &ocmheap->used_head;
34912 +
34913 +       if (size <= 0 || !pfree_head || !pused_head)
34914 +               return NULL;
34915 +
34916 +       /* Align the size */
34917 +       size = (size + 3) & ~3;
34918 +
34919 +       pslot = pfree_head->next;
34920 +       plast = pfree_head;
34921 +
34922 +       /*
34923 +        * search an available piece slot
34924 +        */
34925 +       while (pslot != NULL && size > pslot->size) {
34926 +               plast = pslot;
34927 +               pslot = pslot->next;
34928 +       }
34929 +
34930 +       if (!pslot)
34931 +               return NULL;
34932 +
34933 +       if (pslot->size == size) {
34934 +               /*
34935 +                * Unlink this block from the list
34936 +                */
34937 +               plast->next = pslot->next;
34938 +               pavail = pslot;
34939 +       } else {
34940 +               /*
34941 +                * Split this block in two.
34942 +                */
34943 +               pavail = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
34944 +
34945 +               if (!pavail)
34946 +                       return NULL;
34947 +
34948 +               pavail->paddr = pslot->paddr;
34949 +               pavail->size = size;
34950 +               pslot->paddr += size;
34951 +               pslot->size -= size;
34952 +       }
34953 +
34954 +       pavail->pid = pid;
34955 +
34956 +       pslot = pused_head->next;
34957 +       plast = pused_head;
34958 +
34959 +       /*
34960 +        * insert new piece into used piece list !!!
34961 +        */
34962 +       while (pslot != NULL && pavail->paddr < pslot->paddr) {
34963 +               plast = pslot;
34964 +               pslot = pslot->next;
34965 +       }
34966 +
34967 +       pavail->next = pslot;
34968 +       plast->next = pavail;
34969 +
34970 +       DEBUGP("_ocm_alloc %d bytes at %p from in %p",
34971 +              size, pavail->paddr, ocmheap);
34972 +
34973 +       return pavail->paddr;
34974 +}
34975 +
34976 +#if 0
34977 +/* Allocate the largest available block.  */
34978 +static void *_ocm_alloc_max(struct ocm_heap *ocmheap,
34979 +                            unsigned long *psize)
34980 +{
34981 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
34982 +       struct ocm_piece *pslot, *pmax;
34983 +
34984 +       pmax = pslot = pfree_head->next;
34985 +
34986 +       /* search an available piece slot */
34987 +       while (pslot != NULL) {
34988 +               if (pslot->size > pmax->size)
34989 +                       pmax = pslot;
34990 +               pslot = pslot->next;
34991 +       }
34992 +
34993 +       if (!pmax)
34994 +               return NULL;
34995 +
34996 +       *psize = pmax->size;
34997 +
34998 +       return _ocm_alloc(*psize, ocmheap);
34999 +}
35000 +#endif
35001 +
35002 +/*
35003 + * _ocm_free()
35004 + *     generic free a block in the ocm heap, if successful
35005 + */
35006 +static int _ocm_free(const void *addr,
35007 +                    struct ocm_heap *ocmheap)
35008 +{
35009 +       struct ocm_piece *pslot, *plast, *pavail;
35010 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35011 +       struct ocm_piece *pused_head = &ocmheap->used_head;
35012 +
35013 +       /* search the relevant memory slot */
35014 +       pslot = pused_head->next;
35015 +       plast = pused_head;
35016 +
35017 +       /* search an available piece slot */
35018 +       while (pslot != NULL && pslot->paddr != addr) {
35019 +               plast = pslot;
35020 +               pslot = pslot->next;
35021 +       }
35022 +
35023 +       if (!pslot) {
35024 +               DEBUGP("_ocm_free %p  not found in %p", addr, ocmheap);
35025 +               return -1;
35026 +       }
35027 +       DEBUGP("_ocm_free %p from in %p", addr, ocmheap);
35028 +
35029 +       plast->next = pslot->next;
35030 +       pavail = pslot;
35031 +       pavail->pid = 0;
35032 +
35033 +       /* insert free pieces back to the free list */
35034 +       pslot = pfree_head->next;
35035 +       plast = pfree_head;
35036 +
35037 +       while (pslot != NULL && addr > pslot->paddr) {
35038 +               plast = pslot;
35039 +               pslot = pslot->next;
35040 +       }
35041 +
35042 +       if (plast != pfree_head &&
35043 +           plast->paddr + plast->size == pavail->paddr) {
35044 +               plast->size += pavail->size;
35045 +               kmem_cache_free(ocm_piece_cache, pavail);
35046 +       } else {
35047 +               pavail->next = plast->next;
35048 +               plast->next = pavail;
35049 +               plast = pavail;
35050 +       }
35051 +
35052 +       if (pslot && plast->paddr + plast->size == pslot->paddr) {
35053 +               plast->size += pslot->size;
35054 +               plast->next = pslot->next;
35055 +               kmem_cache_free(ocm_piece_cache, pslot);
35056 +       }
35057 +
35058 +       return 0;
35059 +}
35060 +
35061 +/*
35062 + * ocm_inst_alloc()
35063 + *
35064 + *     allocates a block of size in the ocm instrction heap, if
35065 + *     successful returns address allocated.
35066 + */
35067 +void *ocm_inst_alloc(size_t size, pid_t pid)
35068 +{
35069 +       void *addr;
35070 +
35071 +       if (!OCM_INST_HEAP_LENGTH)
35072 +               return NULL;
35073 +
35074 +
35075 +       mutex_lock(&ocm_inst_heap.lock);
35076 +
35077 +       addr = _ocm_alloc(size, pid, &ocm_inst_heap);
35078 +
35079 +       mutex_unlock(&ocm_inst_heap.lock);
35080 +
35081 +       return addr;
35082 +}
35083 +EXPORT_SYMBOL(ocm_inst_alloc);
35084 +
35085 +/*
35086 + * ocm_inst_free()
35087 + *     free a block in the ocm instrction heap, returns 0 if successful.
35088 + */
35089 +int ocm_inst_free(const void *addr)
35090 +{
35091 +       int ret;
35092 +
35093 +       if (!OCM_INST_HEAP_LENGTH)
35094 +               return -1;
35095 +
35096 +       mutex_lock(&ocm_inst_heap.lock);
35097 +
35098 +       ret = _ocm_free(addr, &ocm_inst_heap);
35099 +
35100 +       mutex_unlock(&ocm_inst_heap.lock);
35101 +
35102 +       return ret;
35103 +}
35104 +EXPORT_SYMBOL(ocm_inst_free);
35105 +
35106 +/*
35107 + * ocm_free()
35108 + *     free a block in one of the ocm heaps, returns 0 if successful.
35109 + */
35110 +int ocm_free(const void *addr)
35111 +{
35112 +       if (addr >= (void *)OCM_INST_HEAP_BEGIN
35113 +                && addr < (void *)(OCM_INST_HEAP_END))
35114 +               return ocm_inst_free(addr);
35115 +       else
35116 +               return -1;
35117 +}
35118 +EXPORT_SYMBOL(ocm_free);
35119 +
35120 +
35121 +#ifdef CONFIG_PROC_FS
35122 +/* Need to keep line of output the same.  Currently, that is 46 bytes
35123 + * (including newline).
35124 + */
35125 +static int _ocm_proc_read(char *buf, int *len, int count, const char *desc,
35126 +                          struct ocm_heap *ocmheap)
35127 +{
35128 +       struct ocm_piece *pslot;
35129 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35130 +       struct ocm_piece *pused_head = &ocmheap->used_head;
35131 +
35132 +       /* The format is the following
35133 +        * --- OCM 123456789012345 Size   PID State     \n
35134 +        * 12345678-12345678 1234567890 12345 1234567890\n
35135 +        */
35136 +       int l;
35137 +       l = sprintf(&buf[*len], "--- OCM %-15s Size   PID State     \n",
35138 +                   desc);
35139 +
35140 +       *len += l;
35141 +       count -= l;
35142 +
35143 +       mutex_lock(&ocm_inst_heap.lock);
35144 +
35145 +       /*
35146 +        * search the relevant memory slot
35147 +        */
35148 +       pslot = pused_head->next;
35149 +
35150 +       while (pslot != NULL && count > 46) {
35151 +               l = sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
35152 +                            pslot->paddr, pslot->paddr + pslot->size,
35153 +                            pslot->size, pslot->pid, "ALLOCATED");
35154 +
35155 +               *len += l;
35156 +               count -= l;
35157 +               pslot = pslot->next;
35158 +       }
35159 +
35160 +       pslot = pfree_head->next;
35161 +
35162 +       while (pslot != NULL && count > 46) {
35163 +               l = sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
35164 +                           pslot->paddr, pslot->paddr + pslot->size,
35165 +                           pslot->size, pslot->pid, "FREE");
35166 +
35167 +               *len += l;
35168 +               count -= l;
35169 +               pslot = pslot->next;
35170 +       }
35171 +
35172 +       mutex_unlock(&ocm_inst_heap.lock);
35173 +
35174 +       return 0;
35175 +}
35176 +static int ocm_proc_read(char *buf, char **start, off_t offset, int count,
35177 +               int *eof, void *data)
35178 +{
35179 +       int len = 0;
35180 +
35181 +       if (_ocm_proc_read(buf, &len, count - len, "Inst Heap",
35182 +                           &ocm_inst_heap))
35183 +               goto not_done;
35184 +       *eof = 1;
35185 + not_done:
35186 +       return len;
35187 +}
35188 +
35189 +static int __init sram_proc_init(void)
35190 +{
35191 +       struct proc_dir_entry *ptr;
35192 +       ptr = create_proc_entry("ocm", S_IFREG | S_IRUGO, NULL);
35193 +       if (!ptr) {
35194 +               printk(KERN_WARNING "unable to create /proc/ocm\n");
35195 +               return -1;
35196 +       }
35197 +       ptr->owner = THIS_MODULE;
35198 +       ptr->read_proc = ocm_proc_read;
35199 +       return 0;
35200 +}
35201 +late_initcall(sram_proc_init);
35202 +#endif
35203 --- /dev/null
35204 +++ b/arch/ubicom32/oprofile/ipProf.h
35205 @@ -0,0 +1,39 @@
35206 +#ifndef __IP_PROF_H__
35207 +#define __IP_PROF_H__
35208 +
35209 +/* This number MUST match what is used in the ultra configuration! */
35210 +#define IPPROFILETIO_MAX_SAMPLES       600
35211 +
35212 +/* Move to .h file used in both; avoid special types  */
35213 +struct profile_sample {
35214 +       unsigned int    pc;             /* PC value */
35215 +       unsigned int    parent;         /* a5 contents, to find the caller */
35216 +       unsigned char   cond_codes;     /* for branch prediction */
35217 +       unsigned char   thread;         /* I-blocked, D-blocked,
35218 +                                          4-bit thread number */
35219 +       unsigned short  active;         /* which threads are active -
35220 +                                          for accurate counting */
35221 +       unsigned short  blocked;        /* which threads are blocked due to
35222 +                                          I or D cache misses */
35223 +       unsigned int    latency;        /* CPU clocks since the last message
35224 +                                          dispatch in this thread
35225 +                                          (thread 0 only for now) */
35226 +};
35227 +
35228 +
35229 +struct profilenode {
35230 +       struct devtree_node dn;
35231 +       volatile unsigned char enabled; /* Is the tio enabled to
35232 +                                          take samples? */
35233 +       volatile unsigned char busy;    /* set when the samples
35234 +                                          are being read */
35235 +       volatile unsigned int mask;     /* Threads that change the MT_EN flag */
35236 +       volatile unsigned short rate;   /* What is the sampling rate? */
35237 +       volatile unsigned short head;   /* sample taker puts samples here */
35238 +       volatile unsigned short tail;   /* packet filler takes samples here */
35239 +       volatile unsigned short count;  /* number of valid samples */
35240 +       volatile unsigned short total;  /* Total samples */
35241 +       struct profile_sample samples[IPPROFILETIO_MAX_SAMPLES];
35242 +};
35243 +
35244 +#endif
35245 --- /dev/null
35246 +++ b/arch/ubicom32/oprofile/Makefile
35247 @@ -0,0 +1,37 @@
35248 +#
35249 +# arch/ubicom32/Makefile
35250 +#       Makefile for Oprofile support on Ubicom32
35251 +#
35252 +# (C) Copyright 2009, Ubicom, Inc.
35253 +#
35254 +# This file is part of the Ubicom32 Linux Kernel Port.
35255 +#
35256 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
35257 +# it and/or modify it under the terms of the GNU General Public License
35258 +# as published by the Free Software Foundation, either version 2 of the
35259 +# License, or (at your option) any later version.
35260 +#
35261 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
35262 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
35263 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35264 +# the GNU General Public License for more details.
35265 +#
35266 +# You should have received a copy of the GNU General Public License
35267 +# along with the Ubicom32 Linux Kernel Port.  If not,
35268 +# see <http://www.gnu.org/licenses/>.
35269 +#
35270 +# Ubicom32 implementation derived from (with many thanks):
35271 +#   arch/m68knommu
35272 +#   arch/blackfin
35273 +#   arch/parisc
35274 +#
35275 +
35276 +obj-$(CONFIG_OPROFILE) += oprofile.o
35277 +
35278 +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
35279 +               oprof.o cpu_buffer.o buffer_sync.o \
35280 +               event_buffer.o oprofile_files.o \
35281 +               oprofilefs.o oprofile_stats.o \
35282 +               timer_int.o )
35283 +
35284 +oprofile-y     := $(DRIVER_OBJS) profile.o
35285 --- /dev/null
35286 +++ b/arch/ubicom32/oprofile/profile.c
35287 @@ -0,0 +1,221 @@
35288 +/*
35289 + * arch/ubicom32/oprofile/profile.c
35290 + *     Oprofile support for arch Ubicom32
35291 + *
35292 + * (C) Copyright 2009, Ubicom, Inc.
35293 + *
35294 + * This file is part of the Ubicom32 Linux Kernel Port.
35295 + *
35296 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35297 + * it and/or modify it under the terms of the GNU General Public License
35298 + * as published by the Free Software Foundation, either version 2 of the
35299 + * License, or (at your option)
35300 + * any later version.
35301 + *
35302 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it will
35303 + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
35304 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35305 + * General Public License for more details.
35306 + *
35307 + * You should have received a copy of the GNU General Public License
35308 + * along with the Ubicom32 Linux Kernel Port.  If not, see
35309 + * <http://www.gnu.org/licenses/>.
35310 + *
35311 + * Ubicom32 implementation derived from (with many thanks):
35312 + *   arch/m68knommu
35313 + *   arch/blackfin
35314 + *   arch/parisc
35315 + */
35316 +
35317 +/**
35318 + * @file profile.c
35319 + *
35320 + * @remark Copyright 2002 OProfile authors
35321 + * @remark Read the file COPYING
35322 + *
35323 + * @author Hunyue Yau <hy@hy-research.com>
35324 + */
35325 +
35326 +#include <linux/oprofile.h>
35327 +#include <linux/init.h>
35328 +#include <linux/errno.h>
35329 +#include <linux/interrupt.h>
35330 +#include <linux/module.h>
35331 +#include <linux/kernel.h>
35332 +
35333 +#include <asm/devtree.h>
35334 +#include <asm/thread.h>
35335 +
35336 +/* For identifying userland vs kernel address */
35337 +#include <asm/stacktrace.h>
35338 +#include "ipProf.h"
35339 +
35340 +/* For communications with the backend */
35341 +static struct profilenode *profile_node;
35342 +
35343 +/* Bitmask containing all Linux threads - as seen by the ROSR reg */
35344 +static unsigned long th_all_mask;
35345 +
35346 +/* Lookup table to translate a hardware thread into a CPU identifier
35347 + * Table is indexed by the ROSR value which is assumed to be
35348 + * relatively small (0...15).
35349 + */
35350 +unsigned int cpu_map[THREAD_ARCHITECTURAL_MAX];
35351 +
35352 +static struct pt_regs regs;
35353 +
35354 +/*
35355 + * For each sample returned, checked to see if they are relevant to
35356 + * us. This is necessary as the ubicom32 architecture has other software
35357 + * running outside of Linux. Only then, put the sample into the relevant
35358 + * cpu bins.
35359 + *
35360 + * To minimize overhead, a global mask with all possible threads of in
35361 + * interest to us is used as a first check. Then a second mask identifying
35362 + * the thread is used to obtain an identifier for that "CPU".
35363 + */
35364 +
35365 +/*
35366 + * ubicom32_build_cpu_th_mask()
35367 + *
35368 + * Build a lookup table for translation between hardware thread
35369 + * "ROSR" values and Linux CPU ids
35370 + *
35371 + * *** This gets executed on all CPUs at once! ***
35372 + */
35373 +static void ubicom32_build_cpu_th_mask(void *mask)
35374 +{
35375 +       thread_t self = thread_get_self();
35376 +       unsigned long *th_m = mask;
35377 +
35378 +       BUG_ON(self <= 0 || self >= THREAD_ARCHITECTURAL_MAX);
35379 +       cpu_map[self] = smp_processor_id();
35380 +
35381 +       set_bit(self, th_m);
35382 +}
35383 +
35384 +/*
35385 + * profile_interrupt()
35386 + *
35387 + * Process samples returned from the profiler backend. The backend
35388 + * may return samples that are irrelevant to us or may even return
35389 + * multiple samples for the same CPU. Note that the sames may be
35390 + * for ANY cpu. At this time, this is unique and to support this requires
35391 + * Oprofile to expose an interface to accept the CPU that the same came
35392 + * frome.
35393 + */
35394 +static irqreturn_t profile_interrupt(int irq, void *arg)
35395 +{
35396 +       int i, buf_entry;
35397 +       int is_kernel;
35398 +       unsigned int bit_th;
35399 +       unsigned int th;
35400 +
35401 +       if (!(profile_node->enabled) || profile_node->count < 0) {
35402 +               printk(KERN_WARNING
35403 +                       "Unexpected interrupt, no samples or not enabled!\n");
35404 +               return IRQ_HANDLED;
35405 +       }
35406 +
35407 +       profile_node->busy = 1;         /* Keep backend out */
35408 +
35409 +       for (i = 0; i < profile_node->count; i++) {
35410 +               buf_entry = profile_node->tail;
35411 +               profile_node->tail++;
35412 +               profile_node->tail %= IPPROFILETIO_MAX_SAMPLES;
35413 +
35414 +               /* Note - the "thread" ID is only the lower 4 bits */
35415 +               th = (0x0f & profile_node->samples[buf_entry].thread);
35416 +               bit_th = (1 << th);
35417 +
35418 +               if ((bit_th & th_all_mask) == 0)
35419 +                       continue;
35420 +
35421 +               regs.pc = profile_node->samples[buf_entry].pc;
35422 +
35423 +               is_kernel = ubicom32_is_kernel(regs.pc);
35424 +
35425 +               oprofile_add_ext_sample_cpu(regs.pc, &regs, 0, is_kernel,
35426 +                                           cpu_map[th]);
35427 +       }
35428 +       profile_node->count = 0;
35429 +       profile_node->busy = 0;
35430 +
35431 +       return IRQ_HANDLED;
35432 +}
35433 +
35434 +/*
35435 + * profile_start()
35436 + *
35437 + * Notification from oprofile to start the profiler
35438 + */
35439 +static int profile_start(void)
35440 +{
35441 +       if (!profile_node)
35442 +               return -1;
35443 +
35444 +       profile_node->enabled = 1;
35445 +
35446 +       return 0;
35447 +}
35448 +
35449 +/*
35450 + * profile_stop()
35451 + *
35452 + * Notification from oprofile to stop the profiler
35453 + */
35454 +static void profile_stop(void)
35455 +{
35456 +       if (profile_node)
35457 +               profile_node->enabled = 0;
35458 +}
35459 +
35460 +/*
35461 + * oprofile_arch_init()
35462 + *
35463 + * Attach to Oprofile after qualify the availability of the backend
35464 + * profiler support.
35465 + */
35466 +int __init oprofile_arch_init(struct oprofile_operations *ops)
35467 +{
35468 +       int r = -ENODEV;
35469 +
35470 +       profile_node = (struct profilenode *)devtree_find_node("profiler");
35471 +
35472 +       if (profile_node == NULL) {
35473 +               printk(KERN_WARNING "Cannot find profiler node\n");
35474 +               return r;
35475 +       }
35476 +
35477 +       r = request_irq(profile_node->dn.recvirq, profile_interrupt,
35478 +                       IRQF_DISABLED, "profiler", NULL);
35479 +
35480 +       if (r < 0) {
35481 +               profile_node = NULL;
35482 +               printk(KERN_WARNING "Cannot get profiler IRQ\n");
35483 +               return r;
35484 +       }
35485 +
35486 +       ops->start = profile_start;
35487 +       ops->stop = profile_stop;
35488 +       ops->cpu_type = "timer";
35489 +
35490 +       memset(cpu_map, 0, sizeof(cpu_map));
35491 +
35492 +       on_each_cpu(ubicom32_build_cpu_th_mask, &th_all_mask, 1);
35493 +
35494 +       memset(&regs, 0, sizeof(regs));
35495 +
35496 +       return r;
35497 +}
35498 +
35499 +/*
35500 + * oprofile_arch_exit()
35501 + *
35502 + * External call to take outselves out.
35503 + * Make sure backend is not running.
35504 + */
35505 +void oprofile_arch_exit(void)
35506 +{
35507 +       BUG_ON(profile_node->enabled);
35508 +}
35509 --- a/drivers/char/hw_random/Kconfig
35510 +++ b/drivers/char/hw_random/Kconfig
35511 @@ -134,3 +134,16 @@ config HW_RANDOM_VIRTIO
35512  
35513           To compile this driver as a module, choose M here: the
35514           module will be called virtio-rng.  If unsure, say N.
35515 +
35516 +config HW_RANDOM_UBICOM32
35517 +       tristate "Ubicom32 HW Random Number Generator support"
35518 +       depends on HW_RANDOM && UBICOM32
35519 +       default HW_RANDOM
35520 +       ---help---
35521 +         This driver provides kernel-side support for the Random Number
35522 +         Generator hardware found on Ubicom32 processors.
35523 +
35524 +         To compile this driver as a module, choose M here: the
35525 +         module will be called pasemi-rng.
35526 +
35527 +         If unsure, say Y.
35528 --- a/drivers/char/hw_random/Makefile
35529 +++ b/drivers/char/hw_random/Makefile
35530 @@ -14,3 +14,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx
35531  obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
35532  obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
35533  obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
35534 +obj-$(CONFIG_HW_RANDOM_UBICOM32) += ubicom32-rng.o
35535 --- /dev/null
35536 +++ b/drivers/char/hw_random/ubicom32-rng.c
35537 @@ -0,0 +1,105 @@
35538 +/*
35539 + * drivers/net/ubi32-eth.c
35540 + *   Ubicom32 hardware random number generator driver.
35541 + *
35542 + * (C) Copyright 2009, Ubicom, Inc.
35543 + *
35544 + * This file is part of the Ubicom32 Linux Kernel Port.
35545 + *
35546 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35547 + * it and/or modify it under the terms of the GNU General Public License
35548 + * as published by the Free Software Foundation, either version 2 of the
35549 + * License, or (at your option) any later version.
35550 + *
35551 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
35552 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
35553 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35554 + * the GNU General Public License for more details.
35555 + *
35556 + * You should have received a copy of the GNU General Public License
35557 + * along with the Ubicom32 Linux Kernel Port.  If not,
35558 + * see <http://www.gnu.org/licenses/>.
35559 + *
35560 + * Ubicom32 implementation derived from (with many thanks):
35561 + *   arch/m68knommu
35562 + *   arch/blackfin
35563 + *   arch/parisc
35564 + */
35565 +
35566 +#include <linux/kernel.h>
35567 +#include <linux/module.h>
35568 +#include <linux/hw_random.h>
35569 +#include <linux/delay.h>
35570 +#include <asm/io.h>
35571 +#include <asm/ip5000.h>
35572 +
35573 +#define MODULE_NAME "ubicom32_rng"
35574 +
35575 +static int ubicom32_rng_data_present(struct hwrng *rng, int wait)
35576 +{
35577 +       int data, i;
35578 +
35579 +       for (i = 0; i < 20; i++) {
35580 +               data = *(int *)(TIMER_BASE + TIMER_TRN);
35581 +               if (data || !wait)
35582 +                       break;
35583 +               udelay(10);
35584 +       }
35585 +       return data;
35586 +}
35587 +
35588 +static int ubicom32_rng_data_read(struct hwrng *rng, u32 *data)
35589 +{
35590 +       *data = *(int *)(TIMER_BASE + TIMER_TRN);
35591 +       return 4;
35592 +}
35593 +
35594 +static int ubicom32_rng_init(struct hwrng *rng)
35595 +{
35596 +       printk(KERN_INFO "ubicom32 rng init\n");
35597 +       *(int *)(TIMER_BASE + TIMER_TRN_CFG) = TIMER_TRN_CFG_ENABLE_OSC;
35598 +       return 0;
35599 +}
35600 +
35601 +static void ubicom32_rng_cleanup(struct hwrng *rng)
35602 +{
35603 +       printk(KERN_INFO "ubicom32 rng cleanup\n");
35604 +       *(int *)(TIMER_BASE + TIMER_TRN_CFG) = 0;
35605 +}
35606 +
35607 +static struct hwrng ubicom32_rng = {
35608 +       .name           = MODULE_NAME,
35609 +       .init           = ubicom32_rng_init,
35610 +       .cleanup        = ubicom32_rng_cleanup,
35611 +       .data_present   = ubicom32_rng_data_present,
35612 +       .data_read      = ubicom32_rng_data_read,
35613 +       .priv           = 0,
35614 +};
35615 +
35616 +static int __init mod_init(void)
35617 +{
35618 +       int err;
35619 +
35620 +       printk(KERN_INFO "ubicom32 rng started\n");
35621 +       err = hwrng_register(&ubicom32_rng);
35622 +       if (err) {
35623 +               printk(KERN_ERR "ubicom32 rng register failed (%d)\n",
35624 +                       err);
35625 +       }
35626 +
35627 +       return err;
35628 +}
35629 +
35630 +static void __exit mod_exit(void)
35631 +{
35632 +       printk(KERN_INFO "ubicom32 rng stopped\n");
35633 +       hwrng_unregister(&ubicom32_rng);
35634 +}
35635 +
35636 +module_init(mod_init);
35637 +module_exit(mod_exit);
35638 +
35639 +MODULE_LICENSE("GPL");
35640 +MODULE_AUTHOR("Ubicom, Inc.");
35641 +MODULE_DESCRIPTION("H/W rng driver for ubicom32 processor");
35642 +MODULE_VERSION("1:1.0.a");
35643 --- a/drivers/crypto/Kconfig
35644 +++ b/drivers/crypto/Kconfig
35645 @@ -61,6 +61,40 @@ config CRYPTO_DEV_GEODE
35646           To compile this driver as a module, choose M here: the module
35647           will be called geode-aes.
35648  
35649 +config CRYPTO_UBICOM32
35650 +        bool "Ubicom32 Security Module"
35651 +        depends on UBICOM32
35652 +        help
35653 +          This is the ubicom32 hardware acceleration common code.
35654 +
35655 +config CRYPTO_AES_UBICOM32
35656 +        tristate "Ubicom32 AES implementation"
35657 +        depends on CRYPTO_UBICOM32
35658 +        select CRYPTO_ALGAPI
35659 +        help
35660 +          This is the ubicom32 hardware AES implementation.
35661 +
35662 +config CRYPTO_DES_UBICOM32
35663 +        tristate "Ubicom32 DES implementation"
35664 +        depends on CRYPTO_UBICOM32
35665 +        select CRYPTO_ALGAPI
35666 +        help
35667 +          This is the ubicom32 hardware DES and 3DES implementation.
35668 +
35669 +config CRYPTO_SHA1_UBICOM32
35670 +        tristate "Ubicom32 SHA1 implementation"
35671 +        depends on CRYPTO_UBICOM32
35672 +        select CRYPTO_ALGAPI
35673 +        help
35674 +          This is the ubicom32 hardware SHA1 implementation.
35675 +
35676 +config CRYPTO_MD5_UBICOM32
35677 +        tristate "Ubicom32 MD5 implementation"
35678 +        depends on CRYPTO_UBICOM32
35679 +        select CRYPTO_ALGAPI
35680 +        help
35681 +          This is the ubicom32 hardware MD5 implementation.
35682 +
35683  config ZCRYPT
35684         tristate "Support for PCI-attached cryptographic adapters"
35685         depends on S390
35686 --- a/drivers/mmc/host/Kconfig
35687 +++ b/drivers/mmc/host/Kconfig
35688 @@ -193,6 +193,13 @@ config MMC_TMIO
35689           This provides support for the SD/MMC cell found in TC6393XB,
35690           T7L66XB and also ipaq ASIC3
35691  
35692 +config MMC_UBICOM32
35693 +       tristate "Ubicom32 MMC/SD host controller"
35694 +       depends on UBICOM32
35695 +       help
35696 +         This provides support for the SD/MMC hardware found on Ubicom32 
35697 +         IP7K processors
35698 +
35699  config GPIOMMC
35700         tristate "MMC/SD over GPIO-based SPI"
35701         depends on MMC && MMC_SPI && (SPI_GPIO || SPI_GPIO_OLD)
35702 --- a/drivers/mmc/host/Makefile
35703 +++ b/drivers/mmc/host/Makefile
35704 @@ -22,5 +22,6 @@ obj-$(CONFIG_MMC_SPI)         += mmc_spi.o
35705  obj-$(CONFIG_MMC_S3C)          += s3cmci.o
35706  obj-$(CONFIG_MMC_SDRICOH_CS)   += sdricoh_cs.o
35707  obj-$(CONFIG_MMC_TMIO)         += tmio_mmc.o
35708 +obj-$(CONFIG_MMC_UBICOM32)     += ubicom32sd.o
35709  obj-$(CONFIG_GPIOMMC)          += gpiommc.o
35710  
35711 --- /dev/null
35712 +++ b/drivers/mmc/host/ubicom32sd.c
35713 @@ -0,0 +1,774 @@
35714 +/*
35715 + * drivers/mmc/host/ubicom32sd.c
35716 + *     Ubicom32 Secure Digital Host Controller Interface driver
35717 + *
35718 + * (C) Copyright 2009, Ubicom, Inc.
35719 + *
35720 + * This file is part of the Ubicom32 Linux Kernel Port.
35721 + *
35722 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35723 + * it and/or modify it under the terms of the GNU General Public License
35724 + * as published by the Free Software Foundation, either version 2 of the
35725 + * License, or (at your option) any later version.
35726 + *
35727 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
35728 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
35729 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35730 + * the GNU General Public License for more details.
35731 + *
35732 + * You should have received a copy of the GNU General Public License
35733 + * along with the Ubicom32 Linux Kernel Port.  If not, 
35734 + * see <http://www.gnu.org/licenses/>.
35735 + */
35736 +
35737 +#include <linux/module.h>
35738 +#include <linux/platform_device.h>
35739 +#include <linux/delay.h>
35740 +#include <linux/scatterlist.h>
35741 +#include <linux/leds.h>
35742 +#include <linux/gpio.h>
35743 +#include <linux/mmc/host.h>
35744 +
35745 +#include <asm/ubicom32sd.h>
35746 +
35747 +#define DRIVER_NAME "ubicom32sd"
35748 +
35749 +#define sd_printk(...)
35750 +//#define sd_printk printk
35751 +
35752 +#define SDTIO_VP_VERSION       3
35753 +
35754 +#define SDTIO_MAX_SG_BLOCKS    16
35755 +
35756 +enum sdtio_commands {
35757 +       SDTIO_COMMAND_NOP,
35758 +       SDTIO_COMMAND_SETUP,
35759 +       SDTIO_COMMAND_SETUP_SDIO,
35760 +       SDTIO_COMMAND_EXECUTE,
35761 +       SDTIO_COMMAND_RESET,
35762 +};
35763 +
35764 +#define SDTIO_COMMAND_SHIFT                    24
35765 +#define SDTIO_COMMAND_FLAG_STOP_RSP_CRC                (1 << 10)
35766 +#define SDTIO_COMMAND_FLAG_STOP_RSP_136                (1 << 9)
35767 +#define SDTIO_COMMAND_FLAG_STOP_RSP            (1 << 8)
35768 +#define SDTIO_COMMAND_FLAG_STOP_CMD            (1 << 7)
35769 +#define SDTIO_COMMAND_FLAG_DATA_STREAM         (1 << 6)
35770 +#define SDTIO_COMMAND_FLAG_DATA_RD             (1 << 5)
35771 +#define SDTIO_COMMAND_FLAG_DATA_WR             (1 << 4)
35772 +#define SDTIO_COMMAND_FLAG_CMD_RSP_CRC         (1 << 3)
35773 +#define SDTIO_COMMAND_FLAG_CMD_RSP_136         (1 << 2)
35774 +#define SDTIO_COMMAND_FLAG_CMD_RSP             (1 << 1)
35775 +#define SDTIO_COMMAND_FLAG_CMD                 (1 << 0)
35776 +
35777 +/*
35778 + * SDTIO_COMMAND_SETUP_SDIO
35779 + */
35780 +#define SDTIO_COMMAND_FLAG_SDIO_INT_EN         (1 << 0)
35781 +
35782 +/*
35783 + * SDTIO_COMMAND_SETUP
35784 + *      clock speed in arg
35785 + */
35786 +#define SDTIO_COMMAND_FLAG_4BIT                 (1 << 3)
35787 +#define SDTIO_COMMAND_FLAG_1BIT                 (1 << 2)
35788 +#define SDTIO_COMMAND_FLAG_SET_CLOCK            (1 << 1)
35789 +#define SDTIO_COMMAND_FLAG_SET_WIDTH            (1 << 0)
35790 +
35791 +#define SDTIO_COMMAND_FLAG_CMD_RSP_MASK                (SDTIO_COMMAND_FLAG_CMD_RSP | SDTIO_COMMAND_FLAG_CMD_RSP_136)
35792 +#define SDTIO_COMMAND_FLAG_STOP_RSP_MASK       (SDTIO_COMMAND_FLAG_STOP_RSP | SDTIO_COMMAND_FLAG_STOP_RSP_136)
35793 +#define SDTIO_COMMAND_FLAG_RSP_MASK            (SDTIO_COMMAND_FLAG_CMD_RSP_MASK | SDTIO_COMMAND_FLAG_STOP_RSP_MASK)
35794 +
35795 +struct sdtio_vp_sg {
35796 +       volatile void           *addr;
35797 +       volatile u32_t          len;
35798 +};
35799 +
35800 +#define SDTIO_VP_INT_STATUS_DONE               (1 << 31)
35801 +#define SDTIO_VP_INT_STATUS_SDIO_INT           (1 << 10)
35802 +#define SDTIO_VP_INT_STATUS_DATA_CRC_ERR       (1 << 9)
35803 +#define SDTIO_VP_INT_STATUS_DATA_PROG_ERR      (1 << 8)
35804 +#define SDTIO_VP_INT_STATUS_DATA_TIMEOUT       (1 << 7)
35805 +#define SDTIO_VP_INT_STATUS_STOP_RSP_CRC       (1 << 6)
35806 +#define SDTIO_VP_INT_STATUS_STOP_RSP_TIMEOUT   (1 << 5)
35807 +#define SDTIO_VP_INT_STATUS_CMD_RSP_CRC                (1 << 4)
35808 +#define SDTIO_VP_INT_STATUS_CMD_RSP_TIMEOUT    (1 << 3)
35809 +#define SDTIO_VP_INT_STATUS_CMD_TIMEOUT                (1 << 2)
35810 +#define SDTIO_VP_INT_STATUS_CARD1_INSERT       (1 << 1)
35811 +#define SDTIO_VP_INT_STATUS_CARD0_INSERT       (1 << 0)
35812 +
35813 +struct sdtio_vp_regs {
35814 +       u32_t                           version;
35815 +       u32_t                           f_max;
35816 +       u32_t                           f_min;
35817 +
35818 +       volatile u32_t                  int_status;
35819 +
35820 +       volatile u32_t                  command;
35821 +       volatile u32_t                  arg;
35822 +
35823 +       volatile u32_t                  cmd_opcode;
35824 +       volatile u32_t                  cmd_arg;
35825 +       volatile u32_t                  cmd_rsp0;
35826 +       volatile u32_t                  cmd_rsp1;
35827 +       volatile u32_t                  cmd_rsp2;
35828 +       volatile u32_t                  cmd_rsp3;
35829 +
35830 +       volatile u32_t                  stop_opcode;
35831 +       volatile u32_t                  stop_arg;
35832 +       volatile u32_t                  stop_rsp0;
35833 +       volatile u32_t                  stop_rsp1;
35834 +       volatile u32_t                  stop_rsp2;
35835 +       volatile u32_t                  stop_rsp3;
35836 +
35837 +       volatile u32_t                  data_timeout_ns;
35838 +       volatile u16_t                  data_blksz;
35839 +       volatile u16_t                  data_blkct;
35840 +       volatile u32_t                  data_bytes_transferred;
35841 +       volatile u32_t                  sg_len;
35842 +       struct sdtio_vp_sg              sg[SDTIO_MAX_SG_BLOCKS];
35843 +};
35844 +
35845 +struct ubicom32sd_data {
35846 +       const struct ubicom32sd_platform_data   *pdata;
35847 +
35848 +       struct mmc_host                         *mmc;
35849 +
35850 +       /*
35851 +        * Lock used to protect the data structure
35852 +       spinlock_t                              lock;
35853 +        */
35854 +       int     int_en;
35855 +       int     int_pend;
35856 +
35857 +       /*
35858 +        * Receive and transmit interrupts used for communicating 
35859 +        * with hardware
35860 +        */
35861 +       int                                     irq_tx;
35862 +       int                                     irq_rx;
35863 +
35864 +       /*
35865 +        * Current outstanding mmc request
35866 +        */
35867 +       struct mmc_request                      *mrq;
35868 +
35869 +       /*
35870 +        * Hardware registers
35871 +        */
35872 +       struct sdtio_vp_regs                    *regs;
35873 +};
35874 +
35875 +/*****************************************************************************\
35876 + *                                                                           *
35877 + * Suspend/resume                                                            *
35878 + *                                                                           *
35879 +\*****************************************************************************/
35880 +
35881 +#if 0//def CONFIG_PM
35882 +
35883 +int ubicom32sd_suspend_host(struct ubicom32sd_host *host, pm_message_t state)
35884 +{
35885 +       int ret;
35886 +
35887 +       ret = mmc_suspend_host(host->mmc, state);
35888 +       if (ret)
35889 +               return ret;
35890 +
35891 +       free_irq(host->irq, host);
35892 +
35893 +       return 0;
35894 +}
35895 +
35896 +EXPORT_SYMBOL_GPL(ubicom32sd_suspend_host);
35897 +
35898 +int ubicom32sd_resume_host(struct ubicom32sd_host *host)
35899 +{
35900 +       int ret;
35901 +
35902 +       if (host->flags & UBICOM32SD_USE_DMA) {
35903 +               if (host->ops->enable_dma)
35904 +                       host->ops->enable_dma(host);
35905 +       }
35906 +
35907 +       ret = request_irq(host->irq, ubicom32sd_irq, IRQF_SHARED,
35908 +                         mmc_hostname(host->mmc), host);
35909 +       if (ret)
35910 +               return ret;
35911 +
35912 +       ubicom32sd_init(host);
35913 +       mmiowb();
35914 +
35915 +       ret = mmc_resume_host(host->mmc);
35916 +       if (ret)
35917 +               return ret;
35918 +
35919 +       return 0;
35920 +}
35921 +
35922 +EXPORT_SYMBOL_GPL(ubicom32sd_resume_host);
35923 +
35924 +#endif /* CONFIG_PM */
35925 +
35926 +/*
35927 + * ubicom32sd_send_command_sync
35928 + */
35929 +static void ubicom32sd_send_command_sync(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
35930 +{
35931 +       ud->regs->command = command;
35932 +       ud->regs->arg = arg;
35933 +       ubicom32_set_interrupt(ud->irq_tx);
35934 +       while (ud->regs->command) {
35935 +               ndelay(100);
35936 +       }
35937 +}
35938 +
35939 +/*
35940 + * ubicom32sd_send_command
35941 + */
35942 +static void ubicom32sd_send_command(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
35943 +{
35944 +       ud->regs->command = command;
35945 +       ud->regs->arg = arg;
35946 +       ubicom32_set_interrupt(ud->irq_tx);
35947 +}
35948 +
35949 +/*
35950 + * ubicom32sd_reset
35951 + */
35952 +static void ubicom32sd_reset(struct ubicom32sd_data *ud)
35953 +{
35954 +       ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_RESET << SDTIO_COMMAND_SHIFT, 0);
35955 +       ud->regs->int_status = 0;
35956 +}
35957 +
35958 +/*
35959 + * ubicom32sd_mmc_request
35960 + */
35961 +static void ubicom32sd_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
35962 +{
35963 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
35964 +       u32_t command = SDTIO_COMMAND_EXECUTE << SDTIO_COMMAND_SHIFT;
35965 +       int ret = 0;
35966 +
35967 +       WARN(ud->mrq != NULL, "ud->mrq still set to %p\n", ud->mrq);
35968 +       //pr_debug("send cmd %08x arg %08x flags %08x\n", cmd->opcode, cmd->arg, cmd->flags);
35969 +
35970 +       if (mrq->cmd) {
35971 +               struct mmc_command *cmd = mrq->cmd;
35972 +
35973 +               sd_printk("%s:\t\t\tsetup cmd %02d arg %08x flags %08x\n", mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags);
35974 +
35975 +               ud->regs->cmd_opcode = cmd->opcode;
35976 +               ud->regs->cmd_arg = cmd->arg;
35977 +
35978 +               command |= SDTIO_COMMAND_FLAG_CMD;
35979 +
35980 +               if (cmd->flags & MMC_RSP_PRESENT) {
35981 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP;
35982 +               }
35983 +
35984 +               if (cmd->flags & MMC_RSP_136) {
35985 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP_136;
35986 +               }
35987 +
35988 +               if (cmd->flags & MMC_RSP_CRC) {
35989 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP_CRC;
35990 +               }
35991 +       }
35992 +
35993 +       if (mrq->data) {
35994 +               struct mmc_data *data = mrq->data;
35995 +               struct scatterlist *sg = data->sg;
35996 +               int i;
35997 +
35998 +printk("%s:\t\t\tsetup data blksz %d num %d sglen=%d fl=%08x Tns=%u\n", mmc_hostname(mmc), data->blksz, data->blocks, data->sg_len, data->flags, data->timeout_ns);
35999 +
36000 +               sd_printk("%s:\t\t\tsetup data blksz %d num %d sglen=%d fl=%08x Tns=%u\n", 
36001 +                         mmc_hostname(mmc), data->blksz, data->blocks, data->sg_len, 
36002 +                         data->flags, data->timeout_ns);
36003 +
36004 +               if (data->sg_len > SDTIO_MAX_SG_BLOCKS) {
36005 +                       ret = -EINVAL;
36006 +                       data->error = -EINVAL;
36007 +                       goto fail;
36008 +               } 
36009 +
36010 +               ud->regs->data_timeout_ns = data->timeout_ns;
36011 +               ud->regs->data_blksz = data->blksz;
36012 +               ud->regs->data_blkct = data->blocks;
36013 +               ud->regs->sg_len = data->sg_len;
36014 +
36015 +               /*
36016 +                * Load all of our sg list into the driver sg buffer
36017 +                */
36018 +               for (i = 0; i < data->sg_len; i++) {
36019 +                       sd_printk("%s: sg %d = %p %d\n", mmc_hostname(mmc), i, sg_virt(sg), sg->length);
36020 +                       ud->regs->sg[i].addr = sg_virt(sg);
36021 +                       ud->regs->sg[i].len = sg->length;
36022 +                       if (((u32_t)ud->regs->sg[i].addr & 0x03) || (sg->length & 0x03)) {
36023 +                               sd_printk("%s: Need aligned buffers\n", mmc_hostname(mmc));
36024 +                               ret = -EINVAL;
36025 +                               data->error = -EINVAL;
36026 +                               goto fail;
36027 +                       }
36028 +                       sg++;
36029 +               }
36030 +               if (data->flags & MMC_DATA_READ) {
36031 +                       command |= SDTIO_COMMAND_FLAG_DATA_RD;
36032 +               } else if (data->flags & MMC_DATA_WRITE) {
36033 +                       command |= SDTIO_COMMAND_FLAG_DATA_WR;
36034 +               } else if (data->flags & MMC_DATA_STREAM) {
36035 +                       command |= SDTIO_COMMAND_FLAG_DATA_STREAM;
36036 +               }
36037 +       }
36038 +
36039 +       if (mrq->stop) {
36040 +               struct mmc_command *stop = mrq->stop;
36041 +               sd_printk("%s: \t\t\tsetup stop %02d arg %08x flags %08x\n", mmc_hostname(mmc), stop->opcode, stop->arg, stop->flags);
36042 +
36043 +               ud->regs->stop_opcode = stop->opcode;
36044 +               ud->regs->stop_arg = stop->arg;
36045 +
36046 +               command |= SDTIO_COMMAND_FLAG_STOP_CMD;
36047 +
36048 +               if (stop->flags & MMC_RSP_PRESENT) {
36049 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP;
36050 +               }
36051 +
36052 +               if (stop->flags & MMC_RSP_136) {
36053 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP_136;
36054 +               }
36055 +
36056 +               if (stop->flags & MMC_RSP_CRC) {
36057 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP_CRC;
36058 +               }
36059 +       }
36060 +
36061 +       ud->mrq = mrq;
36062 +
36063 +       sd_printk("%s: Sending command %08x\n", mmc_hostname(mmc), command);
36064 +
36065 +       ubicom32sd_send_command(ud, command, 0);
36066 +
36067 +       return;
36068 +fail:
36069 +       sd_printk("%s: mmcreq ret = %d\n", mmc_hostname(mmc), ret);
36070 +       mrq->cmd->error = ret;
36071 +       mmc_request_done(mmc, mrq);
36072 +}
36073 +
36074 +/*
36075 + * ubicom32sd_mmc_set_ios
36076 + */
36077 +static void ubicom32sd_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
36078 +{
36079 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36080 +       u32_t command = SDTIO_COMMAND_SETUP << SDTIO_COMMAND_SHIFT;
36081 +       u32_t arg = 0;
36082 +       sd_printk("%s: ios call bw:%u pm:%u clk:%u\n", mmc_hostname(mmc), 1 << ios->bus_width, ios->power_mode, ios->clock);
36083 +
36084 +       switch (ios->bus_width) {
36085 +       case MMC_BUS_WIDTH_1:
36086 +               command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_1BIT;
36087 +               break;
36088 +
36089 +       case MMC_BUS_WIDTH_4:
36090 +               command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_4BIT;
36091 +               break;
36092 +       }
36093 +
36094 +       if (ios->clock) {
36095 +               arg = ios->clock;
36096 +               command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
36097 +       }
36098 +
36099 +       switch (ios->power_mode) {
36100 +
36101 +       /*
36102 +        * Turn off the SD bus (power + clock)
36103 +        */
36104 +       case MMC_POWER_OFF:
36105 +               gpio_set_value(ud->pdata->cards[0].pin_pwr, !ud->pdata->cards[0].pwr_polarity);
36106 +               command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
36107 +               break;
36108 +
36109 +       /*
36110 +        * Turn on the power to the SD bus
36111 +        */
36112 +       case MMC_POWER_ON:
36113 +               gpio_set_value(ud->pdata->cards[0].pin_pwr, ud->pdata->cards[0].pwr_polarity);
36114 +               break;
36115 +
36116 +       /*
36117 +        * Turn on the clock to the SD bus
36118 +        */
36119 +       case MMC_POWER_UP:
36120 +               /*
36121 +                * Done above
36122 +                */
36123 +               break;
36124 +       }
36125 +
36126 +       ubicom32sd_send_command_sync(ud, command, arg);
36127 +
36128 +       /*
36129 +        * Let the power settle down
36130 +        */
36131 +       udelay(500);
36132 +}
36133 +
36134 +/*
36135 + * ubicom32sd_mmc_get_cd
36136 + */
36137 +static int ubicom32sd_mmc_get_cd(struct mmc_host *mmc)
36138 +{
36139 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36140 +       sd_printk("%s: get cd %u %u\n", mmc_hostname(mmc), ud->pdata->cards[0].pin_cd, gpio_get_value(ud->pdata->cards[0].pin_cd));
36141 +
36142 +       return gpio_get_value(ud->pdata->cards[0].pin_cd) ? 
36143 +                               ud->pdata->cards[0].cd_polarity : 
36144 +                               !ud->pdata->cards[0].cd_polarity;
36145 +}
36146 +
36147 +/*
36148 + * ubicom32sd_mmc_get_ro
36149 + */
36150 +static int ubicom32sd_mmc_get_ro(struct mmc_host *mmc)
36151 +{
36152 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36153 +       sd_printk("%s: get ro %u %u\n", mmc_hostname(mmc), ud->pdata->cards[0].pin_wp, gpio_get_value(ud->pdata->cards[0].pin_wp));
36154 +
36155 +       return gpio_get_value(ud->pdata->cards[0].pin_wp) ? 
36156 +                               ud->pdata->cards[0].wp_polarity :
36157 +                               !ud->pdata->cards[0].wp_polarity;
36158 +}
36159 +
36160 +/*
36161 + * ubicom32sd_mmc_enable_sdio_irq
36162 + */
36163 +static void ubicom32sd_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
36164 +{
36165 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36166 +
36167 +       ud->int_en = enable;
36168 +       if (enable && ud->int_pend) {
36169 +               ud->int_pend = 0;
36170 +               mmc_signal_sdio_irq(mmc);
36171 +       }
36172 +}
36173 +
36174 +/*
36175 + * ubicom32sd_interrupt
36176 + */
36177 +static irqreturn_t ubicom32sd_interrupt(int irq, void *dev)
36178 +{
36179 +       struct mmc_host *mmc = (struct mmc_host *)dev;
36180 +       struct mmc_request *mrq;
36181 +       struct ubicom32sd_data *ud;
36182 +       u32_t int_status;
36183 +
36184 +       if (!mmc) {
36185 +               return IRQ_HANDLED;
36186 +       }
36187 +
36188 +       ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36189 +       if (!ud) {
36190 +               return IRQ_HANDLED;
36191 +       }
36192 +
36193 +       int_status = ud->regs->int_status;
36194 +       ud->regs->int_status &= ~int_status;
36195 +
36196 +       if (int_status & SDTIO_VP_INT_STATUS_SDIO_INT) {
36197 +               if (ud->int_en) {
36198 +                       ud->int_pend = 0;
36199 +                       mmc_signal_sdio_irq(mmc);
36200 +               } else {
36201 +                       ud->int_pend++;
36202 +               }
36203 +       }
36204 +
36205 +       if (!(int_status & SDTIO_VP_INT_STATUS_DONE)) {
36206 +               return IRQ_HANDLED;
36207 +       }
36208 +
36209 +       mrq = ud->mrq;
36210 +       if (!mrq) {
36211 +               sd_printk("%s: Spurious interrupt", mmc_hostname(mmc));
36212 +               return IRQ_HANDLED;
36213 +       }
36214 +       ud->mrq = NULL;
36215 +
36216 +       /*
36217 +        * SDTIO_VP_INT_DONE
36218 +        */
36219 +       if (mrq->cmd->flags & MMC_RSP_PRESENT) {
36220 +               struct mmc_command *cmd = mrq->cmd;
36221 +               cmd->error = 0;
36222 +
36223 +               if ((cmd->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_CRC)) {
36224 +                       cmd->error = -EILSEQ;
36225 +               } else if (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_TIMEOUT) {
36226 +                       cmd->error = -ETIMEDOUT;
36227 +                       goto done;
36228 +               } else if (cmd->flags & MMC_RSP_136) {
36229 +                       cmd->resp[0] = ud->regs->cmd_rsp0;
36230 +                       cmd->resp[1] = ud->regs->cmd_rsp1;
36231 +                       cmd->resp[2] = ud->regs->cmd_rsp2;
36232 +                       cmd->resp[3] = ud->regs->cmd_rsp3;
36233 +               } else {
36234 +                       cmd->resp[0] = ud->regs->cmd_rsp0;
36235 +               }
36236 +               sd_printk("%s:\t\t\tResponse %08x %08x %08x %08x err=%d\n", mmc_hostname(mmc), cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
36237 +       }
36238 +
36239 +       if (mrq->data) {
36240 +               struct mmc_data *data = mrq->data;
36241 +
36242 +               if (int_status & SDTIO_VP_INT_STATUS_DATA_TIMEOUT) {
36243 +                       data->error = -ETIMEDOUT;
36244 +                       sd_printk("%s:\t\t\tData Timeout\n", mmc_hostname(mmc));
36245 +                       goto done;
36246 +               } else if (int_status & SDTIO_VP_INT_STATUS_DATA_CRC_ERR) {
36247 +                       data->error = -EILSEQ;
36248 +                       sd_printk("%s:\t\t\tData CRC\n", mmc_hostname(mmc));
36249 +                       goto done;
36250 +               } else if (int_status & SDTIO_VP_INT_STATUS_DATA_PROG_ERR) {
36251 +                       data->error = -EILSEQ;
36252 +                       sd_printk("%s:\t\t\tData Program Error\n", mmc_hostname(mmc));
36253 +                       goto done;
36254 +               } else {
36255 +                       data->error = 0;
36256 +                       data->bytes_xfered = ud->regs->data_bytes_transferred;
36257 +               }
36258 +       }
36259 +
36260 +       if (mrq->stop && (mrq->stop->flags & MMC_RSP_PRESENT)) {
36261 +               struct mmc_command *stop = mrq->stop;
36262 +               stop->error = 0;
36263 +
36264 +               if ((stop->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_CRC)) {
36265 +                       stop->error = -EILSEQ;
36266 +               } else if (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_TIMEOUT) {
36267 +                       stop->error = -ETIMEDOUT;
36268 +                       goto done;
36269 +               } else if (stop->flags & MMC_RSP_136) {
36270 +                       stop->resp[0] = ud->regs->stop_rsp0;
36271 +                       stop->resp[1] = ud->regs->stop_rsp1;
36272 +                       stop->resp[2] = ud->regs->stop_rsp2;
36273 +                       stop->resp[3] = ud->regs->stop_rsp3;
36274 +               } else {
36275 +                       stop->resp[0] = ud->regs->stop_rsp0;
36276 +               }
36277 +               sd_printk("%s:\t\t\tStop Response %08x %08x %08x %08x err=%d\n", mmc_hostname(mmc), stop->resp[0], stop->resp[1], stop->resp[2], stop->resp[3], stop->error);
36278 +       }
36279 +
36280 +done:
36281 +       mmc_request_done(mmc, mrq);
36282 +
36283 +       return IRQ_HANDLED;
36284 +}
36285 +
36286 +static struct mmc_host_ops ubicom32sd_ops = {
36287 +       .request                = ubicom32sd_mmc_request,
36288 +       .set_ios                = ubicom32sd_mmc_set_ios,
36289 +       .get_ro                 = ubicom32sd_mmc_get_ro,
36290 +       .get_cd                 = ubicom32sd_mmc_get_cd,
36291 +       .enable_sdio_irq        = ubicom32sd_mmc_enable_sdio_irq,
36292 +};
36293 +
36294 +/*
36295 + * ubicom32sd_probe
36296 + */
36297 +static int __devinit ubicom32sd_probe(struct platform_device *pdev)
36298 +{
36299 +       struct ubicom32sd_platform_data *pdata = (struct ubicom32sd_platform_data *)pdev->dev.platform_data;
36300 +       struct mmc_host *mmc;
36301 +       struct ubicom32sd_data *ud;
36302 +       struct resource *res_regs;
36303 +       struct resource *res_irq_tx;
36304 +       struct resource *res_irq_rx;
36305 +       int ret;
36306 +
36307 +       /*
36308 +        * Get our resources, regs is the hardware driver base address
36309 +        * and the tx and rx irqs are used to communicate with the 
36310 +        * hardware driver.
36311 +        */
36312 +       res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
36313 +       res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
36314 +       res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
36315 +       if (!res_regs || !res_irq_tx || !res_irq_rx) {
36316 +               ret = -EINVAL;
36317 +               goto fail;
36318 +       }
36319 +
36320 +       /*
36321 +        * Reserve any gpios we need
36322 +        */
36323 +       ret = gpio_request(pdata->cards[0].pin_wp, "sd-wp");
36324 +       if (ret) {
36325 +               goto fail;
36326 +       }
36327 +       gpio_direction_input(pdata->cards[0].pin_wp);
36328 +
36329 +       ret = gpio_request(pdata->cards[0].pin_cd, "sd-cd");
36330 +       if (ret) {
36331 +               goto fail_cd;
36332 +       }
36333 +       gpio_direction_input(pdata->cards[0].pin_cd);
36334 +
36335 +       /*
36336 +        * HACK: for the dual port controller on port F, we don't support the second port right now
36337 +        */
36338 +       if (pdata->ncards > 1) {
36339 +               ret = gpio_request(pdata->cards[1].pin_pwr, "sd-pwr");
36340 +               gpio_direction_output(pdata->cards[1].pin_pwr, !pdata->cards[1].pwr_polarity);
36341 +               gpio_direction_output(pdata->cards[1].pin_pwr, pdata->cards[1].pwr_polarity);
36342 +       }
36343 +
36344 +       ret = gpio_request(pdata->cards[0].pin_pwr, "sd-pwr");
36345 +       if (ret) {
36346 +               goto fail_pwr;
36347 +       }
36348 +       gpio_direction_output(pdata->cards[0].pin_pwr, !pdata->cards[0].pwr_polarity);
36349 +
36350 +       /*
36351 +        * Allocate the MMC driver, it includes memory for our data.
36352 +        */
36353 +       mmc = mmc_alloc_host(sizeof(struct ubicom32sd_data), &pdev->dev);
36354 +       if (!mmc) {
36355 +               ret = -ENOMEM;
36356 +               goto fail_mmc;
36357 +       }
36358 +       ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36359 +       ud->mmc = mmc;
36360 +       ud->pdata = pdata;
36361 +       ud->regs = (struct sdtio_vp_regs *)res_regs->start;
36362 +       ud->irq_tx = res_irq_tx->start;
36363 +       ud->irq_rx = res_irq_rx->start;
36364 +       platform_set_drvdata(pdev, mmc);
36365 +
36366 +       ret = request_irq(ud->irq_rx, ubicom32sd_interrupt, IRQF_DISABLED, mmc_hostname(mmc), mmc);
36367 +       if (ret) {
36368 +               goto fail_mmc;
36369 +       }
36370 +
36371 +       /*
36372 +        * Fill in the mmc structure
36373 +        */
36374 +       mmc->ops = &ubicom32sd_ops;
36375 +       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ |
36376 +                   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
36377 +
36378 +       mmc->f_min = ud->regs->f_min;
36379 +       mmc->f_max = ud->regs->f_max;
36380 +       mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
36381 +
36382 +       /*
36383 +        * Setup some restrictions on transfers
36384 +        *
36385 +        * We allow up to SDTIO_MAX_SG_BLOCKS of data to DMA into, there are
36386 +        * not really any "max_seg_size", "max_req_size", or "max_blk_count"
36387 +        * restrictions (must be less than U32_MAX though), pick
36388 +        * something large?!...
36389 +        *
36390 +        * The hardware can do up to 4095 bytes per block, since the spec
36391 +        * only requires 2048, we'll set it to that and not worry about
36392 +        * potential weird blk lengths.
36393 +        */
36394 +       mmc->max_hw_segs = SDTIO_MAX_SG_BLOCKS;
36395 +       mmc->max_phys_segs = SDTIO_MAX_SG_BLOCKS;
36396 +       mmc->max_seg_size = 1024 * 1024;
36397 +       mmc->max_req_size = 1024 * 1024;
36398 +       mmc->max_blk_count = 1024;
36399 +
36400 +       mmc->max_blk_size = 2048;
36401 +
36402 +       ubicom32sd_reset(ud);
36403 +
36404 +       /*
36405 +        * enable interrupts
36406 +        */
36407 +       ud->int_en = 0;
36408 +       ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_SETUP_SDIO << SDTIO_COMMAND_SHIFT | SDTIO_COMMAND_FLAG_SDIO_INT_EN, 0);
36409 +
36410 +       mmc_add_host(mmc);
36411 +
36412 +       printk(KERN_INFO "%s at %p, irq %d/%d\n", mmc_hostname(mmc),
36413 +                       ud->regs, ud->irq_tx, ud->irq_rx);
36414 +       return 0;
36415 +
36416 +fail_mmc:
36417 +       gpio_free(pdata->cards[0].pin_pwr);
36418 +fail_pwr:
36419 +       gpio_free(pdata->cards[0].pin_cd);
36420 +fail_cd:
36421 +       gpio_free(pdata->cards[0].pin_wp);
36422 +fail:
36423 +       return ret;
36424 +}
36425 +
36426 +/*
36427 + * ubicom32sd_remove
36428 + */
36429 +static int __devexit ubicom32sd_remove(struct platform_device *pdev)
36430 +{
36431 +       struct mmc_host *mmc = platform_get_drvdata(pdev);
36432 +
36433 +       platform_set_drvdata(pdev, NULL);
36434 +
36435 +       if (mmc) {
36436 +               struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36437 +
36438 +               gpio_free(ud->pdata->cards[0].pin_pwr);
36439 +               gpio_free(ud->pdata->cards[0].pin_cd);
36440 +               gpio_free(ud->pdata->cards[0].pin_wp);
36441 +
36442 +               mmc_remove_host(mmc);
36443 +               mmc_free_host(mmc);
36444 +       }
36445 +
36446 +       /*
36447 +        * Note that our data is allocated as part of the mmc structure
36448 +        * so we don't need to free it.
36449 +        */
36450 +       return 0;
36451 +}
36452 +
36453 +static struct platform_driver ubicom32sd_driver = {
36454 +       .driver = {
36455 +               .name = DRIVER_NAME,
36456 +               .owner = THIS_MODULE,
36457 +       },
36458 +       .probe = ubicom32sd_probe,
36459 +       .remove = __devexit_p(ubicom32sd_remove),
36460 +#if 0
36461 +       .suspend = ubicom32sd_suspend,
36462 +       .resume = ubicom32sd_resume,
36463 +#endif
36464 +};
36465 +
36466 +/*
36467 + * ubicom32sd_init
36468 + */
36469 +static int __init ubicom32sd_init(void)
36470 +{
36471 +       return platform_driver_register(&ubicom32sd_driver);
36472 +}
36473 +module_init(ubicom32sd_init);
36474 +
36475 +/*
36476 + * ubicom32sd_exit
36477 + */
36478 +static void __exit ubicom32sd_exit(void)
36479 +{
36480 +    platform_driver_unregister(&ubicom32sd_driver);
36481 +}
36482 +module_exit(ubicom32sd_exit);
36483 +
36484 +MODULE_AUTHOR("Patrick Tjin");
36485 +MODULE_DESCRIPTION("Ubicom32 Secure Digital Host Controller Interface driver");
36486 +MODULE_LICENSE("GPL");
36487 +
36488 --- a/drivers/mtd/devices/Kconfig
36489 +++ b/drivers/mtd/devices/Kconfig
36490 @@ -104,6 +104,17 @@ config M25PXX_USE_FAST_READ
36491         help
36492           This option enables FAST_READ access supported by ST M25Pxx.
36493  
36494 +config MTD_UBI32_M25P80
36495 +       tristate "Ubicom processor support for most SPI Flash chips (AT26DF, M25P, W25X, ...)"
36496 +       depends on UBICOM32
36497 +       default y
36498 +       help
36499 +         This enables access to most modern SPI flash chips, used for
36500 +         program and data storage.   Series supported include Atmel AT26DF,
36501 +         Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X.  Other chips
36502 +         are supported as well.  See the driver source for the current list,
36503 +         or to add other chips.
36504 +
36505  config MTD_SLRAM
36506         tristate "Uncached system RAM"
36507         help
36508 --- a/drivers/mtd/devices/Makefile
36509 +++ b/drivers/mtd/devices/Makefile
36510 @@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_LART)                += lart.o
36511  obj-$(CONFIG_MTD_BLOCK2MTD)    += block2mtd.o
36512  obj-$(CONFIG_MTD_DATAFLASH)    += mtd_dataflash.o
36513  obj-$(CONFIG_MTD_M25P80)       += m25p80.o
36514 +obj-$(CONFIG_MTD_UBI32_M25P80) += ubi32-m25p80.o
36515 --- /dev/null
36516 +++ b/drivers/mtd/devices/ubi32-m25p80.c
36517 @@ -0,0 +1,1066 @@
36518 +/*
36519 + * drivers/mtd/devices/ubi32-m25p80.c
36520 + *   NOR flash driver, Ubicom processor internal SPI flash interface.
36521 + *
36522 + *   This code instantiates the serial flash that contains the
36523 + *   original bootcode.  The serial flash start at address 0x60000000
36524 + *   in both Ubicom32V3 and Ubicom32V4 ISAs.
36525 + *
36526 + *   This piece of flash is made to appear as a Memory Technology
36527 + *   Device (MTD) with this driver to allow Read/Write/Erase operations.
36528 + *
36529 + * (C) Copyright 2009, Ubicom, Inc.
36530 + *
36531 + * This file is part of the Ubicom32 Linux Kernel Port.
36532 + *
36533 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
36534 + * it and/or modify it under the terms of the GNU General Public License
36535 + * as published by the Free Software Foundation, either version 2 of the
36536 + * License, or (at your option) any later version.
36537 + *
36538 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
36539 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
36540 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
36541 + * the GNU General Public License for more details.
36542 + *
36543 + * You should have received a copy of the GNU General Public License
36544 + * along with the Ubicom32 Linux Kernel Port.  If not,
36545 + * see <http://www.gnu.org/licenses/>.
36546 + *
36547 + * Ubicom32 implementation derived from (with many thanks):
36548 + *   arch/m68knommu
36549 + *   arch/blackfin
36550 + *   arch/parisc
36551 + */
36552 +#include <linux/types.h>
36553 +#include <linux/device.h>
36554 +#include <linux/platform_device.h>
36555 +#include <linux/mtd/mtd.h>
36556 +#include <linux/mtd/partitions.h>
36557 +#include <linux/mtd/physmap.h>
36558 +#include <linux/spi/spi.h>
36559 +#include <linux/spi/flash.h>
36560 +
36561 +#include <linux/init.h>
36562 +#include <linux/module.h>
36563 +#include <linux/interrupt.h>
36564 +#include <linux/mutex.h>
36565 +
36566 +#include <asm/ip5000.h>
36567 +#include <asm/devtree.h>
36568 +
36569 +#define UBICOM32_FLASH_BASE    0x60000000
36570 +#define UBICOM32_FLASH_MAX_SIZE 0x01000000
36571 +#define UBICOM32_FLASH_START   0x00000000
36572 +#define UBICOM32_KERNEL_OFFSET 0x00010000 /* The kernel starts after Ubicom
36573 +                                           * .protect section. */
36574 +
36575 +static struct mtd_partition ubicom32_flash_partitions[] = {
36576 +       {
36577 +               .name   = "Bootloader",         /* Protected Section
36578 +                                                * Partition */
36579 +               .size   = 0x10000,
36580 +               .offset = UBICOM32_FLASH_START,
36581 +//             .mask_flags = MTD_WRITEABLE     /* Mark Read-only */
36582 +       },
36583 +       {
36584 +               .name   = "Kernel",             /* Kernel Partition. */
36585 +               .size   = 0,                    /* this will be set up during
36586 +                                                * probe stage. At that time we
36587 +                                                * will know end of linux image
36588 +                                                * in flash. */
36589 +               .offset = MTDPART_OFS_APPEND,   /* Starts right after Protected
36590 +                                                * section. */
36591 +//             .mask_flags = MTD_WRITEABLE     /* Mark Read-only */
36592 +       },
36593 +       {
36594 +               .name   = "Rest",               /* Rest of the flash. */
36595 +               .size   = 0x200000,             /* Use up what remains in the
36596 +                                                * flash. */
36597 +               .offset = MTDPART_OFS_NXTBLK,   /* Starts right after Protected
36598 +                                                * section. */
36599 +       }
36600 +};
36601 +
36602 +static struct flash_platform_data ubicom32_flash_data = {
36603 +       .name = "ubicom32_boot_flash",
36604 +       .parts = ubicom32_flash_partitions,
36605 +       .nr_parts = ARRAY_SIZE(ubicom32_flash_partitions),
36606 +};
36607 +
36608 +static struct resource ubicom32_flash_resource[] = {
36609 +       {
36610 +               .start  = UBICOM32_FLASH_BASE,
36611 +               .end    = UBICOM32_FLASH_BASE +
36612 +               UBICOM32_FLASH_MAX_SIZE - 1,
36613 +               .flags  = IORESOURCE_MEM,
36614 +       },
36615 +};
36616 +
36617 +static struct platform_device ubicom32_flash_device = {
36618 +       .name = "ubicom32flashdriver",
36619 +       .id = 0, /* Bus number */
36620 +       .num_resources = ARRAY_SIZE(ubicom32_flash_resource),
36621 +       .resource = ubicom32_flash_resource,
36622 +       .dev = {
36623 +               .platform_data = &ubicom32_flash_data,
36624 +       },
36625 +};
36626 +
36627 +static struct platform_device *ubicom32_flash_devices[] = {
36628 +       &ubicom32_flash_device,
36629 +};
36630 +
36631 +static int __init ubicom32_flash_init(void)
36632 +{
36633 +       printk(KERN_INFO "%s(): registering device resources\n",
36634 +              __FUNCTION__);
36635 +       platform_add_devices(ubicom32_flash_devices,
36636 +                            ARRAY_SIZE(ubicom32_flash_devices));
36637 +       return 0;
36638 +}
36639 +
36640 +arch_initcall(ubicom32_flash_init);
36641 +
36642 +/*
36643 + * MTD SPI driver for ST M25Pxx (and similar) serial flash chips through
36644 + * Ubicom32 SPI controller.
36645 + *
36646 + * Author: Mike Lavender, mike@steroidmicros.com
36647 + *
36648 + * Copyright (c) 2005, Intec Automation Inc.
36649 + *
36650 + * Some parts are based on lart.c by Abraham Van Der Merwe
36651 + *
36652 + * Cleaned up and generalized based on mtd_dataflash.c
36653 + *
36654 + * This code is free software; you can redistribute it and/or modify
36655 + * it under the terms of the GNU General Public License version 2 as
36656 + * published by the Free Software Foundation.
36657 + *
36658 + */
36659 +
36660 +#define FLASH_PAGESIZE         256
36661 +
36662 +/* Flash opcodes. */
36663 +#define        OPCODE_WREN             0x06    /* Write enable */
36664 +#define        OPCODE_RDSR             0x05    /* Read status register */
36665 +#define        OPCODE_READ             0x03    /* Read data bytes (low frequency) */
36666 +#define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
36667 +#define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
36668 +#define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
36669 +#define        OPCODE_BE_32K           0x52    /* Erase 32KiB block */
36670 +#define        OPCODE_SE               0xd8    /* Sector erase (usually 64KiB) */
36671 +#define        OPCODE_RDID             0x9f    /* Read JEDEC ID */
36672 +
36673 +/* Status Register bits. */
36674 +#define        SR_WIP                  1       /* Write in progress */
36675 +#define        SR_WEL                  2       /* Write enable latch */
36676 +/* meaning of other SR_* bits may differ between vendors */
36677 +#define        SR_BP0                  4       /* Block protect 0 */
36678 +#define        SR_BP1                  8       /* Block protect 1 */
36679 +#define        SR_BP2                  0x10    /* Block protect 2 */
36680 +#define        SR_SRWD                 0x80    /* SR write protect */
36681 +
36682 +/* Define max times to check status register before we give up. */
36683 +#define        MAX_READY_WAIT_COUNT    100000
36684 +
36685 +
36686 +#ifdef CONFIG_MTD_PARTITIONS
36687 +#define        mtd_has_partitions()    (1)
36688 +#else
36689 +#define        mtd_has_partitions()    (0)
36690 +#endif
36691 +
36692 +/*
36693 + * Ubicom32 FLASH Command Set
36694 + */
36695 +#define FLASH_FC_INST_CMD      0x00    /* for SPI command only transaction */
36696 +#define FLASH_FC_INST_WR       0x01    /* for SPI write transaction */
36697 +#define FLASH_FC_INST_RD       0x02    /* for SPI read transaction */
36698 +
36699 +#define ALIGN_DOWN(v, a) ((v) & ~((a) - 1))
36700 +#define ALIGN_UP(v, a) (((v) + ((a) - 1)) & ~((a) - 1))
36701 +
36702 +#define        FLASH_COMMAND_KICK_OFF(io)                                                      \
36703 +       asm volatile(                                                                   \
36704 +       "       bset    "D(IO_INT_CLR)"(%0), #0, #%%bit("D(IO_XFL_INT_DONE)")   \n\t"   \
36705 +       "       jmpt.t  .+4                                                     \n\t"   \
36706 +       "       bset    "D(IO_INT_SET)"(%0), #0, #%%bit("D(IO_XFL_INT_START)")  \n\t"   \
36707 +               :                                                                       \
36708 +               : "a" (io)                                                              \
36709 +               : "memory", "cc"                                                        \
36710 +       );
36711 +
36712 +#define        FLASH_COMMAND_WAIT_FOR_COMPLETION(io)                                           \
36713 +       asm volatile(                                                                   \
36714 +       "       btst    "D(IO_INT_STATUS)"(%0), #%%bit("D(IO_XFL_INT_DONE)")    \n\t"   \
36715 +       "       jmpeq.f .-4                                                     \n\t"   \
36716 +               :                                                                       \
36717 +               : "a" (io)                                                              \
36718 +               : "memory", "cc"                                                                        \
36719 +       );
36720 +
36721 +#define        FLASH_COMMAND_EXEC(io)                                                          \
36722 +       FLASH_COMMAND_KICK_OFF(io)                                                      \
36723 +       FLASH_COMMAND_WAIT_FOR_COMPLETION(io)
36724 +
36725 +
36726 +#define OSC1_FREQ 12000000
36727 +#define TEN_MICRO_SECONDS (OSC1_FREQ * 10 / 1000000)
36728 +
36729 +/*
36730 + * We will have to eventually replace this null definition with the real thing.
36731 + */
36732 +#define WATCHDOG_RESET()
36733 +
36734 +#define EXTFLASH_WRITE_FIFO_SIZE 32
36735 +#define EXTFLASH_WRITE_BLOCK_SIZE EXTFLASH_WRITE_FIFO_SIZE /* limit the size to
36736 +                                                           * FIFO capacity, so
36737 +                                                           * the thread can be
36738 +                                                           * suspended. */
36739 +
36740 +#define JFFS2_FILESYSTEM_SIZE 0x100000
36741 +
36742 +/****************************************************************************/
36743 +
36744 +struct m25p {
36745 +       struct platform_device  *plt_dev;
36746 +       struct mutex            lock;
36747 +       struct mtd_info         mtd;
36748 +       unsigned                partitioned:1;
36749 +       u8                      erase_opcode;
36750 +       u8                      command[4];
36751 +};
36752 +
36753 +static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
36754 +{
36755 +       return container_of(mtd, struct m25p, mtd);
36756 +}
36757 +
36758 +/****************************************************************************/
36759 +
36760 +/*
36761 + * Internal helper functions
36762 + */
36763 +
36764 +/*
36765 + * Read the status register, returning its value in the location
36766 + * Return the status register value.
36767 + * Returns negative if error occurred.
36768 + */
36769 +static int read_sr(struct m25p *flash)
36770 +{
36771 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36772 +
36773 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
36774 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
36775 +               IO_XFL_CTL1_FC_DATA(1);
36776 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDSR);
36777 +       FLASH_COMMAND_EXEC(io);
36778 +
36779 +       return io->status1 & 0xff;
36780 +}
36781 +
36782 +/*
36783 + * mem_flash_io_read_u32()
36784 + */
36785 +static u32 mem_flash_io_read_u32(u32 addr)
36786 +{
36787 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36788 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
36789 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
36790 +               IO_XFL_CTL1_FC_DATA(4) | IO_XFL_CTL1_FC_DUMMY(1) |
36791 +               IO_XFL_CTL1_FC_ADDR;
36792 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_FAST_READ) |
36793 +               IO_XFL_CTL2_FC_ADDR(addr);
36794 +       FLASH_COMMAND_EXEC(io);
36795 +       return io->status1;
36796 +}
36797 +
36798 +/*
36799 + * mem_flash_read_u8()
36800 + */
36801 +static u8 mem_flash_read_u8(u32 addr)
36802 +{
36803 +       u32 tmp_addr = ALIGN_DOWN(addr, 4);
36804 +       u32 tmp_data = mem_flash_io_read_u32(tmp_addr);
36805 +       u8 *ptr = (u8 *)&tmp_data;
36806 +       return ptr[addr & 0x3];
36807 +}
36808 +
36809 +/*
36810 + * mem_flash_read()
36811 + *     No need to lock as read is implemented with ireads (same as normal flash
36812 + *     execution).
36813 + */
36814 +static void mem_flash_read(u32 addr, void *dst, size_t length)
36815 +{
36816 +       /*
36817 +        * Range check
36818 +        */
36819 +       /*
36820 +        * Fix source alignment.
36821 +        */
36822 +       while (addr & 0x03) {
36823 +               if (length == 0) {
36824 +                       return;
36825 +               }
36826 +               *((u8 *)dst) = mem_flash_read_u8(addr++);
36827 +               dst++;
36828 +               length--;
36829 +       }
36830 +
36831 +       while (length >= 4) {
36832 +               u32 tmp_data = mem_flash_io_read_u32(addr);
36833 +               addr += 4;
36834 +               length -= 4;
36835 +
36836 +               /*
36837 +                * Send the data to the destination.
36838 +                */
36839 +               memcpy((void *)dst, (void *)&tmp_data, 4);
36840 +               dst += 4;
36841 +       }
36842 +
36843 +       while (length--) {
36844 +               *((u8 *)dst) = mem_flash_read_u8(addr++);
36845 +               dst++;
36846 +       }
36847 +}
36848 +
36849 +/*
36850 + * mem_flash_wait_until_complete()
36851 + */
36852 +static void mem_flash_wait_until_complete(void)
36853 +{
36854 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36855 +
36856 +       do {
36857 +               /*
36858 +                * Put a delay here to deal with flash programming problem.
36859 +                */
36860 +               u32 mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
36861 +               while (UBICOM32_IO_TIMER->mptval < mptval)
36862 +                       ;
36863 +
36864 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
36865 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
36866 +                       IO_XFL_CTL1_FC_DATA(1);
36867 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDSR);
36868 +               FLASH_COMMAND_EXEC(io);
36869 +       } while (io->status1 & SR_WIP);
36870 +}
36871 +
36872 +/*
36873 + * mem_flash_write_next()
36874 + */
36875 +static size_t mem_flash_write_next(u32 addr, u8 *buf, size_t length)
36876 +{
36877 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36878 +       u32 data_start = addr;
36879 +       u32 data_end = addr + length;
36880 +       size_t count;
36881 +       u32 i, j;
36882 +
36883 +       /*
36884 +        * Top limit address.
36885 +        */
36886 +       u32 block_start = ALIGN_DOWN(data_start, 4);
36887 +       u32 block_end = block_start + EXTFLASH_WRITE_BLOCK_SIZE;
36888 +
36889 +       union {
36890 +               u8 byte[EXTFLASH_WRITE_BLOCK_SIZE];
36891 +               u32 word[EXTFLASH_WRITE_BLOCK_SIZE / 4];
36892 +       } write_buf;
36893 +
36894 +       u32 *flash_addr = (u32 *)block_start;
36895 +
36896 +       /*
36897 +        * The write block must be limited by FLASH internal buffer.
36898 +        */
36899 +       u32 block_end_align = ALIGN_DOWN(block_end, 256);
36900 +       bool write_needed;
36901 +
36902 +       block_end = (block_end_align > block_start)
36903 +               ? block_end_align : block_end;
36904 +       data_end = (data_end <= block_end) ? data_end : block_end;
36905 +       block_end = ALIGN_UP(data_end, 4);
36906 +       count = data_end - data_start;
36907 +
36908 +       /*
36909 +        * Transfer data to a buffer.
36910 +        */
36911 +       for (i = 0; i < (block_end - block_start) / 4; i++) {
36912 +               /*
36913 +                * The FLASH read can hold D-cache for a long time.
36914 +                * Use I/O operation to read FLASH to avoid starving other
36915 +                * threads, especially HRT.  (Do this for application only)
36916 +                */
36917 +               write_buf.word[i] = mem_flash_io_read_u32(
36918 +                       (u32)(&flash_addr[i]));
36919 +       }
36920 +
36921 +       write_needed = false;
36922 +       for (i = 0, j = (data_start - block_start);
36923 +            i < (data_end - data_start); i++, j++) {
36924 +               write_needed = write_needed || (write_buf.byte[j] != buf[i]);
36925 +               write_buf.byte[j] &= buf[i];
36926 +       }
36927 +
36928 +
36929 +       /*
36930 +        * If the data in FLASH is identical to what to be written. Then skip
36931 +        * it.
36932 +        */
36933 +       if (write_needed) {
36934 +               /*
36935 +                * Write to flash.
36936 +                */
36937 +               void *tmp __attribute__((unused));
36938 +               s32 extra_words;
36939 +
36940 +               asm volatile(
36941 +               "       move.4  %0, %2                                                                  \n\t"
36942 +               "       bset    "D(IO_INT_SET)"(%1), #0, #%%bit("D(IO_PORTX_INT_FIFO_TX_RESET)")        \n\t"
36943 +               "       pipe_flush 0                                                                    \n\t"
36944 +               "       .rept   "D(EXTFLASH_WRITE_FIFO_SIZE / 4)"                                       \n\t"
36945 +               "       move.4  "D(IO_TX_FIFO)"(%1), (%0)4++                                            \n\t"
36946 +               "       .endr                                                                           \n\t"
36947 +                       : "=&a" (tmp)
36948 +                       : "a" (io), "r" (&write_buf.word[0])
36949 +                       : "memory", "cc"
36950 +               );
36951 +
36952 +               /* Lock FLASH for write access. */
36953 +               io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
36954 +
36955 +               /* Command: WREN */
36956 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
36957 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD);
36958 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_WREN);
36959 +               FLASH_COMMAND_EXEC(io);
36960 +
36961 +               /* Command: BYTE PROGRAM */
36962 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
36963 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_WR) |
36964 +                       IO_XFL_CTL1_FC_DATA(block_end - block_start) |
36965 +                       IO_XFL_CTL1_FC_ADDR;
36966 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_PP) |
36967 +                       IO_XFL_CTL2_FC_ADDR(block_start);
36968 +               FLASH_COMMAND_KICK_OFF(io);
36969 +
36970 +               extra_words = (s32)(block_end - block_start -
36971 +                                   EXTFLASH_WRITE_FIFO_SIZE) / 4;
36972 +               if (extra_words > 0) {
36973 +                       asm volatile(
36974 +                       "       move.4          %0, %3                          \n\t"
36975 +                       "1:     cmpi            "D(IO_FIFO_LEVEL)"(%1), #4      \n\t"
36976 +                       "       jmpgt.s.t       1b                              \n\t"
36977 +                       "       move.4          "D(IO_TX_FIFO)"(%1), (%0)4++    \n\t"
36978 +                       "       add.4           %2, #-1, %2                     \n\t"
36979 +                       "       jmpgt.t         1b                              \n\t"
36980 +                               : "=&a" (tmp)
36981 +                               : "a" (io), "d" (extra_words),
36982 +                                 "r" (&write_buf.word[EXTFLASH_WRITE_FIFO_SIZE / 4])
36983 +                               : "memory", "cc"
36984 +                       );
36985 +               }
36986 +               FLASH_COMMAND_WAIT_FOR_COMPLETION(io);
36987 +
36988 +               mem_flash_wait_until_complete();
36989 +
36990 +
36991 +               /* Unlock FLASH for cache access. */
36992 +               io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
36993 +       }
36994 +
36995 +       /*
36996 +        * Complete.
36997 +        */
36998 +       return count;
36999 +}
37000 +
37001 +/*
37002 + * mem_flash_write()
37003 + */
37004 +static void mem_flash_write(u32 addr, const void *src, size_t length)
37005 +{
37006 +       /*
37007 +        * Write data
37008 +        */
37009 +       u8_t *ptr = (u8_t *)src;
37010 +       while (length) {
37011 +               size_t count = mem_flash_write_next(addr, ptr, length);
37012 +               addr += count;
37013 +               ptr += count;
37014 +               length -= count;
37015 +       }
37016 +}
37017 +
37018 +/*
37019 + * Service routine to read status register until ready, or timeout occurs.
37020 + * Returns non-zero if error.
37021 + */
37022 +static int wait_till_ready(struct m25p *flash)
37023 +{
37024 +       int count;
37025 +       int sr;
37026 +
37027 +       /* one chip guarantees max 5 msec wait here after page writes,
37028 +        * but potentially three seconds (!) after page erase.
37029 +        */
37030 +       for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
37031 +               u32 mptval;
37032 +               sr = read_sr(flash);
37033 +               if (sr < 0)
37034 +                       break;
37035 +               else if (!(sr & SR_WIP))
37036 +                       return 0;
37037 +
37038 +               /*
37039 +                * Put a 10us delay here to deal with flash programming problem.
37040 +                */
37041 +               mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
37042 +               while ((s32)(mptval - UBICOM32_IO_TIMER->mptval) > 0) {
37043 +                       WATCHDOG_RESET();
37044 +               }
37045 +               /* REVISIT sometimes sleeping would be best */
37046 +       }
37047 +
37048 +       return 1;
37049 +}
37050 +
37051 +/*
37052 + * mem_flash_erase_page()
37053 + */
37054 +static void mem_flash_erase_page(u32 addr)
37055 +{
37056 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37057 +
37058 +       /* Lock FLASH for write access. */
37059 +       io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
37060 +
37061 +       /* Command: WREN */
37062 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37063 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD);
37064 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_WREN);
37065 +       FLASH_COMMAND_EXEC(io);
37066 +
37067 +       /* Command: ERASE */
37068 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37069 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD) |
37070 +               IO_XFL_CTL1_FC_ADDR;
37071 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_SE) |
37072 +               IO_XFL_CTL2_FC_ADDR(addr);
37073 +       FLASH_COMMAND_EXEC(io);
37074 +
37075 +       mem_flash_wait_until_complete();
37076 +
37077 +       /* Unlock FLASH for cache access. */
37078 +       io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
37079 +}
37080 +
37081 +/*
37082 + * mem_flash_erase()
37083 + */
37084 +static u32 mem_flash_erase(u32 addr, u32 length)
37085 +{
37086 +       /*
37087 +        * Calculate the endaddress to be the first address of the page
37088 +        * just beyond this erase section of pages.
37089 +        */
37090 +       u32 endaddr = addr + length;
37091 +
37092 +       /*
37093 +        * Erase.
37094 +        */
37095 +       while (addr < endaddr) {
37096 +               u32 test_addr = addr;
37097 +               mem_flash_erase_page(addr);
37098 +
37099 +               /*
37100 +                * Test how much was erased as actual flash page at this address
37101 +                * may be smaller than the expected page size.
37102 +                */
37103 +               while (test_addr < endaddr) {
37104 +                       /*
37105 +                        * The FLASH read can hold D-cache for a long time.  Use
37106 +                        * I/O operation to read FLASH to avoid starving other
37107 +                        * threads, especially HRT.  (Do this for application
37108 +                        * only)
37109 +                        */
37110 +                       if (mem_flash_io_read_u32(test_addr) != 0xFFFFFFFF) {
37111 +                               break;
37112 +                       }
37113 +                       test_addr += 4;
37114 +               }
37115 +               if (test_addr == addr) {
37116 +                       printk("erase failed at address 0x%x, skipping",
37117 +                              test_addr);
37118 +                       test_addr += 4;
37119 +                       return 1;
37120 +               }
37121 +               addr = test_addr;
37122 +       }
37123 +       return 0;
37124 +}
37125 +
37126 +
37127 +/****************************************************************************/
37128 +
37129 +/*
37130 + * MTD implementation
37131 + */
37132 +
37133 +/*
37134 + * Erase an address range on the flash chip.  The address range may extend
37135 + * one or more erase sectors.  Return an error is there is a problem erasing.
37136 + */
37137 +static int ubicom32_flash_driver_erase(struct mtd_info *mtd,
37138 +                                      struct erase_info *instr)
37139 +{
37140 +       struct m25p *flash = mtd_to_m25p(mtd);
37141 +       u32 addr, len;
37142 +
37143 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37144 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "at",
37145 +                       (u32)instr->addr, instr->len);
37146 +
37147 +       /* sanity checks */
37148 +       if (instr->addr + instr->len > flash->mtd.size)
37149 +               return -EINVAL;
37150 +       if ((instr->addr % mtd->erasesize) != 0
37151 +                       || (instr->len % mtd->erasesize) != 0) {
37152 +               return -EINVAL;
37153 +       }
37154 +
37155 +       addr = instr->addr + UBICOM32_FLASH_BASE;
37156 +       len = instr->len;
37157 +
37158 +       mutex_lock(&flash->lock);
37159 +
37160 +       /* REVISIT in some cases we could speed up erasing large regions
37161 +        * by using OPCODE_SE instead of OPCODE_BE_4K
37162 +        */
37163 +
37164 +       /* now erase those sectors */
37165 +       if (mem_flash_erase(addr, len)) {
37166 +               instr->state = MTD_ERASE_FAILED;
37167 +               mutex_unlock(&flash->lock);
37168 +               return -EIO;
37169 +       }
37170 +
37171 +       mutex_unlock(&flash->lock);
37172 +       instr->state = MTD_ERASE_DONE;
37173 +       mtd_erase_callback(instr);
37174 +       return 0;
37175 +}
37176 +
37177 +/*
37178 + * Read an address range from the flash chip.  The address range
37179 + * may be any size provided it is within the physical boundaries.
37180 + */
37181 +static int ubicom32_flash_driver_read(struct mtd_info *mtd, loff_t from,
37182 +                                     size_t len, size_t *retlen, u_char *buf)
37183 +{
37184 +       struct m25p *flash = mtd_to_m25p(mtd);
37185 +       u32 base_addr = UBICOM32_FLASH_BASE + from;
37186 +
37187 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37188 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "from",
37189 +             (u32)from, len);
37190 +
37191 +       /* sanity checks */
37192 +       if (!len)
37193 +               return 0;
37194 +
37195 +       if (from + len > flash->mtd.size)
37196 +               return -EINVAL;
37197 +
37198 +       /* Byte count starts at zero. */
37199 +       if (retlen)
37200 +               *retlen = 0;
37201 +
37202 +       mutex_lock(&flash->lock);
37203 +
37204 +       /* Wait till previous write/erase is done. */
37205 +       if (wait_till_ready(flash)) {
37206 +               /* REVISIT status return?? */
37207 +               mutex_unlock(&flash->lock);
37208 +               return 1;
37209 +       }
37210 +
37211 +       mem_flash_read(base_addr, (void *)buf, len);
37212 +
37213 +       if (retlen)
37214 +               *retlen = len;
37215 +
37216 +       mutex_unlock(&flash->lock);
37217 +
37218 +       return 0;
37219 +}
37220 +
37221 +/*
37222 + * Write an address range to the flash chip.  Data must be written in
37223 + * FLASH_PAGESIZE chunks.  The address range may be any size provided
37224 + * it is within the physical boundaries.
37225 + */
37226 +static int ubicom32_flash_driver_write(struct mtd_info *mtd, loff_t to,
37227 +                                      size_t len, size_t *retlen,
37228 +                                      const u_char *buf)
37229 +{
37230 +       struct m25p *flash = mtd_to_m25p(mtd);
37231 +       u32 base_addr = UBICOM32_FLASH_BASE + to;
37232 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37233 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "to",
37234 +                       (u32)to, len);
37235 +
37236 +       if (retlen)
37237 +               *retlen = 0;
37238 +
37239 +       /* sanity checks */
37240 +       if (!len)
37241 +               return 0;
37242 +
37243 +       if (to + len > flash->mtd.size)
37244 +               return -EINVAL;
37245 +
37246 +       mutex_lock(&flash->lock);
37247 +
37248 +       mem_flash_write(base_addr, (void *) buf, len);
37249 +
37250 +       /* Wait until finished previous write command. */
37251 +       if (wait_till_ready(flash)) {
37252 +               mutex_unlock(&flash->lock);
37253 +               return 1;
37254 +       }
37255 +
37256 +       if (retlen)
37257 +               *retlen = len;
37258 +
37259 +       mutex_unlock(&flash->lock);
37260 +       return 0;
37261 +}
37262 +
37263 +
37264 +/****************************************************************************/
37265 +
37266 +/*
37267 + * SPI device driver setup and teardown
37268 + */
37269 +
37270 +struct flash_info {
37271 +       char            *name;
37272 +
37273 +       /* JEDEC id zero means "no ID" (most older chips); otherwise it has
37274 +        * a high byte of zero plus three data bytes: the manufacturer id,
37275 +        * then a two byte device id.
37276 +        */
37277 +       u32             jedec_id;
37278 +
37279 +       /* The size listed here is what works with OPCODE_SE, which isn't
37280 +        * necessarily called a "sector" by the vendor.
37281 +        */
37282 +       unsigned        sector_size;
37283 +       u16             n_sectors;
37284 +
37285 +       u16             flags;
37286 +#define        SECT_4K         0x01            /* OPCODE_BE_4K works uniformly */
37287 +};
37288 +
37289 +
37290 +/* NOTE: double check command sets and memory organization when you add
37291 + * more flash chips.  This current list focusses on newer chips, which
37292 + * have been converging on command sets which including JEDEC ID.
37293 + */
37294 +static struct flash_info __devinitdata m25p_data[] = {
37295 +
37296 +       /* Atmel -- some are (confusingly) marketed as "DataFlash" */
37297 +       { "at25fs010",  0x1f6601, 32 * 1024, 4, SECT_4K, },
37298 +       { "at25fs040",  0x1f6604, 64 * 1024, 8, SECT_4K, },
37299 +
37300 +       { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
37301 +
37302 +       { "at26f004",   0x1f0400, 64 * 1024, 8, SECT_4K, },
37303 +       { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
37304 +       { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
37305 +       { "at26df321",  0x1f4701, 64 * 1024, 64, SECT_4K, },
37306 +
37307 +       /* Spansion -- single (large) sector size only, at least
37308 +        * for the chips listed here (without boot sectors).
37309 +        */
37310 +       { "s25sl004a", 0x010212, 64 * 1024, 8, },
37311 +       { "s25sl008a", 0x010213, 64 * 1024, 16, },
37312 +       { "s25sl016a", 0x010214, 64 * 1024, 32, },
37313 +       { "s25sl032a", 0x010215, 64 * 1024, 64, },
37314 +       { "s25sl064a", 0x010216, 64 * 1024, 128, },
37315 +
37316 +       /* SST -- large erase sizes are "overlays", "sectors" are 4K */
37317 +       { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
37318 +       { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
37319 +       { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
37320 +       { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
37321 +
37322 +       /* ST Microelectronics -- newer production may have feature updates */
37323 +       { "m25p05",  0x202010,  32 * 1024, 2, },
37324 +       { "m25p10",  0x202011,  32 * 1024, 4, },
37325 +       { "m25p20",  0x202012,  64 * 1024, 4, },
37326 +       { "m25p40",  0x202013,  64 * 1024, 8, },
37327 +       { "m25p80",         0,  64 * 1024, 16, },
37328 +       { "m25p16",  0x202015,  64 * 1024, 32, },
37329 +       { "m25p32",  0x202016,  64 * 1024, 64, },
37330 +       { "m25p64",  0x202017,  64 * 1024, 128, },
37331 +       { "m25p128", 0x202018, 256 * 1024, 64, },
37332 +
37333 +       { "m45pe80", 0x204014,  64 * 1024, 16, },
37334 +       { "m45pe16", 0x204015,  64 * 1024, 32, },
37335 +
37336 +       { "m25pe80", 0x208014,  64 * 1024, 16, },
37337 +       { "m25pe16", 0x208015,  64 * 1024, 32, SECT_4K, },
37338 +
37339 +       /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
37340 +       { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
37341 +       { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
37342 +       { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
37343 +       { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
37344 +       { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
37345 +       { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
37346 +       { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
37347 +
37348 +       /* Macronix -- mx25lxxx */ 
37349 +       { "mx25l32",  0xc22016, 64 * 1024,  64, }, 
37350 +       { "mx25l64",  0xc22017, 64 * 1024, 128, }, 
37351 +       { "mx25l128", 0xc22018, 64 * 1024, 256, },
37352 +
37353 +};
37354 +
37355 +struct flash_info *__devinit jedec_probe(struct platform_device *spi)
37356 +{
37357 +       int                     tmp;
37358 +       u32                     jedec;
37359 +       struct flash_info       *info;
37360 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37361 +
37362 +       /*
37363 +        * Setup and run RDID command on the flash.
37364 +        */
37365 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37366 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
37367 +               IO_XFL_CTL1_FC_DATA(3);
37368 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDID);
37369 +       FLASH_COMMAND_EXEC(io);
37370 +
37371 +       jedec = io->status1 & 0x00ffffff;
37372 +
37373 +       for (tmp = 0, info = m25p_data;
37374 +                       tmp < ARRAY_SIZE(m25p_data);
37375 +                       tmp++, info++) {
37376 +               if (info->jedec_id == jedec)
37377 +                       return info;
37378 +       }
37379 +       dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
37380 +       return NULL;
37381 +}
37382 +
37383 +
37384 +/*
37385 + * board specific setup should have ensured the SPI clock used here
37386 + * matches what the READ command supports, at least until this driver
37387 + * understands FAST_READ (for clocks over 25 MHz).
37388 + */
37389 +static int __devinit ubicom32_flash_probe(struct platform_device *spi)
37390 +{
37391 +       struct flash_platform_data      *data;
37392 +       struct m25p                     *flash;
37393 +       struct flash_info               *info;
37394 +       unsigned                        i;
37395 +
37396 +       /* Platform data helps sort out which chip type we have, as
37397 +        * well as how this board partitions it.  If we don't have
37398 +        * a chip ID, try the JEDEC id commands; they'll work for most
37399 +        * newer chips, even if we don't recognize the particular chip.
37400 +        */
37401 +       data = spi->dev.platform_data;
37402 +       if (data && data->type) {
37403 +               for (i = 0, info = m25p_data;
37404 +                               i < ARRAY_SIZE(m25p_data);
37405 +                               i++, info++) {
37406 +                       if (strcmp(data->type, info->name) == 0)
37407 +                               break;
37408 +               }
37409 +
37410 +               /* unrecognized chip? */
37411 +               if (i == ARRAY_SIZE(m25p_data)) {
37412 +                       DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
37413 +                                       spi->dev.bus_id, data->type);
37414 +                       info = NULL;
37415 +
37416 +               /* recognized; is that chip really what's there? */
37417 +               } else if (info->jedec_id) {
37418 +                       struct flash_info       *chip = jedec_probe(spi);
37419 +
37420 +                       if (!chip || chip != info) {
37421 +                               dev_warn(&spi->dev, "found %s, expected %s\n",
37422 +                                               chip ? chip->name : "UNKNOWN",
37423 +                                               info->name);
37424 +                               info = NULL;
37425 +                       }
37426 +               }
37427 +       } else
37428 +               info = jedec_probe(spi);
37429 +
37430 +       if (!info)
37431 +               return -ENODEV;
37432 +
37433 +       flash = kzalloc(sizeof *flash, GFP_KERNEL);
37434 +       if (!flash)
37435 +               return -ENOMEM;
37436 +
37437 +       flash->plt_dev = spi;
37438 +       mutex_init(&flash->lock);
37439 +       dev_set_drvdata(&spi->dev, flash);
37440 +
37441 +       if (data && data->name)
37442 +               flash->mtd.name = data->name;
37443 +       else
37444 +               flash->mtd.name = spi->dev.bus_id;
37445 +
37446 +       flash->mtd.type = MTD_NORFLASH;
37447 +       flash->mtd.writesize = 1;
37448 +       flash->mtd.flags = MTD_CAP_NORFLASH;
37449 +       flash->mtd.size = info->sector_size * info->n_sectors;
37450 +       flash->mtd.erase = ubicom32_flash_driver_erase;
37451 +       flash->mtd.read = ubicom32_flash_driver_read;
37452 +       flash->mtd.write = ubicom32_flash_driver_write;
37453 +
37454 +       /* prefer "small sector" erase if possible */
37455 +       /*
37456 +        * The Ubicom erase code does not use the opcode for smaller sectors,
37457 +        * so disable that functionality and keep erasesize == sector_size
37458 +        * so that the test in ubicom32_flash_driver_erase works properly.
37459 +        *
37460 +        * This was: `if (info->flags & SECT_4K) {' instead of `if (0) {'
37461 +        */
37462 +       if (0) {
37463 +               flash->erase_opcode = OPCODE_BE_4K;
37464 +               flash->mtd.erasesize = 4096;
37465 +       } else {
37466 +               flash->erase_opcode = OPCODE_SE;
37467 +               flash->mtd.erasesize = info->sector_size;
37468 +       }
37469 +
37470 +       dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
37471 +                       flash->mtd.size / 1024);
37472 +
37473 +       DEBUG(MTD_DEBUG_LEVEL2,
37474 +               "mtd .name = %s, .size = 0x%.8x (%uMiB) "
37475 +                       ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
37476 +               flash->mtd.name,
37477 +               flash->mtd.size, flash->mtd.size / (1024*1024),
37478 +               flash->mtd.erasesize, flash->mtd.erasesize / 1024,
37479 +               flash->mtd.numeraseregions);
37480 +
37481 +       if (flash->mtd.numeraseregions)
37482 +               for (i = 0; i < flash->mtd.numeraseregions; i++)
37483 +                       DEBUG(MTD_DEBUG_LEVEL2,
37484 +                               "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
37485 +                               ".erasesize = 0x%.8x (%uKiB), "
37486 +                               ".numblocks = %d }\n",
37487 +                               i, flash->mtd.eraseregions[i].offset,
37488 +                               flash->mtd.eraseregions[i].erasesize,
37489 +                               flash->mtd.eraseregions[i].erasesize / 1024,
37490 +                               flash->mtd.eraseregions[i].numblocks);
37491 +
37492 +
37493 +       /* partitions should match sector boundaries; and it may be good to
37494 +        * use readonly partitions for writeprotected sectors (BP2..BP0).
37495 +        */
37496 +       if (mtd_has_partitions()) {
37497 +               struct mtd_partition    *parts = NULL;
37498 +               int                     nr_parts = 0;
37499 +
37500 +#ifdef CONFIG_MTD_CMDLINE_PARTS
37501 +               static const char *part_probes[] = { "cmdlinepart", NULL, };
37502 +
37503 +               nr_parts = parse_mtd_partitions(&flash->mtd,
37504 +                               part_probes, &parts, 0);
37505 +#endif
37506 +
37507 +               if (nr_parts <= 0 && data && data->parts) {
37508 +                       parts = data->parts;
37509 +                       nr_parts = data->nr_parts;
37510 +                       if (nr_parts >= 2) {
37511 +                               /*
37512 +                                * Set last partition size to be 1M.
37513 +                                */
37514 +                               parts[1].size = flash->mtd.size - 
37515 +                                       parts[0].size - JFFS2_FILESYSTEM_SIZE;
37516 +                               parts[2].size = JFFS2_FILESYSTEM_SIZE;
37517 +                       }
37518 +               }
37519 +
37520 +               if (nr_parts > 0) {
37521 +                       for (i = 0; i < nr_parts; i++) {
37522 +                               DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
37523 +                                       "{.name = %s, .offset = 0x%.8x, "
37524 +                                               ".size = 0x%.8x (%uKiB) }\n",
37525 +                                       i, parts[i].name,
37526 +                                       parts[i].offset,
37527 +                                       parts[i].size,
37528 +                                       parts[i].size / 1024);
37529 +                       }
37530 +                       flash->partitioned = 1;
37531 +                       return add_mtd_partitions(&flash->mtd, parts, nr_parts);
37532 +               }
37533 +       } else if (data->nr_parts)
37534 +               dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
37535 +                               data->nr_parts, data->name);
37536 +
37537 +       return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
37538 +}
37539 +
37540 +
37541 +static int __devexit ubicom32_flash_remove(struct spi_device *spi)
37542 +{
37543 +       struct m25p     *flash = dev_get_drvdata(&spi->dev);
37544 +       int             status;
37545 +
37546 +       /* Clean up MTD stuff. */
37547 +       if (mtd_has_partitions() && flash->partitioned)
37548 +               status = del_mtd_partitions(&flash->mtd);
37549 +       else
37550 +               status = del_mtd_device(&flash->mtd);
37551 +       if (status == 0)
37552 +               kfree(flash);
37553 +       return 0;
37554 +}
37555 +
37556 +static struct platform_driver ubicom32_flash_driver = {
37557 +       .driver = {
37558 +               .name   = "ubicom32flashdriver",
37559 +               .bus    = &platform_bus_type,
37560 +               .owner  = THIS_MODULE,
37561 +       },
37562 +       .probe  = ubicom32_flash_probe,
37563 +       .remove = NULL,
37564 +};
37565 +
37566 +static int ubicom32_flash_driver_init(void)
37567 +{
37568 +       return platform_driver_register(&ubicom32_flash_driver);
37569 +}
37570 +
37571 +
37572 +static void ubicom32_flash_driver_exit(void)
37573 +{
37574 +       platform_driver_unregister(&ubicom32_flash_driver);
37575 +}
37576 +
37577 +
37578 +module_init(ubicom32_flash_driver_init);
37579 +module_exit(ubicom32_flash_driver_exit);
37580 +
37581 +MODULE_LICENSE("GPL");
37582 +MODULE_AUTHOR("Mike Lavender");
37583 +MODULE_DESCRIPTION("Ubicom32 MTD SPI driver for ST M25Pxx flash chips");
37584 --- a/drivers/net/Kconfig
37585 +++ b/drivers/net/Kconfig
37586 @@ -2463,6 +2463,25 @@ config JME
37587           To compile this driver as a module, choose M here. The module
37588           will be called jme.
37589  
37590 +config UBICOM32_GMAC
37591 +       tristate "Ubicom Gigabit Ethernet support (EXPERIMENTAL)"
37592 +       depends on UBICOM32
37593 +       help
37594 +         Gigabit Ethernet support for IP5K/IP7K
37595 +
37596 +config UBICOM32_NAPI
37597 +       bool  "USE NAPI (EXPERIMENTAL)"
37598 +       depends on UBICOM32_GMAC
37599 +       help
37600 +         Use NAPI for Ubicom's Ethernet driver
37601 +
37602 +config UBICOM32_OCM_FOR_SKB
37603 +        bool  "USE OCM for SKB (EXPERIMENTAL)"
37604 +        depends on UBICOM32_GMAC
37605 +       default n
37606 +        help
37607 +          Allocate skb from OCM for Ethernet Receive
37608 +
37609  endif # NETDEV_1000
37610  
37611  #
37612 --- a/drivers/net/Makefile
37613 +++ b/drivers/net/Makefile
37614 @@ -262,4 +262,4 @@ obj-$(CONFIG_NETXEN_NIC) += netxen/
37615  obj-$(CONFIG_NIU) += niu.o
37616  obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
37617  obj-$(CONFIG_SFC) += sfc/
37618 -
37619 +obj-$(CONFIG_UBICOM32_GMAC) += ubi32-eth.o
37620 --- /dev/null
37621 +++ b/drivers/net/ubi32-eth.c
37622 @@ -0,0 +1,699 @@
37623 +/*
37624 + * drivers/net/ubi32-eth.c
37625 + *   Ubicom32 ethernet TIO interface driver.
37626 + *
37627 + * (C) Copyright 2009, Ubicom, Inc.
37628 + *
37629 + * This file is part of the Ubicom32 Linux Kernel Port.
37630 + *
37631 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
37632 + * it and/or modify it under the terms of the GNU General Public License
37633 + * as published by the Free Software Foundation, either version 2 of the
37634 + * License, or (at your option) any later version.
37635 + *
37636 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
37637 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
37638 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
37639 + * the GNU General Public License for more details.
37640 + *
37641 + * You should have received a copy of the GNU General Public License
37642 + * along with the Ubicom32 Linux Kernel Port.  If not,
37643 + * see <http://www.gnu.org/licenses/>.
37644 + *
37645 + * Ubicom32 implementation derived from (with many thanks):
37646 + *   arch/m68knommu
37647 + *   arch/blackfin
37648 + *   arch/parisc
37649 + */
37650 +/*
37651 + * ubi32_eth.c
37652 + * Ethernet driver for Ip5k/Ip7K
37653 + */
37654 +
37655 +#include <linux/module.h>
37656 +#include <linux/init.h>
37657 +#include <linux/moduleparam.h>
37658 +
37659 +#include <linux/sched.h>
37660 +#include <linux/kernel.h>
37661 +#include <linux/slab.h>
37662 +#include <linux/errno.h>
37663 +#include <linux/types.h>
37664 +#include <linux/interrupt.h>
37665 +
37666 +#include <linux/in.h>
37667 +#include <linux/netdevice.h>
37668 +#include <linux/etherdevice.h>
37669 +#include <linux/if_vlan.h>
37670 +#include <linux/ip.h>
37671 +#include <linux/tcp.h>
37672 +#include <linux/skbuff.h>
37673 +#include <asm/checksum.h>
37674 +#include "ubi32-eth.h"
37675 +#include <asm/ip5000.h>
37676 +#include <asm/devtree.h>
37677 +#include <asm/system.h>
37678 +
37679 +/* #define USE_POLLING */
37680 +
37681 +/*
37682 + * TODO:
37683 + * mac address from flash
37684 + * multicast filter
37685 + * ethtool support
37686 + * sysfs support
37687 + * skb->nrfrag support
37688 + * ioctl
37689 + * monitor phy status
37690 + */
37691 +
37692 +static const char *eth_if_name[UBI32_ETH_NUM_OF_DEVICES] =
37693 +       {"eth_lan", "eth_wan", "eth_ultra"};
37694 +static struct net_device *ubi32_eth_devices[UBI32_ETH_NUM_OF_DEVICES] =
37695 +       {NULL, NULL, NULL};
37696 +static u8_t mac_addr[UBI32_ETH_NUM_OF_DEVICES][ETH_ALEN] = {
37697 +       {0x00, 0x03, 0x64, 'l', 'a', 'n'},
37698 +       {0x00, 0x03, 0x64, 'w', 'a', 'n'},
37699 +       {0x00, 0x03, 0x64, 'u', 'l', 't'}};
37700 +
37701 +int ubi32_eth_ocm_alloc;
37702 +int ubi32_eth_ddr_alloc;
37703 +
37704 +static inline struct sk_buff *ubi32_alloc_skb(struct net_device *dev, unsigned int length)
37705 +{
37706 +#if (defined(CONFIG_ZONE_DMA) && defined(CONFIG_UBICOM32_OCM_FOR_SKB))
37707 +       struct sk_buff *sk_buff;
37708 +
37709 +       if (dev != ubi32_eth_devices[0])
37710 +               return __dev_alloc_skb(length, GFP_ATOMIC);
37711 +
37712 +       sk_buff = __dev_alloc_skb(length, GFP_ATOMIC | __GFP_NOWARN | __GFP_NORETRY | GFP_DMA);
37713 +       if (sk_buff) {
37714 +               ubi32_eth_ocm_alloc++;
37715 +               return sk_buff;
37716 +       } else {
37717 +               ubi32_eth_ddr_alloc++;
37718 +               return __dev_alloc_skb(length, GFP_ATOMIC);
37719 +       }
37720 +#else
37721 +       return __dev_alloc_skb(length, GFP_ATOMIC);
37722 +#endif
37723 +}
37724 +
37725 +static void ubi32_eth_vp_rxtx_enable(struct net_device *dev)
37726 +{
37727 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37728 +       priv->regs->command = UBI32_ETH_VP_CMD_RX_ENABLE | UBI32_ETH_VP_CMD_TX_ENABLE;
37729 +       priv->regs->int_mask = (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
37730 +       ubicom32_set_interrupt(priv->vp_int_bit);
37731 +}
37732 +
37733 +static void ubi32_eth_vp_rxtx_stop(struct net_device *dev)
37734 +{
37735 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37736 +       priv->regs->command = 0;
37737 +       priv->regs->int_mask = 0;
37738 +       ubicom32_set_interrupt(priv->vp_int_bit);
37739 +
37740 +       /* Wait for graceful shutdown */
37741 +       while (priv->regs->status & (UBI32_ETH_VP_STATUS_RX_STATE | UBI32_ETH_VP_STATUS_TX_STATE));
37742 +}
37743 +
37744 +/*
37745 + * ubi32_eth_tx_done()
37746 + */
37747 +static int ubi32_eth_tx_done(struct net_device *dev)
37748 +{
37749 +       struct ubi32_eth_private *priv;
37750 +       struct sk_buff *skb;
37751 +       volatile void *pdata;
37752 +       struct ubi32_eth_dma_desc *desc;
37753 +       u32_t   count = 0;
37754 +
37755 +       priv = netdev_priv(dev);
37756 +
37757 +       priv->regs->int_status &= ~UBI32_ETH_VP_INT_TX;
37758 +       while (priv->tx_tail != priv->regs->tx_out) {
37759 +               pdata = priv->regs->tx_dma_ring[priv->tx_tail];
37760 +               BUG_ON(pdata == NULL);
37761 +
37762 +               skb = container_of((void *)pdata, struct sk_buff, cb);
37763 +               desc = (struct ubi32_eth_dma_desc *)pdata;
37764 +               if (unlikely(!(desc->status & UBI32_ETH_VP_TX_OK))) {
37765 +                       atomic_inc((atomic_t *)&priv->stats.tx_errors);
37766 +               } else {
37767 +                       priv->stats.tx_packets++;
37768 +                       priv->stats.tx_bytes += skb->len;
37769 +               }
37770 +               dev_kfree_skb_any(skb);
37771 +               priv->regs->tx_dma_ring[priv->tx_tail] = NULL;
37772 +               priv->tx_tail = (priv->tx_tail + 1) & TX_DMA_RING_MASK;
37773 +               count++;
37774 +       }
37775 +
37776 +       if (unlikely(priv->status & UBI32_ETH_PRIV_STATUS_TX_Q_FULL)) {
37777 +               spin_lock(&priv->lock);
37778 +               priv->status &= ~UBI32_ETH_PRIV_STATUS_TX_Q_FULL;
37779 +               netif_wake_queue(dev);
37780 +               spin_unlock(&priv->lock);
37781 +       }
37782 +       return count;
37783 +}
37784 +
37785 +/*
37786 + * ubi32_eth_receive()
37787 + *     To avoid locking overhead, this is called only
37788 + *     by tasklet when not using NAPI, or
37789 + *     by NAPI poll when using NAPI.
37790 + *     return number of frames processed
37791 + */
37792 +static int ubi32_eth_receive(struct net_device *dev, int quota)
37793 +{
37794 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37795 +       unsigned short rx_in = priv->regs->rx_in;
37796 +       struct sk_buff *skb;
37797 +       struct ubi32_eth_dma_desc *desc = NULL;
37798 +       volatile void *pdata;
37799 +
37800 +       /* The number of NET_SKB_PAD bytes are already reserved by skb */
37801 +       int extra_reserve = UBI32_ETH_RESERVE_SPACE - NET_SKB_PAD + UBI32_ETH_RESERVE_EXTRA;
37802 +       int extra_alloc = extra_reserve + UBI32_ETH_TRASHED_MEMORY;
37803 +       int i, replenish_cnt, count = 0;
37804 +       int replenish_max = RX_DMA_MAX_QUEUE_SIZE;
37805 +#if (defined(CONFIG_ZONE_DMA) && defined(CONFIG_UBICOM32_OCM_FOR_SKB))
37806 +       if (dev == ubi32_eth_devices[0])
37807 +               replenish_max = 21;
37808 +#endif
37809 +       BUG_ON((extra_reserve & 3) != NET_IP_ALIGN);    /* Must provide NET_IP_ALIGN (0 or 2) */
37810 +
37811 +       if (unlikely(rx_in == priv->regs->rx_out))
37812 +               priv->vp_stats.rx_q_full_cnt++;
37813 +
37814 +       priv->regs->int_status &= ~UBI32_ETH_VP_INT_RX;
37815 +       while (priv->rx_tail != priv->regs->rx_out) {
37816 +               if (unlikely(count == quota)) {
37817 +                       /* There is still frame pending to be processed */
37818 +                       priv->vp_stats.rx_throttle++;
37819 +                       break;
37820 +               }
37821 +
37822 +               pdata = priv->regs->rx_dma_ring[priv->rx_tail];
37823 +               BUG_ON(pdata == NULL);
37824 +
37825 +               desc = (struct ubi32_eth_dma_desc *)pdata;
37826 +               skb = container_of((void *)pdata, struct sk_buff, cb);
37827 +               count++;
37828 +               priv->regs->rx_dma_ring[priv->rx_tail] = NULL;
37829 +               priv->rx_tail = ((priv->rx_tail + 1) & RX_DMA_RING_MASK);
37830 +
37831 +               /*
37832 +                * Check only RX_OK bit here.
37833 +                * The rest of status word is used as timestamp
37834 +                */
37835 +               if (unlikely(!(desc->status & UBI32_ETH_VP_RX_OK))) {
37836 +                       priv->stats.rx_errors++;
37837 +                       dev_kfree_skb_any(skb);
37838 +                       continue;
37839 +               }
37840 +
37841 +               skb_put(skb, desc->data_len);
37842 +               skb->dev = dev;
37843 +               skb->protocol = eth_type_trans(skb, dev);
37844 +               skb->ip_summed = CHECKSUM_NONE;
37845 +               priv->stats.rx_bytes += skb->len;
37846 +               priv->stats.rx_packets++;
37847 +#ifndef CONFIG_UBICOM32_NAPI
37848 +               netif_rx(skb);
37849 +#else
37850 +               netif_receive_skb(skb);
37851 +#endif
37852 +       }
37853 +
37854 +       /* fill in more descripor for VP*/
37855 +       replenish_cnt =  replenish_max -
37856 +               ((RX_DMA_RING_SIZE + rx_in - priv->rx_tail) & RX_DMA_RING_MASK);
37857 +       if (replenish_cnt > 0) {
37858 +               for (i = 0; i < replenish_cnt; i++) {
37859 +                       skb = ubi32_alloc_skb(dev, RX_BUF_SIZE + extra_alloc);
37860 +                       if (!skb) {
37861 +                               priv->vp_stats.rx_alloc_err++;
37862 +                               break;
37863 +                       }
37864 +                       /* set up dma descriptor */
37865 +                       desc = (struct ubi32_eth_dma_desc *)skb->cb;
37866 +                       skb_reserve(skb, extra_reserve);
37867 +                       BUG_ON((((u32)skb->data + ETH_HLEN) & (CACHE_LINE_SIZE - 1)) != 0);
37868 +                       desc->data_pointer = skb->data;
37869 +                       desc->buffer_len = RX_BUF_SIZE + UBI32_ETH_TRASHED_MEMORY;
37870 +                       desc->data_len = 0;
37871 +                       desc->status = 0;
37872 +                       priv->regs->rx_dma_ring[rx_in] = desc;
37873 +                       rx_in = (rx_in + 1) & RX_DMA_RING_MASK;
37874 +               }
37875 +               wmb();
37876 +               priv->regs->rx_in = rx_in;
37877 +               ubicom32_set_interrupt(priv->vp_int_bit);
37878 +       }
37879 +
37880 +       if (likely(count > 0)) {
37881 +               dev->last_rx = jiffies;
37882 +       }
37883 +       return count;
37884 +}
37885 +
37886 +#ifdef CONFIG_UBICOM32_NAPI
37887 +static int ubi32_eth_napi_poll(struct napi_struct *napi, int budget)
37888 +{
37889 +       struct ubi32_eth_private *priv = container_of(napi, struct ubi32_eth_private, napi);
37890 +       struct net_device *dev = priv->dev;
37891 +       u32_t count;
37892 +
37893 +       if (priv->tx_tail != priv->regs->tx_out) {
37894 +                ubi32_eth_tx_done(dev);
37895 +        }
37896 +
37897 +       count = ubi32_eth_receive(dev, budget);
37898 +
37899 +       priv->regs->int_mask |= (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
37900 +       if (count < budget) {
37901 +               netif_rx_complete(dev, napi);
37902 +               if ((priv->rx_tail != priv->regs->rx_out) || (priv->tx_tail != priv->regs->tx_out)) {
37903 +                       if (netif_rx_reschedule(dev, napi)) {
37904 +                               priv->regs->int_mask = 0;
37905 +                       }
37906 +               }
37907 +       }
37908 +       return count;
37909 +}
37910 +
37911 +#else
37912 +static void ubi32_eth_do_tasklet(unsigned long arg)
37913 +{
37914 +       struct net_device *dev = (struct net_device *)arg;
37915 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37916 +
37917 +       if (priv->tx_tail != priv->regs->tx_out) {
37918 +               ubi32_eth_tx_done(dev);
37919 +       }
37920 +
37921 +       /* always call receive to process new RX frame as well as replenish RX buffers */
37922 +       ubi32_eth_receive(dev, RX_BOUND);
37923 +
37924 +       priv->regs->int_mask |= (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
37925 +       if ((priv->rx_tail != priv->regs->rx_out) || (priv->tx_tail != priv->regs->tx_out)) {
37926 +               priv->regs->int_mask = 0;
37927 +               tasklet_schedule(&priv->tsk);
37928 +       }
37929 +}
37930 +#endif
37931 +
37932 +#if defined(USE_POLLING)
37933 +static struct timer_list eth_poll_timer;
37934 +
37935 +static void ubi32_eth_poll(unsigned long arg)
37936 +{
37937 +       struct net_device *dev;
37938 +       struct ubi32_eth_private *priv;
37939 +       int i;
37940 +
37941 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
37942 +               dev = ubi32_eth_devices[i];
37943 +               if (dev && (dev->flags & IFF_UP)) {
37944 +                       priv = netdev_priv(dev);
37945 +#ifdef CONFIG_UBICOM32_NAPI
37946 +                       netif_rx_schedule(dev, &priv->napi);
37947 +#else
37948 +                       tasklet_schedule(&priv->tsk);
37949 +#endif
37950 +               }
37951 +       }
37952 +
37953 +       eth_poll_timer.expires = jiffies + 2;
37954 +       add_timer(&eth_poll_timer);
37955 +}
37956 +
37957 +#else
37958 +static irqreturn_t ubi32_eth_interrupt(int irq, void *dev_id)
37959 +{
37960 +       struct ubi32_eth_private *priv;
37961 +
37962 +       struct net_device *dev = (struct net_device *)dev_id;
37963 +       BUG_ON(irq != dev->irq);
37964 +
37965 +       priv = netdev_priv(dev);
37966 +       if (unlikely(!(priv->regs->int_status & priv->regs->int_mask))) {
37967 +               return IRQ_NONE;
37968 +       }
37969 +
37970 +       /*
37971 +        * Disable port interrupt
37972 +        */
37973 +#ifdef CONFIG_UBICOM32_NAPI
37974 +       if (netif_rx_schedule_prep(dev, &priv->napi)) {
37975 +               priv->regs->int_mask = 0;
37976 +               __netif_rx_schedule(dev, &priv->napi);
37977 +       }
37978 +#else
37979 +       priv->regs->int_mask = 0;
37980 +       tasklet_schedule(&priv->tsk);
37981 +#endif
37982 +       return IRQ_HANDLED;
37983 +}
37984 +#endif
37985 +
37986 +/*
37987 + * ubi32_eth_open
37988 + */
37989 +static int ubi32_eth_open(struct net_device *dev)
37990 +{
37991 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37992 +       int err;
37993 +
37994 +       printk(KERN_INFO "eth open %s\n",dev->name);
37995 +#ifndef USE_POLLING
37996 +       /* request_region() */
37997 +       err = request_irq(dev->irq, ubi32_eth_interrupt, IRQF_DISABLED, dev->name, dev);
37998 +       if (err) {
37999 +               printk(KERN_WARNING "fail to request_irq %d\n",err);
38000 +                return -ENODEV;
38001 +       }
38002 +#endif
38003 +#ifdef  CONFIG_UBICOM32_NAPI
38004 +       napi_enable(&priv->napi);
38005 +#else
38006 +       tasklet_init(&priv->tsk, ubi32_eth_do_tasklet, (unsigned long)dev);
38007 +#endif
38008 +
38009 +       /* call receive to supply RX buffers */
38010 +       ubi32_eth_receive(dev, RX_DMA_MAX_QUEUE_SIZE);
38011 +
38012 +       /* check phy status and call netif_carrier_on */
38013 +       ubi32_eth_vp_rxtx_enable(dev);
38014 +       netif_start_queue(dev);
38015 +       return 0;
38016 +}
38017 +
38018 +static int ubi32_eth_close(struct net_device *dev)
38019 +{
38020 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38021 +       volatile void *pdata;
38022 +       struct sk_buff *skb;
38023 +
38024 +#ifndef USE_POLLING
38025 +       free_irq(dev->irq, dev);
38026 +#endif
38027 +       netif_stop_queue(dev); /* can't transmit any more */
38028 +#ifdef CONFIG_UBICOM32_NAPI
38029 +       napi_disable(&priv->napi);
38030 +#else
38031 +       tasklet_kill(&priv->tsk);
38032 +#endif
38033 +       ubi32_eth_vp_rxtx_stop(dev);
38034 +
38035 +       /*
38036 +        * RX clean up
38037 +        */
38038 +       while (priv->rx_tail != priv->regs->rx_in) {
38039 +               pdata = priv->regs->rx_dma_ring[priv->rx_tail];
38040 +               skb = container_of((void *)pdata, struct sk_buff, cb);
38041 +               priv->regs->rx_dma_ring[priv->rx_tail] = NULL;
38042 +               dev_kfree_skb_any(skb);
38043 +               priv->rx_tail = ((priv->rx_tail + 1) & RX_DMA_RING_MASK);
38044 +       }
38045 +       priv->regs->rx_in = 0;
38046 +       priv->regs->rx_out = priv->regs->rx_in;
38047 +       priv->rx_tail = priv->regs->rx_in;
38048 +
38049 +       /*
38050 +        * TX clean up
38051 +        */
38052 +       BUG_ON(priv->regs->tx_out != priv->regs->tx_in);
38053 +       ubi32_eth_tx_done(dev);
38054 +       BUG_ON(priv->tx_tail != priv->regs->tx_in);
38055 +       priv->regs->tx_in = 0;
38056 +       priv->regs->tx_out = priv->regs->tx_in;
38057 +       priv->tx_tail = priv->regs->tx_in;
38058 +
38059 +       return 0;
38060 +}
38061 +
38062 +/*
38063 + * ubi32_eth_set_config
38064 + */
38065 +static int ubi32_eth_set_config(struct net_device *dev, struct ifmap *map)
38066 +{
38067 +       /* if must to down to config it */
38068 +       printk(KERN_INFO "set_config %x\n", dev->flags);
38069 +       if (dev->flags & IFF_UP)
38070 +               return -EBUSY;
38071 +
38072 +       /* I/O and IRQ can not be changed */
38073 +       if (map->base_addr != dev->base_addr) {
38074 +               printk(KERN_WARNING "%s: Can't change I/O address\n", dev->name);
38075 +               return -EOPNOTSUPP;
38076 +       }
38077 +
38078 +#ifndef USE_POLLING
38079 +       if (map->irq != dev->irq) {
38080 +               printk(KERN_WARNING "%s: Can't change IRQ\n", dev->name);
38081 +               return -EOPNOTSUPP;
38082 +       }
38083 +#endif
38084 +
38085 +       /* ignore other fields */
38086 +       return 0;
38087 +}
38088 +
38089 +static int ubi32_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
38090 +{
38091 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38092 +       struct ubi32_eth_dma_desc *desc = NULL;
38093 +       unsigned short space, tx_in;
38094 +
38095 +       tx_in = priv->regs->tx_in;
38096 +
38097 +       dev->trans_start = jiffies; /* save the timestamp */
38098 +       space = TX_DMA_RING_MASK - ((TX_DMA_RING_SIZE + tx_in - priv->tx_tail) & TX_DMA_RING_MASK);
38099 +
38100 +       if (unlikely(space == 0)) {
38101 +               atomic_inc((atomic_t *)&priv->stats.tx_errors);
38102 +               if (!(priv->status & UBI32_ETH_PRIV_STATUS_TX_Q_FULL)) {
38103 +                       spin_lock(&priv->lock);
38104 +                       priv->status |= UBI32_ETH_PRIV_STATUS_TX_Q_FULL;
38105 +                       priv->vp_stats.tx_q_full_cnt++;
38106 +                       netif_stop_queue(dev);
38107 +                       spin_unlock(&priv->lock);
38108 +               }
38109 +
38110 +               /* give both HW and this driver an extra trigger */
38111 +               priv->regs->int_mask |= UBI32_ETH_VP_INT_TX;
38112 +#ifndef USE_POLLING
38113 +               ubicom32_set_interrupt(dev->irq);
38114 +#endif
38115 +               ubicom32_set_interrupt(priv->vp_int_bit);
38116 +
38117 +               return NETDEV_TX_BUSY;
38118 +       }
38119 +
38120 +       /*still have room */
38121 +       desc = (struct ubi32_eth_dma_desc *)skb->cb;
38122 +       desc->data_pointer = skb->data;
38123 +       desc->data_len = skb->len;
38124 +       priv->regs->tx_dma_ring[tx_in] = desc;
38125 +       tx_in = ((tx_in + 1) & TX_DMA_RING_MASK);
38126 +       wmb();
38127 +       priv->regs->tx_in = tx_in;
38128 +       /* kick the HRT */
38129 +       ubicom32_set_interrupt(priv->vp_int_bit);
38130 +
38131 +       return 0;
38132 +}
38133 +
38134 +/*
38135 + * Deal with a transmit timeout.
38136 + */
38137 +static void ubi32_eth_tx_timeout (struct net_device *dev)
38138 +{
38139 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38140 +       atomic_inc((atomic_t *)&priv->stats.tx_errors);
38141 +       priv->regs->int_mask |= UBI32_ETH_VP_INT_TX;
38142 +#ifndef USE_POLLING
38143 +       ubicom32_set_interrupt(dev->irq);
38144 +#endif
38145 +       ubicom32_set_interrupt(priv->vp_int_bit);
38146 +}
38147 +
38148 +static int ubi32_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
38149 +{
38150 +       printk(KERN_INFO "ioctl %s, %d\n", dev->name, cmd);
38151 +       return -EINVAL;
38152 +}
38153 +
38154 +/*
38155 + * Return statistics to the caller
38156 + */
38157 +static struct net_device_stats *ubi32_eth_get_stats(struct net_device *dev)
38158 +{
38159 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38160 +       return &priv->stats;
38161 +}
38162 +
38163 +
38164 +static int ubi32_eth_change_mtu(struct net_device *dev, int new_mtu)
38165 +{
38166 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38167 +       unsigned long flags;
38168 +
38169 +       if ((new_mtu < 68) || (new_mtu > 1500))
38170 +               return -EINVAL;
38171 +
38172 +       spin_lock_irqsave(&priv->lock, flags);
38173 +       dev->mtu = new_mtu;
38174 +       spin_unlock_irqrestore(&priv->lock, flags);
38175 +       printk(KERN_INFO "set mtu to %d", new_mtu);
38176 +       return 0;
38177 +}
38178 +
38179 +/*
38180 + * ubi32_eth_cleanup: unload the module
38181 + */
38182 +void ubi32_eth_cleanup(void)
38183 +{
38184 +       struct ubi32_eth_private *priv;
38185 +       struct net_device *dev;
38186 +       int i;
38187 +
38188 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38189 +               dev = ubi32_eth_devices[i];
38190 +               if (dev) {
38191 +                       priv = netdev_priv(dev);
38192 +                       kfree(priv->regs->tx_dma_ring);
38193 +                       unregister_netdev(dev);
38194 +                       free_netdev(dev);
38195 +                       ubi32_eth_devices[i] = NULL;
38196 +               }
38197 +       }
38198 +}
38199 +
38200 +int ubi32_eth_init_module(void)
38201 +{
38202 +       struct ethtionode *eth_node;
38203 +       struct net_device *dev;
38204 +       struct ubi32_eth_private *priv;
38205 +       int i, err;
38206 +
38207 +       /*
38208 +        * Device allocation.
38209 +        */
38210 +       err = 0;
38211 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38212 +               /*
38213 +                * See if the eth_vp is in the device tree.
38214 +                */
38215 +               eth_node = (struct ethtionode *)devtree_find_node(eth_if_name[i]);
38216 +               if (!eth_node) {
38217 +                       printk(KERN_INFO "%s does not exist\n", eth_if_name[i]);
38218 +                       continue;
38219 +               }
38220 +
38221 +               eth_node->tx_dma_ring = (struct ubi32_eth_dma_desc **)kmalloc(
38222 +                               sizeof(struct ubi32_eth_dma_desc *) *
38223 +                               (TX_DMA_RING_SIZE + RX_DMA_RING_SIZE), GFP_ATOMIC | __GFP_NOWARN | __GFP_NORETRY | GFP_DMA);
38224 +
38225 +               if (eth_node->tx_dma_ring == NULL) {
38226 +                       eth_node->tx_dma_ring = (struct ubi32_eth_dma_desc **)kmalloc(
38227 +                               sizeof(struct ubi32_eth_dma_desc *) *
38228 +                               (TX_DMA_RING_SIZE + RX_DMA_RING_SIZE), GFP_KERNEL);
38229 +                       printk(KERN_INFO "Failed to allocate from OCM\n");
38230 +               }
38231 +
38232 +               if (!eth_node->tx_dma_ring) {
38233 +                       err = -ENOMEM;
38234 +                       break;
38235 +               }
38236 +               eth_node->rx_dma_ring = eth_node->tx_dma_ring + TX_DMA_RING_SIZE;
38237 +               eth_node->tx_sz = TX_DMA_RING_SIZE - 1;
38238 +               eth_node->rx_sz = RX_DMA_RING_SIZE - 1;
38239 +
38240 +               dev = alloc_etherdev(sizeof(struct ubi32_eth_private));
38241 +               if (!dev) {
38242 +                       kfree(eth_node->tx_dma_ring);
38243 +                       err = -ENOMEM;
38244 +                       break;
38245 +               }
38246 +               priv = netdev_priv(dev);
38247 +               priv->dev = dev;
38248 +
38249 +               /*
38250 +                * FIX IT! get proper mac address
38251 +                */
38252 +               memcpy(dev->dev_addr, mac_addr[i], ETH_ALEN);
38253 +
38254 +               priv->regs = eth_node;
38255 +               priv->regs->command = 0;
38256 +               priv->regs->int_mask = 0;
38257 +               priv->regs->int_status = 0;
38258 +               priv->regs->tx_out = 0;
38259 +               priv->regs->rx_out = 0;
38260 +               priv->regs->tx_in = 0;
38261 +               priv->regs->rx_in = 0;
38262 +               priv->rx_tail = 0;
38263 +               priv->tx_tail = 0;
38264 +
38265 +               priv->vp_int_bit = eth_node->dn.sendirq;
38266 +               dev->irq = eth_node->dn.recvirq;
38267 +
38268 +               spin_lock_init(&priv->lock);
38269 +
38270 +               dev->open               = ubi32_eth_open;
38271 +               dev->stop               = ubi32_eth_close;
38272 +               dev->hard_start_xmit    = ubi32_eth_start_xmit;
38273 +               dev->tx_timeout         = ubi32_eth_tx_timeout;
38274 +               dev->watchdog_timeo     = UBI32_ETH_VP_TX_TIMEOUT;
38275 +
38276 +               dev->set_config         = ubi32_eth_set_config;
38277 +               dev->do_ioctl           = ubi32_eth_ioctl;
38278 +               dev->get_stats          = ubi32_eth_get_stats;
38279 +               dev->change_mtu         = ubi32_eth_change_mtu;
38280 +#ifdef CONFIG_UBICOM32_NAPI
38281 +               netif_napi_add(dev, &priv->napi, ubi32_eth_napi_poll, UBI32_ETH_NAPI_WEIGHT);
38282 +#endif
38283 +               err = register_netdev(dev);
38284 +               if (err) {
38285 +                       printk(KERN_WARNING "Failed to register netdev %s\n", eth_if_name[i]);
38286 +                       //release_region();
38287 +                       free_netdev(dev);
38288 +                       kfree(eth_node->tx_dma_ring);
38289 +                       break;
38290 +               }
38291 +
38292 +               ubi32_eth_devices[i] = dev;
38293 +               printk(KERN_INFO "%s vp_base:0x%p, tio_int:%d irq:%d\n",
38294 +                       dev->name, priv->regs, eth_node->dn.sendirq, dev->irq);
38295 +       }
38296 +
38297 +       if (err) {
38298 +               ubi32_eth_cleanup();
38299 +               return err;
38300 +       }
38301 +
38302 +       if (!ubi32_eth_devices[0] && !ubi32_eth_devices[1] && !ubi32_eth_devices[2]) {
38303 +               return -ENODEV;
38304 +       }
38305 +
38306 +#if defined(USE_POLLING)
38307 +       init_timer(&eth_poll_timer);
38308 +       eth_poll_timer.function = ubi32_eth_poll;
38309 +       eth_poll_timer.data = (unsigned long)0;
38310 +       eth_poll_timer.expires = jiffies + 2;
38311 +       add_timer(&eth_poll_timer);
38312 +#endif
38313 +
38314 +       return 0;
38315 +}
38316 +
38317 +module_init(ubi32_eth_init_module);
38318 +module_exit(ubi32_eth_cleanup);
38319 +
38320 +MODULE_AUTHOR("Kan Yan, Greg Ren");
38321 +MODULE_LICENSE("GPL");
38322 --- /dev/null
38323 +++ b/drivers/net/ubi32-eth.h
38324 @@ -0,0 +1,133 @@
38325 +/*
38326 + * drivers/net/ubi32-eth.h
38327 + *   Ubicom32 ethernet TIO interface driver definitions.
38328 + *
38329 + * (C) Copyright 2009, Ubicom, Inc.
38330 + *
38331 + * This file is part of the Ubicom32 Linux Kernel Port.
38332 + *
38333 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
38334 + * it and/or modify it under the terms of the GNU General Public License
38335 + * as published by the Free Software Foundation, either version 2 of the
38336 + * License, or (at your option) any later version.
38337 + *
38338 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
38339 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
38340 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
38341 + * the GNU General Public License for more details.
38342 + *
38343 + * You should have received a copy of the GNU General Public License
38344 + * along with the Ubicom32 Linux Kernel Port.  If not,
38345 + * see <http://www.gnu.org/licenses/>.
38346 + *
38347 + * Ubicom32 implementation derived from (with many thanks):
38348 + *   arch/m68knommu
38349 + *   arch/blackfin
38350 + *   arch/parisc
38351 + */
38352 +#ifndef _UBI32_ETH_H
38353 +#define _UBI32_ETH_H
38354 +
38355 +#include <asm/devtree.h>
38356 +
38357 +#define UBI32_ETH_NUM_OF_DEVICES 3
38358 +
38359 +/*
38360 + * Number of bytes trashed beyond the packet data.
38361 + */
38362 +#define UBI32_ETH_TRASHED_MEMORY       (CACHE_LINE_SIZE + ETH_HLEN - 1)
38363 +
38364 +/*
38365 + * Linux already reserves NET_SKB_PAD bytes of headroom in each sk_buff.
38366 + * We want to be able to reserve arbitrarily more space to align Ethernet
38367 + * and IP header to cache line.
38368 + * Note that the TIO expects a CACHE_LINE_SIZE - ETH_HLEN aligned Ethernet
38369 + * header, so the reserved space must be NET_SKB_PAD + NET_IP_ALIGN.
38370 + * (NET_SKB_PAD is 16, NET_IP_ALIGN is 2, CACHE_LINE_SIZE is 32).
38371 + * You can add more space by making UBI32_ETH_iRESERVE_EXTRA != 0.
38372 + */
38373 +#define UBI32_ETH_RESERVE_SPACE        (CACHE_LINE_SIZE - ETH_HLEN)
38374 +#define UBI32_ETH_RESERVE_EXTRA (1 * CACHE_LINE_SIZE)
38375 +
38376 +struct ubi32_eth_dma_desc {
38377 +       volatile void   *data_pointer;  /* pointer to the buffer */
38378 +       volatile u16    buffer_len;     /* the buffer size */
38379 +       volatile u16    data_len;       /* actual frame length */
38380 +       volatile u32    status;         /* bit0: status to be update by VP; bit[31:1] time stamp */
38381 +};
38382 +
38383 +#define TX_DMA_RING_SIZE (1<<8)
38384 +#define TX_DMA_RING_MASK (TX_DMA_RING_SIZE - 1)
38385 +#define RX_DMA_RING_SIZE (1<<8)
38386 +#define RX_DMA_RING_MASK (RX_DMA_RING_SIZE - 1)
38387 +
38388 +#define RX_DMA_MAX_QUEUE_SIZE (RX_DMA_RING_SIZE - 1)   /* no more than (RX_DMA_RING_SIZE - 1) */
38389 +#define RX_MAX_PKT_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN)
38390 +#define RX_MIN_PKT_SIZE        ETH_ZLEN
38391 +#define RX_BUF_SIZE (RX_MAX_PKT_SIZE + VLAN_HLEN)      /* allow double VLAN tag */
38392 +
38393 +#define UBI32_ETH_VP_TX_TIMEOUT (10*HZ)
38394 +
38395 +struct ubi32_eth_vp_stats {
38396 +       u32     rx_alloc_err;
38397 +       u32     tx_q_full_cnt;
38398 +       u32     rx_q_full_cnt;
38399 +       u32     rx_throttle;
38400 +};
38401 +
38402 +struct ubi32_eth_private {
38403 +       struct net_device *dev;
38404 +       struct net_device_stats stats;
38405 +       struct ubi32_eth_vp_stats vp_stats;
38406 +       int status;
38407 +       spinlock_t lock;
38408 +#ifdef CONFIG_UBICOM32_NAPI
38409 +       struct napi_struct napi;
38410 +#else
38411 +       struct tasklet_struct tsk;
38412 +#endif
38413 +       struct ethtionode *regs;
38414 +       u16     rx_tail;
38415 +       u16     tx_tail;
38416 +       u32     vp_int_bit;
38417 +};
38418 +
38419 +struct ethtionode {
38420 +       struct devtree_node dn;
38421 +       volatile u16    command;
38422 +       volatile u16    status;
38423 +       volatile u16    int_mask;       /* interrupt mask */
38424 +       volatile u16    int_status;     /* interrupt mask */
38425 +       volatile u16    tx_in;          /* owned by driver */
38426 +       volatile u16    tx_out;         /* owned by vp */
38427 +       volatile u16    rx_in;          /* owned by driver */
38428 +       volatile u16    rx_out;         /* owned by vp */
38429 +       u16             tx_sz;          /* owned by driver */
38430 +       u16             rx_sz;          /* owned by driver */
38431 +       struct ubi32_eth_dma_desc **tx_dma_ring;
38432 +       struct ubi32_eth_dma_desc **rx_dma_ring;
38433 +};
38434 +
38435 +#define UBI32_ETH_VP_STATUS_LINK       (1<<0)
38436 +#define UBI32_ETH_VP_STATUS_SPEED      (0x2<<1)
38437 +#define UBI32_ETH_VP_STATUS_DUPLEX     (0x1<<3)
38438 +#define UBI32_ETH_VP_STATUS_FLOW_CTRL  (0x1<<4)
38439 +
38440 +#define UBI32_ETH_VP_STATUS_RX_STATE   (0x1<<5)
38441 +#define UBI32_ETH_VP_STATUS_TX_STATE   (0x1<<6)
38442 +
38443 +#define UBI32_ETH_PRIV_STATUS_TX_Q_FULL        (1<<0)
38444 +
38445 +#define UBI32_ETH_VP_INT_RX    (1<<0)
38446 +#define UBI32_ETH_VP_INT_TX    (1<<1)
38447 +
38448 +#define UBI32_ETH_VP_CMD_RX_ENABLE     (1<<0)
38449 +#define UBI32_ETH_VP_CMD_TX_ENABLE     (1<<1)
38450 +
38451 +#define UBI32_ETH_VP_RX_OK             (1<<0)
38452 +#define UBI32_ETH_VP_TX_OK             (1<<1)
38453 +
38454 +#define TX_BOUND               TX_DMA_RING_SIZE
38455 +#define RX_BOUND               64
38456 +#define UBI32_ETH_NAPI_WEIGHT  64              /* for GigE */
38457 +#endif
38458 --- a/drivers/net/usb/asix.c
38459 +++ b/drivers/net/usb/asix.c
38460 @@ -318,14 +318,33 @@ static int asix_rx_fixup(struct usbnet *
38461                 /* get the packet length */
38462                 size = (u16) (header & 0x0000ffff);
38463  
38464 -               if ((skb->len) - ((size + 1) & 0xfffe) == 0)
38465 +               if ((skb->len) - ((size + 1) & 0xfffe) == 0) {
38466 +#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
38467 +                       if (((u32)packet & 0x02) == 0) {
38468 +                               memmove(packet - 2, packet, size);
38469 +                               skb->data -= 2;
38470 +                               skb->tail -= 2;
38471 +                       }
38472 +#endif
38473                         return 2;
38474 +               }
38475 +
38476                 if (size > ETH_FRAME_LEN) {
38477                         deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);
38478                         return 0;
38479                 }
38480                 ax_skb = skb_clone(skb, GFP_ATOMIC);
38481                 if (ax_skb) {
38482 +#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
38483 +                       if (((u32)packet & 0x02) == 0) {
38484 +                               memmove(packet - 2, packet, size);
38485 +                               ax_skb->data = packet - 2;
38486 +                       } else {
38487 +                               ax_skb->data = packet;
38488 +                       }
38489 +#else
38490 +                       ax_skb->data = packet;
38491 +#endif
38492                         ax_skb->len = size;
38493                         ax_skb->data = packet;
38494                         skb_set_tail_pointer(ax_skb, size);
38495 @@ -1102,13 +1121,19 @@ static int ax88178_link_reset(struct usb
38496         mode = AX88178_MEDIUM_DEFAULT;
38497  
38498         if (ecmd.speed == SPEED_1000)
38499 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38500                 mode |= AX_MEDIUM_GM;
38501 +#else
38502 +               mode |= AX_MEDIUM_GM | AX_MEDIUM_ENCK;
38503 +#endif
38504         else if (ecmd.speed == SPEED_100)
38505                 mode |= AX_MEDIUM_PS;
38506         else
38507                 mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
38508  
38509 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38510         mode |= AX_MEDIUM_ENCK;
38511 +#endif
38512  
38513         if (ecmd.duplex == DUPLEX_FULL)
38514                 mode |= AX_MEDIUM_FD;
38515 --- a/drivers/oprofile/cpu_buffer.c
38516 +++ b/drivers/oprofile/cpu_buffer.c
38517 @@ -240,10 +240,11 @@ static void oprofile_end_trace(struct op
38518         cpu_buf->tracing = 0;
38519  }
38520  
38521 -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38522 -                               unsigned long event, int is_kernel)
38523 +
38524 +void oprofile_add_ext_sample_cpu(unsigned long pc, struct pt_regs * const regs,
38525 +                               unsigned long event, int is_kernel, int cpu)
38526  {
38527 -       struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
38528 +       struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu);
38529  
38530         if (!backtrace_depth) {
38531                 log_sample(cpu_buf, pc, is_kernel, event);
38532 @@ -260,6 +261,13 @@ void oprofile_add_ext_sample(unsigned lo
38533         oprofile_end_trace(cpu_buf);
38534  }
38535  
38536 +void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38537 +                               unsigned long event, int is_kernel)
38538 +{
38539 +       oprofile_add_ext_sample_cpu(pc, regs, event,
38540 +                                       is_kernel, smp_processor_id());
38541 +}
38542 +
38543  void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
38544  {
38545         int is_kernel = !user_mode(regs);
38546 --- a/drivers/pci/Makefile
38547 +++ b/drivers/pci/Makefile
38548 @@ -42,8 +42,8 @@ obj-$(CONFIG_PPC) += setup-bus.o
38549  obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
38550  obj-$(CONFIG_X86_VISWS) += setup-irq.o
38551  obj-$(CONFIG_MN10300) += setup-bus.o
38552 +obj-$(CONFIG_UBICOM32) += setup-bus.o setup-irq.o
38553  
38554 -#
38555  # ACPI Related PCI FW Functions
38556  #
38557  obj-$(CONFIG_ACPI)    += pci-acpi.o
38558 --- a/drivers/serial/Kconfig
38559 +++ b/drivers/serial/Kconfig
38560 @@ -827,6 +827,57 @@ config SERIAL_UARTLITE_CONSOLE
38561           console (the system console is the device which receives all kernel
38562           messages and warnings and which allows logins in single user mode).
38563  
38564 +config SERIAL_UBI32_UARTTIO
38565 +        tristate "Ubicom UARTTIO support"
38566 +        depends on UBICOM32=y
38567 +        select SERIAL_CORE
38568 +       default y
38569 +        help
38570 +          Add support for the Ubicom virtual peripherial serial interface.
38571 +
38572 +config SERIAL_UBI32_UARTTIO_NR_UARTS
38573 +       int "Maximum number of UARTTIO virtual serial ports"
38574 +       depends on SERIAL_UBI32_UARTTIO
38575 +       default "4"
38576 +       help
38577 +         Set this to the maximum number of serial ports you want the driver to support.  
38578 +
38579 +config SERIAL_UBI32_UARTTIO_CONSOLE
38580 +        tristate "Ubicom UARTTIO console support"
38581 +        depends on SERIAL_UBI32_UARTTIO=y
38582 +        select SERIAL_CORE_CONSOLE
38583 +       default y
38584 +        help
38585 +          Add support for console on the Ubicom virtual peripherial serial interface.
38586 +
38587 +config SERIAL_UBI32_SERDES
38588 +        bool "Ubicom serial port support"
38589 +        depends on UBICOM32=y
38590 +        select SERIAL_CORE
38591 +       default y
38592 +        help
38593 +          Add support for the Ubicom serial interface.
38594 +
38595 +config SERIAL_UBI32_SERDES_CONSOLE
38596 +        bool "Ubicom serial console support"
38597 +        depends on SERIAL_UBI32_SERDES=y
38598 +        select SERIAL_CORE_CONSOLE
38599 +       default y
38600 +
38601 +config SERIAL_UBI32_MAILBOX
38602 +        bool "Ubicom mailbox support"
38603 +        depends on UBICOM32=y
38604 +        select SERIAL_CORE
38605 +       default n
38606 +        help
38607 +          Add support for the Ubicom mailbox interface.
38608 +
38609 +config SERIAL_UBI32_MAILBOX_CONSOLE
38610 +        bool "Ubicom mailbox console support"
38611 +        depends on SERIAL_UBI32_MAILBOX=y
38612 +        select SERIAL_CORE_CONSOLE
38613 +       default y
38614 +
38615  config SERIAL_SUNCORE
38616         bool
38617         depends on SPARC
38618 --- a/drivers/serial/Makefile
38619 +++ b/drivers/serial/Makefile
38620 @@ -73,3 +73,6 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_s
38621  obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
38622  obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
38623  obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
38624 +obj-$(CONFIG_SERIAL_UBI32_SERDES) += ubi32_serdes.o
38625 +obj-$(CONFIG_SERIAL_UBI32_UARTTIO) += ubi32_uarttio.o
38626 +obj-$(CONFIG_SERIAL_UBI32_MAILBOX) += ubi32_mailbox.o
38627 --- /dev/null
38628 +++ b/drivers/serial/ubi32_mailbox.c
38629 @@ -0,0 +1,928 @@
38630 +/*
38631 + * drivers/serial/ubi32_mailbox.c
38632 + *   Ubicom32 On-Chip Mailbox Driver
38633 + *
38634 + * (C) Copyright 2009, Ubicom, Inc.
38635 + *
38636 + * This file is part of the Ubicom32 Linux Kernel Port.
38637 + *
38638 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
38639 + * it and/or modify it under the terms of the GNU General Public License
38640 + * as published by the Free Software Foundation, either version 2 of the
38641 + * License, or (at your option) any later version.
38642 + *
38643 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
38644 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
38645 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
38646 + * the GNU General Public License for more details.
38647 + *
38648 + * You should have received a copy of the GNU General Public License
38649 + * along with the Ubicom32 Linux Kernel Port.  If not, 
38650 + * see <http://www.gnu.org/licenses/>.
38651 + *
38652 + * Ubicom32 implementation derived from (with many thanks):
38653 + *   arch/m68knommu
38654 + *   arch/blackfin
38655 + *   arch/parisc
38656 + */
38657 +#include <linux/module.h>
38658 +#include <linux/ioport.h>
38659 +#include <linux/init.h>
38660 +#include <linux/console.h>
38661 +#include <linux/sysrq.h>
38662 +#include <linux/platform_device.h>
38663 +#include <linux/tty.h>
38664 +#include <linux/tty_flip.h>
38665 +#include <linux/serial_core.h>
38666 +
38667 +#include <asm/ip5000.h>
38668 +
38669 +#define SERIAL_UBICOM_BAUDRATE 115200
38670 +#define SERIAL_UBICOM_DATA_BIT 8       /* Fixed parameter - do not change */
38671 +#define SERIAL_UBICOM_PAR_BIT  0       /* Fixed parameter - do not change */
38672 +#define SERIAL_UBICOM_STOP_BIT 1       /* Fixed parameter - do not change */
38673 +
38674 +/* UART name and device definitions */
38675 +#define UBI32_MAILBOX_NAME     "ttyUM" // XXX
38676 +#define UBI32_MAILBOX_MAJOR    207 // XXX
38677 +#define UBI32_MAILBOX_MINOR    64
38678 +
38679 +#define PORT_UBI32_MAILBOX     1235
38680 +#define NR_PORTS 1
38681 +
38682 +#define get_sclk() 0
38683 +
38684 +struct ubi32_mailbox_port {
38685 +       struct uart_port port;
38686 +       /*
38687 +        * NOTE (rkeller):
38688 +        * the uart port is wrapped in another structure in case we need to hold more state than 
38689 +        * what we can hold in the uart_port.
38690 +        * Not sure if we need this, I took over the concept from the blackfin driver.
38691 +        */
38692 +} ubi32_mailbox_ports[NR_PORTS];
38693 +
38694 +struct ubi32_mailbox_resource {
38695 +       int uart_base_addr;
38696 +       int uart_irq;
38697 +} ubi32_mailbox_resource[NR_PORTS] = {
38698 +       /*
38699 +        * uart_base_addr has to be non-NULL because it is put in the uart_port membase.
38700 +        * If membase if null the kernel skips the configuration and our port_type never gets set.
38701 +        */
38702 +       {ISD_MAILBOX_BASE, ISD_MAILBOX_INT}
38703 +};
38704 +
38705 +static volatile struct ubicom32_isd_mailbox {
38706 +       volatile u32_t in;
38707 +       volatile u32_t out;
38708 +       volatile u32_t status;
38709 +} *ubi32_mailbox = (struct ubicom32_isd_mailbox *)ISD_MAILBOX_BASE;
38710 +
38711 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart);
38712 +
38713 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart);
38714 +
38715 +#define TRUE 1
38716 +#define FALSE 0
38717 +
38718 +static int mailbox_console_flg = TRUE;
38719 +static int num_timeouts = 0;
38720 +
38721 +/*
38722 + * dummy functions and defined to be able to compile the Blackfin code
38723 + */
38724 +#define UART_GET_LSR(port) (1)
38725 +#define UART_PUT_LSR(port, bits)
38726 +#define UART_CLEAR_LSR(port) (1)
38727 +#define TEMT 1
38728 +#define TFI 1
38729 +#define BI 1
38730 +#define PE 1
38731 +#define OE 1
38732 +#define FE 1
38733 +#define THRE 1
38734 +#define DR 1
38735 +#define UART_GET_LCR(port) (1)
38736 +#define UART_PUT_LCR(port, bits)
38737 +#define SB 1
38738 +#define STB 1
38739 +#define PEN 1
38740 +#define EPS 1
38741 +#define STP 1
38742 +#define WLS(n) 0
38743 +#define UART_GET_IER(port) (1)
38744 +#define UART_SET_IER(port, bits)
38745 +#define UART_CLEAR_IER(port, bits)
38746 +#define ETBEI 0
38747 +#define ERBFI 0
38748 +#define UART_GET_CHAR(port) ubi32_mailbox_get_char()
38749 +#define UART_PUT_CHAR(port, ch) ubi32_mailbox_put_char(ch)
38750 +#define SSYNC()
38751 +#define UART_GET_DLL(port) 0
38752 +#define UART_PUT_DLL(port, ch)
38753 +#define UART_GET_DLH(port) 0
38754 +#define UART_PUT_DLH(port, ch)
38755 +#define UART_GET_GCTL(port) (0)
38756 +#define UART_PUT_GCTL(port, ch)
38757 +#define UCEN 1
38758 +
38759 +/*
38760 + * ubi32_mailbox_get_char_avail()
38761 + */
38762 +static int ubi32_mailbox_get_char_avail(void)
38763 +{
38764 +       return !(ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38765 +}
38766 +
38767 +/*
38768 + * ubi32_mailbox_get_char()
38769 + */
38770 +static u32_t ubi32_mailbox_get_char(void)
38771 +{
38772 +       if (mailbox_console_flg == TRUE) {
38773 +               /*
38774 +                * Mailbox console is connected.
38775 +                */
38776 +               while (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38777 +               return ubi32_mailbox->in & 0xff;
38778 +       }
38779 +
38780 +       /*
38781 +        * Mailbox console was not connected.
38782 +        */
38783 +       if (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY) {
38784 +               return 0xff;
38785 +       }
38786 +
38787 +       /*
38788 +        * Mailbox console is connecting.
38789 +        */
38790 +       mailbox_console_flg = TRUE;
38791 +       num_timeouts = 0;
38792 +       return ubi32_mailbox->in & 0xff;
38793 +}
38794 +
38795 +#define MAILBOX_MAX_ATTEMPTS 1000000
38796 +#define MAILBOX_MAX_TIMEOUTS 5
38797 +/*
38798 + * ubi32_mailbox_put_char()
38799 + */
38800 +static void ubi32_mailbox_put_char(u32_t v)
38801 +{
38802 +       /*
38803 +        * Wait to be able to output.
38804 +        */
38805 +       u32_t num_attempts = 0;
38806 +
38807 +       if(mailbox_console_flg == TRUE) {
38808 +               while(num_attempts++ < MAILBOX_MAX_ATTEMPTS) {
38809 +                       if(ubi32_mailbox->status & ISD_MAILBOX_STATUS_OUT_EMPTY) {
38810 +                               break;
38811 +                       }
38812 +               }
38813 +
38814 +               /*
38815 +                * If timed out more than 5 times on send, mailbox console is disconnected now.
38816 +                */
38817 +               if (num_attempts > MAILBOX_MAX_ATTEMPTS) {
38818 +                       if (num_timeouts++ > MAILBOX_MAX_TIMEOUTS) {
38819 +                               mailbox_console_flg = FALSE;
38820 +                       }
38821 +               }
38822 +       }
38823 +       
38824 +       asm volatile(
38825 +               "pipe_flush 0   \n\t"
38826 +               "pipe_flush 0   \n\t"
38827 +               "pipe_flush 0   \n\t"
38828 +               "pipe_flush 0   \n\t"
38829 +               "pipe_flush 0   \n\t"
38830 +               "pipe_flush 0   \n\t"
38831 +               "pipe_flush 0   \n\t"
38832 +       );
38833 +
38834 +       ubi32_mailbox->out = v & 0xff;
38835 +}
38836 +
38837 +static void ubi32_mailbox_hw_init(struct ubi32_mailbox_port *uart)
38838 +{
38839 +// NOTE: It does not do any good to do these here because we are running on the linux hardware thread,
38840 +//     and these have to be called on the ldsr thread.
38841 +//     ubicom32_clear_interrupt(ISD_MAILBOX_INT);
38842 +//     ubicom32_enable_interrupt(ISD_MAILBOX_INT);
38843 +}
38844 +
38845 +/*
38846 + * interrupts are disabled on entry
38847 + */
38848 +static void ubi32_mailbox_stop_tx(struct uart_port *port)
38849 +{
38850 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
38851 +//     struct circ_buf *xmit = &uart->port.info->xmit;
38852 +
38853 +       while (!(UART_GET_LSR(uart) & TEMT))
38854 +               cpu_relax();
38855 +
38856 +       /* Clear TFI bit */
38857 +       UART_PUT_LSR(uart, TFI);
38858 +       UART_CLEAR_IER(uart, ETBEI);
38859 +}
38860 +
38861 +/*
38862 + * port is locked and interrupts are disabled
38863 + */
38864 +static void ubi32_mailbox_start_tx(struct uart_port *port)
38865 +{
38866 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
38867 +
38868 +       UART_SET_IER(uart, ETBEI);
38869 +
38870 +       ubi32_mailbox_tx_chars(uart);
38871 +}
38872 +
38873 +/*
38874 + * Interrupts are enabled
38875 + */
38876 +static void ubi32_mailbox_stop_rx(struct uart_port *port)
38877 +{
38878 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
38879 +       UART_CLEAR_IER(uart, ERBFI);
38880 +}
38881 +
38882 +/*
38883 + * Set the modem control timer to fire immediately.
38884 + */
38885 +static void ubi32_mailbox_enable_ms(struct uart_port *port)
38886 +{
38887 +}
38888 +
38889 +static void ubi32_mailbox_rx_chars(struct ubi32_mailbox_port *uart)
38890 +{
38891 +       struct uart_info *info = uart->port.info;
38892 +       struct tty_struct *tty = info->port.tty;
38893 +       unsigned int status, ch, flg;
38894 +
38895 +       status = 0; // XXX? UART_GET_LSR(uart);
38896 +       UART_CLEAR_LSR(uart);
38897 +
38898 +       ch = UART_GET_CHAR(uart);
38899 +
38900 +       if(ch == 0xff)
38901 +               return; 
38902 +
38903 +       uart->port.icount.rx++;
38904 +
38905 +       if (status & BI) {
38906 +               uart->port.icount.brk++;
38907 +               if (uart_handle_break(&uart->port))
38908 +                       goto ignore_char;
38909 +               status &= ~(PE | FE);
38910 +       }
38911 +       if (status & PE)
38912 +               uart->port.icount.parity++;
38913 +       if (status & OE)
38914 +               uart->port.icount.overrun++;
38915 +       if (status & FE)
38916 +               uart->port.icount.frame++;
38917 +
38918 +       status &= uart->port.read_status_mask;
38919 +
38920 +       if (status & BI)
38921 +               flg = TTY_BREAK;
38922 +       else if (status & PE)
38923 +               flg = TTY_PARITY;
38924 +       else if (status & FE)
38925 +               flg = TTY_FRAME;
38926 +       else
38927 +               flg = TTY_NORMAL;
38928 +
38929 +       if (uart_handle_sysrq_char(&uart->port, ch))
38930 +               goto ignore_char;
38931 +
38932 +       uart_insert_char(&uart->port, status, OE, ch, flg);
38933 +
38934 + ignore_char:
38935 +       tty_flip_buffer_push(tty);
38936 +}
38937 +
38938 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart)
38939 +{
38940 +       struct circ_buf *xmit = &uart->port.info->xmit;
38941 +
38942 +       if (uart->port.x_char) {
38943 +               UART_PUT_CHAR(uart, uart->port.x_char);
38944 +               uart->port.icount.tx++;
38945 +               uart->port.x_char = 0;
38946 +       }
38947 +       /*
38948 +        * Check the modem control lines before
38949 +        * transmitting anything.
38950 +        */
38951 +       ubi32_mailbox_mctrl_check(uart);
38952 +
38953 +       if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
38954 +               ubi32_mailbox_stop_tx(&uart->port);
38955 +               return;
38956 +       }
38957 +
38958 +       while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) {
38959 +               UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
38960 +               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
38961 +               uart->port.icount.tx++;
38962 +               SSYNC();
38963 +       }
38964 +
38965 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
38966 +               uart_write_wakeup(&uart->port);
38967 +
38968 +       if (uart_circ_empty(xmit))
38969 +               ubi32_mailbox_stop_tx(&uart->port);
38970 +}
38971 +
38972 +static irqreturn_t ubi32_mailbox_isr(int irq, void *dev_id)
38973 +{
38974 +       struct ubi32_mailbox_port *uart = dev_id;
38975 +
38976 +       spin_lock(&uart->port.lock);
38977 +
38978 +       //XXX?while (UART_GET_LSR(uart) & DR)
38979 +
38980 +       /*
38981 +        * RX process
38982 +        */
38983 +       while (ubi32_mailbox_get_char_avail()) {
38984 +               ubi32_mailbox_rx_chars(uart);
38985 +       }
38986 +
38987 +#if 0
38988 +       /*
38989 +        * TX process
38990 +        */
38991 +       if (this_uart.tx_in == this_uart.tx_out) {
38992 +               UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_mask &= ~IO_PORTX_INT_SERDES_TXBE;
38993 +       } else if (UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_status & IO_PORTX_INT_SERDES_TXBE) {
38994 +               uart_ubicom32_send(this_uart.tx_buf[this_uart.tx_out & (SERIAL_UBICOM_BUF_SIZE - 1)]);
38995 +               this_uart.tx_out++;
38996 +               UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_mask |= IO_PORTX_INT_SERDES_TXBE;
38997 +       }
38998 +#endif
38999 +
39000 +       spin_unlock(&uart->port.lock);
39001 +
39002 +       return IRQ_HANDLED;
39003 +}
39004 +#if 0
39005 +static irqreturn_t ubi32_mailbox_tx_int(int irq, void *dev_id)
39006 +{
39007 +       struct ubi32_mailbox_port *uart = dev_id;
39008 +
39009 +       spin_lock(&uart->port.lock);
39010 +       if (UART_GET_LSR(uart) & THRE)
39011 +               ubi32_mailbox_tx_chars(uart);
39012 +       spin_unlock(&uart->port.lock);
39013 +
39014 +       return IRQ_HANDLED;
39015 +}
39016 +#endif
39017 +
39018 +/*
39019 + * Return TIOCSER_TEMT when transmitter is not busy.
39020 + */
39021 +static unsigned int ubi32_mailbox_tx_empty(struct uart_port *port)
39022 +{
39023 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39024 +       unsigned short lsr;
39025 +
39026 +       lsr = UART_GET_LSR(uart);
39027 +       if (lsr & TEMT)
39028 +               return TIOCSER_TEMT;
39029 +       else
39030 +               return 0;
39031 +}
39032 +
39033 +static unsigned int ubi32_mailbox_get_mctrl(struct uart_port *port)
39034 +{
39035 +               return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
39036 +}
39037 +
39038 +static void ubi32_mailbox_set_mctrl(struct uart_port *port, unsigned int mctrl)
39039 +{
39040 +}
39041 +
39042 +/*
39043 + * Handle any change of modem status signal since we were last called.
39044 + */
39045 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart)
39046 +{
39047 +}
39048 +
39049 +/*
39050 + * Interrupts are always disabled.
39051 + */
39052 +static void ubi32_mailbox_break_ctl(struct uart_port *port, int break_state)
39053 +{
39054 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39055 +       u16 lcr = UART_GET_LCR(uart);
39056 +       if (break_state)
39057 +               lcr |= SB;
39058 +       else
39059 +               lcr &= ~SB;
39060 +       UART_PUT_LCR(uart, lcr);
39061 +       SSYNC();
39062 +}
39063 +
39064 +static int ubi32_mailbox_startup(struct uart_port *port)
39065 +{
39066 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39067 +
39068 +       if (request_irq(uart->port.irq, ubi32_mailbox_isr, IRQF_DISABLED,
39069 +            "UBI32_MAILBOX", uart)) {
39070 +               printk(KERN_NOTICE "Unable to attach Ubicom32 SERDES interrupt\n");
39071 +               return -EBUSY;
39072 +       }
39073 +
39074 +       UART_SET_IER(uart, ERBFI);
39075 +       return 0;
39076 +}
39077 +
39078 +static void ubi32_mailbox_shutdown(struct uart_port *port)
39079 +{
39080 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39081 +
39082 +       free_irq(uart->port.irq, uart);
39083 +}
39084 +
39085 +static void
39086 +ubi32_mailbox_set_termios(struct uart_port *port, struct ktermios *termios,
39087 +                  struct ktermios *old)
39088 +{
39089 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39090 +       unsigned long flags;
39091 +       unsigned int baud, quot;
39092 +       unsigned short val, ier, lsr, lcr = 0;
39093 +
39094 +       switch (termios->c_cflag & CSIZE) {
39095 +       case CS8:
39096 +               lcr = WLS(8);
39097 +               break;
39098 +       case CS7:
39099 +               lcr = WLS(7);
39100 +               break;
39101 +       case CS6:
39102 +               lcr = WLS(6);
39103 +               break;
39104 +       case CS5:
39105 +               lcr = WLS(5);
39106 +               break;
39107 +       default:
39108 +               printk(KERN_ERR "%s: word lengh not supported\n",
39109 +                       __FUNCTION__);
39110 +       }
39111 +
39112 +       if (termios->c_cflag & CSTOPB)
39113 +               lcr |= STB;
39114 +       if (termios->c_cflag & PARENB)
39115 +               lcr |= PEN;
39116 +       if (!(termios->c_cflag & PARODD))
39117 +               lcr |= EPS;
39118 +       if (termios->c_cflag & CMSPAR)
39119 +               lcr |= STP;
39120 +
39121 +       port->read_status_mask = OE;
39122 +       if (termios->c_iflag & INPCK)
39123 +               port->read_status_mask |= (FE | PE);
39124 +       if (termios->c_iflag & (BRKINT | PARMRK))
39125 +               port->read_status_mask |= BI;
39126 +
39127 +       /*
39128 +        * Characters to ignore
39129 +        */
39130 +       port->ignore_status_mask = 0;
39131 +       if (termios->c_iflag & IGNPAR)
39132 +               port->ignore_status_mask |= FE | PE;
39133 +       if (termios->c_iflag & IGNBRK) {
39134 +               port->ignore_status_mask |= BI;
39135 +               /*
39136 +                * If we're ignoring parity and break indicators,
39137 +                * ignore overruns too (for real raw support).
39138 +                */
39139 +               if (termios->c_iflag & IGNPAR)
39140 +                       port->ignore_status_mask |= OE;
39141 +       }
39142 +
39143 +       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
39144 +       quot = uart_get_divisor(port, baud);
39145 +       spin_lock_irqsave(&uart->port.lock, flags);
39146 +
39147 +       do {
39148 +               lsr = UART_GET_LSR(uart);
39149 +       } while (!(lsr & TEMT));
39150 +
39151 +       /* Disable UART */
39152 +       ier = UART_GET_IER(uart);
39153 +       UART_CLEAR_IER(uart, 0xF);
39154 +
39155 +       UART_PUT_DLL(uart, quot & 0xFF);
39156 +       SSYNC();
39157 +       UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
39158 +       SSYNC();
39159 +
39160 +       UART_PUT_LCR(uart, lcr);
39161 +
39162 +       /* Enable UART */
39163 +       UART_SET_IER(uart, ier);
39164 +
39165 +       val = UART_GET_GCTL(uart);
39166 +       val |= UCEN;
39167 +       UART_PUT_GCTL(uart, val);
39168 +
39169 +       spin_unlock_irqrestore(&uart->port.lock, flags);
39170 +}
39171 +
39172 +static const char *ubi32_mailbox_type(struct uart_port *port)
39173 +{
39174 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39175 +
39176 +       return uart->port.type == PORT_UBI32_MAILBOX ? "UBI32_MAILBOX" : NULL;
39177 +}
39178 +
39179 +/*
39180 + * Release the memory region(s) being used by 'port'.
39181 + */
39182 +static void ubi32_mailbox_release_port(struct uart_port *port)
39183 +{
39184 +}
39185 +
39186 +/*
39187 + * Request the memory region(s) being used by 'port'.
39188 + */
39189 +static int ubi32_mailbox_request_port(struct uart_port *port)
39190 +{
39191 +       return 0;
39192 +}
39193 +
39194 +/*
39195 + * Configure/autoconfigure the port.
39196 + */
39197 +static void ubi32_mailbox_config_port(struct uart_port *port, int flags)
39198 +{
39199 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39200 +
39201 +       if (flags & UART_CONFIG_TYPE && ubi32_mailbox_request_port(&uart->port) == 0)
39202 +               uart->port.type = PORT_UBI32_MAILBOX;
39203 +}
39204 +
39205 +/*
39206 + * Verify the new serial_struct (for TIOCSSERIAL).
39207 + * The only change we allow are to the flags and type, and
39208 + * even then only between PORT_UBI32_MAILBOX and PORT_UNKNOWN
39209 + */
39210 +static int
39211 +ubi32_mailbox_verify_port(struct uart_port *port, struct serial_struct *ser)
39212 +{
39213 +       return 0;
39214 +}
39215 +
39216 +static struct uart_ops ubi32_mailbox_pops = {
39217 +       .tx_empty       = ubi32_mailbox_tx_empty,
39218 +       .set_mctrl      = ubi32_mailbox_set_mctrl,
39219 +       .get_mctrl      = ubi32_mailbox_get_mctrl,
39220 +       .stop_tx        = ubi32_mailbox_stop_tx,
39221 +       .start_tx       = ubi32_mailbox_start_tx,
39222 +       .stop_rx        = ubi32_mailbox_stop_rx,
39223 +       .enable_ms      = ubi32_mailbox_enable_ms,
39224 +       .break_ctl      = ubi32_mailbox_break_ctl,
39225 +       .startup        = ubi32_mailbox_startup,
39226 +       .shutdown       = ubi32_mailbox_shutdown,
39227 +       .set_termios    = ubi32_mailbox_set_termios,
39228 +       .type           = ubi32_mailbox_type,
39229 +       .release_port   = ubi32_mailbox_release_port,
39230 +       .request_port   = ubi32_mailbox_request_port,
39231 +       .config_port    = ubi32_mailbox_config_port,
39232 +       .verify_port    = ubi32_mailbox_verify_port,
39233 +};
39234 +
39235 +static void __init ubi32_mailbox_init_ports(void)
39236 +{
39237 +       static int first = 1;
39238 +       int i;
39239 +
39240 +       if (!first)
39241 +               return;
39242 +       first = 0;
39243 +
39244 +       for (i = 0; i < NR_PORTS; i++) {
39245 +               ubi32_mailbox_ports[i].port.uartclk   = get_sclk();
39246 +               ubi32_mailbox_ports[i].port.ops       = &ubi32_mailbox_pops;
39247 +               ubi32_mailbox_ports[i].port.line      = i;
39248 +               ubi32_mailbox_ports[i].port.iotype    = UPIO_MEM;
39249 +               ubi32_mailbox_ports[i].port.membase   =
39250 +                       (void __iomem *)ubi32_mailbox_resource[i].uart_base_addr;
39251 +               ubi32_mailbox_ports[i].port.mapbase   =
39252 +                       ubi32_mailbox_resource[i].uart_base_addr;
39253 +               ubi32_mailbox_ports[i].port.irq       =
39254 +                       ubi32_mailbox_resource[i].uart_irq;
39255 +               ubi32_mailbox_ports[i].port.flags     = UPF_BOOT_AUTOCONF;
39256 +               spin_lock_init(&ubi32_mailbox_ports[i].port.lock);
39257 +
39258 +               ubi32_mailbox_hw_init(&ubi32_mailbox_ports[i]);
39259 +       }
39260 +
39261 +}
39262 +
39263 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39264 +/*
39265 + * If the port was already initialised (eg, by a boot loader),
39266 + * try to determine the current setup.
39267 + */
39268 +static void __init
39269 +ubi32_mailbox_console_get_options(struct ubi32_mailbox_port *uart, int *baud,
39270 +                          int *parity, int *bits)
39271 +{
39272 +       unsigned short status;
39273 +
39274 +       status = UART_GET_IER(uart) & (ERBFI | ETBEI);
39275 +       if (status == (ERBFI | ETBEI)) {
39276 +               /* ok, the port was enabled */
39277 +               unsigned short lcr;
39278 +               unsigned short dlh, dll;
39279 +
39280 +               lcr = UART_GET_LCR(uart);
39281 +
39282 +               *parity = 'n';
39283 +               if (lcr & PEN) {
39284 +                       if (lcr & EPS)
39285 +                               *parity = 'e';
39286 +                       else
39287 +                               *parity = 'o';
39288 +               }
39289 +               switch (lcr & 0x03) {
39290 +                       case 0: *bits = 5; break;
39291 +                       case 1: *bits = 6; break;
39292 +                       case 2: *bits = 7; break;
39293 +                       case 3: *bits = 8; break;
39294 +               }
39295 +
39296 +               dll = UART_GET_DLL(uart);
39297 +               dlh = UART_GET_DLH(uart);
39298 +
39299 +               *baud = get_sclk() / (16*(dll | dlh << 8));
39300 +       }
39301 +       pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
39302 +}
39303 +#endif
39304 +
39305 +#if defined(CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
39306 +static struct uart_driver ubi32_mailbox_reg;
39307 +
39308 +static int __init
39309 +ubi32_mailbox_console_setup(struct console *co, char *options)
39310 +{
39311 +       struct ubi32_mailbox_port *uart;
39312 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39313 +       int baud = SERIAL_UBICOM_BAUDRATE;
39314 +       int bits = 8;
39315 +       int parity = 'n';
39316 +       int flow = 'n';
39317 +# endif
39318 +
39319 +       /*
39320 +        * Check whether an invalid uart number has been specified, and
39321 +        * if so, search for the first available port that does have
39322 +        * console support.
39323 +        */
39324 +       if (co->index == -1 || co->index >= NR_PORTS)
39325 +               co->index = 0;
39326 +       uart = &ubi32_mailbox_ports[co->index];
39327 +
39328 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39329 +       if (options)
39330 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
39331 +       else
39332 +               ubi32_mailbox_console_get_options(uart, &baud, &parity, &bits);
39333 +
39334 +       //JB return uart_set_options(&uart->port, co, baud, parity, bits, flow);
39335 +       return 0;
39336 +# else
39337 +       return 0;
39338 +# endif
39339 +}
39340 +#endif /* defined (CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) ||
39341 +                                defined (CONFIG_EARLY_PRINTK) */
39342 +
39343 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39344 +static void ubi32_mailbox_console_putchar(struct uart_port *port, int ch)
39345 +{
39346 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39347 +       while (!(UART_GET_LSR(uart) & THRE))
39348 +               barrier();
39349 +       UART_PUT_CHAR(uart, ch);
39350 +       SSYNC();
39351 +}
39352 +
39353 +/*
39354 + * Interrupts are disabled on entering
39355 + */
39356 +static void
39357 +ubi32_mailbox_console_write(struct console *co, const char *s, unsigned int count)
39358 +{
39359 +       struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[co->index];
39360 +       unsigned long flags = 0;
39361 +
39362 +       spin_lock_irqsave(&uart->port.lock, flags);
39363 +       uart_console_write(&uart->port, s, count, ubi32_mailbox_console_putchar);
39364 +       spin_unlock_irqrestore(&uart->port.lock, flags);
39365 +
39366 +}
39367 +
39368 +static struct console ubi32_mailbox_console = {
39369 +       .name           = UBI32_MAILBOX_NAME,
39370 +       .write          = ubi32_mailbox_console_write,
39371 +       .device         = uart_console_device,
39372 +       .setup          = ubi32_mailbox_console_setup,
39373 +       .flags          = CON_PRINTBUFFER,
39374 +       .index          = -1,
39375 +       .data           = &ubi32_mailbox_reg,
39376 +};
39377 +
39378 +static int __init ubi32_mailbox_console_init(void)
39379 +{
39380 +       ubi32_mailbox_init_ports();
39381 +       register_console(&ubi32_mailbox_console);
39382 +       return 0;
39383 +}
39384 +console_initcall(ubi32_mailbox_console_init);
39385 +
39386 +#define UBI32_MAILBOX_CONSOLE  &ubi32_mailbox_console
39387 +#else
39388 +#define UBI32_MAILBOX_CONSOLE  NULL
39389 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
39390 +
39391 +
39392 +#ifdef CONFIG_EARLY_PRINTK
39393 +static __init void ubi32_mailbox_early_putc(struct uart_port *port, int ch)
39394 +{
39395 +       UART_PUT_CHAR(uart, ch);
39396 +}
39397 +
39398 +static __init void ubi32_mailbox_early_write(struct console *con, const char *s,
39399 +                                       unsigned int n)
39400 +{
39401 +       struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[con->index];
39402 +       unsigned int i;
39403 +
39404 +       for (i = 0; i < n; i++, s++) {
39405 +               if (*s == '\n')
39406 +                       ubi32_mailbox_early_putc(&uart->port, '\r');
39407 +               ubi32_mailbox_early_putc(&uart->port, *s);
39408 +       }
39409 +}
39410 +
39411 +static struct __init console ubi32_mailbox_early_console = {
39412 +       .name = "early_UM",
39413 +       .write = ubi32_mailbox_early_write,
39414 +       .device = uart_console_device,
39415 +       .flags = CON_PRINTBUFFER,
39416 +       .setup = ubi32_mailbox_console_setup,
39417 +       .index = -1,
39418 +       .data  = &ubi32_mailbox_reg,
39419 +};
39420 +
39421 +/*
39422 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
39423 + */
39424 +struct console __init *ubi32_mailbox_early_init(unsigned int port,
39425 +                                               unsigned int cflag)
39426 +{
39427 +       struct ubi32_mailbox_port *uart;
39428 +       struct ktermios t;
39429 +
39430 +       if (port == -1 || port >= NR_PORTS)
39431 +               port = 0;
39432 +       ubi32_mailbox_init_ports();
39433 +       ubi32_mailbox_early_console.index = port;
39434 +       uart = &ubi32_mailbox_ports[port];
39435 +       t.c_cflag = cflag;
39436 +       t.c_iflag = 0;
39437 +       t.c_oflag = 0;
39438 +       t.c_lflag = ICANON;
39439 +       t.c_line = port;
39440 +       ubi32_mailbox_set_termios(&uart->port, &t, &t);
39441 +       return &ubi32_mailbox_early_console;
39442 +}
39443 +
39444 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
39445 +
39446 +static struct uart_driver ubi32_mailbox_reg = {
39447 +       .owner                  = THIS_MODULE,
39448 +       .driver_name            = "ubi32_mailbox",
39449 +       .dev_name               = UBI32_MAILBOX_NAME,
39450 +       .major                  = UBI32_MAILBOX_MAJOR,
39451 +       .minor                  = UBI32_MAILBOX_MINOR,
39452 +       .nr                     = NR_PORTS,
39453 +       .cons                   = UBI32_MAILBOX_CONSOLE,
39454 +};
39455 +
39456 +static int ubi32_mailbox_suspend(struct platform_device *dev, pm_message_t state)
39457 +{
39458 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39459 +
39460 +       if (uart)
39461 +               uart_suspend_port(&ubi32_mailbox_reg, &uart->port);
39462 +
39463 +       return 0;
39464 +}
39465 +
39466 +static int ubi32_mailbox_resume(struct platform_device *dev)
39467 +{
39468 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39469 +
39470 +       if (uart)
39471 +               uart_resume_port(&ubi32_mailbox_reg, &uart->port);
39472 +
39473 +       return 0;
39474 +}
39475 +
39476 +static int ubi32_mailbox_probe(struct platform_device *dev)
39477 +{
39478 +       struct resource *res = dev->resource;
39479 +       int i;
39480 +
39481 +       for (i = 0; i < dev->num_resources; i++, res++)
39482 +               if (res->flags & IORESOURCE_MEM)
39483 +                       break;
39484 +
39485 +       if (i < dev->num_resources) {
39486 +               for (i = 0; i < NR_PORTS; i++, res++) {
39487 +                       if (ubi32_mailbox_ports[i].port.mapbase != res->start)
39488 +                               continue;
39489 +                       ubi32_mailbox_ports[i].port.dev = &dev->dev;
39490 +                       uart_add_one_port(&ubi32_mailbox_reg, &ubi32_mailbox_ports[i].port);
39491 +                       platform_set_drvdata(dev, &ubi32_mailbox_ports[i]);
39492 +               }
39493 +       }
39494 +
39495 +       return 0;
39496 +}
39497 +
39498 +static int ubi32_mailbox_remove(struct platform_device *pdev)
39499 +{
39500 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(pdev);
39501 +
39502 +       platform_set_drvdata(pdev, NULL);
39503 +
39504 +       if (uart)
39505 +               uart_remove_one_port(&ubi32_mailbox_reg, &uart->port);
39506 +
39507 +       return 0;
39508 +}
39509 +
39510 +static struct platform_driver ubi32_mailbox_driver = {
39511 +       .probe          = ubi32_mailbox_probe,
39512 +       .remove         = ubi32_mailbox_remove,
39513 +       .suspend        = ubi32_mailbox_suspend,
39514 +       .resume         = ubi32_mailbox_resume,
39515 +       .driver         = {
39516 +               .name   = "ubi32-mbox",
39517 +               .owner  = THIS_MODULE,
39518 +       },
39519 +};
39520 +
39521 +static int __init ubi32_mailbox_init(void)
39522 +{
39523 +       int ret;
39524 +
39525 +       pr_info("Serial: Ubicom32 mailbox serial driver.\n");
39526 +
39527 +       mailbox_console_flg = TRUE;
39528 +       num_timeouts = 0;
39529 +       ubi32_mailbox_init_ports();
39530 +
39531 +       ret = uart_register_driver(&ubi32_mailbox_reg);
39532 +       if (ret == 0) {
39533 +               ret = platform_driver_register(&ubi32_mailbox_driver);
39534 +               if (ret) {
39535 +                       pr_debug("uart register failed\n");
39536 +                       uart_unregister_driver(&ubi32_mailbox_reg);
39537 +               }
39538 +       }
39539 +
39540 +       /*
39541 +        * XXX HACK: currently probe does not get called, but the port needs to be added to work.
39542 +        */
39543 +       uart_add_one_port(&ubi32_mailbox_reg, &ubi32_mailbox_ports[0].port);
39544 +       return ret;
39545 +}
39546 +
39547 +static void __exit ubi32_mailbox_exit(void)
39548 +{
39549 +       platform_driver_unregister(&ubi32_mailbox_driver);
39550 +       uart_unregister_driver(&ubi32_mailbox_reg);
39551 +}
39552 +
39553 +module_init(ubi32_mailbox_init);
39554 +module_exit(ubi32_mailbox_exit);
39555 +
39556 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_MAILBOX_MAJOR);
39557 +MODULE_ALIAS("platform:ubi32_mailbox");
39558 --- /dev/null
39559 +++ b/drivers/serial/ubi32_serdes.c
39560 @@ -0,0 +1,817 @@
39561 +/*
39562 + * drivers/serial/ubi32_serdes.c
39563 + *   Ubicom32 On-Chip Serial Driver
39564 + *
39565 + * (C) Copyright 2009, Ubicom, Inc.
39566 + *
39567 + * This file is part of the Ubicom32 Linux Kernel Port.
39568 + *
39569 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
39570 + * it and/or modify it under the terms of the GNU General Public License
39571 + * as published by the Free Software Foundation, either version 2 of the
39572 + * License, or (at your option) any later version.
39573 + *
39574 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
39575 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
39576 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
39577 + * the GNU General Public License for more details.
39578 + *
39579 + * You should have received a copy of the GNU General Public License
39580 + * along with the Ubicom32 Linux Kernel Port.  If not, 
39581 + * see <http://www.gnu.org/licenses/>.
39582 + *
39583 + * Ubicom32 implementation derived from (with many thanks):
39584 + *   arch/m68knommu
39585 + *   arch/blackfin
39586 + *   arch/parisc
39587 + */
39588 +#include <linux/module.h>
39589 +#include <linux/ioport.h>
39590 +#include <linux/init.h>
39591 +#include <linux/console.h>
39592 +#include <linux/sysrq.h>
39593 +#include <linux/platform_device.h>
39594 +#include <linux/tty.h>
39595 +#include <linux/tty_flip.h>
39596 +#include <linux/serial_core.h>
39597 +
39598 +#include <asm/ip5000.h>
39599 +#include <asm/ubicom32suart.h>
39600 +
39601 +
39602 +#define SERIAL_UBICOM_PIN_RXD  (1 << 0)
39603 +#define SERIAL_UBICOM_PIN_TXD  (1 << 6)
39604 +#define SERIAL_UBICOM_CTL0     0x8b300000
39605 +#define SERIAL_UBICOM_CTL1     0x00000009
39606 +
39607 +#define SERIAL_UBICOM_DATA_BIT 8       /* Fixed parameter - do not change */
39608 +#define SERIAL_UBICOM_PAR_BIT  0       /* Fixed parameter - do not change */
39609 +#define SERIAL_UBICOM_STOP_BIT 1       /* Fixed parameter - do not change */
39610 +
39611 +/* UART name and device definitions */
39612 +#define UBI32_SERDES_NAME      "ttyUS" // XXX
39613 +#define UBI32_SERDES_MAJOR     206 // XXX
39614 +#define UBI32_SERDES_MINOR     64 // XXX
39615 +
39616 +#define PORT_UBI32_SERDES      1234
39617 +#define NR_PORTS 1
39618 +
39619 +struct uart_port ubi32_serdes_ports[NR_PORTS];
39620 +
39621 +struct ubi32_serdes_resource {
39622 +       void *uart_base_addr;
39623 +       int uart_irq;
39624 +       int uart_clock;
39625 +} ubi32_serdes_resource[NR_PORTS] = {
39626 +       /*
39627 +        * Get params from kernel command line (required for early printk)
39628 +        * or from platform resources.
39629 +        */
39630 +       {0, 0, 0}
39631 +};
39632 +
39633 +/*
39634 + * Can get overridden by 'serdes=' kernel command line.
39635 + */
39636 +static int ubi32_serdes_default_baud_rate = 115200;
39637 +
39638 +
39639 +#define IO_PORT(port) ((struct ubicom32_io_port *)port->membase)
39640 +#define IO_PORT_INT_STATUS(port) (IO_PORT(port)->int_status)
39641 +#define IO_PORT_INT_MASK(port) (IO_PORT(port)->int_mask)
39642 +#define IO_PORT_INT_CLR(port) (IO_PORT(port)->int_clr)
39643 +
39644 +
39645 +/*
39646 + * ubi32_serdes_get_char()
39647 + */
39648 +static u8_t ubi32_serdes_get_char(struct ubicom32_io_port *io_port)
39649 +{
39650 +       /*
39651 +        * Read from hardware (forced 32-bit atomic read).
39652 +        */
39653 +       u32_t data = 0;
39654 +
39655 +       if ( io_port ) {
39656 +               io_port->int_clr = IO_PORTX_INT_SERDES_RXBF;
39657 +               asm volatile (
39658 +                       "move.4         %0, %1          \n\t"
39659 +                       : "=r" (data)
39660 +                       : "m" (*(u32_t *)&(io_port->rx_fifo))
39661 +                       );
39662 +       }
39663 +
39664 +       return (u8_t)(data & 0x000000ff);
39665 +}
39666 +
39667 +/*
39668 + * ubi32_serdes_put_char()
39669 + */
39670 +static void ubi32_serdes_put_char(struct ubicom32_io_port *io_port, u8_t c)
39671 +{
39672 +       u32_t data = 0x0000fe00 | (c << 1);
39673 +
39674 +       if ( io_port ) {
39675 +               /*
39676 +                * Fixed data format: 
39677 +                * [LSB]1 start bit - 8 data bits - no parity - 1 stop bit[MSB]
39678 +                */
39679 +               io_port->int_clr = IO_PORTX_INT_SERDES_TXBE;
39680 +               io_port->ctl2 = data;
39681 +               io_port->int_set = IO_PORTX_INT_SERDES_TXBUF_VALID;
39682 +       }
39683 +}
39684 +
39685 +static void ubi32_serdes_hw_init(struct uart_port *port, int baud)
39686 +{
39687 +       struct ubicom32_io_port *io_port = IO_PORT(port);
39688 +
39689 +       if ( io_port ) {
39690 +               /*
39691 +                * Put port functions 1-4 into reset state.
39692 +                * Function 0 (GPIO) does not need or have a reset bit.
39693 +                *
39694 +                * Select SERDES function for restart below.
39695 +                */
39696 +               io_port->function =
39697 +                       IO_FUNC_FUNCTION_RESET(1) | IO_FUNC_FUNCTION_RESET(2) |
39698 +                       IO_FUNC_FUNCTION_RESET(3) | IO_FUNC_FUNCTION_RESET(4) |
39699 +                       IO_PORTX_FUNC_SERDES;
39700 +
39701 +               /*
39702 +                * Configure SERDES baudrate
39703 +                */
39704 +               if ( baud == 0 ) {
39705 +                       baud = ubi32_serdes_default_baud_rate;
39706 +               }
39707 +
39708 +               io_port->ctl0 =
39709 +                       SERIAL_UBICOM_CTL0 | 
39710 +                       ((port->uartclk / (16 * baud)) - 1);
39711 +
39712 +               io_port->ctl1 =
39713 +                       SERIAL_UBICOM_CTL1;
39714 +
39715 +               /*
39716 +                * don't interrupt until startup and start_tx
39717 +                */
39718 +               io_port->int_mask = 0;
39719 +
39720 +               /*
39721 +                * Set TXD pin output, RXD input and prevent GPIO
39722 +                * override on the TXD & RXD pins
39723 +                */
39724 +               io_port->gpio_ctl &= ~SERIAL_UBICOM_PIN_RXD;
39725 +               io_port->gpio_ctl |= SERIAL_UBICOM_PIN_TXD;
39726 +               io_port->gpio_mask &= ~(SERIAL_UBICOM_PIN_RXD | SERIAL_UBICOM_PIN_TXD);
39727 +
39728 +               /*
39729 +                * Restart (un-reset) the port's SERDES function.
39730 +                */
39731 +               io_port->function &= ~(IO_FUNC_FUNCTION_RESET(IO_PORTX_FUNC_SERDES));
39732 +       }
39733 +}
39734 +
39735 +#define ULITE_STATUS_RXVALID IO_PORTX_INT_SERDES_RXBF
39736 +#define ULITE_STATUS_OVERRUN 0
39737 +#define ULITE_STATUS_FRAME 0
39738 +#define ULITE_STATUS_PARITY 0
39739 +#define ULITE_STATUS_TXEMPTY IO_PORTX_INT_SERDES_TXBE
39740 +#define ULITE_STATUS_TXFULL 0
39741 +
39742 +static int ubi32_serdes_receive(struct uart_port *port, int stat)
39743 +{
39744 +       struct tty_struct *tty = port->info->port.tty;
39745 +       unsigned char ch = 0;
39746 +       char flag = TTY_NORMAL;
39747 +
39748 +       if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
39749 +                    | ULITE_STATUS_FRAME)) == 0)
39750 +               return 0;
39751 +
39752 +       /* stats */
39753 +       if (stat & ULITE_STATUS_RXVALID) {
39754 +               port->icount.rx++;
39755 +               ch = ubi32_serdes_get_char((struct ubicom32_io_port *)port->membase);
39756 +
39757 +               if (stat & ULITE_STATUS_PARITY)
39758 +                       port->icount.parity++;
39759 +       }
39760 +
39761 +       if (stat & ULITE_STATUS_OVERRUN)
39762 +               port->icount.overrun++;
39763 +
39764 +       if (stat & ULITE_STATUS_FRAME)
39765 +               port->icount.frame++;
39766 +
39767 +
39768 +       /* drop byte with parity error if IGNPAR specificed */
39769 +       if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY)
39770 +               stat &= ~ULITE_STATUS_RXVALID;
39771 +
39772 +       stat &= port->read_status_mask;
39773 +
39774 +       if (stat & ULITE_STATUS_PARITY)
39775 +               flag = TTY_PARITY;
39776 +
39777 +       stat &= ~port->ignore_status_mask;
39778 +
39779 +       if (stat & ULITE_STATUS_RXVALID)
39780 +               tty_insert_flip_char(tty, ch, flag);
39781 +
39782 +       if (stat & ULITE_STATUS_FRAME)
39783 +               tty_insert_flip_char(tty, 0, TTY_FRAME);
39784 +
39785 +       if (stat & ULITE_STATUS_OVERRUN)
39786 +               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
39787 +
39788 +       return 1;
39789 +}
39790 +
39791 +/*
39792 + * interrupts are disabled on entry
39793 + */
39794 +static void ubi32_serdes_stop_tx(struct uart_port *port)
39795 +{
39796 +       IO_PORT_INT_MASK(port) = IO_PORT_INT_MASK(port) & ~IO_PORTX_INT_SERDES_TXBE;
39797 +}
39798 +
39799 +static int ubi32_serdes_transmit(struct uart_port *port, int stat)
39800 +{
39801 +       struct circ_buf *xmit  = &port->info->xmit;
39802 +
39803 +       if (!(stat & IO_PORTX_INT_SERDES_TXBE))
39804 +               return 0;
39805 +
39806 +       if (port->x_char) {
39807 +               ubi32_serdes_put_char(IO_PORT(port), port->x_char);
39808 +               port->x_char = 0;
39809 +               port->icount.tx++;
39810 +               return 1;
39811 +       }
39812 +
39813 +       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
39814 +               ubi32_serdes_stop_tx(port);
39815 +               return 0;
39816 +       }
39817 +
39818 +       ubi32_serdes_put_char(IO_PORT(port), xmit->buf[xmit->tail]);
39819 +       xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
39820 +       port->icount.tx++;
39821 +
39822 +       /* wake up */
39823 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
39824 +               uart_write_wakeup(port);
39825 +
39826 +       if (uart_circ_empty(xmit))
39827 +               ubi32_serdes_stop_tx(port);
39828 +
39829 +       return 1;
39830 +}
39831 +
39832 +/*
39833 + * port is locked and interrupts are disabled
39834 + */
39835 +static void ubi32_serdes_start_tx(struct uart_port *port)
39836 +{
39837 +       IO_PORT_INT_MASK(port) = IO_PORT_INT_MASK(port) | IO_PORTX_INT_SERDES_TXBE;
39838 +       ubi32_serdes_transmit(port, IO_PORT_INT_STATUS(port));
39839 +}
39840 +
39841 +/*
39842 + * Interrupts are enabled
39843 + */
39844 +static void ubi32_serdes_stop_rx(struct uart_port *port)
39845 +{
39846 +       /* don't forward any more data (like !CREAD) */
39847 +       port->ignore_status_mask = IO_PORTX_INT_SERDES_RXBF;
39848 +}
39849 +
39850 +/*
39851 + * Set the modem control timer to fire immediately.
39852 + */
39853 +static void ubi32_serdes_enable_ms(struct uart_port *port)
39854 +{
39855 +       /* N/A */
39856 +}
39857 +
39858 +static irqreturn_t ubi32_serdes_isr(int irq, void *dev_id)
39859 +{
39860 +       struct uart_port *port = dev_id;
39861 +       int busy;
39862 +
39863 +       spin_lock(&port->lock);
39864 +
39865 +       do {
39866 +               int stat = IO_PORT_INT_STATUS(port);
39867 +               busy  = ubi32_serdes_receive(port, stat);
39868 +               busy |= ubi32_serdes_transmit(port, stat);
39869 +       } while (busy);
39870 +
39871 +       tty_flip_buffer_push(port->info->port.tty);
39872 +
39873 +       spin_unlock(&port->lock);
39874 +
39875 +       return IRQ_HANDLED;
39876 +}
39877 +
39878 +/*
39879 + * Return TIOCSER_TEMT when transmitter is not busy.
39880 + */
39881 +static unsigned int ubi32_serdes_tx_empty(struct uart_port *port)
39882 +{
39883 +       unsigned long flags;
39884 +       unsigned int ret;
39885 +
39886 +       spin_lock_irqsave(&port->lock, flags);
39887 +       ret = IO_PORT_INT_STATUS(port);
39888 +       spin_unlock_irqrestore(&port->lock, flags);
39889 +
39890 +       return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
39891 +}
39892 +
39893 +static unsigned int ubi32_serdes_get_mctrl(struct uart_port *port)
39894 +{
39895 +       return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
39896 +}
39897 +
39898 +static void ubi32_serdes_set_mctrl(struct uart_port *port, unsigned int mctrl)
39899 +{
39900 +       /* N/A */
39901 +}
39902 +
39903 +/*
39904 + * Interrupts are always disabled.
39905 + */
39906 +static void ubi32_serdes_break_ctl(struct uart_port *port, int break_state)
39907 +{
39908 +       /* N/A */
39909 +}
39910 +
39911 +static int ubi32_serdes_startup(struct uart_port *port)
39912 +{
39913 +       if (request_irq(port->irq, ubi32_serdes_isr, IRQF_DISABLED,
39914 +            "UBI32_SERDES", port)) {
39915 +               printk(KERN_NOTICE "Unable to attach port interrupt\n");
39916 +               return -EBUSY;
39917 +       }
39918 +
39919 +       IO_PORT_INT_CLR(port) = IO_PORTX_INT_SERDES_RXBF;
39920 +       IO_PORT_INT_MASK(port) = IO_PORTX_INT_SERDES_RXBF;
39921 +       return 0;
39922 +}
39923 +
39924 +static void ubi32_serdes_shutdown(struct uart_port *port)
39925 +{
39926 +       struct ubi32_serdes_port *uart = (struct ubi32_serdes_port *)port;
39927 +
39928 +       IO_PORT_INT_MASK(port) = 0;
39929 +       free_irq(port->irq, uart);
39930 +}
39931 +
39932 +static void
39933 +ubi32_serdes_set_termios(struct uart_port *port, struct ktermios *termios,
39934 +                  struct ktermios *old)
39935 +{
39936 +       unsigned long flags;
39937 +       unsigned int baud;
39938 +
39939 +       spin_lock_irqsave(&port->lock, flags);
39940 +
39941 +       port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
39942 +               | ULITE_STATUS_TXFULL;
39943 +
39944 +       if (termios->c_iflag & INPCK)
39945 +               port->read_status_mask |=
39946 +                       ULITE_STATUS_PARITY | ULITE_STATUS_FRAME;
39947 +
39948 +       port->ignore_status_mask = 0;
39949 +       if (termios->c_iflag & IGNPAR)
39950 +               port->ignore_status_mask |= ULITE_STATUS_PARITY
39951 +                       | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
39952 +
39953 +       /* ignore all characters if CREAD is not set */
39954 +       if ((termios->c_cflag & CREAD) == 0)
39955 +               port->ignore_status_mask |=
39956 +                       ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
39957 +                       | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
39958 +
39959 +       /* update timeout */
39960 +       baud = uart_get_baud_rate(port, termios, old, 0, 460800);
39961 +       uart_update_timeout(port, termios->c_cflag, baud);
39962 +
39963 +       IO_PORT(port)->ctl0 = SERIAL_UBICOM_CTL0 | 
39964 +                       ((port->uartclk / (16 * baud)) - 1);
39965 +
39966 +       spin_unlock_irqrestore(&port->lock, flags);
39967 +}
39968 +
39969 +static const char *ubi32_serdes_type(struct uart_port *port)
39970 +{
39971 +       return port->type == PORT_UBI32_SERDES ? "UBI32_SERDES" : NULL;
39972 +}
39973 +
39974 +/*
39975 + * Release the memory region(s) being used by 'port'.
39976 + */
39977 +static void ubi32_serdes_release_port(struct uart_port *port)
39978 +{
39979 +}
39980 +
39981 +/*
39982 + * Request the memory region(s) being used by 'port'.
39983 + */
39984 +static int ubi32_serdes_request_port(struct uart_port *port)
39985 +{
39986 +       return 0;
39987 +}
39988 +
39989 +/*
39990 + * Configure/autoconfigure the port.
39991 + */
39992 +static void ubi32_serdes_config_port(struct uart_port *port, int flags)
39993 +{
39994 +       if (flags & UART_CONFIG_TYPE &&
39995 +           ubi32_serdes_request_port(port) == 0)
39996 +               port->type = PORT_UBI32_SERDES;
39997 +}
39998 +
39999 +/*
40000 + * Verify the new serial_struct (for TIOCSSERIAL).
40001 + * The only change we allow are to the flags and type, and
40002 + * even then only between PORT_UBI32_SERDES and PORT_UNKNOWN
40003 + */
40004 +static int
40005 +ubi32_serdes_verify_port(struct uart_port *port, struct serial_struct *ser)
40006 +{
40007 +       return 0;
40008 +}
40009 +
40010 +static struct uart_ops ubi32_serdes_pops = {
40011 +       .tx_empty       = ubi32_serdes_tx_empty,
40012 +       .set_mctrl      = ubi32_serdes_set_mctrl,
40013 +       .get_mctrl      = ubi32_serdes_get_mctrl,
40014 +       .stop_tx        = ubi32_serdes_stop_tx,
40015 +       .start_tx       = ubi32_serdes_start_tx,
40016 +       .stop_rx        = ubi32_serdes_stop_rx,
40017 +       .enable_ms      = ubi32_serdes_enable_ms,
40018 +       .break_ctl      = ubi32_serdes_break_ctl,
40019 +       .startup        = ubi32_serdes_startup,
40020 +       .shutdown       = ubi32_serdes_shutdown,
40021 +       .set_termios    = ubi32_serdes_set_termios,
40022 +       .type           = ubi32_serdes_type,
40023 +       .release_port   = ubi32_serdes_release_port,
40024 +       .request_port   = ubi32_serdes_request_port,
40025 +       .config_port    = ubi32_serdes_config_port,
40026 +       .verify_port    = ubi32_serdes_verify_port,
40027 +};
40028 +
40029 +static void __init ubi32_serdes_init_ports(void)
40030 +{
40031 +       int i;
40032 +
40033 +       for (i = 0; i < NR_PORTS; i++) {
40034 +               ubi32_serdes_ports[i].uartclk   = ubi32_serdes_resource[i].uart_clock;
40035 +               ubi32_serdes_ports[i].ops       = &ubi32_serdes_pops;
40036 +               ubi32_serdes_ports[i].line      = i;
40037 +               ubi32_serdes_ports[i].iotype    = UPIO_MEM;
40038 +               ubi32_serdes_ports[i].membase   =
40039 +                       (void __iomem *)ubi32_serdes_resource[i].uart_base_addr;
40040 +               ubi32_serdes_ports[i].mapbase   =
40041 +                       (resource_size_t)ubi32_serdes_resource[i].uart_base_addr;
40042 +               ubi32_serdes_ports[i].irq       =
40043 +                       ubi32_serdes_resource[i].uart_irq;
40044 +               ubi32_serdes_ports[i].flags     = UPF_BOOT_AUTOCONF;
40045 +
40046 +               ubi32_serdes_hw_init(&ubi32_serdes_ports[i], 0);
40047 +       }
40048 +
40049 +}
40050 +
40051 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40052 +/*
40053 + * If the port was already initialised (eg, by a boot loader),
40054 + * try to determine the current setup.
40055 + */
40056 +static void __init
40057 +ubi32_serdes_console_get_options(struct uart_port *port, int *baud)
40058 +{
40059 +       u32 round_to = 1200;
40060 +       u32 real_baud;
40061 +
40062 +       /*
40063 +        * We might get called before platform init and with no
40064 +        * kernel command line options, so port might be NULL.
40065 +        */
40066 +       *baud = ubi32_serdes_default_baud_rate;;
40067 +       if ( IO_PORT(port) == 0 )
40068 +               return;
40069 +
40070 +       real_baud = port->uartclk 
40071 +               / (16 * ((IO_PORT(port)->ctl0 & ~SERIAL_UBICOM_CTL0) + 1));
40072 +
40073 +       *baud = ((real_baud + round_to - 1) / round_to) * round_to;
40074 +
40075 +       pr_debug("%s:baud = %d, real_baud = %d\n", __FUNCTION__, *baud, real_baud);
40076 +}
40077 +#endif
40078 +
40079 +#if defined(CONFIG_SERIAL_UBI32_SERDES_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
40080 +static struct uart_driver ubi32_serdes_reg;
40081 +
40082 +static int __init
40083 +ubi32_serdes_console_setup(struct console *co, char *options)
40084 +{
40085 +       struct uart_port *port;
40086 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40087 +       int baud = ubi32_serdes_default_baud_rate;
40088 +       int bits = 8;
40089 +       int parity = 'n';
40090 +       int flow = 'n';
40091 +#endif
40092 +
40093 +       /*
40094 +        * Check whether an invalid uart number has been specified, and
40095 +        * if so, search for the first available port that does have
40096 +        * console support.
40097 +        */
40098 +       if (co->index == -1 || co->index >= NR_PORTS)
40099 +               co->index = 0;
40100 +       port = &ubi32_serdes_ports[co->index];
40101 +
40102 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40103 +       if (options) {
40104 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
40105 +               ubi32_serdes_hw_init(port, baud);
40106 +       }
40107 +       else
40108 +               ubi32_serdes_console_get_options(port, &baud);
40109 +
40110 +       return uart_set_options(port, co, baud, parity, bits, flow);
40111 +#else
40112 +       return 0;
40113 +#endif
40114 +}
40115 +#endif /* defined (CONFIG_SERIAL_UBI32_SERDES_CONSOLE) ||
40116 +                                defined (CONFIG_EARLY_PRINTK) */
40117 +
40118 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40119 +static void 
40120 +ubi32_serdes_console_putchar(struct uart_port *port, int ch)
40121 +{
40122 +       if ( IO_PORT(port) ) {
40123 +               while (!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE))
40124 +                       barrier();
40125 +               ubi32_serdes_put_char(IO_PORT(port), ch);
40126 +       }
40127 +}
40128 +
40129 +/*
40130 + * Interrupts are disabled on entering
40131 + */
40132 +static void
40133 +ubi32_serdes_console_write(struct console *co, const char *s, unsigned int count)
40134 +{
40135 +       struct uart_port *port = &ubi32_serdes_ports[co->index];
40136 +       unsigned long flags = 0;
40137 +
40138 +       spin_lock_irqsave(&port->lock, flags);
40139 +       uart_console_write(port, s, count, ubi32_serdes_console_putchar);
40140 +       spin_unlock_irqrestore(&port->lock, flags);
40141 +
40142 +}
40143 +
40144 +static struct console ubi32_serdes_console = {
40145 +       .name           = UBI32_SERDES_NAME,
40146 +       .write          = ubi32_serdes_console_write,
40147 +       .device         = uart_console_device,
40148 +       .setup          = ubi32_serdes_console_setup,
40149 +       .flags          = CON_PRINTBUFFER,
40150 +       .index          = -1,
40151 +       .data           = &ubi32_serdes_reg,
40152 +};
40153 +
40154 +static int __init ubi32_serdes_console_init(void)
40155 +{
40156 +       ubi32_serdes_init_ports();
40157 +       register_console(&ubi32_serdes_console);
40158 +       return 0;
40159 +}
40160 +console_initcall(ubi32_serdes_console_init);
40161 +
40162 +#define UBI32_SERDES_CONSOLE   &ubi32_serdes_console
40163 +#else
40164 +#define UBI32_SERDES_CONSOLE   NULL
40165 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
40166 +
40167 +
40168 +#ifdef CONFIG_EARLY_PRINTK
40169 +static __init void ubi32_serdes_early_putc(struct uart_port *port, int ch)
40170 +{
40171 +       unsigned timeout = 0xffff;
40172 +
40173 +       while ((!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE)) && --timeout)
40174 +               cpu_relax();
40175 +       ubi32_serdes_put_char(IO_PORT(port), ch);
40176 +}
40177 +
40178 +static __init void ubi32_serdes_early_write(struct console *con, const char *s,
40179 +                                       unsigned int n)
40180 +{
40181 +       struct uart_port *port = &ubi32_serdes_ports[con->index];
40182 +       unsigned int i;
40183 +
40184 +       for (i = 0; i < n; i++, s++) {
40185 +               if (*s == '\n')
40186 +                       ubi32_serdes_early_putc(port, '\r');
40187 +               ubi32_serdes_early_putc(port, *s);
40188 +       }
40189 +}
40190 +
40191 +static struct __init console ubi32_serdes_early_console = {
40192 +       .name = "early_US",
40193 +       .write = ubi32_serdes_early_write,
40194 +       .device = uart_console_device,
40195 +       .flags = CON_PRINTBUFFER,
40196 +       .setup = ubi32_serdes_console_setup,
40197 +       .index = -1,
40198 +       .data  = &ubi32_serdes_reg,
40199 +};
40200 +
40201 +/*
40202 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
40203 + */
40204 +struct console __init *ubi32_serdes_early_init(unsigned int port_index,
40205 +                                               unsigned int cflag)
40206 +{
40207 +       struct uart_port *uart;
40208 +       struct ktermios t;
40209 +
40210 +       if (port_index == -1 || port_index >= NR_PORTS)
40211 +               port_index = 0;
40212 +       ubi32_serdes_init_ports();
40213 +       ubi32_serdes_early_console.index = port_index;
40214 +       uart = &ubi32_serdes_ports[port_index];
40215 +       t.c_cflag = cflag;
40216 +       t.c_iflag = 0;
40217 +       t.c_oflag = 0;
40218 +       t.c_lflag = ICANON;
40219 +       t.c_line = port_index;
40220 +       ubi32_serdes_set_termios(uart, &t, &t);
40221 +       return &ubi32_serdes_early_console;
40222 +}
40223 +
40224 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
40225 +
40226 +static struct uart_driver ubi32_serdes_reg = {
40227 +       .owner                  = THIS_MODULE,
40228 +       .driver_name            = "ubi32_serdes",
40229 +       .dev_name               = UBI32_SERDES_NAME,
40230 +       .major                  = UBI32_SERDES_MAJOR,
40231 +       .minor                  = UBI32_SERDES_MINOR,
40232 +       .nr                     = NR_PORTS,
40233 +       .cons                   = UBI32_SERDES_CONSOLE,
40234 +};
40235 +
40236 +static int ubi32_serdes_suspend(struct platform_device *dev, pm_message_t state)
40237 +{
40238 +       struct uart_port *port = platform_get_drvdata(dev);
40239 +
40240 +       if (port)
40241 +               uart_suspend_port(&ubi32_serdes_reg, port);
40242 +
40243 +       return 0;
40244 +}
40245 +
40246 +static int ubi32_serdes_resume(struct platform_device *dev)
40247 +{
40248 +       struct uart_port *port = platform_get_drvdata(dev);
40249 +
40250 +       if (port)
40251 +               uart_resume_port(&ubi32_serdes_reg, port);
40252 +
40253 +       return 0;
40254 +}
40255 +
40256 +static int ubi32_serdes_probe(struct platform_device *dev)
40257 +{
40258 +       struct resource *res = dev->resource;
40259 +       int i;
40260 +
40261 +       for (i = 0; i < dev->num_resources; i++, res++) {
40262 +               if (res->flags & IORESOURCE_MEM) {
40263 +                       ubi32_serdes_resource[0].uart_base_addr = (void *) res->start;
40264 +               }
40265 +               else if (res->flags & IORESOURCE_IRQ) {
40266 +                       ubi32_serdes_resource[0].uart_irq = res->start;
40267 +               }
40268 +               else if (res->flags & UBICOM32_SUART_IORESOURCE_CLOCK) {
40269 +                       ubi32_serdes_resource[0].uart_clock = res->start;
40270 +               }
40271 +       }
40272 +
40273 +       ubi32_serdes_init_ports();
40274 +
40275 +       return 0;
40276 +}
40277 +
40278 +static int ubi32_serdes_remove(struct platform_device *pdev)
40279 +{
40280 +       struct uart_port *port = platform_get_drvdata(pdev);
40281 +
40282 +       platform_set_drvdata(pdev, NULL);
40283 +
40284 +       if (port)
40285 +               uart_remove_one_port(&ubi32_serdes_reg, port);
40286 +
40287 +       return 0;
40288 +}
40289 +
40290 +static struct platform_driver ubi32_serdes_driver = {
40291 +       .remove         = ubi32_serdes_remove,
40292 +       .suspend        = ubi32_serdes_suspend,
40293 +       .resume         = ubi32_serdes_resume,
40294 +       .driver         = {
40295 +               .name   = "ubicom32suart",
40296 +               .owner  = THIS_MODULE,
40297 +       },
40298 +};
40299 +
40300 +
40301 +#ifndef MODULE
40302 +/*
40303 + * Called at boot time.
40304 + *
40305 + * You can specify IO base, IRQ, and clock for the serdes serial port
40306 + * using kernel command line "serdes=0xiobase,irq,clock".  Values
40307 + * specified will be overwritten by platform device data, if present.
40308 + */
40309 +static int __init ubi32_serdes_setup(char *str)
40310 +{
40311 +#define N_PARMS   (4+1)
40312 +       int ints[N_PARMS];
40313 +       int i;
40314 +
40315 +       str = get_options(str, ARRAY_SIZE(ints), ints);
40316 +
40317 +       for (i = 0; i < N_PARMS; i++) {
40318 +               if (i < ints[0]) {
40319 +                       if (i == 0) {
40320 +                               ubi32_serdes_resource[0].uart_base_addr = (void *) ints[i+1];
40321 +                       }
40322 +                       else if (i == 1) {
40323 +                               ubi32_serdes_resource[0].uart_irq = ints[i+1];
40324 +                       }
40325 +                       else if (i == 2) {
40326 +                               ubi32_serdes_resource[0].uart_clock = ints[i+1];
40327 +                       }
40328 +                       else if (i == 3) {
40329 +                               ubi32_serdes_default_baud_rate = ints[i+1];
40330 +                       }
40331 +               }
40332 +       }
40333 +       return 1;
40334 +}
40335 +
40336 +__setup("serdes=", ubi32_serdes_setup);
40337 +#endif
40338 +
40339 +static int __init ubi32_serdes_init(void)
40340 +{
40341 +       int ret;
40342 +
40343 +       pr_info("Serial: Ubicom32 serdes uart serial driver\n");
40344 +
40345 +       ret = platform_driver_probe(&ubi32_serdes_driver, ubi32_serdes_probe);
40346 +       if (ret != 0) {
40347 +               printk(KERN_INFO "serdes platform_driver_probe() failed: %d\n", ret);
40348 +               return ret;
40349 +       }
40350 +
40351 +       ubi32_serdes_init_ports();
40352 +
40353 +       ret = uart_register_driver(&ubi32_serdes_reg);
40354 +       if ( ret == 0 ) {
40355 +               ret = uart_add_one_port(&ubi32_serdes_reg, &ubi32_serdes_ports[0]);
40356 +               if ( ret != 0 ) {
40357 +                       uart_unregister_driver(&ubi32_serdes_reg);
40358 +               }
40359 +       }
40360 +
40361 +       return ret;
40362 +}
40363 +
40364 +static void __exit ubi32_serdes_exit(void)
40365 +{
40366 +       platform_driver_unregister(&ubi32_serdes_driver);
40367 +       uart_unregister_driver(&ubi32_serdes_reg);
40368 +}
40369 +
40370 +module_init(ubi32_serdes_init);
40371 +module_exit(ubi32_serdes_exit);
40372 +
40373 +MODULE_AUTHOR("Rainer Keller <rkeller@ubicom.com>");
40374 +MODULE_DESCRIPTION("Ubicom generic serial port driver");
40375 +MODULE_LICENSE("GPL");
40376 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_SERDES_MAJOR);
40377 +MODULE_ALIAS("platform:ubi32_serdes");
40378 --- /dev/null
40379 +++ b/drivers/serial/ubi32_uarttio.c
40380 @@ -0,0 +1,1171 @@
40381 +/*
40382 + * drivers/serial/ubi32_uarttio.c
40383 + *   Ubicom32 Serial Virtual Peripherial Driver
40384 + *
40385 + * (C) Copyright 2009, Ubicom, Inc.
40386 + *
40387 + * This file is part of the Ubicom32 Linux Kernel Port.
40388 + *
40389 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
40390 + * it and/or modify it under the terms of the GNU General Public License
40391 + * as published by the Free Software Foundation, either version 2 of the
40392 + * License, or (at your option) any later version.
40393 + *
40394 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
40395 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
40396 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
40397 + * the GNU General Public License for more details.
40398 + *
40399 + * You should have received a copy of the GNU General Public License
40400 + * along with the Ubicom32 Linux Kernel Port.  If not, 
40401 + * see <http://www.gnu.org/licenses/>.
40402 + */
40403 +
40404 +#include <linux/module.h>
40405 +#include <linux/ioport.h>
40406 +#include <linux/init.h>
40407 +#include <linux/console.h>
40408 +#include <linux/sysrq.h>
40409 +#include <linux/platform_device.h>
40410 +#include <linux/tty.h>
40411 +#include <linux/tty_flip.h>
40412 +#include <linux/serial_core.h>
40413 +
40414 +#include <asm/ip5000.h>
40415 +#include <asm/gpio.h>
40416 +#include <asm/thread.h>
40417 +#include <asm/uart_tio.h>
40418 +
40419 +#define DRIVER_NAME    "ubi32_uarttio"
40420 +
40421 +/*
40422 + * For storing the module parameters.
40423 + */
40424 +#define UBI32_UARTTIO_MAX_PARAM_LEN    80
40425 +static char utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN];
40426 +
40427 +/* 
40428 + * UART name and device definitions 
40429 + */
40430 +#define UBI32_UARTTIO_NAME     "ttyUV" // XXX
40431 +#define UBI32_UARTTIO_MAJOR    206 // XXX
40432 +#define UBI32_UARTTIO_MINOR    64 // XXX
40433 +
40434 +/*
40435 + * The following structures are allocated statically because the
40436 + * memory allocation subsystem is not initialized this early on
40437 + */
40438 +
40439 +/*
40440 + * Per port structure
40441 + */
40442 +struct ubi32_uarttio_port {
40443 +       struct uarttio_uart             *uart;
40444 +       unsigned int                    tx_pin;
40445 +       unsigned int                    rx_pin;
40446 +
40447 +       struct uart_port                port;
40448 +
40449 +       u8_t                            added;
40450 +
40451 +       /*
40452 +        * If this value is set, the port has had its direction set already
40453 +        */
40454 +       u8_t                            port_init;
40455 +};
40456 +static struct ubi32_uarttio_port uarttio_ports[CONFIG_SERIAL_UBI32_UARTTIO_NR_UARTS];
40457 +
40458 +/*
40459 + * Number of ports currently initialized
40460 + */
40461 +static int uarttio_nports;
40462 +
40463 +/*
40464 + * Per device structure
40465 + */
40466 +struct ubi32_uarttio_instance {
40467 +       struct uarttio_regs             *regs;
40468 +       struct ubi32_uarttio_port       *ports;
40469 +
40470 +       u8_t                            irq_requested;
40471 +       u8_t                            driver_registered;
40472 +       u8_t                            irq;
40473 +};
40474 +static struct ubi32_uarttio_instance uarttio_inst;
40475 +
40476 +#ifdef CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE
40477 +static struct console ubi32_uarttio_console;
40478 +#define UBI32_UARTTIO_CONSOLE  &ubi32_uarttio_console
40479 +#else
40480 +#define UBI32_UARTTIO_CONSOLE  NULL
40481 +#endif
40482 +
40483 +static struct uart_driver ubi32_uarttio_uart_driver = {
40484 +       .owner                  = THIS_MODULE,
40485 +       .driver_name            = DRIVER_NAME,
40486 +       .dev_name               = UBI32_UARTTIO_NAME,
40487 +       .major                  = UBI32_UARTTIO_MAJOR,
40488 +       .minor                  = UBI32_UARTTIO_MINOR,
40489 +       .cons                   = UBI32_UARTTIO_CONSOLE,
40490 +};
40491 +
40492 +#ifdef UBI32_UARTTIO_UNUSED
40493 +/*
40494 + * ubi32_uarttio_get_send_space
40495 + */
40496 +static int ubi32_uarttio_get_send_space(struct uarttio_uart *uart)
40497 +{
40498 +       int count = uart->tx_fifo_head - uart->tx_fifo_tail;
40499 +       if (count < 0) {
40500 +               count += uart->tx_fifo_size;
40501 +       }
40502 +       return uart->tx_fifo_size - count;
40503 +}
40504 +#endif
40505 +
40506 +/*
40507 + * ubi32_uarttio_get_recv_ready
40508 + */
40509 +static int ubi32_uarttio_get_recv_ready(struct uarttio_uart *uart)
40510 +{
40511 +       int count = uart->rx_fifo_head - uart->rx_fifo_tail;
40512 +       if (count < 0) {
40513 +               count += uart->rx_fifo_size;
40514 +       }
40515 +       return count;
40516 +}
40517 +
40518 +/*
40519 + * ubi32_uarttio_get_char()
40520 + */
40521 +static u8_t ubi32_uarttio_get_char(struct uarttio_uart *uart)
40522 +{
40523 +       /*
40524 +        * Retrieve byte
40525 +        */
40526 +       u32_t tail = uart->rx_fifo_tail;
40527 +       u8_t data = uart->rx_fifo[tail];
40528 +
40529 +       if (++tail == uart->rx_fifo_size) {
40530 +               tail = 0;
40531 +       }
40532 +       uart->rx_fifo_tail = tail;
40533 +
40534 +       return data;
40535 +}
40536 +
40537 +/*
40538 + * ubi32_uarttio_put_char()
40539 + */
40540 +static int ubi32_uarttio_put_char(struct uarttio_uart *uart, u8_t c)
40541 +{
40542 +       u32_t head = uart->tx_fifo_head;
40543 +       u32_t prev = head;
40544 +
40545 +       /*
40546 +        * Wrap
40547 +        */
40548 +       if (++head == uart->tx_fifo_size) {
40549 +               head = 0;
40550 +       }
40551 +
40552 +       /*
40553 +        * If there isn't any space, return EBUSY
40554 +        */
40555 +       if (head == uart->tx_fifo_tail) {
40556 +               return -EBUSY;
40557 +       }
40558 +
40559 +       /*
40560 +        * Put the character in the queue
40561 +        */
40562 +       uart->tx_fifo[prev] = c;
40563 +       uart->tx_fifo_head = head;
40564 +
40565 +       return 0;
40566 +}
40567 +
40568 +/*
40569 + * ubi32_uarttio_set_baud
40570 + */
40571 +static int ubi32_uarttio_set_baud(struct ubi32_uarttio_port *uup, unsigned int baud)
40572 +{
40573 +       if (uup->uart->current_baud_rate == baud) {
40574 +               return 0;
40575 +       }
40576 +
40577 +       uup->uart->baud_rate = baud;
40578 +       uup->uart->flags |= UARTTIO_UART_FLAG_SET_RATE;
40579 +       while (uup->uart->flags & UARTTIO_UART_FLAG_SET_RATE) {
40580 +               cpu_relax();
40581 +       }
40582 +
40583 +       if (uup->uart->current_baud_rate != baud) {
40584 +               /*
40585 +                * Failed to set baud rate
40586 +                */
40587 +               printk(KERN_WARNING "Invalid baud rate %u, running at %u\n", baud, uup->uart->current_baud_rate);
40588 +               return -EINVAL;
40589 +       }
40590 +
40591 +       return 0;
40592 +}
40593 +
40594 +/*
40595 + * ubi32_uarttio_handle_receive
40596 + */
40597 +static void ubi32_uarttio_handle_receive(struct ubi32_uarttio_port *uup, int stat)
40598 +{
40599 +       struct uarttio_uart *uart = uup->uart;
40600 +       struct uart_port *port = &uup->port;
40601 +       struct tty_struct *tty = port->info->port.tty;
40602 +       unsigned char ch = 0;
40603 +       char flag = TTY_NORMAL;
40604 +       int count;
40605 +
40606 +       if ((stat & (UARTTIO_UART_INT_RX | UARTTIO_UART_INT_RXFRAME | UARTTIO_UART_INT_RXOVF)) == 0) {
40607 +               return;
40608 +       }
40609 +
40610 +       if (stat & UARTTIO_UART_INT_RX) {
40611 +               count = ubi32_uarttio_get_recv_ready(uart);
40612 +               port->icount.rx += count;
40613 +       }
40614 +
40615 +       if (stat & UARTTIO_UART_INT_RXOVF) {
40616 +               port->icount.overrun++;
40617 +       }
40618 +
40619 +       if (stat & UARTTIO_UART_INT_RXFRAME) {
40620 +               port->icount.frame++;
40621 +       }
40622 +
40623 +       stat &= ~port->ignore_status_mask;
40624 +
40625 +       if (stat & UARTTIO_UART_INT_RX) {
40626 +               int i;
40627 +               for (i = 0; i < count; i++) {
40628 +                       ch = ubi32_uarttio_get_char(uart);
40629 +                       tty_insert_flip_char(tty, ch, flag);
40630 +               }
40631 +       }
40632 +
40633 +       if (stat & UARTTIO_UART_INT_RXFRAME) {
40634 +               tty_insert_flip_char(tty, 0, TTY_FRAME);
40635 +       }
40636 +
40637 +       if (stat & UARTTIO_UART_INT_RXOVF) {
40638 +               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
40639 +       }
40640 +}
40641 +
40642 +/*
40643 + * ubi32_uarttio_stop_tx
40644 + *     interrupts are disabled on entry
40645 + */
40646 +static void ubi32_uarttio_stop_tx(struct uart_port *port)
40647 +{
40648 +       struct ubi32_uarttio_port *uup = port->private_data;
40649 +
40650 +       uup->uart->int_mask &= ~UARTTIO_UART_INT_TXBE;
40651 +}
40652 +
40653 +/*
40654 + * ubi32_uarttio_handle_transmit
40655 + */
40656 +static void ubi32_uarttio_handle_transmit(struct ubi32_uarttio_port *uup, int stat)
40657 +{
40658 +       struct uarttio_uart *uart = uup->uart;
40659 +       struct uart_port *port = &uup->port;
40660 +       struct circ_buf *xmit  = &port->info->xmit;
40661 +
40662 +       if (!(stat & UARTTIO_UART_INT_TXBE)) {
40663 +               return;
40664 +       }
40665 +
40666 +       if (port->x_char) {
40667 +               if (ubi32_uarttio_put_char(uart, port->x_char)) {
40668 +                       return;
40669 +               }
40670 +               port->x_char = 0;
40671 +               port->icount.tx++;
40672 +               return;
40673 +       }
40674 +
40675 +       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
40676 +               ubi32_uarttio_stop_tx(port);
40677 +               return;
40678 +       }
40679 +
40680 +       /*
40681 +        * Send as many characters as we can
40682 +        */
40683 +       while (ubi32_uarttio_put_char(uart, xmit->buf[xmit->tail]) == 0) {
40684 +               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
40685 +               port->icount.tx++;
40686 +               if (uart_circ_empty(xmit)) {
40687 +                       break;
40688 +               }
40689 +       }
40690 +
40691 +       /* wake up */
40692 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
40693 +               uart_write_wakeup(port);
40694 +       }
40695 +
40696 +       if (uart_circ_empty(xmit)) {
40697 +               ubi32_uarttio_stop_tx(port);
40698 +       }
40699 +}
40700 +
40701 +/*
40702 + * ubi32_uarttio_start_tx
40703 + *     port is locked and interrupts are disabled
40704 + */
40705 +static void ubi32_uarttio_start_tx(struct uart_port *port)
40706 +{
40707 +       struct ubi32_uarttio_port *uup = port->private_data;
40708 +       struct uarttio_uart *uart = uup->uart;
40709 +
40710 +       uart->int_mask |= UARTTIO_UART_INT_TXBE;
40711 +}
40712 +
40713 +/*
40714 + * ubi32_uarttio_stop_rx
40715 + *     Interrupts are enabled
40716 + */
40717 +static void ubi32_uarttio_stop_rx(struct uart_port *port)
40718 +{
40719 +       struct ubi32_uarttio_port *uup = port->private_data;
40720 +       struct uarttio_uart *uart = uup->uart;
40721 +
40722 +       /* 
40723 +        * don't forward any more data (like !CREAD) 
40724 +        */
40725 +       uart->int_mask &= ~UARTTIO_UART_INT_RX;
40726 +       port->ignore_status_mask = UARTTIO_UART_INT_RX;
40727 +}
40728 +
40729 +/*
40730 + * ubi32_uarttio_enable_ms
40731 + *     Set the modem control timer to fire immediately.
40732 + */
40733 +static void ubi32_uarttio_enable_ms(struct uart_port *port)
40734 +{
40735 +       /* N/A */
40736 +}
40737 +
40738 +/*
40739 + * ubi32_uarttio_isr
40740 + */
40741 +static irqreturn_t ubi32_uarttio_isr(int irq, void *appdata)
40742 +{
40743 +       struct ubi32_uarttio_port *uup = uarttio_ports;
40744 +       int i;
40745 +
40746 +       /*
40747 +        * Service all of the ports
40748 +        */
40749 +       for (i = 0; i < uarttio_nports; i++) {
40750 +               unsigned int flags;
40751 +
40752 +               if (!(uup->uart->flags & UARTTIO_UART_FLAG_ENABLED)) {
40753 +                       uup++;
40754 +                       continue;
40755 +               }
40756 +
40757 +               spin_lock(&uup->port.lock);
40758 +
40759 +               flags = uup->uart->int_flags;
40760 +
40761 +               uup->uart->int_flags = 0;
40762 +
40763 +               ubi32_uarttio_handle_receive(uup, flags);
40764 +               ubi32_uarttio_handle_transmit(uup, flags);
40765 +
40766 +               tty_flip_buffer_push(uup->port.info->port.tty);
40767 +
40768 +               spin_unlock(&uup->port.lock);
40769 +
40770 +               uup++;
40771 +       }
40772 +
40773 +       return IRQ_HANDLED;
40774 +}
40775 +
40776 +/*
40777 + * ubi32_uarttio_tx_empty
40778 + *     Return TIOCSER_TEMT when transmitter is not busy.
40779 + */
40780 +static unsigned int ubi32_uarttio_tx_empty(struct uart_port *port)
40781 +{
40782 +       struct ubi32_uarttio_port *uup = port->private_data;
40783 +
40784 +       if (uup->uart->tx_fifo_head == uup->uart->tx_fifo_tail) {
40785 +               return TIOCSER_TEMT;
40786 +       }
40787 +
40788 +       return 0;
40789 +}
40790 +
40791 +/*
40792 + * ubi32_uarttio_get_mctrl
40793 + */
40794 +static unsigned int ubi32_uarttio_get_mctrl(struct uart_port *port)
40795 +{
40796 +       return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
40797 +}
40798 +
40799 +/*
40800 + * ubi32_uarttio_set_mctrl
40801 + */
40802 +static void ubi32_uarttio_set_mctrl(struct uart_port *port, unsigned int mctrl)
40803 +{
40804 +       /* N/A */
40805 +}
40806 +
40807 +/*
40808 + * ubi32_uarttio_break_ctl
40809 + */
40810 +static void ubi32_uarttio_break_ctl(struct uart_port *port, int break_state)
40811 +{
40812 +       /* N/A */
40813 +}
40814 +
40815 +/*
40816 + * ubi32_uarttio_startup
40817 + */
40818 +static int ubi32_uarttio_startup(struct uart_port *port)
40819 +{
40820 +       struct ubi32_uarttio_port *uup = port->private_data;
40821 +       struct uarttio_uart *uart = uup->uart;
40822 +
40823 +       uart->flags |= UARTTIO_UART_FLAG_ENABLED;
40824 +
40825 +       uart->int_mask |= UARTTIO_UART_INT_TXBE | UARTTIO_UART_INT_RX;
40826 +
40827 +       return 0;
40828 +}
40829 +
40830 +/*
40831 + * ubi32_uarttio_shutdown
40832 + */
40833 +static void ubi32_uarttio_shutdown(struct uart_port *port)
40834 +{
40835 +       struct ubi32_uarttio_port *uup = port->private_data;
40836 +       struct uarttio_uart *uart = uup->uart;
40837 +
40838 +       uart->int_mask = 0;
40839 +       uart->flags &= ~UARTTIO_UART_FLAG_ENABLED;
40840 +}
40841 +
40842 +/*
40843 + * ubi32_uarttio_set_termios
40844 + */
40845 +static void ubi32_uarttio_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
40846 +{
40847 +       struct ubi32_uarttio_port *uup = port->private_data;
40848 +       unsigned long flags;
40849 +       unsigned int baud;
40850 +
40851 +       spin_lock_irqsave(&port->lock, flags);
40852 +
40853 +#if 0
40854 +       port->read_status_mask = UBI32_UARTTIO_RX | UBI32_UARTTIO_RXOVF | UBI32_UARTTIO_TXOVF;
40855 +
40856 +       if (termios->c_iflag & INPCK) {
40857 +               port->read_status_mask |= UBI32_UARTTIO_RXFRAME;
40858 +       }
40859 +#endif
40860 +
40861 +       port->ignore_status_mask = 0;
40862 +       if (termios->c_iflag & IGNPAR) {
40863 +               port->ignore_status_mask |= UARTTIO_UART_INT_RXFRAME | 
40864 +                                           UARTTIO_UART_INT_RXOVF;
40865 +       }
40866 +
40867 +       /* 
40868 +        * ignore all characters if CREAD is not set 
40869 +        */
40870 +       if ((termios->c_cflag & CREAD) == 0) {
40871 +               port->ignore_status_mask |= UARTTIO_UART_INT_RX | 
40872 +                                           UARTTIO_UART_INT_RXFRAME | 
40873 +                                           UARTTIO_UART_INT_RXOVF;
40874 +       }
40875 +
40876 +       /* update timeout */
40877 +       baud = uart_get_baud_rate(port, termios, old, 0, 460800);
40878 +       uart_update_timeout(port, termios->c_cflag, baud);
40879 +
40880 +       ubi32_uarttio_set_baud(uup, baud);
40881 +       spin_unlock_irqrestore(&port->lock, flags);
40882 +}
40883 +
40884 +/*
40885 + * ubi32_uarttio_type
40886 + */
40887 +static const char *ubi32_uarttio_type(struct uart_port *port)
40888 +{
40889 +       return (port->type == PORT_UBI32_UARTTIO) ? "UBI32_UARTTIO" : NULL;
40890 +}
40891 +
40892 +/*
40893 + * ubi32_uarttio_release_port
40894 + *     Release the memory region(s) being used by 'port'.
40895 + */
40896 +static void ubi32_uarttio_release_port(struct uart_port *port)
40897 +{
40898 +}
40899 +
40900 +/*
40901 + * ubi32_uarttio_request_port
40902 + *     Request the memory region(s) being used by 'port'.
40903 + */
40904 +static int ubi32_uarttio_request_port(struct uart_port *port)
40905 +{
40906 +       return 0;
40907 +}
40908 +
40909 +/*
40910 + * ubi32_uarttio_config_port
40911 + *     Configure/autoconfigure the port.
40912 + */
40913 +static void ubi32_uarttio_config_port(struct uart_port *port, int flags)
40914 +{
40915 +       if ((flags & UART_CONFIG_TYPE) && (ubi32_uarttio_request_port(port) == 0)) {
40916 +               port->type = PORT_UBI32_UARTTIO;
40917 +       }
40918 +}
40919 +
40920 +/*
40921 + * ubi32_uarttio_verify_port
40922 + *     Verify the new serial_struct (for TIOCSSERIAL).
40923 + *
40924 + * The only change we allow are to the flags and type, and
40925 + * even then only between PORT_UBI32_UARTTIO and PORT_UNKNOWN
40926 + */
40927 +static int ubi32_uarttio_verify_port(struct uart_port *port, struct serial_struct *ser)
40928 +{
40929 +       return 0;
40930 +}
40931 +
40932 +static struct uart_ops ubi32_uarttio_pops = {
40933 +       .tx_empty       = ubi32_uarttio_tx_empty,
40934 +       .set_mctrl      = ubi32_uarttio_set_mctrl,
40935 +       .get_mctrl      = ubi32_uarttio_get_mctrl,
40936 +       .stop_tx        = ubi32_uarttio_stop_tx,
40937 +       .start_tx       = ubi32_uarttio_start_tx,
40938 +       .stop_rx        = ubi32_uarttio_stop_rx,
40939 +       .enable_ms      = ubi32_uarttio_enable_ms,
40940 +       .break_ctl      = ubi32_uarttio_break_ctl,
40941 +       .startup        = ubi32_uarttio_startup,
40942 +       .shutdown       = ubi32_uarttio_shutdown,
40943 +       .set_termios    = ubi32_uarttio_set_termios,
40944 +       .type           = ubi32_uarttio_type,
40945 +       .release_port   = ubi32_uarttio_release_port,
40946 +       .request_port   = ubi32_uarttio_request_port,
40947 +       .config_port    = ubi32_uarttio_config_port,
40948 +       .verify_port    = ubi32_uarttio_verify_port,
40949 +};
40950 +
40951 +/*
40952 + * ubi32_uarttio_add_ports
40953 + */
40954 +static int __init ubi32_uarttio_add_ports(void)
40955 +{
40956 +       int res = 0;
40957 +       struct ubi32_uarttio_port *uup = uarttio_ports;
40958 +       int i = 0;
40959 +
40960 +       for (i = 0; i < uarttio_nports; i++) {
40961 +               /*
40962 +                * Setup the GPIOs
40963 +                */
40964 +               res = gpio_request(uup->tx_pin, "ubi32_uarttio_tx");
40965 +               if (res) {
40966 +                       printk(KERN_WARNING "Failed to request GPIO %d\n", uup->tx_pin);
40967 +                       res = -EBUSY;
40968 +                       goto next;
40969 +               }
40970 +
40971 +               res = gpio_request(uup->rx_pin, "ubi32_uarttio_rx");
40972 +               if (res) {
40973 +                       gpio_free(uup->tx_pin);
40974 +                       printk(KERN_WARNING "Failed to request GPIO %d\n", uup->rx_pin);
40975 +                       res = -EBUSY;
40976 +                       goto next;
40977 +               }
40978 +
40979 +               res = uart_add_one_port(&ubi32_uarttio_uart_driver, &uup->port);
40980 +               if (res) {
40981 +                       gpio_free(uup->rx_pin);
40982 +                       gpio_free(uup->tx_pin);
40983 +                       res = -ENODEV;
40984 +                       printk(KERN_WARNING "Failed to add port %d,%d\n", uup->tx_pin, uup->rx_pin);
40985 +                       goto next;
40986 +               }
40987 +               uup->added = 1;
40988 +
40989 +               /*
40990 +                * Set the direction of the ports now, after we're sure that everything is ok
40991 +                */
40992 +               if (!uup->port_init) {
40993 +                       gpio_direction_output(uup->tx_pin, 1);
40994 +                       gpio_direction_input(uup->rx_pin);
40995 +               }
40996 +
40997 +next:
40998 +               uup++;
40999 +       }
41000 +       return res;
41001 +}
41002 +
41003 +/*
41004 + * ubi32_uarttio_cleanup
41005 + */
41006 +static void ubi32_uarttio_cleanup(void)
41007 +{
41008 +       struct ubi32_uarttio_port *uup;
41009 +       int i;
41010 +
41011 +       /*
41012 +        * Stop the hardware thread
41013 +        */
41014 +       if (uarttio_inst.regs) {
41015 +               thread_disable(uarttio_inst.regs->thread);
41016 +       }
41017 +       if (uarttio_inst.irq_requested) {
41018 +               free_irq(uarttio_inst.irq, NULL);
41019 +       }
41020 +
41021 +       /*
41022 +        * Get rid of the ports
41023 +        */
41024 +       uup = uarttio_inst.ports;
41025 +       for (i = 0; i < uarttio_nports; i++) {
41026 +               gpio_free(uup->tx_pin);
41027 +               gpio_free(uup->rx_pin);
41028 +               if (uup->added) {
41029 +                       uart_remove_one_port(&ubi32_uarttio_uart_driver, &uup->port);
41030 +               }
41031 +               uup++;
41032 +       }
41033 +
41034 +       if (uarttio_inst.driver_registered) {
41035 +               uart_unregister_driver(&ubi32_uarttio_uart_driver);
41036 +       }
41037 +}
41038 +
41039 +/*
41040 + * ubi32_uarttio_setup_port
41041 + *     Setup a port in the TIO registers
41042 + */
41043 +static int ubi32_uarttio_setup_port(int index,
41044 +                                   struct uarttio_uart *uart,
41045 +                                   unsigned int baud, unsigned int tx_pin, 
41046 +                                   unsigned int rx_pin)
41047 +{
41048 +       struct ubi32_uarttio_port *uup = &uarttio_ports[index];
41049 +       void *tx_port = ubi_gpio_get_port(tx_pin);
41050 +       void *rx_port = ubi_gpio_get_port(rx_pin);
41051 +
41052 +       /*
41053 +        * Verify the ports are on chip
41054 +        */
41055 +       if (!tx_port || !rx_port) {
41056 +               printk(KERN_WARNING "Invalid port(s) specified: %u or %u\n", tx_pin, rx_pin);
41057 +               return -EINVAL;
41058 +       }
41059 +
41060 +       uup->tx_pin = tx_pin;
41061 +       uup->rx_pin = rx_pin;
41062 +       uup->uart = uart;
41063 +
41064 +       /*
41065 +        * Setup the port structure
41066 +        */
41067 +       uup->port.ops           = &ubi32_uarttio_pops;
41068 +       uup->port.line          = index;
41069 +       uup->port.iotype        = UPIO_MEM;
41070 +       uup->port.flags         = UPF_BOOT_AUTOCONF;
41071 +       uup->port.fifosize      = uup->uart->tx_fifo_size;
41072 +       uup->port.private_data  = uup;
41073 +
41074 +       /*
41075 +        * We share this IRQ across all ports
41076 +        */
41077 +       uup->port.irq           = uarttio_inst.irq;
41078 +
41079 +       /*
41080 +        * We really don't have a mem/map base but without these variables
41081 +        * set, the serial_core won't startup.
41082 +        */
41083 +       uup->port.membase       = (void __iomem *)uup;
41084 +       uup->port.mapbase       = (resource_size_t)uup;
41085 +       spin_lock_init(&uup->port.lock);
41086 +
41087 +       /*
41088 +        * Set up the hardware
41089 +        */
41090 +       uart->flags = UARTTIO_UART_FLAG_SET_RATE | UARTTIO_UART_FLAG_RESET;
41091 +
41092 +       uart->tx_port = (unsigned int)tx_port;
41093 +       uart->tx_pin = gpio_pin_index(tx_pin);
41094 +       uart->tx_bits = 8;
41095 +       uart->tx_stop_bits = 1;
41096 +
41097 +       uart->rx_port = (unsigned int)rx_port;
41098 +       uart->rx_pin = gpio_pin_index(rx_pin);
41099 +       uart->rx_bits = 8;
41100 +       uart->rx_stop_bits = 1;
41101 +
41102 +       uart->baud_rate = baud;
41103 +
41104 +       return 0;
41105 +}
41106 +
41107 +enum ubi32_uarttio_parse_states {
41108 +       UBI32_UARTTIO_PARSE_STATE_BAUD,
41109 +       UBI32_UARTTIO_PARSE_STATE_TX_PIN,
41110 +       UBI32_UARTTIO_PARSE_STATE_RX_PIN,
41111 +       UBI32_UARTTIO_PARSE_STATE_HS,
41112 +       UBI32_UARTTIO_PARSE_STATE_CTS_PIN,
41113 +       UBI32_UARTTIO_PARSE_STATE_RTS_PIN,
41114 +};
41115 +
41116 +/*
41117 + * ubi32_uarttio_parse_param
41118 + */
41119 +static int ubi32_uarttio_parse_param(char *str)
41120 +{
41121 +       int res;
41122 +       int i;
41123 +       int baud = 0;
41124 +       int tx_pin = 0;
41125 +       int rx_pin = 0;
41126 +       int hs = 0;
41127 +       int cts_pin = 0;
41128 +       int rts_pin = 0;
41129 +       int nfound = 0;
41130 +       enum ubi32_uarttio_parse_states state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41131 +       struct uarttio_uart *uart = uarttio_inst.regs->uarts;
41132 +
41133 +       /*
41134 +        * Run though the options and generate the proper structures
41135 +        */
41136 +       res = get_option(&str, &i);
41137 +       while ((res == 2) || (res == 1)) {
41138 +               switch (state) {
41139 +               case UBI32_UARTTIO_PARSE_STATE_BAUD:
41140 +                       /*
41141 +                        * If we are here and nfound > 0 then create the port 
41142 +                        * based on the previous input
41143 +                        */
41144 +                       if (nfound) {
41145 +                               /*
41146 +                                * Create the port
41147 +                                */
41148 +                               if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41149 +                                       /*
41150 +                                        * Port was invalid
41151 +                                        */
41152 +                                       goto fail;
41153 +                               } else {
41154 +                                       printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41155 +                                       uart++;
41156 +                               }
41157 +                       }
41158 +
41159 +                       /*
41160 +                        * Reset the variables and go to the next state
41161 +                        */
41162 +                       hs = 0;
41163 +                       baud = i;
41164 +                       state = UBI32_UARTTIO_PARSE_STATE_TX_PIN;
41165 +                       break;
41166 +
41167 +               case UBI32_UARTTIO_PARSE_STATE_TX_PIN:
41168 +                       tx_pin = i;
41169 +                       state = UBI32_UARTTIO_PARSE_STATE_RX_PIN;
41170 +                       break;
41171 +
41172 +               case UBI32_UARTTIO_PARSE_STATE_RX_PIN:
41173 +                       rx_pin = i;
41174 +                       state = UBI32_UARTTIO_PARSE_STATE_HS;
41175 +                       break;
41176 +
41177 +               case UBI32_UARTTIO_PARSE_STATE_HS:
41178 +                       hs = i;
41179 +                       if (hs) {
41180 +                               state = UBI32_UARTTIO_PARSE_STATE_CTS_PIN;
41181 +                               break;
41182 +                       }
41183 +
41184 +                       if (nfound == uarttio_inst.regs->max_uarts) {
41185 +                               printk(KERN_WARNING "Maximum number of serial ports reached\n");
41186 +                               goto done;
41187 +                       }
41188 +                       nfound++;
41189 +                       state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41190 +                       break;
41191 +
41192 +               case UBI32_UARTTIO_PARSE_STATE_CTS_PIN:
41193 +                       cts_pin = i;
41194 +                       state = UBI32_UARTTIO_PARSE_STATE_RTS_PIN;
41195 +                       break;
41196 +
41197 +               case UBI32_UARTTIO_PARSE_STATE_RTS_PIN:
41198 +                       rts_pin = i;
41199 +
41200 +                       if (nfound == uarttio_inst.regs->max_uarts) {
41201 +                               printk(KERN_WARNING "Maximum number of serial ports reached\n");
41202 +                               goto done;
41203 +                       }
41204 +                       nfound++;
41205 +                       state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41206 +                       break;
41207 +               }
41208 +               res = get_option(&str, &i);
41209 +       }
41210 +
41211 +       if ((res > 2) || state != UBI32_UARTTIO_PARSE_STATE_BAUD) {
41212 +               printk(KERN_WARNING "Parameter syntax error.\n");
41213 +               res = -EINVAL;
41214 +               goto fail;
41215 +       }
41216 +
41217 +       /*
41218 +        * Create the final port
41219 +        */
41220 +       if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41221 +               goto fail;
41222 +       }
41223 +       printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41224 +
41225 +done:
41226 +       uarttio_nports = nfound;
41227 +
41228 +       return nfound ? 0 : -ENODEV;
41229 +
41230 +fail:
41231 +       /*
41232 +        * Reset the ports
41233 +        */
41234 +       uart = uarttio_inst.regs->uarts;
41235 +       for (i = 0; i < uarttio_inst.regs->max_uarts; i++) {
41236 +               uart->flags = 0;
41237 +               uart++;
41238 +       }
41239 +
41240 +       return res;
41241 +}
41242 +
41243 +/*
41244 + * ubi32_uarttio_probe
41245 + */
41246 +static int ubi32_uarttio_probe(void)
41247 +{
41248 +       int ret;
41249 +       struct uarttio_node *uart_node;
41250 +       char *str = utio_ports_param;
41251 +       static int probed;
41252 +
41253 +       /*
41254 +        * We only want to be probed once, we could be probed twice
41255 +        * for example if we are used as a console
41256 +        */
41257 +       if (probed) {
41258 +               return 0;
41259 +       }
41260 +       probed = 1;
41261 +
41262 +       /*
41263 +        * Extract the TIO name from the setup string
41264 +        */
41265 +       while (*str) {
41266 +               if (*str == ',') {
41267 +                       *str++ = 0;
41268 +                       break;
41269 +               }
41270 +               str++;
41271 +       }
41272 +
41273 +       if (!*str) {
41274 +               return -EINVAL;
41275 +       }
41276 +
41277 +       uart_node = (struct uarttio_node *)devtree_find_node(utio_ports_param);
41278 +       if (!uart_node) {
41279 +               return -ENODEV;
41280 +       }
41281 +
41282 +       uarttio_inst.irq = uart_node->dn.recvirq;
41283 +       uarttio_inst.regs = uart_node->regs;
41284 +
41285 +       /*
41286 +        * Parse module parameters.
41287 +        */
41288 +       ret = ubi32_uarttio_parse_param(str);
41289 +       if (ret != 0) {
41290 +               goto fail;
41291 +       }
41292 +
41293 +       ubi32_uarttio_uart_driver.nr = uarttio_nports;
41294 +
41295 +       return 0;
41296 +
41297 +fail:
41298 +       ubi32_uarttio_cleanup();
41299 +       return ret;
41300 +}
41301 +
41302 +#if defined(CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE)
41303 +/*
41304 + * ubi32_uarttio_console_setup
41305 + */
41306 +static int __init ubi32_uarttio_console_setup(struct console *co, char *options)
41307 +{
41308 +       int baud;
41309 +       int bits = 8;
41310 +       int parity = 'n';
41311 +       int flow = 'n';
41312 +       struct ubi32_uarttio_port *uup;
41313 +
41314 +       /*
41315 +        * Check whether an invalid uart number has been specified, and
41316 +        * if so, search for the first available port that does have
41317 +        * console support.
41318 +        */
41319 +       if (co->index == -1 || co->index >= uarttio_nports) {
41320 +               co->index = 0;
41321 +       }
41322 +       uup = &uarttio_ports[co->index];
41323 +       baud = uup->uart->baud_rate;
41324 +       uup->uart->flags |= UARTTIO_UART_FLAG_ENABLED;
41325 +
41326 +       /*
41327 +        * Setup the GPIOs
41328 +        *      We have to use the direct interface because the gpio
41329 +        *      subsystem is not available at this point.
41330 +        */
41331 +       uup->port_init = 1;
41332 +       UBICOM32_GPIO_SET_PIN_HIGH(uup->tx_pin);
41333 +       UBICOM32_GPIO_SET_PIN_OUTPUT(uup->tx_pin);
41334 +       UBICOM32_GPIO_SET_PIN_INPUT(uup->rx_pin);
41335 +
41336 +       /*
41337 +        * Start the thread
41338 +        */
41339 +       thread_enable(uarttio_inst.regs->thread);
41340 +
41341 +       /*
41342 +        * Process options
41343 +        */
41344 +       if (options) {
41345 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
41346 +               if (ubi32_uarttio_set_baud(uup, baud)) {
41347 +                       baud = uup->uart->current_baud_rate;
41348 +               }
41349 +       }
41350 +
41351 +       return uart_set_options(&uup->port, co, baud, 'n', 8, 'n');
41352 +}
41353 +
41354 +/*
41355 + * ubi32_uarttio_console_putchar
41356 + */
41357 +static void ubi32_uarttio_console_putchar(struct uart_port *port, int ch)
41358 +{
41359 +       struct ubi32_uarttio_port *uup = port->private_data;
41360 +
41361 +       while (ubi32_uarttio_put_char(uup->uart, ch)) {
41362 +               cpu_relax();
41363 +       }
41364 +}
41365 +
41366 +/*
41367 + * ubi32_uarttio_console_write
41368 + *     Interrupts are disabled on entering
41369 + */
41370 +static void ubi32_uarttio_console_write(struct console *co, const char *s, unsigned int count)
41371 +{
41372 +       struct uart_port *port = &(uarttio_ports[co->index].port);
41373 +       unsigned long flags = 0;
41374 +
41375 +       spin_lock_irqsave(&port->lock, flags);
41376 +       uart_console_write(port, s, count, ubi32_uarttio_console_putchar);
41377 +       spin_unlock_irqrestore(&port->lock, flags);
41378 +}
41379 +
41380 +static struct console ubi32_uarttio_console = {
41381 +       .name           = UBI32_UARTTIO_NAME,
41382 +       .write          = ubi32_uarttio_console_write,
41383 +       .device         = uart_console_device,
41384 +       .setup          = ubi32_uarttio_console_setup,
41385 +       .flags          = CON_PRINTBUFFER,
41386 +       .index          = -1,
41387 +       .data           = &ubi32_uarttio_uart_driver,
41388 +};
41389 +
41390 +static int __init ubi32_uarttio_console_init(void)
41391 +{
41392 +       int res;
41393 +       
41394 +       res = ubi32_uarttio_probe();
41395 +       if (res) {
41396 +               return res;
41397 +       }
41398 +
41399 +       register_console(&ubi32_uarttio_console);
41400 +       return 0;
41401 +}
41402 +console_initcall(ubi32_uarttio_console_init);
41403 +#endif /* CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE */
41404 +
41405 +/*
41406 + * ubi32_serial_suspend
41407 + */
41408 +static int ubi32_uarttio_suspend(struct platform_device *pdev, pm_message_t state)
41409 +{
41410 +       int i;
41411 +       for (i = 0; i < uarttio_nports; i++) {
41412 +               uart_suspend_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41413 +       }
41414 +
41415 +       return 0;
41416 +}
41417 +
41418 +/*
41419 + * ubi32_serial_resume
41420 + */
41421 +static int ubi32_uarttio_resume(struct platform_device *pdev)
41422 +{
41423 +       int i;
41424 +       for (i = 0; i < uarttio_nports; i++) {
41425 +               uart_resume_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41426 +       }
41427 +
41428 +       return 0;
41429 +}
41430 +
41431 +/*
41432 + * ubi32_uarttio_remove
41433 + */
41434 +static int __devexit ubi32_uarttio_remove(struct platform_device *pdev)
41435 +{
41436 +       ubi32_uarttio_cleanup();
41437 +
41438 +       uart_unregister_driver(&ubi32_uarttio_uart_driver);
41439 +
41440 +       return 0;
41441 +}
41442 +
41443 +static struct platform_driver ubi32_uarttio_platform_driver = {
41444 +       .remove         = __devexit_p(ubi32_uarttio_remove),
41445 +       .suspend        = ubi32_uarttio_suspend,
41446 +       .resume         = ubi32_uarttio_resume,
41447 +       .driver         = {
41448 +               .name   = DRIVER_NAME,
41449 +               .owner  = THIS_MODULE,
41450 +       },
41451 +};
41452 +
41453 +#ifndef MODULE
41454 +/*
41455 + * Called at boot time.
41456 + *
41457 + * uarttio=TIONAME,(baud,tx_pin,rx_pin,handshake[,cts_pin,rts_pin],...)
41458 + *     TIONAME is the name of the devtree node which describes the UARTTIO
41459 + *     pin is the index of the pin, i.e. PA4 is 5 [(port * 32) + pin]
41460 + *     handshake = 1 to enable handshaking, provide cts_pin, rts_pin (UNSUPPORTED)
41461 + *     handshake = 0 to disable handshaking, do not provide cts_pin, rts_pin
41462 + *     Ex: uarttio=UARTTIO,57600,7,6,0,9600,8,9,0
41463 + */
41464 +static int __init ubi32_uarttio_setup(char *str)
41465 +{
41466 +       strncpy(utio_ports_param, str, UBI32_UARTTIO_MAX_PARAM_LEN);
41467 +       utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN - 1] = 0;
41468 +       return 1;
41469 +}
41470 +__setup("uarttio=", ubi32_uarttio_setup);
41471 +#endif
41472 +
41473 +/*
41474 + * ubi32_uarttio_init
41475 + */
41476 +static int __init ubi32_uarttio_init(void)
41477 +{
41478 +       int ret;
41479 +       int i;
41480 +
41481 +       ret = ubi32_uarttio_probe();
41482 +       if (ret) {
41483 +               return ret;
41484 +       }
41485 +
41486 +       /*
41487 +        * Request the IRQ (do it here since many ports share the same IRQ)
41488 +        */
41489 +       ret = request_irq(uarttio_inst.irq, ubi32_uarttio_isr, IRQF_DISABLED, DRIVER_NAME, NULL);
41490 +       if (ret != 0) {
41491 +               printk(KERN_WARNING "Could not request IRQ %d\n", uarttio_inst.irq);
41492 +               goto fail;
41493 +       }
41494 +       uarttio_inst.irq_requested = 1;
41495 +
41496 +       /*
41497 +        * Register the UART driver and add the ports
41498 +        */
41499 +       ret = uart_register_driver(&ubi32_uarttio_uart_driver);
41500 +       if (ret != 0) {
41501 +               goto fail;
41502 +       }
41503 +       uarttio_inst.driver_registered = 1;
41504 +
41505 +       ret = ubi32_uarttio_add_ports();
41506 +       if (ret != 0) {
41507 +               ubi32_uarttio_cleanup();
41508 +               return ret;
41509 +       }
41510 +
41511 +       /*
41512 +        * Start the thread
41513 +        */
41514 +       thread_enable(uarttio_inst.regs->thread);
41515 +
41516 +       for (i = 0; i < uarttio_nports; i++) {
41517 +               pr_info("Serial: Ubicom32 uarttio #%d: tx:%d rx:%d baud:%d\n", 
41518 +                       i, uarttio_ports[i].tx_pin, uarttio_ports[i].rx_pin,
41519 +                       uarttio_ports[i].uart->current_baud_rate);
41520 +       }
41521 +       pr_info("Serial: Ubicom32 uarttio started on thread:%d irq:%d\n", uarttio_inst.regs->thread, uarttio_inst.irq);
41522 +
41523 +       return ret;
41524 +
41525 +fail:
41526 +       ubi32_uarttio_cleanup();
41527 +       return ret;
41528 +}
41529 +module_init(ubi32_uarttio_init);
41530 +
41531 +/*
41532 + * ubi32_uarttio_exit
41533 + */
41534 +static void __exit ubi32_uarttio_exit(void)
41535 +{
41536 +       platform_driver_unregister(&ubi32_uarttio_platform_driver);
41537 +}
41538 +module_exit(ubi32_uarttio_exit);
41539 +
41540 +module_param_string(ports, utio_ports_param, sizeof(utio_ports_param), 0444);
41541 +MODULE_PARM_DESC(ports, "Sets the ports to allocate: ports=TIONAME,(baud,txpin,rxpin,handshake[,ctspin,rtspin],...)\n"
41542 +                       "     TIONAME is the name of the devtree node which describes the UARTTIO\n"
41543 +                       "     pin is the index of the pin, i.e. PA4 is 5 [(port * 32) + pin]\n"
41544 +                       "     handshake = 1 to enable handshaking, provide ctspin, rtspin (UNSUPPORTED)\n"
41545 +                       "     handshake = 0 to disable handshaking, do not provide ctspin, rtspin\n"
41546 +                       "     Ex: ports=UARTTIO,57600,7,6,0,9600,8,9,0\n");
41547 +MODULE_AUTHOR("Patrick Tjin <pat.tjin@ubicom.com>");
41548 +MODULE_DESCRIPTION("Ubicom serial virtual peripherial driver");
41549 +MODULE_LICENSE("GPL");
41550 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_UARTTIO_MAJOR);
41551 +MODULE_ALIAS("platform:" DRIVER_NAME);
41552 --- a/drivers/spi/Kconfig
41553 +++ b/drivers/spi/Kconfig
41554 @@ -196,6 +196,15 @@ config SPI_S3C24XX
41555         help
41556           SPI driver for Samsung S3C24XX series ARM SoCs
41557  
41558 +config SPI_UBICOM32_GPIO
41559 +       tristate "Ubicom32 SPI over GPIO"
41560 +       depends on SPI_MASTER && UBICOM32 && EXPERIMENTAL
41561 +       select SPI_BITBANG
41562 +       select HAS_DMA
41563 +       help
41564 +         SPI driver for the Ubicom32 architecture using
41565 +         GPIO lines to provide the SPI bus.
41566 +         
41567  config SPI_S3C24XX_GPIO
41568         tristate "Samsung S3C24XX series SPI by GPIO"
41569         depends on ARCH_S3C2410 && EXPERIMENTAL
41570 --- a/drivers/spi/Makefile
41571 +++ b/drivers/spi/Makefile
41572 @@ -27,6 +27,7 @@ obj-$(CONFIG_SPI_ORION)                       += orion_spi.o
41573  obj-$(CONFIG_SPI_MPC52xx_PSC)          += mpc52xx_psc_spi.o
41574  obj-$(CONFIG_SPI_MPC83xx)              += spi_mpc83xx.o
41575  obj-$(CONFIG_SPI_S3C24XX_GPIO)         += spi_s3c24xx_gpio.o
41576 +obj-$(CONFIG_SPI_UBICOM32_GPIO)                += spi_ubicom32_gpio.o
41577  obj-$(CONFIG_SPI_S3C24XX)              += spi_s3c24xx.o
41578  obj-$(CONFIG_SPI_TXX9)                 += spi_txx9.o
41579  obj-$(CONFIG_SPI_XILINX)               += xilinx_spi.o
41580 --- /dev/null
41581 +++ b/drivers/spi/spi_ubicom32_gpio.c
41582 @@ -0,0 +1,268 @@
41583 +/*
41584 + * drivers/spi_spi_ubicom32_gpio.c
41585 + *     Ubicom32 GPIO based SPI driver
41586 + *
41587 + * (C) Copyright 2009, Ubicom, Inc.
41588 + *
41589 + * This file is part of the Ubicom32 Linux Kernel Port.
41590 + *
41591 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
41592 + * it and/or modify it under the terms of the GNU General Public License
41593 + * as published by the Free Software Foundation, either version 2 of the
41594 + * License, or (at your option) any later version.
41595 + *
41596 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
41597 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
41598 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
41599 + * the GNU General Public License for more details.
41600 + *
41601 + * You should have received a copy of the GNU General Public License
41602 + * along with the Ubicom32 Linux Kernel Port.  If not,
41603 + * see <http://www.gnu.org/licenses/>.
41604 + *
41605 + * Ubicom32 implementation derived from (with many thanks):
41606 + *   arch/m68knommu
41607 + *   arch/blackfin
41608 + *   arch/parisc
41609 + */
41610 +#include <linux/kernel.h>
41611 +#include <linux/init.h>
41612 +#include <linux/delay.h>
41613 +#include <linux/spinlock.h>
41614 +#include <linux/workqueue.h>
41615 +#include <linux/platform_device.h>
41616 +
41617 +#include <linux/spi/spi.h>
41618 +#include <linux/spi/spi_bitbang.h>
41619 +
41620 +#include <linux/gpio.h>
41621 +
41622 +#include <asm/ip5000.h>
41623 +#include <asm/ubicom32-spi-gpio.h>
41624 +
41625 +#define DRIVER_NAME "ubicom32-spi-gpio"
41626 +
41627 +struct ubicom32_spi_gpio {
41628 +       struct spi_bitbang                       bitbang;
41629 +
41630 +       struct ubicom32_spi_gpio_platform_data  *pdata;
41631 +
41632 +       struct platform_device                  *dev;
41633 +};
41634 +
41635 +/*
41636 + * The following 4 functions are used by EXPAND_BITBANG_TXRX to bitbang the data out.
41637 + */
41638 +static inline void setsck(struct spi_device *dev, int on)
41639 +{
41640 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41641 +       gpio_set_value(usg->pdata->pin_clk, on ? 1 : 0);
41642 +}
41643 +
41644 +static inline void setmosi(struct spi_device *dev, int on)
41645 +{
41646 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41647 +       gpio_set_value(usg->pdata->pin_mosi, on ? 1 : 0);
41648 +}
41649 +
41650 +static inline u32 getmiso(struct spi_device *dev)
41651 +{
41652 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41653 +       return gpio_get_value(usg->pdata->pin_miso) ? 1 : 0;
41654 +}
41655 +
41656 +#define spidelay(x) ndelay(x)
41657 +
41658 +#define        EXPAND_BITBANG_TXRX
41659 +#include <linux/spi/spi_bitbang.h>
41660 +
41661 +/*
41662 + * ubicom32_spi_gpio_txrx_mode0
41663 + */
41664 +static u32 ubicom32_spi_gpio_txrx_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41665 +{
41666 +       return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
41667 +}
41668 +
41669 +/*
41670 + * ubicom32_spi_gpio_txrx_mode1
41671 + */
41672 +static u32 ubicom32_spi_gpio_txrx_mode1(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41673 +{
41674 +       return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
41675 +}
41676 +
41677 +/*
41678 + * ubicom32_spi_gpio_txrx_mode2
41679 + */
41680 +static u32 ubicom32_spi_gpio_txrx_mode2(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41681 +{
41682 +       return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
41683 +}
41684 +
41685 +/*
41686 + * ubicom32_spi_gpio_txrx_mode3
41687 + */
41688 +static u32 ubicom32_spi_gpio_txrx_mode3(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41689 +{
41690 +       return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
41691 +}
41692 +
41693 +/*
41694 + * ubicom32_spi_gpio_chipselect
41695 + */
41696 +static void ubicom32_spi_gpio_chipselect(struct spi_device *dev, int value)
41697 +{
41698 +       struct ubicom32_spi_gpio_controller_data *cd = (struct ubicom32_spi_gpio_controller_data *)dev->controller_data;
41699 +       unsigned int cs_polarity = dev->mode & SPI_CS_HIGH ? 1 : 0;
41700 +
41701 +       if (value == BITBANG_CS_ACTIVE) {
41702 +               gpio_set_value(cd->pin_cs, cs_polarity);
41703 +               return;
41704 +       }
41705 +       gpio_set_value(cd->pin_cs, !cs_polarity);
41706 +}
41707 +
41708 +/*
41709 + * ubicom32_spi_gpio_probe
41710 + */
41711 +static int ubicom32_spi_gpio_probe(struct platform_device *dev)
41712 +{
41713 +       struct ubicom32_spi_gpio_platform_data *pdata;
41714 +       struct spi_master *master;
41715 +       struct ubicom32_spi_gpio *usg;
41716 +       int ret;
41717 +
41718 +       master = spi_alloc_master(&dev->dev, sizeof(struct ubicom32_spi_gpio));
41719 +       if (master == NULL) {
41720 +               dev_err(&dev->dev, "failed to allocate spi master\n");
41721 +               ret = -ENOMEM;
41722 +               goto err;
41723 +       }
41724 +
41725 +       usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(master);
41726 +
41727 +       platform_set_drvdata(dev, usg);
41728 +
41729 +       /* 
41730 +        * Copy in the platform data
41731 +        */
41732 +       pdata = dev->dev.platform_data;
41733 +       usg->pdata = dev->dev.platform_data;
41734 +
41735 +       /*
41736 +        * Request the GPIO lines
41737 +        */
41738 +       ret = gpio_request(pdata->pin_mosi, "spi-mosi");
41739 +       if (ret) {
41740 +               dev_err(&dev->dev, "Failed to allocate spi-mosi GPIO\n");
41741 +               goto err;
41742 +       }
41743 +
41744 +       ret = gpio_request(pdata->pin_miso, "spi-miso");
41745 +       if (ret) {
41746 +               dev_err(&dev->dev, "Failed to allocate spi-miso GPIO\n");
41747 +               goto err_nomiso;
41748 +       }
41749 +
41750 +       ret = gpio_request(pdata->pin_clk, "spi-clk");
41751 +       if (ret) {
41752 +               dev_err(&dev->dev, "Failed to allocate spi-clk GPIO\n");
41753 +               goto err_noclk;
41754 +       }
41755 +
41756 +       /*
41757 +        * Setup spi-bitbang adaptor
41758 +        */
41759 +       usg->bitbang.flags |= SPI_CS_HIGH;
41760 +       usg->bitbang.master = spi_master_get(master);
41761 +       usg->bitbang.master->bus_num = pdata->bus_num;
41762 +       usg->bitbang.master->num_chipselect = pdata->num_chipselect;
41763 +       usg->bitbang.chipselect = ubicom32_spi_gpio_chipselect;
41764 +
41765 +       usg->bitbang.txrx_word[SPI_MODE_0] = ubicom32_spi_gpio_txrx_mode0;
41766 +       usg->bitbang.txrx_word[SPI_MODE_1] = ubicom32_spi_gpio_txrx_mode1;
41767 +       usg->bitbang.txrx_word[SPI_MODE_2] = ubicom32_spi_gpio_txrx_mode2;
41768 +       usg->bitbang.txrx_word[SPI_MODE_3] = ubicom32_spi_gpio_txrx_mode3;
41769 +
41770 +       /*
41771 +        * Setup the GPIO pins
41772 +        */
41773 +       gpio_direction_output(pdata->pin_clk, pdata->clk_default);
41774 +       gpio_direction_output(pdata->pin_mosi, 0);
41775 +       gpio_direction_input(pdata->pin_miso);
41776 +
41777 +       /*
41778 +        * Ready to go
41779 +        */
41780 +       ret = spi_bitbang_start(&usg->bitbang);
41781 +       if (ret) {
41782 +               goto err_no_bitbang;
41783 +       }
41784 +
41785 +       return 0;
41786 +
41787 +err_no_bitbang:
41788 +       spi_master_put(usg->bitbang.master);
41789 +
41790 +       gpio_free(pdata->pin_clk);
41791 +
41792 +err_noclk:
41793 +       gpio_free(pdata->pin_miso);
41794 +
41795 +err_nomiso:
41796 +       gpio_free(pdata->pin_mosi);
41797 +
41798 +err:
41799 +       return ret;
41800 +}
41801 +
41802 +/*
41803 + * ubicom32_spi_gpio_remove
41804 + */
41805 +static int ubicom32_spi_gpio_remove(struct platform_device *dev)
41806 +{
41807 +       struct ubicom32_spi_gpio *sp = platform_get_drvdata(dev);
41808 +
41809 +       spi_bitbang_stop(&sp->bitbang);
41810 +       spi_master_put(sp->bitbang.master);
41811 +
41812 +       return 0;
41813 +}
41814 +
41815 +/*
41816 + * Work with hotplug and coldplug
41817 + */
41818 +MODULE_ALIAS("platform:ubicom32_spi_gpio");
41819 +
41820 +static struct platform_driver ubicom32_spi_gpio_drv = {
41821 +       .probe          = ubicom32_spi_gpio_probe,
41822 +        .remove                = ubicom32_spi_gpio_remove,
41823 +        .driver                = {
41824 +               .name   = DRIVER_NAME,
41825 +               .owner  = THIS_MODULE,
41826 +        },
41827 +};
41828 +
41829 +/*
41830 + * ubicom32_spi_gpio_init
41831 + */
41832 +static int __init ubicom32_spi_gpio_init(void)
41833 +{
41834 +        return platform_driver_register(&ubicom32_spi_gpio_drv);
41835 +}
41836 +
41837 +/*
41838 + * ubicom32_spi_gpio_exit
41839 + */
41840 +static void __exit ubicom32_spi_gpio_exit(void)
41841 +{
41842 +        platform_driver_unregister(&ubicom32_spi_gpio_drv);
41843 +}
41844 +
41845 +module_init(ubicom32_spi_gpio_init);
41846 +module_exit(ubicom32_spi_gpio_exit);
41847 +
41848 +MODULE_DESCRIPTION("Ubicom32 SPI-GPIO Driver");
41849 +MODULE_AUTHOR("Pat Tjin, <@ubicom.com>");
41850 +MODULE_LICENSE("GPL");
41851 --- a/drivers/uio/Kconfig
41852 +++ b/drivers/uio/Kconfig
41853 @@ -71,4 +71,12 @@ config UIO_SERCOS3
41854  
41855           If you compile this as a module, it will be called uio_sercos3.
41856  
41857 +config UIO_UBICOM32RING
41858 +       tristate "Ubicom32 Ring Buffer driver"
41859 +       default n
41860 +       help
41861 +         Userspace I/O interface for a Ubicom32 Ring Buffer.
41862 +
41863 +         If you compile this as a module, it will be called uio_ubicom32ring
41864 +
41865  endif
41866 --- a/drivers/uio/Makefile
41867 +++ b/drivers/uio/Makefile
41868 @@ -4,3 +4,4 @@ obj-$(CONFIG_UIO_PDRV)  += uio_pdrv.o
41869  obj-$(CONFIG_UIO_PDRV_GENIRQ)  += uio_pdrv_genirq.o
41870  obj-$(CONFIG_UIO_SMX)  += uio_smx.o
41871  obj-$(CONFIG_UIO_SERCOS3)      += uio_sercos3.o
41872 +obj-$(CONFIG_UIO_UBICOM32RING) += uio_ubicom32ring.o
41873 --- /dev/null
41874 +++ b/drivers/uio/uio_ubicom32ring.c
41875 @@ -0,0 +1,289 @@
41876 +/*
41877 + * drivers/uio/uio_ubicom32ring.c
41878 + *
41879 + * Userspace I/O platform driver for Ubicom32 ring buffers
41880 + *
41881 + * (C) Copyright 2009, Ubicom, Inc.
41882 + *
41883 + * This file is part of the Ubicom32 Linux Kernel Port.
41884 + *
41885 + * Based on uio_ubicom32ring.c by Magnus Damm
41886 + *
41887 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
41888 + * it and/or modify it under the terms of the GNU General Public License
41889 + * as published by the Free Software Foundation, either version 2 of the
41890 + * License, or (at your option) any later version.
41891 + *
41892 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
41893 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
41894 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
41895 + * the GNU General Public License for more details.
41896 + *
41897 + * You should have received a copy of the GNU General Public License
41898 + * along with the Ubicom32 Linux Kernel Port.  If not,
41899 + * see <http://www.gnu.org/licenses/>.
41900 + */
41901 +
41902 +#include <linux/platform_device.h>
41903 +#include <linux/uio_driver.h>
41904 +#include <linux/spinlock.h>
41905 +#include <linux/bitops.h>
41906 +#include <linux/interrupt.h>
41907 +#include <linux/stringify.h>
41908 +
41909 +#include <asm/ip5000.h>
41910 +#include <asm/ubicom32ring.h>
41911 +
41912 +#define DRIVER_NAME "uio_ubicom32ring"
41913 +
41914 +struct uio_ubicom32ring_data {
41915 +       struct uio_info                 *uioinfo;
41916 +
41917 +       struct uio_ubicom32ring_regs    *regs;
41918 +
41919 +       /*
41920 +        * IRQ used to kick the ring buffer
41921 +        */
41922 +       int                             irq_tx;
41923 +       int                             irq_rx;
41924 +
41925 +       spinlock_t                      lock;
41926 +
41927 +       unsigned long                   flags;
41928 +
41929 +       char                            name[0];
41930 +};
41931 +
41932 +static irqreturn_t uio_ubicom32ring_handler(int irq, struct uio_info *dev_info)
41933 +{
41934 +       struct uio_ubicom32ring_data *priv = dev_info->priv;
41935 +
41936 +       /* Just disable the interrupt in the interrupt controller, and
41937 +        * remember the state so we can allow user space to enable it later.
41938 +        */
41939 +
41940 +       if (!test_and_set_bit(0, &priv->flags))
41941 +               disable_irq_nosync(irq);
41942 +
41943 +       return IRQ_HANDLED;
41944 +}
41945 +
41946 +static int uio_ubicom32ring_irqcontrol(struct uio_info *dev_info, s32 irq_on)
41947 +{
41948 +       struct uio_ubicom32ring_data *priv = dev_info->priv;
41949 +       unsigned long flags;
41950 +
41951 +       /* Allow user space to enable and disable the interrupt
41952 +        * in the interrupt controller, but keep track of the
41953 +        * state to prevent per-irq depth damage.
41954 +        *
41955 +        * Serialize this operation to support multiple tasks.
41956 +        */
41957 +
41958 +       spin_lock_irqsave(&priv->lock, flags);
41959 +
41960 +       if (irq_on & 2) {
41961 +               /*
41962 +                * Kick the ring buffer (if we can)
41963 +                */
41964 +               if (priv->irq_tx != 0xFF) {
41965 +                       ubicom32_set_interrupt(priv->irq_tx);
41966 +               }
41967 +       }
41968 +       
41969 +       if (priv->irq_rx != 0xFF) {
41970 +               if (irq_on & 1) {
41971 +                       if (test_and_clear_bit(0, &priv->flags))
41972 +                               enable_irq(dev_info->irq);
41973 +               } else {
41974 +                       if (!test_and_set_bit(0, &priv->flags))
41975 +                               disable_irq(dev_info->irq);
41976 +               }
41977 +       }
41978 +
41979 +       spin_unlock_irqrestore(&priv->lock, flags);
41980 +
41981 +       return 0;
41982 +}
41983 +
41984 +static int uio_ubicom32ring_probe(struct platform_device *pdev)
41985 +{
41986 +       struct uio_info *uioinfo;
41987 +       struct uio_mem *uiomem;
41988 +       struct uio_ubicom32ring_data *priv;
41989 +       struct uio_ubicom32ring_regs *regs;
41990 +       struct resource *mem_resource;
41991 +       struct resource *irqtx_resource;
41992 +       struct resource *irqrx_resource;
41993 +       int ret = -EINVAL;
41994 +       int i;
41995 +
41996 +       uioinfo = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
41997 +       if (!uioinfo) {
41998 +               dev_err(&pdev->dev, "unable to kmalloc\n");
41999 +               return -ENOMEM;
42000 +       }
42001 +
42002 +       /*
42003 +        * Allocate private data with some string space after
42004 +        */
42005 +       i = sizeof(DRIVER_NAME) + 1;
42006 +       i += pdev->dev.platform_data ? strlen(pdev->dev.platform_data) : 0;
42007 +       priv = kzalloc(sizeof(struct uio_ubicom32ring_data) + i, GFP_KERNEL);
42008 +       if (!priv) {
42009 +               dev_err(&pdev->dev, "unable to kmalloc\n");
42010 +               kfree(uioinfo);
42011 +               return -ENOMEM;
42012 +       }
42013 +
42014 +       strcpy(priv->name, DRIVER_NAME ":");
42015 +       if (pdev->dev.platform_data) {
42016 +               strcat(priv->name, pdev->dev.platform_data);
42017 +       }
42018 +       uioinfo->priv = priv;
42019 +       uioinfo->name = priv->name;
42020 +       uioinfo->version = "0.1";
42021 +
42022 +       priv->uioinfo = uioinfo;
42023 +       spin_lock_init(&priv->lock);
42024 +       priv->flags = 0; /* interrupt is enabled to begin with */
42025 +
42026 +       /*
42027 +        * Get our resources, the IRQ_TX and IRQ_RX are optional.
42028 +        */
42029 +       priv->irq_tx = 0xFF;
42030 +       irqtx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
42031 +       if (irqtx_resource) {
42032 +               priv->irq_tx = irqtx_resource->start;
42033 +       }
42034 +
42035 +       uioinfo->irq = -1;
42036 +       priv->irq_rx = 0xFF;
42037 +       irqrx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
42038 +       if (irqrx_resource) {
42039 +               priv->irq_rx = irqrx_resource->start;
42040 +               uioinfo->irq = priv->irq_rx;
42041 +               uioinfo->handler = uio_ubicom32ring_handler;
42042 +       }
42043 +
42044 +       mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
42045 +       if (!mem_resource || !mem_resource->start) {
42046 +               dev_err(&pdev->dev, "No valid memory resource found\n");
42047 +               ret = -ENODEV;
42048 +               goto fail;
42049 +       }
42050 +       regs = (struct uio_ubicom32ring_regs *)mem_resource->start;
42051 +       priv->regs = regs;
42052 +
42053 +       if (regs->version != UIO_UBICOM32RING_REG_VERSION) {
42054 +               dev_err(&pdev->dev, "version %d not supported\n", regs->version);
42055 +               ret = -ENODEV;
42056 +               goto fail;
42057 +       }
42058 +
42059 +       /*
42060 +        * First range is the shared register space, if we have any
42061 +        */
42062 +       uiomem = &uioinfo->mem[0];
42063 +       if (regs->regs_size) {
42064 +               uiomem->memtype = UIO_MEM_PHYS;
42065 +               uiomem->addr = (u32_t)regs->regs;
42066 +               uiomem->size = regs->regs_size;
42067 +               ++uiomem;
42068 +               dev_info(&pdev->dev, "regs:%p (%u) / rings: %d found\n", regs->regs, regs->regs_size, regs->num_rings);
42069 +       } else {
42070 +               dev_info(&pdev->dev, "rings: %d found\n", regs->num_rings);
42071 +       }
42072 +
42073 +       /*
42074 +        * The rest of the range correspond to the rings
42075 +        */
42076 +       for (i = 0; i < regs->num_rings; i++) {
42077 +               dev_info(&pdev->dev, "\t%d: entries:%d ring:%p\n", 
42078 +                        i, regs->rings[i]->entries, &(regs->rings[i]->ring));
42079 +               if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
42080 +                       dev_warn(&pdev->dev, "device has more than "
42081 +                                       __stringify(MAX_UIO_MAPS)
42082 +                                       " I/O memory resources.\n");
42083 +                       break;
42084 +               }
42085 +
42086 +               uiomem->memtype = UIO_MEM_PHYS;
42087 +               uiomem->addr = (u32_t)&(regs->rings[i]->head);
42088 +               uiomem->size = (regs->rings[i]->entries * sizeof(u32_t)) + 
42089 +                               sizeof(struct uio_ubicom32ring_desc);
42090 +               ++uiomem;
42091 +       }
42092 +
42093 +       while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
42094 +               uiomem->size = 0;
42095 +               ++uiomem;
42096 +       }
42097 +
42098 +       /* This driver requires no hardware specific kernel code to handle
42099 +        * interrupts. Instead, the interrupt handler simply disables the
42100 +        * interrupt in the interrupt controller. User space is responsible
42101 +        * for performing hardware specific acknowledge and re-enabling of
42102 +        * the interrupt in the interrupt controller.
42103 +        *
42104 +        * Interrupt sharing is not supported.
42105 +        */
42106 +       uioinfo->irq_flags = IRQF_DISABLED;
42107 +       uioinfo->irqcontrol = uio_ubicom32ring_irqcontrol;
42108 +
42109 +       ret = uio_register_device(&pdev->dev, priv->uioinfo);
42110 +       if (ret) {
42111 +               dev_err(&pdev->dev, "unable to register uio device\n");
42112 +               goto fail;
42113 +       }
42114 +
42115 +       platform_set_drvdata(pdev, priv);
42116 +
42117 +       dev_info(&pdev->dev, "'%s' using irq: rx %d tx %d, regs %p\n", 
42118 +                priv->name, priv->irq_rx, priv->irq_tx, priv->regs);
42119 +
42120 +       return 0;
42121 +
42122 +fail:
42123 +       kfree(uioinfo);
42124 +       kfree(priv);
42125 +       return ret;
42126 +}
42127 +
42128 +static int uio_ubicom32ring_remove(struct platform_device *pdev)
42129 +{
42130 +       struct uio_ubicom32ring_data *priv = platform_get_drvdata(pdev);
42131 +
42132 +       uio_unregister_device(priv->uioinfo);
42133 +       kfree(priv->uioinfo);
42134 +       kfree(priv);
42135 +       return 0;
42136 +}
42137 +
42138 +static struct platform_driver uio_ubicom32ring = {
42139 +       .probe = uio_ubicom32ring_probe,
42140 +       .remove = uio_ubicom32ring_remove,
42141 +       .driver = {
42142 +               .name = DRIVER_NAME,
42143 +               .owner = THIS_MODULE,
42144 +       },
42145 +};
42146 +
42147 +static int __init uio_ubicom32ring_init(void)
42148 +{
42149 +       return platform_driver_register(&uio_ubicom32ring);
42150 +}
42151 +
42152 +static void __exit uio_ubicom32ring_exit(void)
42153 +{
42154 +       platform_driver_unregister(&uio_ubicom32ring);
42155 +}
42156 +
42157 +module_init(uio_ubicom32ring_init);
42158 +module_exit(uio_ubicom32ring_exit);
42159 +
42160 +MODULE_AUTHOR("Patrick Tjin");
42161 +MODULE_DESCRIPTION("Userspace I/O driver for Ubicom32 ring buffers");
42162 +MODULE_LICENSE("GPL v2");
42163 +MODULE_ALIAS("platform:" DRIVER_NAME);
42164 +
42165 --- a/drivers/usb/gadget/epautoconf.c
42166 +++ b/drivers/usb/gadget/epautoconf.c
42167 @@ -154,6 +154,10 @@ ep_matches (
42168                         /* configure your hardware with enough buffering!! */
42169                 }
42170                 break;
42171 +       
42172 +       case USB_ENDPOINT_XFER_BULK:
42173 +               if ((gadget->is_dualspeed) && (ep->maxpacket < 512))
42174 +                       return 0;
42175         }
42176  
42177         /* MATCH!! */
42178 @@ -174,7 +178,7 @@ ep_matches (
42179                         return 0;
42180                 desc->bEndpointAddress |= epnum;
42181         }
42182 -
42183 +       
42184         /* report (variable) full speed bulk maxpacket */
42185         if (USB_ENDPOINT_XFER_BULK == type) {
42186                 int size = ep->maxpacket;
42187 --- a/drivers/usb/Kconfig
42188 +++ b/drivers/usb/Kconfig
42189 @@ -22,6 +22,7 @@ config USB_ARCH_HAS_HCD
42190         default y if PCMCIA && !M32R                    # sl811_cs
42191         default y if ARM                                # SL-811
42192         default y if SUPERH                             # r8a66597-hcd
42193 +       default y if UBICOM32                           # Ubicom's onchip USB Duial role controller
42194         default PCI
42195  
42196  # many non-PCI SOC chips embed OHCI
42197 --- a/drivers/usb/musb/Kconfig
42198 +++ b/drivers/usb/musb/Kconfig
42199 @@ -11,7 +11,7 @@ config USB_MUSB_HDRC
42200         depends on (USB || USB_GADGET) && HAVE_CLK
42201         depends on !SUPERH
42202         select TWL4030_USB if MACH_OMAP_3430SDP
42203 -       tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
42204 +       tristate 'Inventra Highspeed Dual Role Controller (TI, Ubicom, ...)'
42205         help
42206           Say Y here if your system has a dual role high speed USB
42207           controller based on the Mentor Graphics silicon IP.  Then
42208 --- a/drivers/usb/musb/Makefile
42209 +++ b/drivers/usb/musb/Makefile
42210 @@ -22,6 +22,10 @@ ifeq ($(CONFIG_ARCH_OMAP3430),y)
42211         musb_hdrc-objs  += omap2430.o
42212  endif
42213  
42214 +ifeq ($(CONFIG_UBICOM32), y)
42215 +        musb_hdrc-objs  += ubi32_usb.o
42216 +endif
42217 +
42218  ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
42219         musb_hdrc-objs          += musb_gadget_ep0.o musb_gadget.o
42220  endif
42221 --- a/drivers/usb/musb/musb_core.c
42222 +++ b/drivers/usb/musb/musb_core.c
42223 @@ -105,6 +105,13 @@
42224  #include <asm/mach-types.h>
42225  #endif
42226  
42227 +#ifdef CONFIG_UBICOM32
42228 +#include <asm/ip5000.h>
42229 +#include <asm/ubicom32-tio.h>
42230 +extern void ubi32_usb_init(void);
42231 +extern void ubi32_usb_int_clr(void);
42232 +#endif
42233 +
42234  #include "musb_core.h"
42235  
42236  
42237 @@ -147,7 +154,7 @@ static inline struct musb *dev_to_musb(s
42238  }
42239  
42240  /*-------------------------------------------------------------------------*/
42241 -
42242 +#ifndef CONFIG_UBICOM32
42243  #ifndef CONFIG_USB_TUSB6010
42244  /*
42245   * Load an endpoint's FIFO
42246 @@ -226,8 +233,38 @@ void musb_read_fifo(struct musb_hw_ep *h
42247                 readsb(fifo, dst, len);
42248         }
42249  }
42250 +#endif /* T6010 */
42251 +#else /* UBICOM */
42252 +
42253 +/*
42254 + * Load an endpoint's FIFO
42255 + */
42256 +void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 wCount, const u8 *pSource)
42257 +{
42258 +       void __iomem *fifo = hw_ep->fifo;
42259 +
42260 +       prefetch((u8 *)pSource);
42261 +
42262 +       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
42263 +                       'T', hw_ep->epnum, fifo, wCount, pSource);
42264 +
42265 +       usb_tio_write_fifo((u32)fifo, (u32)pSource, wCount);
42266 +
42267 +}
42268  
42269 -#endif /* normal PIO */
42270 +
42271 +/*
42272 + * Unload an endpoint's FIFO
42273 + */
42274 +void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 wCount, u8 *pDest)
42275 +{
42276 +
42277 +       void __iomem *fifo = hw_ep->fifo;
42278 +       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
42279 +                       'R', hw_ep->epnum, fifo, wCount, pDest);
42280 +       usb_tio_read_fifo((u32)fifo, (u32)pDest, wCount);
42281 +}
42282 +#endif /* CONFIG_UBICOM32 */
42283  
42284  
42285  /*-------------------------------------------------------------------------*/
42286 @@ -872,12 +909,19 @@ void musb_start(struct musb *musb)
42287         musb_writeb(regs, MUSB_TESTMODE, 0);
42288  
42289         /* put into basic highspeed mode and start session */
42290 +#ifndef CONFIG_UBICOM32
42291         musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
42292                                                 | MUSB_POWER_SOFTCONN
42293                                                 | MUSB_POWER_HSENAB
42294                                                 /* ENSUSPEND wedges tusb */
42295                                                 /* | MUSB_POWER_ENSUSPEND */
42296                                                 );
42297 +#else
42298 +       musb_writeb(regs, MUSB_POWER,  MUSB_POWER_HSENAB
42299 +                                               /* ENSUSPEND wedges tusb */
42300 +                                               /* | MUSB_POWER_ENSUSPEND */
42301 +                                               );
42302 +#endif
42303  
42304         musb->is_active = 0;
42305         devctl = musb_readb(regs, MUSB_DEVCTL);
42306 @@ -1079,6 +1123,7 @@ static struct fifo_cfg __initdata mode_4
42307  };
42308  
42309  
42310 +#ifndef CONFIG_UBICOM32
42311  /*
42312   * configure a fifo; for non-shared endpoints, this may be called
42313   * once for a tx fifo and once for an rx fifo.
42314 @@ -1238,7 +1283,7 @@ static int __init ep_config_from_table(s
42315  
42316         return 0;
42317  }
42318 -
42319 +#endif /* CONFIG_UBICOM32 */
42320  
42321  /*
42322   * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
42323 @@ -1253,13 +1298,23 @@ static int __init ep_config_from_hw(stru
42324         DBG(2, "<== static silicon ep config\n");
42325  
42326         /* FIXME pick up ep0 maxpacket size */
42327 +#ifdef CONFIG_UBICOM32
42328 +       /* set ep0 to shared_fifo, otherwise urb will be put to out_qh but ep0_irq try to get the urb from in_qh*/
42329 +       hw_ep = musb->endpoints;
42330 +       hw_ep->is_shared_fifo = true;
42331 +#endif
42332  
42333         for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
42334                 musb_ep_select(mbase, epnum);
42335                 hw_ep = musb->endpoints + epnum;
42336  
42337                 /* read from core using indexed model */
42338 +#ifndef CONFIG_UBICOM32
42339                 reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
42340 +#else
42341 +               reg = musb_readb(musb->mregs, 0x10 + MUSB_FIFOSIZE);
42342 +#endif
42343 +
42344                 if (!reg) {
42345                         /* 0's returned when no more endpoints */
42346                         break;
42347 @@ -1272,8 +1327,10 @@ static int __init ep_config_from_hw(stru
42348                 /* shared TX/RX FIFO? */
42349                 if ((reg & 0xf0) == 0xf0) {
42350                         hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
42351 -                       hw_ep->is_shared_fifo = true;
42352 -                       continue;
42353 +                       hw_ep->is_shared_fifo = true;                   
42354 +#ifndef CONFIG_UBICOM32
42355 +                       continue; /* For ubicom processors, shared ep is all we get */
42356 +#endif
42357                 } else {
42358                         hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
42359                         hw_ep->is_shared_fifo = false;
42360 @@ -1290,17 +1347,30 @@ static int __init ep_config_from_hw(stru
42361                 /* REVISIT:  this algorithm is lazy, we should at least
42362                  * try to pick a double buffered endpoint.
42363                  */
42364 +#ifndef CONFIG_UBICOM32
42365                 if (musb->bulk_ep)
42366                         continue;
42367                 musb->bulk_ep = hw_ep;
42368 +#else
42369 +               if ((musb->bulk_ep_in) && (musb->bulk_ep_out))
42370 +                       continue;
42371 +               /* Save theEP with 1024 Bytes FIFO for ISO */
42372 +               if(hw_ep->max_packet_sz_tx == 512) {
42373 +                       if (!musb->bulk_ep_in) {
42374 +                               musb->bulk_ep_in = hw_ep;
42375 +                       } else if (!musb->bulk_ep_out) {
42376 +                               musb->bulk_ep_out = hw_ep;
42377 +                       }
42378 +               }
42379 +#endif /* CONFIG_UBICOM32 */
42380  #endif
42381         }
42382  
42383  #ifdef CONFIG_USB_MUSB_HDRC_HCD
42384 -       if (!musb->bulk_ep) {
42385 +       if ((!musb->bulk_ep_in) || (!musb->bulk_ep_out)) {
42386                 pr_debug("%s: missing bulk\n", musb_driver_name);
42387                 return -EINVAL;
42388 -       }
42389 +       }       
42390  #endif
42391  
42392         return 0;
42393 @@ -1408,12 +1478,16 @@ static int __init musb_core_init(u16 mus
42394         musb->epmask = 1;
42395  
42396         if (reg & MUSB_CONFIGDATA_DYNFIFO) {
42397 +#ifndef CONFIG_UBICOM32
42398                 if (musb->config->dyn_fifo)
42399                         status = ep_config_from_table(musb);
42400 -               else {
42401 +               else
42402 +#endif
42403 +               {
42404                         ERR("reconfigure software for Dynamic FIFOs\n");
42405                         status = -ENODEV;
42406                 }
42407 +
42408         } else {
42409                 if (!musb->config->dyn_fifo)
42410                         status = ep_config_from_hw(musb);
42411 @@ -1477,8 +1551,8 @@ static int __init musb_core_init(u16 mus
42412  
42413  /*-------------------------------------------------------------------------*/
42414  
42415 -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
42416 -
42417 +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_UBICOM32)
42418 +static u32_t musb_int_count = 0;
42419  static irqreturn_t generic_interrupt(int irq, void *__hci)
42420  {
42421         unsigned long   flags;
42422 @@ -1487,10 +1561,17 @@ static irqreturn_t generic_interrupt(int
42423  
42424         spin_lock_irqsave(&musb->lock, flags);
42425  
42426 +#ifndef CONFIG_UBICOM32
42427         musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
42428         musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
42429         musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
42430 +#else
42431 +       musb_read_int_status(&musb->int_usb, &musb->int_tx, &musb->int_rx);
42432 +       //ubi32_usb_int_clr();
42433 +       musb_int_count++;
42434 +#endif
42435  
42436 +       DBG(4, "usb %x, tx %x, rx %x", musb->int_usb, musb->int_tx, musb->int_rx);
42437         if (musb->int_usb || musb->int_tx || musb->int_rx)
42438                 retval = musb_interrupt(musb);
42439  
42440 @@ -2222,6 +2303,10 @@ static struct platform_driver musb_drive
42441  
42442  static int __init musb_init(void)
42443  {
42444 +#ifdef CONFIG_UBICOM32
42445 +       ubi32_usb_init();
42446 +#endif
42447 +
42448  #ifdef CONFIG_USB_MUSB_HDRC_HCD
42449         if (usb_disabled())
42450                 return 0;
42451 --- a/drivers/usb/musb/musb_core.h
42452 +++ b/drivers/usb/musb/musb_core.h
42453 @@ -326,7 +326,9 @@ struct musb {
42454          * queue until it completes or NAKs too much; then we try the next
42455          * endpoint.
42456          */
42457 -       struct musb_hw_ep       *bulk_ep;
42458 +       //struct musb_hw_ep     *bulk_ep;
42459 +       struct musb_hw_ep       *bulk_ep_in;    //ubicom
42460 +       struct musb_hw_ep       *bulk_ep_out;
42461  
42462         struct list_head        control;        /* of musb_qh */
42463         struct list_head        in_bulk;        /* of musb_qh */
42464 @@ -467,7 +469,7 @@ extern void musb_platform_disable(struct
42465  
42466  extern void musb_hnp_stop(struct musb *musb);
42467  
42468 -extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode);
42469 +extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
42470  
42471  #if defined(CONFIG_USB_TUSB6010) || \
42472         defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
42473 --- a/drivers/usb/musb/musb_gadget.c
42474 +++ b/drivers/usb/musb/musb_gadget.c
42475 @@ -421,7 +421,7 @@ void musb_g_tx(struct musb *musb, u8 epn
42476                  * probably rates reporting as a host error
42477                  */
42478                 if (csr & MUSB_TXCSR_P_SENTSTALL) {
42479 -                       csr |= MUSB_TXCSR_P_WZC_BITS;
42480 +                       csr &= ~(MUSB_TXCSR_P_WZC_BITS);
42481                         csr &= ~MUSB_TXCSR_P_SENTSTALL;
42482                         musb_writew(epio, MUSB_TXCSR, csr);
42483                         if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
42484 @@ -437,7 +437,7 @@ void musb_g_tx(struct musb *musb, u8 epn
42485  
42486                 if (csr & MUSB_TXCSR_P_UNDERRUN) {
42487                         /* we NAKed, no big deal ... little reason to care */
42488 -                       csr |= MUSB_TXCSR_P_WZC_BITS;
42489 +                       csr &= ~(MUSB_TXCSR_P_WZC_BITS);
42490                         csr &= ~(MUSB_TXCSR_P_UNDERRUN
42491                                         | MUSB_TXCSR_TXPKTRDY);
42492                         musb_writew(epio, MUSB_TXCSR, csr);
42493 @@ -573,10 +573,16 @@ static void rxstate(struct musb *musb, s
42494         u16                     csr = 0;
42495         const u8                epnum = req->epnum;
42496         struct usb_request      *request = &req->request;
42497 -       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
42498 +       struct musb_ep          *musb_ep = NULL;
42499         void __iomem            *epio = musb->endpoints[epnum].regs;
42500         u16                     fifo_count = 0;
42501 -       u16                     len = musb_ep->packet_sz;
42502 +       u16                     len = 0;
42503 +       
42504 +       if (musb->endpoints[epnum].is_shared_fifo)
42505 +               musb_ep = &musb->endpoints[epnum].ep_in;
42506 +       else
42507 +               musb_ep = &musb->endpoints[epnum].ep_out;
42508 +       len =  musb_ep->packet_sz;
42509  
42510         csr = musb_readw(epio, MUSB_RXCSR);
42511  
42512 @@ -715,7 +721,7 @@ static void rxstate(struct musb *musb, s
42513                          */
42514  
42515                         /* ack the read! */
42516 -                       csr |= MUSB_RXCSR_P_WZC_BITS;
42517 +                       csr &= ~MUSB_RXCSR_P_WZC_BITS;
42518                         csr &= ~MUSB_RXCSR_RXPKTRDY;
42519                         musb_writew(epio, MUSB_RXCSR, csr);
42520                 }
42521 @@ -734,10 +740,15 @@ void musb_g_rx(struct musb *musb, u8 epn
42522         u16                     csr;
42523         struct usb_request      *request;
42524         void __iomem            *mbase = musb->mregs;
42525 -       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
42526 +       struct musb_ep          *musb_ep = NULL;
42527         void __iomem            *epio = musb->endpoints[epnum].regs;
42528         struct dma_channel      *dma;
42529  
42530 +       if (musb->endpoints[epnum].is_shared_fifo)
42531 +               musb_ep = &musb->endpoints[epnum].ep_in;
42532 +       else
42533 +               musb_ep = &musb->endpoints[epnum].ep_out;
42534 +       
42535         musb_ep_select(mbase, epnum);
42536  
42537         request = next_request(musb_ep);
42538 @@ -1559,7 +1570,7 @@ init_peripheral_ep(struct musb *musb, st
42539         ep->is_in = is_in;
42540  
42541         INIT_LIST_HEAD(&ep->req_list);
42542 -
42543 +       
42544         sprintf(ep->name, "ep%d%s", epnum,
42545                         (!epnum || hw_ep->is_shared_fifo) ? "" : (
42546                                 is_in ? "in" : "out"));
42547 @@ -1758,7 +1769,9 @@ int usb_gadget_register_driver(struct us
42548                         }
42549                 }
42550         }
42551 -
42552 +#ifndef CONFIG_USB_MUSB_OTG
42553 +       musb_pullup(musb, 1);
42554 +#endif
42555         return retval;
42556  }
42557  EXPORT_SYMBOL(usb_gadget_register_driver);
42558 --- a/drivers/usb/musb/musb_gadget_ep0.c
42559 +++ b/drivers/usb/musb/musb_gadget_ep0.c
42560 @@ -240,14 +240,14 @@ __acquires(musb->lock)
42561                 case USB_REQ_SET_ADDRESS:
42562                         /* change it after the status stage */
42563                         musb->set_address = true;
42564 -                       musb->address = (u8) (ctrlrequest->wValue & 0x7f);
42565 +                       musb->address = (u8) (le16_to_cpu(ctrlrequest->wValue) & 0x7f);
42566                         handled = 1;
42567                         break;
42568  
42569                 case USB_REQ_CLEAR_FEATURE:
42570                         switch (recip) {
42571                         case USB_RECIP_DEVICE:
42572 -                               if (ctrlrequest->wValue
42573 +                               if (le16_to_cpu(ctrlrequest->wValue)
42574                                                 != USB_DEVICE_REMOTE_WAKEUP)
42575                                         break;
42576                                 musb->may_wakeup = 0;
42577 @@ -261,8 +261,8 @@ __acquires(musb->lock)
42578  
42579                                 if (num == 0
42580                                                 || num >= MUSB_C_NUM_EPS
42581 -                                               || ctrlrequest->wValue
42582 -                                                       != USB_ENDPOINT_HALT)
42583 +                                               || le16_to_cpu(ctrlrequest->wValue
42584 +                                                       != USB_ENDPOINT_HALT))
42585                                         break;
42586  
42587                                 if (ctrlrequest->wIndex & USB_DIR_IN)
42588 @@ -292,7 +292,7 @@ __acquires(musb->lock)
42589                         switch (recip) {
42590                         case USB_RECIP_DEVICE:
42591                                 handled = 1;
42592 -                               switch (ctrlrequest->wValue) {
42593 +                               switch (le16_to_cpu(ctrlrequest->wValue)) {
42594                                 case USB_DEVICE_REMOTE_WAKEUP:
42595                                         musb->may_wakeup = 1;
42596                                         break;
42597 @@ -374,8 +374,8 @@ stall:
42598  
42599                                 if (epnum == 0
42600                                                 || epnum >= MUSB_C_NUM_EPS
42601 -                                               || ctrlrequest->wValue
42602 -                                                       != USB_ENDPOINT_HALT)
42603 +                                               || le16_to_cpu(ctrlrequest->wValue
42604 +                                                       != USB_ENDPOINT_HALT))
42605                                         break;
42606  
42607                                 ep = musb->endpoints + epnum;
42608 --- a/drivers/usb/musb/musb_host.c
42609 +++ b/drivers/usb/musb/musb_host.c
42610 @@ -139,7 +139,11 @@ static inline void musb_h_tx_start(struc
42611         /* NOTE: no locks here; caller should lock and select EP */
42612         if (ep->epnum) {
42613                 txcsr = musb_readw(ep->regs, MUSB_TXCSR);
42614 -               txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS;
42615 +#ifndef CONFIG_UBICOM32
42616 +               txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS; 
42617 +#else
42618 +               txcsr |= (MUSB_TXCSR_TXPKTRDY & (~MUSB_TXCSR_H_WZC_BITS)); 
42619 +#endif
42620                 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
42621         } else {
42622                 txcsr = MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY;
42623 @@ -198,8 +202,11 @@ musb_start_urb(struct musb *musb, int is
42624                 len = urb->iso_frame_desc[0].length;
42625                 break;
42626         default:                /* bulk, interrupt */
42627 -               buf = urb->transfer_buffer;
42628 -               len = urb->transfer_buffer_length;
42629 +               /* actual_length may be nonzero on retry paths */
42630 +               if (urb->actual_length) 
42631 +                       DBG(3 ,"musb_start_urb: URB %p retried, len: %d\n", urb, urb->actual_length);
42632 +               buf = urb->transfer_buffer + urb->actual_length;
42633 +               len = urb->transfer_buffer_length - urb->actual_length;
42634         }
42635  
42636         DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
42637 @@ -318,13 +325,13 @@ musb_save_toggle(struct musb_hw_ep *ep, 
42638         if (!is_in) {
42639                 csr = musb_readw(epio, MUSB_TXCSR);
42640                 usb_settoggle(udev, qh->epnum, 1,
42641 -                       (csr & MUSB_TXCSR_H_DATATOGGLE)
42642 -                               ? 1 : 0);
42643 +                       ((csr & MUSB_TXCSR_H_DATATOGGLE)
42644 +                               ? 1 : 0));
42645         } else {
42646                 csr = musb_readw(epio, MUSB_RXCSR);
42647                 usb_settoggle(udev, qh->epnum, 0,
42648 -                       (csr & MUSB_RXCSR_H_DATATOGGLE)
42649 -                               ? 1 : 0);
42650 +                       ((csr & MUSB_RXCSR_H_DATATOGGLE)
42651 +                               ? 1 : 0));
42652         }
42653  }
42654  
42655 @@ -337,9 +344,11 @@ musb_giveback(struct musb_qh *qh, struct
42656         struct musb             *musb = ep->musb;
42657         int                     ready = qh->is_ready;
42658  
42659 +#ifndef CONFIG_UBICOM32 /* BUG! */
42660         if (ep->is_shared_fifo)
42661                 is_in = 1;
42662         else
42663 +#endif
42664                 is_in = usb_pipein(urb->pipe);
42665  
42666         /* save toggle eagerly, for paranoia */
42667 @@ -538,7 +547,11 @@ musb_host_packet_rx(struct musb *musb, s
42668         musb_read_fifo(hw_ep, length, buf);
42669  
42670         csr = musb_readw(epio, MUSB_RXCSR);
42671 +#ifndef CONFIG_UBICOM32
42672         csr |= MUSB_RXCSR_H_WZC_BITS;
42673 +#else
42674 +       csr &= ~MUSB_RXCSR_H_WZC_BITS;
42675 +#endif
42676         if (unlikely(do_flush))
42677                 musb_h_flush_rxfifo(hw_ep, csr);
42678         else {
42679 @@ -572,14 +585,24 @@ musb_rx_reinit(struct musb *musb, struct
42680  
42681         /* if programmed for Tx, put it in RX mode */
42682         if (ep->is_shared_fifo) {
42683 +#ifndef  CONFIG_UBICOM32
42684                 csr = musb_readw(ep->regs, MUSB_TXCSR);
42685                 if (csr & MUSB_TXCSR_MODE) {
42686                         musb_h_tx_flush_fifo(ep);
42687                         musb_writew(ep->regs, MUSB_TXCSR,
42688                                         MUSB_TXCSR_FRCDATATOG);
42689                 }
42690 +#else 
42691                 /* clear mode (and everything else) to enable Rx */
42692                 musb_writew(ep->regs, MUSB_TXCSR, 0);
42693 +               /* scrub all previous state, clearing toggle */
42694 +               csr = musb_readw(ep->regs, MUSB_RXCSR);
42695 +               if (csr & MUSB_RXCSR_RXPKTRDY)
42696 +                       WARNING("rx%d, packet/%d ready?\n", ep->epnum,
42697 +                               musb_readw(ep->regs, MUSB_RXCOUNT));
42698 +
42699 +               musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
42700 +#endif
42701  
42702         /* scrub all previous state, clearing toggle */
42703         } else {
42704 @@ -680,7 +703,7 @@ static void musb_ep_program(struct musb 
42705                         /* ASSERT:  TXCSR_DMAENAB was already cleared */
42706  
42707                         /* flush all old state, set default */
42708 -                       musb_h_tx_flush_fifo(hw_ep);
42709 +                               musb_h_tx_flush_fifo(hw_ep);
42710                         csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
42711                                         | MUSB_TXCSR_DMAMODE
42712                                         | MUSB_TXCSR_FRCDATATOG
42713 @@ -1169,8 +1192,18 @@ void musb_host_tx(struct musb *musb, u8 
42714         void __iomem            *mbase = musb->mregs;
42715         struct dma_channel      *dma;
42716  
42717 +#ifdef CONFIG_UBICOM32
42718 +       if (hw_ep->is_shared_fifo) {
42719 +               qh = hw_ep->in_qh;
42720 +       }
42721 +#ifdef CONFIG_USB_SERIAL_SIERRAWIRELESS
42722 +       printk(KERN_DEBUG "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr,
42723 +                       dma ? ", dma" : "");
42724 +#endif
42725 +#endif
42726         urb = next_urb(qh);
42727  
42728 +
42729         musb_ep_select(mbase, epnum);
42730         tx_csr = musb_readw(epio, MUSB_TXCSR);
42731  
42732 @@ -1210,9 +1243,14 @@ void musb_host_tx(struct musb *musb, u8 
42733                  * we have a candidate... NAKing is *NOT* an error
42734                  */
42735                 musb_ep_select(mbase, epnum);
42736 +#ifndef CONFIG_UBICOM32
42737                 musb_writew(epio, MUSB_TXCSR,
42738                                 MUSB_TXCSR_H_WZC_BITS
42739                                 | MUSB_TXCSR_TXPKTRDY);
42740 +#else
42741 +               musb_writew(epio, MUSB_TXCSR,
42742 +                                MUSB_TXCSR_TXPKTRDY);
42743 +#endif
42744                 goto finish;
42745         }
42746  
42747 @@ -1316,8 +1354,14 @@ void musb_host_tx(struct musb *musb, u8 
42748                 qh->segsize = wLength;
42749  
42750                 musb_ep_select(mbase, epnum);
42751 +#ifndef CONFIG_UBICOM32
42752                 musb_writew(epio, MUSB_TXCSR,
42753 -                               MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
42754 +                                MUSB_TXCSR_MODE | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
42755 +#else
42756 +        musb_writew(epio, MUSB_TXCSR,
42757 +                                 MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY);
42758 +#endif
42759 +
42760         } else
42761                 DBG(1, "not complete, but dma enabled?\n");
42762  
42763 @@ -1365,6 +1409,49 @@ finish:
42764  
42765  #endif
42766  
42767 +/* Schedule next QH from musb->in_bulk and move the current qh to
42768 + * the end; avoids starvation for other endpoints.
42769 + */
42770 +static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
42771 +{
42772 +       struct dma_channel      *dma;
42773 +       struct urb              *urb;
42774 +       void __iomem            *mbase = musb->mregs;
42775 +       void __iomem            *epio = ep->regs;
42776 +       struct musb_qh          *cur_qh, *next_qh;
42777 +       u16                     rx_csr;
42778 +
42779 +       musb_ep_select(mbase, ep->epnum);
42780 +       dma = is_dma_capable() ? ep->rx_channel : NULL;
42781 +       /* clear nak timeout bit */
42782 +       rx_csr = musb_readw(epio, MUSB_RXCSR);
42783 +       rx_csr &= ~MUSB_RXCSR_H_WZC_BITS;
42784 +       rx_csr &= ~MUSB_RXCSR_DATAERROR;
42785 +       musb_writew(epio, MUSB_RXCSR, rx_csr);
42786 +
42787 +       cur_qh = first_qh(&musb->in_bulk);
42788 +       if (cur_qh) {
42789 +               urb = next_urb(cur_qh);
42790 +               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
42791 +                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
42792 +                       musb->dma_controller->channel_abort(dma);
42793 +                       urb->actual_length += dma->actual_len;
42794 +                       dma->actual_len = 0L;
42795 +               }
42796 +               musb_save_toggle(ep, 1, urb);
42797 +
42798 +               /* move cur_qh to end of queue */
42799 +               list_move_tail(&cur_qh->ring, &musb->in_bulk);
42800 +
42801 +               /* get the next qh from musb->in_bulk */
42802 +               next_qh = first_qh(&musb->in_bulk);
42803 +
42804 +               /* set rx_reinit and schedule the next qh */
42805 +               ep->rx_reinit = 1;
42806 +               musb_start_urb(musb, 1, next_qh);
42807 +       }
42808 +}
42809 +
42810  /*
42811   * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
42812   * and high-bandwidth IN transfer cases.
42813 @@ -1383,7 +1470,7 @@ void musb_host_rx(struct musb *musb, u8 
42814         bool                    done = false;
42815         u32                     status;
42816         struct dma_channel      *dma;
42817 -
42818 +       
42819         musb_ep_select(mbase, epnum);
42820  
42821         urb = next_urb(qh);
42822 @@ -1407,6 +1494,13 @@ void musb_host_rx(struct musb *musb, u8 
42823  
42824         pipe = urb->pipe;
42825  
42826 +#ifdef CONFIG_UBICOM32
42827 +#ifdef CONFIG_USB_SERIAL_SIERRAWIRELESS
42828 +               printk(KERN_DEBUG  "RXCSR%d %04x, reqpkt, len %zu%s\n", epnum, rx_csr,
42829 +                               xfer_len, dma ? ", dma" : "");
42830 +#endif
42831 +#endif
42832 +
42833         DBG(5, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n",
42834                 epnum, rx_csr, urb->actual_length,
42835                 dma ? dma->actual_len : 0);
42836 @@ -1428,18 +1522,30 @@ void musb_host_rx(struct musb *musb, u8 
42837         } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
42838  
42839                 if (USB_ENDPOINT_XFER_ISOC != qh->type) {
42840 -                       /* NOTE this code path would be a good place to PAUSE a
42841 -                        * transfer, if there's some other (nonperiodic) rx urb
42842 -                        * that could use this fifo.  (dma complicates it...)
42843 +                       DBG(6, "RX end %d NAK timeout\n", epnum);
42844 +
42845 +                       /* NOTE: NAKing is *NOT* an error, so we want to
42846 +                        * continue.  Except ... if there's a request for
42847 +                        * another QH, use that instead of starving it.
42848                          *
42849 -                        * if (bulk && qh->ring.next != &musb->in_bulk), then
42850 -                        * we have a candidate... NAKing is *NOT* an error
42851 +                        * Devices like Ethernet and serial adapters keep
42852 +                        * reads posted at all times, which will starve
42853 +                        * other devices without this logic.
42854                          */
42855 -                       DBG(6, "RX end %d NAK timeout\n", epnum);
42856 +                       if (usb_pipebulk(urb->pipe)
42857 +                                       && qh->mux == 1
42858 +                                       && !list_is_singular(&musb->in_bulk)) {
42859 +                               musb_bulk_rx_nak_timeout(musb, hw_ep);
42860 +                               return;
42861 +                       }
42862                         musb_ep_select(mbase, epnum);
42863 +#ifndef CONFIG_UBICOM32
42864                         musb_writew(epio, MUSB_RXCSR,
42865                                         MUSB_RXCSR_H_WZC_BITS
42866                                         | MUSB_RXCSR_H_REQPKT);
42867 +#else
42868 +                       musb_writew(epio, MUSB_RXCSR, (~(MUSB_RXCSR_H_WZC_BITS))| MUSB_RXCSR_H_REQPKT);
42869 +#endif
42870  
42871                         goto finish;
42872                 } else {
42873 @@ -1495,8 +1601,13 @@ void musb_host_rx(struct musb *musb, u8 
42874                 rx_csr &= ~MUSB_RXCSR_H_REQPKT;
42875  
42876                 musb_ep_select(mbase, epnum);
42877 +#ifndef CONFIG_UBICOM32
42878                 musb_writew(epio, MUSB_RXCSR,
42879                                 MUSB_RXCSR_H_WZC_BITS | rx_csr);
42880 +#else
42881 +               musb_writew(epio, MUSB_RXCSR,
42882 +                               (~MUSB_RXCSR_H_WZC_BITS) & rx_csr);
42883 +#endif
42884         }
42885  #endif
42886         if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
42887 @@ -1526,7 +1637,7 @@ void musb_host_rx(struct musb *musb, u8 
42888                         else
42889                                 done = false;
42890  
42891 -               } else  {
42892 +               } else {
42893                 /* done if urb buffer is full or short packet is recd */
42894                 done = (urb->actual_length + xfer_len >=
42895                                 urb->transfer_buffer_length
42896 @@ -1743,8 +1854,12 @@ static int musb_schedule(
42897                 if (musb->periodic[epnum])
42898                         continue;
42899                 hw_ep = &musb->endpoints[epnum];
42900 +#ifndef CONFIG_UBICOM32
42901                 if (hw_ep == musb->bulk_ep)
42902 -                       continue;
42903 +#else
42904 +               if ((hw_ep == musb->bulk_ep_in) || (hw_ep == musb->bulk_ep_out)) /* Ubicom */   
42905 +#endif
42906 +                       continue; 
42907  
42908                 if (is_in)
42909                         diff = hw_ep->max_packet_sz_rx - qh->maxpacket;
42910 @@ -1756,7 +1871,14 @@ static int musb_schedule(
42911                         best_end = epnum;
42912                 }
42913         }
42914 +
42915 +#ifdef CONFIG_UBICOM32
42916 +       if (((best_diff >= qh->maxpacket)) && ((qh->type == USB_ENDPOINT_XFER_BULK) && (!is_in)))
42917 +               best_end = -1;
42918 +#endif
42919 +
42920         /* use bulk reserved ep1 if no other ep is free */
42921 +#ifndef CONFIG_UBICOM32
42922         if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
42923                 hw_ep = musb->bulk_ep;
42924                 if (is_in)
42925 @@ -1767,6 +1889,22 @@ static int musb_schedule(
42926         } else if (best_end < 0) {
42927                 return -ENOSPC;
42928         }
42929 +#else
42930 +       if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
42931 +               /* hw_ep = musb->bulk_ep; */
42932 +               if (is_in) {
42933 +                       head = &musb->in_bulk;
42934 +                       hw_ep = musb->bulk_ep_in; /* UBICOM */
42935 +               }
42936 +               else {
42937 +                       head = &musb->out_bulk;
42938 +                       hw_ep = musb->bulk_ep_out; /* UBICOM */
42939 +               }
42940 +               goto success;
42941 +       } else if (best_end < 0) {
42942 +               return -ENOSPC;
42943 +       }
42944 +#endif
42945  
42946         idle = 1;
42947         qh->mux = 0;
42948 @@ -1779,6 +1917,13 @@ success:
42949                 list_add_tail(&qh->ring, head);
42950                 qh->mux = 1;
42951         }
42952 +       /*
42953 +        * It's not make sense to set NAK timeout when qh->mux = 0,
42954 +        * There is nothing else to schedule
42955 +        */
42956 +       if ((qh->type == USB_ENDPOINT_XFER_BULK) && (qh->mux == 0))
42957 +               qh->intv_reg = 0;
42958 +
42959         qh->hw_ep = hw_ep;
42960         qh->hep->hcpriv = qh;
42961         if (idle)
42962 @@ -1884,6 +2029,15 @@ static int musb_urb_enqueue(
42963         case USB_ENDPOINT_XFER_ISOC:
42964                 /* iso always uses log encoding */
42965                 break;
42966 +#ifdef COMFIG_UBICOM32
42967 +       case USB_ENDPOINT_XFER_BULK:
42968 +                if (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
42969 +                       interval = (USB_SPEED_HIGH == urb->dev->speed) ? 16: 2;
42970 +                else
42971 +                       interval = 0;
42972 +                break;
42973 +#endif
42974 +       
42975         default:
42976                 /* REVISIT we actually want to use NAK limits, hinting to the
42977                  * transfer scheduling logic to try some other qh, e.g. try
42978 --- a/drivers/usb/musb/musb_io.h
42979 +++ b/drivers/usb/musb/musb_io.h
42980 @@ -56,6 +56,7 @@ static inline void writesb(const void __
42981  
42982  #endif
42983  
42984 +#ifndef CONFIG_UBICOM32
42985  /* NOTE:  these offsets are all in bytes */
42986  
42987  static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
42988 @@ -70,7 +71,37 @@ static inline void musb_writew(void __io
42989  
42990  static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
42991         { __raw_writel(data, addr + offset); }
42992 +#else
42993 +#include <asm/ubicom32-tio.h>
42994 +static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
42995 +{
42996 +        u16 data;
42997 +        usb_tio_read_u16((u32)(addr + offset), &data);
42998 +        return data;
42999 +}
43000  
43001 +static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43002 +{
43003 +        u8 data;
43004 +        usb_tio_read_u8((u32)(addr + offset), &data);
43005 +        return data;
43006 +}
43007 +
43008 +static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
43009 +{
43010 +        usb_tio_write_u16((u32)(addr + offset), data);
43011 +}
43012 +
43013 +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
43014 +{
43015 +        usb_tio_write_u8((u32)(addr + offset), data);
43016 +}
43017 +
43018 +static inline void  musb_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
43019 +{
43020 +       return usb_tio_read_int_status(int_usb, int_tx, int_rx);
43021 +}
43022 +#endif /* CONFIG_UBICOM32 */
43023  
43024  #ifdef CONFIG_USB_TUSB6010
43025  
43026 @@ -104,7 +135,7 @@ static inline void musb_writeb(void __io
43027         __raw_writew(tmp, addr + (offset & ~1));
43028  }
43029  
43030 -#else
43031 +#elif !defined(CONFIG_UBICOM32)
43032  
43033  static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43034         { return __raw_readb(addr + offset); }
43035 --- /dev/null
43036 +++ b/drivers/usb/musb/ubi32_usb.c
43037 @@ -0,0 +1,156 @@
43038 +/*
43039 + * drivers/usb/musb/ubi32_usb.c
43040 + *   Ubicom32 usb controller driver.
43041 + *
43042 + * (C) Copyright 2009, Ubicom, Inc.
43043 + * Copyright (C) 2005-2006 by Texas Instruments
43044 + *
43045 + * Derived from the Texas Instruments Inventra Controller Driver for Linux.
43046 + *
43047 + * This file is part of the Ubicom32 Linux Kernel Port.
43048 + *
43049 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43050 + * it and/or modify it under the terms of the GNU General Public License
43051 + * as published by the Free Software Foundation, either version 2 of the
43052 + * License, or (at your option) any later version.
43053 + *
43054 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43055 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43056 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43057 + * the GNU General Public License for more details.
43058 + *
43059 + * You should have received a copy of the GNU General Public License
43060 + * along with the Ubicom32 Linux Kernel Port.  If not, 
43061 + * see <http://www.gnu.org/licenses/>.
43062 + *
43063 + * Ubicom32 implementation derived from (with many thanks):
43064 + *   arch/m68knommu
43065 + *   arch/blackfin
43066 + *   arch/parisc
43067 + */
43068 +#include <linux/module.h>
43069 +#include <linux/kernel.h>
43070 +#include <linux/sched.h>
43071 +#include <linux/slab.h>
43072 +#include <linux/init.h>
43073 +#include <linux/list.h>
43074 +#include <linux/clk.h>
43075 +#include <linux/io.h>
43076 +
43077 +#include <asm/io.h>
43078 +#include <asm/ip5000.h>
43079 +#include "musb_core.h"
43080 +
43081 +void musb_platform_enable(struct musb *musb)
43082 +{
43083 +}
43084 +void musb_platform_disable(struct musb *musb)
43085 +{
43086 +}
43087 +
43088 +int musb_platform_set_mode(struct musb *musb, u8 musb_mode) {
43089 +       return 0;
43090 +}
43091 +
43092 +static void ip5k_usb_hcd_vbus_power(struct musb *musb, int is_on, int sleeping)
43093 +{
43094 +}
43095 +
43096 +static void ip5k_usb_hcd_set_vbus(struct musb *musb, int is_on)
43097 +{
43098 +       u8              devctl;
43099 +       /* HDRC controls CPEN, but beware current surges during device
43100 +        * connect.  They can trigger transient overcurrent conditions
43101 +        * that must be ignored.
43102 +        */
43103 +
43104 +       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
43105 +
43106 +       if (is_on) {
43107 +               musb->is_active = 1;
43108 +               musb->xceiv.default_a = 1;
43109 +               musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
43110 +               devctl |= MUSB_DEVCTL_SESSION;
43111 +
43112 +               MUSB_HST_MODE(musb);
43113 +       } else {
43114 +               musb->is_active = 0;
43115 +
43116 +               /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
43117 +                * jumping right to B_IDLE...
43118 +                */
43119 +
43120 +               musb->xceiv.default_a = 0;
43121 +               musb->xceiv.state = OTG_STATE_B_IDLE;
43122 +               devctl &= ~MUSB_DEVCTL_SESSION;
43123 +
43124 +               MUSB_DEV_MODE(musb);
43125 +       }
43126 +       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
43127 +
43128 +       DBG(1, "VBUS %s, devctl %02x "
43129 +               /* otg %3x conf %08x prcm %08x */ "\n",
43130 +               otg_state_string(musb),
43131 +               musb_readb(musb->mregs, MUSB_DEVCTL));
43132 +}
43133 +static int ip5k_usb_hcd_set_power(struct otg_transceiver *x, unsigned mA)
43134 +{
43135 +       return 0;
43136 +}
43137 +
43138 +static int musb_platform_resume(struct musb *musb);
43139 +
43140 +int __init musb_platform_init(struct musb *musb)
43141 +{
43142 +
43143 +#ifdef CONFIG_UBICOM32_V4
43144 +       u32_t chip_id;
43145 +       asm volatile (
43146 +                     "move.4   %0, CHIP_ID     \n\t"
43147 +                     : "=r" (chip_id)
43148 +       );
43149 +       if (chip_id == 0x30001) {
43150 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 30);
43151 +               udelay(1);
43152 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 31);
43153 +       } else {
43154 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 17);
43155 +               udelay(1);
43156 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 14);
43157 +       }
43158 +#endif
43159 +
43160 +        *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_CFG)) |= ((1 << 14) | (1 <<15));
43161 +
43162 +       /* The i-clk is AUTO gated. Hence there is no need
43163 +        * to disable it until the driver is shutdown */
43164 +
43165 +       clk_enable(musb->clock);
43166 +       musb_platform_resume(musb);
43167 +
43168 +       ip5k_usb_hcd_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
43169 +
43170 +       if (is_host_enabled(musb))
43171 +               musb->board_set_vbus = ip5k_usb_hcd_set_vbus;
43172 +       if (is_peripheral_enabled(musb))
43173 +               musb->xceiv.set_power = ip5k_usb_hcd_set_power;
43174 +
43175 +       return 0;
43176 +}
43177 +
43178 +
43179 +int musb_platform_suspend(struct musb *musb)
43180 +{
43181 +       return 0;
43182 +}
43183 +int musb_platform_resume(struct musb *musb)
43184 +{
43185 +       return 0;
43186 +}
43187 +
43188 +int musb_platform_exit(struct musb *musb)
43189 +{
43190 +       ip5k_usb_hcd_vbus_power(musb, 0 /*off*/, 1);
43191 +       musb_platform_suspend(musb);
43192 +       return 0;
43193 +}
43194 --- a/drivers/video/backlight/Kconfig
43195 +++ b/drivers/video/backlight/Kconfig
43196 @@ -84,6 +84,14 @@ config LCD_TOSA
43197           If you have an Sharp SL-6000 Zaurus say Y to enable a driver
43198           for its LCD.
43199  
43200 +config LCD_UBICOM32
43201 +       tristate "Ubicom Backlight Driver"
43202 +       depends on LCD_CLASS_DEVICE && UBICOM32
43203 +       default n
43204 +       help
43205 +         If you have a Ubicom32 based system with an LCD panel, say Y to enable
43206 +         the power control driver for it.
43207 +
43208  #
43209  # Backlight
43210  #
43211 @@ -214,3 +222,11 @@ config BACKLIGHT_SAHARA
43212         help
43213           If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
43214           backlight driver.
43215 +
43216 +config BACKLIGHT_UBICOM32
43217 +       tristate "Ubicom Backlight Driver"
43218 +       depends on BACKLIGHT_CLASS_DEVICE && UBICOM32
43219 +       default n
43220 +       help
43221 +         If you have a Ubicom32 based system with a backlight say Y to enable the
43222 +         backlight driver.
43223 --- a/drivers/video/backlight/Makefile
43224 +++ b/drivers/video/backlight/Makefile
43225 @@ -8,6 +8,8 @@ obj-$(CONFIG_LCD_PLATFORM)         += platfor
43226  obj-$(CONFIG_LCD_VGG2432A4)       += vgg2432a4.o
43227  obj-$(CONFIG_LCD_TDO24M)          += tdo24m.o
43228  obj-$(CONFIG_LCD_TOSA)            += tosa_lcd.o
43229 +obj-$(CONFIG_LCD_LTV350QV)        += ltv350qv.o
43230 +obj-$(CONFIG_LCD_UBICOM32)        += ubicom32lcd.o
43231  
43232  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
43233  obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
43234 @@ -22,4 +24,4 @@ obj-$(CONFIG_BACKLIGHT_DA903X)        += da903x
43235  obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
43236  obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
43237  obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
43238 -
43239 +obj-$(CONFIG_BACKLIGHT_UBICOM32) += ubicom32bl.o
43240 --- /dev/null
43241 +++ b/drivers/video/backlight/ubicom32bl.c
43242 @@ -0,0 +1,378 @@
43243 +/*
43244 + * drivers/video/backlight/ubicom32bl.c
43245 + *     Backlight driver for the Ubicom32 platform
43246 + *
43247 + * (C) Copyright 2009, Ubicom, Inc.
43248 + *
43249 + * This file is part of the Ubicom32 Linux Kernel Port.
43250 + *
43251 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43252 + * it and/or modify it under the terms of the GNU General Public License
43253 + * as published by the Free Software Foundation, either version 2 of the
43254 + * License, or (at your option) any later version.
43255 + *
43256 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43257 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43258 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43259 + * the GNU General Public License for more details.
43260 + *
43261 + * You should have received a copy of the GNU General Public License
43262 + * along with the Ubicom32 Linux Kernel Port.  If not,
43263 + * see <http://www.gnu.org/licenses/>.
43264 + *
43265 + * Ubicom32 implementation derived from (with many thanks):
43266 + *   arch/m68knommu
43267 + *   arch/blackfin
43268 + *   arch/parisc
43269 + */
43270 +#include <linux/init.h>
43271 +#include <linux/kernel.h>
43272 +#include <linux/module.h>
43273 +#include <linux/platform_device.h>
43274 +#include <linux/backlight.h>
43275 +#include <linux/fb.h>
43276 +
43277 +#include <asm/ubicom32bl.h>
43278 +#include <asm/ip5000.h>
43279 +
43280 +#define DRIVER_NAME                    "ubicom32bl"
43281 +#define UBICOM32BL_MAX_BRIGHTNESS      255
43282 +
43283 +struct ubicom32bl_data {
43284 +       /*
43285 +        * Pointer to the platform data structure.  Keep this around since we need values
43286 +        * from it to set the backlight intensity.
43287 +        */
43288 +       const struct ubicom32bl_platform_data   *pdata;
43289 +
43290 +       /*
43291 +        * Backlight device, we have to save this for use when we remove ourselves.
43292 +        */
43293 +       struct backlight_device                 *bldev;
43294 +
43295 +       /*
43296 +        * Current intensity, used for get_intensity.
43297 +        */
43298 +       int                                     cur_intensity;
43299 +
43300 +       /*
43301 +        * Init function for PWM
43302 +        */
43303 +       int (*init_fn)(struct ubicom32bl_data *);
43304 +
43305 +       /*
43306 +        * Set intensity function depending on the backlight type
43307 +        */
43308 +       int (*set_intensity_fn)(struct ubicom32bl_data *, int);
43309 +};
43310 +
43311 +/*
43312 + * ubicom32bl_set_intensity_gpio
43313 + */
43314 +static int ubicom32bl_set_intensity_gpio(struct ubicom32bl_data *ud, int intensity)
43315 +{
43316 +       ud->cur_intensity = intensity ? 255 : 0;
43317 +
43318 +       if (intensity) {
43319 +               // set gpio
43320 +               return 0;
43321 +       }
43322 +
43323 +       // clear gpio
43324 +       return 0;
43325 +}
43326 +
43327 +/*
43328 + * ubicom32bl_set_intensity_hw
43329 + */
43330 +static int ubicom32bl_set_intensity_hw(struct ubicom32bl_data *ud, int intensity)
43331 +{
43332 +       u16_t period = ud->pdata->pwm_period;
43333 +       u16_t duty;
43334 +
43335 +       /*
43336 +        * Calculate the new duty cycle
43337 +        */
43338 +       duty = (period * intensity) / (UBICOM32BL_MAX_BRIGHTNESS + 1);
43339 +
43340 +       /*
43341 +        * Set the new duty cycle
43342 +        */
43343 +       switch (ud->pdata->pwm_channel) {
43344 +       case 0:
43345 +               /*
43346 +                * Channel 0 is in the lower half of PORT C ctl0 and ctl1
43347 +                */
43348 +               UBICOM32_IO_PORT(RC)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43349 +               break;
43350 +
43351 +       case 1:
43352 +               /*
43353 +                * Channel 1 is in the upper half of PORT C ctl0 and ctl2
43354 +                */
43355 +               UBICOM32_IO_PORT(RC)->ctl2 = (ud->pdata->pwm_period << 16) | duty;
43356 +               break;
43357 +
43358 +       case 2:
43359 +               /*
43360 +                * Channel 2 is in PORT H ctl0 and ctl1
43361 +                */
43362 +               UBICOM32_IO_PORT(RH)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43363 +               break;
43364 +       }
43365 +
43366 +       ud->cur_intensity = intensity;
43367 +
43368 +       return 0;
43369 +}
43370 +
43371 +/*
43372 + * ubicom32bl_set_intensity
43373 + */
43374 +static int ubicom32bl_set_intensity(struct backlight_device *bd)
43375 +{
43376 +       struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43377 +       int intensity = bd->props.brightness;
43378 +
43379 +       /*
43380 +        * If we're blanked the the intensity doesn't matter.
43381 +        */
43382 +       if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
43383 +               intensity = 0;
43384 +       }
43385 +
43386 +       /*
43387 +        * Check for inverted backlight.
43388 +        */
43389 +       if (ud->pdata->invert) {
43390 +               intensity = UBICOM32BL_MAX_BRIGHTNESS - intensity;
43391 +       }
43392 +
43393 +       if (ud->set_intensity_fn) {
43394 +               return ud->set_intensity_fn(ud, intensity);
43395 +       }
43396 +
43397 +       return -ENXIO;
43398 +}
43399 +
43400 +/*
43401 + * ubicom32bl_get_intensity
43402 + *     Return the current intensity of the backlight.
43403 + */
43404 +static int ubicom32bl_get_intensity(struct backlight_device *bd)
43405 +{
43406 +       struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43407 +
43408 +       return ud->cur_intensity;
43409 +}
43410 +
43411 +/*
43412 + * ubicom32bl_init_hw_pwm
43413 + *     Set the appropriate PWM registers
43414 + */
43415 +static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud)
43416 +{
43417 +       /*
43418 +        * bit 13: enable
43419 +        */
43420 +       u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ;
43421 +
43422 +       switch (ud->pdata->pwm_channel) {
43423 +       case 0:
43424 +               /*
43425 +                * Channel 0 is in the lower half of PORT C ctl0 and ctl1
43426 +                */
43427 +               UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF;
43428 +               UBICOM32_IO_PORT(RC)->ctl0 |= pwm_cfg;
43429 +               UBICOM32_IO_PORT(RC)->ctl1 = ud->pdata->pwm_period << 16;
43430 +               break;
43431 +
43432 +       case 1:
43433 +               /*
43434 +                * Channel 1 is in the upper half of PORT C ctl0 and ctl2
43435 +                */
43436 +               UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF0000;
43437 +               UBICOM32_IO_PORT(RC)->ctl0 |= (pwm_cfg << 16);
43438 +               UBICOM32_IO_PORT(RC)->ctl2 = ud->pdata->pwm_period << 16;
43439 +               break;
43440 +
43441 +       case 2:
43442 +               /*
43443 +                * Channel 2 is in PORT H ctl0 and ctl1
43444 +                */
43445 +               UBICOM32_IO_PORT(RH)->ctl0 &= ~0xFFFF0000;
43446 +               UBICOM32_IO_PORT(RH)->ctl0 = pwm_cfg;
43447 +               UBICOM32_IO_PORT(RH)->ctl1 = ud->pdata->pwm_period << 16;
43448 +               break;
43449 +       }
43450 +
43451 +       return 0;
43452 +}
43453 +
43454 +/*
43455 + * ubicom32bl_init_gpio
43456 + *     Allocate the appropriate GPIO
43457 + */
43458 +static int ubicom32bl_init_gpio(struct ubicom32bl_data *ud)
43459 +{
43460 +       return 0;
43461 +}
43462 +
43463 +static struct backlight_ops ubicom32bl_ops = {
43464 +       .get_brightness = ubicom32bl_get_intensity,
43465 +       .update_status  = ubicom32bl_set_intensity,
43466 +};
43467 +
43468 +/*
43469 + * ubicom32bl_probe
43470 + */
43471 +static int ubicom32bl_probe(struct platform_device *pdev)
43472 +{
43473 +       const struct ubicom32bl_platform_data *pdata = pdev->dev.platform_data;
43474 +       struct ubicom32bl_data *ud;
43475 +       struct backlight_device *bldev;
43476 +       int retval;
43477 +
43478 +       /*
43479 +        * Check to see if we have any platform data, if we don't then the backlight is not
43480 +        * configured on this device.
43481 +        */
43482 +       if (!pdata) {
43483 +               return -ENODEV;
43484 +       }
43485 +
43486 +       /*
43487 +        * Allocate our private data
43488 +        */
43489 +       ud = kzalloc(sizeof(struct ubicom32bl_data), GFP_KERNEL);
43490 +       if (!ud) {
43491 +               return -ENOMEM;
43492 +       }
43493 +
43494 +       ud->pdata = pdata;
43495 +
43496 +       /*
43497 +        * Check to see that the platform data is valid for this driver
43498 +        */
43499 +       switch (pdata->type) {
43500 +       case UBICOM32BL_TYPE_PWM: 
43501 +               {
43502 +                       /*
43503 +                        * Make sure we have a PWM peripheral
43504 +                        */
43505 +                       u32_t chipid;
43506 +                       asm volatile (
43507 +                               "move.4         %0, CHIP_ID     \n\t"
43508 +                               : "=r" (chipid)
43509 +                       );
43510 +                       if (chipid != 0x00030001) {
43511 +                               retval = -ENODEV;
43512 +                               goto fail;
43513 +                       }
43514 +
43515 +                       if (pdata->pwm_channel > 3) {
43516 +                               retval = -ENODEV;
43517 +                               goto fail;
43518 +                       }
43519 +                       if (pdata->pwm_prescale > 16) {
43520 +                               retval = -EINVAL;
43521 +                               goto fail;
43522 +                       }
43523 +
43524 +                       ud->init_fn = ubicom32bl_init_hw_pwm;
43525 +                       ud->set_intensity_fn = ubicom32bl_set_intensity_hw;
43526 +                       break;
43527 +               }
43528 +
43529 +       case UBICOM32BL_TYPE_PWM_HRT:
43530 +               // For now, PWM HRT devices are treated as binary lights.
43531 +
43532 +       case UBICOM32BL_TYPE_BINARY:
43533 +               ud->init_fn = ubicom32bl_init_gpio;
43534 +               ud->set_intensity_fn = ubicom32bl_set_intensity_gpio;
43535 +               break;
43536 +       }
43537 +
43538 +       /*
43539 +        * Register our backlight device
43540 +        */
43541 +       bldev = backlight_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32bl_ops);
43542 +       if (IS_ERR(bldev)) {
43543 +               retval = PTR_ERR(bldev);
43544 +               goto fail;
43545 +       }
43546 +
43547 +       ud->bldev = bldev;
43548 +       ud->cur_intensity = pdata->default_intensity;
43549 +       platform_set_drvdata(pdev, ud);
43550 +
43551 +       /* 
43552 +        * Start up the backlight at the prescribed default intensity
43553 +        */
43554 +       bldev->props.power = FB_BLANK_UNBLANK;
43555 +       bldev->props.max_brightness = UBICOM32BL_MAX_BRIGHTNESS;
43556 +       bldev->props.brightness = pdata->default_intensity;
43557 +
43558 +       if (ud->init_fn) {
43559 +               if (ud->init_fn(ud) != 0) {
43560 +                       retval = -ENODEV;
43561 +                       backlight_device_unregister(ud->bldev);
43562 +                       goto fail;
43563 +               }
43564 +       }
43565 +       ubicom32bl_set_intensity(bldev);
43566 +
43567 +       printk(KERN_INFO DRIVER_NAME ": Backlight driver started\n");
43568 +
43569 +       return 0;
43570 +
43571 +fail:
43572 +       platform_set_drvdata(pdev, NULL);
43573 +       kfree(ud);
43574 +       return retval;
43575 +}
43576 +
43577 +/*
43578 + * ubicom32bl_remove
43579 + */
43580 +static int __exit ubicom32bl_remove(struct platform_device *pdev)
43581 +{
43582 +       struct ubicom32bl_data *ud = platform_get_drvdata(pdev);
43583 +
43584 +       backlight_device_unregister(ud->bldev);
43585 +       platform_set_drvdata(pdev, NULL);
43586 +       kfree(ud);
43587 +
43588 +       return 0;
43589 +}
43590 +
43591 +static struct platform_driver ubicom32bl_driver = {
43592 +       .driver = {
43593 +               .name = DRIVER_NAME,
43594 +               .owner = THIS_MODULE,
43595 +       },
43596 +
43597 +       .remove = __exit_p(ubicom32bl_remove),
43598 +};
43599 +
43600 +/*
43601 + * ubicom32bl_init
43602 + */
43603 +static int __init ubicom32bl_init(void)
43604 +{
43605 +       return platform_driver_probe(&ubicom32bl_driver, ubicom32bl_probe);
43606 +}
43607 +module_init(ubicom32bl_init);
43608 +
43609 +/*
43610 + * ubicom32bl_exit
43611 + */
43612 +static void __exit ubicom32bl_exit(void)
43613 +{
43614 +       platform_driver_unregister(&ubicom32bl_driver);
43615 +}
43616 +module_exit(ubicom32bl_exit);
43617 +
43618 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
43619 +MODULE_DESCRIPTION("Ubicom32 backlight driver");
43620 +MODULE_LICENSE("GPL");
43621 --- /dev/null
43622 +++ b/drivers/video/backlight/ubicom32lcd.c
43623 @@ -0,0 +1,194 @@
43624 +/*
43625 + * drivers/vdeio/backlight/ubicom32lcd.c
43626 + *     LCD driver for the Ubicom32 platform
43627 + *
43628 + * (C) Copyright 2009, Ubicom, Inc.
43629 + *
43630 + * This file is part of the Ubicom32 Linux Kernel Port.
43631 + *
43632 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43633 + * it and/or modify it under the terms of the GNU General Public License
43634 + * as published by the Free Software Foundation, either version 2 of the
43635 + * License, or (at your option) any later version.
43636 + *
43637 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43638 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43639 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43640 + * the GNU General Public License for more details.
43641 + *
43642 + * You should have received a copy of the GNU General Public License
43643 + * along with the Ubicom32 Linux Kernel Port.  If not,
43644 + * see <http://www.gnu.org/licenses/>.
43645 + *
43646 + * Ubicom32 implementation derived from (with many thanks):
43647 + *   arch/m68knommu
43648 + *   arch/blackfin
43649 + *   arch/parisc
43650 + */
43651 +#include <linux/init.h>
43652 +#include <linux/kernel.h>
43653 +#include <linux/module.h>
43654 +#include <linux/platform_device.h>
43655 +#include <linux/lcd.h>
43656 +#include <linux/fb.h>
43657 +#include <linux/gpio.h>
43658 +
43659 +#include <asm/ubicom32lcd.h>
43660 +#include <asm/ip5000.h>
43661 +
43662 +#define DRIVER_NAME                    "ubicom32lcd"
43663 +
43664 +struct ubicom32lcd_data {
43665 +       /*
43666 +        * Pointer to the platform data structure.  Keep this around since we need values
43667 +        * from it to set the backlight intensity.
43668 +        */
43669 +       const struct ubicom32lcd_platform_data  *pdata;
43670 +
43671 +       /*
43672 +        * LCD device, we have to save this for use when we remove ourselves.
43673 +        */
43674 +       struct lcd_device                       *lcddev;
43675 +};
43676 +
43677 +/*
43678 + * ubicom32lcd_set_power
43679 + */
43680 +static int ubicom32lcd_set_power(struct lcd_device *ld, int power)
43681 +{
43682 +       struct ubicom32lcd_data *ud = (struct ubicom32lcd_data *)lcd_get_data(ld);
43683 +       if (power == FB_BLANK_UNBLANK) {
43684 +               gpio_direction_output(ud->pdata->vgh_gpio, ud->pdata->vgh_polarity);
43685 +               return 0;
43686 +       }
43687 +
43688 +       gpio_direction_output(ud->pdata->vgh_gpio, !ud->pdata->vgh_polarity);
43689 +       return 0;
43690 +}
43691 +
43692 +/*
43693 + * ubicom32lcd_get_power
43694 + */
43695 +static int ubicom32lcd_get_power(struct lcd_device *ld)
43696 +{
43697 +       struct ubicom32lcd_data *ud = (struct ubicom32lcd_data *)lcd_get_data(ld);
43698 +       int vgh = gpio_get_value(ud->pdata->vgh_gpio);
43699 +       if ((vgh && ud->pdata->vgh_polarity) || (!vgh && !ud->pdata->vgh_polarity)) {
43700 +               return 1;
43701 +       }
43702 +
43703 +       return 0;
43704 +}
43705 +
43706 +static struct lcd_ops ubicom32lcd_ops = {
43707 +       .get_power = ubicom32lcd_get_power,
43708 +       .set_power = ubicom32lcd_set_power,
43709 +};
43710 +
43711 +/*
43712 + * ubicom32lcd_probe
43713 + */
43714 +static int ubicom32lcd_probe(struct platform_device *pdev)
43715 +{
43716 +       const struct ubicom32lcd_platform_data *pdata = pdev->dev.platform_data;
43717 +       struct ubicom32lcd_data *ud;
43718 +       struct lcd_device *lcddev;
43719 +       int retval;
43720 +
43721 +       /*
43722 +        * Check to see if we have any platform data, if we don't have a LCD to control
43723 +        */
43724 +       if (!pdata) {
43725 +               return -ENODEV;
43726 +       }
43727 +
43728 +       /*
43729 +        * Allocate our private data
43730 +        */
43731 +       ud = kzalloc(sizeof(struct ubicom32lcd_data), GFP_KERNEL);
43732 +       if (!ud) {
43733 +               return -ENOMEM;
43734 +       }
43735 +
43736 +       ud->pdata = pdata;
43737 +
43738 +       /*
43739 +        * Request our GPIOs
43740 +        */
43741 +       retval = gpio_request(pdata->vgh_gpio, "vgh");
43742 +       if (retval) {
43743 +               dev_err(&pdev->dev, "Failed to allocate vgh GPIO\n");
43744 +               goto fail_gpio;
43745 +       }
43746 +
43747 +       /*
43748 +        * Register our lcd device
43749 +        */
43750 +       lcddev = lcd_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32lcd_ops);
43751 +       if (IS_ERR(lcddev)) {
43752 +               retval = PTR_ERR(lcddev);
43753 +               goto fail;
43754 +       }
43755 +
43756 +       ud->lcddev = lcddev;
43757 +       platform_set_drvdata(pdev, ud);
43758 +
43759 +       ubicom32lcd_set_power(lcddev, FB_BLANK_UNBLANK);
43760 +
43761 +       printk(KERN_INFO DRIVER_NAME ": LCD driver started\n");
43762 +
43763 +       return 0;
43764 +
43765 +fail:
43766 +       gpio_free(pdata->vgh_gpio);
43767 +
43768 +fail_gpio:
43769 +       platform_set_drvdata(pdev, NULL);
43770 +       kfree(ud);
43771 +       return retval;
43772 +}
43773 +
43774 +/*
43775 + * ubicom32lcd_remove
43776 + */
43777 +static int __exit ubicom32lcd_remove(struct platform_device *pdev)
43778 +{
43779 +       struct ubicom32lcd_data *ud = platform_get_drvdata(pdev);
43780 +
43781 +       lcd_device_unregister(ud->lcddev);
43782 +       platform_set_drvdata(pdev, NULL);
43783 +       kfree(ud);
43784 +
43785 +       return 0;
43786 +}
43787 +
43788 +static struct platform_driver ubicom32lcd_driver = {
43789 +       .driver = {
43790 +               .name = DRIVER_NAME,
43791 +               .owner = THIS_MODULE,
43792 +       },
43793 +
43794 +       .remove = __exit_p(ubicom32lcd_remove),
43795 +};
43796 +
43797 +/*
43798 + * ubicom32lcd_init
43799 + */
43800 +static int __init ubicom32lcd_init(void)
43801 +{
43802 +       return platform_driver_probe(&ubicom32lcd_driver, ubicom32lcd_probe);
43803 +}
43804 +module_init(ubicom32lcd_init);
43805 +
43806 +/*
43807 + * ubicom32lcd_exit
43808 + */
43809 +static void __exit ubicom32lcd_exit(void)
43810 +{
43811 +       platform_driver_unregister(&ubicom32lcd_driver);
43812 +}
43813 +module_exit(ubicom32lcd_exit);
43814 +
43815 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
43816 +MODULE_DESCRIPTION("Ubicom32 backlight driver");
43817 +MODULE_LICENSE("GPL");
43818 --- a/drivers/video/Kconfig
43819 +++ b/drivers/video/Kconfig
43820 @@ -609,6 +609,25 @@ config FB_BFIN_T350MCQB
43821          This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
43822          It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
43823  
43824 +config FB_UBICOM32
43825 +       tristate "Ubicom32 Frame Buffer driver"
43826 +       depends on FB && UBICOM32
43827 +       select FB_CFB_FILLRECT
43828 +       select FB_CFB_COPYAREA
43829 +       select FB_CFB_IMAGEBLIT
43830 +       select FONT_6x11 if FRAMEBUFFER_CONSOLE
43831 +       help
43832 +        This is the framebuffer device driver for the Ubicom32 architecture.
43833 +
43834 +config FB_UBICOM32_VIRTUAL
43835 +       tristate "Ubicom32 Virtual Frame Buffer driver"
43836 +       depends on FB && UBICOM32
43837 +       select FB_CFB_FILLRECT
43838 +       select FB_CFB_COPYAREA
43839 +       select FB_CFB_IMAGEBLIT
43840 +       select FONT_6x11 if FRAMEBUFFER_CONSOLE
43841 +       help
43842 +        This is a virtual framebuffer device driver for the Ubicom32 architecture.
43843  
43844  config FB_STI
43845         tristate "HP STI frame buffer device support"
43846 --- a/drivers/video/Makefile
43847 +++ b/drivers/video/Makefile
43848 @@ -132,6 +132,7 @@ obj-$(CONFIG_FB_VGA16)            += vga
43849  obj-$(CONFIG_FB_OF)               += offb.o
43850  obj-$(CONFIG_FB_BF54X_LQ043)     += bf54x-lq043fb.o
43851  obj-$(CONFIG_FB_BFIN_T350MCQB)   += bfin-t350mcqb-fb.o
43852 +obj-$(CONFIG_FB_UBICOM32)         += ubicom32fb.o
43853  
43854  # the test framebuffer is last
43855  obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
43856 --- /dev/null
43857 +++ b/drivers/video/ubicom32fb.c
43858 @@ -0,0 +1,777 @@
43859 +/*
43860 + * drivers/video/ubicom32fb.c
43861 + *     Ubicom32 frame buffer driver
43862 + *
43863 + * (C) Copyright 2009, Ubicom, Inc.
43864 + *
43865 + * This file is part of the Ubicom32 Linux Kernel Port.
43866 + *
43867 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43868 + * it and/or modify it under the terms of the GNU General Public License
43869 + * as published by the Free Software Foundation, either version 2 of the
43870 + * License, or (at your option) any later version.
43871 + *
43872 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43873 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43874 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43875 + * the GNU General Public License for more details.
43876 + *
43877 + * You should have received a copy of the GNU General Public License
43878 + * along with the Ubicom32 Linux Kernel Port.  If not,
43879 + * see <http://www.gnu.org/licenses/>.
43880 + *
43881 + * Ubicom32 implementation derived from (with many thanks):
43882 + *   arch/m68knommu
43883 + *   arch/blackfin
43884 + *   arch/parisc
43885 + */
43886 +
43887 +/*
43888 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
43889 + * Geert Uytterhoeven.
43890 + */
43891 +
43892 +#include <linux/device.h>
43893 +#include <linux/module.h>
43894 +#include <linux/kernel.h>
43895 +#include <linux/version.h>
43896 +#include <linux/errno.h>
43897 +#include <linux/string.h>
43898 +#include <linux/mm.h>
43899 +#include <linux/fb.h>
43900 +#include <linux/init.h>
43901 +#include <linux/dma-mapping.h>
43902 +#include <linux/platform_device.h>
43903 +#include <linux/device.h>
43904 +#include <linux/uaccess.h>
43905 +#include <linux/interrupt.h>
43906 +
43907 +#include <asm/io.h>
43908 +#include <asm/ip5000.h>
43909 +#include <asm/vdc_tio.h>
43910 +#include <asm/ubicom32fb.h>
43911 +
43912 +#define DRIVER_NAME            "ubicom32fb"
43913 +#define DRIVER_DESCRIPTION     "Ubicom32 frame buffer driver"
43914 +
43915 +#define PALETTE_ENTRIES_NO     16
43916 +
43917 +/*
43918 + * Option variables
43919 + *
43920 + * vram_size:  VRAM size in kilobytes, subject to alignment 
43921 + */
43922 +static int vram_size = 0;
43923 +module_param(vram_size, int, 0);
43924 +MODULE_PARM_DESC(vram, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment");
43925 +static int init_value = 0;
43926 +module_param(init_value, int, 0);
43927 +MODULE_PARM_DESC(init, "Initial value of the framebuffer (16-bit number).");
43928 +
43929 +/*
43930 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
43931 + */
43932 +static struct fb_fix_screeninfo ubicom32fb_fix = {
43933 +       .id =           "Ubicom32",
43934 +       .type =         FB_TYPE_PACKED_PIXELS,
43935 +       .visual =       FB_VISUAL_TRUECOLOR,
43936 +       .accel =        FB_ACCEL_NONE
43937 +};
43938 +
43939 +/*
43940 + * Filled in at probe time when we find out what the hardware supports
43941 + */
43942 +static struct fb_var_screeninfo ubicom32fb_var;
43943 +
43944 +/*
43945 + * Private data structure
43946 + */
43947 +struct ubicom32fb_drvdata {
43948 +       struct fb_info                  *fbinfo;
43949 +       bool                            cmap_alloc;
43950 +
43951 +       /*
43952 +        * The address of the framebuffer in memory
43953 +        */
43954 +       void                            *fb;
43955 +       void                            *fb_aligned;
43956 +
43957 +       /*
43958 +        * Total size of vram including alignment allowance
43959 +        */
43960 +       u32                             total_vram_size;
43961 +       
43962 +       /*
43963 +        * Interrupt to set when changing registers
43964 +        */
43965 +       u32                             vp_int;
43966 +
43967 +       /*
43968 +        * Optional: Interrupt used by TIO to signal us
43969 +        */
43970 +       u32                             rx_int;
43971 +       
43972 +       /*
43973 +        * Base address of the regs for VDC_TIO
43974 +        */
43975 +       volatile struct vdc_tio_vp_regs *regs;
43976 +
43977 +       /*
43978 +        * non-zero if we are in yuv mode
43979 +        */
43980 +       u8_t                            is_yuv;
43981 +
43982 +       /* 
43983 +        * Fake palette of 16 colors
43984 +        */
43985 +       u32                             pseudo_palette[PALETTE_ENTRIES_NO];
43986 +
43987 +       /*
43988 +        * Wait queue and lock used to block when we need to wait 
43989 +        * for something to happen.
43990 +        */
43991 +       wait_queue_head_t               waitq;
43992 +       struct mutex                    lock;
43993 +
43994 +};
43995 +
43996 +/*
43997 + * ubicom32fb_set_next_frame
43998 + *     Sets the next frame buffer to display
43999 + *
44000 + * if sync is TRUE then this function will block until the hardware 
44001 + * acknowledges the change
44002 + */
44003 +static inline void ubicom32fb_set_next_frame(struct ubicom32fb_drvdata *ud, void *fb, u8_t sync)
44004 +{
44005 +       ud->regs->next_frame_flags = ud->is_yuv ? VDCTIO_NEXT_FRAME_FLAG_YUV : 0;
44006 +       ud->regs->next_frame = (void *)((u32_t)fb | 1);
44007 +
44008 +       /*
44009 +        * If we have interrupts, then we can wait on it
44010 +        */
44011 +       if (ud->rx_int != -1) {
44012 +               DEFINE_WAIT(wait);
44013 +               unsigned long flags;
44014 +
44015 +               spin_lock_irqsave(&ud->lock, flags);
44016 +               prepare_to_wait(&ud->waitq, &wait, TASK_INTERRUPTIBLE);
44017 +               spin_unlock_irqrestore(&ud->lock, flags);
44018 +               schedule();
44019 +               finish_wait(&ud->waitq, &wait);
44020 +               return;
44021 +       }
44022 +
44023 +       /*
44024 +        * No interrupt, we will just spin here
44025 +        */
44026 +       while (sync && ((u32_t)ud->regs->next_frame & 1));
44027 +}
44028 +
44029 +/*
44030 + * ubicom32fb_send_command
44031 + *     Sends a command/data pair to the VDC
44032 + */
44033 +static inline void ubicom32fb_send_command(struct ubicom32fb_drvdata *ud, u16 command, u8_t block)
44034 +{
44035 +       ud->regs->command = command;
44036 +       ubicom32_set_interrupt(ud->vp_int);
44037 +       while (block && ud->regs->command);
44038 +}
44039 +
44040 +/*
44041 + * ubicom32fb_ioctl
44042 + *     Handles any ioctls sent to us
44043 + */
44044 +static int ubicom32fb_ioctl(struct fb_info *fbi, unsigned int cmd,
44045 +                      unsigned long arg)
44046 +{
44047 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
44048 +       void __user *argp = (void __user *)arg;
44049 +       int retval = -EFAULT;
44050 +
44051 +       switch (cmd) {
44052 +       case UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC:
44053 +               // check alignment, return -EINVAL if necessary
44054 +               ubicom32fb_set_next_frame(ud, argp, 1);
44055 +               retval = 0;
44056 +               break;
44057 +
44058 +       case UBICOM32FB_IOCTL_SET_NEXT_FRAME:
44059 +               // check alignment, return -EINVAL if necessary
44060 +               ubicom32fb_set_next_frame(ud, argp, 0);
44061 +               retval = 0;
44062 +               break;
44063 +
44064 +       case UBICOM32FB_IOCTL_SET_MODE:
44065 +               if (!(ud->regs->caps & VDCTIO_CAPS_SUPPORTS_SCALING)) {
44066 +                       break;
44067 +               } else {
44068 +                       struct ubicom32fb_mode mode;
44069 +                       volatile struct vdc_tio_vp_regs *regs = ud->regs;
44070 +                       u32_t flags = 0;
44071 +
44072 +                       if (copy_from_user(&mode, argp, sizeof(mode))) {
44073 +                               break;
44074 +                       }
44075 +                       
44076 +                       regs->x_in = mode.width;
44077 +                       regs->y_in = mode.height;
44078 +                       regs->x_out = regs->xres;
44079 +                       regs->y_out = regs->yres;
44080 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER) {
44081 +                               flags |= VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER;
44082 +                       }
44083 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER) {
44084 +                               flags |= VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER;
44085 +                       }
44086 +                       ud->is_yuv = mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV;
44087 +                       if (ud->is_yuv) {
44088 +                               flags |= VDCTIO_SCALE_FLAG_YUV;
44089 +                       }
44090 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255) {
44091 +                               flags |= VDCTIO_SCALE_FLAG_VRANGE_16_255;
44092 +                       }
44093 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255) {
44094 +                               flags |= VDCTIO_SCALE_FLAG_VRANGE_0_255;
44095 +                       }
44096 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB) {
44097 +                               flags |= VDCTIO_SCALE_FLAG_VSUB;
44098 +                       }
44099 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1) {
44100 +                               flags |= VDCTIO_SCALE_FLAG_HSUB_2_1;
44101 +                       }
44102 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1) {
44103 +                               flags |= VDCTIO_SCALE_FLAG_HSUB_1_1;
44104 +                       }
44105 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE) {
44106 +                               flags |= VDCTIO_SCALE_FLAG_ENABLE;
44107 +                       }
44108 +                       if (mode.next_frame) {
44109 +                               flags |= VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER;
44110 +                               regs->next_frame = mode.next_frame;
44111 +                       }
44112 +                       
44113 +                       regs->scale_flags = flags;
44114 +                       ubicom32fb_send_command(ud, VDCTIO_COMMAND_SET_SCALE_MODE, 1);
44115 +                       retval = 0;
44116 +                       break;
44117 +               }
44118 +
44119 +       default:
44120 +               retval = -ENOIOCTLCMD;
44121 +               break;
44122 +       }
44123 +
44124 +       return retval;
44125 +}
44126 +
44127 +/*
44128 + * ubicom32fb_interrupt
44129 + *     Called by the OS when the TIO has set the rx_int
44130 + */
44131 +static irqreturn_t ubicom32fb_interrupt(int vec, void *appdata)
44132 +{
44133 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)appdata;
44134 +
44135 +       spin_lock(&ud->lock);
44136 +       if (waitqueue_active(&ud->waitq)) {
44137 +               wake_up(&ud->waitq);
44138 +       }
44139 +       spin_unlock(&ud->lock);
44140 +
44141 +       return IRQ_HANDLED;
44142 +}
44143 +
44144 +/*
44145 + * ubicom32fb_pan_display
44146 + *     Pans the display to a given location.  Supports only y direction panning.
44147 + */
44148 +static int ubicom32fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44149 +{
44150 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
44151 +       void *new_addr;
44152 +
44153 +       /*
44154 +        * Get the last y line that would be displayed.  Since we don't support YWRAP,
44155 +        * it must be less than our virtual y size.
44156 +        */
44157 +       u32 lasty = var->yoffset + var->yres;
44158 +       if (lasty > fbi->var.yres_virtual) {
44159 +               /*
44160 +                * We would fall off the end of our frame buffer if we panned here.
44161 +                */
44162 +               return -EINVAL;
44163 +       }
44164 +
44165 +       if (var->xoffset) {
44166 +               /*
44167 +                * We don't support panning in the x direction
44168 +                */
44169 +               return -EINVAL;
44170 +       }
44171 +
44172 +       /*
44173 +        * Everything looks sane, go ahead and pan
44174 +        *
44175 +        * We have to calculate a new address for the VDC to look at
44176 +        */
44177 +       new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44178 +
44179 +       /*
44180 +        * Send down the command.  The buffer will switch at the next vertical blank
44181 +        */
44182 +       ubicom32fb_set_next_frame(ud, (void *)new_addr, 0);
44183 +
44184 +       return 0;
44185 +}
44186 +
44187 +/*
44188 + * ubicom32fb_setcolreg
44189 + *     Sets a color in our virtual palette
44190 + */
44191 +static int ubicom32fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44192 +{
44193 +       u32 *palette = fbi->pseudo_palette;
44194 +
44195 +       if (regno >= PALETTE_ENTRIES_NO) {
44196 +               return -EINVAL;
44197 +       }
44198 +
44199 +       /*
44200 +        * We only use 8 bits from each color
44201 +        */
44202 +       red >>= 8;
44203 +       green >>= 8;
44204 +       blue >>= 8;
44205 +
44206 +       /*
44207 +        * Convert any grayscale values
44208 +        */
44209 +       if (fbi->var.grayscale) {
44210 +               u16 gray = red + green + blue;
44211 +               gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44212 +               gray >>= 2;
44213 +               if (gray > 255) {
44214 +                       gray = 255;
44215 +               }
44216 +               red = gray;
44217 +               blue = gray;
44218 +               green = gray;
44219 +       }
44220 +
44221 +       palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44222 +                        (blue << fbi->var.blue.offset);
44223 +
44224 +       return 0;
44225 +}
44226 +
44227 +/*
44228 + * ubicom32fb_mmap
44229 + */
44230 +static int ubicom32fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
44231 +{
44232 +       struct ubicom32fb_drvdata *drvdata = (struct ubicom32fb_drvdata *)info->par;
44233 +
44234 +       vma->vm_start = (unsigned long)(drvdata->fb_aligned);
44235 +
44236 +       vma->vm_end = vma->vm_start + info->fix.smem_len;
44237 +
44238 +       /* For those who don't understand how mmap works, go read
44239 +        *   Documentation/nommu-mmap.txt.
44240 +        * For those that do, you will know that the VM_MAYSHARE flag
44241 +        * must be set in the vma->vm_flags structure on noMMU
44242 +        *   Other flags can be set, and are documented in
44243 +        *   include/linux/mm.h
44244 +        */
44245 +
44246 +       vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
44247 +
44248 +       return 0;
44249 +}
44250 +
44251 +/*
44252 + * ubicom32fb_blank
44253 + */
44254 +static int ubicom32fb_blank(int blank_mode, struct fb_info *fbi)
44255 +{
44256 +       return 0;
44257 +#if 0
44258 +       struct ubicom32fb_drvdata *drvdata = to_ubicom32fb_drvdata(fbi);
44259 +
44260 +       switch (blank_mode) {
44261 +       case FB_BLANK_UNBLANK:
44262 +               /* turn on panel */
44263 +               ubicom32fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
44264 +               break;
44265 +
44266 +       case FB_BLANK_NORMAL:
44267 +       case FB_BLANK_VSYNC_SUSPEND:
44268 +       case FB_BLANK_HSYNC_SUSPEND:
44269 +       case FB_BLANK_POWERDOWN:
44270 +               /* turn off panel */
44271 +               ubicom32fb_out_be32(drvdata, REG_CTRL, 0);
44272 +       default:
44273 +               break;
44274 +
44275 +       }
44276 +       return 0; /* success */
44277 +#endif
44278 +}
44279 +
44280 +static struct fb_ops ubicom32fb_ops =
44281 +{
44282 +       .owner                  = THIS_MODULE,
44283 +       .fb_pan_display         = ubicom32fb_pan_display,
44284 +       .fb_setcolreg           = ubicom32fb_setcolreg,
44285 +       .fb_blank               = ubicom32fb_blank,
44286 +       .fb_mmap                = ubicom32fb_mmap,
44287 +       .fb_ioctl               = ubicom32fb_ioctl,
44288 +       .fb_fillrect            = cfb_fillrect,
44289 +       .fb_copyarea            = cfb_copyarea,
44290 +       .fb_imageblit           = cfb_imageblit,
44291 +};
44292 +
44293 +/*
44294 + * ubicom32fb_release
44295 + */
44296 +static int ubicom32fb_release(struct device *dev)
44297 +{
44298 +       struct ubicom32fb_drvdata *ud = dev_get_drvdata(dev);
44299 +
44300 +#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
44301 +       //ubicom32fb_blank(VESA_POWERDOWN, &drvdata->info);
44302 +#endif
44303 +
44304 +       unregister_framebuffer(ud->fbinfo);
44305 +
44306 +       if (ud->cmap_alloc) {
44307 +               fb_dealloc_cmap(&ud->fbinfo->cmap);
44308 +       }
44309 +
44310 +       if (ud->fb) {
44311 +               kfree(ud->fb);
44312 +       }
44313 +
44314 +       if (ud->rx_int != -1) {
44315 +               free_irq(ud->rx_int, ud);
44316 +       }
44317 +
44318 +       /* 
44319 +        * Turn off the display 
44320 +        */
44321 +       //ubicom32fb_out_be32(drvdata, REG_CTRL, 0);
44322 +       //iounmap(drvdata->regs);
44323 +
44324 +       framebuffer_release(ud->fbinfo);
44325 +       dev_set_drvdata(dev, NULL);
44326 +
44327 +       return 0;
44328 +}
44329 +
44330 +/*
44331 + * ubicom32fb_platform_probe
44332 + */
44333 +static int __init ubicom32fb_platform_probe(struct platform_device *pdev)
44334 +{
44335 +       struct ubicom32fb_drvdata *ud;
44336 +       struct resource *irq_resource_rx;
44337 +       struct resource *irq_resource_tx;
44338 +       struct resource *mem_resource;
44339 +       struct fb_info *fbinfo;
44340 +       int rc;
44341 +       size_t fbsize;
44342 +       struct device *dev = &pdev->dev;
44343 +       int offset;
44344 +       struct vdc_tio_vp_regs *regs;
44345 +
44346 +       /*
44347 +        * Get our resources
44348 +        */
44349 +       irq_resource_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
44350 +       if (!irq_resource_tx) {
44351 +               dev_err(dev, "No tx IRQ resource assigned\n");
44352 +               return -ENODEV;
44353 +       }
44354 +
44355 +       irq_resource_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
44356 +       if (!irq_resource_rx) {
44357 +               dev_err(dev, "No rx IRQ resource assigned\n");
44358 +               return -ENODEV;
44359 +       }
44360 +
44361 +       mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
44362 +       if (!mem_resource || !mem_resource->start) {
44363 +               dev_err(dev, "No mem resource assigned\n");
44364 +               return -ENODEV;
44365 +       }
44366 +       regs = (struct vdc_tio_vp_regs *)mem_resource->start;
44367 +       if (regs->version != VDCTIO_VP_VERSION) {
44368 +               dev_err(dev, "VDCTIO is not compatible with this driver tio:%x drv:%x\n", 
44369 +                       regs->version, VDCTIO_VP_VERSION);
44370 +               return -ENODEV;
44371 +       }
44372 +
44373 +       /*
44374 +        * This is the minimum VRAM size
44375 +        */
44376 +       fbsize = regs->xres * regs->yres * (regs->bpp / 8);
44377 +       if (!vram_size) {
44378 +               vram_size = (fbsize + 1023) / 1024;
44379 +       } else {
44380 +               if (fbsize > (vram_size * 1024)) {
44381 +                       dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize);
44382 +                       return -ENOMEM; // should be ebadparam?
44383 +               }
44384 +       }
44385 +
44386 +       /*
44387 +        * Allocate the framebuffer instance + our private data
44388 +        */
44389 +       fbinfo = framebuffer_alloc(sizeof(struct ubicom32fb_drvdata), &pdev->dev);
44390 +       if (!fbinfo) {
44391 +               dev_err(dev, "Not enough memory to allocate instance.\n");
44392 +               return -ENOMEM;
44393 +       }
44394 +
44395 +       /*
44396 +        * Fill in our private data.
44397 +        */
44398 +       ud = (struct ubicom32fb_drvdata *)fbinfo->par;
44399 +       ud->fbinfo = fbinfo;
44400 +       ud->regs = (struct vdc_tio_vp_regs *)(mem_resource->start);
44401 +       dev_set_drvdata(dev, ud);
44402 +
44403 +       ud->vp_int = irq_resource_tx->start;
44404 +
44405 +       /*
44406 +        * If we were provided an rx_irq then we need to init the appropriate
44407 +        * queues, locks, and functions.
44408 +        */
44409 +       ud->rx_int = -1;
44410 +       if (irq_resource_rx->start != DEVTREE_IRQ_NONE) {
44411 +               init_waitqueue_head(&ud->waitq);
44412 +               mutex_init(&ud->lock);
44413 +               if (request_irq(ud->rx_int, ubicom32fb_interrupt, IRQF_SHARED, "ubicom32fb_rx", ud)) {
44414 +                       dev_err(dev, "Couldn't request rx IRQ\n");
44415 +                       rc = -ENOMEM;
44416 +                       goto fail;
44417 +               }
44418 +               ud->rx_int = irq_resource_rx->start;
44419 +       }
44420 +
44421 +       /*
44422 +        * Allocate and align the requested amount of VRAM
44423 +        */
44424 +       ud->total_vram_size = (vram_size * 1024) + regs->fb_align;
44425 +       ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL);
44426 +       if (ud->fb == NULL) {
44427 +               dev_err(dev, "Couldn't allocate VRAM\n");
44428 +               rc = -ENOMEM;
44429 +               goto fail;
44430 +       }
44431 +
44432 +       offset = (u32_t)ud->fb & (regs->fb_align - 1);
44433 +       if (!offset) {
44434 +               ud->fb_aligned = ud->fb;
44435 +       } else {
44436 +               offset = regs->fb_align - offset;
44437 +               ud->fb_aligned = ud->fb + offset;
44438 +       }
44439 +
44440 +       /*
44441 +        * Clear the entire frame buffer
44442 +        */
44443 +       if (!init_value) {
44444 +               memset(ud->fb_aligned, 0, vram_size * 1024);
44445 +       } else {
44446 +               unsigned short *p = ud->fb_aligned;
44447 +               int i;
44448 +               for (i = 0; i < ((vram_size * 1024) / sizeof(u16_t)); i++) {
44449 +                       *p++ = init_value;
44450 +               }
44451 +       }
44452 +
44453 +       /*
44454 +        * Fill in the fb_var_screeninfo structure
44455 +        */
44456 +       memset(&ubicom32fb_var, 0, sizeof(ubicom32fb_var));
44457 +       ubicom32fb_var.bits_per_pixel = regs->bpp;
44458 +       ubicom32fb_var.red.offset = regs->rshift;
44459 +       ubicom32fb_var.green.offset = regs->gshift;
44460 +       ubicom32fb_var.blue.offset = regs->bshift;
44461 +       ubicom32fb_var.red.length = regs->rbits;
44462 +       ubicom32fb_var.green.length = regs->gbits;
44463 +       ubicom32fb_var.blue.length = regs->bbits;
44464 +       ubicom32fb_var.activate = FB_ACTIVATE_NOW;
44465 +
44466 +#if 0
44467 +       /* 
44468 +        * Turn on the display 
44469 +        */
44470 +       ud->reg_ctrl_default = REG_CTRL_ENABLE;
44471 +       if (regs->rotate_screen)
44472 +               ud->reg_ctrl_default |= REG_CTRL_ROTATE;
44473 +       ubicom32fb_out_be32(ud, REG_CTRL, ud->reg_ctrl_default);
44474 +#endif
44475 +
44476 +       /*
44477 +        * Fill in the fb_info structure
44478 +        */
44479 +       ud->fbinfo->device = dev;
44480 +       ud->fbinfo->screen_base = (void *)ud->fb_aligned;
44481 +       ud->fbinfo->fbops = &ubicom32fb_ops;
44482 +       ud->fbinfo->fix = ubicom32fb_fix;
44483 +       ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned;
44484 +       ud->fbinfo->fix.smem_len = fbsize;
44485 +       ud->fbinfo->fix.line_length = regs->xres * (regs->bpp / 8);
44486 +
44487 +       /*
44488 +        * We support panning in the y direction only
44489 +        */
44490 +       ud->fbinfo->fix.xpanstep = 0;
44491 +       ud->fbinfo->fix.ypanstep = 1;
44492 +
44493 +       ud->fbinfo->pseudo_palette = ud->pseudo_palette;
44494 +       ud->fbinfo->flags = FBINFO_DEFAULT;
44495 +       ud->fbinfo->var = ubicom32fb_var;
44496 +       ud->fbinfo->var.xres = regs->xres;
44497 +       ud->fbinfo->var.yres = regs->yres;
44498 +
44499 +       /*
44500 +        * We cannot pan in the X direction, so xres_virtual is regs->xres
44501 +        * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length
44502 +        */
44503 +       ud->fbinfo->var.xres_virtual = regs->xres;
44504 +       ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
44505 +
44506 +       //ud->fbinfo->var.height = regs->height_mm;
44507 +       //ud->fbinfo->var.width = regs->width_mm;
44508 +
44509 +       /* 
44510 +        * Allocate a color map
44511 +        */
44512 +       rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
44513 +       if (rc) {
44514 +               dev_err(dev, "Fail to allocate colormap (%d entries)\n",
44515 +                       PALETTE_ENTRIES_NO);
44516 +               goto fail;
44517 +       }
44518 +       ud->cmap_alloc = true;
44519 +
44520 +       /*
44521 +        * Register new frame buffer
44522 +        */
44523 +       rc = register_framebuffer(ud->fbinfo);
44524 +       if (rc) {
44525 +               dev_err(dev, "Could not register frame buffer\n");
44526 +               goto fail;
44527 +       }
44528 +
44529 +       /*
44530 +        * Start up the VDC
44531 +        */
44532 +       ud->regs->next_frame = ud->fb;
44533 +       ubicom32fb_send_command(ud, VDCTIO_COMMAND_START, 0);
44534 +
44535 +       /*
44536 +        * Tell the log we are here
44537 +        */
44538 +       dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u), regs=%p irqtx=%u irqrx=%u\n", 
44539 +               ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, 
44540 +               ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual, ud->regs,
44541 +               irq_resource_tx->start, irq_resource_rx->start);
44542 +
44543 +       /* 
44544 +        * Success 
44545 +        */
44546 +       return 0;
44547 +
44548 +fail:
44549 +       ubicom32fb_release(dev);
44550 +       return rc;
44551 +}
44552 +
44553 +/*
44554 + * ubicom32fb_platform_remove
44555 + */
44556 +static int ubicom32fb_platform_remove(struct platform_device *pdev)
44557 +{
44558 +       dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
44559 +       return ubicom32fb_release(&pdev->dev);
44560 +}
44561 +
44562 +static struct platform_driver ubicom32fb_platform_driver = {
44563 +       .probe          = ubicom32fb_platform_probe,
44564 +       .remove         = ubicom32fb_platform_remove,
44565 +       .driver = {
44566 +               .name = DRIVER_NAME,
44567 +               .owner = THIS_MODULE,
44568 +       },
44569 +};
44570 +
44571 +#ifndef MODULE
44572 +/*
44573 + * ubicom32fb_setup
44574 + *     Process kernel boot options
44575 + */
44576 +static int __init ubicom32fb_setup(char *options)
44577 +{
44578 +       char *this_opt;
44579 +
44580 +       if (!options || !*options) {
44581 +               return 0;
44582 +       }
44583 +
44584 +       while ((this_opt = strsep(&options, ",")) != NULL) {
44585 +               if (!*this_opt) {
44586 +                       continue;
44587 +               }
44588 +
44589 +               if (!strncmp(this_opt, "init_value=", 10)) {
44590 +                       init_value = simple_strtoul(this_opt + 11, NULL, 0);
44591 +                       continue;
44592 +               }
44593 +
44594 +               if (!strncmp(this_opt, "vram_size=", 10)) {
44595 +                       vram_size = simple_strtoul(this_opt + 10, NULL, 0);
44596 +                       continue;
44597 +               }
44598 +       }
44599 +       return 0;
44600 +}
44601 +#endif /* MODULE */
44602 +
44603 +/*
44604 + * ubicom32fb_init
44605 + */
44606 +static int __devinit ubicom32fb_init(void)
44607 +{
44608 +#ifndef MODULE
44609 +       /*
44610 +        * Get kernel boot options (in 'video=ubicom32fb:<options>')
44611 +        */
44612 +       char *option = NULL;
44613 +
44614 +       if (fb_get_options(DRIVER_NAME, &option)) {
44615 +               return -ENODEV;
44616 +       }
44617 +       ubicom32fb_setup(option);
44618 +#endif /* MODULE */
44619 +
44620 +       return platform_driver_register(&ubicom32fb_platform_driver);
44621 +}
44622 +module_init(ubicom32fb_init);
44623 +
44624 +/*
44625 + * ubicom32fb_exit
44626 + */
44627 +static void __exit ubicom32fb_exit(void)
44628 +{
44629 +       platform_driver_unregister(&ubicom32fb_platform_driver);
44630 +}
44631 +module_exit(ubicom32fb_exit);
44632 +
44633 +MODULE_LICENSE("GPL");
44634 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
44635 +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
44636 --- /dev/null
44637 +++ b/drivers/video/ubicom32vfb.c
44638 @@ -0,0 +1,492 @@
44639 +/*
44640 + * drivers/video/ubicom32vfb.c
44641 + *     Ubicom32 virtual frame buffer driver
44642 + *
44643 + * (C) Copyright 2009, Ubicom, Inc.
44644 + *
44645 + * This file is part of the Ubicom32 Linux Kernel Port.
44646 + *
44647 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
44648 + * it and/or modify it under the terms of the GNU General Public License
44649 + * as published by the Free Software Foundation, either version 2 of the
44650 + * License, or (at your option) any later version.
44651 + *
44652 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
44653 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
44654 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
44655 + * the GNU General Public License for more details.
44656 + *
44657 + * You should have received a copy of the GNU General Public License
44658 + * along with the Ubicom32 Linux Kernel Port.  If not,
44659 + * see <http://www.gnu.org/licenses/>.
44660 + */
44661 +
44662 +/*
44663 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
44664 + * Geert Uytterhoeven.
44665 + */
44666 +
44667 +#include <linux/device.h>
44668 +#include <linux/module.h>
44669 +#include <linux/kernel.h>
44670 +#include <linux/version.h>
44671 +#include <linux/errno.h>
44672 +#include <linux/string.h>
44673 +#include <linux/mm.h>
44674 +#include <linux/fb.h>
44675 +#include <linux/init.h>
44676 +#include <linux/dma-mapping.h>
44677 +#include <linux/platform_device.h>
44678 +#include <linux/device.h>
44679 +#include <linux/uaccess.h>
44680 +
44681 +#define DRIVER_NAME            "ubicom32vfb"
44682 +#define DRIVER_DESCRIPTION     "Ubicom32 virtual frame buffer driver"
44683 +
44684 +#define PALETTE_ENTRIES_NO     16
44685 +
44686 +/*
44687 + * Option variables
44688 + *
44689 + * vram_size:  VRAM size in kilobytes, subject to alignment 
44690 + */
44691 +static int vram_size = 0;
44692 +module_param(vram_size, int, 0);
44693 +MODULE_PARM_DESC(vram_size, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment");
44694 +
44695 +static int xres = 320;
44696 +module_param(xres, int, 0);
44697 +MODULE_PARM_DESC(xres, "x (horizontal) resolution");
44698 +
44699 +static int yres = 240;
44700 +module_param(yres, int, 0);
44701 +MODULE_PARM_DESC(yres, "y (vertical) resolution");
44702 +
44703 +static int bgr = 0;
44704 +module_param(bgr, int, 0);
44705 +MODULE_PARM_DESC(bgr, "display is BGR (Blue is MSB)");
44706 +
44707 +/*
44708 + * Buffer alignment, must not be 0
44709 + */
44710 +#define UBICOM32VFB_ALIGNMENT 4
44711 +
44712 +/*
44713 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
44714 + */
44715 +static struct fb_fix_screeninfo ubicom32vfb_fix = {
44716 +       .id =           "Ubicom32",
44717 +       .type =         FB_TYPE_PACKED_PIXELS,
44718 +       .visual =       FB_VISUAL_TRUECOLOR,
44719 +       .accel =        FB_ACCEL_NONE
44720 +};
44721 +
44722 +/*
44723 + * Filled in at probe time when we find out what the hardware supports
44724 + */
44725 +static struct fb_var_screeninfo ubicom32vfb_var;
44726 +
44727 +/*
44728 + * Private data structure
44729 + */
44730 +struct ubicom32vfb_drvdata {
44731 +       struct fb_info                  *fbinfo;
44732 +       bool                            cmap_alloc;
44733 +
44734 +       /*
44735 +        * The address of the framebuffer in memory
44736 +        */
44737 +       void                            *fb;
44738 +       void                            *fb_aligned;
44739 +
44740 +       /*
44741 +        * Total size of vram including alignment allowance
44742 +        */
44743 +       u32                             total_vram_size;
44744 +       
44745 +       /* 
44746 +        * Fake palette of 16 colors
44747 +        */
44748 +       u32                             pseudo_palette[PALETTE_ENTRIES_NO];
44749 +};
44750 +
44751 +/*
44752 + * ubicom32vfb_pan_display
44753 + *     Pans the display to a given location.  Supports only y direction panning.
44754 + */
44755 +static int ubicom32vfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44756 +{
44757 +       struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)fbi->par;
44758 +       void *new_addr;
44759 +
44760 +       /*
44761 +        * Get the last y line that would be displayed.  Since we don't support YWRAP,
44762 +        * it must be less than our virtual y size.
44763 +        */
44764 +       u32 lasty = var->yoffset + var->yres;
44765 +       if (lasty > fbi->var.yres_virtual) {
44766 +               /*
44767 +                * We would fall off the end of our frame buffer if we panned here.
44768 +                */
44769 +               return -EINVAL;
44770 +       }
44771 +
44772 +       if (var->xoffset) {
44773 +               /*
44774 +                * We don't support panning in the x direction
44775 +                */
44776 +               return -EINVAL;
44777 +       }
44778 +
44779 +       /*
44780 +        * Everything looks sane, go ahead and pan
44781 +        *
44782 +        * We have to calculate a new address for the VDC to look at
44783 +        */
44784 +       new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44785 +
44786 +       return 0;
44787 +}
44788 +
44789 +/*
44790 + * ubicom32vfb_setcolreg
44791 + *     Sets a color in our virtual palette
44792 + */
44793 +static int ubicom32vfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44794 +{
44795 +       u32 *palette = fbi->pseudo_palette;
44796 +
44797 +       if (regno >= PALETTE_ENTRIES_NO) {
44798 +               return -EINVAL;
44799 +       }
44800 +
44801 +       /*
44802 +        * We only use 8 bits from each color
44803 +        */
44804 +       red >>= 8;
44805 +       green >>= 8;
44806 +       blue >>= 8;
44807 +
44808 +       /*
44809 +        * Convert any grayscale values
44810 +        */
44811 +       if (fbi->var.grayscale) {
44812 +               u16 gray = red + green + blue;
44813 +               gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44814 +               gray >>= 2;
44815 +               if (gray > 255) {
44816 +                       gray = 255;
44817 +               }
44818 +               red = gray;
44819 +               blue = gray;
44820 +               green = gray;
44821 +       }
44822 +
44823 +       palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44824 +                        (blue << fbi->var.blue.offset);
44825 +
44826 +       return 0;
44827 +}
44828 +
44829 +/*
44830 + * ubicom32vfb_mmap
44831 + */
44832 +static int ubicom32vfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
44833 +{
44834 +       struct ubicom32vfb_drvdata *drvdata = (struct ubicom32vfb_drvdata *)info->par;
44835 +
44836 +       vma->vm_start = (unsigned long)(drvdata->fb_aligned);
44837 +
44838 +       vma->vm_end = vma->vm_start + info->fix.smem_len;
44839 +
44840 +       /* For those who don't understand how mmap works, go read
44841 +        *   Documentation/nommu-mmap.txt.
44842 +        * For those that do, you will know that the VM_MAYSHARE flag
44843 +        * must be set in the vma->vm_flags structure on noMMU
44844 +        *   Other flags can be set, and are documented in
44845 +        *   include/linux/mm.h
44846 +        */
44847 +
44848 +       vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
44849 +
44850 +       return 0;
44851 +}
44852 +
44853 +static struct fb_ops ubicom32vfb_ops =
44854 +{
44855 +       .owner                  = THIS_MODULE,
44856 +       .fb_pan_display         = ubicom32vfb_pan_display,
44857 +       .fb_setcolreg           = ubicom32vfb_setcolreg,
44858 +       .fb_mmap                = ubicom32vfb_mmap,
44859 +       .fb_fillrect            = cfb_fillrect,
44860 +       .fb_copyarea            = cfb_copyarea,
44861 +       .fb_imageblit           = cfb_imageblit,
44862 +};
44863 +
44864 +/*
44865 + * ubicom32vfb_release
44866 + */
44867 +static int ubicom32vfb_release(struct device *dev)
44868 +{
44869 +       struct ubicom32vfb_drvdata *ud = dev_get_drvdata(dev);
44870 +
44871 +       unregister_framebuffer(ud->fbinfo);
44872 +
44873 +       if (ud->cmap_alloc) {
44874 +               fb_dealloc_cmap(&ud->fbinfo->cmap);
44875 +       }
44876 +
44877 +       if (ud->fb) {
44878 +               kfree(ud->fb);
44879 +       }
44880 +
44881 +       framebuffer_release(ud->fbinfo);
44882 +       dev_set_drvdata(dev, NULL);
44883 +
44884 +       return 0;
44885 +}
44886 +
44887 +/*
44888 + * ubicom32vfb_platform_probe
44889 + */
44890 +static int __init ubicom32vfb_platform_probe(struct platform_device *pdev)
44891 +{
44892 +       struct ubicom32vfb_drvdata *ud;
44893 +       struct fb_info *fbinfo;
44894 +       int rc;
44895 +       size_t fbsize;
44896 +       struct device *dev = &pdev->dev;
44897 +       int offset;
44898 +
44899 +       /*
44900 +        * This is the minimum VRAM size
44901 +        */
44902 +       fbsize = xres * yres * 2;
44903 +       if (!vram_size) {
44904 +               vram_size = (fbsize + 1023) / 1024;
44905 +       } else {
44906 +               if (fbsize > (vram_size * 1024)) {
44907 +                       dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize);
44908 +                       return -ENOMEM; // should be ebadparam?
44909 +               }
44910 +       }
44911 +
44912 +       /*
44913 +        * Allocate the framebuffer instance + our private data
44914 +        */
44915 +       fbinfo = framebuffer_alloc(sizeof(struct ubicom32vfb_drvdata), &pdev->dev);
44916 +       if (!fbinfo) {
44917 +               dev_err(dev, "Not enough memory to allocate instance.\n");
44918 +               return -ENOMEM;
44919 +       }
44920 +
44921 +       /*
44922 +        * Fill in our private data.
44923 +        */
44924 +       ud = (struct ubicom32vfb_drvdata *)fbinfo->par;
44925 +       ud->fbinfo = fbinfo;
44926 +       dev_set_drvdata(dev, ud);
44927 +
44928 +       /*
44929 +        * Allocate and align the requested amount of VRAM
44930 +        */
44931 +       ud->total_vram_size = (vram_size * 1024) + UBICOM32VFB_ALIGNMENT;
44932 +       ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL);
44933 +       if (ud->fb == NULL) {
44934 +               dev_err(dev, "Couldn't allocate VRAM\n");
44935 +               rc = -ENOMEM;
44936 +               goto fail;
44937 +       }
44938 +
44939 +       offset = (u32_t)ud->fb & (UBICOM32VFB_ALIGNMENT - 1);
44940 +       if (!offset) {
44941 +               ud->fb_aligned = ud->fb;
44942 +       } else {
44943 +               offset =  UBICOM32VFB_ALIGNMENT - offset;
44944 +               ud->fb_aligned = ud->fb + offset;
44945 +       }
44946 +
44947 +       /*
44948 +        * Clear the entire frame buffer
44949 +        */
44950 +       memset(ud->fb_aligned, 0, vram_size * 1024);
44951 +
44952 +       /*
44953 +        * Fill in the fb_var_screeninfo structure
44954 +        */
44955 +       memset(&ubicom32vfb_var, 0, sizeof(ubicom32vfb_var));
44956 +       ubicom32vfb_var.bits_per_pixel = 16;
44957 +       ubicom32vfb_var.red.length = 5;
44958 +       ubicom32vfb_var.green.length = 6;
44959 +       ubicom32vfb_var.green.offset = 5;
44960 +       ubicom32vfb_var.blue.length = 5;
44961 +       ubicom32vfb_var.activate = FB_ACTIVATE_NOW;
44962 +
44963 +       if (bgr) {
44964 +               ubicom32vfb_var.red.offset = 0;
44965 +               ubicom32vfb_var.blue.offset = 11;
44966 +       } else {
44967 +               ubicom32vfb_var.red.offset = 11;
44968 +               ubicom32vfb_var.blue.offset = 0;
44969 +       }
44970 +
44971 +       /*
44972 +        * Fill in the fb_info structure
44973 +        */
44974 +       ud->fbinfo->device = dev;
44975 +       ud->fbinfo->screen_base = (void *)ud->fb_aligned;
44976 +       ud->fbinfo->fbops = &ubicom32vfb_ops;
44977 +       ud->fbinfo->fix = ubicom32vfb_fix;
44978 +       ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned;
44979 +       ud->fbinfo->fix.smem_len = fbsize;
44980 +       ud->fbinfo->fix.line_length = xres * 2;
44981 +
44982 +       /*
44983 +        * We support panning in the y direction only
44984 +        */
44985 +       ud->fbinfo->fix.xpanstep = 0;
44986 +       ud->fbinfo->fix.ypanstep = 1;
44987 +
44988 +       ud->fbinfo->pseudo_palette = ud->pseudo_palette;
44989 +       ud->fbinfo->flags = FBINFO_DEFAULT;
44990 +       ud->fbinfo->var = ubicom32vfb_var;
44991 +       ud->fbinfo->var.xres = xres;
44992 +       ud->fbinfo->var.yres = yres;
44993 +
44994 +       /*
44995 +        * We cannot pan in the X direction, so xres_virtual is xres
44996 +        * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length
44997 +        */
44998 +       ud->fbinfo->var.xres_virtual = xres;
44999 +       ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
45000 +
45001 +       /* 
45002 +        * Allocate a color map
45003 +        */
45004 +       rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
45005 +       if (rc) {
45006 +               dev_err(dev, "Fail to allocate colormap (%d entries)\n",
45007 +                       PALETTE_ENTRIES_NO);
45008 +               goto fail;
45009 +       }
45010 +       ud->cmap_alloc = true;
45011 +
45012 +       /*
45013 +        * Register new frame buffer
45014 +        */
45015 +       rc = register_framebuffer(ud->fbinfo);
45016 +       if (rc) {
45017 +               dev_err(dev, "Could not register frame buffer\n");
45018 +               goto fail;
45019 +       }
45020 +
45021 +       /*
45022 +        * Tell the log we are here
45023 +        */
45024 +       dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u)\n",
45025 +               ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, 
45026 +               ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual);
45027 +
45028 +       /* 
45029 +        * Success 
45030 +        */
45031 +       return 0;
45032 +
45033 +fail:
45034 +       ubicom32vfb_release(dev);
45035 +       return rc;
45036 +}
45037 +
45038 +/*
45039 + * ubicom32vfb_platform_remove
45040 + */
45041 +static int ubicom32vfb_platform_remove(struct platform_device *pdev)
45042 +{
45043 +       dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
45044 +       return ubicom32vfb_release(&pdev->dev);
45045 +}
45046 +
45047 +static struct platform_driver ubicom32vfb_platform_driver = {
45048 +       .probe          = ubicom32vfb_platform_probe,
45049 +       .remove         = ubicom32vfb_platform_remove,
45050 +       .driver = {
45051 +               .name = DRIVER_NAME,
45052 +               .owner = THIS_MODULE,
45053 +       },
45054 +};
45055 +
45056 +#ifndef MODULE
45057 +/*
45058 + * ubicom32vfb_setup
45059 + *     Process kernel boot options
45060 + */
45061 +static int __init ubicom32vfb_setup(char *options)
45062 +{
45063 +       char *this_opt;
45064 +
45065 +       if (!options || !*options) {
45066 +               return 0;
45067 +       }
45068 +
45069 +       while ((this_opt = strsep(&options, ",")) != NULL) {
45070 +               if (!*this_opt) {
45071 +                       continue;
45072 +               }
45073 +
45074 +               if (!strncmp(this_opt, "vram_size=", 10)) {
45075 +                       vram_size = simple_strtoul(this_opt + 10, NULL, 0);
45076 +                       continue;
45077 +               }
45078 +
45079 +               if (!strncmp(this_opt, "bgr=", 4)) {
45080 +                       bgr = simple_strtoul(this_opt + 4, NULL, 0);
45081 +                       continue;
45082 +               }
45083 +
45084 +               if (!strncmp(this_opt, "xres=", 5)) {
45085 +                       xres = simple_strtoul(this_opt + 5, NULL, 0);
45086 +                       continue;
45087 +               }
45088 +
45089 +               if (!strncmp(this_opt, "yres=", 5)) {
45090 +                       yres = simple_strtoul(this_opt + 5, NULL, 0);
45091 +                       continue;
45092 +               }
45093 +       }
45094 +       return 0;
45095 +}
45096 +#endif /* MODULE */
45097 +
45098 +/*
45099 + * ubicom32vfb_init
45100 + */
45101 +static int __devinit ubicom32vfb_init(void)
45102 +{
45103 +#ifndef MODULE
45104 +       /*
45105 +        * Get kernel boot options (in 'video=ubicom32vfb:<options>')
45106 +        */
45107 +       char *option = NULL;
45108 +
45109 +       if (fb_get_options(DRIVER_NAME, &option)) {
45110 +               return -ENODEV;
45111 +       }
45112 +       ubicom32vfb_setup(option);
45113 +#endif /* MODULE */
45114 +
45115 +       return platform_driver_register(&ubicom32vfb_platform_driver);
45116 +}
45117 +module_init(ubicom32vfb_init);
45118 +
45119 +/*
45120 + * ubicom32vfb_exit
45121 + */
45122 +static void __exit ubicom32vfb_exit(void)
45123 +{
45124 +       platform_driver_unregister(&ubicom32vfb_platform_driver);
45125 +}
45126 +module_exit(ubicom32vfb_exit);
45127 +
45128 +MODULE_LICENSE("GPL");
45129 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
45130 +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
45131 --- a/drivers/watchdog/Kconfig
45132 +++ b/drivers/watchdog/Kconfig
45133 @@ -856,6 +856,19 @@ config WATCHDOG_RIO
45134           machines.  The watchdog timeout period is normally one minute but
45135           can be changed with a boot-time parameter.
45136  
45137 +# Ubicom32
45138 +
45139 +config UBI32_WDT
45140 +       tristate "Ubicom32 Hardware Watchdog support"
45141 +       depends on UBICOM32
45142 +       ---help---
45143 +         If you say yes here you will get support for the Ubicom32 On-Chip
45144 +         Watchdog Timer. If you have one of these processors and wish to
45145 +         have watchdog support enabled, say Y, otherwise say N.
45146 +
45147 +         To compile this driver as a module, choose M here: the
45148 +         module will be called ubi32_wdt.
45149 +
45150  # XTENSA Architecture
45151  
45152  #
45153 --- a/drivers/watchdog/Makefile
45154 +++ b/drivers/watchdog/Makefile
45155 @@ -130,6 +130,9 @@ obj-$(CONFIG_SH_WDT) += shwdt.o
45156  obj-$(CONFIG_WATCHDOG_RIO)             += riowd.o
45157  obj-$(CONFIG_WATCHDOG_CP1XXX)          += cpwd.o
45158  
45159 +# Ubicom32 Architecture
45160 +obj-$(CONFIG_UBI32_WDT)                        += ubi32_wdt.o
45161 +
45162  # XTENSA Architecture
45163  
45164  # Architecture Independant
45165 --- /dev/null
45166 +++ b/drivers/watchdog/ubi32_wdt.c
45167 @@ -0,0 +1,630 @@
45168 +/*
45169 + * drivers/watchdog/ubi32_wdt.c
45170 + *   Ubicom32 Watchdog Driver
45171 + *
45172 + * Originally based on softdog.c
45173 + * Copyright 2006-2007 Analog Devices Inc.
45174 + * Copyright 2006-2007 Michele d'Amico
45175 + * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>
45176 + * (C) Copyright 2009, Ubicom, Inc.
45177 + *
45178 + * This file is part of the Ubicom32 Linux Kernel Port.
45179 + *
45180 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
45181 + * it and/or modify it under the terms of the GNU General Public License
45182 + * as published by the Free Software Foundation, either version 2 of the
45183 + * License, or (at your option) any later version.
45184 + *
45185 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
45186 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
45187 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
45188 + * the GNU General Public License for more details.
45189 + *
45190 + * You should have received a copy of the GNU General Public License
45191 + * along with the Ubicom32 Linux Kernel Port.  If not,
45192 + * see <http://www.gnu.org/licenses/>.
45193 + *
45194 + * Ubicom32 implementation derived from (with many thanks):
45195 + *   arch/m68knommu
45196 + *   arch/blackfin
45197 + *   arch/parisc
45198 + */
45199 +#include <linux/platform_device.h>
45200 +#include <linux/module.h>
45201 +#include <linux/moduleparam.h>
45202 +#include <linux/types.h>
45203 +#include <linux/timer.h>
45204 +#include <linux/miscdevice.h>
45205 +#include <linux/watchdog.h>
45206 +#include <linux/fs.h>
45207 +#include <linux/notifier.h>
45208 +#include <linux/reboot.h>
45209 +#include <linux/init.h>
45210 +#include <linux/interrupt.h>
45211 +#include <linux/uaccess.h>
45212 +#include <asm/ip5000.h>
45213 +
45214 +#define WATCHDOG_NAME "ubi32-wdt"
45215 +#define PFX WATCHDOG_NAME ": "
45216 +
45217 +#define OSC1_FREQ 12000000
45218 +#define WATCHDOG_SEC_TO_CYC(x) (OSC1_FREQ * (x))
45219 +#define WATCHDOG_MAX_SEC (0xffffffff / OSC1_FREQ)
45220 +
45221 +#define MIN_PROCESSOR_ADDRESS 0x03000000
45222 +
45223 +static DEFINE_SPINLOCK(ubi32_wdt_spinlock);
45224 +
45225 +#define WATCHDOG_TIMEOUT 20
45226 +
45227 +#if defined(CONFIG_WATCHDOG_NOWAYOUT)
45228 +#define WATCHDOG_NOWAYOUT 1
45229 +#else
45230 +#define WATCHDOG_NOWAYOUT 0
45231 +#endif
45232 +
45233 +static unsigned int timeout = WATCHDOG_TIMEOUT;
45234 +static int nowayout = WATCHDOG_NOWAYOUT;
45235 +static struct watchdog_info ubi32_wdt_info;
45236 +static unsigned long open_check;
45237 +static char expect_close;
45238 +
45239 +#if !defined(CONFIG_SMP)
45240 +#define UBI32_WDT_LOCK(lock, flags) local_irq_save(flags)
45241 +#define UBI32_WDT_UNLOCK(lock, flags) local_irq_restore(flags)
45242 +#define UBI32_WDT_LOCK_CHECK()
45243 +#else
45244 +#define UBI32_WDT_LOCK(lock, flags) spin_lock_irqsave((lock), (flags));
45245 +#define UBI32_WDT_UNLOCK(lock, flags) spin_unlock_irqrestore((lock), (flags));
45246 +#define UBI32_WDT_LOCK_CHECK() BUG_ON(!spin_is_locked(&ubi32_wdt_spinlock));
45247 +#endif
45248 +
45249 +/*
45250 + * ubi32_wdt_remaining()
45251 + *     Return the approximate number of seconds remaining
45252 + */
45253 +static int ubi32_wdt_remaining(void)
45254 +{
45255 +       int compare;
45256 +       int curr;
45257 +
45258 +       UBI32_WDT_LOCK_CHECK();
45259 +
45260 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45261 +       compare = ubicom32_read_reg(&UBICOM32_IO_TIMER->wdcom);
45262 +       curr = ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval);
45263 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45264 +       return (compare - curr) / OSC1_FREQ;
45265 +
45266 +}
45267 +
45268 +/*
45269 + * ubi32_wdt_keepalive()
45270 + *     Keep the Userspace Watchdog Alive
45271 + *
45272 + * The Userspace watchdog got a KeepAlive: schedule the next timeout.
45273 + */
45274 +static int ubi32_wdt_keepalive(void)
45275 +{
45276 +       UBI32_WDT_LOCK_CHECK();
45277 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45278 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcom,
45279 +                       ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval)
45280 +                       + WATCHDOG_SEC_TO_CYC(timeout));
45281 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45282 +       return 0;
45283 +}
45284 +
45285 +/*
45286 + * ubi32_wdt_stop()
45287 + *     Stop the on-chip Watchdog
45288 + */
45289 +static int ubi32_wdt_stop(void)
45290 +{
45291 +       UBI32_WDT_LOCK_CHECK();
45292 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45293 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcfg, TIMER_WATCHDOG_DISABLE);
45294 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45295 +       return 0;
45296 +}
45297 +
45298 +/*
45299 + * ubi32_wdt_start()
45300 + *     Start the on-chip Watchdog
45301 + */
45302 +static int ubi32_wdt_start(void)
45303 +{
45304 +       UBI32_WDT_LOCK_CHECK();
45305 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45306 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcom,
45307 +                       ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval)
45308 +                       + WATCHDOG_SEC_TO_CYC(timeout));
45309 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcfg, ~TIMER_WATCHDOG_DISABLE);
45310 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45311 +       return 0;
45312 +}
45313 +
45314 +/*
45315 + * ubi32_wdt_running()
45316 + *     Return true if the watchdog is configured
45317 + */
45318 +static int ubi32_wdt_running(void)
45319 +{
45320 +       int enabled;
45321 +
45322 +       UBI32_WDT_LOCK_CHECK();
45323 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45324 +       enabled = ubicom32_read_reg(&UBICOM32_IO_TIMER->wdcfg) == ~TIMER_WATCHDOG_DISABLE;
45325 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45326 +       return enabled;
45327 +}
45328 +
45329 +/*
45330 + * ubi32_wdt_set_timeout()
45331 + *     Set the Userspace Watchdog timeout
45332 + *
45333 + * - @t: new timeout value (in seconds)
45334 + */
45335 +static int ubi32_wdt_set_timeout(unsigned long t)
45336 +{
45337 +       UBI32_WDT_LOCK_CHECK();
45338 +
45339 +       if (t > WATCHDOG_MAX_SEC) {
45340 +               printk(KERN_WARNING PFX "request to large: %ld [1-%d] sec)\n", t, WATCHDOG_MAX_SEC);
45341 +               return -EINVAL;
45342 +       }
45343 +
45344 +       /*
45345 +        * If we are running, then reset the time value so
45346 +        * that the new value has an immediate effect.
45347 +        */
45348 +       timeout = t;
45349 +       if (ubi32_wdt_running()) {
45350 +               ubi32_wdt_keepalive();
45351 +       }
45352 +       return 0;
45353 +}
45354 +
45355 +/*
45356 + * ubi32_wdt_open()
45357 + *     Open the Device
45358 + */
45359 +static int ubi32_wdt_open(struct inode *inode, struct file *file)
45360 +{
45361 +       unsigned long flags;
45362 +
45363 +       if (test_and_set_bit(0, &open_check))
45364 +               return -EBUSY;
45365 +
45366 +       if (nowayout)
45367 +               __module_get(THIS_MODULE);
45368 +
45369 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45370 +       ubi32_wdt_start();
45371 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45372 +
45373 +       return nonseekable_open(inode, file);
45374 +}
45375 +
45376 +/*
45377 + * ubi32_wdt_close()
45378 + *     Close the Device
45379 + */
45380 +static int ubi32_wdt_release(struct inode *inode, struct file *file)
45381 +{
45382 +       unsigned long flags;
45383 +
45384 +       /*
45385 +        * If we don't expect a close, then the watchdog continues
45386 +        * even though the device is closed.  The caller will have
45387 +        * a full timeout value to reopen the device and continue
45388 +        * stroking it.
45389 +        */
45390 +       if (expect_close != 42) {
45391 +               printk(KERN_CRIT PFX
45392 +                       "Unexpected close, not stopping watchdog!\n");
45393 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45394 +               ubi32_wdt_keepalive();
45395 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45396 +       } else {
45397 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45398 +               ubi32_wdt_stop();
45399 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45400 +       }
45401 +
45402 +       expect_close = 0;
45403 +       clear_bit(0, &open_check);
45404 +       return 0;
45405 +}
45406 +
45407 +/*
45408 + * ubi32_wdt_write()
45409 + *     Write to Device
45410 + *
45411 + * If the user writes nothing, nothing happens.
45412 + * If the user writes a V, then we expect a close and allow a release.
45413 + * If the user writes anything else, it is ignored.
45414 + */
45415 +static ssize_t ubi32_wdt_write(struct file *file, const char __user *data,
45416 +                                               size_t len, loff_t *ppos)
45417 +{
45418 +       size_t i;
45419 +       unsigned long flags;
45420 +
45421 +       /*
45422 +        * Every write resets the expect_close.  The last write
45423 +        * must be a V to allow shutdown on close.
45424 +        */
45425 +       expect_close = 0;
45426 +
45427 +       /*
45428 +        * Empty writes still ping.
45429 +        */
45430 +       if (!len) {
45431 +               goto ping;
45432 +       }
45433 +
45434 +       /*
45435 +        * If nowayout is set, it does not matter if the caller
45436 +        * is trying to send the magic 'V' we will not allow a
45437 +        * close to stop us.
45438 +        */
45439 +       if (nowayout) {
45440 +               goto ping;
45441 +       }
45442 +
45443 +       /*
45444 +        * See if the program wrote a 'V' and if so disable
45445 +        * the watchdog on release.
45446 +        */
45447 +       for (i = 0; i < len; i++) {
45448 +               char c;
45449 +               if (get_user(c, data + i)) {
45450 +                       return -EFAULT;
45451 +               }
45452 +
45453 +               if (c == 'V') {
45454 +                       expect_close = 42;
45455 +               }
45456 +       }
45457 +
45458 +ping:
45459 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45460 +       ubi32_wdt_keepalive();
45461 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45462 +       return len;
45463 +}
45464 +
45465 +/*
45466 + * ubi32_wdt_ioctl()
45467 + *     Query the watchdog device.
45468 + *
45469 + * Query basic information from the device or ping it, as outlined by the
45470 + * watchdog API.
45471 + */
45472 +static long ubi32_wdt_ioctl(struct file *file,
45473 +                               unsigned int cmd, unsigned long arg)
45474 +{
45475 +       void __user *argp = (void __user *)arg;
45476 +       int __user *p = argp;
45477 +
45478 +       switch (cmd) {
45479 +       case WDIOC_GETSUPPORT:
45480 +               if (copy_to_user(argp, &ubi32_wdt_info, sizeof(ubi32_wdt_info))) {
45481 +                       return -EFAULT;
45482 +               }
45483 +               return 0;
45484 +
45485 +       case WDIOC_GETSTATUS: {
45486 +               unsigned long flags;
45487 +               int running;
45488 +
45489 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45490 +               running = ubi32_wdt_running();
45491 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45492 +               return running;
45493 +       }
45494 +
45495 +       case WDIOC_GETBOOTSTATUS:
45496 +               return ubicom32_get_reset_reason();
45497 +
45498 +       case WDIOC_SETOPTIONS: {
45499 +               unsigned long flags;
45500 +               int options, ret = -EINVAL;
45501 +
45502 +               /*
45503 +                * The sample application does not pass a pointer
45504 +                * but directly passes a value of 1 or 2; however
45505 +                * all of the implementations (and thus probably
45506 +                * the real applications) pass a pointer to a value.
45507 +                *
45508 +                * It should be noted that  WDIOC_SETOPTIONS is defined as
45509 +                * _IOR(WATCHDOG_IOCTL_BASE, 4, int), which means
45510 +                * that it should be an int and NOT a pointer.
45511 +                *
45512 +                * TODO: Examine this code for future chips.
45513 +                * TODO: Report the sample code defect.
45514 +                */
45515 +               if ((int)p < MIN_PROCESSOR_ADDRESS) {
45516 +                       options = (int)p;
45517 +               } else {
45518 +                       if (get_user(options, p))
45519 +                       return -EFAULT;
45520 +               }
45521 +
45522 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45523 +               if (options & WDIOS_DISABLECARD) {
45524 +                       ubi32_wdt_stop();
45525 +                       ret = 0;
45526 +               }
45527 +               if (options & WDIOS_ENABLECARD) {
45528 +                       ubi32_wdt_start();
45529 +                       ret = 0;
45530 +               }
45531 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45532 +               return ret;
45533 +       }
45534 +
45535 +       case WDIOC_KEEPALIVE: {
45536 +               unsigned long flags;
45537 +
45538 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45539 +               ubi32_wdt_keepalive();
45540 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45541 +               return 0;
45542 +       }
45543 +
45544 +       case WDIOC_SETTIMEOUT: {
45545 +               int new_timeout;
45546 +               unsigned long flags;
45547 +               int ret  = 0;
45548 +
45549 +               if (get_user(new_timeout, p))
45550 +                       return -EFAULT;
45551 +
45552 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45553 +               ret = ubi32_wdt_set_timeout(new_timeout);
45554 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45555 +               return ret;
45556 +
45557 +       }
45558 +
45559 +       case WDIOC_GETTIMEOUT:
45560 +               return put_user(timeout, p);
45561 +
45562 +       case WDIOC_GETTIMELEFT: {
45563 +               unsigned long flags;
45564 +               int remaining = 0;
45565 +
45566 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45567 +               remaining = ubi32_wdt_remaining();
45568 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45569 +               return put_user(remaining, p);
45570 +       }
45571 +
45572 +       default:
45573 +               return -ENOTTY;
45574 +       }
45575 +}
45576 +
45577 +/*
45578 + * ubi32_wdt_notify_sys()
45579 + *     Notification callback function for system events.
45580 + *
45581 + * Turn off the watchdog during a SYS_DOWN or SYS_HALT.
45582 + */
45583 +static int ubi32_wdt_notify_sys(struct notifier_block *this,
45584 +                                       unsigned long code, void *unused)
45585 +{
45586 +       if (code == SYS_DOWN || code == SYS_HALT) {
45587 +               unsigned long flags;
45588 +
45589 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45590 +               ubi32_wdt_stop();
45591 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45592 +       }
45593 +
45594 +       return NOTIFY_DONE;
45595 +}
45596 +
45597 +#ifdef CONFIG_PM
45598 +static int state_before_suspend;
45599 +
45600 +/*
45601 + * ubi32_wdt_suspend()
45602 + *     suspend the watchdog
45603 + *
45604 + * Remember if the watchdog was running and stop it.
45605 + */
45606 +static int ubi32_wdt_suspend(struct platform_device *pdev, pm_message_t state)
45607 +{
45608 +       unsigned long flags;
45609 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45610 +       state_before_suspend = ubi32_wdt_running();
45611 +       ubi32_wdt_stop();
45612 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45613 +
45614 +       return 0;
45615 +}
45616 +
45617 +/*
45618 + * ubi32_wdt_resume()
45619 + *     Resume the watchdog
45620 + *
45621 + * If the watchdog was running, turn it back on.
45622 + */
45623 +static int ubi32_wdt_resume(struct platform_device *pdev)
45624 +{
45625 +       if (state_before_suspend) {
45626 +               unsigned long flags;
45627 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45628 +               ubi32_wdt_set_timeout(timeout);
45629 +               ubi32_wdt_start();
45630 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45631 +       }
45632 +
45633 +       return 0;
45634 +}
45635 +#else
45636 +# define ubi32_wdt_suspend NULL
45637 +# define ubi32_wdt_resume NULL
45638 +#endif
45639 +
45640 +static const struct file_operations ubi32_wdt_fops = {
45641 +       .owner          = THIS_MODULE,
45642 +       .llseek         = no_llseek,
45643 +       .write          = ubi32_wdt_write,
45644 +       .unlocked_ioctl = ubi32_wdt_ioctl,
45645 +       .open           = ubi32_wdt_open,
45646 +       .release        = ubi32_wdt_release,
45647 +};
45648 +
45649 +static struct miscdevice ubi32_wdt_miscdev = {
45650 +       .minor    = WATCHDOG_MINOR,
45651 +       .name     = "watchdog",
45652 +       .fops     = &ubi32_wdt_fops,
45653 +};
45654 +
45655 +static struct watchdog_info ubi32_wdt_info = {
45656 +       .identity = "Ubicom32 Watchdog",
45657 +       .options  = WDIOF_SETTIMEOUT |
45658 +                   WDIOF_KEEPALIVEPING |
45659 +                   WDIOF_MAGICCLOSE,
45660 +};
45661 +
45662 +static struct notifier_block ubi32_wdt_notifier = {
45663 +       .notifier_call = ubi32_wdt_notify_sys,
45664 +};
45665 +
45666 +/*
45667 + * ubi32_wdt_probe()
45668 + *     Probe/register the watchdog module
45669 + *
45670 + * Registers the misc device and notifier handler.  Actual device
45671 + * initialization is handled by ubi32_wdt_open().
45672 + */
45673 +static int __devinit ubi32_wdt_probe(struct platform_device *pdev)
45674 +{
45675 +       int ret;
45676 +
45677 +       ret = register_reboot_notifier(&ubi32_wdt_notifier);
45678 +       if (ret) {
45679 +               printk(KERN_ERR PFX
45680 +                       "cannot register reboot notifier (err=%d)\n", ret);
45681 +               return ret;
45682 +       }
45683 +
45684 +       ret = misc_register(&ubi32_wdt_miscdev);
45685 +       if (ret) {
45686 +               printk(KERN_ERR PFX
45687 +                       "cannot register miscdev on minor=%d (err=%d)\n",
45688 +                               WATCHDOG_MINOR, ret);
45689 +               unregister_reboot_notifier(&ubi32_wdt_notifier);
45690 +               return ret;
45691 +       }
45692 +
45693 +       printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
45694 +              timeout, nowayout);
45695 +
45696 +       return 0;
45697 +}
45698 +
45699 +/*
45700 + * ubi32_wdt_remove()
45701 + *     Uninstall the module
45702 + *
45703 + * Unregisters the misc device and notifier handler.  Actual device
45704 + * deinitialization is handled by ubi32_wdt_close().
45705 + */
45706 +static int __devexit ubi32_wdt_remove(struct platform_device *pdev)
45707 +{
45708 +       misc_deregister(&ubi32_wdt_miscdev);
45709 +       unregister_reboot_notifier(&ubi32_wdt_notifier);
45710 +       return 0;
45711 +}
45712 +
45713 +static struct platform_device *ubi32_wdt_device;
45714 +
45715 +static struct platform_driver ubi32_wdt_driver = {
45716 +       .probe     = ubi32_wdt_probe,
45717 +       .remove    = __devexit_p(ubi32_wdt_remove),
45718 +       .suspend   = ubi32_wdt_suspend,
45719 +       .resume    = ubi32_wdt_resume,
45720 +       .driver    = {
45721 +               .name  = WATCHDOG_NAME,
45722 +               .owner = THIS_MODULE,
45723 +       },
45724 +};
45725 +
45726 +/*
45727 + * ubi32_wdt_init()
45728 + *     Initialize the watchdog.
45729 + *
45730 + * Checks the module params and registers the platform device & driver.
45731 + * Real work is in the platform probe function.
45732 + */
45733 +static int __init ubi32_wdt_init(void)
45734 +{
45735 +       unsigned long flags;
45736 +       int ret;
45737 +
45738 +       /*
45739 +        * Check that the timeout value is within range
45740 +        */
45741 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45742 +       ret = ubi32_wdt_set_timeout(timeout);
45743 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45744 +       if (ret) {
45745 +               return ret;
45746 +       }
45747 +
45748 +       /*
45749 +        * Since this is an on-chip device and needs no board-specific
45750 +        * resources, we'll handle all the platform device stuff here.
45751 +        */
45752 +       ret = platform_driver_register(&ubi32_wdt_driver);
45753 +       if (ret) {
45754 +               printk(KERN_ERR PFX "unable to register driver\n");
45755 +               return ret;
45756 +       }
45757 +
45758 +       ubi32_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0);
45759 +       if (IS_ERR(ubi32_wdt_device)) {
45760 +               printk(KERN_ERR PFX "unable to register device\n");
45761 +               platform_driver_unregister(&ubi32_wdt_driver);
45762 +               return PTR_ERR(ubi32_wdt_device);
45763 +       }
45764 +
45765 +       return 0;
45766 +}
45767 +
45768 +/*
45769 + * ubi32_wdt_exit()
45770 + *     Deinitialize module
45771 + *
45772 + * Back out the platform device & driver steps.  Real work is in the
45773 + * platform remove function.
45774 + */
45775 +static void __exit ubi32_wdt_exit(void)
45776 +{
45777 +       platform_device_unregister(ubi32_wdt_device);
45778 +       platform_driver_unregister(&ubi32_wdt_driver);
45779 +}
45780 +
45781 +module_init(ubi32_wdt_init);
45782 +module_exit(ubi32_wdt_exit);
45783 +
45784 +MODULE_AUTHOR("Sol Kavy<sol@ubicom.com>");
45785 +MODULE_DESCRIPTION("Ubicom32 Watchdog Device Driver");
45786 +MODULE_LICENSE("GPL");
45787 +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
45788 +
45789 +module_param(timeout, uint, 0);
45790 +MODULE_PARM_DESC(timeout,
45791 +       "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default="
45792 +               __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
45793 +
45794 +module_param(nowayout, int, 0);
45795 +MODULE_PARM_DESC(nowayout,
45796 +       "Watchdog cannot be stopped once started (default="
45797 +               __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
45798 --- a/fs/binfmt_flat.c
45799 +++ b/fs/binfmt_flat.c
45800 @@ -54,6 +54,10 @@
45801  #define        DBG_FLT(a...)
45802  #endif
45803  
45804 +#ifndef ARCH_FLAT_ALIGN
45805 +#define ARCH_FLAT_ALIGN 0
45806 +#endif
45807 +
45808  #define RELOC_FAILED 0xff00ff01                /* Relocation incorrect somewhere */
45809  #define UNLOADED_LIB 0x7ff000ff                /* Placeholder for unused library */
45810  
45811 @@ -127,10 +131,10 @@ static unsigned long create_flat_tables(
45812                 --sp; put_user((unsigned long) argv, sp);
45813         }
45814  
45815 -       put_user(argc,--sp);
45816 +       --sp; put_user(argc,sp);
45817         current->mm->arg_start = (unsigned long) p;
45818         while (argc-->0) {
45819 -               put_user((unsigned long) p, argv++);
45820 +               put_user((unsigned long) p, argv); argv++;
45821                 do {
45822                         get_user(dummy, p); p++;
45823                 } while (dummy);
45824 @@ -425,6 +429,7 @@ static int load_flat_file(struct linux_b
45825         loff_t fpos;
45826         unsigned long start_code, end_code;
45827         int ret;
45828 +       int flush_happened = 0;
45829  
45830         hdr = ((struct flat_hdr *) bprm->buf);          /* exec-header */
45831         inode = bprm->file->f_path.dentry->d_inode;
45832 @@ -510,6 +515,7 @@ static int load_flat_file(struct linux_b
45833  
45834                 /* OK, This is the point of no return */
45835                 set_personality(PER_LINUX_32BIT);
45836 +               flush_happened = 1;
45837         }
45838  
45839         /*
45840 @@ -524,6 +530,12 @@ static int load_flat_file(struct linux_b
45841          * it all together.
45842          */
45843         if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {
45844 +
45845 +#ifdef ARCH_FLAT_ALIGN_TEXT
45846 +               printk("Unable to mmap rom with ARCH alignment requirements\n");
45847 +               ret = -ENOEXEC;
45848 +               goto err;
45849 +#endif
45850                 /*
45851                  * this should give us a ROM ptr,  but if it doesn't we don't
45852                  * really care
45853 @@ -542,7 +554,7 @@ static int load_flat_file(struct linux_b
45854                         goto err;
45855                 }
45856  
45857 -               len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
45858 +               len = data_len + extra + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
45859                 down_write(&current->mm->mmap_sem);
45860                 realdatastart = do_mmap(0, 0, len,
45861                         PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
45862 @@ -565,7 +577,7 @@ static int load_flat_file(struct linux_b
45863                         ret = realdatastart;
45864                         goto err;
45865                 }
45866 -               datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
45867 +               datapos = realdatastart + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
45868  
45869                 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
45870                                 (int)(data_len + bss_len + stack_len), (int)datapos);
45871 @@ -594,7 +606,11 @@ static int load_flat_file(struct linux_b
45872  
45873         } else {
45874  
45875 -               len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
45876 +               len = text_len + data_len + extra + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
45877 +#ifdef ARCH_FLAT_ALIGN_TEXT
45878 +               /* Reserve space for the text alignment. */
45879 +               len += ARCH_FLAT_ALIGN;
45880 +#endif
45881                 down_write(&current->mm->mmap_sem);
45882                 textpos = do_mmap(0, 0, len,
45883                         PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
45884 @@ -617,11 +633,14 @@ static int load_flat_file(struct linux_b
45885                         goto err;
45886                 }
45887  
45888 +               memp = textpos;
45889 +#ifdef ARCH_FLAT_ALIGN_TEXT
45890 +               textpos = ALIGN(textpos + sizeof(struct flat_hdr), ARCH_FLAT_ALIGN) - sizeof(struct flat_hdr);
45891 +#endif
45892                 realdatastart = textpos + ntohl(hdr->data_start);
45893 -               datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
45894 +               datapos = realdatastart + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
45895                 reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
45896 -                               MAX_SHARED_LIBS * sizeof(unsigned long));
45897 -               memp = textpos;
45898 +                                          ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN));
45899  
45900  #ifdef CONFIG_BINFMT_ZFLAT
45901                 /*
45902 @@ -657,7 +676,7 @@ static int load_flat_file(struct linux_b
45903                 }
45904                 if (result >= (unsigned long)-4096) {
45905                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
45906 -                       do_munmap(current->mm, textpos, text_len + data_len + extra +
45907 +                       do_munmap(current->mm, memp, text_len + data_len + extra +
45908                                 MAX_SHARED_LIBS * sizeof(unsigned long));
45909                         ret = result;
45910                         goto err;
45911 @@ -670,6 +689,9 @@ static int load_flat_file(struct linux_b
45912  
45913         /* The main program needs a little extra setup in the task structure */
45914         start_code = textpos + sizeof (struct flat_hdr);
45915 +#ifdef ARCH_FLAT_ALIGN_TEXT
45916 +       BUG_ON(ALIGN(start_code, ARCH_FLAT_ALIGN) != start_code);
45917 +#endif
45918         end_code = textpos + text_len;
45919         if (id == 0) {
45920                 current->mm->start_code = start_code;
45921 @@ -796,6 +818,13 @@ static int load_flat_file(struct linux_b
45922  
45923         return 0;
45924  err:
45925 +       if (flush_happened) {
45926 +               /*
45927 +                * The parent process has already started running. We cannot allow the child to return back to user space
45928 +                * as this child is still uning the parent stack and 2 will clobber each other. We are going to kill this child.
45929 +                */
45930 +               do_exit(SIGTERM);
45931 +       }
45932         return ret;
45933  }
45934  
45935 --- a/fs/Kconfig.binfmt
45936 +++ b/fs/Kconfig.binfmt
45937 @@ -30,7 +30,7 @@ config COMPAT_BINFMT_ELF
45938  config BINFMT_ELF_FDPIC
45939         bool "Kernel support for FDPIC ELF binaries"
45940         default y
45941 -       depends on (FRV || BLACKFIN || (SUPERH32 && !MMU))
45942 +       depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || UBICOM32)
45943         help
45944           ELF FDPIC binaries are based on ELF, but allow the individual load
45945           segments of a binary to be located in memory independently of each
45946 --- a/include/asm-generic/dma-mapping.h
45947 +++ b/include/asm-generic/dma-mapping.h
45948 @@ -255,7 +255,7 @@ dma_sync_sg_for_device(struct device *de
45949  }
45950  
45951  static inline int
45952 -dma_error(dma_addr_t dma_addr)
45953 +dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
45954  {
45955         return 0;
45956  }
45957 --- a/include/linux/elf-em.h
45958 +++ b/include/linux/elf-em.h
45959 @@ -41,6 +41,7 @@
45960   * up with a final number.
45961   */
45962  #define EM_ALPHA       0x9026
45963 +#define EM_UBICOM32            0xde3d  /* Ubicom32; no ABI */
45964  
45965  /* Bogus old v850 magic number, used by old tools. */
45966  #define EM_CYGNUS_V850 0x9080
45967 --- a/include/linux/oprofile.h
45968 +++ b/include/linux/oprofile.h
45969 @@ -100,6 +100,8 @@ void oprofile_add_sample(struct pt_regs 
45970   */
45971  void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
45972                                 unsigned long event, int is_kernel);
45973 +void oprofile_add_ext_sample_cpu(unsigned long pc, struct pt_regs * const regs,
45974 +                               unsigned long event, int is_kernel, int cpu);
45975  
45976  /* Use this instead when the PC value is not from the regs. Doesn't
45977   * backtrace. */
45978 --- a/include/linux/serial_core.h
45979 +++ b/include/linux/serial_core.h
45980 @@ -158,6 +158,9 @@
45981  /* SH-SCI */
45982  #define PORT_SCIFA     83
45983  
45984 +/* Ubicom32 */
45985 +#define PORT_UBI32_UARTTIO     84
45986 +
45987  #ifdef __KERNEL__
45988  
45989  #include <linux/compiler.h>
45990 --- a/kernel/module.c
45991 +++ b/kernel/module.c
45992 @@ -2624,6 +2624,9 @@ static int m_show(struct seq_file *m, vo
45993         /* Used by oprofile and other similar tools. */
45994         seq_printf(m, " 0x%p", mod->module_core);
45995  
45996 +#ifdef ARCH_PROC_MODULES_EXTRA
45997 +       ARCH_PROC_MODULES_EXTRA(m, mod);
45998 +#endif
45999         /* Taints info */
46000         if (mod->taints)
46001                 seq_printf(m, " %s", module_flags(mod, buf));
46002 --- a/kernel/sched_clock.c
46003 +++ b/kernel/sched_clock.c
46004 @@ -37,7 +37,7 @@
46005   */
46006  unsigned long long __attribute__((weak)) sched_clock(void)
46007  {
46008 -       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
46009 +       return (get_jiffies_64() - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
46010  }
46011  
46012  static __read_mostly int sched_clock_running;
46013 --- a/lib/Kconfig.debug
46014 +++ b/lib/Kconfig.debug
46015 @@ -549,7 +549,7 @@ config FRAME_POINTER
46016         bool "Compile the kernel with frame pointers"
46017         depends on DEBUG_KERNEL && \
46018                 (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || \
46019 -                AVR32 || SUPERH || BLACKFIN || MN10300)
46020 +                AVR32 || SUPERH || BLACKFIN || MN10300 || UBICOM32)
46021         default y if DEBUG_INFO && UML
46022         help
46023           If you say Y here the resulting kernel image will be slightly larger
46024 --- a/mm/Makefile
46025 +++ b/mm/Makefile
46026 @@ -34,3 +34,5 @@ obj-$(CONFIG_MIGRATION) += migrate.o
46027  obj-$(CONFIG_SMP) += allocpercpu.o
46028  obj-$(CONFIG_QUICKLIST) += quicklist.o
46029  obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
46030 +
46031 +CFLAGS_slab.o := $(PROFILING) -O2
46032 --- a/scripts/mod/file2alias.c
46033 +++ b/scripts/mod/file2alias.c
46034 @@ -753,6 +753,15 @@ void handle_moddevtable(struct module *m
46035                         + sym->st_value;
46036         }
46037  
46038 +       /*
46039 +        * somehow our gcc is not generating st_size correctly and set 0 for some symbols.
46040 +        * and 0 size will break do_table since it adjust size to (size - id_size)
46041 +        * this is to make sure st_size fall in range.
46042 +        */
46043 +       if (sym->st_size == 0 || sym->st_size > info->sechdrs[sym->st_shndx].sh_size) {
46044 +               sym->st_size = info->sechdrs[sym->st_shndx].sh_size;
46045 +       }
46046 +
46047         if (sym_is(symname, "__mod_pci_device_table"))
46048                 do_table(symval, sym->st_size,
46049                          sizeof(struct pci_device_id), "pci",
46050 --- a/sound/Kconfig
46051 +++ b/sound/Kconfig
46052 @@ -80,6 +80,8 @@ source "sound/parisc/Kconfig"
46053  
46054  source "sound/soc/Kconfig"
46055  
46056 +source "sound/ubicom32/Kconfig"
46057 +
46058  endif # SND
46059  
46060  menuconfig SOUND_PRIME
46061 --- a/sound/Makefile
46062 +++ b/sound/Makefile
46063 @@ -6,7 +6,7 @@ obj-$(CONFIG_SOUND_PRIME) += sound_firmw
46064  obj-$(CONFIG_SOUND_PRIME) += oss/
46065  obj-$(CONFIG_DMASOUND) += oss/
46066  obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
46067 -       sparc/ spi/ parisc/ pcmcia/ mips/ soc/
46068 +       sparc/ spi/ parisc/ pcmcia/ mips/ soc/ ubicom32/
46069  obj-$(CONFIG_SND_AOA) += aoa/
46070  
46071  # This one must be compilable even if sound is configured out
46072 --- /dev/null
46073 +++ b/sound/ubicom32/Kconfig
46074 @@ -0,0 +1,36 @@
46075 +# ALSA Ubicom32 drivers
46076 +
46077 +menuconfig SND_UBI32
46078 +       tristate "Ubicom32 sound devices"
46079 +       select SND_PCM
46080 +       default n
46081 +       help
46082 +         Say Y here to include support for audio on the Ubicom32 platform.
46083 +         To compile this driver as a module, say M here: the module will be
46084 +         called snd_ubi32.
46085 +         
46086 +if SND_UBI32
46087 +
46088 +config SND_UBI32_AUDIO_GENERIC
46089 +       bool "Generic Codec Support"
46090 +       default n
46091 +       help
46092 +         Generic codecs
46093 +
46094 +comment "I2C Based Codecs"
46095 +
46096 +config SND_UBI32_AUDIO_CS4350
46097 +       bool "Cirrus Logic CS4350 DAC"
46098 +       depends on I2C
46099 +       default n
46100 +       help
46101 +         Support for the Cirrus Logic CS4350 DAC.
46102 +
46103 +config SND_UBI32_AUDIO_CS4384
46104 +       bool "Cirrus Logic CS4384 DAC"
46105 +       depends on I2C
46106 +       default n
46107 +       help
46108 +         Support for the Cirrus Logic CS4384 DAC.
46109 +
46110 +endif #SND_UBI32
46111 --- /dev/null
46112 +++ b/sound/ubicom32/Makefile
46113 @@ -0,0 +1,39 @@
46114 +#
46115 +# sound/ubicom32/Makefile
46116 +#      Makefile for ALSA
46117 +#
46118 +# (C) Copyright 2009, Ubicom, Inc.
46119 +#
46120 +# This file is part of the Ubicom32 Linux Kernel Port.
46121 +#
46122 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
46123 +# it and/or modify it under the terms of the GNU General Public License
46124 +# as published by the Free Software Foundation, either version 2 of the
46125 +# License, or (at your option) any later version.
46126 +#
46127 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
46128 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
46129 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46130 +# the GNU General Public License for more details.
46131 +#
46132 +# You should have received a copy of the GNU General Public License
46133 +# along with the Ubicom32 Linux Kernel Port.  If not, 
46134 +# see <http://www.gnu.org/licenses/>.
46135 +#
46136 +# Ubicom32 implementation derived from (with many thanks):
46137 +#   arch/m68knommu
46138 +#   arch/blackfin
46139 +#   arch/parisc
46140 +#
46141 +
46142 +CFLAGS_ubi32.o += -O2
46143 +snd-ubi32-pcm-objs := ubi32-pcm.o
46144 +snd-ubi32-generic-objs := ubi32-generic.o
46145 +snd-ubi32-cs4350-objs := ubi32-cs4350.o
46146 +snd-ubi32-cs4384-objs := ubi32-cs4384.o
46147 +
46148 +# Toplevel Module Dependency
46149 +obj-$(CONFIG_SND_UBI32) += snd-ubi32-pcm.o
46150 +obj-$(CONFIG_SND_UBI32_AUDIO_GENERIC) += snd-ubi32-generic.o
46151 +obj-$(CONFIG_SND_UBI32_AUDIO_CS4350) += snd-ubi32-cs4350.o
46152 +obj-$(CONFIG_SND_UBI32_AUDIO_CS4384) += snd-ubi32-cs4384.o
46153 --- /dev/null
46154 +++ b/sound/ubicom32/ubi32-cs4350.c
46155 @@ -0,0 +1,286 @@
46156 +/*
46157 + * sound/ubicom32/ubi32-cs4350.c
46158 + *     Interface to ubicom32 virtual audio peripheral - using CS4350 DAC
46159 + *
46160 + * (C) Copyright 2009, Ubicom, Inc.
46161 + *
46162 + * This file is part of the Ubicom32 Linux Kernel Port.
46163 + *
46164 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
46165 + * it and/or modify it under the terms of the GNU General Public License
46166 + * as published by the Free Software Foundation, either version 2 of the
46167 + * License, or (at your option) any later version.
46168 + *
46169 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
46170 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
46171 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46172 + * the GNU General Public License for more details.
46173 + *
46174 + * You should have received a copy of the GNU General Public License
46175 + * along with the Ubicom32 Linux Kernel Port.  If not,
46176 + * see <http://www.gnu.org/licenses/>.
46177 + */
46178 +
46179 +#include <linux/i2c.h>
46180 +#include <linux/module.h>
46181 +#include <linux/moduleparam.h>
46182 +#include <sound/core.h>
46183 +#include <sound/pcm.h>
46184 +#include <sound/initval.h>
46185 +#include "ubi32.h"
46186 +
46187 +#define DRIVER_NAME "snd-ubi32-cs4350"
46188 +
46189 +/*
46190 + * Module properties
46191 + */
46192 +static const struct i2c_device_id snd_ubi32_cs4350_id[] = {
46193 +       {"cs4350", 0 },
46194 +       { }
46195 +};
46196 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46197 +
46198 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46199 +
46200 +/*
46201 + * snd_ubi32_cs4350_free
46202 + *     Card private data free function
46203 + */
46204 +void snd_ubi32_cs4350_free(struct snd_card *card)
46205 +{
46206 +       //struct ubi32_snd_priv *ubi32_priv = card->private_data;
46207 +
46208 +       /*
46209 +        * Free all the fields in the snd_ubi32_priv struct
46210 +        */
46211 +       // Nothing to free at this time because ubi32_priv just maintains pointers
46212 +}
46213 +
46214 +/*
46215 + * snd_ubi32_cs4350_dac_init
46216 + */
46217 +static int snd_ubi32_cs4350_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
46218 +{
46219 +       int ret;
46220 +       char send[2];
46221 +       char recv[8];
46222 +
46223 +       /*
46224 +        * Initialize the CS4350 DAC over the I2C interface
46225 +        */
46226 +       snd_printk(KERN_INFO "Initializing CS4350 DAC\n");
46227 +
46228 +       /*
46229 +        * Register 0x01: device/revid
46230 +        */
46231 +       send[0] = 0x01;
46232 +       ret = i2c_master_send(client, send, 1);
46233 +       if (ret != 1) {
46234 +               snd_printk(KERN_ERR "Failed 1st attempt to write to CS4350 register 0x01\n");
46235 +               goto fail;
46236 +       }
46237 +       ret = i2c_master_recv(client, recv, 1);
46238 +       if (ret != 1) {
46239 +               snd_printk(KERN_ERR "Failed initial read of CS4350 registers\n");
46240 +               goto fail;
46241 +       }
46242 +       snd_printk(KERN_INFO "CS4350 DAC Device/Rev: %08x\n", recv[0]);
46243 +
46244 +       /*
46245 +        * Register 0x02: Mode control
46246 +        *      I2S DIF[2:0] = 001, no De-Emphasis, Auto speed mode
46247 +        */
46248 +       send[0] = 0x02;
46249 +       send[1] = 0x10;
46250 +       ret = i2c_master_send(client, send, 2);
46251 +       if (ret != 2) {
46252 +               snd_printk(KERN_ERR "Failed to set CS4350 to I2S mode\n");
46253 +               goto fail;
46254 +       }
46255 +
46256 +       /*
46257 +        * Register 0x05/0x06: Volume control
46258 +        *      Channel A volume set to -16 dB
46259 +        *      Channel B volume set to -16 dB
46260 +        */
46261 +       send[0] = 0x05;
46262 +       send[1] = 0x00;
46263 +       ret = i2c_master_send(client, send, 2);
46264 +       if (ret != 2) {
46265 +               snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46266 +               goto fail;
46267 +       }
46268 +
46269 +       send[0] = 0x06;
46270 +       send[1] = 0x00;
46271 +       ret = i2c_master_send(client, send, 2);
46272 +       if (ret != 2) {
46273 +               snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46274 +               goto fail;
46275 +       }
46276 +
46277 +       /*
46278 +        * Make sure the changes took place, this helps verify we are talking to
46279 +        * the correct chip.
46280 +        */
46281 +       send[0] = 0x81;
46282 +       ret = i2c_master_send(client, send, 1);
46283 +       if (ret != 1) {
46284 +               snd_printk(KERN_ERR "Failed to initiate readback\n");
46285 +               goto fail;
46286 +       }
46287 +
46288 +       ret = i2c_master_recv(client, recv, 8);
46289 +       if (ret != 8) {
46290 +               snd_printk(KERN_ERR "Failed second read of CS4350 registers\n");
46291 +               goto fail;
46292 +       }
46293 +
46294 +       if ((recv[1] != 0x10) || (recv[4] != 0x00) || (recv[5] != 0x00)) {
46295 +               snd_printk(KERN_ERR "Failed to initialize CS4350 DAC\n");
46296 +               goto fail;
46297 +       }
46298 +                      
46299 +       snd_printk(KERN_INFO "CS4350 DAC Initialized\n");
46300 +       return 0;
46301 +
46302 +fail:
46303 +       return -ENODEV;
46304 +}
46305 +
46306 +/*
46307 + * snd_ubi32_cs4350_i2c_probe
46308 + */
46309 +static int snd_ubi32_cs4350_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
46310 +{
46311 +       struct snd_card *card;
46312 +       struct ubi32_snd_priv *ubi32_priv;
46313 +       int err, ret;
46314 +       struct platform_device *pdev;
46315 +
46316 +       pdev = client->dev.platform_data;
46317 +       if (!pdev) {
46318 +               return -ENODEV;
46319 +       }
46320 +
46321 +       /*
46322 +        * Initialize the CS4350 DAC
46323 +        */
46324 +       ret = snd_ubi32_cs4350_dac_init(client, id);
46325 +       if (ret < 0) {
46326 +               /*
46327 +                * Initialization failed.  Propagate the error.
46328 +                */
46329 +               return ret;
46330 +       }
46331 +
46332 +       /*
46333 +        * Create a snd_card structure
46334 +        */
46335 +       card = snd_card_new(index, "Ubi32-CS4350", THIS_MODULE, sizeof(struct ubi32_snd_priv));
46336 +       if (card == NULL) {
46337 +               return -ENOMEM;
46338 +       }
46339 +
46340 +       card->private_free = snd_ubi32_cs4350_free; /* Not sure if correct */
46341 +       ubi32_priv = card->private_data;
46342 +
46343 +       /*
46344 +        * CS4350 DAC has a minimum sample rate of 30khz and an
46345 +        * upper limit of 216khz for it's auto-detect.
46346 +        */
46347 +       ubi32_priv->min_sample_rate = 30000;
46348 +       ubi32_priv->max_sample_rate = 216000;
46349 +
46350 +       /*
46351 +        * Initialize the snd_card's private data structure
46352 +        */
46353 +       ubi32_priv->card = card;
46354 +
46355 +       /*
46356 +        * Create the new PCM instance
46357 +        */
46358 +       err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
46359 +       if (err < 0) {
46360 +               snd_card_free(card);
46361 +               return err; /* What is err?  Need to include correct file */
46362 +       }
46363 +
46364 +       strcpy(card->driver, "Ubi32-CS4350");
46365 +       strcpy(card->shortname, "Ubi32-CS4350");
46366 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
46367 +
46368 +       snd_card_set_dev(card, &client->dev);
46369 +
46370 +       /*
46371 +        * Register the sound card 
46372 +        */
46373 +       if ((err = snd_card_register(card)) != 0) {
46374 +               snd_printk(KERN_INFO "snd_card_register error\n");
46375 +       }
46376 +
46377 +       /* 
46378 +        * Store card for access from other methods 
46379 +        */
46380 +       i2c_set_clientdata(client, card);
46381 +
46382 +       return 0;
46383 +}
46384 +
46385 +/*
46386 + * snd_ubi32_cs4350_i2c_remove
46387 + */
46388 +static int __devexit snd_ubi32_cs4350_i2c_remove(struct i2c_client *client)
46389 +{
46390 +       struct snd_card *card;
46391 +       struct ubi32_snd_priv *ubi32_priv;
46392 +
46393 +       card = i2c_get_clientdata(client);
46394 +
46395 +       ubi32_priv = card->private_data;
46396 +       snd_ubi32_pcm_remove(ubi32_priv);
46397 +
46398 +       snd_card_free(i2c_get_clientdata(client));
46399 +       i2c_set_clientdata(client, NULL);
46400 +
46401 +       return 0;
46402 +}
46403 +
46404 +/*
46405 + * I2C driver description
46406 + */
46407 +static struct i2c_driver snd_ubi32_cs4350_driver = {
46408 +       .driver = {
46409 +               .name = DRIVER_NAME,
46410 +               .owner = THIS_MODULE,
46411 +       },
46412 +       .id_table       = snd_ubi32_cs4350_id,
46413 +       .probe          = snd_ubi32_cs4350_i2c_probe,
46414 +       .remove         = __devexit_p(snd_ubi32_cs4350_i2c_remove),
46415 +};
46416 +
46417 +/*
46418 + * Driver init
46419 + */
46420 +static int __init snd_ubi32_cs4350_init(void)
46421 +{
46422 +       return i2c_add_driver(&snd_ubi32_cs4350_driver);
46423 +}
46424 +module_init(snd_ubi32_cs4350_init);
46425 +
46426 +/*
46427 + * snd_ubi32_cs4350_exit
46428 + */
46429 +static void __exit snd_ubi32_cs4350_exit(void)
46430 +{
46431 +       i2c_del_driver(&snd_ubi32_cs4350_driver);
46432 +}
46433 +module_exit(snd_ubi32_cs4350_exit);
46434 +
46435 +/*
46436 + * Module properties
46437 + */
46438 +MODULE_ALIAS("i2c:" DRIVER_NAME);
46439 +MODULE_AUTHOR("Patrick Tjin");
46440 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4350");
46441 +MODULE_LICENSE("GPL");
46442 --- /dev/null
46443 +++ b/sound/ubicom32/ubi32-cs4384.c
46444 @@ -0,0 +1,982 @@
46445 +/*
46446 + * sound/ubicom32/ubi32-cs4384.c
46447 + *     Interface to ubicom32 virtual audio peripheral - using CS4384 DAC
46448 + *
46449 + * (C) Copyright 2009, Ubicom, Inc.
46450 + *
46451 + * This file is part of the Ubicom32 Linux Kernel Port.
46452 + *
46453 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
46454 + * it and/or modify it under the terms of the GNU General Public License
46455 + * as published by the Free Software Foundation, either version 2 of the
46456 + * License, or (at your option) any later version.
46457 + *
46458 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
46459 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
46460 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46461 + * the GNU General Public License for more details.
46462 + *
46463 + * You should have received a copy of the GNU General Public License
46464 + * along with the Ubicom32 Linux Kernel Port.  If not,
46465 + * see <http://www.gnu.org/licenses/>.
46466 + */
46467 +
46468 +#include <linux/i2c.h>
46469 +#include <linux/module.h>
46470 +#include <linux/moduleparam.h>
46471 +#include <linux/delay.h>
46472 +#include <sound/core.h>
46473 +#include <sound/tlv.h>
46474 +#include <sound/control.h>
46475 +#include <sound/pcm.h>
46476 +#include <sound/initval.h>
46477 +#include <asm/ip5000.h>
46478 +#include <asm/gpio.h>
46479 +#include <asm/audio_tio.h>
46480 +#include <asm/ubi32-cs4384.h>
46481 +#include "ubi32.h"
46482 +
46483 +#define DRIVER_NAME "snd-ubi32-cs4384"
46484 +
46485 +/*
46486 + * Module properties
46487 + */
46488 +static const struct i2c_device_id snd_ubi32_cs4384_id[] = {
46489 +       {"cs4384", 0 },
46490 +       { }
46491 +};
46492 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46493 +
46494 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46495 +
46496 +/*
46497 + * Mixer properties
46498 + */
46499 +enum {
46500 +       /*
46501 +        * Be careful of changing the order of these IDs, they
46502 +        * are used to index the volume array.
46503 +        */
46504 +       SND_UBI32_CS4384_FRONT_ID,
46505 +       SND_UBI32_CS4384_SURROUND_ID,
46506 +       SND_UBI32_CS4384_CENTER_ID,
46507 +       SND_UBI32_CS4384_LFE_ID,
46508 +       SND_UBI32_CS4384_REAR_ID,
46509 +
46510 +       /*
46511 +        * This should be the last ID
46512 +        */
46513 +       SND_UBI32_CS4384_LAST_ID,
46514 +};
46515 +static const u8_t snd_ubi32_cs4384_ch_ofs[] = {0, 2, 4, 5, 6};
46516 +
46517 +static const DECLARE_TLV_DB_SCALE(snd_ubi32_cs4384_db, -12750, 50, 0);
46518 +
46519 +#define snd_ubi32_cs4384_info_mute     snd_ctl_boolean_stereo_info
46520 +#define snd_ubi32_cs4384_info_mute_mono        snd_ctl_boolean_mono_info
46521 +
46522 +/*
46523 + * Mixer controls
46524 + */
46525 +static int snd_ubi32_cs4384_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
46526 +static int snd_ubi32_cs4384_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46527 +static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46528 +static int snd_ubi32_cs4384_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46529 +static int snd_ubi32_cs4384_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46530 +
46531 +/*
46532 + * Make sure to update these if the structure below is changed
46533 + */
46534 +#define SND_UBI32_MUTE_CTL_START       5
46535 +#define SND_UBI32_MUTE_CTL_END         9
46536 +static struct snd_kcontrol_new snd_ubi32_cs4384_controls[] __devinitdata = {
46537 +       {
46538 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46539 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46540 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46541 +               .name = "Front Playback Volume",
46542 +               .info = snd_ubi32_cs4384_info_volume,
46543 +               .get = snd_ubi32_cs4384_get_volume,
46544 +               .put = snd_ubi32_cs4384_put_volume,
46545 +               .private_value = SND_UBI32_CS4384_FRONT_ID,
46546 +               .tlv = {
46547 +                       .p = snd_ubi32_cs4384_db,
46548 +               },
46549 +       },
46550 +       {
46551 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46552 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46553 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46554 +               .name = "Surround Playback Volume",
46555 +               .info = snd_ubi32_cs4384_info_volume,
46556 +               .get = snd_ubi32_cs4384_get_volume,
46557 +               .put = snd_ubi32_cs4384_put_volume,
46558 +               .private_value = SND_UBI32_CS4384_SURROUND_ID,
46559 +               .tlv = {
46560 +                       .p = snd_ubi32_cs4384_db,
46561 +               },
46562 +       },
46563 +       {
46564 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46565 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46566 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46567 +               .name = "Center Playback Volume",
46568 +               .info = snd_ubi32_cs4384_info_volume,
46569 +               .get = snd_ubi32_cs4384_get_volume,
46570 +               .put = snd_ubi32_cs4384_put_volume,
46571 +               .private_value = SND_UBI32_CS4384_CENTER_ID,
46572 +               .tlv = {
46573 +                       .p = snd_ubi32_cs4384_db,
46574 +               },
46575 +       },
46576 +       {
46577 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46578 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46579 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46580 +               .name = "LFE Playback Volume",
46581 +               .info = snd_ubi32_cs4384_info_volume,
46582 +               .get = snd_ubi32_cs4384_get_volume,
46583 +               .put = snd_ubi32_cs4384_put_volume,
46584 +               .private_value = SND_UBI32_CS4384_LFE_ID,
46585 +               .tlv = {
46586 +                       .p = snd_ubi32_cs4384_db,
46587 +               },
46588 +       },
46589 +       {
46590 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46591 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46592 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46593 +               .name = "Rear Playback Volume",
46594 +               .info = snd_ubi32_cs4384_info_volume,
46595 +               .get = snd_ubi32_cs4384_get_volume,
46596 +               .put = snd_ubi32_cs4384_put_volume,
46597 +               .private_value = SND_UBI32_CS4384_REAR_ID,
46598 +               .tlv = {
46599 +                       .p = snd_ubi32_cs4384_db,
46600 +               },
46601 +       },
46602 +       {
46603 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46604 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46605 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46606 +               .name = "Front Playback Switch",
46607 +               .info = snd_ubi32_cs4384_info_mute,
46608 +               .get = snd_ubi32_cs4384_get_mute,
46609 +               .put = snd_ubi32_cs4384_put_mute,
46610 +               .private_value = SND_UBI32_CS4384_FRONT_ID,
46611 +       },
46612 +       {
46613 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46614 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46615 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46616 +               .name = "Surround Playback Switch",
46617 +               .info = snd_ubi32_cs4384_info_mute,
46618 +               .get = snd_ubi32_cs4384_get_mute,
46619 +               .put = snd_ubi32_cs4384_put_mute,
46620 +               .private_value = SND_UBI32_CS4384_SURROUND_ID,
46621 +       },
46622 +       {
46623 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46624 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46625 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46626 +               .name = "Center Playback Switch",
46627 +               .info = snd_ubi32_cs4384_info_mute_mono,
46628 +               .get = snd_ubi32_cs4384_get_mute,
46629 +               .put = snd_ubi32_cs4384_put_mute,
46630 +               .private_value = SND_UBI32_CS4384_CENTER_ID,
46631 +       },
46632 +       {
46633 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46634 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46635 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46636 +               .name = "LFE Playback Switch",
46637 +               .info = snd_ubi32_cs4384_info_mute_mono,
46638 +               .get = snd_ubi32_cs4384_get_mute,
46639 +               .put = snd_ubi32_cs4384_put_mute,
46640 +               .private_value = SND_UBI32_CS4384_LFE_ID,
46641 +       },
46642 +       {
46643 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46644 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46645 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46646 +               .name = "Rear Playback Switch",
46647 +               .info = snd_ubi32_cs4384_info_mute,
46648 +               .get = snd_ubi32_cs4384_get_mute,
46649 +               .put = snd_ubi32_cs4384_put_mute,
46650 +               .private_value = SND_UBI32_CS4384_REAR_ID,
46651 +       },
46652 +};
46653 +
46654 +/*
46655 + * Our private data
46656 + */
46657 +struct snd_ubi32_cs4384_priv {
46658 +       /*
46659 +        * Array of current volumes
46660 +        *      (L, R, SL, SR, C, LFE, RL, RR)
46661 +        */
46662 +       uint8_t volume[8];
46663 +
46664 +       /*
46665 +        * Bitmask of mutes
46666 +        *      MSB (RR, RL, LFE, C, SR, SL, R, L) LSB
46667 +        */
46668 +       uint8_t mute;
46669 +
46670 +       /*
46671 +        * Array of controls
46672 +        */
46673 +       struct snd_kcontrol *kctls[ARRAY_SIZE(snd_ubi32_cs4384_controls)];
46674 +
46675 +       /*
46676 +        * Lock to protect our card
46677 +        */
46678 +       spinlock_t lock;
46679 +};
46680 +
46681 +/*
46682 + * snd_ubi32_cs4384_info_volume
46683 + */
46684 +static int snd_ubi32_cs4384_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
46685 +{
46686 +       unsigned int id = (unsigned int)kcontrol->private_value;
46687 +
46688 +       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
46689 +       uinfo->count = 1;
46690 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
46691 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
46692 +               uinfo->count = 2;
46693 +       }
46694 +       uinfo->value.integer.min = 0;
46695 +       uinfo->value.integer.max = 255;
46696 +       return 0;
46697 +}
46698 +
46699 +/*
46700 + * snd_ubi32_cs4384_get_volume
46701 + */
46702 +static int snd_ubi32_cs4384_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46703 +{
46704 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46705 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46706 +       unsigned int id = (unsigned int)kcontrol->private_value;
46707 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46708 +       unsigned long flags;
46709 +
46710 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46711 +               return -EINVAL;
46712 +       }
46713 +
46714 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46715 +
46716 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46717 +
46718 +       ucontrol->value.integer.value[0] = cs4384_priv->volume[ch];
46719 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
46720 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
46721 +               ch++;
46722 +               ucontrol->value.integer.value[1] = cs4384_priv->volume[ch];
46723 +       }
46724 +
46725 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46726 +
46727 +       return 0;
46728 +}
46729 +
46730 +/*
46731 + * snd_ubi32_cs4384_put_volume
46732 + */
46733 +static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46734 +{
46735 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46736 +       struct i2c_client *client = (struct i2c_client *)priv->client;
46737 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46738 +       unsigned int id = (unsigned int)kcontrol->private_value;
46739 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46740 +       unsigned long flags;
46741 +       unsigned char send[3];
46742 +       int nch;
46743 +       int ret = -EINVAL;
46744 +
46745 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46746 +               return -EINVAL;
46747 +       }
46748 +
46749 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46750 +
46751 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46752 +
46753 +       send[0] = 0;
46754 +       switch (id) {
46755 +       case SND_UBI32_CS4384_REAR_ID:
46756 +               send[0] = 0x06;
46757 +
46758 +               /*
46759 +                * Fall through
46760 +                */
46761 +
46762 +       case SND_UBI32_CS4384_SURROUND_ID:
46763 +               send[0] += 0x03;
46764 +
46765 +               /*
46766 +                * Fall through
46767 +                */
46768 +
46769 +       case SND_UBI32_CS4384_FRONT_ID:
46770 +               send[0] += 0x8B;
46771 +               nch = 2;
46772 +               send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF);
46773 +               send[2] = 255 - (ucontrol->value.integer.value[1] & 0xFF);
46774 +               cs4384_priv->volume[ch++] = send[1];
46775 +               cs4384_priv->volume[ch] = send[2];
46776 +               break;
46777 +
46778 +       case SND_UBI32_CS4384_LFE_ID:
46779 +               send[0] = 0x81;
46780 +
46781 +               /*
46782 +                * Fall through
46783 +                */
46784 +
46785 +       case SND_UBI32_CS4384_CENTER_ID:
46786 +               send[0] += 0x11;
46787 +               nch = 1;
46788 +               send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF);
46789 +               cs4384_priv->volume[ch] = send[1];
46790 +               break;
46791 +
46792 +       default:
46793 +               spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46794 +               goto done;
46795 +
46796 +       }
46797 +
46798 +       /*
46799 +        * Send the volume to the chip
46800 +        */
46801 +       nch++;
46802 +       ret = i2c_master_send(client, send, nch);
46803 +       if (ret != nch) {
46804 +               snd_printk(KERN_ERR "Failed to set volume on CS4384\n");
46805 +       }
46806 +
46807 +done:
46808 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46809 +
46810 +       return ret;
46811 +}
46812 +
46813 +/*
46814 + * snd_ubi32_cs4384_get_mute
46815 + */
46816 +static int snd_ubi32_cs4384_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46817 +{
46818 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46819 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46820 +       unsigned int id = (unsigned int)kcontrol->private_value;
46821 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46822 +       unsigned long flags;
46823 +
46824 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46825 +               return -EINVAL;
46826 +       }
46827 +
46828 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46829 +
46830 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46831 +
46832 +       ucontrol->value.integer.value[0] = !(cs4384_priv->mute & (1 << ch));
46833 +
46834 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
46835 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
46836 +               ch++;
46837 +               ucontrol->value.integer.value[1] = !(cs4384_priv->mute & (1 << ch));
46838 +       }
46839 +
46840 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46841 +
46842 +       return 0;
46843 +}
46844 +
46845 +/*
46846 + * snd_ubi32_cs4384_put_mute
46847 + */
46848 +static int snd_ubi32_cs4384_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46849 +{
46850 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46851 +       struct i2c_client *client = (struct i2c_client *)priv->client;
46852 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46853 +       unsigned int id = (unsigned int)kcontrol->private_value;
46854 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46855 +       unsigned long flags;
46856 +       unsigned char send[2];
46857 +       int ret = -EINVAL;
46858 +
46859 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46860 +               return -EINVAL;
46861 +       }
46862 +
46863 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46864 +
46865 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46866 +
46867 +       if (ucontrol->value.integer.value[0]) {
46868 +               cs4384_priv->mute &= ~(1 << ch);
46869 +       } else {
46870 +               cs4384_priv->mute |= (1 << ch);
46871 +       }
46872 +
46873 +       if ((id != SND_UBI32_CS4384_LFE_ID) && (id != SND_UBI32_CS4384_CENTER_ID)) {
46874 +               ch++;
46875 +               if (ucontrol->value.integer.value[1]) {
46876 +                       cs4384_priv->mute &= ~(1 << ch);
46877 +               } else {
46878 +                       cs4384_priv->mute |= (1 << ch);
46879 +               }
46880 +       }
46881 +
46882 +       /*
46883 +        * Update the chip's mute reigster
46884 +        */
46885 +       send[0] = 0x09;
46886 +       send[1] = cs4384_priv->mute;
46887 +       ret = i2c_master_send(client, send, 2);
46888 +       if (ret != 2) {
46889 +               snd_printk(KERN_ERR "Failed to set mute on CS4384\n");
46890 +       }
46891 +
46892 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46893 +
46894 +       return ret;
46895 +}
46896 +
46897 +/*
46898 + * snd_ubi32_cs4384_mixer
46899 + *     Setup the mixer controls
46900 + */
46901 +static int __devinit snd_ubi32_cs4384_mixer(struct ubi32_snd_priv *priv)
46902 +{
46903 +       struct snd_card *card = priv->card;
46904 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46905 +       int i;
46906 +       
46907 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46908 +       for (i = 0; i < ARRAY_SIZE(snd_ubi32_cs4384_controls); i++) {
46909 +               int err;
46910 +
46911 +               cs4384_priv->kctls[i] = snd_ctl_new1(&snd_ubi32_cs4384_controls[i], priv);
46912 +               err = snd_ctl_add(card, cs4384_priv->kctls[i]);
46913 +               if (err) {
46914 +                       snd_printk(KERN_WARNING "Failed to add control %d\n", i);
46915 +                       return err;
46916 +               }
46917 +       }
46918 +       return 0;
46919 +}
46920 +
46921 +/*
46922 + * snd_ubi32_cs4384_free
46923 + *     Card private data free function
46924 + */
46925 +void snd_ubi32_cs4384_free(struct snd_card *card)
46926 +{
46927 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46928 +       struct ubi32_snd_priv *ubi32_priv;
46929 +       
46930 +       ubi32_priv = card->private_data;
46931 +       cs4384_priv = snd_ubi32_priv_get_drv(ubi32_priv);
46932 +       if (cs4384_priv) {
46933 +               kfree(cs4384_priv);
46934 +       }
46935 +}
46936 +
46937 +/*
46938 + * snd_ubi32_cs4384_setup_mclk
46939 + */
46940 +static int snd_ubi32_cs4384_setup_mclk(struct ubi32_cs4384_platform_data *pdata)
46941 +{
46942 +       struct ubicom32_io_port *ioa = (struct ubicom32_io_port *)RA;
46943 +       struct ubicom32_io_port *ioc = (struct ubicom32_io_port *)RC;
46944 +       struct ubicom32_io_port *ioh = (struct ubicom32_io_port *)RH;
46945 +       unsigned int ctl0;
46946 +       unsigned int ctlx;
46947 +       unsigned int div;
46948 +
46949 +       div = pdata->mclk_entries[0].div;
46950 +
46951 +       ctl0 = (1 << 13);
46952 +       ctlx = ((div - 1) << 16) | (div / 2);
46953 +
46954 +       switch (pdata->mclk_src) {
46955 +       case UBI32_CS4384_MCLK_PWM_0:
46956 +               ioc->function |= 2;
46957 +               ioc->ctl0 |= ctl0;
46958 +               ioc->ctl1 = ctlx;
46959 +               return 0;
46960 +
46961 +       case UBI32_CS4384_MCLK_PWM_1:
46962 +               ioc->function |= 2;
46963 +               ioc->ctl0 |= ctl0 << 16;
46964 +               ioc->ctl2 = ctlx;
46965 +               return 0;
46966 +
46967 +       case UBI32_CS4384_MCLK_PWM_2:
46968 +               ioh->ctl0 |= ctl0;
46969 +               ioh->ctl1 = ctlx;
46970 +               return 0;
46971 +
46972 +       case UBI32_CS4384_MCLK_CLKDIV_1:
46973 +               ioa->gpio_mask &= (1 << 7);
46974 +               ioa->ctl1 &= ~(0x7F << 14);
46975 +               ioa->ctl1 |= ((div - 1) << 14);
46976 +               return 0;
46977 +
46978 +       case UBI32_CS4384_MCLK_OTHER:
46979 +               return 0;
46980 +       }
46981 +
46982 +       return 1;
46983 +}
46984 +
46985 +/*
46986 + * snd_ubi32_cs4384_set_rate
46987 + */
46988 +static int snd_ubi32_cs4384_set_rate(struct ubi32_snd_priv *priv, int rate)
46989 +{
46990 +       struct ubi32_cs4384_platform_data *cpd = priv->pdata->priv_data;
46991 +       struct ubicom32_io_port *ioa = (struct ubicom32_io_port *)RA;
46992 +       struct ubicom32_io_port *ioc = (struct ubicom32_io_port *)RC;
46993 +       struct ubicom32_io_port *ioh = (struct ubicom32_io_port *)RH;
46994 +       unsigned int ctl;
46995 +       unsigned int div = 0;
46996 +       const u16_t mult[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024};
46997 +       int i;
46998 +       int j;
46999 +       
47000 +
47001 +       for (i = 0; i < sizeof(mult) / sizeof(u16_t); i++) {
47002 +               for (j = 0; j < cpd->n_mclk; j++) {
47003 +                       if (((unsigned int)rate * (unsigned int)mult[i]) == 
47004 +                            cpd->mclk_entries[j].rate) {
47005 +                               div = cpd->mclk_entries[j].div;
47006 +                               break;
47007 +                       }
47008 +               }
47009 +       }
47010 +
47011 +       ctl = ((div - 1) << 16) | (div / 2);
47012 +
47013 +       switch (cpd->mclk_src) {
47014 +       case UBI32_CS4384_MCLK_PWM_0:
47015 +               ioc->ctl1 = ctl;
47016 +               return 0;
47017 +
47018 +       case UBI32_CS4384_MCLK_PWM_1:
47019 +               ioc->ctl2 = ctl;
47020 +               return 0;
47021 +
47022 +       case UBI32_CS4384_MCLK_PWM_2:
47023 +               ioh->ctl1 = ctl;
47024 +               return 0;
47025 +
47026 +       case UBI32_CS4384_MCLK_CLKDIV_1:
47027 +               ioa->ctl1 &= ~(0x7F << 14);
47028 +               ioa->ctl1 |= ((div - 1) << 14);
47029 +               return 0;
47030 +
47031 +       case UBI32_CS4384_MCLK_OTHER:
47032 +               return 0;
47033 +       }
47034 +
47035 +       return 1;
47036 +}
47037 +
47038 +/*
47039 + * snd_ubi32_cs4384_set_channels
47040 + *     Mute unused channels
47041 + */
47042 +static int snd_ubi32_cs4384_set_channels(struct ubi32_snd_priv *priv, int channels)
47043 +{
47044 +       struct i2c_client *client = (struct i2c_client *)priv->client;
47045 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47046 +       unsigned char send[2];
47047 +       int ret;
47048 +       int i;
47049 +       unsigned long flags;
47050 +
47051 +       /*
47052 +        * Only support 0, 2, 4, 6, 8 channels
47053 +        */
47054 +       if ((channels > 8) || (channels & 1)) {
47055 +               return -EINVAL;
47056 +       }
47057 +
47058 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
47059 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
47060 +
47061 +       /*
47062 +        * Address 09h, Mute control
47063 +        */
47064 +       send[0] = 0x09;
47065 +       send[1] = (unsigned char)(0xFF << channels);
47066 +
47067 +       ret = i2c_master_send(client, send, 2);
47068 +
47069 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47070 +
47071 +       /*
47072 +        * Notify the system that we changed the mutes
47073 +        */
47074 +       cs4384_priv->mute = (unsigned char)(0xFF << channels);
47075 +
47076 +       for (i = SND_UBI32_MUTE_CTL_START; i < SND_UBI32_MUTE_CTL_END; i++) {
47077 +               snd_ctl_notify(priv->card, SNDRV_CTL_EVENT_MASK_VALUE,
47078 +                              &cs4384_priv->kctls[i]->id);
47079 +       }
47080 +
47081 +       if (ret != 2) {
47082 +               return -ENXIO;
47083 +       }
47084 +
47085 +       return 0;
47086 +}
47087 +
47088 +/*
47089 + * snd_ubi32_cs4384_dac_init
47090 + */
47091 +static int snd_ubi32_cs4384_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
47092 +{
47093 +       int ret;
47094 +       unsigned char send[2];
47095 +       unsigned char recv[2];
47096 +
47097 +       /*
47098 +        * Initialize the CS4384 DAC over the I2C interface
47099 +        */
47100 +       snd_printk(KERN_INFO "Initializing CS4384 DAC\n");
47101 +
47102 +       /*
47103 +        * Register 0x01: device/revid
47104 +        */
47105 +       send[0] = 0x01;
47106 +       ret = i2c_master_send(client, send, 1);
47107 +       if (ret != 1) {
47108 +               snd_printk(KERN_ERR "Failed 1st attempt to write to CS4384 register 0x01\n");
47109 +               goto fail;
47110 +       }
47111 +       ret = i2c_master_recv(client, recv, 1);
47112 +       if (ret != 1) {
47113 +               snd_printk(KERN_ERR "Failed initial read of CS4384 registers\n");
47114 +               goto fail;
47115 +       }
47116 +       snd_printk(KERN_INFO "CS4384 DAC Device/Rev: %08x\n", recv[0]);
47117 +
47118 +       /*
47119 +        * Register 0x02: Mode Control 1
47120 +        *      Control Port Enable, PCM, All DACs enabled, Power Down
47121 +        */
47122 +       send[0] = 0x02;
47123 +       send[1] = 0x81;
47124 +       ret = i2c_master_send(client, send, 2);
47125 +       if (ret != 2) {
47126 +               snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47127 +               goto fail;
47128 +       }
47129 +
47130 +       /*
47131 +        * Register 0x08: Ramp and Mute
47132 +        *      RMP_UP, RMP_DN, PAMUTE, DAMUTE
47133 +        */
47134 +       send[0] = 0x08;
47135 +       send[1] = 0xBC;
47136 +       ret = i2c_master_send(client, send, 2);
47137 +       if (ret != 2) {
47138 +               snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47139 +               goto fail;
47140 +       }
47141 +
47142 +       /*
47143 +        * Register 0x03: PCM Control
47144 +        *      I2S DIF[3:0] = 0001, no De-Emphasis, Auto speed mode
47145 +        */
47146 +       send[0] = 0x03;
47147 +       send[1] = 0x13;
47148 +       ret = i2c_master_send(client, send, 2);
47149 +       if (ret != 2) {
47150 +               snd_printk(KERN_ERR "Failed to set CS4384 to I2S mode\n");
47151 +               goto fail;
47152 +       }
47153 +
47154 +       /*
47155 +        * Register 0x0B/0x0C: Volume control A1/B1
47156 +        * Register 0x0E/0x0F: Volume control A2/B2
47157 +        * Register 0x11/0x12: Volume control A3/B3
47158 +        * Register 0x14/0x15: Volume control A4/B4
47159 +        */
47160 +       send[0] = 0x80 | 0x0B;
47161 +       send[1] = 0x00;
47162 +       send[2] = 0x00;
47163 +       ret = i2c_master_send(client, send, 3);
47164 +       if (ret != 3) {
47165 +               snd_printk(KERN_ERR "Failed to set ch1 volume on CS4384\n");
47166 +               goto fail;
47167 +       }
47168 +
47169 +       send[0] = 0x80 | 0x0E;
47170 +       send[1] = 0x00;
47171 +       send[2] = 0x00;
47172 +       ret = i2c_master_send(client, send, 3);
47173 +       if (ret != 3) {
47174 +               snd_printk(KERN_ERR "Failed to set ch2 volume on CS4384\n");
47175 +               goto fail;
47176 +       }
47177 +
47178 +       send[0] = 0x80 | 0x11;
47179 +       send[1] = 0x00;
47180 +       send[2] = 0x00;
47181 +       ret = i2c_master_send(client, send, 3);
47182 +       if (ret != 3) {
47183 +               snd_printk(KERN_ERR "Failed to set ch3 volume on CS4384\n");
47184 +               goto fail;
47185 +       }
47186 +
47187 +       send[0] = 0x80 | 0x14;
47188 +       send[1] = 0x00;
47189 +       send[2] = 0x00;
47190 +       ret = i2c_master_send(client, send, 3);
47191 +       if (ret != 3) {
47192 +               snd_printk(KERN_ERR "Failed to set ch4 volume on CS4384\n");
47193 +               goto fail;
47194 +       }
47195 +
47196 +       /*
47197 +        * Register 09h: Mute control
47198 +        *      Mute all (we will unmute channels as needed)
47199 +        */
47200 +       send[0] = 0x09;
47201 +       send[1] = 0xFF;
47202 +       ret = i2c_master_send(client, send, 2);
47203 +       if (ret != 2) {
47204 +               snd_printk(KERN_ERR "Failed to power up CS4384\n");
47205 +               goto fail;
47206 +       }
47207 +
47208 +       /*
47209 +        * Register 0x02: Mode Control 1
47210 +        *      Control Port Enable, PCM, All DACs enabled, Power Up
47211 +        */
47212 +       send[0] = 0x02;
47213 +       send[1] = 0x80;
47214 +       ret = i2c_master_send(client, send, 2);
47215 +       if (ret != 2) {
47216 +               snd_printk(KERN_ERR "Failed to power up CS4384\n");
47217 +               goto fail;
47218 +       }
47219 +
47220 +       /*
47221 +        * Make sure the changes took place, this helps verify we are talking to
47222 +        * the correct chip.
47223 +        */
47224 +       send[0] = 0x80 | 0x03;
47225 +       ret = i2c_master_send(client, send, 1);
47226 +       if (ret != 1) {
47227 +               snd_printk(KERN_ERR "Failed to initiate readback\n");
47228 +               goto fail;
47229 +       }
47230 +
47231 +       ret = i2c_master_recv(client, recv, 1);
47232 +       if (ret != 1) {
47233 +               snd_printk(KERN_ERR "Failed second read of CS4384 registers\n");
47234 +               goto fail;
47235 +       }
47236 +
47237 +       if (recv[0] != 0x13) {
47238 +               snd_printk(KERN_ERR "Failed to initialize CS4384 DAC\n");
47239 +               goto fail;
47240 +       }
47241 +                      
47242 +       snd_printk(KERN_INFO "CS4384 DAC Initialized\n");
47243 +       return 0;
47244 +
47245 +fail:
47246 +       return -ENODEV;
47247 +}
47248 +
47249 +/*
47250 + * snd_ubi32_cs4384_i2c_probe
47251 + */
47252 +static int snd_ubi32_cs4384_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
47253 +{
47254 +       struct snd_card *card;
47255 +       struct ubi32_snd_priv *ubi32_priv;
47256 +       int err, ret;
47257 +       struct platform_device *pdev;
47258 +       struct ubi32_cs4384_platform_data *pdata;
47259 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47260 +
47261 +       /*
47262 +        * pdev is audio_tio
47263 +        */
47264 +       pdev = client->dev.platform_data;
47265 +       if (!pdev) {
47266 +               return -ENODEV;
47267 +       }
47268 +
47269 +       /*
47270 +        * pdev->dev.platform_data is ubi32-pcm platform_data
47271 +        */
47272 +       pdata = audio_tio_priv(pdev);
47273 +       if (!pdata) {
47274 +               return -ENODEV;
47275 +       }
47276 +
47277 +       /*
47278 +        * Initialize the CS4384 DAC
47279 +        */
47280 +       ret = snd_ubi32_cs4384_dac_init(client, id);
47281 +       if (ret < 0) {
47282 +               /*
47283 +                * Initialization failed.  Propagate the error.
47284 +                */
47285 +               return ret;
47286 +       }
47287 +
47288 +       if (snd_ubi32_cs4384_setup_mclk(pdata)) {
47289 +               return -EINVAL;
47290 +       }
47291 +
47292 +       /*
47293 +        * Create a snd_card structure
47294 +        */
47295 +       card = snd_card_new(index, "Ubi32-CS4384", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47296 +       if (card == NULL) {
47297 +               return -ENOMEM;
47298 +       }
47299 +
47300 +       card->private_free = snd_ubi32_cs4384_free;
47301 +       ubi32_priv = card->private_data;
47302 +
47303 +       /*
47304 +        * Initialize the snd_card's private data structure
47305 +        */
47306 +       ubi32_priv->card = card;
47307 +       ubi32_priv->client = client;
47308 +       ubi32_priv->set_channels = snd_ubi32_cs4384_set_channels;
47309 +       ubi32_priv->set_rate = snd_ubi32_cs4384_set_rate;
47310 +
47311 +       /*
47312 +        * CS4384 DAC has a minimum sample rate of 4khz and an
47313 +        * upper limit of 216khz for it's auto-detect.
47314 +        */
47315 +       ubi32_priv->min_sample_rate = 4000;
47316 +       ubi32_priv->max_sample_rate = 216000;
47317 +
47318 +       /*
47319 +        * Create our private data (to manage volume, etc)
47320 +        */
47321 +       cs4384_priv = kzalloc(sizeof(struct snd_ubi32_cs4384_priv), GFP_KERNEL);
47322 +       if (!cs4384_priv) {
47323 +               snd_card_free(card);
47324 +               return -ENOMEM;
47325 +       }
47326 +       snd_ubi32_priv_set_drv(ubi32_priv, cs4384_priv);
47327 +       spin_lock_init(&cs4384_priv->lock);
47328 +
47329 +       /*
47330 +        * We start off all muted and max volume
47331 +        */
47332 +       cs4384_priv->mute = 0xFF;
47333 +       memset(cs4384_priv->volume, 0xFF, 8);
47334 +
47335 +       /*
47336 +        * Create the new PCM instance
47337 +        */
47338 +       err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
47339 +       if (err < 0) {
47340 +               snd_card_free(card);
47341 +               return err; /* What is err?  Need to include correct file */
47342 +       }
47343 +
47344 +       strcpy(card->driver, "Ubi32-CS4384");
47345 +       strcpy(card->shortname, "Ubi32-CS4384");
47346 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
47347 +
47348 +       snd_card_set_dev(card, &client->dev);
47349 +
47350 +       /*
47351 +        * Set up the mixer
47352 +        */
47353 +       snd_ubi32_cs4384_mixer(ubi32_priv);
47354 +
47355 +       /*
47356 +        * Register the sound card 
47357 +        */
47358 +       if ((err = snd_card_register(card)) != 0) {
47359 +               snd_printk(KERN_INFO "snd_card_register error\n");
47360 +       }
47361 +
47362 +       /* 
47363 +        * Store card for access from other methods 
47364 +        */
47365 +       i2c_set_clientdata(client, card);
47366 +
47367 +       return 0;
47368 +}
47369 +
47370 +/*
47371 + * snd_ubi32_cs4384_i2c_remove
47372 + */
47373 +static int __devexit snd_ubi32_cs4384_i2c_remove(struct i2c_client *client)
47374 +{
47375 +       struct snd_card *card;
47376 +       struct ubi32_snd_priv *ubi32_priv;
47377 +
47378 +       card = i2c_get_clientdata(client);
47379 +
47380 +       ubi32_priv = card->private_data;
47381 +       snd_ubi32_pcm_remove(ubi32_priv);
47382 +
47383 +       snd_card_free(i2c_get_clientdata(client));
47384 +       i2c_set_clientdata(client, NULL);
47385 +
47386 +       return 0;
47387 +}
47388 +
47389 +/*
47390 + * I2C driver description
47391 + */
47392 +static struct i2c_driver snd_ubi32_cs4384_driver = {
47393 +       .driver = {
47394 +               .name = DRIVER_NAME,
47395 +               .owner = THIS_MODULE,
47396 +       },
47397 +       .id_table       = snd_ubi32_cs4384_id,
47398 +       .probe          = snd_ubi32_cs4384_i2c_probe,
47399 +       .remove         = __devexit_p(snd_ubi32_cs4384_i2c_remove),
47400 +};
47401 +
47402 +/*
47403 + * Driver init
47404 + */
47405 +static int __init snd_ubi32_cs4384_init(void)
47406 +{
47407 +       return i2c_add_driver(&snd_ubi32_cs4384_driver);
47408 +}
47409 +module_init(snd_ubi32_cs4384_init);
47410 +
47411 +/*
47412 + * snd_ubi32_cs4384_exit
47413 + */
47414 +static void __exit snd_ubi32_cs4384_exit(void)
47415 +{
47416 +       i2c_del_driver(&snd_ubi32_cs4384_driver);
47417 +}
47418 +module_exit(snd_ubi32_cs4384_exit);
47419 +
47420 +/*
47421 + * Module properties
47422 + */
47423 +MODULE_ALIAS("i2c:" DRIVER_NAME);
47424 +MODULE_AUTHOR("Patrick Tjin");
47425 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4384");
47426 +MODULE_LICENSE("GPL");
47427 --- /dev/null
47428 +++ b/sound/ubicom32/ubi32-generic.c
47429 @@ -0,0 +1,165 @@
47430 +/*
47431 + * sound/ubicom32/ubi32-generic.c
47432 + *     Interface to ubicom32 virtual audio peripheral
47433 + *
47434 + * (C) Copyright 2009, Ubicom, Inc.
47435 + *
47436 + * This file is part of the Ubicom32 Linux Kernel Port.
47437 + *
47438 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47439 + * it and/or modify it under the terms of the GNU General Public License
47440 + * as published by the Free Software Foundation, either version 2 of the
47441 + * License, or (at your option) any later version.
47442 + *
47443 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47444 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47445 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47446 + * the GNU General Public License for more details.
47447 + *
47448 + * You should have received a copy of the GNU General Public License
47449 + * along with the Ubicom32 Linux Kernel Port.  If not,
47450 + * see <http://www.gnu.org/licenses/>.
47451 + *
47452 + * Ubicom32 implementation derived from (with many thanks):
47453 + *   arch/m68knommu
47454 + *   arch/blackfin
47455 + *   arch/parisc
47456 + */
47457 +
47458 +#include <linux/platform_device.h>
47459 +#include <linux/module.h>
47460 +#include <linux/moduleparam.h>
47461 +#include <sound/core.h>
47462 +#include <sound/pcm.h>
47463 +#include <sound/initval.h>
47464 +#include "ubi32.h"
47465 +
47466 +#define DRIVER_NAME "snd-ubi32-generic"
47467 +
47468 +/*
47469 + * Module properties
47470 + */
47471 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
47472 +
47473 +/*
47474 + * Card private data free function
47475 + */
47476 +void snd_ubi32_generic_free(struct snd_card *card)
47477 +{
47478 +       //struct ubi32_snd_priv *ubi32_priv = card->private_data;
47479 +
47480 +       /*
47481 +        * Free all the fields in the snd_ubi32_priv struct
47482 +        */
47483 +       // Nothing to free at this time because ubi32_priv just maintains pointers
47484 +}
47485 +
47486 +/*
47487 + * Ubicom audio driver probe() method.  Args change depending on whether we use
47488 + * platform_device or i2c_device.
47489 + */
47490 +static int snd_ubi32_generic_probe(struct platform_device *dev)
47491 +{
47492 +       struct snd_card *card;
47493 +       struct ubi32_snd_priv *ubi32_priv;
47494 +       int err;
47495 +
47496 +       /*
47497 +        * Create a snd_card structure
47498 +        */
47499 +       card = snd_card_new(index, "Ubi32-Generic", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47500 +
47501 +       if (card == NULL) {
47502 +               return -ENOMEM;
47503 +       }
47504 +
47505 +       card->private_free = snd_ubi32_generic_free; /* Not sure if correct */
47506 +       ubi32_priv = card->private_data;
47507 +
47508 +       /*
47509 +        * Initialize the snd_card's private data structure
47510 +        */
47511 +       ubi32_priv->card = card;
47512 +
47513 +       /*
47514 +        * Create the new PCM instance
47515 +        */
47516 +       err = snd_ubi32_pcm_probe(ubi32_priv, dev);
47517 +       if (err < 0) {
47518 +               snd_card_free(card);
47519 +               return err;
47520 +       }
47521 +
47522 +       strcpy(card->driver, "Ubi32-Generic");
47523 +       strcpy(card->shortname, "Ubi32-Generic");
47524 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
47525 +
47526 +       snd_card_set_dev(card, &dev->dev);
47527 +
47528 +       /* Register the sound card */
47529 +       if ((err = snd_card_register(card)) != 0) {
47530 +               snd_printk(KERN_INFO "snd_card_register error\n");
47531 +       }
47532 +
47533 +       /* Store card for access from other methods */
47534 +       platform_set_drvdata(dev, card);
47535 +
47536 +       return 0;
47537 +}
47538 +
47539 +/*
47540 + * Ubicom audio driver remove() method
47541 + */
47542 +static int __devexit snd_ubi32_generic_remove(struct platform_device *dev)
47543 +{
47544 +       struct snd_card *card;
47545 +       struct ubi32_snd_priv *ubi32_priv;
47546 +
47547 +       card = platform_get_drvdata(dev);
47548 +       ubi32_priv = card->private_data;
47549 +       snd_ubi32_pcm_remove(ubi32_priv);
47550 +
47551 +       snd_card_free(platform_get_drvdata(dev));
47552 +       platform_set_drvdata(dev, NULL);
47553 +       return 0;
47554 +}
47555 +
47556 +/*
47557 + * Platform driver definition
47558 + */
47559 +static struct platform_driver snd_ubi32_generic_driver = {
47560 +       .driver = {
47561 +               .name = DRIVER_NAME,
47562 +               .owner = THIS_MODULE,
47563 +       },
47564 +       .probe = snd_ubi32_generic_probe,
47565 +       .remove = __devexit_p(snd_ubi32_generic_remove),
47566 +};
47567 +
47568 +/*
47569 + * snd_ubi32_generic_init
47570 + */
47571 +static int __init snd_ubi32_generic_init(void)
47572 +{
47573 +       return platform_driver_register(&snd_ubi32_generic_driver);
47574 +}
47575 +module_init(snd_ubi32_generic_init);
47576 +
47577 +/*
47578 + * snd_ubi32_generic_exit
47579 + */
47580 +static void __exit snd_ubi32_generic_exit(void)
47581 +{
47582 +       platform_driver_unregister(&snd_ubi32_generic_driver);
47583 +}
47584 +module_exit(snd_ubi32_generic_exit);
47585 +
47586 +/*
47587 + * Module properties
47588 + */
47589 +//#if defined(CONFIG_SND_UBI32_AUDIO_I2C)
47590 +//MODULE_ALIAS("i2c:snd-ubi32");
47591 +//#endif
47592 +MODULE_AUTHOR("Aaron Jow, Patrick Tjin");
47593 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices");
47594 +MODULE_LICENSE("GPL");
47595 --- /dev/null
47596 +++ b/sound/ubicom32/ubi32.h
47597 @@ -0,0 +1,96 @@
47598 +/*
47599 + * sound/ubicom32/ubi32.h
47600 + *     Common header file for all ubi32- sound drivers
47601 + *
47602 + * (C) Copyright 2009, Ubicom, Inc.
47603 + *
47604 + * This file is part of the Ubicom32 Linux Kernel Port.
47605 + *
47606 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47607 + * it and/or modify it under the terms of the GNU General Public License
47608 + * as published by the Free Software Foundation, either version 2 of the
47609 + * License, or (at your option) any later version.
47610 + *
47611 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47612 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47613 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47614 + * the GNU General Public License for more details.
47615 + *
47616 + * You should have received a copy of the GNU General Public License
47617 + * along with the Ubicom32 Linux Kernel Port.  If not,
47618 + * see <http://www.gnu.org/licenses/>.
47619 + */
47620 +
47621 +#ifndef _UBI32_H
47622 +#define _UBI32_H
47623 +
47624 +#define SND_UBI32_DEBUG 0 // Debug flag
47625 +
47626 +#include <linux/platform_device.h>
47627 +#include <asm/devtree.h>
47628 +#include <asm/audio_tio.h>
47629 +#include <asm/ubi32-pcm.h>
47630 +
47631 +struct ubi32_snd_priv;
47632 +
47633 +typedef int (*set_channels_t)(struct ubi32_snd_priv *priv, int channels);
47634 +typedef int (*set_rate_t)(struct ubi32_snd_priv *priv, int rate);
47635 +
47636 +struct ubi32_snd_priv {
47637 +       /*
47638 +        * Any variables that are needed locally here but NOT in
47639 +        * the VP itself should go in here.
47640 +        */
47641 +       struct snd_card *card;
47642 +       struct snd_pcm *pcm;
47643 +
47644 +       /*
47645 +        * DAC parameters.  These are the parameters for the specific
47646 +        * DAC we are driving.  The I2S component can run at a range
47647 +        * of frequencies, but the DAC may be limited.  We may want
47648 +        * to make this an array of some sort in the future?
47649 +        *
47650 +        * min/max_sample_rate if set to 0 are ignored.
47651 +        */
47652 +       int max_sample_rate;
47653 +       int min_sample_rate;
47654 +
47655 +       /*
47656 +        * The size a period (group) of audio samples.  The VP does
47657 +        * not need to know this; each DMA transfer is made to be
47658 +        * one period.
47659 +        */
47660 +       u32_t period_size;
47661 +
47662 +       spinlock_t ubi32_lock;
47663 +
47664 +       struct audiotioregs *regs;
47665 +       u8 tx_irq;
47666 +       u8 rx_irq;
47667 +
47668 +       void *client;
47669 +
47670 +       /*
47671 +        * Operations which the base DAC driver can implement
47672 +        */
47673 +       set_channels_t set_channels;
47674 +       set_rate_t set_rate;
47675 +
47676 +       /*
47677 +        * platform data
47678 +        */
47679 +       struct ubi32pcm_platform_data *pdata;
47680 +
47681 +       /*
47682 +        * Private driver data (used for DAC driver control, etc)
47683 +        */
47684 +       void *drvdata;
47685 +};
47686 +
47687 +#define snd_ubi32_priv_get_drv(priv) ((priv)->drvdata)
47688 +#define snd_ubi32_priv_set_drv(priv, data) (((priv)->drvdata) = (void *)(data))
47689 +
47690 +extern int snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev);
47691 +extern void snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv);
47692 +
47693 +#endif
47694 --- /dev/null
47695 +++ b/sound/ubicom32/ubi32-pcm.c
47696 @@ -0,0 +1,680 @@
47697 +/*
47698 + * sound/ubicom32/ubi32-pcm.c
47699 + *     Interface to ubicom32 virtual audio peripheral
47700 + *
47701 + * (C) Copyright 2009, Ubicom, Inc.
47702 + *
47703 + * This file is part of the Ubicom32 Linux Kernel Port.
47704 + *
47705 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47706 + * it and/or modify it under the terms of the GNU General Public License
47707 + * as published by the Free Software Foundation, either version 2 of the
47708 + * License, or (at your option) any later version.
47709 + *
47710 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47711 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47712 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47713 + * the GNU General Public License for more details.
47714 + *
47715 + * You should have received a copy of the GNU General Public License
47716 + * along with the Ubicom32 Linux Kernel Port.  If not,
47717 + * see <http://www.gnu.org/licenses/>.
47718 + *
47719 + * Ubicom32 implementation derived from (with many thanks):
47720 + *   arch/m68knommu
47721 + *   arch/blackfin
47722 + *   arch/parisc
47723 + */
47724 +
47725 +#include <linux/interrupt.h>
47726 +#include <sound/core.h>
47727 +#include <sound/pcm.h>
47728 +#include <sound/pcm_params.h>
47729 +#include <asm/ip5000.h>
47730 +#include <asm/ubi32-pcm.h>
47731 +#include <linux/dma-mapping.h>
47732 +#include <linux/delay.h>
47733 +#include "ubi32.h"
47734 +
47735 +struct ubi32_snd_runtime_data {
47736 +       dma_addr_t dma_buffer;          /* Physical address of DMA buffer */
47737 +       dma_addr_t dma_buffer_end;      /* First address beyond end of DMA buffer */
47738 +       size_t period_size;
47739 +       dma_addr_t period_ptr;          /* Physical address of next period */
47740 +       unsigned int flags;
47741 +};
47742 +
47743 +static void snd_ubi32_vp_int_set(struct snd_pcm *pcm)
47744 +{
47745 +       struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
47746 +       ubicom32_set_interrupt(ubi32_priv->tx_irq);
47747 +}
47748 +
47749 +static snd_pcm_uframes_t snd_ubi32_playback_pointer(struct snd_pcm_substream *substream)
47750 +{
47751 +       struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
47752 +       struct audiotioregs *regs = ubi32_priv->regs;
47753 +       struct snd_pcm_runtime *runtime = substream->runtime;
47754 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47755 +
47756 +       dma_addr_t read_pos;
47757 +
47758 +       snd_pcm_uframes_t frames;
47759 +       if (!regs->current_read_pos) {
47760 +               /*
47761 +                * If current_read_pos is NULL (e.g. right after the HW is started or
47762 +                * when the HW is stopped), then handle this case separately.
47763 +                */
47764 +               return 0;
47765 +       }
47766 +
47767 +       read_pos = (dma_addr_t)regs->current_read_pos;
47768 +       frames = bytes_to_frames(runtime, read_pos - ubi32_rd->dma_buffer);
47769 +       if (frames == runtime->buffer_size) {
47770 +               frames = 0;
47771 +       }
47772 +       return frames;
47773 +}
47774 +
47775 +/*
47776 + * Audio trigger
47777 + */
47778 +static int snd_ubi32_playback_trigger(struct snd_pcm_substream *substream, int cmd)
47779 +{
47780 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
47781 +       struct audiotioregs *regs = ubi32_priv->regs;
47782 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47783 +       int ret = 0;
47784 +
47785 +#if SND_UBI32_DEBUG
47786 +       snd_printk(KERN_INFO "snd_ubi32_playback_trigger cmd=%d=", cmd);
47787 +#endif
47788 +
47789 +       if (regs->command != UBI32_AUDIO_CMD_NONE) {
47790 +               snd_printk(KERN_WARNING "Can't send command to audio device at this time\n");
47791 +               // Set a timer to call this function back later.  How to do this?
47792 +               return 0;
47793 +       }
47794 +
47795 +       /*
47796 +        * Set interrupt flag to indicate that we interrupted audio device
47797 +        * to send a command
47798 +        */
47799 +       //regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47800 +
47801 +       switch (cmd) {
47802 +       case SNDRV_PCM_TRIGGER_START:
47803 +
47804 +#if SND_UBI32_DEBUG
47805 +               snd_printk(KERN_INFO "START\n");
47806 +#endif
47807 +               /*
47808 +                * Ready the DMA transfer
47809 +                */
47810 +               ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
47811 +
47812 +#if SND_UBI32_DEBUG
47813 +               snd_printk(KERN_INFO "trigger period_ptr=%lx\n", (unsigned long)ubi32_rd->period_ptr);
47814 +#endif
47815 +               regs->playback_xfer_requests[0].ptr = (void *)ubi32_rd->period_ptr;
47816 +               regs->playback_xfer_requests[0].ctr = ubi32_rd->period_size;
47817 +               regs->playback_xfer_requests[0].active = 1;
47818 +
47819 +#if SND_UBI32_DEBUG
47820 +               snd_printk(KERN_INFO "xfer_request 0 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
47821 +#endif
47822 +
47823 +               ubi32_rd->period_ptr += ubi32_rd->period_size;
47824 +               regs->playback_xfer_requests[1].ptr = (void *)ubi32_rd->period_ptr;
47825 +               regs->playback_xfer_requests[1].ctr = ubi32_rd->period_size;
47826 +               regs->playback_xfer_requests[1].active = 1;
47827 +
47828 +#if SND_UBI32_DEBUG
47829 +               snd_printk(KERN_INFO "xfer_request 1 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
47830 +#endif
47831 +
47832 +               /*
47833 +                * Tell the VP that we want to begin playback by filling in the
47834 +                * command field and then interrupting the audio VP
47835 +                */
47836 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47837 +               regs->command = UBI32_AUDIO_CMD_START;
47838 +               snd_ubi32_vp_int_set(substream->pcm);
47839 +               break;
47840 +
47841 +       case SNDRV_PCM_TRIGGER_STOP:
47842 +
47843 +#if SND_UBI32_DEBUG
47844 +               snd_printk(KERN_INFO "STOP\n");
47845 +#endif
47846 +
47847 +               /*
47848 +                * Tell the VP that we want to stop playback by filling in the
47849 +                * command field and then interrupting the audio VP
47850 +                */
47851 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47852 +               regs->command = UBI32_AUDIO_CMD_STOP;
47853 +               snd_ubi32_vp_int_set(substream->pcm);
47854 +               break;
47855 +
47856 +       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
47857 +
47858 +#if SND_UBI32_DEBUG
47859 +               snd_printk(KERN_INFO "PAUSE_PUSH\n");
47860 +#endif
47861 +
47862 +               /*
47863 +                * Tell the VP that we want to pause playback by filling in the
47864 +                * command field and then interrupting the audio VP
47865 +                */
47866 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47867 +               regs->command = UBI32_AUDIO_CMD_PAUSE;
47868 +               snd_ubi32_vp_int_set(substream->pcm);
47869 +               break;
47870 +
47871 +       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
47872 +
47873 +#if SND_UBI32_DEBUG
47874 +               snd_printk(KERN_INFO "PAUSE_RELEASE\n");
47875 +#endif
47876 +               /*
47877 +                * Tell the VP that we want to resume paused playback by filling
47878 +                * in the command field and then interrupting the audio VP
47879 +                */
47880 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47881 +               regs->command = UBI32_AUDIO_CMD_RESUME;
47882 +               snd_ubi32_vp_int_set(substream->pcm);
47883 +               break;
47884 +
47885 +       default:
47886 +               snd_printk(KERN_WARNING "Unhandled trigger\n");
47887 +               ret = -EINVAL;
47888 +               break;
47889 +       }
47890 +
47891 +       return ret;
47892 +}
47893 +
47894 +/*
47895 + * Prepare to transfer an audio stream to the codec
47896 + */
47897 +static int snd_ubi32_playback_prepare(struct snd_pcm_substream *substream)
47898 +{
47899 +       /*
47900 +        * Configure registers and setup the runtime instance for DMA transfers
47901 +        */
47902 +       //struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47903 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
47904 +       struct audiotioregs *regs = ubi32_priv->regs;
47905 +
47906 +#if SND_UBI32_DEBUG
47907 +       snd_printk(KERN_INFO "snd_ubi32_playback_prepare: sending STOP command to audio device\n");
47908 +#endif
47909 +
47910 +       /*
47911 +        * Make sure the audio device is stopped
47912 +        */
47913 +
47914 +       /*
47915 +        * Set interrupt flag to indicate that we interrupted audio device
47916 +        * to send a command
47917 +        */
47918 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47919 +       regs->command = UBI32_AUDIO_CMD_STOP;
47920 +       snd_ubi32_vp_int_set(substream->pcm);
47921 +
47922 +       return 0;
47923 +}
47924 +
47925 +/*
47926 + * Allocate DMA buffers from preallocated memory.
47927 + * Preallocation was done in snd_ubi32_pcm_new()
47928 + */
47929 +static int snd_ubi32_playback_hw_params(struct snd_pcm_substream *substream,
47930 +                                       struct snd_pcm_hw_params *hw_params)
47931 +{
47932 +       struct snd_pcm_runtime *runtime = substream->runtime;
47933 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
47934 +       struct audiotioregs *regs = ubi32_priv->regs;
47935 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47936 +
47937 +       /*
47938 +        * Use pre-allocated memory from ubi32_snd_pcm_new() to satisfy
47939 +        * this memory request.
47940 +        */
47941 +       int ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
47942 +
47943 +#if SND_UBI32_DEBUG
47944 +       snd_printk(KERN_INFO "snd_ubi32_playback_hw_params\n");
47945 +#endif
47946 +
47947 +       if (!(regs->channel_mask & (1 << params_channels(hw_params)))) {
47948 +               snd_printk(KERN_INFO "snd_ubi32_playback_hw_params unsupported number of channels %d mask %08x\n", params_channels(hw_params), regs->channel_mask);
47949 +               return -EINVAL;
47950 +       }
47951 +
47952 +       if (ubi32_priv->set_channels) {
47953 +               int ret = ubi32_priv->set_channels(ubi32_priv, params_channels(hw_params));
47954 +               if (ret) {
47955 +                       snd_printk(KERN_WARNING "Unable to set channels to %d, ret=%d\n", params_channels(hw_params), ret);
47956 +                       return ret;
47957 +               }
47958 +       }
47959 +
47960 +       if (ubi32_priv->set_rate) {
47961 +               int ret = ubi32_priv->set_rate(ubi32_priv, params_rate(hw_params));
47962 +               if (ret) {
47963 +                       snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
47964 +                       return ret;
47965 +               }
47966 +       }
47967 +
47968 +       if (ubi32_priv->pdata->set_rate) {
47969 +               int ret = ubi32_priv->pdata->set_rate(ubi32_priv->pdata->appdata, params_rate(hw_params));
47970 +               if (ret) {
47971 +                       snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
47972 +                       return ret;
47973 +               }
47974 +       }
47975 +
47976 +       if (regs->command != UBI32_AUDIO_CMD_NONE) {
47977 +               snd_printk(KERN_WARNING "snd_ubi32_playback_hw_params: tio busy\n");
47978 +               return -EAGAIN;
47979 +       }
47980 +
47981 +       if (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) {
47982 +               regs->flags |= UBI32_CMD_SETUP_FLAG_LE;
47983 +       } else {
47984 +               regs->flags &= ~UBI32_CMD_SETUP_FLAG_LE;
47985 +       }
47986 +       regs->channels = params_channels(hw_params);
47987 +       regs->sample_rate = params_rate(hw_params);
47988 +       regs->command = UBI32_AUDIO_CMD_SETUP;
47989 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47990 +       snd_ubi32_vp_int_set(substream->pcm);
47991 +
47992 +       /*
47993 +        * Wait for the command to complete
47994 +        */
47995 +       while (regs->command != UBI32_AUDIO_CMD_NONE) {
47996 +               udelay(1);
47997 +       }
47998 +
47999 +       //snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
48000 +       //runtime->dma_bytes = params_buffer_bytes(hw_params);
48001 +
48002 +       /*
48003 +        * Put the DMA info into the DMA descriptor that we will
48004 +        * use to do transfers to our audio VP "hardware"
48005 +        */
48006 +
48007 +       /*
48008 +        * Mark both DMA transfers as not ready/inactive
48009 +        */
48010 +       regs->playback_xfer_requests[0].active = 0;
48011 +       regs->playback_xfer_requests[1].active = 0;
48012 +
48013 +       /*
48014 +        * Put the location of the buffer into the runtime data instance
48015 +        */
48016 +       ubi32_rd->dma_buffer = (dma_addr_t)runtime->dma_area;
48017 +       ubi32_rd->dma_buffer_end = (dma_addr_t)(runtime->dma_area + runtime->dma_bytes);
48018 +
48019 +       /*
48020 +        * Get the period size
48021 +        */
48022 +       ubi32_rd->period_size = params_period_bytes(hw_params);
48023 +
48024 +#if SND_UBI32_DEBUG
48025 +       snd_printk(KERN_INFO "DMA for ubi32 audio initialized dma_area=0x%x dma_bytes=%d, period_size=%d\n", (unsigned int)runtime->dma_area, (unsigned int)runtime->dma_bytes, ubi32_rd->period_size);
48026 +       snd_printk(KERN_INFO "Private buffer ubi32_rd: dma_buffer=0x%x dma_buffer_end=0x%x\n", ubi32_rd->dma_buffer, ubi32_rd->dma_buffer_end);
48027 +#endif
48028 +
48029 +       return ret;
48030 +}
48031 +
48032 +/*
48033 + * This is the reverse of snd_ubi32_playback_hw_params
48034 + */
48035 +static int snd_ubi32_playback_hw_free(struct snd_pcm_substream *substream)
48036 +{
48037 +#if SND_UBI32_DEBUG
48038 +       snd_printk(KERN_INFO "snd_ubi32_playback_hw_free\n");
48039 +#endif
48040 +       return snd_pcm_lib_free_pages(substream);
48041 +}
48042 +
48043 +/*
48044 + * Audio virtual peripheral capabilities
48045 + */
48046 +static struct snd_pcm_hardware snd_ubi32_playback_hw =
48047 +{
48048 +       /* FILL IN THIS STRUCT WITH HW PARAMS SPECIFIC TO IPI2SOUT */
48049 +       // This is defined in include/sound/asound.h or
48050 +       // include/sound/pcm.h
48051 +       .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
48052 +                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), // NOT SURE ABOUT THIS
48053 +       //.info                 = (SNDRV_PCM_INFO_INTERLEAVED |
48054 +       //                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
48055 +       //                         SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
48056 +       //                         SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
48057 +       .buffer_bytes_max = (64*1024), // NOT SURE ABOUT THIS
48058 +       .period_bytes_min       = 64,
48059 +       .period_bytes_max       = 8184,//8184,//8176,
48060 +       .periods_min = 2,
48061 +       .periods_max = 255, // THIS WILL ALMOST CERTAINLY NEED TO BE CHANGED
48062 +       .fifo_size = 0, // THIS IS IGNORED BY ALSA
48063 +};
48064 +
48065 +/*
48066 + * We fill this in later
48067 + */
48068 +static struct snd_pcm_hw_constraint_list ubi32_playback_rates;
48069 +
48070 +static int snd_ubi32_playback_close(struct snd_pcm_substream *substream)
48071 +{
48072 +       /* Disable codec, stop DMA, free private data structures */
48073 +       //struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
48074 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48075 +
48076 +#if SND_UBI32_DEBUG
48077 +       snd_printk(KERN_INFO "snd_ubi32_playback_close\n");
48078 +#endif
48079 +
48080 +       substream->runtime->private_data = NULL;
48081 +
48082 +       kfree(ubi32_rd);
48083 +       
48084 +       return 0;
48085 +}
48086 +
48087 +static int snd_ubi32_playback_open(struct snd_pcm_substream *substream)
48088 +{
48089 +       //struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
48090 +       struct snd_pcm_runtime *runtime = substream->runtime;
48091 +       struct ubi32_snd_runtime_data *ubi32_rd;
48092 +       int ret = 0;
48093 +
48094 +#if SND_UBI32_DEBUG
48095 +       snd_printk(KERN_INFO "ubi32 playback open\n");
48096 +#endif
48097 +
48098 +       /* Associate capabilities with component */
48099 +       runtime->hw = snd_ubi32_playback_hw;
48100 +
48101 +       /*
48102 +        * Inform ALSA about constraints of the audio device
48103 +        */
48104 +       ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &ubi32_playback_rates);
48105 +       if (ret < 0) {
48106 +               snd_printk(KERN_INFO "invalid rate\n");
48107 +               goto out;
48108 +       }
48109 +
48110 +       /* Force the buffer size to be an integer multiple of period size */
48111 +       ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
48112 +       if (ret < 0) {
48113 +               snd_printk(KERN_INFO "invalid period\n");
48114 +               goto out;
48115 +       }
48116 +       /* Initialize structures/registers */
48117 +       ubi32_rd = kzalloc(sizeof(struct ubi32_snd_runtime_data), GFP_KERNEL);
48118 +       if (ubi32_rd == NULL) {
48119 +               ret = -ENOMEM;
48120 +               goto out;
48121 +       }
48122 +
48123 +       runtime->private_data = ubi32_rd;
48124 +
48125 +#if SND_UBI32_DEBUG
48126 +       snd_printk(KERN_INFO "snd_ubi32_playback_open returned 0\n");
48127 +#endif
48128 +
48129 +       return 0;
48130 +out:
48131 +#if SND_UBI32_DEBUG
48132 +       snd_printk(KERN_INFO "snd_ubi32_playback_open returned %d\n", ret);
48133 +#endif
48134 +
48135 +       return ret;
48136 +}
48137 +
48138 +static struct snd_pcm_ops snd_ubi32_playback_ops = {
48139 +       .open =         snd_ubi32_playback_open, /* Open */
48140 +       .close =        snd_ubi32_playback_close, /* Close */
48141 +       .ioctl =        snd_pcm_lib_ioctl, /* Generic IOCTL handler */
48142 +       .hw_params =    snd_ubi32_playback_hw_params, /* Hardware parameters/capabilities */
48143 +       .hw_free =      snd_ubi32_playback_hw_free, /* Free function for hw_params */
48144 +       .prepare =      snd_ubi32_playback_prepare,
48145 +       .trigger =      snd_ubi32_playback_trigger,
48146 +       .pointer =      snd_ubi32_playback_pointer,
48147 +};
48148 +
48149 +/*
48150 + * Interrupt handler that gets called when the audio device
48151 + * interrupts Linux
48152 + */
48153 +static irqreturn_t snd_ubi32_pcm_interrupt(int irq, void *appdata)
48154 +{
48155 +       struct snd_pcm *pcm = (struct snd_pcm *)appdata;
48156 +       struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
48157 +       struct audiotioregs *regs = ubi32_priv->regs;
48158 +
48159 +       // Only one substream exists because our VP does not mix
48160 +       // streams.  Therefore we don't have to search through
48161 +       // substreams like the at91 driver does.
48162 +       struct snd_pcm_substream *substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
48163 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48164 +       int dma_to_fill = 0;
48165 +
48166 +#if SND_UBI32_DEBUG
48167 +       snd_printk(KERN_INFO "Ubi32 ALSA interrupt\n");
48168 +#endif
48169 +
48170 +       if (!pcm) {
48171 +               snd_printk(KERN_WARNING "pcm does not exist\n");
48172 +               return IRQ_HANDLED;
48173 +       }
48174 +
48175 +       if (ubi32_rd == NULL) {
48176 +               snd_printk(KERN_WARNING "No runtime data\n");
48177 +               return IRQ_HANDLED;
48178 +       }
48179 +       // Check interrupt cause
48180 +       if (0) {
48181 +               // Handle the underflow case
48182 +       } else if ((regs->status & UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST) ||
48183 +                  (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST)) {
48184 +               if (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST) {
48185 +                       dma_to_fill = 0;
48186 +                       regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST;
48187 +               } else if (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST) {
48188 +                       dma_to_fill = 1;
48189 +                       regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST;
48190 +               }   
48191 +               ubi32_rd->period_ptr += ubi32_rd->period_size;
48192 +               if (ubi32_rd->period_ptr >= ubi32_rd->dma_buffer_end) {
48193 +                       ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
48194 +               }
48195 +               regs->playback_xfer_requests[dma_to_fill].ptr = (void *)ubi32_rd->period_ptr;
48196 +               regs->playback_xfer_requests[dma_to_fill].ctr = ubi32_rd->period_size;
48197 +               regs->playback_xfer_requests[dma_to_fill].active = 1;
48198 +#if SND_UBI32_DEBUG
48199 +               snd_printk(KERN_INFO "xfer_request %d ptr=0x%x ctr=%u\n", dma_to_fill, ubi32_rd->period_ptr, ubi32_rd->period_size);
48200 +#endif
48201 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_MORE_SAMPLES;
48202 +               snd_ubi32_vp_int_set(substream->pcm);
48203 +       }
48204 +       // If we are interrupted by the VP, that means we completed
48205 +       // processing one period of audio.  We need to inform the upper
48206 +       // layers of ALSA of this.
48207 +       snd_pcm_period_elapsed(substream);
48208 +
48209 +       return IRQ_HANDLED;
48210 +}
48211 +
48212 +void __devexit snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv)
48213 +{
48214 +       struct snd_pcm *pcm = ubi32_priv->pcm;
48215 +       free_irq(ubi32_priv->rx_irq, pcm);
48216 +}
48217 +
48218 +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
48219 +#error "Change this table to match pcm.h"
48220 +#endif
48221 +static unsigned int rates[] __initdata = {5512, 8000, 11025, 16000, 22050, 
48222 +                                         32000, 44100, 48000, 64000, 88200, 
48223 +                                         96000, 176400, 192000};
48224 +
48225 +/*
48226 + * snd_ubi32_pcm_probe
48227 + */
48228 +int __devinit snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev)
48229 +{
48230 +       struct snd_pcm *pcm;
48231 +       int ret, err;
48232 +       int i;
48233 +       int j;
48234 +       int nrates;
48235 +       unsigned int rate_max = 0;
48236 +       unsigned int rate_min = 0xFFFFFFFF;
48237 +       unsigned int rate_mask = 0;
48238 +       struct audiotioregs *regs;
48239 +       struct resource *res_regs;
48240 +       struct resource *res_irq_tx;
48241 +       struct resource *res_irq_rx;
48242 +       struct ubi32pcm_platform_data *pdata;
48243 +
48244 +       pdata = pdev->dev.platform_data;
48245 +       if (!pdata) {
48246 +               return -ENODEV;
48247 +       }
48248 +
48249 +       /*
48250 +        * Get our resources, regs is the hardware driver base address
48251 +        * and the tx and rx irqs are used to communicate with the
48252 +        * hardware driver.
48253 +        */
48254 +       res_regs = platform_get_resource(pdev, IORESOURCE_MEM, AUDIOTIO_MEM_RESOURCE);
48255 +       res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIOTIO_TX_IRQ_RESOURCE);
48256 +       res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIOTIO_RX_IRQ_RESOURCE);
48257 +       if (!res_regs || !res_irq_tx || !res_irq_rx) {
48258 +               snd_printk(KERN_WARNING "Could not get resources");
48259 +               return -ENODEV;
48260 +       }
48261 +
48262 +       ubi32_priv->regs = (struct audiotioregs *)res_regs->start;
48263 +       ubi32_priv->tx_irq = res_irq_tx->start;
48264 +       ubi32_priv->rx_irq = res_irq_rx->start;
48265 +
48266 +       /*
48267 +        * Check the version
48268 +        */
48269 +       regs = ubi32_priv->regs;
48270 +       if (regs->version != AUDIOTIOREGS_VERSION) {
48271 +               snd_printk(KERN_WARNING "This audiotioreg is not compatible with this driver\n");
48272 +               return -ENODEV;
48273 +       }
48274 +
48275 +       /*
48276 +        * Find out the standard rates, also find max and min rates
48277 +        */
48278 +       for (i = 0; i < ARRAY_SIZE(rates); i++) {
48279 +               int found = 0;
48280 +               for (j = 0; j < regs->n_sample_rates; j++) {
48281 +                       if (rates[i] == regs->sample_rates[j]) {
48282 +                               /*
48283 +                                * Check to see if it is supported by the dac
48284 +                                */
48285 +                               if ((rates[i] >= ubi32_priv->min_sample_rate) &&
48286 +                                   (!ubi32_priv->max_sample_rate || 
48287 +                                    (ubi32_priv->max_sample_rate && (rates[i] <= ubi32_priv->max_sample_rate)))) {
48288 +                                       found = 1;
48289 +                                       rate_mask |= (1 << i);
48290 +                                       nrates++;
48291 +                                       if (rates[i] < rate_min) {
48292 +                                               rate_min = rates[i];
48293 +                                       }
48294 +                                       if (rates[i] > rate_max) {
48295 +                                               rate_max = rates[i];
48296 +                                       }
48297 +                                       break;
48298 +                               }
48299 +                       }
48300 +               }
48301 +               if (!found) {
48302 +                       rate_mask |= SNDRV_PCM_RATE_KNOT;
48303 +               }
48304 +       }
48305 +
48306 +       snd_ubi32_playback_hw.rates = rate_mask;
48307 +       snd_ubi32_playback_hw.rate_min = rate_min;
48308 +       snd_ubi32_playback_hw.rate_max = rate_max;
48309 +       ubi32_playback_rates.count = regs->n_sample_rates;
48310 +       ubi32_playback_rates.list = regs->sample_rates;
48311 +       ubi32_playback_rates.mask = 0;
48312 +
48313 +       for (i = 0; i < 32; i++) {
48314 +               if (regs->channel_mask & (1 << i)) {
48315 +                       if (!snd_ubi32_playback_hw.channels_min) {
48316 +                               snd_ubi32_playback_hw.channels_min = i;
48317 +                       }
48318 +                       snd_ubi32_playback_hw.channels_max = i;
48319 +               }
48320 +       }
48321 +       snd_printk(KERN_INFO "Ubi32PCM: channels_min:%u channels_max:%u\n",
48322 +                  snd_ubi32_playback_hw.channels_min,
48323 +                  snd_ubi32_playback_hw.channels_max);
48324 +
48325 +       if (regs->caps & AUDIOTIONODE_CAP_BE) {
48326 +               snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_BE;
48327 +       }
48328 +       if (regs->caps & AUDIOTIONODE_CAP_LE) {
48329 +               snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
48330 +       }
48331 +       snd_printk(KERN_INFO "Ubi32PCM: rates:%08x min:%u max:%u count:%d fmts:%016llx\n",
48332 +                  snd_ubi32_playback_hw.rates,
48333 +                  snd_ubi32_playback_hw.rate_min,
48334 +                  snd_ubi32_playback_hw.rate_max,
48335 +                  ubi32_playback_rates.count,
48336 +                  snd_ubi32_playback_hw.formats);
48337 +
48338 +       ret = snd_pcm_new(ubi32_priv->card, "Ubi32 PCM", 0, 1, 0, &pcm);
48339 +       if (ret < 0) {
48340 +               return ret;
48341 +       }
48342 +
48343 +       pcm->private_data = ubi32_priv;
48344 +       ubi32_priv->pcm = pcm;
48345 +       ubi32_priv->pdata = pdata;
48346 +
48347 +       pcm->info_flags = 0; // What is this for?  Just copied from other drivers
48348 +
48349 +       strcpy(pcm->name, "Ubi32-PCM");
48350 +
48351 +       // How do we allocate the buffer for non PCI devices?
48352 +       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
48353 +                                             snd_dma_continuous_data(GFP_KERNEL),
48354 +                                             45*1024, 64*1024); //NOT SURE ABOUT SIZE, CHECK LATER
48355 +
48356 +       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ubi32_playback_ops);
48357 +
48358 +       /*
48359 +        * Start up the TIO
48360 +        */
48361 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48362 +       regs->command = UBI32_AUDIO_CMD_ENABLE;
48363 +       snd_ubi32_vp_int_set(pcm);
48364 +
48365 +       /* 
48366 +        * Request IRQ
48367 +        */
48368 +       err = request_irq(ubi32_priv->rx_irq, snd_ubi32_pcm_interrupt, IRQF_DISABLED, pcm->name, pcm);
48369 +       if (err) {
48370 +               snd_printk(KERN_WARNING "request_irq failed: irq=%d err=%d\n", ubi32_priv->rx_irq, err);
48371 +               return -ENODEV;
48372 +       }
48373 +
48374 +       return ret;
48375 +
48376 +}
48377 --- /dev/null
48378 +++ b/arch/ubicom32/lib/ashldi3.c
48379 @@ -0,0 +1,62 @@
48380 +/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
48381 +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
48382 +
48383 +This file is part of GNU CC.
48384 +
48385 +GNU CC is free software; you can redistribute it and/or modify
48386 +it under the terms of the GNU General Public License as published by
48387 +the Free Software Foundation; either version 2, or (at your option)
48388 +any later version.
48389 +
48390 +GNU CC is distributed in the hope that it will be useful,
48391 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48392 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48393 +GNU General Public License for more details.
48394 +
48395 +You should have received a copy of the GNU General Public License
48396 +along with GNU CC; see the file COPYING.  If not, write to
48397 +the Free Software Foundation, 59 Temple Place - Suite 330,
48398 +Boston, MA 02111-1307, USA.  */
48399 +
48400 +#define BITS_PER_UNIT 8
48401 +
48402 +typedef                 int SItype     __attribute__ ((mode (SI)));
48403 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48404 +typedef                 int DItype     __attribute__ ((mode (DI)));
48405 +typedef int word_type __attribute__ ((mode (__word__)));
48406 +
48407 +struct DIstruct {SItype high, low;};
48408 +
48409 +typedef union
48410 +{
48411 +  struct DIstruct s;
48412 +  DItype ll;
48413 +} DIunion;
48414 +
48415 +DItype
48416 +__ashldi3 (DItype u, word_type b)
48417 +{
48418 +  DIunion w;
48419 +  word_type bm;
48420 +  DIunion uu;
48421 +
48422 +  if (b == 0)
48423 +    return u;
48424 +
48425 +  uu.ll = u;
48426 +
48427 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48428 +  if (bm <= 0)
48429 +    {
48430 +      w.s.low = 0;
48431 +      w.s.high = (USItype)uu.s.low << -bm;
48432 +    }
48433 +  else
48434 +    {
48435 +      USItype carries = (USItype)uu.s.low >> bm;
48436 +      w.s.low = (USItype)uu.s.low << b;
48437 +      w.s.high = ((USItype)uu.s.high << b) | carries;
48438 +    }
48439 +
48440 +  return w.ll;
48441 +}
48442 --- /dev/null
48443 +++ b/arch/ubicom32/lib/ashrdi3.c
48444 @@ -0,0 +1,63 @@
48445 +/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
48446 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48447 +
48448 +This file is part of GNU CC.
48449 +
48450 +GNU CC is free software; you can redistribute it and/or modify
48451 +it under the terms of the GNU General Public License as published by
48452 +the Free Software Foundation; either version 2, or (at your option)
48453 +any later version.
48454 +
48455 +GNU CC is distributed in the hope that it will be useful,
48456 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48457 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48458 +GNU General Public License for more details.
48459 +
48460 +You should have received a copy of the GNU General Public License
48461 +along with GNU CC; see the file COPYING.  If not, write to
48462 +the Free Software Foundation, 59 Temple Place - Suite 330,
48463 +Boston, MA 02111-1307, USA.  */
48464 +
48465 +#define BITS_PER_UNIT 8
48466 +
48467 +typedef                 int SItype     __attribute__ ((mode (SI)));
48468 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48469 +typedef                 int DItype     __attribute__ ((mode (DI)));
48470 +typedef int word_type __attribute__ ((mode (__word__)));
48471 +
48472 +struct DIstruct {SItype high, low;};
48473 +
48474 +typedef union
48475 +{
48476 +  struct DIstruct s;
48477 +  DItype ll;
48478 +} DIunion;
48479 +
48480 +DItype
48481 +__ashrdi3 (DItype u, word_type b)
48482 +{
48483 +  DIunion w;
48484 +  word_type bm;
48485 +  DIunion uu;
48486 +
48487 +  if (b == 0)
48488 +    return u;
48489 +
48490 +  uu.ll = u;
48491 +
48492 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48493 +  if (bm <= 0)
48494 +    {
48495 +      /* w.s.high = 1..1 or 0..0 */
48496 +      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
48497 +      w.s.low = uu.s.high >> -bm;
48498 +    }
48499 +  else
48500 +    {
48501 +      USItype carries = (USItype)uu.s.high << bm;
48502 +      w.s.high = uu.s.high >> b;
48503 +      w.s.low = ((USItype)uu.s.low >> b) | carries;
48504 +    }
48505 +
48506 +  return w.ll;
48507 +}
48508 --- /dev/null
48509 +++ b/arch/ubicom32/lib/divmod.c
48510 @@ -0,0 +1,85 @@
48511 +unsigned long
48512 +udivmodsi4(unsigned long num, unsigned long den, int modwanted)
48513 +{
48514 +  unsigned long bit = 1;
48515 +  unsigned long res = 0;
48516 +
48517 +  while (den < num && bit && !(den & (1L<<31)))
48518 +    {
48519 +      den <<=1;
48520 +      bit <<=1;
48521 +    }
48522 +  while (bit)
48523 +    {
48524 +      if (num >= den)
48525 +       {
48526 +         num -= den;
48527 +         res |= bit;
48528 +       }
48529 +      bit >>=1;
48530 +      den >>=1;
48531 +    }
48532 +  if (modwanted) return num;
48533 +  return res;
48534 +}
48535 +
48536 +long
48537 +__udivsi3 (long a, long b)
48538 +{
48539 +  return udivmodsi4 (a, b, 0);
48540 +}
48541 +
48542 +long
48543 +__umodsi3 (long a, long b)
48544 +{
48545 +  return udivmodsi4 (a, b, 1);
48546 +}
48547 +
48548 +long
48549 +__divsi3 (long a, long b)
48550 +{
48551 +  int neg = 0;
48552 +  long res;
48553 +
48554 +  if (a < 0)
48555 +    {
48556 +      a = -a;
48557 +      neg = !neg;
48558 +    }
48559 +
48560 +  if (b < 0)
48561 +    {
48562 +      b = -b;
48563 +      neg = !neg;
48564 +    }
48565 +
48566 +  res = udivmodsi4 (a, b, 0);
48567 +
48568 +  if (neg)
48569 +    res = -res;
48570 +
48571 +  return res;
48572 +}
48573 +
48574 +long
48575 +__modsi3 (long a, long b)
48576 +{
48577 +  int neg = 0;
48578 +  long res;
48579 +
48580 +  if (a < 0)
48581 +    {
48582 +      a = -a;
48583 +      neg = 1;
48584 +    }
48585 +
48586 +  if (b < 0)
48587 +    b = -b;
48588 +
48589 +  res = udivmodsi4 (a, b, 1);
48590 +
48591 +  if (neg)
48592 +    res = -res;
48593 +
48594 +  return res;
48595 +}
48596 --- /dev/null
48597 +++ b/arch/ubicom32/lib/lshrdi3.c
48598 @@ -0,0 +1,62 @@
48599 +/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
48600 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48601 +
48602 +This file is part of GNU CC.
48603 +
48604 +GNU CC is free software; you can redistribute it and/or modify
48605 +it under the terms of the GNU General Public License as published by
48606 +the Free Software Foundation; either version 2, or (at your option)
48607 +any later version.
48608 +
48609 +GNU CC is distributed in the hope that it will be useful,
48610 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48611 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48612 +GNU General Public License for more details.
48613 +
48614 +You should have received a copy of the GNU General Public License
48615 +along with GNU CC; see the file COPYING.  If not, write to
48616 +the Free Software Foundation, 59 Temple Place - Suite 330,
48617 +Boston, MA 02111-1307, USA.  */
48618 +
48619 +#define BITS_PER_UNIT 8
48620 +
48621 +typedef                 int SItype     __attribute__ ((mode (SI)));
48622 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48623 +typedef                 int DItype     __attribute__ ((mode (DI)));
48624 +typedef int word_type __attribute__ ((mode (__word__)));
48625 +
48626 +struct DIstruct {SItype high, low;};
48627 +
48628 +typedef union
48629 +{
48630 +  struct DIstruct s;
48631 +  DItype ll;
48632 +} DIunion;
48633 +
48634 +DItype
48635 +__lshrdi3 (DItype u, word_type b)
48636 +{
48637 +  DIunion w;
48638 +  word_type bm;
48639 +  DIunion uu;
48640 +
48641 +  if (b == 0)
48642 +    return u;
48643 +
48644 +  uu.ll = u;
48645 +
48646 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48647 +  if (bm <= 0)
48648 +    {
48649 +      w.s.high = 0;
48650 +      w.s.low = (USItype)uu.s.high >> -bm;
48651 +    }
48652 +  else
48653 +    {
48654 +      USItype carries = (USItype)uu.s.high << bm;
48655 +      w.s.high = (USItype)uu.s.high >> b;
48656 +      w.s.low = ((USItype)uu.s.low >> b) | carries;
48657 +    }
48658 +
48659 +  return w.ll;
48660 +}
48661 --- /dev/null
48662 +++ b/arch/ubicom32/lib/muldi3.c
48663 @@ -0,0 +1,87 @@
48664 +/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
48665 +                          gcc-2.7.2.3/longlong.h which is: */
48666 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48667 +
48668 +This file is part of GNU CC.
48669 +
48670 +GNU CC is free software; you can redistribute it and/or modify
48671 +it under the terms of the GNU General Public License as published by
48672 +the Free Software Foundation; either version 2, or (at your option)
48673 +any later version.
48674 +
48675 +GNU CC is distributed in the hope that it will be useful,
48676 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48677 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48678 +GNU General Public License for more details.
48679 +
48680 +You should have received a copy of the GNU General Public License
48681 +along with GNU CC; see the file COPYING.  If not, write to
48682 +the Free Software Foundation, 59 Temple Place - Suite 330,
48683 +Boston, MA 02111-1307, USA.  */
48684 +
48685 +#define UWtype          USItype
48686 +#define UHWtype         USItype
48687 +#define W_TYPE_SIZE     32
48688 +#define __BITS4 (W_TYPE_SIZE / 4)
48689 +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
48690 +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
48691 +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
48692 +
48693 +#define umul_ppmm(w1, w0, u, v)                                         \
48694 +  do {                                                                  \
48695 +    UWtype __x0, __x1, __x2, __x3;                                      \
48696 +    UHWtype __ul, __vl, __uh, __vh;                                     \
48697 +                                                                        \
48698 +    __ul = __ll_lowpart (u);                                            \
48699 +    __uh = __ll_highpart (u);                                           \
48700 +    __vl = __ll_lowpart (v);                                            \
48701 +    __vh = __ll_highpart (v);                                           \
48702 +                                                                        \
48703 +    __x0 = (UWtype) __ul * __vl;                                        \
48704 +    __x1 = (UWtype) __ul * __vh;                                        \
48705 +    __x2 = (UWtype) __uh * __vl;                                        \
48706 +    __x3 = (UWtype) __uh * __vh;                                        \
48707 +                                                                        \
48708 +    __x1 += __ll_highpart (__x0);/* this can't give carry */            \
48709 +    __x1 += __x2;               /* but this indeed can */               \
48710 +    if (__x1 < __x2)            /* did we get it? */                    \
48711 +      __x3 += __ll_B;           /* yes, add it in the proper pos.  */   \
48712 +                                                                        \
48713 +    (w1) = __x3 + __ll_highpart (__x1);                                 \
48714 +    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);          \
48715 +  } while (0)
48716 +
48717 +
48718 +#define __umulsidi3(u, v) \
48719 +  ({DIunion __w;                                                       \
48720 +    umul_ppmm (__w.s.high, __w.s.low, u, v);                           \
48721 +    __w.ll; })
48722 +
48723 +typedef                 int SItype     __attribute__ ((mode (SI)));
48724 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48725 +typedef                 int DItype     __attribute__ ((mode (DI)));
48726 +typedef int word_type __attribute__ ((mode (__word__)));
48727 +
48728 +struct DIstruct {SItype high, low;};
48729 +
48730 +typedef union
48731 +{
48732 +  struct DIstruct s;
48733 +  DItype ll;
48734 +} DIunion;
48735 +
48736 +DItype
48737 +__muldi3 (DItype u, DItype v)
48738 +{
48739 +  DIunion w;
48740 +  DIunion uu, vv;
48741 +
48742 +  uu.ll = u,
48743 +  vv.ll = v;
48744 +
48745 +  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
48746 +  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
48747 +              + (USItype) uu.s.high * (USItype) vv.s.low);
48748 +
48749 +  return w.ll;
48750 +}