Revert "[ubicom32] remove kernel patch for now since it is incomplete and has some...
[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/elf.h~
4834 @@ -0,0 +1,165 @@
4835 +/*
4836 + * arch/ubicom32/include/asm/elf.h
4837 + *   Definitions for elf executable format 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_ELF_H
4863 +#define _ASM_UBICOM32_ELF_H
4864 +
4865 +/*
4866 + * ELF register definitions..
4867 + */
4868 +
4869 +#include <asm/ptrace.h>
4870 +#include <asm/user.h>
4871 +
4872 +/*
4873 + * Processor specific flags for the ELF header e_flags field.
4874 + */
4875 +#define EF_UBICOM32_V3         0x00000001      /* -fmarch=ubicom32v3 */
4876 +#define EF_UBICOM32_V4         0x00000002      /* -fmarch=ubicom32v4 */
4877 +#define EF_UBICOM32_PIC                0x80000000      /* -fpic */
4878 +#define EF_UBICOM32_FDPIC      0x40000000      /* -mfdpic */
4879 +
4880 +/*
4881 + * Ubicom32 ELF relocation types
4882 + */
4883 +#define R_UBICOM32_NONE                        0
4884 +#define R_UBICOM32_16                  1
4885 +#define R_UBICOM32_32                  2
4886 +#define R_UBICOM32_LO16                        3
4887 +#define R_UBICOM32_HI16                        4
4888 +#define R_UBICOM32_21_PCREL            5
4889 +#define R_UBICOM32_24_PCREL            6
4890 +#define R_UBICOM32_HI24                        7
4891 +#define R_UBICOM32_LO7_S               8
4892 +#define R_UBICOM32_LO7_2_S             9
4893 +#define R_UBICOM32_LO7_4_S             10
4894 +#define R_UBICOM32_LO7_D               11
4895 +#define R_UBICOM32_LO7_2_D             12
4896 +#define R_UBICOM32_LO7_4_D             13
4897 +#define R_UBICOM32_32_HARVARD          14
4898 +#define R_UBICOM32_LO7_CALLI           15
4899 +#define R_UBICOM32_LO16_CALLI          16
4900 +#define R_UBICOM32_GOT_HI24            17
4901 +#define R_UBICOM32_GOT_LO7_S           18
4902 +#define R_UBICOM32_GOT_LO7_2_S         19
4903 +#define R_UBICOM32_GOT_LO7_4_S         20
4904 +#define R_UBICOM32_GOT_LO7_D           21
4905 +#define R_UBICOM32_GOT_LO7_2_D         22
4906 +#define R_UBICOM32_GOT_LO7_4_D         23
4907 +#define R_UBICOM32_FUNCDESC_GOT_HI24    24
4908 +#define R_UBICOM32_FUNCDESC_GOT_LO7_S   25
4909 +#define R_UBICOM32_FUNCDESC_GOT_LO7_2_S 26
4910 +#define R_UBICOM32_FUNCDESC_GOT_LO7_4_S 27
4911 +#define R_UBICOM32_FUNCDESC_GOT_LO7_D   28
4912 +#define R_UBICOM32_FUNCDESC_GOT_LO7_2_D 29
4913 +#define R_UBICOM32_FUNCDESC_GOT_LO7_4_D 30
4914 +#define R_UBICOM32_GOT_LO7_CALLI        31
4915 +#define R_UBICOM32_FUNCDESC_GOT_LO7_CALLI 32
4916 +#define R_UBICOM32_FUNCDESC_VALUE       33
4917 +#define R_UBICOM32_FUNCDESC             34
4918 +#define R_UBICOM32_GOTOFFSET_LO         35
4919 +#define R_UBICOM32_GOTOFFSET_HI         36
4920 +#define R_UBICOM32_FUNCDESC_GOTOFFSET_LO 37
4921 +#define R_UBICOM32_FUNCDESC_GOTOFFSET_HI 38
4922 +#define R_UBICOM32_GNU_VTINHERIT        200
4923 +#define R_UBICOM32_GNU_VTENTRY          201
4924 +
4925 +typedef unsigned long elf_greg_t;
4926 +
4927 +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
4928 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
4929 +
4930 +typedef struct user_ubicom32fp_struct elf_fpregset_t;
4931 +
4932 +/*
4933 + * This is used to ensure we don't load something for the wrong architecture.
4934 + */
4935 +#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
4936 +
4937 +#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
4938 +
4939 +#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
4940 +
4941 +/*
4942 + * These are used to set parameters in the core dumps.
4943 + */
4944 +#define ELF_CLASS      ELFCLASS32
4945 +#define ELF_DATA       ELFDATA2MSB
4946 +#define ELF_ARCH       EM_UBICOM32
4947 +
4948 +/* For SVR4/m68k the function pointer to be registered with `atexit' is
4949 +   passed in %a1.  Although my copy of the ABI has no such statement, it
4950 +   is actually used on ASV.  */
4951 +#define ELF_PLAT_INIT(_r, load_addr)   _r->a1 = 0
4952 +
4953 +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr,   \
4954 +                           _dynamic_addr)                              \
4955 +       do {                                                            \
4956 +               _regs->dn[1]    = _exec_map_addr;                       \
4957 +               _regs->dn[2]    = _interp_map_addr;                     \
4958 +               _regs->dn[3]    = _dynamic_addr;                        \
4959 +               _regs->an[1]    = 0; /* dl_fini will be set by ldso */  \
4960 +       } while (0)
4961 +
4962 +#define USE_ELF_CORE_DUMP
4963 +#define ELF_EXEC_PAGESIZE      4096
4964 +
4965 +#ifdef CONFIG_UBICOM32_V4
4966 +#define ELF_FDPIC_CORE_EFLAGS  (EF_UBICOM32_FDPIC | EF_UBICOM32_V4)
4967 +#elif defined CONFIG_UBICOM32_V3
4968 +#define ELF_FDPIC_CORE_EFLAGS  (EF_UBICOM32_FDPIC | EF_UBICOM32_V3)
4969 +#else
4970 +#error Unknown/Unsupported ubicom32 architecture.
4971 +#endif
4972 +
4973 +/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
4974 +   use of this is to invoke "./ld.so someprog" to test out a new version of
4975 +   the loader.  We need to make sure that it is out of the way of the program
4976 +   that it will "exec", and that there is sufficient room for the brk.  */
4977 +
4978 +#define ELF_ET_DYN_BASE         0xD0000000UL
4979 +
4980 +/*
4981 + * For Ubicom32, the elf_gregset_t and struct pt_regs are the same size
4982 + * data structure so a copy is performed instead of providing the
4983 + * ELF_CORE_COPY_REGS macro.
4984 + */
4985 +
4986 +/* This yields a mask that user programs can use to figure out what
4987 +   instruction set this cpu supports.  */
4988 +
4989 +#define ELF_HWCAP      (0)
4990 +
4991 +/* This yields a string that ld.so will use to load implementation
4992 +   specific libraries for optimization.  This is more specific in
4993 +   intent than poking at uname or /proc/cpuinfo.  */
4994 +
4995 +#define ELF_PLATFORM  (NULL)
4996 +
4997 +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
4998 +
4999 +#endif /* _ASM_UBICOM32_ELF_H */
5000 --- /dev/null
5001 +++ b/arch/ubicom32/include/asm/emergency-restart.h
5002 @@ -0,0 +1,33 @@
5003 +/*
5004 + * arch/ubicom32/include/asm/emergency-restart.h
5005 + *   Generic emergency-restart.h for Ubicom32 architecture.
5006 + *
5007 + * (C) Copyright 2009, Ubicom, Inc.
5008 + *
5009 + * This file is part of the Ubicom32 Linux Kernel Port.
5010 + *
5011 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5012 + * it and/or modify it under the terms of the GNU General Public License
5013 + * as published by the Free Software Foundation, either version 2 of the
5014 + * License, or (at your option) any later version.
5015 + *
5016 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5017 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5018 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5019 + * the GNU General Public License for more details.
5020 + *
5021 + * You should have received a copy of the GNU General Public License
5022 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5023 + * see <http://www.gnu.org/licenses/>.
5024 + *
5025 + * Ubicom32 implementation derived from (with many thanks):
5026 + *   arch/m68knommu
5027 + *   arch/blackfin
5028 + *   arch/parisc
5029 + */
5030 +#ifndef _ASM_UBICOM32_EMERGENCY_RESTART_H
5031 +#define _ASM_UBICOM32_EMERGENCY_RESTART_H
5032 +
5033 +#include <asm-generic/emergency-restart.h>
5034 +
5035 +#endif /* _ASM_UBICOM32_EMERGENCY_RESTART_H */
5036 --- /dev/null
5037 +++ b/arch/ubicom32/include/asm/entry.h
5038 @@ -0,0 +1,34 @@
5039 +/*
5040 + * arch/ubicom32/include/asm/entry.h
5041 + *   Entry register/stack definitions for Ubicom32 architecture.
5042 + *
5043 + * (C) Copyright 2009, Ubicom, Inc.
5044 + *
5045 + * This file is part of the Ubicom32 Linux Kernel Port.
5046 + *
5047 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5048 + * it and/or modify it under the terms of the GNU General Public License
5049 + * as published by the Free Software Foundation, either version 2 of the
5050 + * License, or (at your option) any later version.
5051 + *
5052 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5053 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5054 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5055 + * the GNU General Public License for more details.
5056 + *
5057 + * You should have received a copy of the GNU General Public License
5058 + * along with the Ubicom32 Linux Kernel Port.  If not,
5059 + * see <http://www.gnu.org/licenses/>.
5060 + *
5061 + * Ubicom32 implementation derived from (with many thanks):
5062 + *   arch/m68knommu
5063 + *   arch/blackfin
5064 + *   arch/parisc
5065 + */
5066 +#ifndef _ASM_UBICOM32_ENTRY_H
5067 +#define _ASM_UBICOM32_ENTRY_H
5068 +
5069 +#include <asm/setup.h>
5070 +#include <asm/page.h>
5071 +
5072 +#endif /* _ASM_UBICOM32_ENTRY_H */
5073 --- /dev/null
5074 +++ b/arch/ubicom32/include/asm/errno.h
5075 @@ -0,0 +1,33 @@
5076 +/*
5077 + * arch/ubicom32/include/asm/errno.h
5078 + *   Generic errno.h for Ubicom32 architecture.
5079 + *
5080 + * (C) Copyright 2009, Ubicom, Inc.
5081 + *
5082 + * This file is part of the Ubicom32 Linux Kernel Port.
5083 + *
5084 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5085 + * it and/or modify it under the terms of the GNU General Public License
5086 + * as published by the Free Software Foundation, either version 2 of the
5087 + * License, or (at your option) any later version.
5088 + *
5089 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5090 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5091 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5092 + * the GNU General Public License for more details.
5093 + *
5094 + * You should have received a copy of the GNU General Public License
5095 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5096 + * see <http://www.gnu.org/licenses/>.
5097 + *
5098 + * Ubicom32 implementation derived from (with many thanks):
5099 + *   arch/m68knommu
5100 + *   arch/blackfin
5101 + *   arch/parisc
5102 + */
5103 +#ifndef _ASM_UBICOM32_ERRNO_H
5104 +#define _ASM_UBICOM32_ERRNO_H
5105 +
5106 +#include <asm-generic/errno.h>
5107 +
5108 +#endif /* _ASM_UBICOM32_ERRNO_H */
5109 --- /dev/null
5110 +++ b/arch/ubicom32/include/asm/fb.h
5111 @@ -0,0 +1,39 @@
5112 +/*
5113 + * arch/ubicom32/include/asm/fb.h
5114 + *   Definition of fb_is_primary_device() for Ubicom32 architecture.
5115 + *
5116 + * (C) Copyright 2009, Ubicom, Inc.
5117 + *
5118 + * This file is part of the Ubicom32 Linux Kernel Port.
5119 + *
5120 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5121 + * it and/or modify it under the terms of the GNU General Public License
5122 + * as published by the Free Software Foundation, either version 2 of the
5123 + * License, or (at your option) any later version.
5124 + *
5125 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5126 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5127 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5128 + * the GNU General Public License for more details.
5129 + *
5130 + * You should have received a copy of the GNU General Public License
5131 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5132 + * see <http://www.gnu.org/licenses/>.
5133 + *
5134 + * Ubicom32 implementation derived from (with many thanks):
5135 + *   arch/m68knommu
5136 + *   arch/blackfin
5137 + *   arch/parisc
5138 + */
5139 +#ifndef _ASM_UBICOM32_FB_H
5140 +#define _ASM_UBICOM32_FB_H
5141 +#include <linux/fb.h>
5142 +
5143 +#define fb_pgprotect(...) do {} while (0)
5144 +
5145 +static inline int fb_is_primary_device(struct fb_info *info)
5146 +{
5147 +       return 0;
5148 +}
5149 +
5150 +#endif /* _ASM_UBICOM32_FB_H */
5151 --- /dev/null
5152 +++ b/arch/ubicom32/include/asm/fcntl.h
5153 @@ -0,0 +1,38 @@
5154 +/*
5155 + * arch/ubicom32/include/asm/fcntl.h
5156 + *   File control bit definitions for Ubicom32 architecture.
5157 + *
5158 + * (C) Copyright 2009, Ubicom, Inc.
5159 + *
5160 + * This file is part of the Ubicom32 Linux Kernel Port.
5161 + *
5162 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5163 + * it and/or modify it under the terms of the GNU General Public License
5164 + * as published by the Free Software Foundation, either version 2 of the
5165 + * License, or (at your option) any later version.
5166 + *
5167 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5168 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5169 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5170 + * the GNU General Public License for more details.
5171 + *
5172 + * You should have received a copy of the GNU General Public License
5173 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5174 + * see <http://www.gnu.org/licenses/>.
5175 + *
5176 + * Ubicom32 implementation derived from (with many thanks):
5177 + *   arch/m68knommu
5178 + *   arch/blackfin
5179 + *   arch/parisc
5180 + */
5181 +#ifndef _ASM_UBICOM32_FCNTL_H
5182 +#define _ASM_UBICOM32_FCNTL_H
5183 +
5184 +#define O_DIRECTORY    040000  /* must be a directory */
5185 +#define O_NOFOLLOW     0100000 /* don't follow links */
5186 +#define O_DIRECT       0200000 /* direct disk access hint - currently ignored */
5187 +#define O_LARGEFILE    0400000
5188 +
5189 +#include <asm-generic/fcntl.h>
5190 +
5191 +#endif /* _ASM_UBICOM32_FCNTL_H */
5192 --- /dev/null
5193 +++ b/arch/ubicom32/include/asm/flat.h
5194 @@ -0,0 +1,73 @@
5195 +/*
5196 + * arch/ubicom32/include/asm/flat.h
5197 + *   Definitions to support flat-format executables.
5198 + *
5199 + * (C) Copyright 2009, Ubicom, Inc.
5200 + *
5201 + * This file is part of the Ubicom32 Linux Kernel Port.
5202 + *
5203 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5204 + * it and/or modify it under the terms of the GNU General Public License
5205 + * as published by the Free Software Foundation, either version 2 of the
5206 + * License, or (at your option) any later version.
5207 + *
5208 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5209 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5210 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5211 + * the GNU General Public License for more details.
5212 + *
5213 + * You should have received a copy of the GNU General Public License
5214 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5215 + * see <http://www.gnu.org/licenses/>.
5216 + *
5217 + * Ubicom32 implementation derived from (with many thanks):
5218 + *   arch/m68knommu
5219 + *   arch/blackfin
5220 + *   arch/parisc
5221 + */
5222 +
5223 +#ifndef _ASM_UBICOM32_FLAT_H
5224 +#define _ASM_UBICOM32_FLAT_H
5225 +
5226 +#define ARCH_FLAT_ALIGN 0x80
5227 +#define ARCH_FLAT_ALIGN_TEXT 1
5228 +
5229 +#define  R_UBICOM32_32         2
5230 +#define  R_UBICOM32_HI24       7
5231 +#define  R_UBICOM32_LO7_S      8
5232 +#define  R_UBICOM32_LO7_2_S    9
5233 +#define  R_UBICOM32_LO7_4_S    10
5234 +#define  R_UBICOM32_LO7_D      11
5235 +#define  R_UBICOM32_LO7_2_D    12
5236 +#define  R_UBICOM32_LO7_4_D    13
5237 +#define  R_UBICOM32_LO7_CALLI  15
5238 +#define  R_UBICOM32_LO16_CALLI 16
5239 +
5240 +extern void ubicom32_flat_put_addr_at_rp(unsigned long *rp, u32_t val, u32_t rval, unsigned long  *p);
5241 +extern unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp, u32_t relval, u32_t flags, unsigned long *p);
5242 +
5243 +#define        flat_stack_align(sp)                    /* nothing needed */
5244 +#define        flat_argvp_envp_on_stack()              1
5245 +#define        flat_old_ram_flag(flags)                (flags)
5246 +#define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
5247 +#define        flat_get_addr_from_rp(rp, relval, flags, p)     (ubicom32_flat_get_addr_from_rp(rp, relval,flags, p))
5248 +#define        flat_put_addr_at_rp(rp, val, relval)    do {ubicom32_flat_put_addr_at_rp(rp, val, relval, &persistent);} while(0)
5249 +#define        flat_get_relocate_addr(rel)             ((persistent) ? (persistent & 0x07ffffff) : (rel & 0x07ffffff))
5250 +
5251 +static inline int flat_set_persistent(unsigned int relval, unsigned long *p)
5252 +{
5253 +       if (*p) {
5254 +               return 0;
5255 +       } else {
5256 +               if ((relval >> 27) != R_UBICOM32_32) {
5257 +                       /*
5258 +                        * Something other than UBICOM32_32. The next entry has the relocation.
5259 +                        */
5260 +                       *p = relval;
5261 +                       return 1;
5262 +               }
5263 +       }
5264 +       return 0;
5265 +}
5266 +
5267 +#endif /* _ASM_UBICOM32_FLAT_H */
5268 --- /dev/null
5269 +++ b/arch/ubicom32/include/asm/fpu.h
5270 @@ -0,0 +1,37 @@
5271 +/*
5272 + * arch/ubicom32/include/asm/fpu.h
5273 + *   Floating point state definitions for Ubicom32 architecture.
5274 + *
5275 + * (C) Copyright 2009, Ubicom, Inc.
5276 + *
5277 + * This file is part of the Ubicom32 Linux Kernel Port.
5278 + *
5279 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5280 + * it and/or modify it under the terms of the GNU General Public License
5281 + * as published by the Free Software Foundation, either version 2 of the
5282 + * License, or (at your option) any later version.
5283 + *
5284 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5285 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5286 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5287 + * the GNU General Public License for more details.
5288 + *
5289 + * You should have received a copy of the GNU General Public License
5290 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5291 + * see <http://www.gnu.org/licenses/>.
5292 + *
5293 + * Ubicom32 implementation derived from (with many thanks):
5294 + *   arch/m68knommu
5295 + *   arch/blackfin
5296 + *   arch/parisc
5297 + */
5298 +#ifndef _ASM_UBICOM32_FPU_H
5299 +#define _ASM_UBICOM32_FPU_H
5300 +
5301 +/*
5302 + * MAX floating point unit state size (FSAVE/FRESTORE)
5303 + */
5304 +/* No FP unit present then... */
5305 +#define FPSTATESIZE (2) /* dummy size */
5306 +
5307 +#endif /* _ASM_UBICOM32_FPU_H */
5308 --- /dev/null
5309 +++ b/arch/ubicom32/include/asm/futex.h
5310 @@ -0,0 +1,33 @@
5311 +/*
5312 + * arch/ubicom32/include/asm/futex.h
5313 + *   Generic futex.h for Ubicom32 architecture.
5314 + *
5315 + * (C) Copyright 2009, Ubicom, Inc.
5316 + *
5317 + * This file is part of the Ubicom32 Linux Kernel Port.
5318 + *
5319 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5320 + * it and/or modify it under the terms of the GNU General Public License
5321 + * as published by the Free Software Foundation, either version 2 of the
5322 + * License, or (at your option) any later version.
5323 + *
5324 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5325 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5326 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5327 + * the GNU General Public License for more details.
5328 + *
5329 + * You should have received a copy of the GNU General Public License
5330 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5331 + * see <http://www.gnu.org/licenses/>.
5332 + *
5333 + * Ubicom32 implementation derived from (with many thanks):
5334 + *   arch/m68knommu
5335 + *   arch/blackfin
5336 + *   arch/parisc
5337 + */
5338 +#ifndef _ASM_UBICOM32_FUTEX_H
5339 +#define _ASM_UBICOM32_FUTEX_H
5340 +
5341 +#include <asm-generic/futex.h>
5342 +
5343 +#endif /* _ASM_UBICOM32_FUTEX_H */
5344 --- /dev/null
5345 +++ b/arch/ubicom32/include/asm/.gitignore
5346 @@ -0,0 +1 @@
5347 +/ocm_size.h
5348 --- /dev/null
5349 +++ b/arch/ubicom32/include/asm/gpio.h
5350 @@ -0,0 +1,451 @@
5351 +/*
5352 + * arch/ubicom32/include/asm/gpio.h
5353 + *   Definitions for GPIO operations on Ubicom32 architecture.
5354 + *
5355 + * (C) Copyright 2009, Ubicom, Inc.
5356 + *
5357 + * This file is part of the Ubicom32 Linux Kernel Port.
5358 + *
5359 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5360 + * it and/or modify it under the terms of the GNU General Public License
5361 + * as published by the Free Software Foundation, either version 2 of the
5362 + * License, or (at your option) any later version.
5363 + *
5364 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5365 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5366 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5367 + * the GNU General Public License for more details.
5368 + *
5369 + * You should have received a copy of the GNU General Public License
5370 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5371 + * see <http://www.gnu.org/licenses/>.
5372 + *
5373 + * Ubicom32 implementation derived from (with many thanks):
5374 + *   arch/m68knommu
5375 + *   arch/blackfin
5376 + *   arch/parisc
5377 + */
5378 +#ifndef _ASM_UBICOM32_GPIO_H
5379 +#define _ASM_UBICOM32_GPIO_H
5380 +
5381 +#include <linux/compiler.h>
5382 +#include <asm/irq.h>
5383 +
5384 +#include <asm/ip5000.h>
5385 +
5386 +#define ARCH_NR_GPIOS           512
5387 +#define MAX_UBICOM_ONCHIP_GPIO   (9 * 32)
5388 +
5389 +/*
5390 + * Macros for manipulating GPIO numbers
5391 + */
5392 +#define gpio_bit(gn)                   (1 << (gn & 0x1f))
5393 +#define gpio_bank(gn)                  (gn >> 5)
5394 +
5395 +#define gpio_pin_index(gn)             (gn & 0x1f)
5396 +#define gpio_port_index(gn)            (gn >> 5)
5397 +
5398 +#define GPIO_RA_0    ((32 * 0) + 0)
5399 +#define GPIO_RA_1    ((32 * 0) + 1)
5400 +#define GPIO_RA_2    ((32 * 0) + 2)
5401 +#define GPIO_RA_3    ((32 * 0) + 3)
5402 +#define GPIO_RA_4    ((32 * 0) + 4)
5403 +#define GPIO_RA_5    ((32 * 0) + 5)
5404 +#define GPIO_RA_6    ((32 * 0) + 6)
5405 +#define GPIO_RA_7    ((32 * 0) + 7)
5406 +
5407 +#define GPIO_RB_0    ((32 * 1) + 0)
5408 +#define GPIO_RB_1    ((32 * 1) + 1)
5409 +#define GPIO_RB_2    ((32 * 1) + 2)
5410 +#define GPIO_RB_3    ((32 * 1) + 3)
5411 +#define GPIO_RB_4    ((32 * 1) + 4)
5412 +#define GPIO_RB_5    ((32 * 1) + 5)
5413 +#define GPIO_RB_6    ((32 * 1) + 6)
5414 +#define GPIO_RB_7    ((32 * 1) + 7)
5415 +#define GPIO_RB_8    ((32 * 1) + 8)
5416 +#define GPIO_RB_9    ((32 * 1) + 9)
5417 +#define GPIO_RB_10   ((32 * 1) + 10)
5418 +#define GPIO_RB_11   ((32 * 1) + 11)
5419 +#define GPIO_RB_12   ((32 * 1) + 12)
5420 +#define GPIO_RB_13   ((32 * 1) + 13)
5421 +#define GPIO_RB_14   ((32 * 1) + 14)
5422 +#define GPIO_RB_15   ((32 * 1) + 15)
5423 +#define GPIO_RB_16   ((32 * 1) + 16)
5424 +#define GPIO_RB_17   ((32 * 1) + 17)
5425 +#define GPIO_RB_18   ((32 * 1) + 18)
5426 +#define GPIO_RB_19   ((32 * 1) + 19)
5427 +
5428 +#define GPIO_RC_0    ((32 * 2) + 0)
5429 +#define GPIO_RC_1    ((32 * 2) + 1)
5430 +#define GPIO_RC_2    ((32 * 2) + 2)
5431 +#define GPIO_RC_3    ((32 * 2) + 3)
5432 +#define GPIO_RC_4    ((32 * 2) + 4)
5433 +#define GPIO_RC_5    ((32 * 2) + 5)
5434 +#define GPIO_RC_6    ((32 * 2) + 6)
5435 +#define GPIO_RC_7    ((32 * 2) + 7)
5436 +#define GPIO_RC_8    ((32 * 2) + 8)
5437 +#define GPIO_RC_9    ((32 * 2) + 9)
5438 +#define GPIO_RC_10   ((32 * 2) + 10)
5439 +#define GPIO_RC_11   ((32 * 2) + 11)
5440 +#define GPIO_RC_12   ((32 * 2) + 12)
5441 +#define GPIO_RC_13   ((32 * 2) + 13)
5442 +#define GPIO_RC_14   ((32 * 2) + 14)
5443 +#define GPIO_RC_15   ((32 * 2) + 15)
5444 +#define GPIO_RC_16   ((32 * 2) + 16)
5445 +#define GPIO_RC_17   ((32 * 2) + 17)
5446 +#define GPIO_RC_18   ((32 * 2) + 18)
5447 +#define GPIO_RC_19   ((32 * 2) + 19)
5448 +#define GPIO_RC_20   ((32 * 2) + 20)
5449 +#define GPIO_RC_21   ((32 * 2) + 21)
5450 +#define GPIO_RC_22   ((32 * 2) + 22)
5451 +#define GPIO_RC_23   ((32 * 2) + 23)
5452 +#define GPIO_RC_24   ((32 * 2) + 24)
5453 +#define GPIO_RC_25   ((32 * 2) + 25)
5454 +#define GPIO_RC_26   ((32 * 2) + 26)
5455 +#define GPIO_RC_27   ((32 * 2) + 27)
5456 +#define GPIO_RC_28   ((32 * 2) + 28)
5457 +#define GPIO_RC_29   ((32 * 2) + 29)
5458 +#define GPIO_RC_30   ((32 * 2) + 30)
5459 +#define GPIO_RC_31   ((32 * 2) + 31)
5460 +
5461 +#define GPIO_RD_0    ((32 * 3) + 0)
5462 +#define GPIO_RD_1    ((32 * 3) + 1)
5463 +#define GPIO_RD_2    ((32 * 3) + 2)
5464 +#define GPIO_RD_3    ((32 * 3) + 3)
5465 +#define GPIO_RD_4    ((32 * 3) + 4)
5466 +#define GPIO_RD_5    ((32 * 3) + 5)
5467 +#define GPIO_RD_6    ((32 * 3) + 6)
5468 +#define GPIO_RD_7    ((32 * 3) + 7)
5469 +#define GPIO_RD_8    ((32 * 3) + 8)
5470 +#define GPIO_RD_9    ((32 * 3) + 9)
5471 +#define GPIO_RD_10   ((32 * 3) + 10)
5472 +#define GPIO_RD_11   ((32 * 3) + 11)
5473 +
5474 +#define GPIO_RE_0    ((32 * 4) + 0)
5475 +#define GPIO_RE_1    ((32 * 4) + 1)
5476 +#define GPIO_RE_2    ((32 * 4) + 2)
5477 +#define GPIO_RE_3    ((32 * 4) + 3)
5478 +#define GPIO_RE_4    ((32 * 4) + 4)
5479 +#define GPIO_RE_5    ((32 * 4) + 5)
5480 +#define GPIO_RE_6    ((32 * 4) + 6)
5481 +#define GPIO_RE_7    ((32 * 4) + 7)
5482 +
5483 +#define GPIO_RF_0    ((32 * 5) + 0)
5484 +#define GPIO_RF_1    ((32 * 5) + 1)
5485 +#define GPIO_RF_2    ((32 * 5) + 2)
5486 +#define GPIO_RF_3    ((32 * 5) + 3)
5487 +#define GPIO_RF_4    ((32 * 5) + 4)
5488 +#define GPIO_RF_5    ((32 * 5) + 5)
5489 +#define GPIO_RF_6    ((32 * 5) + 6)
5490 +#define GPIO_RF_7    ((32 * 5) + 7)
5491 +#define GPIO_RF_8    ((32 * 5) + 8)
5492 +#define GPIO_RF_9    ((32 * 5) + 9)
5493 +#define GPIO_RF_10   ((32 * 5) + 10)
5494 +#define GPIO_RF_11   ((32 * 5) + 11)
5495 +#define GPIO_RF_12   ((32 * 5) + 12)
5496 +#define GPIO_RF_13   ((32 * 5) + 13)
5497 +#define GPIO_RF_14   ((32 * 5) + 14)
5498 +#define GPIO_RF_15   ((32 * 5) + 15)
5499 +
5500 +#define GPIO_RG_0    ((32 * 6) + 0)
5501 +#define GPIO_RG_1    ((32 * 6) + 1)
5502 +#define GPIO_RG_2    ((32 * 6) + 2)
5503 +#define GPIO_RG_3    ((32 * 6) + 3)
5504 +#define GPIO_RG_4    ((32 * 6) + 4)
5505 +#define GPIO_RG_5    ((32 * 6) + 5)
5506 +#define GPIO_RG_6    ((32 * 6) + 6)
5507 +#define GPIO_RG_7    ((32 * 6) + 7)
5508 +#define GPIO_RG_8    ((32 * 6) + 8)
5509 +#define GPIO_RG_9    ((32 * 6) + 9)
5510 +#define GPIO_RG_10   ((32 * 6) + 10)
5511 +#define GPIO_RG_11   ((32 * 6) + 11)
5512 +#define GPIO_RG_12   ((32 * 6) + 12)
5513 +#define GPIO_RG_13   ((32 * 6) + 13)
5514 +#define GPIO_RG_14   ((32 * 6) + 14)
5515 +#define GPIO_RG_15   ((32 * 6) + 15)
5516 +#define GPIO_RG_16   ((32 * 6) + 16)
5517 +#define GPIO_RG_17   ((32 * 6) + 17)
5518 +#define GPIO_RG_18   ((32 * 6) + 18)
5519 +#define GPIO_RG_19   ((32 * 6) + 19)
5520 +#define GPIO_RG_20   ((32 * 6) + 20)
5521 +#define GPIO_RG_21   ((32 * 6) + 21)
5522 +#define GPIO_RG_22   ((32 * 6) + 22)
5523 +#define GPIO_RG_23   ((32 * 6) + 23)
5524 +#define GPIO_RG_24   ((32 * 6) + 24)
5525 +#define GPIO_RG_25   ((32 * 6) + 25)
5526 +#define GPIO_RG_26   ((32 * 6) + 26)
5527 +#define GPIO_RG_27   ((32 * 6) + 27)
5528 +#define GPIO_RG_28   ((32 * 6) + 28)
5529 +#define GPIO_RG_29   ((32 * 6) + 29)
5530 +#define GPIO_RG_30   ((32 * 6) + 30)
5531 +#define GPIO_RG_31   ((32 * 6) + 31)
5532 +
5533 +#define GPIO_RH_0    ((32 * 7) + 0)
5534 +#define GPIO_RH_1    ((32 * 7) + 1)
5535 +#define GPIO_RH_2    ((32 * 7) + 2)
5536 +#define GPIO_RH_3    ((32 * 7) + 3)
5537 +#define GPIO_RH_4    ((32 * 7) + 4)
5538 +#define GPIO_RH_5    ((32 * 7) + 5)
5539 +#define GPIO_RH_6    ((32 * 7) + 6)
5540 +#define GPIO_RH_7    ((32 * 7) + 7)
5541 +#define GPIO_RH_8    ((32 * 7) + 8)
5542 +#define GPIO_RH_9    ((32 * 7) + 9)
5543 +
5544 +#define GPIO_RI_0    ((32 * 8) + 0)
5545 +#define GPIO_RI_1    ((32 * 8) + 1)
5546 +#define GPIO_RI_2    ((32 * 8) + 2)
5547 +#define GPIO_RI_3    ((32 * 8) + 3)
5548 +#define GPIO_RI_4    ((32 * 8) + 4)
5549 +#define GPIO_RI_5    ((32 * 8) + 5)
5550 +#define GPIO_RI_6    ((32 * 8) + 6)
5551 +#define GPIO_RI_7    ((32 * 8) + 7)
5552 +#define GPIO_RI_8    ((32 * 8) + 8)
5553 +#define GPIO_RI_9    ((32 * 8) + 9)
5554 +#define GPIO_RI_10   ((32 * 8) + 10)
5555 +#define GPIO_RI_11   ((32 * 8) + 11)
5556 +#define GPIO_RI_12   ((32 * 8) + 12)
5557 +#define GPIO_RI_13   ((32 * 8) + 13)
5558 +
5559 +/*
5560 + * The following section defines extra GPIO available to some boards.
5561 + * These GPIO are generally external to the processor (i.e. SPI/I2C
5562 + * expander chips).
5563 + *
5564 + * Note that these defines show all possible GPIO available, however,
5565 + * depending on the actual board configuration, some GPIO are not
5566 + * available for use.
5567 + */
5568 +#ifdef CONFIG_IP7500MEDIA
5569 +/*
5570 + * U15
5571 + */
5572 +#define IP7500MEDIA_U15_BASE   (32 * 10)
5573 +#define IP7500MEDIA_IO0                (IP7500MEDIA_U15_BASE + 0)
5574 +#define IP7500MEDIA_IO1                (IP7500MEDIA_U15_BASE + 1)
5575 +#define IP7500MEDIA_IO2                (IP7500MEDIA_U15_BASE + 2)
5576 +#define IP7500MEDIA_IO3                (IP7500MEDIA_U15_BASE + 3)
5577 +#define IP7500MEDIA_IO4                (IP7500MEDIA_U15_BASE + 4)
5578 +#define IP7500MEDIA_IO5                (IP7500MEDIA_U15_BASE + 5)
5579 +#define IP7500MEDIA_IO6                (IP7500MEDIA_U15_BASE + 6)
5580 +#define IP7500MEDIA_IO7                (IP7500MEDIA_U15_BASE + 7)
5581 +
5582 +/*
5583 + * U16
5584 + */
5585 +#define IP7500MEDIA_U16_BASE   (32 * 11)
5586 +#define IP7500MEDIA_IO8                (IP7500MEDIA_U16_BASE + 0)
5587 +#define IP7500MEDIA_IO9                (IP7500MEDIA_U16_BASE + 1)
5588 +#define IP7500MEDIA_IO10       (IP7500MEDIA_U16_BASE + 2)
5589 +#define IP7500MEDIA_IO11       (IP7500MEDIA_U16_BASE + 3)
5590 +#define IP7500MEDIA_IO12       (IP7500MEDIA_U16_BASE + 4)
5591 +#define IP7500MEDIA_IO13       (IP7500MEDIA_U16_BASE + 5)
5592 +#define IP7500MEDIA_IO14       (IP7500MEDIA_U16_BASE + 6)
5593 +#define IP7500MEDIA_IO15       (IP7500MEDIA_U16_BASE + 7)
5594 +
5595 +/*
5596 + * U17
5597 + */
5598 +#define IP7500MEDIA_U17_BASE   (32 * 12)
5599 +#define IP7500MEDIA_IO16       (IP7500MEDIA_U17_BASE + 0)
5600 +#define IP7500MEDIA_IO17       (IP7500MEDIA_U17_BASE + 1)
5601 +#define IP7500MEDIA_IO18       (IP7500MEDIA_U17_BASE + 2)
5602 +#define IP7500MEDIA_IO19       (IP7500MEDIA_U17_BASE + 3)
5603 +#define IP7500MEDIA_IO20       (IP7500MEDIA_U17_BASE + 4)
5604 +#define IP7500MEDIA_IO21       (IP7500MEDIA_U17_BASE + 5)
5605 +#define IP7500MEDIA_IO22       (IP7500MEDIA_U17_BASE + 6)
5606 +#define IP7500MEDIA_IO23       (IP7500MEDIA_U17_BASE + 7)
5607 +
5608 +/*
5609 + * U18
5610 + */
5611 +#define IP7500MEDIA_U18_BASE   (32 * 13)
5612 +#define IP7500MEDIA_IO24       (IP7500MEDIA_U18_BASE + 0)
5613 +#define IP7500MEDIA_IO25       (IP7500MEDIA_U18_BASE + 1)
5614 +#define IP7500MEDIA_IO26       (IP7500MEDIA_U18_BASE + 2)
5615 +#define IP7500MEDIA_IO27       (IP7500MEDIA_U18_BASE + 3)
5616 +#define IP7500MEDIA_IO28       (IP7500MEDIA_U18_BASE + 4)
5617 +#define IP7500MEDIA_IO29       (IP7500MEDIA_U18_BASE + 5)
5618 +#define IP7500MEDIA_IO30       (IP7500MEDIA_U18_BASE + 6)
5619 +#define IP7500MEDIA_IO31       (IP7500MEDIA_U18_BASE + 7)
5620 +#endif
5621 +
5622 +#ifdef CONFIG_IP7145DPF
5623 +/*
5624 + * U48
5625 + */
5626 +#define IP7145DPF_U48_BASE     (32 * 10)
5627 +#define IP7145DPF_IO0          (IP7145DPF_U48_BASE + 0)
5628 +#define IP7145DPF_IO1          (IP7145DPF_U48_BASE + 1)
5629 +#define IP7145DPF_IO2          (IP7145DPF_U48_BASE + 2)
5630 +#define IP7145DPF_IO3          (IP7145DPF_U48_BASE + 3)
5631 +#define IP7145DPF_IO4          (IP7145DPF_U48_BASE + 4)
5632 +#define IP7145DPF_IO5          (IP7145DPF_U48_BASE + 5)
5633 +#define IP7145DPF_IO6          (IP7145DPF_U48_BASE + 6)
5634 +#define IP7145DPF_IO7          (IP7145DPF_U48_BASE + 7)
5635 +
5636 +/*
5637 + * U72
5638 + */
5639 +#define IP7145DPF_U72_BASE     (32 * 11)
5640 +#define IP7145DPF_IOB0         (IP7145DPF_U72_BASE + 0)
5641 +#define IP7145DPF_IOB1         (IP7145DPF_U72_BASE + 1)
5642 +#define IP7145DPF_IOB2         (IP7145DPF_U72_BASE + 2)
5643 +#define IP7145DPF_IOB3         (IP7145DPF_U72_BASE + 3)
5644 +#define IP7145DPF_IOB4         (IP7145DPF_U72_BASE + 4)
5645 +#define IP7145DPF_IOB5         (IP7145DPF_U72_BASE + 5)
5646 +#define IP7145DPF_IOB6         (IP7145DPF_U72_BASE + 6)
5647 +#define IP7145DPF_IOB7         (IP7145DPF_U72_BASE + 7)
5648 +#endif
5649 +
5650 +#include <asm-generic/gpio.h>
5651 +
5652 +/*
5653 + * The following macros bypass gpiolib to generate direct references
5654 + * to the port registers.  These assume, minimally, that either
5655 + * gpio_direction_input() or gpio_direction_output() have already been
5656 + * called to setup the pin direction and to enable the pin function to
5657 + * be gpio.  These macros generate the hardware port address based on
5658 + * the assumption that all ports are 32 bits wide (even though we know
5659 + * they are not).  This is so we can efficiently turn pin numbers into
5660 + * port addresses without a lookup.
5661 + *
5662 + * These operations must be done in one instruction to prevent clobbering
5663 + * other thread's accesses to the same port.
5664 + */
5665 +#define UBICOM32_GPIO_ENABLE(pin)                              \
5666 +       do {                                                    \
5667 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5668 +                               :                                                                               \
5669 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
5670 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5671 +                               : "cc", "memory"                                                                \
5672 +               );                                                                                              \
5673 +       } while (0);
5674 +
5675 +#define UBICOM32_GPIO_DISABLE(pin)                             \
5676 +       do {                                                    \
5677 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5678 +                               :                                                                               \
5679 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
5680 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5681 +                               : "cc", "memory"                                                                \
5682 +               );                                                                                              \
5683 +       } while (0);
5684 +
5685 +#define UBICOM32_GPIO_SET_PIN_INPUT(pin)                       \
5686 +       do {                                                    \
5687 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5688 +                               :                                                                               \
5689 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
5690 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5691 +                               : "cc", "memory"                                                                \
5692 +               );                                                                                              \
5693 +       } while (0);
5694 +
5695 +#define UBICOM32_GPIO_SET_PIN_OUTPUT(pin)                      \
5696 +       do {                                                    \
5697 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5698 +                               :                                                                               \
5699 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
5700 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5701 +                               : "cc", "memory"                                                                \
5702 +               );                                                                                              \
5703 +       } while (0);
5704 +
5705 +#define UBICOM32_GPIO_SET_PIN_TOGGLE(pin)                      \
5706 +       do {                                                    \
5707 +               asm volatile ("xor.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5708 +                               :                                                                               \
5709 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5710 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5711 +                               : "cc", "memory"                                                                \
5712 +               );                                                                                              \
5713 +       } while (0);
5714 +
5715 +#define UBICOM32_GPIO_SET_PIN_HIGH(pin)                                \
5716 +       do {                                                    \
5717 +               asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
5718 +                               :                                                                               \
5719 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5720 +                                 [mask] "d" (gpio_bit(pin))                                                    \
5721 +                               : "cc", "memory"                                                                \
5722 +               );                                                                                              \
5723 +       } while (0);
5724 +
5725 +#define UBICOM32_GPIO_SET_PIN_LOW(pin)                         \
5726 +       do {                                                    \
5727 +               asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
5728 +                               :                                                                               \
5729 +                               : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
5730 +                                 [mask] "d" (~gpio_bit(pin))                                                   \
5731 +                               : "cc", "memory"                                                                \
5732 +               );                                                                                              \
5733 +       } while (0);
5734 +
5735 +#define UBICOM32_GPIO_SET_PIN(pin, val) \
5736 +  if ( val ) {                          \
5737 +    UBICOM32_GPIO_SET_PIN_HIGH(pin);    \
5738 +  } else {                              \
5739 +    UBICOM32_GPIO_SET_PIN_LOW(pin);    \
5740 +  }
5741 +
5742 +#define UBICOM32_GPIO_GET_PIN(pin)                                    \
5743 +  (0 != (UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_in  \
5744 +        & gpio_bit(pin)))
5745 +
5746 +
5747 +static inline int gpio_get_value(unsigned gpio) 
5748 +{
5749 +  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5750 +    return UBICOM32_GPIO_GET_PIN(gpio);
5751 +  else
5752 +    return __gpio_get_value(gpio);
5753 +}
5754 +
5755 +static inline void gpio_set_value(unsigned gpio, int value)
5756 +{
5757 +  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5758 +    {
5759 +      UBICOM32_GPIO_SET_PIN(gpio, value);
5760 +    }
5761 +  else
5762 +    {
5763 +      __gpio_set_value(gpio, value);
5764 +    }
5765 +}
5766 +
5767 +static inline int gpio_cansleep(unsigned gpio)
5768 +{
5769 +  return __gpio_cansleep(gpio);
5770 +}
5771 +
5772 +static inline int gpio_to_irq(unsigned gpio)
5773 +{
5774 +#if defined(IP5000) || defined(IP5000_REV2)
5775 +  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5776 +    return 25;
5777 +  else
5778 +    return -ENXIO;
5779 +
5780 +#elif defined(IP7000) || defined(IP7000_REV2)
5781 +  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5782 +    return 44 + (gpio - GPIO_RA_4);
5783 +  else
5784 +    return -ENXIO;
5785 +
5786 +#else
5787 +    return -ENXIO;
5788 +
5789 +#endif
5790 +}
5791 +
5792 +static inline int irq_to_gpio(unsigned gpio)
5793 +{
5794 +       return -ENXIO;
5795 +}
5796 +
5797 +extern struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio);
5798 +
5799 +extern int __init ubi_gpio_init(void);
5800 +
5801 +#endif /* _ASM_UBICOM32_GPIO_H */
5802 --- /dev/null
5803 +++ b/arch/ubicom32/include/asm/hardirq.h
5804 @@ -0,0 +1,55 @@
5805 +/*
5806 + * arch/ubicom32/include/asm/hardirq.h
5807 + *   Definition of ack_bad_irq() for Ubicom32 architecture.
5808 + *
5809 + * (C) Copyright 2009, Ubicom, Inc.
5810 + * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
5811 + * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
5812 + * Copyright (C) 2001 MIPS Technologies, Inc.
5813 + *
5814 + * This file is part of the Ubicom32 Linux Kernel Port.
5815 + *
5816 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5817 + * it and/or modify it under the terms of the GNU General Public License
5818 + * as published by the Free Software Foundation, either version 2 of the
5819 + * License, or (at your option) any later version.
5820 + *
5821 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5822 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5823 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5824 + * the GNU General Public License for more details.
5825 + *
5826 + * You should have received a copy of the GNU General Public License
5827 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5828 + * see <http://www.gnu.org/licenses/>.
5829 + *
5830 + * Ubicom32 implementation derived from (with many thanks):
5831 + *   arch/m68knommu
5832 + *   arch/blackfin
5833 + *   arch/parisc
5834 + */
5835 +#ifndef _ASM_UBICOM32_HARDIRQ_H
5836 +#define _ASM_UBICOM32_HARDIRQ_H
5837 +
5838 +#include <linux/threads.h>
5839 +#include <linux/irq.h>
5840 +
5841 +/*
5842 + * The hardirq mask has to be large enough to have space
5843 + * for potentially all IRQ sources in the system nesting
5844 + * on a single CPU.  For Ubicom32, we have 64 IRQ sources.
5845 + */
5846 +#define HARDIRQ_BITS   6
5847 +#if (1 << HARDIRQ_BITS) < NR_IRQS
5848 +# error HARDIRQ_BITS is too low!
5849 +#endif
5850 +
5851 +typedef struct {
5852 +       unsigned int __softirq_pending;
5853 +} ____cacheline_aligned irq_cpustat_t;
5854 +
5855 +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
5856 +
5857 +extern void ack_bad_irq(unsigned int irq);
5858 +
5859 +#endif /* _ASM_UBICOM32_HARDIRQ_H */
5860 --- /dev/null
5861 +++ b/arch/ubicom32/include/asm/hw_irq.h
5862 @@ -0,0 +1,31 @@
5863 +/*
5864 + * arch/ubicom32/include/asm/hw_irq.h
5865 + *   Ubicom32 architecture APIC support.
5866 + *
5867 + * (C) Copyright 2009, Ubicom, Inc.
5868 + *
5869 + * This file is part of the Ubicom32 Linux Kernel Port.
5870 + *
5871 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5872 + * it and/or modify it under the terms of the GNU General Public License
5873 + * as published by the Free Software Foundation, either version 2 of the
5874 + * License, or (at your option) any later version.
5875 + *
5876 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5877 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5878 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5879 + * the GNU General Public License for more details.
5880 + *
5881 + * You should have received a copy of the GNU General Public License
5882 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5883 + * see <http://www.gnu.org/licenses/>.
5884 + *
5885 + * Ubicom32 implementation derived from (with many thanks):
5886 + *   arch/m68knommu
5887 + *   arch/blackfin
5888 + *   arch/parisc
5889 + */
5890 +#ifndef _ASM_UBICOM32_HW_IRQ_H
5891 +#define _ASM_UBICOM32_HW_IRQ_H
5892 +
5893 +#endif /* _ASM_UBICOM32_HW_IRQ_H */
5894 --- /dev/null
5895 +++ b/arch/ubicom32/include/asm/ioctl.h
5896 @@ -0,0 +1,33 @@
5897 +/*
5898 + * arch/ubicom32/include/asm/ioctl.h
5899 + *   Generic ioctl.h for Ubicom32 architecture.
5900 + *
5901 + * (C) Copyright 2009, Ubicom, Inc.
5902 + *
5903 + * This file is part of the Ubicom32 Linux Kernel Port.
5904 + *
5905 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5906 + * it and/or modify it under the terms of the GNU General Public License
5907 + * as published by the Free Software Foundation, either version 2 of the
5908 + * License, or (at your option) any later version.
5909 + *
5910 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5911 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5912 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5913 + * the GNU General Public License for more details.
5914 + *
5915 + * You should have received a copy of the GNU General Public License
5916 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5917 + * see <http://www.gnu.org/licenses/>.
5918 + *
5919 + * Ubicom32 implementation derived from (with many thanks):
5920 + *   arch/m68knommu
5921 + *   arch/blackfin
5922 + *   arch/parisc
5923 + */
5924 +#ifndef _ASM_UBICOM32_IOCTL_H
5925 +#define _ASM_UBICOM32_IOCTL_H
5926 +
5927 +#include <asm-generic/ioctl.h>
5928 +
5929 +#endif /* _ASM_UBICOM32_IOCTL_H */
5930 --- /dev/null
5931 +++ b/arch/ubicom32/include/asm/ioctls.h
5932 @@ -0,0 +1,111 @@
5933 +/*
5934 + * arch/ubicom32/include/asm/ioctls.h
5935 + *   Definitions of ioctls for Ubicom32 architecture.
5936 + *
5937 + * (C) Copyright 2009, Ubicom, Inc.
5938 + *
5939 + * This file is part of the Ubicom32 Linux Kernel Port.
5940 + *
5941 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
5942 + * it and/or modify it under the terms of the GNU General Public License
5943 + * as published by the Free Software Foundation, either version 2 of the
5944 + * License, or (at your option) any later version.
5945 + *
5946 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
5947 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
5948 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
5949 + * the GNU General Public License for more details.
5950 + *
5951 + * You should have received a copy of the GNU General Public License
5952 + * along with the Ubicom32 Linux Kernel Port.  If not, 
5953 + * see <http://www.gnu.org/licenses/>.
5954 + *
5955 + * Ubicom32 implementation derived from (with many thanks):
5956 + *   arch/m68knommu
5957 + *   arch/blackfin
5958 + *   arch/parisc
5959 + */
5960 +#ifndef _ASM_UBICOM32_IOCTLS_H
5961 +#define _ASM_UBICOM32_IOCTLS_H
5962 +
5963 +#include <asm/ioctl.h>
5964 +
5965 +/* 0x54 is just a magic number to make these relatively unique ('T') */
5966 +
5967 +#define TCGETS         0x5401
5968 +#define TCSETS         0x5402
5969 +#define TCSETSW                0x5403
5970 +#define TCSETSF                0x5404
5971 +#define TCGETA         0x5405
5972 +#define TCSETA         0x5406
5973 +#define TCSETAW                0x5407
5974 +#define TCSETAF                0x5408
5975 +#define TCSBRK         0x5409
5976 +#define TCXONC         0x540A
5977 +#define TCFLSH         0x540B
5978 +#define TIOCEXCL       0x540C
5979 +#define TIOCNXCL       0x540D
5980 +#define TIOCSCTTY      0x540E
5981 +#define TIOCGPGRP      0x540F
5982 +#define TIOCSPGRP      0x5410
5983 +#define TIOCOUTQ       0x5411
5984 +#define TIOCSTI                0x5412
5985 +#define TIOCGWINSZ     0x5413
5986 +#define TIOCSWINSZ     0x5414
5987 +#define TIOCMGET       0x5415
5988 +#define TIOCMBIS       0x5416
5989 +#define TIOCMBIC       0x5417
5990 +#define TIOCMSET       0x5418
5991 +#define TIOCGSOFTCAR   0x5419
5992 +#define TIOCSSOFTCAR   0x541A
5993 +#define FIONREAD       0x541B
5994 +#define TIOCINQ                FIONREAD
5995 +#define TIOCLINUX      0x541C
5996 +#define TIOCCONS       0x541D
5997 +#define TIOCGSERIAL    0x541E
5998 +#define TIOCSSERIAL    0x541F
5999 +#define TIOCPKT                0x5420
6000 +#define FIONBIO                0x5421
6001 +#define TIOCNOTTY      0x5422
6002 +#define TIOCSETD       0x5423
6003 +#define TIOCGETD       0x5424
6004 +#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
6005 +#define TIOCSBRK       0x5427  /* BSD compatibility */
6006 +#define TIOCCBRK       0x5428  /* BSD compatibility */
6007 +#define TIOCGSID       0x5429  /* Return the session ID of FD */
6008 +#define TCGETS2                _IOR('T',0x2A, struct termios2)
6009 +#define TCSETS2                _IOW('T',0x2B, struct termios2)
6010 +#define TCSETSW2       _IOW('T',0x2C, struct termios2)
6011 +#define TCSETSF2       _IOW('T',0x2D, struct termios2)
6012 +#define TIOCGPTN       _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
6013 +#define TIOCSPTLCK     _IOW('T',0x31, int)  /* Lock/unlock Pty */
6014 +
6015 +#define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
6016 +#define FIOCLEX                0x5451
6017 +#define FIOASYNC       0x5452
6018 +#define TIOCSERCONFIG  0x5453
6019 +#define TIOCSERGWILD   0x5454
6020 +#define TIOCSERSWILD   0x5455
6021 +#define TIOCGLCKTRMIOS 0x5456
6022 +#define TIOCSLCKTRMIOS 0x5457
6023 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
6024 +#define TIOCSERGETLSR   0x5459 /* Get line status register */
6025 +#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
6026 +#define TIOCSERSETMULTI 0x545B /* Set multiport config */
6027 +
6028 +#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
6029 +#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
6030 +#define FIOQSIZE       0x545E
6031 +
6032 +/* Used for packet mode */
6033 +#define TIOCPKT_DATA            0
6034 +#define TIOCPKT_FLUSHREAD       1
6035 +#define TIOCPKT_FLUSHWRITE      2
6036 +#define TIOCPKT_STOP            4
6037 +#define TIOCPKT_START           8
6038 +#define TIOCPKT_NOSTOP         16
6039 +#define TIOCPKT_DOSTOP         32
6040 +
6041 +#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
6042 +
6043 +#endif /* _ASM_UBICOM32_IOCTLS_H */
6044 --- /dev/null
6045 +++ b/arch/ubicom32/include/asm/io.h
6046 @@ -0,0 +1,313 @@
6047 +/*
6048 + * arch/ubicom32/include/asm/io.h
6049 + *   I/O memory accessor functions for Ubicom32 architecture.
6050 + *
6051 + * (C) Copyright 2009, Ubicom, Inc.
6052 + *
6053 + * This file is part of the Ubicom32 Linux Kernel Port.
6054 + *
6055 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
6056 + * it and/or modify it under the terms of the GNU General Public License
6057 + * as published by the Free Software Foundation, either version 2 of the
6058 + * License, or (at your option) any later version.
6059 + *
6060 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
6061 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
6062 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
6063 + * the GNU General Public License for more details.
6064 + *
6065 + * You should have received a copy of the GNU General Public License
6066 + * along with the Ubicom32 Linux Kernel Port.  If not, 
6067 + * see <http://www.gnu.org/licenses/>.
6068 + *
6069 + * Ubicom32 implementation derived from (with many thanks):
6070 + *   arch/m68knommu
6071 + *   arch/blackfin
6072 + *   arch/parisc
6073 + */
6074 +#ifndef _ASM_UBICOM32_IO_H
6075 +#define _ASM_UBICOM32_IO_H
6076 +
6077 +#ifdef __KERNEL__
6078 +#include <linux/string.h>
6079 +#include <linux/compiler.h>
6080 +
6081 +static inline unsigned short _swapw(volatile unsigned short v)
6082 +{
6083 +    return ((v << 8) | (v >> 8));
6084 +}
6085 +
6086 +static inline unsigned int _swapl(volatile unsigned long v)
6087 +{
6088 +    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
6089 +}
6090 +
6091 +#ifndef CONFIG_PCI
6092 +#define readb(addr) \
6093 +    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
6094 +#define readw(addr) \
6095 +    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
6096 +#define readl(addr) \
6097 +    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
6098 +
6099 +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
6100 +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
6101 +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
6102 +#else /*CONFIG_PCI */
6103 +
6104 +#define PCI_CPU_REG_BASE (0x00000000UL)   /* taking lower 2GB space */
6105 +#define PCI_DEV_REG_BASE (0x80000000UL)
6106 +
6107 +#if PCI_CPU_REG_BASE > PCI_DEV_REG_BASE
6108 +#define IS_PCI_ADDRESS(x) (((unsigned int)(x)&(PCI_CPU_REG_BASE)) == 0)
6109 +#else
6110 +#define IS_PCI_ADDRESS(x) ((unsigned int)(x)&(PCI_DEV_REG_BASE))
6111 +#endif 
6112 +
6113 +extern unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr);
6114 +extern unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr);
6115 +extern unsigned char ubi32_pci_read_u8(const volatile void __iomem *addr);
6116 +extern  void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr);
6117 +extern  void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr);
6118 +extern  void ubi32_pci_write_u8(unsigned char val, const volatile void __iomem *addr);
6119 +
6120 +static  inline unsigned char readb(const volatile void __iomem *addr)
6121 +{
6122 +       if (IS_PCI_ADDRESS(addr))
6123 +               return ubi32_pci_read_u8(addr);
6124 +       else 
6125 +               return (unsigned char)(*(volatile unsigned char *)addr); 
6126 +}
6127 +static inline unsigned short readw(const volatile void __iomem *addr)
6128 +{
6129 +       if (IS_PCI_ADDRESS(addr))
6130 +               return ubi32_pci_read_u16(addr);
6131 +       else 
6132 +               return (unsigned short)(*(volatile unsigned short *)addr);      
6133 +}
6134 +
6135 +static  inline unsigned int  readl(const volatile void __iomem *addr)
6136 +{
6137 +       if (IS_PCI_ADDRESS(addr))
6138 +               return ubi32_pci_read_u32(addr);
6139 +       else 
6140 +               return (unsigned int)(*(volatile unsigned int *)addr);
6141 +}
6142 +
6143 +static inline void writel(unsigned int val, volatile void __iomem *addr)
6144 +{
6145 +       if (IS_PCI_ADDRESS(addr))
6146 +                ubi32_pci_write_u32(val, addr);
6147 +        else
6148 +                       *(volatile unsigned int *)addr = val; 
6149 +}
6150 +
6151 +static inline void writew(unsigned short val, volatile void __iomem *addr)
6152 +{
6153 +       if (IS_PCI_ADDRESS(addr))
6154 +                ubi32_pci_write_u16(val, addr);
6155 +        else
6156 +                       *(volatile unsigned short *)addr = val; 
6157 +}
6158 +
6159 +static inline void writeb(unsigned char val, volatile void __iomem *addr)
6160 +{
6161 +       if (IS_PCI_ADDRESS(addr))
6162 +                ubi32_pci_write_u8(val, addr);
6163 +        else
6164 +                       *(volatile unsigned char *)addr = val; 
6165 +}
6166 +#endif
6167 +
6168 +#define readb_relaxed(addr) readb(addr)
6169 +#define readw_relaxed(addr) readw(addr)
6170 +#define readl_relaxed(addr) readl(addr)
6171 +
6172 +
6173 +#define __raw_readb readb
6174 +#define __raw_readw readw
6175 +#define __raw_readl readl
6176 +#define __raw_writeb writeb
6177 +#define __raw_writew writew
6178 +#define __raw_writel writel
6179 +
6180 +static inline void io_outsb(unsigned int addr, const void *buf, int len)
6181 +{
6182 +       volatile unsigned char *ap = (volatile unsigned char *) addr;
6183 +       unsigned char *bp = (unsigned char *) buf;
6184 +       while (len--)
6185 +               *ap = *bp++;
6186 +}
6187 +
6188 +static inline void io_outsw(unsigned int addr, const void *buf, int len)
6189 +{
6190 +       volatile unsigned short *ap = (volatile unsigned short *) addr;
6191 +       unsigned short *bp = (unsigned short *) buf;
6192 +       while (len--)
6193 +               *ap = _swapw(*bp++);
6194 +}
6195 +
6196 +static inline void io_outsl(unsigned int addr, const void *buf, int len)
6197 +{
6198 +       volatile unsigned int *ap = (volatile unsigned int *) addr;
6199 +       unsigned int *bp = (unsigned int *) buf;
6200 +       while (len--)
6201 +               *ap = _swapl(*bp++);
6202 +}
6203 +
6204 +static inline void io_insb(unsigned int addr, void *buf, int len)
6205 +{
6206 +       volatile unsigned char *ap = (volatile unsigned char *) addr;
6207 +       unsigned char *bp = (unsigned char *) buf;
6208 +       while (len--)
6209 +               *bp++ = *ap;
6210 +}
6211 +
6212 +static inline void io_insw(unsigned int addr, void *buf, int len)
6213 +{
6214 +       volatile unsigned short *ap = (volatile unsigned short *) addr;
6215 +       unsigned short *bp = (unsigned short *) buf;
6216 +       while (len--)
6217 +               *bp++ = _swapw(*ap);
6218 +}
6219 +
6220 +static inline void io_insl(unsigned int addr, void *buf, int len)
6221 +{
6222 +       volatile unsigned int *ap = (volatile unsigned int *) addr;
6223 +       unsigned int *bp = (unsigned int *) buf;
6224 +       while (len--)
6225 +               *bp++ = _swapl(*ap);
6226 +}
6227 +
6228 +#define mmiowb()
6229 +
6230 +/*
6231 + *     make the short names macros so specific devices
6232 + *     can override them as required
6233 + */
6234 +#ifndef CONFIG_PCI
6235 +#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
6236 +#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
6237 +#define memcpy_toio(a,b,c)     memcpy((void *)(a),(b),(c))
6238 +#else 
6239 +extern void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len);
6240 +extern void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len);
6241 +extern void memset_io(volatile void __iomem *addr, int val, size_t count);
6242 +#endif
6243 +
6244 +#define inb(addr)    readb(addr)
6245 +#define inw(addr)    readw(addr)
6246 +#define inl(addr)    readl(addr)
6247 +#define outb(x,addr) ((void) writeb(x,addr))
6248 +#define outw(x,addr) ((void) writew(x,addr))
6249 +#define outl(x,addr) ((void) writel(x,addr))
6250 +
6251 +#define inb_p(addr)    inb(addr)
6252 +#define inw_p(addr)    inw(addr)
6253 +#define inl_p(addr)    inl(addr)
6254 +#define outb_p(x,addr) outb(x,addr)
6255 +#define outw_p(x,addr) outw(x,addr)
6256 +#define outl_p(x,addr) outl(x,addr)
6257 +
6258 +#define outsb(a,b,l) io_outsb(a,b,l)
6259 +#define outsw(a,b,l) io_outsw(a,b,l)
6260 +#define outsl(a,b,l) io_outsl(a,b,l)
6261 +
6262 +#define insb(a,b,l) io_insb(a,b,l)
6263 +#define insw(a,b,l) io_insw(a,b,l)
6264 +#define insl(a,b,l) io_insl(a,b,l)
6265 +
6266 +#ifndef CONFIG_PCI
6267 +#define ioread8_rep(a,d,c)     insb(a,d,c)
6268 +#define ioread16_rep(a,d,c)    insw(a,d,c)
6269 +#define ioread32_rep(a,d,c)    insl(a,d,c)
6270 +#define iowrite8_rep(a,s,c)    outsb(a,s,c)
6271 +#define iowrite16_rep(a,s,c)   outsw(a,s,c)
6272 +#define iowrite32_rep(a,s,c)   outsl(a,s,c)
6273 +#else
6274 +extern void  ioread8_rep(void __iomem *port, void *buf, unsigned long count);
6275 +extern void  ioread16_rep(void __iomem *port, void *buf, unsigned long count);
6276 +extern void  ioread32_rep(void __iomem *port, void *buf, unsigned long count);
6277 +extern void  iowrite8_rep(void __iomem *port, const void *buf, unsigned long count);
6278 +extern void  iowrite16_rep(void __iomem *port, const void *buf, unsigned long count);
6279 +extern void  iowrite32_rep(void __iomem *port, const void *buf, unsigned long count);
6280 +#endif
6281 +
6282 +
6283 +#ifndef CONFIG_PCI
6284 +#define ioread8(X)                     readb(X)
6285 +#define ioread16(X)                    readw(X)
6286 +#define ioread32(X)                    readl(X)
6287 +#define iowrite8(val,X)                        writeb(val,X)
6288 +#define iowrite16(val,X)               writew(val,X)
6289 +#define iowrite32(val,X)               writel(val,X)
6290 +#else /*CONFIG_PCI */
6291 +extern  unsigned char  ioread8(void __iomem *addr);
6292 +extern  unsigned short ioread16(void __iomem *addr);
6293 +extern  unsigned int  ioread32(void __iomem *addr);
6294 +extern  void iowrite8(unsigned char val, void __iomem *addr);
6295 +extern  void iowrite16(unsigned short val, void __iomem *addr);
6296 +extern  void iowrite32(unsigned int val, void __iomem *addr);
6297 +#endif /* CONFIG_PCI */
6298 +
6299 +#define IO_SPACE_LIMIT 0xffff
6300 +
6301 +/* Values for nocacheflag and cmode */
6302 +#define IOMAP_FULL_CACHING             0
6303 +#define IOMAP_NOCACHE_SER              1
6304 +#define IOMAP_NOCACHE_NONSER           2
6305 +#define IOMAP_WRITETHROUGH             3
6306 +
6307 +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
6308 +extern void __iounmap(void *addr, unsigned long size);
6309 +
6310 +static inline void *ioremap(unsigned long physaddr, unsigned long size)
6311 +{
6312 +       return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6313 +}
6314 +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
6315 +{
6316 +       return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6317 +}
6318 +static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
6319 +{
6320 +       return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
6321 +}
6322 +static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
6323 +{
6324 +       return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
6325 +}
6326 +
6327 +extern void iounmap(void *addr);
6328 +
6329 +#define ioport_map(port, nr)            ((void __iomem*)(port))
6330 +#define ioport_unmap(addr)
6331 +
6332 +
6333 +/* Pages to physical address... */
6334 +#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
6335 +#define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
6336 +
6337 +/*
6338 + * Macros used for converting between virtual and physical mappings.
6339 + */
6340 +#define phys_to_virt(vaddr)    ((void *) (vaddr))
6341 +#define virt_to_phys(vaddr)    ((unsigned long) (vaddr))
6342 +
6343 +#define virt_to_bus virt_to_phys
6344 +#define bus_to_virt phys_to_virt
6345 +
6346 +/*
6347 + * Convert a physical pointer to a virtual kernel pointer for /dev/mem
6348 + * access
6349 + */
6350 +#define xlate_dev_mem_ptr(p)   __va(p)
6351 +
6352 +/*
6353 + * Convert a virtual cached pointer to an uncached pointer
6354 + */
6355 +#define xlate_dev_kmem_ptr(p)  p
6356 +
6357 +#endif /* __KERNEL__ */
6358 +
6359 +#endif /* _ASM_UBICOM32_IO_H */
6360 --- /dev/null
6361 +++ b/arch/ubicom32/include/asm/ip5000-asm.h
6362 @@ -0,0 +1,156 @@
6363 +/*
6364 + * arch/ubicom32/include/asm/ip5000-asm.h
6365 + *     Instruction macros for the IP5000.
6366 + *
6367 + * (C) Copyright 2009, Ubicom, Inc.
6368 + *
6369 + * This file is part of the Ubicom32 Linux Kernel Port.
6370 + *
6371 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
6372 + * it and/or modify it under the terms of the GNU General Public License
6373 + * as published by the Free Software Foundation, either version 2 of the
6374 + * License, or (at your option) any later version.
6375 + *
6376 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
6377 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
6378 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
6379 + * the GNU General Public License for more details.
6380 + *
6381 + * You should have received a copy of the GNU General Public License
6382 + * along with the Ubicom32 Linux Kernel Port.  If not,
6383 + * see <http://www.gnu.org/licenses/>.
6384 + *
6385 + * Ubicom32 implementation derived from (with many thanks):
6386 + *   arch/m68knommu
6387 + *   arch/blackfin
6388 + *   arch/parisc
6389 + */
6390 +
6391 +#ifndef _ASM_UBICOM32_IP5000_ASM_H
6392 +#define _ASM_UBICOM32_IP5000_ASM_H
6393 +
6394 +#if !defined(__LINKER__)
6395 +
6396 +#if defined(__ASSEMBLY__)
6397 +.macro cycles  quant
6398 +.if    (\quant) == 1
6399 +       nop
6400 +.else
6401 +.if    (((\quant) + 3) / 8) > 0
6402 +.rept  (((\quant) + 3) / 8)
6403 +       jmpt.f          .+4
6404 +.endr
6405 +.endif
6406 +.if    ((((\quant) + 3) % 8) / 4) > 0
6407 +       jmpt.t          .+4
6408 +.endif
6409 +.endif
6410 +.endm
6411 +#else
6412 +/*
6413 + * Same macro as above just in C inline asm
6414 + */
6415 +asm ("                                 \n\
6416 +.macro cycles  quant                   \n\
6417 +.if    (\\quant) == 1                  \n\
6418 +       nop                             \n\
6419 +.else                                  \n\
6420 +.if    (((\\quant) + 3) / 8) > 0       \n\
6421 +.rept  (((\\quant) + 3) / 8)           \n\
6422 +       jmpt.f          .+4             \n\
6423 +.endr                                  \n\
6424 +.endif                                 \n\
6425 +.if    ((((\\quant) + 3) % 8) / 4) > 0 \n\
6426 +       jmpt.t          .+4             \n\
6427 +.endif                                 \n\
6428 +.endif                                 \n\
6429 +.endm                                  \n\
6430 +");
6431 +#endif
6432 +
6433 +
6434 +#if defined(__ASSEMBLY__)
6435 +.macro pipe_flush      cyc
6436 +       cycles          11 - (\cyc)
6437 +.endm
6438 +#else
6439 +/*
6440 + * Same macro as above just in C inline asm
6441 + */
6442 +asm ("                                 \n\
6443 +.macro pipe_flush      cyc             \n\
6444 +       cycles          11 - (\\cyc)    \n\
6445 +.endm                                  \n\
6446 +");
6447 +
6448 +#endif
6449 +
6450 +#if defined(__ASSEMBLY__)
6451 +.macro setcsr_flush    cyc
6452 +       cycles          5 - (\cyc)
6453 +.endm
6454 +#else
6455 +/*
6456 + * Same macro as above just in C inline asm
6457 + */
6458 +asm ("                                 \n\
6459 +.macro setcsr_flush    cyc             \n\
6460 +       cycles          5 - (\\cyc)     \n\
6461 +.endm                                  \n\
6462 +");
6463 +#endif
6464 +
6465 +/*
6466 + * Macros for prefetch (using miss-aligned memory write)
6467 + */
6468 +#if defined(__ASSEMBLY__)
6469 +
6470 +.macro pre_fetch_macro thread_num, Ascratch, Aaddress length
6471 +       bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
6472 +       bset            \Ascratch, \Aaddress, #0        ; force a miss-aligned address
6473 +       jmpt.t          .+4                             ; delay for both address setup and trap disable
6474 +       move.4          (\Ascratch), #0
6475 +       .if             (\length > 32)
6476 +       move.4          32(\Ascratch), #0
6477 +       .endif
6478 +       .if             (\length > 64)
6479 +       move.4          64(\Ascratch), #0
6480 +       .endif
6481 +       .if             (\length > 96)
6482 +       move.4          96(\Ascratch), #0
6483 +       .endif
6484 +       .if             (\length > 128)
6485 +       invalid_instruction                             ; maximum pre-fetch size is 4 cache lines
6486 +       .endif
6487 +       bset            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
6488 +.endm
6489 +
6490 +#else
6491 +/*
6492 + * Same macro as above just in C inline asm
6493 + */
6494 +asm ("                                                         \n\
6495 +.macro pre_fetch_macro thread_num, Ascratch, Aaddress length   \n\
6496 +       bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)  \n\
6497 +       bset            \\Ascratch, \\Aaddress, #0      ; force a miss-aligned address \n\
6498 +       jmpt.t          .+4                             ; delay for both address setup and trap disable \n\
6499 +       move.4          (\\Ascratch), #0                        \n\
6500 +       .if             (\\length > 32)                         \n\
6501 +       move.4          32(\\Ascratch), #0                      \n\
6502 +       .endif                                                  \n\
6503 +       .if             (\\length > 64)                         \n\
6504 +       move.4          64(\\Ascratch), #0                      \n\
6505 +       .endif                                                  \n\
6506 +       .if             (\\length > 96)                         \n\
6507 +       move.4          96(\\Ascratch), #0                      \n\
6508 +       .endif                                                  \n\
6509 +       .if             (\\length > 128)                        \n\
6510 +       invalid_instruction                             ; maximum pre-fetch size is 4 cache lines \n\
6511 +       .endif                                                  \n\
6512 +       bset            MT_TRAP_EN, MT_TRAP_EN, #(\\thread_num) \n\
6513 +.endm                                                          \n\
6514 +");
6515 +#endif
6516 +
6517 +#endif /* !defined(__LINKER__) */
6518 +#endif /* defined _ASM_UBICOM32_IP5000_ASM_H */
6519 --- /dev/null
6520 +++ b/arch/ubicom32/include/asm/ip5000.h
6521 @@ -0,0 +1,860 @@
6522 +/*
6523 + * arch/ubicom32/include/asm/ip5000.h
6524 + *   Specific details for the Ubicom IP5000 processor.
6525 + *
6526 + * (C) Copyright 2009, Ubicom, Inc.
6527 + *
6528 + * This file is part of the Ubicom32 Linux Kernel Port.
6529 + *
6530 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
6531 + * it and/or modify it under the terms of the GNU General Public License
6532 + * as published by the Free Software Foundation, either version 2 of the
6533 + * License, or (at your option) any later version.
6534 + *
6535 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
6536 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
6537 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
6538 + * the GNU General Public License for more details.
6539 + *
6540 + * You should have received a copy of the GNU General Public License
6541 + * along with the Ubicom32 Linux Kernel Port.  If not,
6542 + * see <http://www.gnu.org/licenses/>.
6543 + *
6544 + * Ubicom32 implementation derived from (with many thanks):
6545 + *   arch/m68knommu
6546 + *   arch/blackfin
6547 + *   arch/parisc
6548 + */
6549 +
6550 +#ifndef _ASM_UBICOM32_IP5000_H
6551 +#define _ASM_UBICOM32_IP5000_H
6552 +
6553 +/*
6554 + * Inline assembly define
6555 + */
6556 +#define S(arg) #arg
6557 +#define D(arg) S(arg)
6558 +
6559 +/*
6560 + * Assembler include file
6561 + */
6562 +#include <asm/ip5000-asm.h>
6563 +
6564 +/*
6565 + * Timing
6566 + */
6567 +#define JMPT_PENALTY 3
6568 +#define JMPF_PENALTY 7
6569 +#define RET_PENALTY 7
6570 +
6571 +/*
6572 + * Threads
6573 + */
6574 +#if defined(IP5000) || defined(IP5000_REV2)
6575 +#define THREAD_COUNT 10
6576 +#elif defined(IP7000) || defined(IP7000_REV2)
6577 +#define THREAD_COUNT 12
6578 +#else
6579 +#error "Unknown IP5K silicon"
6580 +#endif
6581 +
6582 +/*
6583 + * Arch
6584 + */
6585 +#if defined(IP5000) || defined(IP5000_REV2)
6586 +#define UBICOM32_ARCH_VERSION 3
6587 +#elif defined(IP7000) || defined(IP7000_REV2)
6588 +#define UBICOM32_ARCH_VERSION 4
6589 +#else
6590 +#error "Unknown IP5K silicon"
6591 +#endif
6592 +
6593 +/*
6594 + * Memory Size
6595 + */
6596 +#define OCM_SECTOR_SIZE        0x00008000              /* 32K */
6597 +
6598 +#if defined(IP5000) || defined(IP5000_REV2)
6599 +#define OCMSIZE        0x00030000              /* 192K on-chip RAM for both program and data */
6600 +#elif defined(IP7000) || defined(IP7000_REV2)
6601 +#define OCMSIZE        0x0003C000              /* 240K on-chip RAM for both program and data */
6602 +#else
6603 +#error "Unknown IP5K silicon"
6604 +#endif
6605 +
6606 +#define OCMSTART       0x3ffc0000              /* alias from 0x03000000 for easy jump to/from SDRAM */
6607 +#define OCMEND         (OCMSTART + OCMSIZE)
6608 +#define SDRAMSTART     0x40000000
6609 +#define FLASHSTART     0x60000000
6610 +
6611 +/*
6612 + * Registers
6613 + */
6614 +#define ROSR_INT (1 << 0)
6615 +
6616 +/* Interrupts */
6617 +#define INT_CHIP(reg, bit) (((reg) << 5) | (bit))
6618 +#define INT_REG(interrupt) (((interrupt) >> 5) * 4)
6619 +#define INT_SET(interrupt) 0x0114 + INT_REG(interrupt)
6620 +#define INT_CLR(interrupt) 0x0124 + INT_REG(interrupt)
6621 +#define INT_STAT(interrupt) 0x0104 + INT_REG(interrupt)
6622 +#define INT_MASK(interrupt) 0x00C0 + INT_REG(interrupt)
6623 +#define INT_BIT(interrupt) ((interrupt) & 0x1F)
6624 +#define INT_BIT_MASK(interrupt) (1 << INT_BIT(interrupt))
6625 +
6626 +/*
6627 + * The LOCK_INT and THREAD_INT are used to wake up corresponding thread. They are sharing
6628 + * the same set of SW interrupt resource.
6629 + *
6630 + * LOCK_INT(n): One SW INT per NRT thread that can participate lock operation.
6631 + *     The threads that can participate lock are application threads and DSR thread.
6632 + *     (Lock locks - numbers are hard-coded in lock.h)
6633 + * THREAD_INT(n):   One SW INT per HRT thread for wake up trigger.
6634 + */
6635 +#define LOCK_INT(thread)       INT_CHIP(0, (thread))
6636 +#define THREAD_INT(thread)     INT_CHIP(0, (thread))
6637 +
6638 +/*
6639 + * The SYSTEM_INT and DSR_INT are sharing the same set of SW interrupt resource.
6640 + *
6641 + * SYSTEM_INT(n): One SW INT per NRT threads (application threads) as system queue interrupt,
6642 + *     and for DSR as self-trigger interrupt.
6643 + *     (The application threads include at least thread 0)
6644 + * DSR_INT(n):    One SW INT per HRT thread to request DSR service.
6645 + */
6646 +#define SYSTEM_INT(thread)     INT_CHIP(0, THREAD_COUNT + (thread))
6647 +#define DSR_INT(thread)                INT_CHIP(0, THREAD_COUNT + (thread))
6648 +
6649 +/* GLOBAL_CTRL */
6650 +#define GLOBAL_CTRL_TRAP_RST_EN (1 << 9)
6651 +#define GLOBAL_CTRL_AERROR_RST_EN (1 << 8)
6652 +#define GLOBAL_CTRL_MT_MIN_DELAY(x) ((x) << 3)
6653 +#define GLOBAL_CTRL_HRT_BANK_SELECT (1 << 2)
6654 +#define GLOBAL_CTRL_INT_EN (1 << 0)
6655 +
6656 +/*
6657 + * HRT Tables
6658 + */
6659 +#define HRT_TABLE0_BASE 0x0800
6660 +#define HRT_TABLE1_BASE 0x0900
6661 +#define HRT_TABLE_SIZE 64
6662 +
6663 +/*
6664 + * Break Point Trap Register
6665 + */
6666 +#define ASYNCERROR_INT INT_CHIP(0, 31)
6667 +#define BREAKPOINT_INT INT_CHIP(1, 31)
6668 +
6669 +/*
6670 + * Port interrupts
6671 + *     The non-existing FIFO INTs are mapped to INT2 for the ports.
6672 + */
6673 +#define IO_PORT_PTR_TO_NUM(port) (((port) & 0x0000ffff) >> 12)
6674 +#define RX_FIFO_INT(port) \
6675 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
6676 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 26) : \
6677 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6678 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 24) : \
6679 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 27) : \
6680 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 16) : \
6681 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6682 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6683 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 21) : \
6684 +       INT_CHIP(1, 15))))))))))
6685 +#define TX_FIFO_INT(port) \
6686 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 24) : \
6687 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 27) : \
6688 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6689 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 25) : \
6690 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 28) : \
6691 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 17) : \
6692 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6693 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6694 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 22) : \
6695 +       INT_CHIP(1, 15))))))))))
6696 +#define PORT_OTHER_INT(port) \
6697 +       ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
6698 +       ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 28) : \
6699 +       ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
6700 +       ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 26) : \
6701 +       ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 29) : \
6702 +       ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 18) : \
6703 +       ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
6704 +       ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
6705 +       ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 23) : \
6706 +       INT_CHIP(1, 15))))))))))
6707 +
6708 +/*
6709 + * On Chip Peripherals Base.
6710 + */
6711 +#define OCP_BASE       0x01000000
6712 +#define OCP_GENERAL    0x000
6713 +#define OCP_TIMERS     0x100
6714 +#define OCP_TRNG       0x200   /* True Random Number Generator Control Reigsters */
6715 +#define OCP_DEBUG      0x300
6716 +#define OCP_SECURITY   0x400
6717 +#define OCP_ICCR       0x500   /* I-Cache Control Registers */
6718 +#define OCP_DCCR       0x600   /* D-Cache Control Registers */
6719 +#define OCP_OCMC       0x700   /* On Chip Memory Control Registers */
6720 +#define OCP_STATISTICS 0x800   /* Statistics Counters */
6721 +#define OCP_MTEST      0x900   /* Memory Test Registers */
6722 +#define OCP_MCFG       0xa00   /* Memory Configuration Registers -- IP7000 only */
6723 +#define OCP_DEBUG_INST 0x000   /* Up to 16M */
6724 +
6725 +/*
6726 + * General Configuration Registers (PLL)
6727 + */
6728 +#define GENERAL_CFG_BASE (OCP_BASE + OCP_GENERAL)
6729 +#define GEN_CLK_CORE_CFG 0x00
6730 +#define GEN_CLK_IO_CFG 0x04
6731 +#define GEN_CLK_DDR_CFG 0x08
6732 +#define GEN_CLK_DDRDS_CFG 0x0c
6733 +#define GEN_CLK_SLIP_CLR 0x10
6734 +#define GEN_CLK_SLIP_START 0x14
6735 +#define GEN_CLK_SERDES_SEL 0x18        /* IP7000 only */
6736 +#define GEN_CLK_DDR_CFG2 0x1c  /* IP7000 only */
6737 +#define GEN_DDR_CAL_CTRL 0x30  /* IP5000 only */
6738 +#define GEN_DDR_CAL_STAT 0x34  /* IP5000 only */
6739 +#define GEN_USB_DFT_CTRL 0x38  /* IP5000 only */
6740 +#define GEN_USB_DFT_STAT 0x3c  /* IP5000 only */
6741 +#define GEN_USB_PHY_CFG 0x40   /* IP7000 only */
6742 +#define GEN_USB_PHY_TEST 0x44  /* IP7000 only */
6743 +#define GEN_USB_PHY_STAT 0x48  /* IP7000 only */
6744 +#define GEN_SW_RESET 0x80
6745 +#define GEN_RESET_REASON 0x84
6746 +#define GEN_BOND_CFG 0x88
6747 +#define GEN_IO_PU_CFG 0x8c
6748 +#define GEN_MEM_RM_CFG 0x90
6749 +#define GEN_IO_CONFIG 0x94
6750 +
6751 +#define GEN_CLK_PLL_SECURITY_BIT_NO 31
6752 +#define GEN_CLK_PLL_SECURITY (1 << GEN_CLK_PLL_SECURITY_BIT_NO)
6753 +#define GEN_CLK_PLL_ENSAT (1 << 30)
6754 +#define GEN_CLK_PLL_FASTEN (1 << 29)
6755 +#define GEN_CLK_PLL_NR(v) (((v) - 1) << 23)
6756 +#define GEN_CLK_PLL_NF(v) (((v) - 1) << 11)
6757 +#define GEN_CLK_PLL_OD(v) (((v) - 1) << 8)
6758 +#define GEN_CLK_PLL_RESET (1 << 7)
6759 +#define GEN_CLK_PLL_BYPASS (1 << 6)
6760 +#define GEN_CLK_PLL_POWERDOWN (1 << 5)
6761 +#define GEN_CLK_PLL_SELECT (1 << 4)
6762 +
6763 +#define GEN_GET_CLK_PLL_NR(v) ((((v) >> 23) & 0x003f) + 1)
6764 +#define GEN_GET_CLK_PLL_NF(v) ((((v) >> 11) & 0x0fff) + 1)
6765 +#define GEN_GET_CLK_PLL_OD(v) ((((v) >> 8) & 0x7) + 1)
6766 +
6767 +
6768 +#define RESET_FLAG_DST_MEM_ERROR (1 << 18)
6769 +#define RESET_FLAG_SRC1_MEM_ERROR (1 << 17)
6770 +#define RESET_FLAG_WRITE_ADDR (1 << 16)
6771 +#define RESET_FLAG_DST_SYNC_ERROR (1 << 15)
6772 +#define RESET_FLAG_SRC1_SYNC_ERROR (1 << 14)
6773 +#define RESET_FLAG_DST_ALGN_ERROR (1 << 13)
6774 +#define RESET_FLAG_SRC1_ALGN_ERROR (1 << 12)
6775 +#define RESET_FLAG_DST_ADDR_ERROR (1 << 11)
6776 +#define RESET_FLAG_SRC1_ADDR_ERROR (1 << 10)
6777 +#define RESET_FLAG_ILLEGAL_INST (1 << 9)
6778 +#define RESET_FLAG_INST_SYNC_ERROR (1 << 8)
6779 +#define RESET_FLAG_INST_ADDR_ERROR (1 << 7)
6780 +#define RESET_FLAG_DATA_PORT_ERROR (1 << 6)
6781 +#define RESET_FLAG_INST_PORT_ERROR (1 << 5)
6782 +#define RESET_FLAG_SW_RESET (1 << 4)
6783 +#define RESET_FLAG_DEBUG (1 << 3)
6784 +#define RESET_FLAG_WATCHDOG (1 << 2)
6785 +#define RESET_FLAG_POWER_ON (1 << 1)
6786 +#define RESET_FLAG_EXTERNAL (1 << 0)
6787 +
6788 +/*
6789 + * Timer block
6790 + */
6791 +#define TIMER_BASE (OCP_BASE + OCP_TIMERS)
6792 +#define TIMER_MPTVAL 0x00
6793 +#define TIMER_RTCOM 0x04
6794 +#define TIMER_TKEY 0x08
6795 +#define TIMER_WDCOM 0x0c
6796 +#define TIMER_WDCFG 0x10
6797 +#define TIMER_SYSVAL 0x14
6798 +#define TIMER_SYSCOM(tmr) (0x18 + (tmr) * 4)
6799 +#define TIMER_TRN_CFG 0x100
6800 +#define TIMER_TRN 0x104
6801 +
6802 +#define TIMER_COUNT 10
6803 +#define TIMER_INT(tmr) INT_CHIP(1, (tmr))
6804 +#define TIMER_TKEYVAL 0xa1b2c3d4
6805 +#define TIMER_WATCHDOG_DISABLE 0x4d3c2b1a
6806 +#define TIMER_TRN_CFG_ENABLE_OSC 0x00000007
6807 +
6808 +#ifndef __ASSEMBLY__
6809 +/*
6810 + * ubicom32_io_timer
6811 + */
6812 +struct ubicom32_io_timer {
6813 +       volatile u32_t mptval;
6814 +       volatile u32_t rtcom;
6815 +       volatile u32_t tkey;
6816 +       volatile u32_t wdcom;
6817 +       volatile u32_t wdcfg;
6818 +       volatile u32_t sysval;
6819 +       volatile u32_t syscom[TIMER_COUNT];
6820 +       volatile u32_t reserved[64 - 6 - TIMER_COUNT];  // skip all the way to OCP-TRNG section
6821 +       volatile u32_t rsgcfg;
6822 +       volatile u32_t trn;
6823 +};
6824 +
6825 +#define UBICOM32_IO_TIMER ((struct ubicom32_io_timer *)TIMER_BASE)
6826 +#endif
6827 +
6828 +#define UBICOM32_VECTOR_TO_TIMER_INDEX(vector) (vector - TIMER_INT(0))
6829 +
6830 +/*
6831 + * OCP-Debug Module (Mailbox)
6832 + */
6833 +#define ISD_MAILBOX_BASE (OCP_BASE + OCP_DEBUG)
6834 +#define ISD_MAILBOX_IN 0x00
6835 +#define ISD_MAILBOX_OUT 0x04
6836 +#define ISD_MAILBOX_STATUS 0x08
6837 +
6838 +#define ISD_MAILBOX_INT INT_CHIP(1, 30)
6839 +
6840 +#define ISD_MAILBOX_STATUS_IN_FULL (1 << 31)
6841 +#define ISD_MAILBOX_STATUS_IN_EMPTY (1 << 30)
6842 +#define ISD_MAILBOX_STATUS_OUT_FULL (1 << 29)
6843 +#define ISD_MAILBOX_STATUS_OUT_EMPTY (1 << 28)
6844 +
6845 +/*
6846 + * OCP-Security
6847 + */
6848 +#define SECURITY_BASE (OCP_BASE + OCP_SECURITY)
6849 +#define SECURITY_BASE_EFFECTIVE_ADDRESS (SECURITY_BASE >> 7) // To load the base address in a single instruction
6850 +#define SECURITY_CTRL 0x00
6851 +#define SECURITY_CTRL_BYTE_OFFSET(x) ((x) << 16)
6852 +#define SECURITY_CTRL_KEY_SIZE(x) ((x) << 8)
6853 +#define SECURITY_CTRL_HASH_ALG_NONE (0 << 4)
6854 +#define SECURITY_CTRL_HASH_ALG_MD5 (1 << 4)
6855 +#define SECURITY_CTRL_HASH_ALG_SHA1 (2 << 4)
6856 +#define SECURITY_CTRL_CBC (1 << 3)
6857 +#define SECURITY_CTRL_CIPHER_ALG_AES (0 << 1)
6858 +#define SECURITY_CTRL_CIPHER_ALG_NONE (1 << 1)
6859 +#define SECURITY_CTRL_CIPHER_ALG_DES (2 << 1)
6860 +#define SECURITY_CTRL_CIPHER_ALG_3DES (3 << 1)
6861 +#define SECURITY_CTRL_ENCIPHER (1 << 0)
6862 +#define SECURITY_CTRL_DECIPHER (0 << 0)
6863 +#define SECURITY_STAT 0x04
6864 +#define SECURITY_STAT_BUSY (1 << 0)
6865 +#define SECURITY_KEY_VALUE(x) (0x10 + (x) * 4)
6866 +#define SECURITY_KEY_IN(x) (0x30 + (x) * 4)
6867 +#define SECURITY_KEY_OUT(x) (0x50 + (x) * 4)
6868 +#define SECURITY_KEY_HASH(x) (0x70 + (x) * 4)
6869 +
6870 +/*
6871 + * OCP-ICCR
6872 + */
6873 +#define ICCR_BASE (OCP_BASE + OCP_ICCR)
6874 +#define ICACHE_TOTAL_SIZE 16384                        /* in bytes */
6875 +
6876 +/*
6877 + * OCP-DCCR
6878 + */
6879 +#define DCCR_BASE (OCP_BASE + OCP_DCCR)
6880 +#if defined(IP5000) || defined(IP5000_REV2)
6881 +#define DCACHE_TOTAL_SIZE 8192                 /* in bytes */
6882 +#elif defined(IP7000) || defined(IP7000_REV2)
6883 +#define DCACHE_TOTAL_SIZE 16384                        /* in bytes */
6884 +#endif
6885 +
6886 +#if defined(IP5000) || defined(IP5000_REV2) || defined(IP7000) || defined(IP7000_REV2)
6887 +#define DCACHE_WRITE_QUEUE_LENGTH 6
6888 +#else
6889 +#error "Unknown IP5K silicon"
6890 +#endif
6891 +
6892 +#define CACHE_LINE_SIZE 32                     /* in bytes */
6893 +
6894 +#define CCR_ADDR 0x00
6895 +#define CCR_RDD 0x04
6896 +#define CCR_WRD 0x08
6897 +#define CCR_STAT 0x0c
6898 +#define CCR_CTRL 0x10
6899 +
6900 +#define CCR_STAT_MCBE 0
6901 +#define CCR_STAT_WIDEL 1                       /* D-cache only */
6902 +
6903 +#define CCR_CTRL_DONE 0
6904 +#define CCR_CTRL_RESET 2
6905 +#define CCR_CTRL_VALID 3
6906 +#define CCR_CTRL_RD_DATA (1 << 4)
6907 +#define CCR_CTRL_RD_TAG (2 << 4)
6908 +#define CCR_CTRL_WR_DATA (3 << 4)
6909 +#define CCR_CTRL_WR_TAG (4 << 4)
6910 +#define CCR_CTRL_INV_INDEX (5 << 4)
6911 +#define CCR_CTRL_INV_ADDR (6 << 4)
6912 +#define CCR_CTRL_FLUSH_INDEX (7 << 4)          /* D-cache only */
6913 +#define CCR_CTRL_FLUSH_INV_INDEX (8 << 4)      /* D-cache only */
6914 +#define CCR_CTRL_FLUSH_ADDR (9 << 4)           /* D-cache only */
6915 +#define CCR_CTRL_FLUSH_INV_ADDR (10 << 4)      /* D-cache only */
6916 +
6917 +/*
6918 + * OCP-OCMC
6919 + */
6920 +#define OCMC_BASE (OCP_BASE + OCP_OCMC)
6921 +#define OCMC_BANK_MASK 0x00
6922 +#define OCMC_BIST_CNTL 0x04    /* IP5000 only */
6923 +#define OCMC_BIST_STAT 0x08    /* IP5000 only */
6924 +
6925 +#define OCMC_BANK_PROG(n) ((1<<(n))-1)
6926 +
6927 +#define OCMC_BIST_WRCK (1 << 7)
6928 +#define OCMC_BIST_RESET (1 << 5)
6929 +#define OCMC_BIST_SMART (1 << 4)
6930 +#define OCMC_BIST_RUN (1 << 3)
6931 +#define OCMC_BIST_REPAIR (1 << 2)
6932 +
6933 +#define OCMC_BIST_READY (1 << 3)
6934 +#define OCMC_BIST_FAIL (1 << 2)
6935 +
6936 +/*
6937 + * OCP-STATISTICS
6938 + */
6939 +#define STATISTICS_BASE (OCP_BASE + OCP_STATISTICS)
6940 +#define STAT_COUNTER_CTRL(n) ((n)*8)
6941 +#define STAT_COUNTER(n) ((n)*8 + 4)
6942 +
6943 +#define STAT_EVENT_MP_INST 0
6944 +#define STAT_EVENT_OCM_ACCESS 4
6945 +#define STAT_EVENT_OCM_REQ 5
6946 +#define STAT_EVENT_IC_REQ_INVAL 13
6947 +#define STAT_EVENT_IC_MISS_INVAL 14
6948 +#define STAT_EVENT_IC_REQ_INVAL_NACK 15
6949 +#define STAT_EVENT_IC_REQ_VAL 16
6950 +#define STAT_EVENT_IC_MISS_VAL 17
6951 +#define STAT_EVENT_IC_REQ_VAL_NACK 18
6952 +#define STAT_EVENT_IC_MISS_Q 19
6953 +#define STAT_EVENT_DC_RD_REQ 20
6954 +#define STAT_EVENT_DC_RD_MISS 21
6955 +#define STAT_EVENT_DC_WR_REQ 22
6956 +#define STAT_EVENT_DC_WR_MISS 23
6957 +#define STAT_EVENT_DC_MISS_Q 24
6958 +#define STAT_EVENT_DC_WB_FULL 25
6959 +#define STAT_EVENT_DC_REQ_NACK 26
6960 +#define STAT_EVENT_DC_CORE_REQ 27
6961 +#define STAT_EVENT_DC_MISS 28
6962 +#define STAT_EVENT_DC_EVICT 29
6963 +#define STAT_EVENT_TRUE 30
6964 +#define STAT_EVENT_FALSE 31
6965 +
6966 +/*
6967 + * OCP_MTEST
6968 + */
6969 +#define MTEST_BASE (OCP_BASE + OCP_MTEST)
6970 +#define MTEST_ADDR 0x00
6971 +#define MTEST_WR 0x04
6972 +#define MTEST_RD 0x08
6973 +#define MTEST_CTRL 0x0c
6974 +
6975 +/*
6976 + * OCP_MCFG (IP7000 only)
6977 + */
6978 +#define MCFG_BASE (OCP_BASE + OCP_MCFG)
6979 +#define MCFG_CTRL 0x00
6980 +#define MCFG_WCFG 0x04
6981 +#define MCFG_RCFG 0x08
6982 +
6983 +/*
6984 + * Port registers
6985 + */
6986 +#define IO_BASE 0x02000000
6987 +#define RA (IO_BASE + 0x00000000)
6988 +#define RB (IO_BASE + 0x00001000)
6989 +#define RC (IO_BASE + 0x00002000)
6990 +#define RD (IO_BASE + 0x00003000)
6991 +#define RE (IO_BASE + 0x00004000)
6992 +#define RF (IO_BASE + 0x00005000)
6993 +#define RG (IO_BASE + 0x00006000)
6994 +#define RH (IO_BASE + 0x00007000)
6995 +#define RI (IO_BASE + 0x00008000)
6996 +#define RJ (IO_BASE + 0x00009000)
6997 +#define RLATCH (IO_BASE + 0x00ff0000)  // For latched output only
6998 +#define IO_PORT_BR_OFFSET 0x00000800
6999 +
7000 +/*
7001 + * General I/O Register Map (per port)
7002 + */
7003 +#define IO_FUNC 0x00
7004 +#define IO_GPIO_CTL 0x04
7005 +#define IO_GPIO_OUT 0x08
7006 +#define IO_GPIO_IN 0x0C
7007 +#define IO_INT_STATUS 0x10
7008 +#define IO_INT_MASK 0x14
7009 +#define IO_INT_SET 0x18
7010 +#define IO_INT_CLR 0x1C
7011 +#define IO_TX_FIFO 0x20
7012 +#define IO_TX_FIFO_HI 0x24
7013 +#define IO_RX_FIFO 0x28
7014 +#define IO_RX_FIFO_HI 0x2c
7015 +#define IO_CTL0 0x30
7016 +#define IO_CTL1 0x34
7017 +#define IO_CTL2 0x38
7018 +#define IO_STATUS0 0x3c
7019 +#define IO_STATUS1 0x40
7020 +#define IO_STATUS2 0x44
7021 +#define IO_FIFO_WATER 0x48
7022 +#define IO_FIFO_LEVEL 0x4c
7023 +#define IO_GPIO_MASK 0x50
7024 +
7025 +#define IO_FUNC_FUNCTION_RESET(func) ((1 << ((func) - 1)) << 4)        /* Function 0 doesn't need reset */
7026 +#define IO_FUNC_RX_FIFO (1 << 3)
7027 +#define IO_FUNC_SELECT(func) ((func) << 0)
7028 +
7029 +/*
7030 + * External interrupt pins.
7031 + */
7032 +#define EXT_INT_IO_BIT(pin) ((pin) + 5)        // Interrupt pin number -> I/O INT bit
7033 +#define EXT_INT_RISING_EDGE(pin) (0x2 << (2*(pin) + 7))
7034 +#define EXT_INT_FALLING_EDGE(pin) (0x1 << (2*(pin) + 7))
7035 +
7036 +/*
7037 + * Flash
7038 + */
7039 +#define IO_XFL_BASE RA
7040 +
7041 +#define IO_XFL_INT_START (1 << 16)
7042 +#define IO_XFL_INT_ERR (1 << 8)
7043 +#define IO_XFL_INT_DONE (1 << 0)
7044 +
7045 +#define IO_XFL_CTL0_MASK (0xffe07fff)
7046 +#define IO_XFL_CTL0_RD_CMD(cmd) (((cmd) & 0xff) << 24)
7047 +#define IO_XFL_CTL0_RD_DUMMY(n) (((n) & 0x7) << 21)
7048 +#define IO_XFL_CTL0_CLK_WIDTH(core_cycles) ((((core_cycles) + 1) & 0x7e) << 8) /* must be even number */
7049 +#define IO_XFL_CTL0_CE_WAIT(spi_cycles) (((spi_cycles) & 0x3f) << 2)
7050 +#define IO_XFL_CTL0_MCB_LOCK (1 << 1)
7051 +#define IO_XFL_CTL0_ENABLE (1 << 0)
7052 +#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)
7053 +#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)
7054 +
7055 +#define IO_XFL_CTL1_MASK (0xc0003fff)
7056 +#define IO_XFL_CTL1_FC_INST(inst) (((inst) & 0x3) << 30)
7057 +#define IO_XFL_CTL1_FC_DATA(n) (((n) & 0x3ff) << 4)
7058 +#define IO_XFL_CTL1_FC_DUMMY(n) (((n) & 0x7) << 1)
7059 +#define IO_XFL_CTL1_FC_ADDR (1 << 0)
7060 +
7061 +#define IO_XFL_CTL2_FC_CMD(cmd) (((cmd) & 0xff) << 24)
7062 +#define IO_XFL_CTL2_FC_ADDR(addr) ((addr) & 0x00ffffff)        /* Only up to 24 bits */
7063 +
7064 +#define IO_XFL_STATUS0_MCB_ACTIVE (1 << 0)
7065 +#define IO_XFL_STATUS0_IOPCS_ACTIVE (1 << 1)
7066 +
7067 +/*
7068 + * SDRAM
7069 + */
7070 +#define IO_SDRAM_DATA_BASE RG
7071 +#define IO_SDRAM_CNTL_BASE RH
7072 +
7073 +#define IO_SDRAM_CTRL0_EN_REF (1 << 0)
7074 +
7075 +/*
7076 + * Port function code (common fucntion codes for all I/O ports)
7077 + */
7078 +#define IO_PORTX_FUNC_GPIO 0x00
7079 +#define IO_PORTX_FUNC_XFL 0x01
7080 +#define IO_PORTX_FUNC_PCI 0x01
7081 +#define IO_PORTX_FUNC_SERDES 0x01
7082 +#define IO_PORTX_FUNC_GMII 0x01
7083 +#define IO_PORTX_FUNC_DDR 0x01
7084 +#define IO_PORTX_FUNC_PCIX 0x01
7085 +#define IO_PORTX_FUNC_USB2_0 0x01
7086 +#define IO_PORTX_FUNC_GPIO_INT_CLK 0x02
7087 +#define IO_PORTX_FUNC_PLIO 0x02
7088 +#define IO_PORTX_FUNC_GPIO_INT 0x03
7089 +#define IO_PORTX_FUNC_MII 0x03
7090 +
7091 +/*
7092 + * Port 0
7093 + */
7094 +#define IO_PORT0_FUNC_GPIO IO_PORTX_FUNC_GPIO
7095 +#define IO_PORT0_FUNC_XFL_INT_CLK IO_PORTX_FUNC_XFL    // Default mode after reset
7096 +#define IO_PORT0_FUNC_GPIO_INT_CLK IO_PORTX_FUNC_GPIO_INT_CLK
7097 +#define IO_PORT0_FUNC_GPIO_INT IO_PORTX_FUNC_GPIO_INT
7098 +
7099 +/*
7100 + * Port 1
7101 + */
7102 +#define IO_PORT1_FUNC_GPIO IO_PORTX_FUNC_GPIO
7103 +#define IO_PORT1_FUNC_PCI IO_PORTX_FUNC_PCI            // PCI control
7104 +#define IO_PORT1_FUNC_MII IO_PORTX_FUNC_MII            // port 4 MII extension
7105 +
7106 +/*
7107 + * Port 2
7108 + */
7109 +#define IO_PORT2_FUNC_GPIO IO_PORTX_FUNC_GPIO
7110 +#define IO_PORT2_FUNC_PCI IO_PORTX_FUNC_PCI            // PCI data I/O
7111 +#define IO_PORT2_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
7112 +
7113 +/*
7114 + * Port 3
7115 + */
7116 +#define IO_PORT3_FUNC_GPIO IO_PORTX_FUNC_GPIO
7117 +#define IO_PORT3_FUNC_SERDES IO_PORTX_FUNC_SERDES
7118 +#define IO_PORT3_FUNC_PLIO IO_PORTX_FUNC_PLIO
7119 +
7120 +/*
7121 + * Port 4
7122 + */
7123 +#define IO_PORT4_FUNC_GPIO IO_PORTX_FUNC_GPIO
7124 +#define IO_PORT4_FUNC_SERDES IO_PORTX_FUNC_SERDES
7125 +#define IO_PORT4_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
7126 +#define IO_PORT4_FUNC_MII IO_PORTX_FUNC_MII
7127 +
7128 +/*
7129 + * Port 5
7130 + */
7131 +#define IO_PORT5_FUNC_GPIO IO_PORTX_FUNC_GPIO
7132 +#define IO_PORT5_FUNC_GMII IO_PORTX_FUNC_GMII
7133 +
7134 +/*
7135 + * Port 6
7136 + */
7137 +#define IO_PORT6_FUNC_GPIO IO_PORTX_FUNC_GPIO
7138 +#define IO_PORT6_FUNC_DDR IO_PORTX_FUNC_DDR
7139 +
7140 +/*
7141 + * Port 7
7142 + */
7143 +#define IO_PORT7_FUNC_GPIO IO_PORTX_FUNC_GPIO
7144 +#define IO_PORT7_FUNC_DDR IO_PORTX_FUNC_DDR
7145 +
7146 +/*
7147 + * Port 8
7148 + */
7149 +#define IO_PORT8_FUNC_GPIO IO_PORTX_FUNC_GPIO
7150 +#define IO_PORT8_FUNC_PCIX IO_PORTX_FUNC_PCIX
7151 +#define IO_PORT8_FUNC_PLIO IO_PORTX_FUNC_PLIO          // Extended LM
7152 +#define IO_PORT8_FUNC_MII IO_PORTX_FUNC_MII            // port 4 MII extension
7153 +
7154 +/*
7155 + * Port 9
7156 + */
7157 +#define IO_PORT9_FUNC_USB2_0 IO_PORTX_FUNC_USB2_0
7158 +
7159 +/*
7160 + * FIFO
7161 + */
7162 +#define IO_PORTX_INT_FIFO_TX_RESET (1 << 31)
7163 +#define IO_PORTX_INT_FIFO_RX_RESET (1 << 30)
7164 +#define IO_PORTX_INT_FIFO_TX_UF (1 << 15)
7165 +#define IO_PORTX_INT_FIFO_TX_WM (1 << 14)
7166 +#define IO_PORTX_INT_FIFO_RX_OF (1 << 13)
7167 +#define IO_PORTX_INT_FIFO_RX_WM (1 << 12)
7168 +
7169 +#define IO_PORTX_FUNC_FIFO_TX_WM(n) ((n) << 16)
7170 +#define IO_PORTX_FUNC_FIFO_RX_WM(n) ((n) << 0)
7171 +
7172 +/*
7173 + * MII
7174 + */
7175 +#define IO_PORTX_INT_MII_TX_ERR_SEND (1 << 18)
7176 +#define IO_PORTX_INT_MII_TX_HALT (1 << 17)
7177 +#define IO_PORTX_INT_MII_TX_START (1 << 16)
7178 +#define IO_PORTX_INT_MII_THRESHOLD (1 << 8)
7179 +#define IO_PORTX_INT_MII_RX_EOP (1 << 7)
7180 +#define IO_PORTX_INT_MII_RX_SFD (1 << 6)
7181 +#define IO_PORTX_INT_MII_RX_ERR (1 << 5)
7182 +#define IO_PORTX_INT_MII_TX_EOP (1 << 4)
7183 +#define IO_PORTX_INT_MII_COL (1 << 3)
7184 +#define IO_PORTX_INT_MII_CRS (1 << 2)
7185 +#define IO_PORTX_INT_MII_ODD_NIB_ERR (1 << 1)
7186 +#define IO_PORTX_INT_MII_FALSE_CARRIER (1 << 0)
7187 +
7188 +/*
7189 + * SerDes
7190 + */
7191 +#define IO_PORTX_INT_SERDES_TXBUF_VALID (1 << 16)
7192 +#define IO_PORTX_INT_SERDES_RXERR (1 << 7)
7193 +#define IO_PORTX_INT_SERDES_RXEOP (1 << 6)
7194 +#define IO_PORTX_INT_SERDES_SYND (1 << 5)
7195 +#define IO_PORTX_INT_SERDES_TXBE (1 << 4)
7196 +#define IO_PORTX_INT_SERDES_TXEOP (1 << 3)
7197 +#define IO_PORTX_INT_SERDES_SXLP (1 << 2)
7198 +#define IO_PORTX_INT_SERDES_RXBF (1 << 1)
7199 +#define IO_PORTX_INT_SERDES_RXCRS (1 << 0)
7200 +
7201 +#ifndef __ASSEMBLY__
7202 +struct ubicom32_io_port {
7203 +       volatile u32_t function;
7204 +       volatile u32_t gpio_ctl;
7205 +       volatile u32_t gpio_out;
7206 +       volatile u32_t gpio_in;
7207 +       volatile u32_t int_status;
7208 +       volatile u32_t int_mask;
7209 +       volatile u32_t int_set;
7210 +       volatile u32_t int_clr;
7211 +       volatile u32_t tx_fifo;
7212 +       volatile u32_t tx_fifo_hi;
7213 +       volatile u32_t rx_fifo;
7214 +       volatile u32_t rx_fifo_hi;
7215 +       volatile u32_t ctl0;
7216 +       volatile u32_t ctl1;
7217 +       volatile u32_t ctl2;
7218 +       volatile u32_t status0;
7219 +       volatile u32_t status1;
7220 +       volatile u32_t status2;
7221 +       volatile u32_t fifo_watermark;
7222 +       volatile u32_t fifo_level;
7223 +       volatile u32_t gpio_mask;
7224 +};
7225 +
7226 +#define UBICOM32_IO_PORT(port) ((struct ubicom32_io_port *)((port)))
7227 +#endif
7228 +
7229 +#ifndef __ASSEMBLY__
7230 +/*
7231 + * ubicom32_set_interrupt()
7232 + */
7233 +extern inline void ubicom32_set_interrupt(u8_t interrupt)
7234 +{
7235 +       u32_t ibit = INT_BIT_MASK(interrupt);
7236 +
7237 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7238 +               asm volatile (
7239 +                       "move.4         "D(INT_SET(INT_CHIP(0, 0)))", %0\n\t"
7240 +                       :
7241 +                       : "r" (ibit)
7242 +               );
7243 +
7244 +               return;
7245 +       }
7246 +
7247 +       asm volatile (
7248 +               "move.4         "D(INT_SET(INT_CHIP(1, 0)))", %0\n\t"
7249 +               :
7250 +               : "r" (ibit)
7251 +       );
7252 +}
7253 +
7254 +/*
7255 + * ubicom32_clear_interrupt()
7256 + */
7257 +extern inline void ubicom32_clear_interrupt(u8_t interrupt)
7258 +{
7259 +       u32_t ibit = INT_BIT_MASK(interrupt);
7260 +
7261 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7262 +               asm volatile (
7263 +                       "move.4         "D(INT_CLR(INT_CHIP(0, 0)))", %0\n\t"
7264 +                       :
7265 +                       : "r" (ibit)
7266 +               );
7267 +
7268 +               return;
7269 +       }
7270 +
7271 +       asm volatile (
7272 +               "move.4         "D(INT_CLR(INT_CHIP(1, 0)))", %0\n\t"
7273 +               :
7274 +               : "r" (ibit)
7275 +       );
7276 +}
7277 +
7278 +/*
7279 + * ubicom32_enable_interrupt()
7280 + */
7281 +extern inline void ubicom32_enable_interrupt(u8_t interrupt)
7282 +{
7283 +       u32_t ibit = INT_BIT_MASK(interrupt);
7284 +
7285 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7286 +               asm volatile (
7287 +                       "or.4           "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7288 +                       :
7289 +                       : "d" (ibit)
7290 +               );
7291 +
7292 +               return;
7293 +       }
7294 +
7295 +       asm volatile (
7296 +               "or.4           "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7297 +               :
7298 +               : "d" (ibit)
7299 +       );
7300 +}
7301 +
7302 +/*
7303 + * ubicom32_disable_interrupt()
7304 + */
7305 +extern inline void ubicom32_disable_interrupt(u8_t interrupt)
7306 +{
7307 +       u32_t ibit = ~INT_BIT_MASK(interrupt);
7308 +
7309 +       if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7310 +               asm volatile (
7311 +                       "and.4          "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7312 +                       :
7313 +                       : "d" (ibit)
7314 +               );
7315 +
7316 +               return;
7317 +       }
7318 +
7319 +       asm volatile (
7320 +               "and.4          "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7321 +               :
7322 +               : "d" (ibit)
7323 +       );
7324 +}
7325 +
7326 +/*
7327 + * ubicom32_enable_global_interrupts()
7328 + */
7329 +extern inline void ubicom32_enable_global_interrupts(void)
7330 +{
7331 +       asm volatile(
7332 +               "bset           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7333 +       );
7334 +}
7335 +
7336 +/*
7337 + * ubicom32_disable_global_interrupts()
7338 + */
7339 +extern inline void ubicom32_disable_global_interrupts(void)
7340 +{
7341 +       asm volatile(
7342 +               "bclr           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7343 +       );
7344 +}
7345 +
7346 +/*
7347 + * ubicom32_get_reset_reason()
7348 + */
7349 +extern inline u32_t ubicom32_get_reset_reason(void)
7350 +{
7351 +       return *(u32_t *)(GENERAL_CFG_BASE + GEN_RESET_REASON);
7352 +}
7353 +
7354 +/*
7355 + * ubicom32_read_reg()
7356 + */
7357 +extern inline u32_t ubicom32_read_reg(volatile void *reg)
7358 +{
7359 +       u32_t v;
7360 +       asm volatile (
7361 +               "move.4         %[dest], %[src] \n\t"
7362 +               : [dest] "=r" (v)
7363 +               : [src] "m" (*(u32_t *)reg)
7364 +       );
7365 +       return v;
7366 +}
7367 +
7368 +/*
7369 + * ubicom32_write_reg()
7370 + */
7371 +extern inline void ubicom32_write_reg(volatile void *reg, u32_t v)
7372 +{
7373 +       asm volatile (
7374 +               "move.4         %[dest], %[src] \n\t"
7375 +               :
7376 +               : [src] "r" (v), [dest] "m" (*(u32_t *)reg)
7377 +       );
7378 +}
7379 +
7380 +#endif /* __ASSEMBLY__ */
7381 +#endif /* _ASM_UBICOM32_IP5000_H */
7382 --- /dev/null
7383 +++ b/arch/ubicom32/include/asm/ipcbuf.h
7384 @@ -0,0 +1,55 @@
7385 +/*
7386 + * arch/ubicom32/include/asm/ipcbuf.h
7387 + *   Definition of ipc64_perm struct for Ubicom32 architecture.
7388 + *
7389 + * (C) Copyright 2009, Ubicom, Inc.
7390 + *
7391 + * This file is part of the Ubicom32 Linux Kernel Port.
7392 + *
7393 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7394 + * it and/or modify it under the terms of the GNU General Public License
7395 + * as published by the Free Software Foundation, either version 2 of the
7396 + * License, or (at your option) any later version.
7397 + *
7398 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7399 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7400 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7401 + * the GNU General Public License for more details.
7402 + *
7403 + * You should have received a copy of the GNU General Public License
7404 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7405 + * see <http://www.gnu.org/licenses/>.
7406 + *
7407 + * Ubicom32 implementation derived from (with many thanks):
7408 + *   arch/m68knommu
7409 + *   arch/blackfin
7410 + *   arch/parisc
7411 + */
7412 +#ifndef _ASM_UBICOM32_IPCBUF_H
7413 +#define _ASM_UBICOM32_IPCBUF_H
7414 +
7415 +/*
7416 + * The user_ipc_perm structure for m68k architecture.
7417 + * Note extra padding because this structure is passed back and forth
7418 + * between kernel and user space.
7419 + *
7420 + * Pad space is left for:
7421 + * - 32-bit mode_t and seq
7422 + * - 2 miscellaneous 32-bit values
7423 + */
7424 +struct ipc64_perm
7425 +{
7426 +       __kernel_key_t          key;
7427 +       __kernel_uid32_t        uid;
7428 +       __kernel_gid32_t        gid;
7429 +       __kernel_uid32_t        cuid;
7430 +       __kernel_gid32_t        cgid;
7431 +       __kernel_mode_t         mode;
7432 +       unsigned short          __pad1;
7433 +       unsigned short          seq;
7434 +       unsigned short          __pad2;
7435 +       unsigned long           __unused1;
7436 +       unsigned long           __unused2;
7437 +};
7438 +
7439 +#endif /* _ASM_UBICOM32_IPCBUF_H */
7440 --- /dev/null
7441 +++ b/arch/ubicom32/include/asm/irqflags.h
7442 @@ -0,0 +1,94 @@
7443 +/*
7444 + * arch/ubicom32/include/asm/irqflags.h
7445 + *   Raw implementation of local IRQ functions.
7446 + *
7447 + * (C) Copyright 2009, Ubicom, Inc.
7448 + *
7449 + * This file is part of the Ubicom32 Linux Kernel Port.
7450 + *
7451 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7452 + * it and/or modify it under the terms of the GNU General Public License
7453 + * as published by the Free Software Foundation, either version 2 of the
7454 + * License, or (at your option) any later version.
7455 + *
7456 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7457 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7458 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7459 + * the GNU General Public License for more details.
7460 + *
7461 + * You should have received a copy of the GNU General Public License
7462 + * along with the Ubicom32 Linux Kernel Port.  If not,
7463 + * see <http://www.gnu.org/licenses/>.
7464 + *
7465 + * Ubicom32 implementation derived from (with many thanks):
7466 + *   arch/m68knommu
7467 + *   arch/blackfin
7468 + *   arch/parisc
7469 + */
7470 +#ifndef _ASM_UBICOM32_IRQFLAGS_H
7471 +#define _ASM_UBICOM32_IRQFLAGS_H
7472 +
7473 +#include <linux/thread_info.h>
7474 +#include <asm/ubicom32-common.h>
7475 +#include <asm/smp.h>
7476 +#include <asm/ldsr.h>
7477 +
7478 +#if defined(CONFIG_PREEMPT)
7479 +#error Not supported by Ubicom32 irq handling, yet!
7480 +#endif
7481 +
7482 +/*
7483 + * raw_local_irq_enable()
7484 + *     Enable interrupts for this thread.
7485 + */
7486 +static inline void raw_local_irq_enable(void)
7487 +{
7488 +       ldsr_local_irq_enable();
7489 +}
7490 +
7491 +/*
7492 + * raw_local_irq_disable()
7493 + *     Disable interrupts for this thread.
7494 + */
7495 +static inline void raw_local_irq_disable(void)
7496 +{
7497 +       ldsr_local_irq_disable();
7498 +}
7499 +
7500 +/*
7501 + * raw_local_save_flags()
7502 + *     Get the current IRQ state.
7503 + */
7504 +#define raw_local_save_flags(flags)            \
7505 +do {                                           \
7506 +       (flags) = ldsr_local_irq_is_disabled(); \
7507 +} while (0)
7508 +
7509 +/*
7510 + * raw_local_irq_save()
7511 + *     Save the current interrupt state and disable interrupts.
7512 + */
7513 +#define raw_local_irq_save(flags)              \
7514 +do {                                           \
7515 +       (flags) = ldsr_local_irq_save();        \
7516 +} while (0)
7517 +
7518 +/*
7519 + * raw_local_irq_restore()
7520 + *     Restore the IRQ state back to flags.
7521 + */
7522 +static inline void raw_local_irq_restore(unsigned long flags)
7523 +{
7524 +       ldsr_local_irq_restore(flags);
7525 +}
7526 +
7527 +/*
7528 + * raw_irqs_disabled_flags()
7529 + *     Return true if the flags indicate that IRQ(s) are disabled.
7530 + */
7531 +static inline int raw_irqs_disabled_flags(unsigned long flags)
7532 +{
7533 +       return (flags);
7534 +}
7535 +
7536 +#endif /* _ASM_UBICOM32_IRQFLAGS_H */
7537 --- /dev/null
7538 +++ b/arch/ubicom32/include/asm/irq.h
7539 @@ -0,0 +1,45 @@
7540 +/*
7541 + * arch/ubicom32/include/asm/irq.h
7542 + *   IRQ definitions for Ubicom32 architecture.
7543 + *
7544 + * (C) Copyright 2009, Ubicom, Inc.
7545 + *
7546 + * This file is part of the Ubicom32 Linux Kernel Port.
7547 + *
7548 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7549 + * it and/or modify it under the terms of the GNU General Public License
7550 + * as published by the Free Software Foundation, either version 2 of the
7551 + * License, or (at your option) any later version.
7552 + *
7553 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7554 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7555 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7556 + * the GNU General Public License for more details.
7557 + *
7558 + * You should have received a copy of the GNU General Public License
7559 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7560 + * see <http://www.gnu.org/licenses/>.
7561 + *
7562 + * Ubicom32 implementation derived from (with many thanks):
7563 + *   arch/m68knommu
7564 + *   arch/blackfin
7565 + *   arch/parisc
7566 + */
7567 +#ifndef _ASM_UBICOM32_IRQ_H
7568 +#define _ASM_UBICOM32_IRQ_H
7569 +
7570 +#include <asm/irqflags.h>
7571 +
7572 +/*
7573 + * We setup the IRQS to cover the full range of interrupt registers in
7574 + * processor.
7575 + */
7576 +#define NR_IRQS                64
7577 +
7578 +#define irq_canonicalize(irq) (irq)
7579 +
7580 +extern int irq_soft_alloc(unsigned int *soft);
7581 +extern void ack_bad_irq(unsigned int irq);
7582 +extern void do_IRQ(int irq, struct pt_regs *fp);
7583 +
7584 +#endif /* _ASM_UBICOM32_IRQ_H */
7585 --- /dev/null
7586 +++ b/arch/ubicom32/include/asm/irq_regs.h
7587 @@ -0,0 +1,33 @@
7588 +/*
7589 + * arch/ubicom32/include/asm/irq_regs.h
7590 + *   Generic irq_regs.h for Ubicom32 architecture.
7591 + *
7592 + * (C) Copyright 2009, Ubicom, Inc.
7593 + *
7594 + * This file is part of the Ubicom32 Linux Kernel Port.
7595 + *
7596 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7597 + * it and/or modify it under the terms of the GNU General Public License
7598 + * as published by the Free Software Foundation, either version 2 of the
7599 + * License, or (at your option) any later version.
7600 + *
7601 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7602 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7603 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7604 + * the GNU General Public License for more details.
7605 + *
7606 + * You should have received a copy of the GNU General Public License
7607 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7608 + * see <http://www.gnu.org/licenses/>.
7609 + *
7610 + * Ubicom32 implementation derived from (with many thanks):
7611 + *   arch/m68knommu
7612 + *   arch/blackfin
7613 + *   arch/parisc
7614 + */
7615 +#ifndef _ASM_UBICOM32_IRQ_REGS_H
7616 +#define _ASM_UBICOM32_IRQ_REGS_H
7617 +
7618 +#include <asm-generic/irq_regs.h>
7619 +
7620 +#endif /* _ASM_UBICOM32_IRQ_REGS_H */
7621 --- /dev/null
7622 +++ b/arch/ubicom32/include/asm/Kbuild
7623 @@ -0,0 +1 @@
7624 +include include/asm-generic/Kbuild.asm
7625 --- /dev/null
7626 +++ b/arch/ubicom32/include/asm/kdebug.h
7627 @@ -0,0 +1,33 @@
7628 +/*
7629 + * arch/ubicom32/include/asm/kdebug.h
7630 + *   Generic kdebug.h for Ubicom32 architecture.
7631 + *
7632 + * (C) Copyright 2009, Ubicom, Inc.
7633 + *
7634 + * This file is part of the Ubicom32 Linux Kernel Port.
7635 + *
7636 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7637 + * it and/or modify it under the terms of the GNU General Public License
7638 + * as published by the Free Software Foundation, either version 2 of the
7639 + * License, or (at your option) any later version.
7640 + *
7641 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7642 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7643 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7644 + * the GNU General Public License for more details.
7645 + *
7646 + * You should have received a copy of the GNU General Public License
7647 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7648 + * see <http://www.gnu.org/licenses/>.
7649 + *
7650 + * Ubicom32 implementation derived from (with many thanks):
7651 + *   arch/m68knommu
7652 + *   arch/blackfin
7653 + *   arch/parisc
7654 + */
7655 +#ifndef _ASM_UBICOM32_KDEBUG_H
7656 +#define _ASM_UBICOM32_KDEBUG_H
7657 +
7658 +#include <asm-generic/kdebug.h>
7659 +
7660 +#endif /* _ASM_UBICOM32_KDEBUG_H */
7661 --- /dev/null
7662 +++ b/arch/ubicom32/include/asm/kmap_types.h
7663 @@ -0,0 +1,48 @@
7664 +/*
7665 + * arch/ubicom32/include/asm/kmap_types.h
7666 + *   Definition of km_type's for Ubicom32 architecture.
7667 + *
7668 + * (C) Copyright 2009, Ubicom, Inc.
7669 + *
7670 + * This file is part of the Ubicom32 Linux Kernel Port.
7671 + *
7672 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7673 + * it and/or modify it under the terms of the GNU General Public License
7674 + * as published by the Free Software Foundation, either version 2 of the
7675 + * License, or (at your option) any later version.
7676 + *
7677 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7678 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7679 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7680 + * the GNU General Public License for more details.
7681 + *
7682 + * You should have received a copy of the GNU General Public License
7683 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7684 + * see <http://www.gnu.org/licenses/>.
7685 + *
7686 + * Ubicom32 implementation derived from (with many thanks):
7687 + *   arch/m68knommu
7688 + *   arch/blackfin
7689 + *   arch/parisc
7690 + */
7691 +#ifndef _ASM_UBICOM32_KMAP_TYPES_H
7692 +#define _ASM_UBICOM32_KMAP_TYPES_H
7693 +
7694 +enum km_type {
7695 +       KM_BOUNCE_READ,
7696 +       KM_SKB_SUNRPC_DATA,
7697 +       KM_SKB_DATA_SOFTIRQ,
7698 +       KM_USER0,
7699 +       KM_USER1,
7700 +       KM_BIO_SRC_IRQ,
7701 +       KM_BIO_DST_IRQ,
7702 +       KM_PTE0,
7703 +       KM_PTE1,
7704 +       KM_IRQ0,
7705 +       KM_IRQ1,
7706 +       KM_SOFTIRQ0,
7707 +       KM_SOFTIRQ1,
7708 +       KM_TYPE_NR
7709 +};
7710 +
7711 +#endif /* _ASM_UBICOM32_KMAP_TYPES_H */
7712 --- /dev/null
7713 +++ b/arch/ubicom32/include/asm/ldsr.h
7714 @@ -0,0 +1,186 @@
7715 +/*
7716 + * arch/ubicom32/include/asm/ldsr.h
7717 + *   Ubicom32 LDSR interface definitions.
7718 + *
7719 + * (C) Copyright 2009, Ubicom, Inc.
7720 + *
7721 + * This file is part of the Ubicom32 Linux Kernel Port.
7722 + *
7723 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7724 + * it and/or modify it under the terms of the GNU General Public License
7725 + * as published by the Free Software Foundation, either version 2 of the
7726 + * License, or (at your option) any later version.
7727 + *
7728 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7729 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7730 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7731 + * the GNU General Public License for more details.
7732 + *
7733 + * You should have received a copy of the GNU General Public License
7734 + * along with the Ubicom32 Linux Kernel Port.  If not,
7735 + * see <http://www.gnu.org/licenses/>.
7736 + *
7737 + * Ubicom32 implementation derived from (with many thanks):
7738 + *   arch/m68knommu
7739 + *   arch/blackfin
7740 + *   arch/parisc
7741 + */
7742 +#ifndef _ASM_UBICOM32_LDSR_H
7743 +#define _ASM_UBICOM32_LDSR_H
7744 +
7745 +#include <asm/ubicom32-common.h>
7746 +#include <asm/types.h>
7747 +#include <asm/thread.h>
7748 +
7749 +extern unsigned int ldsr_soft_irq_mask;
7750 +
7751 +/*
7752 + * ldsr_local_irq_is_disabled()
7753 + *     Test if interrupts are disabled for this thread?
7754 + */
7755 +static inline int ldsr_local_irq_is_disabled(void)
7756 +{
7757 +       int ret;
7758 +       thread_t self = thread_get_self();
7759 +       unsigned int mask = (1 << self);
7760 +
7761 +       asm volatile (
7762 +       "       and.4   %0, scratchpad1, %1     \n\t"
7763 +               : "=r" (ret)
7764 +               : "d" (mask)
7765 +               : "cc"
7766 +       );
7767 +
7768 +       /*
7769 +        *  We return a simple 1 == disabled, 0 == enabled
7770 +        *  losing which tid this is for, because Linux
7771 +        *  can restore interrupts on a different thread.
7772 +        */
7773 +       return ret >> self;
7774 +}
7775 +
7776 +/*
7777 + * ldsr_local_irq_save()
7778 + *     Get the current interrupt state and disable interrupts.
7779 + */
7780 +static inline unsigned int ldsr_local_irq_save(void)
7781 +{
7782 +       int ret;
7783 +       thread_t self = thread_get_self();
7784 +       unsigned int mask = (1 << self);
7785 +
7786 +       /*
7787 +        * Ensure the compiler can not optimize out the code
7788 +        * (volatile) and that it does not "cache" values around
7789 +        * the interrupt state change (memory).  This ensures
7790 +        * that interrupt changes are treated as a critical
7791 +        * section.
7792 +        */
7793 +       asm volatile (
7794 +       "       and.4   %0, scratchpad1, %1             \n\t"
7795 +       "       or.4    scratchpad1, scratchpad1, %1    \n\t"
7796 +               : "=&r" (ret)
7797 +               : "d" (mask)
7798 +               : "cc", "memory"
7799 +       );
7800 +
7801 +       /*
7802 +        *  We return a simple 1 == disabled, 0 == enabled
7803 +        *  losing which tid this is for, because Linux
7804 +        *  can restore interrupts on a different thread.
7805 +        */
7806 +       return ret >> self;
7807 +}
7808 +
7809 +/*
7810 + * ldsr_local_irq_restore()
7811 + *     Restore this cpu's interrupt enable/disable state.
7812 + *
7813 + * Note: flags is either 0 or 1.
7814 + */
7815 +static inline void ldsr_local_irq_restore(unsigned int flags)
7816 +{
7817 +       unsigned int temp;
7818 +       thread_t self = thread_get_self();
7819 +       unsigned int mask = (1 << self);
7820 +       flags = (flags << self);
7821 +
7822 +       /*
7823 +        * Ensure the compiler can not optimize out the code
7824 +        * (volatile) and that it does not "cache" values around
7825 +        * the interrupt state change (memory).  This ensures
7826 +        * that interrupt changes are treated as a critical
7827 +        * section.
7828 +        *
7829 +        * Atomic change to our bit in scratchpad1 without
7830 +        * causing any temporary glitch in the value and
7831 +        * without effecting other values.  Also this uses
7832 +        * no branches so no penalties.
7833 +        */
7834 +       asm volatile (
7835 +       "       xor.4   %0, scratchpad1, %1             \n\t"
7836 +       "       and.4   %0, %2, %0                      \n\t"
7837 +       "       xor.4   scratchpad1, scratchpad1, %0    \n\t"
7838 +       "       move.4  int_set0, %3                    \n\t"
7839 +               : "=&d"(temp)
7840 +               : "d"(flags), "r"(mask), "r"(ldsr_soft_irq_mask)
7841 +               : "cc", "memory"
7842 +       );
7843 +}
7844 +
7845 +/*
7846 + * ldsr_local_irq_disable_interrupt()
7847 + *     Disable ints for this thread.
7848 + */
7849 +static inline void ldsr_local_irq_disable(void)
7850 +{
7851 +       unsigned int mask = (1 << thread_get_self());
7852 +
7853 +       /*
7854 +        * Ensure the compiler can not optimize out the code
7855 +        * (volatile) and that it does not "cache" values around
7856 +        * the interrupt state change (memory).  This ensures
7857 +        * that interrupt changes are treated as a critical
7858 +        * section.
7859 +        */
7860 +       asm  volatile (
7861 +       "       or.4    scratchpad1, scratchpad1, %0    \n\t"
7862 +               :
7863 +               : "d" (mask)
7864 +               : "cc", "memory"
7865 +       );
7866 +}
7867 +
7868 +/*
7869 + * ldsr_local_irq_enable_interrupt
7870 + *     Enable ints for this thread.
7871 + */
7872 +static inline void ldsr_local_irq_enable(void)
7873 +{
7874 +       unsigned int mask = (1 << thread_get_self());
7875 +
7876 +       /*
7877 +        * Ensure the compiler can not optimize out the code
7878 +        * (volatile) and that it does not "cache" values around
7879 +        * the interrupt state change (memory).  This ensures
7880 +        * that interrupt changes are treated as a critical
7881 +        * section.
7882 +        */
7883 +       asm volatile (
7884 +       "       and.4   scratchpad1, scratchpad1, %0    \n\t"
7885 +       "       move.4  int_set0, %1                    \n\t"
7886 +               :
7887 +               : "d" (~mask), "r" (ldsr_soft_irq_mask)
7888 +               : "cc", "memory"
7889 +       );
7890 +}
7891 +
7892 +extern void ldsr_init(void);
7893 +extern void ldsr_set_trap_irq(unsigned int irq);
7894 +extern void ldsr_mask_vector(unsigned int vector);
7895 +extern void ldsr_unmask_vector(unsigned int vector);
7896 +extern void ldsr_enable_vector(unsigned int vector);
7897 +extern void ldsr_disable_vector(unsigned int vector);
7898 +extern thread_t ldsr_get_threadid(void);
7899 +
7900 +#endif /* _ASM_UBICOM32_LDSR_H */
7901 --- /dev/null
7902 +++ b/arch/ubicom32/include/asm/linkage.h
7903 @@ -0,0 +1,34 @@
7904 +/*
7905 + * arch/ubicom32/include/asm/linkage.h
7906 + *   Definition of Ubicom32 architecture specific linkage types.
7907 + *
7908 + * (C) Copyright 2009, Ubicom, Inc.
7909 + *
7910 + * This file is part of the Ubicom32 Linux Kernel Port.
7911 + *
7912 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7913 + * it and/or modify it under the terms of the GNU General Public License
7914 + * as published by the Free Software Foundation, either version 2 of the
7915 + * License, or (at your option) any later version.
7916 + *
7917 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7918 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7919 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7920 + * the GNU General Public License for more details.
7921 + *
7922 + * You should have received a copy of the GNU General Public License
7923 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7924 + * see <http://www.gnu.org/licenses/>.
7925 + *
7926 + * Ubicom32 implementation derived from (with many thanks):
7927 + *   arch/m68knommu
7928 + *   arch/blackfin
7929 + *   arch/parisc
7930 + */
7931 +#ifndef _ASM_UBICOM32_LINKAGE_H
7932 +#define _ASM_UBICOM32_LINKAGE_H
7933 +
7934 +#define __ocm_text __section(.ocm_text)
7935 +#define __ocm_data __section(.ocm_data)
7936 +
7937 +#endif /* _ASM_UBICOM32_LINKAGE_H */
7938 --- /dev/null
7939 +++ b/arch/ubicom32/include/asm/local.h
7940 @@ -0,0 +1,33 @@
7941 +/*
7942 + * arch/ubicom32/include/asm/local.h
7943 + *   Generic local.h for Ubicom32 architecture.
7944 + *
7945 + * (C) Copyright 2009, Ubicom, Inc.
7946 + *
7947 + * This file is part of the Ubicom32 Linux Kernel Port.
7948 + *
7949 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7950 + * it and/or modify it under the terms of the GNU General Public License
7951 + * as published by the Free Software Foundation, either version 2 of the
7952 + * License, or (at your option) any later version.
7953 + *
7954 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7955 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7956 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7957 + * the GNU General Public License for more details.
7958 + *
7959 + * You should have received a copy of the GNU General Public License
7960 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7961 + * see <http://www.gnu.org/licenses/>.
7962 + *
7963 + * Ubicom32 implementation derived from (with many thanks):
7964 + *   arch/m68knommu
7965 + *   arch/blackfin
7966 + *   arch/parisc
7967 + */
7968 +#ifndef _ASM_UBICOM32_LOCAL_H
7969 +#define _ASM_UBICOM32_LOCAL_H
7970 +
7971 +#include <asm-generic/local.h>
7972 +
7973 +#endif /* _ASM_UBICOM32_LOCAL_H */
7974 --- /dev/null
7975 +++ b/arch/ubicom32/include/asm/machdep.h
7976 @@ -0,0 +1,43 @@
7977 +/*
7978 + * arch/ubicom32/include/asm/machdep.h
7979 + *   Machine dependent utility routines.
7980 + *
7981 + * (C) Copyright 2009, Ubicom, Inc.
7982 + *
7983 + * This file is part of the Ubicom32 Linux Kernel Port.
7984 + *
7985 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
7986 + * it and/or modify it under the terms of the GNU General Public License
7987 + * as published by the Free Software Foundation, either version 2 of the
7988 + * License, or (at your option) any later version.
7989 + *
7990 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
7991 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
7992 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
7993 + * the GNU General Public License for more details.
7994 + *
7995 + * You should have received a copy of the GNU General Public License
7996 + * along with the Ubicom32 Linux Kernel Port.  If not, 
7997 + * see <http://www.gnu.org/licenses/>.
7998 + *
7999 + * Ubicom32 implementation derived from (with many thanks):
8000 + *   arch/m68knommu
8001 + *   arch/blackfin
8002 + *   arch/parisc
8003 + */
8004 +#ifndef _ASM_UBICOM32_MACHDEP_H
8005 +#define _ASM_UBICOM32_MACHDEP_H
8006 +
8007 +#include <linux/interrupt.h>
8008 +
8009 +/* Hardware clock functions */
8010 +extern unsigned long hw_timer_offset(void);
8011 +
8012 +/* machine dependent power off functions */
8013 +extern void (*mach_reset)(void);
8014 +extern void (*mach_halt)(void);
8015 +extern void (*mach_power_off)(void);
8016 +
8017 +extern void config_BSP(char *command, int len);
8018 +
8019 +#endif /* _ASM_UBICOM32_MACHDEP_H */
8020 --- /dev/null
8021 +++ b/arch/ubicom32/include/asm/mc146818rtc.h
8022 @@ -0,0 +1,36 @@
8023 +/*
8024 + * arch/ubicom32/include/asm/mc146818rtc.h
8025 + *   Generic mc146818rtc.h for Ubicom32 architecture.
8026 + *
8027 + * (C) Copyright 2009, Ubicom, Inc.
8028 + *
8029 + * This file is part of the Ubicom32 Linux Kernel Port.
8030 + *
8031 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8032 + * it and/or modify it under the terms of the GNU General Public License
8033 + * as published by the Free Software Foundation, either version 2 of the
8034 + * License, or (at your option) any later version.
8035 + *
8036 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8037 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8038 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8039 + * the GNU General Public License for more details.
8040 + *
8041 + * You should have received a copy of the GNU General Public License
8042 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8043 + * see <http://www.gnu.org/licenses/>.
8044 + *
8045 + * Ubicom32 implementation derived from (with many thanks):
8046 + *   arch/m68knommu
8047 + *   arch/blackfin
8048 + *   arch/parisc
8049 + */
8050 +/*
8051 + * Machine dependent access functions for RTC registers.
8052 + */
8053 +#ifndef _ASM_UBICOM32_MC146818RTC_H
8054 +#define _ASM_UBICOM32_MC146818RTC_H
8055 +
8056 +/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
8057 +
8058 +#endif /* _ASM_UBICOM32_MC146818RTC_H */
8059 --- /dev/null
8060 +++ b/arch/ubicom32/include/asm/mman.h
8061 @@ -0,0 +1,44 @@
8062 +/*
8063 + * arch/ubicom32/include/asm/mman.h
8064 + *   Memory mapping definitions for Ubicom32 architecture.
8065 + *
8066 + * (C) Copyright 2009, Ubicom, Inc.
8067 + *
8068 + * This file is part of the Ubicom32 Linux Kernel Port.
8069 + *
8070 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8071 + * it and/or modify it under the terms of the GNU General Public License
8072 + * as published by the Free Software Foundation, either version 2 of the
8073 + * License, or (at your option) any later version.
8074 + *
8075 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8076 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8077 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8078 + * the GNU General Public License for more details.
8079 + *
8080 + * You should have received a copy of the GNU General Public License
8081 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8082 + * see <http://www.gnu.org/licenses/>.
8083 + *
8084 + * Ubicom32 implementation derived from (with many thanks):
8085 + *   arch/m68knommu
8086 + *   arch/blackfin
8087 + *   arch/parisc
8088 + */
8089 +#ifndef _ASM_UBICOM32_MMAN_H
8090 +#define _ASM_UBICOM32_MMAN_H
8091 +
8092 +#include <asm-generic/mman.h>
8093 +
8094 +#define MAP_GROWSDOWN  0x0100          /* stack-like segment */
8095 +#define MAP_DENYWRITE  0x0800          /* ETXTBSY */
8096 +#define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
8097 +#define MAP_LOCKED     0x2000          /* pages are locked */
8098 +#define MAP_NORESERVE  0x4000          /* don't check for reservations */
8099 +#define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
8100 +#define MAP_NONBLOCK   0x10000         /* do not block on IO */
8101 +
8102 +#define MCL_CURRENT    1               /* lock all current mappings */
8103 +#define MCL_FUTURE     2               /* lock all future mappings */
8104 +
8105 +#endif /* _ASM_UBICOM32_MMAN_H */
8106 --- /dev/null
8107 +++ b/arch/ubicom32/include/asm/mmu_context.h
8108 @@ -0,0 +1,60 @@
8109 +/*
8110 + * arch/ubicom32/include/asm/mmu_context.h
8111 + *   MMU context definitions for Ubicom32 architecture.
8112 + *
8113 + * (C) Copyright 2009, Ubicom, Inc.
8114 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.          
8115 + *
8116 + * This file is part of the Ubicom32 Linux Kernel Port.
8117 + *
8118 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8119 + * it and/or modify it under the terms of the GNU General Public License
8120 + * as published by the Free Software Foundation, either version 2 of the
8121 + * License, or (at your option) any later version.
8122 + *
8123 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8124 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8125 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8126 + * the GNU General Public License for more details.
8127 + *
8128 + * You should have received a copy of the GNU General Public License
8129 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8130 + * see <http://www.gnu.org/licenses/>.
8131 + *
8132 + * Ubicom32 implementation derived from (with many thanks):
8133 + *   arch/m68knommu
8134 + *   arch/blackfin
8135 + *   arch/parisc
8136 + */
8137 +
8138 +#ifndef _ASM_UBICOM32_MMU_CONTEXT_H
8139 +#define _ASM_UBICOM32_MMU_CONTEXT_H
8140 +
8141 +#include <asm/setup.h>
8142 +#include <asm/page.h>
8143 +#include <asm/pgalloc.h>
8144 +
8145 +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
8146 +{
8147 +}
8148 +
8149 +extern inline int
8150 +init_new_context(struct task_struct *tsk, struct mm_struct *mm)
8151 +{
8152 +       // mm->context = virt_to_phys(mm->pgd);
8153 +       return(0);
8154 +}
8155 +
8156 +#define destroy_context(mm)            do { } while(0)
8157 +
8158 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
8159 +{
8160 +}
8161 +
8162 +#define deactivate_mm(tsk,mm)  do { } while (0)
8163 +
8164 +extern inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
8165 +{
8166 +}
8167 +
8168 +#endif /* _ASM_UBICOM32_MMU_CONTEXT_H */
8169 --- /dev/null
8170 +++ b/arch/ubicom32/include/asm/mmu.h
8171 @@ -0,0 +1,41 @@
8172 +/*
8173 + * arch/ubicom32/include/asm/mmu.h
8174 + *   Definition of mm_context_t struct for Ubicom32 architecture.
8175 + *
8176 + * (C) Copyright 2009, Ubicom, Inc.
8177 + * Copyright (C) 2002, David McCullough <davidm@snapgear.com>
8178 + *
8179 + * This file is part of the Ubicom32 Linux Kernel Port.
8180 + *
8181 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8182 + * it and/or modify it under the terms of the GNU General Public License
8183 + * as published by the Free Software Foundation, either version 2 of the
8184 + * License, or (at your option) any later version.
8185 + *
8186 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8187 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8188 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8189 + * the GNU General Public License for more details.
8190 + *
8191 + * You should have received a copy of the GNU General Public License
8192 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8193 + * see <http://www.gnu.org/licenses/>.
8194 + *
8195 + * Ubicom32 implementation derived from (with many thanks):
8196 + *   arch/m68knommu
8197 + *   arch/blackfin
8198 + *   arch/parisc
8199 + */
8200 +#ifndef _ASM_UBICOM32_MMU_H
8201 +#define _ASM_UBICOM32_MMU_H
8202 +
8203 +typedef struct {
8204 +       struct vm_list_struct   *vmlist;
8205 +       unsigned long           end_brk;
8206 +#ifdef CONFIG_BINFMT_ELF_FDPIC
8207 +       unsigned long   exec_fdpic_loadmap;
8208 +       unsigned long   interp_fdpic_loadmap;
8209 +#endif
8210 +} mm_context_t;
8211 +
8212 +#endif /* _ASM_UBICOM32_MMU_H */
8213 --- /dev/null
8214 +++ b/arch/ubicom32/include/asm/module.h
8215 @@ -0,0 +1,44 @@
8216 +/*
8217 + * arch/ubicom32/include/asm/module.h
8218 + *   Ubicom32 architecture specific module definitions.
8219 + *
8220 + * (C) Copyright 2009, Ubicom, Inc.
8221 + *
8222 + * This file is part of the Ubicom32 Linux Kernel Port.
8223 + *
8224 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8225 + * it and/or modify it under the terms of the GNU General Public License
8226 + * as published by the Free Software Foundation, either version 2 of the
8227 + * License, or (at your option) any later version.
8228 + *
8229 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8230 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8231 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8232 + * the GNU General Public License for more details.
8233 + *
8234 + * You should have received a copy of the GNU General Public License
8235 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8236 + * see <http://www.gnu.org/licenses/>.
8237 + *
8238 + * Ubicom32 implementation derived from (with many thanks):
8239 + *   arch/m68knommu
8240 + *   arch/blackfin
8241 + *   arch/parisc
8242 + */
8243 +#ifndef _ASM_UBICOM32_MODULE_H
8244 +#define _ASM_UBICOM32_MODULE_H
8245 +
8246 +struct mod_arch_specific {
8247 +       void *ocm_inst;
8248 +       int ocm_inst_size;
8249 +};
8250 +
8251 +#define Elf_Shdr Elf32_Shdr
8252 +#define Elf_Sym Elf32_Sym
8253 +#define Elf_Ehdr Elf32_Ehdr
8254 +
8255 +#define ARCH_PROC_MODULES_EXTRA(m,mod) \
8256 +       seq_printf(m, " OCM(%d bytes @ 0x%p)", \
8257 +                  (mod)->arch.ocm_inst_size, (mod)->arch.ocm_inst)
8258 +
8259 +#endif /* _ASM_UBICOM32_MODULE_H */
8260 --- /dev/null
8261 +++ b/arch/ubicom32/include/asm/msgbuf.h
8262 @@ -0,0 +1,58 @@
8263 +/*
8264 + * arch/ubicom32/include/asm/msgbuf.h
8265 + *   Definition of msqid64_ds struct for Ubicom32 architecture.
8266 + *
8267 + * (C) Copyright 2009, Ubicom, Inc.
8268 + *
8269 + * This file is part of the Ubicom32 Linux Kernel Port.
8270 + *
8271 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8272 + * it and/or modify it under the terms of the GNU General Public License
8273 + * as published by the Free Software Foundation, either version 2 of the
8274 + * License, or (at your option) any later version.
8275 + *
8276 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8277 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8278 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8279 + * the GNU General Public License for more details.
8280 + *
8281 + * You should have received a copy of the GNU General Public License
8282 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8283 + * see <http://www.gnu.org/licenses/>.
8284 + *
8285 + * Ubicom32 implementation derived from (with many thanks):
8286 + *   arch/m68knommu
8287 + *   arch/blackfin
8288 + *   arch/parisc
8289 + */
8290 +#ifndef _ASM_UBICOM32_MSGBUF_H
8291 +#define _ASM_UBICOM32_MSGBUF_H
8292 +
8293 +/*
8294 + * The msqid64_ds structure for ubicom32 architecture.
8295 + * Note extra padding because this structure is passed back and forth
8296 + * between kernel and user space.
8297 + *
8298 + * Pad space is left for:
8299 + * - 64-bit time_t to solve y2038 problem
8300 + * - 2 miscellaneous 32-bit values
8301 + */
8302 +
8303 +struct msqid64_ds {
8304 +       struct ipc64_perm msg_perm;
8305 +       __kernel_time_t msg_stime;      /* last msgsnd time */
8306 +       unsigned long   __unused1;
8307 +       __kernel_time_t msg_rtime;      /* last msgrcv time */
8308 +       unsigned long   __unused2;
8309 +       __kernel_time_t msg_ctime;      /* last change time */
8310 +       unsigned long   __unused3;
8311 +       unsigned long  msg_cbytes;      /* current number of bytes on queue */
8312 +       unsigned long  msg_qnum;        /* number of messages in queue */
8313 +       unsigned long  msg_qbytes;      /* max number of bytes on queue */
8314 +       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
8315 +       __kernel_pid_t msg_lrpid;       /* last receive pid */
8316 +       unsigned long  __unused4;
8317 +       unsigned long  __unused5;
8318 +};
8319 +
8320 +#endif /* _ASM_UBICOM32_MSGBUF_H */
8321 --- /dev/null
8322 +++ b/arch/ubicom32/include/asm/mutex.h
8323 @@ -0,0 +1,41 @@
8324 +/*
8325 + * arch/ubicom32/include/asm/mutex.h
8326 + *   Generic mutex.h for Ubicom32 architecture.
8327 + *
8328 + * (C) Copyright 2009, Ubicom, Inc.
8329 + *
8330 + * This file is part of the Ubicom32 Linux Kernel Port.
8331 + *
8332 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8333 + * it and/or modify it under the terms of the GNU General Public License
8334 + * as published by the Free Software Foundation, either version 2 of the
8335 + * License, or (at your option) any later version.
8336 + *
8337 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8338 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8339 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8340 + * the GNU General Public License for more details.
8341 + *
8342 + * You should have received a copy of the GNU General Public License
8343 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8344 + * see <http://www.gnu.org/licenses/>.
8345 + *
8346 + * Ubicom32 implementation derived from (with many thanks):
8347 + *   arch/m68knommu
8348 + *   arch/blackfin
8349 + *   arch/parisc
8350 + */
8351 +/*
8352 + * Pull in the generic implementation for the mutex fastpath.
8353 + *
8354 + * TODO: implement optimized primitives instead, or leave the generic
8355 + * implementation in place, or pick the atomic_xchg() based generic
8356 + * implementation. (see asm-generic/mutex-xchg.h for details)
8357 + */
8358 +
8359 +#ifndef _ASM_UBICOM32_MUTEX_H
8360 +#define _ASM_UBICOM32_MUTEX_H
8361 +
8362 +#include <asm-generic/mutex-dec.h>
8363 +
8364 +#endif /* _ASM_UBICOM32_MUTEX_H */
8365 --- /dev/null
8366 +++ b/arch/ubicom32/include/asm/namei.h
8367 @@ -0,0 +1,38 @@
8368 +/*
8369 + * arch/ubicom32/include/asm/namei.h
8370 + *   Definition of __emul_prefix() for Ubicom32 architecture.
8371 + *
8372 + * (C) Copyright 2009, Ubicom, Inc.
8373 + *
8374 + * This file is part of the Ubicom32 Linux Kernel Port.
8375 + *
8376 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8377 + * it and/or modify it under the terms of the GNU General Public License
8378 + * as published by the Free Software Foundation, either version 2 of the
8379 + * License, or (at your option) any later version.
8380 + *
8381 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8382 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8383 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8384 + * the GNU General Public License for more details.
8385 + *
8386 + * You should have received a copy of the GNU General Public License
8387 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8388 + * see <http://www.gnu.org/licenses/>.
8389 + *
8390 + * Ubicom32 implementation derived from (with many thanks):
8391 + *   arch/m68knommu
8392 + *   arch/blackfin
8393 + *   arch/parisc
8394 + */
8395 +#ifndef _ASM_UBICOM32_NAMEI_H
8396 +#define _ASM_UBICOM32_NAMEI_H
8397 +
8398 +/* This dummy routine maybe changed to something useful
8399 + * for /usr/gnemul/ emulation stuff.
8400 + * Look at asm-sparc/namei.h for details.
8401 + */
8402 +
8403 +#define __emul_prefix() NULL
8404 +
8405 +#endif /* _ASM_UBICOM32_NAMEI_H */
8406 --- /dev/null
8407 +++ b/arch/ubicom32/include/asm/ocm-alloc.h
8408 @@ -0,0 +1,36 @@
8409 +/*
8410 + * arch/ubicom32/include/asm/ocm-alloc.h
8411 + *   Ubicom32 architecture specific ocm definitions.
8412 + *
8413 + * (C) Copyright 2009, Ubicom, Inc.
8414 + *
8415 + * This file is part of the Ubicom32 Linux Kernel Port.
8416 + *
8417 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8418 + * it and/or modify it under the terms of the GNU General Public License
8419 + * as published by the Free Software Foundation, either version 2 of the
8420 + * License, or (at your option) any later version.
8421 + *
8422 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8423 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8424 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8425 + * the GNU General Public License for more details.
8426 + *
8427 + * You should have received a copy of the GNU General Public License
8428 + * along with the Ubicom32 Linux Kernel Port.  If not,
8429 + * see <http://www.gnu.org/licenses/>.
8430 + *
8431 + * Ubicom32 implementation derived from (with many thanks):
8432 + *   arch/m68knommu
8433 + *   arch/blackfin
8434 + *   arch/parisc
8435 + */
8436 +#ifndef _ASM_UBICOM32_OCM_ALLOC_H
8437 +#define _ASM_UBICOM32_OCM_ALLOC_H
8438 +
8439 +
8440 +extern void *ocm_inst_alloc(size_t size, pid_t pid);
8441 +extern int ocm_free(const void *ptr);
8442 +extern int ocm_inst_free(const void *ptr);
8443 +
8444 +#endif /* _ASM_UBICOM32_OCM_ALLOC_H */
8445 --- /dev/null
8446 +++ b/arch/ubicom32/include/asm/ocm_size.h
8447 @@ -0,0 +1,2 @@
8448 +#define APP_OCM_CODE_SIZE (0x3ffc2e00-0x3ffc0000)
8449 +#define APP_OCM_DATA_SIZE (0x3ffd3500-0x3ffc8000)
8450 --- /dev/null
8451 +++ b/arch/ubicom32/include/asm/ocm_text.lds.inc
8452 @@ -0,0 +1,175 @@
8453 +/*
8454 + * arch/ubicom32/include/asm/ocm_text.lds.inc
8455 + *     <TODO: Replace with short file description>
8456 + *
8457 + * (C) Copyright 2009, Ubicom, Inc.
8458 + *
8459 + * This file is part of the Ubicom32 Linux Kernel Port.
8460 + *
8461 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8462 + * it and/or modify it under the terms of the GNU General Public License
8463 + * as published by the Free Software Foundation, either version 2 of the
8464 + * License, or (at your option) any later version.
8465 + *
8466 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8467 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8468 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8469 + * the GNU General Public License for more details.
8470 + *
8471 + * You should have received a copy of the GNU General Public License
8472 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8473 + * see <http://www.gnu.org/licenses/>.
8474 + *
8475 + * Ubicom32 implementation derived from (with many thanks):
8476 + *   arch/m68knommu
8477 + *   arch/blackfin
8478 + *   arch/parisc
8479 + */
8480 +*(.text.do_csum)
8481 +*(.text.tcp_packet)
8482 +*(.text.ipt_do_table)
8483 +*(.text.nf_conntrack_in)
8484 +*(.text.ip_forward)
8485 +*(.text.dev_queue_xmit)
8486 +*(.text.netif_receive_skb)
8487 +*(.text.ip_route_input)
8488 +*(.text.ip_finish_output)
8489 +*(.text.nf_iterate)
8490 +*(.text.__hash_conntrack)
8491 +*(.text.memset)
8492 +*(.text.memcpy)
8493 +*(.text.ip_rcv)
8494 +*(.text.__nf_conntrack_find)
8495 +*(.text.dev_hard_start_xmit)
8496 +*(.text.vlan_dev_hard_start_xmit)
8497 +*(.text.vlan_dev_hard_header)
8498 +*(.text.__nf_ct_refresh_acct)
8499 +*(.text.tcp_error)
8500 +*(.text.pfifo_fast_enqueue)
8501 +*(.text.ipv4_confirm)
8502 +*(.text.ip_output)
8503 +*(.text.neigh_connected_output)
8504 +*(.text.nf_hook_slow)
8505 +*(.text.nf_nat_packet)
8506 +*(.text.local_bh_enable)
8507 +*(.text.pfifo_fast_dequeue)
8508 +*(.text.ubi32_eth_receive)
8509 +*(.text.nf_nat_fn)
8510 +*(.text.skb_checksum)
8511 +*(.text.memmove)
8512 +*(.text.ubi32_eth_tx_done)
8513 +*(.text.eth_header)
8514 +*(.text.skb_release_data)
8515 +*(.text.nf_conntrack_find_get)
8516 +*(.text.process_backlog)
8517 +*(.text.vlan_skb_recv)
8518 +*(.text.ip_rcv_finish)
8519 +*(.text.__qdisc_run)
8520 +*(.text.skb_push)
8521 +*(.text.eth_type_trans)
8522 +*(.text.__alloc_skb)
8523 +*(.text.netif_rx)
8524 +*(.text.nf_ip_checksum)
8525 +*(.text.__skb_checksum_complete_head)
8526 +*(.text.ipv4_conntrack_defrag)
8527 +*(.text.tcp_pkt_to_tuple)
8528 +*(.text.kfree)
8529 +*(.text.tcp_manip_pkt)
8530 +*(.text.skb_put)
8531 +*(.text.nf_ct_get_tuple)
8532 +*(.text.__kmalloc)
8533 +*(.text.ubi32_eth_start_xmit)
8534 +*(.text.free_block)
8535 +*(.text.ipt_hook)
8536 +*(.text.kmem_cache_free)
8537 +*(.text.skb_pull_rcsum)
8538 +*(.text.cache_alloc_refill)
8539 +*(.text.skb_release_head_state)
8540 +*(.text.manip_pkt)
8541 +*(.text.ip_sabotage_in)
8542 +*(.text.ip_forward_finish)
8543 +*(.text.kmem_cache_alloc)
8544 +*(.text.local_bh_disable)
8545 +*(.text.ipv4_pkt_to_tuple)
8546 +*(.text.inet_proto_csum_replace4)
8547 +*(.text.__nf_ct_l4proto_find)
8548 +*(.text.csum_partial)
8549 +*(.text.neigh_resolve_output)
8550 +*(.text.__kfree_skb)
8551 +*(.text.kfree_skb)
8552 +*(.text.__find_vlan_dev)
8553 +*(.text.ldsr_ctxsw_thread)
8554 +*(.text.__do_IRQ)
8555 +*(.text.skb_pull)
8556 +*(.text.ipv4_invert_tuple)
8557 +*(.text.nf_ct_invert_tuplepr)
8558 +*(.text.skb_make_writable)
8559 +*(.text.ipv4_get_l4proto)
8560 +*(.text.handle_IRQ_event)
8561 +*(.text.net_rx_action)
8562 +*(.text.__do_softirq)
8563 +*(.text.nf_nat_in)
8564 +*(.text.note_interrupt)
8565 +*(.text.ipv4_conntrack_in)
8566 +*(.text.dst_release)
8567 +*(.text.tasklet_action)
8568 +*(.text.nf_nat_out)
8569 +*(.text.nf_ct_invert_tuple)
8570 +*(.text.do_IRQ)
8571 +*(.text.__tasklet_schedule)
8572 +*(.text.__skb_checksum_complete)
8573 +*(.text.ubi32_eth_interrupt)
8574 +*(.text.dev_kfree_skb_any)
8575 +*(.text.ret_from_interrupt_to_kernel)
8576 +*(.text.preemptive_context_save)
8577 +*(.text.irq_ack_vector)
8578 +*(.text.update_wall_time)
8579 +*(.text.ldsr_thread)
8580 +*(.text.irq_exit)
8581 +*(.text.ubi32_eth_do_tasklet)
8582 +*(.text.__napi_schedule)
8583 +*(.text.idle_cpu)
8584 +*(.text.run_timer_softirq)
8585 +*(.text.ldsr_mask_vector)
8586 +*(.text.irq_enter)
8587 +*(.text.ldsr_get_lsb)
8588 +*(.text.ldsr_unmask_vector)
8589 +*(.text.ip_fast_csum)
8590 +*(.text.hrtimer_run_queues)
8591 +*(.text.tcp_invert_tuple)
8592 +*(.text.T___705)
8593 +*(.text.run_posix_cpu_timers)
8594 +*(.text.free_hot_cold_page)
8595 +*(.text.lock_timer_base)
8596 +*(.text.calc_delta_mine)
8597 +*(.text.slab_destroy)
8598 +*(.text.rcu_pending)
8599 +*(.text.scheduler_tick)
8600 +*(.text.hrtimer_run_pending)
8601 +*(.text.do_softirq)
8602 +*(.text.del_timer)
8603 +*(.text.irq_end_vector)
8604 +*(.text.pci_read_u32)
8605 +*(.text.udivmodsi4)
8606 +*(.text.memcmp)
8607 +*(.text.memset)
8608 +*(.text.__slab_alloc)
8609 +*(.text.br_handle_frame)
8610 +*(.text.br_fdb_update)
8611 +*(.text.__br_fdb_get)
8612 +*(.text.br_forward)
8613 +*(.text.br_handle_frame_finish)
8614 +*(.text.pci_write_u32)
8615 +*(.text.kmem_freepages)
8616 +*(.text.br_dev_queue_push_xmit)
8617 +*(.text.ioread32)
8618 +*(.text.next_zones_zonelist)
8619 +*(.text.ubi32_pci_read_u32)
8620 +*(.text.zone_watermark_ok)
8621 +*(.text.__rmqueue_smallest)
8622 +*(.text.ubi32_eth_napi_poll)
8623 +*(.text.ubi32_pci_write_u32)
8624 +*(.text.ubi32_pci_read_u32)
8625 +*(.text._local_bh_enable)
8626 +*(.text._local_bh_disable)
8627 +*(.text.get_slab)
8628 --- /dev/null
8629 +++ b/arch/ubicom32/include/asm/page.h
8630 @@ -0,0 +1,106 @@
8631 +/*
8632 + * arch/ubicom32/include/asm/page.h
8633 + *   Memory page related operations and definitions.
8634 + *
8635 + * (C) Copyright 2009, Ubicom, Inc.
8636 + *
8637 + * This file is part of the Ubicom32 Linux Kernel Port.
8638 + *
8639 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8640 + * it and/or modify it under the terms of the GNU General Public License
8641 + * as published by the Free Software Foundation, either version 2 of the
8642 + * License, or (at your option) any later version.
8643 + *
8644 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8645 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8646 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8647 + * the GNU General Public License for more details.
8648 + *
8649 + * You should have received a copy of the GNU General Public License
8650 + * along with the Ubicom32 Linux Kernel Port.  If not,
8651 + * see <http://www.gnu.org/licenses/>.
8652 + *
8653 + * Ubicom32 implementation derived from (with many thanks):
8654 + *   arch/m68knommu
8655 + *   arch/blackfin
8656 + *   arch/parisc
8657 + */
8658 +#ifndef _ASM_UBICOM32_PAGE_H
8659 +#define _ASM_UBICOM32_PAGE_H
8660 +
8661 +/* PAGE_SHIFT determines the page size */
8662 +
8663 +#define PAGE_SHIFT     12
8664 +#define PAGE_SIZE      (1 << PAGE_SHIFT)
8665 +#define PAGE_MASK      (~(PAGE_SIZE-1))
8666 +
8667 +#include <asm/setup.h>
8668 +
8669 +#ifndef __ASSEMBLY__
8670 +
8671 +#define get_user_page(vaddr)           __get_free_page(GFP_KERNEL)
8672 +#define free_user_page(page, addr)     free_page(addr)
8673 +
8674 +#define clear_page(page)       memset((page), 0, PAGE_SIZE)
8675 +#define copy_page(to,from)     memcpy((to), (from), PAGE_SIZE)
8676 +
8677 +#define clear_user_page(page, vaddr, pg)       clear_page(page)
8678 +#define copy_user_page(to, from, vaddr, pg)    copy_page(to, from)
8679 +
8680 +#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
8681 +       alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
8682 +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
8683 +
8684 +/*
8685 + * These are used to make use of C type-checking..
8686 + */
8687 +typedef struct { unsigned long pte; } pte_t;
8688 +typedef struct { unsigned long pmd[16]; } pmd_t;
8689 +typedef struct { unsigned long pgd; } pgd_t;
8690 +typedef struct { unsigned long pgprot; } pgprot_t;
8691 +typedef struct page *pgtable_t;
8692 +
8693 +#define pte_val(x)     ((x).pte)
8694 +#define pmd_val(x)     ((&x)->pmd[0])
8695 +#define pgd_val(x)     ((x).pgd)
8696 +#define pgprot_val(x)  ((x).pgprot)
8697 +
8698 +#define __pte(x)       ((pte_t) { (x) } )
8699 +#define __pmd(x)       ((pmd_t) { (x) } )
8700 +#define __pgd(x)       ((pgd_t) { (x) } )
8701 +#define __pgprot(x)    ((pgprot_t) { (x) } )
8702 +
8703 +extern unsigned long memory_start;
8704 +extern unsigned long memory_end;
8705 +
8706 +#endif /* !__ASSEMBLY__ */
8707 +
8708 +#include <asm/page_offset.h>
8709 +
8710 +#define PAGE_OFFSET            (PAGE_OFFSET_RAW)
8711 +
8712 +#ifndef __ASSEMBLY__
8713 +
8714 +#define __pa(vaddr)            virt_to_phys((void *)(vaddr))
8715 +#define __va(paddr)            phys_to_virt((unsigned long)(paddr))
8716 +
8717 +#define virt_to_pfn(kaddr)     (__pa(kaddr) >> PAGE_SHIFT)
8718 +#define pfn_to_virt(pfn)       __va((pfn) << PAGE_SHIFT)
8719 +
8720 +#define virt_to_page(addr)     (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
8721 +#define page_to_virt(page)     ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
8722 +
8723 +#define pfn_to_page(pfn)       virt_to_page(pfn_to_virt(pfn))
8724 +#define page_to_pfn(page)      virt_to_pfn(page_to_virt(page))
8725 +#define pfn_valid(pfn)         ((pfn) < max_mapnr)
8726 +
8727 +#define        virt_addr_valid(kaddr)  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
8728 +                               ((void *)(kaddr) < (void *)memory_end))
8729 +
8730 +#endif /* __ASSEMBLY__ */
8731 +
8732 +#ifdef __KERNEL__
8733 +#include <asm-generic/page.h>
8734 +#endif
8735 +
8736 +#endif /* _ASM_UBICOM32_PAGE_H */
8737 --- /dev/null
8738 +++ b/arch/ubicom32/include/asm/page_offset.h
8739 @@ -0,0 +1,35 @@
8740 +/*
8741 + * arch/ubicom32/include/asm/page_offset.h
8742 + *   Definition of PAGE_OFFSET_RAW for Ubicom32 architecture.
8743 + *
8744 + * (C) Copyright 2009, Ubicom, Inc.
8745 + *
8746 + * This file is part of the Ubicom32 Linux Kernel Port.
8747 + *
8748 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8749 + * it and/or modify it under the terms of the GNU General Public License
8750 + * as published by the Free Software Foundation, either version 2 of the
8751 + * License, or (at your option) any later version.
8752 + *
8753 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8754 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8755 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8756 + * the GNU General Public License for more details.
8757 + *
8758 + * You should have received a copy of the GNU General Public License
8759 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8760 + * see <http://www.gnu.org/licenses/>.
8761 + *
8762 + * Ubicom32 implementation derived from (with many thanks):
8763 + *   arch/m68knommu
8764 + *   arch/blackfin
8765 + *   arch/parisc
8766 + */
8767 +
8768 +#ifndef _ASM_UBICOM32_PAGE_OFFSET_H
8769 +#define _ASM_UBICOM32_PAGE_OFFSET_H
8770 +
8771 +/* This handles the memory map.. */
8772 +#define        PAGE_OFFSET_RAW         0x3ffc0000
8773 +
8774 +#endif /* _ASM_UBICOM32_PAGE_OFFSET_H */
8775 --- /dev/null
8776 +++ b/arch/ubicom32/include/asm/param.h
8777 @@ -0,0 +1,49 @@
8778 +/*
8779 + * arch/ubicom32/include/asm/param.h
8780 + *   Definition of miscellaneous constants, including HZ.
8781 + *
8782 + * (C) Copyright 2009, Ubicom, Inc.
8783 + *
8784 + * This file is part of the Ubicom32 Linux Kernel Port.
8785 + *
8786 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8787 + * it and/or modify it under the terms of the GNU General Public License
8788 + * as published by the Free Software Foundation, either version 2 of the
8789 + * License, or (at your option) any later version.
8790 + *
8791 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8792 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8793 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8794 + * the GNU General Public License for more details.
8795 + *
8796 + * You should have received a copy of the GNU General Public License
8797 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8798 + * see <http://www.gnu.org/licenses/>.
8799 + *
8800 + * Ubicom32 implementation derived from (with many thanks):
8801 + *   arch/m68knommu
8802 + *   arch/blackfin
8803 + *   arch/parisc
8804 + */
8805 +#ifndef _ASM_UBICOM32_PARAM_H
8806 +#define _ASM_UBICOM32_PARAM_H
8807 +
8808 +#ifdef __KERNEL__
8809 +#define HZ CONFIG_HZ
8810 +#define        USER_HZ         HZ
8811 +#define        CLOCKS_PER_SEC  (USER_HZ)
8812 +#endif
8813 +
8814 +#ifndef HZ
8815 +#define HZ     100
8816 +#endif
8817 +
8818 +#define EXEC_PAGESIZE  4096
8819 +
8820 +#ifndef NOGROUP
8821 +#define NOGROUP                (-1)
8822 +#endif
8823 +
8824 +#define MAXHOSTNAMELEN 64      /* max length of hostname */
8825 +
8826 +#endif /* _ASM_UBICOM32_PARAM_H */
8827 --- /dev/null
8828 +++ b/arch/ubicom32/include/asm/pci.h
8829 @@ -0,0 +1,210 @@
8830 +/*
8831 + * arch/ubicom32/include/asm/pci.h
8832 + *   Definitions of PCI operations for Ubicom32 architecture.
8833 + *
8834 + * (C) Copyright 2009, Ubicom, Inc.
8835 + *
8836 + * This file is part of the Ubicom32 Linux Kernel Port.
8837 + *
8838 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
8839 + * it and/or modify it under the terms of the GNU General Public License
8840 + * as published by the Free Software Foundation, either version 2 of the
8841 + * License, or (at your option) any later version.
8842 + *
8843 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
8844 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
8845 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
8846 + * the GNU General Public License for more details.
8847 + *
8848 + * You should have received a copy of the GNU General Public License
8849 + * along with the Ubicom32 Linux Kernel Port.  If not, 
8850 + * see <http://www.gnu.org/licenses/>.
8851 + *
8852 + * Ubicom32 implementation derived from (with many thanks):
8853 + *   arch/m68knommu
8854 + *   arch/blackfin
8855 + *   arch/parisc
8856 + */
8857 +#ifndef _ASM_UBICOM32_PCI_H
8858 +#define _ASM_UBICOM32_PCI_H
8859 +
8860 +#include <asm/io.h>
8861 +
8862 +/* The PCI address space does equal the physical memory
8863 + * address space.  The networking and block device layers use
8864 + * this boolean for bounce buffer decisions.
8865 + */
8866 +#define PCI_DMA_BUS_IS_PHYS    (1)
8867 +
8868 +
8869 +
8870 +/*
8871 + * Perform a master read/write to the PCI bus.
8872 + * These functions return a PCI_RESP_xxx code.
8873 + */
8874 +extern u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data);
8875 +extern u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data);
8876 +extern u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data);
8877 +extern u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data);
8878 +extern u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data);
8879 +extern u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data);
8880 +
8881 +
8882 +#define PCIBIOS_MIN_IO          0x100
8883 +#define PCIBIOS_MIN_MEM         0x10000000
8884 +
8885 +#define pcibios_assign_all_busses()    0
8886 +#define pcibios_scan_all_fns(a, b)     0
8887 +extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
8888 +       struct resource *res);
8889 +
8890 +extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
8891 +       struct pci_bus_region *region);
8892 +
8893 +struct pci_sys_data;
8894 +struct pci_bus;
8895 +
8896 +struct hw_pci {
8897 +        struct list_head buses;
8898 +        int             nr_controllers;
8899 +        int             (*setup)(int nr, struct pci_sys_data *);
8900 +        struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
8901 +        void            (*preinit)(void);
8902 +        void            (*postinit)(void);
8903 +        u8              (*swizzle)(struct pci_dev *dev, u8 *pin);
8904 +        int             (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
8905 +};
8906 +
8907 +/*
8908 + * Per-controller structure
8909 + */
8910 +struct pci_sys_data {
8911 +        struct list_head node;
8912 +        int             busnr;          /* primary bus number                   */
8913 +        u64             mem_offset;     /* bus->cpu memory mapping offset       */
8914 +        unsigned long   io_offset;      /* bus->cpu IO mapping offset           */
8915 +        struct pci_bus  *bus;           /* PCI bus                              */
8916 +        struct resource *resource[3];   /* Primary PCI bus resources            */
8917 +                                        /* Bridge swizzling                     */
8918 +        u8              (*swizzle)(struct pci_dev *, u8 *);
8919 +                                        /* IRQ mapping                          */
8920 +        int             (*map_irq)(struct pci_dev *, u8, u8);
8921 +        struct hw_pci   *hw;
8922 +};
8923 +
8924 +static  inline struct resource *
8925 +pcibios_select_root(struct pci_dev *pdev, struct resource *res)
8926 +{
8927 +        struct resource *root = NULL;
8928 +
8929 +        if (res->flags & IORESOURCE_IO)
8930 +                root = &ioport_resource;
8931 +        if (res->flags & IORESOURCE_MEM)
8932 +                root = &iomem_resource;
8933 +
8934 +        return root;
8935 +}
8936 +
8937 +static inline void pcibios_set_master(struct pci_dev *dev)
8938 +{
8939 +        /* No special bus mastering setup handling */
8940 +}
8941 +#define HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE 1
8942 +#define HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY 1
8943 +
8944 +#ifdef CONFIG_PCI
8945 +static inline void * pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
8946 +                     dma_addr_t *dma_handle)
8947 +{
8948 +    void *vaddr = kmalloc(size, GFP_KERNEL);
8949 +    if(vaddr != NULL) {
8950 +        *dma_handle = virt_to_phys(vaddr);
8951 +    }
8952 +    return vaddr;
8953 +}
8954 +
8955 +static  inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
8956 +{
8957 +       return 1;
8958 +}
8959 +
8960 +static  inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
8961 +       void *cpu_addr, dma_addr_t dma_handle)
8962 +{ 
8963 +       kfree(cpu_addr);
8964 +       return;
8965 +}
8966 +
8967 +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
8968 +       size_t size, int direction)
8969 +{
8970 +        return virt_to_phys(ptr);
8971 +}
8972 +
8973 +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
8974 +       size_t size, int direction)
8975 +{
8976 +        return;
8977 +}
8978 +
8979 +static inline dma_addr_t
8980 +pci_map_page(struct pci_dev *hwdev, struct page *page,
8981 +             unsigned long offset, size_t size, int direction)
8982 +{
8983 +        return pci_map_single(hwdev, page_address(page) + offset, size, (int)direction);
8984 +}
8985 +
8986 +static inline void
8987 +pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
8988 +               size_t size, int direction)
8989 +{
8990 +       pci_unmap_single(hwdev, dma_address, size, direction);
8991 +}
8992 +
8993 +static inline int
8994 +pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
8995 +           int nents, int direction)
8996 +{
8997 +        return nents; 
8998 +}
8999 +
9000 +static inline void
9001 +pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
9002 +             int nents, int direction)
9003 +{
9004 +}
9005 +
9006 +static inline void
9007 +pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
9008 +                int nelems, int direction)
9009 +{
9010 +}
9011 +
9012 +static inline void
9013 +pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
9014 +                int nelems, int direction)
9015 +{
9016 +}
9017 +
9018 +static inline void
9019 +pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
9020 +                    size_t size, int direction)
9021 +{
9022 +}
9023 +
9024 +static inline void
9025 +pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
9026 +                    size_t size, int direction)
9027 +{
9028 +}
9029 +
9030 +static inline int
9031 +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
9032 +{
9033 +        return dma_addr == 0;
9034 +}
9035 +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
9036 +extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
9037 +#endif
9038 +
9039 +#endif /* _ASM_UBICOM32_PCI_H */
9040 --- /dev/null
9041 +++ b/arch/ubicom32/include/asm/percpu.h
9042 @@ -0,0 +1,33 @@
9043 +/*
9044 + * arch/ubicom32/include/asm/percpu.h
9045 + *   Generic percpu.h for the Ubicom32 architecture.
9046 + *
9047 + * (C) Copyright 2009, Ubicom, Inc.
9048 + *
9049 + * This file is part of the Ubicom32 Linux Kernel Port.
9050 + *
9051 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9052 + * it and/or modify it under the terms of the GNU General Public License
9053 + * as published by the Free Software Foundation, either version 2 of the
9054 + * License, or (at your option) any later version.
9055 + *
9056 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9057 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9058 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9059 + * the GNU General Public License for more details.
9060 + *
9061 + * You should have received a copy of the GNU General Public License
9062 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9063 + * see <http://www.gnu.org/licenses/>.
9064 + *
9065 + * Ubicom32 implementation derived from (with many thanks):
9066 + *   arch/m68knommu
9067 + *   arch/blackfin
9068 + *   arch/parisc
9069 + */
9070 +#ifndef _ASM_UBICOM32_PERCPU_H
9071 +#define _ASM_UBICOM32_PERCPU_H
9072 +
9073 +#include <asm-generic/percpu.h>
9074 +
9075 +#endif /* _ASM_UBICOM32_PERCPU_H */
9076 --- /dev/null
9077 +++ b/arch/ubicom32/include/asm/pgalloc.h
9078 @@ -0,0 +1,36 @@
9079 +/*
9080 + * arch/ubicom32/include/asm/pgalloc.h
9081 + *   Page table allocation definitions.
9082 + *
9083 + * (C) Copyright 2009, Ubicom, Inc.
9084 + *
9085 + * This file is part of the Ubicom32 Linux Kernel Port.
9086 + *
9087 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9088 + * it and/or modify it under the terms of the GNU General Public License
9089 + * as published by the Free Software Foundation, either version 2 of the
9090 + * License, or (at your option) any later version.
9091 + *
9092 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9093 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9094 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9095 + * the GNU General Public License for more details.
9096 + *
9097 + * You should have received a copy of the GNU General Public License
9098 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9099 + * see <http://www.gnu.org/licenses/>.
9100 + *
9101 + * Ubicom32 implementation derived from (with many thanks):
9102 + *   arch/m68knommu
9103 + *   arch/blackfin
9104 + *   arch/parisc
9105 + */
9106 +#ifndef _ASM_UBICOM32_PGALLOC_H
9107 +#define _ASM_UBICOM32_PGALLOC_H
9108 +
9109 +#include <linux/mm.h>
9110 +#include <asm/setup.h>
9111 +
9112 +#define check_pgt_cache()      do { } while (0)
9113 +
9114 +#endif /* _ASM_UBICOM32_PGALLOC_H */
9115 --- /dev/null
9116 +++ b/arch/ubicom32/include/asm/pgtable.h
9117 @@ -0,0 +1,124 @@
9118 +/*
9119 + * arch/ubicom32/include/asm/pgtable.h
9120 + *   Ubicom32 pseudo page table definitions and operations.
9121 + *
9122 + * (C) Copyright 2009, Ubicom, Inc.
9123 + * Copyright (C) 2004   Microtronix Datacom Ltd
9124 + *
9125 + * This file is part of the Ubicom32 Linux Kernel Port.
9126 + *
9127 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9128 + * it and/or modify it under the terms of the GNU General Public License
9129 + * as published by the Free Software Foundation, either version 2 of the
9130 + * License, or (at your option) any later version.
9131 + *
9132 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9133 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9134 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9135 + * the GNU General Public License for more details.
9136 + *
9137 + * You should have received a copy of the GNU General Public License
9138 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9139 + * see <http://www.gnu.org/licenses/>.
9140 + *
9141 + * Ubicom32 implementation derived from (with many thanks):
9142 + *   arch/m68knommu
9143 + *   arch/blackfin
9144 + *   arch/parisc
9145 + *   and various works, Alpha, ix86, M68K, Sparc, ...et al
9146 + */
9147 +#ifndef _ASM_UBICOM32_PGTABLE_H
9148 +#define _ASM_UBICOM32_PGTABLE_H
9149 +
9150 +#include <asm-generic/4level-fixup.h>
9151 +
9152 +//vic - this bit copied from m68knommu version
9153 +#include <asm/setup.h>
9154 +#include <asm/io.h>
9155 +#include <linux/sched.h>
9156 +
9157 +typedef pte_t *pte_addr_t;
9158 +
9159 +#define pgd_present(pgd)       (1)       /* pages are always present on NO_MM */
9160 +#define pgd_none(pgd)          (0)
9161 +#define pgd_bad(pgd)           (0)
9162 +#define pgd_clear(pgdp)
9163 +#define kern_addr_valid(addr)  (1)
9164 +#define        pmd_offset(a, b)        ((void *)0)
9165 +
9166 +#define PAGE_NONE              __pgprot(0)    /* these mean nothing to NO_MM */
9167 +#define PAGE_SHARED            __pgprot(0)    /* these mean nothing to NO_MM */
9168 +#define PAGE_COPY              __pgprot(0)    /* these mean nothing to NO_MM */
9169 +#define PAGE_READONLY          __pgprot(0)    /* these mean nothing to NO_MM */
9170 +#define PAGE_KERNEL            __pgprot(0)    /* these mean nothing to NO_MM */
9171 +//vic - this bit copied from m68knommu version
9172 +
9173 +extern void paging_init(void);
9174 +#define swapper_pg_dir ((pgd_t *) 0)
9175 +
9176 +#define __swp_type(x)          (0)
9177 +#define __swp_offset(x)                (0)
9178 +#define __swp_entry(typ,off)   ((swp_entry_t) { ((typ) | ((off) << 7)) })
9179 +#define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
9180 +#define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
9181 +
9182 +/*
9183 + * pgprot_noncached() is only for infiniband pci support, and a real
9184 + * implementation for RAM would be more complicated.
9185 + */
9186 +#define pgprot_noncached(prot) (prot)
9187 +
9188 +static inline int pte_file(pte_t pte) { return 0; }
9189 +
9190 +/*
9191 + * ZERO_PAGE is a global shared page that is always zero: used
9192 + * for zero-mapped memory areas etc..
9193 + */
9194 +#define ZERO_PAGE(vaddr)       (virt_to_page(0))
9195 +
9196 +extern unsigned int kobjsize(const void *objp);
9197 +extern int is_in_rom(unsigned long);
9198 +
9199 +/*
9200 + * No page table caches to initialise
9201 + */
9202 +#define pgtable_cache_init()   do { } while (0)
9203 +
9204 +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
9205 +               remap_pfn_range(vma, vaddr, pfn, size, prot)
9206 +
9207 +extern inline void flush_cache_mm(struct mm_struct *mm)
9208 +{
9209 +}
9210 +
9211 +extern inline void flush_cache_range(struct mm_struct *mm,
9212 +                                    unsigned long start,
9213 +                                    unsigned long end)
9214 +{
9215 +}
9216 +
9217 +/* Push the page at kernel virtual address and clear the icache */
9218 +extern inline void flush_page_to_ram (unsigned long address)
9219 +{
9220 +}
9221 +
9222 +/* Push n pages at kernel virtual address and clear the icache */
9223 +extern inline void flush_pages_to_ram (unsigned long address, int n)
9224 +{
9225 +}
9226 +
9227 +/*
9228 + * All 32bit addresses are effectively valid for vmalloc...
9229 + * Sort of meaningless for non-VM targets.
9230 + */
9231 +#define        VMALLOC_START   0
9232 +#define        VMALLOC_END     0xffffffff
9233 +
9234 +#define arch_enter_lazy_mmu_mode()     do {} while (0)
9235 +#define arch_leave_lazy_mmu_mode()     do {} while (0)
9236 +#define arch_flush_lazy_mmu_mode()     do {} while (0)
9237 +#define arch_enter_lazy_cpu_mode()     do {} while (0)
9238 +#define arch_leave_lazy_cpu_mode()     do {} while (0)
9239 +#define arch_flush_lazy_cpu_mode()     do {} while (0)
9240 +
9241 +#endif /* _ASM_UBICOM32_PGTABLE_H */
9242 --- /dev/null
9243 +++ b/arch/ubicom32/include/asm/poll.h
9244 @@ -0,0 +1,36 @@
9245 +/*
9246 + * arch/ubicom32/include/asm/poll.h
9247 + *   Ubicom32 specific poll() related flags definitions.
9248 + *
9249 + * (C) Copyright 2009, Ubicom, Inc.
9250 + *
9251 + * This file is part of the Ubicom32 Linux Kernel Port.
9252 + *
9253 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9254 + * it and/or modify it under the terms of the GNU General Public License
9255 + * as published by the Free Software Foundation, either version 2 of the
9256 + * License, or (at your option) any later version.
9257 + *
9258 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9259 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9260 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9261 + * the GNU General Public License for more details.
9262 + *
9263 + * You should have received a copy of the GNU General Public License
9264 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9265 + * see <http://www.gnu.org/licenses/>.
9266 + *
9267 + * Ubicom32 implementation derived from (with many thanks):
9268 + *   arch/m68knommu
9269 + *   arch/blackfin
9270 + *   arch/parisc
9271 + */
9272 +#ifndef _ASM_UBICOM32_POLL_H
9273 +#define _ASM_UBICOM32_POLL_H
9274 +
9275 +#define POLLWRNORM     POLLOUT
9276 +#define POLLWRBAND     0x0100
9277 +
9278 +#include <asm-generic/poll.h>
9279 +
9280 +#endif /* _ASM_UBICOM32_POLL_H */
9281 --- /dev/null
9282 +++ b/arch/ubicom32/include/asm/posix_types.h
9283 @@ -0,0 +1,93 @@
9284 +/*
9285 + * arch/ubicom32/include/asm/posix_types.h
9286 + *   Ubicom32 architecture posix types.
9287 + *
9288 + * (C) Copyright 2009, Ubicom, Inc.
9289 + * Copyright (C) 2004   Microtronix Datacom Ltd
9290 + *
9291 + * This file is part of the Ubicom32 Linux Kernel Port.
9292 + *
9293 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9294 + * it and/or modify it under the terms of the GNU General Public License
9295 + * as published by the Free Software Foundation, either version 2 of the
9296 + * License, or (at your option) any later version.
9297 + *
9298 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9299 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9300 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9301 + * the GNU General Public License for more details.
9302 + *
9303 + * You should have received a copy of the GNU General Public License
9304 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9305 + * see <http://www.gnu.org/licenses/>.
9306 + *
9307 + * Ubicom32 implementation derived from (with many thanks):
9308 + *   arch/m68knommu
9309 + *   arch/blackfin
9310 + *   arch/parisc
9311 + */
9312 +#ifndef __ARCH_UBICOM32_POSIX_TYPES_H
9313 +#define __ARCH_UBICOM32_POSIX_TYPES_H
9314 +
9315 +/*
9316 + * This file is generally used by user-level software, so you need to
9317 + * be a little careful about namespace pollution etc.  Also, we cannot
9318 + * assume GCC is being used.
9319 + */
9320 +
9321 +typedef unsigned long  __kernel_ino_t;
9322 +typedef unsigned short __kernel_mode_t;
9323 +typedef unsigned short __kernel_nlink_t;
9324 +typedef long           __kernel_off_t;
9325 +typedef int            __kernel_pid_t;
9326 +typedef unsigned short __kernel_ipc_pid_t;
9327 +typedef unsigned short __kernel_uid_t;
9328 +typedef unsigned short __kernel_gid_t;
9329 +typedef unsigned int   __kernel_size_t;
9330 +typedef int            __kernel_ssize_t;
9331 +typedef int            __kernel_ptrdiff_t;
9332 +typedef long           __kernel_time_t;
9333 +typedef long           __kernel_suseconds_t;
9334 +typedef long           __kernel_clock_t;
9335 +typedef int            __kernel_timer_t;
9336 +typedef int            __kernel_clockid_t;
9337 +typedef int            __kernel_daddr_t;
9338 +typedef char *         __kernel_caddr_t;
9339 +typedef unsigned short __kernel_uid16_t;
9340 +typedef unsigned short __kernel_gid16_t;
9341 +typedef unsigned int   __kernel_uid32_t;
9342 +typedef unsigned int   __kernel_gid32_t;
9343 +
9344 +typedef unsigned short __kernel_old_uid_t;
9345 +typedef unsigned short __kernel_old_gid_t;
9346 +typedef unsigned short __kernel_old_dev_t;
9347 +
9348 +#ifdef __GNUC__
9349 +typedef long long      __kernel_loff_t;
9350 +#endif
9351 +
9352 +typedef struct {
9353 +#if defined(__KERNEL__) || defined(__USE_ALL)
9354 +       int     val[2];
9355 +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9356 +       int     __val[2];
9357 +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9358 +} __kernel_fsid_t;
9359 +
9360 +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
9361 +
9362 +#undef __FD_SET
9363 +#define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
9364 +
9365 +#undef __FD_CLR
9366 +#define        __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
9367 +
9368 +#undef __FD_ISSET
9369 +#define        __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
9370 +
9371 +#undef __FD_ZERO
9372 +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
9373 +
9374 +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
9375 +
9376 +#endif
9377 --- /dev/null
9378 +++ b/arch/ubicom32/include/asm/processor.h
9379 @@ -0,0 +1,163 @@
9380 +/*
9381 + * arch/ubicom32/include/asm/processor.h
9382 + *   Thread related definitions for Ubicom32 architecture.
9383 + *
9384 + * (C) Copyright 2009, Ubicom, Inc.
9385 + * Copyright (C) 1995 Hamish Macdonald
9386 + *
9387 + * This file is part of the Ubicom32 Linux Kernel Port.
9388 + *
9389 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9390 + * it and/or modify it under the terms of the GNU General Public License
9391 + * as published by the Free Software Foundation, either version 2 of the
9392 + * License, or (at your option) any later version.
9393 + *
9394 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9395 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9396 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9397 + * the GNU General Public License for more details.
9398 + *
9399 + * You should have received a copy of the GNU General Public License
9400 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9401 + * see <http://www.gnu.org/licenses/>.
9402 + *
9403 + * Ubicom32 implementation derived from (with many thanks):
9404 + *   arch/m68knommu
9405 + *   arch/blackfin
9406 + *   arch/parisc
9407 + */
9408 +
9409 +#ifndef _ASM_UBICOM32_PROCESSOR_H
9410 +#define _ASM_UBICOM32_PROCESSOR_H
9411 +
9412 +/*
9413 + * Default implementation of macro that returns current
9414 + * instruction pointer ("program counter").
9415 + */
9416 +#define current_text_addr() ({ __label__ _l; _l: &&_l;})
9417 +
9418 +#include <linux/compiler.h>
9419 +#include <linux/threads.h>
9420 +#include <asm/types.h>
9421 +#include <asm/segment.h>
9422 +#include <asm/fpu.h>
9423 +#include <asm/ptrace.h>
9424 +#include <asm/current.h>
9425 +#include <asm/thread_info.h>
9426 +
9427 +#if defined(CONFIG_UBICOM32_V3)
9428 +       #define CPU "IP5K"
9429 +#endif
9430 +#if defined(CONFIG_UBICOM32_V4)
9431 +       #define CPU "IP7K"
9432 +#endif
9433 +#ifndef CPU
9434 +       #define CPU "UNKNOWN"
9435 +#endif
9436 +
9437 +/*
9438 + * User space process size: 1st byte beyond user address space.
9439 + */
9440 +extern unsigned long memory_end;
9441 +#define TASK_SIZE      (memory_end)
9442 +
9443 +/*
9444 + * This decides where the kernel will search for a free chunk of vm
9445 + * space during mmap's. We won't be using it
9446 + */
9447 +#define TASK_UNMAPPED_BASE     0
9448 +
9449 +/*
9450 + * This is the structure where we are going to save callee-saved registers.
9451 + * A5 is the return address, A7 is the stack pointer, A6 is the frame
9452 + * pointer.  This is the frame that is created because of switch_to. This
9453 + * is not the frame due to interrupt preemption or because of syscall entry.
9454 + */
9455 +
9456 +struct thread_struct {
9457 +       unsigned long  d10;             /* D10  */
9458 +       unsigned long  d11;             /* D11  */
9459 +       unsigned long  d12;             /* D12  */
9460 +       unsigned long  d13;             /* D13  */
9461 +       unsigned long  a1;              /* A1  */
9462 +       unsigned long  a2;              /* A2  */
9463 +       unsigned long  a5;              /* A5 return address. */
9464 +       unsigned long  a6;              /* A6 */
9465 +       unsigned long  sp;              /* A7 kernel stack pointer. */
9466 +};
9467 +
9468 +#define INIT_THREAD  { \
9469 +       0, 0, 0, 0, 0, 0, 0, 0, \
9470 +       sizeof(init_stack) + (unsigned long) init_stack - 8, \
9471 +}
9472 +
9473 +/*
9474 + * Do necessary setup to start up a newly executed thread.
9475 + *
9476 + * pass the data segment into user programs if it exists,
9477 + * it can't hurt anything as far as I can tell
9478 + */
9479 +/*
9480 + * Do necessary setup to start up a newly executed thread.
9481 + */
9482 +#define start_thread(regs, new_pc, new_sp)      \
9483 +       do {                                     \
9484 +               regs->pc = new_pc & ~3;          \
9485 +               regs->an[5] = new_pc & ~3;       \
9486 +               regs->an[7] = new_sp;            \
9487 +               regs->nesting_level = -1;        \
9488 +               regs->frame_type = UBICOM32_FRAME_TYPE_NEW_THREAD; \
9489 +               regs->thread_type = NORMAL_THREAD; \
9490 +       } while(0)
9491 +
9492 +/* Forward declaration, a strange C thing */
9493 +struct task_struct;
9494 +
9495 +/* Free all resources held by a thread. */
9496 +static inline void release_thread(struct task_struct *dead_task)
9497 +{
9498 +}
9499 +
9500 +/* Prepare to copy thread state - unlazy all lazy status */
9501 +#define prepare_to_copy(tsk)   do { } while (0)
9502 +
9503 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
9504 +
9505 +/*
9506 + * Free current thread data structures etc..
9507 + */
9508 +static inline void exit_thread(void)
9509 +{
9510 +}
9511 +
9512 +unsigned long thread_saved_pc(struct task_struct *tsk);
9513 +unsigned long get_wchan(struct task_struct *p);
9514 +
9515 +#define        KSTK_EIP(tsk)   (tsk->thread.a5)
9516 +#define        KSTK_ESP(tsk)   (tsk->thread.sp)
9517 +
9518 +#define cpu_relax()    barrier()
9519 +
9520 +extern void processor_init(void);
9521 +extern unsigned int processor_timers(void);
9522 +extern unsigned int processor_threads(void);
9523 +extern unsigned int processor_frequency(void);
9524 +extern int processor_interrupts(unsigned int *int0, unsigned int *int1);
9525 +extern int processor_ocm(void **socm, void **eocm);
9526 +extern int processor_dram(void **sdram, void **edram);
9527 +
9528 +#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
9529 +#define KSTK_TOP(info)                                                 \
9530 +({                                                                     \
9531 +       unsigned long *__ptr = (unsigned long *)(info);                 \
9532 +       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
9533 +})
9534 +
9535 +#define task_pt_regs(task)                                             \
9536 +({                                                                     \
9537 +       struct pt_regs *__regs__;                                       \
9538 +       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
9539 +       __regs__ - 1;                                                   \
9540 +})
9541 +
9542 +#endif /* _ASM_UBICOM32_PROCESSOR_H */
9543 --- /dev/null
9544 +++ b/arch/ubicom32/include/asm/ptrace.h
9545 @@ -0,0 +1,177 @@
9546 +/*
9547 + * arch/ubicom32/include/asm/ptrace.h
9548 + *   Ubicom32 architecture ptrace support.
9549 + *
9550 + * (C) Copyright 2009, Ubicom, Inc.
9551 + *
9552 + * This file is part of the Ubicom32 Linux Kernel Port.
9553 + *
9554 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9555 + * it and/or modify it under the terms of the GNU General Public License
9556 + * as published by the Free Software Foundation, either version 2 of the
9557 + * License, or (at your option) any later version.
9558 + *
9559 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9560 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9561 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9562 + * the GNU General Public License for more details.
9563 + *
9564 + * You should have received a copy of the GNU General Public License
9565 + * along with the Ubicom32 Linux Kernel Port.  If not,
9566 + * see <http://www.gnu.org/licenses/>.
9567 + *
9568 + * Ubicom32 implementation derived from (with many thanks):
9569 + *   arch/m68knommu
9570 + *   arch/blackfin
9571 + *   arch/parisc
9572 + */
9573 +#ifndef _ASM_UBICOM32_PTRACE_H
9574 +#define _ASM_UBICOM32_PTRACE_H
9575 +
9576 +#ifndef __ASSEMBLY__
9577 +
9578 +/*
9579 + * We use hard coded constants because this is shared with user
9580 + * space and the values are NOT allowed to change.  Only fields
9581 + * that are intended to be exposed get values.
9582 + */
9583 +#define PT_D0           0
9584 +#define PT_D1           4
9585 +#define PT_D2           8
9586 +#define PT_D3           12
9587 +#define PT_D4           16
9588 +#define PT_D5           20
9589 +#define PT_D6           24
9590 +#define PT_D7           28
9591 +#define PT_D8           32
9592 +#define PT_D9           36
9593 +#define PT_D10          40
9594 +#define PT_D11          44
9595 +#define PT_D12          48
9596 +#define PT_D13          52
9597 +#define PT_D14          56
9598 +#define PT_D15          60
9599 +#define PT_A0           64
9600 +#define PT_A1           68
9601 +#define PT_A2           72
9602 +#define PT_A3           76
9603 +#define PT_A4           80
9604 +#define PT_A5           84
9605 +#define PT_A6           88
9606 +#define PT_A7           92
9607 +#define PT_SP           92
9608 +#define PT_ACC0HI       96
9609 +#define PT_ACC0LO       100
9610 +#define PT_MAC_RC16     104
9611 +#define PT_ACC1HI       108
9612 +#define PT_ACC1LO       112
9613 +#define PT_SOURCE3      116
9614 +#define PT_INST_CNT     120
9615 +#define PT_CSR          124
9616 +#define PT_DUMMY_UNUSED 128
9617 +#define PT_INT_MASK0    132
9618 +#define PT_INT_MASK1    136
9619 +#define PT_TRAP_CAUSE   140
9620 +#define PT_PC           144
9621 +#define PT_ORIGINAL_D0  148
9622 +#define PT_FRAME_TYPE   152
9623 +
9624 +/*
9625 + * The following 'registers' are not registers at all but are used
9626 + * locate the relocated sections.
9627 + */
9628 +#define PT_TEXT_ADDR           200
9629 +#define PT_TEXT_END_ADDR       204
9630 +#define PT_DATA_ADDR           208
9631 +#define PT_EXEC_FDPIC_LOADMAP  212
9632 +#define PT_INTERP_FDPIC_LOADMAP        216
9633 +
9634 +/*
9635 + * This struct defines the way the registers are stored on the
9636 + * stack during a system call.
9637 + */
9638 +enum thread_type {
9639 +       NORMAL_THREAD,
9640 +       KERNEL_THREAD,
9641 +};
9642 +
9643 +#define UBICOM32_FRAME_TYPE_SYSCALL    -1 /* System call frame */
9644 +#define UBICOM32_FRAME_TYPE_INVALID    0 /* Invalid frame, no longer in use */
9645 +#define UBICOM32_FRAME_TYPE_INTERRUPT  1 /* Interrupt frame */
9646 +#define UBICOM32_FRAME_TYPE_TRAP       2 /* Trap frame */
9647 +#define UBICOM32_FRAME_TYPE_SIGTRAMP   3 /* Signal trampoline frame. */
9648 +#define UBICOM32_FRAME_TYPE_NEW_THREAD 4 /* New Thread. */
9649 +
9650 +struct pt_regs {
9651 +       /*
9652 +        * Data Registers
9653 +        */
9654 +       unsigned long dn[16];
9655 +
9656 +       /*
9657 +        * Address Registers
9658 +        */
9659 +       unsigned long an[8];
9660 +
9661 +       /*
9662 +        * Per thread misc registers.
9663 +        */
9664 +       unsigned long acc0[2];
9665 +       unsigned long mac_rc16;
9666 +       unsigned long acc1[2];
9667 +       unsigned long source3;
9668 +       unsigned long inst_cnt;
9669 +       unsigned long csr;
9670 +       unsigned long dummy_unused;
9671 +       unsigned long int_mask0;
9672 +       unsigned long int_mask1;
9673 +       unsigned long trap_cause;
9674 +       unsigned long pc;
9675 +       unsigned long original_dn_0;
9676 +
9677 +       /*
9678 +        * Frame type. Syscall frames are -1. For other types look above.
9679 +        */
9680 +       unsigned long frame_type;
9681 +
9682 +       /*
9683 +        * These fields are not exposed to ptrace.
9684 +        */
9685 +       unsigned long previous_pc;
9686 +       long nesting_level;             /* When the kernel in in user space this
9687 +                                        * will be -1. */
9688 +       unsigned long thread_type;      /* This indicates if this is a kernel
9689 +                                        * thread. */
9690 +};
9691 +
9692 +/*
9693 + * This is the extended stack used by signal handlers and the context
9694 + * switcher: it's pushed after the normal "struct pt_regs".
9695 + */
9696 +struct switch_stack {
9697 +       unsigned long  dummy;
9698 +};
9699 +
9700 +#ifdef __KERNEL__
9701 +
9702 +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
9703 +#define PTRACE_GETREGS         12
9704 +#define PTRACE_SETREGS         13
9705 +
9706 +#ifndef PS_S
9707 +#define PS_S  (0x2000)
9708 +#define PS_M  (0x1000)
9709 +#endif
9710 +
9711 +extern  int __user_mode(unsigned long sp);
9712 +
9713 +#define user_mode(regs) (__user_mode((regs->an[7])))
9714 +#define user_stack(regs) ((regs)->an[7])
9715 +#define instruction_pointer(regs) ((regs)->pc)
9716 +#define profile_pc(regs) instruction_pointer(regs)
9717 +extern void show_regs(struct pt_regs *);
9718 +#endif /* __KERNEL__ */
9719 +
9720 +#endif /* __ASSEMBLY__ */
9721 +
9722 +#endif /* _ASM_UBICOM32_PTRACE_H */
9723 --- /dev/null
9724 +++ b/arch/ubicom32/include/asm/range-protect-asm.h
9725 @@ -0,0 +1,91 @@
9726 +/*
9727 + * arch/ubicom32/include/asm/range-protect-asm.h
9728 + *   Assembly macros for enabling memory protection.
9729 + *
9730 + * (C) Copyright 2009, Ubicom, Inc.
9731 + *
9732 + * This file is part of the Ubicom32 Linux Kernel Port.
9733 + *
9734 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9735 + * it and/or modify it under the terms of the GNU General Public License
9736 + * as published by the Free Software Foundation, either version 2 of the
9737 + * License, or (at your option) any later version.
9738 + *
9739 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9740 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9741 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9742 + * the GNU General Public License for more details.
9743 + *
9744 + * You should have received a copy of the GNU General Public License
9745 + * along with the Ubicom32 Linux Kernel Port.  If not,
9746 + * see <http://www.gnu.org/licenses/>.
9747 + *
9748 + * Ubicom32 implementation derived from (with many thanks):
9749 + *   arch/m68knommu
9750 + *   arch/blackfin
9751 + *   arch/parisc
9752 + */
9753 +
9754 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9755 +#define _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9756 +
9757 +#if defined(__ASSEMBLY__)
9758 +
9759 +#include <asm/thread-asm.h>
9760 +
9761 +/*
9762 + * You should only use the enable/disable ranges when you have the atomic lock,
9763 + * if you do not there will be problems.
9764 + */
9765 +
9766 +/*
9767 + * enable_kernel_ranges
9768 + *     Enable the kernel ranges (disabling protection) for thread,
9769 + *     where thread == (1 << thread number)
9770 + */
9771 +.macro enable_kernel_ranges thread
9772 +#ifdef CONFIG_PROTECT_KERNEL
9773 +       or.4    I_RANGE0_EN, I_RANGE0_EN, \thread        /* Enable Range Register */
9774 +       or.4    D_RANGE0_EN, D_RANGE0_EN, \thread
9775 +       or.4    D_RANGE1_EN, D_RANGE1_EN, \thread
9776 +#endif
9777 +.endm
9778 +
9779 +/*
9780 + * enable_kernel_ranges_for_current
9781 + *     Enable the kernel ranges (disabling protection) for this thread
9782 + */
9783 +.macro enable_kernel_ranges_for_current scratch_reg
9784 +#ifdef CONFIG_PROTECT_KERNEL
9785 +       thread_get_self_mask \scratch_reg
9786 +       enable_kernel_ranges \scratch_reg
9787 +#endif
9788 +.endm
9789 +
9790 +/*
9791 + * disable_kernel_ranges
9792 + *     Disables the kernel ranges (enabling protection) for thread
9793 + *     where thread == (1 << thread number)
9794 + */
9795 +.macro disable_kernel_ranges thread
9796 +#ifdef CONFIG_PROTECT_KERNEL
9797 +       not.4   \thread, \thread
9798 +       and.4   I_RANGE0_EN, I_RANGE0_EN, \thread        /* Disable Range Register */
9799 +       and.4   D_RANGE0_EN, D_RANGE0_EN, \thread
9800 +       and.4   D_RANGE1_EN, D_RANGE1_EN, \thread
9801 +#endif
9802 +.endm
9803 +
9804 +/*
9805 + * disable_kernel_ranges_for_current
9806 + *     Disable kernel ranges (enabling protection) for this thread
9807 + */
9808 +.macro disable_kernel_ranges_for_current scratch_reg
9809 +#ifdef CONFIG_PROTECT_KERNEL
9810 +       thread_get_self_mask \scratch_reg
9811 +       disable_kernel_ranges \scratch_reg
9812 +#endif
9813 +.endm
9814 +#endif
9815 +
9816 +#endif  /* _ASM_UBICOM32_RANGE_PROTECT_ASM_H */
9817 --- /dev/null
9818 +++ b/arch/ubicom32/include/asm/range-protect.h
9819 @@ -0,0 +1,62 @@
9820 +/*
9821 + * arch/ubicom32/include/asm/range-protect.h
9822 + *   Assembly macros declared in C for enabling memory protection.
9823 + *
9824 + * (C) Copyright 2009, Ubicom, Inc.
9825 + *
9826 + * This file is part of the Ubicom32 Linux Kernel Port.
9827 + *
9828 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9829 + * it and/or modify it under the terms of the GNU General Public License
9830 + * as published by the Free Software Foundation, either version 2 of the
9831 + * License, or (at your option) any later version.
9832 + *
9833 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9834 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9835 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9836 + * the GNU General Public License for more details.
9837 + *
9838 + * You should have received a copy of the GNU General Public License
9839 + * along with the Ubicom32 Linux Kernel Port.  If not,
9840 + * see <http://www.gnu.org/licenses/>.
9841 + *
9842 + * Ubicom32 implementation derived from (with many thanks):
9843 + *   arch/m68knommu
9844 + *   arch/blackfin
9845 + *   arch/parisc
9846 + */
9847 +
9848 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_H
9849 +#define _ASM_UBICOM32_RANGE_PROTECT_H
9850 +
9851 +#if !defined(__ASSEMBLY__)
9852 +#include <asm/thread.h>
9853 +/*
9854 + * The following macros should be the identical to the ones in
9855 + * range-protect-asm.h
9856 + *
9857 + * You should only use the enable/disable ranges when you have the atomic lock,
9858 + * if you do not there will be problems.
9859 + */
9860 +
9861 +/*
9862 + * enable_kernel_ranges
9863 + *     Enable the kernel ranges (disabling protection) for thread,
9864 + *     where thread == (1 << thread number)
9865 + */
9866 +asm (
9867 +       ".macro enable_kernel_ranges thread                     \n\t"
9868 +#ifdef CONFIG_PROTECT_KERNEL
9869 +       "       or.4    I_RANGE0_EN, I_RANGE0_EN, \\thread      \n\t" /* Enable Range Register */
9870 +       "       or.4    D_RANGE0_EN, D_RANGE0_EN, \\thread      \n\t"
9871 +       "       or.4    D_RANGE1_EN, D_RANGE1_EN, \\thread      \n\t"
9872 +#endif
9873 +       ".endm                                                  \n\t"
9874 +);
9875 +
9876 +#else /* __ASSEMBLY__ */
9877 +
9878 +#include <asm/range-protect-asm.h>
9879 +
9880 +#endif
9881 +#endif  /* _ASM_UBICOM32_RANGE_PROTECT_H */
9882 --- /dev/null
9883 +++ b/arch/ubicom32/include/asm/resource.h
9884 @@ -0,0 +1,33 @@
9885 +/*
9886 + * arch/ubicom32/include/asm/resource.h
9887 + *   Generic 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_RESOURCE_H
9913 +#define _ASM_UBICOM32_RESOURCE_H
9914 +
9915 +#include <asm-generic/resource.h>
9916 +
9917 +#endif /* _ASM_UBICOM32_RESOURCE_H */
9918 --- /dev/null
9919 +++ b/arch/ubicom32/include/asm/ring_tio.h
9920 @@ -0,0 +1,42 @@
9921 +/*
9922 + * arch/ubicom32/include/asm/ring_tio.h
9923 + *   Ubicom32 architecture Ring TIO definitions.
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 +#ifndef _ASM_UBICOM32_RING_TIO_H
9944 +#define _ASM_UBICOM32_RING_TIO_H
9945 +
9946 +#include <asm/devtree.h>
9947 +
9948 +#define RING_TIO_NODE_VERSION  2
9949 +
9950 +/*
9951 + * Devtree node for ring
9952 + */
9953 +struct ring_tio_node {
9954 +       struct devtree_node     dn;
9955 +
9956 +       u32_t                   version;
9957 +       void                    *regs;
9958 +};
9959 +
9960 +extern void ring_tio_init(const char *node_name);
9961 +
9962 +#endif /* _ASM_UBICOM32_RING_TIO_H */
9963 --- /dev/null
9964 +++ b/arch/ubicom32/include/asm/scatterlist.h
9965 @@ -0,0 +1,49 @@
9966 +/*
9967 + * arch/ubicom32/include/asm/scatterlist.h
9968 + *   Definitions of struct scatterlist for Ubicom32 architecture.
9969 + *
9970 + * (C) Copyright 2009, Ubicom, Inc.
9971 + *
9972 + * This file is part of the Ubicom32 Linux Kernel Port.
9973 + *
9974 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
9975 + * it and/or modify it under the terms of the GNU General Public License
9976 + * as published by the Free Software Foundation, either version 2 of the
9977 + * License, or (at your option) any later version.
9978 + *
9979 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
9980 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
9981 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
9982 + * the GNU General Public License for more details.
9983 + *
9984 + * You should have received a copy of the GNU General Public License
9985 + * along with the Ubicom32 Linux Kernel Port.  If not, 
9986 + * see <http://www.gnu.org/licenses/>.
9987 + *
9988 + * Ubicom32 implementation derived from (with many thanks):
9989 + *   arch/m68knommu
9990 + *   arch/blackfin
9991 + *   arch/parisc
9992 + */
9993 +#ifndef _ASM_UBICOM32_SCATTERLIST_H
9994 +#define _ASM_UBICOM32_SCATTERLIST_H
9995 +
9996 +#include <linux/mm.h>
9997 +#include <asm/types.h>
9998 +
9999 +struct scatterlist {
10000 +#ifdef CONFIG_DEBUG_SG
10001 +       unsigned long   sg_magic;
10002 +#endif
10003 +       unsigned long   page_link;
10004 +       unsigned int    offset;
10005 +       dma_addr_t      dma_address;
10006 +       unsigned int    length;
10007 +};
10008 +
10009 +#define sg_dma_address(sg)      ((sg)->dma_address)
10010 +#define sg_dma_len(sg)          ((sg)->length)
10011 +
10012 +#define ISA_DMA_THRESHOLD      (0xffffffff)
10013 +
10014 +#endif /* _ASM_UBICOM32_SCATTERLIST_H */
10015 --- /dev/null
10016 +++ b/arch/ubicom32/include/asm/sd_tio.h
10017 @@ -0,0 +1,36 @@
10018 +/*
10019 + * arch/ubicom32/include/asm/sd_tio.h
10020 + *   SD TIO definitions
10021 + *
10022 + * (C) Copyright 2009, Ubicom, Inc.
10023 + *
10024 + * This file is part of the Ubicom32 Linux Kernel Port.
10025 + *
10026 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10027 + * it and/or modify it under the terms of the GNU General Public License
10028 + * as published by the Free Software Foundation, either version 2 of the
10029 + * License, or (at your option) any later version.
10030 + *
10031 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10032 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10033 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10034 + * the GNU General Public License for more details.
10035 + *
10036 + * You should have received a copy of the GNU General Public License
10037 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10038 + * see <http://www.gnu.org/licenses/>.
10039 + */
10040 +#ifndef _ASM_UBICOM32_SD_TIO_H
10041 +#define _ASM_UBICOM32_SD_TIO_H
10042 +
10043 +#include <asm/devtree.h>
10044 +
10045 +/*
10046 + * Devtree node for SD
10047 + */
10048 +struct sd_tio_node {
10049 +       struct devtree_node     dn;
10050 +       void                    *regs;
10051 +};
10052 +
10053 +#endif /* _ASM_UBICOM32_SD_TIO_H */
10054 --- /dev/null
10055 +++ b/arch/ubicom32/include/asm/sections.h
10056 @@ -0,0 +1,33 @@
10057 +/*
10058 + * arch/ubicom32/include/asm/sections.h
10059 + *   Generic sections.h definitions for Ubicom32 architecture.
10060 + *
10061 + * (C) Copyright 2009, Ubicom, Inc.
10062 + *
10063 + * This file is part of the Ubicom32 Linux Kernel Port.
10064 + *
10065 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10066 + * it and/or modify it under the terms of the GNU General Public License
10067 + * as published by the Free Software Foundation, either version 2 of the
10068 + * License, or (at your option) any later version.
10069 + *
10070 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10071 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10072 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10073 + * the GNU General Public License for more details.
10074 + *
10075 + * You should have received a copy of the GNU General Public License
10076 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10077 + * see <http://www.gnu.org/licenses/>.
10078 + *
10079 + * Ubicom32 implementation derived from (with many thanks):
10080 + *   arch/m68knommu
10081 + *   arch/blackfin
10082 + *   arch/parisc
10083 + */
10084 +#ifndef _ASM_UBICOM32_SECTIONS_H
10085 +#define _ASM_UBICOM32_SECTIONS_H
10086 +
10087 +#include <asm-generic/sections.h>
10088 +
10089 +#endif /* _ASM_UBICOM32_SECTIONS_H */
10090 --- /dev/null
10091 +++ b/arch/ubicom32/include/asm/segment.h
10092 @@ -0,0 +1,78 @@
10093 +/*
10094 + * arch/ubicom32/include/asm/segment.h
10095 + *   Memory segment definitions for Ubicom32 architecture.
10096 + *
10097 + * (C) Copyright 2009, Ubicom, Inc.
10098 + *
10099 + * This file is part of the Ubicom32 Linux Kernel Port.
10100 + *
10101 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10102 + * it and/or modify it under the terms of the GNU General Public License
10103 + * as published by the Free Software Foundation, either version 2 of the
10104 + * License, or (at your option) any later version.
10105 + *
10106 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10107 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10108 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10109 + * the GNU General Public License for more details.
10110 + *
10111 + * You should have received a copy of the GNU General Public License
10112 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10113 + * see <http://www.gnu.org/licenses/>.
10114 + *
10115 + * Ubicom32 implementation derived from (with many thanks):
10116 + *   arch/m68knommu
10117 + *   arch/blackfin
10118 + *   arch/parisc
10119 + */
10120 +#ifndef _ASM_UBICOM32_SEGMENT_H
10121 +#define _ASM_UBICOM32_SEGMENT_H
10122 +
10123 +/* define constants */
10124 +/* Address spaces (FC0-FC2) */
10125 +#define USER_DATA     (1)
10126 +#ifndef __USER_DS
10127 +#define __USER_DS     (USER_DATA)
10128 +#endif
10129 +#define USER_PROGRAM  (2)
10130 +#define SUPER_DATA    (5)
10131 +#ifndef __KERNEL_DS
10132 +#define __KERNEL_DS   (SUPER_DATA)
10133 +#endif
10134 +#define SUPER_PROGRAM (6)
10135 +#define CPU_SPACE     (7)
10136 +
10137 +#ifndef __ASSEMBLY__
10138 +
10139 +typedef struct {
10140 +       unsigned long seg;
10141 +} mm_segment_t;
10142 +
10143 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
10144 +#define USER_DS                MAKE_MM_SEG(__USER_DS)
10145 +#define KERNEL_DS      MAKE_MM_SEG(__KERNEL_DS)
10146 +
10147 +/*
10148 + * Get/set the SFC/DFC registers for MOVES instructions
10149 + */
10150 +
10151 +static inline mm_segment_t get_fs(void)
10152 +{
10153 +    return USER_DS;
10154 +}
10155 +
10156 +static inline mm_segment_t get_ds(void)
10157 +{
10158 +    /* return the supervisor data space code */
10159 +    return KERNEL_DS;
10160 +}
10161 +
10162 +static inline void set_fs(mm_segment_t val)
10163 +{
10164 +}
10165 +
10166 +#define segment_eq(a,b)        ((a).seg == (b).seg)
10167 +
10168 +#endif /* __ASSEMBLY__ */
10169 +
10170 +#endif /* _ASM_UBICOM32_SEGMENT_H */
10171 --- /dev/null
10172 +++ b/arch/ubicom32/include/asm/semaphore.h
10173 @@ -0,0 +1,140 @@
10174 +/*
10175 + * arch/ubicom32/include/asm/semaphore.h
10176 + *   Interrupt-safe semaphores for Ubicom32 architecture.
10177 + *
10178 + * (C) Copyright 2009, Ubicom, Inc.
10179 + * (C) Copyright 1996 Linus Torvalds
10180 + * m68k version by Andreas Schwab
10181 + * Copyright (C) 2004   Microtronix Datacom Ltd
10182 + *
10183 + * This file is part of the Ubicom32 Linux Kernel Port.
10184 + *
10185 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10186 + * it and/or modify it under the terms of the GNU General Public License
10187 + * as published by the Free Software Foundation, either version 2 of the
10188 + * License, or (at your option) any later version.
10189 + *
10190 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10191 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10192 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10193 + * the GNU General Public License for more details.
10194 + *
10195 + * You should have received a copy of the GNU General Public License
10196 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10197 + * see <http://www.gnu.org/licenses/>.
10198 + *
10199 + * Ubicom32 implementation derived from (with many thanks):
10200 + *   arch/m68knommu
10201 + *   arch/blackfin
10202 + *   arch/parisc
10203 + */
10204 +#ifndef _ASM_UBICOM32_SEMAPHORE_H
10205 +#define _ASM_UBICOM32_SEMAPHORE_H
10206 +
10207 +#define RW_LOCK_BIAS            0x01000000
10208 +
10209 +#ifndef __ASSEMBLY__
10210 +
10211 +#include <linux/linkage.h>
10212 +#include <linux/wait.h>
10213 +#include <linux/spinlock.h>
10214 +#include <linux/rwsem.h>
10215 +
10216 +#include <asm/system.h>
10217 +#include <asm/atomic.h>
10218 +
10219 +struct semaphore {
10220 +       atomic_t count;
10221 +       atomic_t waking;
10222 +       wait_queue_head_t wait;
10223 +};
10224 +
10225 +#define __SEMAPHORE_INITIALIZER(name, n)                               \
10226 +{                                                                      \
10227 +       .count          = ATOMIC_INIT(n),                               \
10228 +       .waking         = ATOMIC_INIT(0),                               \
10229 +       .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
10230 +}
10231 +
10232 +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
10233 +       struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
10234 +
10235 +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
10236 +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
10237 +
10238 +static inline void sema_init (struct semaphore *sem, int val)
10239 +{
10240 +       *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
10241 +}
10242 +
10243 +static inline void init_MUTEX (struct semaphore *sem)
10244 +{
10245 +       sema_init(sem, 1);
10246 +}
10247 +
10248 +static inline void init_MUTEX_LOCKED (struct semaphore *sem)
10249 +{
10250 +       sema_init(sem, 0);
10251 +}
10252 +
10253 +asmlinkage void __down_failed(void /* special register calling convention */);
10254 +asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
10255 +asmlinkage int  __down_failed_trylock(void  /* params in registers */);
10256 +asmlinkage void __up_wakeup(void /* special register calling convention */);
10257 +
10258 +asmlinkage void __down(struct semaphore * sem);
10259 +asmlinkage int  __down_interruptible(struct semaphore * sem);
10260 +asmlinkage int  __down_trylock(struct semaphore * sem);
10261 +asmlinkage void __up(struct semaphore * sem);
10262 +
10263 +extern spinlock_t semaphore_wake_lock;
10264 +
10265 +/*
10266 + * This is ugly, but we want the default case to fall through.
10267 + * "down_failed" is a special asm handler that calls the C
10268 + * routine that actually waits.
10269 + */
10270 +static inline void down(struct semaphore * sem)
10271 +{
10272 +       might_sleep();
10273 +
10274 +       if (atomic_dec_return(&sem->count) < 0)
10275 +               __down(sem);
10276 +}
10277 +
10278 +static inline int down_interruptible(struct semaphore * sem)
10279 +{
10280 +       int ret = 0;
10281 +
10282 +
10283 +       might_sleep();
10284 +
10285 +       if(atomic_dec_return(&sem->count) < 0)
10286 +               ret = __down_interruptible(sem);
10287 +       return ret;
10288 +}
10289 +
10290 +static inline int down_trylock(struct semaphore * sem)
10291 +{
10292 +       int ret = 0;
10293 +
10294 +       if (atomic_dec_return (&sem->count) < 0)
10295 +               ret = __down_trylock(sem);
10296 +       return ret;
10297 +}
10298 +
10299 +/*
10300 + * Note! This is subtle. We jump to wake people up only if
10301 + * the semaphore was negative (== somebody was waiting on it).
10302 + * The default case (no contention) will result in NO
10303 + * jumps for both down() and up().
10304 + */
10305 +static inline void up(struct semaphore * sem)
10306 +{
10307 +       if (atomic_inc_return(&sem->count) <= 0)
10308 +               __up(sem);
10309 +}
10310 +
10311 +#endif /* __ASSEMBLY__ */
10312 +
10313 +#endif /* _ASM_UBICOM32_SEMAPHORE_H */
10314 --- /dev/null
10315 +++ b/arch/ubicom32/include/asm/semaphore-helper.h
10316 @@ -0,0 +1,109 @@
10317 +/*
10318 + * arch/ubicom32/include/asm/semaphore-helper.h
10319 + *   Semaphore related definitions for Ubicom32 architecture.
10320 + *
10321 + * (C) Copyright 2009, Ubicom, Inc.
10322 + *
10323 + * This file is part of the Ubicom32 Linux Kernel Port.
10324 + *
10325 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10326 + * it and/or modify it under the terms of the GNU General Public License
10327 + * as published by the Free Software Foundation, either version 2 of the
10328 + * License, or (at your option) any later version.
10329 + *
10330 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10331 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10332 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10333 + * the GNU General Public License for more details.
10334 + *
10335 + * You should have received a copy of the GNU General Public License
10336 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10337 + * see <http://www.gnu.org/licenses/>.
10338 + *
10339 + * Ubicom32 implementation derived from (with many thanks):
10340 + *   arch/m68knommu
10341 + *   arch/blackfin
10342 + *   arch/parisc
10343 + */
10344 +#ifndef _ASM_UBICOM32_SEMAPHORE_HELPER_H
10345 +#define _ASM_UBICOM32_SEMAPHORE_HELPER_H
10346 +
10347 +/*
10348 + * SMP- and interrupt-safe semaphores helper functions.
10349 + *
10350 + * (C) Copyright 1996 Linus Torvalds
10351 + *
10352 + * m68k version by Andreas Schwab
10353 + */
10354 +
10355 +
10356 +/*
10357 + * These two _must_ execute atomically wrt each other.
10358 + */
10359 +static inline void wake_one_more(struct semaphore * sem)
10360 +{
10361 +       atomic_inc(&sem->waking);
10362 +}
10363 +
10364 +static inline int waking_non_zero(struct semaphore *sem)
10365 +{
10366 +       int ret;
10367 +       unsigned long flags;
10368 +
10369 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10370 +       ret = 0;
10371 +       if (atomic_read(&sem->waking) > 0) {
10372 +               atomic_dec(&sem->waking);
10373 +               ret = 1;
10374 +       }
10375 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10376 +       return ret;
10377 +}
10378 +
10379 +/*
10380 + * waking_non_zero_interruptible:
10381 + *     1       got the lock
10382 + *     0       go to sleep
10383 + *     -EINTR  interrupted
10384 + */
10385 +static inline int waking_non_zero_interruptible(struct semaphore *sem,
10386 +                                               struct task_struct *tsk)
10387 +{
10388 +       int ret;
10389 +       unsigned long flags;
10390 +
10391 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10392 +       ret = 0;
10393 +       if (atomic_read(&sem->waking) > 0) {
10394 +               atomic_dec(&sem->waking);
10395 +               ret = 1;
10396 +       } else if (signal_pending(tsk)) {
10397 +               atomic_inc(&sem->count);
10398 +               ret = -EINTR;
10399 +       }
10400 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10401 +       return ret;
10402 +}
10403 +
10404 +/*
10405 + * waking_non_zero_trylock:
10406 + *     1       failed to lock
10407 + *     0       got the lock
10408 + */
10409 +static inline int waking_non_zero_trylock(struct semaphore *sem)
10410 +{
10411 +       int ret;
10412 +       unsigned long flags;
10413 +
10414 +       spin_lock_irqsave(&semaphore_wake_lock, flags);
10415 +       ret = 1;
10416 +       if (atomic_read(&sem->waking) > 0) {
10417 +               atomic_dec(&sem->waking);
10418 +               ret = 0;
10419 +       } else
10420 +               atomic_inc(&sem->count);
10421 +       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10422 +       return ret;
10423 +}
10424 +
10425 +#endif /* _ASM_UBICOM32_SEMAPHORE_HELPER_H */
10426 --- /dev/null
10427 +++ b/arch/ubicom32/include/asm/sembuf.h
10428 @@ -0,0 +1,52 @@
10429 +/*
10430 + * arch/ubicom32/include/asm/sembuf.h
10431 + *   The semid64_ds structure for Ubicom32 architecture.
10432 + *
10433 + * (C) Copyright 2009, Ubicom, Inc.
10434 + *
10435 + * This file is part of the Ubicom32 Linux Kernel Port.
10436 + *
10437 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10438 + * it and/or modify it under the terms of the GNU General Public License
10439 + * as published by the Free Software Foundation, either version 2 of the
10440 + * License, or (at your option) any later version.
10441 + *
10442 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10443 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10444 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10445 + * the GNU General Public License for more details.
10446 + *
10447 + * You should have received a copy of the GNU General Public License
10448 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10449 + * see <http://www.gnu.org/licenses/>.
10450 + *
10451 + * Ubicom32 implementation derived from (with many thanks):
10452 + *   arch/m68knommu
10453 + *   arch/blackfin
10454 + *   arch/parisc
10455 + */
10456 +#ifndef _ASM_UBICOM32_SEMBUF_H
10457 +#define _ASM_UBICOM32_SEMBUF_H
10458 +
10459 +/*
10460 + * The semid64_ds structure for ubicom32 architecture.
10461 + * Note extra padding because this structure is passed back and forth
10462 + * between kernel and user space.
10463 + *
10464 + * Pad space is left for:
10465 + * - 64-bit time_t to solve y2038 problem
10466 + * - 2 miscellaneous 32-bit values
10467 + */
10468 +
10469 +struct semid64_ds {
10470 +       struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
10471 +       __kernel_time_t sem_otime;              /* last semop time */
10472 +       unsigned long   __unused1;
10473 +       __kernel_time_t sem_ctime;              /* last change time */
10474 +       unsigned long   __unused2;
10475 +       unsigned long   sem_nsems;              /* no. of semaphores in array */
10476 +       unsigned long   __unused3;
10477 +       unsigned long   __unused4;
10478 +};
10479 +
10480 +#endif /* _ASM_UBICOM32_SEMBUF_H */
10481 --- /dev/null
10482 +++ b/arch/ubicom32/include/asm/setup.h
10483 @@ -0,0 +1,35 @@
10484 +/*
10485 + * arch/ubicom32/include/asm/setup.h
10486 + *   Kernel command line length definition.
10487 + *
10488 + * (C) Copyright 2009, Ubicom, Inc.
10489 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.
10490 + *
10491 + * This file is part of the Ubicom32 Linux Kernel Port.
10492 + *
10493 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10494 + * it and/or modify it under the terms of the GNU General Public License
10495 + * as published by the Free Software Foundation, either version 2 of the
10496 + * License, or (at your option) any later version.
10497 + *
10498 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10499 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10500 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10501 + * the GNU General Public License for more details.
10502 + *
10503 + * You should have received a copy of the GNU General Public License
10504 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10505 + * see <http://www.gnu.org/licenses/>.
10506 + *
10507 + * Ubicom32 implementation derived from (with many thanks):
10508 + *   arch/m68knommu
10509 + *   arch/blackfin
10510 + *   arch/parisc
10511 + */
10512 +
10513 +#ifndef _ASM_UBICOM32_SETUP_H
10514 +#define _ASM_UBICOM32_SETUP_H
10515 +
10516 +#define COMMAND_LINE_SIZE 512
10517 +
10518 +#endif /* _ASM_UBICOM32_SETUP_H */
10519 --- /dev/null
10520 +++ b/arch/ubicom32/include/asm/shmbuf.h
10521 @@ -0,0 +1,69 @@
10522 +/*
10523 + * arch/ubicom32/include/asm/shmbuf.h
10524 + *   The shmid64_ds structure for the Ubicom32 architecture.
10525 + *
10526 + * (C) Copyright 2009, Ubicom, Inc.
10527 + *
10528 + * This file is part of the Ubicom32 Linux Kernel Port.
10529 + *
10530 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10531 + * it and/or modify it under the terms of the GNU General Public License
10532 + * as published by the Free Software Foundation, either version 2 of the
10533 + * License, or (at your option) any later version.
10534 + *
10535 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10536 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10537 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10538 + * the GNU General Public License for more details.
10539 + *
10540 + * You should have received a copy of the GNU General Public License
10541 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10542 + * see <http://www.gnu.org/licenses/>.
10543 + *
10544 + * Ubicom32 implementation derived from (with many thanks):
10545 + *   arch/m68knommu
10546 + *   arch/blackfin
10547 + *   arch/parisc
10548 + */
10549 +#ifndef _ASM_UBICOM32_SHMBUF_H
10550 +#define _ASM_UBICOM32_SHMBUF_H
10551 +
10552 +/*
10553 + * The shmid64_ds structure for m68k architecture.
10554 + * Note extra padding because this structure is passed back and forth
10555 + * between kernel and user space.
10556 + *
10557 + * Pad space is left for:
10558 + * - 64-bit time_t to solve y2038 problem
10559 + * - 2 miscellaneous 32-bit values
10560 + */
10561 +
10562 +struct shmid64_ds {
10563 +       struct ipc64_perm       shm_perm;       /* operation perms */
10564 +       size_t                  shm_segsz;      /* size of segment (bytes) */
10565 +       __kernel_time_t         shm_atime;      /* last attach time */
10566 +       unsigned long           __unused1;
10567 +       __kernel_time_t         shm_dtime;      /* last detach time */
10568 +       unsigned long           __unused2;
10569 +       __kernel_time_t         shm_ctime;      /* last change time */
10570 +       unsigned long           __unused3;
10571 +       __kernel_pid_t          shm_cpid;       /* pid of creator */
10572 +       __kernel_pid_t          shm_lpid;       /* pid of last operator */
10573 +       unsigned long           shm_nattch;     /* no. of current attaches */
10574 +       unsigned long           __unused4;
10575 +       unsigned long           __unused5;
10576 +};
10577 +
10578 +struct shminfo64 {
10579 +       unsigned long   shmmax;
10580 +       unsigned long   shmmin;
10581 +       unsigned long   shmmni;
10582 +       unsigned long   shmseg;
10583 +       unsigned long   shmall;
10584 +       unsigned long   __unused1;
10585 +       unsigned long   __unused2;
10586 +       unsigned long   __unused3;
10587 +       unsigned long   __unused4;
10588 +};
10589 +
10590 +#endif /* _ASM_UBICOM32_SHMBUF_H */
10591 --- /dev/null
10592 +++ b/arch/ubicom32/include/asm/shmparam.h
10593 @@ -0,0 +1,35 @@
10594 +/*
10595 + * arch/ubicom32/include/asm/shmparam.h
10596 + *   Shared memory definitions for Ubicom32 architecture.
10597 + *
10598 + * (C) Copyright 2009, Ubicom, Inc.
10599 + * Copyright (C) 2004   Microtronix Datacom Ltd
10600 + *
10601 + * This file is part of the Ubicom32 Linux Kernel Port.
10602 + *
10603 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10604 + * it and/or modify it under the terms of the GNU General Public License
10605 + * as published by the Free Software Foundation, either version 2 of the
10606 + * License, or (at your option) any later version.
10607 + *
10608 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10609 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10610 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10611 + * the GNU General Public License for more details.
10612 + *
10613 + * You should have received a copy of the GNU General Public License
10614 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10615 + * see <http://www.gnu.org/licenses/>.
10616 + *
10617 + * Ubicom32 implementation derived from (with many thanks):
10618 + *   arch/m68knommu
10619 + *   arch/blackfin
10620 + *   arch/parisc
10621 + *   Alpha, ix86, M68K, Sparc, ...et al
10622 + */
10623 +#ifndef _ASM_UBICOM32_SHMPARAM_H
10624 +#define _ASM_UBICOM32_SHMPARAM_H
10625 +
10626 +#define        SHMLBA          PAGE_SIZE       /* attach addr a multiple of this */
10627 +
10628 +#endif /* _ASM_UBICOM32_SHMPARAM_H */
10629 --- /dev/null
10630 +++ b/arch/ubicom32/include/asm/sigcontext.h
10631 @@ -0,0 +1,37 @@
10632 +/*
10633 + * arch/ubicom32/include/asm/sigcontext.h
10634 + *   Definition of sigcontext struct for Ubicom32 architecture.
10635 + *
10636 + * (C) Copyright 2009, Ubicom, Inc.
10637 + *
10638 + * This file is part of the Ubicom32 Linux Kernel Port.
10639 + *
10640 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10641 + * it and/or modify it under the terms of the GNU General Public License
10642 + * as published by the Free Software Foundation, either version 2 of the
10643 + * License, or (at your option) any later version.
10644 + *
10645 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10646 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10647 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10648 + * the GNU General Public License for more details.
10649 + *
10650 + * You should have received a copy of the GNU General Public License
10651 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10652 + * see <http://www.gnu.org/licenses/>.
10653 + *
10654 + * Ubicom32 implementation derived from (with many thanks):
10655 + *   arch/m68knommu
10656 + *   arch/blackfin
10657 + *   arch/parisc
10658 + */
10659 +#ifndef _ASM_UBICOM32_SIGCONTEXT_H
10660 +#define _ASM_UBICOM32_SIGCONTEXT_H
10661 +
10662 +#include <asm/ptrace.h>
10663 +
10664 +struct sigcontext {
10665 +       struct pt_regs sc_regs;
10666 +};
10667 +
10668 +#endif /* _ASM_UBICOM32_SIGCONTEXT_H */
10669 --- /dev/null
10670 +++ b/arch/ubicom32/include/asm/siginfo.h
10671 @@ -0,0 +1,33 @@
10672 +/*
10673 + * arch/ubicom32/include/asm/siginfo.h
10674 + *   Generic siginfo.h definitions for Ubicom32 architecture.
10675 + *
10676 + * (C) Copyright 2009, Ubicom, Inc.
10677 + *
10678 + * This file is part of the Ubicom32 Linux Kernel Port.
10679 + *
10680 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10681 + * it and/or modify it under the terms of the GNU General Public License
10682 + * as published by the Free Software Foundation, either version 2 of the
10683 + * License, or (at your option) any later version.
10684 + *
10685 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10686 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10687 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10688 + * the GNU General Public License for more details.
10689 + *
10690 + * You should have received a copy of the GNU General Public License
10691 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10692 + * see <http://www.gnu.org/licenses/>.
10693 + *
10694 + * Ubicom32 implementation derived from (with many thanks):
10695 + *   arch/m68knommu
10696 + *   arch/blackfin
10697 + *   arch/parisc
10698 + */
10699 +#ifndef _ASM_UBICOM32_SIGINFO_H
10700 +#define _ASM_UBICOM32_SIGINFO_H
10701 +
10702 +#include <asm-generic/siginfo.h>
10703 +
10704 +#endif /* _ASM_UBICOM32_SIGINFO_H */
10705 --- /dev/null
10706 +++ b/arch/ubicom32/include/asm/signal.h
10707 @@ -0,0 +1,180 @@
10708 +/*
10709 + * arch/ubicom32/include/asm/signal.h
10710 + *   Signal related definitions for Ubicom32 architecture.
10711 + *
10712 + * (C) Copyright 2009, Ubicom, Inc.
10713 + *
10714 + * This file is part of the Ubicom32 Linux Kernel Port.
10715 + *
10716 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10717 + * it and/or modify it under the terms of the GNU General Public License
10718 + * as published by the Free Software Foundation, either version 2 of the
10719 + * License, or (at your option) any later version.
10720 + *
10721 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10722 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10723 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10724 + * the GNU General Public License for more details.
10725 + *
10726 + * You should have received a copy of the GNU General Public License
10727 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10728 + * see <http://www.gnu.org/licenses/>.
10729 + *
10730 + * Ubicom32 implementation derived from (with many thanks):
10731 + *   arch/m68knommu
10732 + *   arch/blackfin
10733 + *   arch/parisc
10734 + */
10735 +#ifndef _ASM_UBICOM32_SIGNAL_H
10736 +#define _ASM_UBICOM32_SIGNAL_H
10737 +
10738 +#include <linux/types.h>
10739 +
10740 +/* Avoid too many header ordering problems.  */
10741 +struct siginfo;
10742 +
10743 +#ifdef __KERNEL__
10744 +/* Most things should be clean enough to redefine this at will, if care
10745 +   is taken to make libc match.  */
10746 +
10747 +#define _NSIG          64
10748 +#define _NSIG_BPW      32
10749 +#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
10750 +
10751 +typedef unsigned long old_sigset_t;            /* at least 32 bits */
10752 +
10753 +typedef struct {
10754 +       unsigned long sig[_NSIG_WORDS];
10755 +} sigset_t;
10756 +
10757 +#endif /* __KERNEL__ */
10758 +
10759 +#define SIGHUP          1
10760 +#define SIGINT          2
10761 +#define SIGQUIT                 3
10762 +#define SIGILL          4
10763 +#define SIGTRAP                 5
10764 +#define SIGABRT                 6
10765 +#define SIGIOT          6
10766 +#define SIGBUS          7
10767 +#define SIGFPE          8
10768 +#define SIGKILL                 9
10769 +#define SIGUSR1                10
10770 +#define SIGSEGV                11
10771 +#define SIGUSR2                12
10772 +#define SIGPIPE                13
10773 +#define SIGALRM                14
10774 +#define SIGTERM                15
10775 +#define SIGSTKFLT      16
10776 +#define SIGCHLD                17
10777 +#define SIGCONT                18
10778 +#define SIGSTOP                19
10779 +#define SIGTSTP                20
10780 +#define SIGTTIN                21
10781 +#define SIGTTOU                22
10782 +#define SIGURG         23
10783 +#define SIGXCPU                24
10784 +#define SIGXFSZ                25
10785 +#define SIGVTALRM      26
10786 +#define SIGPROF                27
10787 +#define SIGWINCH       28
10788 +#define SIGIO          29
10789 +#define SIGPOLL                SIGIO
10790 +/*
10791 +#define SIGLOST                29
10792 +*/
10793 +#define SIGPWR         30
10794 +#define SIGSYS         31
10795 +#define        SIGUNUSED       31
10796 +
10797 +/* These should not be considered constants from userland.  */
10798 +#define SIGRTMIN       32
10799 +#define SIGRTMAX       _NSIG
10800 +
10801 +/*
10802 + * SA_FLAGS values:
10803 + *
10804 + * SA_ONSTACK indicates that a registered stack_t will be used.
10805 + * SA_RESTART flag to get restarting signals (which were the default long ago)
10806 + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
10807 + * SA_RESETHAND clears the handler when the signal is delivered.
10808 + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
10809 + * SA_NODEFER prevents the current signal from being masked in the handler.
10810 + *
10811 + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
10812 + * Unix names RESETHAND and NODEFER respectively.
10813 + */
10814 +#define SA_NOCLDSTOP   0x00000001
10815 +#define SA_NOCLDWAIT   0x00000002
10816 +#define SA_SIGINFO     0x00000004
10817 +#define SA_ONSTACK     0x08000000
10818 +#define SA_RESTART     0x10000000
10819 +#define SA_NODEFER     0x40000000
10820 +#define SA_RESETHAND   0x80000000
10821 +
10822 +#define SA_NOMASK      SA_NODEFER
10823 +#define SA_ONESHOT     SA_RESETHAND
10824 +
10825 +/* 
10826 + * sigaltstack controls
10827 + */
10828 +#define SS_ONSTACK     1
10829 +#define SS_DISABLE     2
10830 +
10831 +#define MINSIGSTKSZ    2048
10832 +#define SIGSTKSZ       8192
10833 +
10834 +#include <asm-generic/signal.h>
10835 +
10836 +#ifdef __KERNEL__
10837 +struct old_sigaction {
10838 +       __sighandler_t sa_handler;
10839 +       old_sigset_t sa_mask;
10840 +       unsigned long sa_flags;
10841 +       void (*sa_restorer)(void);
10842 +};
10843 +
10844 +struct sigaction {
10845 +       __sighandler_t sa_handler;
10846 +       unsigned long sa_flags;
10847 +       void (*sa_restorer)(void);
10848 +       sigset_t sa_mask;               /* mask last for extensibility */
10849 +};
10850 +
10851 +struct k_sigaction {
10852 +       struct sigaction sa;
10853 +};
10854 +#else
10855 +/* Here we must cater to libcs that poke about in kernel headers.  */
10856 +
10857 +struct sigaction {
10858 +       union {
10859 +         __sighandler_t _sa_handler;
10860 +         void (*_sa_sigaction)(int, struct siginfo *, void *);
10861 +       } _u;
10862 +       sigset_t sa_mask;
10863 +       unsigned long sa_flags;
10864 +       void (*sa_restorer)(void);
10865 +};
10866 +
10867 +#define sa_handler     _u._sa_handler
10868 +#define sa_sigaction   _u._sa_sigaction
10869 +
10870 +#endif /* __KERNEL__ */
10871 +
10872 +typedef struct sigaltstack {
10873 +       void *ss_sp;
10874 +       int ss_flags;
10875 +       size_t ss_size;
10876 +} stack_t;
10877 +
10878 +#ifdef __KERNEL__
10879 +
10880 +#include <asm/sigcontext.h>
10881 +#undef __HAVE_ARCH_SIG_BITOPS
10882 +
10883 +#define ptrace_signal_deliver(regs, cookie) do { } while (0)
10884 +
10885 +#endif /* __KERNEL__ */
10886 +
10887 +#endif /* _ASM_UBICOM32_SIGNAL_H */
10888 --- /dev/null
10889 +++ b/arch/ubicom32/include/asm/smp.h
10890 @@ -0,0 +1,83 @@
10891 +/*
10892 + * arch/ubicom32/include/asm/smp.h
10893 + *   SMP definitions for Ubicom32 architecture.
10894 + *
10895 + * (C) Copyright 2009, Ubicom, Inc.
10896 + *
10897 + * This file is part of the Ubicom32 Linux Kernel Port.
10898 + *
10899 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10900 + * it and/or modify it under the terms of the GNU General Public License
10901 + * as published by the Free Software Foundation, either version 2 of the
10902 + * License, or (at your option) any later version.
10903 + *
10904 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10905 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10906 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10907 + * the GNU General Public License for more details.
10908 + *
10909 + * You should have received a copy of the GNU General Public License
10910 + * along with the Ubicom32 Linux Kernel Port.  If not,
10911 + * see <http://www.gnu.org/licenses/>.
10912 + *
10913 + * Ubicom32 implementation derived from (with many thanks):
10914 + *   arch/m68knommu
10915 + *   arch/blackfin
10916 + *   arch/parisc
10917 + */
10918 +#ifndef _ASM_UBICOM32_SMP_H
10919 +#define _ASM_UBICOM32_SMP_H
10920 +
10921 +#ifndef ASSEMBLY
10922 +#include <linux/bitops.h>
10923 +#include <linux/threads.h>
10924 +#include <linux/cpumask.h>
10925 +#include <asm/ip5000.h>
10926 +
10927 +typedef unsigned long address_t;
10928 +extern cpumask_t cpu_online_map;
10929 +extern unsigned int smp_ipi_irq;
10930 +
10931 +/*
10932 + * This magic constant controls our willingness to transfer
10933 + * a process across CPUs.
10934 + *
10935 + * Such a transfer incurs cache and tlb
10936 + * misses. The current value is inherited from i386. Still needs
10937 + * to be tuned for parisc.
10938 + */
10939 +#define PROC_CHANGE_PENALTY    15              /* Schedule penalty */
10940 +#define NO_PROC_ID             0xFF            /* No processor magic marker */
10941 +#define ANY_PROC_ID            0xFF            /* Any processor magic marker */
10942 +
10943 +#ifdef CONFIG_SMP
10944 +#define raw_smp_processor_id() (current_thread_info()->cpu)
10945 +#endif /* CONFIG_SMP */
10946 +
10947 +static inline int __cpu_disable (void)
10948 +{
10949 +  return 0;
10950 +}
10951 +
10952 +static inline void __cpu_die (unsigned int cpu)
10953 +{
10954 +       while(1) {
10955 +       };
10956 +}
10957 +
10958 +extern int __cpu_up(unsigned int cpu);
10959 +extern void smp_send_timer_all(void);
10960 +extern void smp_timer_broadcast(cpumask_t mask);
10961 +extern void smp_set_affinity(unsigned int irq, cpumask_t dest);
10962 +extern void arch_send_call_function_single_ipi(int cpu);
10963 +extern void arch_send_call_function_ipi(cpumask_t mask);
10964 +
10965 +/*
10966 + * TODO: Once these are fully tested, we should turn them into
10967 + * inline macros for performance.
10968 + */
10969 +extern unsigned long smp_get_affinity(unsigned int irq, int *all);
10970 +extern void smp_reset_ipi(unsigned long mask);
10971 +
10972 +#endif /* !ASSEMBLY */
10973 +#endif /*  _ASM_UBICOM32_SMP_H */
10974 --- /dev/null
10975 +++ b/arch/ubicom32/include/asm/socket.h
10976 @@ -0,0 +1,84 @@
10977 +/*
10978 + * arch/ubicom32/include/asm/socket.h
10979 + *   Socket options definitions for Ubicom32 architecture.
10980 + *
10981 + * (C) Copyright 2009, Ubicom, Inc.
10982 + *
10983 + * This file is part of the Ubicom32 Linux Kernel Port.
10984 + *
10985 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10986 + * it and/or modify it under the terms of the GNU General Public License
10987 + * as published by the Free Software Foundation, either version 2 of the
10988 + * License, or (at your option) any later version.
10989 + *
10990 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
10991 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
10992 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
10993 + * the GNU General Public License for more details.
10994 + *
10995 + * You should have received a copy of the GNU General Public License
10996 + * along with the Ubicom32 Linux Kernel Port.  If not, 
10997 + * see <http://www.gnu.org/licenses/>.
10998 + *
10999 + * Ubicom32 implementation derived from (with many thanks):
11000 + *   arch/m68knommu
11001 + *   arch/blackfin
11002 + *   arch/parisc
11003 + */
11004 +#ifndef _ASM_UBICOM32_SOCKET_H
11005 +#define _ASM_UBICOM32_SOCKET_H
11006 +
11007 +#include <asm/sockios.h>
11008 +
11009 +/* For setsockopt(2) */
11010 +#define SOL_SOCKET     1
11011 +
11012 +#define SO_DEBUG       1
11013 +#define SO_REUSEADDR   2
11014 +#define SO_TYPE                3
11015 +#define SO_ERROR       4
11016 +#define SO_DONTROUTE   5
11017 +#define SO_BROADCAST   6
11018 +#define SO_SNDBUF      7
11019 +#define SO_RCVBUF      8
11020 +#define SO_SNDBUFFORCE 32
11021 +#define SO_RCVBUFFORCE 33
11022 +#define SO_KEEPALIVE   9
11023 +#define SO_OOBINLINE   10
11024 +#define SO_NO_CHECK    11
11025 +#define SO_PRIORITY    12
11026 +#define SO_LINGER      13
11027 +#define SO_BSDCOMPAT   14
11028 +/* To add :#define SO_REUSEPORT 15 */
11029 +#define SO_PASSCRED    16
11030 +#define SO_PEERCRED    17
11031 +#define SO_RCVLOWAT    18
11032 +#define SO_SNDLOWAT    19
11033 +#define SO_RCVTIMEO    20
11034 +#define SO_SNDTIMEO    21
11035 +
11036 +/* Security levels - as per NRL IPv6 - don't actually do anything */
11037 +#define SO_SECURITY_AUTHENTICATION             22
11038 +#define SO_SECURITY_ENCRYPTION_TRANSPORT       23
11039 +#define SO_SECURITY_ENCRYPTION_NETWORK         24
11040 +
11041 +#define SO_BINDTODEVICE        25
11042 +
11043 +/* Socket filtering */
11044 +#define SO_ATTACH_FILTER        26
11045 +#define SO_DETACH_FILTER        27
11046 +
11047 +#define SO_PEERNAME             28
11048 +#define SO_TIMESTAMP           29
11049 +#define SCM_TIMESTAMP          SO_TIMESTAMP
11050 +
11051 +#define SO_ACCEPTCONN          30
11052 +
11053 +#define SO_PEERSEC              31
11054 +#define SO_PASSSEC             34
11055 +#define SO_TIMESTAMPNS         35
11056 +#define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
11057 +
11058 +#define SO_MARK                        36
11059 +
11060 +#endif /* _ASM_UBICOM32_SOCKET_H */
11061 --- /dev/null
11062 +++ b/arch/ubicom32/include/asm/sockios.h
11063 @@ -0,0 +1,40 @@
11064 +/*
11065 + * arch/ubicom32/include/asm/sockios.h
11066 + *   Socket-level ioctl definitions for Ubicom32 architecture.
11067 + *
11068 + * (C) Copyright 2009, Ubicom, Inc.
11069 + *
11070 + * This file is part of the Ubicom32 Linux Kernel Port.
11071 + *
11072 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11073 + * it and/or modify it under the terms of the GNU General Public License
11074 + * as published by the Free Software Foundation, either version 2 of the
11075 + * License, or (at your option) any later version.
11076 + *
11077 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11078 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11079 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11080 + * the GNU General Public License for more details.
11081 + *
11082 + * You should have received a copy of the GNU General Public License
11083 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11084 + * see <http://www.gnu.org/licenses/>.
11085 + *
11086 + * Ubicom32 implementation derived from (with many thanks):
11087 + *   arch/m68knommu
11088 + *   arch/blackfin
11089 + *   arch/parisc
11090 + */
11091 +#ifndef _ASM_UBICOM32_SOCKIOS_H
11092 +#define _ASM_UBICOM32_SOCKIOS_H
11093 +
11094 +/* Socket-level I/O control calls. */
11095 +#define FIOSETOWN      0x8901
11096 +#define SIOCSPGRP      0x8902
11097 +#define FIOGETOWN      0x8903
11098 +#define SIOCGPGRP      0x8904
11099 +#define SIOCATMARK     0x8905
11100 +#define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
11101 +#define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
11102 +
11103 +#endif /* _ASM_UBICOM32_SOCKIOS_H */
11104 --- /dev/null
11105 +++ b/arch/ubicom32/include/asm/spinlock.h
11106 @@ -0,0 +1,293 @@
11107 +/*
11108 + * arch/ubicom32/include/asm/spinlock.h
11109 + *   Spinlock related definitions for Ubicom32 architecture.
11110 + *
11111 + * (C) Copyright 2009, Ubicom, Inc.
11112 + *
11113 + * This file is part of the Ubicom32 Linux Kernel Port.
11114 + *
11115 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11116 + * it and/or modify it under the terms of the GNU General Public License
11117 + * as published by the Free Software Foundation, either version 2 of the
11118 + * License, or (at your option) any later version.
11119 + *
11120 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11121 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11122 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11123 + * the GNU General Public License for more details.
11124 + *
11125 + * You should have received a copy of the GNU General Public License
11126 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11127 + * see <http://www.gnu.org/licenses/>.
11128 + *
11129 + * Ubicom32 implementation derived from (with many thanks):
11130 + *   arch/m68knommu
11131 + *   arch/blackfin
11132 + *   arch/parisc
11133 + */
11134 +#ifndef _ASM_UBICOM32_SPINLOCK_H
11135 +#define _ASM_UBICOM32_SPINLOCK_H
11136 +
11137 +#include <asm/system.h>
11138 +#include <asm/processor.h>
11139 +#include <asm/spinlock_types.h>
11140 +
11141 +/*
11142 + * __raw_spin_lock()
11143 + *     Lock the lock.
11144 + */
11145 +static inline void __raw_spin_lock(raw_spinlock_t *x)
11146 +{
11147 +       asm volatile (
11148 +       "1:     bset    %0, %0, #0      \n\t"
11149 +       "       jmpne.f 1b              \n\t"
11150 +               : "+U4" (x->lock)
11151 +               :
11152 +               : "memory", "cc"
11153 +       );
11154 +}
11155 +
11156 +/*
11157 + * __raw_spin_unlock()
11158 + *     Unlock the lock.
11159 + */
11160 +static inline void __raw_spin_unlock(raw_spinlock_t *x)
11161 +{
11162 +       asm volatile (
11163 +       "       bclr    %0, %0, #0      \n\t"
11164 +               : "+U4" (x->lock)
11165 +               :
11166 +               : "memory", "cc"
11167 +       );
11168 +}
11169 +
11170 +/*
11171 + * __raw_spin_is_locked()
11172 + *     Test if the lock is locked.
11173 + */
11174 +static inline int __raw_spin_is_locked(raw_spinlock_t *x)
11175 +{
11176 +       return x->lock;
11177 +}
11178 +
11179 +/*
11180 + * __raw_spin_unlock_wait()
11181 + *     Wait for the lock to be unlocked.
11182 + *
11183 + * Note: the caller has not guarantee that the lock will not
11184 + * be acquired before they get to it.
11185 + */
11186 +static inline void __raw_spin_unlock_wait(raw_spinlock_t *x)
11187 +{
11188 +       do { 
11189 +               cpu_relax(); 
11190 +       } while (__raw_spin_is_locked(x));
11191 +}
11192 +
11193 +/*
11194 + * __raw_spin_trylock()
11195 + *     Try the lock, return 0 on failure, 1 on success.
11196 + */
11197 +static inline int __raw_spin_trylock(raw_spinlock_t *x)
11198 +{
11199 +       int ret = 0;
11200 +
11201 +       asm volatile (
11202 +       "       bset    %1, %1, #0      \n\t"
11203 +       "       jmpne.f 1f              \n\t"
11204 +       "       move.4  %0, #1          \n\t"
11205 +       "1:                             \n\t"
11206 +               : "+r" (ret), "+U4" (x->lock)
11207 +               :
11208 +               : "memory", "cc"
11209 +       );
11210 +
11211 +       return ret;
11212 +}
11213 +
11214 +/*
11215 + * __raw_spin_lock_flags()
11216 + *     Spin waiting for the lock (enabling IRQ(s))
11217 + */
11218 +static inline void __raw_spin_lock_flags(raw_spinlock_t *x, unsigned long flags)
11219 +{
11220 +       mb();
11221 +       while (!__raw_spin_trylock(x)) {
11222 +               /*
11223 +                * If the flags from the IRQ are set, interrupts are disabled and we 
11224 +                * need to re-enable them.
11225 +                */
11226 +               if (!flags) {
11227 +                       cpu_relax();
11228 +               } else {
11229 +                       raw_local_irq_enable();
11230 +                       cpu_relax();
11231 +                       raw_local_irq_disable();
11232 +               }
11233 +       }
11234 +       mb();
11235 +}
11236 +
11237 +/*
11238 + * Read-write spinlocks, allowing multiple readers but only one writer.
11239 + * Linux rwlocks are unfair to writers; they can be starved for an indefinite
11240 + * time by readers.  With care, they can also be taken in interrupt context.
11241 + *
11242 + * In Ubicom32 architecture implementation, we have a spinlock and a counter.
11243 + * Readers use the lock to serialise their access to the counter (which
11244 + * records how many readers currently hold the lock).
11245 + * Writers hold the spinlock, preventing any readers or other writers from
11246 + * grabbing the rwlock.
11247 + */
11248 +
11249 +/*
11250 + * __raw_read_lock()
11251 + *     Increment the counter in the rwlock.
11252 + *
11253 + * Note that we have to ensure interrupts are disabled in case we're
11254 + * interrupted by some other code that wants to grab the same read lock 
11255 + */
11256 +static inline void __raw_read_lock(raw_rwlock_t *rw)
11257 +{
11258 +       unsigned long flags;
11259 +       raw_local_irq_save(flags);
11260 +       __raw_spin_lock_flags(&rw->lock, flags);
11261 +       rw->counter++;
11262 +       __raw_spin_unlock(&rw->lock);
11263 +       raw_local_irq_restore(flags);
11264 +}
11265 +
11266 +/*
11267 + * __raw_read_unlock()
11268 + *     Decrement the counter.
11269 + *
11270 + * Note that we have to ensure interrupts are disabled in case we're
11271 + * interrupted by some other code that wants to grab the same read lock 
11272 + */
11273 +static inline void __raw_read_unlock(raw_rwlock_t *rw)
11274 +{
11275 +       unsigned long flags;
11276 +       raw_local_irq_save(flags);
11277 +       __raw_spin_lock_flags(&rw->lock, flags);
11278 +       rw->counter--;
11279 +       __raw_spin_unlock(&rw->lock);
11280 +       raw_local_irq_restore(flags);
11281 +}
11282 +
11283 +/* 
11284 + * __raw_read_trylock()
11285 + *     Increment the counter if we can.
11286 + *
11287 + * Note that we have to ensure interrupts are disabled in case we're
11288 + * interrupted by some other code that wants to grab the same read lock 
11289 + */
11290 +static inline int __raw_read_trylock(raw_rwlock_t *rw)
11291 +{
11292 +       unsigned long flags;
11293 + retry:
11294 +       raw_local_irq_save(flags);
11295 +       if (__raw_spin_trylock(&rw->lock)) {
11296 +               rw->counter++;
11297 +               __raw_spin_unlock(&rw->lock);
11298 +               raw_local_irq_restore(flags);
11299 +               return 1;
11300 +       }
11301 +
11302 +       raw_local_irq_restore(flags);
11303 +
11304 +       /* 
11305 +        * If write-locked, we fail to acquire the lock 
11306 +        */
11307 +       if (rw->counter < 0) {
11308 +               return 0;
11309 +       }
11310 +
11311 +       /* 
11312 +        * Wait until we have a realistic chance at the lock 
11313 +        */
11314 +       while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0) {
11315 +               cpu_relax();
11316 +       }
11317 +
11318 +       goto retry;
11319 +}
11320 +
11321 +/*
11322 + * __raw_write_lock()
11323 + *     
11324 + * Note that we have to ensure interrupts are disabled in case we're
11325 + * interrupted by some other code that wants to read_trylock() this lock 
11326 + */
11327 +static inline void __raw_write_lock(raw_rwlock_t *rw)
11328 +{
11329 +       unsigned long flags;
11330 +retry:
11331 +       raw_local_irq_save(flags);
11332 +       __raw_spin_lock_flags(&rw->lock, flags);
11333 +
11334 +       if (rw->counter != 0) {
11335 +               __raw_spin_unlock(&rw->lock);
11336 +               raw_local_irq_restore(flags);
11337 +
11338 +               while (rw->counter != 0)
11339 +                       cpu_relax();
11340 +
11341 +               goto retry;
11342 +       }
11343 +
11344 +       rw->counter = -1; /* mark as write-locked */
11345 +       mb();
11346 +       raw_local_irq_restore(flags);
11347 +}
11348 +
11349 +static inline void __raw_write_unlock(raw_rwlock_t *rw)
11350 +{
11351 +       rw->counter = 0;
11352 +       __raw_spin_unlock(&rw->lock);
11353 +}
11354 +
11355 +/* Note that we have to ensure interrupts are disabled in case we're
11356 + * interrupted by some other code that wants to read_trylock() this lock */
11357 +static inline int __raw_write_trylock(raw_rwlock_t *rw)
11358 +{
11359 +       unsigned long flags;
11360 +       int result = 0;
11361 +
11362 +       raw_local_irq_save(flags);
11363 +       if (__raw_spin_trylock(&rw->lock)) {
11364 +               if (rw->counter == 0) {
11365 +                       rw->counter = -1;
11366 +                       result = 1;
11367 +               } else {
11368 +                       /* Read-locked.  Oh well. */
11369 +                       __raw_spin_unlock(&rw->lock);
11370 +               }
11371 +       }
11372 +       raw_local_irq_restore(flags);
11373 +
11374 +       return result;
11375 +}
11376 +
11377 +/*
11378 + * read_can_lock - would read_trylock() succeed?
11379 + * @lock: the rwlock in question.
11380 + */
11381 +static inline int __raw_read_can_lock(raw_rwlock_t *rw)
11382 +{
11383 +       return rw->counter >= 0;
11384 +}
11385 +
11386 +/*
11387 + * write_can_lock - would write_trylock() succeed?
11388 + * @lock: the rwlock in question.
11389 + */
11390 +static inline int __raw_write_can_lock(raw_rwlock_t *rw)
11391 +{
11392 +       return !rw->counter;
11393 +}
11394 +
11395 +#define _raw_spin_relax(lock)  cpu_relax()
11396 +#define _raw_read_relax(lock)  cpu_relax()
11397 +#define _raw_write_relax(lock) cpu_relax()
11398 +
11399 +#endif /* _ASM_UBICOM32_SPINLOCK_H */
11400 --- /dev/null
11401 +++ b/arch/ubicom32/include/asm/spinlock_types.h
11402 @@ -0,0 +1,43 @@
11403 +/*
11404 + * arch/ubicom32/include/asm/spinlock_types.h
11405 + *   Spinlock related structure definitions for Ubicom32 architecture.
11406 + *
11407 + * (C) Copyright 2009, Ubicom, Inc.
11408 + *
11409 + * This file is part of the Ubicom32 Linux Kernel Port.
11410 + *
11411 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11412 + * it and/or modify it under the terms of the GNU General Public License
11413 + * as published by the Free Software Foundation, either version 2 of the
11414 + * License, or (at your option) any later version.
11415 + *
11416 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11417 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11418 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11419 + * the GNU General Public License for more details.
11420 + *
11421 + * You should have received a copy of the GNU General Public License
11422 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11423 + * see <http://www.gnu.org/licenses/>.
11424 + *
11425 + * Ubicom32 implementation derived from (with many thanks):
11426 + *   arch/m68knommu
11427 + *   arch/blackfin
11428 + *   arch/parisc
11429 + */
11430 +#ifndef _ASM_UBICOM32_SPINLOCK_TYPES_H
11431 +#define _ASM_UBICOM32_SPINLOCK_TYPES_H
11432 +
11433 +typedef struct {
11434 +       volatile unsigned int lock;
11435 +} raw_spinlock_t;
11436 +
11437 +typedef struct {
11438 +       raw_spinlock_t lock;
11439 +       volatile int counter;
11440 +} raw_rwlock_t;
11441 +
11442 +#define __RAW_SPIN_LOCK_UNLOCKED       { 0 }
11443 +#define __RAW_RW_LOCK_UNLOCKED         { __RAW_SPIN_LOCK_UNLOCKED, 0 }
11444 +
11445 +#endif /* _ASM_UBICOM32_SPINLOCK_TYPES_H */
11446 --- /dev/null
11447 +++ b/arch/ubicom32/include/asm/stacktrace.h
11448 @@ -0,0 +1,72 @@
11449 +/*
11450 + * arch/ubicom32/include/asm/stacktrace.h
11451 + *   Stacktrace functions for the Ubicom32 architecture.
11452 + *
11453 + * (C) Copyright 2009, Ubicom, Inc.
11454 + *
11455 + * This file is part of the Ubicom32 Linux Kernel Port.
11456 + *
11457 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11458 + * it and/or modify it under the terms of the GNU General Public License
11459 + * as published by the Free Software Foundation, either version 2 of the
11460 + * License, or (at your option) any later version.
11461 + *
11462 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11463 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11464 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11465 + * the GNU General Public License for more details.
11466 + *
11467 + * You should have received a copy of the GNU General Public License
11468 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11469 + * see <http://www.gnu.org/licenses/>.
11470 + *
11471 + * Ubicom32 implementation derived from (with many thanks):
11472 + *   arch/m68knommu
11473 + *   arch/blackfin
11474 + *   arch/parisc
11475 + */
11476 +#ifndef _ASM_UBICOM32_STACKTRACE_H
11477 +#define _ASM_UBICOM32_STACKTRACE_H
11478 +
11479 +#define between(a, b, c)       (( \
11480 +                       ((unsigned long) a) >= ((unsigned long) b)) && \
11481 +                       (((unsigned long)a) <= ((unsigned long)c)))
11482 +
11483 +/*
11484 + * These symbols are filled in by the linker.
11485 + */
11486 +extern unsigned long _stext;
11487 +extern unsigned long _etext;
11488 +
11489 +/* OCM text goes from __ocm_text_run_begin to __data_begin */
11490 +extern unsigned long __ocm_text_run_begin;
11491 +extern unsigned long __data_begin;
11492 +
11493 +/* Account for OCM case - see stacktrace.c maybe combine(also trap.c) */
11494 +/*
11495 + * ubicom32_is_kernel()
11496 + *
11497 + *     Check to see if the given address belongs to the kernel.
11498 + * NOMMU does not permit any other means.
11499 + */
11500 +static inline int ubicom32_is_kernel(unsigned long addr)
11501 +{
11502 +       int is_kernel = between(addr, &_stext, &_etext) || \
11503 +                       between(addr, &__ocm_text_run_begin, &__data_begin);
11504 +
11505 +#ifdef CONFIG_MODULES
11506 +       if (!is_kernel)
11507 +               is_kernel = is_module_address(addr);
11508 +#endif
11509 +       return is_kernel;
11510 +}
11511 +
11512 +extern unsigned long stacktrace_iterate(
11513 +                               unsigned long **trace, 
11514 +                               unsigned long stext, unsigned long etext,
11515 +                               unsigned long ocm_stext, unsigned long ocm_etext, 
11516 +                               unsigned long sstack, unsigned long estack);
11517 +#ifdef CONFIG_STACKTRACE
11518 +void stacktrace_save_entries(struct task_struct *tsk, struct stack_trace *trace, unsigned long sp);
11519 +#endif
11520 +#endif /* _ASM_UBICOM32_STACKTRACE_H */
11521 --- /dev/null
11522 +++ b/arch/ubicom32/include/asm/statfs.h
11523 @@ -0,0 +1,33 @@
11524 +/*
11525 + * arch/ubicom32/include/asm/statfs.h
11526 + *   Generic statfs.h definitions
11527 + *
11528 + * (C) Copyright 2009, Ubicom, Inc.
11529 + *
11530 + * This file is part of the Ubicom32 Linux Kernel Port.
11531 + *
11532 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11533 + * it and/or modify it under the terms of the GNU General Public License
11534 + * as published by the Free Software Foundation, either version 2 of the
11535 + * License, or (at your option) any later version.
11536 + *
11537 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11538 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11539 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11540 + * the GNU General Public License for more details.
11541 + *
11542 + * You should have received a copy of the GNU General Public License
11543 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11544 + * see <http://www.gnu.org/licenses/>.
11545 + *
11546 + * Ubicom32 implementation derived from (with many thanks):
11547 + *   arch/m68knommu
11548 + *   arch/blackfin
11549 + *   arch/parisc
11550 + */
11551 +#ifndef _ASM_UBICOM32_STATFS_H
11552 +#define _ASM_UBICOM32_STATFS_H
11553 +
11554 +#include <asm-generic/statfs.h>
11555 +
11556 +#endif /* _ASM_UBICOM32_STATFS_H */
11557 --- /dev/null
11558 +++ b/arch/ubicom32/include/asm/stat.h
11559 @@ -0,0 +1,104 @@
11560 +/*
11561 + * arch/ubicom32/include/asm/stat.h
11562 + *   File status definitions for Ubicom32 architecture.
11563 + *
11564 + * (C) Copyright 2009, Ubicom, Inc.
11565 + *
11566 + * This file is part of the Ubicom32 Linux Kernel Port.
11567 + *
11568 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11569 + * it and/or modify it under the terms of the GNU General Public License
11570 + * as published by the Free Software Foundation, either version 2 of the
11571 + * License, or (at your option) any later version.
11572 + *
11573 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11574 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11575 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11576 + * the GNU General Public License for more details.
11577 + *
11578 + * You should have received a copy of the GNU General Public License
11579 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11580 + * see <http://www.gnu.org/licenses/>.
11581 + *
11582 + * Ubicom32 implementation derived from (with many thanks):
11583 + *   arch/m68knommu
11584 + *   arch/blackfin
11585 + *   arch/parisc
11586 + */
11587 +#ifndef _ASM_UBICOM32_STAT_H
11588 +#define _ASM_UBICOM32_STAT_H
11589 +
11590 +struct __old_kernel_stat {
11591 +       unsigned short st_dev;
11592 +       unsigned short st_ino;
11593 +       unsigned short st_mode;
11594 +       unsigned short st_nlink;
11595 +       unsigned short st_uid;
11596 +       unsigned short st_gid;
11597 +       unsigned short st_rdev;
11598 +       unsigned long  st_size;
11599 +       unsigned long  st_atime;
11600 +       unsigned long  st_mtime;
11601 +       unsigned long  st_ctime;
11602 +};
11603 +
11604 +struct stat {
11605 +       unsigned short st_dev;
11606 +       unsigned short __pad1;
11607 +       unsigned long  st_ino;
11608 +       unsigned short st_mode;
11609 +       unsigned short st_nlink;
11610 +       unsigned short st_uid;
11611 +       unsigned short st_gid;
11612 +       unsigned short st_rdev;
11613 +       unsigned short __pad2;
11614 +       unsigned long  st_size;
11615 +       unsigned long  st_blksize;
11616 +       unsigned long  st_blocks;
11617 +       unsigned long  st_atime;
11618 +       unsigned long  __unused1;
11619 +       unsigned long  st_mtime;
11620 +       unsigned long  __unused2;
11621 +       unsigned long  st_ctime;
11622 +       unsigned long  __unused3;
11623 +       unsigned long  __unused4;
11624 +       unsigned long  __unused5;
11625 +};
11626 +
11627 +/* This matches struct stat64 in glibc2.1, hence the absolutely
11628 + * insane amounts of padding around dev_t's.
11629 + */
11630 +struct stat64 {
11631 +       unsigned long long      st_dev;
11632 +       unsigned char   __pad1[2];
11633 +
11634 +#define STAT64_HAS_BROKEN_ST_INO       1
11635 +       unsigned long   __st_ino;
11636 +
11637 +       unsigned int    st_mode;
11638 +       unsigned int    st_nlink;
11639 +
11640 +       unsigned long   st_uid;
11641 +       unsigned long   st_gid;
11642 +
11643 +       unsigned long long      st_rdev;
11644 +       unsigned char   __pad3[2];
11645 +
11646 +       long long       st_size;
11647 +       unsigned long   st_blksize;
11648 +
11649 +       unsigned long long      st_blocks;      /* Number 512-byte blocks allocated. */
11650 +
11651 +       unsigned long   st_atime;
11652 +       unsigned long   st_atime_nsec;
11653 +
11654 +       unsigned long   st_mtime;
11655 +       unsigned long   st_mtime_nsec;
11656 +
11657 +       unsigned long   st_ctime;
11658 +       unsigned long   st_ctime_nsec;
11659 +
11660 +       unsigned long long      st_ino;
11661 +};
11662 +
11663 +#endif /* _ASM_UBICOM32_STAT_H */
11664 --- /dev/null
11665 +++ b/arch/ubicom32/include/asm/string.h
11666 @@ -0,0 +1,37 @@
11667 +/*
11668 + * arch/ubicom32/include/asm/string.h
11669 + *   String operation definitions for Ubicom32 architecture.
11670 + *
11671 + * (C) Copyright 2009, Ubicom, Inc.
11672 + *
11673 + * This file is part of the Ubicom32 Linux Kernel Port.
11674 + *
11675 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11676 + * it and/or modify it under the terms of the GNU General Public License
11677 + * as published by the Free Software Foundation, either version 2 of the
11678 + * License, or (at your option) any later version.
11679 + *
11680 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11681 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11682 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11683 + * the GNU General Public License for more details.
11684 + *
11685 + * You should have received a copy of the GNU General Public License
11686 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11687 + * see <http://www.gnu.org/licenses/>.
11688 + *
11689 + * Ubicom32 implementation derived from (with many thanks):
11690 + *   arch/m68knommu
11691 + *   arch/blackfin
11692 + *   arch/parisc
11693 + */
11694 +#ifndef _ASM_UBICOM32_STRING_H
11695 +#define _ASM_UBICOM32_STRING_H
11696 +
11697 +#define __HAVE_ARCH_MEMSET
11698 +extern void *memset(void *b, int c, size_t len);
11699 +
11700 +#define __HAVE_ARCH_MEMCPY
11701 +extern void *memcpy(void *to, const void *from, size_t len);
11702 +
11703 +#endif /* _ASM_UBICOM32_STRING_H */
11704 --- /dev/null
11705 +++ b/arch/ubicom32/include/asm/switch-bcm539x.h
11706 @@ -0,0 +1,57 @@
11707 +/*
11708 + * arch/ubicom32/include/asm/switch-bcm539x.h
11709 + *   Broadcom bcm539x platform data definitions for Ubicom32 architecture.
11710 + *
11711 + * (C) Copyright 2009, Ubicom, Inc.
11712 + *
11713 + * This file is part of the Ubicom32 Linux Kernel Port.
11714 + *
11715 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11716 + * it and/or modify it under the terms of the GNU General Public License
11717 + * as published by the Free Software Foundation, either version 2 of the
11718 + * License, or (at your option) any later version.
11719 + *
11720 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11721 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11722 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11723 + * the GNU General Public License for more details.
11724 + *
11725 + * You should have received a copy of the GNU General Public License
11726 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11727 + * see <http://www.gnu.org/licenses/>.
11728 + *
11729 + * Ubicom32 implementation derived from (with many thanks):
11730 + *   arch/m68knommu
11731 + *   arch/blackfin
11732 + *   arch/parisc
11733 + */
11734 +#ifndef _ASM_UBICOM32_SWITCH_BCM539X_H
11735 +#define _ASM_UBICOM32_SWITCH_BCM539X_H
11736 +
11737 +#define SWITCH_BCM539X_FLAG_HW_RESET   0x01
11738 +#define SWITCH_BCM539X_FLAG_SW_RESET   0x02
11739 +
11740 +struct switch_bcm539x_platform_data {
11741 +       /*
11742 +        * See flags above
11743 +        */
11744 +       u32_t           flags;
11745 +
11746 +       /*
11747 +        * GPIO to use for nReset
11748 +        */
11749 +       int             pin_reset;
11750 +
11751 +
11752 +       /*
11753 +        * GPIO to use for chip select
11754 +        */
11755 +       int             pin_cs;
11756 +
11757 +       /*
11758 +        * Name of this switch
11759 +        */
11760 +       const char      *name;
11761 +};
11762 +
11763 +#endif /* _ASM_UBICOM32_SWITCH_BCM539X_H */
11764 --- /dev/null
11765 +++ b/arch/ubicom32/include/asm/system.h
11766 @@ -0,0 +1,101 @@
11767 +/*
11768 + * arch/ubicom32/include/asm/system.h
11769 + *   Low level switching definitions.
11770 + *
11771 + * (C) Copyright 2009, Ubicom, Inc.
11772 + *
11773 + * This file is part of the Ubicom32 Linux Kernel Port.
11774 + *
11775 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11776 + * it and/or modify it under the terms of the GNU General Public License
11777 + * as published by the Free Software Foundation, either version 2 of the
11778 + * License, or (at your option) any later version.
11779 + *
11780 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11781 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11782 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11783 + * the GNU General Public License for more details.
11784 + *
11785 + * You should have received a copy of the GNU General Public License
11786 + * along with the Ubicom32 Linux Kernel Port.  If not,
11787 + * see <http://www.gnu.org/licenses/>.
11788 + *
11789 + * Ubicom32 implementation derived from (with many thanks):
11790 + *   arch/m68knommu
11791 + *   arch/blackfin
11792 + *   arch/parisc
11793 + */
11794 +#ifndef _ASM_UBICOM32_SYSTEM_H
11795 +#define _ASM_UBICOM32_SYSTEM_H
11796 +
11797 +#include <linux/irqflags.h>
11798 +#include <linux/linkage.h>
11799 +#include <asm/segment.h>
11800 +#include <asm/entry.h>
11801 +#include <asm/ldsr.h>
11802 +#include <asm/irq.h>
11803 +#include <asm/percpu.h>
11804 +#include <asm/ubicom32-common.h>
11805 +#include <asm/processor.h>
11806 +
11807 +/*
11808 + * switch_to(n) should switch tasks to task ptr, first checking that
11809 + * ptr isn't the current task, in which case it does nothing.
11810 + */
11811 +asmlinkage void resume(void);
11812 +extern void *__switch_to(struct task_struct *prev,
11813 +               struct thread_struct *prev_switch,
11814 +               struct thread_struct *next_switch);
11815 +
11816 +/*
11817 + * We will need a per linux thread sw_ksp for the switch_to macro to
11818 + * track the kernel stack pointer for the current thread on that linux thread.
11819 + */
11820 +#define switch_to(prev,next,last)                                      \
11821 +({                                                                     \
11822 +       void *_last;                                                    \
11823 +       _last = (void *)                                                \
11824 +               __switch_to(prev, &prev->thread, &next->thread);        \
11825 +       (last) = _last;                                                 \
11826 +})
11827 +
11828 +/*
11829 + * Force strict CPU ordering.
11830 + * Not really required on ubicom32...
11831 + */
11832 +#define nop()  asm volatile ("nop"::)
11833 +#define mb()   asm volatile (""   : : :"memory")
11834 +#define rmb()  asm volatile (""   : : :"memory")
11835 +#define wmb()  asm volatile (""   : : :"memory")
11836 +#define set_mb(var, value)     ({ (var) = (value); wmb(); })
11837 +
11838 +#ifdef CONFIG_SMP
11839 +#define smp_mb()       mb()
11840 +#define smp_rmb()      rmb()
11841 +#define smp_wmb()      wmb()
11842 +#define smp_read_barrier_depends()     read_barrier_depends()
11843 +#else
11844 +#define smp_mb()       mb()
11845 +#define smp_rmb()      rmb()
11846 +#define smp_wmb()      wmb()
11847 +#define smp_read_barrier_depends()     do { } while(0)
11848 +#endif
11849 +
11850 +#define read_barrier_depends()  ((void)0)
11851 +
11852 +/*
11853 + * The following defines change how the scheduler calls the switch_to()
11854 + * macro.
11855 + *
11856 + * 1) The first causes the runqueue to be unlocked on entry to
11857 + * switch_to().  Since our ctx code does not play with the runqueue
11858 + * we do not need it unlocked.
11859 + *
11860 + * 2) The later turns interrupts on during a ctxsw to reduce the latency of
11861 + * interrupts during ctx.  At this point in the port, we believe that this
11862 + * latency is not a problem since we have very little code to perform a ctxsw.
11863 + */
11864 +// #define __ARCH_WANT_UNLOCKED_CTXSW
11865 +// #define __ARCH_WANT_INTERRUPTS_ON_CTXSW
11866 +
11867 +#endif /* _ASM_UBICOM32_SYSTEM_H */
11868 --- /dev/null
11869 +++ b/arch/ubicom32/include/asm/termbits.h
11870 @@ -0,0 +1,227 @@
11871 +/*
11872 + * arch/ubicom32/include/asm/termbits.h
11873 + *   Terminal/serial port definitions for Ubicom32 architecture.
11874 + *
11875 + * (C) Copyright 2009, Ubicom, Inc.
11876 + *
11877 + * This file is part of the Ubicom32 Linux Kernel Port.
11878 + *
11879 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
11880 + * it and/or modify it under the terms of the GNU General Public License
11881 + * as published by the Free Software Foundation, either version 2 of the
11882 + * License, or (at your option) any later version.
11883 + *
11884 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
11885 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11886 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11887 + * the GNU General Public License for more details.
11888 + *
11889 + * You should have received a copy of the GNU General Public License
11890 + * along with the Ubicom32 Linux Kernel Port.  If not, 
11891 + * see <http://www.gnu.org/licenses/>.
11892 + *
11893 + * Ubicom32 implementation derived from (with many thanks):
11894 + *   arch/m68knommu
11895 + *   arch/blackfin
11896 + *   arch/parisc
11897 + */
11898 +#ifndef _ASM_UBICOM32_TERMBITS_H
11899 +#define _ASM_UBICOM32_TERMBITS_H
11900 +
11901 +#include <linux/posix_types.h>
11902 +
11903 +typedef unsigned char  cc_t;
11904 +typedef unsigned int   speed_t;
11905 +typedef unsigned int   tcflag_t;
11906 +
11907 +#define NCCS 19
11908 +struct termios {
11909 +       tcflag_t c_iflag;               /* input mode flags */
11910 +       tcflag_t c_oflag;               /* output mode flags */
11911 +       tcflag_t c_cflag;               /* control mode flags */
11912 +       tcflag_t c_lflag;               /* local mode flags */
11913 +       cc_t c_line;                    /* line discipline */
11914 +       cc_t c_cc[NCCS];                /* control characters */
11915 +};
11916 +
11917 +struct termios2 {
11918 +       tcflag_t c_iflag;               /* input mode flags */
11919 +       tcflag_t c_oflag;               /* output mode flags */
11920 +       tcflag_t c_cflag;               /* control mode flags */
11921 +       tcflag_t c_lflag;               /* local mode flags */
11922 +       cc_t c_line;                    /* line discipline */
11923 +       cc_t c_cc[NCCS];                /* control characters */
11924 +       speed_t c_ispeed;               /* input speed */
11925 +       speed_t c_ospeed;               /* output speed */
11926 +};
11927 +
11928 +struct ktermios {
11929 +       tcflag_t c_iflag;               /* input mode flags */
11930 +       tcflag_t c_oflag;               /* output mode flags */
11931 +       tcflag_t c_cflag;               /* control mode flags */
11932 +       tcflag_t c_lflag;               /* local mode flags */
11933 +       cc_t c_line;                    /* line discipline */
11934 +       cc_t c_cc[NCCS];                /* control characters */
11935 +       speed_t c_ispeed;               /* input speed */
11936 +       speed_t c_ospeed;               /* output speed */
11937 +};
11938 +
11939 +/* c_cc characters */
11940 +#define VINTR 0
11941 +#define VQUIT 1
11942 +#define VERASE 2
11943 +#define VKILL 3
11944 +#define VEOF 4
11945 +#define VTIME 5
11946 +#define VMIN 6
11947 +#define VSWTC 7
11948 +#define VSTART 8
11949 +#define VSTOP 9
11950 +#define VSUSP 10
11951 +#define VEOL 11
11952 +#define VREPRINT 12
11953 +#define VDISCARD 13
11954 +#define VWERASE 14
11955 +#define VLNEXT 15
11956 +#define VEOL2 16
11957 +
11958 +
11959 +/* c_iflag bits */
11960 +#define IGNBRK 0000001
11961 +#define BRKINT 0000002
11962 +#define IGNPAR 0000004
11963 +#define PARMRK 0000010
11964 +#define INPCK  0000020
11965 +#define ISTRIP 0000040
11966 +#define INLCR  0000100
11967 +#define IGNCR  0000200
11968 +#define ICRNL  0000400
11969 +#define IUCLC  0001000
11970 +#define IXON   0002000
11971 +#define IXANY  0004000
11972 +#define IXOFF  0010000
11973 +#define IMAXBEL        0020000
11974 +#define IUTF8  0040000
11975 +
11976 +/* c_oflag bits */
11977 +#define OPOST  0000001
11978 +#define OLCUC  0000002
11979 +#define ONLCR  0000004
11980 +#define OCRNL  0000010
11981 +#define ONOCR  0000020
11982 +#define ONLRET 0000040
11983 +#define OFILL  0000100
11984 +#define OFDEL  0000200
11985 +#define NLDLY  0000400
11986 +#define   NL0  0000000
11987 +#define   NL1  0000400
11988 +#define CRDLY  0003000
11989 +#define   CR0  0000000
11990 +#define   CR1  0001000
11991 +#define   CR2  0002000
11992 +#define   CR3  0003000
11993 +#define TABDLY 0014000
11994 +#define   TAB0 0000000
11995 +#define   TAB1 0004000
11996 +#define   TAB2 0010000
11997 +#define   TAB3 0014000
11998 +#define   XTABS        0014000
11999 +#define BSDLY  0020000
12000 +#define   BS0  0000000
12001 +#define   BS1  0020000
12002 +#define VTDLY  0040000
12003 +#define   VT0  0000000
12004 +#define   VT1  0040000
12005 +#define FFDLY  0100000
12006 +#define   FF0  0000000
12007 +#define   FF1  0100000
12008 +
12009 +/* c_cflag bit meaning */
12010 +#define CBAUD  0010017
12011 +#define  B0    0000000         /* hang up */
12012 +#define  B50   0000001
12013 +#define  B75   0000002
12014 +#define  B110  0000003
12015 +#define  B134  0000004
12016 +#define  B150  0000005
12017 +#define  B200  0000006
12018 +#define  B300  0000007
12019 +#define  B600  0000010
12020 +#define  B1200 0000011
12021 +#define  B1800 0000012
12022 +#define  B2400 0000013
12023 +#define  B4800 0000014
12024 +#define  B9600 0000015
12025 +#define  B19200        0000016
12026 +#define  B38400        0000017
12027 +#define EXTA B19200
12028 +#define EXTB B38400
12029 +#define CSIZE  0000060
12030 +#define   CS5  0000000
12031 +#define   CS6  0000020
12032 +#define   CS7  0000040
12033 +#define   CS8  0000060
12034 +#define CSTOPB 0000100
12035 +#define CREAD  0000200
12036 +#define PARENB 0000400
12037 +#define PARODD 0001000
12038 +#define HUPCL  0002000
12039 +#define CLOCAL 0004000
12040 +#define CBAUDEX 0010000
12041 +#define    BOTHER 0010000
12042 +#define    B57600 0010001
12043 +#define   B115200 0010002
12044 +#define   B230400 0010003
12045 +#define   B460800 0010004
12046 +#define   B500000 0010005
12047 +#define   B576000 0010006
12048 +#define   B921600 0010007
12049 +#define  B1000000 0010010
12050 +#define  B1152000 0010011
12051 +#define  B1500000 0010012
12052 +#define  B2000000 0010013
12053 +#define  B2500000 0010014
12054 +#define  B3000000 0010015
12055 +#define  B3500000 0010016
12056 +#define  B4000000 0010017
12057 +#define CIBAUD   002003600000          /* input baud rate */
12058 +#define CMSPAR   010000000000          /* mark or space (stick) parity */
12059 +#define CRTSCTS          020000000000          /* flow control */
12060 +
12061 +#define IBSHIFT        16                      /* Shift from CBAUD to CIBAUD */
12062 +
12063 +/* c_lflag bits */
12064 +#define ISIG   0000001
12065 +#define ICANON 0000002
12066 +#define XCASE  0000004
12067 +#define ECHO   0000010
12068 +#define ECHOE  0000020
12069 +#define ECHOK  0000040
12070 +#define ECHONL 0000100
12071 +#define NOFLSH 0000200
12072 +#define TOSTOP 0000400
12073 +#define ECHOCTL        0001000
12074 +#define ECHOPRT        0002000
12075 +#define ECHOKE 0004000
12076 +#define FLUSHO 0010000
12077 +#define PENDIN 0040000
12078 +#define IEXTEN 0100000
12079 +
12080 +
12081 +/* tcflow() and TCXONC use these */
12082 +#define        TCOOFF          0
12083 +#define        TCOON           1
12084 +#define        TCIOFF          2
12085 +#define        TCION           3
12086 +
12087 +/* tcflush() and TCFLSH use these */
12088 +#define        TCIFLUSH        0
12089 +#define        TCOFLUSH        1
12090 +#define        TCIOFLUSH       2
12091 +
12092 +/* tcsetattr uses these */
12093 +#define        TCSANOW         0
12094 +#define        TCSADRAIN       1
12095 +#define        TCSAFLUSH       2
12096 +
12097 +#endif /* _ASM_UBICOM32_TERMBITS_H */
12098 --- /dev/null
12099 +++ b/arch/ubicom32/include/asm/termios.h
12100 @@ -0,0 +1,119 @@
12101 +/*
12102 + * arch/ubicom32/include/asm/termios.h
12103 + *   Ubicom32 termio definitions.
12104 + *
12105 + * (C) Copyright 2009, Ubicom, Inc.
12106 + *
12107 + * This file is part of the Ubicom32 Linux Kernel Port.
12108 + *
12109 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12110 + * it and/or modify it under the terms of the GNU General Public License
12111 + * as published by the Free Software Foundation, either version 2 of the
12112 + * License, or (at your option) any later version.
12113 + *
12114 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12115 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12116 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12117 + * the GNU General Public License for more details.
12118 + *
12119 + * You should have received a copy of the GNU General Public License
12120 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12121 + * see <http://www.gnu.org/licenses/>.
12122 + *
12123 + * Ubicom32 implementation derived from (with many thanks):
12124 + *   arch/m68knommu
12125 + *   arch/blackfin
12126 + *   arch/parisc
12127 + */
12128 +#ifndef _ASM_UBICOM32_TERMIOS_H
12129 +#define _ASM_UBICOM32_TERMIOS_H
12130 +
12131 +#include <asm/termbits.h>
12132 +#include <asm/ioctls.h>
12133 +
12134 +struct winsize {
12135 +       unsigned short ws_row;
12136 +       unsigned short ws_col;
12137 +       unsigned short ws_xpixel;
12138 +       unsigned short ws_ypixel;
12139 +};
12140 +
12141 +#define NCC 8
12142 +struct termio {
12143 +       unsigned short c_iflag;         /* input mode flags */
12144 +       unsigned short c_oflag;         /* output mode flags */
12145 +       unsigned short c_cflag;         /* control mode flags */
12146 +       unsigned short c_lflag;         /* local mode flags */
12147 +       unsigned char c_line;           /* line discipline */
12148 +       unsigned char c_cc[NCC];        /* control characters */
12149 +};
12150 +
12151 +#ifdef __KERNEL__
12152 +/*     intr=^C         quit=^|         erase=del       kill=^U
12153 +       eof=^D          vtime=\0        vmin=\1         sxtc=\0
12154 +       start=^Q        stop=^S         susp=^Z         eol=\0
12155 +       reprint=^R      discard=^U      werase=^W       lnext=^V
12156 +       eol2=\0
12157 +*/
12158 +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
12159 +#endif
12160 +
12161 +/* modem lines */
12162 +#define TIOCM_LE       0x001
12163 +#define TIOCM_DTR      0x002
12164 +#define TIOCM_RTS      0x004
12165 +#define TIOCM_ST       0x008
12166 +#define TIOCM_SR       0x010
12167 +#define TIOCM_CTS      0x020
12168 +#define TIOCM_CAR      0x040
12169 +#define TIOCM_RNG      0x080
12170 +#define TIOCM_DSR      0x100
12171 +#define TIOCM_CD       TIOCM_CAR
12172 +#define TIOCM_RI       TIOCM_RNG
12173 +#define TIOCM_OUT1     0x2000
12174 +#define TIOCM_OUT2     0x4000
12175 +#define TIOCM_LOOP     0x8000
12176 +
12177 +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
12178 +
12179 +#ifdef __KERNEL__
12180 +
12181 +/*
12182 + * Translate a "termio" structure into a "termios". Ugh.
12183 + */
12184 +#define user_termio_to_kernel_termios(termios, termio) \
12185 +({ \
12186 +       unsigned short tmp; \
12187 +       get_user(tmp, &(termio)->c_iflag); \
12188 +       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
12189 +       get_user(tmp, &(termio)->c_oflag); \
12190 +       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
12191 +       get_user(tmp, &(termio)->c_cflag); \
12192 +       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
12193 +       get_user(tmp, &(termio)->c_lflag); \
12194 +       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
12195 +       get_user((termios)->c_line, &(termio)->c_line); \
12196 +       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
12197 +})
12198 +
12199 +/*
12200 + * Translate a "termios" structure into a "termio". Ugh.
12201 + */
12202 +#define kernel_termios_to_user_termio(termio, termios) \
12203 +({ \
12204 +       put_user((termios)->c_iflag, &(termio)->c_iflag); \
12205 +       put_user((termios)->c_oflag, &(termio)->c_oflag); \
12206 +       put_user((termios)->c_cflag, &(termio)->c_cflag); \
12207 +       put_user((termios)->c_lflag, &(termio)->c_lflag); \
12208 +       put_user((termios)->c_line,  &(termio)->c_line); \
12209 +       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
12210 +})
12211 +
12212 +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
12213 +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
12214 +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
12215 +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
12216 +
12217 +#endif /* __KERNEL__ */
12218 +
12219 +#endif /* _ASM_UBICOM32_TERMIOS_H */
12220 --- /dev/null
12221 +++ b/arch/ubicom32/include/asm/thread-asm.h
12222 @@ -0,0 +1,49 @@
12223 +/*
12224 + * arch/ubicom32/include/asm/thread-asm.h
12225 + *   Ubicom32 architecture specific thread definitions.
12226 + *
12227 + * (C) Copyright 2009, Ubicom, Inc.
12228 + *
12229 + * This file is part of the Ubicom32 Linux Kernel Port.
12230 + *
12231 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12232 + * it and/or modify it under the terms of the GNU General Public License
12233 + * as published by the Free Software Foundation, either version 2 of the
12234 + * License, or (at your option) any later version.
12235 + *
12236 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12237 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12238 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12239 + * the GNU General Public License for more details.
12240 + *
12241 + * You should have received a copy of the GNU General Public License
12242 + * along with the Ubicom32 Linux Kernel Port.  If not,
12243 + * see <http://www.gnu.org/licenses/>.
12244 + *
12245 + * Ubicom32 implementation derived from (with many thanks):
12246 + *   arch/m68knommu
12247 + *   arch/blackfin
12248 + *   arch/parisc
12249 + */
12250 +#ifndef _ASM_UBICOM32_THREAD_ASM_H
12251 +#define _ASM_UBICOM32_THREAD_ASM_H
12252 +
12253 +/*
12254 + * thread_get_self
12255 + *     Read and shift the current thread into reg
12256 + */
12257 +.macro thread_get_self reg
12258 +       lsr.4   \reg, ROSR, #2
12259 +       and.4   \reg, #31, \reg  /* Mask to get thread number into register */
12260 +.endm
12261 +
12262 +/*
12263 + * thread_get_self_mask
12264 + *     Read and shift the current thread mask into reg
12265 + */
12266 +.macro thread_get_self_mask reg
12267 +       lsr.4   \reg, ROSR, #2
12268 +       lsl.4   \reg, #1, \reg   /* Thread bit */
12269 +.endm
12270 +
12271 +#endif /* _ASM_UBICOM32_THREAD_ASM_H */
12272 --- /dev/null
12273 +++ b/arch/ubicom32/include/asm/thread.h
12274 @@ -0,0 +1,313 @@
12275 +/*
12276 + * arch/ubicom32/include/asm/thread.h
12277 + *   Ubicom32 architecture specific thread definitions.
12278 + *
12279 + * (C) Copyright 2009, Ubicom, Inc.
12280 + *
12281 + * This file is part of the Ubicom32 Linux Kernel Port.
12282 + *
12283 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12284 + * it and/or modify it under the terms of the GNU General Public License
12285 + * as published by the Free Software Foundation, either version 2 of the
12286 + * License, or (at your option) any later version.
12287 + *
12288 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12289 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12290 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12291 + * the GNU General Public License for more details.
12292 + *
12293 + * You should have received a copy of the GNU General Public License
12294 + * along with the Ubicom32 Linux Kernel Port.  If not,
12295 + * see <http://www.gnu.org/licenses/>.
12296 + *
12297 + * Ubicom32 implementation derived from (with many thanks):
12298 + *   arch/m68knommu
12299 + *   arch/blackfin
12300 + *   arch/parisc
12301 + */
12302 +#ifndef _ASM_UBICOM32_THREAD_H
12303 +#define _ASM_UBICOM32_THREAD_H
12304 +
12305 +#if !defined(__ASSEMBLY__)
12306 +
12307 +#include <asm/ptrace.h>
12308 +#include <asm/ubicom32-common.h>
12309 +
12310 +typedef int thread_t;
12311 +typedef unsigned char thread_type_t;
12312 +typedef void (*thread_exec_fn_t)(void *arg);
12313 +
12314 +#define THREAD_NULL 0x40
12315 +#define THREAD_TYPE_HRT (1 << 0)
12316 +#define THREAD_TYPE_SPECIAL 0
12317 +#define THREAD_TYPE_NORMAL 0
12318 +#define THREAD_TYPE_BACKGROUND (1 << 1)
12319 +
12320 +/*
12321 + * This is the upper bound on the maximum hardware threads that one will find
12322 + * on a Ubicom processor. It is used to size per hardware thread data structures.
12323 + */
12324 +#define THREAD_ARCHITECTURAL_MAX 16
12325 +
12326 +/*
12327 + * TODO: Rename this at some point to be thread_
12328 + */
12329 +extern unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
12330 +
12331 +
12332 +/*
12333 + * thread_get_self()
12334 + */
12335 +static inline thread_t thread_get_self(void)
12336 +{
12337 +       thread_t result;
12338 +       asm (
12339 +               "lsr.4  %0, ROSR, #2    \n\t"
12340 +               : "=d" (result)
12341 +               :
12342 +               : "cc"
12343 +       );
12344 +       return result & 31;
12345 +}
12346 +
12347 +/*
12348 + * thread_suspend()
12349 + */
12350 +static inline void thread_suspend(void)
12351 +{
12352 +       asm volatile (
12353 +               "suspend\n\t"
12354 +               :
12355 +               :
12356 +       );
12357 +}
12358 +
12359 +/*
12360 + * thread_resume()
12361 + */
12362 +static inline void thread_resume(thread_t thread)
12363 +{
12364 +       asm volatile (
12365 +               "move.4         MT_ACTIVE_SET, %0       \n\t"
12366 +               "pipe_flush     0                       \n\t"
12367 +               "pipe_flush     0                       \n\t"
12368 +               :
12369 +               : "d" (1 << thread)
12370 +       );
12371 +}
12372 +
12373 +
12374 +
12375 +/*
12376 + * thread_enable_mask()
12377 + *     Enable all threads in the mask.
12378 + *
12379 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12380 + */
12381 +static inline void thread_enable_mask(unsigned int mask)
12382 +{
12383 +       /*
12384 +        * must flush the pipeline twice.
12385 +        * first pipe_flush is to ensure write to MT_EN is completed
12386 +        * second one is to ensure any new instructions from
12387 +        * the targeted thread (the one being disabled), that
12388 +        * are issued while the write to MT_EN is being executed,
12389 +        * are completed.
12390 +        */
12391 +       UBICOM32_LOCK(MT_EN_LOCK_BIT);
12392 +       asm volatile (
12393 +               "or.4           MT_EN, MT_EN, %0        \n\t"
12394 +               "pipe_flush     0                       \n\t"
12395 +               "pipe_flush     0                       \n\t"
12396 +               :
12397 +               : "d" (mask)
12398 +               : "cc"
12399 +       );
12400 +       UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12401 +}
12402 +
12403 +/*
12404 + * thread_enable()
12405 + */
12406 +static inline void thread_enable(thread_t thread)
12407 +{
12408 +       thread_enable_mask(1 << thread);
12409 +}
12410 +
12411 +/*
12412 + * thread_disable_mask()
12413 + *     Disable all threads in the mask.
12414 + *
12415 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12416 + */
12417 +static inline void thread_disable_mask(unsigned int mask)
12418 +{
12419 +       /*
12420 +        * must flush the pipeline twice.
12421 +        * first pipe_flush is to ensure write to MT_EN is completed
12422 +        * second one is to ensure any new instructions from
12423 +        * the targeted thread (the one being disabled), that
12424 +        * are issued while the write to MT_EN is being executed,
12425 +        * are completed.
12426 +        */
12427 +       UBICOM32_LOCK(MT_EN_LOCK_BIT);
12428 +       asm volatile (
12429 +               "and.4          MT_EN, MT_EN, %0        \n\t"
12430 +               "pipe_flush     0                       \n\t"
12431 +               "pipe_flush     0                       \n\t"
12432 +               :
12433 +               : "d" (~mask)
12434 +               : "cc"
12435 +       );
12436 +       UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12437 +}
12438 +
12439 +/*
12440 + * thread_disable()
12441 + */
12442 +static inline void thread_disable(thread_t thread)
12443 +{
12444 +       thread_disable_mask(1 << thread);
12445 +}
12446 +
12447 +/*
12448 + * thread_disable_others()
12449 + *     Disable all other threads
12450 + */
12451 +static inline void thread_disable_others(void)
12452 +{
12453 +       thread_t self = thread_get_self();
12454 +       thread_disable_mask(~(1 << self));
12455 +}
12456 +
12457 +/*
12458 + * thread_is_trapped()
12459 + *     Is the specified tid trapped?
12460 + */
12461 +static inline int thread_is_trapped(thread_t tid)
12462 +{
12463 +       int thread_mask = (1 << tid);
12464 +       int trap_thread;
12465 +
12466 +       asm (
12467 +               "move.4         %0, MT_TRAP             \n\t"
12468 +               : "=d" (trap_thread)
12469 +               :
12470 +       );
12471 +       return (trap_thread & thread_mask);
12472 +}
12473 +
12474 +/*
12475 + * thread_is_enabled()
12476 + *     Is the specified tid enabled?
12477 + */
12478 +static inline int thread_is_enabled(thread_t tid)
12479 +{
12480 +       int thread_mask = (1 << tid);
12481 +       int enabled_threads;
12482 +
12483 +       asm (
12484 +               "move.4         %0, MT_EN               \n\t"
12485 +               : "=d" (enabled_threads)
12486 +               :
12487 +       );
12488 +       return (enabled_threads & thread_mask);
12489 +}
12490 +
12491 +/*
12492 + * thread_get_instruction_count()
12493 + */
12494 +static inline unsigned int thread_get_instruction_count(void)
12495 +{
12496 +       unsigned int result;
12497 +       asm (
12498 +               "move.4         %0, INST_CNT            \n\t"
12499 +               : "=r" (result)
12500 +       );
12501 +       return result;
12502 +}
12503 +
12504 +/*
12505 + * thread_get_pc()
12506 + *     pc could point to a speculative and cancelled instruction unless thread is disabled
12507 + */
12508 +static inline void *thread_get_pc(thread_t thread)
12509 +{
12510 +       void *result;
12511 +       asm (
12512 +               "move.4         csr, %1         \n\t"
12513 +               "setcsr_flush   0               \n\t"
12514 +               "move.4         %0, pc          \n\t"
12515 +               "move.4         csr, #0         \n\t"
12516 +               "setcsr_flush   0               \n\t"
12517 +               : "=r" (result)
12518 +               : "r" ((thread << 9) | (1 << 8))
12519 +       );
12520 +       return result;
12521 +}
12522 +
12523 +/*
12524 + * thread_get_trap_cause()
12525 + *     This should be called only when the thread is not running
12526 + */
12527 +static inline unsigned int thread_get_trap_cause(thread_t thread)
12528 +{
12529 +       unsigned int result;
12530 +       asm (
12531 +               "move.4         csr, %1         \n\t"
12532 +               "setcsr_flush   0               \n\t"
12533 +               "move.4         %0, trap_cause  \n\t"
12534 +               "move.4         csr, #0         \n\t"
12535 +               "setcsr_flush   0               \n\t"
12536 +               : "=r" (result)
12537 +               : "r" ((thread << 9) | (1 << 8))
12538 +       );
12539 +       return result;
12540 +}
12541 +
12542 +/*
12543 + * THREAD_STALL macro.
12544 + */
12545 +#define THREAD_STALL \
12546 +               asm volatile ( \
12547 +                       "move.4 mt_dbg_active_clr, #-1  \n\t" \
12548 +                       "pipe_flush 0                   \n\t" \
12549 +                       : \
12550 +                       : \
12551 +               )
12552 +
12553 +extern unsigned int thread_get_mainline(void);
12554 +extern void thread_set_mainline(thread_t tid);
12555 +extern thread_t thread_alloc(void);
12556 +extern thread_t thread_start(thread_t thread, thread_exec_fn_t exec, void *arg, unsigned int *sp_high, thread_type_t type);
12557 +
12558 +/*
12559 + * asm macros
12560 + */
12561 +asm (
12562 +/*
12563 + * thread_get_self
12564 + *     Read and shift the current thread into reg
12565 + */
12566 +".macro        thread_get_self reg             \n\t"
12567 +"      lsr.4   \\reg, ROSR, #2         \n\t"
12568 +"      and.4   \\reg, #31, \\reg       \n\t"/* Mask to get thread number into
12569 +                                             * register */
12570 +".endm                                 \n\t"
12571 +
12572 +/*
12573 + * thread_get_self_mask
12574 + *     Read and shift the current thread mask into reg
12575 + */
12576 +".macro        thread_get_self_mask reg        \n\t"
12577 +"      lsr.4   \\reg, ROSR, #2         \n\t"
12578 +"      lsl.4   \\reg, #1, \\reg        \n\t"    /* Thread bit */
12579 +".endm                                 \n\t"
12580 +       );
12581 +
12582 +#else /* __ASSEMBLY__ */
12583 +
12584 +#include <asm/thread-asm.h>
12585 +
12586 +#endif /* __ASSEMBLY__ */
12587 +#endif /* _ASM_UBICOM32_THREAD_H */
12588 --- /dev/null
12589 +++ b/arch/ubicom32/include/asm/thread_info.h
12590 @@ -0,0 +1,134 @@
12591 +/*
12592 + * arch/ubicom32/include/asm/thread_info.h
12593 + *   Ubicom32 architecture low-level thread information.
12594 + *
12595 + * (C) Copyright 2009, Ubicom, Inc.
12596 + * Adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com)
12597 + * Copyright (C) 2002  David Howells (dhowells@redhat.com)
12598 + * - Incorporating suggestions made by Linus Torvalds and Dave Miller
12599 + *
12600 + * This file is part of the Ubicom32 Linux Kernel Port.
12601 + *
12602 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12603 + * it and/or modify it under the terms of the GNU General Public License
12604 + * as published by the Free Software Foundation, either version 2 of the
12605 + * License, or (at your option) any later version.
12606 + *
12607 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12608 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12609 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12610 + * the GNU General Public License for more details.
12611 + *
12612 + * You should have received a copy of the GNU General Public License
12613 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12614 + * see <http://www.gnu.org/licenses/>.
12615 + *
12616 + * Ubicom32 implementation derived from (with many thanks):
12617 + *   arch/m68knommu
12618 + *   arch/blackfin
12619 + *   arch/parisc
12620 + */
12621 +
12622 +#ifndef _ASM_UBICOM32_THREAD_INFO_H
12623 +#define _ASM_UBICOM32_THREAD_INFO_H
12624 +
12625 +#include <asm/page.h>
12626 +
12627 +/*
12628 + * Size of kernel stack for each process. This must be a power of 2...
12629 + */
12630 +#ifdef CONFIG_4KSTACKS
12631 +#define THREAD_SIZE_ORDER (0)
12632 +#else
12633 +#define THREAD_SIZE_ORDER (1)
12634 +#endif
12635 +
12636 +/*
12637 + * for asm files, THREAD_SIZE is now generated by asm-offsets.c
12638 + */
12639 +#define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
12640 +
12641 +#ifdef __KERNEL__
12642 +
12643 +#ifndef __ASSEMBLY__
12644 +
12645 +/*
12646 + * low level task data.
12647 + */
12648 +struct thread_info {
12649 +       struct task_struct *task;               /* main task structure */
12650 +       struct exec_domain *exec_domain;        /* execution domain */
12651 +       unsigned long      flags;               /* low level flags */
12652 +       int                cpu;                 /* cpu we're on */
12653 +       int                preempt_count;       /* 0 => preemptable, <0 => BUG */
12654 +       int                interrupt_nesting;   /* Interrupt nesting level. */
12655 +       struct restart_block restart_block;
12656 +};
12657 +
12658 +/*
12659 + * macros/functions for gaining access to the thread information structure
12660 + */
12661 +#define INIT_THREAD_INFO(tsk)                  \
12662 +{                                              \
12663 +       .task           = &tsk,                 \
12664 +       .exec_domain    = &default_exec_domain, \
12665 +       .flags          = 0,                    \
12666 +       .cpu            = 0,                    \
12667 +       .interrupt_nesting      = 0,            \
12668 +       .restart_block  = {                     \
12669 +               .fn = do_no_restart_syscall,    \
12670 +       },                                      \
12671 +}
12672 +
12673 +#define init_thread_info       (init_thread_union.thread_info)
12674 +#define init_stack             (init_thread_union.stack)
12675 +
12676 +
12677 +/* how to get the thread information struct from C */
12678 +static inline struct thread_info *current_thread_info(void)
12679 +{
12680 +       struct thread_info *ti;
12681 +
12682 +       asm (
12683 +               "and.4  %0, sp, %1\n\t"
12684 +               : "=&r" (ti)
12685 +               : "d" (~(THREAD_SIZE-1))
12686 +               : "cc"
12687 +       );
12688 +
12689 +       return ti;
12690 +}
12691 +
12692 +#define STACK_WARN (THREAD_SIZE / 8)
12693 +
12694 +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 1
12695 +
12696 +/* thread information allocation */
12697 +#define alloc_thread_info(tsk) ((struct thread_info *) \
12698 +                               __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER))
12699 +#define free_thread_info(ti)   free_pages((unsigned long) (ti), THREAD_SIZE_ORDER)
12700 +#endif /* __ASSEMBLY__ */
12701 +
12702 +#define        PREEMPT_ACTIVE  0x4000000
12703 +
12704 +/*
12705 + * thread information flag bit numbers
12706 + */
12707 +#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
12708 +#define TIF_SIGPENDING         1       /* signal pending */
12709 +#define TIF_NEED_RESCHED       2       /* rescheduling necessary */
12710 +#define TIF_POLLING_NRFLAG     3       /* true if poll_idle() is polling
12711 +                                          TIF_NEED_RESCHED */
12712 +#define TIF_MEMDIE             4
12713 +
12714 +/* as above, but as bit values */
12715 +#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
12716 +#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
12717 +#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
12718 +#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
12719 +
12720 +#define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
12721 +
12722 +#endif /* __KERNEL__ */
12723 +
12724 +#endif /* _ASM_UBICOM32_THREAD_INFO_H */
12725 --- /dev/null
12726 +++ b/arch/ubicom32/include/asm/timex.h
12727 @@ -0,0 +1,56 @@
12728 +/*
12729 + * arch/ubicom32/include/asm/timex.h
12730 + *   Ubicom32 architecture timex specifications.
12731 + *
12732 + * (C) Copyright 2009, Ubicom, Inc.
12733 + *
12734 + * This file is part of the Ubicom32 Linux Kernel Port.
12735 + *
12736 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12737 + * it and/or modify it under the terms of the GNU General Public License
12738 + * as published by the Free Software Foundation, either version 2 of the
12739 + * License, or (at your option) any later version.
12740 + *
12741 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12742 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12743 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12744 + * the GNU General Public License for more details.
12745 + *
12746 + * You should have received a copy of the GNU General Public License
12747 + * along with the Ubicom32 Linux Kernel Port.  If not,
12748 + * see <http://www.gnu.org/licenses/>.
12749 + *
12750 + * Ubicom32 implementation derived from (with many thanks):
12751 + *   arch/m68knommu
12752 + *   arch/blackfin
12753 + *   arch/parisc
12754 + */
12755 +#ifndef _ASM_UBICOM32_TIMEX_H
12756 +#define _ASM_UBICOM32_TIMEX_H
12757 +
12758 +#define CLOCK_TICK_RATE        266000000
12759 +
12760 +// #define ARCH_HAS_READ_CURRENT_TIMER
12761 +
12762 +typedef unsigned long cycles_t;
12763 +
12764 +static inline cycles_t get_cycles(void)
12765 +{
12766 +       return 0;
12767 +}
12768 +
12769 +extern int timer_alloc(void);
12770 +extern void timer_set(int timervector, unsigned int cycles);
12771 +extern int timer_reset(int timervector, unsigned int cycles);
12772 +extern void timer_tick_init(void);
12773 +extern void timer_device_init(void);
12774 +
12775 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12776 +extern void local_timer_interrupt(void);
12777 +#endif
12778 +
12779 +#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12780 +extern int local_timer_setup(unsigned int cpu);
12781 +#endif
12782 +
12783 +#endif /* _ASM_UBICOM32_TIMEX_H */
12784 --- /dev/null
12785 +++ b/arch/ubicom32/include/asm/tlbflush.h
12786 @@ -0,0 +1,79 @@
12787 +/*
12788 + * arch/ubicom32/include/asm/tlbflush.h
12789 + *   TLB operations for Ubicom32 architecture.
12790 + *
12791 + * (C) Copyright 2009, Ubicom, Inc.
12792 + * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
12793 + * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
12794 + *
12795 + * This file is part of the Ubicom32 Linux Kernel Port.
12796 + *
12797 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12798 + * it and/or modify it under the terms of the GNU General Public License
12799 + * as published by the Free Software Foundation, either version 2 of the
12800 + * License, or (at your option) any later version.
12801 + *
12802 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12803 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12804 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12805 + * the GNU General Public License for more details.
12806 + *
12807 + * You should have received a copy of the GNU General Public License
12808 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12809 + * see <http://www.gnu.org/licenses/>.
12810 + *
12811 + * Ubicom32 implementation derived from (with many thanks):
12812 + *   arch/m68knommu
12813 + *   arch/blackfin
12814 + *   arch/parisc
12815 + */
12816 +#ifndef _ASM_UBICOM32_TLB_FLUSH_H
12817 +#define _ASM_UBICOM32_TLB_FLUSH_H
12818 +
12819 +#include <asm/setup.h>
12820 +
12821 +/*
12822 + * flush all user-space atc entries.
12823 + */
12824 +static inline void __flush_tlb(void)
12825 +{
12826 +       BUG();
12827 +}
12828 +
12829 +static inline void __flush_tlb_one(unsigned long addr)
12830 +{
12831 +       BUG();
12832 +}
12833 +
12834 +#define flush_tlb() __flush_tlb()
12835 +
12836 +/*
12837 + * flush all atc entries (both kernel and user-space entries).
12838 + */
12839 +static inline void flush_tlb_all(void)
12840 +{
12841 +       BUG();
12842 +}
12843 +
12844 +static inline void flush_tlb_mm(struct mm_struct *mm)
12845 +{
12846 +       BUG();
12847 +}
12848 +
12849 +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
12850 +{
12851 +       BUG();
12852 +}
12853 +
12854 +static inline void flush_tlb_range(struct mm_struct *mm,
12855 +                                  unsigned long start, unsigned long end)
12856 +{
12857 +       BUG();
12858 +}
12859 +
12860 +static inline void flush_tlb_kernel_page(unsigned long addr)
12861 +{
12862 +       BUG();
12863 +}
12864 +
12865 +#endif /* _ASM_UBICOM32_TLB_FLUSH_H */
12866 --- /dev/null
12867 +++ b/arch/ubicom32/include/asm/tlb.h
12868 @@ -0,0 +1,47 @@
12869 +/*
12870 + * arch/ubicom32/include/asm/tlb.h
12871 + *   Ubicom32 architecture TLB operations.
12872 + *
12873 + * (C) Copyright 2009, Ubicom, Inc.
12874 + *
12875 + * This file is part of the Ubicom32 Linux Kernel Port.
12876 + *
12877 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12878 + * it and/or modify it under the terms of the GNU General Public License
12879 + * as published by the Free Software Foundation, either version 2 of the
12880 + * License, or (at your option) any later version.
12881 + *
12882 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12883 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12884 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12885 + * the GNU General Public License for more details.
12886 + *
12887 + * You should have received a copy of the GNU General Public License
12888 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12889 + * see <http://www.gnu.org/licenses/>.
12890 + *
12891 + * Ubicom32 implementation derived from (with many thanks):
12892 + *   arch/m68knommu
12893 + *   arch/blackfin
12894 + *   arch/parisc
12895 + */
12896 +#ifndef _ASM_UBICOM32_TLB_H
12897 +#define _ASM_UBICOM32_TLB_H
12898 +
12899 +/*
12900 + * ubicom32 doesn't need any special per-pte or
12901 + * per-vma handling..
12902 + */
12903 +#define tlb_start_vma(tlb, vma)        do { } while (0)
12904 +#define tlb_end_vma(tlb, vma)  do { } while (0)
12905 +#define __tlb_remove_tlb_entry(tlb, ptep, address)     do { } while (0)
12906 +
12907 +/*
12908 + * .. because we flush the whole mm when it
12909 + * fills up.
12910 + */
12911 +#define tlb_flush(tlb)
12912 +
12913 +#include <asm-generic/tlb.h>
12914 +
12915 +#endif /* _ASM_UBICOM32_TLB_H */
12916 --- /dev/null
12917 +++ b/arch/ubicom32/include/asm/topology.h
12918 @@ -0,0 +1,33 @@
12919 +/*
12920 + * arch/ubicom32/include/asm/topology.h
12921 + *   Generic topology.h definitions 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 + */
12946 +#ifndef _ASM_UBICOM32_TOPOLOGY_H
12947 +#define _ASM_UBICOM32_TOPOLOGY_H
12948 +
12949 +#include <asm-generic/topology.h>
12950 +
12951 +#endif /* _ASM_UBICOM32_TOPOLOGY_H */
12952 --- /dev/null
12953 +++ b/arch/ubicom32/include/asm/traps.h
12954 @@ -0,0 +1,55 @@
12955 +/*
12956 + * arch/ubicom32/include/asm/traps.h
12957 + *   Trap related definitions for Ubicom32 architecture.
12958 + *
12959 + * (C) Copyright 2009, Ubicom, Inc.
12960 + *
12961 + * This file is part of the Ubicom32 Linux Kernel Port.
12962 + *
12963 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
12964 + * it and/or modify it under the terms of the GNU General Public License
12965 + * as published by the Free Software Foundation, either version 2 of the
12966 + * License, or (at your option) any later version.
12967 + *
12968 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
12969 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12970 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12971 + * the GNU General Public License for more details.
12972 + *
12973 + * You should have received a copy of the GNU General Public License
12974 + * along with the Ubicom32 Linux Kernel Port.  If not, 
12975 + * see <http://www.gnu.org/licenses/>.
12976 + *
12977 + * Ubicom32 implementation derived from (with many thanks):
12978 + *   arch/m68knommu
12979 + *   arch/blackfin
12980 + *   arch/parisc
12981 + */
12982 +
12983 +#ifndef _ASM_UBICOM32_TRAPS_H
12984 +#define _ASM_UBICOM32_TRAPS_H
12985 +
12986 +/*
12987 + * Trap causes passed from ultra to Host OS
12988 + */
12989 +#define TRAP_CAUSE_TOTAL               13
12990 +#define TRAP_CAUSE_DST_RANGE_ERR       12
12991 +#define TRAP_CAUSE_SRC1_RANGE_ERR      11
12992 +#define TRAP_CAUSE_I_RANGE_ERR         10
12993 +#define TRAP_CAUSE_DCAPT               9
12994 +#define TRAP_CAUSE_DST_SERROR          8
12995 +#define TRAP_CAUSE_SRC1_SERROR         7
12996 +#define TRAP_CAUSE_DST_MISALIGNED      6
12997 +#define TRAP_CAUSE_SRC1_MISALIGNED     5
12998 +#define TRAP_CAUSE_DST_DECODE_ERR      4
12999 +#define TRAP_CAUSE_SRC1_DECODE_ERR     3
13000 +#define TRAP_CAUSE_ILLEGAL_INST                2
13001 +#define TRAP_CAUSE_I_SERROR            1
13002 +#define TRAP_CAUSE_I_DECODE_ERR                0
13003 +
13004 +extern void trap_handler(int irq, struct pt_regs *regs);
13005 +extern void trap_init_interrupt(void);
13006 +extern void unaligned_emulate(unsigned int thread);
13007 +extern int unaligned_only(unsigned int cause);
13008 +
13009 +#endif /* _ASM_UBICOM32_TRAPS_H */
13010 --- /dev/null
13011 +++ b/arch/ubicom32/include/asm/types.h
13012 @@ -0,0 +1,75 @@
13013 +/*
13014 + * arch/ubicom32/include/asm/types.h
13015 + *   Date type definitions for Ubicom32 architecture.
13016 + *
13017 + * (C) Copyright 2009, Ubicom, Inc.
13018 + *
13019 + * This file is part of the Ubicom32 Linux Kernel Port.
13020 + *
13021 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13022 + * it and/or modify it under the terms of the GNU General Public License
13023 + * as published by the Free Software Foundation, either version 2 of the
13024 + * License, or (at your option) any later version.
13025 + *
13026 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13027 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13028 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13029 + * the GNU General Public License for more details.
13030 + *
13031 + * You should have received a copy of the GNU General Public License
13032 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13033 + * see <http://www.gnu.org/licenses/>.
13034 + *
13035 + * Ubicom32 implementation derived from (with many thanks):
13036 + *   arch/m68knommu
13037 + *   arch/blackfin
13038 + *   arch/parisc
13039 + */
13040 +#ifndef _ASM_UBICOM32_TYPES_H
13041 +#define _ASM_UBICOM32_TYPES_H
13042 +
13043 +/*
13044 + * This file is never included by application software unless
13045 + * explicitly requested (e.g., via linux/types.h) in which case the
13046 + * application is Linux specific so (user-) name space pollution is
13047 + * not a major issue.  However, for interoperability, libraries still
13048 + * need to be careful to avoid a name clashes.
13049 + */
13050 +
13051 +#include <asm-generic/int-ll64.h>
13052 +
13053 +#ifndef __ASSEMBLY__
13054 +
13055 +typedef unsigned short umode_t;
13056 +
13057 +#endif /* __ASSEMBLY__ */
13058 +
13059 +/*
13060 + * These aren't exported outside the kernel to avoid name space clashes
13061 + */
13062 +#ifdef __KERNEL__
13063 +
13064 +#define BITS_PER_LONG 32
13065 +
13066 +#ifndef __ASSEMBLY__
13067 +
13068 +/* DMA addresses are always 32-bits wide */
13069 +
13070 +typedef u32 dma_addr_t;
13071 +typedef u32 dma64_addr_t;
13072 +
13073 +/*
13074 + * XXX These are "Ubicom style" typedefs. They should be removed in all files used by linux.
13075 + */
13076 +typedef u32 u32_t;
13077 +typedef s32 s32_t;
13078 +typedef u16 u16_t;
13079 +typedef s16 s16_t;
13080 +typedef u8 u8_t;
13081 +typedef s8 s8_t;
13082 +
13083 +#endif /* __ASSEMBLY__ */
13084 +
13085 +#endif /* __KERNEL__ */
13086 +
13087 +#endif /* _ASM_UBICOM32_TYPES_H */
13088 --- /dev/null
13089 +++ b/arch/ubicom32/include/asm/uaccess.h
13090 @@ -0,0 +1,347 @@
13091 +/*
13092 + * arch/ubicom32/include/asm/uaccess.h
13093 + *   User space memory access functions for Ubicom32 architecture.
13094 + *
13095 + * (C) Copyright 2009, Ubicom, Inc.
13096 + *
13097 + * This file is part of the Ubicom32 Linux Kernel Port.
13098 + *
13099 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13100 + * it and/or modify it under the terms of the GNU General Public License
13101 + * as published by the Free Software Foundation, either version 2 of the
13102 + * License, or (at your option) any later version.
13103 + *
13104 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13105 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13106 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13107 + * the GNU General Public License for more details.
13108 + *
13109 + * You should have received a copy of the GNU General Public License
13110 + * along with the Ubicom32 Linux Kernel Port.  If not,
13111 + * see <http://www.gnu.org/licenses/>.
13112 + *
13113 + * Ubicom32 implementation derived from (with many thanks):
13114 + *   arch/m68knommu
13115 + *   arch/blackfin
13116 + *   arch/parisc
13117 + *   arch/alpha
13118 + */
13119 +#ifndef _ASM_UBICOM32_UACCESS_H
13120 +#define _ASM_UBICOM32_UACCESS_H
13121 +
13122 +/*
13123 + * User space memory access functions
13124 + */
13125 +#include <linux/sched.h>
13126 +#include <linux/mm.h>
13127 +#include <linux/string.h>
13128 +
13129 +#include <asm/segment.h>
13130 +
13131 +#define VERIFY_READ    0
13132 +#define VERIFY_WRITE   1
13133 +
13134 +/*
13135 + * The exception table consists of pairs of addresses: the first is the
13136 + * address of an instruction that is allowed to fault, and the second is
13137 + * the address at which the program should continue.  No registers are
13138 + * modified, so it is entirely up to the continuation code to figure out
13139 + * what to do.
13140 + *
13141 + * All the routines below use bits of fixup code that are out of line
13142 + * with the main instruction path.  This means when everything is well,
13143 + * we don't even have to jump over them.  Further, they do not intrude
13144 + * on our cache or tlb entries.
13145 + */
13146 +struct exception_table_entry
13147 +{
13148 +       unsigned long insn, fixup;
13149 +};
13150 +
13151 +/* 
13152 + * Ubicom32 does not currently support the exception table handling.
13153 + */
13154 +extern unsigned long search_exception_table(unsigned long);
13155 +
13156 +
13157 +#if defined(CONFIG_ACCESS_OK_CHECKS_ENABLED)
13158 +extern int __access_ok(unsigned long addr, unsigned long size);
13159 +#else
13160 +static inline int __access_ok(unsigned long addr, unsigned long size)
13161 +{
13162 +       return 1;
13163 +}
13164 +#endif
13165 +#define access_ok(type, addr, size) \
13166 +       likely(__access_ok((unsigned long)(addr), (size)))
13167 +
13168 +/*
13169 + * The following functions do not exist.  They keep callers
13170 + * of put_user and get_user from passing unsupported argument
13171 + * types.  They result in a link time error.
13172 + */
13173 +extern int __put_user_bad(void);
13174 +extern int __get_user_bad(void);
13175 +
13176 +/*
13177 + * __put_user_no_check()
13178 + *     Put the requested data into the user space verifying the address
13179 + *
13180 + * Careful to not
13181 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13182 + * (b) require any knowledge of processes at this stage
13183 + */
13184 +#define __put_user_no_check(x, ptr, size)              \
13185 +({                                                     \
13186 +       int __pu_err = 0;                               \
13187 +       __typeof__(*(ptr)) __user *__pu_addr = (ptr);   \
13188 +       switch (size) {                                 \
13189 +       case 1:                                         \
13190 +       case 2:                                         \
13191 +       case 4:                                         \
13192 +       case 8:                                         \
13193 +               *__pu_addr = (__typeof__(*(ptr)))x;     \
13194 +               break;                                  \
13195 +       default:                                        \
13196 +               __pu_err = __put_user_bad();            \
13197 +               break;                                  \
13198 +       }                                               \
13199 +       __pu_err;                                       \
13200 +})
13201 +
13202 +/*
13203 + * __put_user_check()
13204 + *     Put the requested data into the user space verifying the address
13205 + *
13206 + * Careful to not
13207 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13208 + * (b) require any knowledge of processes at this stage
13209 + *
13210 + * If requested, access_ok() will verify that ptr is a valid user
13211 + * pointer.
13212 + */
13213 +#define __put_user_check(x, ptr, size)                         \
13214 +({                                                             \
13215 +       int __pu_err = -EFAULT;                                 \
13216 +       __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
13217 +       if (access_ok(VERIFY_WRITE, __pu_addr, size)) {         \
13218 +               __pu_err = 0;                                   \
13219 +               switch (size) {                                 \
13220 +               case 1:                                         \
13221 +               case 2:                                         \
13222 +               case 4:                                         \
13223 +               case 8:                                         \
13224 +                       *__pu_addr = (__typeof__(*(ptr)))x;     \
13225 +                       break;                                  \
13226 +               default:                                        \
13227 +                       __pu_err = __put_user_bad();            \
13228 +                       break;                                  \
13229 +               }                                               \
13230 +       }                                                       \
13231 +       __pu_err;                                               \
13232 +})
13233 +
13234 +/*
13235 + * __get_user_no_check()
13236 + *     Read the value at ptr into x.
13237 + *
13238 + * If requested, access_ok() will verify that ptr is a valid user
13239 + * pointer.  If the caller passes a modifying argument for ptr (e.g. x++)
13240 + * this macro will not work.
13241 + */
13242 +#define __get_user_no_check(x, ptr, size)                      \
13243 +({                                                             \
13244 +       int __gu_err = 0;                                       \
13245 +       __typeof__((x)) __gu_val = 0;                           \
13246 +       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);     \
13247 +       switch (size) {                                         \
13248 +       case 1:                                                 \
13249 +       case 2:                                                 \
13250 +       case 4:                                                 \
13251 +       case 8:                                                 \
13252 +               __gu_val = (__typeof__((x)))*(__gu_addr);       \
13253 +               break;                                          \
13254 +       default:                                                \
13255 +               __gu_err = __get_user_bad();                    \
13256 +               (x) = 0;                                        \
13257 +               break;                                          \
13258 +       }                                                       \
13259 +       (x) = __gu_val;                                         \
13260 +       __gu_err;                                               \
13261 +})
13262 +
13263 +/*
13264 + * __get_user_check()
13265 + *     Read the value at ptr into x.
13266 + *
13267 + * If requested, access_ok() will verify that ptr is a valid user
13268 + * pointer.
13269 + */
13270 +#define __get_user_check(x, ptr, size)                                 \
13271 +({                                                                     \
13272 +       int __gu_err = -EFAULT;                                         \
13273 +       __typeof__(x) __gu_val = 0;                                     \
13274 +       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);             \
13275 +       if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
13276 +               __gu_err = 0;                                           \
13277 +               switch (size) {                                         \
13278 +               case 1:                                                 \
13279 +               case 2:                                                 \
13280 +               case 4:                                                 \
13281 +               case 8:                                                 \
13282 +                       __gu_val = (__typeof__((x)))*(__gu_addr);       \
13283 +                       break;                                          \
13284 +               default:                                                \
13285 +                       __gu_err = __get_user_bad();                    \
13286 +                       (x) = 0;                                        \
13287 +                       break;                                          \
13288 +               }                                                       \
13289 +       }                                                               \
13290 +       (x) = __gu_val;                                                 \
13291 +       __gu_err;                                                       \
13292 +})
13293 +
13294 +/*
13295 + * The "xxx" versions are allowed to perform some amount of address
13296 + * space checking.  See access_ok().
13297 + */
13298 +#define put_user(x,ptr) \
13299 +       __put_user_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
13300 +#define get_user(x,ptr) \
13301 +       __get_user_check((x), (ptr), sizeof(*(ptr)))
13302 +
13303 +/*
13304 + * The "__xxx" versions do not do address space checking, useful when
13305 + * doing multiple accesses to the same area (the programmer has to do the
13306 + * checks by hand with "access_ok()")
13307 + */
13308 +#define __put_user(x,ptr) \
13309 +       __put_user_no_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
13310 +#define __get_user(x,ptr) \
13311 +       __get_user_no_check((x), (ptr), sizeof(*(ptr)))
13312 +
13313 +/*
13314 + * __copy_tofrom_user_no_check()
13315 + *     Copy the data either to or from user space.
13316 + *
13317 + * Return the number of bytes NOT copied.
13318 + */
13319 +static inline unsigned long
13320 +__copy_tofrom_user_no_check(void *to, const void *from, unsigned long n)
13321 +{
13322 +       memcpy(to, from, n);
13323 +       return 0;
13324 +}
13325 +
13326 +/*
13327 + * copy_to_user()
13328 + *     Copy the kernel data to user space.
13329 + *
13330 + * Return the number of bytes that were copied.
13331 + */
13332 +static inline unsigned long 
13333 +copy_to_user(void __user *to, const void *from, unsigned long n)
13334 +{
13335 +       if (!access_ok(VERIFY_WRITE, to, n)) {
13336 +               return n;
13337 +       }
13338 +       return __copy_tofrom_user_no_check((__force void *)to, from, n);
13339 +}
13340 +
13341 +/*
13342 + * copy_from_user()
13343 + *     Copy the user data to kernel space.
13344 + *
13345 + * Return the number of bytes that were copied.  On error, we zero 
13346 + * out the destination.
13347 + */
13348 +static inline unsigned long
13349 +copy_from_user(void *to, const void __user *from, unsigned long n)
13350 +{
13351 +       if (!access_ok(VERIFY_READ, from, n)) {
13352 +               return n;
13353 +       }
13354 +       return __copy_tofrom_user_no_check(to, (__force void *)from, n);
13355 +}
13356 +
13357 +#define __copy_to_user(to, from, n) \
13358 +       __copy_tofrom_user_no_check((__force void *)to, from, n)
13359 +#define __copy_from_user(to, from, n) \
13360 +       __copy_tofrom_user_no_check(to, (__force void *)from, n)
13361 +#define __copy_to_user_inatomic(to, from, n) \
13362 +       __copy_tofrom_user_no_check((__force void *)to, from, n)
13363 +#define __copy_from_user_inatomic(to, from, n) \
13364 +       __copy_tofrom_user_no_check(to, (__force void *)from, n)
13365 +
13366 +#define copy_to_user_ret(to, from, n, retval) \
13367 +       ({ if (copy_to_user(to, from, n)) return retval; })
13368 +
13369 +#define copy_from_user_ret(to, from, n, retval) \
13370 +       ({ if (copy_from_user(to, from, n)) return retval; })
13371 +
13372 +/*
13373 + * strncpy_from_user()
13374 + *     Copy a null terminated string from userspace.
13375 + *
13376 + * dst - Destination in kernel space.  The buffer must be at least count.
13377 + * src - Address of string in user space.
13378 + * count - Maximum number of bytes to copy (including the trailing NULL).
13379 + * 
13380 + * Returns the length of the string (not including the trailing NULL.  If 
13381 + * count is smaller than the length of the string, we copy count bytes
13382 + * and return count.
13383 + *
13384 + */
13385 +static inline long strncpy_from_user(char *dst, const __user char *src, long count)
13386 +{
13387 +       char *tmp;
13388 +       if (!access_ok(VERIFY_READ, src, 1)) {
13389 +               return -EFAULT;
13390 +       }
13391 +
13392 +       strncpy(dst, src, count);
13393 +       for (tmp = dst; *tmp && count > 0; tmp++, count--) {
13394 +               ;
13395 +       }
13396 +       return(tmp - dst);
13397 +}
13398 +
13399 +/*
13400 + * strnlen_user()
13401 + *     Return the size of a string (including the ending 0)
13402 + *
13403 + * Return -EFAULT on exception, a value greater than <n> if too long
13404 + */
13405 +static inline long strnlen_user(const __user char *src, long n)
13406 +{
13407 +       if (!access_ok(VERIFY_READ, src, 1)) {
13408 +               return -EFAULT;
13409 +       }
13410 +       return(strlen(src) + 1);
13411 +}
13412 +
13413 +#define strlen_user(str) strnlen_user(str, 32767)
13414 +
13415 +/*
13416 + * __clear_user()
13417 + *     Zero Userspace
13418 + */
13419 +static inline unsigned long __clear_user(__user void *to, unsigned long n)
13420 +{
13421 +       memset(to, 0, n);
13422 +       return 0;
13423 +}
13424 +
13425 +/*
13426 + * clear_user()
13427 + *     Zero user space (check for valid addresses)
13428 + */
13429 +static inline unsigned long clear_user(__user void *to, unsigned long n)
13430 +{
13431 +       if (!access_ok(VERIFY_WRITE, to, n)) {
13432 +               return -EFAULT;
13433 +       }
13434 +       return __clear_user(to, n);
13435 +}
13436 +
13437 +#endif /* _ASM_UBICOM32_UACCESS_H */
13438 --- /dev/null
13439 +++ b/arch/ubicom32/include/asm/ubi32-cs4384.h
13440 @@ -0,0 +1,53 @@
13441 +/*
13442 + * arch/ubicom32/include/asm/ubi32-cs4384.h
13443 + *   Ubicom32 architecture CS4384 driver platform data definitions.
13444 + *
13445 + * (C) Copyright 2009, Ubicom, Inc.
13446 + *
13447 + * This file is part of the Ubicom32 Linux Kernel Port.
13448 + *
13449 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13450 + * it and/or modify it under the terms of the GNU General Public License
13451 + * as published by the Free Software Foundation, either version 2 of the
13452 + * License, or (at your option) any later version.
13453 + *
13454 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13455 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13456 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13457 + * the GNU General Public License for more details.
13458 + *
13459 + * You should have received a copy of the GNU General Public License
13460 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13461 + * see <http://www.gnu.org/licenses/>.
13462 + */
13463 +#ifndef _ASM_UBICOM32_UBI32_CS4384_H
13464 +#define _ASM_UBICOM32_UBI32_CS4384_H
13465 +
13466 +enum ubi32_cs4384_mclk_source {
13467 +       UBI32_CS4384_MCLK_PWM_0,
13468 +       UBI32_CS4384_MCLK_PWM_1,
13469 +       UBI32_CS4384_MCLK_PWM_2,
13470 +       UBI32_CS4384_MCLK_CLKDIV_1,
13471 +       UBI32_CS4384_MCLK_OTHER,
13472 +};
13473 +
13474 +struct ubi32_cs4384_mclk_entry {
13475 +       /*
13476 +        * Rate, in Hz, of this entry
13477 +        */
13478 +       int rate;
13479 +
13480 +       /*
13481 +        * The divider to program to get the rate
13482 +        */
13483 +       int div;
13484 +};
13485 +
13486 +struct ubi32_cs4384_platform_data {
13487 +       enum ubi32_cs4384_mclk_source   mclk_src;
13488 +
13489 +       int                             n_mclk;
13490 +       struct ubi32_cs4384_mclk_entry  *mclk_entries;
13491 +};
13492 +#endif /* _ASM_UBICOM32_UBI32_CS4384_H */
13493 +
13494 --- /dev/null
13495 +++ b/arch/ubicom32/include/asm/ubi32-pcm.h
13496 @@ -0,0 +1,53 @@
13497 +/*
13498 + * arch/ubicom32/include/asm/ubi32-pcm.h
13499 + *   Ubicom32 architecture PCM driver platform data definitions.
13500 + *
13501 + * (C) Copyright 2009, Ubicom, Inc.
13502 + *
13503 + * This file is part of the Ubicom32 Linux Kernel Port.
13504 + *
13505 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13506 + * it and/or modify it under the terms of the GNU General Public License
13507 + * as published by the Free Software Foundation, either version 2 of the
13508 + * License, or (at your option) any later version.
13509 + *
13510 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13511 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13512 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13513 + * the GNU General Public License for more details.
13514 + *
13515 + * You should have received a copy of the GNU General Public License
13516 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13517 + * see <http://www.gnu.org/licenses/>.
13518 + */
13519 +#ifndef _ASM_UBICOM32_UBI32_PCM_H
13520 +#define _ASM_UBICOM32_UBI32_PCM_H
13521 +
13522 +/*
13523 + * This function is called when the sample rate has changed
13524 + */
13525 +typedef int (*ubi32_pcm_set_rate_fn_t)(void *appdata, int rate);
13526 +
13527 +struct ubi32pcm_platform_data {
13528 +       /*
13529 +        * Name of the audiotio node
13530 +        */
13531 +       const char              *node_name;
13532 +
13533 +       /*
13534 +        * Application specific data provided when calling functions
13535 +        */
13536 +       void                    *appdata;
13537 +
13538 +       /*
13539 +        * Functions called when various things happen
13540 +        */
13541 +       ubi32_pcm_set_rate_fn_t set_rate;
13542 +
13543 +       /*
13544 +        * Pointer to optional upper layer data (i.e. DAC config, etc)
13545 +        */
13546 +       void                    *priv_data;
13547 +};
13548 +#endif /* _ASM_UBICOM32_UBI32_PCM_H */
13549 +
13550 --- /dev/null
13551 +++ b/arch/ubicom32/include/asm/ubicom32bl.h
13552 @@ -0,0 +1,84 @@
13553 +/*
13554 + * arch/ubicom32/include/asm/ubicom32bl.h
13555 + *   Ubicom32 architecture backlight driver platform data definitions.
13556 + *
13557 + * (C) Copyright 2009, Ubicom, Inc.
13558 + *
13559 + * This file is part of the Ubicom32 Linux Kernel Port.
13560 + *
13561 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13562 + * it and/or modify it under the terms of the GNU General Public License
13563 + * as published by the Free Software Foundation, either version 2 of the
13564 + * License, or (at your option) any later version.
13565 + *
13566 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13567 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13568 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13569 + * the GNU General Public License for more details.
13570 + *
13571 + * You should have received a copy of the GNU General Public License
13572 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13573 + * see <http://www.gnu.org/licenses/>.
13574 + *
13575 + * Ubicom32 implementation derived from (with many thanks):
13576 + *   arch/m68knommu
13577 + *   arch/blackfin
13578 + *   arch/parisc
13579 + */
13580 +#ifndef _ASM_UBICOM32_UBICOM32_BL_H
13581 +#define _ASM_UBICOM32_UBICOM32_BL_H
13582 +
13583 +/*
13584 + * Different backlight control mechanisms
13585 + */
13586 +enum ubicom32bl_pwm_types {
13587 +       /*
13588 +        * PWM controlled backlight
13589 +        */
13590 +       UBICOM32BL_TYPE_PWM,
13591 +
13592 +       /*
13593 +        * HRT based PWM backlight
13594 +        */
13595 +       UBICOM32BL_TYPE_PWM_HRT,
13596 +
13597 +       /*
13598 +        * No dimming, just on or off
13599 +        */
13600 +       UBICOM32BL_TYPE_BINARY,
13601 +};
13602 +
13603 +struct ubicom32bl_platform_data {
13604 +       /*
13605 +        * Default intensity of the backlight 0-255
13606 +        */
13607 +       u8_t                            default_intensity;
13608 +
13609 +       /*
13610 +        * TRUE if the backlight sense is active low. (inverted)
13611 +        * FALSE if the backlight sense is active high.
13612 +        */
13613 +       bool                            invert;
13614 +
13615 +       /*
13616 +        * Type of the backlight
13617 +        */
13618 +       enum ubicom32bl_pwm_types       type;
13619 +
13620 +       /*
13621 +        * GPIO of the backlight if UBICOM32BL_TYPE_PWM_HRT, UBICOM32BL_TYPE_BINARY
13622 +        */
13623 +       unsigned                        gpio;
13624 +
13625 +       /*
13626 +        * PWM channel and parameters of the backlight if UBICOM32BL_TYPE_PWM
13627 +        *      pre_scaler: sets the rate at which the PWM timer is clocked. (clk_core / 2^pre_scaler)
13628 +        *      period: sets the period of the timer in timer cycles
13629 +        * The duty cycle will be directly proportional to the brightness setting.
13630 +        */
13631 +       u32_t                           pwm_channel;
13632 +       u8_t                            pwm_prescale;
13633 +       u16_t                           pwm_period;
13634 +};
13635 +
13636 +#endif /* _ASM_UBICOM32_UBICOM32_BL_H */
13637 --- /dev/null
13638 +++ b/arch/ubicom32/include/asm/ubicom32-common-asm.h
13639 @@ -0,0 +1,49 @@
13640 +/*
13641 + * arch/ubicom32/include/asm/ubicom32-common-asm.h
13642 + *   Ubicom32 atomic lock operations.
13643 + *
13644 + * (C) Copyright 2009, Ubicom, Inc.
13645 + *
13646 + * This file is part of the Ubicom32 Linux Kernel Port.
13647 + *
13648 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13649 + * it and/or modify it under the terms of the GNU General Public License
13650 + * as published by the Free Software Foundation, either version 2 of the
13651 + * License, or (at your option) any later version.
13652 + *
13653 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13654 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13655 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13656 + * the GNU General Public License for more details.
13657 + *
13658 + * You should have received a copy of the GNU General Public License
13659 + * along with the Ubicom32 Linux Kernel Port.  If not,
13660 + * see <http://www.gnu.org/licenses/>.
13661 + *
13662 + * Ubicom32 implementation derived from (with many thanks):
13663 + *   arch/m68knommu
13664 + *   arch/blackfin
13665 + *   arch/parisc
13666 + */
13667 +
13668 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13669 +#define _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13670 +
13671 +/*
13672 + * atomic_lock_acquire macro
13673 + *     Equivalent to __atomic_lock_acquire()
13674 + */
13675 +.macro atomic_lock_acquire
13676 +       bset scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13677 +       jmpne.f .-4
13678 +.endm
13679 +
13680 +/*
13681 + * atomic_lock_release macro
13682 + *     Equivalent to __atomic_lock_release()
13683 + */
13684 +.macro atomic_lock_release
13685 +       bclr scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13686 +.endm
13687 +
13688 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_ASM_H */
13689 --- /dev/null
13690 +++ b/arch/ubicom32/include/asm/ubicom32-common.h
13691 @@ -0,0 +1,124 @@
13692 +/*
13693 + * arch/ubicom32/include/asm/ubicom32-common.h
13694 + *   Ubicom32 atomic lock operations.
13695 + *
13696 + * (C) Copyright 2009, Ubicom, Inc.
13697 + *
13698 + * This file is part of the Ubicom32 Linux Kernel Port.
13699 + *
13700 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13701 + * it and/or modify it under the terms of the GNU General Public License
13702 + * as published by the Free Software Foundation, either version 2 of the
13703 + * License, or (at your option) any later version.
13704 + *
13705 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13706 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13707 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13708 + * the GNU General Public License for more details.
13709 + *
13710 + * You should have received a copy of the GNU General Public License
13711 + * along with the Ubicom32 Linux Kernel Port.  If not,
13712 + * see <http://www.gnu.org/licenses/>.
13713 + *
13714 + * Ubicom32 implementation derived from (with many thanks):
13715 + *   arch/m68knommu
13716 + *   arch/blackfin
13717 + *   arch/parisc
13718 + */
13719 +
13720 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_H
13721 +#define _ASM_UBICOM32_UBICOM32_COMMON_H
13722 +
13723 +#define S(arg) #arg
13724 +#define D(arg) S(arg)
13725 +/*
13726 + * scratchpad1 is owned by the LDSR.  
13727 + * 
13728 + * The upper bits provide 16 global spinlocks.  Acquiring one of these
13729 + * global spinlocks synchornizes across multiple threads and prevents 
13730 + * the LDSR from delivering any interrupts while the lock is held.
13731 + * Use these locks only when absolutely required.
13732 + *
13733 + * The lower 16 bits of scratchpad1 are used as per thread interrupt
13734 + * enable/disable bits.  These bits will prevent a thread from receiving
13735 + * any interrupts.
13736 + *
13737 + * Bit Usage:
13738 + * - MT_EN_LOCK_BIT   - Protects writes to MT_EN, so code can read current value
13739 + *                     then write a new value atomically (profiler for example)
13740 + * - ATOMIC_LOCK_BIT - Used to provide general purpose atomic handling.
13741 + * - LDSR_LOCK_BIT   - Used by the LDSR exclusively to provide protection.
13742 + * - LSB 16 bits     - Used by the LDSR to represent thread enable/disable bits.
13743 + */
13744 +#define MT_EN_LOCK_BIT 31
13745 +#define ATOMIC_LOCK_BIT 30
13746 +#define LDSR_LOCK_BIT   29
13747 +#define PCI_LOCK_BIT   28
13748 +
13749 +#if !defined(__ASSEMBLY__)
13750 +
13751 +#define UBICOM32_TRYLOCK(bit) \
13752 +       asm volatile (                                                \
13753 +       "       move.4 %0, #0                                   \n\t" \
13754 +       "       bset scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13755 +       "       jmpne.f 1f                                      \n\t" \
13756 +       "       move.4 %0, #1                                   \n\t" \
13757 +       "1:                                                     \n\t" \
13758 +               : "=r" (ret)                                          \
13759 +               :                                                     \
13760 +               : "cc", "memory"                                      \
13761 +       );                                                            \
13762 +
13763 +#define UBICOM32_UNLOCK(bit) \
13764 +       asm volatile (                                                \
13765 +       "       bclr scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13766 +               :                                                     \
13767 +               :                                                     \
13768 +               : "cc", "memory"                                      \
13769 +       );                                                            \
13770 +
13771 +#define UBICOM32_LOCK(bit) \
13772 +       asm volatile (                                                \
13773 +       "1:     bset scratchpad1, scratchpad1, #"D(bit)"        \n\t" \
13774 +       "       jmpne.f 1b                                      \n\t" \
13775 +               :                                                     \
13776 +               :                                                     \
13777 +               : "cc", "memory"                                      \
13778 +       );                                                            \
13779 +
13780 +/*
13781 + * __atomic_lock_trylock()
13782 + *     Attempt to acquire the lock, return TRUE if acquired.
13783 + */
13784 +static inline int __atomic_lock_trylock(void)
13785 +{
13786 +       int ret;
13787 +       UBICOM32_TRYLOCK(ATOMIC_LOCK_BIT);
13788 +       return ret;
13789 +}
13790 +
13791 +/*
13792 + * __atomic_lock_release()
13793 + *     Release the global atomic lock.
13794 + *
13795 + * Note: no one is suspended waiting since this lock is a spinning lock.
13796 + */
13797 +static inline void __atomic_lock_release(void)
13798 +{
13799 +       UBICOM32_UNLOCK(ATOMIC_LOCK_BIT);
13800 +}
13801 +
13802 +/*
13803 + * __atomic_lock_acquire()
13804 + *     Acquire the global atomic lock, spin if not available.
13805 + */
13806 +static inline void __atomic_lock_acquire(void)
13807 +{
13808 +       UBICOM32_LOCK(ATOMIC_LOCK_BIT);
13809 +}
13810 +#else /* __ASSEMBLY__ */
13811 +
13812 +#include <asm/ubicom32-common-asm.h>
13813 +
13814 +#endif /* __ASSEMBLY__ */
13815 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_H */
13816 --- /dev/null
13817 +++ b/arch/ubicom32/include/asm/ubicom32fb.h
13818 @@ -0,0 +1,56 @@
13819 +/*
13820 + * arch/ubicom32/include/asm/ubicom32fb.h
13821 + *   Ubicom32 architecture video frame buffer definitions.
13822 + *
13823 + * (C) Copyright 2009, Ubicom, Inc.
13824 + *
13825 + * This file is part of the Ubicom32 Linux Kernel Port.
13826 + *
13827 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13828 + * it and/or modify it under the terms of the GNU General Public License
13829 + * as published by the Free Software Foundation, either version 2 of the
13830 + * License, or (at your option) any later version.
13831 + *
13832 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13833 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13834 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13835 + * the GNU General Public License for more details.
13836 + *
13837 + * You should have received a copy of the GNU General Public License
13838 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13839 + * see <http://www.gnu.org/licenses/>.
13840 + */
13841 +#ifndef _ASM_UBICOM32_UBICOM32FB_H
13842 +#define _ASM_UBICOM32_UBICOM32FB_H
13843 +
13844 +#include <linux/ioctl.h>
13845 +
13846 +/* 
13847 + * Set next frame
13848 + */
13849 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME                _IOW('r',  1, void *) 
13850 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC   _IOW('r',  2, void *) 
13851 +
13852 +/*
13853 + * Set Mode
13854 + */
13855 +#define UBICOM32FB_IOCTL_SET_MODE              _IOW('r',  3, void *) 
13856 +struct ubicom32fb_mode {
13857 +       unsigned long   width;
13858 +       unsigned long   height;
13859 +       unsigned long   flags;
13860 +       void            *next_frame;
13861 +};
13862 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER  (1 << 8)
13863 +
13864 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER (1 << 7)
13865 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV             (1 << 6)
13866 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB            (1 << 5)
13867 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255   (1 << 4)
13868 +
13869 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255    (1 << 3)
13870 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1                (1 << 2)
13871 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1                (1 << 1)
13872 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE    (1 << 0)
13873 +
13874 +#endif /* _ASM_UBICOM32_UBICOM32FB_H */
13875 --- /dev/null
13876 +++ b/arch/ubicom32/include/asm/ubicom32hid.h
13877 @@ -0,0 +1,133 @@
13878 +/*
13879 + * arch/ubicom32/include/asm/ubicom32hid.h
13880 + *   Ubicom32 architecture HID driver platform data definitions.
13881 + *
13882 + * (C) Copyright 2009, Ubicom, Inc.
13883 + *
13884 + * This file is part of the Ubicom32 Linux Kernel Port.
13885 + *
13886 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13887 + * it and/or modify it under the terms of the GNU General Public License
13888 + * as published by the Free Software Foundation, either version 2 of the
13889 + * License, or (at your option) any later version.
13890 + *
13891 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
13892 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13893 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13894 + * the GNU General Public License for more details.
13895 + *
13896 + * You should have received a copy of the GNU General Public License
13897 + * along with the Ubicom32 Linux Kernel Port.  If not, 
13898 + * see <http://www.gnu.org/licenses/>.
13899 + *
13900 + * Ubicom32 implementation derived from (with many thanks):
13901 + *   arch/m68knommu
13902 + *   arch/blackfin
13903 + *   arch/parisc
13904 + */
13905 +#ifndef _ASM_UBICOM32_UBICOM32_HID_H
13906 +#define _ASM_UBICOM32_UBICOM32_HID_H
13907 +
13908 +enum ubicom32hid_bl_types {
13909 +       /*
13910 +        * On or off, using command SET_BL_EN, PB4
13911 +        */
13912 +       UBICOM32HID_BL_TYPE_BINARY,
13913 +
13914 +       /*
13915 +        * Dimmable, using command SET_PWM, PB3
13916 +        */
13917 +       UBICOM32HID_BL_TYPE_PWM,
13918 +};
13919 +
13920 +/*
13921 + * IR code mapping to event code.
13922 + *     If there are no button mappings and no ir mappings 
13923 + *     then no input driver will be registered.
13924 + */
13925 +struct ubicom32hid_ir {
13926 +       /*
13927 +        * Input event code (KEY_*, SW_*, etc)
13928 +        */
13929 +       int             code;
13930 +
13931 +       /*
13932 +        * Input event type (EV_KEY, EV_SW, etc)
13933 +        */
13934 +       int             type;
13935 +
13936 +       /*
13937 +        * The IR code of this button.
13938 +        */
13939 +       uint32_t        ir_code;
13940 +};
13941 +
13942 +/*
13943 + * Button mapping to event code.
13944 + *     If there are no button mappings and no ir mappings 
13945 + *     then no input driver will be registered.
13946 + */
13947 +struct ubicom32hid_button {
13948 +       /*
13949 +        * Input event code (KEY_*, SW_*, etc)
13950 +        */
13951 +       int             code;
13952 +
13953 +       /*
13954 +        * Input event type (EV_KEY, EV_SW, etc)
13955 +        */
13956 +       int             type;
13957 +
13958 +       /*
13959 +        * Bit number of this button.
13960 +        */
13961 +       uint8_t         bit;
13962 +};
13963 +
13964 +struct ubicom32hid_platform_data {
13965 +       /*
13966 +        * Default intensity of the backlight 0-255
13967 +        */
13968 +       u8_t                            default_intensity;
13969 +
13970 +       /*
13971 +        * GPIO number of the reset line and its polarity.
13972 +        */
13973 +       unsigned                        gpio_reset;
13974 +       int                             gpio_reset_polarity;
13975 +
13976 +       /*
13977 +        * TRUE if the backlight sense is active low. (inverted)
13978 +        * FALSE if the backlight sense is active high.
13979 +        */
13980 +       bool                            invert;
13981 +
13982 +       /*
13983 +        * Type of the backlight we are controlling
13984 +        */
13985 +       enum ubicom32hid_bl_types       type;
13986 +
13987 +       /*
13988 +        * Optional polling rate for input, in ms, defaults to 100ms
13989 +        */
13990 +       int                             poll_interval;
13991 +       
13992 +       /*
13993 +        * Optional name to register as input device
13994 +        */
13995 +       const char                      *input_name;
13996 +
13997 +       /*
13998 +        * Button mapping array
13999 +        */
14000 +       const struct ubicom32hid_button *buttons;
14001 +       int                             nbuttons;
14002 +
14003 +       /*
14004 +        * IR mapping array
14005 +        */
14006 +       const struct ubicom32hid_ir     *ircodes;
14007 +       int                             nircodes;
14008 +};
14009 +
14010 +#endif /* _ASM_UBICOM32_UBICOM32_HID_H */
14011 --- /dev/null
14012 +++ b/arch/ubicom32/include/asm/ubicom32input.h
14013 @@ -0,0 +1,76 @@
14014 +/*
14015 + * arch/ubicom32/include/asm/ubicom32input.h
14016 + *   Ubicom32 Input driver, based on gpio-keys
14017 + *
14018 + * (C) Copyright 2009, Ubicom, Inc.
14019 + *
14020 + * This file is part of the Ubicom32 Linux Kernel Port.
14021 + *
14022 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14023 + * it and/or modify it under the terms of the GNU General Public License
14024 + * as published by the Free Software Foundation, either version 2 of the
14025 + * License, or (at your option) any later version.
14026 + *
14027 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14028 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14029 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14030 + * the GNU General Public License for more details.
14031 + *
14032 + * You should have received a copy of the GNU General Public License
14033 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14034 + * see <http://www.gnu.org/licenses/>.
14035 + *
14036 + * Ubicom32 implementation derived from (with many thanks):
14037 + *   arch/m68knommu
14038 + *   arch/blackfin
14039 + *   arch/parisc
14040 + *
14041 + * TODO: add groups for inputs which can be sampled together
14042 + */
14043 +
14044 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_H
14045 +#define _ASM_UBICOM32_UBICOM32_INPUT_H
14046 +
14047 +struct ubicom32input_button {
14048 +       /*
14049 +        * Input event code (KEY_*, SW_*, etc)
14050 +        */
14051 +       int             code;
14052 +
14053 +       /*
14054 +        * Input event type (EV_KEY, EV_SW, etc)
14055 +        */
14056 +       int             type;
14057 +
14058 +       /*
14059 +        * GPIO to poll
14060 +        */
14061 +       int             gpio;
14062 +
14063 +       /*
14064 +        * 1 for active low, 0 for active high
14065 +        */
14066 +       int             active_low;
14067 +
14068 +       /*
14069 +        * Description, used for reserving GPIOs
14070 +        */
14071 +       const char      *desc;
14072 +};
14073 +
14074 +struct ubicom32input_platform_data {
14075 +       struct ubicom32input_button     *buttons;
14076 +       int                             nbuttons;
14077 +
14078 +       /*
14079 +        * Optional poll interval, in ms, defaults to 50ms
14080 +        */
14081 +       int                             poll_interval;
14082 +
14083 +       /*
14084 +        * Option Name of this driver
14085 +        */
14086 +       const char                      *name;
14087 +};
14088 +
14089 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_H */
14090 --- /dev/null
14091 +++ b/arch/ubicom32/include/asm/ubicom32input_i2c.h
14092 @@ -0,0 +1,71 @@
14093 +/*
14094 + * arch/ubicom32/include/asm/ubicom32input_i2c.h
14095 + *   Ubicom32 architecture Input driver over I2C platform data definitions.
14096 + *
14097 + * (C) Copyright 2009, Ubicom, Inc.
14098 + *
14099 + * This file is part of the Ubicom32 Linux Kernel Port.
14100 + *
14101 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14102 + * it and/or modify it under the terms of the GNU General Public License
14103 + * as published by the Free Software Foundation, either version 2 of the
14104 + * License, or (at your option) any later version.
14105 + *
14106 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14107 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14108 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14109 + * the GNU General Public License for more details.
14110 + *
14111 + * You should have received a copy of the GNU General Public License
14112 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14113 + * see <http://www.gnu.org/licenses/>.
14114 + *
14115 + * Ubicom32 implementation derived from (with many thanks):
14116 + *   arch/m68knommu
14117 + *   arch/blackfin
14118 + *   arch/parisc
14119 + *
14120 + * TODO: add groups for inputs which can be sampled together
14121 + */
14122 +
14123 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
14124 +#define _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
14125 +
14126 +struct ubicom32input_i2c_button {
14127 +       /*
14128 +        * Input event code (KEY_*, SW_*, etc)
14129 +        */
14130 +       int             code;
14131 +
14132 +       /*
14133 +        * Input event type (EV_KEY, EV_SW, etc)
14134 +        */
14135 +       int             type;
14136 +
14137 +       /*
14138 +        * Bit number of this button. (0 - ngpio)
14139 +        */
14140 +       int             bit;
14141 +
14142 +       /*
14143 +        * 1 for active low, 0 for active high
14144 +        */
14145 +       int             active_low;
14146 +};
14147 +
14148 +struct ubicom32input_i2c_platform_data {
14149 +       struct ubicom32input_i2c_button *buttons;
14150 +       int                             nbuttons;
14151 +
14152 +       /*
14153 +        * Optional poll interval, in ms, defaults to 100ms
14154 +        */
14155 +       int                             poll_interval;
14156 +
14157 +       /*
14158 +        * Option Name of this driver
14159 +        */
14160 +       const char                      *name;
14161 +};
14162 +
14163 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_I2C_H */
14164 --- /dev/null
14165 +++ b/arch/ubicom32/include/asm/ubicom32lcd.h
14166 @@ -0,0 +1,39 @@
14167 +/*
14168 + * arch/ubicom32/include/asm/ubicom32lcd.h
14169 + *   Ubicom32 architecture LCD driver platform data definitions.
14170 + *
14171 + * (C) Copyright 2009, Ubicom, Inc.
14172 + *
14173 + * This file is part of the Ubicom32 Linux Kernel Port.
14174 + *
14175 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14176 + * it and/or modify it under the terms of the GNU General Public License
14177 + * as published by the Free Software Foundation, either version 2 of the
14178 + * License, or (at your option) any later version.
14179 + *
14180 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14181 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14182 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14183 + * the GNU General Public License for more details.
14184 + *
14185 + * You should have received a copy of the GNU General Public License
14186 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14187 + * see <http://www.gnu.org/licenses/>.
14188 + *
14189 + * Ubicom32 implementation derived from (with many thanks):
14190 + *   arch/m68knommu
14191 + *   arch/blackfin
14192 + *   arch/parisc
14193 + */
14194 +#ifndef _ASM_UBICOM32_UBICOM32_LCD_H
14195 +#define _ASM_UBICOM32_UBICOM32_LCD_H
14196 +
14197 +struct ubicom32lcd_platform_data {
14198 +       /*
14199 +        * GPIO and polarity for VGH signal.  A FALSE polarity is active low, TRUE is active high.
14200 +        */
14201 +       int             vgh_gpio;
14202 +       bool            vgh_polarity;
14203 +};
14204 +
14205 +#endif /* _ASM_UBICOM32_UBICOM32_LCD_H */
14206 --- /dev/null
14207 +++ b/arch/ubicom32/include/asm/ubicom32ring.h
14208 @@ -0,0 +1,103 @@
14209 +/*
14210 + * arch/ubicom32/include/asm/ubicom32ring.h
14211 + * Userspace I/O platform driver for Ubicom32 ring buffers
14212 + *
14213 + * (C) Copyright 2009, Ubicom, Inc.
14214 + *
14215 + * This file is part of the Ubicom32 Linux Kernel Port.
14216 + *
14217 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14218 + * it and/or modify it under the terms of the GNU General Public License
14219 + * as published by the Free Software Foundation, either version 2 of the
14220 + * License, or (at your option) any later version.
14221 + *
14222 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14223 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14224 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14225 + * the GNU General Public License for more details.
14226 + *
14227 + * You should have received a copy of the GNU General Public License
14228 + * along with the Ubicom32 Linux Kernel Port.  If not,
14229 + * see <http://www.gnu.org/licenses/>.
14230 + */
14231 +
14232 +#ifndef _ASM_UBICOM32_UBICOM32RING_H
14233 +#define _ASM_UBICOM32_UBICOM32RING_H
14234 +
14235 +#define UIO_UBICOM32RING_REG_VERSION   2
14236 +
14237 +struct uio_ubicom32ring_desc {
14238 +       volatile unsigned int           head;
14239 +       volatile unsigned int           tail;
14240 +       unsigned int                    entries;
14241 +       volatile unsigned int           ring[0];
14242 +};
14243 +
14244 +struct uio_ubicom32ring_regs {
14245 +       unsigned int                    version;
14246 +
14247 +       /*
14248 +        * Magic type used to identify the ring set.  Each driver will
14249 +        * have a different magic value.
14250 +        */
14251 +       unsigned int                    magic;
14252 +
14253 +       /*
14254 +        * Registers defined by the driver
14255 +        */
14256 +       unsigned int                    regs_size;
14257 +       void                            *regs;
14258 +
14259 +       /*
14260 +        * The locations of the rings
14261 +        *
14262 +        * DO NOT ADD ANYTHING BELOW THIS LINE
14263 +        */
14264 +       unsigned int                    num_rings;
14265 +       struct uio_ubicom32ring_desc    *rings[0];
14266 +};
14267 +
14268 +/*
14269 + * ringtio_ring_flush
14270 + */
14271 +static inline void ringtio_ring_flush(struct uio_ubicom32ring_desc *rd)
14272 +{
14273 +       rd->head = rd->tail = 0;
14274 +}
14275 +
14276 +/*
14277 + * ringtio_ring_get
14278 + */
14279 +static inline int ringtio_ring_get(struct uio_ubicom32ring_desc *rd, void **val)
14280 +{
14281 +       if (rd->head == rd->tail) {
14282 +               return 0;
14283 +       }
14284 +
14285 +       *val = (void *)rd->ring[rd->head++];
14286 +       if (rd->head == rd->entries) {
14287 +               rd->head = 0;
14288 +       }
14289 +       return 1;
14290 +}
14291 +
14292 +/*
14293 + * ringtio_ring_put
14294 + */
14295 +static inline int ringtio_ring_put(struct uio_ubicom32ring_desc *rd, void *val)
14296 +{
14297 +       unsigned int newtail = rd->tail + 1;
14298 +       if (newtail == rd->entries) {
14299 +               newtail = 0;
14300 +       }
14301 +
14302 +       if (newtail == rd->head) {
14303 +               return 0;
14304 +       }
14305 +
14306 +       rd->ring[rd->tail] = (unsigned int)val;
14307 +       rd->tail = newtail;
14308 +       return 1;
14309 +}
14310 +
14311 +#endif /* _ASM_UBICOM32_UBICOM32RING_H */
14312 --- /dev/null
14313 +++ b/arch/ubicom32/include/asm/ubicom32sd.h
14314 @@ -0,0 +1,45 @@
14315 +/*
14316 + * arch/ubicom32/include/asm/ubicom32sd.h
14317 + *   Ubicom32SD public include file
14318 + *
14319 + * (C) Copyright 2009, Ubicom, Inc.
14320 + *
14321 + * This file is part of the Ubicom32 Linux Kernel Port.
14322 + *
14323 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14324 + * it and/or modify it under the terms of the GNU General Public License
14325 + * as published by the Free Software Foundation, either version 2 of the
14326 + * License, or (at your option) any later version.
14327 + *
14328 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14329 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14330 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14331 + * the GNU General Public License for more details.
14332 + *
14333 + * You should have received a copy of the GNU General Public License
14334 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14335 + * see <http://www.gnu.org/licenses/>.
14336 + */
14337 +#ifndef _ASM_UBICOM32_UBICOM32_SD_H
14338 +#define _ASM_UBICOM32_UBICOM32_SD_H
14339 +
14340 +struct ubicom32sd_card {
14341 +       /*
14342 +        * GPIOs of PWR, WP and CD lines.
14343 +        * Polarity is 1 for active high and 0 for active low
14344 +        */
14345 +       int                             pin_pwr;
14346 +       bool                            pwr_polarity;
14347 +       int                             pin_wp;
14348 +       bool                            wp_polarity;
14349 +       int                             pin_cd;
14350 +       bool                            cd_polarity;
14351 +};
14352 +
14353 +struct ubicom32sd_platform_data {
14354 +       int                     ncards;
14355 +
14356 +       struct ubicom32sd_card  *cards;
14357 +};
14358 +
14359 +#endif /* _ASM_UBICOM32_UBICOM32_SD_H */
14360 --- /dev/null
14361 +++ b/arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14362 @@ -0,0 +1,62 @@
14363 +/*
14364 + * arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14365 + *   Platform driver data definitions for GPIO based SPI driver.
14366 + *
14367 + * (C) Copyright 2009, Ubicom, Inc.
14368 + *
14369 + * This file is part of the Ubicom32 Linux Kernel Port.
14370 + *
14371 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14372 + * it and/or modify it under the terms of the GNU General Public License
14373 + * as published by the Free Software Foundation, either version 2 of the
14374 + * License, or (at your option) any later version.
14375 + *
14376 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14377 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14378 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14379 + * the GNU General Public License for more details.
14380 + *
14381 + * You should have received a copy of the GNU General Public License
14382 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14383 + * see <http://www.gnu.org/licenses/>.
14384 + *
14385 + * Ubicom32 implementation derived from (with many thanks):
14386 + *   arch/m68knommu
14387 + *   arch/blackfin
14388 + *   arch/parisc
14389 + */
14390 +#ifndef _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14391 +#define _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14392 +
14393 +struct ubicom32_spi_gpio_platform_data {
14394 +       /*
14395 +        * GPIO to use for MOSI, MISO, CLK
14396 +        */
14397 +       int     pin_mosi;
14398 +       int     pin_miso;
14399 +       int     pin_clk;
14400 +
14401 +       /*
14402 +        * Default state of CLK line
14403 +        */
14404 +       int     clk_default;
14405 +
14406 +       /*
14407 +        * Number of chip selects on this bus
14408 +        */
14409 +       int     num_chipselect;
14410 +
14411 +       /*
14412 +        * The bus number of this chip
14413 +        */
14414 +       int     bus_num;
14415 +};
14416 +
14417 +struct ubicom32_spi_gpio_controller_data {
14418 +       /*
14419 +        * GPIO to use for chip select
14420 +        */
14421 +       int     pin_cs;
14422 +};
14423 +
14424 +#endif /* _ASM_UBICOM32_UBICOM32_SPI_GPIO_H */
14425 --- /dev/null
14426 +++ b/arch/ubicom32/include/asm/ubicom32suart.h
14427 @@ -0,0 +1,36 @@
14428 +/*
14429 + * arch/ubicom32/include/asm/ubicom32suart.h
14430 + *   <TODO: Replace with short file description>
14431 + *
14432 + * (C) Copyright 2009, Ubicom, Inc.
14433 + *
14434 + * This file is part of the Ubicom32 Linux Kernel Port.
14435 + *
14436 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14437 + * it and/or modify it under the terms of the GNU General Public License
14438 + * as published by the Free Software Foundation, either version 2 of the
14439 + * License, or (at your option) any later version.
14440 + *
14441 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14442 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14443 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14444 + * the GNU General Public License for more details.
14445 + *
14446 + * You should have received a copy of the GNU General Public License
14447 + * along with the Ubicom32 Linux Kernel Port.  If not,
14448 + * see <http://www.gnu.org/licenses/>.
14449 + *
14450 + * Ubicom32 implementation derived from (with many thanks):
14451 + *   arch/m68knommu
14452 + *   arch/blackfin
14453 + *   arch/parisc
14454 + */
14455 +#ifndef _ASM_UBICOM32_UBICOM32_SUART_H
14456 +#define _ASM_UBICOM32_UBICOM32_SUART_H
14457 +
14458 +/*
14459 + * Platform resource id for serdes uart clock parameter
14460 + */
14461 +#define UBICOM32_SUART_IORESOURCE_CLOCK                (1)
14462 +
14463 +#endif /* _ASM_UBICOM32_UBICOM32_SUART_H */
14464 --- /dev/null
14465 +++ b/arch/ubicom32/include/asm/ubicom32-tio.h
14466 @@ -0,0 +1,42 @@
14467 +/*
14468 + * arch/ubicom32/include/asm/ubicom32-tio.h
14469 + *   Threaded I/O interface definitions.
14470 + *
14471 + * (C) Copyright 2009, Ubicom, Inc.
14472 + *
14473 + * This file is part of the Ubicom32 Linux Kernel Port.
14474 + *
14475 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14476 + * it and/or modify it under the terms of the GNU General Public License
14477 + * as published by the Free Software Foundation, either version 2 of the
14478 + * License, or (at your option) any later version.
14479 + *
14480 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14481 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14482 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14483 + * the GNU General Public License for more details.
14484 + *
14485 + * You should have received a copy of the GNU General Public License
14486 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14487 + * see <http://www.gnu.org/licenses/>.
14488 + *
14489 + * Ubicom32 implementation derived from (with many thanks):
14490 + *   arch/m68knommu
14491 + *   arch/blackfin
14492 + *   arch/parisc
14493 + */
14494 +#ifndef _ASM_UBICOM32_UBICOM32_TIO_H
14495 +#define _ASM_UBICOM32_UBICOM32_TIO_H
14496 +
14497 +extern u8_t usb_tio_read_u16(u32_t address, u16_t *data);
14498 +extern u8_t usb_tio_read_u8(u32_t address, u8_t *data);
14499 +
14500 +extern u8_t usb_tio_write_u16(u32_t address, u16_t data);
14501 +extern u8_t usb_tio_write_u8(u32_t address, u8_t data);
14502 +
14503 +extern u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes);
14504 +extern u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes);
14505 +extern u8_t usb_tio_write_fifo_sync(u32_t address, u32_t buffer, u32_t bytes);
14506 +extern void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx);
14507 +
14508 +#endif /* _ASM_UBICOM32_UBICOM32_TIO_H */
14509 --- /dev/null
14510 +++ b/arch/ubicom32/include/asm/ucontext.h
14511 @@ -0,0 +1,39 @@
14512 +/*
14513 + * arch/ubicom32/include/asm/ucontext.h
14514 + *   Definition of ucontext structure for Ubicom32 architecture.
14515 + *
14516 + * (C) Copyright 2009, Ubicom, Inc.
14517 + *
14518 + * This file is part of the Ubicom32 Linux Kernel Port.
14519 + *
14520 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14521 + * it and/or modify it under the terms of the GNU General Public License
14522 + * as published by the Free Software Foundation, either version 2 of the
14523 + * License, or (at your option) any later version.
14524 + *
14525 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14526 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14527 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14528 + * the GNU General Public License for more details.
14529 + *
14530 + * You should have received a copy of the GNU General Public License
14531 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14532 + * see <http://www.gnu.org/licenses/>.
14533 + *
14534 + * Ubicom32 implementation derived from (with many thanks):
14535 + *   arch/m68knommu
14536 + *   arch/blackfin
14537 + *   arch/parisc
14538 + */
14539 +#ifndef _ASM_UBICOM32_UCONTEXT_H
14540 +#define _ASM_UBICOM32_UCONTEXT_H
14541 +
14542 +struct ucontext {
14543 +       unsigned long     uc_flags;
14544 +       struct ucontext  *uc_link;
14545 +       stack_t           uc_stack;
14546 +       struct sigcontext         uc_mcontext;
14547 +       sigset_t          uc_sigmask;   /* mask last for extensibility */
14548 +};
14549 +
14550 +#endif /* _ASM_UBICOM32_UCONTEXT_H */
14551 --- /dev/null
14552 +++ b/arch/ubicom32/include/asm/unaligned.h
14553 @@ -0,0 +1,44 @@
14554 +/*
14555 + * arch/ubicom32/include/asm/unaligned.h
14556 + *   Ubicom32 architecture unaligned memory access definitions.
14557 + *
14558 + * (C) Copyright 2009, Ubicom, Inc.
14559 + *
14560 + * This file is part of the Ubicom32 Linux Kernel Port.
14561 + *
14562 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14563 + * it and/or modify it under the terms of the GNU General Public License
14564 + * as published by the Free Software Foundation, either version 2 of the
14565 + * License, or (at your option) any later version.
14566 + *
14567 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14568 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14569 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14570 + * the GNU General Public License for more details.
14571 + *
14572 + * You should have received a copy of the GNU General Public License
14573 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14574 + * see <http://www.gnu.org/licenses/>.
14575 + *
14576 + * Ubicom32 implementation derived from (with many thanks):
14577 + *   arch/m68knommu
14578 + *   arch/blackfin
14579 + *   arch/parisc
14580 + *
14581 + * TODO: This is a copy of arm unaligned handling that probably needs
14582 + * to be optimized for UBICOM32, but it works for now.
14583 + */
14584 +
14585 +#ifndef _ASM_UBICOM32_UNALIGNED_H
14586 +#define _ASM_UBICOM32_UNALIGNED_H
14587 +
14588 +#include <asm/types.h>
14589 +
14590 +#include <linux/unaligned/le_byteshift.h>
14591 +#include <linux/unaligned/be_byteshift.h>
14592 +#include <linux/unaligned/generic.h>
14593 +
14594 +#define get_unaligned  __get_unaligned_be
14595 +#define put_unaligned  __put_unaligned_be
14596 +
14597 +#endif /* _ASM_UBICOM32_UNALIGNED_H */
14598 --- /dev/null
14599 +++ b/arch/ubicom32/include/asm/unistd.h
14600 @@ -0,0 +1,400 @@
14601 +/*
14602 + * arch/ubicom32/include/asm/unistd.h
14603 + *   Ubicom32 architecture syscall definitions.
14604 + *
14605 + * (C) Copyright 2009, Ubicom, Inc.
14606 + *
14607 + * This file is part of the Ubicom32 Linux Kernel Port.
14608 + *
14609 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
14610 + * it and/or modify it under the terms of the GNU General Public License
14611 + * as published by the Free Software Foundation, either version 2 of the
14612 + * License, or (at your option) any later version.
14613 + *
14614 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
14615 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14616 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14617 + * the GNU General Public License for more details.
14618 + *
14619 + * You should have received a copy of the GNU General Public License
14620 + * along with the Ubicom32 Linux Kernel Port.  If not, 
14621 + * see <http://www.gnu.org/licenses/>.
14622 + *
14623 + * Ubicom32 implementation derived from (with many thanks):
14624 + *   arch/m68knommu
14625 + *   arch/blackfin
14626 + *   arch/parisc
14627 + */
14628 +#ifndef _ASM_UBICOM32_UNISTD_H
14629 +#define _ASM_UBICOM32_UNISTD_H
14630 +
14631 +/*
14632 + * This file contains the system call numbers.
14633 + */
14634 +
14635 +#define __NR_restart_syscall      0
14636 +#define __NR_exit                1
14637 +#define __NR_fork                2
14638 +#define __NR_read                3
14639 +#define __NR_write               4
14640 +#define __NR_open                5
14641 +#define __NR_close               6
14642 +#define __NR_waitpid             7
14643 +#define __NR_creat               8
14644 +#define __NR_link                9
14645 +#define __NR_unlink             10
14646 +#define __NR_execve             11
14647 +#define __NR_chdir              12
14648 +#define __NR_time               13
14649 +#define __NR_mknod              14
14650 +#define __NR_chmod              15
14651 +#define __NR_chown              16
14652 +#define __NR_break              17
14653 +#define __NR_oldstat            18
14654 +#define __NR_lseek              19
14655 +#define __NR_getpid             20
14656 +#define __NR_mount              21
14657 +#define __NR_umount             22
14658 +#define __NR_setuid             23
14659 +#define __NR_getuid             24
14660 +#define __NR_stime              25
14661 +#define __NR_ptrace             26
14662 +#define __NR_alarm              27
14663 +#define __NR_oldfstat           28
14664 +#define __NR_pause              29
14665 +#define __NR_utime              30
14666 +#define __NR_stty               31
14667 +#define __NR_gtty               32
14668 +#define __NR_access             33
14669 +#define __NR_nice               34
14670 +#define __NR_ftime              35
14671 +#define __NR_sync               36
14672 +#define __NR_kill               37
14673 +#define __NR_rename             38
14674 +#define __NR_mkdir              39
14675 +#define __NR_rmdir              40
14676 +#define __NR_dup                41
14677 +#define __NR_pipe               42
14678 +#define __NR_times              43
14679 +#define __NR_prof               44
14680 +#define __NR_brk                45
14681 +#define __NR_setgid             46
14682 +#define __NR_getgid             47
14683 +#define __NR_signal             48
14684 +#define __NR_geteuid            49
14685 +#define __NR_getegid            50
14686 +#define __NR_acct               51
14687 +#define __NR_umount2            52
14688 +#define __NR_lock               53
14689 +#define __NR_ioctl              54
14690 +#define __NR_fcntl              55
14691 +#define __NR_mpx                56
14692 +#define __NR_setpgid            57
14693 +#define __NR_ulimit             58
14694 +#define __NR_oldolduname        59
14695 +#define __NR_umask              60
14696 +#define __NR_chroot             61
14697 +#define __NR_ustat              62
14698 +#define __NR_dup2               63
14699 +#define __NR_getppid            64
14700 +#define __NR_getpgrp            65
14701 +#define __NR_setsid             66
14702 +#define __NR_sigaction          67
14703 +#define __NR_sgetmask           68
14704 +#define __NR_ssetmask           69
14705 +#define __NR_setreuid           70
14706 +#define __NR_setregid           71
14707 +#define __NR_sigsuspend                 72
14708 +#define __NR_sigpending                 73
14709 +#define __NR_sethostname        74
14710 +#define __NR_setrlimit          75
14711 +#define __NR_getrlimit          76
14712 +#define __NR_getrusage          77
14713 +#define __NR_gettimeofday       78
14714 +#define __NR_settimeofday       79
14715 +#define __NR_getgroups          80
14716 +#define __NR_setgroups          81
14717 +#define __NR_select             82
14718 +#define __NR_symlink            83
14719 +#define __NR_oldlstat           84
14720 +#define __NR_readlink           85
14721 +#define __NR_uselib             86
14722 +#define __NR_swapon             87
14723 +#define __NR_reboot             88
14724 +#define __NR_readdir            89
14725 +#define __NR_mmap               90
14726 +#define __NR_munmap             91
14727 +#define __NR_truncate           92
14728 +#define __NR_ftruncate          93
14729 +#define __NR_fchmod             94
14730 +#define __NR_fchown             95
14731 +#define __NR_getpriority        96
14732 +#define __NR_setpriority        97
14733 +#define __NR_profil             98
14734 +#define __NR_statfs             99
14735 +#define __NR_fstatfs           100
14736 +#define __NR_ioperm            101
14737 +#define __NR_socketcall                102
14738 +#define __NR_syslog            103
14739 +#define __NR_setitimer         104
14740 +#define __NR_getitimer         105
14741 +#define __NR_stat              106
14742 +#define __NR_lstat             107
14743 +#define __NR_fstat             108
14744 +#define __NR_olduname          109
14745 +#define __NR_iopl              /* 110 */ not supported
14746 +#define __NR_vhangup           111
14747 +#define __NR_idle              /* 112 */ Obsolete
14748 +#define __NR_vm86              /* 113 */ not supported
14749 +#define __NR_wait4             114
14750 +#define __NR_swapoff           115
14751 +#define __NR_sysinfo           116
14752 +#define __NR_ipc               117
14753 +#define __NR_fsync             118
14754 +#define __NR_sigreturn         119
14755 +#define __NR_clone             120
14756 +#define __NR_setdomainname     121
14757 +#define __NR_uname             122
14758 +#define __NR_cacheflush                123
14759 +#define __NR_adjtimex          124
14760 +#define __NR_mprotect          125
14761 +#define __NR_sigprocmask       126
14762 +#define __NR_create_module     127
14763 +#define __NR_init_module       128
14764 +#define __NR_delete_module     129
14765 +#define __NR_get_kernel_syms   130
14766 +#define __NR_quotactl          131
14767 +#define __NR_getpgid           132
14768 +#define __NR_fchdir            133
14769 +#define __NR_bdflush           134
14770 +#define __NR_sysfs             135
14771 +#define __NR_personality       136
14772 +#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
14773 +#define __NR_setfsuid          138
14774 +#define __NR_setfsgid          139
14775 +#define __NR__llseek           140
14776 +#define __NR_getdents          141
14777 +#define __NR__newselect                142
14778 +#define __NR_flock             143
14779 +#define __NR_msync             144
14780 +#define __NR_readv             145
14781 +#define __NR_writev            146
14782 +#define __NR_getsid            147
14783 +#define __NR_fdatasync         148
14784 +#define __NR__sysctl           149
14785 +#define __NR_mlock             150
14786 +#define __NR_munlock           151
14787 +#define __NR_mlockall          152
14788 +#define __NR_munlockall                153
14789 +#define __NR_sched_setparam            154
14790 +#define __NR_sched_getparam            155
14791 +#define __NR_sched_setscheduler                156
14792 +#define __NR_sched_getscheduler                157
14793 +#define __NR_sched_yield               158
14794 +#define __NR_sched_get_priority_max    159
14795 +#define __NR_sched_get_priority_min    160
14796 +#define __NR_sched_rr_get_interval     161
14797 +#define __NR_nanosleep         162
14798 +#define __NR_mremap            163
14799 +#define __NR_setresuid         164
14800 +#define __NR_getresuid         165
14801 +#define __NR_getpagesize       166
14802 +#define __NR_query_module      167
14803 +#define __NR_poll              168
14804 +#define __NR_nfsservctl                169
14805 +#define __NR_setresgid         170
14806 +#define __NR_getresgid         171
14807 +#define __NR_prctl             172
14808 +#define __NR_rt_sigreturn      173
14809 +#define __NR_rt_sigaction      174
14810 +#define __NR_rt_sigprocmask    175
14811 +#define __NR_rt_sigpending     176
14812 +#define __NR_rt_sigtimedwait   177
14813 +#define __NR_rt_sigqueueinfo   178
14814 +#define __NR_rt_sigsuspend     179
14815 +#define __NR_pread64           180
14816 +#define __NR_pwrite64          181
14817 +#define __NR_lchown            182
14818 +#define __NR_getcwd            183
14819 +#define __NR_capget            184
14820 +#define __NR_capset            185
14821 +#define __NR_sigaltstack       186
14822 +#define __NR_sendfile          187
14823 +#define __NR_getpmsg           188     /* some people actually want streams */
14824 +#define __NR_putpmsg           189     /* some people actually want streams */
14825 +#define __NR_vfork             190
14826 +#define __NR_ugetrlimit                191
14827 +#define __NR_mmap2             192
14828 +#define __NR_truncate64                193
14829 +#define __NR_ftruncate64       194
14830 +#define __NR_stat64            195
14831 +#define __NR_lstat64           196
14832 +#define __NR_fstat64           197
14833 +#define __NR_chown32           198
14834 +#define __NR_getuid32          199
14835 +#define __NR_getgid32          200
14836 +#define __NR_geteuid32         201
14837 +#define __NR_getegid32         202
14838 +#define __NR_setreuid32                203
14839 +#define __NR_setregid32                204
14840 +#define __NR_getgroups32       205
14841 +#define __NR_setgroups32       206
14842 +#define __NR_fchown32          207
14843 +#define __NR_setresuid32       208
14844 +#define __NR_getresuid32       209
14845 +#define __NR_setresgid32       210
14846 +#define __NR_getresgid32       211
14847 +#define __NR_lchown32          212
14848 +#define __NR_setuid32          213
14849 +#define __NR_setgid32          214
14850 +#define __NR_setfsuid32                215
14851 +#define __NR_setfsgid32                216
14852 +#define __NR_pivot_root                217
14853 +#define __NR_getdents64                220
14854 +#define __NR_gettid            221
14855 +#define __NR_tkill             222
14856 +#define __NR_setxattr          223
14857 +#define __NR_lsetxattr         224
14858 +#define __NR_fsetxattr         225
14859 +#define __NR_getxattr          226
14860 +#define __NR_lgetxattr         227
14861 +#define __NR_fgetxattr         228
14862 +#define __NR_listxattr         229
14863 +#define __NR_llistxattr                230
14864 +#define __NR_flistxattr                231
14865 +#define __NR_removexattr       232
14866 +#define __NR_lremovexattr      233
14867 +#define __NR_fremovexattr      234
14868 +#define __NR_futex             235
14869 +#define __NR_sendfile64                236
14870 +#define __NR_mincore           237
14871 +#define __NR_madvise           238
14872 +#define __NR_fcntl64           239
14873 +#define __NR_readahead         240
14874 +#define __NR_io_setup          241
14875 +#define __NR_io_destroy                242
14876 +#define __NR_io_getevents      243
14877 +#define __NR_io_submit         244
14878 +#define __NR_io_cancel         245
14879 +#define __NR_fadvise64         246
14880 +#define __NR_exit_group                247
14881 +#define __NR_lookup_dcookie    248
14882 +#define __NR_epoll_create      249
14883 +#define __NR_epoll_ctl         250
14884 +#define __NR_epoll_wait                251
14885 +#define __NR_remap_file_pages  252
14886 +#define __NR_set_tid_address   253
14887 +#define __NR_timer_create      254
14888 +#define __NR_timer_settime     255
14889 +#define __NR_timer_gettime     256
14890 +#define __NR_timer_getoverrun  257
14891 +#define __NR_timer_delete      258
14892 +#define __NR_clock_settime     259
14893 +#define __NR_clock_gettime     260
14894 +#define __NR_clock_getres      261
14895 +#define __NR_clock_nanosleep   262
14896 +#define __NR_statfs64          263
14897 +#define __NR_fstatfs64         264
14898 +#define __NR_tgkill            265
14899 +#define __NR_utimes            266
14900 +#define __NR_fadvise64_64      267
14901 +#define __NR_mbind             268
14902 +#define __NR_get_mempolicy     269
14903 +#define __NR_set_mempolicy     270
14904 +#define __NR_mq_open           271
14905 +#define __NR_mq_unlink         272
14906 +#define __NR_mq_timedsend      273
14907 +#define __NR_mq_timedreceive   274
14908 +#define __NR_mq_notify         275
14909 +#define __NR_mq_getsetattr     276
14910 +#define __NR_waitid            277
14911 +#define __NR_vserver           278
14912 +#define __NR_add_key           279
14913 +#define __NR_request_key       280
14914 +#define __NR_keyctl            281
14915 +#define __NR_ioprio_set                282
14916 +#define __NR_ioprio_get                283
14917 +#define __NR_inotify_init      284
14918 +#define __NR_inotify_add_watch 285
14919 +#define __NR_inotify_rm_watch  286
14920 +#define __NR_migrate_pages     287
14921 +#define __NR_openat            288
14922 +#define __NR_mkdirat           289
14923 +#define __NR_mknodat           290
14924 +#define __NR_fchownat          291
14925 +#define __NR_futimesat         292
14926 +#define __NR_fstatat64         293
14927 +#define __NR_unlinkat          294
14928 +#define __NR_renameat          295
14929 +#define __NR_linkat            296
14930 +#define __NR_symlinkat         297
14931 +#define __NR_readlinkat                298
14932 +#define __NR_fchmodat          299
14933 +#define __NR_faccessat         300
14934 +#define __NR_pselect6          301
14935 +#define __NR_ppoll             302
14936 +#define __NR_unshare           303
14937 +#define __NR_set_robust_list   304
14938 +#define __NR_get_robust_list   305
14939 +#define __NR_splice            306
14940 +#define __NR_sync_file_range   307
14941 +#define __NR_tee               308
14942 +#define __NR_vmsplice          309
14943 +#define __NR_move_pages                310
14944 +#define __NR_sched_setaffinity 311
14945 +#define __NR_sched_getaffinity 312
14946 +#define __NR_kexec_load                313
14947 +#define __NR_getcpu            314
14948 +#define __NR_epoll_pwait       315
14949 +#define __NR_utimensat         316
14950 +#define __NR_signalfd          317
14951 +#define __NR_timerfd_create    318
14952 +#define __NR_eventfd           319
14953 +#define __NR_fallocate         320
14954 +#define __NR_timerfd_settime   321
14955 +#define __NR_timerfd_gettime   322
14956 +#define __NR_signalfd4         323
14957 +#define __NR_eventfd2          324
14958 +#define __NR_epoll_create1     325
14959 +#define __NR_dup3              326
14960 +#define __NR_pipe2             327
14961 +#define __NR_inotify_init1     328
14962 +
14963 +#ifdef __KERNEL__
14964 +
14965 +#define NR_syscalls            329
14966 +
14967 +#define __ARCH_WANT_IPC_PARSE_VERSION
14968 +#define __ARCH_WANT_OLD_READDIR
14969 +#define __ARCH_WANT_OLD_STAT
14970 +#define __ARCH_WANT_STAT64
14971 +#define __ARCH_WANT_SYS_ALARM
14972 +#define __ARCH_WANT_SYS_GETHOSTNAME
14973 +#define __ARCH_WANT_SYS_PAUSE
14974 +#define __ARCH_WANT_SYS_SGETMASK
14975 +#define __ARCH_WANT_SYS_SIGNAL
14976 +#define __ARCH_WANT_SYS_TIME
14977 +#define __ARCH_WANT_SYS_UTIME
14978 +#define __ARCH_WANT_SYS_WAITPID
14979 +#define __ARCH_WANT_SYS_SOCKETCALL
14980 +#define __ARCH_WANT_SYS_FADVISE64
14981 +#define __ARCH_WANT_SYS_GETPGRP
14982 +#define __ARCH_WANT_SYS_LLSEEK
14983 +#define __ARCH_WANT_SYS_NICE
14984 +#define __ARCH_WANT_SYS_OLD_GETRLIMIT
14985 +#define __ARCH_WANT_SYS_OLDUMOUNT
14986 +#define __ARCH_WANT_SYS_SIGPENDING
14987 +#define __ARCH_WANT_SYS_SIGPROCMASK
14988 +#define __ARCH_WANT_SYS_RT_SIGACTION
14989 +
14990 +/*
14991 + * "Conditional" syscalls
14992 + *
14993 + * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
14994 + * but it doesn't work on all toolchains, so we just do it by hand
14995 + */
14996 +//#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
14997 +#define cond_syscall(x) long x(void)  __attribute__((weak,alias("sys_ni_syscall")))
14998 +#endif /* __KERNEL__ */
14999 +
15000 +#endif /* _ASM_UBICOM32_UNISTD_H */
15001 --- /dev/null
15002 +++ b/arch/ubicom32/include/asm/user.h
15003 @@ -0,0 +1,82 @@
15004 +/*
15005 + * arch/ubicom32/include/asm/user.h
15006 + *   Ubicom32 architecture core file definitions.
15007 + *
15008 + * (C) Copyright 2009, Ubicom, Inc.
15009 + *
15010 + * This file is part of the Ubicom32 Linux Kernel Port.
15011 + *
15012 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15013 + * it and/or modify it under the terms of the GNU General Public License
15014 + * as published by the Free Software Foundation, either version 2 of the
15015 + * License, or (at your option) any later version.
15016 + *
15017 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15018 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15019 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15020 + * the GNU General Public License for more details.
15021 + *
15022 + * You should have received a copy of the GNU General Public License
15023 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15024 + * see <http://www.gnu.org/licenses/>.
15025 + *
15026 + * Ubicom32 implementation derived from (with many thanks):
15027 + *   arch/m68knommu
15028 + *   arch/blackfin
15029 + *   arch/parisc
15030 + */
15031 +#ifndef _ASM_UBICOM32_USER_H
15032 +#define _ASM_UBICOM32_USER_H
15033 +
15034 +#include <asm/ptrace.h>
15035 +#include <asm/page.h>
15036 +/*
15037 + * Adapted from <asm-powerpc/user.h>
15038 + *
15039 + * Core file format: The core file is written in such a way that gdb
15040 + * can understand it and provide useful information to the user (under
15041 + * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
15042 + * are as follows:
15043 + *
15044 + *  upage: 1 page consisting of a user struct that tells gdb
15045 + *     what is present in the file.  Directly after this is a
15046 + *     copy of the task_struct, which is currently not used by gdb,
15047 + *     but it may come in handy at some point.  All of the registers
15048 + *     are stored as part of the upage.  The upage should always be
15049 + *     only one page long.
15050 + *  data: The data segment follows next.  We use current->end_text to
15051 + *     current->brk to pick up all of the user variables, plus any memory
15052 + *     that may have been sbrk'ed.  No attempt is made to determine if a
15053 + *     page is demand-zero or if a page is totally unused, we just cover
15054 + *     the entire range.  All of the addresses are rounded in such a way
15055 + *     that an integral number of pages is written.
15056 + *  stack: We need the stack information in order to get a meaningful
15057 + *     backtrace.  We need to write the data from usp to
15058 + *     current->start_stack, so we round each of these in order to be able
15059 + *     to write an integer number of pages.
15060 + */
15061 +
15062 +struct user_ubicom32fp_struct {
15063 +};
15064 +
15065 +struct user {
15066 +       struct pt_regs  regs;                   /* entire machine state */
15067 +       size_t          u_tsize;                /* text size (pages) */
15068 +       size_t          u_dsize;                /* data size (pages) */
15069 +       size_t          u_ssize;                /* stack size (pages) */
15070 +       unsigned long   start_code;             /* text starting address */
15071 +       unsigned long   start_data;             /* data starting address */
15072 +       unsigned long   start_stack;            /* stack starting address */
15073 +       long int        signal;                 /* signal causing core dump */
15074 +       unsigned long   u_ar0;                  /* help gdb find registers */
15075 +       unsigned long   magic;                  /* identifies a core file */
15076 +       char            u_comm[32];             /* user command name */
15077 +};
15078 +
15079 +#define NBPG                   PAGE_SIZE
15080 +#define UPAGES                 1
15081 +#define HOST_TEXT_START_ADDR   (u.start_code)
15082 +#define HOST_DATA_START_ADDR   (u.start_data)
15083 +#define HOST_STACK_END_ADDR    (u.start_stack + u.u_ssize * NBPG)
15084 +
15085 +#endif /* _ASM_UBICOM32_USER_H */
15086 --- /dev/null
15087 +++ b/arch/ubicom32/include/asm/vdc_tio.h
15088 @@ -0,0 +1,129 @@
15089 +/*
15090 + * arch/ubicom32/include/asm/vdc_tio.h
15091 + *   Ubicom32 architecture VDC TIO definitions.
15092 + *
15093 + * (C) Copyright 2009, Ubicom, Inc.
15094 + *
15095 + * This file is part of the Ubicom32 Linux Kernel Port.
15096 + *
15097 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15098 + * it and/or modify it under the terms of the GNU General Public License
15099 + * as published by the Free Software Foundation, either version 2 of the
15100 + * License, or (at your option) any later version.
15101 + *
15102 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15103 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15104 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15105 + * the GNU General Public License for more details.
15106 + *
15107 + * You should have received a copy of the GNU General Public License
15108 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15109 + * see <http://www.gnu.org/licenses/>.
15110 + *
15111 + * Ubicom32 implementation derived from (with many thanks):
15112 + *   arch/m68knommu
15113 + *   arch/blackfin
15114 + *   arch/parisc
15115 + */
15116 +#ifndef _ASM_UBICOM32_VDC_TIO_H
15117 +#define _ASM_UBICOM32_VDC_TIO_H
15118 +
15119 +#include <asm/devtree.h>
15120 +
15121 +#define VDCTIO_VP_VERSION                      5
15122 +
15123 +#define VDCTIO_SCALE_FLAG_VSUB                 (1 << 9)
15124 +#define VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER       (1 << 8)
15125 +#define VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER      (1 << 7)
15126 +#define VDCTIO_SCALE_FLAG_YUV                  (1 << 6)
15127 +#define VDCTIO_SCALE_FLAG_VRANGE_16_255                (1 << 5)
15128 +#define VDCTIO_SCALE_FLAG_VRANGE_0_255         (1 << 4)
15129 +#define VDCTIO_SCALE_FLAG_HSUB_2_1             (1 << 3)
15130 +#define VDCTIO_SCALE_FLAG_HSUB_1_1             (1 << 2)
15131 +#define VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER     (1 << 1)
15132 +#define VDCTIO_SCALE_FLAG_ENABLE               (1 << 0)
15133 +
15134 +#define VDCTIO_NEXT_FRAME_FLAG_YUV_BIT         0
15135 +#define VDCTIO_NEXT_FRAME_FLAG_YUV             (1 << (VDCTIO_NEXT_FRAME_FLAG_YUV_BIT))
15136 +
15137 +#define VDCTIO_CAPS_SUPPORTS_SCALING           (1 << 0)
15138 +
15139 +#define VDCTIO_COMMAND_START                   (1 << 3)
15140 +#define VDCTIO_COMMAND_SET_COEFF               (1 << 2)
15141 +#define VDCTIO_COMMAND_SET_LUT                 (1 << 1)
15142 +#define VDCTIO_COMMAND_SET_SCALE_MODE          (1 << 0)
15143 +
15144 +/*
15145 + * Command / Data registers to access the VDC
15146 + */
15147 +struct vdc_tio_vp_regs {
15148 +       /*
15149 +        * Version of this TIO register map
15150 +        */
15151 +       u32_t           version;
15152 +
15153 +       volatile u32_t  command;
15154 +
15155 +       /*
15156 +        * Next frame pointer, when the command VDCTIO_COMMAND_SET_FRAME_BUFFER is set,
15157 +        * the vdc will take the pointer here and display it.
15158 +        */
15159 +       void            *next_frame;
15160 +       u32_t           next_frame_flags;
15161 +
15162 +       /*
15163 +        * These map directly into the PIXP registers 0x20-0x80.  
15164 +        * DO NOT change the order of these three variables.
15165 +        */
15166 +       u32_t           red_lut[6];
15167 +       u32_t           blue_lut[6];
15168 +       u32_t           green_lut[13];
15169 +
15170 +       /*
15171 +        * These map directly into the PIXP registers 0x04, 0x08
15172 +        */
15173 +       u32_t           coeff0;
15174 +       u32_t           coeff1;
15175 +
15176 +       /*
15177 +        * There are used to set the scaling parameters
15178 +        */
15179 +       u32_t           x_in;
15180 +       u32_t           x_out;
15181 +       u32_t           y_in;
15182 +       u32_t           y_out;
15183 +       u32_t           scale_flags;
15184 +
15185 +       /*
15186 +        * Current frame number, monotonically increasing number
15187 +        */
15188 +       u32_t           frame_number;
15189 +
15190 +       /*
15191 +        * These variables tell the guest OS what the underlying hardware looks like
15192 +        */
15193 +       u32_t           caps;
15194 +       u32_t           xres;
15195 +       u32_t           yres;
15196 +       u32_t           fb_align;
15197 +       u8_t            bpp;
15198 +       u8_t            rbits;
15199 +       u8_t            gbits;
15200 +       u8_t            bbits;
15201 +       u8_t            rshift;
15202 +       u8_t            gshift;
15203 +       u8_t            bshift;
15204 +};
15205 +
15206 +/*
15207 + * Devtree node for VDC
15208 + */
15209 +struct vdc_tio_node {
15210 +       struct devtree_node     dn;
15211 +
15212 +       struct vdc_tio_vp_regs  *regs;
15213 +};
15214 +
15215 +extern void vdc_tio_init(void);
15216 +
15217 +#endif /* _ASM_UBICOM32_VDC_TIO_H */
15218 --- /dev/null
15219 +++ b/arch/ubicom32/include/asm/vga.h
15220 @@ -0,0 +1,71 @@
15221 +/*
15222 + * arch/ubicom32/include/asm/vga.h
15223 + *   Ubicom32 low level  VGA/frame buffer definitions.
15224 + *
15225 + * (C) Copyright 2009, Ubicom, Inc.
15226 + * (c) 1998 Martin Mares <mj@ucw.cz>
15227 + *
15228 + * This file is part of the Ubicom32 Linux Kernel Port.
15229 + *
15230 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15231 + * it and/or modify it under the terms of the GNU General Public License
15232 + * as published by the Free Software Foundation, either version 2 of the
15233 + * License, or (at your option) any later version.
15234 + *
15235 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15236 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15237 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15238 + * the GNU General Public License for more details.
15239 + *
15240 + * You should have received a copy of the GNU General Public License
15241 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15242 + * see <http://www.gnu.org/licenses/>.
15243 + *
15244 + * Ubicom32 implementation derived from (with many thanks):
15245 + *   arch/m68knommu
15246 + *   arch/blackfin
15247 + *   arch/parisc
15248 + */
15249 +
15250 +#ifndef _ASM_UBICOM32_VGA_H
15251 +#define _ASM_UBICOM32_VGA_H
15252 +
15253 +#include <asm/byteorder.h>
15254 +
15255 +/*
15256 + *     On the PC, we can just recalculate addresses and then
15257 + *     access the videoram directly without any black magic.
15258 + */
15259 +
15260 +#define VGA_MAP_MEM(x, s)      (0xb0000000L + (unsigned long)(x))
15261 +
15262 +#define vga_readb(x)   (*(x))
15263 +#define vga_writeb(x, y)       (*(y) = (x))
15264 +
15265 +#define VT_BUF_HAVE_RW
15266 +/*
15267 + *  These are only needed for supporting VGA or MDA text mode, which use little
15268 + *  endian byte ordering.
15269 + *  In other cases, we can optimize by using native byte ordering and
15270 + *  <linux/vt_buffer.h> has already done the right job for us.
15271 + */
15272 +
15273 +#undef scr_writew
15274 +#undef scr_readw
15275 +
15276 +static inline void scr_writew(u16 val, volatile u16 *addr)
15277 +{
15278 +       *addr = cpu_to_le16(val);
15279 +}
15280 +
15281 +static inline u16 scr_readw(volatile const u16 *addr)
15282 +{
15283 +       return le16_to_cpu(*addr);
15284 +}
15285 +
15286 +#define scr_memcpyw(d, s, c) memcpy(d, s, c)
15287 +#define scr_memmovew(d, s, c) memmove(d, s, c)
15288 +#define VT_BUF_HAVE_MEMCPYW
15289 +#define VT_BUF_HAVE_MEMMOVEW
15290 +
15291 +#endif /* _ASM_UBICOM32_VGA_H */
15292 --- /dev/null
15293 +++ b/arch/ubicom32/include/asm/xor.h
15294 @@ -0,0 +1,33 @@
15295 +/*
15296 + * arch/ubicom32/include/asm/xor.h
15297 + *   Generic xor.h definitions for Ubicom32 architecture.
15298 + *
15299 + * (C) Copyright 2009, Ubicom, Inc.
15300 + *
15301 + * This file is part of the Ubicom32 Linux Kernel Port.
15302 + *
15303 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15304 + * it and/or modify it under the terms of the GNU General Public License
15305 + * as published by the Free Software Foundation, either version 2 of the
15306 + * License, or (at your option) any later version.
15307 + *
15308 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15309 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15310 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15311 + * the GNU General Public License for more details.
15312 + *
15313 + * You should have received a copy of the GNU General Public License
15314 + * along with the Ubicom32 Linux Kernel Port.  If not, 
15315 + * see <http://www.gnu.org/licenses/>.
15316 + *
15317 + * Ubicom32 implementation derived from (with many thanks):
15318 + *   arch/m68knommu
15319 + *   arch/blackfin
15320 + *   arch/parisc
15321 + */
15322 +#ifndef _ASM_UBICOM32_XOR_H
15323 +#define _ASM_UBICOM32_XOR_H
15324 +
15325 +#include <asm-generic/xor.h>
15326 +
15327 +#endif /* _ASM_UBICOM32_XOR_H */
15328 --- /dev/null
15329 +++ b/arch/ubicom32/Kconfig
15330 @@ -0,0 +1,455 @@
15331 +#
15332 +# For a description of the syntax of this configuration file,
15333 +# see Documentation/kbuild/kconfig-language.txt.
15334 +#
15335 +
15336 +mainmenu "uClinux/ubicom32 (w/o MMU) Kernel Configuration"
15337 +
15338 +config RAMBASE
15339 +       hex
15340 +       default "0x40000000"
15341 +       help
15342 +               Define the address that RAM starts at.
15343 +
15344 +config UBICOM32
15345 +       bool
15346 +       select HAVE_OPROFILE
15347 +       default y
15348 +
15349 +config RAMKERNEL
15350 +       bool
15351 +       default y
15352 +
15353 +config CPU_BIG_ENDIAN
15354 +       bool
15355 +       default y
15356 +
15357 +config FORCE_MAX_ZONEORDER
15358 +       int
15359 +       default "14"
15360 +
15361 +config HAVE_CLK
15362 +       bool
15363 +       default y
15364 +
15365 +config MMU
15366 +       bool
15367 +       default n
15368 +
15369 +config FPU
15370 +       bool
15371 +       default n
15372 +
15373 +config ZONE_DMA
15374 +       bool
15375 +       default y
15376 +
15377 +config RWSEM_GENERIC_SPINLOCK
15378 +       bool
15379 +       default y
15380 +
15381 +config RWSEM_XCHGADD_ALGORITHM
15382 +       bool
15383 +       default n
15384 +
15385 +config ARCH_HAS_ILOG2_U32
15386 +       bool
15387 +       default n
15388 +
15389 +config ARCH_HAS_ILOG2_U64
15390 +       bool
15391 +       default n
15392 +
15393 +config GENERIC_FIND_NEXT_BIT
15394 +       bool
15395 +       default y
15396 +
15397 +config GENERIC_GPIO
15398 +       bool
15399 +       default y
15400 +
15401 +config GPIOLIB
15402 +       bool
15403 +       default y
15404 +
15405 +config GENERIC_HWEIGHT
15406 +       bool
15407 +       default y
15408 +
15409 +config GENERIC_HARDIRQS
15410 +       bool
15411 +       default y
15412 +
15413 +config STACKTRACE_SUPPORT
15414 +       bool
15415 +       default y
15416 +
15417 +config LOCKDEP_SUPPORT
15418 +       bool
15419 +       default y
15420 +
15421 +config GENERIC_CALIBRATE_DELAY
15422 +       bool
15423 +       default y
15424 +
15425 +config GENERIC_TIME
15426 +       bool
15427 +       default y
15428 +
15429 +config TIME_LOW_RES
15430 +       bool
15431 +       default y
15432 +
15433 +config GENERIC_CLOCKEVENTS
15434 +       bool
15435 +       default y
15436 +
15437 +config GENERIC_CLOCKEVENTS_BROADCAST
15438 +       bool
15439 +       depends on GENERIC_CLOCKEVENTS
15440 +       default y if SMP && !LOCAL_TIMERS
15441 +
15442 +config NO_IOPORT
15443 +       def_bool y
15444 +
15445 +config ARCH_SUPPORTS_AOUT
15446 +       def_bool y
15447 +
15448 +config IRQ_PER_CPU
15449 +       bool
15450 +       default y
15451 +
15452 +config SCHED_NO_NO_OMIT_FRAME_POINTER
15453 +       bool
15454 +       default y
15455 +
15456 +menu "Processor type and features"
15457 +
15458 +config BRD_32MB
15459 +       bool
15460 +       depends on IP5160EVAL
15461 +       help
15462 +               Board has 32MB of RAM on it.  It is a hidden option used to select default for size of RAM
15463 +       default n
15464 +
15465 +config BRD_64MB
15466 +       bool
15467 +       depends on IP7145DPF || IP7160RGW || IP7160BRINGUP || IP7160DPF || IP5170DPF || IP5160DEV
15468 +       help
15469 +               Board has 64MB of RAM on it.  It is a hidden option used to select default for size of RAM
15470 +       default n
15471 +
15472 +config BRD_128MB
15473 +       bool
15474 +       depends on IP7500MODULE || IP7500AV || IP7500MEDIA
15475 +       help
15476 +               Board has 128MB of RAM on it.  It is a hidden option used to select default for size of RAM
15477 +       default n
15478 +
15479 +comment "Processor type will be selected by Board"
15480 +
15481 +config UBICOM32_V3
15482 +       bool
15483 +       help
15484 +         Ubicom IP5xxx series processor support.
15485 +
15486 +config UBICOM32_V4
15487 +       bool
15488 +       help
15489 +         Ubicom IP7xxx series processor support.
15490 +
15491 +comment "Board"
15492 +choice
15493 +       prompt "Board type"
15494 +       help
15495 +               Select your board.
15496 +
15497 +config NOBOARD
15498 +       bool "No board selected"
15499 +       help
15500 +               Default. Don't select any board specific config. Will not build unless you change!
15501 +
15502 +# Add your boards here
15503 +source "arch/ubicom32/mach-ip5k/Kconfig"
15504 +source "arch/ubicom32/mach-ip7k/Kconfig"
15505 +
15506 +endchoice
15507 +
15508 +comment "Kernel Options"
15509 +config SMP
15510 +       bool "Symmetric multi-processing support"
15511 +       select USE_GENERIC_SMP_HELPERS
15512 +       default n
15513 +       help
15514 +         Enables multithreading support.  Enabling SMP support increases
15515 +         the size of system data structures.  SMP support can have either 
15516 +         positive or negative impact on performance depending on workloads. 
15517 +
15518 +         If you do not know what to do here, say N.
15519 +
15520 +config NR_CPUS
15521 +       int "Number of configured CPUs"
15522 +       range 2 32
15523 +       default 2
15524 +       depends on SMP
15525 +       help
15526 +               Upper bound on the number of CPUs. Space is reserved 
15527 +               at compile time for this many CPUs.
15528 +               
15529 +config LOCAL_TIMERS
15530 +       bool "Use local timer interrupts"
15531 +       depends on SMP
15532 +       default y
15533 +       help
15534 +         Enable support for local timers on SMP platforms, rather then the
15535 +         legacy IPI broadcast method.  Local timers allows the system
15536 +         accounting to be spread across the timer interval, preventing a
15537 +         "thundering herd" at every timer tick.  A physical timer is allocated
15538 +         per cpu.              
15539 +
15540 +config TIMER_EXTRA_ALLOC
15541 +       int "Number of additional physical timer events to create"
15542 +       depends on GENERIC_CLOCKEVENTS
15543 +       default 0
15544 +       help
15545 +               The Ubicom32 processor has a number of event timers that can be wrapped
15546 +               in Linux clock event structures (assuming that the timers are not being
15547 +               used for another purpose).  Based on the value of LOCAL_TIMERS, either 
15548 +               2 timers will be used or a timer will be used for every CPU.  This value
15549 +               allows the programmer to select additional timers over that amount.
15550 +                       
15551 +config IRQSTACKS
15552 +       bool "Create separate stacks for interrupt handling"
15553 +       default n
15554 +       help
15555 +               Selecting this causes interrupts to be created on a separate
15556 +               stack instead of nesting the interrupts on the kernel stack.
15557 +               
15558 +config IRQSTACKS_USEOCM
15559 +       bool "Use OCM for interrupt stacks"
15560 +       default n
15561 +       depends on IRQSTACKS
15562 +       help
15563 +               Selecting this cause the interrupt stacks to be placed in OCM
15564 +               reducing cache misses at the expense of using the OCM for servicing
15565 +               interrupts.
15566 +
15567 +menu "OCM Instruction Heap"
15568 +
15569 +config OCM_MODULES_RESERVATION
15570 +       int "OCM Instruction heap reservation. 0-192 kB"
15571 +       range 0 192
15572 +       default "0"
15573 +       help
15574 +         The minimum amount of OCM memory to reserve for kernel loadable module
15575 +         code. If you are not using this memory it cannot be used for anything
15576 +         else. Leave it as 0 if you have prebuilt modules that are compiled with
15577 +         OCM support.
15578 +
15579 +config OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
15580 +       bool "Give all unused ocm code space to the ocm instruction heap."
15581 +       default n
15582 +       help
15583 +         Allow the OCM instruction heap allocation to consume any remaining
15584 +         unused OCM code space.  The result of this is that you will not have
15585 +         and deterministic results, but you will not have any waste either.
15586 +
15587 +config OCM_MODULES_FALLBACK_TO_DDR
15588 +       bool "Loadable Modules requiring OCM may fallback to use DDR."
15589 +       default n
15590 +       help
15591 +         If a module cannot get the OCM code it requires allow DDR to
15592 +         be used instead.
15593 +endmenu
15594 +
15595 +config HZ
15596 +       int "Frequency of 'jiffies' (for polling)"
15597 +       default 1000
15598 +       help
15599 +               100 is common for embedded systems, but 1000 allows
15600 +               you to do more drivers without actually having
15601 +               interrupts working properly.
15602 +
15603 +comment "RAM configuration"
15604 +
15605 +if BRD_32MB
15606 +
15607 +config RAMSIZE
15608 +       hex "Size of RAM (in bytes)"
15609 +       range 0x00000000 0x02000000
15610 +       default "0x02000000"
15611 +       help
15612 +               Define the size of the system RAM. If you select 0 then the
15613 +               kernel will try to probe the RAM size at runtime. This is not
15614 +               supported on all CPU types.
15615 +
15616 +endif
15617 +
15618 +if BRD_64MB
15619 +
15620 +config RAMSIZE
15621 +       hex "Size of RAM (in bytes)"
15622 +       range 0x00000000 0x04000000
15623 +       default "0x04000000"
15624 +       help
15625 +               Define the size of the system RAM. If you select 0 then the
15626 +               kernel will try to probe the RAM size at runtime. This is not
15627 +               supported on all CPU types.
15628 +
15629 +endif
15630 +
15631 +if BRD_128MB
15632 +
15633 +config RAMSIZE
15634 +       hex "Size of RAM (in bytes)"
15635 +       range 0x00000000 0x08000000
15636 +       default "0x08000000"
15637 +       help
15638 +               Define the size of the system RAM. If you select 0 then the
15639 +               kernel will try to probe the RAM size at runtime. This is not
15640 +               supported on all CPU types.
15641 +
15642 +endif
15643 +
15644 +config KERNELBASE
15645 +       hex "Address of the base of kernel code"
15646 +       default "0x40400000"
15647 +       help
15648 +               For the time being we are going to start the Kernel at a 4 meg offset.
15649 +
15650 +comment "Build options"
15651 +config LINKER_RELAXATION
15652 +       bool "Linker Relaxation"
15653 +       default y
15654 +       help
15655 +         Turns on linker relaxation that will produce smaller
15656 +         faster code. Increases link time.
15657 +
15658 +comment "Driver options"
15659 +menu "PCI Bus"
15660 +config PCI
15661 +       bool "PCI bus"
15662 +       default true
15663 +       help
15664 +         Enable/Disable PCI bus
15665 +       source "drivers/pci/Kconfig"
15666 +
15667 +
15668 +config PCI_DEV0_IDSEL
15669 +       hex "slot 0 address"
15670 +       depends on PCI
15671 +       default "0x01000000"
15672 +       help
15673 +         Slot 0 address.  This address should correspond to the address line
15674 +         which the IDSEL bit for this slot is connected to.
15675 +
15676 +config PCI_DEV1_IDSEL
15677 +       hex "slot 1 address"
15678 +       depends on PCI
15679 +       default "0x02000000"
15680 +       help
15681 +         Slot 1 address.  This address should correspond to the address line
15682 +         which the IDSEL bit for this slot is connected to.
15683 +endmenu
15684 +# End PCI
15685 +
15686 +menu "Input devices"
15687 +config UBICOM_INPUT
15688 +       bool "Ubicom polled GPIO input driver"
15689 +       select INPUT
15690 +       select INPUT_POLLDEV
15691 +       help
15692 +               Polling input driver, much like the GPIO input driver, except that it doesn't
15693 +               rely on interrupts.  It will report events via the input subsystem.
15694 +       default n
15695 +
15696 +config UBICOM_INPUT_I2C
15697 +       bool "Ubicom polled GPIO input driver over I2C"
15698 +       select INPUT
15699 +       select INPUT_POLLDEV
15700 +       help
15701 +               Polling input driver, much like the PCA953x driver, it can support a variety of
15702 +               different I2C I/O expanders.  This device polls the I2C I/O expander for events
15703 +               and reports them via the input subsystem.
15704 +       default n
15705 +endmenu
15706 +# Input devices
15707 +
15708 +menu "Misc devices"
15709 +config UBICOM_HID
15710 +       bool "Ubicom HID driver"
15711 +       select INPUT
15712 +       select INPUT_POLLDEV
15713 +       select LCD_CLASS_DEVICE
15714 +       help
15715 +               Driver for HID chip found on some Ubicom reference designs.  This chip handles
15716 +               PWM, button input, and IR remote control.  It registers as an input device and
15717 +               a backlight device.
15718 +       default n
15719 +endmenu
15720 +# Misc devices
15721 +
15722 +config CMDLINE_BOOL
15723 +       bool "Built-in kernel command line"
15724 +       default n
15725 +       help
15726 +         Allow for specifying boot arguments to the kernel at
15727 +         build time.  On some systems (e.g. embedded ones), it is
15728 +         necessary or convenient to provide some or all of the
15729 +         kernel boot arguments with the kernel itself (that is,
15730 +         to not rely on the boot loader to provide them.)
15731 +
15732 +         To compile command line arguments into the kernel,
15733 +         set this option to 'Y', then fill in the
15734 +         the boot arguments in CONFIG_CMDLINE.
15735 +
15736 +         Systems with fully functional boot loaders (i.e. non-embedded)
15737 +         should leave this option set to 'N'.
15738 +
15739 +config CMDLINE
15740 +       string "Built-in kernel command string"
15741 +       depends on CMDLINE_BOOL
15742 +       default ""
15743 +       help
15744 +         Enter arguments here that should be compiled into the kernel
15745 +         image and used at boot time.  If the boot loader provides a
15746 +         command line at boot time, it is appended to this string to
15747 +         form the full kernel command line, when the system boots.
15748 +
15749 +         However, you can use the CONFIG_CMDLINE_OVERRIDE option to
15750 +         change this behavior.
15751 +
15752 +         In most cases, the command line (whether built-in or provided
15753 +         by the boot loader) should specify the device for the root
15754 +         file system.
15755 +
15756 +config CMDLINE_OVERRIDE
15757 +       bool "Built-in command line overrides boot loader arguments"
15758 +       default n
15759 +       depends on CMDLINE_BOOL
15760 +       help
15761 +         Set this option to 'Y' to have the kernel ignore the boot loader
15762 +         command line, and use ONLY the built-in command line.
15763 +
15764 +         This is used to work around broken boot loaders.  This should
15765 +         be set to 'N' under normal conditions.
15766 +
15767 +endmenu
15768 +# End Processor type and features
15769 +
15770 +source "arch/ubicom32/Kconfig.debug"
15771 +
15772 +menu "Executable file formats"
15773 +source "fs/Kconfig.binfmt"
15774 +endmenu
15775 +
15776 +source "init/Kconfig"
15777 +source "kernel/Kconfig.preempt"
15778 +source "kernel/time/Kconfig"
15779 +source "mm/Kconfig"
15780 +source "net/Kconfig"
15781 +source "drivers/Kconfig"
15782 +source "fs/Kconfig"
15783 +source "security/Kconfig"
15784 +source "crypto/Kconfig"
15785 +source "lib/Kconfig"
15786 --- /dev/null
15787 +++ b/arch/ubicom32/Kconfig.debug
15788 @@ -0,0 +1,117 @@
15789 +menu "Kernel hacking"
15790 +
15791 +config TRACE_IRQFLAGS_SUPPORT
15792 +       def_bool y
15793 +       
15794 +config PROTECT_KERNEL
15795 +       default y
15796 +       bool 'Enable Kernel range register Protection'
15797 +       help
15798 +         Adds code to enable/disable range registers to protect static
15799 +         kernel code/data from userspace.  Currently the ranges covered
15800 +         do no protect kernel loadable modules or dynamically allocated
15801 +         kernel data.
15802 +
15803 +config NO_KERNEL_MSG
15804 +       bool "Suppress Kernel BUG Messages"
15805 +       help
15806 +         Do not output any debug BUG messages within the kernel.
15807 +
15808 +config EARLY_PRINTK
15809 +       bool "Use the driver that you selected as console also for early printk (to debug kernel bootup)."
15810 +       default n
15811 +       help
15812 +         If you want to use the serdes driver (console=ttyUS0) for
15813 +         early printk, you must also supply an additional kernel boot
15814 +         parameter like this:
15815 +
15816 +               serdes=ioportaddr,irq,clockrate,baud
15817 +
15818 +         For an IP7160RGW eval board, you could use this:
15819 +
15820 +               serdes=0x2004000,61,250000000,57600
15821 +
15822 +         which will let you see early printk output at 57600 baud.
15823 +
15824 +config STOP_ON_TRAP
15825 +       bool "Enable stopping at the LDSR for all traps"
15826 +       default n
15827 +       help
15828 +       Cause the LDSR to stop all threads whenever a trap is about to be serviced
15829 +       
15830 +config STOP_ON_BUG
15831 +       bool "Enable stopping on failed BUG_ON()"
15832 +       default n
15833 +       help
15834 +       Cause all BUG_ON failures to stop all threads
15835 +       
15836 +config DEBUG_IRQMEASURE
15837 +       bool "Enable IRQ handler measurements"
15838 +       default n
15839 +       help
15840 +       When enabled each IRQ's min/avg/max times will be printed.  If the handler
15841 +       re-enables interrupt, the times will show the full time including to service
15842 +       nested interrupts.  See /proc/irq_measurements.
15843 +       
15844 +config DEBUG_PCIMEASURE
15845 +       bool "Enable PCI transaction measurements"
15846 +       default n
15847 +       help
15848 +       When enabled the system will measure the min/avg/max timer for each PCI transactions.
15849 +       See /proc/pci_measurements.
15850 +
15851 +config ACCESS_OK_CHECKS_ENABLED
15852 +       bool "Enable user space access checks"
15853 +       default n
15854 +       help
15855 +       Enabling this check causes the kernel to verify that addresses passed
15856 +       to the kernel by the user space code are within the processes 
15857 +       address space.  On a no-mmu system, this is done by examining the
15858 +       processes memory data structures (adversly affecting performance) but
15859 +       ensuring that a process does not ask the kernel to violate another 
15860 +       processes address space.  Sadly, the kernel uses access_ok() for 
15861 +       address that are in the kernel which results in a large volume of 
15862 +       false positives.
15863 +
15864 +choice
15865 +       prompt "Unaligned Access Support"
15866 +       default UNALIGNED_ACCESS_ENABLED
15867 +       help
15868 +               Kernel / Userspace unaligned access handling.
15869 +
15870 +config  UNALIGNED_ACCESS_ENABLED
15871 +       bool "Kernel and Userspace"
15872 +       help
15873 +
15874 +config  UNALIGNED_ACCESS_USERSPACE_ONLY
15875 +       bool "Userspace Only"
15876 +       help
15877 +
15878 +config  UNALIGNED_ACCESS_DISABLED
15879 +       bool "Disabled"
15880 +       help
15881 +
15882 +endchoice
15883 +
15884 +config DEBUG_STACKOVERFLOW
15885 +       bool "Check for stack overflows"
15886 +       default n
15887 +       depends on DEBUG_KERNEL
15888 +       help
15889 +         This option will cause messages to be printed if free kernel stack space
15890 +         drops below a certain limit (THREAD_SIZE /8).
15891 +
15892 +config DEBUG_STACK_USAGE
15893 +       bool "Stack utilization instrumentation"
15894 +       default n
15895 +       depends on DEBUG_KERNEL
15896 +       help
15897 +         Enables the display of the minimum amount of free kernel stack which each
15898 +         task has ever had available in the sysrq-T and sysrq-P debug output.
15899 +
15900 +         This option will slow down process creation somewhat.
15901 +
15902 +source "lib/Kconfig.debug"
15903 +
15904 +endmenu
15905 +
15906 --- /dev/null
15907 +++ b/arch/ubicom32/kernel/asm-offsets.c
15908 @@ -0,0 +1,162 @@
15909 +/*
15910 + * arch/ubicom32/kernel/asm-offsets.c
15911 + *   Ubicom32 architecture definitions needed by assembly language modules.
15912 + *
15913 + * (C) Copyright 2009, Ubicom, Inc.
15914 + *
15915 + * This file is part of the Ubicom32 Linux Kernel Port.
15916 + *
15917 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
15918 + * it and/or modify it under the terms of the GNU General Public License
15919 + * as published by the Free Software Foundation, either version 2 of the
15920 + * License, or (at your option) any later version.
15921 + *
15922 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15923 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15924 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15925 + * the GNU General Public License for more details.
15926 + *
15927 + * You should have received a copy of the GNU General Public License
15928 + * along with the Ubicom32 Linux Kernel Port.  If not,
15929 + * see <http://www.gnu.org/licenses/>.
15930 + *
15931 + * Ubicom32 implementation derived from (with many thanks):
15932 + *   arch/m68knommu
15933 + *   arch/blackfin
15934 + *   arch/parisc
15935 + */
15936 +/*
15937 + * This program is used to generate definitions needed by
15938 + * assembly language modules.
15939 + *
15940 + * We use the technique used in the OSF Mach kernel code:
15941 + * generate asm statements containing #defines,
15942 + * compile this file to assembler, and then extract the
15943 + * #defines from the assembly-language output.
15944 + */
15945 +
15946 +#include <linux/module.h>
15947 +#include <linux/stddef.h>
15948 +#include <linux/sched.h>
15949 +#include <linux/kernel_stat.h>
15950 +#include <linux/ptrace.h>
15951 +#include <linux/hardirq.h>
15952 +#include <asm/bootinfo.h>
15953 +#include <asm/irq.h>
15954 +#include <asm/thread_info.h>
15955 +
15956 +#define DEFINE(sym, val) \
15957 +        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
15958 +
15959 +#define BLANK() asm volatile("\n->" : : )
15960 +
15961 +int main(void)
15962 +{
15963 +       /* offsets into the task struct */
15964 +       DEFINE(TASK_STATE, offsetof(struct task_struct, state));
15965 +       DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
15966 +       DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
15967 +       DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
15968 +       DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
15969 +       DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
15970 +       DEFINE(TASK_MM, offsetof(struct task_struct, mm));
15971 +       DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
15972 +
15973 +       /* offsets into the kernel_stat struct */
15974 +       DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
15975 +
15976 +       /* offsets into the irq_cpustat_t struct */
15977 +       DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
15978 +
15979 +       /* offsets into the thread struct */
15980 +       DEFINE(THREAD_D10, offsetof(struct thread_struct, d10));
15981 +       DEFINE(THREAD_D11, offsetof(struct thread_struct, d11));
15982 +       DEFINE(THREAD_D12, offsetof(struct thread_struct, d12));
15983 +       DEFINE(THREAD_D13, offsetof(struct thread_struct, d13));
15984 +       DEFINE(THREAD_A1, offsetof(struct thread_struct, a1));
15985 +       DEFINE(THREAD_A2, offsetof(struct thread_struct, a2));
15986 +       DEFINE(THREAD_A5, offsetof(struct thread_struct, a5));
15987 +       DEFINE(THREAD_A6, offsetof(struct thread_struct, a6));
15988 +       DEFINE(THREAD_SP, offsetof(struct thread_struct, sp));
15989 +
15990 +       /* offsets into the pt_regs */
15991 +       DEFINE(PT_D0, offsetof(struct pt_regs, dn[0]));
15992 +       DEFINE(PT_D1, offsetof(struct pt_regs, dn[1]));
15993 +       DEFINE(PT_D2, offsetof(struct pt_regs, dn[2]));
15994 +       DEFINE(PT_D3, offsetof(struct pt_regs, dn[3]));
15995 +       DEFINE(PT_D4, offsetof(struct pt_regs, dn[4]));
15996 +       DEFINE(PT_D5, offsetof(struct pt_regs, dn[5]));
15997 +       DEFINE(PT_D6, offsetof(struct pt_regs, dn[6]));
15998 +       DEFINE(PT_D7, offsetof(struct pt_regs, dn[7]));
15999 +       DEFINE(PT_D8, offsetof(struct pt_regs, dn[8]));
16000 +       DEFINE(PT_D9, offsetof(struct pt_regs, dn[9]));
16001 +       DEFINE(PT_D10, offsetof(struct pt_regs, dn[10]));
16002 +       DEFINE(PT_D11, offsetof(struct pt_regs, dn[11]));
16003 +       DEFINE(PT_D12, offsetof(struct pt_regs, dn[12]));
16004 +       DEFINE(PT_D13, offsetof(struct pt_regs, dn[13]));
16005 +       DEFINE(PT_D14, offsetof(struct pt_regs, dn[14]));
16006 +       DEFINE(PT_D15, offsetof(struct pt_regs, dn[15]));
16007 +       DEFINE(PT_A0, offsetof(struct pt_regs, an[0]));
16008 +       DEFINE(PT_A1, offsetof(struct pt_regs, an[1]));
16009 +       DEFINE(PT_A2, offsetof(struct pt_regs, an[2]));
16010 +       DEFINE(PT_A3, offsetof(struct pt_regs, an[3]));
16011 +       DEFINE(PT_A4, offsetof(struct pt_regs, an[4]));
16012 +       DEFINE(PT_A5, offsetof(struct pt_regs, an[5]));
16013 +       DEFINE(PT_A6, offsetof(struct pt_regs, an[6]));
16014 +       DEFINE(PT_A7, offsetof(struct pt_regs, an[7]));
16015 +       DEFINE(PT_SP, offsetof(struct pt_regs, an[7]));
16016 +
16017 +       DEFINE(PT_ACC0HI, offsetof(struct pt_regs, acc0[0]));
16018 +       DEFINE(PT_ACC0LO, offsetof(struct pt_regs, acc0[1]));
16019 +       DEFINE(PT_MAC_RC16, offsetof(struct pt_regs, mac_rc16));
16020 +
16021 +       DEFINE(PT_ACC1HI, offsetof(struct pt_regs, acc1[0]));
16022 +       DEFINE(PT_ACC1LO, offsetof(struct pt_regs, acc1[1]));
16023 +
16024 +       DEFINE(PT_SOURCE3, offsetof(struct pt_regs, source3));
16025 +       DEFINE(PT_INST_CNT, offsetof(struct pt_regs, inst_cnt));
16026 +       DEFINE(PT_CSR, offsetof(struct pt_regs, csr));
16027 +       DEFINE(PT_DUMMY_UNUSED, offsetof(struct pt_regs, dummy_unused));
16028 +
16029 +       DEFINE(PT_INT_MASK0, offsetof(struct pt_regs, int_mask0));
16030 +       DEFINE(PT_INT_MASK1, offsetof(struct pt_regs, int_mask1));
16031 +
16032 +       DEFINE(PT_PC, offsetof(struct pt_regs, pc));
16033 +
16034 +       DEFINE(PT_TRAP_CAUSE, offsetof(struct pt_regs, trap_cause));
16035 +
16036 +       DEFINE(PT_SIZE, sizeof(struct pt_regs));
16037 +
16038 +       DEFINE(PT_FRAME_TYPE, offsetof(struct pt_regs, frame_type));
16039 +
16040 +       DEFINE(PT_ORIGINAL_D0, offsetof(struct pt_regs, original_dn_0));
16041 +       DEFINE(PT_PREVIOUS_PC, offsetof(struct pt_regs, previous_pc));
16042 +
16043 +       /* offsets into the kernel_stat struct */
16044 +       DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
16045 +
16046 +       /* signal defines */
16047 +       DEFINE(SIGSEGV, SIGSEGV);
16048 +       //DEFINE(SEGV_MAPERR, SEGV_MAPERR);
16049 +       DEFINE(SIGTRAP, SIGTRAP);
16050 +       //DEFINE(TRAP_TRACE, TRAP_TRACE);
16051 +
16052 +       DEFINE(PT_PTRACED, PT_PTRACED);
16053 +       DEFINE(PT_DTRACE, PT_DTRACE);
16054 +
16055 +       DEFINE(ASM_THREAD_SIZE, THREAD_SIZE);
16056 +
16057 +       /* Offsets in thread_info structure */
16058 +       DEFINE(TI_TASK, offsetof(struct thread_info, task));
16059 +       DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
16060 +       DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
16061 +       DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
16062 +       DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
16063 +       DEFINE(TI_INTR_NESTING, offsetof(struct thread_info, interrupt_nesting));
16064 +       DEFINE(ASM_TIF_NEED_RESCHED, TIF_NEED_RESCHED);
16065 +       DEFINE(ASM_TIF_SYSCALL_TRACE, TIF_SYSCALL_TRACE);
16066 +       DEFINE(ASM_TIF_SIGPENDING, TIF_SIGPENDING);
16067 +
16068 +       DEFINE(ASM_RAM_END, (CONFIG_RAMBASE + CONFIG_RAMSIZE));
16069 +       return 0;
16070 +}
16071 --- /dev/null
16072 +++ b/arch/ubicom32/kernel/devtree.c
16073 @@ -0,0 +1,173 @@
16074 +/*
16075 + * arch/ubicom32/kernel/devtree.c
16076 + *   Ubicom32 architecture device tree implementation.
16077 + *
16078 + * (C) Copyright 2009, Ubicom, Inc.
16079 + *
16080 + * This file is part of the Ubicom32 Linux Kernel Port.
16081 + *
16082 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16083 + * it and/or modify it under the terms of the GNU General Public License
16084 + * as published by the Free Software Foundation, either version 2 of the
16085 + * License, or (at your option) any later version.
16086 + *
16087 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16088 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16089 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16090 + * the GNU General Public License for more details.
16091 + *
16092 + * You should have received a copy of the GNU General Public License
16093 + * along with the Ubicom32 Linux Kernel Port.  If not,
16094 + * see <http://www.gnu.org/licenses/>.
16095 + *
16096 + * Ubicom32 implementation derived from (with many thanks):
16097 + *   arch/m68knommu
16098 + *   arch/blackfin
16099 + *   arch/parisc
16100 + */
16101 +
16102 +#include <linux/module.h>
16103 +#include <linux/kernel.h>
16104 +#include <linux/string.h>
16105 +#include <linux/errno.h>
16106 +#include <asm/devtree.h>
16107 +
16108 +/*
16109 + * The device tree.
16110 + */
16111 +struct devtree_node *devtree;
16112 +
16113 +/*
16114 + * devtree_print()
16115 + *     Print the device tree.
16116 + */
16117 +void devtree_print(void)
16118 +{
16119 +       struct devtree_node *p = devtree;
16120 +       printk(KERN_INFO "Device Tree:\n");
16121 +       while (p) {
16122 +               if (p->magic != DEVTREE_NODE_MAGIC) {
16123 +                       printk(KERN_EMERG
16124 +                              "device tree has improper node: %p\n", p);
16125 +                       return;
16126 +               }
16127 +               printk(KERN_INFO "\t%p: sendirq=%03d, recvirq=%03d, "
16128 +                      " name=%s\n", p, p->sendirq, p->recvirq, p->name);
16129 +               p = p->next;
16130 +       }
16131 +}
16132 +EXPORT_SYMBOL(devtree_print);
16133 +
16134 +/*
16135 + * devtree_irq()
16136 + *     Return the IRQ(s) associated with devtree node.
16137 + */
16138 +int devtree_irq(struct devtree_node *dn,
16139 +               unsigned char *sendirq,
16140 +               unsigned char *recvirq)
16141 +{
16142 +       if (dn->magic != DEVTREE_NODE_MAGIC) {
16143 +               printk(KERN_EMERG "improper node: %p\n", dn);
16144 +               if (sendirq) {
16145 +                       *sendirq = DEVTREE_IRQ_NONE;
16146 +               }
16147 +               if (recvirq) {
16148 +                       *recvirq = DEVTREE_IRQ_NONE;
16149 +               }
16150 +               return -EFAULT;
16151 +       }
16152 +
16153 +       /*
16154 +        * Copy the devtree irq(s) to the output parameters.
16155 +        */
16156 +       if (sendirq) {
16157 +               *sendirq = dn->sendirq;
16158 +       }
16159 +       if (recvirq) {
16160 +               *recvirq = dn->recvirq;
16161 +       }
16162 +       return 0;
16163 +}
16164 +EXPORT_SYMBOL(devtree_irq);
16165 +
16166 +/*
16167 + * devtree_find_next()
16168 + *     Provide an iterator for walking the device tree.
16169 + */
16170 +struct devtree_node *devtree_find_next(struct devtree_node **cur)
16171 +{
16172 +       struct devtree_node *p = *cur;
16173 +       if (!p) {
16174 +               *cur = devtree;
16175 +               return devtree;
16176 +       }
16177 +       p = p->next;
16178 +       *cur = p;
16179 +       return p;
16180 +}
16181 +
16182 +/*
16183 + * devtree_find_by_irq()
16184 + *     Return the node associated with a given irq.
16185 + */
16186 +struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq)
16187 +{
16188 +       struct devtree_node *p = devtree;
16189 +
16190 +       if (sendirq == recvirq) {
16191 +               printk(KERN_EMERG "identical request makes no sense sendirq = "
16192 +                      "%d, recvirq= %d\n", sendirq, recvirq);
16193 +               return NULL;
16194 +       }
16195 +
16196 +       while (p) {
16197 +               if (p->magic != DEVTREE_NODE_MAGIC) {
16198 +                       printk(KERN_EMERG
16199 +                              "device tree has improper node: %p\n", p);
16200 +                       return NULL;
16201 +               }
16202 +
16203 +               /*
16204 +                * See if we can find a match on the IRQ(s) specified.
16205 +                */
16206 +               if ((sendirq == p->sendirq) && (recvirq == p->recvirq)) {
16207 +                       return p;
16208 +               }
16209 +
16210 +               if ((sendirq == DEVTREE_IRQ_DONTCARE) &&
16211 +                   (p->recvirq == recvirq)) {
16212 +                       return p;
16213 +               }
16214 +
16215 +               if ((recvirq == DEVTREE_IRQ_DONTCARE) &&
16216 +                   (p->sendirq == sendirq)) {
16217 +                       return p;
16218 +               }
16219 +
16220 +               p = p->next;
16221 +       }
16222 +       return NULL;
16223 +}
16224 +EXPORT_SYMBOL(devtree_find_by_irq);
16225 +
16226 +/*
16227 + * devtree_find_node()
16228 + *     Find a node in the device tree by name.
16229 + */
16230 +struct devtree_node *devtree_find_node(const char *str)
16231 +{
16232 +       struct devtree_node *p = devtree;
16233 +       while (p) {
16234 +               if (p->magic != DEVTREE_NODE_MAGIC) {
16235 +                       printk(KERN_EMERG
16236 +                              "device tree has improper node: %p\n", p);
16237 +                       return NULL;
16238 +               }
16239 +               if (strcmp(p->name, str) == 0) {
16240 +                       return p;
16241 +               }
16242 +               p = p->next;
16243 +       }
16244 +       return NULL;
16245 +}
16246 +EXPORT_SYMBOL(devtree_find_node);
16247 --- /dev/null
16248 +++ b/arch/ubicom32/kernel/dma.c
16249 @@ -0,0 +1,60 @@
16250 +/*
16251 + * arch/ubicom32/kernel/dma.c
16252 + *   Ubicom32 architecture dynamic DMA mapping support.
16253 + *
16254 + * (C) Copyright 2009, Ubicom, Inc.
16255 + *
16256 + * This file is part of the Ubicom32 Linux Kernel Port.
16257 + *
16258 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16259 + * it and/or modify it under the terms of the GNU General Public License
16260 + * as published by the Free Software Foundation, either version 2 of the
16261 + * License, or (at your option) any later version.
16262 + *
16263 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16264 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16265 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16266 + * the GNU General Public License for more details.
16267 + *
16268 + * You should have received a copy of the GNU General Public License
16269 + * along with the Ubicom32 Linux Kernel Port.  If not,
16270 + * see <http://www.gnu.org/licenses/>.
16271 + *
16272 + * Ubicom32 implementation derived from (with many thanks):
16273 + *   arch/m68knommu
16274 + *   arch/blackfin
16275 + *   arch/parisc
16276 + *
16277 + * We never have any address translations to worry about, so this
16278 + * is just alloc/free.
16279 + */
16280 +
16281 +#include <linux/types.h>
16282 +#include <linux/mm.h>
16283 +#include <linux/string.h>
16284 +#include <linux/device.h>
16285 +#include <linux/io.h>
16286 +
16287 +void *dma_alloc_coherent(struct device *dev, size_t size,
16288 +                          dma_addr_t *dma_handle, int gfp)
16289 +{
16290 +       void *ret;
16291 +       /* ignore region specifiers */
16292 +       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
16293 +
16294 +       if (dev == NULL || (*dev->dma_mask < 0xffffffff))
16295 +               gfp |= GFP_DMA;
16296 +       ret = (void *)__get_free_pages(gfp, get_order(size));
16297 +
16298 +       if (ret != NULL) {
16299 +               memset(ret, 0, size);
16300 +               *dma_handle = virt_to_phys(ret);
16301 +       }
16302 +       return ret;
16303 +}
16304 +
16305 +void dma_free_coherent(struct device *dev, size_t size,
16306 +                        void *vaddr, dma_addr_t dma_handle)
16307 +{
16308 +       free_pages((unsigned long)vaddr, get_order(size));
16309 +}
16310 --- /dev/null
16311 +++ b/arch/ubicom32/kernel/flat.c
16312 @@ -0,0 +1,206 @@
16313 +/*
16314 + * arch/ubicom32/kernel/flat.c
16315 + *   Ubicom32 architecture flat executable format support.
16316 + *
16317 + * (C) Copyright 2009, Ubicom, Inc.
16318 + *
16319 + * This file is part of the Ubicom32 Linux Kernel Port.
16320 + *
16321 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16322 + * it and/or modify it under the terms of the GNU General Public License
16323 + * as published by the Free Software Foundation, either version 2 of the
16324 + * License, or (at your option) any later version.
16325 + *
16326 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16327 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16328 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16329 + * the GNU General Public License for more details.
16330 + *
16331 + * You should have received a copy of the GNU General Public License
16332 + * along with the Ubicom32 Linux Kernel Port.  If not,
16333 + * see <http://www.gnu.org/licenses/>.
16334 + *
16335 + * Ubicom32 implementation derived from (with many thanks):
16336 + *   arch/m68knommu
16337 + *   arch/blackfin
16338 + *   arch/parisc
16339 + */
16340 +#include <linux/module.h>
16341 +#include <linux/types.h>
16342 +#include <linux/flat.h>
16343 +
16344 +unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp,
16345 +                                            u32_t relval,
16346 +                                            u32_t flags,
16347 +                                            unsigned long *persistent)
16348 +{
16349 +       u32_t relval_reloc_type = relval >> 27;
16350 +       u32_t insn = *rp;
16351 +
16352 +       if (*persistent) {
16353 +               /*
16354 +                * relval holds the relocation that has to be adjusted.
16355 +                */
16356 +               if (relval == 0) {
16357 +                       *persistent = 0;
16358 +               }
16359 +
16360 +               return relval;
16361 +       }
16362 +
16363 +       if (relval_reloc_type == R_UBICOM32_32) {
16364 +               /*
16365 +                * insn holds the relocation
16366 +                */
16367 +               return insn;
16368 +       }
16369 +
16370 +       /*
16371 +        * We don't know this one.
16372 +        */
16373 +       return 0;
16374 +}
16375 +
16376 +void ubicom32_flat_put_addr_at_rp(unsigned long *rp,
16377 +                                 u32_t val,
16378 +                                 u32_t relval,
16379 +                                 unsigned long *persistent)
16380 +{
16381 +       u32_t reloc_type = (relval >> 27) & 0x1f;
16382 +       u32_t insn = *rp;
16383 +
16384 +       /*
16385 +        * If persistent is set then it contains the relocation type.
16386 +        */
16387 +       if (*persistent) {
16388 +               /*
16389 +                * If persistent is set then it contains the relocation type.
16390 +                */
16391 +               reloc_type = (*persistent >> 27) & 0x1f;
16392 +       }
16393 +
16394 +       switch (reloc_type) {
16395 +       case R_UBICOM32_32:
16396 +               /*
16397 +                * Store the 32 bits as is.
16398 +                */
16399 +               *rp = val;
16400 +               break;
16401 +       case R_UBICOM32_HI24:
16402 +               {
16403 +                       /*
16404 +                        * 24 bit relocation that is part of the MOVEAI
16405 +                        * instruction. The 24 bits come from bits 7 - 30 of the
16406 +                        * relocation. The 24 bits eventually get split into 2
16407 +                        * fields in the instruction encoding.
16408 +                        *
16409 +                        * - Bits 7 - 27 of the relocation are encoded into bits
16410 +                        * 0 - 20 of the instruction.
16411 +                        *
16412 +                        * - Bits 28 - 30 of the relocation are encoded into bit
16413 +                        * 24 - 26 of the instruction.
16414 +                        */
16415 +                       u32_t mask = 0x1fffff | (0x7 << 24);
16416 +                       u32_t valid24bits = (val >> 7) & 0xffffff;
16417 +                       u32_t bot_21 = valid24bits & 0x1fffff;
16418 +                       u32_t upper_3_bits = ((valid24bits & 0xe00000) << 3);
16419 +                       insn &= ~mask;
16420 +
16421 +                       insn |= bot_21;
16422 +                       insn |= upper_3_bits;
16423 +                       *rp = insn;
16424 +               }
16425 +               break;
16426 +       case R_UBICOM32_LO7_S:
16427 +       case R_UBICOM32_LO7_2_S:
16428 +       case R_UBICOM32_LO7_4_S:
16429 +               {
16430 +                       /*
16431 +                        * Bits 0 - 6 of the relocation are encoded into the
16432 +                        * 7bit unsigned immediate fields of the SOURCE-1 field
16433 +                        * of the instruction.  The immediate value is left
16434 +                        * shifted by (0, 1, 2) based on the operand size.
16435 +                        */
16436 +                       u32_t mask = 0x1f | (0x3 << 8);
16437 +                       u32_t bottom, top;
16438 +                       val &= 0x7f;
16439 +                       if (reloc_type == R_UBICOM32_LO7_2_S) {
16440 +                               val >>= 1;
16441 +                       } else if (reloc_type == R_UBICOM32_LO7_4_S) {
16442 +                               val >>= 2;
16443 +                       }
16444 +
16445 +                       bottom  = val & 0x1f;
16446 +                       top = val >> 5;
16447 +                       insn &= ~mask;
16448 +                       insn |= bottom;
16449 +                       insn |= (top << 8);
16450 +                       BUG_ON(*rp != insn);
16451 +                       *rp = insn;
16452 +                       break;
16453 +               }
16454 +       case R_UBICOM32_LO7_D:
16455 +       case R_UBICOM32_LO7_2_D:
16456 +       case R_UBICOM32_LO7_4_D:
16457 +               {
16458 +                       /*
16459 +                        * Bits 0 - 6 of the relocation are encoded into the
16460 +                        * 7bit unsigned immediate fields of the DESTINATION
16461 +                        * field of the instruction.  The immediate value is
16462 +                        * left shifted by (0, 1, 2) based on the operand size.
16463 +                        */
16464 +                       u32_t mask = (0x1f | (0x3 << 8)) << 16;
16465 +                       u32_t bottom, top;
16466 +                       val &= 0x7f;
16467 +                       if (reloc_type == R_UBICOM32_LO7_2_D) {
16468 +                               val >>= 1;
16469 +                       } else if (reloc_type == R_UBICOM32_LO7_4_D) {
16470 +                               val >>= 2;
16471 +                       }
16472 +                       bottom  = (val & 0x1f) << 16;
16473 +                       top = (val >> 5) << 16;
16474 +                       insn &= ~mask;
16475 +                       insn |= bottom;
16476 +                       insn |= (top << 8);
16477 +                       BUG_ON(*rp != insn);
16478 +                       *rp = insn;
16479 +                       break;
16480 +               }
16481 +       case R_UBICOM32_LO7_CALLI:
16482 +       case R_UBICOM32_LO16_CALLI:
16483 +               {
16484 +                       /*
16485 +                        * Extract the offset for a CALLI instruction. The
16486 +                        * offsets can be either 7 bits or 18 bits. Since all
16487 +                        * instructions in ubicom32 architecture are at work
16488 +                        * aligned addresses the truncated offset is right
16489 +                        * shifted by 2 before being encoded in the instruction.
16490 +                        */
16491 +                       if (reloc_type == R_UBICOM32_LO7_CALLI) {
16492 +                               val &= 0x7f;
16493 +                       } else {
16494 +                               val &= 0x3ffff;
16495 +                       }
16496 +
16497 +                       val >>= 2;
16498 +
16499 +                       insn &= ~0x071f071f;
16500 +                       insn |= (val & 0x1f) << 0;
16501 +                       val >>= 5;
16502 +                       insn |= (val & 0x07) << 8;
16503 +                       val >>= 3;
16504 +                       insn |= (val & 0x1f) << 16;
16505 +                       val >>= 5;
16506 +                       insn |= (val & 0x07) << 24;
16507 +                       if (reloc_type == R_UBICOM32_LO7_CALLI) {
16508 +                               BUG_ON(*rp != insn);
16509 +                       }
16510 +                       *rp = insn;
16511 +               }
16512 +               break;
16513 +       }
16514 +
16515 +       if (*persistent) {
16516 +               *persistent = 0;
16517 +       }
16518 +}
16519 --- /dev/null
16520 +++ b/arch/ubicom32/kernel/head.S
16521 @@ -0,0 +1,247 @@
16522 +/*
16523 + * arch/ubicom32/kernel/head.S
16524 + *     <TODO: Replace with short file description>
16525 + *
16526 + * (C) Copyright 2009, Ubicom, Inc.
16527 + *
16528 + * This file is part of the Ubicom32 Linux Kernel Port.
16529 + *
16530 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16531 + * it and/or modify it under the terms of the GNU General Public License
16532 + * as published by the Free Software Foundation, either version 2 of the
16533 + * License, or (at your option) any later version.
16534 + *
16535 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16536 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16537 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16538 + * the GNU General Public License for more details.
16539 + *
16540 + * You should have received a copy of the GNU General Public License
16541 + * along with the Ubicom32 Linux Kernel Port.  If not,
16542 + * see <http://www.gnu.org/licenses/>.
16543 + *
16544 + * Ubicom32 implementation derived from (with many thanks):
16545 + *   arch/m68knommu
16546 + *   arch/blackfin
16547 + *   arch/parisc
16548 + */
16549 +#include <linux/sys.h>
16550 +#include <linux/linkage.h>
16551 +#include <asm/asm-offsets.h>
16552 +#include <asm/page_offset.h>
16553 +#define __ASM__
16554 +#include <asm/ip5000.h>
16555 +
16556 +
16557 +#define SRC_AN A3
16558 +#define DST_AN A4
16559 +
16560 +#define PARAM_DN D0
16561 +#define TMP_DN D15
16562 +#define TMP2_DN D14
16563 +
16564 +/*
16565 + * The following code is placed at the start of the Linux section of memory.
16566 + * This is the primary entry point for Linux.
16567 + *
16568 + * However, we also want the syscall entry/exit code to be at a fixed address.
16569 + * So we take the primary entry point and reserve 16 bytes.  That address is
16570 + * where the system_call entry point exists.  This 16 bytes basically allows
16571 + * us to jump around the system_call entry point code to the actual startup
16572 + * code.
16573 + *
16574 + * Linux Memory Map (see vlinux.lds.S):
16575 + * 0x40400000 - Primary Entry Point for Linux (jump around code below).
16576 + * 0x40400010 - Syscall Entry Point.
16577 + */
16578 +
16579 +       .sect   .skip_syscall, "ax", @progbits
16580 +       .global __skip_syscall_section
16581 +__skip_syscall_section:
16582 +       moveai          A3, #%hi(_start)
16583 +       lea.1           A3, %lo(_start)(A3)
16584 +       ret             A3
16585 +/*
16586 + * __os_node_offset contains the offset from KERNELBASE to the os_node, it is
16587 + * not intended to be used by anything except the boot code.
16588 + */
16589 +__os_node_offset:
16590 +.long  (_os_node - CONFIG_KERNELBASE)
16591 +
16592 +.text
16593 +.global        _start
16594 +
16595 +/*
16596 + * start()
16597 + *     This is the start of the Linux kernel.
16598 + */
16599 +_start:
16600 +       move.4          SCRATCHPAD1, #0
16601 +
16602 +
16603 +/*
16604 + * Setup the range registers... the loader has setup a few, but we will go ahead
16605 + * and correct them for our own limits. Note that once set these are never
16606 + * changed again.  The ranges are as follows
16607 + *
16608 + *  D_RANGE0 - io block (set up by loaded)
16609 + *
16610 + *  I_RANGE0 and D_RANGE1 - kernel/ultra loader address space bottom of ocm-> top
16611 + *     of ram typically 0x3ffc0000 - 0x440000000
16612 + *  I_RANGE1 - kernel / userspace transition area (aka syscalls, context switches)
16613 + *     typically 0x40400000 - ~0x40400400
16614 + *  I_RANGE2 / D_RANGE2 - slab area
16615 + *     typically 0x40A00000 - ~0x44000000
16616 + *
16617 + *  I_RANGE4, D_RANGE3, D_RANGE3 - unused.
16618 + */
16619 +       moveai          SRC_AN, #%hi(PAGE_OFFSET_RAW)
16620 +       lea.4           SRC_AN, %lo(PAGE_OFFSET_RAW)(SRC_AN)
16621 +       move.4          D_RANGE1_LO, SRC_AN
16622 +       move.4          I_RANGE0_LO, SRC_AN
16623 +
16624 +; don't try to calculate I_RANGE_HI, see below
16625 +;      moveai          SRC_AN, #%hi(___init_end-4)
16626 +;      lea.4           SRC_AN, %lo(___init_end-4)(SRC_AN)
16627 +;      move.4          I_RANGE0_HI, SRC_AN
16628 +
16629 +       moveai          SRC_AN, #%hi(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)
16630 +       lea.4           SRC_AN, %lo(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)(SRC_AN)
16631 +       move.4          D_RANGE1_HI, SRC_AN
16632 +
16633 +; for now allow the whole ram to be executable as well so we don't run into problems
16634 +; once we load user more code.
16635 +       move.4          I_RANGE0_HI, SRC_AN
16636 +
16637 +#ifdef CONFIG_PROTECT_KERNEL
16638 +; when kernel protection is enabled, we only open up syscall and non kernel text
16639 +; for userspace apps, for now only irange registers registers 1 and 2 are used for userspace.
16640 +
16641 +       ;; syscall range
16642 +       moveai          SRC_AN, #%hi(_begin)
16643 +       lea.4           SRC_AN, %lo(_begin)(SRC_AN)
16644 +       move.4          I_RANGE1_LO, SRC_AN
16645 +       moveai          SRC_AN, #%hi(__fixed_text_end)
16646 +       lea.4           SRC_AN, %lo(__fixed_text_end)(SRC_AN)
16647 +       move.4          I_RANGE1_HI, SRC_AN
16648 +
16649 +       ;; slab instructions
16650 +       moveai          SRC_AN, #%hi(_edata)
16651 +       lea.4           SRC_AN, %lo(_edata)(SRC_AN)
16652 +       move.4          I_RANGE2_LO, SRC_AN
16653 +       ;; End of DDR is already in range0 hi so just copy it.
16654 +       move.4          I_RANGE2_HI, I_RANGE0_HI
16655 +
16656 +       ;; slab data (same as slab instructions but starting a little earlier).
16657 +       moveai          SRC_AN, #%hi(_data_protection_end)
16658 +       lea.4           SRC_AN, %lo(_data_protection_end)(SRC_AN)
16659 +       move.4          D_RANGE2_LO, SRC_AN
16660 +       move.4          D_RANGE2_HI, I_RANGE0_HI
16661 +
16662 +;; enable ranges
16663 +       ;; skip I_RANGE0_EN
16664 +       move.4          I_RANGE1_EN, #-1
16665 +       move.4          I_RANGE2_EN, #-1
16666 +       move.4          I_RANGE3_EN, #0
16667 +
16668 +       ;; skip D_RANGE0_EN or D_RANGE1_EN
16669 +       move.4          D_RANGE2_EN, #-1
16670 +       move.4          D_RANGE3_EN, #0
16671 +       move.4          D_RANGE4_EN, #0
16672 +#endif
16673 +
16674 +;
16675 +; If __ocm_free_begin is smaller than __ocm_free_end the
16676 +; setup OCM text and data ram banks properly
16677 +;
16678 +       moveai          DST_AN, #%hi(__ocm_free_begin)
16679 +       lea.4           TMP_DN, %lo(__ocm_free_begin)(DST_AN)
16680 +       moveai          DST_AN, #%hi(__ocm_free_end)
16681 +       lea.4           TMP2_DN, %lo(__ocm_free_end)(DST_AN)
16682 +       sub.4           #0, TMP2_DN, TMP_DN
16683 +       jmple.f         2f
16684 +       moveai          DST_AN, #%hi(__data_begin)
16685 +       lea.4           TMP_DN, %lo(__data_begin)(DST_AN)
16686 +       moveai          DST_AN, #%hi(OCMSTART)
16687 +       lea.4           TMP2_DN, %lo(OCMSTART)(DST_AN)
16688 +       sub.4           TMP_DN, TMP_DN, TMP2_DN
16689 +       lsr.4           TMP_DN, TMP_DN, #15
16690 +       lsl.4           TMP_DN, #1, TMP_DN
16691 +       moveai          DST_AN, #%hi(OCMC_BASE)
16692 +       add.4           OCMC_BANK_MASK(DST_AN), #-1, TMP_DN
16693 +       pipe_flush      0
16694 +2:
16695 +;
16696 +; Load .ocm_text
16697 +;
16698 +       moveai          DST_AN, #%hi(__ocm_text_run_end)
16699 +       lea.4           TMP_DN, %lo(__ocm_text_run_end)(DST_AN)
16700 +       moveai          DST_AN, #%hi(__ocm_text_run_begin)
16701 +       lea.4           DST_AN, %lo(__ocm_text_run_begin)(DST_AN)
16702 +       moveai          SRC_AN, #%hi(__ocm_text_load_begin)
16703 +       lea.4           SRC_AN, %lo(__ocm_text_load_begin)(SRC_AN)
16704 +       jmpt.t          2f
16705 +
16706 +1:      move.4          (DST_AN)4++, (SRC_AN)4++
16707 +
16708 +2:      sub.4           #0, DST_AN, TMP_DN
16709 +       jmpne.t         1b
16710 +
16711 +;
16712 +; Load .ocm_data
16713 +;
16714 +       moveai          DST_AN, #%hi(__ocm_data_run_end)
16715 +       lea.4           TMP_DN, %lo(__ocm_data_run_end)(DST_AN)
16716 +       moveai          DST_AN, #%hi(__ocm_data_run_begin)
16717 +       lea.4           DST_AN, %lo(__ocm_data_run_begin)(DST_AN)
16718 +       moveai          SRC_AN, #%hi(__ocm_data_load_begin)
16719 +       lea.4           SRC_AN, %lo(__ocm_data_load_begin)(SRC_AN)
16720 +       jmpt.t          2f
16721 +
16722 +1:      move.4          (DST_AN)4++, (SRC_AN)4++
16723 +
16724 +2:      sub.4           #0, DST_AN, TMP_DN
16725 +       jmpne.t         1b
16726 +
16727 +; Clear .bss
16728 +;
16729 +       moveai          SRC_AN, #%hi(_ebss)
16730 +       lea.4           TMP_DN, %lo(_ebss)(SRC_AN)
16731 +       moveai          DST_AN, #%hi(_sbss)
16732 +       lea.4           DST_AN, %lo(_sbss)(DST_AN)
16733 +       jmpt.t          2f
16734 +
16735 +1:     move.4          (DST_AN)4++, #0
16736 +
16737 +2:     sub.4           #0, DST_AN, TMP_DN
16738 +       jmpne.t         1b
16739 +
16740 +; save our parameter to devtree (after clearing .bss)
16741 +       moveai          DST_AN, #%hi(devtree)
16742 +       lea.4           DST_AN, %lo(devtree)(DST_AN)
16743 +       move.4          (DST_AN), PARAM_DN
16744 +
16745 +       moveai          sp, #%hi(init_thread_union)
16746 +       lea.4           sp, %lo(init_thread_union)(sp)
16747 +       movei           TMP_DN, #ASM_THREAD_SIZE
16748 +       add.4           sp, sp, TMP_DN
16749 +       move.4          -4(sp)++, #0 ; nesting level = 0
16750 +       move.4          -4(sp)++, #1 ; KERNEL_THREAD
16751 +
16752 +;; ip3k-elf-gdb backend now sets scratchpad3 to 1 when either continue
16753 +;; or single step commands are issued. scratchpad3 is set to 0 when the
16754 +;; debugger detaches from the board.
16755 +       move.4          TMP_DN, scratchpad3
16756 +       lsl.4           TMP_DN, TMP_DN, #0x0
16757 +       jmpeq.f         _jump_to_start_kernel
16758 +_ok_to_set_break_points_in_linux:
16759 +;; THREAD_STALL
16760 +       move.4          mt_dbg_active_clr,#-1
16761 +;; stalling the threads isn't instantaneous.. need to flush the pipe.
16762 +       pipe_flush      0
16763 +       pipe_flush      0
16764 +
16765 +_jump_to_start_kernel:
16766 +       moveai          SRC_AN, #%hi(start_kernel)
16767 +       lea.4           SRC_AN, %lo(start_kernel)(SRC_AN)
16768 +       ret             SRC_AN
16769 --- /dev/null
16770 +++ b/arch/ubicom32/kernel/init_task.c
16771 @@ -0,0 +1,62 @@
16772 +/*
16773 + * arch/ubicom32/kernel/init_task.c
16774 + *   Ubicom32 architecture task initialization implementation.
16775 + *
16776 + * (C) Copyright 2009, Ubicom, Inc.
16777 + *
16778 + * This file is part of the Ubicom32 Linux Kernel Port.
16779 + *
16780 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16781 + * it and/or modify it under the terms of the GNU General Public License
16782 + * as published by the Free Software Foundation, either version 2 of the
16783 + * License, or (at your option) any later version.
16784 + *
16785 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16786 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16787 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16788 + * the GNU General Public License for more details.
16789 + *
16790 + * You should have received a copy of the GNU General Public License
16791 + * along with the Ubicom32 Linux Kernel Port.  If not,
16792 + * see <http://www.gnu.org/licenses/>.
16793 + *
16794 + * Ubicom32 implementation derived from (with many thanks):
16795 + *   arch/m68knommu
16796 + *   arch/blackfin
16797 + *   arch/parisc
16798 + */
16799 +#include <linux/mm.h>
16800 +#include <linux/module.h>
16801 +#include <linux/sched.h>
16802 +#include <linux/init.h>
16803 +#include <linux/init_task.h>
16804 +#include <linux/fs.h>
16805 +#include <linux/mqueue.h>
16806 +#include <linux/uaccess.h>
16807 +#include <asm/pgtable.h>
16808 +
16809 +static struct fs_struct init_fs = INIT_FS;
16810 +static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
16811 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
16812 +struct mm_struct init_mm = INIT_MM(init_mm);
16813 +EXPORT_SYMBOL(init_mm);
16814 +
16815 +/*
16816 + * Initial task structure.
16817 + *
16818 + * All other task structs will be allocated on slabs in fork.c
16819 + */
16820 +struct task_struct init_task = INIT_TASK(init_task);
16821 +
16822 +EXPORT_SYMBOL(init_task);
16823 +
16824 +/*
16825 + * Initial thread structure.
16826 + *
16827 + * We need to make sure that this is 8192-byte aligned due to the
16828 + * way process stacks are handled. This is done by having a special
16829 + * "init_task" linker map entry..
16830 + */
16831 +union thread_union init_thread_union
16832 +       __attribute__((__section__(".data.init_task"))) =
16833 +               { INIT_THREAD_INFO(init_task) };
16834 --- /dev/null
16835 +++ b/arch/ubicom32/kernel/irq.c
16836 @@ -0,0 +1,596 @@
16837 +/*
16838 + * arch/ubicom32/kernel/irq.c
16839 + *   Ubicom32 architecture IRQ support.
16840 + *
16841 + * (C) Copyright 2009, Ubicom, Inc.
16842 + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
16843 + *
16844 + * This file is part of the Ubicom32 Linux Kernel Port.
16845 + *
16846 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16847 + * it and/or modify it under the terms of the GNU General Public License
16848 + * as published by the Free Software Foundation, either version 2 of the
16849 + * License, or (at your option) any later version.
16850 + *
16851 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
16852 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16853 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16854 + * the GNU General Public License for more details.
16855 + *
16856 + * You should have received a copy of the GNU General Public License
16857 + * along with the Ubicom32 Linux Kernel Port.  If not,
16858 + * see <http://www.gnu.org/licenses/>.
16859 + *
16860 + * Ubicom32 implementation derived from (with many thanks):
16861 + *   arch/m68knommu
16862 + *   arch/blackfin
16863 + *   arch/parisc
16864 + */
16865 +
16866 +#include <linux/types.h>
16867 +#include <linux/irq.h>
16868 +#include <linux/init.h>
16869 +#include <linux/kernel.h>
16870 +#include <linux/kernel_stat.h>
16871 +#include <linux/module.h>
16872 +#include <linux/seq_file.h>
16873 +#include <linux/proc_fs.h>
16874 +#include <asm/system.h>
16875 +#include <asm/traps.h>
16876 +#include <asm/ldsr.h>
16877 +#include <asm/ip5000.h>
16878 +#include <asm/machdep.h>
16879 +#include <asm/asm-offsets.h>
16880 +#include <asm/thread.h>
16881 +#include <asm/devtree.h>
16882 +
16883 +unsigned int irq_soft_avail;
16884 +static struct irqaction ubicom32_reserve_action[NR_IRQS];
16885 +
16886 +#if !defined(CONFIG_DEBUG_IRQMEASURE)
16887 +#define IRQ_DECLARE_MEASUREMENT
16888 +#define IRQ_MEASUREMENT_START()
16889 +#define IRQ_MEASUREMENT_END(irq)
16890 +#else
16891 +#define IRQ_DECLARE_MEASUREMENT \
16892 +       int __diff;             \
16893 +       unsigned int __tstart;
16894 +
16895 +#define IRQ_MEASUREMENT_START() \
16896 +       __tstart = UBICOM32_IO_TIMER->sysval;
16897 +
16898 +#define IRQ_MEASUREMENT_END(irq) \
16899 +       __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
16900 +       irq_measurement_update((irq), __diff);
16901 +
16902 +/*
16903 + * We keep track of the time spent in both irq_enter()
16904 + * and irq_exit().
16905 + */
16906 +#define IRQ_WEIGHT 32
16907 +
16908 +struct irq_measurement {
16909 +       volatile unsigned int min;
16910 +       volatile unsigned int avg;
16911 +       volatile unsigned int max;
16912 +};
16913 +
16914 +static DEFINE_SPINLOCK(irq_measurement_lock);
16915 +
16916 +/*
16917 + *  Add 1 in for softirq (irq_exit());
16918 + */
16919 +static struct irq_measurement irq_measurements[NR_IRQS + 1];
16920 +
16921 +/*
16922 + * irq_measurement_update()
16923 + *     Update an entry in the measurement array for this irq.
16924 + */
16925 +static void irq_measurement_update(int irq, int sample)
16926 +{
16927 +       struct irq_measurement *im = &irq_measurements[irq];
16928 +       spin_lock(&irq_measurement_lock);
16929 +       if ((im->min == 0) || (im->min > sample)) {
16930 +               im->min = sample;
16931 +       }
16932 +       if (im->max < sample) {
16933 +               im->max = sample;
16934 +       }
16935 +       im->avg = ((im->avg * (IRQ_WEIGHT - 1)) + sample) / IRQ_WEIGHT;
16936 +       spin_unlock(&irq_measurement_lock);
16937 +}
16938 +#endif
16939 +
16940 +/*
16941 + * irq_kernel_stack_check()
16942 + *     See if the kernel stack is within STACK_WARN of the end.
16943 + */
16944 +static void irq_kernel_stack_check(int irq, struct pt_regs *regs)
16945 +{
16946 +#ifdef CONFIG_DEBUG_STACKOVERFLOW
16947 +       unsigned long sp;
16948 +
16949 +       /*
16950 +        * Make sure that we are not close to the top of the stack and thus
16951 +        * can not really service this interrupt.
16952 +        */
16953 +       asm volatile (
16954 +               "and.4          %0, SP, %1 \n\t"
16955 +               : "=d" (sp)
16956 +               : "d" (THREAD_SIZE - 1)
16957 +               : "cc"
16958 +       );
16959 +
16960 +       if (sp < (sizeof(struct thread_info) + STACK_WARN)) {
16961 +               printk(KERN_WARNING
16962 +                       "cpu[%d]: possible overflow detected sp remain: %p, "
16963 +                      "irq: %d, regs: %p\n",
16964 +                       thread_get_self(), (void *)sp, irq, regs);
16965 +               dump_stack();
16966 +       }
16967 +
16968 +       if (sp < (sizeof(struct thread_info) + 16)) {
16969 +               THREAD_STALL;
16970 +       }
16971 +#endif
16972 +}
16973 +
16974 +/*
16975 + * irq_get_lsb()
16976 + *     Get the LSB set in value
16977 + */
16978 +static int irq_get_lsb(unsigned int value)
16979 +{
16980 +       static unsigned char irq_bits[8] = {
16981 +               3, 0, 1, 0, 2, 0, 1, 0
16982 +       };
16983 +       u32_t nextbit = 0;
16984 +
16985 +       value = (value >> nextbit) | (value << ((sizeof(value) * 8) - nextbit));
16986 +
16987 +       /*
16988 +        * It's unlikely that we find that we execute the body of this while
16989 +        * loop.  50% of the time we won't take this at all and then of the
16990 +        * cases where we do about 50% of those we only execute once.
16991 +        */
16992 +       if (!(value & 0xffff)) {
16993 +               nextbit += 0x10;
16994 +               value >>= 16;
16995 +       }
16996 +
16997 +       if (!(value & 0xff)) {
16998 +               nextbit += 0x08;
16999 +               value >>= 8;
17000 +       }
17001 +
17002 +       if (!(value & 0xf)) {
17003 +               nextbit += 0x04;
17004 +               value >>= 4;
17005 +       }
17006 +
17007 +       nextbit += irq_bits[value & 0x7];
17008 +       if (nextbit > 63) {
17009 +               panic("nextbit out of range: %d\n", nextbit);
17010 +       }
17011 +       return nextbit;
17012 +}
17013 +
17014 +/*
17015 + * ubicom32_reserve_handler()
17016 + *     Bogus handler associated with pre-reserved IRQ(s).
17017 + */
17018 +static irqreturn_t ubicom32_reserve_handler(int irq, void *dev_id)
17019 +{
17020 +       BUG();
17021 +       return IRQ_HANDLED;
17022 +}
17023 +
17024 +/*
17025 + * __irq_disable_vector()
17026 + *     Disable the interrupt by clearing the appropriate bit in the
17027 + *     LDSR Mask Register.
17028 + */
17029 +static void __irq_disable_vector(unsigned int irq)
17030 +{
17031 +       ldsr_disable_vector(irq);
17032 +}
17033 +
17034 +/*
17035 + * __irq_ack_vector()
17036 + *     Acknowledge the specific interrupt by clearing the associate bit in
17037 + *     hardware
17038 + */
17039 +static void __irq_ack_vector(unsigned int irq)
17040 +{
17041 +       if (irq < 32) {
17042 +               asm volatile ("move.4 INT_CLR0, %0" : : "d" (1 << irq));
17043 +       } else {
17044 +               asm volatile ("move.4 INT_CLR1, %0" : : "d" (1 << (irq - 32)));
17045 +       }
17046 +}
17047 +
17048 +/*
17049 + * __irq_enable_vector()
17050 + *     Clean and then enable the interrupt by setting the appropriate bit in
17051 + *     the LDSR Mask Register.
17052 + */
17053 +static void __irq_enable_vector(unsigned int irq)
17054 +{
17055 +       /*
17056 +        * Acknowledge, really clear the vector.
17057 +        */
17058 +       __irq_ack_vector(irq);
17059 +       ldsr_enable_vector(irq);
17060 +}
17061 +
17062 +/*
17063 + * __irq_mask_vector()
17064 + */
17065 +static void __irq_mask_vector(unsigned int irq)
17066 +{
17067 +       ldsr_mask_vector(irq);
17068 +}
17069 +
17070 +/*
17071 + * __irq_unmask_vector()
17072 + */
17073 +static void __irq_unmask_vector(unsigned int irq)
17074 +{
17075 +       ldsr_unmask_vector(irq);
17076 +}
17077 +
17078 +/*
17079 + * __irq_end_vector()
17080 + *     Called once an interrupt is completed (reset the LDSR mask).
17081 + */
17082 +static void __irq_end_vector(unsigned int irq)
17083 +{
17084 +       ldsr_unmask_vector(irq);
17085 +}
17086 +
17087 +#if defined(CONFIG_SMP)
17088 +/*
17089 + * __irq_set_affinity()
17090 + *     Set the cpu affinity for this interrupt.
17091 + */
17092 +static void __irq_set_affinity(unsigned int irq, cpumask_t dest)
17093 +{
17094 +       smp_set_affinity(irq, dest);
17095 +       irq_desc[irq].affinity = dest;
17096 +}
17097 +#endif
17098 +
17099 +/*
17100 + * On-Chip Generic Interrupt function handling.
17101 + */
17102 +static struct irq_chip ubicom32_irq_chip = {
17103 +       .name           = "Ubicom32",
17104 +       .startup        = NULL,
17105 +       .shutdown       = NULL,
17106 +       .enable         = __irq_enable_vector,
17107 +       .disable        = __irq_disable_vector,
17108 +       .ack            = __irq_ack_vector,
17109 +       .mask           = __irq_mask_vector,
17110 +       .unmask         = __irq_unmask_vector,
17111 +       .end            = __irq_end_vector,
17112 +#if defined(CONFIG_SMP)
17113 +       .set_affinity   = __irq_set_affinity,
17114 +#endif
17115 +};
17116 +
17117 +/*
17118 + * do_IRQ()
17119 + *     Primary interface for handling IRQ() requests.
17120 + */
17121 +asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
17122 +{
17123 +       struct pt_regs *oldregs;
17124 +       struct thread_info *ti;
17125 +       unsigned long sp;
17126 +
17127 +       IRQ_DECLARE_MEASUREMENT;
17128 +
17129 +       oldregs = set_irq_regs(regs);
17130 +
17131 +       /*
17132 +        * Before we call the handler and potentially enable
17133 +        * interrupts, track the nesting level.
17134 +        */
17135 +       asm volatile (
17136 +               "and.4          %0, SP, %1 \n\t"
17137 +               : "=d" (sp)
17138 +               : "d" (~(THREAD_SIZE - 1))
17139 +               : "cc"
17140 +       );
17141 +       ti = (struct thread_info *)sp;
17142 +       ti->interrupt_nesting++;
17143 +
17144 +       /*
17145 +        * Check for possible stack overflow on the kernel stack.
17146 +        */
17147 +       irq_kernel_stack_check(irq, regs);
17148 +
17149 +       /*
17150 +        * Execute the IRQ handler and any pending SoftIRQ requests.
17151 +        */
17152 +       BUG_ON(!irqs_disabled());
17153 +       irq_enter();
17154 +
17155 +       BUG_ON(!irqs_disabled());
17156 +       IRQ_MEASUREMENT_START();
17157 +       __do_IRQ(irq);
17158 +       IRQ_MEASUREMENT_END(irq);
17159 +       BUG_ON(!irqs_disabled());
17160 +
17161 +       IRQ_MEASUREMENT_START();
17162 +       irq_exit();
17163 +       IRQ_MEASUREMENT_END(NR_IRQS);
17164 +       BUG_ON(!irqs_disabled());
17165 +
17166 +       set_irq_regs(oldregs);
17167 +       ti->interrupt_nesting--;
17168 +}
17169 +
17170 +/*
17171 + * irq_soft_alloc()
17172 + *     Allocate a soft IRQ.
17173 + */
17174 +int irq_soft_alloc(unsigned int *soft)
17175 +{
17176 +       if (irq_soft_avail == 0) {
17177 +               printk(KERN_NOTICE "no soft irqs to allocate\n");
17178 +               return -EFAULT;
17179 +       }
17180 +
17181 +       *soft = irq_get_lsb(irq_soft_avail);
17182 +       irq_soft_avail &= ~(1 << *soft);
17183 +       return 0;
17184 +}
17185 +
17186 +/*
17187 + * ack_bad_irq()
17188 + *     Called to handle an bad irq request.
17189 + */
17190 +void ack_bad_irq(unsigned int irq)
17191 +{
17192 +       printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
17193 +       __irq_end_vector(irq);
17194 +}
17195 +
17196 +/*
17197 + * show_interrupts()
17198 + *     Return a string that displays the state of each of the interrupts.
17199 + */
17200 +int show_interrupts(struct seq_file *p, void *v)
17201 +{
17202 +       struct irqaction *ap;
17203 +       int irq = *((loff_t *) v);
17204 +       int j;
17205 +
17206 +       if (irq >= NR_IRQS) {
17207 +               return 0;
17208 +       }
17209 +
17210 +       if (irq == 0) {
17211 +               seq_puts(p, "           ");
17212 +               for_each_online_cpu(j) {
17213 +                       seq_printf(p, "CPU%d       ", j);
17214 +               }
17215 +               seq_putc(p, '\n');
17216 +       }
17217 +
17218 +       ap = irq_desc[irq].action;
17219 +       if (ap) {
17220 +               seq_printf(p, "%3d: ", irq);
17221 +               for_each_online_cpu(j) {
17222 +                       seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
17223 +               }
17224 +               seq_printf(p, "%14s  ", irq_desc[irq].chip->name);
17225 +               seq_printf(p, "%s", ap->name);
17226 +               for (ap = ap->next; ap; ap = ap->next) {
17227 +                       seq_printf(p, ", %s", ap->name);
17228 +               }
17229 +               seq_putc(p, '\n');
17230 +       }
17231 +       return 0;
17232 +}
17233 +
17234 +#if defined(CONFIG_DEBUG_IRQMEASURE)
17235 +static unsigned int irq_cycles_to_micro(unsigned int cycles, unsigned int frequency)
17236 +{
17237 +       unsigned int micro = (cycles / (frequency / 1000000));
17238 +       return micro;
17239 +}
17240 +
17241 +/*
17242 + * irq_measurement_show()
17243 + *     Print out the min, avg, max values for each IRQ
17244 + *
17245 + * By request, the max value is reset after each dump.
17246 + */
17247 +static int irq_measurement_show(struct seq_file *p, void *v)
17248 +{
17249 +       struct irqaction *ap;
17250 +       unsigned int freq = processor_frequency();
17251 +       int irq = *((loff_t *) v);
17252 +
17253 +
17254 +       if (irq == 0) {
17255 +               seq_puts(p, "\tmin\tavg\tmax\t(micro-seconds)\n");
17256 +       }
17257 +
17258 +       if (irq > NR_IRQS) {
17259 +               return 0;
17260 +       }
17261 +
17262 +       if (irq == NR_IRQS) {
17263 +               unsigned int min, avg, max;
17264 +               spin_lock(&irq_measurement_lock);
17265 +               min = irq_cycles_to_micro(irq_measurements[irq].min, freq);
17266 +               avg = irq_cycles_to_micro(irq_measurements[irq].avg, freq);
17267 +               max = irq_cycles_to_micro(irq_measurements[irq].max, freq);
17268 +               irq_measurements[irq].max = 0;
17269 +               spin_unlock(&irq_measurement_lock);
17270 +               seq_printf(p, "   \t%u\t%u\t%u\tsoftirq\n", min, avg, max);
17271 +               return 0;
17272 +       }
17273 +
17274 +       ap = irq_desc[irq].action;
17275 +       if (ap) {
17276 +               unsigned int min, avg, max;
17277 +               spin_lock(&irq_measurement_lock);
17278 +               min = irq_cycles_to_micro(irq_measurements[irq].min, freq);
17279 +               avg = irq_cycles_to_micro(irq_measurements[irq].avg, freq);
17280 +               max = irq_cycles_to_micro(irq_measurements[irq].max, freq);
17281 +               irq_measurements[irq].max = 0;
17282 +               spin_unlock(&irq_measurement_lock);
17283 +               seq_printf(p, "%2u:\t%u\t%u\t%u\t%s\n", irq, min, avg, max, ap->name);
17284 +       }
17285 +       return 0;
17286 +}
17287 +
17288 +static void *irq_measurement_start(struct seq_file *f, loff_t *pos)
17289 +{
17290 +       return (*pos <= NR_IRQS) ? pos : NULL;
17291 +}
17292 +
17293 +static void *irq_measurement_next(struct seq_file *f, void *v, loff_t *pos)
17294 +{
17295 +       (*pos)++;
17296 +       if (*pos > NR_IRQS)
17297 +               return NULL;
17298 +       return pos;
17299 +}
17300 +
17301 +static void irq_measurement_stop(struct seq_file *f, void *v)
17302 +{
17303 +       /* Nothing to do */
17304 +}
17305 +
17306 +static const struct seq_operations irq_measurement_seq_ops = {
17307 +       .start = irq_measurement_start,
17308 +       .next  = irq_measurement_next,
17309 +       .stop  = irq_measurement_stop,
17310 +       .show  = irq_measurement_show,
17311 +};
17312 +
17313 +static int irq_measurement_open(struct inode *inode, struct file *filp)
17314 +{
17315 +       return seq_open(filp, &irq_measurement_seq_ops);
17316 +}
17317 +
17318 +static const struct file_operations irq_measurement_fops = {
17319 +       .open           = irq_measurement_open,
17320 +       .read           = seq_read,
17321 +       .llseek         = seq_lseek,
17322 +       .release        = seq_release,
17323 +};
17324 +
17325 +static int __init irq_measurement_init(void)
17326 +{
17327 +       proc_create("irq_measurements", 0, NULL, &irq_measurement_fops);
17328 +       return 0;
17329 +}
17330 +module_init(irq_measurement_init);
17331 +#endif
17332 +
17333 +/*
17334 + * init_IRQ(void)
17335 + *     Initialize the on-chip IRQ subsystem.
17336 + */
17337 +void __init init_IRQ(void)
17338 +{
17339 +       int irq;
17340 +       struct devtree_node *p = NULL;
17341 +       struct devtree_node *iter = NULL;
17342 +       unsigned int mask = 0;
17343 +       unsigned int reserved = 0;
17344 +
17345 +       /*
17346 +        * Pull out the list of software interrupts that are avialable to
17347 +        * Linux and provide an allocation function for them.  The first
17348 +        * 24 interrupts of INT0 are software interrupts.
17349 +        */
17350 +       irq_soft_avail = 0;
17351 +       if (processor_interrupts(&irq_soft_avail, NULL) < 0) {
17352 +               printk(KERN_WARNING "No Soft IRQ(s) available\n");
17353 +       }
17354 +       irq_soft_avail &= ((1 << 24) - 1);
17355 +
17356 +       /*
17357 +        * Initialize all of the on-chip interrupt handling
17358 +        * to use a common set of interrupt functions.
17359 +        */
17360 +       for (irq = 0; irq < NR_IRQS; irq++) {
17361 +               irq_desc[irq].status = IRQ_DISABLED;
17362 +               irq_desc[irq].action = NULL;
17363 +               irq_desc[irq].depth = 1;
17364 +               set_irq_chip(irq, &ubicom32_irq_chip);
17365 +       }
17366 +
17367 +       /*
17368 +        * The sendirq of a devnode is not registered within Linux but instead
17369 +        * is used by the software I/O thread.  These interrupts are reserved.
17370 +        * The recvirq is used by Linux and registered by a device driver, these
17371 +        * are not reserved.
17372 +        *
17373 +        * recvirq(s) that are in the software interrupt range are not supposed
17374 +        * to be marked as reserved.  We track this while we scan the device
17375 +        * nodes.
17376 +        */
17377 +       p = devtree_find_next(&iter);
17378 +       while (p) {
17379 +               unsigned char sendirq, recvirq;
17380 +               devtree_irq(p, &sendirq, &recvirq);
17381 +
17382 +               /*
17383 +                * If the sendirq is valid, mark that irq as taken by the
17384 +                * devtree node.
17385 +                */
17386 +               if (sendirq < NR_IRQS) {
17387 +                       ubicom32_reserve_action[sendirq].handler =
17388 +                               ubicom32_reserve_handler;
17389 +                       ubicom32_reserve_action[sendirq].name = p->name;
17390 +                       irq_desc[sendirq].action =
17391 +                               &ubicom32_reserve_action[sendirq];
17392 +                       mask |= (1 << sendirq);
17393 +               }
17394 +
17395 +               /*
17396 +                * Track the relevant recieve IRQ(s)
17397 +                */
17398 +               if (recvirq < 24) {
17399 +                       mask |= (1 << recvirq);
17400 +               }
17401 +
17402 +               /*
17403 +                * Move to the next node.
17404 +                */
17405 +               p = devtree_find_next(&iter);
17406 +       }
17407 +
17408 +       /*
17409 +        * Remove these bits from the irq_soft_avail list and then use the
17410 +        * result as the list of pre-reserved IRQ(s).
17411 +        */
17412 +       reserved = ~irq_soft_avail & ~mask;
17413 +       for (irq = 0; irq < 24; irq++) {
17414 +               if ((reserved & (1 << irq))) {
17415 +                       ubicom32_reserve_action[irq].handler =
17416 +                               ubicom32_reserve_handler;
17417 +                       ubicom32_reserve_action[irq].name = "reserved";
17418 +                       irq_desc[irq].action = &ubicom32_reserve_action[irq];
17419 +               }
17420 +       }
17421 +
17422 +       /*
17423 +        * Initialize the LDSR which is the Ubicom32 programmable
17424 +        * interrupt controller.
17425 +        */
17426 +       ldsr_init();
17427 +
17428 +       /*
17429 +        * The Ubicom trap code needs a 2nd init after IRQ(s) are setup.
17430 +        */
17431 +       trap_init_interrupt();
17432 +}
17433 --- /dev/null
17434 +++ b/arch/ubicom32/kernel/ldsr.c
17435 @@ -0,0 +1,1176 @@
17436 +/*
17437 + * arch/ubicom32/kernel/ldsr.c
17438 + *   Ubicom32 architecture Linux Device Services Driver Interface
17439 + *
17440 + * (C) Copyright 2009, Ubicom, Inc.
17441 + *
17442 + * This file is part of the Ubicom32 Linux Kernel Port.
17443 + *
17444 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
17445 + * it and/or modify it under the terms of the GNU General Public License
17446 + * as published by the Free Software Foundation, either version 2 of the
17447 + * License, or (at your option) any later version.
17448 + *
17449 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
17450 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
17451 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17452 + * the GNU General Public License for more details.
17453 + *
17454 + * You should have received a copy of the GNU General Public License
17455 + * along with the Ubicom32 Linux Kernel Port.  If not,
17456 + * see <http://www.gnu.org/licenses/>.
17457 + *
17458 + * Ubicom32 implementation derived from (with many thanks):
17459 + *   arch/m68knommu
17460 + *   arch/blackfin
17461 + *   arch/parisc
17462 + *
17463 + * NOTES:
17464 + *
17465 + * The LDSR is a programmable interrupt controller that is written in software.
17466 + * It emulates the behavior of an pic by fielding the interrupts, choosing a
17467 + * victim thread to take the interrupt and forcing that thread to take a context
17468 + * switch to the appropriate interrupt handler.
17469 + *
17470 + * Because traps are treated as just a special class of interrupts, the LDSR
17471 + * also handles the processing of traps.
17472 + *
17473 + * Because we compile Linux both UP and SMP, we need the LDSR to use
17474 + * architectural locking that is not "compiled out" when compiling UP.  For now,
17475 + * we use the single atomic bit lock.
17476 + */
17477 +#include <linux/kernel.h>
17478 +#include <linux/init.h>
17479 +#include <linux/sched.h>
17480 +#include <linux/interrupt.h>
17481 +#include <linux/irq.h>
17482 +#include <linux/profile.h>
17483 +#include <linux/clocksource.h>
17484 +#include <linux/types.h>
17485 +#include <linux/module.h>
17486 +#include <linux/cpumask.h>
17487 +#include <linux/bug.h>
17488 +#include <linux/delay.h>
17489 +#include <asm/ip5000.h>
17490 +#include <asm/atomic.h>
17491 +#include <asm/machdep.h>
17492 +#include <asm/asm-offsets.h>
17493 +#include <asm/traps.h>
17494 +#include <asm/thread.h>
17495 +#include <asm/range-protect.h>
17496 +
17497 +/*
17498 + * One can not print from the LDSR so the best we can do is
17499 + * check a condition and stall all of the threads.
17500 + */
17501 +
17502 +// #define DEBUG_LDSR 1
17503 +#if defined(DEBUG_LDSR)
17504 +#define DEBUG_ASSERT(cond) \
17505 +       if (!(cond)) { \
17506 +               THREAD_STALL; \
17507 +       }
17508 +#else
17509 +#define DEBUG_ASSERT(cond)
17510 +#endif
17511 +
17512 +/*
17513 + * Make global so that we can use it in the RFI code in assembly.
17514 + */
17515 +unsigned int ldsr_soft_irq_mask;
17516 +EXPORT_SYMBOL(ldsr_soft_irq_mask);
17517 +
17518 +static unsigned int ldsr_suspend_mask;
17519 +static unsigned int ldsr_soft_irq;
17520 +static unsigned int ldsr_stack_space[1024];
17521 +
17522 +static struct ldsr_register_bank {
17523 +       volatile unsigned int enabled0;
17524 +       volatile unsigned int enabled1;
17525 +       volatile unsigned int mask0;
17526 +       volatile unsigned int mask1;
17527 +       unsigned int total;
17528 +       unsigned int retry;
17529 +       unsigned int backout;
17530 +} ldsr_interrupt;
17531 +
17532 +/*
17533 + * Which thread/cpu are we?
17534 + */
17535 +static int ldsr_tid = -1;
17536 +
17537 +#if defined(CONFIG_IRQSTACKS)
17538 +/*
17539 + * per-CPU IRQ stacks (thread information and stack)
17540 + *
17541 + * NOTE: Do not use DEFINE_PER_CPU() as it makes it harder
17542 + * to find the location of ctx from assembly language.
17543 + */
17544 +union irq_ctx {
17545 +       struct thread_info      tinfo;
17546 +       u32                     stack[THREAD_SIZE/sizeof(u32)];
17547 +};
17548 +static union irq_ctx *percpu_irq_ctxs[NR_CPUS];
17549 +
17550 +/*
17551 + *  Storage for the interrupt stack.
17552 + */
17553 +#if !defined(CONFIG_IRQSTACKS_USEOCM)
17554 +static char percpu_irq_stacks[(NR_CPUS * THREAD_SIZE) + (THREAD_SIZE - 1)];
17555 +#else
17556 +/*
17557 + *  For OCM, the linker will ensure that space is allocated for the stack
17558 + *  see (vmlinux.lds.S)
17559 + */
17560 +static char percpu_irq_stacks[];
17561 +#endif
17562 +
17563 +#endif
17564 +
17565 +/*
17566 + * Save trap IRQ because we need to un-suspend if it gets set.
17567 + */
17568 +static unsigned int ldsr_trap_irq_mask;
17569 +static unsigned int ldsr_trap_irq;
17570 +
17571 +/*
17572 + * ret_from_interrupt_to_kernel
17573 + *     Just restore the context and do nothing else.
17574 + */
17575 +asmlinkage void ret_from_interrupt_to_kernel(void)__attribute__((naked));
17576 +
17577 +/*
17578 + * ret_from_interrupt_to_user
17579 + *     Call scheduler if needed. Just restore the context.
17580 + */
17581 +asmlinkage void ret_from_interrupt_to_user(void)__attribute__((naked));
17582 +
17583 +#ifdef DEBUG_LDSR
17584 +u32_t old_sp, old_pc, old_a0, old_a5, old_a3;
17585 +struct pt_regs copy_regs, *copy_save_area;
17586 +#endif
17587 +
17588 +int __user_mode(unsigned long sp)
17589 +{
17590 +
17591 +       u32_t saved_stack_base = sp & ~(ASM_THREAD_SIZE - 1);
17592 +#if defined(CONFIG_IRQSTACKS_USEOCM)
17593 +       if ((union irq_ctx *)saved_stack_base == percpu_irq_ctxs[smp_processor_id()]) {
17594 +               /*
17595 +                *  On the interrupt stack.
17596 +                */
17597 +               return 0;
17598 +       }
17599 +#endif
17600 +
17601 +       if (!(u32_t)current) {
17602 +               return 0;
17603 +       }
17604 +       return saved_stack_base != ((u32_t)current->stack);
17605 +}
17606 +
17607 +/*
17608 + * ldsr_lock_release()
17609 + *     Release the LDSR lock.
17610 + */
17611 +static void ldsr_lock_release(void)
17612 +{
17613 +       UBICOM32_UNLOCK(LDSR_LOCK_BIT);
17614 +}
17615 +
17616 +/*
17617 + * ldsr_lock_acquire()
17618 + *     Acquire the LDSR lock, spin if not available.
17619 + */
17620 +static void ldsr_lock_acquire(void)
17621 +{
17622 +       UBICOM32_LOCK(LDSR_LOCK_BIT);
17623 +}
17624 +
17625 +/*
17626 + * ldsr_thread_irq_disable()
17627 + *     Disable interrupts for the specified thread.
17628 + */
17629 +static void ldsr_thread_irq_disable(unsigned int tid)
17630 +{
17631 +       unsigned int mask = (1 << tid);
17632 +
17633 +       asm volatile (
17634 +       "       or.4    scratchpad1, scratchpad1, %0    \n\t"
17635 +               :
17636 +               : "d"(mask)
17637 +               : "cc"
17638 +       );
17639 +}
17640 +
17641 +/*
17642 + * ldsr_thread_get_interrupts()
17643 + *     Get the interrupt state for all threads.
17644 + */
17645 +static unsigned long ldsr_thread_get_interrupts(void)
17646 +{
17647 +       unsigned long ret = 0;
17648 +       asm volatile (
17649 +       "       move.4  %0, scratchpad1 \n\t"
17650 +               : "=r" (ret)
17651 +               :
17652 +       );
17653 +       return ret;
17654 +}
17655 +
17656 +/*
17657 + * ldsr_emulate_and_run()
17658 + *     Emulate the instruction and then set the thread to run.
17659 + */
17660 +static void ldsr_emulate_and_run(unsigned int tid)
17661 +{
17662 +       unsigned int thread_mask = (1 << tid);
17663 +       u32_t write_csr = (tid << 15) | (1 << 14);
17664 +
17665 +       /*
17666 +        * Emulate the unaligned access.
17667 +        */
17668 +       unaligned_emulate(tid);
17669 +
17670 +       /*
17671 +        * Get the thread back in a running state.
17672 +        */
17673 +       asm volatile (
17674 +       "       setcsr  %0                      \n\t"
17675 +       "       setcsr_flush 0                  \n\t"
17676 +       "       move.4  trap_cause, #0          \n\t" /* Clear the trap cause
17677 +                                                      * register */
17678 +       "       setcsr  #0                      \n\t"
17679 +       "       setcsr_flush 0                  \n\t"
17680 +       "       move.4  mt_dbg_active_set, %1   \n\t" /* Activate thread even if
17681 +                                                      * in dbg/fault state */
17682 +       "       move.4  mt_active_set, %1       \n\t" /* Restart target
17683 +                                                      * thread. */
17684 +               :
17685 +               : "r" (write_csr), "d" (thread_mask)
17686 +               : "cc"
17687 +       );
17688 +       thread_enable_mask(thread_mask);
17689 +}
17690 +
17691 +/*
17692 + * ldsr_preemptive_context_save()
17693 + *     save thread context from another hardware thread.  The other thread must
17694 + *     be stalled.
17695 + */
17696 +static inline void ldsr_preemptive_context_save(u32_t thread,
17697 +                                               struct pt_regs *regs)
17698 +{
17699 +       /*
17700 +        * Save the current state of the specified thread
17701 +        */
17702 +       asm volatile (
17703 +       "       move.4  a3, %0                                  \n\t"
17704 +
17705 +               /* set src1 from the target thread */
17706 +       "       move.4  csr, %1                                 \n\t"
17707 +       "       setcsr_flush 0                                  \n\t"
17708 +       "       setcsr_flush 0                                  \n\t"
17709 +
17710 +               /* copy state from the other thread */
17711 +       "       move.4  "D(PT_D0)"(a3), d0                      \n\t"
17712 +       "       move.4  "D(PT_D1)"(a3), d1                      \n\t"
17713 +       "       move.4  "D(PT_D2)"(a3), d2                      \n\t"
17714 +       "       move.4  "D(PT_D3)"(a3), d3                      \n\t"
17715 +       "       move.4  "D(PT_D4)"(a3), d4                      \n\t"
17716 +       "       move.4  "D(PT_D5)"(a3), d5                      \n\t"
17717 +       "       move.4  "D(PT_D6)"(a3), d6                      \n\t"
17718 +       "       move.4  "D(PT_D7)"(a3), d7                      \n\t"
17719 +       "       move.4  "D(PT_D8)"(a3), d8                      \n\t"
17720 +       "       move.4  "D(PT_D9)"(a3), d9                      \n\t"
17721 +       "       move.4  "D(PT_D10)"(a3), d10                    \n\t"
17722 +       "       move.4  "D(PT_D11)"(a3), d11                    \n\t"
17723 +       "       move.4  "D(PT_D12)"(a3), d12                    \n\t"
17724 +       "       move.4  "D(PT_D13)"(a3), d13                    \n\t"
17725 +       "       move.4  "D(PT_D14)"(a3), d14                    \n\t"
17726 +       "       move.4  "D(PT_D15)"(a3), d15                    \n\t"
17727 +       "       move.4  "D(PT_A0)"(a3), a0                      \n\t"
17728 +       "       move.4  "D(PT_A1)"(a3), a1                      \n\t"
17729 +       "       move.4  "D(PT_A2)"(a3), a2                      \n\t"
17730 +       "       move.4  "D(PT_A3)"(a3), a3                      \n\t"
17731 +       "       move.4  "D(PT_A4)"(a3), a4                      \n\t"
17732 +       "       move.4  "D(PT_A5)"(a3), a5                      \n\t"
17733 +       "       move.4  "D(PT_A6)"(a3), a6                      \n\t"
17734 +       "       move.4  "D(PT_SP)"(a3), a7                      \n\t"
17735 +       "       move.4  "D(PT_ACC0HI)"(a3), acc0_hi             \n\t"
17736 +       "       move.4  "D(PT_ACC0LO)"(a3), acc0_lo             \n\t"
17737 +       "       move.4  "D(PT_MAC_RC16)"(a3), mac_rc16          \n\t"
17738 +       "       move.4  "D(PT_ACC1HI)"(a3), acc1_hi             \n\t"
17739 +       "       move.4  "D(PT_ACC1LO)"(a3), acc1_lo             \n\t"
17740 +       "       move.4  "D(PT_SOURCE3)"(a3), source3            \n\t"
17741 +       "       move.4  "D(PT_INST_CNT)"(a3), inst_cnt          \n\t"
17742 +       "       move.4  "D(PT_CSR)"(a3), csr                    \n\t"
17743 +       "       move.4  "D(PT_DUMMY_UNUSED)"(a3), #0            \n\t"
17744 +       "       move.4  "D(PT_INT_MASK0)"(a3), int_mask0        \n\t"
17745 +       "       move.4  "D(PT_INT_MASK1)"(a3), int_mask1        \n\t"
17746 +       "       move.4  "D(PT_TRAP_CAUSE)"(a3), trap_cause      \n\t"
17747 +       "       move.4  "D(PT_PC)"(a3), pc                      \n\t"
17748 +       "       move.4  "D(PT_PREVIOUS_PC)"(a3), previous_pc    \n\t"
17749 +               /* disable csr thread select */
17750 +       "       movei   csr, #0                                 \n\t"
17751 +       "       setcsr_flush 0                                  \n\t"
17752 +       :
17753 +       : "r" (regs->dn), "d" ((thread << 9) | (1 << 8))
17754 +       : "a3"
17755 +       );
17756 +}
17757 +
17758 +/*
17759 + * ldsr_rotate_threads()
17760 + *     Simple round robin algorithm for choosing the next cpu
17761 + */
17762 +static int ldsr_rotate_threads(unsigned long cpus)
17763 +{
17764 +       static unsigned char ldsr_bits[8] = {
17765 +               3, 0, 1, 0, 2, 0, 1, 0
17766 +       };
17767 +
17768 +       static int nextbit;
17769 +       int thisbit;
17770 +
17771 +       /*
17772 +        * Move the interrupts down so that we consider interrupts from where
17773 +        * we left off, then take the interrupts we would lose and move them
17774 +        * to the top half of the interrupts value.
17775 +        */
17776 +       cpus = (cpus >> nextbit) | (cpus << ((sizeof(cpus) * 8) - nextbit));
17777 +
17778 +       /*
17779 +        * 50% of the time we won't take this at all and then of the cases where
17780 +        * we do about 50% of those we only execute once.
17781 +        */
17782 +       if (!(cpus & 0xffff)) {
17783 +               nextbit += 16;
17784 +               cpus >>= 16;
17785 +       }
17786 +
17787 +       if (!(cpus & 0xff)) {
17788 +               nextbit += 8;
17789 +               cpus >>= 8;
17790 +       }
17791 +
17792 +       if (!(cpus & 0xf)) {
17793 +               nextbit += 4;
17794 +               cpus >>= 4;
17795 +       }
17796 +
17797 +       nextbit += ldsr_bits[cpus & 0x7];
17798 +       thisbit = (nextbit & ((sizeof(cpus) * 8) - 1));
17799 +       nextbit = (thisbit + 1) & ((sizeof(cpus) * 8) - 1);
17800 +       DEBUG_ASSERT(thisbit < THREAD_ARCHITECTURAL_MAX);
17801 +       return thisbit;
17802 +}
17803 +
17804 +/*
17805 + * ldsr_rotate_interrupts()
17806 + *     Get rotating next set bit value.
17807 + */
17808 +static int ldsr_rotate_interrupts(unsigned long long interrupts)
17809 +{
17810 +       static unsigned char ldsr_bits[8] = {
17811 +               3, 0, 1, 0, 2, 0, 1, 0
17812 +       };
17813 +
17814 +       static int nextbit;
17815 +       int thisbit;
17816 +
17817 +       /*
17818 +        * Move the interrupts down so that we consider interrupts from where
17819 +        * we left off, then take the interrupts we would lose and move them
17820 +        * to the top half of the interrupts value.
17821 +        */
17822 +       interrupts = (interrupts >> nextbit) |
17823 +               (interrupts << ((sizeof(interrupts) * 8) - nextbit));
17824 +
17825 +       /*
17826 +        * 50% of the time we won't take this at all and then of the cases where
17827 +        * we do about 50% of those we only execute once.
17828 +        */
17829 +       if (!(interrupts & 0xffffffff)) {
17830 +               nextbit += 32;
17831 +               interrupts >>= 32;
17832 +       }
17833 +
17834 +       if (!(interrupts & 0xffff)) {
17835 +               nextbit += 16;
17836 +               interrupts >>= 16;
17837 +       }
17838 +
17839 +       if (!(interrupts & 0xff)) {
17840 +               nextbit += 8;
17841 +               interrupts >>= 8;
17842 +       }
17843 +
17844 +       if (!(interrupts & 0xf)) {
17845 +               nextbit += 4;
17846 +               interrupts >>= 4;
17847 +       }
17848 +
17849 +       nextbit += ldsr_bits[interrupts & 0x7];
17850 +       thisbit = (nextbit & ((sizeof(interrupts) * 8) - 1));
17851 +       nextbit = (thisbit + 1) & ((sizeof(interrupts) * 8) - 1);
17852 +
17853 +       DEBUG_ASSERT(thisbit < (sizeof(interrupts) * 8));
17854 +       return thisbit;
17855 +}
17856 +
17857 +/*
17858 + * ldsr_backout_or_irq()
17859 + *
17860 + * One way or the other this interrupt is not being
17861 + * processed, make sure that it is reset.  We are
17862 + * not going to call irq_end_vector() so unmask the
17863 + * interrupt.
17864 + */
17865 +static void ldsr_backout_of_irq(int vector, unsigned long tid_mask)
17866 +{
17867 +#if defined(CONFIG_SMP)
17868 +       if (unlikely(vector == smp_ipi_irq)) {
17869 +               smp_reset_ipi(tid_mask);
17870 +       }
17871 +#endif
17872 +       ldsr_unmask_vector(vector);
17873 +       ldsr_interrupt.backout++;
17874 +}
17875 +
17876 +#if defined(CONFIG_IRQSTACKS)
17877 +/*
17878 + * ldsr_choose_savearea_and_returnvec()
17879 + *     Test our current state (user, kernel, interrupt) and set things up.
17880 + *
17881 + * This version of the function uses 3 stacks and nests interrupts
17882 + * on the interrupt stack.
17883 + */
17884 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
17885 +{
17886 +       struct pt_regs *save_area;
17887 +       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
17888 +       struct thread_info * ti= (struct thread_info *)sw_ksp[tid];
17889 +
17890 +#if defined(CONFIG_SMP)
17891 +       union irq_ctx *icp = percpu_irq_ctxs[tid];
17892 +#else
17893 +       union irq_ctx *icp = percpu_irq_ctxs[0];
17894 +#endif
17895 +
17896 +       if (masked_linux_sp == (u32_t)icp) {
17897 +               /*
17898 +                * Fault/Interrupt occurred while on the interrupt stack.
17899 +                */
17900 +               save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17901 +               *pvec = (u32_t)(&ret_from_interrupt_to_kernel);
17902 +       } else {
17903 +               /*
17904 +                *  Fault/Interrupt occurred while on user/kernel stack.  This is a new
17905 +                *  first use of the interrupt stack.
17906 +                */
17907 +               save_area = (struct pt_regs *) ((char *)icp + sizeof(icp->stack) - sizeof(struct pt_regs) - 8);
17908 +               if (masked_linux_sp == (u32_t)ti) {
17909 +                       *pvec  = (u32_t)(&ret_from_interrupt_to_kernel);
17910 +               } else {
17911 +                       *pvec  = (u32_t)(&ret_from_interrupt_to_user);
17912 +               }
17913 +
17914 +               /*
17915 +                * Because the softirq code will execute on the "interrupt" stack, we
17916 +                * need to maintain the knowledge of what "task" was executing on the
17917 +                * cpu.  This is done by copying the thread_info->task from the cpu
17918 +                * we are about to context switch into the interrupt contexts thread_info
17919 +                * structure.
17920 +                */
17921 +               icp->tinfo.task = ti->task;
17922 +               icp->tinfo.preempt_count =
17923 +                               (icp->tinfo.preempt_count & ~SOFTIRQ_MASK) |
17924 +                               (ti->preempt_count & SOFTIRQ_MASK);
17925 +               icp->tinfo.interrupt_nesting = 0;
17926 +       }
17927 +       save_area->nesting_level = icp->tinfo.interrupt_nesting;
17928 +       return save_area;
17929 +}
17930 +
17931 +#else
17932 +/*
17933 + * ldsr_choose_savearea_and_returnvec()
17934 + *     Test our current state (user, kernel, interrupt) and set things up.
17935 + *
17936 + * The version of the function uses just the user & kernel stack and
17937 + * nests interrupts on the existing kernel stack.
17938 + */
17939 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
17940 +{
17941 +       struct pt_regs *save_area;
17942 +       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
17943 +       struct thread_info *ti = (struct thread_info *)sw_ksp[tid];
17944 +
17945 +       if (masked_linux_sp == (u32_t)ti) {
17946 +               /*
17947 +                * Fault/Interrupt occurred while on the kernel stack.
17948 +                */
17949 +               save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17950 +               *pvec = (u32_t) (&ret_from_interrupt_to_kernel);
17951 +       } else {
17952 +               /*
17953 +                *  Fault/Interrupt occurred while on user stack.
17954 +                */
17955 +               ti->interrupt_nesting = 0;
17956 +               save_area = (struct pt_regs *)((u32_t)ti + THREAD_SIZE - sizeof(struct pt_regs) - 8);
17957 +               *pvec  = (u32_t) (&ret_from_interrupt_to_user);
17958 +       }
17959 +       save_area->nesting_level = ti->interrupt_nesting;
17960 +       return save_area;
17961 +}
17962 +#endif
17963 +
17964 +/*
17965 + * ldsr_ctxsw_thread()
17966 + *     Context switch a mainline thread to execute do_IRQ() for the specified
17967 + *     vector.
17968 + */
17969 +static void ldsr_ctxsw_thread(int vector, thread_t tid)
17970 +{
17971 +       u32_t linux_sp;
17972 +       u32_t return_vector;
17973 +       struct pt_regs *save_area, *regs;
17974 +       u32_t thread_mask = (1 << tid);
17975 +       u32_t read_csr = ((tid << 9) | (1 << 8));
17976 +       u32_t write_csr = (tid << 15) | (1 << 14);
17977 +       u32_t interrupt_vector = (u32_t)(&do_IRQ);
17978 +
17979 +       unsigned int frame_type = UBICOM32_FRAME_TYPE_INTERRUPT;
17980 +
17981 +
17982 +       DEBUG_ASSERT(!thread_is_enabled(tid));
17983 +
17984 +       /*
17985 +        * Acquire the necessary global and per thread locks for tid.
17986 +        * As a side effect, we ensure that the thread has not trapped
17987 +        * and return true if it has.
17988 +        */
17989 +       if (unlikely(thread_is_trapped(tid))) {
17990 +               /*
17991 +                * Read the trap cause, the sp and clear the MT_TRAP bits.
17992 +                */
17993 +               unsigned int cause;
17994 +               asm volatile (
17995 +               "       setcsr  %3              \n\t"
17996 +               "       setcsr_flush 0          \n\t"
17997 +               "       setcsr_flush 0          \n\t"
17998 +               "       move.4  %0, TRAP_CAUSE  \n\t"
17999 +               "       move.4  %1, SP          \n\t"
18000 +               "       setcsr  #0              \n\t"
18001 +               "       setcsr_flush 0          \n\t"
18002 +               "       move.4  MT_BREAK_CLR, %2\n\t"
18003 +               "       move.4  MT_TRAP_CLR, %2 \n\t"
18004 +                       : "=&r" (cause), "=&r" (linux_sp)
18005 +                       : "r" (thread_mask), "m" (read_csr)
18006 +               );
18007 +
18008 +               ldsr_backout_of_irq(vector, (1 << tid));
18009 +
18010 +#if !defined(CONFIG_UNALIGNED_ACCESS_DISABLED)
18011 +               /*
18012 +                * See if the unaligned trap handler can deal with this.
18013 +                * If so, emulate the instruction and then just restart
18014 +                * the thread.
18015 +                */
18016 +               if (unaligned_only(cause)) {
18017 +#if defined(CONFIG_UNALIGNED_ACCESS_USERSPACE_ONLY)
18018 +                       /*
18019 +                        * Check if this is a kernel stack if so we will not
18020 +                        * handle the trap
18021 +                        */
18022 +                       u32_t masked_linux_sp = linux_sp & ~(THREAD_SIZE - 1);
18023 +                       if ((masked_linux_sp != (u32_t)sw_ksp[tid]) &&
18024 +                           unaligned_only(cause)) {
18025 +                               ldsr_emulate_and_run(tid);
18026 +                               return;
18027 +                       }
18028 +#else
18029 +                       ldsr_emulate_and_run(tid);
18030 +                       return;
18031 +#endif
18032 +
18033 +               }
18034 +#endif
18035 +
18036 +               interrupt_vector = (u32_t)(&trap_handler);
18037 +               frame_type = UBICOM32_FRAME_TYPE_TRAP;
18038 +       } else {
18039 +               /*
18040 +                * Read the target thread's SP
18041 +                */
18042 +               asm volatile (
18043 +               "       setcsr  %1              \n\t"
18044 +               "       setcsr_flush 0          \n\t"
18045 +               "       setcsr_flush 0          \n\t"
18046 +               "       move.4  %0, SP          \n\t"
18047 +               "       setcsr  #0              \n\t"
18048 +               "       setcsr_flush 0          \n\t"
18049 +                       : "=m" (linux_sp)
18050 +                       : "m" (read_csr)
18051 +               );
18052 +       }
18053 +
18054 +       /*
18055 +        * We are delivering an interrupt, count it.
18056 +        */
18057 +       ldsr_interrupt.total++;
18058 +
18059 +       /*
18060 +        * At this point, we will definitely force this thread to
18061 +        * a new context, show its interrupts as disabled.
18062 +        */
18063 +       ldsr_thread_irq_disable(tid);
18064 +
18065 +       /*
18066 +        * Test our current state (user, kernel, interrupt).  Save the
18067 +        * appropriate data and setup for the return.
18068 +        */
18069 +       save_area = ldsr_choose_savearea_and_returnvec(tid, linux_sp, &return_vector);
18070 +
18071 +       /*
18072 +        *  The pt_regs (save_area) contains the type of thread that we are dealing
18073 +        *  with (KERNEL/NORMAL) and is copied into each pt_regs area.  We get this
18074 +        *  from the current tasks kernel pt_regs area that always exists at the
18075 +        *  top of the kernel stack.
18076 +        */
18077 +       regs = (struct pt_regs *)((u32_t)sw_ksp[tid] + THREAD_SIZE - sizeof(struct pt_regs) - 8);
18078 +       save_area->thread_type = regs->thread_type;
18079 +
18080 +       /*
18081 +        * Preserve the context of the Linux thread.
18082 +        */
18083 +       ldsr_preemptive_context_save(tid, save_area);
18084 +
18085 +       /*
18086 +        * Load the fram_type into the save_area.
18087 +        */
18088 +       save_area->frame_type = frame_type;
18089 +
18090 +#ifdef CONFIG_STOP_ON_TRAP
18091 +       /*
18092 +        * Before we get backtrace and showing stacks working well, it sometimes
18093 +        * helps to enter the debugger when a trap occurs before we change the
18094 +        * thread to handle the fault.  This optional code causes all threads to
18095 +        * stop on every trap frame.  One assumes that GDB connected via the
18096 +        * mailbox interface will be used to recover from this state.
18097 +        */
18098 +       if (frame_type == UBICOM32_FRAME_TYPE_TRAP) {
18099 +               THREAD_STALL;
18100 +       }
18101 +#endif
18102 +
18103 +#ifdef DEBUG_LDSR
18104 +       copy_regs = *save_area;
18105 +       copy_save_area = save_area;
18106 +
18107 +       old_a0 = save_area->an[0];
18108 +       old_a3 = save_area->an[3];
18109 +       old_sp = save_area->an[7];
18110 +       old_a5 = save_area->an[5];
18111 +       old_pc = save_area->pc;
18112 +#endif
18113 +
18114 +       /*
18115 +        * Now we have to switch the kernel thread to run do_IRQ function.
18116 +        *      Set pc to do_IRQ
18117 +        *      Set d0 to vector
18118 +        *      Set d1 to save_area.
18119 +        *      Set a5 to the proper return vector.
18120 +        */
18121 +       asm volatile (
18122 +       "       setcsr  %0                      \n\t"
18123 +       "       setcsr_flush 0                  \n\t"
18124 +       "       move.4  d0, %5                  \n\t" /* d0 = 0 vector # */
18125 +       "       move.4  d1, %1                  \n\t" /* d1 = save_area */
18126 +       "       move.4  sp, %1                  \n\t" /* sp = save_area */
18127 +       "       move.4  a5, %2                  \n\t" /* a5 = return_vector */
18128 +       "       move.4  pc, %3                  \n\t" /* pc = do_IRQ routine. */
18129 +       "       move.4  trap_cause, #0          \n\t" /* Clear the trap cause
18130 +                                                      * register */
18131 +       "       setcsr  #0                      \n\t"
18132 +       "       setcsr_flush 0                  \n\t"
18133 +       "       enable_kernel_ranges %4         \n\t"
18134 +       "       move.4  mt_dbg_active_set, %4   \n\t" /* Activate thread even if
18135 +                                                      * in dbg/fault state */
18136 +       "       move.4  mt_active_set, %4       \n\t" /* Restart target
18137 +                                                      * thread. */
18138 +               :
18139 +               : "r" (write_csr), "r" (save_area),
18140 +                 "r" (return_vector), "r" (interrupt_vector),
18141 +                 "d" (thread_mask), "r" (vector)
18142 +               : "cc"
18143 +       );
18144 +       thread_enable_mask(thread_mask);
18145 +}
18146 +
18147 +/*
18148 + * ldsr_deliver_interrupt()
18149 + *     Deliver the interrupt to one of the threads or all of the threads.
18150 + */
18151 +static void ldsr_deliver_interrupt(int vector,
18152 +                                  unsigned long deliver_to,
18153 +                                  int all)
18154 +{
18155 +       unsigned long disabled_threads;
18156 +       unsigned long possible_threads;
18157 +       unsigned long trapped_threads;
18158 +       unsigned long global_locks;
18159 +
18160 +       /*
18161 +        * Disable all of the threads that we might want to send
18162 +        * this interrupt to.
18163 +        */
18164 +retry:
18165 +       DEBUG_ASSERT(deliver_to);
18166 +       thread_disable_mask(deliver_to);
18167 +
18168 +       /*
18169 +        * If any threads are in the trap state, we have to service the
18170 +        * trap for those threads first.
18171 +        */
18172 +       asm volatile (
18173 +               "move.4 %0, MT_TRAP             \n\t"
18174 +               : "=r" (trapped_threads)
18175 +               :
18176 +       );
18177 +
18178 +       trapped_threads &= deliver_to;
18179 +       if (unlikely(trapped_threads)) {
18180 +               /*
18181 +                * all traps will be handled, so clear the trap bit before restarting any threads
18182 +                */
18183 +               ubicom32_clear_interrupt(ldsr_trap_irq);
18184 +
18185 +               /*
18186 +                * Let the remaining untrapped threads, continue.
18187 +                */
18188 +               deliver_to &= ~trapped_threads;
18189 +               if (deliver_to) {
18190 +                       thread_enable_mask(deliver_to);
18191 +               }
18192 +
18193 +               /*
18194 +                * For the trapped threads force them to handle
18195 +                * a trap.
18196 +                */
18197 +               while (trapped_threads) {
18198 +                       unsigned long which = ffz(~trapped_threads);
18199 +                       trapped_threads &= ~(1 << which);
18200 +                       ldsr_ctxsw_thread(vector, which);
18201 +               }
18202 +               return;
18203 +       }
18204 +
18205 +       /*
18206 +        * Can we deliver an interrupt to any of the threads?
18207 +        */
18208 +       disabled_threads = ldsr_thread_get_interrupts();
18209 +       possible_threads = deliver_to & ~disabled_threads;
18210 +       if (unlikely(!possible_threads)) {
18211 +#if defined(CONFIG_SMP)
18212 +               /*
18213 +                * In the SMP case, we can not wait because 1 cpu might be
18214 +                * sending an IPI to another cpu which is currently blocked.
18215 +                * The only way to ensure IPI delivery is to backout and
18216 +                * keep trying.  For SMP, we don't sleep until the interrupts
18217 +                * are delivered.
18218 +                */
18219 +               thread_enable_mask(deliver_to);
18220 +               ldsr_backout_of_irq(vector, deliver_to);
18221 +               return;
18222 +#else
18223 +               /*
18224 +                * In the UP case, we have nothing to do so we should wait.
18225 +                *
18226 +                * Since the INT_MASK0 and INT_MASK1 are "re-loaded" before we
18227 +                * suspend in the outer loop, we do not need to save them here.
18228 +                *
18229 +                * We test that we were awakened for our specific interrupts
18230 +                * because the ldsr mask/unmask operations will force the ldsr
18231 +                * awake even if the interrupt on the mainline thread is not
18232 +                * completed.
18233 +                */
18234 +               unsigned int scratch = 0;
18235 +               thread_enable_mask(deliver_to);
18236 +               asm volatile (
18237 +               "       move.4  INT_MASK0, %1           \n\t"
18238 +               "       move.4  INT_MASK1, #0           \n\t"
18239 +
18240 +               "1:     suspend                         \n\t"
18241 +               "       move.4  %0, INT_STAT0           \n\t"
18242 +               "       and.4   %0, %0, %1              \n\t"
18243 +               "       jmpeq.f 1b                      \n\t"
18244 +
18245 +               "       move.4  INT_CLR0, %2            \n\t"
18246 +                       : "+r" (scratch)
18247 +                       : "d" (ldsr_suspend_mask), "r" (ldsr_soft_irq_mask)
18248 +                       : "cc"
18249 +               );
18250 +
18251 +               /*
18252 +                * This delay is sized to coincide with the time it takes a
18253 +                * thread to complete the exit (see return_from_interrupt).
18254 +                */
18255 +               ldsr_interrupt.retry++;
18256 +               __delay(10);
18257 +               goto retry;
18258 +#endif
18259 +       }
18260 +
18261 +       /*
18262 +        * If any of the global locks are held, we can not deliver any
18263 +        * interrupts, we spin delay(10) and then try again.  If our
18264 +        * spinning becomes a bottle neck, we will need to suspend but for
18265 +        * now lets just spin.
18266 +        */
18267 +       asm volatile (
18268 +               "move.4 %0, scratchpad1         \n\t"
18269 +               : "=r" (global_locks)
18270 +               :
18271 +       );
18272 +       if (unlikely(global_locks & 0xffff0000)) {
18273 +               thread_enable_mask(deliver_to);
18274 +
18275 +               /*
18276 +                * This delay is sized to coincide with the average time it
18277 +                * takes a thread to release a global lock.
18278 +                */
18279 +               ldsr_interrupt.retry++;
18280 +               __delay(10);
18281 +               goto retry;
18282 +       }
18283 +
18284 +       /*
18285 +        * Deliver to one cpu.
18286 +        */
18287 +       if (!all) {
18288 +               /*
18289 +                * Find our victim and then enable everyone else.
18290 +                */
18291 +               unsigned long victim = ldsr_rotate_threads(possible_threads);
18292 +               DEBUG_ASSERT((deliver_to & (1 << victim)));
18293 +               DEBUG_ASSERT((possible_threads & (1 << victim)));
18294 +
18295 +               deliver_to &= ~(1 << victim);
18296 +               if (deliver_to) {
18297 +                       thread_enable_mask(deliver_to);
18298 +               }
18299 +               ldsr_ctxsw_thread(vector, victim);
18300 +               return;
18301 +       }
18302 +
18303 +       /*
18304 +        * If we can't deliver to some threads, wake them
18305 +        * back up and reset things to deliver to them.
18306 +        */
18307 +       deliver_to &= ~possible_threads;
18308 +       if (unlikely(deliver_to)) {
18309 +               thread_enable_mask(deliver_to);
18310 +               ldsr_backout_of_irq(vector, deliver_to);
18311 +       }
18312 +
18313 +       /*
18314 +        * Deliver to all possible threads(s).
18315 +        */
18316 +       while (possible_threads) {
18317 +               unsigned long victim = ffz(~possible_threads);
18318 +               possible_threads &= ~(1 << victim);
18319 +               ldsr_ctxsw_thread(vector, victim);
18320 +       }
18321 +}
18322 +
18323 +/*
18324 + * ldsr_thread()
18325 + *     This thread acts as the interrupt controller for Linux.
18326 + */
18327 +static void ldsr_thread(void *arg)
18328 +{
18329 +       int stat0;
18330 +       int stat1;
18331 +       int interrupt0;
18332 +       int interrupt1;
18333 +       long long interrupts;
18334 +       unsigned long cpus;
18335 +
18336 +#if !defined(CONFIG_SMP)
18337 +       /*
18338 +        * In a non-smp configuration, we can not use the cpu(s) arrays because
18339 +        * there is not a 1-1 correspondence between cpus(s) and our threads.
18340 +        * Thus we must get a local idea of the mainline threads and use the
18341 +        * one and only 1 set as the victim.  We do this once before the ldsr
18342 +        * loop.
18343 +        *
18344 +        * In the SMP case, we will use the cpu(s) map to determine which cpu(s)
18345 +        * are valid to send interrupts to.
18346 +        */
18347 +       int victim = 0;
18348 +       unsigned int mainline = thread_get_mainline();
18349 +       if (mainline == 0) {
18350 +               panic("no mainline Linux threads to interrupt");
18351 +               return;
18352 +       }
18353 +       victim = ffz(~mainline);
18354 +       cpus = (1 << victim);
18355 +#endif
18356 +
18357 +       while (1) {
18358 +               /*
18359 +                * If one changes this code not to reload the INT_MASK(s), you
18360 +                * need to know that code in the lock waiting above does not
18361 +                * reset the MASK registers back; so that code will need to be
18362 +                * changed.
18363 +                */
18364 +               ldsr_lock_acquire();
18365 +               asm volatile (
18366 +               "       move.4 INT_MASK0, %0    \n\t"
18367 +               "       move.4 INT_MASK1, %1    \n\t"
18368 +                       :
18369 +                       : "U4" (ldsr_interrupt.mask0), "U4" (ldsr_interrupt.mask1)
18370 +               );
18371 +               ldsr_lock_release();
18372 +               thread_suspend();
18373 +
18374 +               /*
18375 +                * Read the interrupt status registers
18376 +                */
18377 +               asm volatile (
18378 +                       "move.4 %0, INT_STAT0   \n\t"
18379 +                       "move.4 %1, INT_STAT1   \n\t"
18380 +                       : "=r" (stat0), "=r" (stat1)
18381 +                       :
18382 +               );
18383 +
18384 +               /*
18385 +                * We only care about interrupts that we have been told to care
18386 +                * about.  The interrupt must be enabled, unmasked, and have
18387 +                * occurred in the hardware.
18388 +                */
18389 +               ldsr_lock_acquire();
18390 +               interrupt0 = ldsr_interrupt.enabled0 &
18391 +                       ldsr_interrupt.mask0 & stat0;
18392 +               interrupt1 = ldsr_interrupt.enabled1 &
18393 +                       ldsr_interrupt.mask1 & stat1;
18394 +               ldsr_lock_release();
18395 +
18396 +               /*
18397 +                * For each interrupt in the "snapshot" we will mask the
18398 +                * interrupt handle the interrupt (typically calling do_IRQ()).
18399 +                *
18400 +                * The interrupt is unmasked by desc->chip->end() function in
18401 +                * the per chip generic interrupt handling code
18402 +                * (arch/ubicom32/kernel/irq.c).8
18403 +                */
18404 +               interrupts = ((unsigned long long)interrupt1 << 32) |
18405 +                       interrupt0;
18406 +               while (interrupts) {
18407 +                       int all = 0;
18408 +                       int vector = ldsr_rotate_interrupts(interrupts);
18409 +                       interrupts &= ~((unsigned long long)1 << vector);
18410 +
18411 +                       /*
18412 +                        * Now mask off this vector so that the LDSR ignores
18413 +                        * it until it is acknowledged.
18414 +                        */
18415 +                       ldsr_mask_vector(vector);
18416 +#if !defined(CONFIG_SMP)
18417 +                       ldsr_deliver_interrupt(vector, cpus, all);
18418 +#else
18419 +                       cpus = smp_get_affinity(vector, &all);
18420 +                       if (cpus) {
18421 +                               ldsr_deliver_interrupt(vector, cpus, all);
18422 +                       }
18423 +#endif
18424 +               }
18425 +       }
18426 +
18427 +       /* NOTREACHED */
18428 +}
18429 +
18430 +/*
18431 + * ldsr_mask_vector()
18432 + *     Temporarily mask the interrupt vector, turn off the bit in the mask
18433 + *     register.
18434 + */
18435 +void ldsr_mask_vector(unsigned int vector)
18436 +{
18437 +       unsigned int mask;
18438 +       if (vector < 32) {
18439 +               mask = ~(1 << vector);
18440 +               ldsr_lock_acquire();
18441 +               ldsr_interrupt.mask0 &= mask;
18442 +               ldsr_lock_release();
18443 +               thread_resume(ldsr_tid);
18444 +               return;
18445 +       }
18446 +
18447 +       mask = ~(1 << (vector - 32));
18448 +       ldsr_lock_acquire();
18449 +       ldsr_interrupt.mask1 &= mask;
18450 +       ldsr_lock_release();
18451 +       thread_resume(ldsr_tid);
18452 +}
18453 +
18454 +/*
18455 + * ldsr_unmask_vector()
18456 + *     Unmask the interrupt vector so that it can be used, turn on the bit in
18457 + *     the mask register.
18458 + *
18459 + * Because it is legal for the interrupt path to disable an interrupt,
18460 + * the unmasking code must ensure that disabled interrupts are not
18461 + * unmasked.
18462 + */
18463 +void ldsr_unmask_vector(unsigned int vector)
18464 +{
18465 +       unsigned int mask;
18466 +       if (vector < 32) {
18467 +               mask = (1 << vector);
18468 +               ldsr_lock_acquire();
18469 +               ldsr_interrupt.mask0 |= (mask & ldsr_interrupt.enabled0);
18470 +               ldsr_lock_release();
18471 +               thread_resume(ldsr_tid);
18472 +               return;
18473 +       }
18474 +
18475 +       mask = (1 << (vector - 32));
18476 +       ldsr_lock_acquire();
18477 +       ldsr_interrupt.mask1 |= (mask & ldsr_interrupt.enabled1);
18478 +       ldsr_lock_release();
18479 +       thread_resume(ldsr_tid);
18480 +}
18481 +
18482 +/*
18483 + * ldsr_enable_vector()
18484 + *     The LDSR implements an interrupt controller and has a local (to the
18485 + *     LDSR) copy of its interrupt mask.
18486 + */
18487 +void ldsr_enable_vector(unsigned int vector)
18488 +{
18489 +       unsigned int mask;
18490 +       if (vector < 32) {
18491 +               mask = (1 << vector);
18492 +               ldsr_lock_acquire();
18493 +               ldsr_interrupt.enabled0 |= mask;
18494 +               ldsr_interrupt.mask0 |= mask;
18495 +               ldsr_lock_release();
18496 +               thread_resume(ldsr_tid);
18497 +               return;
18498 +       }
18499 +
18500 +       mask = (1 << (vector - 32));
18501 +       ldsr_lock_acquire();
18502 +       ldsr_interrupt.enabled1 |= mask;
18503 +       ldsr_interrupt.mask1 |= mask;
18504 +       ldsr_lock_release();
18505 +       thread_resume(ldsr_tid);
18506 +}
18507 +
18508 +/*
18509 + * ldsr_disable_vector()
18510 + *     The LDSR implements an interrupt controller and has a local (to the
18511 + *     LDSR) copy of its interrupt mask.
18512 + */
18513 +void ldsr_disable_vector(unsigned int vector)
18514 +{
18515 +       unsigned int mask;
18516 +
18517 +       if (vector < 32) {
18518 +               mask = ~(1 << vector);
18519 +               ldsr_lock_acquire();
18520 +               ldsr_interrupt.enabled0 &= mask;
18521 +               ldsr_interrupt.mask0 &= mask;
18522 +               ldsr_lock_release();
18523 +               thread_resume(ldsr_tid);
18524 +               return;
18525 +       }
18526 +
18527 +       mask = ~(1 << (vector - 32));
18528 +       ldsr_lock_acquire();
18529 +       ldsr_interrupt.enabled1 &= mask;
18530 +       ldsr_interrupt.mask1 &= mask;
18531 +       ldsr_lock_release();
18532 +       thread_resume(ldsr_tid);
18533 +}
18534 +
18535 +/*
18536 + * ldsr_get_threadid()
18537 + *     Return the threadid of the LDSR thread.
18538 + */
18539 +thread_t ldsr_get_threadid(void)
18540 +{
18541 +       return ldsr_tid;
18542 +}
18543 +
18544 +/*
18545 + * ldsr_set_trap_irq()
18546 + *     Save away the trap Soft IRQ
18547 + *
18548 + * See the per thread lock suspend code above for an explination.
18549 + */
18550 +void ldsr_set_trap_irq(unsigned int irq)
18551 +{
18552 +       ldsr_trap_irq = irq;
18553 +       ldsr_trap_irq_mask = (1 << irq);
18554 +       ldsr_suspend_mask |= ldsr_trap_irq_mask;
18555 +}
18556 +
18557 +/*
18558 + * ldsr_init()
18559 + *     Initialize the LDSR (Interrupt Controller)
18560 + */
18561 +void ldsr_init(void)
18562 +{
18563 +#if defined(CONFIG_IRQSTACKS)
18564 +       int i;
18565 +       union irq_ctx *icp;
18566 +#endif
18567 +
18568 +       void *stack_high = (void *)ldsr_stack_space;
18569 +       stack_high += sizeof(ldsr_stack_space);
18570 +       stack_high -= 8;
18571 +
18572 +
18573 +       /*
18574 +        * Obtain a soft IRQ to use
18575 +        */
18576 +       if (irq_soft_alloc(&ldsr_soft_irq) < 0) {
18577 +               panic("no software IRQ is available\n");
18578 +               return;
18579 +       }
18580 +       ldsr_soft_irq_mask |= (1 << ldsr_soft_irq);
18581 +       ldsr_suspend_mask |= ldsr_soft_irq_mask;
18582 +
18583 +       /*
18584 +        * Now allocate and start the LDSR thread.
18585 +        */
18586 +       ldsr_tid = thread_alloc();
18587 +       if (ldsr_tid < 0) {
18588 +               panic("no thread available to run LDSR");
18589 +               return;
18590 +       }
18591 +
18592 +#if defined(CONFIG_IRQSTACKS)
18593 +       /*
18594 +        * Initialize the per-cpu irq thread_info structure that
18595 +        * is at the top of each per-cpu irq stack.
18596 +        */
18597 +       icp = (union irq_ctx *)
18598 +               (((unsigned long)percpu_irq_stacks + (THREAD_SIZE - 1)) & ~(THREAD_SIZE - 1));
18599 +       for (i = 0; i < NR_CPUS; i++) {
18600 +               struct thread_info *ti = &(icp->tinfo);
18601 +               ti->task = NULL;
18602 +               ti->exec_domain = NULL;
18603 +               ti->cpu = i;
18604 +               ti->preempt_count = 0;
18605 +               ti->interrupt_nesting = 0;
18606 +               percpu_irq_ctxs[i] = icp++;
18607 +       }
18608 +#endif
18609 +       thread_start(ldsr_tid, ldsr_thread, NULL,
18610 +                    stack_high, THREAD_TYPE_NORMAL);
18611 +}
18612 --- /dev/null
18613 +++ b/arch/ubicom32/kernel/Makefile
18614 @@ -0,0 +1,64 @@
18615 +#
18616 +# arch/ubicom32/kernel/Makefile
18617 +#      Main Makefile for the Ubicom32 arch directory.
18618 +#
18619 +# (C) Copyright 2009, Ubicom, Inc.
18620 +#
18621 +# This file is part of the Ubicom32 Linux Kernel Port.
18622 +#
18623 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
18624 +# it and/or modify it under the terms of the GNU General Public License
18625 +# as published by the Free Software Foundation, either version 2 of the
18626 +# License, or (at your option) any later version.
18627 +#
18628 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
18629 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
18630 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18631 +# the GNU General Public License for more details.
18632 +#
18633 +# You should have received a copy of the GNU General Public License
18634 +# along with the Ubicom32 Linux Kernel Port.  If not, 
18635 +# see <http://www.gnu.org/licenses/>.
18636 +#
18637 +# Ubicom32 implementation derived from (with many thanks):
18638 +#   arch/m68knommu
18639 +#   arch/blackfin
18640 +#   arch/parisc
18641 +#
18642 +
18643 +extra-y := head.o vmlinux.lds
18644 +
18645 +obj-y += \
18646 +       devtree.o \
18647 +       dma.o \
18648 +       flat.o \
18649 +       init_task.o \
18650 +       irq.o \
18651 +       ldsr.o \
18652 +       os_node.o \
18653 +       process.o \
18654 +       processor.o \
18655 +       ptrace.o \
18656 +       setup.o \
18657 +       signal.o \
18658 +       stacktrace.o \
18659 +       sys_ubicom32.o \
18660 +       syscalltable.o \
18661 +       thread.o \
18662 +       time.o \
18663 +       traps.o \
18664 +       ubicom32_context_switch.o \
18665 +       ubicom32_ksyms.o \
18666 +       ubicom32_syscall.o \
18667 +       unaligned_trap.o
18668 +
18669 +obj-$(CONFIG_MODULES)                          += module.o
18670 +obj-$(CONFIG_COMEMPCI)                         += comempci.o
18671 +obj-$(CONFIG_SMP)                              += smp.o topology.o
18672 +obj-$(CONFIG_ACCESS_OK_CHECKS_ENABLED)         += uaccess.o
18673 +obj-$(CONFIG_GENERIC_CLOCKEVENTS)              += timer_device.o
18674 +obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)    += timer_broadcast.o
18675 +
18676 +ifndef CONFIG_GENERIC_CLOCKEVENTS
18677 +obj-y                  += timer_tick.o
18678 +endif
18679 --- /dev/null
18680 +++ b/arch/ubicom32/kernel/module.c
18681 @@ -0,0 +1,463 @@
18682 +/*
18683 + * arch/ubicom32/kernel/module.c
18684 + *   Ubicom32 architecture loadable module support.
18685 + *
18686 + * (C) Copyright 2009, Ubicom, Inc.
18687 + *
18688 + * This file is part of the Ubicom32 Linux Kernel Port.
18689 + *
18690 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
18691 + * it and/or modify it under the terms of the GNU General Public License
18692 + * as published by the Free Software Foundation, either version 2 of the
18693 + * License, or (at your option) any later version.
18694 + *
18695 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
18696 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18697 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18698 + * the GNU General Public License for more details.
18699 + *
18700 + * You should have received a copy of the GNU General Public License
18701 + * along with the Ubicom32 Linux Kernel Port.  If not,
18702 + * see <http://www.gnu.org/licenses/>.
18703 + *
18704 + * Ubicom32 implementation derived from (with many thanks):
18705 + *   arch/m68knommu
18706 + *   arch/blackfin
18707 + *   arch/parisc
18708 + */
18709 +#include <linux/moduleloader.h>
18710 +#include <linux/bug.h>
18711 +#include <linux/elf.h>
18712 +#include <linux/vmalloc.h>
18713 +#include <linux/fs.h>
18714 +#include <linux/string.h>
18715 +#include <linux/kernel.h>
18716 +#include <asm/ocm-alloc.h>
18717 +
18718 +#if 0
18719 +#define DEBUGP printk
18720 +#else
18721 +#define DEBUGP(fmt...)
18722 +#endif
18723 +
18724 +static void _module_free_ocm(struct module *mod)
18725 +{
18726 +       printk(KERN_INFO "module arch cleanup %s: OCM instruction memory free "
18727 +              " of %d @%p\n", mod->name, mod->arch.ocm_inst_size,
18728 +              mod->arch.ocm_inst);
18729 +
18730 +       if (mod->arch.ocm_inst) {
18731 +               ocm_inst_free(mod->arch.ocm_inst);
18732 +               mod->arch.ocm_inst = 0;
18733 +               mod->arch.ocm_inst_size = 0;
18734 +       }
18735 +}
18736 +
18737 +void *module_alloc(unsigned long size)
18738 +{
18739 +       if (size == 0)
18740 +               return NULL;
18741 +       return vmalloc(size);
18742 +}
18743 +
18744 +
18745 +/* Free memory returned from module_alloc */
18746 +void module_free(struct module *mod, void *module_region)
18747 +{
18748 +       vfree(module_region);
18749 +       /* FIXME: If module_region == mod->init_region, trim exception
18750 +          table entries. */
18751 +
18752 +       /*
18753 +        * This is expected to be final module free, use this to prune the
18754 +        * ocm
18755 +        */
18756 +       if (module_region && module_region == mod->module_core)
18757 +               _module_free_ocm(mod);
18758 +
18759 +}
18760 +
18761 +/*
18762 + * module_frob_arch_sections()
18763 + *     Called from kernel/module.c allowing arch specific handling of
18764 + *     sections/headers.
18765 + */
18766 +int module_frob_arch_sections(Elf_Ehdr *hdr,
18767 +                             Elf_Shdr *sechdrs,
18768 +                             char *secstrings,
18769 +                             struct module *mod)
18770 +{
18771 +       Elf_Shdr *s, *sechdrs_end;
18772 +       void *ocm_inst = NULL;
18773 +       int ocm_inst_size = 0;
18774 +
18775 +       /*
18776 +        * Ubicom32 v3 and v4 are almost binary compatible but not completely.
18777 +        * To be safe check that the module was compiled with the correct -march
18778 +        * which is flags.
18779 +        */
18780 +#ifdef CONFIG_UBICOM32_V4
18781 +       if ((hdr->e_flags & 0xFFFF) != EF_UBICOM32_V4) {
18782 +               printk(KERN_WARNING "Module %s was not compiled for "
18783 +                      "ubicom32v4, elf_flags:%x,\n",
18784 +                      mod->name, hdr->e_flags);
18785 +               return -ENOEXEC;
18786 +       }
18787 +#elif defined CONFIG_UBICOM32_V3
18788 +       if ((hdr->e_flags & 0xFFFF) != EF_UBICOM32_V3) {
18789 +               printk(KERN_WARNING "Module %s was not compiled for "
18790 +                      "ubicom32v3, elf_flags:%x\n",
18791 +                      mod->name, hdr->e_flags);
18792 +               return -ENOEXEC;
18793 +       }
18794 +#else
18795 +#error Unknown/Unsupported ubicom32 architecture.
18796 +#endif
18797 +
18798 +       /*
18799 +        * XXX: sechdrs are vmalloced in kernel/module.c
18800 +        * and would be vfreed just after module is loaded,
18801 +        * so we hack to keep the only information we needed
18802 +        * in mod->arch to correctly free L1 I/D sram later.
18803 +        * NOTE: this breaks the semantic of mod->arch structure.
18804 +        */
18805 +       sechdrs_end = sechdrs + hdr->e_shnum;
18806 +       for (s = sechdrs; s < sechdrs_end; ++s) {
18807 +               if (strncmp(".ocm_text", secstrings + s->sh_name, 9) == 0)
18808 +                       ocm_inst_size += s->sh_size;
18809 +       }
18810 +
18811 +       if (!ocm_inst_size)
18812 +               return 0;
18813 +
18814 +       ocm_inst = ocm_inst_alloc(ocm_inst_size, 0 /* internal */);
18815 +       if (ocm_inst == NULL) {
18816 +#ifdef CONFIG_OCM_MODULES_FALLBACK_TO_DDR
18817 +               printk(KERN_WARNING
18818 +                      "module %s: OCM instruction memory allocation of %d"
18819 +                      "failed, fallback to DDR\n", mod->name, ocm_inst_size);
18820 +               return 0;
18821 +#else
18822 +               printk(KERN_ERR
18823 +                      "module %s: OCM instruction memory allocation of %d"
18824 +                      "failed.\n", mod->name, ocm_inst_size);
18825 +               return -ENOMEM;
18826 +#endif
18827 +       }
18828 +
18829 +       mod->arch.ocm_inst = ocm_inst;
18830 +       mod->arch.ocm_inst_size = ocm_inst_size;
18831 +
18832 +       printk(KERN_INFO
18833 +              "module %s: OCM instruction memory allocation of %d @%p\n",
18834 +              mod->name, mod->arch.ocm_inst_size, mod->arch.ocm_inst);
18835 +
18836 +       for (s = sechdrs; s < sechdrs_end; ++s) {
18837 +               if (strncmp(".ocm_text", secstrings + s->sh_name, 9) == 0) {
18838 +                       memcpy(ocm_inst, (void *)s->sh_addr, s->sh_size);
18839 +                       s->sh_flags &= ~SHF_ALLOC;
18840 +                       s->sh_addr = (unsigned long)ocm_inst;
18841 +                       ocm_inst += s->sh_size;
18842 +               }
18843 +       }
18844 +
18845 +       return 0;
18846 +}
18847 +
18848 +int apply_relocate(Elf32_Shdr *sechdrs,
18849 +                  const char *strtab,
18850 +                  unsigned int symindex,
18851 +                  unsigned int relsec,
18852 +                  struct module *me)
18853 +{
18854 +       DEBUGP("Invalid Applying relocate section %u to %u\n", relsec,
18855 +              sechdrs[relsec].sh_info);
18856 +       return -EINVAL;
18857 +}
18858 +
18859 +int apply_relocate_add(Elf32_Shdr *sechdrs,
18860 +                      const char *strtab,
18861 +                      unsigned int symindex,
18862 +                      unsigned int relsec,
18863 +                      struct module *me)
18864 +{
18865 +       unsigned int i;
18866 +       Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
18867 +       Elf32_Sym *sym;
18868 +       uint32_t *location;
18869 +       uint32_t insn;
18870 +
18871 +       DEBUGP("Applying relocate_add section %u to %u\n", relsec,
18872 +              sechdrs[relsec].sh_info);
18873 +       for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
18874 +               uint32_t v;
18875 +               const int elf32_rtype = ELF32_R_TYPE(rel[i].r_info);
18876 +
18877 +               /* This is where to make the change */
18878 +               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
18879 +                       + rel[i].r_offset;
18880 +               /* This is the symbol it is referring to.  Note that all
18881 +                  undefined symbols have been resolved.  */
18882 +               sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
18883 +                       + ELF32_R_SYM(rel[i].r_info);
18884 +
18885 +               v = rel[i].r_addend + sym->st_value;
18886 +
18887 +
18888 +               switch (elf32_rtype) {
18889 +               case R_UBICOM32_32:
18890 +               {
18891 +                       /*
18892 +                        * Store the 32 bit relocation as is.
18893 +                        */
18894 +                       *location = v;
18895 +                       break;
18896 +               }
18897 +               case R_UBICOM32_HI24:
18898 +               {
18899 +                       /*
18900 +                        * 24 bit relocation that is part of the MOVEAI
18901 +                        * instruction. The 24 bits come from bits 7 - 30 of the
18902 +                        * relocation. Theses bits eventually get split into 2
18903 +                        * fields in the instruction encoding.
18904 +                        *
18905 +                        * - Bits 7 - 27 of the relocation are encoded into bits
18906 +                        * 0 - 20 of the instruction.
18907 +                        *
18908 +                        *  - Bits 28 - 30 of the relocation are encoded into
18909 +                        *  bit 24 - 26 of the instruction.
18910 +                        */
18911 +                       uint32_t valid24 = (v >> 7) & 0xffffff;
18912 +                       insn = *location;
18913 +
18914 +                       insn &= ~(0x1fffff | (0x7 << 24));
18915 +                       insn |= (valid24 & 0x1fffff);
18916 +                       insn |= ((valid24 & 0xe00000) << 3);
18917 +                       *location = insn;
18918 +               }
18919 +               break;
18920 +               case R_UBICOM32_LO7_S:
18921 +               case R_UBICOM32_LO7_2_S:
18922 +               case R_UBICOM32_LO7_4_S:
18923 +               {
18924 +                       /*
18925 +                        * Bits 0 - 6 of the relocation are encoded into the
18926 +                        * 7bit unsigned immediate fields of the SOURCE-1 field
18927 +                        * of the instruction.  The immediate value is left
18928 +                        * shifted by (0, 1, 2) based on the operand size.
18929 +                        */
18930 +                       uint32_t valid7 = v & 0x7f;
18931 +                       insn = *location;
18932 +
18933 +                       if (elf32_rtype == R_UBICOM32_LO7_2_S) {
18934 +                               valid7 >>= 1;
18935 +                       } else if (elf32_rtype == R_UBICOM32_LO7_4_S) {
18936 +                               valid7 >>= 2;
18937 +                       }
18938 +
18939 +                       insn &= ~(0x1f | (0x3 << 8));
18940 +                       insn |= (valid7 & 0x1f);
18941 +                       insn |= ((valid7 & 0x60) << 3);
18942 +                       *location = insn;
18943 +               }
18944 +               break;
18945 +               case R_UBICOM32_LO7_D:
18946 +               case R_UBICOM32_LO7_2_D:
18947 +               case R_UBICOM32_LO7_4_D:
18948 +               {
18949 +                       /*
18950 +                        * Bits 0 - 6 of the relocation are encoded into the
18951 +                        * 7bit unsigned immediate fields of the DESTINATION
18952 +                        * field of the instruction.  The immediate value is
18953 +                        * left shifted by (0, 1, 2) based on the operand size.
18954 +                        */
18955 +                       uint32_t valid7 = v & 0x7f;
18956 +                       insn = *location;
18957 +
18958 +                       if (elf32_rtype == R_UBICOM32_LO7_2_D) {
18959 +                               valid7 >>= 1;
18960 +                       } else if (elf32_rtype == R_UBICOM32_LO7_4_D) {
18961 +                               valid7 >>= 2;
18962 +                       }
18963 +
18964 +                       insn &= ~((0x1f | (0x3 << 8)) << 16);
18965 +                       insn |= ((valid7 & 0x1f) << 16);
18966 +                       insn |= ((valid7 & 0x60) << 19);
18967 +                       *location = insn;
18968 +               }
18969 +               break;
18970 +               case R_UBICOM32_LO7_CALLI:
18971 +               case R_UBICOM32_LO16_CALLI:
18972 +               {
18973 +                       /*
18974 +                        * Extract the offset for a CALLI instruction. The
18975 +                        * offsets can be either 7 bits or 18 bits. Since all
18976 +                        * instructions in ubicom32 architecture are at work
18977 +                        * aligned addresses the truncated offset is right
18978 +                        * shifted by 2 before being encoded in the instruction.
18979 +                        */
18980 +                       uint32_t val;
18981 +                       if (elf32_rtype == R_UBICOM32_LO7_CALLI) {
18982 +                               val  = v & 0x7f;
18983 +                       } else {
18984 +                               val  = v & 0x3ffff;
18985 +                       }
18986 +
18987 +                       val >>= 2;
18988 +
18989 +                       insn = *location;
18990 +
18991 +                       insn &= ~0x071f071f;
18992 +                       insn |= (val & 0x1f) << 0;
18993 +                       val >>= 5;
18994 +                       insn |= (val & 0x07) << 8;
18995 +                       val >>= 3;
18996 +                       insn |= (val & 0x1f) << 16;
18997 +                       val >>= 5;
18998 +                       insn |= (val & 0x07) << 24;
18999 +                       *location = insn;
19000 +               }
19001 +               break;
19002 +               case R_UBICOM32_24_PCREL:
19003 +               {
19004 +                       /*
19005 +                        * Extract 26 bit signed PC relative offset for CALL
19006 +                        * instructions. Since instruction addresses are word
19007 +                        * aligned the offset is right shited by 2 before
19008 +                        * encoding into instruction.
19009 +                        */
19010 +                       int32_t val = v - (int32_t)location;
19011 +
19012 +                       /*
19013 +                        * Check that the top 7 bits are all equal to the sign
19014 +                        * bit (26), i.e all 0's or all 1's.  If they are not then
19015 +                        * the absolute difference is greater than 25 bits.
19016 +                        */
19017 +                       if (((uint32_t)val & 0xFE000000) != 0xFE000000 &&
19018 +                               ((uint32_t)val & 0xFE000000) != 0x0) {
19019 +                               /*
19020 +                                * The relocation is beyond our addressable
19021 +                                * range with a 26 bit call.
19022 +                                */
19023 +                               printk(KERN_ERR "module %s: PC Relative "
19024 +                                       "relocation out of range: "
19025 +                                       "%u (%x->%x, %x)\n",
19026 +                                       me->name, elf32_rtype,
19027 +                                       v, (uint32_t) location, val);
19028 +                               return -ENOEXEC;
19029 +                       }
19030 +
19031 +                       val = (val & 0x3ffffff) >> 2;
19032 +                       insn = *location;
19033 +                       insn = insn & 0xf8e00000;
19034 +
19035 +                       insn |= (val >> 21) << 24;
19036 +                       insn |= (val & 0x1fffff);
19037 +                       *location = insn;
19038 +               }
19039 +               break;
19040 +               case R_UBICOM32_LO16:
19041 +               case R_UBICOM32_HI16:
19042 +               {
19043 +                       /*
19044 +                        * 16 bit immediate value that is encoded into bit 0 -
19045 +                        * 15 of the instruction.
19046 +                        */
19047 +                       uint32_t val;
19048 +
19049 +                       if (elf32_rtype == R_UBICOM32_LO16) {
19050 +                               val  = v & 0xffff;
19051 +                       } else {
19052 +                               val  = (v >> 16) & 0xffff;
19053 +                       }
19054 +
19055 +                       insn = *location;
19056 +                       insn &= 0xffff0000;
19057 +
19058 +                       insn |= val;
19059 +                       *location = insn;
19060 +               }
19061 +               break;
19062 +               case R_UBICOM32_21_PCREL:
19063 +               {
19064 +                       /*
19065 +                        * Extract 23 bit signed PC relative offset for JMP<cc>
19066 +                        * instructions. Since instruction addresses are word
19067 +                        * aligned the offset is right shited by 2 before
19068 +                        * encoding into instruction.
19069 +                        */
19070 +                       int32_t val = v - (int32_t)location;
19071 +
19072 +                       val = (val & 0x7fffff) >> 2;
19073 +                       insn = *location;
19074 +                       insn = insn & 0xffe00000;
19075 +
19076 +                       insn |= (val >> 21) << 24;
19077 +                       insn |= val;
19078 +                       *location = insn;
19079 +               }
19080 +               break;
19081 +               default:
19082 +                       BUG();
19083 +                       printk(KERN_ERR "module %s: Unknown relocation: %u\n",
19084 +                              me->name, elf32_rtype);
19085 +                       return -ENOEXEC;
19086 +               }
19087 +       }
19088 +       return 0;
19089 +}
19090 +
19091 +int module_finalize(const Elf_Ehdr *hdr,
19092 +                   const Elf_Shdr *sechdrs,
19093 +                   struct module *mod)
19094 +{
19095 +       unsigned int i, strindex = 0, symindex = 0;
19096 +       char *secstrings;
19097 +       int err;
19098 +
19099 +       err = module_bug_finalize(hdr, sechdrs, mod);
19100 +       if (err)
19101 +               return err;
19102 +
19103 +       if (!mod->arch.ocm_inst) {
19104 +               /*
19105 +                * No OCM code, so nothing more to do.
19106 +                */
19107 +               return 0;
19108 +       }
19109 +
19110 +       secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
19111 +
19112 +       for (i = 1; i < hdr->e_shnum; i++) {
19113 +               /* Internal symbols and strings. */
19114 +               if (sechdrs[i].sh_type == SHT_SYMTAB) {
19115 +                       symindex = i;
19116 +                       strindex = sechdrs[i].sh_link;
19117 +               }
19118 +       }
19119 +
19120 +       for (i = 1; i < hdr->e_shnum; i++) {
19121 +               const char *strtab = (char *)sechdrs[strindex].sh_addr;
19122 +               unsigned int info = sechdrs[i].sh_info;
19123 +
19124 +               /* Not a valid relocation section? */
19125 +               if (info >= hdr->e_shnum)
19126 +                       continue;
19127 +
19128 +               if ((sechdrs[i].sh_type == SHT_RELA) &&
19129 +                   (strncmp(".rela.ocm_text",
19130 +                            secstrings + sechdrs[i].sh_name, 5 + 9) == 0)) {
19131 +                       err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
19132 +                                                symindex, i, mod);
19133 +                       if (err)
19134 +                               return err;
19135 +               }
19136 +       }
19137 +
19138 +       return 0;
19139 +}
19140 +
19141 +void module_arch_cleanup(struct module *mod)
19142 +{
19143 +       module_bug_cleanup(mod);
19144 +}
19145 --- /dev/null
19146 +++ b/arch/ubicom32/kernel/os_node.c
19147 @@ -0,0 +1,80 @@
19148 +/*
19149 + * arch/ubicom32/kernel/os_node.c
19150 + *   <TODO: Replace with short file description>
19151 + *
19152 + * (C) Copyright 2009, Ubicom, Inc.
19153 + *
19154 + * This file is part of the Ubicom32 Linux Kernel Port.
19155 + *
19156 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19157 + * it and/or modify it under the terms of the GNU General Public License
19158 + * as published by the Free Software Foundation, either version 2 of the
19159 + * License, or (at your option) any later version.
19160 + *
19161 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19162 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19163 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19164 + * the GNU General Public License for more details.
19165 + *
19166 + * You should have received a copy of the GNU General Public License
19167 + * along with the Ubicom32 Linux Kernel Port.  If not,
19168 + * see <http://www.gnu.org/licenses/>.
19169 + *
19170 + */
19171 +#include "linux/types.h"
19172 +#include "linux/linkage.h"
19173 +#include "linux/uts.h"
19174 +#include "linux/utsrelease.h"
19175 +#include "linux/version.h"
19176 +#include <asm/ocm_size.h>
19177 +#include <asm/devtree.h>
19178 +#include <asm/ip5000.h>
19179 +
19180 +extern asmlinkage void *_start;
19181 +
19182 +/*
19183 + * This file provides static information to the boot code allowing it to decide
19184 + * if the os is compatible. Thus hopefully enabling the boot code to prevent
19185 + * accidentally booting a kernel that has no hope of running.
19186 + */
19187 +struct os_node {
19188 +       struct devtree_node node;
19189 +       unsigned long version; /* Always 1 */
19190 +       unsigned long entry_point;
19191 +       const char    os_name[32]; /* For diagnostic purposes only */
19192 +       const char    os_version_str[32];
19193 +       unsigned long os_version_num;
19194 +       unsigned long expected_ocm_code_start;/* OS Code */
19195 +       unsigned long expected_ocm_data_end;  /* OS Data */
19196 +       unsigned long expected_ram_start;
19197 +       unsigned long expected_ram_end;
19198 +       unsigned long arch_version;
19199 +};
19200 +
19201 +
19202 +/*
19203 + * The os_node is only referenced by head.S and should never be modified at
19204 + * run-time.
19205 + */
19206 +asmlinkage const struct os_node _os_node = {
19207 +       .node = {
19208 +               .next = NULL,
19209 +               .name = { "OS" },
19210 +               .magic = 0x10203040,
19211 +       },
19212 +       .version = 0x10001,
19213 +       .entry_point = (unsigned long)&_start,
19214 +#if APP_OCM_CODE_SIZE || APP_OCM_DATA_SIZE
19215 +       .expected_ocm_code_start = OCMSTART + APP_OCM_CODE_SIZE,
19216 +       .expected_ocm_data_end   = OCMEND   - APP_OCM_DATA_SIZE,
19217 +#else
19218 +       .expected_ocm_code_start = OCMEND,
19219 +       .expected_ocm_data_end   = OCMEND,
19220 +#endif
19221 +       .os_name = { UTS_SYSNAME },
19222 +       .os_version_str = { UTS_RELEASE },
19223 +       .os_version_num = LINUX_VERSION_CODE,
19224 +       .expected_ram_start = CONFIG_KERNELBASE,
19225 +       .expected_ram_end = CONFIG_RAMBASE + CONFIG_RAMSIZE,
19226 +       .arch_version = UBICOM32_ARCH_VERSION
19227 +};
19228 --- /dev/null
19229 +++ b/arch/ubicom32/kernel/process.c
19230 @@ -0,0 +1,494 @@
19231 +/*
19232 + * arch/ubicom32/kernel/process.c
19233 + *   Ubicom32 architecture-dependent process handling.
19234 + *
19235 + * (C) Copyright 2009, Ubicom, Inc.
19236 + * Copyright (C) 1995  Hamish Macdonald
19237 + *
19238 + * 68060 fixes by Jesper Skov
19239 + *
19240 + * uClinux changes
19241 + * Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
19242 + *
19243 + * This file is part of the Ubicom32 Linux Kernel Port.
19244 + *
19245 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19246 + * it and/or modify it under the terms of the GNU General Public License
19247 + * as published by the Free Software Foundation, either version 2 of the
19248 + * License, or (at your option) any later version.
19249 + *
19250 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19251 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19252 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19253 + * the GNU General Public License for more details.
19254 + *
19255 + * You should have received a copy of the GNU General Public License
19256 + * along with the Ubicom32 Linux Kernel Port.  If not,
19257 + * see <http://www.gnu.org/licenses/>.
19258 + *
19259 + * Ubicom32 implementation derived from (with many thanks):
19260 + *   arch/m68knommu
19261 + *   arch/blackfin
19262 + *   arch/parisc
19263 + */
19264 +
19265 +/*
19266 + * This file handles the architecture-dependent parts of process handling..
19267 + */
19268 +
19269 +#include <linux/module.h>
19270 +#include <linux/errno.h>
19271 +#include <linux/sched.h>
19272 +#include <linux/kernel.h>
19273 +#include <linux/mm.h>
19274 +#include <linux/smp.h>
19275 +#include <linux/smp_lock.h>
19276 +#include <linux/stddef.h>
19277 +#include <linux/unistd.h>
19278 +#include <linux/ptrace.h>
19279 +#include <linux/slab.h>
19280 +#include <linux/user.h>
19281 +#include <linux/a.out.h>
19282 +#include <linux/interrupt.h>
19283 +#include <linux/reboot.h>
19284 +#include <linux/fs.h>
19285 +#include <linux/pm.h>
19286 +
19287 +#include <linux/uaccess.h>
19288 +#include <asm/system.h>
19289 +#include <asm/traps.h>
19290 +#include <asm/machdep.h>
19291 +#include <asm/setup.h>
19292 +#include <asm/pgtable.h>
19293 +#include <asm/ip5000.h>
19294 +#include <asm/range-protect.h>
19295 +
19296 +asmlinkage void ret_from_fork(void);
19297 +
19298 +void (*pm_power_off)(void) = machine_power_off;
19299 +EXPORT_SYMBOL(pm_power_off);
19300 +
19301 +/* machine-dependent / hardware-specific power functions */
19302 +void (*mach_reset)(void);
19303 +void (*mach_halt)(void);
19304 +void (*mach_power_off)(void);
19305 +
19306 +/*
19307 + * cpu_idle()
19308 + *     The idle thread.
19309 + *
19310 + * Our idle loop suspends and is woken up by a timer interrupt.
19311 + */
19312 +void cpu_idle(void)
19313 +{
19314 +       while (1) {
19315 +               local_irq_disable();
19316 +               while (!need_resched()) {
19317 +                       local_irq_enable();
19318 +                       thread_suspend();
19319 +                       local_irq_disable();
19320 +               }
19321 +               local_irq_enable();
19322 +               preempt_enable_no_resched();
19323 +               schedule();
19324 +               preempt_disable();
19325 +       }
19326 +}
19327 +
19328 +/*
19329 + * dump_fpu()
19330 + *
19331 + *     Fill in the fpu structure for a core dump. (just a stub as we don't have
19332 + *     an fpu)
19333 + */
19334 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
19335 +{
19336 +       return 1;
19337 +}
19338 +
19339 +/*
19340 + * machine_restart()
19341 + *     Resets the system.
19342 + */
19343 +void machine_restart(char *__unused)
19344 +{
19345 +       /*
19346 +        * Disable all threads except myself. We can do this
19347 +        * directly without needing to call smp_send_stop
19348 +        * because we have a unique architecture where
19349 +        * one thread can disable one or more other threads.
19350 +        */
19351 +       thread_disable_others();
19352 +
19353 +       /*
19354 +        * Call the hardware-specific machine reset function.
19355 +        */
19356 +       if (mach_reset) {
19357 +               mach_reset();
19358 +       }
19359 +
19360 +       printk(KERN_EMERG "System Restarting\n");
19361 +
19362 +       /*
19363 +        * Set watchdog to trigger (after 1ms delay) (12 Mhz is the fixed OSC)
19364 +        */
19365 +       UBICOM32_IO_TIMER->tkey = TIMER_TKEYVAL;
19366 +       UBICOM32_IO_TIMER->wdcom = UBICOM32_IO_TIMER->mptval +
19367 +               (12000000 / 1000);
19368 +       UBICOM32_IO_TIMER->wdcfg = 0;
19369 +       UBICOM32_IO_TIMER->tkey = 0;
19370 +
19371 +       /*
19372 +        * Wait for watchdog
19373 +        */
19374 +       asm volatile (
19375 +               "       move.4          MT_EN, #0               \n\t"
19376 +               "       pipe_flush      0                       \n\t"
19377 +       );
19378 +
19379 +       local_irq_disable();
19380 +       for (;;) {
19381 +               thread_suspend();
19382 +       }
19383 +}
19384 +
19385 +/*
19386 + * machine_halt()
19387 + *     Halt the machine.
19388 + *
19389 + * Similar to machine_power_off, but don't shut off power.  Add code
19390 + * here to freeze the system for e.g. post-mortem debug purpose when
19391 + * possible.  This halt has nothing to do with the idle halt.
19392 + */
19393 +void machine_halt(void)
19394 +{
19395 +       /*
19396 +        * Disable all threads except myself. We can do this
19397 +        * directly without needing to call smp_send_stop
19398 +        * because we have a unique architecture where
19399 +        * one thread can disable one or more other threads.
19400 +        */
19401 +       thread_disable_others();
19402 +
19403 +       /*
19404 +        * Call the hardware-specific machine halt function.
19405 +        */
19406 +       if (mach_halt) {
19407 +               mach_halt();
19408 +       }
19409 +
19410 +       printk(KERN_EMERG "System Halted, OK to turn off power\n");
19411 +       local_irq_disable();
19412 +       for (;;) {
19413 +               thread_suspend();
19414 +       }
19415 +}
19416 +
19417 +/*
19418 + * machine_power_off()
19419 + *     Turn the power off, if a power off handler is defined, otherwise, spin
19420 + *     endlessly.
19421 + */
19422 +void machine_power_off(void)
19423 +{
19424 +       /*
19425 +        * Disable all threads except myself. We can do this
19426 +        * directly without needing to call smp_send_stop
19427 +        * because we have a unique architecture where
19428 +        * one thread can disable one or more other threads.
19429 +        */
19430 +       thread_disable_others();
19431 +
19432 +       /*
19433 +        * Call the hardware-specific machine power off function.
19434 +        */
19435 +       if (mach_power_off) {
19436 +               mach_power_off();
19437 +       }
19438 +
19439 +       printk(KERN_EMERG "System Halted, OK to turn off power\n");
19440 +       local_irq_disable();
19441 +       for (;;) {
19442 +               thread_suspend();
19443 +       }
19444 +}
19445 +
19446 +/*
19447 + * show_regs()
19448 + *     Print out all of the registers.
19449 + */
19450 +void show_regs(struct pt_regs *regs)
19451 +{
19452 +       unsigned int i;
19453 +
19454 +       printk(KERN_NOTICE "regs: %p, tid: %d\n",
19455 +               (void *)regs,
19456 +               thread_get_self());
19457 +
19458 +       printk(KERN_NOTICE "pc: %08x, previous_pc: %08x\n\n",
19459 +               (unsigned int)regs->pc,
19460 +               (unsigned int)regs->previous_pc);
19461 +
19462 +       printk(KERN_NOTICE "Data registers\n");
19463 +       for (i = 0; i < 16; i++) {
19464 +               printk("D%02d: %08x, ", i, (unsigned int)regs->dn[i]);
19465 +               if ((i % 4) == 3) {
19466 +                       printk("\n");
19467 +               }
19468 +       }
19469 +       printk("\n");
19470 +
19471 +       printk(KERN_NOTICE "Address registers\n");
19472 +       for (i = 0; i < 8; i++) {
19473 +               printk("A%02d: %08x, ", i, (unsigned int)regs->an[i]);
19474 +               if ((i % 4) == 3) {
19475 +                       printk("\n");
19476 +               }
19477 +       }
19478 +       printk("\n");
19479 +
19480 +       printk(KERN_NOTICE "acc0: %08x-%08x, acc1: %08x-%08x\n",
19481 +               (unsigned int)regs->acc0[1],
19482 +               (unsigned int)regs->acc0[0],
19483 +               (unsigned int)regs->acc1[1],
19484 +               (unsigned int)regs->acc1[0]);
19485 +
19486 +       printk(KERN_NOTICE "mac_rc16: %08x, source3: %08x\n",
19487 +               (unsigned int)regs->mac_rc16,
19488 +               (unsigned int)regs->source3);
19489 +
19490 +       printk(KERN_NOTICE "inst_cnt: %08x, csr: %08x\n",
19491 +               (unsigned int)regs->inst_cnt,
19492 +               (unsigned int)regs->csr);
19493 +
19494 +       printk(KERN_NOTICE "int_mask0: %08x, int_mask1: %08x\n",
19495 +               (unsigned int)regs->int_mask0,
19496 +               (unsigned int)regs->int_mask1);
19497 +
19498 +       printk(KERN_NOTICE "frame_type: %d, nesting_level: %d, thread_type %d\n\n",
19499 +               (int)regs->frame_type,
19500 +               (int)regs->nesting_level,
19501 +               (int)regs->thread_type);
19502 +}
19503 +
19504 +/*
19505 + * kernel_thread_helper()
19506 + *     On execution d0 will be 0, d1 will be the argument to be passed to the
19507 + *     kernel function.  d2 contains the kernel function that needs to get
19508 + *     called. d3 will contain address to do_exit which need to get moved
19509 + *     into a5. On return from fork the child thread d0 will be 0. We call
19510 + *     this dummy function which in turn loads the argument
19511 + */
19512 +asmlinkage void kernel_thread_helper(void);
19513 +
19514 +/*
19515 + * kernel_thread()
19516 + *     Create a kernel thread
19517 + */
19518 +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
19519 +{
19520 +       struct pt_regs regs;
19521 +
19522 +       memset(&regs, 0, sizeof(regs));
19523 +
19524 +       regs.dn[1] = (unsigned long)arg;
19525 +       regs.dn[2] = (unsigned long)fn;
19526 +       regs.dn[3] = (unsigned long)do_exit;
19527 +       regs.an[5] = (unsigned long)kernel_thread_helper;
19528 +       regs.pc = (unsigned long)kernel_thread_helper;
19529 +       regs.nesting_level = 0;
19530 +       regs.thread_type = KERNEL_THREAD;
19531 +
19532 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
19533 +                      0, &regs, 0, NULL, NULL);
19534 +}
19535 +EXPORT_SYMBOL(kernel_thread);
19536 +
19537 +/*
19538 + * flush_thread()
19539 + *     XXX todo
19540 + */
19541 +void flush_thread(void)
19542 +{
19543 +       /* XXX todo */
19544 +}
19545 +
19546 +/*
19547 + * sys_fork()
19548 + *     Not implemented on no-mmu.
19549 + */
19550 +asmlinkage int sys_fork(struct pt_regs *regs)
19551 +{
19552 +       /* fork almost works, enough to trick you into looking elsewhere :-( */
19553 +       return -EINVAL;
19554 +}
19555 +
19556 +/*
19557 + * sys_vfork()
19558 + *     By the time we get here, the non-volatile registers have also been saved
19559 + *     on the stack. We do some ugly pointer stuff here.. (see also copy_thread
19560 + *     which does context copy).
19561 + */
19562 +asmlinkage int sys_vfork(struct pt_regs *regs)
19563 +{
19564 +       unsigned long old_sp = regs->an[7];
19565 +       unsigned long old_a5 = regs->an[5];
19566 +       unsigned long old_return_address;
19567 +       long do_fork_return;
19568 +
19569 +       /*
19570 +        * Read the old retrun address from the stack.
19571 +        */
19572 +       if (copy_from_user(&old_return_address,
19573 +                          (void *)old_sp, sizeof(unsigned long))) {
19574 +               force_sig(SIGSEGV, current);
19575 +               return 0;
19576 +       }
19577 +
19578 +       /*
19579 +        * Pop the vfork call frame by setting a5 and pc to the old_return
19580 +        * address and incrementing the stack pointer by 4.
19581 +        */
19582 +       regs->an[5] = old_return_address;
19583 +       regs->pc = old_return_address;
19584 +       regs->an[7] += 4;
19585 +
19586 +       do_fork_return = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
19587 +                                regs->an[7], regs, 0, NULL, NULL);
19588 +
19589 +       /*
19590 +        * Now we have to test if the return code is an error. If it is an error
19591 +        * then restore the frame and we will execute error processing in user
19592 +        * space. Other wise the child and the parent will return to the correct
19593 +        * places.
19594 +        */
19595 +       if ((unsigned long)(do_fork_return) >= (unsigned long)(-125)) {
19596 +               /*
19597 +                * Error case. We need to restore the frame.
19598 +                */
19599 +               regs->an[5] = old_a5;
19600 +               regs->pc = old_a5;
19601 +               regs->an[7] = old_sp;
19602 +       }
19603 +
19604 +       return do_fork_return;
19605 +}
19606 +
19607 +/*
19608 + * sys_clone()
19609 + *     creates a child thread.
19610 + */
19611 +asmlinkage int sys_clone(unsigned long clone_flags,
19612 +                        unsigned long newsp,
19613 +                        struct pt_regs *regs)
19614 +{
19615 +       if (!newsp)
19616 +               newsp = regs->an[7];
19617 +       return do_fork(clone_flags, newsp, regs, 0,
19618 +                      NULL, NULL);
19619 +}
19620 +
19621 +/*
19622 + * copy_thread()
19623 + *     low level thread copy, only used by do_fork in kernel/fork.c
19624 + */
19625 +int copy_thread(int nr, unsigned long clone_flags,
19626 +               unsigned long usp, unsigned long topstk,
19627 +               struct task_struct *p, struct pt_regs *regs)
19628 +{
19629 +       struct pt_regs *childregs;
19630 +
19631 +       childregs = (struct pt_regs *)
19632 +               (task_stack_page(p) + THREAD_SIZE - 8) - 1;
19633 +
19634 +       *childregs = *regs;
19635 +
19636 +       /*
19637 +        * Set return value for child to be 0.
19638 +        */
19639 +       childregs->dn[0] = 0;
19640 +
19641 +       if (usp)
19642 +               childregs->an[7] = usp;
19643 +       else
19644 +               childregs->an[7] = (unsigned long)task_stack_page(p) +
19645 +                       THREAD_SIZE - 8;
19646 +
19647 +       /*
19648 +        * Set up the switch_to frame to return to "ret_from_fork"
19649 +        */
19650 +       p->thread.a5 = (unsigned long)ret_from_fork;
19651 +       p->thread.sp = (unsigned long)childregs;
19652 +
19653 +       return 0;
19654 +}
19655 +
19656 +/*
19657 + * sys_execve()
19658 + *     executes a new program.
19659 + */
19660 +asmlinkage int sys_execve(char *name, char **argv,
19661 +                         char **envp, struct pt_regs *regs)
19662 +{
19663 +       int error;
19664 +       char *filename;
19665 +
19666 +       lock_kernel();
19667 +       filename = getname(name);
19668 +       error = PTR_ERR(filename);
19669 +       if (IS_ERR(filename))
19670 +               goto out;
19671 +       error = do_execve(filename, argv, envp, regs);
19672 +       putname(filename);
19673 +       asm ("       .global sys_execve_complete\n"
19674 +            "       sys_execve_complete:");
19675 +out:
19676 +       unlock_kernel();
19677 +       return error;
19678 +}
19679 +
19680 +/*
19681 + * Return saved PC of a blocked thread.
19682 + */
19683 +unsigned long thread_saved_pc(struct task_struct *tsk)
19684 +{
19685 +       return tsk->thread.a5;
19686 +}
19687 +
19688 +
19689 +unsigned long get_wchan(struct task_struct *p)
19690 +{
19691 +       unsigned long pc;
19692 +
19693 +       /*
19694 +        * If we don't have a process, or it is not the current
19695 +        * one or not RUNNING, it makes no sense to ask for a
19696 +        * wchan.
19697 +        */
19698 +       if (!p || p == current || p->state == TASK_RUNNING)
19699 +               return 0;
19700 +
19701 +       /*
19702 +        * TODO: If the process is in the middle of schedule, we
19703 +        * are supposed to do something different but for now we
19704 +        * will return the same thing in both situations.
19705 +        */
19706 +       pc = thread_saved_pc(p);
19707 +       if (in_sched_functions(pc))
19708 +               return pc;
19709 +       return pc;
19710 +}
19711 +
19712 +/*
19713 + * __switch_to is the function that implements the contex save and
19714 + * switch within the kernel. Since this is a function call very few
19715 + * registers have to be saved to pull this off. d0 holds prev and we
19716 + * want to preserve it. prev_switch is a pointer to task->thread
19717 + * structure. This is where we will save the register state. next_switch
19718 + * is pointer to the next task's thread structure that holds the
19719 + * registers.
19720 + */
19721 +asmlinkage void *__switch_to(struct task_struct *prev,
19722 +                            struct thread_struct *prev_switch,
19723 +                            struct thread_struct *next_switch)
19724 +       __attribute__((naked));
19725 --- /dev/null
19726 +++ b/arch/ubicom32/kernel/processor.c
19727 @@ -0,0 +1,258 @@
19728 +/*
19729 + * arch/ubicom32/kernel/processor.c
19730 + *   Ubicom32 architecture processor info implementation.
19731 + *
19732 + * (C) Copyright 2009, Ubicom, Inc.
19733 + *
19734 + * This file is part of the Ubicom32 Linux Kernel Port.
19735 + *
19736 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
19737 + * it and/or modify it under the terms of the GNU General Public License
19738 + * as published by the Free Software Foundation, either version 2 of the
19739 + * License, or (at your option) any later version.
19740 + *
19741 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
19742 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19743 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
19744 + * the GNU General Public License for more details.
19745 + *
19746 + * You should have received a copy of the GNU General Public License
19747 + * along with the Ubicom32 Linux Kernel Port.  If not,
19748 + * see <http://www.gnu.org/licenses/>.
19749 + *
19750 + * Ubicom32 implementation derived from (with many thanks):
19751 + *   arch/m68knommu
19752 + *   arch/blackfin
19753 + *   arch/parisc
19754 + */
19755 +#include <linux/module.h>
19756 +#include <linux/kernel.h>
19757 +#include <linux/init.h>
19758 +#include <linux/sched.h>
19759 +#include <linux/interrupt.h>
19760 +#include <linux/irq.h>
19761 +#include <linux/profile.h>
19762 +#include <linux/clocksource.h>
19763 +#include <linux/types.h>
19764 +#include <linux/seq_file.h>
19765 +#include <linux/delay.h>
19766 +#include <linux/cpu.h>
19767 +#include <asm/devtree.h>
19768 +#include <asm/processor.h>
19769 +#include <asm/cpu.h>
19770 +
19771 +struct procnode {
19772 +       struct devtree_node dn;
19773 +       unsigned int threads;
19774 +       unsigned int timers;
19775 +       unsigned int frequency;
19776 +       unsigned int interrupt0;
19777 +       unsigned int interrupt1;
19778 +       void *socm;
19779 +       void *eocm;
19780 +       void *sdram;
19781 +       void *edram;
19782 +};
19783 +
19784 +struct procnode *pn;
19785 +
19786 +/*
19787 + * show_processorinfo()
19788 + *     Print the actual processor information.
19789 + */
19790 +static void show_processorinfo(struct seq_file *m)
19791 +{
19792 +       char *cpu, *mmu, *fpu;
19793 +       unsigned int clockfreq;
19794 +       unsigned int chipid;
19795 +
19796 +       cpu = CPU;
19797 +       mmu = "none";
19798 +       fpu = "none";
19799 +
19800 +       asm volatile (
19801 +       "move.4         %0, CHIP_ID     \n\t"
19802 +       : "=r" (chipid)
19803 +       );
19804 +
19805 +       /*
19806 +        * General Processor Information.
19807 +        */
19808 +       seq_printf(m, "Vendor:\t\t%s\n", "Ubicom");
19809 +       seq_printf(m, "CPU:\t\t%s\n", cpu);
19810 +       seq_printf(m, "MMU:\t\t%s\n", mmu);
19811 +       seq_printf(m, "FPU:\t\t%s\n", fpu);
19812 +       seq_printf(m, "Arch:\t\t%hx\n", chipid >> 16);
19813 +       seq_printf(m, "Rev:\t\t%hx\n", (chipid & 0xffff));
19814 +
19815 +       /*
19816 +        * Now compute the clock frequency in Mhz.
19817 +        */
19818 +       clockfreq = processor_frequency();
19819 +       seq_printf(m, "Clock Freq:\t%u.%1u MHz\n",
19820 +                  clockfreq / 1000000,
19821 +                  (clockfreq / 100000) % 10);
19822 +       seq_printf(m, "BogoMips:\t%lu.%02lu\n",
19823 +                  (loops_per_jiffy * HZ) / 500000,
19824 +                  ((loops_per_jiffy * HZ) / 5000) % 100);
19825 +       seq_printf(m, "Calibration:\t%lu loops\n", (loops_per_jiffy * HZ));
19826 +}
19827 +
19828 +/*
19829 + * show_cpuinfo()
19830 + *     Get CPU information for use by the procfs.
19831 + */
19832 +static int show_cpuinfo(struct seq_file *m, void *v)
19833 +{
19834 +       unsigned long n = (unsigned long)v - 1;
19835 +
19836 +#if defined(CONFIG_SMP)
19837 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, n);
19838 +#endif
19839 +
19840 +       /*
19841 +        * Print the general processor information on the first
19842 +        * call.
19843 +        */
19844 +       if (n == 0) {
19845 +               show_processorinfo(m);
19846 +       }
19847 +
19848 +#if defined(CONFIG_SMP)
19849 +       /*
19850 +        * For each hwthread, print if this hwthread is running Linux
19851 +        * or is an I/O thread.
19852 +        */
19853 +       if (cpu_isset(n, cpu_online_map)) {
19854 +               seq_printf(m, "cpu[%02lu]:\tthread id - %lu\n", n, p->tid);
19855 +       } else {
19856 +               seq_printf(m, "cpu[%02lu]:\toff-line\n", n);
19857 +       }
19858 +#endif
19859 +       return 0;
19860 +
19861 +}
19862 +
19863 +static void *c_start(struct seq_file *m, loff_t *pos)
19864 +{
19865 +       unsigned long i = *pos;
19866 +
19867 +       return i < NR_CPUS ? (void *)(i + 1) : NULL;
19868 +}
19869 +
19870 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
19871 +{
19872 +       ++*pos;
19873 +       return c_start(m, pos);
19874 +}
19875 +
19876 +static void c_stop(struct seq_file *m, void *v)
19877 +{
19878 +}
19879 +
19880 +const struct seq_operations cpuinfo_op = {
19881 +       .start  = c_start,
19882 +       .next   = c_next,
19883 +       .stop   = c_stop,
19884 +       .show   = show_cpuinfo,
19885 +};
19886 +
19887 +/*
19888 + * processor_timers()
19889 + *     Returns the timers available to Linux.
19890 + */
19891 +unsigned int processor_timers(void)
19892 +{
19893 +       if (!pn) {
19894 +               return 0;
19895 +       }
19896 +       return pn->timers;
19897 +}
19898 +
19899 +/*
19900 + * processor_threads()
19901 + *     Returns the threads available to Linux.
19902 + */
19903 +unsigned int processor_threads(void)
19904 +{
19905 +       if (!pn) {
19906 +               return 0;
19907 +       }
19908 +       return pn->threads;
19909 +}
19910 +
19911 +/*
19912 + * processor_frequency()
19913 + *     Returns the frequency of the system clock.
19914 + */
19915 +unsigned int processor_frequency(void)
19916 +{
19917 +       if (!pn) {
19918 +               return 0;
19919 +       }
19920 +       return pn->frequency;
19921 +}
19922 +EXPORT_SYMBOL(processor_frequency);
19923 +
19924 +/*
19925 + * processor_interrupts()
19926 + *     Return the interrupts that are setup at boot time.
19927 + */
19928 +int processor_interrupts(unsigned int *int0, unsigned int *int1)
19929 +{
19930 +       if (!pn) {
19931 +               return -EFAULT;
19932 +       }
19933 +
19934 +       if (int0) {
19935 +               *int0 = pn->interrupt0;
19936 +       }
19937 +
19938 +       if (int1) {
19939 +               *int1 = pn->interrupt1;
19940 +       }
19941 +       return 0;
19942 +}
19943 +
19944 +/*
19945 + * processor_ocm()
19946 + *     Returns the OCM available to Linux.
19947 + */
19948 +int processor_ocm(void **socm, void **eocm)
19949 +{
19950 +       if (!pn) {
19951 +               return -ENOSYS;
19952 +       }
19953 +
19954 +       *socm = pn->socm;
19955 +       *eocm = pn->eocm;
19956 +       return 0;
19957 +}
19958 +
19959 +/*
19960 + * processor_dram()
19961 + *     Returns the dram available to Linux.
19962 + */
19963 +int processor_dram(void **sdram, void **edram)
19964 +{
19965 +       if (!pn) {
19966 +               return -ENOSYS;
19967 +       }
19968 +
19969 +       *sdram = pn->sdram;
19970 +       *edram = pn->edram;
19971 +       return 0;
19972 +}
19973 +
19974 +void __init processor_init(void)
19975 +{
19976 +       /*
19977 +        * If we do not have a trap node in the device tree, we leave the fault
19978 +        * handling to the underlying hardware.
19979 +        */
19980 +       pn = (struct procnode *)devtree_find_node("processor");
19981 +       if (!pn) {
19982 +               printk(KERN_WARNING "processor node not found\n");
19983 +               return;
19984 +       }
19985 +}
19986 --- /dev/null
19987 +++ b/arch/ubicom32/kernel/ptrace.c
19988 @@ -0,0 +1,275 @@
19989 +/*
19990 + * arch/ubicom32/kernel/ptrace.c
19991 + *   Ubicom32 architecture ptrace implementation.
19992 + *
19993 + * (C) Copyright 2009, Ubicom, Inc.
19994 + * (C) 1994 by Hamish Macdonald
19995 + * Taken from linux/kernel/ptrace.c and modified for M680x0.
19996 + * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
19997 + *
19998 + * This file is part of the Ubicom32 Linux Kernel Port.
19999 + *
20000 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20001 + * it and/or modify it under the terms of the GNU General Public License
20002 + * as published by the Free Software Foundation, either version 2 of the
20003 + * License, or (at your option) any later version.
20004 + *
20005 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20006 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20007 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20008 + * the GNU General Public License for more details.
20009 + *
20010 + * You should have received a copy of the GNU General Public License
20011 + * along with the Ubicom32 Linux Kernel Port.  If not,
20012 + * see <http://www.gnu.org/licenses/>.
20013 + *
20014 + * Ubicom32 implementation derived from (with many thanks):
20015 + *   arch/m68knommu
20016 + *   arch/blackfin
20017 + *   arch/parisc
20018 + */
20019 +
20020 +#include <linux/module.h>
20021 +#include <linux/kernel.h>
20022 +#include <linux/sched.h>
20023 +#include <linux/mm.h>
20024 +#include <linux/smp.h>
20025 +#include <linux/errno.h>
20026 +#include <linux/ptrace.h>
20027 +#include <linux/user.h>
20028 +#include <linux/signal.h>
20029 +#include <linux/uaccess.h>
20030 +
20031 +#include <asm/page.h>
20032 +#include <asm/pgtable.h>
20033 +#include <asm/system.h>
20034 +#include <asm/cacheflush.h>
20035 +#include <asm/processor.h>
20036 +
20037 +/*
20038 + * ptrace_getregs()
20039 + *
20040 + *     Get all user integer registers.
20041 + */
20042 +static inline int ptrace_getregs(struct task_struct *task, void __user *uregs)
20043 +{
20044 +       struct pt_regs *regs = task_pt_regs(task);
20045 +       return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
20046 +}
20047 +
20048 +/*
20049 + * ptrace_get_reg()
20050 + *
20051 + *     Get contents of register REGNO in task TASK.
20052 + */
20053 +static unsigned long ptrace_get_reg(struct task_struct *task, int regno)
20054 +{
20055 +       if (regno < sizeof(struct pt_regs)) {
20056 +               struct pt_regs *pt_regs = task_pt_regs(task);
20057 +               return *(unsigned long *)((long) pt_regs + regno);
20058 +       }
20059 +
20060 +       return -EIO;
20061 +}
20062 +
20063 +/*
20064 + * ptrace_put_reg()
20065 + *     Write contents of register REGNO in task TASK.
20066 + */
20067 +static int ptrace_put_reg(struct task_struct *task, int regno,
20068 +                         unsigned long data)
20069 +{
20070 +       if (regno <= sizeof(struct pt_regs) && regno != PT_FRAME_TYPE) {
20071 +               struct pt_regs *pt_regs = task_pt_regs(task);
20072 +               *(unsigned long *)((long) pt_regs + regno) = data;
20073 +               return 0;
20074 +       }
20075 +       return -EIO;
20076 +}
20077 +
20078 +/*
20079 + * ptrace_disable_single_step()
20080 + *     Disable Single Step
20081 + */
20082 +static int ptrace_disable_single_step(struct task_struct *task)
20083 +{
20084 +       /*
20085 +        * Single Step not yet implemented, so must always be disabled
20086 +        */
20087 +       return 0;
20088 +}
20089 +
20090 +/*
20091 + * ptrace_disable()
20092 + *     Make sure the single step bit is not set.
20093 + * Called by kernel/ptrace.c when detaching..
20094 + */
20095 +void ptrace_disable(struct task_struct *child)
20096 +{
20097 +       ptrace_disable_single_step(child);
20098 +}
20099 +
20100 +/*
20101 + * arch_ptrace()
20102 + *     architecture specific ptrace routine.
20103 + */
20104 +long arch_ptrace(struct task_struct *child, long request, long addr, long data)
20105 +{
20106 +       int ret;
20107 +       switch (request) {
20108 +       /* when I and D space are separate, these will need to be fixed. */
20109 +       case PTRACE_PEEKTEXT: /* read word at location addr. */
20110 +       case PTRACE_PEEKDATA:
20111 +               ret = generic_ptrace_peekdata(child, addr, data);
20112 +               break;
20113 +
20114 +       /* read the word at location addr in the USER area. */
20115 +       case PTRACE_PEEKUSR: {
20116 +               unsigned long tmp;
20117 +
20118 +               ret = -EIO;
20119 +               if (((unsigned long) addr > PT_INTERP_FDPIC_LOADMAP)
20120 +                   || (addr & 3))
20121 +                       break;
20122 +
20123 +               tmp = 0;  /* Default return condition */
20124 +
20125 +               ret = -EIO;
20126 +               if (addr < sizeof(struct pt_regs)) {
20127 +                       tmp = ptrace_get_reg(child, addr);
20128 +               } else if (addr == PT_TEXT_ADDR) {
20129 +                       tmp = child->mm->start_code;
20130 +               } else if (addr == PT_TEXT_END_ADDR) {
20131 +                       tmp = child->mm->end_code;
20132 +               } else if (addr == PT_DATA_ADDR) {
20133 +                       tmp = child->mm->start_data;
20134 +               } else if (addr == PT_EXEC_FDPIC_LOADMAP) {
20135 +#ifdef CONFIG_BINFMT_ELF_FDPIC
20136 +                       tmp = child->mm->context.exec_fdpic_loadmap;
20137 +#endif
20138 +               } else if (addr == PT_INTERP_FDPIC_LOADMAP) {
20139 +#ifdef CONFIG_BINFMT_ELF_FDPIC
20140 +                       tmp = child->mm->context.interp_fdpic_loadmap;
20141 +#endif
20142 +               } else {
20143 +                       break;
20144 +               }
20145 +
20146 +               ret = put_user(tmp, (unsigned long *)data);
20147 +               break;
20148 +       }
20149 +
20150 +       case PTRACE_POKETEXT: /* write the word at location addr. */
20151 +       case PTRACE_POKEDATA:
20152 +               ret = generic_ptrace_pokedata(child, addr, data);
20153 +
20154 +               /*
20155 +                * If we just changed some code so we need to
20156 +                * correct the caches
20157 +                */
20158 +               if (request == PTRACE_POKETEXT && ret == 0) {
20159 +                       flush_icache_range(addr, addr + 4);
20160 +               }
20161 +               break;
20162 +
20163 +       case PTRACE_POKEUSR: /* write the word at location addr
20164 +                             * in the USER area */
20165 +               ret = -EIO;
20166 +
20167 +               if (((unsigned long) addr > PT_DATA_ADDR) || (addr & 3))
20168 +                       break;
20169 +
20170 +               if (addr < sizeof(struct pt_regs)) {
20171 +                       ret = ptrace_put_reg(child, addr, data);
20172 +               }
20173 +               break;
20174 +
20175 +       case PTRACE_SYSCALL: /* continue and stop at next (return from)
20176 +                             * syscall */
20177 +       case PTRACE_CONT: { /* restart after signal. */
20178 +
20179 +               ret = -EIO;
20180 +               if (!valid_signal(data))
20181 +                       break;
20182 +               if (request == PTRACE_SYSCALL)
20183 +                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
20184 +               else
20185 +                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
20186 +               child->exit_code = data;
20187 +               /* make sure the single step bit is not set. */
20188 +               ptrace_disable_single_step(child);
20189 +               wake_up_process(child);
20190 +               ret = 0;
20191 +               break;
20192 +       }
20193 +
20194 +       /*
20195 +        * make the child exit.  Best I can do is send it a sigkill.
20196 +        * perhaps it should be put in the status that it wants to exit.
20197 +        */
20198 +       case PTRACE_KILL: {
20199 +               ret = 0;
20200 +               if (child->exit_state == EXIT_ZOMBIE) /* already dead */
20201 +                       break;
20202 +               child->exit_code = SIGKILL;
20203 +               /* make sure the single step bit is not set. */
20204 +               ptrace_disable_single_step(child);
20205 +               wake_up_process(child);
20206 +               break;
20207 +       }
20208 +
20209 +       case PTRACE_DETACH:     /* detach a process that was attached. */
20210 +               ret = ptrace_detach(child, data);
20211 +               break;
20212 +
20213 +       case PTRACE_GETREGS:    /* Get all gp regs from the child. */
20214 +               ptrace_getregs(child, (unsigned long *)data);
20215 +               ret = 0;
20216 +               break;
20217 +
20218 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
20219 +               int i;
20220 +               unsigned long tmp;
20221 +               int count = sizeof(struct pt_regs) / sizeof(unsigned long);
20222 +               for (i = 0; i < count; i++) {
20223 +                       if (get_user(tmp, (unsigned long *) data)) {
20224 +                               ret = -EFAULT;
20225 +                               break;
20226 +                       }
20227 +                       ptrace_put_reg(child, sizeof(unsigned long) * i, tmp);
20228 +                       data += sizeof(long);
20229 +               }
20230 +               ret = 0;
20231 +               break;
20232 +       }
20233 +
20234 +       default:
20235 +               return ptrace_request(child, request, addr, data);
20236 +               break;
20237 +       }
20238 +       return ret;
20239 +}
20240 +/*
20241 + * syscall_trace
20242 + *
20243 + * called by syscall enter/exit when the TIF_SYSCALL_TRACE bit is set.
20244 + */
20245 +asmlinkage void syscall_trace(void)
20246 +{
20247 +       struct task_struct *cur = current;
20248 +       if (!test_thread_flag(TIF_SYSCALL_TRACE))
20249 +               return;
20250 +       if (!(cur->ptrace & PT_PTRACED))
20251 +               return;
20252 +       ptrace_notify(SIGTRAP | ((cur->ptrace & PT_TRACESYSGOOD)
20253 +                                ? 0x80 : 0));
20254 +       /*
20255 +        * this isn't the same as continuing with a signal, but it will do
20256 +        * for normal use.  strace only continues with a signal if the
20257 +        * stopping signal is not SIGTRAP.  -brl
20258 +        */
20259 +       if (cur->exit_code) {
20260 +               send_sig(cur->exit_code, current, 1);
20261 +               current->exit_code = 0;
20262 +       }
20263 +}
20264 --- /dev/null
20265 +++ b/arch/ubicom32/kernel/semaphore.c
20266 @@ -0,0 +1,159 @@
20267 +/*
20268 + * arch/ubicom32/kernel/semaphore.c
20269 + *   Ubicom32 architecture semaphore implementation.
20270 + *
20271 + * (C) Copyright 2009, Ubicom, Inc.
20272 + *
20273 + * This file is part of the Ubicom32 Linux Kernel Port.
20274 + *
20275 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20276 + * it and/or modify it under the terms of the GNU General Public License
20277 + * as published by the Free Software Foundation, either version 2 of the
20278 + * License, or (at your option) any later version.
20279 + *
20280 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20281 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20282 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20283 + * the GNU General Public License for more details.
20284 + *
20285 + * You should have received a copy of the GNU General Public License
20286 + * along with the Ubicom32 Linux Kernel Port.  If not,
20287 + * see <http://www.gnu.org/licenses/>.
20288 + *
20289 + * Ubicom32 implementation derived from (with many thanks):
20290 + *   arch/m68knommu
20291 + *   arch/blackfin
20292 + *   arch/parisc
20293 + */
20294 +/*
20295 + *  Generic semaphore code. Buyer beware. Do your own
20296 + * specific changes in <asm/semaphore-helper.h>
20297 + */
20298 +
20299 +#include <linux/sched.h>
20300 +#include <linux/err.h>
20301 +#include <linux/init.h>
20302 +#include <asm/semaphore-helper.h>
20303 +
20304 +#ifndef CONFIG_RMW_INSNS
20305 +spinlock_t semaphore_wake_lock;
20306 +#endif
20307 +
20308 +/*
20309 + * Semaphores are implemented using a two-way counter:
20310 + * The "count" variable is decremented for each process
20311 + * that tries to sleep, while the "waking" variable is
20312 + * incremented when the "up()" code goes to wake up waiting
20313 + * processes.
20314 + *
20315 + * Notably, the inline "up()" and "down()" functions can
20316 + * efficiently test if they need to do any extra work (up
20317 + * needs to do something only if count was negative before
20318 + * the increment operation.
20319 + *
20320 + * waking_non_zero() (from asm/semaphore.h) must execute
20321 + * atomically.
20322 + *
20323 + * When __up() is called, the count was negative before
20324 + * incrementing it, and we need to wake up somebody.
20325 + *
20326 + * This routine adds one to the count of processes that need to
20327 + * wake up and exit.  ALL waiting processes actually wake up but
20328 + * only the one that gets to the "waking" field first will gate
20329 + * through and acquire the semaphore.  The others will go back
20330 + * to sleep.
20331 + *
20332 + * Note that these functions are only called when there is
20333 + * contention on the lock, and as such all this is the
20334 + * "non-critical" part of the whole semaphore business. The
20335 + * critical part is the inline stuff in <asm/semaphore.h>
20336 + * where we want to avoid any extra jumps and calls.
20337 + */
20338 +void __up(struct semaphore *sem)
20339 +{
20340 +       wake_one_more(sem);
20341 +       wake_up(&sem->wait);
20342 +}
20343 +
20344 +/*
20345 + * Perform the "down" function.  Return zero for semaphore acquired,
20346 + * return negative for signalled out of the function.
20347 + *
20348 + * If called from __down, the return is ignored and the wait loop is
20349 + * not interruptible.  This means that a task waiting on a semaphore
20350 + * using "down()" cannot be killed until someone does an "up()" on
20351 + * the semaphore.
20352 + *
20353 + * If called from __down_interruptible, the return value gets checked
20354 + * upon return.  If the return value is negative then the task continues
20355 + * with the negative value in the return register (it can be tested by
20356 + * the caller).
20357 + *
20358 + * Either form may be used in conjunction with "up()".
20359 + *
20360 + */
20361 +
20362 +
20363 +#define DOWN_HEAD(task_state)                                          \
20364 +                                                                       \
20365 +                                                                       \
20366 +       current->state = (task_state);                                  \
20367 +       add_wait_queue(&sem->wait, &wait);                              \
20368 +                                                                       \
20369 +       /*                                                              \
20370 +        * Ok, we're set up.  sem->count is known to be less than zero  \
20371 +        * so we must wait.                                             \
20372 +        *                                                              \
20373 +        * We can let go the lock for purposes of waiting.              \
20374 +        * We re-acquire it after awaking so as to protect              \
20375 +        * all semaphore operations.                                    \
20376 +        *                                                              \
20377 +        * If "up()" is called before we call waking_non_zero() then    \
20378 +        * we will catch it right away.  If it is called later then     \
20379 +        * we will have to go through a wakeup cycle to catch it.       \
20380 +        *                                                              \
20381 +        * Multiple waiters contend for the semaphore lock to see       \
20382 +        * who gets to gate through and who has to wait some more.      \
20383 +        */                                                             \
20384 +       for (;;) {
20385 +
20386 +#define DOWN_TAIL(task_state)                  \
20387 +               current->state = (task_state);  \
20388 +       }                                       \
20389 +       current->state = TASK_RUNNING;          \
20390 +       remove_wait_queue(&sem->wait, &wait);
20391 +
20392 +void __sched __down(struct semaphore *sem)
20393 +{
20394 +       DECLARE_WAITQUEUE(wait, current);
20395 +
20396 +       DOWN_HEAD(TASK_UNINTERRUPTIBLE)
20397 +       if (waking_non_zero(sem))
20398 +               break;
20399 +       schedule();
20400 +       DOWN_TAIL(TASK_UNINTERRUPTIBLE)
20401 +}
20402 +
20403 +int __sched __down_interruptible(struct semaphore *sem)
20404 +{
20405 +       DECLARE_WAITQUEUE(wait, current);
20406 +       int ret = 0;
20407 +
20408 +       DOWN_HEAD(TASK_INTERRUPTIBLE)
20409 +
20410 +       ret = waking_non_zero_interruptible(sem, current);
20411 +       if (ret) {
20412 +               if (ret == 1)
20413 +                       /* ret != 0 only if we get interrupted -arca */
20414 +                       ret = 0;
20415 +               break;
20416 +       }
20417 +       schedule();
20418 +       DOWN_TAIL(TASK_INTERRUPTIBLE)
20419 +       return ret;
20420 +}
20421 +
20422 +int __down_trylock(struct semaphore *sem)
20423 +{
20424 +       return waking_non_zero_trylock(sem);
20425 +}
20426 --- /dev/null
20427 +++ b/arch/ubicom32/kernel/setup.c
20428 @@ -0,0 +1,189 @@
20429 +/*
20430 + * arch/ubicom32/kernel/setup.c
20431 + *   Ubicom32 architecture-dependent parts of system setup.
20432 + *
20433 + * (C) Copyright 2009, Ubicom, Inc.
20434 + * Copyright (C) 1999-2007  Greg Ungerer (gerg@snapgear.com)
20435 + * Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
20436 + * Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
20437 + * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
20438 + * Copyright (C) 1995       Hamish Macdonald
20439 + * Copyright (C) 2000       Lineo Inc. (www.lineo.com)
20440 + * Copyright (C) 2001      Lineo, Inc. <www.lineo.com>
20441 + * 68VZ328 Fixes/support    Evan Stawnyczy <e@lineo.ca>
20442 + *
20443 + * This file is part of the Ubicom32 Linux Kernel Port.
20444 + *
20445 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20446 + * it and/or modify it under the terms of the GNU General Public License
20447 + * as published by the Free Software Foundation, either version 2 of the
20448 + * License, or (at your option) any later version.
20449 + *
20450 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20451 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20452 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20453 + * the GNU General Public License for more details.
20454 + *
20455 + * You should have received a copy of the GNU General Public License
20456 + * along with the Ubicom32 Linux Kernel Port.  If not,
20457 + * see <http://www.gnu.org/licenses/>.
20458 + *
20459 + * Ubicom32 implementation derived from (with many thanks):
20460 + *   arch/m68knommu
20461 + *   arch/blackfin
20462 + *   arch/parisc
20463 + */
20464 +
20465 +#include <linux/kernel.h>
20466 +#include <linux/sched.h>
20467 +#include <linux/delay.h>
20468 +#include <linux/interrupt.h>
20469 +#include <linux/fb.h>
20470 +#include <linux/module.h>
20471 +#include <linux/console.h>
20472 +#include <linux/errno.h>
20473 +#include <linux/string.h>
20474 +#include <linux/bootmem.h>
20475 +#include <linux/seq_file.h>
20476 +#include <linux/init.h>
20477 +
20478 +#include <asm/devtree.h>
20479 +#include <asm/setup.h>
20480 +#include <asm/irq.h>
20481 +#include <asm/machdep.h>
20482 +#include <asm/pgtable.h>
20483 +#include <asm/pgalloc.h>
20484 +#include <asm/ubicom32-common.h>
20485 +#include <asm/processor.h>
20486 +#include <asm/bootargs.h>
20487 +#include <asm/thread.h>
20488 +
20489 +unsigned long memory_start;
20490 +EXPORT_SYMBOL(memory_start);
20491 +
20492 +unsigned long memory_end;
20493 +EXPORT_SYMBOL(memory_end);
20494 +
20495 +static char __initdata command_line[COMMAND_LINE_SIZE];
20496 +#ifdef CONFIG_CMDLINE_BOOL
20497 +static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
20498 +#endif
20499 +
20500 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
20501 +
20502 +/*
20503 + * setup_arch()
20504 + *     Setup the architecture dependent portions of the system.
20505 + */
20506 +void __init setup_arch(char **cmdline_p)
20507 +{
20508 +       int bootmap_size;
20509 +
20510 +       processor_init();
20511 +       bootargs_init();
20512 +
20513 +       /*
20514 +        * TODO: The memory regions should really come from the
20515 +        * processor node.
20516 +        */
20517 +       memory_start = PAGE_ALIGN(((unsigned long)&_end));
20518 +       memory_end = CONFIG_RAMBASE+CONFIG_RAMSIZE;
20519 +
20520 +       init_mm.start_code = (unsigned long) &_stext;
20521 +       init_mm.end_code = (unsigned long) &_etext;
20522 +       init_mm.end_data = (unsigned long) &_edata;
20523 +       init_mm.brk = (unsigned long) 0;
20524 +
20525 +       strlcpy(boot_command_line, bootargs_get_cmdline(), COMMAND_LINE_SIZE);
20526 +
20527 +#ifdef CONFIG_CMDLINE_BOOL
20528 +#ifdef CONFIG_CMDLINE_OVERRIDE
20529 +       strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
20530 +#else
20531 +       if (builtin_cmdline[0]) {
20532 +               /* append boot loader cmdline to builtin */
20533 +               strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
20534 +               strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
20535 +               strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
20536 +       }
20537 +#endif
20538 +#endif
20539 +
20540 +       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
20541 +       *cmdline_p = command_line;
20542 +
20543 +       parse_early_param();
20544 +
20545 +       printk(KERN_INFO "%s Processor, Ubicom, Inc. <www.ubicom.com>\n", CPU);
20546 +
20547 +#if defined(DEBUG)
20548 +       printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
20549 +               "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
20550 +               (int) &_sdata, (int) &_edata,
20551 +               (int) &_sbss, (int) &_ebss);
20552 +       printk(KERN_DEBUG "MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
20553 +               (int) &_ebss, (int) memory_start,
20554 +               (int) memory_start, (int) memory_end);
20555 +#endif
20556 +
20557 +       /* Keep a copy of command line */
20558 +       *cmdline_p = &command_line[0];
20559 +       memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
20560 +       boot_command_line[COMMAND_LINE_SIZE-1] = 0;
20561 +
20562 +#ifdef DEBUG
20563 +       if (strlen(*cmdline_p))
20564 +               printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
20565 +#endif
20566 +
20567 +#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
20568 +       conswitchp = &dummy_con;
20569 +#endif
20570 +
20571 +       /*
20572 +        * If we have a device tree, see if we have the nodes we need.
20573 +        */
20574 +       if (devtree) {
20575 +               devtree_print();
20576 +       }
20577 +
20578 +       /*
20579 +        * From the arm initialization comment:
20580 +        *
20581 +        * This doesn't seem to be used by the Linux memory manager any
20582 +        * more, but is used by ll_rw_block.  If we can get rid of it, we
20583 +        * also get rid of some of the stuff above as well.
20584 +        *
20585 +        * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
20586 +        * the system, not the maximum PFN.
20587 +        */
20588 +       max_pfn = max_low_pfn = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
20589 +
20590 +       /*
20591 +        * Give all the memory to the bootmap allocator, tell it to put the
20592 +        * boot mem_map at the start of memory.
20593 +        */
20594 +       bootmap_size = init_bootmem_node(
20595 +                       NODE_DATA(0),
20596 +                       memory_start >> PAGE_SHIFT,     /* map goes here */
20597 +                       PAGE_OFFSET >> PAGE_SHIFT,      /* 0 on coldfire */
20598 +                       memory_end >> PAGE_SHIFT);
20599 +       /*
20600 +        * Free the usable memory, we have to make sure we do not free
20601 +        * the bootmem bitmap so we then reserve it after freeing it :-)
20602 +        */
20603 +       free_bootmem(memory_start, memory_end - memory_start);
20604 +       reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
20605 +
20606 +       /*
20607 +        * Get kmalloc into gear.
20608 +        */
20609 +       paging_init();
20610 +
20611 +       /*
20612 +        * Fix up the thread_info structure, indicate this is a mainline Linux
20613 +        * thread and setup the sw_ksp().
20614 +        */
20615 +       sw_ksp[thread_get_self()] = (unsigned int) current_thread_info();
20616 +       thread_set_mainline(thread_get_self());
20617 +}
20618 --- /dev/null
20619 +++ b/arch/ubicom32/kernel/signal.c
20620 @@ -0,0 +1,458 @@
20621 +/*
20622 + * arch/ubicom32/kernel/signal.c
20623 + *   Ubicom32 architecture signal handling implementation.
20624 + *
20625 + * (C) Copyright 2009, Ubicom, Inc.
20626 + * Copyright (C) 1991, 1992  Linus Torvalds
20627 + * Linux/m68k support by Hamish Macdonald
20628 + * 68060 fixes by Jesper Skov
20629 + * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
20630 + * mathemu support by Roman Zippel
20631 + * ++roman (07/09/96): implemented signal stacks
20632 + *
20633 + * This file is part of the Ubicom32 Linux Kernel Port.
20634 + *
20635 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
20636 + * it and/or modify it under the terms of the GNU General Public License
20637 + * as published by the Free Software Foundation, either version 2 of the
20638 + * License, or (at your option) any later version.
20639 + *
20640 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
20641 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20642 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
20643 + * the GNU General Public License for more details.
20644 + *
20645 + * You should have received a copy of the GNU General Public License
20646 + * along with the Ubicom32 Linux Kernel Port.  If not,
20647 + * see <http://www.gnu.org/licenses/>.
20648 + *
20649 + * Ubicom32 implementation derived from (with many thanks):
20650 + *   arch/m68knommu
20651 + *   arch/blackfin
20652 + *   arch/parisc
20653 + *
20654 + * mathemu support by Roman Zippel
20655 + *  (Note: fpstate in the signal context is completely ignored for the emulator
20656 + *         and the internal floating point format is put on stack)
20657 + *
20658 + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
20659 + * Atari :-) Current limitation: Only one sigstack can be active at one time.
20660 + * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
20661 + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
20662 + * signal handlers!
20663 + */
20664 +
20665 +#include <linux/module.h>
20666 +#include <linux/sched.h>
20667 +#include <linux/mm.h>
20668 +#include <linux/kernel.h>
20669 +#include <linux/signal.h>
20670 +#include <linux/syscalls.h>
20671 +#include <linux/errno.h>
20672 +#include <linux/wait.h>
20673 +#include <linux/ptrace.h>
20674 +#include <linux/unistd.h>
20675 +#include <linux/stddef.h>
20676 +#include <linux/highuid.h>
20677 +#include <linux/tty.h>
20678 +#include <linux/personality.h>
20679 +#include <linux/binfmts.h>
20680 +
20681 +#include <asm/setup.h>
20682 +#include <asm/uaccess.h>
20683 +#include <asm/pgtable.h>
20684 +#include <asm/traps.h>
20685 +#include <asm/ucontext.h>
20686 +
20687 +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
20688 +
20689 +/*
20690 + * asm signal return handlers.
20691 + */
20692 +void ret_from_user_signal(void);
20693 +void ret_from_user_rt_signal(void);
20694 +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
20695 +
20696 +/*
20697 + * Common signal suspend implementation
20698 + */
20699 +static int signal_suspend(sigset_t *saveset, struct pt_regs *regs)
20700 +{
20701 +       regs->dn[0] = -EINTR;
20702 +       while (1) {
20703 +               current->state = TASK_INTERRUPTIBLE;
20704 +               schedule();
20705 +               if (!do_signal(saveset, regs)) {
20706 +                       continue;
20707 +               }
20708 +               /*
20709 +                * If the current frame type is a signal trampoline we are
20710 +                * actually going to call the signal handler so we return the
20711 +                * desired d0 as the return value.
20712 +                */
20713 +               if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) {
20714 +                       return regs->dn[0];
20715 +               }
20716 +               return -EINTR;
20717 +       }
20718 +       /*
20719 +        * Should never get here
20720 +        */
20721 +       BUG();
20722 +       return 0;
20723 +}
20724 +
20725 +/*
20726 + * Atomically swap in the new signal mask, and wait for a signal.
20727 + */
20728 +asmlinkage int do_sigsuspend(struct pt_regs *regs)
20729 +{
20730 +       old_sigset_t mask = regs->dn[0];
20731 +       sigset_t saveset;
20732 +
20733 +       mask &= _BLOCKABLE;
20734 +       spin_lock_irq(&current->sighand->siglock);
20735 +       saveset = current->blocked;
20736 +       siginitset(&current->blocked, mask);
20737 +       recalc_sigpending();
20738 +       spin_unlock_irq(&current->sighand->siglock);
20739 +
20740 +       /*
20741 +        * Call common handler
20742 +        */
20743 +       return signal_suspend(&saveset, regs);
20744 +}
20745 +
20746 +asmlinkage int
20747 +do_rt_sigsuspend(struct pt_regs *regs)
20748 +{
20749 +       sigset_t *unewset = (sigset_t *)regs->dn[0];
20750 +       size_t sigsetsize = (size_t)regs->dn[1];
20751 +       sigset_t saveset, newset;
20752 +
20753 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
20754 +       if (sigsetsize != sizeof(sigset_t))
20755 +               return -EINVAL;
20756 +
20757 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
20758 +               return -EFAULT;
20759 +       sigdelsetmask(&newset, ~_BLOCKABLE);
20760 +
20761 +       spin_lock_irq(&current->sighand->siglock);
20762 +       saveset = current->blocked;
20763 +       current->blocked = newset;
20764 +       recalc_sigpending();
20765 +       spin_unlock_irq(&current->sighand->siglock);
20766 +
20767 +       /*
20768 +        * Call common handler
20769 +        */
20770 +       return signal_suspend(&saveset, regs);
20771 +}
20772 +
20773 +asmlinkage int
20774 +sys_sigaction(int sig, const struct old_sigaction *act,
20775 +             struct old_sigaction *oact)
20776 +{
20777 +       struct k_sigaction new_ka, old_ka;
20778 +       int ret;
20779 +
20780 +       if (act) {
20781 +               old_sigset_t mask;
20782 +               if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
20783 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
20784 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
20785 +                       return -EFAULT;
20786 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
20787 +               __get_user(mask, &act->sa_mask);
20788 +               siginitset(&new_ka.sa.sa_mask, mask);
20789 +       }
20790 +
20791 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
20792 +
20793 +       if (!ret && oact) {
20794 +               if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
20795 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
20796 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
20797 +                       return -EFAULT;
20798 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
20799 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
20800 +       }
20801 +
20802 +       return ret;
20803 +}
20804 +
20805 +asmlinkage int
20806 +do_sys_sigaltstack(struct pt_regs *regs)
20807 +{
20808 +       const stack_t *uss = (stack_t *) regs->dn[0];
20809 +       stack_t *uoss = (stack_t *)regs->dn[1];
20810 +       return do_sigaltstack(uss, uoss, regs->an[7]);
20811 +}
20812 +
20813 +/*
20814 + * fdpic_func_descriptor describes sa_handler when the application is FDPIC
20815 + */
20816 +struct fdpic_func_descriptor {
20817 +       unsigned long   text;
20818 +       unsigned long   GOT;
20819 +};
20820 +
20821 +/*
20822 + * rt_sigframe is stored on the user stack immediately before (above)
20823 + * the signal handlers stack.
20824 + */
20825 +struct rt_sigframe
20826 +{
20827 +       unsigned long syscall_number;   /* This holds __NR_rt_sigreturn. */
20828 +       unsigned long restore_all_regs; /* This field gets set to 1 if the frame
20829 +                                        * type is TRAP or INTERRUPT. */
20830 +       siginfo_t *info;
20831 +       struct ucontext uc;
20832 +       int sig;
20833 +       void *pretcode;
20834 +};
20835 +
20836 +/*
20837 + * Do a signal return; undo the signal stack.
20838 + */
20839 +asmlinkage int do_sigreturn(unsigned long __unused)
20840 +{
20841 +       BUG();
20842 +       return 0;
20843 +}
20844 +
20845 +asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
20846 +{
20847 +       unsigned long usp = regs->an[7];
20848 +       struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
20849 +       sigset_t set;
20850 +
20851 +       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
20852 +               goto badframe;
20853 +       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
20854 +               goto badframe;
20855 +
20856 +       sigdelsetmask(&set, ~_BLOCKABLE);
20857 +       spin_lock_irq(&current->sighand->siglock);
20858 +       current->blocked = set;
20859 +       recalc_sigpending();
20860 +       spin_unlock_irq(&current->sighand->siglock);
20861 +
20862 +       if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs)))
20863 +               goto badframe;
20864 +       return regs->dn[0];
20865 +
20866 +badframe:
20867 +       force_sig(SIGSEGV, current);
20868 +       return 0;
20869 +}
20870 +
20871 +static inline void *
20872 +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
20873 +{
20874 +       unsigned long usp;
20875 +
20876 +       /* Default to using normal stack.  */
20877 +       usp = regs->an[7];
20878 +
20879 +       /* This is the X/Open sanctioned signal stack switching.  */
20880 +       if (ka->sa.sa_flags & SA_ONSTACK) {
20881 +               if (!sas_ss_flags(usp))
20882 +                       usp = current->sas_ss_sp + current->sas_ss_size;
20883 +       }
20884 +       return (void *)((usp - frame_size) & ~0x3);
20885 +}
20886 +
20887 +/*
20888 + * signal_trampoline:  Defined in ubicom32_syscall.S
20889 + */
20890 +asmlinkage void signal_trampoline(void)__attribute__((naked));
20891 +
20892 +static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
20893 +                           sigset_t *set, struct pt_regs *regs)
20894 +{
20895 +       struct rt_sigframe *frame;
20896 +       int err = 0;
20897 +
20898 +       frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame));
20899 +
20900 +       /*
20901 +        * The 'err |=' have been may criticized as bad code style, but I
20902 +        * strongly suspect that we want this code to be fast.  So for
20903 +        * now it stays as is.
20904 +        */
20905 +       err |= __put_user( (  (current_thread_info()->exec_domain)
20906 +                          && (current_thread_info()->exec_domain->signal_invmap)
20907 +                          && (sig < 32) )
20908 +                          ? current_thread_info()->exec_domain->signal_invmap[sig]
20909 +                          : sig, &frame->sig);
20910 +       err |= __put_user(info, &frame->info);
20911 +
20912 +       /* Create the ucontext.  */
20913 +       err |= __put_user(0, &frame->uc.uc_flags);
20914 +       err |= __put_user(0, &frame->uc.uc_link);
20915 +       err |= __put_user((void *)current->sas_ss_sp,
20916 +                         &frame->uc.uc_stack.ss_sp);
20917 +       err |= __put_user(sas_ss_flags(regs->an[7]),
20918 +                         &frame->uc.uc_stack.ss_flags);
20919 +       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
20920 +       err |= __put_user(__NR_rt_sigreturn, &frame->syscall_number);
20921 +       if ((regs->frame_type == UBICOM32_FRAME_TYPE_TRAP) ||
20922 +           (regs->frame_type == UBICOM32_FRAME_TYPE_INTERRUPT)) {
20923 +               err |= __put_user(1, &frame->restore_all_regs);
20924 +       } else {
20925 +               err |= __put_user(0, &frame->restore_all_regs);
20926 +       }
20927 +       err |= copy_to_user (&frame->uc.uc_mcontext.sc_regs, regs, sizeof(struct pt_regs));
20928 +       err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
20929 +
20930 +       if (err)
20931 +               goto give_sigsegv;
20932 +
20933 +       /*
20934 +        * Set up registers for signal handler NOTE: Do not modify dn[14], it
20935 +        * contains the userspace tls pointer, so it important that it carries
20936 +        * over to the signal handler.
20937 +        */
20938 +       regs->an[7] = (unsigned long)frame;
20939 +       regs->pc = (unsigned long) signal_trampoline;
20940 +       regs->an[5] = (unsigned long) signal_trampoline;
20941 +       regs->dn[0] = sig;
20942 +       regs->dn[1] = (unsigned long) frame->info;
20943 +       regs->dn[2] = (unsigned int) &frame->uc;
20944 +
20945 +       /*
20946 +        * If this is FDPIC then the signal handler is actually a function
20947 +        * descriptor.
20948 +        */
20949 +       if (current->personality & FDPIC_FUNCPTRS) {
20950 +               struct fdpic_func_descriptor __user *funcptr =
20951 +                       (struct fdpic_func_descriptor *) ka->sa.sa_handler;
20952 +               err |= __get_user(regs->dn[3], &funcptr->text);
20953 +               err |= __get_user(regs->an[0], &funcptr->GOT);
20954 +               if (err)
20955 +                       goto give_sigsegv;
20956 +
20957 +               /*
20958 +                * The funcdesc must be in a3 as this is required for the lazy
20959 +                * resolver in ld.so, if the application is not FDPIC a3 is not
20960 +                * used.
20961 +                */
20962 +               regs->an[3] = (unsigned long) funcptr;
20963 +
20964 +       } else {
20965 +               regs->dn[3] = (unsigned long)ka->sa.sa_handler;
20966 +               regs->an[0] = 0;
20967 +       }
20968 +
20969 +       regs->frame_type =  UBICOM32_FRAME_TYPE_SIGTRAMP;
20970 +
20971 +       return;
20972 +
20973 +give_sigsegv:
20974 +       /* user space exception */
20975 +       force_sigsegv(sig, current);
20976 +}
20977 +
20978 +static inline void
20979 +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
20980 +{
20981 +       switch (regs->dn[0]) {
20982 +       case -ERESTARTNOHAND:
20983 +               if (!has_handler)
20984 +                       goto do_restart;
20985 +               regs->dn[0] = -EINTR;
20986 +               break;
20987 +
20988 +       case -ERESTARTSYS:
20989 +               if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
20990 +                       regs->dn[0] = -EINTR;
20991 +                       break;
20992 +               }
20993 +       /* fallthrough */
20994 +       case -ERESTARTNOINTR:
20995 +       do_restart:
20996 +               regs->dn[0] = regs->original_dn_0;
20997 +               regs->pc -= 8;
20998 +               regs->an[5] -= 8;
20999 +               break;
21000 +       }
21001 +}
21002 +
21003 +/*
21004 + * OK, we're invoking a handler
21005 + */
21006 +static void
21007 +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
21008 +             sigset_t *oldset, struct pt_regs *regs)
21009 +{
21010 +       /* are we from a system call? */
21011 +       if (regs->frame_type == -1)
21012 +               /* If so, check system call restarting.. */
21013 +               handle_restart(regs, ka, 1);
21014 +
21015 +       /* set up the stack frame */
21016 +       setup_rt_frame(sig, ka, info, oldset, regs);
21017 +
21018 +       if (ka->sa.sa_flags & SA_ONESHOT)
21019 +               ka->sa.sa_handler = SIG_DFL;
21020 +
21021 +       spin_lock_irq(&current->sighand->siglock);
21022 +       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
21023 +       if (!(ka->sa.sa_flags & SA_NODEFER))
21024 +               sigaddset(&current->blocked,sig);
21025 +       recalc_sigpending();
21026 +       spin_unlock_irq(&current->sighand->siglock);
21027 +}
21028 +
21029 +/*
21030 + * Note that 'init' is a special process: it doesn't get signals it doesn't
21031 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
21032 + * mistake.
21033 + */
21034 +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
21035 +{
21036 +       struct k_sigaction ka;
21037 +       siginfo_t info;
21038 +       int signr;
21039 +
21040 +       /*
21041 +        * We want the common case to go fast, which
21042 +        * is why we may in certain cases get here from
21043 +        * kernel mode. Just return without doing anything
21044 +        * if so.
21045 +        */
21046 +       if (!user_mode(regs))
21047 +               return 1;
21048 +
21049 +       if (!oldset)
21050 +               oldset = &current->blocked;
21051 +
21052 +       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
21053 +       if (signr > 0) {
21054 +               /* Whee!  Actually deliver the signal.  */
21055 +               handle_signal(signr, &ka, &info, oldset, regs);
21056 +               return 1;
21057 +       }
21058 +
21059 +       /* Did we come from a system call? */
21060 +       if (regs->frame_type == -1) {
21061 +               /* Restart the system call - no handlers present */
21062 +               handle_restart(regs, NULL, 0);
21063 +       }
21064 +
21065 +       return 0;
21066 +}
21067 +
21068 +/*
21069 + * sys_sigreturn()
21070 + *     Return handler for signal clean-up.
21071 + *
21072 + * NOTE: Ubicom32 does not use this syscall.  Instead we rely
21073 + * on do_rt_sigreturn().
21074 + */
21075 +asmlinkage long sys_sigreturn(void)
21076 +{
21077 +       return -ENOSYS;
21078 +}
21079 --- /dev/null
21080 +++ b/arch/ubicom32/kernel/smp.c
21081 @@ -0,0 +1,808 @@
21082 +/*
21083 + * arch/ubicom32/kernel/smp.c
21084 + *   SMP implementation for Ubicom32 processors.
21085 + *
21086 + * (C) Copyright 2009, Ubicom, Inc.
21087 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
21088 + * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
21089 + * Copyright (C) 2001,2004 Grant Grundler <grundler@parisc-linux.org>
21090 + *
21091 + * This file is part of the Ubicom32 Linux Kernel Port.
21092 + *
21093 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
21094 + * it and/or modify it under the terms of the GNU General Public License
21095 + * as published by the Free Software Foundation, either version 2 of the
21096 + * License, or (at your option) any later version.
21097 + *
21098 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21099 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
21100 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
21101 + * the GNU General Public License for more details.
21102 + *
21103 + * You should have received a copy of the GNU General Public License
21104 + * along with the Ubicom32 Linux Kernel Port.  If not,
21105 + * see <http://www.gnu.org/licenses/>.
21106 + *
21107 + * Ubicom32 implementation derived from (with many thanks):
21108 + *   arch/m68knommu
21109 + *   arch/blackfin
21110 + *   arch/parisc
21111 + */
21112 +
21113 +#include <linux/types.h>
21114 +#include <linux/spinlock.h>
21115 +#include <linux/slab.h>
21116 +
21117 +#include <linux/kernel.h>
21118 +#include <linux/bootmem.h>
21119 +#include <linux/module.h>
21120 +#include <linux/sched.h>
21121 +#include <linux/init.h>
21122 +#include <linux/interrupt.h>
21123 +#include <linux/smp.h>
21124 +#include <linux/kernel_stat.h>
21125 +#include <linux/mm.h>
21126 +#include <linux/err.h>
21127 +#include <linux/delay.h>
21128 +#include <linux/bitops.h>
21129 +#include <linux/cpu.h>
21130 +#include <linux/profile.h>
21131 +#include <linux/delay.h>
21132 +#include <linux/io.h>
21133 +#include <linux/ptrace.h>
21134 +#include <linux/unistd.h>
21135 +#include <linux/irq.h>
21136 +
21137 +#include <asm/system.h>
21138 +#include <asm/atomic.h>
21139 +#include <asm/current.h>
21140 +#include <asm/tlbflush.h>
21141 +#include <asm/timex.h>
21142 +#include <asm/cpu.h>
21143 +#include <asm/irq.h>
21144 +#include <asm/processor.h>
21145 +#include <asm/thread.h>
21146 +#include <asm/sections.h>
21147 +#include <asm/ip5000.h>
21148 +
21149 +/*
21150 + * Mask the debug printout for IPI because they are too verbose
21151 + * for regular debugging.
21152 + */
21153 +
21154 +// #define DEBUG_SMP 1
21155 +#if !defined(DEBUG_SMP)
21156 +#define smp_debug(lvl, ...)
21157 +#else
21158 +static unsigned int smp_debug_lvl = 50;
21159 +#define smp_debug(lvl, printargs...)           \
21160 +       if (lvl >= smp_debug_lvl) {             \
21161 +                       printk(printargs);      \
21162 +       }
21163 +#endif
21164 +
21165 +#if !defined(DEBUG_SMP)
21166 +#define DEBUG_ASSERT(cond)
21167 +#else
21168 +#define DEBUG_ASSERT(cond) \
21169 +       if (!(cond)) { \
21170 +               THREAD_STALL; \
21171 +       }
21172 +#endif
21173 +
21174 +/*
21175 + * List of IPI Commands (more than one can be set at a time).
21176 + */
21177 +enum ipi_message_type {
21178 +       IPI_NOP,
21179 +       IPI_RESCHEDULE,
21180 +       IPI_CALL_FUNC,
21181 +       IPI_CALL_FUNC_SINGLE,
21182 +       IPI_CPU_STOP,
21183 +       IPI_CPU_TIMER,
21184 +};
21185 +
21186 +/*
21187 + * These values are properly adjusted by smp_prepare_cpus() below.  They are
21188 + * required to be declared in the arch directory if CONFIG_SMP is set.
21189 + */
21190 +cpumask_t cpu_online_map = CPU_MASK_NONE;  /* Bitmap of online CPUs */
21191 +EXPORT_SYMBOL(cpu_online_map);
21192 +
21193 +cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */
21194 +EXPORT_SYMBOL(cpu_possible_map);
21195 +
21196 +/*
21197 + * We maintain a hardware thread oriented view of online threads
21198 + * and those involved or needing IPI.
21199 + */
21200 +static unsigned long smp_online_threads = 0;
21201 +static unsigned long smp_needs_ipi = 0;
21202 +static unsigned long smp_inside_ipi = 0;
21203 +static unsigned long smp_irq_affinity[NR_IRQS];
21204 +
21205 +/*
21206 + * What do we need to track on a per cpu/thread basis?
21207 + */
21208 +DEFINE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
21209 +
21210 +/*
21211 + * Each thread cpuinfo IPI information is guarded by a lock
21212 + * that is kept local to this file.
21213 + */
21214 +DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
21215 +
21216 +/*
21217 + * The IPI(s) are based on a software IRQ through the LDSR.
21218 + */
21219 +unsigned int smp_ipi_irq;
21220 +
21221 +/*
21222 + * Define a spinlock so that only one cpu is able to modify the
21223 + * smp_needs_ipi and to set/clear the IRQ at a time.
21224 + */
21225 +DEFINE_SPINLOCK(smp_ipi_lock);
21226 +
21227 +/*
21228 + * smp_halt_processor()
21229 + *     Halt this hardware thread.
21230 + */
21231 +static void smp_halt_processor(void)
21232 +{
21233 +       int cpuid = thread_get_self();
21234 +       cpu_clear(smp_processor_id(), cpu_online_map);
21235 +       local_irq_disable();
21236 +       printk(KERN_EMERG "cpu[%d] has halted. It is not OK to turn off power \
21237 +               until all cpu's are off.\n", cpuid);
21238 +       for (;;) {
21239 +               thread_suspend();
21240 +       }
21241 +}
21242 +
21243 +/*
21244 + * ipi_interrupt()
21245 + *     Handle an Interprocessor Interrupt.
21246 + */
21247 +static irqreturn_t ipi_interrupt(int irq, void *dev_id)
21248 +{
21249 +       int cpuid = smp_processor_id();
21250 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21251 +       unsigned long ops;
21252 +
21253 +       /*
21254 +        * Count this now; we may make a call that never returns.
21255 +        */
21256 +       p->ipi_count++;
21257 +
21258 +       /*
21259 +        * We are about to process all ops.  If another cpu has stated
21260 +        * that we need an IPI, we will have already processed it.  By
21261 +        * clearing our smp_needs_ipi, and processing all ops,
21262 +        * we reduce the number of IPI interrupts.  However, this introduces
21263 +        * the possibility that smp_needs_ipi will be clear and the soft irq
21264 +        * will have gone off; so we need to make the get_affinity() path
21265 +        * tolerant of spurious interrupts.
21266 +        */
21267 +       spin_lock(&smp_ipi_lock);
21268 +       smp_needs_ipi &= ~p->tid;
21269 +       spin_unlock(&smp_ipi_lock);
21270 +
21271 +       for (;;) {
21272 +               /*
21273 +                * Read the set of IPI commands we should handle.
21274 +                */
21275 +               spinlock_t *lock = &per_cpu(ipi_lock, cpuid);
21276 +               spin_lock(lock);
21277 +               ops = p->ipi_pending;
21278 +               p->ipi_pending = 0;
21279 +               spin_unlock(lock);
21280 +
21281 +               /*
21282 +                * If we have no IPI commands to execute, break out.
21283 +                */
21284 +               if (!ops) {
21285 +                       break;
21286 +               }
21287 +
21288 +               /*
21289 +                * Execute the set of commands in the ops word, one command
21290 +                * at a time in no particular order.  Strip of each command
21291 +                * as we execute it.
21292 +                */
21293 +               while (ops) {
21294 +                       unsigned long which = ffz(~ops);
21295 +                       ops &= ~(1 << which);
21296 +
21297 +                       BUG_ON(!irqs_disabled());
21298 +                       switch (which) {
21299 +                       case IPI_NOP:
21300 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21301 +                                         "IPI_NOP\n", cpuid);
21302 +                               break;
21303 +
21304 +                       case IPI_RESCHEDULE:
21305 +                               /*
21306 +                                * Reschedule callback.  Everything to be
21307 +                                * done is done by the interrupt return path.
21308 +                                */
21309 +                               smp_debug(200, KERN_INFO "cpu[%d]: "
21310 +                                         "IPI_RESCHEDULE\n", cpuid);
21311 +                               break;
21312 +
21313 +                       case IPI_CALL_FUNC:
21314 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21315 +                                         "IPI_CALL_FUNC\n", cpuid);
21316 +                               generic_smp_call_function_interrupt();
21317 +                               break;
21318 +
21319 +                       case IPI_CALL_FUNC_SINGLE:
21320 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21321 +                                         "IPI_CALL_FUNC_SINGLE\n", cpuid);
21322 +                               generic_smp_call_function_single_interrupt();
21323 +                               break;
21324 +
21325 +                       case IPI_CPU_STOP:
21326 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21327 +                                         "IPI_CPU_STOP\n", cpuid);
21328 +                               smp_halt_processor();
21329 +                               break;
21330 +
21331 +#if !defined(CONFIG_LOCAL_TIMERS)
21332 +                       case IPI_CPU_TIMER:
21333 +                               smp_debug(100, KERN_INFO "cpu[%d]: "
21334 +                                         "IPI_CPU_TIMER\n", cpuid);
21335 +#if defined(CONFIG_GENERIC_CLOCKEVENTS)
21336 +                               local_timer_interrupt();
21337 +#else
21338 +                               update_process_times(user_mode(get_irq_regs()));
21339 +                               profile_tick(CPU_PROFILING);
21340 +#endif
21341 +#endif
21342 +                               break;
21343 +
21344 +                       default:
21345 +                               printk(KERN_CRIT "cpu[%d]: "
21346 +                                         "Unknown IPI: %lu\n", cpuid, which);
21347 +
21348 +                               return IRQ_NONE;
21349 +                       }
21350 +
21351 +                       /*
21352 +                        * Let in any pending interrupts
21353 +                        */
21354 +                       BUG_ON(!irqs_disabled());
21355 +                       local_irq_enable();
21356 +                       local_irq_disable();
21357 +               }
21358 +       }
21359 +       return IRQ_HANDLED;
21360 +}
21361 +
21362 +/*
21363 + * ipi_send()
21364 + *     Send an Interprocessor Interrupt.
21365 + */
21366 +static void ipi_send(int cpu, enum ipi_message_type op)
21367 +{
21368 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21369 +       spinlock_t *lock = &per_cpu(ipi_lock, cpu);
21370 +       unsigned long flags;
21371 +
21372 +       /*
21373 +        * We protect the setting of the ipi_pending field and ensure
21374 +        * that the ipi delivery mechanism and interrupt are atomically
21375 +        * handled.
21376 +        */
21377 +       spin_lock_irqsave(lock, flags);
21378 +       p->ipi_pending |= 1 << op;
21379 +       spin_unlock_irqrestore(lock, flags);
21380 +
21381 +       spin_lock_irqsave(&smp_ipi_lock, flags);
21382 +       smp_needs_ipi |= (1 << p->tid);
21383 +       ubicom32_set_interrupt(smp_ipi_irq);
21384 +       spin_unlock_irqrestore(&smp_ipi_lock, flags);
21385 +}
21386 +
21387 +/*
21388 + * ipi_send_mask
21389 + *     Send an IPI to each cpu in mask.
21390 + */
21391 +static inline void ipi_send_mask(unsigned int op, cpumask_t mask)
21392 +{
21393 +       int cpu;
21394 +       for_each_cpu_mask(cpu, mask) {
21395 +               ipi_send(cpu, op);
21396 +       }
21397 +}
21398 +
21399 +/*
21400 + * ipi_send_allbutself()
21401 + *     Send an IPI to all threads but ourselves.
21402 + */
21403 +static inline void ipi_send_allbutself(unsigned int op)
21404 +{
21405 +       int self = smp_processor_id();
21406 +       cpumask_t result = cpu_online_map;
21407 +       cpu_clear(self, result);
21408 +       ipi_send_mask(op, result);
21409 +}
21410 +
21411 +/*
21412 + * smp_enable_vector()
21413 + */
21414 +static void smp_enable_vector(unsigned int irq)
21415 +{
21416 +       ubicom32_clear_interrupt(smp_ipi_irq);
21417 +       ldsr_enable_vector(irq);
21418 +}
21419 +
21420 +/*
21421 + * smp_disable_vector()
21422 + *     Disable the interrupt by clearing the appropriate bit in the
21423 + *     LDSR Mask Register.
21424 + */
21425 +static void smp_disable_vector(unsigned int irq)
21426 +{
21427 +       ldsr_disable_vector(irq);
21428 +}
21429 +
21430 +/*
21431 + * smp_mask_vector()
21432 + */
21433 +static void smp_mask_vector(unsigned int irq)
21434 +{
21435 +       ldsr_mask_vector(irq);
21436 +}
21437 +
21438 +/*
21439 + * smp_unmask_vector()
21440 + */
21441 +static void smp_unmask_vector(unsigned int irq)
21442 +{
21443 +       ldsr_unmask_vector(irq);
21444 +}
21445 +
21446 +/*
21447 + * smp_end_vector()
21448 + *     Called once an interrupt is completed (reset the LDSR mask).
21449 + */
21450 +static void smp_end_vector(unsigned int irq)
21451 +{
21452 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, smp_processor_id());
21453 +       spin_lock(&smp_ipi_lock);
21454 +       smp_inside_ipi &= ~(1 << p->tid);
21455 +       if (smp_inside_ipi) {
21456 +               spin_unlock(&smp_ipi_lock);
21457 +               return;
21458 +       }
21459 +       spin_unlock(&smp_ipi_lock);
21460 +       ldsr_unmask_vector(irq);
21461 +}
21462 +
21463 +/*
21464 + * Special hanlder functions for SMP.
21465 + */
21466 +static struct irq_chip ubicom32_smp_chip = {
21467 +       .name           = "UbicoIPI",
21468 +       .startup        = NULL,
21469 +       .shutdown       = NULL,
21470 +       .enable         = smp_enable_vector,
21471 +       .disable        = smp_disable_vector,
21472 +       .ack            = NULL,
21473 +       .mask           = smp_mask_vector,
21474 +       .unmask         = smp_unmask_vector,
21475 +       .end            = smp_end_vector,
21476 +};
21477 +
21478 +/*
21479 + * smp_reset_ipi()
21480 + *     None of these cpu(s) got their IPI, turn it back on.
21481 + *
21482 + * Note: This is called by the LDSR which is not a full
21483 + * Linux cpu.  Thus you must use the raw form of locks
21484 + * because lock debugging will not work on the partial
21485 + * cpu nature of the LDSR.
21486 + */
21487 +void smp_reset_ipi(unsigned long mask)
21488 +{
21489 +       __raw_spin_lock(&smp_ipi_lock.raw_lock);
21490 +       smp_needs_ipi |= mask;
21491 +       smp_inside_ipi &= ~mask;
21492 +       ubicom32_set_interrupt(smp_ipi_irq);
21493 +       __raw_spin_unlock(&smp_ipi_lock.raw_lock);
21494 +}
21495 +
21496 +/*
21497 + * smp_get_affinity()
21498 + *     Choose the thread affinity for this interrupt.
21499 + *
21500 + * Note: This is called by the LDSR which is not a full
21501 + * Linux cpu.  Thus you must use the raw form of locks
21502 + * because lock debugging will not work on the partial
21503 + * cpu nature of the LDSR.
21504 + */
21505 +unsigned long smp_get_affinity(unsigned int irq, int *all)
21506 +{
21507 +       unsigned long mask = 0;
21508 +
21509 +       /*
21510 +        * Most IRQ(s) are delivered in a round robin fashion.
21511 +        */
21512 +       if (irq != smp_ipi_irq) {
21513 +               unsigned long result = smp_irq_affinity[irq] & smp_online_threads;
21514 +               DEBUG_ASSERT(result);
21515 +               *all = 0;
21516 +               return result;
21517 +       }
21518 +
21519 +       /*
21520 +        * This is an IPI request.  Return all cpu(s) scheduled for an IPI.
21521 +        * We also track those cpu(s) that are going to be "receiving" IPI this
21522 +        * round.  When all CPU(s) have called smp_end_vector(),
21523 +        * we will unmask the IPI interrupt.
21524 +        */
21525 +       __raw_spin_lock(&smp_ipi_lock.raw_lock);
21526 +       ubicom32_clear_interrupt(smp_ipi_irq);
21527 +       if (smp_needs_ipi) {
21528 +               mask = smp_needs_ipi;
21529 +               smp_inside_ipi |= smp_needs_ipi;
21530 +               smp_needs_ipi = 0;
21531 +       }
21532 +       __raw_spin_unlock(&smp_ipi_lock.raw_lock);
21533 +       *all = 1;
21534 +       return mask;
21535 +}
21536 +
21537 +/*
21538 + *  smp_set_affinity()
21539 + *     Set the affinity for this irq but store the value in tid(s).
21540 + */
21541 +void smp_set_affinity(unsigned int irq, cpumask_t dest)
21542 +{
21543 +       int cpuid;
21544 +       unsigned long *paffinity = &smp_irq_affinity[irq];
21545 +
21546 +       /*
21547 +        *  If none specified, all cpus are allowed.
21548 +        */
21549 +       if (cpus_empty(dest)) {
21550 +               *paffinity = 0xffffffff;
21551 +               return;
21552 +       }
21553 +
21554 +       /*
21555 +        * Make sure to clear the old value before setting up the
21556 +        * list.
21557 +        */
21558 +       *paffinity = 0;
21559 +       for_each_cpu_mask(cpuid, dest) {
21560 +               struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21561 +               *paffinity |= (1 << p->tid);
21562 +       }
21563 +}
21564 +
21565 +/*
21566 + * smp_send_stop()
21567 + *     Send a stop request to all CPU but this one.
21568 + */
21569 +void smp_send_stop(void)
21570 +{
21571 +       ipi_send_allbutself(IPI_CPU_STOP);
21572 +}
21573 +
21574 +/*
21575 + * smp_send_timer_all()
21576 + *     Send all cpu(s) but this one, a request to update times.
21577 + */
21578 +void smp_send_timer_all(void)
21579 +{
21580 +       ipi_send_allbutself(IPI_CPU_TIMER);
21581 +}
21582 +
21583 +/*
21584 + * smp_timer_broadcast()
21585 + *     Use an IPI to broadcast a timer message
21586 + */
21587 +void smp_timer_broadcast(cpumask_t mask)
21588 +{
21589 +       ipi_send_mask(IPI_CPU_TIMER, mask);
21590 +}
21591 +
21592 +/*
21593 + * smp_send_reschedule()
21594 + *     Send a reschedule request to the specified cpu.
21595 + */
21596 +void smp_send_reschedule(int cpu)
21597 +{
21598 +       ipi_send(cpu, IPI_RESCHEDULE);
21599 +}
21600 +
21601 +/*
21602 + * arch_send_call_function_ipi()
21603 + *     Cause each cpu in the mask to call the generic function handler.
21604 + */
21605 +void arch_send_call_function_ipi(cpumask_t mask)
21606 +{
21607 +       int cpu;
21608 +       for_each_cpu_mask(cpu, mask) {
21609 +               ipi_send(cpu, IPI_CALL_FUNC);
21610 +       }
21611 +}
21612 +
21613 +/*
21614 + * arch_send_call_function_single_ipi()
21615 + *     Cause the specified cpu to call the generic function handler.
21616 + */
21617 +void arch_send_call_function_single_ipi(int cpu)
21618 +{
21619 +       ipi_send(cpu, IPI_CALL_FUNC_SINGLE);
21620 +}
21621 +
21622 +/*
21623 + * smp_mainline_start()
21624 + *     Start a slave thread executing a mainline Linux context.
21625 + */
21626 +static void __init smp_mainline_start(void *arg)
21627 +{
21628 +       int cpuid = smp_processor_id();
21629 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21630 +
21631 +       BUG_ON(p->tid != thread_get_self());
21632 +
21633 +       /*
21634 +        * Well, support 2.4 linux scheme as well.
21635 +        */
21636 +       if (cpu_test_and_set(cpuid, cpu_online_map)) {
21637 +               printk(KERN_CRIT "cpu[%d]: already initialized!\n", cpuid);
21638 +               smp_halt_processor();
21639 +               return;
21640 +       }
21641 +
21642 +       /*
21643 +        * Initialise the idle task for this CPU
21644 +        */
21645 +       atomic_inc(&init_mm.mm_count);
21646 +       current->active_mm = &init_mm;
21647 +       if (current->mm) {
21648 +               printk(KERN_CRIT "cpu[%d]: idle task already has memory "
21649 +                      "management\n", cpuid);
21650 +               smp_halt_processor();
21651 +               return;
21652 +       }
21653 +
21654 +       /*
21655 +        * TODO: X86 does this prior to calling notify, try to understand why?
21656 +        */
21657 +       preempt_disable();
21658 +
21659 +#if defined(CONFIG_GENERIC_CLOCKEVENTS)
21660 +       /*
21661 +        * Setup a local timer event so that this cpu will get timer interrupts
21662 +        */
21663 +       if (local_timer_setup(cpuid) == -1) {
21664 +               printk(KERN_CRIT "cpu[%d]: timer alloc failed\n", cpuid);
21665 +               smp_halt_processor();
21666 +               return;
21667 +       }
21668 +#endif
21669 +
21670 +       /*
21671 +        * Notify those interested that we are up and alive.  This must
21672 +        * be done before interrupts are enabled.  It must also be completed
21673 +        * before the bootstrap cpu returns from __cpu_up() (see comment
21674 +        * above cpu_set() of the cpu_online_map).
21675 +        */
21676 +       notify_cpu_starting(cpuid);
21677 +
21678 +       /*
21679 +        * Indicate that this thread is now online and present.   Setting
21680 +        * cpu_online_map has the side effect of allowing the bootstrap
21681 +        * cpu to continue along; so anything that MUST be done prior to the
21682 +        * bootstrap cpu returning from __cpu_up() needs to go above here.
21683 +        */
21684 +       cpu_set(cpuid, cpu_online_map);
21685 +       cpu_set(cpuid, cpu_present_map);
21686 +
21687 +       /*
21688 +        * Maintain a thread mapping in addition to the cpu mapping.
21689 +        */
21690 +       smp_online_threads |= (1 << p->tid);
21691 +
21692 +       /*
21693 +        * Enable interrupts for this thread.
21694 +        */
21695 +       local_irq_enable();
21696 +
21697 +       /*
21698 +        * Enter the idle loop and wait for a timer to schedule some work.
21699 +        */
21700 +       printk(KERN_INFO "cpu[%d]: entering cpu_idle()\n", cpuid);
21701 +       cpu_idle();
21702 +
21703 +       /* Not Reached */
21704 +}
21705 +
21706 +/*
21707 + * smp_cpus_done()
21708 + *     Called once the kernel_init() has brought up all cpu(s).
21709 + */
21710 +void smp_cpus_done(unsigned int cpu_max)
21711 +{
21712 +       /* Do Nothing */
21713 +}
21714 +
21715 +/*
21716 + * __cpu_up()
21717 + *     Called to startup a sepcific cpu.
21718 + */
21719 +int __cpuinit __cpu_up(unsigned int cpu)
21720 +{
21721 +       struct task_struct *idle;
21722 +       unsigned int *stack;
21723 +       long timeout;
21724 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21725 +
21726 +       /*
21727 +        * Create an idle task for this CPU.
21728 +        */
21729 +       idle = fork_idle(cpu);
21730 +       if (IS_ERR(idle)) {
21731 +               panic("cpu[%d]: fork failed\n", cpu);
21732 +               return -ENOSYS;
21733 +       }
21734 +       task_thread_info(idle)->cpu = cpu;
21735 +
21736 +       /*
21737 +        * Setup the sw_ksp[] to point to this new task.
21738 +        */
21739 +       sw_ksp[p->tid] = (unsigned int)idle->stack;
21740 +       stack = (unsigned int *)(sw_ksp[p->tid] + PAGE_SIZE - 8);
21741 +
21742 +       /*
21743 +        * Cause the specified thread to execute our smp_mainline_start
21744 +        * function as a TYPE_NORMAL thread.
21745 +        */
21746 +       printk(KERN_INFO "cpu[%d]: launching mainline Linux thread\n", cpu);
21747 +       if (thread_start(p->tid, smp_mainline_start, (void *)NULL, stack,
21748 +                        THREAD_TYPE_NORMAL) == -1) {
21749 +               printk(KERN_WARNING "cpu[%d]: failed thread_start\n", cpu);
21750 +               return -ENOSYS;
21751 +       }
21752 +
21753 +       /*
21754 +        * Wait for the thread to start up.  The thread will set
21755 +        * the online bit when it is running.  Our caller execpts the
21756 +        * cpu to be online if we return 0.
21757 +        */
21758 +       for (timeout = 0; timeout < 10000; timeout++) {
21759 +               if (cpu_online(cpu)) {
21760 +                       break;
21761 +               }
21762 +
21763 +               udelay(100);
21764 +               barrier();
21765 +               continue;
21766 +       }
21767 +
21768 +       if (!cpu_online(cpu)) {
21769 +               printk(KERN_CRIT "cpu[%d]: failed to live after %ld us\n",
21770 +                      cpu, timeout * 100);
21771 +               return -ENOSYS;
21772 +       }
21773 +
21774 +       printk(KERN_INFO "cpu[%d]: came alive after %ld us\n",
21775 +              cpu, timeout * 100);
21776 +       return 0;
21777 +}
21778 +
21779 +/*
21780 + * Data used by setup_irq for the IPI.
21781 + */
21782 +static struct irqaction ipi_irq = {
21783 +       .name    = "ipi",
21784 +       .flags   = IRQF_DISABLED | IRQF_PERCPU,
21785 +       .handler = ipi_interrupt,
21786 +};
21787 +
21788 +/*
21789 + * smp_prepare_cpus()
21790 + *     Mark threads that are available to Linux as possible cpus(s).
21791 + */
21792 +void __init smp_prepare_cpus(unsigned int max_cpus)
21793 +{
21794 +       int i;
21795 +
21796 +       /*
21797 +        * We will need a software IRQ to send IPI(s).  We will use
21798 +        * a single software IRQ for all IPI(s).
21799 +        */
21800 +       if (irq_soft_alloc(&smp_ipi_irq) < 0) {
21801 +               panic("no software IRQ is available\n");
21802 +               return;
21803 +       }
21804 +
21805 +       /*
21806 +        * For the IPI interrupt, we want to use our own chip definition.
21807 +        * This allows us to define what happens in SMP IPI without affecting
21808 +        * the performance of the other interrupts.
21809 +        *
21810 +        * Next, Register the IPI interrupt function against the soft IRQ.
21811 +        */
21812 +       set_irq_chip(smp_ipi_irq, &ubicom32_smp_chip);
21813 +       setup_irq(smp_ipi_irq, &ipi_irq);
21814 +
21815 +       /*
21816 +        * We use the device tree node to determine how many
21817 +        * free cpus we will have (up to NR_CPUS) and we indicate
21818 +        * that those cpus are present.
21819 +        *
21820 +        * We need to do this very early in the SMP case
21821 +        * because the Linux init code uses the cpu_present_map.
21822 +        */
21823 +       for_each_possible_cpu(i) {
21824 +               thread_t tid;
21825 +               struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, i);
21826 +
21827 +               /*
21828 +                *  Skip the bootstrap cpu
21829 +                */
21830 +               if (i == 0) {
21831 +                       continue;
21832 +               }
21833 +
21834 +               /*
21835 +                * If we have a free thread left in the mask,
21836 +                * indicate that the cpu is present.
21837 +                */
21838 +               tid = thread_alloc();
21839 +               if (tid == (thread_t)-1) {
21840 +                       break;
21841 +               }
21842 +
21843 +               /*
21844 +                * Save the hardware thread id for this cpu.
21845 +                */
21846 +               p->tid = tid;
21847 +               cpu_set(i, cpu_present_map);
21848 +               printk(KERN_INFO "cpu[%d]: added to cpu_present_map - tid: %d\n", i, tid);
21849 +       }
21850 +}
21851 +
21852 +/*
21853 + * smp_prepare_boot_cpu()
21854 + *     Copy the per_cpu data into the appropriate spot for the bootstrap cpu.
21855 + *
21856 + * The code in boot_cpu_init() has already set the boot cpu's
21857 + * state in the possible, present, and online maps.
21858 + */
21859 +void __devinit smp_prepare_boot_cpu(void)
21860 +{
21861 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
21862 +
21863 +       smp_online_threads |= (1 << p->tid);
21864 +       printk(KERN_INFO "cpu[%d]: bootstrap CPU online - tid: %ld\n",
21865 +                       current_thread_info()->cpu, p->tid);
21866 +}
21867 +
21868 +/*
21869 + * smp_setup_processor_id()
21870 + *     Set the current_thread_info() structure cpu value.
21871 + *
21872 + * We set the value to the true hardware thread value that we are running on.
21873 + * NOTE: this function overrides the weak alias function in main.c
21874 + */
21875 +void __init smp_setup_processor_id(void)
21876 +{
21877 +       struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
21878 +       current_thread_info()->cpu = 0;
21879 +       p->tid = thread_get_self();
21880 +}
21881 +
21882 +/*
21883 + * setup_profiling_timer()
21884 + *     Dummy function created to keep Oprofile happy in the SMP case.
21885 + */
21886 +int setup_profiling_timer(unsigned int multiplier)
21887 +{
21888 +       return 0;
21889 +}
21890 --- /dev/null
21891 +++ b/arch/ubicom32/kernel/stacktrace.c
21892 @@ -0,0 +1,243 @@
21893 +/*
21894 + * arch/ubicom32/kernel/stacktrace.c
21895 + *   Ubicom32 architecture stack back trace implementation.
21896 + *
21897 + * (C) Copyright 2009, Ubicom, Inc.
21898 + *
21899 + * This file is part of the Ubicom32 Linux Kernel Port.
21900 + *
21901 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
21902 + * it and/or modify it under the terms of the GNU General Public License
21903 + * as published by the Free Software Foundation, either version 2 of the
21904 + * License, or (at your option) any later version.
21905 + *
21906 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21907 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
21908 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
21909 + * the GNU General Public License for more details.
21910 + *
21911 + * You should have received a copy of the GNU General Public License
21912 + * along with the Ubicom32 Linux Kernel Port.  If not,
21913 + * see <http://www.gnu.org/licenses/>.
21914 + *
21915 + * Ubicom32 implementation derived from (with many thanks):
21916 + *   arch/m68knommu
21917 + *   arch/blackfin
21918 + *   arch/parisc
21919 + */
21920 +#include <linux/sched.h>
21921 +#include <linux/stacktrace.h>
21922 +#include <linux/module.h>
21923 +#include <asm/stacktrace.h>
21924 +#include <asm/thread.h>
21925 +
21926 +/*
21927 + * These symbols are filled in by the linker.
21928 + */
21929 +extern unsigned long _stext;
21930 +extern unsigned long _etext;
21931 +
21932 +extern unsigned long __ocm_text_run_begin;
21933 +extern unsigned long __data_begin;
21934 +
21935 +/*
21936 + * stacktrace_iterate()
21937 + *     Walk the stack looking for call and calli instructions on an aligned
21938 + *     boundary.
21939 + *
21940 + * Trace must point to the top of the current stack frame.
21941 + */
21942 +unsigned long stacktrace_iterate(unsigned long **trace,
21943 +                                unsigned long stext,
21944 +                                unsigned long etext,
21945 +                                unsigned long ocm_stext,
21946 +                                unsigned long ocm_etext,
21947 +                                unsigned long sstack,
21948 +                                unsigned long estack)
21949 +{
21950 +       unsigned int thread_trap_en, instruction;
21951 +       unsigned long address;
21952 +       unsigned int limit = 0;
21953 +       unsigned long result = 0;
21954 +       unsigned long *sp = *trace;
21955 +
21956 +       /*
21957 +        * Exclude the current thread from being monitored for traps.
21958 +        */
21959 +       asm volatile(
21960 +               "       thread_get_self_mask d15                \n\t"
21961 +                       /* save current trap status */
21962 +               "       and.4   %0, MT_TRAP_EN, d15             \n\t"
21963 +               "       not.4   d15, d15                        \n\t"
21964 +                       /* disable trap */
21965 +               "       and.4   MT_TRAP_EN, MT_TRAP_EN, d15     \n\t"
21966 +               "       pipe_flush 0                            \n\t"
21967 +               : "=r" (thread_trap_en)
21968 +               :
21969 +               : "d15", "cc"
21970 +       );
21971 +
21972 +       while (limit++ < 256) {
21973 +               /*
21974 +                * See if we have a valid stack.
21975 +                */
21976 +               if (!between((unsigned long)sp, sstack, estack)) {
21977 +#ifdef TRAP_DEBUG_STACK_TRACE
21978 +                       printk(KERN_EMERG "stack address is out of range - "
21979 +                              "sp: %x, sstack: %x, estack: %x\n",
21980 +                              (unsigned int)sp, (unsigned int)sstack,
21981 +                              (unsigned int)estack);
21982 +#endif
21983 +                       result = 0;
21984 +                       *trace = 0;
21985 +                       break;
21986 +               }
21987 +
21988 +               /*
21989 +                * Get the value off the stack and back up 4 bytes to what
21990 +                * should be the address of a call or calli.
21991 +                */
21992 +               address = (*sp++) - 4;
21993 +
21994 +               /*
21995 +                * If the address is not within the text segment, skip this
21996 +                * value.
21997 +                */
21998 +               if (!between(address, stext, etext) &&
21999 +                   !between(address, ocm_stext, ocm_etext)) {
22000 +#ifdef TRAP_DEBUG_STACK_TRACE
22001 +                       printk(KERN_EMERG "not a text address - "
22002 +                              "address: %08x, stext: %08x, etext: %08x\n"
22003 +                              "ocm_stext: %08x, ocm_etext: %08x\n",
22004 +                              (unsigned int)address,
22005 +                              (unsigned int)stext,
22006 +                              (unsigned int)etext,
22007 +                              (unsigned int)ocm_stext,
22008 +                              (unsigned int)ocm_etext);
22009 +#endif
22010 +                       continue;
22011 +
22012 +               }
22013 +
22014 +               /*
22015 +                * If the address is not on an aligned boundary it can not be a
22016 +                * return address.
22017 +                */
22018 +               if (address & 0x3) {
22019 +                       continue;
22020 +               }
22021 +
22022 +               /*
22023 +                * Read the probable instruction.
22024 +                */
22025 +               instruction = *(unsigned int *)address;
22026 +
22027 +               /*
22028 +                * Is this a call instruction?
22029 +                */
22030 +               if ((instruction & 0xF8000000) == (u32_t)(0x1B << 27)) {
22031 +#ifdef TRAP_DEBUG_STACK_TRACE
22032 +                       printk(KERN_EMERG "call inst. result: %x, "
22033 +                              "test: %x\n", (unsigned int)address,
22034 +                              (unsigned int)instruction);
22035 +#endif
22036 +                       *trace = sp;
22037 +                       result = address;
22038 +                       break;
22039 +               }
22040 +
22041 +               /*
22042 +                * Is this a calli instruction?
22043 +                */
22044 +               if ((instruction & 0xF8000000) == (u32_t)(0x1E << 27)) {
22045 +#ifdef TRAP_DEBUG_STACK_TRACE
22046 +                       printk(KERN_EMERG "calli inst. result: %x, "
22047 +                              "test: %x\n", (unsigned int)address,
22048 +                              (unsigned int)instruction);
22049 +#endif
22050 +                       *trace = sp;
22051 +                       result = address;
22052 +                       break;
22053 +               }
22054 +       }
22055 +
22056 +       /*
22057 +        * Restore the current thread to be monitored for traps.
22058 +        */
22059 +       if (thread_trap_en) {
22060 +               asm volatile(
22061 +               "       thread_get_self_mask d15                \n\t"
22062 +               "       or.4    MT_TRAP_EN, MT_TRAP_EN, d15     \n\t"
22063 +                       :
22064 +                       :
22065 +                       : "d15", "cc"
22066 +               );
22067 +       }
22068 +       return result;
22069 +}
22070 +
22071 +#ifdef CONFIG_STACKTRACE
22072 +/*
22073 + * stacktrace_save_entries()
22074 + *     Save stack back trace information into the provided trace structure.
22075 + */
22076 +void stacktrace_save_entries(struct task_struct *tsk,
22077 +                            struct stack_trace *trace,
22078 +                            unsigned long sp)
22079 +{
22080 +       unsigned long code_start = (unsigned long)&_stext;
22081 +       unsigned long code_end = (unsigned long)&_etext;
22082 +       unsigned long ocm_code_start = (unsigned long)&__ocm_text_run_begin;
22083 +       unsigned long ocm_code_end = (unsigned long)&__data_begin;
22084 +       unsigned long stack_end = (unsigned long)(tsk->stack + THREAD_SIZE - 8);
22085 +       unsigned long stack = (unsigned long)sp;
22086 +       unsigned int idx = 0;
22087 +       unsigned long *handle;
22088 +       int skip = trace->skip;
22089 +
22090 +       handle = (unsigned long *)stack;
22091 +       while (idx < trace->max_entries) {
22092 +               if (skip) {
22093 +                       skip--;
22094 +                       continue;
22095 +               }
22096 +               trace->entries[idx] = stacktrace_iterate(&handle,
22097 +                                       code_start, code_end,
22098 +                                       ocm_code_start, ocm_code_end,
22099 +                                       (unsigned long)stack, stack_end);
22100 +               if (trace->entries[idx] == 0) {
22101 +                       break;
22102 +               }
22103 +               idx++;
22104 +       }
22105 +}
22106 +
22107 +/*
22108 + * save_stack_trace()
22109 + *     Save the specified amount of the kernel stack trace information
22110 + *     for the current task.
22111 + */
22112 +void save_stack_trace(struct stack_trace *trace)
22113 +{
22114 +       unsigned long sp = 0;
22115 +       asm volatile (
22116 +       "       move.4  %0, SP          \n\t"
22117 +               : "=r" (sp)
22118 +       );
22119 +       stacktrace_save_entries(current, trace, sp);
22120 +}
22121 +EXPORT_SYMBOL_GPL(save_stack_trace);
22122 +
22123 +/*
22124 + * save_stack_trace_tsk()
22125 + *     Save the specified amount of the kernel stack trace information
22126 + *     for the specified task.
22127 + *
22128 + * Note: We assume the specified task is not currently running.
22129 + */
22130 +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
22131 +{
22132 +       stacktrace_save_entries(tsk, trace, tsk->thread.sp);
22133 +}
22134 +EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
22135 +#endif /* CONFIG_STACKTRACE */
22136 --- /dev/null
22137 +++ b/arch/ubicom32/kernel/syscalltable.S
22138 @@ -0,0 +1,377 @@
22139 +/*
22140 + * arch/ubicom32/kernel/syscalltable.S
22141 + *     <TODO: Replace with short file description>
22142 + *
22143 + * (C) Copyright 2009, Ubicom, Inc.
22144 + *
22145 + * This file is part of the Ubicom32 Linux Kernel Port.
22146 + *
22147 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22148 + * it and/or modify it under the terms of the GNU General Public License
22149 + * as published by the Free Software Foundation, either version 2 of the
22150 + * License, or (at your option) any later version.
22151 + *
22152 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22153 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22154 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22155 + * the GNU General Public License for more details.
22156 + *
22157 + * You should have received a copy of the GNU General Public License
22158 + * along with the Ubicom32 Linux Kernel Port.  If not, 
22159 + * see <http://www.gnu.org/licenses/>.
22160 + *
22161 + * Ubicom32 implementation derived from (with many thanks):
22162 + *   arch/m68knommu
22163 + *   arch/blackfin
22164 + *   arch/parisc
22165 + */
22166 +/*
22167 + *
22168 + *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
22169 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>, Kenneth Albanowski <kjahds@kjahds.com>,
22170 + *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
22171 + *  Copyright (C) 1991, 1992  Linus Torvalds
22172 + */
22173 +
22174 +#include <linux/sys.h>
22175 +#include <linux/linkage.h>
22176 +#include <asm/unistd.h>
22177 +
22178 +.text
22179 +ALIGN
22180 +       .global sys_call_table
22181 +sys_call_table:        
22182 +       .long sys_ni_syscall    /* 0  -  old "setup()" system call*/
22183 +       .long sys_exit
22184 +       .long sys_fork
22185 +       .long sys_read
22186 +       .long sys_write
22187 +       .long sys_open          /* 5 */
22188 +       .long sys_close
22189 +       .long sys_waitpid
22190 +       .long sys_creat
22191 +       .long sys_link
22192 +       .long sys_unlink        /* 10 */
22193 +       .long execve_intercept
22194 +       .long sys_chdir
22195 +       .long sys_time
22196 +       .long sys_mknod
22197 +       .long sys_chmod         /* 15 */
22198 +       .long sys_chown16
22199 +       .long sys_ni_syscall    /* old break syscall holder */
22200 +       .long sys_stat
22201 +       .long sys_lseek
22202 +       .long sys_getpid        /* 20 */
22203 +       .long sys_mount
22204 +       .long sys_oldumount
22205 +       .long sys_setuid16
22206 +       .long sys_getuid16
22207 +       .long sys_stime         /* 25 */
22208 +       .long sys_ptrace
22209 +       .long sys_alarm
22210 +       .long sys_fstat
22211 +       .long sys_pause
22212 +       .long sys_utime         /* 30 */
22213 +       .long sys_ni_syscall    /* old stty syscall holder */
22214 +       .long sys_ni_syscall    /* old gtty syscall holder */
22215 +       .long sys_access
22216 +       .long sys_nice
22217 +       .long sys_ni_syscall    /* 35 */ /* old ftime syscall holder */
22218 +       .long sys_sync
22219 +       .long sys_kill
22220 +       .long sys_rename
22221 +       .long sys_mkdir
22222 +       .long sys_rmdir         /* 40 */
22223 +       .long sys_dup
22224 +       .long sys_pipe
22225 +       .long sys_times
22226 +       .long sys_ni_syscall    /* old prof syscall holder */
22227 +       .long sys_brk           /* 45 */
22228 +       .long sys_setgid16
22229 +       .long sys_getgid16
22230 +       .long sys_signal
22231 +       .long sys_geteuid16
22232 +       .long sys_getegid16     /* 50 */
22233 +       .long sys_acct
22234 +       .long sys_umount        /* recycled never used phys() */
22235 +       .long sys_ni_syscall    /* old lock syscall holder */
22236 +       .long sys_ioctl
22237 +       .long sys_fcntl         /* 55 */
22238 +       .long sys_ni_syscall    /* old mpx syscall holder */
22239 +       .long sys_setpgid
22240 +       .long sys_ni_syscall    /* old ulimit syscall holder */
22241 +       .long sys_ni_syscall
22242 +       .long sys_umask         /* 60 */
22243 +       .long sys_chroot
22244 +       .long sys_ustat
22245 +       .long sys_dup2
22246 +       .long sys_getppid
22247 +       .long sys_getpgrp       /* 65 */
22248 +       .long sys_setsid
22249 +       .long sys_sigaction
22250 +       .long sys_sgetmask
22251 +       .long sys_ssetmask
22252 +       .long sys_setreuid16    /* 70 */
22253 +       .long sys_setregid16
22254 +       .long sys_sigsuspend
22255 +       .long sys_sigpending
22256 +       .long sys_sethostname
22257 +       .long sys_setrlimit     /* 75 */
22258 +       .long sys_old_getrlimit
22259 +       .long sys_getrusage
22260 +       .long sys_gettimeofday
22261 +       .long sys_settimeofday
22262 +       .long sys_getgroups16   /* 80 */
22263 +       .long sys_setgroups16
22264 +       .long old_select
22265 +       .long sys_symlink
22266 +       .long sys_lstat
22267 +       .long sys_readlink      /* 85 */
22268 +       .long sys_uselib
22269 +       .long sys_ni_syscall    /* _sys_swapon */
22270 +       .long sys_reboot
22271 +       .long sys_old_readdir
22272 +       .long old_mmap          /* 90 */
22273 +       .long sys_munmap
22274 +       .long sys_truncate
22275 +       .long sys_ftruncate
22276 +       .long sys_fchmod
22277 +       .long sys_fchown16      /* 95 */
22278 +       .long sys_getpriority
22279 +       .long sys_setpriority
22280 +       .long sys_ni_syscall    /* old profil syscall holder */
22281 +       .long sys_statfs
22282 +       .long sys_fstatfs       /* 100 */
22283 +       .long sys_ni_syscall    /* ioperm for i386 */
22284 +       .long sys_socketcall
22285 +       .long sys_syslog
22286 +       .long sys_setitimer
22287 +       .long sys_getitimer     /* 105 */
22288 +       .long sys_newstat
22289 +       .long sys_newlstat
22290 +       .long sys_newfstat
22291 +       .long sys_ni_syscall
22292 +       .long sys_ni_syscall    /* iopl for i386 */ /* 110 */
22293 +       .long sys_vhangup
22294 +       .long sys_ni_syscall    /* obsolete idle() syscall */
22295 +       .long sys_ni_syscall    /* vm86old for i386 */
22296 +       .long sys_wait4
22297 +       .long sys_ni_syscall    /* 115 */ /* _sys_swapoff */
22298 +       .long sys_sysinfo
22299 +       .long sys_ipc
22300 +       .long sys_fsync
22301 +       .long sys_sigreturn
22302 +       .long clone_intercept   /* 120 */
22303 +       .long sys_setdomainname
22304 +       .long sys_newuname
22305 +       .long sys_cacheflush    /* modify_ldt for i386 */
22306 +       .long sys_adjtimex
22307 +       .long sys_ni_syscall    /* 125 */ /* _sys_mprotect */
22308 +       .long sys_sigprocmask
22309 +       .long sys_ni_syscall    /* old "creat_module" */
22310 +       .long sys_init_module
22311 +       .long sys_delete_module
22312 +       .long sys_ni_syscall    /* 130: old "get_kernel_syms" */
22313 +       .long sys_quotactl
22314 +       .long sys_getpgid
22315 +       .long sys_fchdir
22316 +       .long sys_bdflush
22317 +       .long sys_sysfs         /* 135 */
22318 +       .long sys_personality
22319 +       .long sys_ni_syscall    /* for afs_syscall */
22320 +       .long sys_setfsuid16
22321 +       .long sys_setfsgid16
22322 +       .long sys_llseek        /* 140 */
22323 +       .long sys_getdents
22324 +       .long sys_select
22325 +       .long sys_flock
22326 +       .long sys_ni_syscall    /* _sys_msync */
22327 +       .long sys_readv         /* 145 */
22328 +       .long sys_writev
22329 +       .long sys_getsid
22330 +       .long sys_fdatasync
22331 +       .long sys_sysctl
22332 +       .long sys_ni_syscall    /* 150 */ /* _sys_mlock */
22333 +       .long sys_ni_syscall    /* _sys_munlock */
22334 +       .long sys_ni_syscall    /* _sys_mlockall */
22335 +       .long sys_ni_syscall    /* _sys_munlockall */
22336 +       .long sys_sched_setparam
22337 +       .long sys_sched_getparam /* 155 */
22338 +       .long sys_sched_setscheduler
22339 +       .long sys_sched_getscheduler
22340 +       .long sys_sched_yield
22341 +       .long sys_sched_get_priority_max
22342 +       .long sys_sched_get_priority_min  /* 160 */
22343 +       .long sys_sched_rr_get_interval
22344 +       .long sys_nanosleep
22345 +       .long sys_ni_syscall    /* _sys_mremap */
22346 +       .long sys_setresuid16
22347 +       .long sys_getresuid16   /* 165 */
22348 +       .long sys_getpagesize   /* _sys_getpagesize */
22349 +       .long sys_ni_syscall    /* old "query_module" */
22350 +       .long sys_poll
22351 +       .long sys_ni_syscall    /* _sys_nfsservctl */
22352 +       .long sys_setresgid16   /* 170 */
22353 +       .long sys_getresgid16
22354 +       .long sys_prctl
22355 +       .long sys_rt_sigreturn
22356 +       .long sys_rt_sigaction
22357 +       .long sys_rt_sigprocmask /* 175 */
22358 +       .long sys_rt_sigpending
22359 +       .long sys_rt_sigtimedwait
22360 +       .long sys_rt_sigqueueinfo
22361 +       .long sys_rt_sigsuspend
22362 +       .long sys_pread64       /* 180 */
22363 +       .long sys_pwrite64
22364 +       .long sys_lchown16
22365 +       .long sys_getcwd
22366 +       .long sys_capget
22367 +       .long sys_capset        /* 185 */
22368 +       .long sys_sigaltstack
22369 +       .long sys_sendfile
22370 +       .long sys_ni_syscall    /* streams1 */
22371 +       .long sys_ni_syscall    /* streams2 */
22372 +       .long vfork_intercept           /* 190 */
22373 +       .long sys_getrlimit
22374 +       .long sys_mmap2
22375 +       .long sys_truncate64
22376 +       .long sys_ftruncate64
22377 +       .long sys_stat64        /* 195 */
22378 +       .long sys_lstat64
22379 +       .long sys_fstat64
22380 +       .long sys_chown
22381 +       .long sys_getuid
22382 +       .long sys_getgid        /* 200 */
22383 +       .long sys_geteuid
22384 +       .long sys_getegid
22385 +       .long sys_setreuid
22386 +       .long sys_setregid
22387 +       .long sys_getgroups     /* 205 */
22388 +       .long sys_setgroups
22389 +       .long sys_fchown
22390 +       .long sys_setresuid
22391 +       .long sys_getresuid
22392 +       .long sys_setresgid     /* 210 */
22393 +       .long sys_getresgid
22394 +       .long sys_lchown
22395 +       .long sys_setuid
22396 +       .long sys_setgid
22397 +       .long sys_setfsuid      /* 215 */
22398 +       .long sys_setfsgid
22399 +       .long sys_pivot_root
22400 +       .long sys_ni_syscall
22401 +       .long sys_ni_syscall
22402 +       .long sys_getdents64    /* 220 */
22403 +       .long sys_gettid
22404 +       .long sys_tkill
22405 +       .long sys_setxattr
22406 +       .long sys_lsetxattr
22407 +       .long sys_fsetxattr     /* 225 */
22408 +       .long sys_getxattr
22409 +       .long sys_lgetxattr
22410 +       .long sys_fgetxattr
22411 +       .long sys_listxattr
22412 +       .long sys_llistxattr    /* 230 */
22413 +       .long sys_flistxattr
22414 +       .long sys_removexattr
22415 +       .long sys_lremovexattr
22416 +       .long sys_fremovexattr
22417 +       .long sys_futex         /* 235 */
22418 +       .long sys_sendfile64
22419 +       .long sys_ni_syscall    /* _sys_mincore */
22420 +       .long sys_ni_syscall    /* _sys_madvise */
22421 +       .long sys_fcntl64
22422 +       .long sys_readahead     /* 240 */
22423 +       .long sys_io_setup
22424 +       .long sys_io_destroy
22425 +       .long sys_io_getevents
22426 +       .long sys_io_submit
22427 +       .long sys_io_cancel     /* 245 */
22428 +       .long sys_fadvise64
22429 +       .long sys_exit_group
22430 +       .long sys_lookup_dcookie
22431 +       .long sys_epoll_create
22432 +       .long sys_epoll_ctl     /* 250 */
22433 +       .long sys_epoll_wait
22434 +       .long sys_ni_syscall    /* _sys_remap_file_pages */
22435 +       .long sys_set_tid_address
22436 +       .long sys_timer_create
22437 +       .long sys_timer_settime /* 255 */
22438 +       .long sys_timer_gettime
22439 +       .long sys_timer_getoverrun
22440 +       .long sys_timer_delete
22441 +       .long sys_clock_settime
22442 +       .long sys_clock_gettime /* 260 */
22443 +       .long sys_clock_getres
22444 +       .long sys_clock_nanosleep
22445 +       .long sys_statfs64
22446 +       .long sys_fstatfs64
22447 +       .long sys_tgkill        /* 265 */
22448 +       .long sys_utimes
22449 +       .long sys_fadvise64_64
22450 +       .long sys_mbind 
22451 +       .long sys_get_mempolicy
22452 +       .long sys_set_mempolicy /* 270 */
22453 +       .long sys_mq_open
22454 +       .long sys_mq_unlink
22455 +       .long sys_mq_timedsend
22456 +       .long sys_mq_timedreceive
22457 +       .long sys_mq_notify     /* 275 */
22458 +       .long sys_mq_getsetattr
22459 +       .long sys_waitid
22460 +       .long sys_ni_syscall    /* for _sys_vserver */
22461 +       .long sys_add_key
22462 +       .long sys_request_key   /* 280 */
22463 +       .long sys_keyctl
22464 +       .long sys_ioprio_set
22465 +       .long sys_ioprio_get
22466 +       .long sys_inotify_init
22467 +       .long sys_inotify_add_watch     /* 285 */
22468 +       .long sys_inotify_rm_watch
22469 +       .long sys_migrate_pages
22470 +       .long sys_openat
22471 +       .long sys_mkdirat
22472 +       .long sys_mknodat               /* 290 */
22473 +       .long sys_fchownat
22474 +       .long sys_futimesat
22475 +       .long sys_fstatat64
22476 +       .long sys_unlinkat
22477 +       .long sys_renameat              /* 295 */
22478 +       .long sys_linkat
22479 +       .long sys_symlinkat
22480 +       .long sys_readlinkat
22481 +       .long sys_fchmodat
22482 +       .long sys_faccessat             /* 300 */
22483 +       .long sys_ni_syscall            /* Reserved for pselect6 */
22484 +       .long sys_ni_syscall            /* Reserved for ppoll */
22485 +       .long sys_unshare
22486 +       .long sys_set_robust_list
22487 +       .long sys_get_robust_list       /* 305 */
22488 +       .long sys_splice
22489 +       .long sys_sync_file_range
22490 +       .long sys_tee
22491 +       .long sys_vmsplice
22492 +       .long sys_move_pages            /* 310 */
22493 +       .long sys_sched_setaffinity
22494 +       .long sys_sched_getaffinity
22495 +       .long sys_kexec_load
22496 +       .long sys_getcpu
22497 +       .long sys_epoll_pwait           /* 315 */
22498 +       .long sys_utimensat
22499 +       .long sys_signalfd
22500 +       .long sys_timerfd_create
22501 +       .long sys_eventfd
22502 +       .long sys_fallocate             /* 320 */
22503 +       .long sys_timerfd_settime
22504 +       .long sys_timerfd_gettime
22505 +       .long sys_ni_syscall            /* sys_signalfd4 */
22506 +       .long sys_ni_syscall            /* sys_eventfd2 */
22507 +       .long sys_ni_syscall            /* sys_epoll_create1 */
22508 +                                       /* 325 */
22509 +       .long sys_ni_syscall            /* sys_dup3 */
22510 +       .long sys_ni_syscall            /* sys_pipe2 */
22511 +       .long sys_ni_syscall            /* sys_inotify_init1 */
22512 +       .rept NR_syscalls-(.-sys_call_table)/4
22513 +               .long sys_ni_syscall
22514 +       .endr
22515 +
22516 --- /dev/null
22517 +++ b/arch/ubicom32/kernel/sys_ubicom32.c
22518 @@ -0,0 +1,237 @@
22519 +/*
22520 + * arch/ubicom32/kernel/sys_ubicom32.c
22521 + *   Ubicom32 architecture system call support implementation.
22522 + *
22523 + * (C) Copyright 2009, Ubicom, Inc.
22524 + *
22525 + * This file is part of the Ubicom32 Linux Kernel Port.
22526 + *
22527 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22528 + * it and/or modify it under the terms of the GNU General Public License
22529 + * as published by the Free Software Foundation, either version 2 of the
22530 + * License, or (at your option) any later version.
22531 + *
22532 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22533 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22534 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22535 + * the GNU General Public License for more details.
22536 + *
22537 + * You should have received a copy of the GNU General Public License
22538 + * along with the Ubicom32 Linux Kernel Port.  If not,
22539 + * see <http://www.gnu.org/licenses/>.
22540 + *
22541 + * Ubicom32 implementation derived from (with many thanks):
22542 + *   arch/m68knommu
22543 + *   arch/blackfin
22544 + *   arch/parisc
22545 + *
22546 + * This file contains various random system calls that
22547 + * have a non-standard calling sequence on the Linux/ubicom32
22548 + * platform.
22549 + */
22550 +
22551 +#include <linux/module.h>
22552 +#include <linux/errno.h>
22553 +#include <linux/sched.h>
22554 +#include <linux/mm.h>
22555 +#include <linux/smp.h>
22556 +#include <linux/sem.h>
22557 +#include <linux/msg.h>
22558 +#include <linux/shm.h>
22559 +#include <linux/stat.h>
22560 +#include <linux/syscalls.h>
22561 +#include <linux/mman.h>
22562 +#include <linux/file.h>
22563 +#include <linux/utsname.h>
22564 +#include <linux/ipc.h>
22565 +#include <linux/fs.h>
22566 +#include <linux/uaccess.h>
22567 +#include <linux/unistd.h>
22568 +
22569 +#include <asm/setup.h>
22570 +#include <asm/traps.h>
22571 +#include <asm/cacheflush.h>
22572 +
22573 +/* common code for old and new mmaps */
22574 +static inline long do_mmap2(
22575 +       unsigned long addr, unsigned long len,
22576 +       unsigned long prot, unsigned long flags,
22577 +       unsigned long fd, unsigned long pgoff)
22578 +{
22579 +       int error = -EBADF;
22580 +       struct file *file = NULL;
22581 +
22582 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22583 +       if (!(flags & MAP_ANONYMOUS)) {
22584 +               file = fget(fd);
22585 +               if (!file)
22586 +                       goto out;
22587 +       }
22588 +
22589 +       down_write(&current->mm->mmap_sem);
22590 +       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
22591 +       up_write(&current->mm->mmap_sem);
22592 +
22593 +       if (file)
22594 +               fput(file);
22595 +out:
22596 +       return error;
22597 +}
22598 +
22599 +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
22600 +       unsigned long prot, unsigned long flags,
22601 +       unsigned long fd, unsigned long pgoff)
22602 +{
22603 +       return do_mmap2(addr, len, prot, flags, fd, pgoff);
22604 +}
22605 +
22606 +/*
22607 + * Perform the select(nd, in, out, ex, tv) and mmap() system
22608 + * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
22609 + * handle more than 4 system call parameters, so these system calls
22610 + * used a memory block for parameter passing..
22611 + */
22612 +
22613 +struct mmap_arg_struct {
22614 +       unsigned long addr;
22615 +       unsigned long len;
22616 +       unsigned long prot;
22617 +       unsigned long flags;
22618 +       unsigned long fd;
22619 +       unsigned long offset;
22620 +};
22621 +
22622 +asmlinkage int old_mmap(struct mmap_arg_struct *arg)
22623 +{
22624 +       struct mmap_arg_struct a;
22625 +       int error = -EFAULT;
22626 +
22627 +       if (copy_from_user(&a, arg, sizeof(a)))
22628 +               goto out;
22629 +
22630 +       error = -EINVAL;
22631 +       if (a.offset & ~PAGE_MASK)
22632 +               goto out;
22633 +
22634 +       a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22635 +
22636 +       error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd,
22637 +                        a.offset >> PAGE_SHIFT);
22638 +out:
22639 +       return error;
22640 +}
22641 +
22642 +struct sel_arg_struct {
22643 +       unsigned long n;
22644 +       fd_set *inp, *outp, *exp;
22645 +       struct timeval *tvp;
22646 +};
22647 +
22648 +asmlinkage int old_select(struct sel_arg_struct *arg)
22649 +{
22650 +       struct sel_arg_struct a;
22651 +
22652 +       if (copy_from_user(&a, arg, sizeof(a)))
22653 +               return -EFAULT;
22654 +       /* sys_select() does the appropriate kernel locking */
22655 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
22656 +}
22657 +
22658 +/*
22659 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
22660 + *
22661 + * This is really horribly ugly.
22662 + */
22663 +asmlinkage int sys_ipc(uint call, int first, int second,
22664 +                       int third, void *ptr, long fifth)
22665 +{
22666 +       int version, ret;
22667 +
22668 +       version = call >> 16; /* hack for backward compatibility */
22669 +       call &= 0xffff;
22670 +
22671 +       if (call <= SEMCTL)
22672 +               switch (call) {
22673 +               case SEMOP:
22674 +                       return sys_semop(first, (struct sembuf *)ptr, second);
22675 +               case SEMGET:
22676 +                       return sys_semget(first, second, third);
22677 +               case SEMCTL: {
22678 +                       union semun fourth;
22679 +                       if (!ptr)
22680 +                               return -EINVAL;
22681 +                       if (get_user(fourth.__pad, (void **) ptr))
22682 +                               return -EFAULT;
22683 +                       return sys_semctl(first, second, third, fourth);
22684 +                       }
22685 +               default:
22686 +                       return -EINVAL;
22687 +               }
22688 +       if (call <= MSGCTL)
22689 +               switch (call) {
22690 +               case MSGSND:
22691 +                       return sys_msgsnd(first, (struct msgbuf *) ptr,
22692 +                                         second, third);
22693 +               case MSGRCV:
22694 +                       switch (version) {
22695 +                       case 0: {
22696 +                               struct ipc_kludge tmp;
22697 +                               if (!ptr)
22698 +                                       return -EINVAL;
22699 +                               if (copy_from_user(&tmp,
22700 +                                                  (struct ipc_kludge *)ptr,
22701 +                                                  sizeof(tmp)))
22702 +                                       return -EFAULT;
22703 +                               return sys_msgrcv(first, tmp.msgp, second,
22704 +                                                  tmp.msgtyp, third);
22705 +                               }
22706 +                       default:
22707 +                               return sys_msgrcv(first,
22708 +                                                 (struct msgbuf *) ptr,
22709 +                                                 second, fifth, third);
22710 +                       }
22711 +               case MSGGET:
22712 +                       return sys_msgget((key_t) first, second);
22713 +               case MSGCTL:
22714 +                       return sys_msgctl(first, second,
22715 +                                          (struct msqid_ds *) ptr);
22716 +               default:
22717 +                       return -EINVAL;
22718 +               }
22719 +       if (call <= SHMCTL)
22720 +               switch (call) {
22721 +               case SHMAT:
22722 +                       switch (version) {
22723 +                       default: {
22724 +                               ulong raddr;
22725 +                               ret = do_shmat(first, ptr, second, &raddr);
22726 +                               if (ret)
22727 +                                       return ret;
22728 +                               return put_user(raddr, (ulong __user *) third);
22729 +                       }
22730 +                       }
22731 +               case SHMDT:
22732 +                       return sys_shmdt(ptr);
22733 +               case SHMGET:
22734 +                       return sys_shmget(first, second, third);
22735 +               case SHMCTL:
22736 +                       return sys_shmctl(first, second, ptr);
22737 +               default:
22738 +                       return -ENOSYS;
22739 +               }
22740 +
22741 +       return -EINVAL;
22742 +}
22743 +
22744 +/* sys_cacheflush -- flush (part of) the processor cache.  */
22745 +asmlinkage int
22746 +sys_cacheflush(unsigned long addr, int scope, int cache, unsigned long len)
22747 +{
22748 +       flush_cache_all();
22749 +       return 0;
22750 +}
22751 +
22752 +asmlinkage int sys_getpagesize(void)
22753 +{
22754 +       return PAGE_SIZE;
22755 +}
22756 --- /dev/null
22757 +++ b/arch/ubicom32/kernel/thread.c
22758 @@ -0,0 +1,228 @@
22759 +/*
22760 + * arch/ubicom32/kernel/thread.c
22761 + *   Ubicom32 architecture hardware thread support.
22762 + *
22763 + * (C) Copyright 2009, Ubicom, Inc.
22764 + *
22765 + * This file is part of the Ubicom32 Linux Kernel Port.
22766 + *
22767 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
22768 + * it and/or modify it under the terms of the GNU General Public License
22769 + * as published by the Free Software Foundation, either version 2 of the
22770 + * License, or (at your option) any later version.
22771 + *
22772 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
22773 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22774 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
22775 + * the GNU General Public License for more details.
22776 + *
22777 + * You should have received a copy of the GNU General Public License
22778 + * along with the Ubicom32 Linux Kernel Port.  If not,
22779 + * see <http://www.gnu.org/licenses/>.
22780 + *
22781 + * Ubicom32 implementation derived from (with many thanks):
22782 + *   arch/m68knommu
22783 + *   arch/blackfin
22784 + *   arch/parisc
22785 + */
22786 +
22787 +#include <linux/module.h>
22788 +#include <linux/kernel.h>
22789 +#include <linux/init.h>
22790 +#include <linux/sched.h>
22791 +#include <linux/interrupt.h>
22792 +#include <linux/irq.h>
22793 +#include <linux/profile.h>
22794 +#include <linux/clocksource.h>
22795 +#include <linux/types.h>
22796 +#include <asm/ip5000.h>
22797 +#include <asm/machdep.h>
22798 +#include <asm/asm-offsets.h>
22799 +#include <asm/thread.h>
22800 +
22801 +/*
22802 + * TODO: At some point change the name here to be thread_ksp
22803 + */
22804 +unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
22805 +
22806 +static unsigned int thread_mask = -1;
22807 +static unsigned int thread_mainline_mask;
22808 +
22809 +/*
22810 + * thread_entry()
22811 + *     Returning from the called function will disable the thread.
22812 + *
22813 + * This could be a naked call to allow for hwthreads that do not have stacks.
22814 + * However, with -O0, the code still writes to thex stack, and this was
22815 + * corrupting memory just after the callers stack.
22816 + */
22817 +static void thread_entry(void *arg, thread_exec_fn_t exec)
22818 +{
22819 +       /*
22820 +        * Call thread function
22821 +        */
22822 +       exec(arg);
22823 +
22824 +       /*
22825 +        * Complete => Disable self
22826 +        */
22827 +       thread_disable(thread_get_self());
22828 +}
22829 +
22830 +/*
22831 + * thread_start()
22832 + *     Start the specified function on the specified hardware thread.
22833 + */
22834 +thread_t thread_start(thread_t thread,
22835 +                     thread_exec_fn_t exec,
22836 +                     void *arg,
22837 +                     unsigned int *sp_high,
22838 +                     thread_type_t type)
22839 +{
22840 +       /*
22841 +        * Sanity check
22842 +        */
22843 +       unsigned int enabled, mask, csr;
22844 +       asm volatile (
22845 +               "move.4         %0, MT_EN\n\t"
22846 +               : "=m" (enabled)
22847 +       );
22848 +
22849 +       mask = 1 << thread;
22850 +       if (enabled & mask) {
22851 +               printk(KERN_WARNING "request to enable a previously enabled thread\n");
22852 +               return (thread_t)-1;
22853 +       }
22854 +
22855 +       /*
22856 +        * Update thread state
22857 +        */
22858 +       csr = (thread << 15) | (1 << 14);
22859 +       asm volatile (
22860 +               "setcsr         %0              \n\t"
22861 +               "setcsr_flush   0               \n\t"
22862 +
22863 +               "move.4         A0, #0          \n\t"
22864 +               "move.4         A1, #0          \n\t"
22865 +               "move.4         A2, #0          \n\t"
22866 +               "move.4         A3, #0          \n\t"
22867 +               "move.4         A4, #0          \n\t"
22868 +               "move.4         A5, #0          \n\t"
22869 +               "move.4         A6, #0          \n\t"
22870 +               "move.4         SP, %4          \n\t"   /* A7 is SP */
22871 +
22872 +               "move.4         D0, %3          \n\t"
22873 +               "move.4         D1, %2          \n\t"
22874 +               "move.4         D2, #0          \n\t"
22875 +               "move.4         D3, #0          \n\t"
22876 +               "move.4         D4, #0          \n\t"
22877 +               "move.4         D5, #0          \n\t"
22878 +               "move.4         D6, #0          \n\t"
22879 +               "move.4         D7, #0          \n\t"
22880 +               "move.4         D8, #0          \n\t"
22881 +               "move.4         D9, #0          \n\t"
22882 +               "move.4         D10, #0         \n\t"
22883 +               "move.4         D11, #0         \n\t"
22884 +               "move.4         D12, #0         \n\t"
22885 +               "move.4         D13, #0         \n\t"
22886 +               "move.4         D14, #0         \n\t"
22887 +               "move.4         D15, #0         \n\t"
22888 +
22889 +               "move.4         INT_MASK0, #0   \n\t"
22890 +               "move.4         INT_MASK1, #0   \n\t"
22891 +               "move.4         PC, %1          \n\t"
22892 +               "setcsr         #0              \n\t"
22893 +               "setcsr_flush   0               \n\t"
22894 +               :
22895 +               : "r" (csr), "r" (thread_entry), "r" (exec),
22896 +                 "r" (arg), "r" (sp_high)
22897 +       );
22898 +
22899 +       /*
22900 +        * Apply HRT state
22901 +        */
22902 +       if (type & THREAD_TYPE_HRT) {
22903 +               asm volatile (
22904 +                       "or.4           MT_HRT, MT_HRT, %0\n\t"
22905 +                       :
22906 +                       : "d" (mask)
22907 +                       : "cc"
22908 +               );
22909 +       } else {
22910 +               asm volatile (
22911 +                       "and.4          MT_HRT, MT_HRT, %0\n\t"
22912 +                       :
22913 +                       : "d" (~mask)
22914 +                       : "cc"
22915 +               );
22916 +       }
22917 +
22918 +       /*
22919 +        * Set priority
22920 +        */
22921 +       asm volatile (
22922 +               "or.4           MT_HPRI, MT_HPRI, %0\n\t"
22923 +               :
22924 +               : "d" (mask)
22925 +               : "cc"
22926 +       );
22927 +
22928 +       /*
22929 +        * Enable thread
22930 +        */
22931 +       asm volatile (
22932 +               "move.4         MT_ACTIVE_SET, %0       \n\t"
22933 +               :
22934 +               : "d" (mask)
22935 +       );
22936 +       thread_enable_mask(mask);
22937 +       return thread;
22938 +}
22939 +
22940 +/*
22941 + * thread_get_mainline()
22942 + *     Return a mask of those threads that are Linux mainline threads.
22943 + */
22944 +unsigned int thread_get_mainline(void)
22945 +{
22946 +       return thread_mainline_mask;
22947 +}
22948 +
22949 +/*
22950 + * thread_set_mainline()
22951 + *     Indicate that the specified thread is a Linux mainline thread.
22952 + */
22953 +void thread_set_mainline(thread_t tid)
22954 +{
22955 +       thread_mainline_mask |= (1 << tid);
22956 +}
22957 +
22958 +/*
22959 + * thread_alloc()
22960 + *     Allocate an unused hardware thread.
22961 + */
22962 +thread_t thread_alloc(void)
22963 +{
22964 +       thread_t tid;
22965 +
22966 +       /*
22967 +        * If this is the first time we are here get the list of unused
22968 +        * threads from the processor device tree node.
22969 +        */
22970 +       if (thread_mask == -1) {
22971 +               thread_mask = processor_threads();
22972 +       }
22973 +
22974 +       if (!thread_mask) {
22975 +               return (thread_t)-1;
22976 +       }
22977 +
22978 +       tid = ffs(thread_mask);
22979 +       if (tid != 0) {
22980 +               tid--;
22981 +               thread_mask &= ~(1 << tid);
22982 +               return tid;
22983 +       }
22984 +
22985 +       return (thread_t)-1;
22986 +}
22987 --- /dev/null
22988 +++ b/arch/ubicom32/kernel/time.c
22989 @@ -0,0 +1,212 @@
22990 +/*
22991 + * arch/ubicom32/kernel/time.c
22992 + *     Initialize the timer list and start the appropriate timers.
22993 + *
22994 + * (C) Copyright 2009, Ubicom, Inc.
22995 + * Copyright (C) 1991, 1992, 1995  Linus Torvalds
22996 + *
22997 + * This file is part of the Ubicom32 Linux Kernel Port.
22998 + *
22999 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23000 + * it and/or modify it under the terms of the GNU General Public License
23001 + * as published by the Free Software Foundation, either version 2 of the
23002 + * License, or (at your option) any later version.
23003 + *
23004 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23005 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23006 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23007 + * the GNU General Public License for more details.
23008 + *
23009 + * You should have received a copy of the GNU General Public License
23010 + * along with the Ubicom32 Linux Kernel Port.  If not,
23011 + * see <http://www.gnu.org/licenses/>.
23012 + *
23013 + * Ubicom32 implementation derived from (with many thanks):
23014 + *   arch/m68knommu
23015 + *   arch/blackfin
23016 + *   arch/parisc
23017 + */
23018 +
23019 +#include <linux/profile.h>
23020 +#include <linux/smp.h>
23021 +#include <asm/ip5000.h>
23022 +#include <asm/machdep.h>
23023 +
23024 +/*
23025 + * A bitmap of the timers on the processor indicates
23026 + * that the timer is free or in-use.
23027 + */
23028 +static unsigned int timers;
23029 +
23030 +/*
23031 + * timer_set()
23032 + *     Init the specified compare register to go off <n> cycles from now.
23033 + */
23034 +void timer_set(int timervector, unsigned int cycles)
23035 +{
23036 +       int idx = UBICOM32_VECTOR_TO_TIMER_INDEX(timervector);
23037 +       UBICOM32_IO_TIMER->syscom[idx] =
23038 +                       UBICOM32_IO_TIMER->sysval + cycles;
23039 +       ldsr_enable_vector(timervector);
23040 +}
23041 +
23042 +/*
23043 + * timer_reset()
23044 + *     Set/reset the timer to go off again.
23045 + *
23046 + * Because sysval is a continuous timer, this function is able
23047 + * to ensure that we do not have clock sku by using the previous
23048 + * value in syscom to set the next value for syscom.
23049 + *
23050 + * Returns the number of ticks that transpired since the last event.
23051 + */
23052 +int timer_reset(int timervector, unsigned int cycles)
23053 +{
23054 +       /*
23055 +        * Reset the timer in the LDSR thread to go off appropriately.
23056 +        *
23057 +        * Use the previous value of the timer to calculate the new stop
23058 +        * time.  This allows us to account for it taking an
23059 +        * indeterminate amount of time to get here.
23060 +        */
23061 +       const int timer_index = UBICOM32_VECTOR_TO_TIMER_INDEX(timervector);
23062 +       unsigned int prev = UBICOM32_IO_TIMER->syscom[timer_index];
23063 +       unsigned int next = prev + cycles;
23064 +       int scratchpad3;
23065 +       int diff;
23066 +       int ticks = 1;
23067 +
23068 +       /*
23069 +        * If the difference is negative, we have missed at least one
23070 +        * timer tick.
23071 +        *
23072 +        * TODO: Decide if we want to "ignore" time (as done below) or
23073 +        * if we want to process time (unevenly) by calling timer_tick()
23074 +        * lost_ticks times.
23075 +        */
23076 +       while (1) {
23077 +               /*
23078 +                * Set our future time first.
23079 +                */
23080 +               UBICOM32_IO_TIMER->syscom[timer_index] = next;
23081 +
23082 +               /*
23083 +                * Then check if we are really set time in the futrue.
23084 +                */
23085 +               diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
23086 +               if (diff >= 0) {
23087 +                       break;
23088 +               }
23089 +
23090 +               /*
23091 +                * Oops, we are too slow. Playing catch up.
23092 +                *
23093 +                * If the debugger is connected the there is a good
23094 +                * chance that we lost time because we were in a
23095 +                * break-point, so in this case we do not print out
23096 +                * diagnostics.
23097 +                */
23098 +               asm volatile ("move.4 %0, scratchpad3"
23099 +                             : "=r" (scratchpad3));
23100 +               if ((scratchpad3 & 0x1) == 0) {
23101 +                       /*
23102 +                        * No debugger attached, print to the console
23103 +                        */
23104 +                       printk(KERN_EMERG "diff: %d, timer has lost %u "
23105 +                              "ticks [rounded up]\n",
23106 +                              -diff,
23107 +                              (unsigned int)((-diff + cycles - 1) / cycles));
23108 +               }
23109 +
23110 +               do {
23111 +                       next += cycles;
23112 +                       diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
23113 +                       ticks++;
23114 +               } while (diff < 0);
23115 +       }
23116 +       return ticks;
23117 +}
23118 +
23119 +/*
23120 + * sched_clock()
23121 + *     Returns current time in nano-second units.
23122 + *
23123 + * Notes:
23124 + * 1) This is an override for the weak alias in
23125 + * kernel/sched_clock.c.
23126 + * 2) Do not use xtime_lock as this function is
23127 + * sometimes called with xtime_lock held.
23128 + * 3) We use a retry algorithm to ensure that
23129 + * we get a consistent value.
23130 + * 4) sched_clock must be overwritten if IRQ tracing
23131 + * is enabled because the default implementation uses
23132 + * the xtime_lock sequence while holding xtime_lock.
23133 + */
23134 +unsigned long long sched_clock(void)
23135 +{
23136 +       unsigned long long my_jiffies;
23137 +       unsigned long jiffies_top;
23138 +       unsigned long jiffies_bottom;
23139 +
23140 +       do {
23141 +               jiffies_top = jiffies_64 >> 32;
23142 +               jiffies_bottom = jiffies_64 & 0xffffffff;
23143 +       } while (unlikely(jiffies_top != (unsigned long)(jiffies_64 >> 32)));
23144 +
23145 +       my_jiffies = ((unsigned long long)jiffies_top << 32) | (jiffies_bottom);
23146 +       return (my_jiffies - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
23147 +}
23148 +
23149 +/*
23150 + * timer_free()
23151 + *     Free a hardware timer.
23152 + */
23153 +void timer_free(int interrupt)
23154 +{
23155 +       unsigned int bit = interrupt - TIMER_INT(0);
23156 +
23157 +       /*
23158 +        * The timer had not been allocated.
23159 +        */
23160 +       BUG_ON(timers & (1 << bit));
23161 +       timers |= (1 << bit);
23162 +}
23163 +
23164 +/*
23165 + * timer_alloc()
23166 + *     Allocate a hardware timer.
23167 + */
23168 +int timer_alloc(void)
23169 +{
23170 +       unsigned int bit = find_first_bit((unsigned long *)&timers, 32);
23171 +       if (!bit) {
23172 +               printk(KERN_WARNING "no more free timers\n");
23173 +               return -1;
23174 +       }
23175 +
23176 +       timers &= ~(1 << bit);
23177 +       return bit + TIMER_INT(0);
23178 +}
23179 +
23180 +/*
23181 + * time_init()
23182 + *     Time init function.
23183 + */
23184 +void time_init(void)
23185 +{
23186 +       /*
23187 +        * Find the processor node and determine what timers are
23188 +        * available for us.
23189 +        */
23190 +       timers = processor_timers();
23191 +       if (timers == 0) {
23192 +               printk(KERN_WARNING "no timers are available for Linux\n");
23193 +               return;
23194 +       }
23195 +
23196 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
23197 +       timer_device_init();
23198 +#else
23199 +       timer_tick_init();
23200 +#endif
23201 +}
23202 --- /dev/null
23203 +++ b/arch/ubicom32/kernel/timer_broadcast.c
23204 @@ -0,0 +1,102 @@
23205 +/*
23206 + * arch/ubicom32/kernel/timer_broadcast.c
23207 + *   Implements a dummy clock event for each cpu.
23208 + *
23209 + * Copyright (C) 2008  Paul Mundt
23210 + * (C) Copyright 2009, Ubicom, Inc.
23211 + *
23212 + * This file is part of the Ubicom32 Linux Kernel Port.
23213 + *
23214 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23215 + * it and/or modify it under the terms of the GNU General Public License
23216 + * as published by the Free Software Foundation, either version 2 of the
23217 + * License, or (at your option) any later version.
23218 + *
23219 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23220 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23221 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23222 + * the GNU General Public License for more details.
23223 + *
23224 + * You should have received a copy of the GNU General Public License
23225 + * along with the Ubicom32 Linux Kernel Port.  If not,
23226 + * see <http://www.gnu.org/licenses/>.
23227 + *
23228 + * Ubicom32 implementation derived from (with many thanks):
23229 + *   arch/m68knommu
23230 + *   arch/blackfin
23231 + *   arch/parisc
23232 + *   arch/arm
23233 + *   arch/sh
23234 + */
23235 +#include <linux/init.h>
23236 +#include <linux/kernel.h>
23237 +#include <linux/delay.h>
23238 +#include <linux/device.h>
23239 +#include <linux/smp.h>
23240 +#include <linux/jiffies.h>
23241 +#include <linux/percpu.h>
23242 +#include <linux/clockchips.h>
23243 +#include <linux/irq.h>
23244 +
23245 +static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
23246 +
23247 +/*
23248 + *  The broadcast trick only works when the timer will be used in a periodic mode.
23249 + *  If the user has configured either NO_HZ or HIGH_RES_TIMERS they must have
23250 + *  a per cpu timer.
23251 + */
23252 +#if defined(CONFIG_NO_HZ) || defined(CONFIG_HIGH_RES_TIMERS)
23253 +#error "Tickless and High Resolution Timers require per-CPU local timers: CONFIG_LOCAL_TIMERS"
23254 +#endif
23255 +
23256 +/*
23257 + * local_timer_interrupt()
23258 + *     Used on SMP for local timer interrupt sent via an IPI.
23259 + */
23260 +void local_timer_interrupt(void)
23261 +{
23262 +       struct clock_event_device *dev = &__get_cpu_var(local_clockevent);
23263 +
23264 +       dev->event_handler(dev);
23265 +}
23266 +
23267 +/*
23268 + * dummy_timer_set_next_event()
23269 + *     Cause the timer to go off "cycles" from now.
23270 + */
23271 +static int dummy_timer_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23272 +{
23273 +       return 0;
23274 +}
23275 +
23276 +/*
23277 + * dummy_timer_set_mode()
23278 + *     Do Nothing.
23279 + */
23280 +static void dummy_timer_set_mode(enum clock_event_mode mode,
23281 +                                struct clock_event_device *clk)
23282 +{
23283 +}
23284 +
23285 +/*
23286 + * local_timer_setup()
23287 + *     Adds a clock event for the specified cpu.
23288 + */
23289 +int __cpuinit local_timer_setup(unsigned int cpu)
23290 +{
23291 +       struct clock_event_device *dev = &per_cpu(local_clockevent, cpu);
23292 +
23293 +       dev->name               = "timer-dummy";
23294 +       dev->features           = CLOCK_EVT_FEAT_DUMMY;
23295 +       dev->rating             = 200;
23296 +       dev->mult               = 1;
23297 +       dev->set_mode           = dummy_timer_set_mode;
23298 +       dev->set_next_event     = dummy_timer_set_next_event;
23299 +       dev->broadcast          = smp_timer_broadcast;
23300 +       dev->cpumask            = cpumask_of_cpu(cpu);
23301 +       dev->irq                = -1;
23302 +       printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
23303 +
23304 +       clockevents_register_device(dev);
23305 +       return 0;
23306 +}
23307 --- /dev/null
23308 +++ b/arch/ubicom32/kernel/timer_device.c
23309 @@ -0,0 +1,302 @@
23310 +/*
23311 + * arch/ubicom32/kernel/timer_device.c
23312 + *   Implements a Ubicom32 clock device and event devices.
23313 + *
23314 + * (C) Copyright 2009, Ubicom, Inc.
23315 + *
23316 + * This file is part of the Ubicom32 Linux Kernel Port.
23317 + *
23318 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23319 + * it and/or modify it under the terms of the GNU General Public License
23320 + * as published by the Free Software Foundation, either version 2 of the
23321 + * License, or (at your option) any later version.
23322 + *
23323 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23324 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23325 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23326 + * the GNU General Public License for more details.
23327 + *
23328 + * You should have received a copy of the GNU General Public License
23329 + * along with the Ubicom32 Linux Kernel Port.  If not,
23330 + * see <http://www.gnu.org/licenses/>.
23331 + *
23332 + * Ubicom32 implementation derived from (with many thanks):
23333 + *   arch/m68knommu
23334 + *   arch/blackfin
23335 + *   arch/parisc
23336 + */
23337 +#include <linux/types.h>
23338 +#include <linux/clockchips.h>
23339 +#include <linux/clocksource.h>
23340 +#include <linux/spinlock.h>
23341 +#include <asm/ip5000.h>
23342 +#include <asm/machdep.h>
23343 +
23344 +#if defined(CONFIG_SMP)
23345 +#include <asm/smp.h>
23346 +#endif
23347 +
23348 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23349 +#define MAX_TIMERS (2 + CONFIG_TIMER_EXTRA_ALLOC)
23350 +#else
23351 +#define MAX_TIMERS (NR_CPUS + CONFIG_TIMER_EXTRA_ALLOC)
23352 +#endif
23353 +
23354 +#if (MAX_TIMERS > 10)
23355 +#error "Ubicom32 only has 10 timers"
23356 +#endif
23357 +
23358 +static unsigned int frequency;
23359 +static struct clock_event_device timer_device_devs[MAX_TIMERS];
23360 +static struct irqaction timer_device_irqs[MAX_TIMERS];
23361 +static int timer_device_next_timer = 0;
23362 +
23363 +DEFINE_SPINLOCK(timer_device_lock);
23364 +
23365 +/*
23366 + * timer_device_set_next_event()
23367 + *     Cause the timer to go off "cycles" from now.
23368 + */
23369 +static int timer_device_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23370 +{
23371 +       timer_set(dev->irq, cycles);
23372 +       return 0;
23373 +}
23374 +
23375 +/*
23376 + * timer_device_set_mode()
23377 + *     Handle the mode switch for a clock event device.
23378 + */
23379 +static void timer_device_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
23380 +{
23381 +       switch (mode) {
23382 +       case CLOCK_EVT_MODE_SHUTDOWN:
23383 +               /*
23384 +                * Make sure the vector is disabled
23385 +                * until the next event is set.
23386 +                */
23387 +               printk(KERN_NOTICE "timer[%d]: shutdown\n", dev->irq);
23388 +               ldsr_disable_vector(dev->irq);
23389 +               break;
23390 +
23391 +       case CLOCK_EVT_MODE_ONESHOT:
23392 +               /*
23393 +                * Make sure the vector is disabled
23394 +                * until the next event is set.
23395 +                */
23396 +               printk(KERN_NOTICE "timer[%d]: oneshot\n", dev->irq);
23397 +               ldsr_disable_vector(dev->irq);
23398 +               break;
23399 +
23400 +       case CLOCK_EVT_MODE_PERIODIC:
23401 +               /*
23402 +                * The periodic request is 1 per jiffies
23403 +                */
23404 +               printk(KERN_NOTICE "timer[%d]: periodic: %d cycles\n",
23405 +                       dev->irq, frequency / CONFIG_HZ);
23406 +               timer_set(dev->irq, frequency / CONFIG_HZ);
23407 +               break;
23408 +
23409 +       case CLOCK_EVT_MODE_UNUSED:
23410 +       case CLOCK_EVT_MODE_RESUME:
23411 +               printk(KERN_WARNING "timer[%d]: unimplemented mode: %d\n",
23412 +                       dev->irq, mode);
23413 +               break;
23414 +       };
23415 +}
23416 +
23417 +/*
23418 + * timer_device_event()
23419 + *     Call the device's event handler.
23420 + *
23421 + * The pointer is initialized by the generic Linux code
23422 + * to the function to be called.
23423 + */
23424 +static irqreturn_t timer_device_event(int irq, void *dev_id)
23425 +{
23426 +       struct clock_event_device *dev = (struct clock_event_device *)dev_id;
23427 +
23428 +       if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
23429 +               /*
23430 +                * The periodic request is 1 per jiffies
23431 +                */
23432 +               timer_reset(dev->irq, frequency / CONFIG_HZ);
23433 +       } else {
23434 +               /*
23435 +                * The timer will go off again at the rollover
23436 +                * point.  We must disable the IRQ to prevent
23437 +                * getting a spurious interrupt.
23438 +                */
23439 +               ldsr_disable_vector(dev->irq);
23440 +       }
23441 +
23442 +       if (!dev->event_handler) {
23443 +               printk(KERN_CRIT "no registered event handler\n");
23444 +               return IRQ_HANDLED;
23445 +       }
23446 +
23447 +       dev->event_handler(dev);
23448 +       return IRQ_HANDLED;
23449 +}
23450 +
23451 +/*
23452 + * timer_device_clockbase_read()
23453 + *     Provide a primary clocksource around the sysval timer.
23454 + */
23455 +static cycle_t timer_device_clockbase_read(void)
23456 +{
23457 +       return (cycle_t)UBICOM32_IO_TIMER->sysval;
23458 +}
23459 +
23460 +/*
23461 + * Primary Clock Source Description
23462 + *
23463 + * We use 24 for the shift factor because we want
23464 + * to ensure there are less than 2^24 clocks
23465 + * in a jiffie of 10 ms.
23466 + */
23467 +static struct clocksource timer_device_clockbase = {
23468 +       .name   = "sysval",
23469 +       .rating = 400,
23470 +       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
23471 +       .mask   = CLOCKSOURCE_MASK(32),
23472 +       .shift  = 24,
23473 +       .mult   = 0,
23474 +       .read   = timer_device_clockbase_read,
23475 +};
23476 +
23477 +/*
23478 + * timer_device_alloc_event()
23479 + *     Allocate a timer device event.
23480 + */
23481 +static int timer_device_alloc_event(const char *name, int cpuid, cpumask_t mask)
23482 +{
23483 +       struct clock_event_device *dev;
23484 +       struct irqaction *action;
23485 +
23486 +       /*
23487 +        * Are we out of configured timers?
23488 +        */
23489 +       spin_lock(&timer_device_lock);
23490 +       if (timer_device_next_timer >= MAX_TIMERS) {
23491 +               spin_unlock(&timer_device_lock);
23492 +               printk(KERN_WARNING "out of timer event entries\n");
23493 +               return -1;
23494 +       }
23495 +       dev = &timer_device_devs[timer_device_next_timer];
23496 +       action = &timer_device_irqs[timer_device_next_timer];
23497 +       timer_device_next_timer++;
23498 +       spin_unlock(&timer_device_lock);
23499 +
23500 +       /*
23501 +        * Now allocate a timer to ourselves.
23502 +        */
23503 +       dev->irq = timer_alloc();
23504 +       if (dev->irq == -1) {
23505 +               spin_lock(&timer_device_lock);
23506 +               timer_device_next_timer--;
23507 +               spin_unlock(&timer_device_lock);
23508 +               printk(KERN_WARNING "out of hardware timers\n");
23509 +               return -1;
23510 +       }
23511 +
23512 +       /*
23513 +        * Init the IRQ action structure.  Make sure
23514 +        * this in place before you register the clock
23515 +        * event device.
23516 +        */
23517 +       action->name = name;
23518 +       action->flags = IRQF_DISABLED | IRQF_TIMER;
23519 +       action->handler = timer_device_event;
23520 +       action->mask = mask;
23521 +       action->dev_id = dev;
23522 +       setup_irq(dev->irq, action);
23523 +       irq_set_affinity(dev->irq, mask);
23524 +       ldsr_disable_vector(dev->irq);
23525 +
23526 +       /*
23527 +        * init clock dev structure.
23528 +        *
23529 +        * The min_delta_ns is chosen to ensure that setting next
23530 +        * event will never be requested with too small of value.
23531 +        */
23532 +       dev->name = name;
23533 +       dev->rating = timer_device_clockbase.rating;
23534 +       dev->shift = timer_device_clockbase.shift;
23535 +       dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
23536 +       dev->set_mode = timer_device_set_mode;
23537 +       dev->set_next_event = timer_device_set_next_event;
23538 +       dev->mult = div_sc(frequency, NSEC_PER_SEC, dev->shift);
23539 +       dev->max_delta_ns = clockevent_delta2ns(0xffffffff, dev);
23540 +       dev->min_delta_ns = clockevent_delta2ns(100, dev);
23541 +       dev->cpumask = mask;
23542 +       printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
23543 +
23544 +       /*
23545 +        * Now register the device.
23546 +        */
23547 +       clockevents_register_device(dev);
23548 +       return dev->irq;
23549 +}
23550 +
23551 +#if defined(CONFIG_LOCAL_TIMERS)
23552 +/*
23553 + * local_timer_setup()
23554 + *     Allocation function for creating a per cpu local timer.
23555 + */
23556 +int __cpuinit local_timer_setup(unsigned int cpu)
23557 +{
23558 +       return timer_device_alloc_event("timer-cpu", cpu, cpumask_of_cpu(cpu));
23559 +}
23560 +#endif
23561 +
23562 +/*
23563 + * timer_device_init()
23564 + *     Create and init a generic clock driver for Ubicom32.
23565 + */
23566 +void timer_device_init(void)
23567 +{
23568 +       int i;
23569 +
23570 +       /*
23571 +        * Get the frequency from the processor device tree node or use
23572 +        * the default if not available. We will store this as the frequency
23573 +        * of the timer to avoid future calculations.
23574 +        */
23575 +       frequency = processor_frequency();
23576 +       if (frequency == 0) {
23577 +               frequency = CLOCK_TICK_RATE;
23578 +       }
23579 +
23580 +       /*
23581 +        * Setup the primary clock source around sysval.  Linux does not
23582 +        * supply a Mhz multiplier so convert down to khz.
23583 +        */
23584 +       timer_device_clockbase.mult =
23585 +               clocksource_khz2mult(frequency / 1000,
23586 +                       timer_device_clockbase.shift);
23587 +       if (clocksource_register(&timer_device_clockbase)) {
23588 +               printk(KERN_ERR "timer: clocksource failed to register\n");
23589 +               return;
23590 +       }
23591 +
23592 +       /*
23593 +        * Always allocate a primary timer.
23594 +        */
23595 +       timer_device_alloc_event("timer-primary", -1, CPU_MASK_ALL);
23596 +
23597 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23598 +       /*
23599 +        * If BROADCAST is selected we need to add a broadcast timer.
23600 +        */
23601 +       timer_device_alloc_event("timer-broadcast", -1, CPU_MASK_ALL);
23602 +#endif
23603 +
23604 +       /*
23605 +        * Allocate extra timers that are requested.
23606 +        */
23607 +       for (i = 0; i < CONFIG_TIMER_EXTRA_ALLOC; i++) {
23608 +               timer_device_alloc_event("timer-extra", -1, CPU_MASK_ALL);
23609 +       }
23610 +}
23611 +
23612 --- /dev/null
23613 +++ b/arch/ubicom32/kernel/timer_tick.c
23614 @@ -0,0 +1,109 @@
23615 +/*
23616 + * arch/ubicom32/kernel/timer_tick.c
23617 + *     Impelemets a perodic timer.
23618 + *
23619 + * (C) Copyright 2009, Ubicom, Inc.
23620 + * Copyright (C) 1991, 1992, 1995  Linus Torvalds
23621 + *
23622 + * This file is part of the Ubicom32 Linux Kernel Port.
23623 + *
23624 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23625 + * it and/or modify it under the terms of the GNU General Public License
23626 + * as published by the Free Software Foundation, either version 2 of the
23627 + * License, or (at your option) any later version.
23628 + *
23629 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23630 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23631 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23632 + * the GNU General Public License for more details.
23633 + *
23634 + * You should have received a copy of the GNU General Public License
23635 + * along with the Ubicom32 Linux Kernel Port.  If not, 
23636 + * see <http://www.gnu.org/licenses/>.
23637 + *
23638 + * Ubicom32 implementation derived from (with many thanks):
23639 + *   arch/m68knommu
23640 + *   arch/blackfin
23641 + *   arch/parisc
23642 + */
23643 +
23644 +#include <linux/profile.h>
23645 +
23646 +#include <asm/ip5000.h>
23647 +#include <asm/machdep.h>
23648 +#if defined(CONFIG_SMP)
23649 +#include <asm/smp.h>
23650 +#endif
23651 +
23652 +static unsigned int timervector;
23653 +static unsigned int frequency;
23654 +
23655 +/*
23656 + * timer_tick()
23657 + *     Kernel system timer support. Needs to keep up the real-time clock, 
23658 + *     as well as call the "do_timer()" routine every clocktick.
23659 + */
23660 +static irqreturn_t timer_tick(int irq, void *dummy)
23661 +{
23662 +       int ticks;
23663 +
23664 +       BUG_ON(!irqs_disabled());
23665 +       ticks = timer_reset(timervector, frequency);
23666 +
23667 +       write_seqlock(&xtime_lock);
23668 +       do_timer(ticks);
23669 +       write_sequnlock(&xtime_lock);
23670 +
23671 +       update_process_times(user_mode(get_irq_regs()));
23672 +       profile_tick(CPU_PROFILING);
23673 +
23674 +#if defined(CONFIG_SMP)
23675 +       smp_send_timer_all();
23676 +#endif
23677 +       return(IRQ_HANDLED);
23678 +}
23679 +
23680 +/*
23681 + * Data used by setup_irq for the timer.
23682 + */
23683 +static struct irqaction timer_irq = {
23684 +       .name    = "timer",
23685 +       .flags   = IRQF_DISABLED | IRQF_TIMER,
23686 +       .handler = timer_tick,
23687 +};
23688 +
23689 +/*
23690 + * timer_tick_init()
23691 + *     Implements a periodic timer
23692 + *
23693 + * This implementation directly calls the timer_tick() and move
23694 + * the Linux kernel forward.  This is used when the user has not
23695 + * selected GENERIC_CLOCKEVENTS.
23696 + */
23697 +void timer_tick_init(void)
23698 +{
23699 +       /*
23700 +        * Now allocate a timer to ourselves.
23701 +        */
23702 +       timervector = timer_alloc();
23703 +       if (timervector == -1) {
23704 +               printk(KERN_WARNING "where did the timer go?\n");
23705 +               return;
23706 +       }
23707 +
23708 +       setup_irq(timervector, &timer_irq);
23709 +
23710 +       /*
23711 +        * Get the frequency from the processor device tree node or use
23712 +        * the default if not available. We will store this as the frequency
23713 +        * of the timer to avoid future calculations.
23714 +        */
23715 +       frequency = processor_frequency();
23716 +       if (frequency == 0) {
23717 +               frequency = CLOCK_TICK_RATE;
23718 +       }
23719 +       frequency /= CONFIG_HZ;
23720 +
23721 +       printk(KERN_NOTICE "timer will interrupt every: %d cycles\n", frequency);
23722 +       timer_set(timervector, frequency);
23723 +}
23724 --- /dev/null
23725 +++ b/arch/ubicom32/kernel/topology.c
23726 @@ -0,0 +1,47 @@
23727 +/*
23728 + * arch/ubicom32/kernel/topology.c
23729 + *   Ubicom32 architecture sysfs topology information.
23730 + *
23731 + * (C) Copyright 2009, Ubicom, Inc.
23732 + *
23733 + * This file is part of the Ubicom32 Linux Kernel Port.
23734 + *
23735 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23736 + * it and/or modify it under the terms of the GNU General Public License
23737 + * as published by the Free Software Foundation, either version 2 of the
23738 + * License, or (at your option) any later version.
23739 + *
23740 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23741 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23742 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23743 + * the GNU General Public License for more details.
23744 + *
23745 + * You should have received a copy of the GNU General Public License
23746 + * along with the Ubicom32 Linux Kernel Port.  If not, 
23747 + * see <http://www.gnu.org/licenses/>.
23748 + *
23749 + * Ubicom32 implementation derived from (with many thanks):
23750 + *   arch/m68knommu
23751 + *   arch/blackfin
23752 + *   arch/parisc
23753 + */
23754 +
23755 +#include <linux/init.h>
23756 +#include <linux/smp.h>
23757 +#include <linux/cpu.h>
23758 +#include <linux/cache.h>
23759 +
23760 +static struct cpu cpu_devices[NR_CPUS] __read_mostly;
23761 +
23762 +static int __init topology_init(void)
23763 +{
23764 +       int num;
23765 +
23766 +       for_each_present_cpu(num) {
23767 +               cpu_devices[num].hotpluggable = 0;
23768 +               register_cpu(&cpu_devices[num], num);
23769 +       }
23770 +       return 0;
23771 +}
23772 +
23773 +subsys_initcall(topology_init);
23774 --- /dev/null
23775 +++ b/arch/ubicom32/kernel/traps.c
23776 @@ -0,0 +1,510 @@
23777 +/*
23778 + * arch/ubicom32/kernel/traps.c
23779 + *   Ubicom32 architecture trap handling support.
23780 + *
23781 + * (C) Copyright 2009, Ubicom, Inc.
23782 + *
23783 + * This file is part of the Ubicom32 Linux Kernel Port.
23784 + *
23785 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
23786 + * it and/or modify it under the terms of the GNU General Public License
23787 + * as published by the Free Software Foundation, either version 2 of the
23788 + * License, or (at your option) any later version.
23789 + *
23790 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
23791 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23792 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23793 + * the GNU General Public License for more details.
23794 + *
23795 + * You should have received a copy of the GNU General Public License
23796 + * along with the Ubicom32 Linux Kernel Port.  If not,
23797 + * see <http://www.gnu.org/licenses/>.
23798 + *
23799 + * Ubicom32 implementation derived from (with many thanks):
23800 + *   arch/m68knommu
23801 + *   arch/blackfin
23802 + *   arch/parisc
23803 + */
23804 +
23805 +/*
23806 + * Sets up all exception vectors
23807 + */
23808 +#include <linux/sched.h>
23809 +#include <linux/signal.h>
23810 +#include <linux/kernel.h>
23811 +#include <linux/mm.h>
23812 +#include <linux/module.h>
23813 +#include <linux/types.h>
23814 +#include <linux/a.out.h>
23815 +#include <linux/user.h>
23816 +#include <linux/string.h>
23817 +#include <linux/linkage.h>
23818 +#include <linux/init.h>
23819 +#include <linux/ptrace.h>
23820 +#include <linux/kallsyms.h>
23821 +#include <linux/compiler.h>
23822 +#include <linux/stacktrace.h>
23823 +#include <linux/personality.h>
23824 +
23825 +#include <asm/uaccess.h>
23826 +#include <asm/stacktrace.h>
23827 +#include <asm/devtree.h>
23828 +#include <asm/setup.h>
23829 +#include <asm/fpu.h>
23830 +#include <asm/system.h>
23831 +#include <asm/traps.h>
23832 +#include <asm/pgtable.h>
23833 +#include <asm/machdep.h>
23834 +#include <asm/siginfo.h>
23835 +#include <asm/ip5000.h>
23836 +#include <asm/thread.h>
23837 +
23838 +#define TRAP_MAX_STACK_DEPTH 20
23839 +
23840 +/*
23841 + * These symbols are filled in by the linker.
23842 + */
23843 +extern unsigned long _stext;
23844 +extern unsigned long _etext;
23845 +
23846 +extern unsigned long __ocm_text_run_begin;
23847 +extern unsigned long __data_begin;
23848 +
23849 +const char *trap_cause_strings[] = {
23850 +       /*0*/   "inst address decode error",
23851 +       /*1*/   "inst sync error",
23852 +       /*2*/   "inst illegal",
23853 +       /*3*/   "src1 address decode error",
23854 +       /*4*/   "dst address decode error",
23855 +       /*5*/   "src1 alignment error",
23856 +       /*6*/   "dst alignment error",
23857 +       /*7*/   "src1 sync error",
23858 +       /*8*/   "dst sync error",
23859 +       /*9*/   "DCAPT error",
23860 +       /*10*/  "inst range error",
23861 +       /*11*/  "src1 range error",
23862 +       /*12*/  "dst range error",
23863 +};
23864 +
23865 +/*
23866 + * The device tree trap node definition.
23867 + */
23868 +struct trapnode {
23869 +       struct devtree_node dn;
23870 +       unsigned int intthread;
23871 +};
23872 +
23873 +static struct trapnode *tn;;
23874 +
23875 +/*
23876 + * trap_interrupt_handler()
23877 + *     Software Interrupt to ensure that a trap is serviced.
23878 + */
23879 +static irqreturn_t trap_interrupt_handler(int irq, void *dummy)
23880 +{
23881 +       /* Do Nothing */
23882 +       return IRQ_HANDLED;
23883 +}
23884 +
23885 +/*
23886 + * Data used by setup_irq for the timer.
23887 + */
23888 +static struct irqaction trap_irq = {
23889 +       .name    = "trap",
23890 +       .flags   = IRQF_DISABLED,
23891 +       .handler = trap_interrupt_handler,
23892 +};
23893 +
23894 +/*
23895 + * trap_cause_to_str()
23896 + *     Convert a trap_cause into a series of printk
23897 + */
23898 +static void trap_cause_to_str(long status)
23899 +{
23900 +       int bit;
23901 +
23902 +       if ((status & ((1 << TRAP_CAUSE_TOTAL) - 1)) == 0) {
23903 +               printk(KERN_NOTICE "decode: UNKNOWN CAUSES\n");
23904 +               return;
23905 +       }
23906 +
23907 +       for (bit = 0; bit < TRAP_CAUSE_TOTAL; bit++) {
23908 +               if (status & (1 << bit)) {
23909 +                       printk(KERN_NOTICE "\tdecode: %08x %s\n",
23910 +                              1 << bit, trap_cause_strings[bit]);
23911 +               }
23912 +       }
23913 +}
23914 +
23915 +/*
23916 + * trap_print_information()
23917 + *     Print the cause of the trap and additional info.
23918 + */
23919 +static void trap_print_information(const char *str, struct pt_regs *regs)
23920 +{
23921 +       printk(KERN_WARNING "\n");
23922 +
23923 +       if (current) {
23924 +               printk(KERN_WARNING "Process %s (pid: %d)\n",
23925 +                       current->comm, current->pid);
23926 +       }
23927 +
23928 +       if (current && current->mm) {
23929 +               printk(KERN_NOTICE "text = 0x%p-0x%p  data = 0x%p-0x%p\n"
23930 +                       KERN_NOTICE "bss = 0x%p-0x%p   user-stack = 0x%p\n"
23931 +                       KERN_NOTICE "\n",
23932 +                       (void *)current->mm->start_code,
23933 +                       (void *)current->mm->end_code,
23934 +                       (void *)current->mm->start_data,
23935 +                       (void *)current->mm->end_data,
23936 +                       (void *)current->mm->end_data,
23937 +                       (void *)current->mm->brk,
23938 +                       (void *)current->mm->start_stack);
23939 +       }
23940 +
23941 +       printk(KERN_WARNING "%s: Causes: 0x%08x\n", str,
23942 +                       (unsigned int)regs->trap_cause);
23943 +       trap_cause_to_str(regs->trap_cause);
23944 +       show_regs(regs);
23945 +       show_stack(NULL, (unsigned long *)regs->an[7]);
23946 +       printk(KERN_NOTICE "--- End Trap --- \n");
23947 +}
23948 +
23949 +/*
23950 + * dump_stack()
23951 + *     Dump the stack of the current task.
23952 + */
23953 +void dump_stack(void)
23954 +{
23955 +       show_stack(NULL, NULL);
23956 +}
23957 +EXPORT_SYMBOL(dump_stack);
23958 +
23959 +/*
23960 + * show_stack()
23961 + *     Print out information from the current stack.
23962 + */
23963 +void show_stack(struct task_struct *task, unsigned long *sp)
23964 +{
23965 +       /*
23966 +        *  Allocate just enough entries on the stack.
23967 +        */
23968 +       unsigned int calls[TRAP_MAX_STACK_DEPTH];
23969 +       unsigned long code_start = (unsigned long)CONFIG_RAMBASE;
23970 +       unsigned long code_end = (unsigned long)CONFIG_RAMBASE+CONFIG_RAMSIZE;
23971 +       unsigned long ocm_code_start = (unsigned long)&__ocm_text_run_begin;
23972 +       unsigned long ocm_code_end = (unsigned long)&__data_begin;
23973 +       unsigned long stack_end = (unsigned long)(current->stack + THREAD_SIZE - 8);
23974 +       unsigned long stack = (unsigned long)sp;
23975 +       int kernel_stack = 1;
23976 +
23977 +       /*
23978 +        * Which task are we talking about.
23979 +        */
23980 +       if (!task) {
23981 +               task = current;
23982 +       }
23983 +
23984 +       /*
23985 +        * Find the stack for the task if one was not specified.  Otherwise
23986 +        * use the specified stack.
23987 +        */
23988 +       if (!stack) {
23989 +               if (task != current) {
23990 +                       stack = task->thread.sp;
23991 +                       stack_end = (unsigned long)task->stack + THREAD_SIZE - 8;
23992 +               } else {
23993 +                       asm volatile (
23994 +                               "move.4         %0, SP          \n\t"
23995 +                               : "=r" (stack)
23996 +                       );
23997 +               }
23998 +       }
23999 +
24000 +       printk(KERN_NOTICE "Starting backtrace: PID %d '%s'\n",
24001 +                       task->pid, task->comm);
24002 +
24003 +       /*
24004 +        * We do 2 passes the first pass is Kernel stack is the second
24005 +        * User stack.
24006 +        */
24007 +       while (kernel_stack) {
24008 +               unsigned long *handle;
24009 +               unsigned int i, idx = 0;
24010 +               struct pt_regs *pt = task_pt_regs(task);
24011 +
24012 +               /*
24013 +                * If the task is in user mode, reset the start
24014 +                * and end values for text.
24015 +                */
24016 +               if (__user_mode(stack)) {
24017 +                       if (!(task->personality & FDPIC_FUNCPTRS)) {
24018 +                               printk(KERN_NOTICE "  User Stack:\n");
24019 +                               code_start = task->mm->start_code;
24020 +                               code_end = task->mm->end_code;
24021 +                       } else {
24022 +                               printk(KERN_NOTICE "  User Stack (fdpic):\n");
24023 +
24024 +                       }
24025 +                       stack_end = task->mm->start_stack;
24026 +                       ocm_code_end = ocm_code_start = 0;
24027 +                       kernel_stack = 0;
24028 +               } else {
24029 +                       printk(KERN_NOTICE "  Kernel Stack:\n");
24030 +               }
24031 +
24032 +               /*
24033 +                * Collect the stack back trace information.
24034 +                */
24035 +               printk("    code[0x%lx-0x%lx]", code_start, code_end);
24036 +               if (ocm_code_start) {
24037 +                       printk(" ocm_code[0x%lx-0x%lx]",
24038 +                              ocm_code_start, ocm_code_end);
24039 +               }
24040 +               printk("\n    stack[0x%lx-0x%lx]\n", stack, stack_end);
24041 +
24042 +               handle = (unsigned long*)stack;
24043 +               while (idx < TRAP_MAX_STACK_DEPTH) {
24044 +                       calls[idx] = stacktrace_iterate(&handle,
24045 +                                       code_start, code_end,
24046 +                                       ocm_code_start, ocm_code_end,
24047 +                                       (unsigned long)stack, stack_end);
24048 +                       if (calls[idx] == 0) {
24049 +                               break;
24050 +                       }
24051 +                       idx++;
24052 +               }
24053 +
24054 +               /*
24055 +                * Now print out the data.
24056 +                */
24057 +               printk(KERN_NOTICE "  CALL && CALLI on stack:");
24058 +               for (i = 0; i < idx; i++) {
24059 +                       printk("%s0x%x, ", (i & 0x3) == 0 ?  "\n    " : "",
24060 +                                       calls[i]);
24061 +               }
24062 +               printk(idx == TRAP_MAX_STACK_DEPTH ? "...\n" : "\n");
24063 +
24064 +               /*
24065 +                * If we are doing user stack we are done
24066 +                */
24067 +               if (!kernel_stack) {
24068 +                       break;
24069 +               }
24070 +
24071 +               /*
24072 +                * Does this kernel stack have a mm (i.e. is it user)
24073 +                */
24074 +               if (!task->mm) {
24075 +                       printk("No mm for userspace stack.\n");
24076 +                       break;
24077 +               }
24078 +               /*
24079 +                * Get the user-mode stack (if any)
24080 +                */
24081 +               stack = pt->an[7];
24082 +               printk(KERN_NOTICE "Userspace stack at 0x%lx frame type %d\n",
24083 +                               stack, (int)pt->frame_type);
24084 +               if (!__user_mode(stack)) {
24085 +                       break;
24086 +               }
24087 +       }
24088 +}
24089 +
24090 +/*
24091 + * die_if_kernel()
24092 + *     Determine if we are in kernel mode and if so print stuff out and die.
24093 + */
24094 +void die_if_kernel(char *str, struct pt_regs *regs, long trap_cause)
24095 +{
24096 +       unsigned int s3value;
24097 +
24098 +       if (user_mode(regs)) {
24099 +               return;
24100 +       }
24101 +
24102 +       console_verbose();
24103 +       trap_print_information(str, regs);
24104 +
24105 +       /*
24106 +        * If the debugger is attached via the hardware mailbox protocol,
24107 +        * go into an infinite loop and the debugger will figure things out.
24108 +        */
24109 +       asm volatile (
24110 +             "move.4 %0, scratchpad3"
24111 +             : "=r" (s3value)
24112 +       );
24113 +       if (s3value) {
24114 +               asm volatile("1:        jmpt.t 1b");
24115 +       }
24116 +
24117 +       /*
24118 +        * Set the debug taint value.
24119 +        */
24120 +       add_taint(TAINT_DIE);
24121 +       do_exit(SIGSEGV);
24122 +}
24123 +
24124 +/*
24125 + * trap_handler()
24126 + *     Handle traps.
24127 + *
24128 + * Traps are treated as interrupts and registered with the LDSR.  When
24129 + * the LDSR takes the interrupt, it will determine if a trap has occurred
24130 + * and service the trap prior to servicing the interrupt.
24131 + *
24132 + * This function is directly called by the LDSR.
24133 + */
24134 +void trap_handler(int irq, struct pt_regs *regs)
24135 +{
24136 +       int sig = SIGSEGV;
24137 +       siginfo_t info;
24138 +       unsigned int trap_cause = regs->trap_cause;
24139 +
24140 +       BUG_ON(!irqs_disabled());
24141 +
24142 +       /*
24143 +        * test if in kernel and die.
24144 +        */
24145 +       die_if_kernel("Kernel Trap", regs, trap_cause);
24146 +
24147 +       /*
24148 +        * User process problem, setup a signal for this process
24149 +        */
24150 +       if ((trap_cause & (1 << TRAP_CAUSE_DST_RANGE_ERR)) ||
24151 +           (trap_cause & (1 << TRAP_CAUSE_SRC1_RANGE_ERR)) ||
24152 +           (trap_cause & (1 << TRAP_CAUSE_I_RANGE_ERR))) {
24153 +               sig = SIGSEGV;
24154 +               info.si_code = SEGV_MAPERR;
24155 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DST_MISALIGNED)) ||
24156 +                  (trap_cause & (1 << TRAP_CAUSE_SRC1_MISALIGNED))) {
24157 +               sig = SIGBUS;
24158 +               info.si_code = BUS_ADRALN;
24159 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DST_DECODE_ERR)) ||
24160 +                  (trap_cause & (1 << TRAP_CAUSE_SRC1_DECODE_ERR))) {
24161 +               sig = SIGILL;
24162 +               info.si_code = ILL_ILLOPN;
24163 +       } else if ((trap_cause & (1 << TRAP_CAUSE_ILLEGAL_INST))) {
24164 +               /*
24165 +                * Check for software break point and if found signal trap
24166 +                * not illegal instruction.
24167 +                */
24168 +               unsigned long instruction;
24169 +               if (between(regs->pc, CONFIG_RAMBASE,
24170 +                           CONFIG_RAMBASE + CONFIG_RAMSIZE) &&
24171 +                       (regs->pc & 3) == 0 &&
24172 +                       get_user(instruction, (unsigned long *)regs->pc) == 0) {
24173 +
24174 +                       /*
24175 +                        * This used to be 0xaabbccdd but it turns out
24176 +                        * that is now valid in ubicom32v4 isa so we
24177 +                        * have switched to 0xfabbccdd
24178 +                        */
24179 +                       if ((instruction == 0xfabbccdd) ||
24180 +                           (instruction == 0xaabbccdd)) {
24181 +                               sig = SIGTRAP;
24182 +                               info.si_code = TRAP_BRKPT;
24183 +                               goto send_signal;
24184 +                       }
24185 +               }
24186 +               sig = SIGILL;
24187 +               info.si_code = ILL_ILLOPC;
24188 +       } else if ((trap_cause & (1 << TRAP_CAUSE_I_DECODE_ERR))) {
24189 +               sig = SIGILL;
24190 +               info.si_code = ILL_ILLOPC;
24191 +       } else if ((trap_cause & (1 << TRAP_CAUSE_DCAPT))) {
24192 +               sig = SIGTRAP;
24193 +               info.si_code = TRAP_TRACE;
24194 +       }
24195 +
24196 +       /*
24197 +        * Print a trap information block to the console, do not
24198 +        * print this above the case because we don't want it
24199 +        * printed for software break points.
24200 +        */
24201 +       trap_print_information("User Trap", regs);
24202 +
24203 +send_signal:
24204 +
24205 +       force_sig_info(sig, &info, current);
24206 +
24207 +       /*
24208 +        * Interrupts are disabled, re-enable them now.
24209 +        */
24210 +       if (!irqs_disabled()) {
24211 +               printk(KERN_EMERG "interrupts enabled on exit, irq=%d, regs=%p",
24212 +                               irq, regs);
24213 +               BUG();
24214 +       }
24215 +}
24216 +
24217 +/*
24218 + * trap_init_interrupt()
24219 + *     We need a 2nd trap handling init that will occur after init_IRQ().
24220 + */
24221 +void __init trap_init_interrupt(void)
24222 +{
24223 +       int err;
24224 +       unsigned char tirq;
24225 +       struct devtree_node *dn = (struct devtree_node *)tn;
24226 +
24227 +       /*
24228 +        * Now setup the Software IRQ so that if a trap occurs the LDSR
24229 +        * is started.  The irq is there just to "force" the LDSR to run.
24230 +        */
24231 +       if (!tn) {
24232 +               printk(KERN_WARNING "trap_init_interrupt skipped.\n");
24233 +               return;
24234 +       }
24235 +
24236 +       err = devtree_irq(dn, NULL, &tirq);
24237 +       if (err) {
24238 +               printk(KERN_WARNING "error obtaining trap irq value: %d\n",
24239 +                       err);
24240 +               return;
24241 +       }
24242 +
24243 +       if (tirq == DEVTREE_IRQ_NONE) {
24244 +               printk(KERN_WARNING "trap irq not available: %d\n", tirq);
24245 +               return;
24246 +       }
24247 +
24248 +       err = setup_irq(tirq, &trap_irq);
24249 +       if (err) {
24250 +               printk(KERN_WARNING "trap irq setup failed: %d\n", err);
24251 +               return;
24252 +       }
24253 +
24254 +       /*
24255 +        * Let ultra know which thread is handling the traps and
24256 +        * what the interrupt to use is.
24257 +        */
24258 +       tn->intthread = ldsr_get_threadid();
24259 +
24260 +       /*
24261 +        * Tell the LDSR about our IRQ so that it will unsuspend
24262 +        * if one occurs while waiting for the per thread lock.
24263 +        */
24264 +       ldsr_set_trap_irq(tirq);
24265 +}
24266 +
24267 +/*
24268 + * trap_init()
24269 + *     init trap handling
24270 + *
24271 + * Trap handling is done through the ldsr.  Every time an interrupt
24272 + * occurs, the LDSR looks for threads that are listed in the TRAP
24273 + * register and forces a call to the trap handler.
24274 + */
24275 +void __init trap_init(void)
24276 +{
24277 +       /*
24278 +        * If we do not have a trap node in the device tree, we leave the fault
24279 +        * handling to the underlying hardware.
24280 +        */
24281 +       tn = (struct trapnode *)devtree_find_node("traps");
24282 +       if (!tn) {
24283 +               printk(KERN_WARNING "traps are not handled by linux\n");
24284 +               return;
24285 +       }
24286 +}
24287 --- /dev/null
24288 +++ b/arch/ubicom32/kernel/uaccess.c
24289 @@ -0,0 +1,109 @@
24290 +/*
24291 + * arch/ubicom32/include/asm/uaccess.c
24292 + *   User space memory access functions for Ubicom32 architecture.
24293 + *
24294 + * (C) Copyright 2009, Ubicom, Inc.
24295 + *
24296 + * This file is part of the Ubicom32 Linux Kernel Port.
24297 + *
24298 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24299 + * it and/or modify it under the terms of the GNU General Public License
24300 + * as published by the Free Software Foundation, either version 2 of the
24301 + * License, or (at your option) any later version.
24302 + *
24303 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24304 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24305 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24306 + * the GNU General Public License for more details.
24307 + *
24308 + * You should have received a copy of the GNU General Public License
24309 + * along with the Ubicom32 Linux Kernel Port.  If not,
24310 + * see <http://www.gnu.org/licenses/>.
24311 + *
24312 + * Ubicom32 implementation derived from (with many thanks):
24313 + *   arch/m68knommu
24314 + *   arch/blackfin
24315 + *   arch/parisc
24316 + */
24317 +
24318 +#include <linux/sched.h>
24319 +#include <linux/mm.h>
24320 +#include <linux/string.h>
24321 +#include <linux/module.h>
24322 +
24323 +#include <asm/segment.h>
24324 +#include <asm/uaccess.h>
24325 +
24326 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
24327 +
24328 +/*
24329 + * __access_ok()
24330 + *     Check that the address is in the current processes.
24331 + * 
24332 + * NOTE: The kernel uses "pretend" user addresses that wind
24333 + * up calling access_ok() so this approach has only marginal
24334 + * value because you wind up with lots of false positives.
24335 + */
24336 +int __access_ok(unsigned long addr, unsigned long size)
24337 +{
24338 +       // struct vm_area_struct *vma;
24339 +
24340 +       /*
24341 +        * Don't do anything if we are not a running system yet.
24342 +        */
24343 +       if (system_state != SYSTEM_RUNNING) {
24344 +               return 1;
24345 +       }
24346 +
24347 +       /*
24348 +        * It appears that Linux will call this function even when we are not
24349 +        * in the context of a user space application that has a VM address 
24350 +        * space.  So we must check that current and mm are valid before
24351 +        * performing the check.
24352 +        */
24353 +       if ((!current) || (!current->mm)) {
24354 +               return 1;
24355 +       }
24356 +
24357 +       /*
24358 +        * We perform some basic checks on the address to ensure that it
24359 +        * is at least within the range of DRAM.
24360 +        */
24361 +       if ((addr < (int)&_etext) || (addr > memory_end)) {
24362 +               printk(KERN_WARNING "pid=%d[%s]: range [%lx - %lx] not in memory area: [%lx - %lx]\n",
24363 +                       current->pid, current->comm, 
24364 +                       addr, addr + size,
24365 +                       memory_start, memory_end);
24366 +               return 0;
24367 +       }
24368 +
24369 +       /*
24370 +        * For nommu Linux we can check this by looking at the allowed
24371 +        * memory map for the process.
24372 +        *
24373 +        * TODO: Since the kernel passes addresses in it's own space as though
24374 +        * they were user address, we can not validate the addresses this way.
24375 +        */
24376 +#if 0
24377 +       if (!down_read_trylock(&current->mm->mmap_sem)) {
24378 +               return 1;
24379 +       }
24380 +       vma = find_vma(current->mm, addr);
24381 +       if (!vma) {
24382 +               up_read(&current->mm->mmap_sem);
24383 +               printk(KERN_WARNING "pid=%d[%s]: possible invalid acesss on range: [%lx - %lx]\n",
24384 +                               current->pid, current->comm, addr, addr + size);
24385 +               return 1;
24386 +       }
24387 +       if ((addr + size) > vma->vm_end) {
24388 +               up_read(&current->mm->mmap_sem);
24389 +               printk(KERN_WARNING "pid=%d[%s]: possible invalid length on range: [%lx - %lx]\n",
24390 +                               current->pid, current->comm, addr, addr + size);
24391 +               return 1;
24392 +       }
24393 +       up_read(&current->mm->mmap_sem);
24394 +#endif
24395 +       return 1;
24396 +}
24397 +
24398 +EXPORT_SYMBOL(__access_ok);
24399 --- /dev/null
24400 +++ b/arch/ubicom32/kernel/ubicom32_context_switch.S
24401 @@ -0,0 +1,325 @@
24402 +/*
24403 + * arch/ubicom32/kernel/ubicom32_context_switch.S
24404 + *     Implements context switch and return functions.
24405 + *
24406 + * (C) Copyright 2009, Ubicom, Inc.
24407 + *
24408 + * This file is part of the Ubicom32 Linux Kernel Port.
24409 + *
24410 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24411 + * it and/or modify it under the terms of the GNU General Public License
24412 + * as published by the Free Software Foundation, either version 2 of the
24413 + * License, or (at your option) any later version.
24414 + *
24415 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24416 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24417 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24418 + * the GNU General Public License for more details.
24419 + *
24420 + * You should have received a copy of the GNU General Public License
24421 + * along with the Ubicom32 Linux Kernel Port.  If not,
24422 + * see <http://www.gnu.org/licenses/>.
24423 + *
24424 + * Ubicom32 implementation derived from (with many thanks):
24425 + *   arch/m68knommu
24426 + *   arch/blackfin
24427 + *   arch/parisc
24428 + */
24429 +#include <linux/sys.h>
24430 +#include <linux/linkage.h>
24431 +#include <asm/asm-offsets.h>
24432 +#include <asm/ubicom32-common.h>
24433 +#include <asm/ip5000.h>
24434 +#include <asm/range-protect.h>
24435 +
24436 +/*
24437 + * restore_context()
24438 + *     Restore the full context from sp (struct pt_reg *)
24439 + *
24440 + * Note: Recovered PC and CSR are saved on the stack and are to be popped off
24441 + * before returning.
24442 + */
24443 +.macro restore_context
24444 +       move.4  a0, sp                  ; Set up a0 as base address for register recovery
24445 +       move.4  sp, PT_SP(a0)           ; Recover Stack pointer from save area
24446 +       move.4  -4(sp)++, PT_PC(a0)     ; Recover saved PC and save to stack
24447 +       move.4  -4(sp)++, PT_CSR(a0)    ; Recover saved csr and save to stack
24448 +       move.4  d0, PT_D0(a0)
24449 +       move.4  d1, PT_D1(a0)
24450 +       move.4  d2, PT_D2(a0)
24451 +       move.4  d3, PT_D3(a0)
24452 +       move.4  d4, PT_D4(a0)
24453 +       move.4  d5, PT_D5(a0)
24454 +       move.4  d6, PT_D6(a0)
24455 +       move.4  d7, PT_D7(a0)
24456 +       move.4  d8, PT_D8(a0)
24457 +       move.4  d9, PT_D9(a0)
24458 +       move.4  d10, PT_D10(a0)
24459 +       move.4  d11, PT_D11(a0)
24460 +       move.4  d12, PT_D12(a0)
24461 +       move.4  d13, PT_D13(a0)
24462 +       move.4  d14, PT_D14(a0)
24463 +       move.4  d15, PT_D15(a0)
24464 +       move.4  a1, PT_A1(a0)
24465 +       move.4  a2, PT_A2(a0)
24466 +       move.4  a3, PT_A3(a0)
24467 +       move.4  a4, PT_A4(a0)
24468 +       move.4  a5, PT_A5(a0)
24469 +       move.4  a6, PT_A6(a0)
24470 +       move.4  acc0_hi, PT_ACC0HI(a0)
24471 +       move.4  acc0_lo, PT_ACC0LO(a0)
24472 +       move.4  mac_rc16, PT_MAC_RC16(a0)
24473 +       move.4  acc1_hi, PT_ACC1HI(a0)
24474 +       move.4  acc1_lo, PT_ACC1LO(a0)
24475 +       move.4  source3, PT_SOURCE3(a0)
24476 +       move.4  int_mask0, PT_INT_MASK0(a0)
24477 +       move.4  int_mask1, PT_INT_MASK1(a0)
24478 +       move.4  a0, PT_A0(a0)
24479 +.endm
24480 +
24481 +/*
24482 + * ldsr_thread_enable_interrupts()
24483 + *     An assembly version of the enable interrupts function.
24484 + *
24485 + * The stack is fair game but all registers MUST be preserved.
24486 + *
24487 + */
24488 +.macro ldsr_thread_enable_interrupts
24489 +       move.4  -4(sp)++, d3    ; Push d3
24490 +       move.4  -4(sp)++, a3    ; Push a3
24491 +
24492 +       /*
24493 +        * Read the ROSR and obtain ~(1 << tid)
24494 +        */
24495 +       lsr.4   d3, rosr, #0x2  ; Move the thread portion of ROSR into d3
24496 +       lsl.4   d3, #1, d3      ; perform a (1 << tid)
24497 +       not.4   d3, d3          ; Negate the value of d3 == ~(1 << threadid)
24498 +
24499 +       /*
24500 +        * Get the value of the ldsr_soft_irq_mask
24501 +        */
24502 +       moveai  a3, #%hi(ldsr_soft_irq_mask)
24503 +       move.4  a3, %lo(ldsr_soft_irq_mask)(a3)
24504 +
24505 +       /*
24506 +        * Now re-enable interrupts for this thread and then
24507 +        * wakeup the LDSR.
24508 +        */
24509 +       and.4   scratchpad1, scratchpad1, d3
24510 +       move.4  int_set0, a3
24511 +
24512 +       /*
24513 +        * Restore the registers.
24514 +        */
24515 +       move.4  a3, (sp)4++
24516 +       move.4  d3, (sp)4++
24517 +.endm
24518 +
24519 +/*
24520 + * ret_from_interrupt_to_kernel()
24521 + *     RFI function that is where do_IRQ() returns to if the thread was in kernel space.
24522 + */
24523 +       .section .text.ret_from_interrupt_to_kernel
24524 +       .global ret_from_interrupt_to_kernel
24525 +ret_from_interrupt_to_kernel:
24526 +       atomic_lock_acquire             ; Enter critical section
24527 +       restore_context                 ; Restore the thread context
24528 +       atomic_lock_release             ; Leave critical section
24529 +       ldsr_thread_enable_interrupts   ; enable the threads interrupts
24530 +       move.4  csr, (sp)4++            ; Restore csr from the stack
24531 +       ret     (sp)4++
24532 +
24533 +/*
24534 + * ret_from_interrupt_to_user()
24535 + *     RFI function that is where do_IRQ() returns to if the thread was in user space.
24536 + *
24537 + * TODO: Do we really need the ciritical section handling in this code?
24538 + *
24539 + */
24540 +       .section .ret_from_interrupt_to_user.text
24541 +       .global ret_from_interrupt_to_user
24542 +ret_from_interrupt_to_user:
24543 +       ldsr_thread_enable_interrupts                   ; enable the threads interrupts
24544 +       movei   d0, #(~(ASM_THREAD_SIZE-1))
24545 +       and.4   a3, sp, d0                              ; a3 now has the thread info pointer
24546 +
24547 +       /*
24548 +        * Test if the scheduler needs to be called.
24549 +        */
24550 +       btst    TI_FLAGS(a3), #ASM_TIF_NEED_RESCHED
24551 +       jmpeq.t 2f
24552 +       moveai  a5, #%hi(schedule)
24553 +       calli   a5, %lo(schedule)(a5)                   ; Call the scheduler. I will come back here.
24554 +
24555 +       /*
24556 +        * See if we have pending signals and call do_signal
24557 +        * if needed.
24558 +        */
24559 +2:     atomic_lock_acquire                             ; Enter critical section
24560 +       move.4  -4(sp)++, a1                            ; Save A1 on the stack. We are going to use a1 it.
24561 +       movei   d0, #(~(ASM_THREAD_SIZE-1))
24562 +       and.4   a1, sp, d0                              ; a1 now has the thread info pointer
24563 +       btst    TI_FLAGS(a1), #ASM_TIF_SIGPENDING       ; Any signals needed?
24564 +       jmpeq.t 1f
24565 +
24566 +
24567 +       /*
24568 +        * Now call do_signal()
24569 +        */
24570 +       atomic_lock_release                             ; Leave critical section
24571 +       move.4  d0, #0                                  ; oldset pointer is NULL
24572 +       lea.1   d1, 4(sp)                               ; d1 is the regs pointer
24573 +       moveai  a5, #%hi(do_signal)
24574 +       calli   a5, %lo(do_signal)(a5)                  ; Call do_signal()
24575 +
24576 +       /*
24577 +        * Back from do_signal(), re-enter critical section.
24578 +        */
24579 +       atomic_lock_acquire                             ; Enter critical section
24580 +
24581 +1:     move.4  a1, (sp)4++                             ; pop A1 off the stack
24582 +
24583 +       disable_kernel_ranges_for_current d15           ; disable kernel ranges
24584 +
24585 +       restore_context                                 ; restore the previous context
24586 +       atomic_lock_release                             ; Leave critical section
24587 +       move.4  csr, (sp)4++                            ; Restore csr from the stack
24588 +       ret     (sp)4++
24589 +
24590 +/*
24591 + * restore_all_registers()
24592 + *
24593 + * restore_all_registers will be the alternate exit route for
24594 + * preempted processes that have called a signal handler
24595 + * and are returning back to user space.
24596 + */
24597 +       .global restore_all_registers
24598 +restore_all_registers:
24599 +       atomic_lock_acquire                     ; Enter critical section
24600 +       disable_kernel_ranges_for_current d15   ; disable kernel ranges
24601 +       atomic_lock_release                     ; Leave critical section
24602 +       restore_context                         ; restore previous context
24603 +       move.4  csr, (sp)4++                    ; Restore csr from the stack
24604 +       ret     (sp)4++
24605 +
24606 +/*
24607 + * ret_from_fork()
24608 + *     Called on the child's return from fork system call.
24609 + */
24610 +       .section .ret_from_fork.text
24611 +       .global ret_from_fork
24612 +ret_from_fork:
24613 +       ;;;  d0 contains the arg for schedule_tail
24614 +       ;;;  the others we don't care about as they are in PT_REGS (sp)
24615 +       moveai  a5, #%hi(schedule_tail)
24616 +       calli   a5, %lo(schedule_tail)(a5)
24617 +
24618 +       atomic_lock_acquire             ; Enter critical section
24619 +
24620 +       move.4  a3, sp
24621 +       move.4  d0, PT_D0(a3)           ; Restore D0
24622 +       move.4  d1, PT_D1(a3)           ; Restore D1
24623 +       move.4  d2, PT_D2(a3)           ; Restore D2
24624 +       move.4  d3, PT_D3(a3)           ; Restore D3
24625 +       move.4  d10, PT_D10(a3)         ; Restore D10
24626 +       move.4  d11, PT_D11(a3)         ; Restore D11
24627 +       move.4  d12, PT_D12(a3)         ; Restore D12
24628 +       move.4  d13, PT_D13(a3)         ; Restore D13
24629 +       move.4  a1, PT_A1(a3)           ; Restore A1
24630 +       move.4  a2, PT_A2(a3)           ; Restore A2
24631 +       move.4  a5, PT_A5(a3)           ; Restore A5
24632 +       move.4  a6, PT_A6(a3)           ; Restore A6
24633 +       move.4  sp, PT_SP(a3)           ; Restore sp
24634 +       move.4  a4, PT_PC(a3)           ; Restore pc in register a4
24635 +       move.4  PT_FRAME_TYPE(a3), #0   ; Clear frame_type to indicate it is invalid.
24636 +
24637 +       disable_kernel_ranges_for_current d15
24638 +       atomic_lock_release             ; Leave critical section
24639 +       calli   a4, 0(a4)               ; Return.
24640 +
24641 +/*
24642 + * __switch_to()
24643 + *
24644 + * Call with:
24645 + *     void *__switch_to(struct task_struct *prev, struct thread_struct *prev_switch,
24646 + *                             struct thread_struct *next_switch)
24647 + */
24648 +       .global __switch_to
24649 +__switch_to:
24650 +
24651 +       /*
24652 +        * Set up register a3 to point to save area.
24653 +        */
24654 +       movea   a3, d1                  ; a3 now holds prev_switch
24655 +       move.4  (a3)4++, d10
24656 +       move.4  (a3)4++, d11
24657 +       move.4  (a3)4++, d12
24658 +       move.4  (a3)4++, d13
24659 +       move.4  (a3)4++, a1
24660 +       move.4  (a3)4++, a2
24661 +       move.4  (a3)4++, a5
24662 +       move.4  (a3)4++, a6
24663 +       move.4  (a3)4++, a7
24664 +
24665 +       /*
24666 +        * Set up register a3 to point to restore area.
24667 +        */
24668 +       movea   a3, d2                  ; a3 now holds next_switch
24669 +       move.4  d10 , (a3)4++
24670 +       move.4  d11 , (a3)4++
24671 +       move.4  d12 , (a3)4++
24672 +       move.4  d13 , (a3)4++
24673 +       move.4  a1 , (a3)4++
24674 +       move.4  a2 , (a3)4++
24675 +       move.4  a5 , (a3)4++
24676 +       move.4  a6 , (a3)4++
24677 +       move.4  a7 , (a3)4++
24678 +
24679 +       /*
24680 +        * Load the sw_ksp with the proper thread_info pointer.
24681 +        */
24682 +       movei   d15, #(~(ASM_THREAD_SIZE-1))
24683 +       and.4   a3, sp, d15             ; a3 now has the thread info pointer
24684 +       moveai  a4, #%hi(sw_ksp)
24685 +       lea.1   a4, %lo(sw_ksp)(a4)     ; a4 now has the base address of sw_ksp array
24686 +       lsr.4   d15, ROSR, #2           ; Thread number + garbage
24687 +       and.4   d15, #31, D15           ; Mask to get thread number into register D15
24688 +       move.4  (a4, d15), a3           ; Load the thread info pointer into the hw_ksp array..
24689 +
24690 +       /*
24691 +        * We are done with context switch. Time to return..
24692 +        */
24693 +       ret     a5
24694 +
24695 +
24696 +/*
24697 + * ubicom32_emulate_insn()
24698 + *     Emulates the instruction.
24699 + *
24700 + * Call with:
24701 + *     unsigned int ubicom32_emulate_insn(int source1, int source2, int source3, int *save_acc, int *save_csr);
24702 + */
24703 +       .global ubicom32_emulate_insn
24704 +       .global trap_emulate
24705 +ubicom32_emulate_insn:
24706 +       movea   a3, d3          ; a3 holds save_acc pointer
24707 +       movea   a4, d4          ; a4 hods save_csr pointer
24708 +       move.4  source3, d2
24709 +       move.4  acc0_lo, (a3)
24710 +       move.4  acc0_hi, 4(a3)
24711 +       move.4  acc1_lo, 8(a3)
24712 +       move.4  acc1_hi, 12(a3)
24713 +       move.4  mac_rc16, 16(a3)
24714 +       move.4  CSR, (a4)
24715 +       setcsr_flush 0
24716 +
24717 +trap_emulate:
24718 +       move.4  d0, d1
24719 +       setcsr_flush 0
24720 +       move.4  (a4), CSR       ; Save csr
24721 +       move.4  (a3), acc0_lo
24722 +       move.4  4(a3), acc0_hi
24723 +       move.4  8(a3), acc1_lo
24724 +       move.4  12(a3), acc1_hi
24725 +       move.4  16(a3), mac_rc16
24726 +       ret     a5
24727 --- /dev/null
24728 +++ b/arch/ubicom32/kernel/ubicom32_ksyms.c
24729 @@ -0,0 +1,95 @@
24730 +/*
24731 + * arch/ubicom32/kernel/ubicom32_ksyms.c
24732 + *   Ubicom32 architecture compiler support and misc symbols.
24733 + *
24734 + * (C) Copyright 2009, Ubicom, Inc.
24735 + *
24736 + * This file is part of the Ubicom32 Linux Kernel Port.
24737 + *
24738 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24739 + * it and/or modify it under the terms of the GNU General Public License
24740 + * as published by the Free Software Foundation, either version 2 of the
24741 + * License, or (at your option) any later version.
24742 + *
24743 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24744 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24745 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24746 + * the GNU General Public License for more details.
24747 + *
24748 + * You should have received a copy of the GNU General Public License
24749 + * along with the Ubicom32 Linux Kernel Port.  If not,
24750 + * see <http://www.gnu.org/licenses/>.
24751 + *
24752 + * Ubicom32 implementation derived from (with many thanks):
24753 + *   arch/m68knommu
24754 + *   arch/blackfin
24755 + *   arch/parisc
24756 + */
24757 +#include <linux/module.h>
24758 +#include <linux/linkage.h>
24759 +#include <linux/sched.h>
24760 +#include <linux/string.h>
24761 +#include <linux/mm.h>
24762 +#include <linux/user.h>
24763 +#include <linux/elfcore.h>
24764 +#include <linux/in6.h>
24765 +#include <linux/interrupt.h>
24766 +#include <linux/io.h>
24767 +#include <linux/semaphore.h>
24768 +
24769 +#include <asm/setup.h>
24770 +#include <asm/machdep.h>
24771 +#include <asm/pgalloc.h>
24772 +#include <asm/irq.h>
24773 +#include <asm/checksum.h>
24774 +#include <asm/current.h>
24775 +
24776 +/* platform dependent support */
24777 +
24778 +EXPORT_SYMBOL(__ioremap);
24779 +EXPORT_SYMBOL(iounmap);
24780 +
24781 +EXPORT_SYMBOL(ip_fast_csum);
24782 +
24783 +
24784 +/* Networking helper routines. */
24785 +EXPORT_SYMBOL(csum_partial_copy_nocheck);
24786 +
24787 +/* The following are special because they're not called
24788 +   explicitly (the C compiler generates them).  Fortunately,
24789 +   their interface isn't gonna change any time soon now, so
24790 +   it's OK to leave it out of version control.  */
24791 +EXPORT_SYMBOL(memcpy);
24792 +EXPORT_SYMBOL(memset);
24793 +
24794 +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4
24795 +/*
24796 + * libgcc functions - functions that are used internally by the
24797 + * compiler...  (prototypes are not correct though, but that
24798 + * doesn't really matter since they're not versioned).
24799 + */
24800 +extern void __ashldi3(void);
24801 +extern void __ashrdi3(void);
24802 +extern void __divsi3(void);
24803 +extern void __lshrdi3(void);
24804 +extern void __modsi3(void);
24805 +extern void __muldi3(void);
24806 +extern void __udivsi3(void);
24807 +extern void __umodsi3(void);
24808 +
24809 +/* gcc lib functions */
24810 +EXPORT_SYMBOL(__ashldi3);
24811 +EXPORT_SYMBOL(__ashrdi3);
24812 +EXPORT_SYMBOL(__divsi3);
24813 +EXPORT_SYMBOL(__lshrdi3);
24814 +EXPORT_SYMBOL(__modsi3);
24815 +EXPORT_SYMBOL(__muldi3);
24816 +EXPORT_SYMBOL(__udivsi3);
24817 +EXPORT_SYMBOL(__umodsi3);
24818 +#else
24819 +extern void __libgcc_udivmodsi(void);
24820 +extern void __libgcc_divmodsi(void);
24821 +
24822 +EXPORT_SYMBOL(__libgcc_udivmodsi);
24823 +EXPORT_SYMBOL(__libgcc_divmodsi);
24824 +#endif
24825 --- /dev/null
24826 +++ b/arch/ubicom32/kernel/ubicom32_syscall.S
24827 @@ -0,0 +1,643 @@
24828 +/*
24829 + * arch/ubicom32/kernel/ubicom32_syscall.S
24830 + *     <TODO: Replace with short file description>
24831 + *
24832 + * (C) Copyright 2009, Ubicom, Inc.
24833 + *
24834 + * This file is part of the Ubicom32 Linux Kernel Port.
24835 + *
24836 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
24837 + * it and/or modify it under the terms of the GNU General Public License
24838 + * as published by the Free Software Foundation, either version 2 of the
24839 + * License, or (at your option) any later version.
24840 + *
24841 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
24842 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24843 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
24844 + * the GNU General Public License for more details.
24845 + *
24846 + * You should have received a copy of the GNU General Public License
24847 + * along with the Ubicom32 Linux Kernel Port.  If not,
24848 + * see <http://www.gnu.org/licenses/>.
24849 + *
24850 + * Ubicom32 implementation derived from (with many thanks):
24851 + *   arch/m68knommu
24852 + *   arch/blackfin
24853 + *   arch/parisc
24854 + */
24855 +#include <linux/sys.h>
24856 +#include <linux/linkage.h>
24857 +#include <linux/unistd.h>
24858 +
24859 +#include <asm/ubicom32-common.h>
24860 +#include <asm/thread_info.h>
24861 +#include <asm/asm-offsets.h>
24862 +#include <asm/range-protect.h>
24863 +
24864 +/*
24865 + * system_call()
24866 + */
24867 +       .section .syscall_entry.text
24868 +       .global system_call
24869 +system_call:
24870 +       /*
24871 +        * Regular ABI rules for function calls apply for syscall.  d8 holds
24872 +        * the syscall number. We will use that to index into the syscall table.
24873 +        * d0 - d5 hold the parameters.
24874 +        *
24875 +        * First we get the current thread_info and swap to the kernel stack.
24876 +        * This is done by reading the current thread and looking up the ksp
24877 +        * from the sw_ksp array and storing it in a3.
24878 +        *
24879 +        * Then we reserve space for the syscall context a struct pt_regs and
24880 +        * save it using a4 initially and later as sp.
24881 +        * Once sp is set to the kernel sp we can leave the critical section.
24882 +        *
24883 +        * For the user case the kernel stack will have the following layout.
24884 +        *
24885 +        *  a3           ksp[0] +-----------------------+
24886 +        *                      | Thread info area      |
24887 +        *                      | struct thread_info    |
24888 +        *                      +-----------------------+
24889 +        *                      :                       :
24890 +        *                      |   Kernel Stack Area   |
24891 +        *                      |                       |
24892 +        *  a4 / sp >>>         +-----------------------+
24893 +        *                      | Context save area     |
24894 +        *                      | struct pt_reg         |
24895 +        *  ksp[THREAD_SIZE-8]  +-----------------------+
24896 +        *                      | 8 Byte Buffer Zone    |
24897 +        *  ksp[THREAD_SIZE]    +-----------------------+
24898 +
24899 +        *
24900 +        * For kernel syscalls the layout is as follows.
24901 +        *
24902 +        *  a3           ksp[0] +-----------------------+
24903 +        *                      | Thread info area      |
24904 +        *                      | struct thread_info    |
24905 +        *                      +-----------------------+
24906 +        *                      :                       :
24907 +        *                      |   Kernel Stack Area   |
24908 +        *                      |                       |
24909 +        *  a4 / sp >>>         +-----------------------+
24910 +        *                      | Context save area     |
24911 +        *                      | struct pt_reg         |
24912 +        * sp at syscall entry  +-----------------------+
24913 +        *                      | Callers Kernel Stack  |
24914 +        *                      :                       :
24915 +        *
24916 +        * Once the context is saved we optionally call syscall_trace and setup
24917 +        * the exit routine and jump to the syscall.
24918 +        */
24919 +
24920 +       /*
24921 +        * load the base address for sw_ksp into a3
24922 +        * Note.. we cannot access it just yet as protection is still on.
24923 +        */
24924 +       moveai  a3, #%hi(sw_ksp)
24925 +       lea.1   a3, %lo(sw_ksp)(a3)
24926 +
24927 +       /*
24928 +        * Enter critical section .
24929 +        *
24930 +        * The 'critical' aspects here are the switching the to the ksp and
24931 +        * changing the protection registers, these both use per thread
24932 +        * information so we need to protect from a context switch. For now this
24933 +        * is done using the global atomic lock.
24934 +        */
24935 +       atomic_lock_acquire
24936 +
24937 +       thread_get_self d15                     ; Load current thread number
24938 +#ifdef CONFIG_PROTECT_KERNEL
24939 +       lsl.4   d9, #1, d15                     ; Convert to thread bit
24940 +       enable_kernel_ranges d9
24941 +#endif
24942 +       /*
24943 +        * We need to Determine if this is a kernel syscall or user syscall.
24944 +        * Start by loading the pointer for the thread_info structure for the
24945 +        * current process in to a3.
24946 +        */
24947 +       move.4  a3, (a3, d15)                   ; a3 = sw_ksp[d15]
24948 +
24949 +       /*
24950 +        * Now if this is a kernel thread the same value can be a acheived by
24951 +        * masking off the lower bits on the current stack pointer.
24952 +        */
24953 +       movei   d9, #(~(ASM_THREAD_SIZE-1))     ; load mask
24954 +       and.4   d9, sp, d9                      ; apply mask
24955 +
24956 +       /*
24957 +        * d9 now has the masked version of the sp. If this is identical to
24958 +        * what is in a3 then don't switch to ksp as we are already in the
24959 +        * kernel.
24960 +        */
24961 +       sub.4   #0, a3, d9
24962 +
24963 +       /*
24964 +        * if d9 and a3 are not equal. We are usespace and have to shift to
24965 +        * ksp.
24966 +        */
24967 +       jmpne.t 1f
24968 +
24969 +       /*
24970 +        * Kernel Syscall.
24971 +        *
24972 +        * The kernel has called this routine. We have to pdec space for pt_regs
24973 +        * from sp.
24974 +        */
24975 +       pdec    a4, PT_SIZE(sp)                 ; a4 = ksp - PT_SIZE
24976 +       jmpt.t  2f
24977 +
24978 +       /*
24979 +        * Userspace Syscall.
24980 +        *
24981 +        * Add THREAD_SIZE and subtract PT_SIZE to create the proper ksp
24982 +        */
24983 +1:     movei   d15, #(ASM_THREAD_SIZE - 8 - PT_SIZE)
24984 +       lea.1   a4, (a3, d15)                   ; a4 = ksp + d15
24985 +
24986 +       /*
24987 +        * Replace user stack pointer with kernel stack pointer (a4)
24988 +        * Load -1 into frame_type in save area to indicate this is system call
24989 +        * frame.
24990 +        */
24991 +2:     move.4  PT_A7(a4), a7                   ; Save old sp/A7 on kernel stack
24992 +       move.4  PT_FRAME_TYPE(a4), #-1          ; Set the frame type.
24993 +       move.4  sp, a4                          ; Change to ksp.
24994 +       /*
24995 +        * We are now officially back in the kernel!
24996 +        */
24997 +
24998 +       /*
24999 +        * Now that we are on the ksp we can leave the critical section
25000 +        */
25001 +       atomic_lock_release
25002 +
25003 +       /*
25004 +        * We need to save a0 because we need to be able to restore it in
25005 +        * the event that we need to handle a signal.  It's not generally
25006 +        * a callee-saved register but is the GOT pointer.
25007 +        */
25008 +       move.4  PT_A0(sp), a0                   ; Save A0 on kernel stack
25009 +
25010 +       /*
25011 +        * We still need to save d10-d13, a1, a2, a5, a6 in the kernel frame
25012 +        * for this process, we also save the system call params in the case of
25013 +        * syscall restart. (note a7 was saved above)
25014 +        */
25015 +       move.4  PT_A1(sp), a1                   ; Save A1 on kernel stack
25016 +       move.4  PT_A2(sp), a2                   ; Save A2 on kernel stack
25017 +       move.4  PT_A5(sp), a5                   ; Save A5 on kernel stack
25018 +       move.4  PT_A6(sp), a6                   ; Save A6 on kernel stack
25019 +       move.4  PT_PC(sp), a5                   ; Save A5 at the PC location
25020 +       move.4  PT_D10(sp), d10                 ; Save D10 on kernel stack
25021 +       move.4  PT_D11(sp), d11                 ; Save D11 on kernel stack
25022 +       move.4  PT_D12(sp), d12                 ; Save D12 on kernel stack
25023 +       move.4  PT_D13(sp), d13                 ; Save D13 on kernel stack
25024 +
25025 +       /*
25026 +        * Now save the syscall parameters
25027 +        */
25028 +       move.4  PT_D0(sp), d0                   ; Save d0 on kernel stack
25029 +       move.4  PT_ORIGINAL_D0(sp), d0          ; Save d0 on kernel stack
25030 +       move.4  PT_D1(sp), d1                   ; Save d1 on kernel stack
25031 +       move.4  PT_D2(sp), d2                   ; Save d2 on kernel stack
25032 +       move.4  PT_D3(sp), d3                   ; Save d3 on kernel stack
25033 +       move.4  PT_D4(sp), d4                   ; Save d4 on kernel stack
25034 +       move.4  PT_D5(sp), d5                   ; Save d5 on kernel stack
25035 +       /* add this back if we ever have a syscall with 7 args */
25036 +       move.4  PT_D8(sp), d8                   ; Save d8 on kernel stack
25037 +
25038 +       /*
25039 +        * Test if syscalls are being traced and if they are jump to syscall
25040 +        * trace (it will comeback here)
25041 +        */
25042 +       btst    TI_FLAGS(a3), #ASM_TIF_SYSCALL_TRACE
25043 +       jmpne.f .Lsystem_call__trace
25044 +.Lsystem_call__trace_complete:
25045 +       /*
25046 +        * Check for a valid call number [ 0 <= syscall_number < NR_syscalls ]
25047 +        */
25048 +       cmpi    d8, #0
25049 +       jmplt.f 3f
25050 +       cmpi    d8, #NR_syscalls
25051 +       jmplt.t 4f
25052 +
25053 +       /*
25054 +        * They have passed an invalid number. Call sys_ni_syscall staring by
25055 +        * load a4 with the base address of sys_ni_syscall
25056 +        */
25057 +3:     moveai  a4, #%hi(sys_ni_syscall)
25058 +       lea.1   a4, %lo(sys_ni_syscall)(a4)
25059 +       jmpt.t  5f                              ; Jump to regular processing
25060 +
25061 +       /*
25062 +        * Validated syscall, load the syscall table base address into a3 and
25063 +        * read the syscall ptr out.
25064 +        */
25065 +4:     moveai  a3, #%hi(sys_call_table)
25066 +       lea.1   a3, %lo(sys_call_table)(a3)     ; a3 = sys_call_table
25067 +       move.4  a4, (a3, d8)                    ; a4 = sys_call_table[d8]
25068 +
25069 +       /*
25070 +        * Before calling the syscall, setup a5 so that syscall_exit is called
25071 +        * on return from syscall
25072 +        */
25073 +5:     moveai  a5, #%hi(syscall_exit)          ; Setup return address
25074 +       lea.1   a5, %lo(syscall_exit)(a5)       ; from system call
25075 +
25076 +       /*
25077 +        * If the syscall is __NR_rt_rigreturn then we have to test d1 to
25078 +        * figure out if we have to change change the return routine to restore
25079 +        * all registers.
25080 +        */
25081 +       cmpi    d8, #__NR_rt_sigreturn
25082 +       jmpeq.f 6f
25083 +
25084 +       /*
25085 +        * Launch system call (it will return through a5 - syscall_exit)
25086 +        */
25087 +       calli   a3, 0(a4)
25088 +
25089 +       /*
25090 +        * System call is rt_sigreturn. Test d1. If it is 1 we have to
25091 +        * change the return address to restore_all_registers
25092 +        */
25093 +6:     cmpi    d1, #1
25094 +       jmpne.t 7f
25095 +
25096 +       moveai  a5, #%hi(restore_all_registers)  ; Setup return address
25097 +       lea.1   a5, %lo(restore_all_registers)(a5) ; to restore_all_registers.
25098 +
25099 +       /*
25100 +        * Launch system call  (it will return through a5)
25101 +        */
25102 +7:     calli   a3, 0(a4)                        ; Launch system call
25103 +
25104 +.Lsystem_call__trace:
25105 +       /*
25106 +        * Syscalls are being traced.
25107 +        * Call syscall_trace, (return here)
25108 +        */
25109 +       moveai  a4, #%hi(syscall_trace)
25110 +       calli   a5, %lo(syscall_trace)(a4)
25111 +
25112 +       /*
25113 +        * Restore syscall state (it would have been discarded during the
25114 +        * syscall trace)
25115 +        */
25116 +       move.4  d0, PT_D0(sp)                   ; Restore d0 from kernel stack
25117 +       move.4  d1, PT_D1(sp)                   ; Restore d1 from kernel stack
25118 +       move.4  d2, PT_D2(sp)                   ; Restore d2 from kernel stack
25119 +       move.4  d3, PT_D3(sp)                   ; Restore d3 from kernel stack
25120 +       move.4  d4, PT_D4(sp)                   ; Restore d4 from kernel stack
25121 +       move.4  d5, PT_D5(sp)                   ; Restore d5 from kernel stack
25122 +       /* add this back if we ever have a syscall with 7 args */
25123 +       move.4  d8, PT_D8(sp)                   ; Restore d8 from kernel stack
25124 +
25125 +       /*
25126 +        * return to syscall
25127 +        */
25128 +       jmpt.t .Lsystem_call__trace_complete
25129 +       .size system_call, . - system_call
25130 +
25131 +/*
25132 + * syscall_exit()
25133 + */
25134 +       .section .syscall_exit.text
25135 +       .global syscall_exit
25136 +syscall_exit:
25137 +       /*
25138 +        * d0 contains the return value. We should move that into the kernel
25139 +        * stack d0 location.  We will be transitioning from kernel to user
25140 +        * mode. Test the flags and see if we have to call schedule. If we are
25141 +        * going to truly exit then all that has to be done is that from the
25142 +        * kernel stack we have to restore d0, a0, a1, a2, a5, a6 and sp (a7)bb
25143 +        * and then return via a5.
25144 +        */
25145 +
25146 +       /*
25147 +        * Save d0 to pt_regs
25148 +        */
25149 +       move.4  PT_D0(sp), d0                   ; Save d0 into the kernel stack
25150 +
25151 +       /*
25152 +        * load the thread_info structure by masking off the THREAD_SIZE
25153 +        * bits.
25154 +        *
25155 +        * Note: we used to push a1, but now we don't as we are going
25156 +        * to eventually restore it to the userspace a1.
25157 +        */
25158 +       movei   d9, #(~(ASM_THREAD_SIZE-1))
25159 +       and.4   a1, sp, d9
25160 +
25161 +       /*
25162 +        * Are any interesting bits set on TI flags, if there are jump
25163 +        * aside to post_processing.
25164 +        */
25165 +       move.4  d9, #(_TIF_SYSCALL_TRACE | _TIF_NEED_RESCHED | _TIF_SIGPENDING)
25166 +       and.4   #0, TI_FLAGS(a1), d9
25167 +       jmpne.f .Lsyscall_exit__post_processing ; jump to handler
25168 +.Lsyscall_exit__post_processing_complete:
25169 +
25170 +       move.4  d0, PT_D0(sp)                   ; Restore D0 from kernel stack
25171 +       move.4  d1, PT_D1(sp)                   ; Restore d1 from kernel stack
25172 +       move.4  d2, PT_D2(sp)                   ; Restore d2 from kernel stack
25173 +       move.4  d3, PT_D3(sp)                   ; Restore d3 from kernel stack
25174 +       move.4  d4, PT_D4(sp)                   ; Restore d4 from kernel stack
25175 +       move.4  d5, PT_D5(sp)                   ; Restore d5 from kernel stack
25176 +       move.4  d8, PT_D8(sp)                   ; Restore d8 from kernel stack
25177 +       move.4  d10, PT_D10(sp)                 ; Restore d10 from kernel stack
25178 +       move.4  d11, PT_D11(sp)                 ; Restore d11 from kernel stack
25179 +       move.4  d12, PT_D12(sp)                 ; Restore d12 from kernel stack
25180 +       move.4  d13, PT_D13(sp)                 ; Restore d13 from kernel stack
25181 +       move.4  a1, PT_A1(sp)                   ; Restore A1 from kernel stack
25182 +       move.4  a2, PT_A2(sp)                   ; Restore A2 from kernel stack
25183 +       move.4  a5, PT_A5(sp)                   ; Restore A5 from kernel stack
25184 +       move.4  a6, PT_A6(sp)                   ; Restore A6 from kernel stack
25185 +       move.4  a0, PT_A0(sp)                   ; Restore A6 from kernel stack
25186 +
25187 +       /*
25188 +        * this is only for debug, and could be removed for production builds
25189 +        */
25190 +       move.4  PT_FRAME_TYPE(sp), #0           ; invalidate frame_type
25191 +
25192 +#ifdef CONFIG_PROTECT_KERNEL
25193 +       /*
25194 +        * Enter critical section
25195 +        */
25196 +       atomic_lock_acquire
25197 +       disable_kernel_ranges_for_current d15
25198 +#endif
25199 +       /*
25200 +        * Lastly restore userspace stack ptr
25201 +        *
25202 +        * Note: that when protection is on we need to hold the lock around the
25203 +        * stack swap as well because otherwise the protection could get
25204 +        * inadvertently disabled again at the end of a context switch.
25205 +        */
25206 +       move.4  a7, PT_A7(sp)                   ; Restore A7 from kernel stack
25207 +
25208 +       /*
25209 +        * We are now officially back in userspace!
25210 +        */
25211 +
25212 +#ifdef CONFIG_PROTECT_KERNEL
25213 +       /*
25214 +        * Leave critical section and return to user space.
25215 +        */
25216 +       atomic_lock_release
25217 +#endif
25218 +       calli   a5, 0(a5)                       ; Back to userspace code.
25219 +
25220 +       bkpt #-1                                ; we will never get here
25221 +
25222 +       /*
25223 +        * Post syscall processing. (unlikely part of syscall_exit)
25224 +        *
25225 +        * Are we tracing syscalls. If TIF_SYSCALL_TRACE is set, call
25226 +        * syscall_trace routine and return here.
25227 +        */
25228 +.Lsyscall_exit__post_processing:
25229 +       btst    TI_FLAGS(a1), #ASM_TIF_SYSCALL_TRACE
25230 +       jmpeq.t 1f
25231 +       moveai  a5, #%hi(syscall_trace)
25232 +       calli   a5, %lo(syscall_trace)(a5)
25233 +
25234 +       /*
25235 +        * Do we need to resched ie call schedule. If TIF_NEED_RESCHED is set,
25236 +        * call the scheduler, it will come back here.
25237 +        */
25238 +1:     btst    TI_FLAGS(a1), #ASM_TIF_NEED_RESCHED
25239 +       jmpeq.t 2f
25240 +       moveai  a5, #%hi(schedule)
25241 +       calli   a5, %lo(schedule)(a5)
25242 +
25243 +       /*
25244 +        * Do we need to post a signal, if TIF_SIGPENDING is set call the
25245 +        * do_signal.
25246 +        */
25247 +2:     btst    TI_FLAGS(a1), #ASM_TIF_SIGPENDING
25248 +       jmpeq.t .Lsyscall_exit__post_processing_complete
25249 +
25250 +       /*
25251 +        * setup the do signal call
25252 +        */
25253 +       move.4  d0, #0                          ; oldset pointer is NULL
25254 +       lea.1   d1, (sp)                        ; d1 is the regs pointer.
25255 +       moveai  a5, #%hi(do_signal)             ; Have to call do_signal
25256 +       calli   a5, %lo(do_signal)(a5)
25257 +
25258 +       jmpt.t  .Lsyscall_exit__post_processing_complete
25259 +
25260 +       .size syscall_exit, . - syscall_exit
25261 +
25262 +/*
25263 + * kernel_execve()
25264 + *     kernel_execv is called when we the kernel is starting a
25265 + *     userspace application.
25266 + */
25267 +       .section .kernel_unprotected
25268 +       .global kernel_execve
25269 +kernel_execve:
25270 +       move.4  -4(sp)++, a5                    ; Save return address
25271 +       /*
25272 +        * Call execve
25273 +        */
25274 +       movei   d8, #__NR_execve                ; call execve
25275 +       moveai  a3, #%hi(system_call)
25276 +       calli   a5, %lo(system_call)(a3)
25277 +       move.4  a5, (sp)4++
25278 +
25279 +       /*
25280 +        * protection was enabled again at syscall exit, but we want
25281 +        * to return to kernel so we enable it again.
25282 +        */
25283 +#ifdef CONFIG_PROTECT_KERNEL
25284 +       /*
25285 +        * We are entering the kernel so we need to disable the protection.
25286 +        * Enter critical section, disable ranges and leave critical section.
25287 +        */
25288 +       atomic_lock_acquire                     ; Enter critical section
25289 +       enable_kernel_ranges_for_current d15
25290 +       atomic_lock_release                     ; Leave critical section
25291 +#endif
25292 +       ret a5                                  ; jump back to the kernel
25293 +
25294 +       .size kernel_execve, . - kernel_execve
25295 +
25296 +/*
25297 + * signal_trampoline()
25298 + *
25299 + *     Deals with transitioning from to userspace signal handlers and returning
25300 + *     to userspace, only called from the kernel.
25301 + *
25302 + */
25303 +       .section .kernel_unprotected
25304 +       .global signal_trampoline
25305 +signal_trampoline:
25306 +       /*
25307 +        * signal_trampoline is called when we are jumping from the kernel to
25308 +        * the userspace signal handler.
25309 +        *
25310 +        * The following registers are relevant. (set setup_rt_frame)
25311 +        *   sp is the user space stack not the kernel stack
25312 +        *  d0 = signal number
25313 +        *  d1 = siginfo_t *
25314 +        *  d2 = ucontext *
25315 +        *  d3 = the user space signal handler
25316 +        *  a0 is set to the GOT if userspace application is FDPIC, otherwise 0
25317 +        *  a3 is set to the FD for the signal if userspace application is FDPIC
25318 +        */
25319 +#ifdef CONFIG_PROTECT_KERNEL
25320 +       /*
25321 +        * We are leaving the kernel so we need to enable the protection.
25322 +        * Enter critical section, disable ranges and leave critical section.
25323 +        */
25324 +       atomic_lock_acquire                     ; Enter critical section
25325 +       disable_kernel_ranges_for_current d15   ; disable kernel ranges
25326 +       atomic_lock_release                     ; Leave critical section
25327 +#endif
25328 +       /*
25329 +        * The signal handler pointer is in register d3 so tranfer it to a4 and
25330 +        * call it
25331 +        */
25332 +       movea   a4, d3                          ; signal handler
25333 +       calli   a5, 0(a4)
25334 +
25335 +       /*
25336 +        * Return to userspace through rt_syscall which is stored on top of the
25337 +        * stack d1 contains ret_via_interrupt status.
25338 +        */
25339 +       move.4  d8, (sp)                        ; d8 (syscall #) = rt_syscall
25340 +       move.4  d1, 4(sp)                       ; d1 = ret_via_interrupt
25341 +       moveai  a3, #%hi(system_call)           ; call system_call
25342 +       calli   a5, %lo(system_call)(a3)
25343 +
25344 +       bkpt -1                                 ; will never get here.
25345 +       .size signal_trampoline, . - signal_trampoline
25346 +
25347 +/*
25348 + * kernel_thread_helper()
25349 + *
25350 + *     Entry point for kernel threads (only referenced by kernel_thread()).
25351 + *
25352 + *     On execution d0 will be 0, d1 will be the argument to be passed to the
25353 + *     kernel function.
25354 + *     d2 contains the kernel function that needs to get called.
25355 + *     d3 will contain address to do_exit which needs to get moved into a5.
25356 + *
25357 + *     On return from fork the child thread d0 will be 0. We call this dummy
25358 + *     function which in turn loads the argument
25359 + */
25360 +       .section .kernel_unprotected
25361 +       .global kernel_thread_helper
25362 +kernel_thread_helper:
25363 +       /*
25364 +        * Create a kernel thread. This is called from ret_from_vfork (a
25365 +        * userspace return routine) so we need to put it in an unprotected
25366 +        * section and re-enable protection before calling the vector in d2.
25367 +        */
25368 +
25369 +#ifdef CONFIG_PROTECT_KERNEL
25370 +       /*
25371 +        * We are entering the kernel so we need to disable the protection.
25372 +        * Enter critical section, disable ranges and leave critical section.
25373 +        */
25374 +       atomic_lock_acquire                     ; Enter critical section
25375 +       enable_kernel_ranges_for_current d0
25376 +       atomic_lock_release                     ; Leave critical section
25377 +#endif
25378 +       /*
25379 +        * Move argument for kernel function into d0, and set a5 return address
25380 +        * (a5) to do_exit and return through a2
25381 +        */
25382 +       move.4  d0, d1                          ; d0 = arg
25383 +       move.4  a5, d3                          ; a5 = do_exit
25384 +       ret     d2                              ; call function ptr in d2
25385 +
25386 +       .size kernel_thread_helper, . - kernel_thread_helper
25387 +
25388 +/*
25389 + * execve_intercept()
25390 + */
25391 +       .section .text
25392 +       .global execve_intercept
25393 +execve_intercept:
25394 +       move.4  d3, sp  ; Save retrun address
25395 +       moveai  a3, #%hi(sys_execve)
25396 +       calli   a3, %lo(sys_execve)(a3)
25397 +
25398 +       .size execve_intercept, . - execve_intercept
25399 +
25400 +/*
25401 + * vfork_intercept()
25402 + */
25403 +       .section .text
25404 +       .global vfork_intercept
25405 +vfork_intercept:
25406 +       move.4  d0, sp  ; Save pt_regs address
25407 +       moveai  a3, #%hi(sys_vfork)
25408 +       calli   a3, %lo(sys_vfork)(a3)
25409 +
25410 +       .size vfork_intercept, . - vfork_intercept
25411 +
25412 +/*
25413 + * clone_intercept()
25414 + */
25415 +       .section .text
25416 +       .global clone_intercept
25417 +clone_intercept:
25418 +       move.4  d2, sp  ; Save pt_regs address
25419 +       moveai  a3, #%hi(sys_clone)
25420 +       calli   a3, %lo(sys_clone)(a3)
25421 +
25422 +       .size clone_intercept, . - clone_intercept
25423 +
25424 +/*
25425 + * sys_sigsuspend()
25426 + */
25427 +       .section .text
25428 +       .global sys_sigsuspend
25429 +sys_sigsuspend:
25430 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25431 +       moveai  a3, #%hi(do_sigsuspend)
25432 +       calli   a3, %lo(do_sigsuspend)(a3)
25433 +
25434 +       .size sys_sigsuspend, . - sys_sigsuspend
25435 +
25436 +/*
25437 + * sys_rt_sigsuspend()
25438 + */
25439 +       .section .text
25440 +       .global sys_rt_sigsuspend
25441 +sys_rt_sigsuspend:
25442 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25443 +       moveai  a3, #%hi(do_rt_sigsuspend)
25444 +       calli   a3, %lo(do_rt_sigsuspend)(a3)
25445 +
25446 +       .size sys_rt_sigsuspend, . - sys_rt_sigsuspend
25447 +
25448 +/*
25449 + * sys_rt_sigreturn()
25450 + */
25451 +       .section .text
25452 +       .global sys_rt_sigreturn
25453 +sys_rt_sigreturn:
25454 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25455 +       moveai  a3, #%hi(do_rt_sigreturn)
25456 +       calli   a3, %lo(do_rt_sigreturn)(a3)
25457 +
25458 +       .size sys_rt_sigreturn, . - sys_rt_sigreturn
25459 +
25460 +/*
25461 + * sys_sigaltstack()
25462 + */
25463 +       .section .text
25464 +       .global sys_sigaltstack
25465 +sys_sigaltstack:
25466 +       move.4  d0, sp  ; Pass pointer to pt_regs in d0
25467 +       moveai  a3, #%hi(do_sys_sigaltstack)
25468 +       calli   a3, %lo(do_sys_sigaltstack)(a3)
25469 +
25470 +       .size sys_sigaltstack, . - sys_sigaltstack
25471 --- /dev/null
25472 +++ b/arch/ubicom32/kernel/unaligned_trap.c
25473 @@ -0,0 +1,698 @@
25474 +/*
25475 + * arch/ubicom32/kernel/unaligned_trap.c
25476 + *   Handle unaligned traps in both user or kernel space.
25477 + *
25478 + * (C) Copyright 2009, Ubicom, Inc.
25479 + *
25480 + * This file is part of the Ubicom32 Linux Kernel Port.
25481 + *
25482 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
25483 + * it and/or modify it under the terms of the GNU General Public License
25484 + * as published by the Free Software Foundation, either version 2 of the
25485 + * License, or (at your option) any later version.
25486 + *
25487 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
25488 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
25489 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
25490 + * the GNU General Public License for more details.
25491 + *
25492 + * You should have received a copy of the GNU General Public License
25493 + * along with the Ubicom32 Linux Kernel Port.  If not,
25494 + * see <http://www.gnu.org/licenses/>.
25495 + *
25496 + * Ubicom32 implementation derived from (with many thanks):
25497 + *   arch/m68knommu
25498 + *   arch/blackfin
25499 + *   arch/parisc
25500 + */
25501 +
25502 +#include <linux/types.h>
25503 +#include <linux/kernel.h>
25504 +#include <asm/cacheflush.h>
25505 +#include <asm/traps.h>
25506 +
25507 +#define FALSE 0
25508 +#define TRUE 1
25509 +
25510 +/* no possible trap */
25511 +#define UNUSED 0
25512 +/* possible source operand trap */
25513 +#define SRC 1
25514 +#define SRC_2 2
25515 +/* possible destination operand trap */
25516 +#define DEST 3
25517 +#define DEST_2 4
25518 +/* can be either source or destination or both */
25519 +#define TWO_OP 5
25520 +#define TWO_OP_2 6
25521 +
25522 +/* TODO: What is the real value here, put something in to make it compile for
25523 + * now */
25524 +#define MOVE_2 0x0d
25525 +#define LSL_2  0x11
25526 +#define LSR_2  0x13
25527 +#define MOVEI  0x19
25528 +#define CMPI   0x18
25529 +
25530 +static int op_format[32] =
25531 +{
25532 +       TWO_OP,         /* 0x00 */
25533 +       UNUSED,
25534 +       SRC,
25535 +       UNUSED,
25536 +       TWO_OP,         /* 0x04 */
25537 +       TWO_OP,
25538 +       SRC,
25539 +       UNUSED,
25540 +       TWO_OP_2,       /* 0x08 */
25541 +       TWO_OP,
25542 +       TWO_OP_2,
25543 +       TWO_OP,
25544 +       TWO_OP_2,       /* 0x0C */
25545 +       TWO_OP,
25546 +       TWO_OP_2,
25547 +       TWO_OP,
25548 +       TWO_OP,         /* 0x10 */
25549 +       TWO_OP_2,
25550 +       TWO_OP,
25551 +       TWO_OP,
25552 +       UNUSED,         /* 0x14 */
25553 +       UNUSED,
25554 +       UNUSED,
25555 +       UNUSED,
25556 +       SRC_2,          /* 0x18 */
25557 +       DEST_2,
25558 +       UNUSED,
25559 +       UNUSED,
25560 +       UNUSED,         /* 0x1C */
25561 +       UNUSED,
25562 +       UNUSED,         /* unaligned CALLI will not be fixed. */
25563 +       UNUSED
25564 +};
25565 +
25566 +static int op_0_format[32] =
25567 +{
25568 +       UNUSED,         /* 0x00 */
25569 +       UNUSED,
25570 +       UNUSED,
25571 +       UNUSED,
25572 +       UNUSED,         /* 0x04 - ret don't fix - bad ret is always wrong */
25573 +       UNUSED,
25574 +       UNUSED,
25575 +       UNUSED,
25576 +       UNUSED,         /* 0x08 */
25577 +       UNUSED,
25578 +       TWO_OP,
25579 +       TWO_OP_2,
25580 +       TWO_OP,         /* 0x0c */
25581 +       TWO_OP_2,
25582 +       TWO_OP,
25583 +       UNUSED,         /* .1 can't trap */
25584 +       UNUSED,         /* 0x10 */
25585 +       UNUSED,
25586 +       SRC,
25587 +       UNUSED,
25588 +       UNUSED,         /* 0x14 */
25589 +       TWO_OP_2,
25590 +       UNUSED,
25591 +       UNUSED,
25592 +       UNUSED,         /* 0x18 */
25593 +       UNUSED,
25594 +       UNUSED,
25595 +       UNUSED,
25596 +       DEST,           /* 0x1c */
25597 +       DEST,
25598 +       DEST,
25599 +       DEST,           /* all lea have 32-bit destination */
25600 +};
25601 +
25602 +static int op_2_format[32] =
25603 +{
25604 +       UNUSED,         /* 0x00 */
25605 +       UNUSED,
25606 +       UNUSED,
25607 +       UNUSED,
25608 +       UNUSED,         /* 0x04 */
25609 +       UNUSED,
25610 +       SRC,
25611 +       UNUSED,
25612 +       UNUSED,         /* 0x08 crcgen is .1 */
25613 +       UNUSED,
25614 +       UNUSED,
25615 +       UNUSED,
25616 +       UNUSED,         /* 0x0c */
25617 +       UNUSED,
25618 +       UNUSED,
25619 +       UNUSED,
25620 +       SRC,            /* 0x10 */
25621 +       SRC_2,
25622 +       SRC,
25623 +       SRC_2,
25624 +       SRC,            /* 0x14 */
25625 +       SRC_2,
25626 +       SRC,
25627 +       UNUSED,
25628 +       UNUSED,         /* 0x18 */
25629 +       UNUSED,
25630 +       SRC,
25631 +       UNUSED,
25632 +       SRC,            /* 0x1c */
25633 +       UNUSED,
25634 +       SRC_2,
25635 +       UNUSED,
25636 +};
25637 +
25638 +static int op_6_format[32] =
25639 +{
25640 +       SRC_2,          /* 0x00 */
25641 +       SRC_2,
25642 +       SRC_2,
25643 +       SRC_2,
25644 +       SRC_2,          /* 0x04 */
25645 +       SRC_2,
25646 +       UNUSED,
25647 +       SRC_2,
25648 +       SRC,            /* 0x08 MULS.4 */
25649 +       SRC_2,
25650 +       SRC,
25651 +       UNUSED,
25652 +       UNUSED,         /* 0x0c */
25653 +       UNUSED,
25654 +       UNUSED,
25655 +       UNUSED,
25656 +       SRC,            /* 0x10 */
25657 +       SRC_2,
25658 +       SRC,
25659 +       SRC_2,
25660 +       UNUSED,         /* 0x14 */
25661 +       UNUSED,
25662 +       UNUSED,
25663 +       UNUSED,
25664 +       UNUSED,         /* 0x18 */
25665 +       UNUSED,
25666 +       UNUSED,
25667 +       UNUSED,
25668 +       UNUSED,         /* 0x1c */
25669 +       UNUSED,
25670 +       UNUSED,
25671 +       UNUSED,
25672 +};
25673 +
25674 +/*
25675 + * unaligned_get_address()
25676 + *     get an address using save_an and save_dn registers, and updates save_an
25677 + *     with side effects
25678 + */
25679 +unsigned char *unaligned_get_address(int thread, int specifier, int four_byte,
25680 +                                    unsigned int save_an[],
25681 +                                    unsigned int save_dn[], int *write_back_an)
25682 +{
25683 +       unsigned char *address;
25684 +
25685 +       int areg = (specifier >> 5) & 7;
25686 +       if ((specifier >> 8) == 2) {
25687 +               int offset = specifier & 0xf;
25688 +               offset = ((offset << 28) >> 28);
25689 +               if (likely(four_byte)) {
25690 +                       offset <<= 2;
25691 +               } else {
25692 +                       offset <<= 1;
25693 +               }
25694 +               if (specifier & 0x10) {
25695 +                       address = (unsigned char *)(save_an[areg] + offset);
25696 +               } else {
25697 +                       address = (unsigned char *)save_an[areg];
25698 +               }
25699 +               save_an[areg] = save_an[areg] + offset;
25700 +
25701 +               /*
25702 +                * Let caller know An registers have been modified.
25703 +                */
25704 +               *write_back_an = 1;
25705 +       } else if ((specifier >> 8) == 3) {
25706 +               int dreg = specifier & 0xf;
25707 +               if (likely(four_byte)) {
25708 +                       address = (unsigned char *)(save_an[areg] +
25709 +                                                   (save_dn[dreg] << 2));
25710 +               } else {
25711 +                       address = (unsigned char *)(save_an[areg] +
25712 +                                                   (save_dn[dreg] << 1));
25713 +               }
25714 +       } else {
25715 +               int offset = ((specifier >> 3) & 0x60) | (specifier & 0x1f);
25716 +               if (likely(four_byte)) {
25717 +                       address = (unsigned char *)(save_an[areg] +
25718 +                                                   (offset << 2));
25719 +               } else {
25720 +                       address = (unsigned char *)(save_an[areg] +
25721 +                                                   (offset << 1));
25722 +               }
25723 +       }
25724 +
25725 +       return address;
25726 +}
25727 +
25728 +static int save_dn[16];
25729 +static int save_an[8];
25730 +static int save_acc[5];
25731 +
25732 +/*
25733 + * unaligned_emulate()
25734 + *     emulate the instruction at thread's pc that has taken an unaligned data
25735 + *     trap.
25736 + *
25737 + * source or destination or both might be unaligned
25738 + * the instruction must have a memory source or destination or both
25739 + * the emulated instruction is copied and executed in this thread
25740 + *
25741 + *     TODO: Protection is handled outside of this function
25742 + *     TODO: handling simultaneous unaligned and memory protection traps
25743 + *
25744 + *     Get thread state
25745 + *             the PC and instruction (and local copy, emulate_inst), and An
25746 + *             and Dn registers
25747 + *             All implicit soruce state (source3, CSR, accumulators)
25748 +
25749 + *     if the instruction has a memory source
25750 + *             Use the instruction, An and Dn registers to form src_address
25751 + *             get unaligned source data from src_address (usually sign
25752 + *             extended)
25753 + *                     (2 bytes, with or without sign extension, or 4 bytes)
25754 + *             modify emulate_inst to use d0 as source
25755 + *     else
25756 + *             get the soure operand from one of thread's registers
25757 + *     if instruction has a memory destination
25758 + *             Use the instruction, An and Dn registers to form dest_address
25759 + *             modify emulate_inst to use d0 as destination
25760 + *     if there was a memory source
25761 + *             put the source data in thread's d0
25762 + *     get the source-2 Dn operand and source 3 operand from thread
25763 + *     execute modified inst
25764 + *             (save it, flush caches, set up local values for implicit
25765 + *             sources, execute, save explicit and implicit results)
25766 + *     if inst has destination address
25767 + *             copy result to dest_address, possibly unaligned, 1, 2, or 4
25768 + *             bytes
25769 + *     restore thread's implicit results (modified address registers, CSR,
25770 + *     accumulators) add 4 to thread's pc
25771 + */
25772 +void unaligned_emulate(unsigned int thread)
25773 +{
25774 +       unsigned int pc;
25775 +       unsigned int inst;
25776 +       unsigned int op;
25777 +       unsigned int subop;
25778 +       int format;
25779 +       unsigned int emulate_inst;
25780 +       int four_byte;
25781 +       int src_operand, dest_operand;
25782 +       int save_csr;
25783 +       int source3;
25784 +       unsigned int source1;
25785 +       unsigned int source_data;
25786 +       unsigned char *dest_address = NULL;
25787 +       int source2 = 0;
25788 +       unsigned int result;
25789 +       unsigned int write_back_an = 0;
25790 +       unsigned int chip_id_copy;
25791 +
25792 +       extern unsigned int trap_emulate;
25793 +       extern unsigned int ubicom32_emulate_insn(int source1, int source2,
25794 +                                                 int source3, int *save_acc,
25795 +                                                 int *save_csr);
25796 +
25797 +       /*
25798 +        * get the chip_id
25799 +        */
25800 +       asm volatile (
25801 +       "       move.4          %0, chip_id             \n\t" /* get chip_id. */
25802 +               : "=r"(chip_id_copy)
25803 +               :
25804 +       );
25805 +
25806 +       /*
25807 +        * get the pc
25808 +        */
25809 +       asm volatile (
25810 +       "       move.4          CSR, %1         \n\t" /* set source thread in
25811 +                                                      * CSR */
25812 +       "       setcsr_flush    0               \n\t"
25813 +       "       move.4          %0, pc          \n\t"
25814 +       "       move.4          CSR, #0         \n\t" /* restore CSR */
25815 +       "       setcsr_flush    0               \n\t"
25816 +               : "=a"(pc)
25817 +               : "d" ((1 << 8) | (thread << 9))
25818 +               : "cc"
25819 +       );
25820 +
25821 +       inst = *((unsigned int *)pc);
25822 +       op = inst >> 27;
25823 +       if (unlikely(op == 2 || op == 6)) {
25824 +               subop = (inst >> 21) & 0x1f;
25825 +       } else {
25826 +               subop = (inst >> 11) & 0x1f;
25827 +       }
25828 +       format = op_format[op];
25829 +       emulate_inst = inst;
25830 +
25831 +       if (op == 0) {
25832 +               format = op_0_format[subop];
25833 +       } else if (op == 2) {
25834 +               format = op_2_format[subop];
25835 +       } else if (op == 6) {
25836 +               format = op_6_format[subop];
25837 +       }
25838 +
25839 +       if (unlikely(format == UNUSED)) {
25840 +               /*
25841 +                * We are not going to emulate this. Bump PC by 4 and move on.
25842 +                */
25843 +               asm volatile (
25844 +               "       move.4          CSR, %0                 \n\t"
25845 +               "       setcsr_flush    0                       \n\t"
25846 +               "       move.4          pc, %1                  \n\t"
25847 +               "       setcsr          #0                      \n\t"
25848 +               "       setcsr_flush    0                       \n\t"
25849 +                       :
25850 +                       : "d"((1 << 14) | (thread << 15)), "d"(pc + 4)
25851 +                       : "cc"
25852 +               );
25853 +               return;
25854 +       }
25855 +
25856 +       four_byte = (format == TWO_OP || format == DEST || format == SRC);
25857 +
25858 +       /*
25859 +        * source or destination memory operand needs emulation
25860 +        */
25861 +       src_operand = (format == SRC ||
25862 +                      format == SRC_2 ||
25863 +                      format == TWO_OP ||
25864 +                      format == TWO_OP_2) &&
25865 +               ((inst >> 8) & 7) > 1;
25866 +
25867 +       dest_operand = (format == DEST ||
25868 +                       format == DEST_2 ||
25869 +                       format == TWO_OP ||
25870 +                       format == TWO_OP_2) &&
25871 +               ((inst >> 24) & 7) > 1;
25872 +
25873 +       /*
25874 +        * get thread's implicit sources (not covered by source context select).
25875 +        * data and address registers and CSR (for flag bits) and src3 and
25876 +        * accumulators
25877 +        */
25878 +       asm volatile (
25879 +       "       move.4          CSR, %2         \n\t"   /* set source thread in
25880 +                                                        * CSR */
25881 +       "       setcsr_flush    0               \n\t"
25882 +       "       move.4          (%3), d0        \n\t"   /* get dn registers */
25883 +       "       move.4          4(%3), d1       \n\t"
25884 +       "       move.4          8(%3), d2       \n\t"
25885 +       "       move.4          12(%3), d3      \n\t"
25886 +       "       move.4          16(%3), d4      \n\t"
25887 +       "       move.4          20(%3), d5      \n\t"
25888 +       "       move.4          24(%3), d6      \n\t"
25889 +       "       move.4          28(%3), d7      \n\t"
25890 +       "       move.4          32(%3), d8      \n\t"
25891 +       "       move.4          36(%3), d9      \n\t"
25892 +       "       move.4          40(%3), d10     \n\t"
25893 +       "       move.4          44(%3), d11     \n\t"
25894 +       "       move.4          48(%3), d12     \n\t"
25895 +       "       move.4          52(%3), d13     \n\t"
25896 +       "       move.4          56(%3), d14     \n\t"
25897 +       "       move.4          60(%3), d15     \n\t"
25898 +       "       move.4          (%4), a0        \n\t"   /* get an registers */
25899 +       "       move.4          4(%4), a1       \n\t"
25900 +       "       move.4          8(%4), a2       \n\t"
25901 +       "       move.4          12(%4), a3      \n\t"
25902 +       "       move.4          16(%4), a4      \n\t"
25903 +       "       move.4          20(%4), a5      \n\t"
25904 +       "       move.4          24(%4), a6      \n\t"
25905 +       "       move.4          28(%4), a7      \n\t"
25906 +       "       move.4          %0, CSR         \n\t"   /* get csr and source3
25907 +                                                        * implicit operands */
25908 +       "       move.4          %1, source3     \n\t"
25909 +       "       move.4          (%5), acc0_lo   \n\t"   /* get accumulators */
25910 +       "       move.4          4(%5), acc0_hi  \n\t"
25911 +       "       move.4          8(%5), acc1_lo  \n\t"
25912 +       "       move.4          12(%5), acc1_hi \n\t"
25913 +       "       move.4          16(%5), mac_rc16        \n\t"
25914 +       "       move.4          CSR, #0         \n\t"   /* restore CSR */
25915 +       "       setcsr_flush    0               \n\t"
25916 +               : "=m"(save_csr), "=m"(source3)
25917 +               : "d"((1 << 8) | (thread << 9)),
25918 +                 "a"(save_dn), "a"(save_an), "a"(save_acc)
25919 +               : "cc"
25920 +       );
25921 +
25922 +       /*
25923 +        * turn off thread select bits if they were on
25924 +        */
25925 +       BUG_ON((save_csr & 0x04100) != 0);
25926 +       if (unlikely(save_csr & 0x04100)) {
25927 +               /*
25928 +                * Things are in funny state as thread select bits are on in
25929 +                * csr. PANIC.
25930 +                */
25931 +               panic("In unaligned trap handler. Trap thread CSR has thread "
25932 +                     "select bits on.\n");
25933 +       }
25934 +
25935 +       save_csr = save_csr & 0x1000ff;
25936 +
25937 +       /*
25938 +        * get the source1 operand
25939 +        */
25940 +       source1 = 0;
25941 +       if (src_operand) {
25942 +               unsigned char *src_address;
25943 +
25944 +               /*
25945 +                * source1 comes from memory
25946 +                */
25947 +               BUG_ON(!(format == TWO_OP || format == TWO_OP_2 ||
25948 +                        format == SRC || format == SRC_2));
25949 +               src_address = unaligned_get_address(thread, inst & 0x7ff,
25950 +                                                   four_byte, save_an,
25951 +                                                   save_dn, &write_back_an);
25952 +
25953 +               /*
25954 +                * get data (possibly unaligned)
25955 +                */
25956 +               if (likely(four_byte)) {
25957 +                       source_data = (*src_address << 24) |
25958 +                               (*(src_address + 1) << 16) |
25959 +                               (*(src_address + 2) << 8) |
25960 +                               *(src_address + 3);
25961 +                       source1 = source_data;
25962 +               } else {
25963 +                       source1 = *src_address << 8 |
25964 +                               *(src_address + 1);
25965 +
25966 +                       /*
25967 +                        * Source is not extended if the instrution is MOVE.2 or
25968 +                        * if the cpu CHIP_ID >= 0x30000 and the instruction is
25969 +                        * either LSL.2 or LSR.2.  All other cases have to be
25970 +                        * sign extended.
25971 +                        */
25972 +                       if ((!(op == 2 && subop == MOVE_2)) &&
25973 +                           (!((chip_id_copy >= 0x30000) &&
25974 +                              (subop == LSL_2 || subop == LSR_2)))) {
25975 +                               /*
25976 +                                * Have to sign extend the .2 entry.
25977 +                                */
25978 +                               source1 = ((unsigned int)
25979 +                                          ((signed int)
25980 +                                           ((signed short) source1)));
25981 +                       }
25982 +               }
25983 +       } else if (likely(op != MOVEI)) {
25984 +               /*
25985 +                * source1 comes from a register, using move.4 d0, src1
25986 +                * unaligned_emulate_get_source is pointer to code to insert remulated instruction
25987 +                */
25988 +               extern unsigned int unaligned_emulate_get_src;
25989 +               *((int *)&unaligned_emulate_get_src) &= ~(0x7ff);
25990 +               *((int *)&unaligned_emulate_get_src) |= (inst & 0x7ff);
25991 +               flush_dcache_range((unsigned long)(&unaligned_emulate_get_src),
25992 +                                  (unsigned long)(&unaligned_emulate_get_src) + 4);
25993 +
25994 +               asm volatile (
25995 +                       /* source1 uses thread's registers */
25996 +               "       move.4          CSR, %1                 \n\t"
25997 +               "       setcsr_flush 0                          \n\t"
25998 +               "unaligned_emulate_get_src:                     \n\t"
25999 +               "       move.4  %0, #0                          \n\t"
26000 +               "       setcsr          #0                      \n\t"
26001 +               "       setcsr_flush    0                       \n\t"
26002 +                       : "=d" (source1)
26003 +                       : "d" ((1 << 8) | (thread << 9))
26004 +                       : "cc"
26005 +               );
26006 +       }
26007 +
26008 +       /*
26009 +        * get the destination address
26010 +        */
26011 +       if (dest_operand) {
26012 +               BUG_ON(!(format == TWO_OP || format == TWO_OP_2 ||
26013 +                        format == DEST || format == DEST_2));
26014 +               dest_address = unaligned_get_address(thread,
26015 +                                                    ((inst >> 16) & 0x7ff),
26016 +                                                    four_byte, save_an,
26017 +                                                    save_dn, &write_back_an);
26018 +       }
26019 +
26020 +       if (write_back_an) {
26021 +               /*
26022 +                * restore any modified An registers
26023 +                */
26024 +               asm volatile (
26025 +               "       move.4          CSR, %0                 \n\t"
26026 +               "       setcsr_flush    0                       \n\t"
26027 +               "       move.4          a0, (%1)                \n\t"
26028 +               "       move.4          a1, 4(%1)               \n\t"
26029 +               "       move.4          a2, 8(%1)               \n\t"
26030 +               "       move.4          a3, 12(%1)              \n\t"
26031 +               "       move.4          a4, 16(%1)              \n\t"
26032 +               "       move.4          a5, 20(%1)              \n\t"
26033 +               "       move.4          a6, 24(%1)              \n\t"
26034 +               "       move.4          a7, 28(%1)              \n\t"
26035 +               "       setcsr          #0                      \n\t"
26036 +               "       setcsr_flush    0                       \n\t"
26037 +                       :
26038 +                       : "d" ((1 << 14) | (thread << 15)), "a" (save_an)
26039 +                       : "cc"
26040 +               );
26041 +       }
26042 +
26043 +       /*
26044 +        * get source 2 register if needed, and modify inst to use d1 for
26045 +        * source-2 source-2 will come from this thread, not the trapping thread
26046 +        */
26047 +       source2 = 0;
26048 +       if ((op >= 8 && op <= 0x17) ||
26049 +           ((op == 2 || op == 6) && (inst & 0x4000000))) {
26050 +               int src_dn = (inst >> 11) & 0xf;
26051 +               source2 = save_dn[src_dn];
26052 +               /*
26053 +                * force the emulated instruction to use d1 for source2 operand
26054 +                */
26055 +               emulate_inst = (emulate_inst & 0xffff07ff) | 0x800;
26056 +       }
26057 +
26058 +       if (likely(op != MOVEI)) {
26059 +               /*
26060 +                * change emulated instruction source1 to d0
26061 +                */
26062 +               emulate_inst &= ~0x7ff;
26063 +               emulate_inst |= 1 << 8;
26064 +       }
26065 +
26066 +       if (unlikely(op == 6 || op == 2)) {
26067 +               /*
26068 +                * Set destination to d0
26069 +                */
26070 +               emulate_inst &= ~(0xf << 16);
26071 +       } else if (likely(op != CMPI)) {
26072 +               /*
26073 +                * Set general destination field to d0.
26074 +                */
26075 +               emulate_inst &= ~(0x7ff << 16);
26076 +               emulate_inst |= 1 << 24;
26077 +       }
26078 +
26079 +       /*
26080 +        * execute emulated instruction d0, to d0, no memory access
26081 +        * source2 if needed will be in d1
26082 +        * source3, CSR, and accumulators are set up before execution
26083 +        */
26084 +       *((unsigned int *)&trap_emulate) = emulate_inst;
26085 +       flush_dcache_range((unsigned long)(&trap_emulate),
26086 +                          (unsigned long)(&trap_emulate) + 4);
26087 +
26088 +       result = ubicom32_emulate_insn(source1, source2, source3,
26089 +                                      save_acc, &save_csr);
26090 +
26091 +       /*
26092 +        * set the result value
26093 +        */
26094 +       if (dest_operand) {
26095 +               /*
26096 +                * copy result to memory
26097 +                */
26098 +               if (four_byte) {
26099 +                       *dest_address++ =
26100 +                               (unsigned char)((result >> 24) & 0xff);
26101 +                       *dest_address++ =
26102 +                               (unsigned char)((result >> 16) & 0xff);
26103 +               }
26104 +               *dest_address++ = (unsigned char)((result >> 8) & 0xff);
26105 +               *dest_address = (unsigned char)(result & 0xff);
26106 +       } else if (likely(op != CMPI)) {
26107 +               /*
26108 +                * copy result to a register, using move.4 dest, result
26109 +                */
26110 +               extern unsigned int unaligned_trap_set_result;
26111 +               *((unsigned int *)&unaligned_trap_set_result) &= ~0x7ff0000;
26112 +
26113 +               if (op == 2 || op == 6) {
26114 +                       *((unsigned int *)&unaligned_trap_set_result) |=
26115 +                               ((inst & 0x000f0000) | 0x01000000);
26116 +               } else {
26117 +                       *((unsigned int *)&unaligned_trap_set_result) |=
26118 +                               (inst & 0x7ff0000);
26119 +               }
26120 +               flush_dcache_range((unsigned long)&unaligned_trap_set_result,
26121 +                                  ((unsigned long)(&unaligned_trap_set_result) + 4));
26122 +
26123 +               asm volatile (
26124 +                       /* result uses thread's registers */
26125 +               "       move.4          CSR, %1                 \n\t"
26126 +               "       setcsr_flush 0                          \n\t"
26127 +               "unaligned_trap_set_result:                     \n\t"
26128 +               "       move.4 #0, %0                           \n\t"
26129 +               "       setcsr          #0                      \n\t"
26130 +               "       setcsr_flush    0                       \n\t"
26131 +                       :
26132 +                       : "d"(result), "d" ((1 << 14) | (thread << 15))
26133 +                       : "cc"
26134 +               );
26135 +       }
26136 +
26137 +       /*
26138 +        * bump PC in thread and restore implicit register changes
26139 +        */
26140 +       asm volatile (
26141 +       "       move.4          CSR, %0                 \n\t"
26142 +       "       setcsr_flush    0                       \n\t"
26143 +       "       move.4          pc, %1                  \n\t"
26144 +       "       move.4          acc0_lo, (%3)           \n\t"
26145 +       "       move.4          acc0_hi, 4(%3)          \n\t"
26146 +       "       move.4          acc1_lo, 8(%3)          \n\t"
26147 +       "       move.4          acc1_hi, 12(%3)         \n\t"
26148 +       "       move.4          mac_rc16, 16(%3)        \n\t"
26149 +       "       move.4          CSR, %2                 \n\t"
26150 +       "       setcsr          #0                      \n\t"
26151 +       "       setcsr_flush    0                       \n\t"
26152 +               :
26153 +               : "d"((1 << 14) | (thread << 15)),
26154 +                 "d"(pc + 4), "d"(save_csr), "a"(save_acc)
26155 +               : "cc"
26156 +       );
26157 +}
26158 +
26159 +/*
26160 + * unaligned_only()
26161 + *     Return true if either of the unaligned causes are set (and no others).
26162 + */
26163 +int unaligned_only(unsigned int cause)
26164 +{
26165 +       unsigned int unaligned_cause_mask =
26166 +               (1 << TRAP_CAUSE_DST_MISALIGNED) |
26167 +               (1 << TRAP_CAUSE_SRC1_MISALIGNED);
26168 +
26169 +       BUG_ON(cause == 0);
26170 +       return (cause & unaligned_cause_mask) == cause;
26171 +}
26172 --- /dev/null
26173 +++ b/arch/ubicom32/kernel/vmlinux.lds.S
26174 @@ -0,0 +1,303 @@
26175 +/*
26176 + * arch/ubicom32/kernel/vmlinux.lds.S
26177 + *     vmlinux primary linker script
26178 + *
26179 + * (C) Copyright 2009, Ubicom, Inc.
26180 + *
26181 + * This file is part of the Ubicom32 Linux Kernel Port.
26182 + *
26183 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26184 + * it and/or modify it under the terms of the GNU General Public License
26185 + * as published by the Free Software Foundation, either version 2 of the
26186 + * License, or (at your option) any later version.
26187 + *
26188 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26189 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26190 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26191 + * the GNU General Public License for more details.
26192 + *
26193 + * You should have received a copy of the GNU General Public License
26194 + * along with the Ubicom32 Linux Kernel Port.  If not,
26195 + * see <http://www.gnu.org/licenses/>.
26196 + *
26197 + * Ubicom32 implementation derived from (with many thanks):
26198 + *   arch/m68knommu
26199 + *   arch/blackfin
26200 + *   arch/parisc
26201 + */
26202 +#include <asm-generic/vmlinux.lds.h>
26203 +#include <asm/ocm_size.h>
26204 +#include <asm/thread_info.h>
26205 +#include <linux/threads.h>
26206 +
26207 +/*
26208 + * Sanity checks to prevent errors later on that are much harder to understand
26209 + */
26210 +#if !defined APP_OCM_CODE_SIZE
26211 +#error APP_OCM_CODE_SIZE has not been defined in ocm_size.h
26212 +#endif
26213 +
26214 +#if !defined APP_OCM_DATA_SIZE
26215 +#error APP_OCM_DATA_SIZE has not been defined in ocm_size.h
26216 +#endif
26217 +
26218 +/*
26219 + * XXX Should get these from a common header file, but <asm/ip5000.h> is a mess
26220 + * and can't be included by anything other than C code at the moment.
26221 + */
26222 +/*
26223 + * Memory Size
26224 + */
26225 +#define OCM_SECTOR_SIZE 0x00008000              /* 32K */
26226 +
26227 +#if defined(CONFIG_UBICOM32_V3)
26228 +#define OCMSIZE         0x00030000              /* 192K on-chip RAM for both program and data */
26229 +#elif defined(CONFIG_UBICOM32_V4)
26230 +#define OCMSIZE         0x0003C000              /* 240K on-chip RAM for both program and data */
26231 +#else
26232 +#error "Unknown IP5K silicon"
26233 +#endif
26234 +
26235 +#define OCMSTART        0x3ffc0000              /* alias from 0x03000000 for easy jump to/from SDRAM */
26236 +#define OCMEND          (OCMSTART + OCMSIZE)
26237 +
26238 +/*
26239 + * The `free' ocm area that ultra does not use.
26240 + */
26241 +#if APP_OCM_CODE_SIZE || APP_OCM_DATA_SIZE
26242 +#define OCM_FREE_START (OCMSTART + APP_OCM_CODE_SIZE)
26243 +#define OCM_FREE_LENGTH        (OCMSIZE - APP_OCM_CODE_SIZE - APP_OCM_DATA_SIZE)
26244 +#else
26245 +#define OCM_FREE_START OCMEND
26246 +#define OCM_FREE_LENGTH 0
26247 +#endif
26248 +/*
26249 + * If you want to limit OCM use for text/data or completely disable it you can change these values.
26250 + */
26251 +#define OCM_TEXT_LENGTH        OCM_FREE_LENGTH
26252 +#define OCM_DATA_LENGTH        OCM_FREE_LENGTH
26253 +
26254 +#define        RAM_START       CONFIG_KERNELBASE
26255 +#define        RAM_LENGTH      (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
26256 +#define        TEXT            ram
26257 +#define        DATA            ram
26258 +#define        INIT            ram
26259 +#define        BSS             ram
26260 +
26261 +#ifndef DATA_ADDR
26262 +#define        DATA_ADDR
26263 +#endif
26264 +
26265 +OUTPUT_ARCH(ubicom32)
26266 +ENTRY(_start)
26267 +
26268 +MEMORY {
26269 +       ram             : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
26270 +       ocm             : ORIGIN = OCM_FREE_START, LENGTH = OCM_FREE_LENGTH
26271 +}
26272 +
26273 +jiffies = jiffies_64 + 4;
26274 +
26275 +/*
26276 + * Fixed locations required by gdb coredumps.
26277 + *
26278 + * Note that the names are what gdb is expecting so renaming will break
26279 + * the toolchain.
26280 + */
26281 +__ocm_begin            = OCMSTART;
26282 +__ocm_limit            = __ocm_begin + OCMSIZE;
26283 +__sdram_begin          = CONFIG_RAMBASE;
26284 +__sdram_limit          = __sdram_begin + CONFIG_RAMSIZE;
26285 +__filemedia_begin_addr = 0x60000000;
26286 +__filemedia_end_addr   = __filemedia_begin_addr + 0x00800000;
26287 +
26288 +SECTIONS {
26289 +
26290 +       .fixed_text : {
26291 +               _begin = .;
26292 +               *(.skip_syscall)
26293 +               *(.syscall_entry.text)
26294 +               *(.syscall_exit.text)
26295 +               *(.ret_from_interrupt_to_user.text)
26296 +               *(.ret_from_fork.text)
26297 +               *(.kernel_unprotected)
26298 +               __fixed_text_end = .;
26299 +       } > TEXT
26300 +       . = _begin + SIZEOF(.fixed_text) ;
26301 +
26302 +       __ocm_text_load_begin = .;
26303 +       __ocm_text_run_begin = OCM_FREE_START ;
26304 +       .ocm_text __ocm_text_run_begin : AT(__ocm_text_load_begin) {
26305 +#if OCM_TEXT_LENGTH
26306 +               *(.ocm_text)
26307 +               *(.sched.text)
26308 +               *(.spinlock.text)
26309 +#include <asm/ocm_text.lds.inc>
26310 +               . = ALIGN(4);
26311 +#endif
26312 +               __ocm_text_run_end = .;
26313 +               __data_begin = ALIGN(OCM_SECTOR_SIZE);
26314 +       } > ocm /* .ocm_text */
26315 +
26316 +       .ocm_module_text __ocm_text_run_end (NOLOAD) : AT(__ocm_text_run_end) {
26317 +               __ocm_inst_heap_begin = .;
26318 +               /* Reserve the min requested */
26319 +               . += (CONFIG_OCM_MODULES_RESERVATION) * 1024;
26320 +#ifdef CONFIG_OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
26321 +               /* Round up to OCM sector size (we cannot use it for data) */
26322 +               . = ALIGN(OCM_SECTOR_SIZE);
26323 +#endif
26324 +               __ocm_inst_heap_end = .;
26325 +               /* update __data_begin */
26326 +               __data_begin = ALIGN(OCM_SECTOR_SIZE);
26327 +       } > ocm  /* .ocm_module_text */
26328 +
26329 +       . = __ocm_text_load_begin + __ocm_text_run_end - __ocm_text_run_begin ;
26330 +       __ocm_text_load_end = .;
26331 +
26332 +       __ocm_data_load_begin = .;
26333 +       __ocm_data_run_begin = __data_begin ;
26334 +#if OCM_DATA_LENGTH
26335 +       .ocm_data __ocm_data_run_begin : AT(__ocm_data_load_begin) {
26336 +#if defined(CONFIG_IRQSTACKS_USEOCM)
26337 +               percpu_irq_stacks = .;
26338 +               . += NR_CPUS * THREAD_SIZE;
26339 +#endif
26340 +               *(.ocm_data)
26341 +               . = ALIGN(4) ;
26342 +               __ocm_data_run_end = .;
26343 +       } > ocm
26344 +       . = __ocm_data_load_begin + __ocm_data_run_end - __ocm_data_run_begin ;
26345 +#else
26346 +       __ocm_data_run_end = __ocm_data_run_begin;
26347 +#endif
26348 +       __ocm_data_load_end = .;
26349 +
26350 +       __ocm_free_begin = __ocm_data_run_end;
26351 +       __ocm_free_end = OCM_FREE_START + OCM_FREE_LENGTH;
26352 +
26353 +       .text __ocm_data_load_end : AT(__ocm_data_load_end) {
26354 +               . = ALIGN(4);
26355 +               _stext = .;
26356 +               _text = .;
26357 +               TEXT_TEXT
26358 +               SCHED_TEXT
26359 +               LOCK_TEXT
26360 +               *(.text.lock)
26361 +               *(.text.__libgcc_udivmodsi)
26362 +               *(.text.__libgcc_divmodsi)
26363 +               *(.text.__libgcc_muldi3)
26364 +               *(.text.__libgcc_udivmoddi)
26365 +               *(.text.__libgcc_divmoddi)
26366 +               *(.text.*)
26367 +#if OCM_TEXT_LENGTH == 0
26368 +               *(.ocm_text)
26369 +               *(.sched.text)
26370 +               *(.spinlock.text)
26371 +#endif
26372 +               . = ALIGN(16);          /* Exception table              */
26373 +               __start___ex_table = .;
26374 +               *(__ex_table)
26375 +               __stop___ex_table = .;
26376 +
26377 +       } > TEXT
26378 +
26379 +       RO_DATA(16)
26380 +
26381 +       .rodata : {} > TEXT
26382 +       .rodata1 : {} > TEXT
26383 +       .pci_fixup : {} > TEXT
26384 +       .builtin_fw : {} > TEXT
26385 +       .rio_route : {} > TEXT
26386 +       .tracedata : {} > TEXT
26387 +       __ksymtab : {} > TEXT
26388 +       __ksymtab_gpl : {} > TEXT
26389 +       __ksymtab_gpl_future : {} > TEXT
26390 +       __kcrctab_gpl : {} > TEXT
26391 +       __kcrctab_unused : {} > TEXT
26392 +       __kcrctab_unused_gpl : {} > TEXT
26393 +       __kcrctab_gpl_future : {} > TEXT
26394 +       __ksymtab_strings : {} > TEXT
26395 +       __init_rodata : {} > TEXT
26396 +       __param : {} > TEXT
26397 +
26398 +       _etext = .;
26399 +
26400 +       .data DATA_ADDR : {
26401 +               . = ALIGN(4);
26402 +               _sdata = . ;
26403 +               DATA_DATA
26404 +#if OCM_DATA_LENGTH == 0
26405 +               *(.ocm_data)
26406 +#endif
26407 +               . = ALIGN(8192) ;
26408 +               _data_protection_end = .;
26409 +               *(.data.init_task)
26410 +               . = ALIGN(4);
26411 +               _edata = . ;
26412 +       } > DATA
26413 +
26414 +       .init : {
26415 +               . = ALIGN(4096);
26416 +               __init_begin = .;
26417 +               _sinittext = .;
26418 +               INIT_TEXT
26419 +               _einittext = .;
26420 +               *(.init.rodata)
26421 +               INIT_DATA
26422 +               . = ALIGN(16);
26423 +               __setup_start = .;
26424 +               *(.init.setup)
26425 +               __setup_end = .;
26426 +               __initcall_start = .;
26427 +               INITCALLS
26428 +               __initcall_end = .;
26429 +               __con_initcall_start = .;
26430 +               *(.con_initcall.init)
26431 +               __con_initcall_end = .;
26432 +               ___security_initcall_start = .;
26433 +               *(.security_initcall.init)
26434 +               ___security_initcall_end = .;
26435 +#ifdef CONFIG_BLK_DEV_INITRD
26436 +               . = ALIGN(4);
26437 +               __initramfs_start = .;
26438 +               *(.init.ramfs)
26439 +               __initramfs_end = .;
26440 +#endif
26441 +               . = ALIGN(4096);
26442 +               __per_cpu_start = .;
26443 +                       *(.data.percpu)
26444 +                       *(.data.percpu.shared_aligned)
26445 +               __per_cpu_end = .;
26446 +
26447 +               . = ALIGN(4096);
26448 +               __init_end = .;
26449 +       } > INIT
26450 +
26451 +         .eh_frame   :
26452 +         {
26453 +           PROVIDE (___eh_frame_begin = .);
26454 +           *(.eh_frame)
26455 +           LONG (0);
26456 +           PROVIDE (___eh_frame_end = .);
26457 +         } > INIT
26458 +
26459 +       .bss : {
26460 +               . = ALIGN(4);
26461 +               _sbss = . ;
26462 +               *(.bss)
26463 +               *(COMMON)
26464 +               . = ALIGN(4) ;
26465 +               _ebss = . ;
26466 +               _end = . ;
26467 +       } > BSS
26468 +
26469 +       /DISCARD/ : {
26470 +               EXIT_TEXT
26471 +               EXIT_DATA
26472 +               *(.exitcall.exit)
26473 +       }
26474 +
26475 +       NOTES > BSS
26476 +
26477 +}
26478 --- /dev/null
26479 +++ b/arch/ubicom32/lib/checksum.c
26480 @@ -0,0 +1,250 @@
26481 +/*
26482 + * arch/ubicom32/lib/checksum.c
26483 + *   Optimized checksum utilities for IP.
26484 + *
26485 + * (C) Copyright 2009, Ubicom, Inc.
26486 + *
26487 + * This file is part of the Ubicom32 Linux Kernel Port.
26488 + *
26489 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26490 + * it and/or modify it under the terms of the GNU General Public License
26491 + * as published by the Free Software Foundation, either version 2 of the
26492 + * License, or (at your option) any later version.
26493 + *
26494 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26495 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26496 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26497 + * the GNU General Public License for more details.
26498 + *
26499 + * You should have received a copy of the GNU General Public License
26500 + * along with the Ubicom32 Linux Kernel Port.  If not, 
26501 + * see <http://www.gnu.org/licenses/>.
26502 + *
26503 + * Ubicom32 implementation derived from (with many thanks):
26504 + *   arch/m68knommu
26505 + *   arch/blackfin
26506 + *   arch/parisc
26507 + */
26508 +/*
26509 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
26510 + *             operating system.  INET is implemented using the  BSD Socket
26511 + *             interface as the means of communication with the user level.
26512 + *
26513 + *             IP/TCP/UDP checksumming routines
26514 + *
26515 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
26516 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
26517 + *             Tom May, <ftom@netcom.com>
26518 + *             Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
26519 + *             Lots of code moved from tcp.c and ip.c; see those files
26520 + *             for more names.
26521 + *
26522 + * 03/02/96    Jes Sorensen, Andreas Schwab, Roman Hodek:
26523 + *             Fixed some nasty bugs, causing some horrible crashes.
26524 + *             A: At some points, the sum (%0) was used as
26525 + *             length-counter instead of the length counter
26526 + *             (%1). Thanks to Roman Hodek for pointing this out.
26527 + *             B: GCC seems to mess up if one uses too many
26528 + *             data-registers to hold input values and one tries to
26529 + *             specify d0 and d1 as scratch registers. Letting gcc choose these
26530 + *             registers itself solves the problem.
26531 + *
26532 + *             This program is free software; you can redistribute it and/or
26533 + *             modify it under the terms of the GNU General Public License
26534 + *             as published by the Free Software Foundation; either version
26535 + *             2 of the License, or (at your option) any later version.
26536 + */
26537 +
26538 +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
26539 +   of the assembly has to go. */
26540 +
26541 +#include <linux/module.h>
26542 +#include <net/checksum.h>
26543 +
26544 +static unsigned long do_csum(const unsigned char * buff, int len)
26545 +{
26546 +       int count;
26547 +       unsigned long result = 0;
26548 +
26549 +       /*
26550 +        * The following optimized assembly code cannot handle data length less than 7 bytes!
26551 +        */
26552 +       if (likely(len >= 7)) {
26553 +               len -= (4 - (int)buff) & 3;
26554 +               count = len >> 2;
26555 +               asm (
26556 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26557 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26558 +
26559 +               "       bfextu          d14, %0, #2             \n\t"   // test 2 LSB of buff
26560 +               "       jmpne.w.f       100f                    \n\t"
26561 +               "       add.4           %1, #0, %1              \n\t"   // clear C
26562 +               "       moveai          a3, #%%hi(1f)           \n\t"   // table jump
26563 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26564 +               "       lea.4           a3, (a3,d15)            \n\t"
26565 +               "       calli           a3, 0(a3)               \n\t"
26566 +
26567 +               "100:   sub.4           %0, %0, d14             \n\t"
26568 +               "       sub.4           d14, #4, d14            \n\t"
26569 +               "       lsl.4           d14, d14, #3            \n\t"
26570 +               "       add.4           %1, #0, %1              \n\t"   // clear C
26571 +               "       moveai          a3, #%%hi(1f)           \n\t"   // table jump
26572 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26573 +               "       lea.4           a3, (a3,d15)            \n\t"
26574 +               "       bfextu          %1, (%0)4++, d14        \n\t"   // read first partial word
26575 +               "       calli           a3, 0(a3)               \n\t"
26576 +#if 1
26577 +               "200:   lsl.4           %3, %3, #3              \n\t"
26578 +               "       bfrvrs          d15, (%0), #0           \n\t"   // read last word (partial)
26579 +               "       bfextu          d15, d15, %3            \n\t"
26580 +               "       bfrvrs          d15, d15, #0            \n\t"
26581 +               "       add.4           %1, d15, %1             \n\t"
26582 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26583 +               "       jmpt.w.t        2f                      \n\t"
26584 +#else
26585 +               "200:   move.1          d15, 0(%0)              \n\t"
26586 +               "       lsl.4           d15, d15, #8            \n\t"
26587 +               "       add.4           %1, d15, %1             \n\t"
26588 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26589 +               "       add.4           %3, #-1, %3             \n\t"
26590 +               "       jmpeq.w.t       2f                      \n\t"
26591 +
26592 +               "       move.1          d15, 1(%0)              \n\t"
26593 +               "       add.4           %1, d15, %1             \n\t"
26594 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26595 +               "       add.4           %3, #-1, %3             \n\t"
26596 +               "       jmpeq.w.t       2f                      \n\t"
26597 +
26598 +               "       move.1          d15, 2(%0)              \n\t"
26599 +               "       lsl.4           d15, d15, #8            \n\t"
26600 +               "       add.4           %1, d15, %1             \n\t"
26601 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26602 +               "       jmpt.w.t        2f                      \n\t"
26603 +#endif
26604 +#if defined(IP7000) || defined(IP7000_REV2)
26605 +               "300:   swapb.2         %1, %1                  \n\t"
26606 +#else
26607 +               "300:   shmrg.2         %1, %1, %1              \n\t"
26608 +               "       lsr.4           %1, %1, #8              \n\t"
26609 +               "       bfextu          %1, %1, #16             \n\t"
26610 +#endif
26611 +               "       jmpt.w.t        3f                      \n\t"
26612 +
26613 +               "1:     add.4           %1, (%0)4++, %1         \n\t"   // first add without C
26614 +               "       .rept           31                      \n\t"
26615 +               "       addc            %1, (%0)4++, %1         \n\t"
26616 +               "       .endr                                   \n\t"
26617 +               "       addc            %1, #0, %1              \n\t"   // sample C again
26618 +               "       add.4           %2, #-32, %2            \n\t"
26619 +               "       jmpgt.w.t       1b                      \n\t"
26620 +
26621 +               "       and.4           %3, #3, %3              \n\t"   // check n
26622 +               "       jmpne.w.f       200b                    \n\t"
26623 +
26624 +               "2:     .rept           2                       \n\t"
26625 +               "       lsr.4           d15, %1, #16            \n\t"
26626 +               "       bfextu          %1, %1, #16             \n\t"
26627 +               "       add.4           %1, d15, %1             \n\t"
26628 +               "       .endr                                   \n\t"
26629 +               "       btst            d14, #3                 \n\t"   // start from odd address (<< 3)?
26630 +               "       jmpne.w.f       300b                    \n\t"
26631 +               "3:                                             \n\t"
26632 +
26633 +                       : "+a"(buff), "+d"(result), "+d"(count), "+d"(len)
26634 +                       :
26635 +                       : "d15", "d14", "a3", "cc"
26636 +               );
26637 +
26638 +               return result;
26639 +       }
26640 +
26641 +       /*
26642 +        * handle a few bytes and fold result into 16-bit
26643 +        */
26644 +       while (len-- > 0) {
26645 +               result += (*buff++ << 8);
26646 +               if (len) {
26647 +                       result += *buff++;
26648 +                       len--;
26649 +               }
26650 +       }
26651 +       asm (
26652 +       "       .rept           2                       \n\t"
26653 +       "       lsr.4           d15, %0, #16            \n\t"
26654 +       "       bfextu          %0, %0, #16             \n\t"
26655 +       "       add.4           %0, d15, %0             \n\t"
26656 +       "       .endr                                   \n\t"
26657 +               : "+d" (result)
26658 +               :
26659 +               : "d15", "cc"
26660 +       );
26661 +
26662 +       return result;
26663 +}
26664 +
26665 +/*
26666 + *     This is a version of ip_compute_csum() optimized for IP headers,
26667 + *     which always checksum on 4 octet boundaries.
26668 + */
26669 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
26670 +{
26671 +       return (__force __sum16)~do_csum(iph,ihl*4);
26672 +}
26673 +
26674 +/*
26675 + * computes the checksum of a memory block at buff, length len,
26676 + * and adds in "sum" (32-bit)
26677 + *
26678 + * returns a 32-bit number suitable for feeding into itself
26679 + * or csum_tcpudp_magic
26680 + *
26681 + * this function must be called with even lengths, except
26682 + * for the last fragment, which may be odd
26683 + *
26684 + * it's best to have buff aligned on a 32-bit boundary
26685 + */
26686 +__wsum csum_partial(const void *buff, int len, __wsum sum)
26687 +{
26688 +       unsigned int result = do_csum(buff, len);
26689 +
26690 +       /* add in old sum, and carry.. */
26691 +       result += (__force u32)sum;
26692 +       if ((__force u32)sum > result)
26693 +               result += 1;
26694 +       return (__force __wsum)result;
26695 +}
26696 +
26697 +EXPORT_SYMBOL(csum_partial);
26698 +
26699 +/*
26700 + * this routine is used for miscellaneous IP-like checksums, mainly
26701 + * in icmp.c
26702 + */
26703 +__sum16 ip_compute_csum(const void *buff, int len)
26704 +{
26705 +       return (__force __sum16)~do_csum(buff,len);
26706 +}
26707 +
26708 +/*
26709 + * copy from fs while checksumming, otherwise like csum_partial
26710 + */
26711 +
26712 +__wsum
26713 +csum_partial_copy_from_user(const void __user *src, void *dst,
26714 +                           int len, __wsum sum, int *csum_err)
26715 +{
26716 +       if (csum_err) *csum_err = 0;
26717 +       memcpy(dst, (__force const void *)src, len);
26718 +       return csum_partial(dst, len, sum);
26719 +}
26720 +
26721 +/*
26722 + * copy from ds while checksumming, otherwise like csum_partial
26723 + */
26724 +
26725 +__wsum
26726 +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
26727 +{
26728 +       memcpy(dst, src, len);
26729 +       return csum_partial(dst, len, sum);
26730 +}
26731 --- /dev/null
26732 +++ b/arch/ubicom32/lib/delay.c
26733 @@ -0,0 +1,49 @@
26734 +/*
26735 + * arch/ubicom32/lib/delay.c
26736 + *   Ubicom32 implementation of udelay()
26737 + *
26738 + * (C) Copyright 2009, Ubicom, Inc.
26739 + *
26740 + * This file is part of the Ubicom32 Linux Kernel Port.
26741 + *
26742 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26743 + * it and/or modify it under the terms of the GNU General Public License
26744 + * as published by the Free Software Foundation, either version 2 of the
26745 + * License, or (at your option) any later version.
26746 + *
26747 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26748 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26749 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26750 + * the GNU General Public License for more details.
26751 + *
26752 + * You should have received a copy of the GNU General Public License
26753 + * along with the Ubicom32 Linux Kernel Port.  If not, 
26754 + * see <http://www.gnu.org/licenses/>.
26755 + *
26756 + * Ubicom32 implementation derived from (with many thanks):
26757 + *   arch/m68knommu
26758 + *   arch/blackfin
26759 + *   arch/parisc
26760 + */
26761 +
26762 +#include <linux/module.h>
26763 +#include <asm/param.h>
26764 +#include <asm/delay.h>
26765 +#include <asm/ip5000.h>
26766 +
26767 +/*
26768 + * read_current_timer()
26769 + *     Return the current value of sysval.
26770 + */
26771 +int __devinit read_current_timer(unsigned long *timer_val)
26772 +{
26773 +       *timer_val = (long)(UBICOM32_IO_TIMER->sysval);
26774 +       return 0;
26775 +}
26776 +
26777 +
26778 +void udelay(unsigned long usecs)
26779 +{
26780 +       _udelay(usecs);
26781 +}
26782 +EXPORT_SYMBOL(udelay);
26783 --- /dev/null
26784 +++ b/arch/ubicom32/lib/Makefile
26785 @@ -0,0 +1,32 @@
26786 +#
26787 +# arch/ubicom32/lib/Makefile
26788 +#      <TODO: Replace with short file description>
26789 +#
26790 +# (C) Copyright 2009, Ubicom, Inc.
26791 +#
26792 +# This file is part of the Ubicom32 Linux Kernel Port.
26793 +#
26794 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
26795 +# it and/or modify it under the terms of the GNU General Public License
26796 +# as published by the Free Software Foundation, either version 2 of the
26797 +# License, or (at your option) any later version.
26798 +#
26799 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
26800 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
26801 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26802 +# the GNU General Public License for more details.
26803 +#
26804 +# You should have received a copy of the GNU General Public License
26805 +# along with the Ubicom32 Linux Kernel Port.  If not, 
26806 +# see <http://www.gnu.org/licenses/>.
26807 +#
26808 +# Ubicom32 implementation derived from (with many thanks):
26809 +#   arch/m68knommu
26810 +#   arch/blackfin
26811 +#   arch/parisc
26812 +#
26813 +#
26814 +# Makefile for m68knommu specific library files..
26815 +#
26816 +
26817 +lib-y  := checksum.o delay.o mem_ubicom32.o muldi3.o lshrdi3.o ashldi3.o ashrdi3.o divmod.o
26818 --- /dev/null
26819 +++ b/arch/ubicom32/lib/mem_ubicom32.c
26820 @@ -0,0 +1,242 @@
26821 +/*
26822 + * arch/ubicom32/lib/mem_ubicom32.c
26823 + *   String functions.
26824 + *
26825 + * (C) Copyright 2009, Ubicom, Inc.
26826 + *
26827 + * This file is part of the Ubicom32 Linux Kernel Port.
26828 + *
26829 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
26830 + * it and/or modify it under the terms of the GNU General Public License
26831 + * as published by the Free Software Foundation, either version 2 of the
26832 + * License, or (at your option) any later version.
26833 + *
26834 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
26835 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
26836 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26837 + * the GNU General Public License for more details.
26838 + *
26839 + * You should have received a copy of the GNU General Public License
26840 + * along with the Ubicom32 Linux Kernel Port.  If not,
26841 + * see <http://www.gnu.org/licenses/>.
26842 + *
26843 + * Ubicom32 implementation derived from (with many thanks):
26844 + *   arch/m68knommu
26845 + *   arch/blackfin
26846 + *   arch/parisc
26847 + */
26848 +
26849 +#include <linux/module.h>
26850 +#include <linux/types.h>
26851 +#include <linux/compiler.h>
26852 +
26853 +#define LIKELY likely
26854 +#define UNLIKELY unlikely
26855 +
26856 +typedef u32_t addr_t;
26857 +
26858 +/*
26859 + * memcpy()
26860 + */
26861 +void *memcpy(void *dest, const void *src, size_t n)
26862 +{
26863 +       void *dest_ret = dest;
26864 +
26865 +       if (LIKELY((((addr_t)dest ^ (addr_t)src) & 3) == 0) && LIKELY(n > 6)) {
26866 +               size_t m;
26867 +               n -= (4 - (addr_t)dest) & 0x03;
26868 +               m = n >> 2;
26869 +               asm volatile (
26870 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26871 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26872 +               "       moveai          a3, #%%hi(1f)           \n\t"
26873 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26874 +               "       lea.4           a3, (a3,d15)            \n\t"
26875 +
26876 +               "       bfextu          d15, %0, #2             \n\t"   // d15 = (dest & 3)
26877 +               "       jmpne.w.f       100f                    \n\t"
26878 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
26879 +
26880 +               "100:   cmpi            d15, #2                 \n\t"
26881 +               "       jmpne.s.f       101f                    \n\t"
26882 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26883 +               "       calli           a3, 0(a3)               \n\t"   // 2-byte alignment
26884 +
26885 +               "101:   move.1          (%0)1++, (%1)1++        \n\t"
26886 +               "       jmpgt.s.f       102f                    \n\t"   // 3-byte alignment
26887 +               "       move.2          (%0)2++, (%1)2++        \n\t"   // 1-byte alignment
26888 +               "102:   calli           a3, 0(a3)               \n\t"
26889 +
26890 +               "200:   cmpi            %3, #2                  \n\t"
26891 +               "       jmplt.s.f       201f                    \n\t"
26892 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26893 +               "       jmpeq.s.t       2f                      \n\t"
26894 +               "201:   move.1          (%0)1++, (%1)1++        \n\t"
26895 +               "       jmpt.w.t        2f                      \n\t"
26896 +
26897 +               "1:     .rept           25                      \n\t"
26898 +               "       movea           (%0)4++, (%1)4++        \n\t"
26899 +               "       .endr                                   \n\t"
26900 +               "       .rept           7                       \n\t"
26901 +               "       move.4          (%0)4++, (%1)4++        \n\t"
26902 +               "       .endr                                   \n\t"
26903 +               "       add.4           %2, #-32, %2            \n\t"
26904 +               "       jmpgt.w.f       1b                      \n\t"
26905 +
26906 +               "       and.4           %3, #3, %3              \n\t"   // check n
26907 +               "       jmpne.w.f       200b                    \n\t"
26908 +               "2:                                             \n\t"
26909 +                       : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26910 +                       :
26911 +                       : "d15", "a3", "memory", "cc"
26912 +               );
26913 +
26914 +               return dest_ret;
26915 +       }
26916 +
26917 +       if (LIKELY((((addr_t)dest ^ (addr_t)src) & 1) == 0) && LIKELY(n > 2)) {
26918 +               size_t m;
26919 +               n -= (addr_t)dest & 0x01;
26920 +               m = n >> 1;
26921 +               asm volatile (
26922 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26923 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26924 +               "       moveai          a3, #%%hi(1f)           \n\t"
26925 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26926 +               "       lea.4           a3, (a3,d15)            \n\t"
26927 +
26928 +               "       btst            %0, #0                  \n\t"   // check bit 0
26929 +               "       jmpne.w.f       100f                    \n\t"
26930 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
26931 +
26932 +               "100:   move.1          (%0)1++, (%1)1++        \n\t"
26933 +               "       calli           a3, 0(a3)               \n\t"
26934 +
26935 +               "200:   move.1          (%0)1++, (%1)1++        \n\t"
26936 +               "       jmpt.w.t        2f                      \n\t"
26937 +
26938 +               "1:     .rept           32                      \n\t"
26939 +               "       move.2          (%0)2++, (%1)2++        \n\t"
26940 +               "       .endr                                   \n\t"
26941 +               "       add.4           %2, #-32, %2            \n\t"
26942 +               "       jmpgt.w.f       1b                      \n\t"
26943 +
26944 +               "       and.4           %3, #1, %3              \n\t"   // check n
26945 +               "       jmpne.w.f       200b                    \n\t"
26946 +               "2:                                             \n\t"
26947 +
26948 +                       : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26949 +                       :
26950 +                       : "d15", "a3", "memory", "cc"
26951 +               );
26952 +
26953 +               return dest_ret;
26954 +       }
26955 +
26956 +       asm volatile (
26957 +       "       sub.4           d15, #0, %2             \n\t"
26958 +       "       jmpeq.w.f       2f                      \n\t"
26959 +       "       and.4           d15, #(16-1), d15       \n\t"   // d15 = (-n) & (16 - 1)
26960 +       "       moveai          a3, #%%hi(1f)           \n\t"
26961 +       "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26962 +       "       lea.4           a3, (a3,d15)            \n\t"
26963 +       "       calli           a3, 0(a3)               \n\t"
26964 +
26965 +       "1:     .rept           16                      \n\t"
26966 +       "       move.1          (%0)1++, (%1)1++        \n\t"
26967 +       "       .endr                                   \n\t"
26968 +       "       add.4           %2, #-16, %2            \n\t"
26969 +       "       jmpgt.w.f       1b                      \n\t"
26970 +       "2:                                             \n\t"
26971 +
26972 +               : "+a" (dest), "+a" (src), "+d" (n)
26973 +               :
26974 +               : "d15", "a3", "memory", "cc"
26975 +       );
26976 +
26977 +       return dest_ret;
26978 +}
26979 +
26980 +/*
26981 + * memset()
26982 + */
26983 +void *memset(void *s, int c, size_t n)
26984 +{
26985 +       void *s_ret = s;
26986 +
26987 +       if (LIKELY(n > 6)) {
26988 +               size_t m;
26989 +               n -= (4 - (addr_t)s) & 0x03;
26990 +               m = n >> 2;
26991 +               asm volatile (
26992 +               "       sub.4           d15, #0, %2             \n\t"   // set up for jump table
26993 +               "       and.4           d15, #(32-1), d15       \n\t"   // d15 = (-m) & (32 - 1)
26994 +               "       shmrg.1         %1, %1, %1              \n\t"
26995 +               "       shmrg.2         %1, %1, %1              \n\t"   // %1 = (c<<24)|(c<<16)|(c<<8)|c
26996 +               "       moveai          a3, #%%hi(1f)           \n\t"
26997 +               "       lea.1           a3, %%lo(1f)(a3)        \n\t"
26998 +               "       lea.4           a3, (a3,d15)            \n\t"
26999 +
27000 +               "       bfextu          d15, %0, #2             \n\t"   // d15 = (s & 3)
27001 +               "       jmpne.w.f       100f                    \n\t"
27002 +               "       calli           a3, 0(a3)               \n\t"   // 4-byte alignment
27003 +
27004 +               "100:   cmpi            d15, #2                 \n\t"
27005 +               "       jmpne.s.f       101f                    \n\t"
27006 +               "       move.2          (%0)2++, %1             \n\t"
27007 +               "       calli           a3, 0(a3)               \n\t"   // 2-byte alignment
27008 +
27009 +               "101:   move.1          (%0)1++, %1             \n\t"
27010 +               "       jmpgt.s.f       102f                    \n\t"   // 3-byte alignment
27011 +               "       move.2          (%0)2++, %1             \n\t"   // 1-byte alignment
27012 +               "102:   calli           a3, 0(a3)               \n\t"
27013 +
27014 +               "200:   cmpi            %3, #2                  \n\t"
27015 +               "       jmplt.s.f       201f                    \n\t"
27016 +               "       move.2          (%0)2++, %1             \n\t"
27017 +               "       jmpeq.s.t       2f                      \n\t"
27018 +               "201:   move.1          (%0)1++, %1             \n\t"
27019 +               "       jmpt.w.t        2f                      \n\t"
27020 +
27021 +               "1:     .rept           25                      \n\t"
27022 +               "       movea           (%0)4++, %1             \n\t"
27023 +               "       .endr                                   \n\t"
27024 +               "       .rept           7                       \n\t"
27025 +               "       move.4          (%0)4++, %1             \n\t"
27026 +               "       .endr                                   \n\t"
27027 +               "       add.4           %2, #-32, %2            \n\t"
27028 +               "       jmpgt.w.f       1b                      \n\t"
27029 +
27030 +               "       and.4           %3, #3, %3              \n\t"   // test bit 1 of n
27031 +               "       jmpne.w.f       200b                    \n\t"
27032 +               "2:                                             \n\t"
27033 +
27034 +                       : "+a" (s), "+d" (c), "+d" (m), "+d" (n)
27035 +                       :
27036 +                       : "d15", "a3", "memory", "cc"
27037 +               );
27038 +
27039 +               return s_ret;
27040 +       }
27041 +
27042 +       asm volatile (
27043 +       "       sub.4           d15, #0, %2             \n\t"
27044 +       "       jmpeq.w.f       2f                      \n\t"
27045 +       "       and.4           d15, #(8-1), d15        \n\t"   // d15 = (-%2) & (16 - 1)
27046 +       "       moveai          a3, #%%hi(1f)           \n\t"
27047 +       "       lea.1           a3, %%lo(1f)(a3)        \n\t"
27048 +       "       lea.4           a3, (a3,d15)            \n\t"
27049 +       "       calli           a3, 0(a3)               \n\t"
27050 +
27051 +       "1:     .rept           8                       \n\t"
27052 +       "       move.1          (%0)1++, %1             \n\t"
27053 +       "       .endr                                   \n\t"
27054 +       "2:                                             \n\t"
27055 +
27056 +               : "+a" (s), "+d" (c), "+d" (n)
27057 +               :
27058 +               : "d15", "a3", "memory", "cc"
27059 +       );
27060 +
27061 +       return s_ret;
27062 +}
27063 --- /dev/null
27064 +++ b/arch/ubicom32/mach-common/audio_tio.c
27065 @@ -0,0 +1,115 @@
27066 +/*
27067 + * arch/ubicom32/mach-common/audio_tio.c
27068 + *   Generic initialization for Ubicom32 Audio
27069 + *
27070 + * (C) Copyright 2009, Ubicom, Inc.
27071 + *
27072 + * This file is part of the Ubicom32 Linux Kernel Port.
27073 + *
27074 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27075 + * it and/or modify it under the terms of the GNU General Public License
27076 + * as published by the Free Software Foundation, either version 2 of the
27077 + * License, or (at your option) any later version.
27078 + *
27079 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27080 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27081 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27082 + * the GNU General Public License for more details.
27083 + *
27084 + * You should have received a copy of the GNU General Public License
27085 + * along with the Ubicom32 Linux Kernel Port.  If not,
27086 + * see <http://www.gnu.org/licenses/>.
27087 + */
27088 +
27089 +#include <linux/platform_device.h>
27090 +#include <linux/types.h>
27091 +
27092 +#include <asm/devtree.h>
27093 +#include <asm/audio_tio.h>
27094 +#include <asm/ubi32-pcm.h>
27095 +
27096 +/*
27097 + * The number of audio_tio's currently allocated, used for .id
27098 + */
27099 +static int __initdata audio_tio_count;
27100 +
27101 +/*
27102 + * The maximum number of resources that the audio_tio will have.
27103 + * Currently 3, a register space, and up to 2 interrupts.
27104 + */
27105 +#define AUDIO_TIO_MAX_RESOURCES        3
27106 +
27107 +/*
27108 + * audio_tio_alloc
27109 + *     Checks the device tree and allocates a platform_device if found
27110 + */
27111 +struct platform_device * __init audio_tio_alloc(const char *driver_name, 
27112 +               const char *node_name, int priv_bytes)
27113 +{
27114 +       struct platform_device *pdev;
27115 +       struct resource *res;
27116 +       struct audiotionode *audio_node;
27117 +       struct ubi32pcm_platform_data *pdata;
27118 +
27119 +       /*
27120 +        * Check the device tree for the audio_tio
27121 +        */
27122 +       audio_node = (struct audiotionode *)devtree_find_node(node_name);
27123 +       if (!audio_node) {
27124 +               printk(KERN_WARNING "audio TIO '%s' found\n", node_name);
27125 +               return NULL;
27126 +       }
27127 +
27128 +       if (audio_node->version != AUDIOTIONODE_VERSION) {
27129 +               printk(KERN_WARNING "audio_tio not compatible\n");
27130 +               return NULL;
27131 +       }
27132 +
27133 +       /*
27134 +        * Dynamically create the platform_device structure and resources
27135 +        */
27136 +       pdev = kzalloc(sizeof(struct platform_device) + 
27137 +                      sizeof(struct ubi32pcm_platform_data) + 
27138 +                      priv_bytes , GFP_KERNEL);
27139 +       if (!pdev) {
27140 +               printk(KERN_WARNING "audio_tio could not alloc pdev\n");
27141 +               return NULL;
27142 +       }
27143 +
27144 +       res = kzalloc(sizeof(struct resource) * AUDIO_TIO_MAX_RESOURCES,
27145 +                       GFP_KERNEL);
27146 +       if (!res) {
27147 +               kfree(pdev);
27148 +               printk(KERN_WARNING "audio_tio could not alloc res\n");
27149 +               return NULL;
27150 +       }
27151 +
27152 +       pdev->name = driver_name;
27153 +       pdev->id = audio_tio_count++;
27154 +       pdev->resource = res;
27155 +
27156 +       /*
27157 +        * Fill in the resources and platform data from devtree information
27158 +        */
27159 +       res[0].start = (u32_t)(audio_node->regs);
27160 +       res[0].end = (u32_t)(audio_node->regs);
27161 +       res[0].flags = IORESOURCE_MEM;
27162 +       res[1 + AUDIOTIO_TX_IRQ_RESOURCE].start = audio_node->dn.sendirq;
27163 +       res[1 + AUDIOTIO_TX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
27164 +       res[1 + AUDIOTIO_RX_IRQ_RESOURCE].start = audio_node->dn.recvirq;
27165 +       res[1 + AUDIOTIO_RX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
27166 +       pdev->num_resources = 3;
27167 +
27168 +       printk(KERN_INFO "AudioTIO.%d '%s' found irq=%d/%d regs=%p pdev=%p/%p\n",
27169 +               audio_tio_count - 1, node_name, audio_node->dn.sendirq,
27170 +               audio_node->dn.recvirq, audio_node->regs, pdev, res);
27171 +       pdata = (struct ubi32pcm_platform_data *)(pdev + 1);
27172 +       pdev->dev.platform_data = pdata;
27173 +       pdata->node_name = node_name;
27174 +       if (priv_bytes) {
27175 +               pdata->priv_data = pdata + 1;
27176 +       }
27177 +
27178 +       return pdev;
27179 +}
27180 +
27181 --- /dev/null
27182 +++ b/arch/ubicom32/mach-common/board.c
27183 @@ -0,0 +1,63 @@
27184 +/*
27185 + * arch/ubicom32/mach-common/board.c
27186 + *   Board init and support code.
27187 + *
27188 + * (C) Copyright 2009, Ubicom, Inc.
27189 + *
27190 + * This file is part of the Ubicom32 Linux Kernel Port.
27191 + *
27192 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27193 + * it and/or modify it under the terms of the GNU General Public License
27194 + * as published by the Free Software Foundation, either version 2 of the
27195 + * License, or (at your option) any later version.
27196 + *
27197 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27198 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27199 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27200 + * the GNU General Public License for more details.
27201 + *
27202 + * You should have received a copy of the GNU General Public License
27203 + * along with the Ubicom32 Linux Kernel Port.  If not,
27204 + * see <http://www.gnu.org/licenses/>.
27205 + *
27206 + * Ubicom32 implementation derived from (with many thanks):
27207 + *   arch/m68knommu
27208 + *   arch/blackfin
27209 + *   arch/parisc
27210 + */
27211 +#include <linux/module.h>
27212 +#include <linux/types.h>
27213 +#include <linux/cpu.h>
27214 +#include <asm/devtree.h>
27215 +
27216 +struct boardnode {
27217 +       struct devtree_node dn;
27218 +       const char *revision;
27219 +};
27220 +
27221 +static const struct boardnode *bn;
27222 +
27223 +/*
27224 + * board_get_revision()
27225 + *     Returns revision string of the board.
27226 + */
27227 +const char *board_get_revision(void)
27228 +{
27229 +       if (!bn) {
27230 +               return "NULL";
27231 +       }
27232 +
27233 +       return bn->revision;
27234 +}
27235 +
27236 +/*
27237 + * board_init
27238 + */
27239 +void __init board_init(void)
27240 +{
27241 +       bn = (struct boardnode *)devtree_find_node("board");
27242 +       if (!bn) {
27243 +               printk(KERN_WARNING "board node not found\n");
27244 +               return;
27245 +       }
27246 +}
27247 --- /dev/null
27248 +++ b/arch/ubicom32/mach-common/bootargs.c
27249 @@ -0,0 +1,63 @@
27250 +/*
27251 + * arch/ubicom32/mach-common/bootargs.c
27252 + *   Board init and support code.
27253 + *
27254 + * (C) Copyright 2009, Ubicom, Inc.
27255 + *
27256 + * This file is part of the Ubicom32 Linux Kernel Port.
27257 + *
27258 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27259 + * it and/or modify it under the terms of the GNU General Public License
27260 + * as published by the Free Software Foundation, either version 2 of the
27261 + * License, or (at your option) any later version.
27262 + *
27263 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27264 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27265 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27266 + * the GNU General Public License for more details.
27267 + *
27268 + * You should have received a copy of the GNU General Public License
27269 + * along with the Ubicom32 Linux Kernel Port.  If not,
27270 + * see <http://www.gnu.org/licenses/>.
27271 + *
27272 + * Ubicom32 implementation derived from (with many thanks):
27273 + *   arch/m68knommu
27274 + *   arch/blackfin
27275 + *   arch/parisc
27276 + */
27277 +#include <linux/module.h>
27278 +#include <linux/types.h>
27279 +#include <linux/cpu.h>
27280 +#include <asm/devtree.h>
27281 +
27282 +struct bootargsnode {
27283 +       struct devtree_node dn;
27284 +       const char cmdline[512];
27285 +};
27286 +
27287 +static const struct bootargsnode *ban;
27288 +
27289 +/*
27290 + * bootargs_get_cmdline()
27291 + *     Returns kernel boot arguments set by the bootloader.
27292 + */
27293 +const char *bootargs_get_cmdline(void)
27294 +{
27295 +       if (!ban) {
27296 +               return "";
27297 +       }
27298 +
27299 +       return ban->cmdline;
27300 +}
27301 +
27302 +/*
27303 + * bootargs_init
27304 + */
27305 +void __init bootargs_init(void)
27306 +{
27307 +       ban = (struct bootargsnode *)devtree_find_node("bootargs");
27308 +       if (!ban) {
27309 +               printk(KERN_WARNING "bootargs node not found\n");
27310 +               return;
27311 +       }
27312 +}
27313 --- /dev/null
27314 +++ b/arch/ubicom32/mach-common/cachectl.c
27315 @@ -0,0 +1,125 @@
27316 +/*
27317 + * arch/ubicom32/mach-common/cachectl.c
27318 + *   Architecture cache control support
27319 + *
27320 + * (C) Copyright 2009, Ubicom, Inc.
27321 + *
27322 + * This file is part of the Ubicom32 Linux Kernel Port.
27323 + *
27324 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27325 + * it and/or modify it under the terms of the GNU General Public License
27326 + * as published by the Free Software Foundation, either version 2 of the
27327 + * License, or (at your option) any later version.
27328 + *
27329 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27330 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27331 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27332 + * the GNU General Public License for more details.
27333 + *
27334 + * You should have received a copy of the GNU General Public License
27335 + * along with the Ubicom32 Linux Kernel Port.  If not,
27336 + * see <http://www.gnu.org/licenses/>.
27337 + *
27338 + * Ubicom32 implementation derived from (with many thanks):
27339 + *   arch/m68knommu
27340 + *   arch/blackfin
27341 + *   arch/parisc
27342 + */
27343 +
27344 +#include <linux/types.h>
27345 +#include <linux/module.h>
27346 +#include <asm/cachectl.h>
27347 +
27348 +/*
27349 + * The write queue flush procedure in mem_cache_control needs to make
27350 + * DCACHE_WRITE_QUEUE_LENGTH writes to DDR (not OCM). Here we reserve some
27351 + * memory for this operation.
27352 + * Allocate array of cache lines of least DCACHE_WRITE_QUEUE_LENGTH + 1 words in
27353 + * length rounded up to the nearest cache line.
27354 + */
27355 +#define CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE \
27356 +       ALIGN(sizeof(int) * (DCACHE_WRITE_QUEUE_LENGTH + 1), CACHE_LINE_SIZE)
27357 +
27358 +static char cache_write_queue_flush_area[CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE]
27359 +       __attribute__((aligned(CACHE_LINE_SIZE)));
27360 +
27361 +/*
27362 + * ONE_CCR_ADDR_OP is a helper macro that executes a single CCR operation.
27363 + */
27364 +#define ONE_CCR_ADDR_OP(cc, op_addr, op)                               \
27365 +       do {                                                            \
27366 +               asm volatile (                                          \
27367 +               "       btst    "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_VALID)"                         \n\t" \
27368 +               "       jmpne.f .-4                                                             \n\t" \
27369 +               "       move.4  "D(CCR_ADDR)"(%0), %1                                           \n\t" \
27370 +               "       move.1  "D(CCR_CTRL+3)"(%0), %2                                         \n\t" \
27371 +               "       bset    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_VALID)"      \n\t" \
27372 +               "       cycles  2                                                               \n\t" \
27373 +               "       btst    "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_DONE)"                          \n\t" \
27374 +               "       jmpeq.f .-4                                                             \n\t" \
27375 +                       :                                               \
27376 +                       : "a"(cc), "r"(op_addr), "r"(op & 0xff)         \
27377 +                       : "cc"                                          \
27378 +               );                                                      \
27379 +       } while (0)
27380 +
27381 +/*
27382 + * mem_cache_control()
27383 + *     Special cache control operation
27384 + */
27385 +void mem_cache_control(unsigned long cc, unsigned long begin_addr,
27386 +                      unsigned long end_addr, unsigned long op)
27387 +{
27388 +       unsigned long op_addr;
27389 +
27390 +       if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
27391 +               /*
27392 +                * We ensure all previous writes have left the data cache write
27393 +                * queue by sending DCACHE_WRITE_QUEUE_LENGTH writes (to
27394 +                * different words) down the queue.  If this is not done it's
27395 +                * possible that the data we are trying to flush hasn't even
27396 +                * entered the data cache.
27397 +                * The +1 ensure that the final 'flush' is actually a flush.
27398 +                */
27399 +               int *flush_area = (int *)cache_write_queue_flush_area;
27400 +               asm volatile(
27401 +                       "       .rept "D(DCACHE_WRITE_QUEUE_LENGTH + 1)"        \n\t"
27402 +                       "       move.4 (%0)4++, d0                              \n\t"
27403 +                       "       .endr                                           \n\t"
27404 +                       : "+a"(flush_area)
27405 +                       );
27406 +       }
27407 +
27408 +       /*
27409 +        * Calculate the cache lines we need to operate on that include
27410 +        * begin_addr though end_addr.
27411 +        */
27412 +       begin_addr = begin_addr & ~(CACHE_LINE_SIZE - 1);
27413 +       end_addr = (end_addr + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
27414 +       op_addr = begin_addr;
27415 +
27416 +       do {
27417 +               ONE_CCR_ADDR_OP(cc, op_addr, op);
27418 +               op_addr += CACHE_LINE_SIZE;
27419 +       } while (likely(op_addr < end_addr));
27420 +
27421 +       if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
27422 +               /*
27423 +                * It turns out that when flushing the data cache the last flush
27424 +                * isn't actually complete at this point. This is because there
27425 +                * is another write buffer on the DDR side of the cache that is
27426 +                * arbitrated with the I-Cache.
27427 +                *
27428 +                * The only foolproof method that ensures that the last data
27429 +                * cache flush *actually* completed is to do another flush on a
27430 +                * dirty cache line. This flush will block until the DDR write
27431 +                * buffer is empty.
27432 +                *
27433 +                * Rather than creating a another dirty cache line, we use the
27434 +                * flush_area above as we know that it is dirty from previous
27435 +                * writes.
27436 +                */
27437 +               ONE_CCR_ADDR_OP(cc, cache_write_queue_flush_area, op);
27438 +       }
27439 +}
27440 +EXPORT_SYMBOL(mem_cache_control);
27441 --- /dev/null
27442 +++ b/arch/ubicom32/mach-common/common.c
27443 @@ -0,0 +1,64 @@
27444 +/*
27445 + * arch/ubicom32/mach-common/common.c
27446 + *   Common platform support.
27447 + *
27448 + * (C) Copyright 2009, Ubicom, Inc.
27449 + *
27450 + * This file is part of the Ubicom32 Linux Kernel Port.
27451 + *
27452 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27453 + * it and/or modify it under the terms of the GNU General Public License
27454 + * as published by the Free Software Foundation, either version 2 of the
27455 + * License, or (at your option) any later version.
27456 + *
27457 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27458 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27459 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27460 + * the GNU General Public License for more details.
27461 + *
27462 + * You should have received a copy of the GNU General Public License
27463 + * along with the Ubicom32 Linux Kernel Port.  If not,
27464 + * see <http://www.gnu.org/licenses/>.
27465 + *
27466 + * Ubicom32 implementation derived from (with many thanks):
27467 + *   arch/m68knommu
27468 + *   arch/blackfin
27469 + *   arch/parisc
27470 + */
27471 +#include <linux/version.h>
27472 +#include <linux/kernel.h>
27473 +#include <linux/init.h>
27474 +#include <linux/module.h>
27475 +#include <linux/list.h>
27476 +#include <linux/errno.h>
27477 +#include <linux/err.h>
27478 +#include <linux/string.h>
27479 +#include <linux/clk.h>
27480 +#include <linux/mutex.h>
27481 +#include <linux/platform_device.h>
27482 +
27483 +
27484 +/* Minimum CLK support */
27485 +
27486 +struct clk *clk_get(struct device *dev, const char *id)
27487 +{
27488 +       return ERR_PTR(-ENOENT);
27489 +}
27490 +EXPORT_SYMBOL(clk_get);
27491 +
27492 +void clk_put(struct clk *clk)
27493 +{
27494 +}
27495 +EXPORT_SYMBOL(clk_put);
27496 +
27497 +int clk_enable(struct clk *clk)
27498 +{
27499 +       return 0;
27500 +}
27501 +EXPORT_SYMBOL(clk_enable);
27502 +
27503 +
27504 +void clk_disable(struct clk *clk)
27505 +{
27506 +}
27507 +EXPORT_SYMBOL(clk_disable);
27508 --- /dev/null
27509 +++ b/arch/ubicom32/mach-common/io.c
27510 @@ -0,0 +1,250 @@
27511 +/*
27512 + * arch/ubicom32/mach-common/io.c
27513 + *   PCI I/O memory read/write support functions.
27514 + *
27515 + * (C) Copyright 2009, Ubicom, Inc.
27516 + *
27517 + * This file is part of the Ubicom32 Linux Kernel Port.
27518 + *
27519 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27520 + * it and/or modify it under the terms of the GNU General Public License
27521 + * as published by the Free Software Foundation, either version 2 of the
27522 + * License, or (at your option) any later version.
27523 + *
27524 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27525 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27526 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27527 + * the GNU General Public License for more details.
27528 + *
27529 + * You should have received a copy of the GNU General Public License
27530 + * along with the Ubicom32 Linux Kernel Port.  If not,
27531 + * see <http://www.gnu.org/licenses/>.
27532 + *
27533 + * Ubicom32 implementation derived from (with many thanks):
27534 + *   arch/m68knommu
27535 + *   arch/blackfin
27536 + *   arch/parisc
27537 + */
27538 +#include <linux/module.h>
27539 +#include <linux/kernel.h>
27540 +#include <linux/io.h>
27541 +
27542 +#ifdef CONFIG_PCI
27543 +unsigned char  ioread8(void __iomem *addr)
27544 +{
27545 +       if (IS_PCI_ADDRESS(addr))
27546 +               return ubi32_pci_read_u8(addr);
27547 +       else
27548 +               return (unsigned char)(*(volatile unsigned char *)addr);
27549 +}
27550 +EXPORT_SYMBOL(ioread8);
27551 +
27552 +unsigned short  ioread16(void __iomem *addr)
27553 +{
27554 +       if (IS_PCI_ADDRESS(addr))
27555 +               return ubi32_pci_read_u16(addr);
27556 +       else
27557 +               return (unsigned short)(*(volatile unsigned short *)addr);
27558 +}
27559 +EXPORT_SYMBOL(ioread16);
27560 +
27561 +unsigned int  ioread32(void __iomem *addr)
27562 +{
27563 +       if (IS_PCI_ADDRESS(addr))
27564 +               return ubi32_pci_read_u32(addr);
27565 +       else
27566 +               return (unsigned int)(*(volatile unsigned int *)addr);
27567 +}
27568 +EXPORT_SYMBOL(ioread32);
27569 +
27570 +void iowrite32(unsigned int val, void __iomem *addr)
27571 +{
27572 +       if (IS_PCI_ADDRESS(addr))
27573 +               ubi32_pci_write_u32(val, addr);
27574 +       else
27575 +               *(volatile unsigned int *)addr = val;
27576 +}
27577 +EXPORT_SYMBOL(iowrite32);
27578 +
27579 +void iowrite16(unsigned short val, void __iomem *addr)
27580 +{
27581 +       if (IS_PCI_ADDRESS(addr))
27582 +               ubi32_pci_write_u16(val, addr);
27583 +       else
27584 +               *(volatile unsigned short *)addr = val;
27585 +}
27586 +EXPORT_SYMBOL(iowrite16);
27587 +
27588 +void iowrite8(unsigned char val, void __iomem *addr)
27589 +{
27590 +       if (IS_PCI_ADDRESS(addr))
27591 +               ubi32_pci_write_u8(val, addr);
27592 +       else
27593 +               *(volatile unsigned char *)addr = val;
27594 +}
27595 +EXPORT_SYMBOL(iowrite8);
27596 +
27597 +void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
27598 +{
27599 +       if (IS_PCI_ADDRESS(from)) {
27600 +               if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
27601 +                       while ((int)len >= 4) {
27602 +                               *(u32_t *)to = ubi32_pci_read_u32(from);
27603 +                               to += 4;
27604 +                               from += 4;
27605 +                               len -= 4;
27606 +                       }
27607 +               } else if ((((u32_t)from & 0x1) == 0) &&
27608 +                          (((u32_t)to & 0x1) == 0)) {
27609 +                       while ((int)len >= 2) {
27610 +                                *(u16_t *)to = ubi32_pci_read_u16(from);
27611 +                                to += 2;
27612 +                                from += 2;
27613 +                                len -= 2;
27614 +                       }
27615 +               }
27616 +
27617 +               while (len) {
27618 +                       *(u8_t *)to = ubi32_pci_read_u8(from);
27619 +                       to++;
27620 +                       from++;
27621 +                       len--;
27622 +               }
27623 +       } else
27624 +               memcpy(to, (void *)from, len);
27625 +}
27626 +EXPORT_SYMBOL(memcpy_fromio);
27627 +
27628 +void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
27629 +{
27630 +       if (IS_PCI_ADDRESS(to)) {
27631 +               if ((((u32_t)from & 0x3) == 0) && (((u32_t)to & 0x3) == 0)) {
27632 +                       while ((int)len >= 4) {
27633 +                               ubi32_pci_write_u32(*(u32_t *)from, to);
27634 +                               to += 4;
27635 +                               from += 4;
27636 +                               len -= 4;
27637 +                       }
27638 +               } else if ((((u32_t)from & 0x1) == 0) &&
27639 +                          (((u32_t)to & 0x1) == 0)) {
27640 +                       while ((int)len >= 2) {
27641 +                               ubi32_pci_write_u16(*(u16_t *)from, to);
27642 +                               to += 2;
27643 +                               from += 2;
27644 +                               len -= 2;
27645 +                       }
27646 +               }
27647 +
27648 +               while (len) {
27649 +                       ubi32_pci_write_u8(*(u8_t *)from, to);
27650 +                       from++;
27651 +                       to++;
27652 +                       len--;
27653 +               }
27654 +       } else
27655 +               memcpy((void *)to, from, len);
27656 +
27657 +}
27658 +EXPORT_SYMBOL(memcpy_toio);
27659 +
27660 +void memset_io(volatile void __iomem *addr, int val, size_t len)
27661 +{
27662 +       if (IS_PCI_ADDRESS(addr)) {
27663 +               while (len) {
27664 +                       ubi32_pci_write_u8((unsigned char)val, addr);
27665 +                       addr++;
27666 +                       len--;
27667 +               }
27668 +       } else
27669 +               memset((void *)addr, val, len);
27670 +
27671 +}
27672 +EXPORT_SYMBOL(memset_io);
27673 +
27674 +void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
27675 +{
27676 +       if (IS_PCI_ADDRESS(port)) {
27677 +               while (count) {
27678 +                       *(u8_t *)buf = ioread8(port);
27679 +                       buf++;
27680 +                       count--;
27681 +               }
27682 +       } else {
27683 +               insb((unsigned int)port, buf, count);
27684 +       }
27685 +
27686 +}
27687 +EXPORT_SYMBOL(ioread8_rep);
27688 +
27689 +void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
27690 +{
27691 +       if (IS_PCI_ADDRESS(port)) {
27692 +               while (count) {
27693 +                       *(u16_t *)buf = ioread16(port);
27694 +                       buf += 2;
27695 +                       count--;
27696 +               }
27697 +       } else {
27698 +               insw((unsigned int)port, buf, count);
27699 +       }
27700 +}
27701 +EXPORT_SYMBOL(ioread16_rep);
27702 +
27703 +void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
27704 +{
27705 +        if (IS_PCI_ADDRESS(port)) {
27706 +               while (count) {
27707 +                       *(u32_t *)buf = ioread32(port);
27708 +                       buf += 4;
27709 +                       count--;
27710 +               }
27711 +       } else {
27712 +               insl((unsigned int)port, buf, count);
27713 +       }
27714 +}
27715 +EXPORT_SYMBOL(ioread32_rep);
27716 +
27717 +void  iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
27718 +{
27719 +         if (IS_PCI_ADDRESS(port)) {
27720 +               while (count) {
27721 +                       iowrite8(*(u8_t *)buf, port);
27722 +                       buf++;
27723 +                       count--;
27724 +               }
27725 +       } else {
27726 +               outsb((unsigned int)port, buf, count);
27727 +       }
27728 +
27729 +}
27730 +EXPORT_SYMBOL(iowrite8_rep);
27731 +
27732 +void  iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
27733 +{
27734 +       if (IS_PCI_ADDRESS(port)) {
27735 +               while (count) {
27736 +                       iowrite16(*(u16_t *)buf, port);
27737 +                       buf += 2;
27738 +                       count--;
27739 +               }
27740 +       } else {
27741 +               outsw((unsigned int)port, buf, count);
27742 +       }
27743 +}
27744 +EXPORT_SYMBOL(iowrite16_rep);
27745 +
27746 +void  iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
27747 +{
27748 +       if (IS_PCI_ADDRESS(port)) {
27749 +               while (count) {
27750 +                       iowrite32(*(u32_t *)buf, port);
27751 +                       buf += 4;
27752 +                       count--;
27753 +               }
27754 +       } else {
27755 +               outsl((unsigned int)port, buf, count);
27756 +       }
27757 +}
27758 +EXPORT_SYMBOL(iowrite32_rep);
27759 +
27760 +#endif /* CONFIG_PCI */
27761 --- /dev/null
27762 +++ b/arch/ubicom32/mach-common/Makefile
27763 @@ -0,0 +1,38 @@
27764 +#
27765 +# arch/ubicom32/mach-common/Makefile
27766 +#      Makefile for Ubicom32 generic drivers/code.
27767 +#
27768 +# (C) Copyright 2009, Ubicom, Inc.
27769 +#
27770 +# This file is part of the Ubicom32 Linux Kernel Port.
27771 +#
27772 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
27773 +# it and/or modify it under the terms of the GNU General Public License
27774 +# as published by the Free Software Foundation, either version 2 of the
27775 +# License, or (at your option) any later version.
27776 +#
27777 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
27778 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
27779 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27780 +# the GNU General Public License for more details.
27781 +#
27782 +# You should have received a copy of the GNU General Public License
27783 +# along with the Ubicom32 Linux Kernel Port.  If not, 
27784 +# see <http://www.gnu.org/licenses/>.
27785 +#
27786 +# Ubicom32 implementation derived from (with many thanks):
27787 +#   arch/m68knommu
27788 +#   arch/blackfin
27789 +#   arch/parisc
27790 +#
27791 +
27792 +obj-y += cachectl.o common.o usb_tio.o usb.o ubi32-gpio.o board.o bootargs.o
27793 +obj-$(CONFIG_PCI) += pci.o io.o
27794 +
27795 +obj-$(CONFIG_FB_UBICOM32) += vdc_tio.o
27796 +obj-$(CONFIG_UBICOM_HID) += ubicom32hid.o
27797 +obj-$(CONFIG_UBICOM_INPUT) += ubicom32input.o
27798 +obj-$(CONFIG_UBICOM_INPUT_I2C) += ubicom32input_i2c.o
27799 +obj-$(CONFIG_UIO_UBICOM32RING) += ring_tio.o
27800 +obj-$(CONFIG_SND_UBI32) += audio_tio.o
27801 +
27802 --- /dev/null
27803 +++ b/arch/ubicom32/mach-common/pci.c
27804 @@ -0,0 +1,1157 @@
27805 +/*
27806 + * arch/ubicom32/mach-common/pci.c
27807 + *     PCI interface management.
27808 + *
27809 + * (C) Copyright 2009, Ubicom, Inc.
27810 + *
27811 + * This file is part of the Ubicom32 Linux Kernel Port.
27812 + *
27813 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
27814 + * it and/or modify it under the terms of the GNU General Public License
27815 + * as published by the Free Software Foundation, either version 2 of the
27816 + * License, or (at your option) any later version.
27817 + *
27818 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
27819 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
27820 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
27821 + * the GNU General Public License for more details.
27822 + *
27823 + * You should have received a copy of the GNU General Public License
27824 + * along with the Ubicom32 Linux Kernel Port.  If not,
27825 + * see <http://www.gnu.org/licenses/>.
27826 + *
27827 + * Ubicom32 implementation derived from (with many thanks):
27828 + *   arch/m68knommu
27829 + *   arch/blackfin
27830 + *   arch/parisc
27831 + */
27832 +
27833 +#include <linux/module.h>
27834 +#include <linux/kernel.h>
27835 +#include <linux/pci.h>
27836 +#include <linux/slab.h>
27837 +#include <linux/init.h>
27838 +#include <linux/io.h>
27839 +#include <linux/seq_file.h>
27840 +#include <linux/proc_fs.h>
27841 +
27842 +#include <asm/devtree.h>
27843 +#include <asm/ip5000.h>
27844 +#include <asm/ubicom32-common.h>
27845 +
27846 +static int debug_pci = 1 ;
27847 +
27848 +/* #define PCI_USE_INTERNAL_LOCK 1 */
27849 +
27850 +#ifdef PCI_USE_INTERNAL_LOCK
27851 +#define PCI_LOCK(lock, irqflag)        pci_lock_acquire(irqflag)
27852 +#define PCI_UNLOCK(lock, irqflag) pci_lock_release(irqflag)
27853 +#elif defined(CONFIG_SMP)
27854 +static DEFINE_SPINLOCK(pci_master_lock);
27855 +#define PCI_LOCK(lock, irqflag)        spin_lock_irqsave(lock, irqflag)
27856 +#define PCI_UNLOCK(lock, irqflag) spin_unlock_irqrestore(lock, irqflag)
27857 +#else
27858 +#define PCI_LOCK(lock, irqflag)                local_irq_save(irqflag)
27859 +#define PCI_UNLOCK(lock, irqflag)      local_irq_restore(irqflag)
27860 +#endif
27861 +
27862 +#define PCI_DEV0_IDSEL CONFIG_PCI_DEV0_IDSEL
27863 +#define PCI_DEV1_IDSEL CONFIG_PCI_DEV1_IDSEL
27864 +
27865 +/*
27866 + * PCI commands
27867 + */
27868 +#define PCI_CMD_INT_ACK                0x00    /* not supported */
27869 +#define PCI_CMD_SPECIAL                0x01    /* not supported */
27870 +#define PCI_CMD_IO_READ                0x02
27871 +#define PCI_CMD_IO_WRITE       0x03
27872 +#define PCI_CMD_MEM_READ       0x06
27873 +#define PCI_CMD_MEM_WRITE      0x07
27874 +#define PCI_CMD_CFG_READ       0x0a
27875 +#define PCI_CMD_CFG_WRITE      0x0b
27876 +#define PCI_CMD_MEM_READ_MULT  0x0c    /* not supported */
27877 +#define PCI_CMD_DUAL_ADDR      0x0d    /* not supported */
27878 +#define PCI_CMD_MEM_READ_LINE  0x0e    /* not supported */
27879 +#define PCI_CMD_MEM_WRITE_INVAL        0x0f    /* not supported */
27880 +/*
27881 + * Status codes, returned by pci_read_u32() and pci_write_u32()
27882 + */
27883 +#define PCI_RESP_IN_PROGRESS   0xff  /* request still in queue */
27884 +#define PCI_RESP_OK            0
27885 +/*
27886 + * The following codes indicate that the request has completed
27887 + */
27888 +#define PCI_RESP_NO_DEVSEL             1  /* timeout before target asserted
27889 +                                           * DEVSEL! */
27890 +#define PCI_RESP_LOST_DEVSEL           2  /* had DEVSEL, but went away before
27891 +                                           * transfer completed! */
27892 +#define PCI_RESP_BAD_TRDY              3  /* target asserted TRDY without
27893 +                                           * DEVSEL! */
27894 +#define PCI_RESP_NO_TRDY               4  /* timeout before target asserted
27895 +                                           * TRDY! */
27896 +#define PCI_RESP_BAD_STOP              5  /* target asserted STOP and TRDY
27897 +                                           * without DEVSEL! */
27898 +#define PCI_RESP_TARGET_ABORT          6
27899 +#define PCI_RESP_TARGET_RETRY          7
27900 +#define        PCI_RESP_TARGET_DISCONNECT      8
27901 +#define PCI_RESP_MISMATCH              9  /* data read back doesn't match data
27902 +                                           * written - debug only, the core PCI
27903 +                                           * routines never return this */
27904 +#define PCI_RESP_DET_SERR              10
27905 +#define PCI_RESP_DET_PERR              11
27906 +#define PCI_RESP_MALFORMED_REQ         12 /* Could be due to misaligned
27907 +                                           * requests or invalid address */
27908 +#define PCI_RESP_NO_RESOURCE           13 /* Could be memory or other resourse
27909 +                                           * like queue space */
27910 +#define PCI_RESP_ERROR                 14 /* All emcompassing error */
27911 +
27912 +/* registers in PCI config space */
27913 +#define PCI_DEVICE_VENDOR_ID_REG       0x00
27914 +#define PCI_STATUS_COMMAND_REG         0x04
27915 +#define PCI_CLASS_REVISION_REG         0x08
27916 +#define PCI_BHLC_REG                   0x0c  /* BIST, Header type, Latency
27917 +                                              * timer, Cache line size */
27918 +#define PCI_BASE_ADDR_REG              0x10
27919 +#define PCI_BASE_REG_COUNT             6
27920 +#define CARDBUS_CIS_PTR_REG            0x28
27921 +#define PCI_SUB_SYSTEM_ID_REG          0x2c
27922 +#define PCI_EXP_ROM_ADDR_REG           0x30
27923 +#define PCI_CAP_PTR_REG                        0x34
27924 +#define PCI_LGPL_REG                   0x3C  /* max Latency, min Gnt, interrupt
27925 +                                              * Pin, interrupt Line */
27926 +
27927 +struct pci_master_request {
27928 +       volatile u32_t pci_address;     /* must be 4-byte aligned */
27929 +       volatile u32_t data;            /* must be 4-byte aligned */
27930 +       volatile u8_t cmd;
27931 +       volatile u8_t byte_valid;
27932 +       volatile u8_t status;
27933 +};
27934 +
27935 +struct pci_devnode {
27936 +       struct devtree_node dn;
27937 +       u32_t pci_idsel_0;
27938 +       u32_t pci_idsel_1;
27939 +       u32_t pci_cpu_address;
27940 +       struct pci_master_request volatile *volatile req;
27941 +};
27942 +
27943 +static struct pci_master_request req;  /* globally used for faster master write
27944 +                                        * (discarding result when possible) */
27945 +static struct pci_devnode *pci_node;
27946 +
27947 +#if !defined(CONFIG_DEBUG_PCIMEASURE)
27948 +#define PCI_DECLARE_MEASUREMENT
27949 +#define PCI_MEASUREMENT_START()
27950 +#define PCI_MEASUREMENT_END(idx)
27951 +#else
27952 +#define PCI_DECLARE_MEASUREMENT \
27953 +       int __diff;             \
27954 +       unsigned int __tstart;
27955 +
27956 +#define PCI_MEASUREMENT_START() \
27957 +       __tstart = UBICOM32_IO_TIMER->sysval;
27958 +
27959 +#define PCI_MEASUREMENT_END(idx) \
27960 +       __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
27961 +       pci_measurement_update((idx), __diff);
27962 +
27963 +#define PCI_WEIGHT 32
27964 +
27965 +struct pci_measurement {
27966 +       volatile unsigned int min;
27967 +       volatile unsigned int avg;
27968 +       volatile unsigned int max;
27969 +};
27970 +
27971 +enum pci_measurement_list {
27972 +       PCI_MEASUREMENT_READ32,
27973 +       PCI_MEASUREMENT_WRITE32,
27974 +       PCI_MEASUREMENT_READ16,
27975 +       PCI_MEASUREMENT_WRITE16,
27976 +       PCI_MEASUREMENT_READ8,
27977 +       PCI_MEASUREMENT_WRITE8,
27978 +       PCI_MEASUREMENT_LAST,
27979 +};
27980 +
27981 +static const char *pci_measurement_name_list[PCI_MEASUREMENT_LAST] = {
27982 +       "READ32",
27983 +       "WRITE32",
27984 +       "READ16",
27985 +       "WRITE16",
27986 +       "READ8",
27987 +       "WRITE8"
27988 +};
27989 +static struct pci_measurement pci_measurements[PCI_MEASUREMENT_LAST];
27990 +
27991 +/*
27992 + * pci_measurement_update()
27993 + *     Update an entry in the measurement array for this idx.
27994 + */
27995 +static void pci_measurement_update(int idx, int sample)
27996 +{
27997 +       struct pci_measurement *pm = &pci_measurements[idx];
27998 +       if ((pm->min == 0) || (pm->min > sample)) {
27999 +               pm->min = sample;
28000 +       }
28001 +       if (pm->max < sample) {
28002 +               pm->max = sample;
28003 +       }
28004 +       pm->avg = ((pm->avg * (PCI_WEIGHT - 1)) + sample) / PCI_WEIGHT;
28005 +}
28006 +#endif
28007 +
28008 +#if defined(PCI_USE_INTERNAL_LOCK)
28009 +/*
28010 + * pci_lock_release()
28011 + *     Release the PCI lock.
28012 + */
28013 +static void pci_lock_release(unsigned long irqflag)
28014 +{
28015 +       UBICOM32_UNLOCK(PCI_LOCK_BIT);
28016 +}
28017 +
28018 +/*
28019 + * pci_lock_acquire()
28020 + *     Acquire the PCI lock, spin if not available.
28021 + */
28022 +static void pci_lock_acquire(unsigned long irqflag)
28023 +{
28024 +       UBICOM32_LOCK(PCI_LOCK_BIT);
28025 +}
28026 +#endif
28027 +
28028 +/*
28029 + * pci_set_hrt_interrupt()
28030 + */
28031 +static inline void pci_set_hrt_interrupt(struct pci_devnode *pci_node)
28032 +{
28033 +       ubicom32_set_interrupt(pci_node->dn.sendirq);
28034 +}
28035 +
28036 +/*
28037 + * pci_read_u32()
28038 + *     Synchronously read 32 bits from PCI space.
28039 + */
28040 +u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data)
28041 +{
28042 +       u8 status;
28043 +       unsigned long irqflag;
28044 +
28045 +
28046 +       /*
28047 +        * Fill in the request.
28048 +        */
28049 +       volatile struct pci_master_request lreq;
28050 +       PCI_DECLARE_MEASUREMENT;
28051 +
28052 +       lreq.pci_address = address;
28053 +       lreq.cmd = pci_cmd;
28054 +       lreq.byte_valid = 0xf;          /* enable all bytes */
28055 +
28056 +       /*
28057 +        * Wait for any previous request to complete and then make this request.
28058 +        */
28059 +       PCI_MEASUREMENT_START();
28060 +       PCI_LOCK(&pci_master_lock, irqflag);
28061 +       while (unlikely(pci_node->req == &req))
28062 +               ;
28063 +       pci_node->req = &lreq;
28064 +       pci_set_hrt_interrupt(pci_node);
28065 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28066 +
28067 +       /*
28068 +        * Wait for the result to show up.
28069 +        */
28070 +       while (unlikely(pci_node->req == &lreq))
28071 +               ;
28072 +       status = lreq.status;
28073 +       if (likely(status == PCI_RESP_OK))
28074 +               *data = le32_to_cpu(lreq.data);
28075 +       else
28076 +               *data = 0;
28077 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ32);
28078 +       return status;
28079 +}
28080 +
28081 +/*
28082 + * pci_write_u32()
28083 + *     Asyncrhnously or synchronously write 32 bits to PCI master space.
28084 + */
28085 +u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data)
28086 +{
28087 +       unsigned long irqflag;
28088 +       PCI_DECLARE_MEASUREMENT;
28089 +
28090 +       /*
28091 +        * Wait for any previous write or pending read to complete.
28092 +        *
28093 +        * We use a global data block because once we write the request
28094 +        * we do not wait for it to complete before exiting.
28095 +        */
28096 +       PCI_MEASUREMENT_START();
28097 +       PCI_LOCK(&pci_master_lock, irqflag);
28098 +       while (unlikely(pci_node->req == &req))
28099 +               ;
28100 +       req.pci_address = address;
28101 +       req.data = cpu_to_le32(data);
28102 +       req.cmd = pci_cmd;
28103 +       req.byte_valid = 0xf;           /* enable all bytes */
28104 +       pci_node->req = &req;
28105 +       pci_set_hrt_interrupt(pci_node);
28106 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28107 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE32);
28108 +       return PCI_RESP_OK;
28109 +}
28110 +
28111 +/*
28112 + * pci_read_u16()
28113 + *     Synchronously read 16 bits from PCI space.
28114 + */
28115 +u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data)
28116 +{
28117 +       u8 status;
28118 +       unsigned long irqflag;
28119 +
28120 +       /*
28121 +        * Fill in the request.
28122 +        */
28123 +       volatile struct pci_master_request lreq;
28124 +       PCI_DECLARE_MEASUREMENT;
28125 +
28126 +       lreq.pci_address = address & ~2;
28127 +       lreq.cmd = pci_cmd;
28128 +       lreq.byte_valid = (address & 2) ? 0xc : 0x3;
28129 +
28130 +       /*
28131 +        * Wait for any previous request to complete and then make this request.
28132 +        */
28133 +       PCI_MEASUREMENT_START();
28134 +       PCI_LOCK(&pci_master_lock, irqflag);
28135 +       while (unlikely(pci_node->req == &req))
28136 +               ;
28137 +       pci_node->req = &lreq;
28138 +       pci_set_hrt_interrupt(pci_node);
28139 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28140 +
28141 +       /*
28142 +        * Wait for the result to show up.
28143 +        */
28144 +       while (unlikely(pci_node->req == &lreq))
28145 +               ;
28146 +       status = lreq.status;
28147 +       if (likely(status == PCI_RESP_OK)) {
28148 +               lreq.data = le32_to_cpu(lreq.data);
28149 +               *data = (u16)((address & 2) ? (lreq.data >> 16) : lreq.data);
28150 +       } else
28151 +               *data = 0;
28152 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ16);
28153 +       return status;
28154 +}
28155 +
28156 +/*
28157 + * pci_write_u16()
28158 + *     Asyncrhnously or synchronously write 16 bits to PCI master space.
28159 + */
28160 +u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data)
28161 +{
28162 +       unsigned long irqflag;
28163 +       PCI_DECLARE_MEASUREMENT;
28164 +
28165 +       /*
28166 +        * Wait for any previous write or pending read to complete.
28167 +        *
28168 +        * We use a global data block because once we write the request
28169 +        * we do not wait for it to complete before exiting.
28170 +        */
28171 +       PCI_MEASUREMENT_START();
28172 +       PCI_LOCK(&pci_master_lock, irqflag);
28173 +       while (unlikely(pci_node->req == &req))
28174 +               ;
28175 +       req.pci_address = address & ~2;
28176 +       req.data = (u32)data;
28177 +       req.data = cpu_to_le32((address & 2) ? (req.data << 16) : req.data);
28178 +       req.cmd = pci_cmd;
28179 +       req.byte_valid = (address & 2) ? 0xc : 0x3;
28180 +       pci_node->req = &req;
28181 +       pci_set_hrt_interrupt(pci_node);
28182 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28183 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE16);
28184 +       return PCI_RESP_OK;
28185 +}
28186 +
28187 +/*
28188 + * pci_read_u8()
28189 + *     Synchronously read 8 bits from PCI space.
28190 + */
28191 +u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data)
28192 +{
28193 +       u8 status;
28194 +       unsigned long irqflag;
28195 +
28196 +       /*
28197 +        * Fill in the request.
28198 +        */
28199 +       volatile struct pci_master_request lreq;
28200 +       PCI_DECLARE_MEASUREMENT;
28201 +
28202 +       lreq.pci_address = address & ~3;
28203 +       lreq.cmd = pci_cmd;
28204 +       lreq.byte_valid = 1 << (address & 0x3);
28205 +
28206 +       /*
28207 +        * Wait for any previous request to complete and then make this request.
28208 +        */
28209 +       PCI_MEASUREMENT_START();
28210 +       PCI_LOCK(&pci_master_lock, irqflag);
28211 +       while (unlikely(pci_node->req == &req))
28212 +               ;
28213 +       pci_node->req = &lreq;
28214 +       pci_set_hrt_interrupt(pci_node);
28215 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28216 +
28217 +       /*
28218 +        * Wait for the result to show up.
28219 +        */
28220 +       while (unlikely(pci_node->req == &lreq))
28221 +               ;
28222 +       status = lreq.status;
28223 +       if (likely(status == PCI_RESP_OK)) {
28224 +               *data = (u8)(lreq.data >> (24 - ((address & 0x3) << 3)));
28225 +       } else
28226 +               *data = 0;
28227 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ8);
28228 +       return status;
28229 +}
28230 +
28231 +/*
28232 + * pci_write_u8()
28233 + *     Asyncrhnously or synchronously write 8 bits to PCI master space.
28234 + */
28235 +u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data)
28236 +{
28237 +       unsigned long irqflag;
28238 +       PCI_DECLARE_MEASUREMENT;
28239 +
28240 +       /*
28241 +        * Wait for any previous write or pending read to complete.
28242 +        *
28243 +        * We use a global data block because once we write the request
28244 +        * we do not wait for it to complete before exiting.
28245 +        */
28246 +       PCI_MEASUREMENT_START();
28247 +       PCI_LOCK(&pci_master_lock, irqflag);
28248 +       while (unlikely(pci_node->req == &req))
28249 +               ;
28250 +       req.pci_address = address & ~3;
28251 +       req.data = ((u32)data << (24 - ((address & 0x3) << 3)));
28252 +       req.cmd = pci_cmd;
28253 +       req.byte_valid = 1 << (address & 0x3);
28254 +       pci_node->req = &req;
28255 +       pci_set_hrt_interrupt(pci_node);
28256 +       PCI_UNLOCK(&pci_master_lock, irqflag);
28257 +       PCI_MEASUREMENT_END(PCI_MEASUREMENT_WRITE8);
28258 +       return PCI_RESP_OK;
28259 +}
28260 +
28261 +unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr)
28262 +{
28263 +       unsigned int data;
28264 +       pci_read_u32(PCI_CMD_MEM_READ, (u32)addr, &data);
28265 +       return data;
28266 +}
28267 +EXPORT_SYMBOL(ubi32_pci_read_u32);
28268 +
28269 +unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr)
28270 +{
28271 +       unsigned short data;
28272 +       pci_read_u16(PCI_CMD_MEM_READ, (u32)addr, &data);
28273 +       return data;
28274 +}
28275 +EXPORT_SYMBOL(ubi32_pci_read_u16);
28276 +
28277 +unsigned char  ubi32_pci_read_u8(const volatile void __iomem *addr)
28278 +{
28279 +       unsigned char  data;
28280 +       pci_read_u8(PCI_CMD_MEM_READ, (u32)addr, &data);
28281 +       return data;
28282 +}
28283 +EXPORT_SYMBOL(ubi32_pci_read_u8);
28284 +
28285 +void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr)
28286 +{
28287 +       pci_write_u32(PCI_CMD_MEM_WRITE, (u32)addr, val);
28288 +}
28289 +EXPORT_SYMBOL(ubi32_pci_write_u32);
28290 +
28291 +void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr)
28292 +{
28293 +       pci_write_u16(PCI_CMD_MEM_WRITE, (u32)addr, val);
28294 +}
28295 +EXPORT_SYMBOL(ubi32_pci_write_u16);
28296 +
28297 +void ubi32_pci_write_u8(unsigned char val, const void volatile __iomem *addr)
28298 +{
28299 +       pci_write_u8(PCI_CMD_MEM_WRITE, (u32)addr, val);
28300 +}
28301 +EXPORT_SYMBOL(ubi32_pci_write_u8);
28302 +
28303 +#if defined(CONFIG_DEBUG_PCIMEASURE)
28304 +static unsigned int pci_cycles_to_nano(unsigned int cycles, unsigned int frequency)
28305 +{
28306 +       unsigned int nano = ((cycles * 1000) / (frequency / 1000000));
28307 +       return nano;
28308 +}
28309 +
28310 +/*
28311 + * pci_measurement_show()
28312 + *     Print out the min, avg, max values for each PCI transaction type.
28313 + *
28314 + * By request, the max value is reset after each dump.
28315 + */
28316 +static int pci_measurement_show(struct seq_file *p, void *v)
28317 +{
28318 +       unsigned int min, avg, max;
28319 +       unsigned int freq = processor_frequency();
28320 +       int trans = *((loff_t *) v);
28321 +
28322 +       if (trans == 0) {
28323 +               seq_puts(p, "min\tavg\tmax\t(nano-seconds)\n");
28324 +       }
28325 +
28326 +       if (trans >= PCI_MEASUREMENT_LAST) {
28327 +               return 0;
28328 +       }
28329 +
28330 +       min = pci_cycles_to_nano(pci_measurements[trans].min, freq);
28331 +       avg = pci_cycles_to_nano(pci_measurements[trans].avg, freq);
28332 +       max = pci_cycles_to_nano(pci_measurements[trans].max, freq);
28333 +       pci_measurements[trans].max = 0;
28334 +       seq_printf(p, "%u\t%u\t%u\t%s\n", min, avg, max, pci_measurement_name_list[trans]);
28335 +       return 0;
28336 +}
28337 +
28338 +static void *pci_measurement_start(struct seq_file *f, loff_t *pos)
28339 +{
28340 +       return (*pos < PCI_MEASUREMENT_LAST) ? pos : NULL;
28341 +}
28342 +
28343 +static void *pci_measurement_next(struct seq_file *f, void *v, loff_t *pos)
28344 +{
28345 +       (*pos)++;
28346 +       if (*pos >= PCI_MEASUREMENT_LAST)
28347 +               return NULL;
28348 +       return pos;
28349 +}
28350 +
28351 +static void pci_measurement_stop(struct seq_file *f, void *v)
28352 +{
28353 +       /* Nothing to do */
28354 +}
28355 +
28356 +static const struct seq_operations pci_measurement_seq_ops = {
28357 +       .start = pci_measurement_start,
28358 +       .next  = pci_measurement_next,
28359 +       .stop  = pci_measurement_stop,
28360 +       .show  = pci_measurement_show,
28361 +};
28362 +
28363 +static int pci_measurement_open(struct inode *inode, struct file *filp)
28364 +{
28365 +       return seq_open(filp, &pci_measurement_seq_ops);
28366 +}
28367 +
28368 +static const struct file_operations pci_measurement_fops = {
28369 +       .open           = pci_measurement_open,
28370 +       .read           = seq_read,
28371 +       .llseek         = seq_lseek,
28372 +       .release        = seq_release,
28373 +};
28374 +
28375 +static int __init pci_measurement_init(void)
28376 +{
28377 +       proc_create("pci_measurements", 0, NULL, &pci_measurement_fops);
28378 +       return 0;
28379 +}
28380 +module_init(pci_measurement_init);
28381 +#endif
28382 +
28383 +static int ubi32_pci_read_config(struct pci_bus *bus, unsigned int devfn,
28384 +                                int where, int size, u32 *value)
28385 +{
28386 +       u8 cmd;
28387 +       u32 addr;
28388 +       u8  data8;
28389 +       u16 data16;
28390 +
28391 +       u8 slot = PCI_SLOT(devfn);
28392 +       u8 fn = PCI_FUNC(devfn);
28393 +
28394 +       if (slot > 1) {
28395 +               return PCIBIOS_DEVICE_NOT_FOUND;
28396 +       } else if (slot == 0) {
28397 +               addr = PCI_DEV0_IDSEL + where;
28398 +       } else {
28399 +               addr = PCI_DEV1_IDSEL + where;
28400 +       }
28401 +
28402 +       addr += (fn << 8);
28403 +
28404 +       cmd = PCI_CMD_CFG_READ;
28405 +       if (size == 1) {
28406 +               pci_read_u8(cmd, addr, &data8);
28407 +               *value = (u32)data8;
28408 +       } else if (size == 2) {
28409 +               pci_read_u16(cmd, addr, &data16);
28410 +               *value = (u32)data16;
28411 +       } else {
28412 +               pci_read_u32(cmd, addr, value);
28413 +       }
28414 +
28415 +       return PCIBIOS_SUCCESSFUL;
28416 +}
28417 +
28418 +static int ubi32_pci_write_config(struct pci_bus *bus, unsigned int devfn,
28419 +                                 int where, int size, u32 value)
28420 +{
28421 +       u8 cmd;
28422 +       u32 addr;
28423 +       u8 slot = PCI_SLOT(devfn);
28424 +       u8 fn = PCI_FUNC(devfn);
28425 +
28426 +       if (slot > 1) {
28427 +               return PCIBIOS_DEVICE_NOT_FOUND;
28428 +       } else if (slot == 0) {
28429 +               addr = PCI_DEV0_IDSEL + where;
28430 +       } else {
28431 +               addr = PCI_DEV1_IDSEL + where;
28432 +       }
28433 +
28434 +       addr += (fn << 8);
28435 +
28436 +       cmd = PCI_CMD_CFG_WRITE;
28437 +       if (size == 1) {
28438 +               pci_write_u8(cmd, addr, (u8)value);
28439 +       } else if (size == 2) {
28440 +               pci_write_u16(cmd, addr, (u16)value);
28441 +       } else {
28442 +               pci_write_u32(cmd, addr, value);
28443 +       }
28444 +
28445 +       return PCIBIOS_SUCCESSFUL;
28446 +}
28447 +
28448 +int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
28449 +{
28450 +       return -EIO;
28451 +}
28452 +EXPORT_SYMBOL(pci_set_dma_max_seg_size);
28453 +
28454 +int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
28455 +{
28456 +       return -EIO;
28457 +}
28458 +EXPORT_SYMBOL(pci_set_dma_seg_boundary);
28459 +
28460 +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
28461 +{
28462 +       resource_size_t start = pci_resource_start(dev, bar);
28463 +       resource_size_t len   = pci_resource_len(dev, bar);
28464 +       unsigned long flags = pci_resource_flags(dev, bar);
28465 +
28466 +       if (!len || !start) {
28467 +               return NULL;
28468 +       }
28469 +
28470 +       if (maxlen && len > maxlen) {
28471 +               len = maxlen;
28472 +       }
28473 +
28474 +       if (flags & IORESOURCE_IO) {
28475 +               return ioport_map(start, len);
28476 +       }
28477 +
28478 +       if (flags & IORESOURCE_MEM) {
28479 +               if (flags & IORESOURCE_CACHEABLE) {
28480 +                       return ioremap(start, len);
28481 +               }
28482 +               return ioremap_nocache(start, len);
28483 +       }
28484 +       return NULL;
28485 +}
28486 +EXPORT_SYMBOL(pci_iomap);
28487 +
28488 +void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
28489 +{
28490 +       if ((unsigned long)addr >= VMALLOC_START &&
28491 +           (unsigned long)addr < VMALLOC_END) {
28492 +               iounmap(addr);
28493 +       }
28494 +}
28495 +EXPORT_SYMBOL(pci_iounmap);
28496 +
28497 +/*
28498 + *  From arch/arm/kernel/bios32.c
28499 + *
28500 + *  PCI bios-type initialisation for PCI machines
28501 + *
28502 + *  Bits taken from various places.
28503 + */
28504 +static void __init pcibios_init_hw(struct hw_pci *hw)
28505 +{
28506 +       struct pci_sys_data *sys = NULL;
28507 +       int ret;
28508 +       int nr, busnr;
28509 +
28510 +       for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
28511 +               sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
28512 +               if (!sys)
28513 +                       panic("PCI: unable to allocate sys data!");
28514 +
28515 +               sys->hw      = hw;
28516 +               sys->busnr   = busnr;
28517 +               sys->map_irq = hw->map_irq;
28518 +               sys->resource[0] = &ioport_resource;
28519 +               sys->resource[1] = &iomem_resource;
28520 +
28521 +               ret = hw->setup(nr, sys);
28522 +
28523 +               if (ret > 0) {
28524 +                       sys->bus = hw->scan(nr, sys);
28525 +
28526 +                       if (!sys->bus)
28527 +                               panic("PCI: unable to scan bus!");
28528 +
28529 +                       busnr = sys->bus->subordinate + 1;
28530 +
28531 +                       list_add(&sys->node, &hw->buses);
28532 +               } else {
28533 +                       kfree(sys);
28534 +                       if (ret < 0)
28535 +                               break;
28536 +               }
28537 +       }
28538 +}
28539 +
28540 +/*
28541 + * Swizzle the device pin each time we cross a bridge.
28542 + * This might update pin and returns the slot number.
28543 + */
28544 +static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin)
28545 +{
28546 +       struct pci_sys_data *sys = dev->sysdata;
28547 +       int slot = 0, oldpin = *pin;
28548 +
28549 +       if (sys->swizzle)
28550 +               slot = sys->swizzle(dev, pin);
28551 +
28552 +       if (debug_pci)
28553 +               printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
28554 +                       pci_name(dev), oldpin, *pin, slot);
28555 +       return slot;
28556 +}
28557 +
28558 +/*
28559 + * Map a slot/pin to an IRQ.
28560 + */
28561 +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28562 +{
28563 +       struct pci_sys_data *sys = dev->sysdata;
28564 +       int irq = -1;
28565 +
28566 +       if (sys->map_irq)
28567 +               irq = sys->map_irq(dev, slot, pin);
28568 +
28569 +       if (debug_pci)
28570 +               printk("PCI: %s mapping slot %d pin %d => irq %d\n",
28571 +                       pci_name(dev), slot, pin, irq);
28572 +
28573 +       return irq;
28574 +}
28575 +
28576 +void __init pci_common_init(struct hw_pci *hw)
28577 +{
28578 +       struct pci_sys_data *sys;
28579 +
28580 +       INIT_LIST_HEAD(&hw->buses);
28581 +
28582 +       if (hw->preinit)
28583 +               hw->preinit();
28584 +       pcibios_init_hw(hw);
28585 +       if (hw->postinit)
28586 +               hw->postinit();
28587 +
28588 +       pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
28589 +       list_for_each_entry(sys, &hw->buses, node) {
28590 +               struct pci_bus *bus = sys->bus;
28591 +               /*
28592 +                * Size the bridge windows.
28593 +                */
28594 +               pci_bus_size_bridges(bus);
28595 +               /*
28596 +                * Assign resources.
28597 +                */
28598 +               pci_bus_assign_resources(bus);
28599 +
28600 +               /*
28601 +                * Tell drivers about devices found.
28602 +                */
28603 +               pci_bus_add_devices(bus);
28604 +       }
28605 +}
28606 +
28607 +char * __init pcibios_setup(char *str)
28608 +{
28609 +       if (!strcmp(str, "debug")) {
28610 +               debug_pci = 1;
28611 +               return NULL;
28612 +       }
28613 +       return str;
28614 +}
28615 +
28616 +/*
28617 + * From arch/i386/kernel/pci-i386.c:
28618 + *
28619 + * We need to avoid collisions with `mirrored' VGA ports
28620 + * and other strange ISA hardware, so we always want the
28621 + * addresses to be allocated in the 0x000-0x0ff region
28622 + * modulo 0x400.
28623 + *
28624 + * Why? Because some silly external IO cards only decode
28625 + * the low 10 bits of the IO address. The 0x00-0xff region
28626 + * is reserved for motherboard devices that decode all 16
28627 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
28628 + * but we want to try to avoid allocating at 0x2900-0x2bff
28629 + * which might be mirrored at 0x0100-0x03ff..
28630 + */
28631 +void pcibios_align_resource(void *data, struct resource *res,
28632 +                           resource_size_t size, resource_size_t align)
28633 +{
28634 +       resource_size_t start = res->start;
28635 +
28636 +       if (res->flags & IORESOURCE_IO && start & 0x300)
28637 +               start = (start + 0x3ff) & ~0x3ff;
28638 +
28639 +       res->start = (start + align - 1) & ~(align - 1);
28640 +}
28641 +
28642 +
28643 +void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
28644 +{
28645 +       if (debug_pci)
28646 +               printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
28647 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
28648 +}
28649 +
28650 +/*
28651 + * If the bus contains any of these devices, then we must not turn on
28652 + * parity checking of any kind.  Currently this is CyberPro 20x0 only.
28653 + */
28654 +static inline int pdev_bad_for_parity(struct pci_dev *dev)
28655 +{
28656 +       return (dev->vendor == PCI_VENDOR_ID_INTERG &&
28657 +               (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
28658 +                dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
28659 +               (dev->vendor == PCI_VENDOR_ID_ITE &&
28660 +                dev->device == PCI_DEVICE_ID_ITE_8152);
28661 +
28662 +}
28663 +
28664 +/*
28665 + * Adjust the device resources from bus-centric to Linux-centric.
28666 + */
28667 +static void __devinit
28668 +pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
28669 +{
28670 +       resource_size_t offset;
28671 +       int i;
28672 +
28673 +       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
28674 +               if (dev->resource[i].start == 0)
28675 +                       continue;
28676 +               if (dev->resource[i].flags & IORESOURCE_MEM)
28677 +                       offset = root->mem_offset;
28678 +               else
28679 +                       offset = root->io_offset;
28680 +
28681 +               dev->resource[i].start += offset;
28682 +               dev->resource[i].end   += offset;
28683 +       }
28684 +}
28685 +
28686 +static void __devinit
28687 +pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
28688 +{
28689 +       struct pci_dev *dev = bus->self;
28690 +       int i;
28691 +
28692 +       if (!dev) {
28693 +               /*
28694 +                * Assign root bus resources.
28695 +                */
28696 +               for (i = 0; i < 3; i++)
28697 +                       bus->resource[i] = root->resource[i];
28698 +       }
28699 +}
28700 +
28701 +/*
28702 + * pcibios_fixup_bus - Called after each bus is probed,
28703 + * but before its children are examined.
28704 + */
28705 +void pcibios_fixup_bus(struct pci_bus *bus)
28706 +{
28707 +       struct pci_sys_data *root = bus->sysdata;
28708 +       struct pci_dev *dev;
28709 +       u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
28710 +               PCI_COMMAND_FAST_BACK;
28711 +
28712 +       pbus_assign_bus_resources(bus, root);
28713 +
28714 +       /*
28715 +        * Walk the devices on this bus, working out what we can
28716 +        * and can't support.
28717 +        */
28718 +       list_for_each_entry(dev, &bus->devices, bus_list) {
28719 +               u16 status;
28720 +
28721 +               pdev_fixup_device_resources(root, dev);
28722 +
28723 +               pci_read_config_word(dev, PCI_STATUS, &status);
28724 +
28725 +               /*
28726 +                * If any device on this bus does not support fast back
28727 +                * to back transfers, then the bus as a whole is not able
28728 +                * to support them.  Having fast back to back transfers
28729 +                * on saves us one PCI cycle per transaction.
28730 +                */
28731 +               if (!(status & PCI_STATUS_FAST_BACK))
28732 +                       features &= ~PCI_COMMAND_FAST_BACK;
28733 +
28734 +               if (pdev_bad_for_parity(dev))
28735 +                       features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
28736 +
28737 +               switch (dev->class >> 8) {
28738 +               case PCI_CLASS_BRIDGE_PCI:
28739 +                       pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status);
28740 +                       status |= PCI_BRIDGE_CTL_PARITY |
28741 +                               PCI_BRIDGE_CTL_MASTER_ABORT;
28742 +                       status &= ~(PCI_BRIDGE_CTL_BUS_RESET |
28743 +                                   PCI_BRIDGE_CTL_FAST_BACK);
28744 +                       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status);
28745 +                       break;
28746 +
28747 +               case PCI_CLASS_BRIDGE_CARDBUS:
28748 +                       pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28749 +                                            &status);
28750 +                       status |= PCI_CB_BRIDGE_CTL_PARITY |
28751 +                               PCI_CB_BRIDGE_CTL_MASTER_ABORT;
28752 +                       pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28753 +                                             status);
28754 +                       break;
28755 +               }
28756 +       }
28757 +
28758 +       /*
28759 +        * Now walk the devices again, this time setting them up.
28760 +        */
28761 +       list_for_each_entry(dev, &bus->devices, bus_list) {
28762 +               u16 cmd;
28763 +
28764 +               pci_read_config_word(dev, PCI_COMMAND, &cmd);
28765 +               cmd |= features;
28766 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
28767 +
28768 +               pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
28769 +                                     L1_CACHE_BYTES >> 2);
28770 +       }
28771 +
28772 +       /*
28773 +        * Propagate the flags to the PCI bridge.
28774 +        */
28775 +       if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
28776 +               if (features & PCI_COMMAND_FAST_BACK)
28777 +                       bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK;
28778 +               if (features & PCI_COMMAND_PARITY)
28779 +                       bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY;
28780 +       }
28781 +
28782 +       /*
28783 +        * Report what we did for this bus
28784 +        */
28785 +       printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
28786 +               bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
28787 +}
28788 +/*
28789 + * Convert from Linux-centric to bus-centric addresses for bridge devices.
28790 + */
28791 +void
28792 +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
28793 +                        struct resource *res)
28794 +{
28795 +       struct pci_sys_data *root = dev->sysdata;
28796 +       unsigned long offset = 0;
28797 +
28798 +       if (res->flags & IORESOURCE_IO)
28799 +               offset = root->io_offset;
28800 +       if (res->flags & IORESOURCE_MEM)
28801 +               offset = root->mem_offset;
28802 +
28803 +       region->start = res->start - offset;
28804 +       region->end   = res->end - offset;
28805 +}
28806 +
28807 +void __devinit
28808 +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
28809 +                       struct pci_bus_region *region)
28810 +{
28811 +       struct pci_sys_data *root = dev->sysdata;
28812 +       unsigned long offset = 0;
28813 +
28814 +       if (res->flags & IORESOURCE_IO)
28815 +               offset = root->io_offset;
28816 +       if (res->flags & IORESOURCE_MEM)
28817 +               offset = root->mem_offset;
28818 +
28819 +       res->start = region->start + offset;
28820 +       res->end   = region->end + offset;
28821 +}
28822 +
28823 +#ifdef CONFIG_HOTPLUG
28824 +EXPORT_SYMBOL(pcibios_fixup_bus);
28825 +EXPORT_SYMBOL(pcibios_resource_to_bus);
28826 +EXPORT_SYMBOL(pcibios_bus_to_resource);
28827 +#endif
28828 +
28829 +/**
28830 + * pcibios_enable_device - Enable I/O and memory.
28831 + * @dev: PCI device to be enabled
28832 + */
28833 +int pcibios_enable_device(struct pci_dev *dev, int mask)
28834 +{
28835 +       u16 cmd, old_cmd;
28836 +       int idx;
28837 +       struct resource *r;
28838 +
28839 +       pci_read_config_word(dev, PCI_COMMAND, &cmd);
28840 +       old_cmd = cmd;
28841 +       for (idx = 0; idx < 6; idx++) {
28842 +               /* Only set up the requested stuff */
28843 +               if (!(mask & (1 << idx)))
28844 +                       continue;
28845 +
28846 +               r = dev->resource + idx;
28847 +               if (!r->start && r->end) {
28848 +                       printk(KERN_ERR "PCI: Device %s not available because"
28849 +                              " of resource collisions\n", pci_name(dev));
28850 +                       return -EINVAL;
28851 +               }
28852 +               if (r->flags & IORESOURCE_IO)
28853 +                       cmd |= PCI_COMMAND_IO;
28854 +               if (r->flags & IORESOURCE_MEM)
28855 +                       cmd |= PCI_COMMAND_MEMORY;
28856 +       }
28857 +
28858 +       /*
28859 +        * Bridges (eg, cardbus bridges) need to be fully enabled
28860 +        */
28861 +       if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
28862 +               cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
28863 +
28864 +       if (cmd != old_cmd) {
28865 +               printk("PCI: enabling device %s (%04x -> %04x)\n",
28866 +                      pci_name(dev), old_cmd, cmd);
28867 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
28868 +       }
28869 +       return 0;
28870 +}
28871 +
28872 +
28873 +struct pci_ops ubi32_pci_ops = {
28874 +       .read   = ubi32_pci_read_config,
28875 +       .write  = ubi32_pci_write_config,
28876 +};
28877 +
28878 +static struct pci_bus *ubi32_pci_scan_bus(int nr, struct pci_sys_data *sys)
28879 +{
28880 +       return pci_scan_bus(sys->busnr, &ubi32_pci_ops, sys);
28881 +}
28882 +
28883 +#define UBI32_PCI_MEM_BASE PCI_DEV_REG_BASE
28884 +#define UBI32_PCI_MEM_LEN  0x80000000
28885 +
28886 +#define UBI32_PCI_IO_BASE 0x0
28887 +#define UBI32_PCI_IO_END  0x0
28888 +
28889 +static struct resource ubi32_pci_mem = {
28890 +       .name   = "PCI memory space",
28891 +       .start  = UBI32_PCI_MEM_BASE,
28892 +       .end    = UBI32_PCI_MEM_BASE + UBI32_PCI_MEM_LEN - 1,
28893 +       .flags  = IORESOURCE_MEM,
28894 +};
28895 +
28896 +static struct resource ubi32_pci_io = {
28897 +       .name   = "PCI IO space",
28898 +       .start  = UBI32_PCI_IO_BASE,
28899 +       .end    = UBI32_PCI_IO_END,
28900 +       .flags  = IORESOURCE_IO,
28901 +};
28902 +
28903 +static int __init ubi32_pci_setup(int nr, struct pci_sys_data *sys)
28904 +{
28905 +       if (nr > 0)
28906 +               return 0;
28907 +
28908 +       request_resource(&iomem_resource, &ubi32_pci_mem);
28909 +       request_resource(&ioport_resource, &ubi32_pci_io);
28910 +
28911 +       sys->resource[0] = &ubi32_pci_io;
28912 +       sys->resource[1] = &ubi32_pci_mem;
28913 +       sys->resource[2] = NULL;
28914 +
28915 +       return 1;
28916 +}
28917 +
28918 +static void __init ubi32_pci_preinit(void)
28919 +{
28920 +}
28921 +
28922 +static int __init ubi32_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28923 +{
28924 +       return pci_node->dn.recvirq;
28925 +}
28926 +
28927 +struct hw_pci ubi32_pci __initdata = {
28928 +       .nr_controllers = 1,
28929 +       .preinit        = ubi32_pci_preinit,
28930 +       .setup          = ubi32_pci_setup,
28931 +       .scan           = ubi32_pci_scan_bus,
28932 +       .map_irq        = ubi32_pci_map_irq,
28933 +};
28934 +
28935 +static int __init ubi32_pci_init(void)
28936 +{
28937 +       pci_node = (struct pci_devnode *)devtree_find_node("pci");
28938 +       if (pci_node == NULL) {
28939 +               printk(KERN_WARNING "PCI init failed\n");
28940 +               return -ENOSYS;
28941 +       }
28942 +       pci_common_init(&ubi32_pci);
28943 +       return 0;
28944 +}
28945 +
28946 +subsys_initcall(ubi32_pci_init);
28947 +
28948 +/*
28949 + * workaround for dual PCI card interrupt
28950 + */
28951 +#define PCI_COMMON_INT_BIT (1 << 19)
28952 +void ubi32_pci_int_wr(void)
28953 +{
28954 +       volatile unsigned int pci_int_line;
28955 +       pci_int_line = UBICOM32_IO_PORT(RB)->gpio_in;
28956 +       if (!(pci_int_line & PCI_COMMON_INT_BIT))
28957 +       {
28958 +               ubicom32_set_interrupt(pci_node->dn.recvirq);
28959 +       }
28960 +}
28961 +EXPORT_SYMBOL(ubi32_pci_int_wr);
28962 --- /dev/null
28963 +++ b/arch/ubicom32/mach-common/ring_tio.c
28964 @@ -0,0 +1,123 @@
28965 +/*
28966 + * arch/ubicom32/mach-common/ring_tio.c
28967 + *   Generic initialization for UIO Ubicom32 Ring
28968 + *
28969 + * (C) Copyright 2009, Ubicom, Inc.
28970 + *
28971 + * This file is part of the Ubicom32 Linux Kernel Port.
28972 + *
28973 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
28974 + * it and/or modify it under the terms of the GNU General Public License
28975 + * as published by the Free Software Foundation, either version 2 of the
28976 + * License, or (at your option) any later version.
28977 + *
28978 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
28979 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
28980 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
28981 + * the GNU General Public License for more details.
28982 + *
28983 + * You should have received a copy of the GNU General Public License
28984 + * along with the Ubicom32 Linux Kernel Port.  If not,
28985 + * see <http://www.gnu.org/licenses/>.
28986 + */
28987 +
28988 +#include <linux/platform_device.h>
28989 +#include <linux/types.h>
28990 +
28991 +#include <asm/devtree.h>
28992 +#include <asm/ring_tio.h>
28993 +
28994 +static const char *ring_tio_driver_name = "uio_ubicom32ring";
28995 +
28996 +/*
28997 + * The number of ring_tio's currently allocated, used for .id
28998 + */
28999 +static int __initdata ring_tio_count;
29000 +
29001 +/*
29002 + * The maximum number of resources that the ring_tio will have.
29003 + * Currently 3, a register space, and up to 2 interrupts.
29004 + */
29005 +#define RING_TIO_MAX_RESOURCES 3
29006 +
29007 +/*
29008 + * ring_tio_init
29009 + *     Checks the device tree and instantiates the driver if found
29010 + */
29011 +void __init ring_tio_init(const char *node_name)
29012 +{
29013 +       struct platform_device *pdev;
29014 +       struct resource *res;
29015 +       int resource_idx = 0;
29016 +       struct ring_tio_node *ring_node;
29017 +
29018 +       /*
29019 +        * Check the device tree for the ring_tio
29020 +        */
29021 +       ring_node = (struct ring_tio_node *)devtree_find_node(node_name);
29022 +       if (!ring_node) {
29023 +               printk(KERN_WARNING "Ring TIO '%s' not found\n", node_name);
29024 +               return;
29025 +       }
29026 +
29027 +       if (ring_node->version != RING_TIO_NODE_VERSION) {
29028 +               printk(KERN_WARNING "ring_tio not compatible\n");
29029 +               return;
29030 +       }
29031 +
29032 +       /*
29033 +        * Dynamically create the platform_device structure and resources
29034 +        */
29035 +       pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
29036 +       if (!pdev) {
29037 +               printk(KERN_WARNING "ring_tio could not alloc pdev\n");
29038 +               return;
29039 +       }
29040 +
29041 +       res = kzalloc(sizeof(struct resource) * RING_TIO_MAX_RESOURCES,
29042 +                       GFP_KERNEL);
29043 +       if (!res) {
29044 +               kfree(pdev);
29045 +               printk(KERN_WARNING "ring_tio could not alloc res\n");
29046 +               return;
29047 +       }
29048 +
29049 +       pdev->name = ring_tio_driver_name;
29050 +       pdev->id = ring_tio_count++;
29051 +       pdev->resource = res;
29052 +
29053 +       /*
29054 +        * Fill in the resources and platform data from devtree information
29055 +        */
29056 +       res[resource_idx].start = (u32_t)(ring_node->regs);
29057 +       res[resource_idx].end = (u32_t)(ring_node->regs);
29058 +       res[resource_idx].flags = IORESOURCE_MEM;
29059 +       resource_idx++;
29060 +
29061 +       if (ring_node->dn.sendirq != 0xFF) {
29062 +               res[resource_idx].start = ring_node->dn.sendirq;
29063 +               res[resource_idx].flags = IORESOURCE_IRQ;
29064 +               resource_idx++;
29065 +       }
29066 +
29067 +       if (ring_node->dn.recvirq != 0xFF) {
29068 +               res[resource_idx].start = ring_node->dn.recvirq;
29069 +               res[resource_idx].flags = IORESOURCE_IRQ;
29070 +               resource_idx++;
29071 +       }
29072 +       pdev->num_resources = resource_idx;
29073 +
29074 +       printk(KERN_INFO "RingTIO.%d '%s' found irq=%d/%d regs=%p pdev=%p/%p\n",
29075 +               ring_tio_count - 1, node_name, ring_node->dn.sendirq,
29076 +               ring_node->dn.recvirq, ring_node->regs, pdev, res);
29077 +
29078 +       /*
29079 +        * Try to get the device registered
29080 +        */
29081 +       pdev->dev.platform_data = (void *)node_name;
29082 +       if (platform_device_register(pdev) < 0) {
29083 +               printk(KERN_WARNING "Ring failed to register\n");
29084 +               kfree(pdev);
29085 +               kfree(res);
29086 +       }
29087 +}
29088 --- /dev/null
29089 +++ b/arch/ubicom32/mach-common/ubi32-gpio.c
29090 @@ -0,0 +1,411 @@
29091 +/*
29092 + * arch/ubicom32/mach-common/ubi32-gpio.c
29093 + *   Ubicom gpio driver
29094 + *
29095 + * (C) Copyright 2009, Ubicom, Inc.
29096 + *
29097 + * This file is part of the Ubicom32 Linux Kernel Port.
29098 + *
29099 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
29100 + * it and/or modify it under the terms of the GNU General Public License
29101 + * as published by the Free Software Foundation, either version 2 of the
29102 + * License, or (at your option) any later version.
29103 + *
29104 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
29105 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
29106 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
29107 + * the GNU General Public License for more details.
29108 + *
29109 + * You should have received a copy of the GNU General Public License
29110 + * along with the Ubicom32 Linux Kernel Port.  If not,
29111 + * see <http://www.gnu.org/licenses/>.
29112 + *
29113 + * Ubicom32 implementation derived from (with many thanks):
29114 + *   arch/m68knommu
29115 + *   arch/blackfin
29116 + *   arch/parisc
29117 + */
29118 +
29119 +#include <linux/module.h>
29120 +#include <linux/init.h>
29121 +#include <linux/errno.h>
29122 +#include <linux/kernel.h>
29123 +#include <linux/io.h>
29124 +#include <linux/gpio.h>
29125 +#include <linux/irq.h>
29126 +#include <linux/version.h>
29127 +
29128 +#if defined(CONFIG_PROC_FS)
29129 +#include <linux/proc_fs.h>
29130 +#endif
29131 +
29132 +#include <linux/io.h>
29133 +#include <asm/ip5000.h>
29134 +#include <linux/gpio.h>
29135 +
29136 +#define UBI_GPIO_CHECK_RANGE     0  /* !0 enables range checking */
29137 +
29138 +
29139 +/*
29140 + * Each I/O port can be configured to operate in one of several
29141 + * functional modes. One of these modes is GPIO, which causes the
29142 + * entire port to function as a GPIO port.  Since the various port
29143 + * registers serve the system with other important functions, such as
29144 + * ethernet, serial, USB, etc., it isn't advantageous to set any of
29145 + * the ports to be entirely dedicated for GPIO use.  The processor
29146 + * alternatively allows individual bits of a port to be assigned to be
29147 + * used as GPIO independently from the overall port function.  This
29148 + * bit-by-bit assignment is selected by setting the corresponding bit
29149 + * in the port's gpio_mask register.  When set, the selected bit is
29150 + * then enabled as a GPIO.  If the corresponding bit is set in the
29151 + * gpio_ctl register of the port, the bit is configured as a GPIO
29152 + * output.  Otherwise, it is an input.
29153 + *
29154 + * NOTE: This driver uses the bit-by-bit GPIO function assignment
29155 + * exclusively and *never* sets the port function registers to the
29156 + * GPIO function.
29157 + *
29158 + * GPIO is not the main function of any of the I/O ports.  The port
29159 + * bit widths are variable from one port to the next, determined by
29160 + * the more common I/O functions of the ports.  For simplicity, this
29161 + * driver assumes all the ports are 32 bits wide regardless of the
29162 + * real bit width of the port.  GPIO bits are numbered from zero to
29163 + * MAX_UBICOM_GPIOS.  Within a port, the least significant bit is
29164 + * numbered bit zero, the most significant is bit 31.  Since the ports
29165 + * are considered logically contiguous, GPIO #32 is the zeroth bit in
29166 + * port #1, and so on.  Due to the hardware definition, there are
29167 + * large gaps in the GPIO numbers representing real pins.
29168 + *
29169 + * NOTE: It is up to the programmer to refer to the processor data
29170 + * sheet to determine which bits in which ports can be accessed and
29171 + * used for GPIO.
29172 + *
29173 + */
29174 +
29175 +
29176 +/* There are 9 ports, A through I. Not all 32 bits in each
29177 + * port can be a GPIO, but we pretend they are.  Its up to the
29178 + * programmer to refer to the processor data sheet.
29179 + */
29180 +#define MAX_UBICOM_GPIOS   (9 * 32) /* ARCH_NR_GPIOS */
29181 +#define NUM_GPIO_PORTS     (gpio_bank(MAX_UBICOM_GPIOS))
29182 +
29183 +
29184 +/* GPIO reservation bit map array */
29185 +static int reserved_gpio_map[NUM_GPIO_PORTS];
29186 +
29187 +
29188 +/* Array of hardware io_port addresses */
29189 +static struct ubicom32_io_port *gpio_bank_addr[NUM_GPIO_PORTS] =
29190 +{
29191 +       UBICOM32_IO_PORT(RA),
29192 +       UBICOM32_IO_PORT(RB),
29193 +       UBICOM32_IO_PORT(RC),
29194 +       UBICOM32_IO_PORT(RD),
29195 +       UBICOM32_IO_PORT(RE),
29196 +       UBICOM32_IO_PORT(RF),
29197 +       UBICOM32_IO_PORT(RG),
29198 +       UBICOM32_IO_PORT(RH),
29199 +       UBICOM32_IO_PORT(RI)
29200 +};
29201 +
29202 +
29203 +struct ubi_gpio_chip {
29204 +       /*
29205 +        * Right now, nothing else lives here.
29206 +        */
29207 +       struct gpio_chip gpio_chip;
29208 +};
29209 +
29210 +
29211 +#if UBI_GPIO_CHECK_RANGE
29212 +inline int check_gpio(unsigned gpio)
29213 +{
29214 +       if (gpio >= MAX_UBICOM_GPIOS)
29215 +               return -EINVAL;
29216 +       return 0;
29217 +}
29218 +#else
29219 +#define check_gpio(n)   (0)
29220 +#endif
29221 +
29222 +/*
29223 + * ubi_gpio_get_port
29224 + *     Get the IO port associated with a certain gpio
29225 + */
29226 +struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio)
29227 +{
29228 +       if (gpio_bank(gpio) > NUM_GPIO_PORTS) {
29229 +               return NULL;
29230 +       }
29231 +       return gpio_bank_addr[gpio_bank(gpio)];
29232 +}
29233 +
29234 +/*
29235 + * ubi_gpio_error()
29236 + */
29237 +static void ubi_gpio_error(unsigned gpio)
29238 +{
29239 +       printk(KERN_ERR "ubicom-gpio: GPIO %d wasn't requested!\n", gpio);
29240 +}
29241 +
29242 +/*
29243 + * ubi_port_setup()
29244 + */
29245 +static void ubi_port_setup(unsigned gpio, unsigned short usage)
29246 +{
29247 +       if (!check_gpio(gpio)) {
29248 +               if (usage) {
29249 +                       UBICOM32_GPIO_ENABLE(gpio);
29250 +               } else {
29251 +                       UBICOM32_GPIO_DISABLE(gpio);
29252 +               }
29253 +       }
29254 +}
29255 +
29256 +/*
29257 + * ubi_gpio_request()
29258 + */
29259 +static int ubi_gpio_request(struct gpio_chip *chip, unsigned gpio)
29260 +{
29261 +       unsigned long flags;
29262 +
29263 +       if (check_gpio(gpio) < 0)
29264 +               return -EINVAL;
29265 +
29266 +       local_irq_save(flags);
29267 +
29268 +       if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29269 +               printk(KERN_ERR "ubi-gpio: GPIO %d is already reserved!\n",
29270 +                      gpio);
29271 +               local_irq_restore(flags);
29272 +               return -EBUSY;
29273 +       }
29274 +
29275 +       reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
29276 +
29277 +       ubi_port_setup(gpio, 1);
29278 +
29279 +       local_irq_restore(flags);
29280 +
29281 +       return 0;
29282 +}
29283 +
29284 +/*
29285 + * ubi_gpio_free()
29286 + */
29287 +static void ubi_gpio_free(struct gpio_chip *chip, unsigned gpio)
29288 +{
29289 +       unsigned long flags;
29290 +
29291 +       if (check_gpio(gpio) < 0)
29292 +               return;
29293 +
29294 +       local_irq_save(flags);
29295 +
29296 +       if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
29297 +               ubi_gpio_error(gpio);
29298 +               local_irq_restore(flags);
29299 +               return;
29300 +       }
29301 +
29302 +       /* Assert the pin is no longer claimed */
29303 +       reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
29304 +
29305 +       /* Revert port bit to use specified by port->function */
29306 +       ubi_port_setup(gpio, 0);
29307 +
29308 +       local_irq_restore(flags);
29309 +}
29310 +
29311 +/*
29312 + * ubi_gpio_direction_input()
29313 + */
29314 +static int ubi_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
29315 +{
29316 +       unsigned long flags;
29317 +
29318 +       if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29319 +               ubi_gpio_error(gpio);
29320 +               return -EINVAL;
29321 +       }
29322 +
29323 +       local_irq_save(flags);
29324 +
29325 +       /* Configure pin as gpio */
29326 +       ubi_port_setup(gpio, 1);
29327 +
29328 +       /* Assert pin is an input */
29329 +       UBICOM32_GPIO_SET_PIN_INPUT(gpio);
29330 +
29331 +       local_irq_restore(flags);
29332 +
29333 +       return 0;
29334 +}
29335 +
29336 +
29337 +/*
29338 + * ubi_gpio_direction_output()
29339 + */
29340 +static int ubi_gpio_direction_output(struct gpio_chip *chip,
29341 +                                    unsigned gpio, int value)
29342 +{
29343 +       unsigned long flags;
29344 +
29345 +       if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29346 +               ubi_gpio_error(gpio);
29347 +               return -EINVAL;
29348 +       }
29349 +
29350 +       local_irq_save(flags);
29351 +
29352 +       /* Configure pin as gpio and set initial value in gpio_out register
29353 +        * so that when we enable it as an output, it will have the correct
29354 +        * initial value.
29355 +        */
29356 +       ubi_port_setup(gpio, 1);
29357 +       if (value) {
29358 +               UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29359 +       } else {
29360 +               UBICOM32_GPIO_SET_PIN_LOW(gpio);
29361 +       }
29362 +
29363 +       /* Enable the pin as an output */
29364 +       UBICOM32_GPIO_SET_PIN_OUTPUT(gpio);
29365 +
29366 +       local_irq_restore(flags);
29367 +
29368 +       return 0;
29369 +}
29370 +
29371 +
29372 +/*
29373 + * ubi_gpio_get_value()
29374 + */
29375 +static int ubi_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
29376 +{
29377 +       return 0 != (gpio_bank_addr[gpio_bank(gpio)]->gpio_in & gpio_bit(gpio));
29378 +}
29379 +
29380 +
29381 +/*
29382 + * ubi_gpio_set_value()
29383 + */
29384 +static void ubi_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
29385 +                              int arg)
29386 +{
29387 +       unsigned long flags;
29388 +       local_irq_save(flags);
29389 +
29390 +       if (arg) {
29391 +               UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29392 +       } else {
29393 +               UBICOM32_GPIO_SET_PIN_LOW(gpio);
29394 +       }
29395 +
29396 +       local_irq_restore(flags);
29397 +}
29398 +
29399 +
29400 +/*
29401 + * ubi_gpio_to_irq()
29402 + */
29403 +static int ubi_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
29404 +{
29405 +       return gpio_to_irq(gpio);
29406 +}
29407 +
29408 +
29409 +/*
29410 + * ubi_gpio_init()
29411 + */
29412 +int __init ubi_gpio_init(void)
29413 +{
29414 +       int k;
29415 +       int status;
29416 +       struct ubi_gpio_chip *chip;
29417 +       struct gpio_chip *gc;
29418 +
29419 +       printk(KERN_INFO "Ubicom GPIO Controller\n");
29420 +
29421 +       chip = kzalloc(sizeof(struct ubi_gpio_chip), GFP_KERNEL);
29422 +       if (chip == NULL)
29423 +               return -ENOMEM;
29424 +
29425 +       gc = &chip->gpio_chip;
29426 +       gc->request          = ubi_gpio_request;
29427 +       gc->free             = ubi_gpio_free;
29428 +       gc->to_irq           = ubi_gpio_to_irq;
29429 +       gc->direction_input  = ubi_gpio_direction_input;
29430 +       gc->direction_output = ubi_gpio_direction_output;
29431 +       gc->get              = ubi_gpio_get_value;
29432 +       gc->set              = ubi_gpio_set_value;
29433 +       gc->can_sleep        = 0;
29434 +       gc->base             = 0;
29435 +       gc->ngpio            = MAX_UBICOM_GPIOS; /* ARCH_NR_GPIOS - 1 */
29436 +       gc->label            = "ubi_gpio";
29437 +
29438 +       status = gpiochip_add(gc);
29439 +       if (status != 0) {
29440 +               kfree(chip);
29441 +               return status;
29442 +       }
29443 +
29444 +       /* Assert all pins are free */
29445 +       for (k = 0; k < NUM_GPIO_PORTS; k++) {
29446 +               reserved_gpio_map[k] = 0;
29447 +       }
29448 +
29449 +       return 0;
29450 +}
29451 +
29452 +#if defined(CONFIG_PROC_FS)
29453 +/*
29454 + * ubi_get_gpio_dir()
29455 + */
29456 +static int ubi_get_gpio_dir(unsigned gpio)
29457 +{
29458 +       if (gpio_bank_addr[gpio_bank(gpio)]->gpio_ctl & gpio_bit(gpio))
29459 +               return 1;
29460 +       else
29461 +               return 0;
29462 +}
29463 +
29464 +/*
29465 + * gpio_proc_read()
29466 + */
29467 +static int ubi_gpio_proc_read(char *buf, char **start, off_t offset,
29468 +                         int len, int *unused_i, void *unused_v)
29469 +{
29470 +       int c, outlen = 0;
29471 +
29472 +       for (c = 0; c < MAX_UBICOM_GPIOS; c++) {
29473 +               if (!check_gpio(c) &&
29474 +                   (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) {
29475 +                       len = sprintf(buf, "GPIO_%d:\t\tGPIO %s\n", c,
29476 +                                     ubi_get_gpio_dir(c) ? "OUTPUT" : "INPUT");
29477 +               } else {
29478 +                       continue;
29479 +               }
29480 +
29481 +               buf += len;
29482 +               outlen += len;
29483 +       }
29484 +       return outlen;
29485 +}
29486 +
29487 +/*
29488 + * ubi_gpio_register_proc()
29489 + */
29490 +static __init int ubi_gpio_register_proc(void)
29491 +{
29492 +       struct proc_dir_entry *proc_gpio;
29493 +
29494 +       proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
29495 +       if (proc_gpio)
29496 +               proc_gpio->read_proc = ubi_gpio_proc_read;
29497 +
29498 +       return proc_gpio != NULL;
29499 +}
29500 +device_initcall(ubi_gpio_register_proc);
29501 +#endif
29502 --- /dev/null
29503 +++ b/arch/ubicom32/mach-common/ubicom32hid.c
29504 @@ -0,0 +1,557 @@
29505 +/*
29506 + * arch/ubicom32/mach-common/ubicom32hid.c
29507 + *   I2C driver for HID coprocessor found on some DPF implementations.
29508 + *
29509 + * (C) Copyright 2009, Ubicom, Inc.
29510 + *
29511 + * This file is part of the Ubicom32 Linux Kernel Port.
29512 + *
29513 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
29514 + * it and/or modify it under the terms of the GNU General Public License
29515 + * as published by the Free Software Foundation, either version 2 of the
29516 + * License, or (at your option) any later version.
29517 + *
29518 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
29519 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
29520 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
29521 + * the GNU General Public License for more details.
29522 + *
29523 + * You should have received a copy of the GNU General Public License
29524 + * along with the Ubicom32 Linux Kernel Port.  If not,
29525 + * see <http://www.gnu.org/licenses/>.
29526 + *
29527 + * Ubicom32 implementation derived from (with many thanks):
29528 + *   arch/m68knommu
29529 + *   arch/blackfin
29530 + *   arch/parisc
29531 + */
29532 +
29533 +#include <linux/module.h>
29534 +#include <linux/init.h>
29535 +#include <linux/gpio.h>
29536 +#include <linux/delay.h>
29537 +#include <linux/platform_device.h>
29538 +#include <linux/i2c.h>
29539 +#include <linux/backlight.h>
29540 +#include <linux/fb.h>
29541 +#include <linux/input.h>
29542 +#include <linux/input-polldev.h>
29543 +
29544 +#include <asm/ubicom32hid.h>
29545 +
29546 +#define DRIVER_NAME "ubicom32hid"
29547 +
29548 +#ifdef DEBUG
29549 +static int ubicom32hid_debug;
29550 +#endif
29551 +
29552 +static const struct i2c_device_id ubicom32hid_id[] = {
29553 +       { DRIVER_NAME, },
29554 +       { }
29555 +};
29556 +MODULE_DEVICE_TABLE(i2c, ubicom32hid_id);
29557 +
29558 +/*
29559 + * Define this to make IR checking strict, in general, it's not needed
29560 + */
29561 +#undef UBICOM32HID_STRICT_IR_CHECK
29562 +
29563 +#define UBICOM32HID_CMD_SET_PWM                0x01
29564 +#define UBICOM32HID_CMD_SET_BL_EN      0x02
29565 +#define UBICOM32HID_BL_EN_LOW          0x00
29566 +#define UBICOM32HID_BL_EN_HIZ          0x01
29567 +#define UBICOM32HID_BL_EN_HI           0x02
29568 +#define UBICOM32HID_CMD_FLUSH          0x99
29569 +#define UBICOM32HID_CMD_RESET          0x99
29570 +#define UBICOM32HID_CMD_GET_IR_SWITCH  0xC0
29571 +#define UBICOM32HID_CMD_GET_REVISION   0xfd
29572 +#define UBICOM32HID_CMD_GET_DEVICE_ID  0xfe
29573 +#define UBICOM32HID_CMD_GET_VERSION    0xff
29574 +#define UBICOM32HID_DEVICE_ID          0x49
29575 +
29576 +#define UBICOM32HID_MAX_BRIGHTNESS_PWM 255
29577 +
29578 +/*
29579 + * Data structure returned by the HID device
29580 + */
29581 +struct ubicom32hid_input_data {
29582 +       uint32_t        ircmd;
29583 +       uint8_t         sw_state;
29584 +       uint8_t         sw_changed;
29585 +};
29586 +
29587 +/*
29588 + * Our private data
29589 + */
29590 +struct ubicom32hid_data {
29591 +       /*
29592 +        * Pointer to the platform data structure, we need the settings.
29593 +        */
29594 +       const struct ubicom32hid_platform_data  *pdata;
29595 +
29596 +       /*
29597 +        * Backlight device
29598 +        */
29599 +       struct backlight_device                 *bldev;
29600 +
29601 +       /*
29602 +        * I2C client, for sending messages to the HID device
29603 +        */
29604 +       struct i2c_client                       *client;
29605 +
29606 +       /*
29607 +        * Current intensity, used for get_intensity.
29608 +        */
29609 +       int                                     cur_intensity;
29610 +
29611 +       /*
29612 +        * Input subsystem
29613 +        *      We won't register an input subsystem if there are no mappings.
29614 +        */
29615 +       struct input_polled_dev                 *poll_dev;
29616 +};
29617 +
29618 +
29619 +/*
29620 + * ubicom32hid_set_intensity
29621 + */
29622 +static int ubicom32hid_set_intensity(struct backlight_device *bd)
29623 +{
29624 +       struct ubicom32hid_data *ud =
29625 +               (struct ubicom32hid_data *)bl_get_data(bd);
29626 +       int intensity = bd->props.brightness;
29627 +       int reg;
29628 +       u8_t val;
29629 +       int ret;
29630 +
29631 +       /*
29632 +        * If we're blanked the the intensity doesn't matter.
29633 +        */
29634 +       if ((bd->props.power != FB_BLANK_UNBLANK) ||
29635 +           (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
29636 +               intensity = 0;
29637 +       }
29638 +
29639 +       /*
29640 +        * Set the brightness based on the type of backlight
29641 +        */
29642 +       if (ud->pdata->type == UBICOM32HID_BL_TYPE_BINARY) {
29643 +               reg = UBICOM32HID_CMD_SET_BL_EN;
29644 +               if (intensity) {
29645 +                       val = ud->pdata->invert
29646 +                               ? UBICOM32HID_BL_EN_LOW : UBICOM32HID_BL_EN_HI;
29647 +               } else {
29648 +                       val = ud->pdata->invert
29649 +                               ? UBICOM32HID_BL_EN_HI : UBICOM32HID_BL_EN_LOW;
29650 +               }
29651 +       } else {
29652 +               reg = UBICOM32HID_CMD_SET_PWM;
29653 +               val = ud->pdata->invert
29654 +                       ? (UBICOM32HID_MAX_BRIGHTNESS_PWM - intensity) :
29655 +                       intensity;
29656 +       }
29657 +
29658 +       /*
29659 +        * Send the command
29660 +        */
29661 +       ret = i2c_smbus_write_byte_data(ud->client, reg, val);
29662 +       if (ret < 0) {
29663 +               dev_warn(&ud->client->dev, "Unable to write backlight err=%d\n",
29664 +                        ret);
29665 +               return ret;
29666 +       }
29667 +
29668 +       ud->cur_intensity = intensity;
29669 +
29670 +       return 0;
29671 +}
29672 +
29673 +/*
29674 + * ubicom32hid_get_intensity
29675 + *     Return the current intensity of the backlight.
29676 + */
29677 +static int ubicom32hid_get_intensity(struct backlight_device *bd)
29678 +{
29679 +       struct ubicom32hid_data *ud =
29680 +               (struct ubicom32hid_data *)bl_get_data(bd);
29681 +
29682 +       return ud->cur_intensity;
29683 +}
29684 +
29685 +/*
29686 + * ubicom32hid_verify_data
29687 + *     Verify the data to see if there is any action to be taken
29688 + *
29689 + * Returns 0 if no action is to be taken, non-zero otherwise
29690 + */
29691 +static int ubicom32hid_verify_data(struct ubicom32hid_data *ud,
29692 +                                  struct ubicom32hid_input_data *data)
29693 +{
29694 +       uint8_t *ircmd = (uint8_t *)&(data->ircmd);
29695 +
29696 +       /*
29697 +        * ircmd == DEADBEEF means ir queue is empty.  Since this is a
29698 +        * meaningful code, that means the rest of the message is most likely
29699 +        * correct, so only process the data if the switch state has changed.
29700 +        */
29701 +       if (data->ircmd == 0xDEADBEEF) {
29702 +               return data->sw_changed != 0;
29703 +       }
29704 +
29705 +       /*
29706 +        * We have an ircmd which is not empty:
29707 +        *      Data[1] should be the complement of Data[0]
29708 +        */
29709 +       if (ircmd[0] != (u8_t)~ircmd[1]) {
29710 +               return 0;
29711 +       }
29712 +
29713 +#ifdef UBICOM32HID_STRICT_IR_CHECK
29714 +       /*
29715 +        * It seems that some remote controls don't follow the NEC protocol
29716 +        * properly, so only do this check if the remote does indeed follow the
29717 +        * spec.  Data[3] should be the complement of Data[2]
29718 +        */
29719 +       if (ircmd[2] == (u8_t)~ircmd[3]) {
29720 +               return 1;
29721 +       }
29722 +
29723 +       /*
29724 +        * For non-compliant remotes, check the system code according to what
29725 +        * they send.
29726 +        */
29727 +       if ((ircmd[2] != UBICOM32HID_IR_SYSTEM_CODE_CHECK) ||
29728 +           (ircmd[3] != UBICOM32HID_IR_SYSTEM_CODE)) {
29729 +               return 0;
29730 +       }
29731 +#endif
29732 +
29733 +       /*
29734 +        * Data checks out, process
29735 +        */
29736 +       return 1;
29737 +}
29738 +
29739 +/*
29740 + * ubicom32hid_poll_input
29741 + *     Poll the input from the HID device.
29742 + */
29743 +static void ubicom32hid_poll_input(struct input_polled_dev *dev)
29744 +{
29745 +       struct ubicom32hid_data *ud = (struct ubicom32hid_data *)dev->private;
29746 +       const struct ubicom32hid_platform_data *pdata = ud->pdata;
29747 +       struct ubicom32hid_input_data data;
29748 +       struct input_dev *id = dev->input;
29749 +       int i;
29750 +       int sync_needed = 0;
29751 +       uint8_t cmd;
29752 +       int ret;
29753 +
29754 +       /*
29755 +        * Flush the queue
29756 +        */
29757 +       cmd = UBICOM32HID_CMD_FLUSH;
29758 +       ret = i2c_master_send(ud->client, &cmd, 1);
29759 +       if (ret < 0) {
29760 +               return;
29761 +       }
29762 +
29763 +       ret = i2c_smbus_read_i2c_block_data(
29764 +               ud->client, UBICOM32HID_CMD_GET_IR_SWITCH, 6, (void *)&data);
29765 +       if (ret < 0) {
29766 +               return;
29767 +       }
29768 +
29769 +       /*
29770 +        * Verify the data to see if there is any action to be taken
29771 +        */
29772 +       if (!ubicom32hid_verify_data(ud, &data)) {
29773 +               return;
29774 +       }
29775 +
29776 +#ifdef DEBUG
29777 +       if (ubicom32hid_debug) {
29778 +               printk("Polled ircmd=%8x swstate=%2x swchanged=%2x\n",
29779 +                      data.ircmd, data.sw_state, data.sw_changed);
29780 +       }
29781 +#endif
29782 +
29783 +       /*
29784 +        * Process changed switches
29785 +        */
29786 +       if (data.sw_changed) {
29787 +               const struct ubicom32hid_button *ub = pdata->buttons;
29788 +               for (i = 0; i < pdata->nbuttons; i++, ub++) {
29789 +                       uint8_t mask = (1 << ub->bit);
29790 +                       if (!(data.sw_changed & mask)) {
29791 +                               continue;
29792 +                       }
29793 +
29794 +                       sync_needed = 1;
29795 +                       input_event(id, ub->type, ub->code,
29796 +                                   (data.sw_state & mask) ? 1 : 0);
29797 +               }
29798 +       }
29799 +       if (sync_needed) {
29800 +               input_sync(id);
29801 +       }
29802 +
29803 +       /*
29804 +        * Process ir codes
29805 +        */
29806 +       if (data.ircmd != 0xDEADBEEF) {
29807 +               const struct ubicom32hid_ir *ui = pdata->ircodes;
29808 +               for (i = 0; i < pdata->nircodes; i++, ui++) {
29809 +                       if (ui->ir_code == data.ircmd) {
29810 +                               /*
29811 +                                * Simulate a up/down event
29812 +                                */
29813 +                               input_event(id, ui->type, ui->code, 1);
29814 +                               input_sync(id);
29815 +                               input_event(id, ui->type, ui->code, 0);
29816 +                               input_sync(id);
29817 +                       }
29818 +               }
29819 +       }
29820 +}
29821 +
29822 +
29823 +/*
29824 + * Backlight ops
29825 + */
29826 +static struct backlight_ops ubicom32hid_blops = {
29827 +       .get_brightness = ubicom32hid_get_intensity,
29828 +       .update_status  = ubicom32hid_set_intensity,
29829 +};
29830 +
29831 +/*
29832 + * ubicom32hid_probe
29833 + */
29834 +static int ubicom32hid_probe(struct i2c_client *client,
29835 +                            const struct i2c_device_id *id)
29836 +{
29837 +       struct ubicom32hid_platform_data *pdata;
29838 +       struct ubicom32hid_data *ud;
29839 +       int ret;
29840 +       int i;
29841 +       u8 version[2];
29842 +       char buf[1];
29843 +
29844 +       pdata = client->dev.platform_data;
29845 +       if (pdata == NULL) {
29846 +               return -ENODEV;
29847 +       }
29848 +
29849 +       /*
29850 +        * See if we even have a device available before allocating memory.
29851 +        *
29852 +        * Hard reset the device
29853 +        */
29854 +       ret = gpio_request(pdata->gpio_reset, "ubicom32hid-reset");
29855 +       if (ret < 0) {
29856 +               return ret;
29857 +       }
29858 +       gpio_direction_output(pdata->gpio_reset, pdata->gpio_reset_polarity);
29859 +       udelay(100);
29860 +       gpio_set_value(pdata->gpio_reset, !pdata->gpio_reset_polarity);
29861 +       udelay(100);
29862 +
29863 +       /*
29864 +        * soft reset the device.  It sometimes takes a while to do this.
29865 +        */
29866 +       for (i = 0; i < 50; i++) {
29867 +               buf[0] = UBICOM32HID_CMD_RESET;
29868 +               ret = i2c_master_send(client, buf, 1);
29869 +               if (ret > 0) {
29870 +                       break;
29871 +               }
29872 +               udelay(10000);
29873 +       }
29874 +       if (i == 50) {
29875 +               dev_warn(&client->dev, "Unable to reset device\n");
29876 +               goto fail;
29877 +       }
29878 +
29879 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_DEVICE_ID);
29880 +       if (ret != UBICOM32HID_DEVICE_ID) {
29881 +               dev_warn(&client->dev, "Incorrect device id %02x\n", buf[0]);
29882 +               ret = -ENODEV;
29883 +               goto fail;
29884 +       }
29885 +
29886 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_VERSION);
29887 +       if (ret < 0) {
29888 +               dev_warn(&client->dev, "Unable to get version\n");
29889 +               goto fail;
29890 +       }
29891 +       version[0] = ret;
29892 +
29893 +       ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_REVISION);
29894 +       if (ret < 0) {
29895 +               dev_warn(&client->dev, "Unable to get revision\n");
29896 +               goto fail;
29897 +       }
29898 +       version[1] = ret;
29899 +
29900 +       /*
29901 +        * Allocate our private data
29902 +        */
29903 +       ud = kzalloc(sizeof(struct ubicom32hid_data), GFP_KERNEL);
29904 +       if (!ud) {
29905 +               ret = -ENOMEM;
29906 +               goto fail;
29907 +       }
29908 +       ud->pdata = pdata;
29909 +       ud->client = client;
29910 +
29911 +       /*
29912 +        * Register our backlight device
29913 +        */
29914 +       ud->bldev = backlight_device_register(DRIVER_NAME, &client->dev,
29915 +                                             ud, &ubicom32hid_blops);
29916 +       if (IS_ERR(ud->bldev)) {
29917 +               ret = PTR_ERR(ud->bldev);
29918 +               goto fail2;
29919 +       }
29920 +       platform_set_drvdata(client, ud);
29921 +
29922 +       /*
29923 +        * Start up the backlight with the requested intensity
29924 +        */
29925 +       ud->bldev->props.power = FB_BLANK_UNBLANK;
29926 +       ud->bldev->props.max_brightness =
29927 +               (pdata->type == UBICOM32HID_BL_TYPE_PWM) ?
29928 +               UBICOM32HID_MAX_BRIGHTNESS_PWM : 1;
29929 +       if (pdata->default_intensity < ud->bldev->props.max_brightness) {
29930 +               ud->bldev->props.brightness = pdata->default_intensity;
29931 +       } else {
29932 +               dev_warn(&client->dev, "Default brightness out of range, "
29933 +                        "setting to max\n");
29934 +               ud->bldev->props.brightness = ud->bldev->props.max_brightness;
29935 +       }
29936 +
29937 +       ubicom32hid_set_intensity(ud->bldev);
29938 +
29939 +       /*
29940 +        * Check to see if we have any inputs
29941 +        */
29942 +       if (!pdata->nbuttons && !pdata->nircodes) {
29943 +               goto done;
29944 +       }
29945 +
29946 +       /*
29947 +        * We have buttons or codes, we must register an input device
29948 +        */
29949 +       ud->poll_dev = input_allocate_polled_device();
29950 +       if (!ud->poll_dev) {
29951 +               ret = -ENOMEM;
29952 +               goto fail3;
29953 +       }
29954 +
29955 +       /*
29956 +        * Setup the polling to default to 100ms
29957 +        */
29958 +       ud->poll_dev->poll = ubicom32hid_poll_input;
29959 +       ud->poll_dev->poll_interval =
29960 +               pdata->poll_interval ? pdata->poll_interval : 100;
29961 +       ud->poll_dev->private = ud;
29962 +
29963 +       ud->poll_dev->input->name =
29964 +               pdata->input_name ? pdata->input_name : "Ubicom32HID";
29965 +       ud->poll_dev->input->phys = "ubicom32hid/input0";
29966 +       ud->poll_dev->input->dev.parent = &client->dev;
29967 +       ud->poll_dev->input->id.bustype = BUS_I2C;
29968 +
29969 +       /*
29970 +        * Set the capabilities by running through the buttons and ir codes
29971 +        */
29972 +       for (i = 0; i < pdata->nbuttons; i++) {
29973 +               const struct ubicom32hid_button *ub = &pdata->buttons[i];
29974 +
29975 +               input_set_capability(ud->poll_dev->input,
29976 +                                    ub->type ? ub->type : EV_KEY, ub->code);
29977 +       }
29978 +
29979 +       for (i = 0; i < pdata->nircodes; i++) {
29980 +               const struct ubicom32hid_ir *ui = &pdata->ircodes[i];
29981 +
29982 +               input_set_capability(ud->poll_dev->input,
29983 +                                    ui->type ? ui->type : EV_KEY, ui->code);
29984 +       }
29985 +
29986 +       ret = input_register_polled_device(ud->poll_dev);
29987 +       if (ret) {
29988 +               goto fail3;
29989 +       }
29990 +
29991 +done:
29992 +       printk(KERN_INFO DRIVER_NAME ": enabled, version=%02x.%02x\n",
29993 +              version[0], version[1]);
29994 +
29995 +       return 0;
29996 +
29997 +fail3:
29998 +       gpio_free(ud->pdata->gpio_reset);
29999 +       backlight_device_unregister(ud->bldev);
30000 +fail2:
30001 +       kfree(ud);
30002 +fail:
30003 +       gpio_free(pdata->gpio_reset);
30004 +       return ret;
30005 +}
30006 +
30007 +/*
30008 + * ubicom32hid_remove
30009 + */
30010 +static int ubicom32hid_remove(struct i2c_client *client)
30011 +{
30012 +       struct ubicom32hid_data *ud =
30013 +               (struct ubicom32hid_data *)platform_get_drvdata(client);
30014 +
30015 +       gpio_free(ud->pdata->gpio_reset);
30016 +
30017 +       backlight_device_unregister(ud->bldev);
30018 +
30019 +       if (ud->poll_dev) {
30020 +               input_unregister_polled_device(ud->poll_dev);
30021 +               input_free_polled_device(ud->poll_dev);
30022 +       }
30023 +
30024 +       platform_set_drvdata(client, NULL);
30025 +
30026 +       kfree(ud);
30027 +
30028 +       return 0;
30029 +}
30030 +
30031 +static struct i2c_driver ubicom32hid_driver = {
30032 +       .driver = {
30033 +               .name   = DRIVER_NAME,
30034 +               .owner  = THIS_MODULE,
30035 +       },
30036 +       .probe          = ubicom32hid_probe,
30037 +       .remove         = __exit_p(ubicom32hid_remove),
30038 +       .id_table       = ubicom32hid_id,
30039 +};
30040 +
30041 +/*
30042 + * ubicom32hid_init
30043 + */
30044 +static int __init ubicom32hid_init(void)
30045 +{
30046 +       return i2c_add_driver(&ubicom32hid_driver);
30047 +}
30048 +module_init(ubicom32hid_init);
30049 +
30050 +/*
30051 + * ubicom32hid_exit
30052 + */
30053 +static void __exit ubicom32hid_exit(void)
30054 +{
30055 +       i2c_del_driver(&ubicom32hid_driver);
30056 +}
30057 +module_exit(ubicom32hid_exit);
30058 +
30059 +MODULE_AUTHOR("Pat Tjin <@ubicom.com>")
30060 +MODULE_DESCRIPTION("Ubicom HID driver");
30061 +MODULE_LICENSE("GPL");
30062 --- /dev/null
30063 +++ b/arch/ubicom32/mach-common/ubicom32input.c
30064 @@ -0,0 +1,265 @@
30065 +/*
30066 + * arch/ubicom32/mach-common/ubicom32input.c
30067 + *   Ubicom32 Input driver
30068 + *
30069 + *   based on gpio-keys
30070 + *
30071 + * (C) Copyright 2009, Ubicom, Inc.
30072 + *
30073 + * This file is part of the Ubicom32 Linux Kernel Port.
30074 + *
30075 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30076 + * it and/or modify it under the terms of the GNU General Public License
30077 + * as published by the Free Software Foundation, either version 2 of the
30078 + * License, or (at your option) any later version.
30079 + *
30080 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30081 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30082 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
30083 + * the GNU General Public License for more details.
30084 + *
30085 + * You should have received a copy of the GNU General Public License
30086 + * along with the Ubicom32 Linux Kernel Port.  If not,
30087 + * see <http://www.gnu.org/licenses/>.
30088 + *
30089 + * Ubicom32 implementation derived from (with many thanks):
30090 + *   arch/m68knommu
30091 + *   arch/blackfin
30092 + *   arch/parisc
30093 + *
30094 + *
30095 + * TODO: add groups for inputs which can be sampled together (i.e. I2C)
30096 + */
30097 +
30098 +#include <linux/kernel.h>
30099 +#include <linux/module.h>
30100 +#include <linux/platform_device.h>
30101 +#include <linux/input.h>
30102 +#include <linux/input-polldev.h>
30103 +#include <linux/delay.h>
30104 +#include <linux/gpio.h>
30105 +
30106 +#include <asm/ubicom32input.h>
30107 +
30108 +struct ubicom32input_data {
30109 +       struct ubicom32input_platform_data      *pdata;
30110 +
30111 +       struct input_polled_dev                 *poll_dev;
30112 +
30113 +       /*
30114 +        * collection of previous states for buttons
30115 +        */
30116 +       u8                                      prev_state[0];
30117 +};
30118 +
30119 +/*
30120 + * ubicom32input_poll
30121 + */
30122 +static void ubicom32input_poll(struct input_polled_dev *dev)
30123 +{
30124 +       struct ubicom32input_data *ud =
30125 +               (struct ubicom32input_data *)dev->private;
30126 +       struct ubicom32input_platform_data *pdata = ud->pdata;
30127 +       struct input_dev *id = dev->input;
30128 +       int i;
30129 +       int sync_needed = 0;
30130 +
30131 +       for (i = 0; i < pdata->nbuttons; i++) {
30132 +               const struct ubicom32input_button *ub = &pdata->buttons[i];
30133 +               int state = 0;
30134 +
30135 +               int val = gpio_get_value(ub->gpio);
30136 +
30137 +               /*
30138 +                * Check to see if the state changed from the last time we
30139 +                * looked
30140 +                */
30141 +               if (val == ud->prev_state[i]) {
30142 +                       continue;
30143 +               }
30144 +
30145 +               /*
30146 +                * The state has changed, determine if we are "up" or "down"
30147 +                */
30148 +               ud->prev_state[i] = val;
30149 +
30150 +               if ((!val && ub->active_low) || (val && !ub->active_low)) {
30151 +                       state = 1;
30152 +               }
30153 +
30154 +               input_event(id, ub->type, ub->code, state);
30155 +               sync_needed = 1;
30156 +       }
30157 +
30158 +       if (sync_needed) {
30159 +               input_sync(id);
30160 +       }
30161 +}
30162 +
30163 +/*
30164 + * ubicom32input_probe
30165 + */
30166 +static int __devinit ubicom32input_probe(struct platform_device *pdev)
30167 +{
30168 +       int i;
30169 +       struct ubicom32input_data *ud;
30170 +       struct input_polled_dev *poll_dev;
30171 +       struct input_dev *input_dev;
30172 +       struct ubicom32input_platform_data *pdata;
30173 +       int ret;
30174 +
30175 +       pdata = pdev->dev.platform_data;
30176 +       if (!pdata) {
30177 +               return -EINVAL;
30178 +       }
30179 +
30180 +       ud = kzalloc(sizeof(struct ubicom32input_data) +
30181 +                    pdata->nbuttons, GFP_KERNEL);
30182 +       if (!ud) {
30183 +               return -ENOMEM;
30184 +       }
30185 +       ud->pdata = pdata;
30186 +
30187 +       poll_dev = input_allocate_polled_device();
30188 +       if (!poll_dev) {
30189 +               ret = -ENOMEM;
30190 +               goto fail;
30191 +       }
30192 +
30193 +       platform_set_drvdata(pdev, ud);
30194 +
30195 +       ud->poll_dev = poll_dev;
30196 +       poll_dev->private = ud;
30197 +       poll_dev->poll = ubicom32input_poll;
30198 +
30199 +       /*
30200 +        * Set the poll interval requested, default to 50 msec
30201 +        */
30202 +       if (pdata->poll_interval) {
30203 +               poll_dev->poll_interval = pdata->poll_interval;
30204 +       } else {
30205 +               poll_dev->poll_interval = 50;
30206 +       }
30207 +
30208 +       /*
30209 +        * Setup the input device
30210 +        */
30211 +       input_dev = poll_dev->input;
30212 +       input_dev->name = pdata->name ? pdata->name : "Ubicom32 Input";
30213 +       input_dev->phys = "ubicom32input/input0";
30214 +       input_dev->dev.parent = &pdev->dev;
30215 +       input_dev->id.bustype = BUS_HOST;
30216 +
30217 +       /*
30218 +        * Reserve the GPIOs
30219 +        */
30220 +       for (i = 0; i < pdata->nbuttons; i++) {
30221 +               const struct ubicom32input_button *ub = &pdata->buttons[i];
30222 +
30223 +               ret = gpio_request(ub->gpio,
30224 +                                  ub->desc ? ub->desc : "ubicom32input");
30225 +               if (ret < 0) {
30226 +                       pr_err("ubicom32input: failed to request "
30227 +                              "GPIO %d ret=%d\n", ub->gpio, ret);
30228 +                       goto fail2;
30229 +               }
30230 +
30231 +               ret = gpio_direction_input(ub->gpio);
30232 +               if (ret < 0) {
30233 +                       pr_err("ubicom32input: failed to set "
30234 +                              "GPIO %d to input ret=%d\n", ub->gpio, ret);
30235 +                       goto fail2;
30236 +               }
30237 +
30238 +               /*
30239 +                * Set the previous state to the non-active stae
30240 +                */
30241 +               ud->prev_state[i] = ub->active_low;
30242 +
30243 +               input_set_capability(input_dev,
30244 +                                    ub->type ? ub->type : EV_KEY, ub->code);
30245 +       }
30246 +
30247 +       /*
30248 +        * Register
30249 +        */
30250 +       ret = input_register_polled_device(ud->poll_dev);
30251 +       if (ret) {
30252 +               goto fail2;
30253 +       }
30254 +
30255 +       return 0;
30256 +
30257 +fail2:
30258 +       /*
30259 +        * release the GPIOs we have already requested.
30260 +        */
30261 +       while (--i >= 0) {
30262 +               gpio_free(pdata->buttons[i].gpio);
30263 +       }
30264 +
30265 +fail:
30266 +       printk(KERN_ERR "Ubicom32Input: Failed to register driver %d", ret);
30267 +       platform_set_drvdata(pdev, NULL);
30268 +       input_free_polled_device(poll_dev);
30269 +       kfree(ud);
30270 +       return ret;
30271 +}
30272 +
30273 +/*
30274 + * ubicom32input_remove
30275 + */
30276 +static int __devexit ubicom32input_remove(struct platform_device *dev)
30277 +{
30278 +       struct ubicom32input_data *ud =
30279 +               (struct ubicom32input_data *)platform_get_drvdata(dev);
30280 +       int i;
30281 +
30282 +       /*
30283 +        * Free the GPIOs
30284 +        */
30285 +       for (i = 0; i < ud->pdata->nbuttons; i++) {
30286 +               gpio_free(ud->pdata->buttons[i].gpio);
30287 +       }
30288 +
30289 +       platform_set_drvdata(dev, NULL);
30290 +       input_unregister_polled_device(ud->poll_dev);
30291 +       input_free_polled_device(ud->poll_dev);
30292 +
30293 +       kfree(ud);
30294 +
30295 +       return 0;
30296 +}
30297 +
30298 +static struct platform_driver ubicom32input_driver = {
30299 +       .driver         = {
30300 +               .name   = "ubicom32input",
30301 +               .owner  = THIS_MODULE,
30302 +       },
30303 +       .probe          = ubicom32input_probe,
30304 +       .remove         = __devexit_p(ubicom32input_remove),
30305 +};
30306 +
30307 +/*
30308 + * ubicom32input_init
30309 + */
30310 +static int __devinit ubicom32input_init(void)
30311 +{
30312 +       return platform_driver_register(&ubicom32input_driver);
30313 +}
30314 +
30315 +/*
30316 + * ubicom32input_exit
30317 + */
30318 +static void __exit ubicom32input_exit(void)
30319 +{
30320 +       platform_driver_unregister(&ubicom32input_driver);
30321 +}
30322 +
30323 +module_init(ubicom32input_init);
30324 +module_exit(ubicom32input_exit);
30325 +
30326 +MODULE_AUTHOR("Pat Tjin <pattjin@ubicom.com>");
30327 +MODULE_DESCRIPTION("Ubicom32 Input Driver");
30328 +MODULE_LICENSE("GPL");
30329 +MODULE_ALIAS("platform:ubicom32-input");
30330 --- /dev/null
30331 +++ b/arch/ubicom32/mach-common/ubicom32input_i2c.c
30332 @@ -0,0 +1,325 @@
30333 +/*
30334 + * arch/ubicom32/mach-common/ubicom32input_i2c.c
30335 + *   Ubicom32 Input driver for I2C
30336 + *       Supports PCA953x and family
30337 + *
30338 + *   We hog the I2C device, turning it all to input.
30339 + *
30340 + *   Based on gpio-keys, pca953x
30341 + *
30342 + * (C) Copyright 2009, Ubicom, Inc.
30343 + *
30344 + * This file is part of the Ubicom32 Linux Kernel Port.
30345 + *
30346 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30347 + * it and/or modify it under the terms of the GNU General Public License
30348 + * as published by the Free Software Foundation, either version 2 of the
30349 + * License, or (at your option) any later version.
30350 + *
30351 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30352 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30353 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
30354 + * the GNU General Public License for more details.
30355 + *
30356 + * You should have received a copy of the GNU General Public License
30357 + * along with the Ubicom32 Linux Kernel Port.  If not,
30358 + * see <http://www.gnu.org/licenses/>.
30359 + *
30360 + * Ubicom32 implementation derived from (with many thanks):
30361 + *   arch/m68knommu
30362 + *   arch/blackfin
30363 + *   arch/parisc
30364 + */
30365 +#include <linux/kernel.h>
30366 +#include <linux/module.h>
30367 +#include <linux/platform_device.h>
30368 +#include <linux/input.h>
30369 +#include <linux/input-polldev.h>
30370 +#include <linux/i2c.h>
30371 +
30372 +#include <asm/ubicom32input_i2c.h>
30373 +
30374 +#define UBICOM32INPUT_I2C_REG_INPUT    0
30375 +#define UBICOM32INPUT_I2C_REG_OUTPUT   1
30376 +#define UBICOM32INPUT_I2C_REG_INVERT   2
30377 +#define UBICOM32INPUT_I2C_REG_DIRECTION        3
30378 +
30379 +static const struct i2c_device_id ubicom32input_i2c_id[] = {
30380 +       { "ubicom32in_pca9534", 8, },
30381 +       { "ubicom32in_pca9535", 16, },
30382 +       { "ubicom32in_pca9536", 4, },
30383 +       { "ubicom32in_pca9537", 4, },
30384 +       { "ubicom32in_pca9538", 8, },
30385 +       { "ubicom32in_pca9539", 16, },
30386 +       { "ubicom32in_pca9554", 8, },
30387 +       { "ubicom32in_pca9555", 16, },
30388 +       { "ubicom32in_pca9557", 8, },
30389 +       { "ubicom32in_max7310", 8, },
30390 +       { }
30391 +};
30392 +MODULE_DEVICE_TABLE(i2c, ubicom32input_i2c_id);
30393 +
30394 +struct ubicom32input_i2c_data {
30395 +       struct ubicom32input_i2c_platform_data  *pdata;
30396 +
30397 +       struct i2c_client                       *client;
30398 +
30399 +       struct input_polled_dev                 *poll_dev;
30400 +
30401 +       /*
30402 +        * collection of previous states for buttons
30403 +        */
30404 +       uint16_t                                prev_state;
30405 +
30406 +       uint8_t                                 ngpios;
30407 +};
30408 +
30409 +/*
30410 + * ubicom32input_i2c_write_reg
30411 + *     writes a register to the I2C device.
30412 + */
30413 +static int ubicom32input_i2c_write_reg(struct ubicom32input_i2c_data *ud,
30414 +                                      int reg, uint16_t val)
30415 +{
30416 +       int ret;
30417 +
30418 +       if (ud->ngpios <= 8) {
30419 +               ret = i2c_smbus_write_byte_data(ud->client, reg, val);
30420 +       } else {
30421 +               ret = i2c_smbus_write_word_data(ud->client, reg << 1, val);
30422 +       }
30423 +
30424 +       if (ret < 0) {
30425 +               return ret;
30426 +       }
30427 +
30428 +       return 0;
30429 +}
30430 +
30431 +/*
30432 + * ubicom32input_i2c_read_reg
30433 + *     reads a register from the I2C device.
30434 + */
30435 +static int ubicom32input_i2c_read_reg(struct ubicom32input_i2c_data *ud,
30436 +                                     int reg, uint16_t *val)
30437 +{
30438 +       int ret;
30439 +
30440 +       if (ud->ngpios <= 8) {
30441 +               ret = i2c_smbus_read_byte_data(ud->client, reg);
30442 +       } else {
30443 +               ret = i2c_smbus_read_word_data(ud->client, reg);
30444 +       }
30445 +
30446 +       if (ret < 0) {
30447 +               return ret;
30448 +       }
30449 +
30450 +       *val = (uint16_t)ret;
30451 +
30452 +       return 0;
30453 +}
30454 +
30455 +/*
30456 + * ubicom32input_i2c_poll
30457 + */
30458 +static void ubicom32input_i2c_poll(struct input_polled_dev *dev)
30459 +{
30460 +       struct ubicom32input_i2c_data *ud =
30461 +               (struct ubicom32input_i2c_data *)dev->private;
30462 +       struct ubicom32input_i2c_platform_data *pdata = ud->pdata;
30463 +       struct input_dev *id = dev->input;
30464 +       int i;
30465 +       int sync_needed = 0;
30466 +       uint16_t val;
30467 +       uint16_t change_mask;
30468 +
30469 +       /*
30470 +        * Try to get the input status, if we fail, bail out, maybe we can do it
30471 +        * next time.
30472 +        */
30473 +       if (ubicom32input_i2c_read_reg(ud, UBICOM32INPUT_I2C_REG_INPUT, &val)) {
30474 +               return;
30475 +       }
30476 +
30477 +       /*
30478 +        * see if anything changed by using XOR
30479 +        */
30480 +       change_mask = ud->prev_state ^ val;
30481 +       ud->prev_state = val;
30482 +
30483 +       for (i = 0; i < pdata->nbuttons; i++) {
30484 +               const struct ubicom32input_i2c_button *ub = &pdata->buttons[i];
30485 +               uint16_t mask = 1 << ub->bit;
30486 +               int state = val & mask;
30487 +
30488 +               /*
30489 +                * Check to see if the state changed from the last time we
30490 +                * looked
30491 +                */
30492 +               if (!(change_mask & mask)) {
30493 +                       continue;
30494 +               }
30495 +               input_event(id, ub->type, ub->code, state);
30496 +               sync_needed = 1;
30497 +       }
30498 +
30499 +       if (sync_needed) {
30500 +               input_sync(id);
30501 +       }
30502 +}
30503 +
30504 +/*
30505 + * ubicom32input_i2c_probe
30506 + */
30507 +static int __devinit ubicom32input_i2c_probe(struct i2c_client *client,
30508 +                                            const struct i2c_device_id *id)
30509 +{
30510 +       int i;
30511 +       struct ubicom32input_i2c_data *ud;
30512 +       struct input_polled_dev *poll_dev;
30513 +       struct input_dev *input_dev;
30514 +       struct ubicom32input_i2c_platform_data *pdata;
30515 +       int ret;
30516 +       uint16_t invert_mask = 0;
30517 +
30518 +       pdata = client->dev.platform_data;
30519 +       if (!pdata) {
30520 +               return -EINVAL;
30521 +       }
30522 +
30523 +       ud = kzalloc(sizeof(struct ubicom32input_i2c_data), GFP_KERNEL);
30524 +       if (!ud) {
30525 +               return -ENOMEM;
30526 +       }
30527 +       ud->pdata = pdata;
30528 +       ud->client = client;
30529 +       ud->ngpios = id->driver_data;
30530 +
30531 +       poll_dev = input_allocate_polled_device();
30532 +       if (!poll_dev) {
30533 +               ret = -ENOMEM;
30534 +               goto fail;
30535 +       }
30536 +
30537 +       ud->poll_dev = poll_dev;
30538 +       poll_dev->private = ud;
30539 +       poll_dev->poll = ubicom32input_i2c_poll;
30540 +
30541 +       /*
30542 +        * Set the poll interval requested, default to 100 msec
30543 +        */
30544 +       if (pdata->poll_interval) {
30545 +               poll_dev->poll_interval = pdata->poll_interval;
30546 +       } else {
30547 +               poll_dev->poll_interval = 100;
30548 +       }
30549 +
30550 +       /*
30551 +        * Setup the input device
30552 +        */
30553 +       input_dev = poll_dev->input;
30554 +       input_dev->name = pdata->name ? pdata->name : "Ubicom32 Input I2C";
30555 +       input_dev->phys = "ubicom32input_i2c/input0";
30556 +       input_dev->dev.parent = &client->dev;
30557 +       input_dev->id.bustype = BUS_I2C;
30558 +
30559 +       /*
30560 +        * Set the capabilities
30561 +        */
30562 +       for (i = 0; i < pdata->nbuttons; i++) {
30563 +               const struct ubicom32input_i2c_button *ub = &pdata->buttons[i];
30564 +
30565 +               if (ub->active_low) {
30566 +                       invert_mask |= (1 << ub->bit);
30567 +               }
30568 +
30569 +               input_set_capability(input_dev,
30570 +                                    ub->type ? ub->type : EV_KEY, ub->code);
30571 +       }
30572 +
30573 +       /*
30574 +        * Setup the device (all inputs)
30575 +        */
30576 +       ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_DIRECTION,
30577 +                                         0xFFFF);
30578 +       if (ret < 0) {
30579 +               goto fail;
30580 +       }
30581 +
30582 +       ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_INVERT,
30583 +                                         invert_mask);
30584 +       if (ret < 0) {
30585 +               goto fail;
30586 +       }
30587 +
30588 +       /*
30589 +        * Register
30590 +        */
30591 +       ret = input_register_polled_device(ud->poll_dev);
30592 +       if (ret) {
30593 +               goto fail;
30594 +       }
30595 +
30596 +       i2c_set_clientdata(client, ud);
30597 +
30598 +       return 0;
30599 +
30600 +fail:
30601 +       printk(KERN_ERR "ubicom32input_i2c: Failed to register driver %d\n",
30602 +              ret);
30603 +       input_free_polled_device(poll_dev);
30604 +       kfree(ud);
30605 +       return ret;
30606 +}
30607 +
30608 +/*
30609 + * ubicom32input_i2c_remove
30610 + */
30611 +static int __devexit ubicom32input_i2c_remove(struct i2c_client *client)
30612 +{
30613 +       struct ubicom32input_i2c_data *ud =
30614 +               (struct ubicom32input_i2c_data *)i2c_get_clientdata(client);
30615 +
30616 +       i2c_set_clientdata(client, NULL);
30617 +       input_unregister_polled_device(ud->poll_dev);
30618 +       input_free_polled_device(ud->poll_dev);
30619 +
30620 +       kfree(ud);
30621 +
30622 +       return 0;
30623 +}
30624 +
30625 +static struct i2c_driver ubicom32input_i2c_driver = {
30626 +       .driver         = {
30627 +               .name   = "ubicom32input_i2c",
30628 +               .owner  = THIS_MODULE,
30629 +       },
30630 +       .remove         = __devexit_p(ubicom32input_i2c_remove),
30631 +       .id_table       = ubicom32input_i2c_id,
30632 +       .probe          = ubicom32input_i2c_probe,
30633 +};
30634 +
30635 +/*
30636 + * ubicom32input_i2c_init
30637 + */
30638 +static int __devinit ubicom32input_i2c_init(void)
30639 +{
30640 +       return i2c_add_driver(&ubicom32input_i2c_driver);
30641 +}
30642 +
30643 +/*
30644 + * ubicom32input_i2c_exit
30645 + */
30646 +static void __exit ubicom32input_i2c_exit(void)
30647 +{
30648 +       i2c_del_driver(&ubicom32input_i2c_driver);
30649 +}
30650 +
30651 +module_init(ubicom32input_i2c_init);
30652 +module_exit(ubicom32input_i2c_exit);
30653 +
30654 +MODULE_AUTHOR("Pat Tjin <pattjin@ubicom.com>");
30655 +MODULE_DESCRIPTION("Ubicom32 Input Driver I2C");
30656 +MODULE_LICENSE("GPL");
30657 +MODULE_ALIAS("platform:ubicom32-input");
30658 --- /dev/null
30659 +++ b/arch/ubicom32/mach-common/usb.c
30660 @@ -0,0 +1,133 @@
30661 +/*
30662 + * arch/ubicom32/mach-common/ip5k_usb.c
30663 + *   Ubicom32 architecture usb support.
30664 + *
30665 + * (C) Copyright 2009, Ubicom, Inc.
30666 + * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
30667 + * Author: Kevin Hilman
30668 + *
30669 + * This file is part of the Ubicom32 Linux Kernel Port.
30670 + *
30671 + * The Ubicom32 Linux Kernel Port is free software: you can
30672 + * redistribute it and/or modify it under the terms of the GNU General
30673 + * Public License as published by the Free Software Foundation, either
30674 + * version 2 of the License, or (at your option) any later version.
30675 + *
30676 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30677 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30678 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30679 + * See the GNU General Public License for more details.
30680 + *
30681 + * You should have received a copy of the GNU General Public License
30682 + * along with the Ubicom32 Linux Kernel Port.  If not, 
30683 + * see <http://www.gnu.org/licenses/>.
30684 + *
30685 + * Ubicom32 implementation derived from (with many thanks):
30686 + *   arch/m68knommu
30687 + *   arch/blackfin
30688 + *   arch/parisc
30689 + */
30690 +
30691 +#include <linux/types.h>
30692 +#include <linux/errno.h>
30693 +#include <linux/delay.h>
30694 +#include <linux/platform_device.h>
30695 +#include <linux/dma-mapping.h>
30696 +#include <linux/usb/musb.h>
30697 +#include <asm/devtree.h>
30698 +#include <asm/ip5000.h>
30699 +#include "usb_tio.h"
30700 +
30701 +struct usbtionode *unode = NULL;
30702 +
30703 +static struct resource usb_resources[] = {
30704 +       [0] = {
30705 +               .start  = RJ + 0x800,
30706 +               .end    = RJ + 0x1000,
30707 +               .flags  = IORESOURCE_MEM,
30708 +       },
30709 +       [1] = { /* general IRQ */
30710 +               .start  = 1, /* this is a dummy value, the real irq number is passed from kernel_setup_param */
30711 +               .flags  = IORESOURCE_IRQ,
30712 +       },
30713 +};
30714 +
30715 +
30716 +static struct musb_hdrc_eps_bits musb_eps[] = {
30717 +       { "ep1_tx", 4, },
30718 +       { "ep1_rx", 4, },
30719 +       { "ep2_tx", 10, },
30720 +       { "ep2_rx", 10, },
30721 +       { "ep3_tx", 9, },
30722 +       { "ep3_rx", 9, },
30723 +       { "ep4_tx", 9, },
30724 +       { "ep4_rx", 9, },
30725 +       { "ep5_tx", 6, },
30726 +       { "ep5_rx", 6, },
30727 +};
30728 +
30729 +static struct musb_hdrc_config musb_config = {
30730 +       .multipoint     = true,
30731 +       .dyn_fifo       = false,
30732 +       .soft_con       = true,
30733 +       .dma            = false,
30734 +
30735 +       .num_eps        = 6,
30736 +       .dma_channels   = 0,
30737 +       .ram_bits       = 0,
30738 +       .eps_bits       = musb_eps,
30739 +};
30740 +
30741 +static struct musb_hdrc_platform_data usb_data = {
30742 +#ifdef CONFIG_USB_MUSB_OTG
30743 +       .mode           = MUSB_OTG,
30744 +#else
30745 +#ifdef CONFIG_USB_MUSB_HDRC_HCD
30746 +       .mode           = MUSB_HOST,
30747 +#else
30748 +#ifdef CONFIG_USB_GADGET_MUSB_HDRC
30749 +       .mode           = MUSB_PERIPHERAL,
30750 +#endif
30751 +#endif
30752 +#endif
30753 +       .clock          = NULL,
30754 +       .set_clock      = NULL,
30755 +       .config         = &musb_config,
30756 +};
30757 +
30758 +static struct platform_device musb_device = {
30759 +       .name           = "musb_hdrc",
30760 +       .id             = 0,
30761 +       .dev = {
30762 +               .platform_data          = &usb_data,
30763 +               .dma_mask               = NULL,
30764 +               .coherent_dma_mask      = 0,
30765 +       },
30766 +       .resource       = usb_resources,
30767 +       .num_resources  = ARRAY_SIZE(usb_resources),
30768 +};
30769 +
30770 +struct usbtio_node *usb_node = NULL;
30771 +void ubi32_usb_init(void)
30772 +{
30773 +       /*
30774 +        * See if the usbtio is in the device tree.
30775 +        */
30776 +       usb_node = (struct usbtio_node *)devtree_find_node("usbtio");
30777 +       if (!usb_node) {
30778 +               printk(KERN_WARNING "usb init failed\n");
30779 +               return;
30780 +       }
30781 +
30782 +       usb_resources[1].start = usb_node->dn.recvirq;
30783 +       if (platform_device_register(&musb_device) < 0) {
30784 +               printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
30785 +               return;
30786 +       }
30787 +}
30788 +
30789 +void ubi32_usb_int_clr(void)
30790 +{
30791 +        UBICOM32_IO_PORT(RJ)->int_clr = (1 << 3);
30792 +}
30793 +
30794 --- /dev/null
30795 +++ b/arch/ubicom32/mach-common/usb_tio.c
30796 @@ -0,0 +1,356 @@
30797 +/*
30798 + * arch/ubicom32/mach-common/usb_tio.c
30799 + *  Linux side Ubicom USB TIO driver
30800 + *
30801 + * (C) Copyright 2009, Ubicom, Inc.
30802 + *
30803 + * This file is part of the Ubicom32 Linux Kernel Port.
30804 + *
30805 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
30806 + * it and/or modify it under the terms of the GNU General Public License
30807 + * as published by the Free Software Foundation, either version 2 of the
30808 + * License, or (at your option) any later version.
30809 + *
30810 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
30811 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
30812 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
30813 + * the GNU General Public License for more details.
30814 + *
30815 + * You should have received a copy of the GNU General Public License
30816 + * along with the Ubicom32 Linux Kernel Port.  If not, 
30817 + * see <http://www.gnu.org/licenses/>.
30818 + *
30819 + * Ubicom32 implementation derived from (with many thanks):
30820 + *   arch/m68knommu
30821 + *   arch/blackfin
30822 + *   arch/parisc
30823 + */
30824 +#include <linux/module.h>
30825 +#include <linux/spinlock.h>
30826 +#include <linux/slab.h>
30827 +#include <asm/devtree.h>
30828 +#include "usb_tio.h"
30829 +
30830 +#ifdef CONFIG_SMP
30831 +static DEFINE_SPINLOCK(tio_lock);
30832 +#define USB_TIO_LOCK(lock, flag) spin_lock_irqsave(lock, flag)
30833 +#define USB_TIO_UNLOCK(lock, flag) spin_unlock_irqrestore(lock, flag)
30834 +#define USB_TIO_LOCK_ISLOCKED(lock) spin_try_lock(lock)
30835 +#else
30836 +#define USB_TIO_LOCK(lock, flag) local_irq_save(flag)
30837 +#define USB_TIO_UNLOCK(lock, flag) local_irq_restore(flag)
30838 +#endif
30839 +
30840 +spinlock_t usb_tio_lock;
30841 +
30842 +/*
30843 + * usb_tio_set_hrt_interrupt()
30844 + */
30845 +static inline void usb_tio_set_hrt_interrupt(void)
30846 +{
30847 +       ubicom32_set_interrupt(usb_node->dn.sendirq);
30848 +}
30849 +
30850 +static inline void usb_tio_wait_hrt(void)
30851 +{
30852 +       while (unlikely(usb_node->pdesc));
30853 +}
30854 +
30855 +#if defined(USB_TIO_DEBUG)
30856 +static void usb_tio_request_verify_magic(volatile struct usb_tio_request *req)
30857 +{
30858 +       BUG_ON(req->magic != USB_TIO_REQUEST_MAGIC2);
30859 +}
30860 +
30861 +static void usb_tio_request_clear_magic(volatile struct usb_tio_request *req)
30862 +{
30863 +       req->magic = 0;
30864 +}
30865 +#endif
30866 +
30867 +static void usb_tio_request_set_magic(volatile struct usb_tio_request *req)
30868 +{
30869 +       req->magic = USB_TIO_REQUEST_MAGIC1;
30870 +}
30871 +
30872 +/*
30873 + * usb_tio_commit_request()
30874 + */
30875 +static inline void usb_tio_commit_request(volatile struct usb_tio_request *request)
30876 +{
30877 +       wmb();
30878 +       usb_node->pdesc = request;
30879 +
30880 +       /*
30881 +        * next thing to do is alway checking if (usb_node->pdesc == NULL) 
30882 +        * to see if the request is done, so add a mb() here
30883 +        */
30884 +       mb();
30885 +       usb_tio_set_hrt_interrupt();
30886 +}
30887 +
30888 +/*
30889 + * usb_tio_read_u16()
30890 + *     Synchronously read 16 bits.
30891 + */
30892 +u8_t usb_tio_read_u16(u32_t address, u16_t *data)
30893 +{
30894 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30895 +       unsigned long flag;
30896 +
30897 +       /*
30898 +        * Wait for any previous request to complete and then make this request.
30899 +        */
30900 +       USB_TIO_LOCK(&tio_lock, flag);
30901 +       usb_tio_wait_hrt();
30902 +
30903 +       /*
30904 +        * Fill in the request.
30905 +        */
30906 +       tio_req->address = address;
30907 +       tio_req->cmd = USB_TIO_READ16_SYNC;
30908 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30909 +       usb_tio_commit_request(tio_req);
30910 +
30911 +       /*
30912 +        * Wait for the result to show up.
30913 +        */
30914 +       usb_tio_wait_hrt();
30915 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30916 +       *data = (u16_t)tio_req->data;
30917 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30918 +       USB_TIO_UNLOCK(&tio_lock, flag);
30919 +       return USB_TIO_OK;
30920 +}
30921 +
30922 +/*
30923 + * usb_tio_read_u8()
30924 + *     Synchronously read 16 bits.
30925 + */
30926 +u8_t usb_tio_read_u8(u32_t address, u8_t *data)
30927 +{
30928 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30929 +       unsigned long flag;
30930 +
30931 +       /*
30932 +        * Wait for any previous request to complete and then make this request.
30933 +        */
30934 +       USB_TIO_LOCK(&tio_lock, flag);
30935 +       usb_tio_wait_hrt();
30936 +
30937 +       /*
30938 +        * Fill in the request.
30939 +        */
30940 +       tio_req->address = address;
30941 +       tio_req->cmd = USB_TIO_READ8_SYNC;
30942 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30943 +
30944 +       /*
30945 +        * commit the request
30946 +        */
30947 +       usb_tio_commit_request(tio_req);
30948 +
30949 +       /*
30950 +        * Wait for the result to show up.
30951 +        */
30952 +       usb_tio_wait_hrt();
30953 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
30954 +       *data = (u8_t)tio_req->data;
30955 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
30956 +       USB_TIO_UNLOCK(&tio_lock, flag);
30957 +       return USB_TIO_OK;
30958 +}
30959 +
30960 +/*
30961 + * usb_tio_write_u16()
30962 + *     Asynchronously  write 16 bits.
30963 + */
30964 +u8_t usb_tio_write_u16(u32_t address, u16_t data)
30965 +{
30966 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30967 +       unsigned long flag;
30968 +
30969 +       /*
30970 +        * Wait for any previous write or pending read to complete.
30971 +        */
30972 +       USB_TIO_LOCK(&tio_lock, flag);
30973 +       usb_tio_wait_hrt();
30974 +
30975 +       tio_req->address = address;
30976 +       tio_req->data = data;
30977 +       tio_req->cmd = USB_TIO_WRITE16_ASYNC;
30978 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
30979 +
30980 +       /*
30981 +        * commit the request
30982 +        */
30983 +       usb_tio_commit_request(tio_req);
30984 +       USB_TIO_UNLOCK(&tio_lock, flag);
30985 +       return USB_TIO_OK;
30986 +}
30987 +
30988 +/*
30989 + * usb_tio_write_u8()
30990 + *     Asynchronously  write 8 bits.
30991 + */
30992 +u8_t usb_tio_write_u8(u32_t address, u8_t data)
30993 +{
30994 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
30995 +       unsigned long flag;
30996 +
30997 +       /*
30998 +        * Wait for any previous write or pending read to complete.
30999 +        */
31000 +       USB_TIO_LOCK(&tio_lock, flag);
31001 +       usb_tio_wait_hrt();
31002 +
31003 +       tio_req->address = address;
31004 +       tio_req->data = data;
31005 +       tio_req->cmd = USB_TIO_WRITE8_ASYNC;
31006 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
31007 +
31008 +       /*
31009 +        * commit the request
31010 +        */
31011 +       usb_tio_commit_request(tio_req);
31012 +       USB_TIO_UNLOCK(&tio_lock, flag);
31013 +       return USB_TIO_OK;
31014 +}
31015 +
31016 +/*
31017 + * usb_tio_read_fifo()
31018 + *     Synchronously read FIFO.
31019 + */
31020 +u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes)
31021 +{
31022 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
31023 +       unsigned long flag;
31024 +
31025 +       /*
31026 +        * Wait for any previous request to complete and then make this request.
31027 +        */
31028 +       USB_TIO_LOCK(&tio_lock, flag);
31029 +       usb_tio_wait_hrt();
31030 +
31031 +       /*
31032 +        * Fill in the request.
31033 +        */
31034 +       tio_req->address = address;
31035 +       tio_req->cmd = USB_TIO_READ_FIFO_SYNC;
31036 +       tio_req->buffer = buffer;
31037 +       tio_req->transfer_length = bytes;
31038 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
31039 +
31040 +       /*
31041 +        * commit the request
31042 +        */
31043 +       usb_tio_commit_request(tio_req);
31044 +
31045 +        /*
31046 +        * Wait for the result to show up.
31047 +        */
31048 +       usb_tio_wait_hrt();
31049 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
31050 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
31051 +       USB_TIO_UNLOCK(&tio_lock, flag);
31052 +       return USB_TIO_OK;
31053 +}
31054 +
31055 +/*
31056 + * usb_tio_write_fifo()
31057 + *     Synchronously  write 32 bits.
31058 + */
31059 +u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes)
31060 +{
31061 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
31062 +       unsigned long flag;
31063 +
31064 +       USB_TIO_LOCK(&tio_lock, flag);
31065 +       usb_tio_wait_hrt();
31066 +
31067 +       tio_req->address = address;
31068 +       tio_req->buffer = buffer;
31069 +       tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
31070 +       tio_req->transfer_length = bytes;
31071 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
31072 +       /*
31073 +        * commit the request
31074 +        */
31075 +       usb_tio_commit_request(tio_req);
31076 +       
31077 +       /*
31078 +        * Wait for the result to show up.
31079 +        */
31080 +       usb_tio_wait_hrt();
31081 +       USB_TIO_REQUEST_VERIFY_MAGIC(tio_req);
31082 +       USB_TIO_REQUEST_CLEAR_MAGIC(tio_req);
31083 +       USB_TIO_UNLOCK(&tio_lock, flag);
31084 +       return USB_TIO_OK;
31085 +}
31086 +
31087 +/*
31088 + * usb_tio_write_fifo_async()
31089 + *     Asynchronously write 32 bits.
31090 + */
31091 +u8_t usb_tio_write_fifo_async(u32_t address, u32_t buffer, u32_t bytes)
31092 +{
31093 +       volatile struct usb_tio_request *tio_req = &usb_node->request;
31094 +       unsigned long flag;
31095 +
31096 +       USB_TIO_LOCK(&tio_lock, flag);
31097 +       usb_tio_wait_hrt();
31098 +
31099 +       tio_req->address = address;
31100 +       
31101 +       /*
31102 +        * Is it necessary to make a local copy of the buffer? Any chance the URB is aborted before TIO finished the FIFO write?
31103 +        */
31104 +       tio_req->buffer = buffer;
31105 +       tio_req->cmd = USB_TIO_WRITE_FIFO_SYNC;
31106 +       tio_req->transfer_length = bytes;
31107 +       USB_TIO_REQUEST_SET_MAGIC(tio_req);
31108 +       /*
31109 +        * commit the request
31110 +        */
31111 +       usb_tio_commit_request(tio_req);
31112 +       USB_TIO_UNLOCK(&tio_lock, flag);
31113 +       return USB_TIO_OK;
31114 +}
31115 +
31116 +/*
31117 + * usb_tio_read_int_status()
31118 + *     read and clear the interrupt status registers
31119 + */
31120 +void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
31121 +{
31122 +
31123 +       /*
31124 +        * clear the interrupt must be syncronized with the TIO thread to prevent the racing condiiton 
31125 +        * that TIO thread try to set it at same time
31126 +        */
31127 +       asm volatile (
31128 +       "1:     bset (%0), (%0), #0     \n\t" \
31129 +       "       jmpne.f 1b              \n\t" \
31130 +               :
31131 +               : "a" (&usb_node->usb_vp_control)
31132 +               : "memory", "cc"
31133 +       );
31134 +
31135 +       *int_usb = usb_node->usb_vp_hw_int_usb;
31136 +       *int_tx  = cpu_to_le16(usb_node->usb_vp_hw_int_tx);
31137 +       *int_rx  = cpu_to_le16(usb_node->usb_vp_hw_int_rx);
31138 +
31139 +       //printk(KERN_INFO "int read %x, %x, %x\n", *int_usb, *int_tx, *int_rx);
31140 +       
31141 +       /* 
31142 +        * The interrupt status register is read-clean, so clear it now
31143 +        */
31144 +       usb_node->usb_vp_hw_int_usb = 0;
31145 +       usb_node->usb_vp_hw_int_tx = 0;
31146 +       usb_node->usb_vp_hw_int_rx = 0;
31147 +
31148 +       /*
31149 +        * release the lock bit
31150 +        */
31151 +       usb_node->usb_vp_control &= 0xfffe;
31152 +}
31153 --- /dev/null
31154 +++ b/arch/ubicom32/mach-common/usb_tio.h
31155 @@ -0,0 +1,111 @@
31156 +/*
31157 + * arch/ubicom32/mach-common/usb_tio.h
31158 + *   Definitions for usb_tio.c
31159 + *
31160 + * (C) Copyright 2009, Ubicom, Inc.
31161 + *
31162 + * This file is part of the Ubicom32 Linux Kernel Port.
31163 + *
31164 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31165 + * it and/or modify it under the terms of the GNU General Public License
31166 + * as published by the Free Software Foundation, either version 2 of the
31167 + * License, or (at your option) any later version.
31168 + *
31169 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31170 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31171 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31172 + * the GNU General Public License for more details.
31173 + *
31174 + * You should have received a copy of the GNU General Public License
31175 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31176 + * see <http://www.gnu.org/licenses/>.
31177 + *
31178 + * Ubicom32 implementation derived from (with many thanks):
31179 + *   arch/m68knommu
31180 + *   arch/blackfin
31181 + *   arch/parisc
31182 + */
31183 +
31184 +#include <linux/version.h>
31185 +#include <linux/kernel.h>
31186 +#include <linux/types.h>
31187 +#include <linux/errno.h>
31188 +#include <linux/err.h>
31189 +#include <asm/devtree.h>
31190 +#include <asm/ip5000.h>
31191 +
31192 +#ifndef _USB_TIO_H
31193 +#define _USB_TIO_H
31194 +
31195 +#undef  USB_TIO_DEBUG
31196 +
31197 +#define USB_TIO_REQUEST_MAGIC1 0x2307
31198 +#define USB_TIO_REQUEST_MAGIC2 0x0789
31199 +#if defined(USB_TIO_DEBUG)
31200 +#define USB_TIO_REQUEST_VERIFY_MAGIC(req)      usb_tio_request_verify_magic(req)
31201 +#define USB_TIO_REQUEST_SET_MAGIC(req)          usb_tio_request_set_magic(req)
31202 +#define USB_TIO_REQUEST_CLEAR_MAGIC(req)       usb_tio_request_clear_magic(req)
31203 +#else
31204 +#define USB_TIO_REQUEST_VERIFY_MAGIC(req)
31205 +#define USB_TIO_REQUEST_SET_MAGIC(req)          usb_tio_request_set_magic(req)
31206 +#define USB_TIO_REQUEST_CLEAR_MAGIC(req)
31207 +#endif
31208 +
31209 +enum USB_TIO_status {
31210 +       USB_TIO_OK,
31211 +       USB_TIO_ERROR,
31212 +       USB_TIO_ERROR_COMMIT,
31213 +};
31214 +
31215 +enum USB_TIO_cmds {
31216 +       USB_TIO_READ16_SYNC,
31217 +       USB_TIO_READ8_SYNC,
31218 +       USB_TIO_READ_FIFO_SYNC,
31219 +
31220 +       USB_TIO_WRITE16_ASYNC,
31221 +       USB_TIO_WRITE8_ASYNC,
31222 +       USB_TIO_WRITE_FIFO_ASYNC,
31223 +
31224 +       USB_TIO_WRITE16_SYNC,
31225 +       USB_TIO_WRITE8_SYNC,
31226 +       USB_TIO_WRITE_FIFO_SYNC,
31227 +
31228 +};
31229 +
31230 +enum USB_TIO_state {
31231 +       USB_TIO_NORMAL,
31232 +       USB_TIO_DMA_SETUP,
31233 +};
31234 +
31235 +struct usb_tio_request {
31236 +       volatile u32_t address;
31237 +       union {
31238 +               volatile u32_t data;
31239 +               volatile u32_t buffer;
31240 +       };
31241 +       volatile u16_t cmd;
31242 +       const volatile u16_t status;
31243 +       volatile u32_t transfer_length;
31244 +       volatile u32_t thread_mask;
31245 +       volatile u16_t magic;
31246 +};
31247 +
31248 +struct usbtio_node {
31249 +       struct devtree_node dn;
31250 +       volatile struct usb_tio_request * volatile pdesc;
31251 +       struct usb_tio_request  request;
31252 +       volatile u32_t usb_vp_config;
31253 +       volatile u32_t usb_vp_control;
31254 +       const volatile u32_t usb_vp_status;
31255 +       volatile u16_t usb_vp_hw_int_tx;
31256 +       volatile u16_t usb_vp_hw_int_rx;
31257 +       volatile u8_t  usb_vp_hw_int_usb;
31258 +       volatile u8_t usb_vp_hw_int_mask_usb;
31259 +        volatile u16_t usb_vp_hw_int_mask_tx;
31260 +        volatile u16_t usb_vp_hw_int_mask_rx;
31261 +
31262 +};
31263 +
31264 +extern struct usbtio_node *usb_node;
31265 +extern void ubi32_usb_init(void);
31266 +#endif
31267 --- /dev/null
31268 +++ b/arch/ubicom32/mach-common/vdc_tio.c
31269 @@ -0,0 +1,111 @@
31270 +/*
31271 + * arch/ubicom32/mach-common/vdc_tio.c
31272 + *   Generic initialization for VDC
31273 + *
31274 + * (C) Copyright 2009, Ubicom, Inc.
31275 + *
31276 + * This file is part of the Ubicom32 Linux Kernel Port.
31277 + *
31278 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31279 + * it and/or modify it under the terms of the GNU General Public License
31280 + * as published by the Free Software Foundation, either version 2 of the
31281 + * License, or (at your option) any later version.
31282 + *
31283 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31284 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31285 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31286 + * the GNU General Public License for more details.
31287 + *
31288 + * You should have received a copy of the GNU General Public License
31289 + * along with the Ubicom32 Linux Kernel Port.  If not,
31290 + * see <http://www.gnu.org/licenses/>.
31291 + *
31292 + * Ubicom32 implementation derived from (with many thanks):
31293 + *   arch/m68knommu
31294 + *   arch/blackfin
31295 + *   arch/parisc
31296 + */
31297 +
31298 +#include <linux/platform_device.h>
31299 +#include <linux/types.h>
31300 +
31301 +#include <asm/devtree.h>
31302 +#include <asm/vdc_tio.h>
31303 +
31304 +/*
31305 + * Resources that this driver uses
31306 + */
31307 +static struct resource vdc_tio_resources[] = {
31308 +       /*
31309 +        * Send IRQ
31310 +        */
31311 +       [0] = {
31312 +               /*
31313 +                * The init routine will query the devtree and fill this in
31314 +                */
31315 +               .flags  = IORESOURCE_IRQ,
31316 +       },
31317 +
31318 +       /*
31319 +        * Receive IRQ (optional)
31320 +        */
31321 +       [1] = {
31322 +               /*
31323 +                * The init routine will query the devtree and fill this in
31324 +                */
31325 +               .flags  = IORESOURCE_IRQ,
31326 +       },
31327 +
31328 +       /*
31329 +        * Memory Mapped Registers
31330 +        */
31331 +       [2] = {
31332 +               /*
31333 +                * The init routine will query the devtree and fill this in
31334 +                */
31335 +               .flags  = IORESOURCE_MEM,
31336 +       },
31337 +};
31338 +
31339 +/*
31340 + * The platform_device structure which is passed to the driver
31341 + */
31342 +static struct platform_device vdc_tio_platform_device = {
31343 +       .name           = "ubicom32fb",
31344 +       .id             = -1,
31345 +       .resource       = vdc_tio_resources,
31346 +       .num_resources  = ARRAY_SIZE(vdc_tio_resources),
31347 +};
31348 +
31349 +/*
31350 + * vdc_tio_init
31351 + *     Checks the device tree and instantiates the driver if found
31352 + */
31353 +void __init vdc_tio_init(void)
31354 +{
31355 +       /*
31356 +        * Check the device tree for the vdc_tio
31357 +        */
31358 +       struct vdc_tio_node *vdc_node =
31359 +               (struct vdc_tio_node *)devtree_find_node("vdctio");
31360 +       if (!vdc_node) {
31361 +               printk(KERN_WARNING "No vdc_tio found\n");
31362 +               return;
31363 +       }
31364 +
31365 +       /*
31366 +        * Fill in the resources and platform data from devtree information
31367 +        */
31368 +       vdc_tio_resources[0].start = vdc_node->dn.sendirq;
31369 +       vdc_tio_resources[1].start = vdc_node->dn.recvirq;
31370 +       vdc_tio_resources[2].start = (u32_t)vdc_node->regs;
31371 +       vdc_tio_resources[2].end = (u32_t)vdc_node->regs +
31372 +               sizeof(struct vdc_tio_vp_regs);
31373 +
31374 +       /*
31375 +        * Try to get the device registered
31376 +        */
31377 +       if (platform_device_register(&vdc_tio_platform_device) < 0) {
31378 +               printk(KERN_WARNING "VDC failed to register\n");
31379 +       }
31380 +}
31381 --- /dev/null
31382 +++ b/arch/ubicom32/mach-ip5k/board-ip5160dev.c
31383 @@ -0,0 +1,110 @@
31384 +/*
31385 + * arch/ubicom32/mach-ip5k/board-ip5160dev.c
31386 + *   Platform initialization for ip5160dev board.
31387 + *
31388 + * (C) Copyright 2009, Ubicom, Inc.
31389 + *
31390 + * This file is part of the Ubicom32 Linux Kernel Port.
31391 + *
31392 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31393 + * it and/or modify it under the terms of the GNU General Public License
31394 + * as published by the Free Software Foundation, either version 2 of the
31395 + * License, or (at your option) any later version.
31396 + *
31397 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31398 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31399 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31400 + * the GNU General Public License for more details.
31401 + *
31402 + * You should have received a copy of the GNU General Public License
31403 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31404 + * see <http://www.gnu.org/licenses/>.
31405 + *
31406 + * Ubicom32 implementation derived from (with many thanks):
31407 + *   arch/m68knommu
31408 + *   arch/blackfin
31409 + *   arch/parisc
31410 + */
31411 +#include <linux/device.h>
31412 +#include <linux/platform_device.h>
31413 +#include <linux/gpio.h>
31414 +
31415 +#include <asm/board.h>
31416 +#include <asm/machdep.h>
31417 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31418 +#include <asm/ubicom32suart.h>
31419 +#endif
31420 +
31421 +/*
31422 + * Factory Default Button on the board at PXn
31423 + * TODO: This is just a placeholder and it needs to include proper header files
31424 + */
31425 +struct ubicom32fdb_platform_data {
31426 +       int             fdb_gpio;
31427 +       bool            fdb_polarity;
31428 +};
31429 +
31430 +static struct ubicom32fdb_platform_data ip5160dev_fdb_data = {
31431 +       .fdb_gpio               = 0,
31432 +       .fdb_polarity           = true,
31433 +};
31434 +
31435 +static struct platform_device ip5160dev_fdb_device = {
31436 +       .name   = "ubicom32fdb",
31437 +       .id     = -1,
31438 +       .dev    = {
31439 +               .platform_data = &ip5160dev_fdb_data,
31440 +       },
31441 +};
31442 +
31443 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31444 +static struct resource ip5160dev_ubicom32_suart_resources[] = {
31445 +        {
31446 +               .start  = RD,
31447 +               .end    = RD,
31448 +               .flags  = IORESOURCE_MEM,
31449 +        },
31450 +        {
31451 +               .start  = PORT_OTHER_INT(RD),
31452 +               .end    = PORT_OTHER_INT(RD),
31453 +               .flags  = IORESOURCE_IRQ,
31454 +        },
31455 +        {
31456 +               .start  = 240000000,
31457 +               .end    = 240000000,
31458 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
31459 +        },
31460 +};
31461 +
31462 +static struct platform_device ip5160dev_ubicom32_suart_device = {
31463 +       .name           = "ubicom32suart",
31464 +       .id             = -1,
31465 +        .num_resources  = ARRAY_SIZE(ip5160dev_ubicom32_suart_resources),
31466 +        .resource       = ip5160dev_ubicom32_suart_resources,
31467 +};
31468 +#endif
31469 +
31470 +/*
31471 + * List of all devices in our system
31472 + */
31473 +static struct platform_device *ip5160dev_devices[] __initdata = {
31474 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31475 +       &ip5160dev_ubicom32_suart_device,
31476 +#endif
31477 +       &ip5160dev_fdb_device,
31478 +};
31479 +
31480 +/*
31481 + * ip5160dev_init
31482 + *     Called to add the devices which we have on this board
31483 + */
31484 +static int __init ip5160dev_init(void)
31485 +{
31486 +       ubi_gpio_init();
31487 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31488 +       platform_add_devices(ip5160dev_devices, ARRAY_SIZE(ip5160dev_devices));
31489 +       return 0;
31490 +}
31491 +
31492 +arch_initcall(ip5160dev_init);
31493 +
31494 --- /dev/null
31495 +++ b/arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31496 @@ -0,0 +1,76 @@
31497 +/*
31498 + * arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31499 + *   Platform initialization for ip5160rgw board.
31500 + *
31501 + * (C) Copyright 2009, Ubicom, Inc.
31502 + *
31503 + * This file is part of the Ubicom32 Linux Kernel Port.
31504 + *
31505 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31506 + * it and/or modify it under the terms of the GNU General Public License
31507 + * as published by the Free Software Foundation, either version 2 of the
31508 + * License, or (at your option) any later version.
31509 + *
31510 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31511 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31512 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31513 + * the GNU General Public License for more details.
31514 + *
31515 + * You should have received a copy of the GNU General Public License
31516 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31517 + * see <http://www.gnu.org/licenses/>.
31518 + *
31519 + * Ubicom32 implementation derived from (with many thanks):
31520 + *   arch/m68knommu
31521 + *   arch/blackfin
31522 + *   arch/parisc
31523 + */
31524 +#include <linux/device.h>
31525 +#include <linux/platform_device.h>
31526 +#include <linux/gpio.h>
31527 +#include <asm/board.h>
31528 +#include <asm/machdep.h>
31529 +
31530 +/*
31531 + * Factory Default Button on the board at PXn
31532 + * TODO: This is just a placeholder and it needs to include proper header files
31533 + */
31534 +struct ubicom32fdb_platform_data {
31535 +       int             fdb_gpio;
31536 +       bool            fdb_polarity;
31537 +};
31538 +
31539 +static struct ubicom32fdb_platform_data ip5160rgw_fdb_data = {
31540 +       .fdb_gpio               = 0,
31541 +       .fdb_polarity           = true,
31542 +};
31543 +
31544 +static struct platform_device ip5160rgw_fdb_device = {
31545 +       .name   = "ubicom32fdb",
31546 +       .id     = -1,
31547 +       .dev    = {
31548 +               .platform_data = &ip5160rgw_fdb_data,
31549 +       },
31550 +};
31551 +
31552 +/*
31553 + * List of all devices in our system
31554 + */
31555 +static struct platform_device *ip5160rgw_devices[] __initdata = {
31556 +       &ip5160rgw_fdb_device,
31557 +};
31558 +
31559 +/*
31560 + * ip5160rgw_init
31561 + *     Called to add the devices which we have on this board
31562 + */
31563 +static int __init ip5160rgw_init(void)
31564 +{
31565 +       ubi_gpio_init();
31566 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31567 +       platform_add_devices(ip5160rgw_devices, ARRAY_SIZE(ip5160rgw_devices));
31568 +       return 0;
31569 +}
31570 +
31571 +arch_initcall(ip5160rgw_init);
31572 +
31573 --- /dev/null
31574 +++ b/arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31575 @@ -0,0 +1,280 @@
31576 +/*
31577 + * arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31578 + *   Platform initialization for ip5160dpf board.
31579 + *
31580 + * (C) Copyright 2009, Ubicom, Inc.
31581 + *
31582 + * This file is part of the Ubicom32 Linux Kernel Port.
31583 + *
31584 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31585 + * it and/or modify it under the terms of the GNU General Public License
31586 + * as published by the Free Software Foundation, either version 2 of the
31587 + * License, or (at your option) any later version.
31588 + *
31589 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31590 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31591 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31592 + * the GNU General Public License for more details.
31593 + *
31594 + * You should have received a copy of the GNU General Public License
31595 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31596 + * see <http://www.gnu.org/licenses/>.
31597 + *
31598 + * Ubicom32 implementation derived from (with many thanks):
31599 + *   arch/m68knommu
31600 + *   arch/blackfin
31601 + *   arch/parisc
31602 + */
31603 +#include <linux/device.h>
31604 +#include <linux/platform_device.h>
31605 +#include <linux/gpio.h>
31606 +#include <linux/leds.h>
31607 +
31608 +#include <linux/i2c.h>
31609 +#include <linux/i2c-gpio.h>
31610 +
31611 +#include <linux/input.h>
31612 +#include <asm/board.h>
31613 +#include <asm/machdep.h>
31614 +#include <asm/ubicom32hid.h>
31615 +#include <asm/vdc_tio.h>
31616 +
31617 +/*
31618 + * LEDs
31619 + *
31620 + * WLAN                        PD9     (Note this is shared with MISO, but we don't use it)
31621 + * WPS                 PD8
31622 + *
31623 + * TODO: check triggers, are they generic?
31624 + */
31625 +static struct gpio_led ip5170dpf_gpio_leds[] = {
31626 +       {
31627 +               .name                   = "d31:green:WLAN1",
31628 +               .default_trigger        = "WLAN1",
31629 +               .gpio                   = GPIO_RD_9,
31630 +               .active_low             = 1,
31631 +       },
31632 +       {
31633 +               .name                   = "d30:green:WPS",
31634 +               .default_trigger        = "WPS",
31635 +               .gpio                   = GPIO_RD_8,
31636 +               .active_low             = 1,
31637 +       },
31638 +};
31639 +
31640 +static struct gpio_led_platform_data ip5170dpf_gpio_led_platform_data = {
31641 +       .num_leds       = 2,
31642 +       .leds           = ip5170dpf_gpio_leds,
31643 +};
31644 +
31645 +static struct platform_device ip5170dpf_gpio_leds_device = {
31646 +       .name           = "leds-gpio",
31647 +       .id             = -1,
31648 +       .dev = {
31649 +               .platform_data = &ip5170dpf_gpio_led_platform_data,
31650 +       },
31651 +};
31652 +
31653 +/*
31654 + * Backlight on the board PD0, hardware PWM
31655 + */
31656 +static const struct ubicom32hid_button ip5170dpf_ubicom32hid_buttons[] = {
31657 +       {
31658 +               .type   = EV_KEY,
31659 +               .code   = KEY_UP,
31660 +               .bit    = 0,
31661 +       },
31662 +       {
31663 +               .type   = EV_KEY,
31664 +               .code   = KEY_LEFT,
31665 +               .bit    = 1,
31666 +       },
31667 +       {
31668 +               .type   = EV_KEY,
31669 +               .code   = KEY_RIGHT,
31670 +               .bit    = 2,
31671 +       },
31672 +       {
31673 +               .type   = EV_KEY,
31674 +               .code   = KEY_DOWN,
31675 +               .bit    = 3,
31676 +       },
31677 +       {
31678 +               .type   = EV_KEY,
31679 +               .code   = KEY_ENTER,
31680 +               .bit    = 4,
31681 +       },
31682 +       {
31683 +               .type   = EV_KEY,
31684 +               .code   = KEY_MENU,
31685 +               .bit    = 5,
31686 +       },
31687 +       {
31688 +               .type   = EV_KEY,
31689 +               .code   = KEY_ESC,
31690 +               .bit    = 7,
31691 +       },
31692 +};
31693 +
31694 +static const struct ubicom32hid_ir ip5170dpf_ubicom32hid_ircodes[] = {
31695 +       {
31696 +               .type           = EV_KEY,
31697 +               .code           = KEY_UP,
31698 +               .ir_code        = 0xF807916E
31699 +       },
31700 +       {
31701 +               .type           = EV_KEY,
31702 +               .code           = KEY_DOWN,
31703 +               .ir_code        = 0xF20D916E
31704 +       },
31705 +       {
31706 +               .type           = EV_KEY,
31707 +               .code           = KEY_LEFT,
31708 +               .ir_code        = 0xF609916E
31709 +       },
31710 +       {
31711 +               .type           = EV_KEY,
31712 +               .code           = KEY_RIGHT,
31713 +               .ir_code        = 0xF40B916E
31714 +       },
31715 +       {
31716 +               .type           = EV_KEY,
31717 +               .code           = KEY_ENTER,
31718 +               .ir_code        = 0xF50A916E
31719 +       },
31720 +       {       /* rotate */
31721 +               .type           = EV_KEY,
31722 +               .code           = KEY_FN_F1,
31723 +               .ir_code        = 0xF906916E
31724 +       },
31725 +       {
31726 +               .type           = EV_KEY,
31727 +               .code           = KEY_MENU,
31728 +               .ir_code        = 0xF708916E
31729 +       },
31730 +       {       /* font size */
31731 +               .type           = EV_KEY,
31732 +               .code           = KEY_FN_F2,
31733 +               .ir_code        = 0xF30C916E
31734 +       },
31735 +       {       
31736 +               .type           = EV_KEY,
31737 +               .code           = KEY_ESC,
31738 +               .ir_code        = 0xF10E916E
31739 +       },
31740 +       {
31741 +               .type           = EV_KEY,
31742 +               .code           = KEY_VOLUMEUP,
31743 +               .ir_code        = 0xF00F916E
31744 +       },
31745 +       {
31746 +               .type           = EV_KEY,
31747 +               .code           = KEY_VOLUMEDOWN,
31748 +               .ir_code        = 0xED12916E
31749 +       },
31750 +       {
31751 +               .type           = EV_KEY,
31752 +               .code           = KEY_MUTE,
31753 +               .ir_code        = 0xEA15916E
31754 +       },
31755 +       {
31756 +               .type           = EV_KEY,
31757 +               .code           = KEY_INFO,
31758 +               .ir_code        = 0xEF10916E
31759 +       },
31760 +       {       /* Like */
31761 +               .type           = EV_KEY,
31762 +               .code           = KEY_FN_F3,
31763 +               .ir_code        = 0xEE11916E
31764 +       },
31765 +       {       /* Dislike */
31766 +               .type           = EV_KEY,
31767 +               .code           = KEY_FN_F4,
31768 +               .ir_code        = 0xEB14916E
31769 +       },
31770 +       {
31771 +               .type           = EV_KEY,
31772 +               .code           = KEY_POWER,
31773 +               .ir_code        = 0xFD02916E
31774 +       },
31775 +};
31776 +
31777 +static struct ubicom32hid_platform_data ip5170dpf_ubicom32hid_platform_data = {
31778 +       .gpio_reset             = GPIO_RA_4,
31779 +       .gpio_reset_polarity    = 0,
31780 +       .type                   = UBICOM32HID_BL_TYPE_BINARY,
31781 +       .invert                 = 0,
31782 +       .default_intensity      = 1,
31783 +       .buttons                = ip5170dpf_ubicom32hid_buttons,
31784 +       .nbuttons               = ARRAY_SIZE(ip5170dpf_ubicom32hid_buttons),
31785 +       .ircodes                = ip5170dpf_ubicom32hid_ircodes,
31786 +       .nircodes               = ARRAY_SIZE(ip5170dpf_ubicom32hid_ircodes),
31787 +};
31788 +
31789 +/*
31790 + * Devices on the I2C bus
31791 + */
31792 +static struct i2c_board_info __initdata ip5170dpf_i2c_board_info[] = {
31793 +       /*
31794 +        * U24, ubicom32hid
31795 +        */
31796 +       {
31797 +               .type           = "ubicom32hid",
31798 +               .addr           = 0x08,
31799 +               .platform_data  = &ip5170dpf_ubicom32hid_platform_data,
31800 +       },
31801 +
31802 +       /*
31803 +        * U14, CS4350 DAC, address 0x4B
31804 +        */
31805 +};
31806 +
31807 +/*
31808 + * I2C bus on the board, SDA PF13, SCL PF14
31809 + */
31810 +static struct i2c_gpio_platform_data ip5170dpf_i2c_data = {
31811 +       .sda_pin                = GPIO_RF_13,
31812 +       .scl_pin                = GPIO_RF_14,
31813 +       .sda_is_open_drain      = 0,
31814 +       .scl_is_open_drain      = 0,
31815 +       .scl_is_output_only     = 1,
31816 +       .udelay                 = 5,
31817 +};
31818 +
31819 +static struct platform_device ip5170dpf_i2c_device = {
31820 +       .name   = "i2c-gpio",
31821 +       .id     = 0,
31822 +       .dev    = {
31823 +               .platform_data = &ip5170dpf_i2c_data,
31824 +       },
31825 +};
31826 +
31827 +/*
31828 + * List of all devices in our system
31829 + */
31830 +static struct platform_device *ip5170dpf_devices[] __initdata = {
31831 +       &ip5170dpf_i2c_device,
31832 +       &ip5170dpf_gpio_leds_device,
31833 +};
31834 +
31835 +/*
31836 + * ip5170dpf_init
31837 + *     Called to add the devices which we have on this board
31838 + */
31839 +static int __init ip5170dpf_init(void)
31840 +{
31841 +       ubi_gpio_init();
31842 +
31843 +       vdc_tio_init();
31844 +
31845 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31846 +       platform_add_devices(ip5170dpf_devices, ARRAY_SIZE(ip5170dpf_devices));
31847 +
31848 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
31849 +       i2c_register_board_info(0, ip5170dpf_i2c_board_info, ARRAY_SIZE(ip5170dpf_i2c_board_info));
31850 +
31851 +       return 0;
31852 +}
31853 +
31854 +arch_initcall(ip5170dpf_init);
31855 +
31856 --- /dev/null
31857 +++ b/arch/ubicom32/mach-ip5k/Kconfig
31858 @@ -0,0 +1,32 @@
31859 +
31860 +config IP5170DPF
31861 +       bool "IP5170DPF"
31862 +       select UBICOM32_V3
31863 +       select I2C
31864 +       select I2C_GPIO
31865 +       select FB
31866 +       select FB_UBICOM32
31867 +       select BACKLIGHT_LCD_SUPPORT
31868 +       select BACKLIGHT_CLASS_DEVICE
31869 +       select UBICOM_HID
31870 +       select NEW_LEDS
31871 +       select LEDS_CLASS
31872 +       select LEDS_GPIO
31873 +       select BRD_64MB
31874 +       help
31875 +               IP5170 Digital Picture Frame board, 8005-1113, IP5K-BEV-0011-13 v1.3
31876 +
31877 +config IP5160DEV
31878 +       bool "IP5160Dev_Ver1Dot1"
31879 +       select UBICOM32_V3
31880 +       select BRD_64MB
31881 +       help
31882 +               Ubicom StreamEngine 5000 Development Board, IP5K-BDV-0004-11 v1.1
31883 +
31884 +config IP5160EVAL
31885 +       bool "IP5160RGWEval_Ver2Rev2"
31886 +       select UBICOM32_V3
31887 +       select BRD_32MB
31888 +       help
31889 +               Ubicom StreamEngine 5000 RGW Evaluation Board, IP5K-RGW-0004-11 v2.2
31890 +
31891 --- /dev/null
31892 +++ b/arch/ubicom32/mach-ip5k/Makefile
31893 @@ -0,0 +1,32 @@
31894 +#
31895 +# arch/ubicom32/mach-ip5k/Makefile
31896 +#      Makefile for boards which have an ip5k on them.
31897 +#
31898 +# (C) Copyright 2009, Ubicom, Inc.
31899 +#
31900 +# This file is part of the Ubicom32 Linux Kernel Port.
31901 +#
31902 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
31903 +# it and/or modify it under the terms of the GNU General Public License
31904 +# as published by the Free Software Foundation, either version 2 of the
31905 +# License, or (at your option) any later version.
31906 +#
31907 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
31908 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
31909 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31910 +# the GNU General Public License for more details.
31911 +#
31912 +# You should have received a copy of the GNU General Public License
31913 +# along with the Ubicom32 Linux Kernel Port.  If not, 
31914 +# see <http://www.gnu.org/licenses/>.
31915 +#
31916 +# Ubicom32 implementation derived from (with many thanks):
31917 +#   arch/m68knommu
31918 +#   arch/blackfin
31919 +#   arch/parisc
31920 +#
31921 +
31922 +obj-$(CONFIG_IP5170DPF)                += board-ip5170dpf.o
31923 +obj-$(CONFIG_IP5160DEV)                += board-ip5160dev.o
31924 +obj-$(CONFIG_IP5160EVAL)       += board-ip5160rgw.o
31925 +
31926 --- /dev/null
31927 +++ b/arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31928 @@ -0,0 +1,716 @@
31929 +/*
31930 + * arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31931 + *   Board file for IP7145DPF, rev 1.0, P/N 8007-0410
31932 + *
31933 + * (C) Copyright 2009, Ubicom, Inc.
31934 + *
31935 + * This file is part of the Ubicom32 Linux Kernel Port.
31936 + *
31937 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
31938 + * it and/or modify it under the terms of the GNU General Public License
31939 + * as published by the Free Software Foundation, either version 2 of the
31940 + * License, or (at your option) any later version.
31941 + *
31942 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
31943 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
31944 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31945 + * the GNU General Public License for more details.
31946 + *
31947 + * You should have received a copy of the GNU General Public License
31948 + * along with the Ubicom32 Linux Kernel Port.  If not, 
31949 + * see <http://www.gnu.org/licenses/>.
31950 + *
31951 + * Ubicom32 implementation derived from (with many thanks):
31952 + *   arch/m68knommu
31953 + *   arch/blackfin
31954 + *   arch/parisc
31955 + */
31956 +#include <linux/device.h>
31957 +#include <linux/platform_device.h>
31958 +#include <linux/gpio.h>
31959 +
31960 +#include <linux/input.h>
31961 +
31962 +#include <linux/i2c.h>
31963 +#include <linux/i2c-gpio.h>
31964 +#include <linux/i2c/pca953x.h>
31965 +
31966 +#include <asm/board.h>
31967 +#include <asm/machdep.h>
31968 +#include <asm/ubicom32input.h>
31969 +#include <asm/ubicom32input_i2c.h>
31970 +#include <asm/ubicom32bl.h>
31971 +#include <asm/ubicom32lcd.h>
31972 +#include <asm/vdc_tio.h>
31973 +
31974 +#include <asm/ubicom32sd.h>
31975 +#include <asm/sd_tio.h>
31976 +#include <asm/devtree.h>
31977 +#include <asm/audio_tio.h>
31978 +
31979 +#include <asm/ring_tio.h>
31980 +
31981 +/******************************************************************************
31982 + * SD/IO Port F (Slot 1) platform data
31983 + */
31984 +static struct resource ip7145dpf_portf_sd_resources[] = {
31985 +       /*
31986 +        * Send IRQ
31987 +        */
31988 +       [0] = {
31989 +               /* 
31990 +                * The init routine will query the devtree and fill this in
31991 +                */
31992 +               .flags  = IORESOURCE_IRQ,
31993 +       },
31994 +
31995 +       /*
31996 +        * Receive IRQ
31997 +        */
31998 +       [1] = {
31999 +               /* 
32000 +                * The init routine will query the devtree and fill this in
32001 +                */
32002 +               .flags  = IORESOURCE_IRQ,
32003 +       },
32004 +
32005 +       /*
32006 +        * Memory Mapped Registers
32007 +        */
32008 +       [2] = {
32009 +               /* 
32010 +                * The init routine will query the devtree and fill this in
32011 +                */
32012 +               .flags  = IORESOURCE_MEM,
32013 +       },
32014 +};
32015 +
32016 +static struct ubicom32sd_card ip7145dpf_portf_sd_cards[] = {
32017 +       [0] = {
32018 +               .pin_wp         = IP7145DPF_IOB0,
32019 +               .wp_polarity    = 1,
32020 +               .pin_pwr        = IP7145DPF_IOB4,
32021 +               .pin_cd         = GPIO_RA_4,
32022 +       },
32023 +       [1] = {
32024 +               .pin_wp         = IP7145DPF_IOB1,
32025 +               .wp_polarity    = 1,
32026 +               .pin_pwr        = IP7145DPF_IOB5,
32027 +               .pin_cd         = GPIO_RA_6,
32028 +       },
32029 +};
32030 +
32031 +static struct ubicom32sd_platform_data ip7145dpf_portf_sd_platform_data = {
32032 +       .ncards         = 2,
32033 +       .cards          = ip7145dpf_portf_sd_cards, 
32034 +};
32035 +
32036 +static struct platform_device ip7145dpf_portf_sd_device = {
32037 +       .name           = "ubicom32sd",
32038 +       .id             = 0,
32039 +       .resource       = ip7145dpf_portf_sd_resources,
32040 +       .num_resources  = ARRAY_SIZE(ip7145dpf_portf_sd_resources),
32041 +       .dev            = {
32042 +                       .platform_data = &ip7145dpf_portf_sd_platform_data,
32043 +       },
32044 +
32045 +};
32046 +
32047 +/*
32048 + * ip7145dpf_portf_sd_init
32049 + */
32050 +static void ip7145dpf_portf_sd_init(void)
32051 +{
32052 +       /*
32053 +        * Check the device tree for the sd_tio
32054 +        */
32055 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
32056 +       if (!sd_node) {
32057 +               printk(KERN_INFO "PortF SDTIO not found\n");
32058 +               return;
32059 +       }
32060 +
32061 +       /*
32062 +        * Fill in the resources and platform data from devtree information
32063 +        */
32064 +       ip7145dpf_portf_sd_resources[0].start = sd_node->dn.sendirq;
32065 +       ip7145dpf_portf_sd_resources[1].start = sd_node->dn.recvirq;
32066 +       ip7145dpf_portf_sd_resources[2].start = (u32_t)&(sd_node->regs);
32067 +       ip7145dpf_portf_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
32068 +
32069 +       platform_device_register(&ip7145dpf_portf_sd_device);
32070 +}
32071 +
32072 +/******************************************************************************
32073 + * SD/IO Port B (Slot 2) platform data
32074 + */
32075 +static struct resource ip7145dpf_portb_sd_resources[] = {
32076 +       /*
32077 +        * Send IRQ
32078 +        */
32079 +       [0] = {
32080 +               /* 
32081 +                * The init routine will query the devtree and fill this in
32082 +                */
32083 +               .flags  = IORESOURCE_IRQ,
32084 +       },
32085 +
32086 +       /*
32087 +        * Receive IRQ
32088 +        */
32089 +       [1] = {
32090 +               /* 
32091 +                * The init routine will query the devtree and fill this in
32092 +                */
32093 +               .flags  = IORESOURCE_IRQ,
32094 +       },
32095 +
32096 +       /*
32097 +        * Memory Mapped Registers
32098 +        */
32099 +       [2] = {
32100 +               /* 
32101 +                * The init routine will query the devtree and fill this in
32102 +                */
32103 +               .flags  = IORESOURCE_MEM,
32104 +       },
32105 +};
32106 +
32107 +static struct ubicom32sd_card ip7145dpf_portb_sd_cards[] = {
32108 +       [0] = {
32109 +               .pin_wp         = IP7145DPF_IOB2,
32110 +               .wp_polarity    = 1,
32111 +               .pin_pwr        = IP7145DPF_IOB6,
32112 +               .pin_cd         = IP7145DPF_IOB3,
32113 +       },
32114 +};
32115 +
32116 +static struct ubicom32sd_platform_data ip7145dpf_portb_sd_platform_data = {
32117 +       .ncards         = 1,
32118 +       .cards          = ip7145dpf_portb_sd_cards,
32119 +};
32120 +
32121 +static struct platform_device ip7145dpf_portb_sd_device = {
32122 +       .name           = "ubicom32sd",
32123 +       .id             = 1,
32124 +       .resource       = ip7145dpf_portb_sd_resources,
32125 +       .num_resources  = ARRAY_SIZE(ip7145dpf_portb_sd_resources),
32126 +       .dev            = {
32127 +                       .platform_data = &ip7145dpf_portb_sd_platform_data,
32128 +       },
32129 +
32130 +};
32131 +
32132 +/*
32133 + * ip7145dpf_portb_sd_init
32134 + */
32135 +static void ip7145dpf_portb_sd_init(void)
32136 +{
32137 +       /*
32138 +        * Check the device tree for the sd_tio
32139 +        */
32140 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
32141 +       if (!sd_node) {
32142 +               printk(KERN_INFO "PortB SDTIO not found\n");
32143 +               return;
32144 +       }
32145 +
32146 +       /*
32147 +        * Fill in the resources and platform data from devtree information
32148 +        */
32149 +       ip7145dpf_portb_sd_resources[0].start = sd_node->dn.sendirq;
32150 +       ip7145dpf_portb_sd_resources[1].start = sd_node->dn.recvirq;
32151 +       ip7145dpf_portb_sd_resources[2].start = (u32_t)&(sd_node->regs);
32152 +       ip7145dpf_portb_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
32153 +
32154 +       platform_device_register(&ip7145dpf_portb_sd_device);
32155 +}
32156 +
32157 +
32158 +#ifdef IP7145DPF_USE_MMC_SPI
32159 +/******************************************************************************
32160 + * SPI over GPIO (MMC_SPI)
32161 + */
32162 +#include <linux/spi/spi.h>
32163 +#include <linux/spi/mmc_spi.h>
32164 +#include <linux/mmc/host.h>
32165 +#include <asm/ubicom32-spi-gpio.h>
32166 +
32167 +#define MMC_CS GPIO_RF_5       // PF5 D3
32168 +#define MMC_CD GPIO_RA_4       // PA4 CD
32169 +#define MMC_WP IP7145DPF_IOB0  // IOB0 WP
32170 +#define MMC_PWR        IP7145DPF_IOB4  // IOB4 PWR
32171 +
32172 +/*
32173 + * SPI bus over GPIO (for SD card)
32174 + */
32175 +static struct ubicom32_spi_gpio_platform_data ip7145dpf_spi_gpio_data = {
32176 +       .pin_mosi       = GPIO_RF_0,    // PF0 CMD
32177 +       .pin_miso       = GPIO_RF_2,    // PF2 D0
32178 +       .pin_clk        = GPIO_RF_1,    // PF1 CLK
32179 +       .bus_num        = 0,            // We'll call this SPI bus 0
32180 +       .num_chipselect = 1,            // only one device on this SPI bus 
32181 +};
32182 +
32183 +static struct platform_device ip7145dpf_spi_gpio_device = {
32184 +       .name   = "ubicom32-spi-gpio",
32185 +       .id     = 0,
32186 +       .dev    = {
32187 +               .platform_data = &ip7145dpf_spi_gpio_data,
32188 +       },
32189 +};
32190 +
32191 +/*
32192 + * ip7145dpf_mmc_spi_setpower_slot_a
32193 + *     Set the power state for slot A
32194 + */
32195 +static void ip7145dpf_mmc_spi_setpower_slot_a(struct device *dev, unsigned int vdd)
32196 +{
32197 +       struct mmc_spi_platform_data *pd = dev->platform_data;
32198 +
32199 +       /*
32200 +        * Power is inverted, we could tell the IOB to do it, but it's cleaner this way.
32201 +        */
32202 +       if ((1 << vdd) & pd->ocr_mask) {
32203 +               gpio_set_value(MMC_PWR, 0);
32204 +               return;
32205 +       }
32206 +       gpio_set_value(MMC_PWR, 1);
32207 +}
32208 +
32209 +/*
32210 + * ip7145dpf_mmc_spi_get_cd_slot_a
32211 + *     Get the CD bit for slot A
32212 + */
32213 +static int ip7145dpf_mmc_spi_get_cd_slot_a(struct device *dev)
32214 +{
32215 +       /*
32216 +        * Note that the sense of the GPIO is inverted
32217 +        */
32218 +       return !gpio_get_value(MMC_CD);
32219 +}
32220 +
32221 +/*
32222 + * ip7145dpf_mmc_spi_get_ro_slot_a
32223 + *     Get the WP bit for slot A
32224 + */
32225 +static int ip7145dpf_mmc_spi_get_ro_slot_a(struct device *dev)
32226 +{
32227 +       /*
32228 +        * Note that the sense of the GPIO is inverted, we could tell the IOB to do it, but
32229 +        * it's clearer this way.
32230 +        */
32231 +       return !gpio_get_value(MMC_WP);
32232 +}
32233 +
32234 +/*
32235 + * ip7145dpf_mmc_spi_exit_slot_a
32236 + *     Free the appropriate GPIOs for slot A SD slot.
32237 + */
32238 +static void ip7145dpf_mmc_spi_exit_slot_a(struct device *dev, void *appdata)
32239 +{
32240 +       gpio_free(MMC_CD);
32241 +       gpio_free(MMC_CS);
32242 +       gpio_free(MMC_WP);
32243 +       gpio_free(MMC_PWR);
32244 +       platform_device_unregister(&ip7145dpf_spi_gpio_device);
32245 +}
32246 +
32247 +/*
32248 + * ip7145dpf_mmc_spi_init_slot_a
32249 + *     Allocate the appropriate GPIOs for slot A SD slot.
32250 + *     WP is on IOB0, CD is PA4, CS is on PF5
32251 + *     TODO: make CD an interrupt
32252 + */
32253 +static int ip7145dpf_mmc_spi_init_slot_a(void)
32254 +{
32255 +       int ret = gpio_request(MMC_CD, "mmc-a-cd");
32256 +       if (ret) {
32257 +               printk(KERN_ERR "%s: could not request mmc-a-cd pin\n", __FUNCTION__);
32258 +               return -ENOSYS;
32259 +       }
32260 +       gpio_direction_input(MMC_CD);
32261 +
32262 +       ret = gpio_request(MMC_CS, "mmc-a-cs");
32263 +       if (ret) {
32264 +               printk(KERN_ERR "%s: could not request mmc-a-cs pin\n", __FUNCTION__);
32265 +               goto no_cs;
32266 +       }
32267 +       gpio_direction_output(MMC_CS, 0);
32268 +
32269 +       ret = gpio_request(MMC_WP, "mmc-a-wp");
32270 +       if (ret) {
32271 +               printk(KERN_ERR "%s: could not request mmc-a-wp pin\n", __FUNCTION__);
32272 +               goto no_wp;
32273 +       }
32274 +       gpio_direction_input(MMC_WP);
32275 +
32276 +       /*
32277 +        * Start off with power off
32278 +        */
32279 +       ret = gpio_request(MMC_PWR, "mmc-a-pwr");
32280 +       if (ret) {
32281 +               printk(KERN_ERR "%s: could not request mmc-a-pwr pin\n", __FUNCTION__);
32282 +               goto no_pwr;
32283 +       }
32284 +       ret = gpio_direction_output(MMC_PWR, 1);
32285 +
32286 +       return 0;
32287 +
32288 +no_pwr:
32289 +       gpio_free(MMC_WP);
32290 +
32291 +no_wp:
32292 +       gpio_free(MMC_CS);
32293 +
32294 +no_cs:
32295 +       gpio_free(MMC_CD);
32296 +       return -ENOSYS;
32297 +}
32298 +
32299 +/*
32300 + * MMC_SPI driver (currently bitbang)
32301 + */
32302 +static struct mmc_spi_platform_data ip7145dpf_mmc_platform_data = {
32303 +       .ocr_mask       = MMC_VDD_33_34,
32304 +       .exit           = ip7145dpf_mmc_spi_exit_slot_a,
32305 +       .get_ro         = ip7145dpf_mmc_spi_get_ro_slot_a,
32306 +       .get_cd         = ip7145dpf_mmc_spi_get_cd_slot_a,
32307 +
32308 +       .setpower       = ip7145dpf_mmc_spi_setpower_slot_a,
32309 +       .powerup_msecs  = 500,
32310 +
32311 +       .detect_delay   = 100,
32312 +
32313 +       .caps           = MMC_CAP_NEEDS_POLL,
32314 +};
32315 +
32316 +static struct ubicom32_spi_gpio_controller_data ip7145dpf_mmc_controller_data = {
32317 +       .pin_cs =  MMC_CS,
32318 +};
32319 +
32320 +static struct spi_board_info ip7145dpf_spi_board_info[] = {
32321 +       {
32322 +               .modalias = "mmc_spi",
32323 +               .bus_num = 0,
32324 +               .chip_select = 0,
32325 +               .max_speed_hz = 2000000,
32326 +               .platform_data = &ip7145dpf_mmc_platform_data,
32327 +               .controller_data = &ip7145dpf_mmc_controller_data,
32328 +       }
32329 +};
32330 +#endif /* IP7145DPF_USE_MMC_SPI */
32331 +
32332 +/*
32333 + * ip7145dpf_u72_setup
32334 + *     Called by I2C to tell us that u72 is setup.
32335 + *
32336 + * This function is called by I2C to tell us that u72 has been setup.  All
32337 + * devices which rely on this chip being initialized (or even present) need to
32338 + * be initialized in this function otherwise they may get initialized too early.
32339 + *
32340 + * Currently the only device depending on u72 is the SPI
32341 + */
32342 +static int __init ip7145dpf_u72_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
32343 +{
32344 +#ifdef IP7145DPF_USE_MMC_SPI
32345 +       if (ip7145dpf_mmc_spi_init_slot_a()) {
32346 +               printk(KERN_ERR "%s: could not request mmc resources\n", __FUNCTION__);
32347 +       } else {
32348 +               printk(KERN_INFO "%s: registering SPI resources\n", __FUNCTION__);
32349 +               spi_register_board_info(ip7145dpf_spi_board_info, ARRAY_SIZE(ip7145dpf_spi_board_info));
32350 +               platform_device_register(&ip7145dpf_spi_gpio_device);
32351 +       }
32352 +#else
32353 +       /*
32354 +        * Initialize the Port F/Port B SD slots
32355 +        */
32356 +       ip7145dpf_portf_sd_init();
32357 +       ip7145dpf_portb_sd_init();
32358 +#endif
32359 +       return 0;
32360 +}
32361 +
32362 +/******************************************************************************
32363 + * LCD VGH on the board at PE6
32364 + */
32365 +static struct ubicom32lcd_platform_data ip7145dpf_lcd_data = {
32366 +       .vgh_gpio               = GPIO_RE_6,
32367 +       .vgh_polarity           = true,
32368 +};
32369 +
32370 +static struct platform_device ip7145dpf_lcd_device = {
32371 +       .name   = "ubicom32lcd",
32372 +       .id     = -1,
32373 +       .dev    = {
32374 +               .platform_data = &ip7145dpf_lcd_data,
32375 +       },
32376 +};
32377 +
32378 +/******************************************************************************
32379 + * Backlight on the board PD0, hardware PWM
32380 + */
32381 +static struct ubicom32bl_platform_data ip7145dpf_backlight_data = {
32382 +       .type                   = UBICOM32BL_TYPE_PWM,
32383 +       .pwm_channel            = 2,
32384 +       .pwm_prescale           = 15,
32385 +       .pwm_period             = 60,
32386 +       .default_intensity      = 0x80,
32387 +};
32388 +
32389 +static struct platform_device ip7145dpf_backlight_device = {
32390 +       .name   = "ubicom32bl",
32391 +       .id     = -1,
32392 +       .dev    = {
32393 +               .platform_data = &ip7145dpf_backlight_data,
32394 +       },
32395 +};
32396 +
32397 +/******************************************************************************
32398 + * Ubicom32Input on I2C, U48 MAX7310, address 0x18, 8 bits
32399 + */
32400 +static struct ubicom32input_i2c_button ip7145dpf_ubicom32input_i2c_u48_buttons[] = {
32401 +       {
32402 +               .type           = EV_KEY,
32403 +               .code           = KEY_UP,
32404 +               .bit            = 0,
32405 +               .active_low     = 1,
32406 +       },
32407 +       {
32408 +               .type           = EV_KEY,
32409 +               .code           = KEY_LEFT,
32410 +               .bit            = 1,
32411 +               .active_low     = 1,
32412 +       },
32413 +       {
32414 +               .type           = EV_KEY,
32415 +               .code           = KEY_RIGHT,
32416 +               .bit            = 2,
32417 +               .active_low     = 1,
32418 +       },
32419 +       {
32420 +               .type           = EV_KEY,
32421 +               .code           = KEY_DOWN,
32422 +               .bit            = 3,
32423 +               .active_low     = 1,
32424 +       },
32425 +       {
32426 +               .type           = EV_KEY,
32427 +               .code           = KEY_ENTER,
32428 +               .bit            = 4,
32429 +               .active_low     = 1,
32430 +       },
32431 +       {
32432 +               .type           = EV_KEY,
32433 +               .code           = KEY_MENU,
32434 +               .bit            = 5,
32435 +               .active_low     = 1,
32436 +       },
32437 +       {
32438 +               .type           = EV_KEY,
32439 +               .code           = KEY_ESC,
32440 +               .bit            = 6,
32441 +               .active_low     = 1,
32442 +       },
32443 +};
32444 +
32445 +static struct ubicom32input_i2c_platform_data ip7145dpf_ubicom32input_i2c_u48_platform_data = {
32446 +       .buttons        = ip7145dpf_ubicom32input_i2c_u48_buttons,
32447 +       .nbuttons       = ARRAY_SIZE(ip7145dpf_ubicom32input_i2c_u48_buttons),
32448 +       .name           = "Ubicom32 Input I2C U48",
32449 +};
32450 +
32451 +/******************************************************************************
32452 + * Additional GPIO chips
32453 + */
32454 +static struct pca953x_platform_data ip7145dpf_gpio_u72_platform_data = {
32455 +       .gpio_base = IP7145DPF_U72_BASE,
32456 +       .setup = ip7145dpf_u72_setup,
32457 +};
32458 +
32459 +/******************************************************************************
32460 + * Devices on the I2C bus
32461 + */
32462 +static struct i2c_board_info __initdata ip7145dpf_i2c_board_info[] = {
32463 +       /*
32464 +        * U51, S35390A RTC, address 0x30
32465 +        */
32466 +       {
32467 +               .type           = "s35390a",
32468 +               .addr           = 0x30,
32469 +       },
32470 +
32471 +       /*
32472 +        * U48, MAX7310 IO expander, 8 bits, address 0x18
32473 +        */
32474 +       {
32475 +               .type           = "ubicom32in_max7310",
32476 +               .addr           = 0x18,
32477 +               .platform_data  = &ip7145dpf_ubicom32input_i2c_u48_platform_data,
32478 +       },
32479 +
32480 +       /*
32481 +        * U72, MAX7310 IOB expander, 8 bits, address 0x19
32482 +        */
32483 +       {
32484 +               .type           = "max7310",
32485 +               .addr           = 0x19,
32486 +               .platform_data  = &ip7145dpf_gpio_u72_platform_data,
32487 +       },
32488 +};
32489 +
32490 +/*
32491 + * I2C bus on the board, SDA PE1, SCL PE2
32492 + */
32493 +static struct i2c_gpio_platform_data ip7145dpf_i2c_data = {
32494 +       .sda_pin                = GPIO_RE_1,
32495 +       .scl_pin                = GPIO_RE_2,
32496 +       .sda_is_open_drain      = 0,
32497 +       .scl_is_open_drain      = 0,
32498 +};
32499 +
32500 +static struct platform_device ip7145dpf_i2c_device = {
32501 +       .name   = "i2c-gpio",
32502 +       .id     = 0,
32503 +       .dev    = {
32504 +               .platform_data = &ip7145dpf_i2c_data,
32505 +       },
32506 +};
32507 +
32508 +/******************************************************************************
32509 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32510 + *
32511 + * WPS                 PF12
32512 + * FACT_DEFAULT                PF13
32513 + * POWER               PE4
32514 + *
32515 + * Not sutable for the keypad buttons since those run on I2C GPIO.  The polling
32516 + * of ubicom32input would seem to be excessive for this.
32517 + *
32518 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32519 + */
32520 +static struct ubicom32input_button ip7145dpf_ubicom32input_buttons[] = {
32521 +       {
32522 +               .type           = EV_KEY,
32523 +               .code           = KEY_FN_F1,
32524 +               .gpio           = GPIO_RF_12,
32525 +               .desc           = "WPS",
32526 +               .active_low     = 1,
32527 +       },
32528 +       {
32529 +               .type           = EV_KEY,
32530 +               .code           = KEY_FN_F2,
32531 +               .gpio           = GPIO_RF_13,
32532 +               .desc           = "Factory Default",
32533 +               .active_low     = 1,
32534 +       },
32535 +       {
32536 +               .type           = EV_KEY,
32537 +               .code           = KEY_POWER,
32538 +               .gpio           = GPIO_RE_4,
32539 +               .desc           = "Power",
32540 +               .active_low     = 1,
32541 +       },
32542 +};
32543 +
32544 +static struct ubicom32input_platform_data ip7145dpf_ubicom32input_data = {
32545 +       .buttons        = ip7145dpf_ubicom32input_buttons,
32546 +       .nbuttons       = ARRAY_SIZE(ip7145dpf_ubicom32input_buttons),
32547 +};
32548 +
32549 +static struct platform_device ip7145dpf_ubicom32input_device = {
32550 +       .name   = "ubicom32input",
32551 +       .id     = -1,
32552 +       .dev    = {
32553 +               .platform_data = &ip7145dpf_ubicom32input_data,
32554 +       },
32555 +};
32556 +
32557 +/*
32558 + * List of all devices in our system
32559 + */
32560 +static struct platform_device *ip7145dpf_devices[] __initdata = {
32561 +       &ip7145dpf_i2c_device,
32562 +       &ip7145dpf_lcd_device,
32563 +       &ip7145dpf_backlight_device,
32564 +       &ip7145dpf_ubicom32input_device,
32565 +};
32566 +
32567 +/*
32568 + * ip7145dpf_power_off
32569 + *     Called to turn the power off for this board
32570 + */
32571 +static void ip7145dpf_power_off(void)
32572 +{
32573 +       gpio_set_value(GPIO_RE_5, 0);
32574 +}
32575 +
32576 +/*
32577 + * ip7145dpf_init
32578 + *     Called to add the devices which we have on this board
32579 + */
32580 +static int __init ip7145dpf_init(void)
32581 +{
32582 +       int ret;
32583 +       struct platform_device *audio_dev;
32584 +
32585 +       ubi_gpio_init();
32586 +
32587 +#ifdef CONFIG_UIO_UBICOM32RING
32588 +       ring_tio_init("decoder_ring");
32589 +#endif
32590 +
32591 +       /*
32592 +        * Start up the video driver first
32593 +        */
32594 +       vdc_tio_init();
32595 +
32596 +       /*
32597 +        * Take over holding of the power from the system
32598 +        */
32599 +       ret = gpio_request(GPIO_RE_5, "power_hold");
32600 +       if (ret) {
32601 +               printk(KERN_ERR "%s: could not request power hold GPIO\n", __FUNCTION__);
32602 +       }
32603 +       gpio_direction_output(GPIO_RE_5, 1);
32604 +       mach_power_off = ip7145dpf_power_off;
32605 +
32606 +       /*
32607 +        * USB SEL_HOST_USB line
32608 +        */
32609 +       ret = gpio_request(GPIO_RF_11, "SEL_HOST_USB");
32610 +       if (ret) {
32611 +               printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
32612 +       }
32613 +       gpio_direction_output(GPIO_RF_11, 0);
32614 +
32615 +       /*
32616 +        * Setup audio
32617 +        */
32618 +       audio_dev = audio_tio_alloc("snd-ubi32-generic", "audiotio-i2sout", 0);
32619 +       if (audio_dev) {
32620 +               platform_device_register(audio_dev);
32621 +       }
32622 +
32623 +       /*
32624 +        * Register all of the devices we have on this board
32625 +        */
32626 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32627 +       platform_add_devices(ip7145dpf_devices, ARRAY_SIZE(ip7145dpf_devices));
32628 +
32629 +       /*
32630 +        * Register all of the devices which sit on the I2C bus
32631 +        */
32632 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
32633 +       i2c_register_board_info(0, ip7145dpf_i2c_board_info, ARRAY_SIZE(ip7145dpf_i2c_board_info));
32634 +
32635 +       /*
32636 +        * We have to initialize the SPI after the I2C IOB gets setup. SPI is initialized in 
32637 +        * ip7145dpf_u72_setup
32638 +        */
32639 +
32640 +       return 0;
32641 +}
32642 +
32643 +arch_initcall(ip7145dpf_init);
32644 +
32645 --- /dev/null
32646 +++ b/arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32647 @@ -0,0 +1,135 @@
32648 +/*
32649 + * arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32650 + *   Support for the IP7160 bringup board.
32651 + *
32652 + * (C) Copyright 2009, Ubicom, Inc.
32653 + *
32654 + * This file is part of the Ubicom32 Linux Kernel Port.
32655 + *
32656 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
32657 + * it and/or modify it under the terms of the GNU General Public License
32658 + * as published by the Free Software Foundation, either version 2 of the
32659 + * License, or (at your option) any later version.
32660 + *
32661 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
32662 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
32663 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
32664 + * the GNU General Public License for more details.
32665 + *
32666 + * You should have received a copy of the GNU General Public License
32667 + * along with the Ubicom32 Linux Kernel Port.  If not, 
32668 + * see <http://www.gnu.org/licenses/>.
32669 + *
32670 + * Ubicom32 implementation derived from (with many thanks):
32671 + *   arch/m68knommu
32672 + *   arch/blackfin
32673 + *   arch/parisc
32674 + */
32675 +#include <linux/device.h>
32676 +#include <linux/platform_device.h>
32677 +#include <linux/gpio.h>
32678 +#include <linux/leds.h>
32679 +#include <linux/delay.h>
32680 +#include <linux/input.h>
32681 +
32682 +#include <asm/board.h>
32683 +#include <asm/machdep.h>
32684 +#include <asm/ubicom32input.h>
32685 +
32686 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32687 +#include <asm/ubicom32suart.h>
32688 +#endif
32689 +
32690 +/*
32691 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32692 + *
32693 + * WPS                 PD5
32694 + * FACT_DEFAULT                PD6
32695 + *
32696 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32697 + */
32698 +static struct ubicom32input_button ip7160bringup_ubicom32input_buttons[] = {
32699 +       {
32700 +               .type           = EV_KEY,
32701 +               .code           = KEY_FN_F1,
32702 +               .gpio           = GPIO_RD_5,
32703 +               .desc           = "WPS",
32704 +               .active_low     = 1,
32705 +       },
32706 +       {
32707 +               .type           = EV_KEY,
32708 +               .code           = KEY_FN_F2,
32709 +               .gpio           = GPIO_RD_6,
32710 +               .desc           = "Factory Default",
32711 +               .active_low     = 1,
32712 +       },
32713 +};
32714 +
32715 +static struct ubicom32input_platform_data ip7160bringup_ubicom32input_data = {
32716 +       .buttons        = ip7160bringup_ubicom32input_buttons,
32717 +       .nbuttons       = ARRAY_SIZE(ip7160bringup_ubicom32input_buttons),
32718 +};
32719 +
32720 +static struct platform_device ip7160bringup_ubicom32input_device = {
32721 +       .name   = "ubicom32input",
32722 +       .id     = -1,
32723 +       .dev    = {
32724 +               .platform_data = &ip7160bringup_ubicom32input_data,
32725 +       },
32726 +};
32727 +
32728 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32729 +static struct resource ip7160bringup_ubicom32_suart_resources[] = {
32730 +       {
32731 +               .start  = RE,
32732 +               .end    = RE,
32733 +               .flags  = IORESOURCE_MEM,
32734 +       },
32735 +       {
32736 +               .start  = PORT_OTHER_INT(RE),
32737 +               .end    = PORT_OTHER_INT(RE),
32738 +               .flags  = IORESOURCE_IRQ,
32739 +       },
32740 +       {
32741 +               .start  = 250000000,
32742 +               .end    = 250000000,
32743 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
32744 +       },
32745 +};
32746 +
32747 +static struct platform_device ip7160bringup_ubicom32_suart_device = {
32748 +       .name           = "ubicom32suart",
32749 +       .id             = -1,
32750 +       .num_resources  = ARRAY_SIZE(ip7160bringup_ubicom32_suart_resources),
32751 +       .resource       = ip7160bringup_ubicom32_suart_resources,
32752 +};
32753 +#endif
32754 +
32755 +/*
32756 + * List of all devices in our system
32757 + */
32758 +static struct platform_device *ip7160bringup_devices[] __initdata = {
32759 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32760 +       &ip7160bringup_ubicom32_suart_device,
32761 +#endif
32762 +       &ip7160bringup_ubicom32input_device,
32763 +};
32764 +
32765 +/*
32766 + * ip7160bringup_init
32767 + *     Called to add the devices which we have on this board
32768 + */
32769 +static int __init ip7160bringup_init(void)
32770 +{
32771 +       board_init();
32772 +
32773 +       ubi_gpio_init();
32774 +
32775 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32776 +       platform_add_devices(ip7160bringup_devices, ARRAY_SIZE(ip7160bringup_devices));
32777 +
32778 +       return 0;
32779 +}
32780 +
32781 +arch_initcall(ip7160bringup_init);
32782 +
32783 --- /dev/null
32784 +++ b/arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32785 @@ -0,0 +1,327 @@
32786 +/*
32787 + * arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32788 + *   Platform initialization for ip7160dpf board.
32789 + *
32790 + * (C) Copyright 2009, Ubicom, Inc.
32791 + *
32792 + * This file is part of the Ubicom32 Linux Kernel Port.
32793 + *
32794 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
32795 + * it and/or modify it under the terms of the GNU General Public License
32796 + * as published by the Free Software Foundation, either version 2 of the
32797 + * License, or (at your option) any later version.
32798 + *
32799 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
32800 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
32801 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
32802 + * the GNU General Public License for more details.
32803 + *
32804 + * You should have received a copy of the GNU General Public License
32805 + * along with the Ubicom32 Linux Kernel Port.  If not, 
32806 + * see <http://www.gnu.org/licenses/>.
32807 + *
32808 + * Ubicom32 implementation derived from (with many thanks):
32809 + *   arch/m68knommu
32810 + *   arch/blackfin
32811 + *   arch/parisc
32812 + */
32813 +#include <linux/device.h>
32814 +#include <linux/platform_device.h>
32815 +#include <linux/delay.h>
32816 +#include <linux/gpio.h>
32817 +
32818 +#include <linux/i2c.h>
32819 +#include <linux/i2c-gpio.h>
32820 +
32821 +#include <linux/input.h>
32822 +
32823 +#include <asm/board.h>
32824 +#include <asm/machdep.h>
32825 +#include <asm/ubicom32hid.h>
32826 +#include <asm/vdc_tio.h>
32827 +#include <asm/audio_tio.h>
32828 +
32829 +/*
32830 + * Backlight on the board PD0, hardware PWM
32831 + */
32832 +static const struct ubicom32hid_button ip7160dpf_ubicom32hid_buttons[] = {
32833 +       {
32834 +               .type   = EV_KEY,
32835 +               .code   = KEY_UP,
32836 +               .bit    = 0,
32837 +       },
32838 +       {
32839 +               .type   = EV_KEY,
32840 +               .code   = KEY_LEFT,
32841 +               .bit    = 1,
32842 +       },
32843 +       {
32844 +               .type   = EV_KEY,
32845 +               .code   = KEY_RIGHT,
32846 +               .bit    = 2,
32847 +       },
32848 +       {
32849 +               .type   = EV_KEY,
32850 +               .code   = KEY_DOWN,
32851 +               .bit    = 3,
32852 +       },
32853 +       {
32854 +               .type   = EV_KEY,
32855 +               .code   = KEY_ENTER,
32856 +               .bit    = 4,
32857 +       },
32858 +       {
32859 +               .type   = EV_KEY,
32860 +               .code   = KEY_MENU,
32861 +               .bit    = 5,
32862 +       },
32863 +       {
32864 +               .type   = EV_KEY,
32865 +               .code   = KEY_ESC,
32866 +               .bit    = 7,
32867 +       },
32868 +};
32869 +
32870 +static const struct ubicom32hid_ir ip7160dpf_ubicom32hid_ircodes[] = {
32871 +       {
32872 +               .type           = EV_KEY,
32873 +               .code           = KEY_UP,
32874 +               .ir_code        = 0xF807916E
32875 +       },
32876 +       {
32877 +               .type           = EV_KEY,
32878 +               .code           = KEY_DOWN,
32879 +               .ir_code        = 0xF20D916E
32880 +       },
32881 +       {
32882 +               .type           = EV_KEY,
32883 +               .code           = KEY_LEFT,
32884 +               .ir_code        = 0xF609916E
32885 +       },
32886 +       {
32887 +               .type           = EV_KEY,
32888 +               .code           = KEY_RIGHT,
32889 +               .ir_code        = 0xF40B916E
32890 +       },
32891 +       {
32892 +               .type           = EV_KEY,
32893 +               .code           = KEY_ENTER,
32894 +               .ir_code        = 0xF50A916E
32895 +       },
32896 +       {       /* rotate */
32897 +               .type           = EV_KEY,
32898 +               .code           = KEY_FN_F1,
32899 +               .ir_code        = 0xF906916E
32900 +       },
32901 +       {
32902 +               .type           = EV_KEY,
32903 +               .code           = KEY_MENU,
32904 +               .ir_code        = 0xF708916E
32905 +       },
32906 +       {       /* font size */
32907 +               .type           = EV_KEY,
32908 +               .code           = KEY_FN_F2,
32909 +               .ir_code        = 0xF30C916E
32910 +       },
32911 +       {       
32912 +               .type           = EV_KEY,
32913 +               .code           = KEY_ESC,
32914 +               .ir_code        = 0xF10E916E
32915 +       },
32916 +       {
32917 +               .type           = EV_KEY,
32918 +               .code           = KEY_VOLUMEUP,
32919 +               .ir_code        = 0xF00F916E
32920 +       },
32921 +       {
32922 +               .type           = EV_KEY,
32923 +               .code           = KEY_VOLUMEDOWN,
32924 +               .ir_code        = 0xED12916E
32925 +       },
32926 +       {
32927 +               .type           = EV_KEY,
32928 +               .code           = KEY_MUTE,
32929 +               .ir_code        = 0xEA15916E
32930 +       },
32931 +       {
32932 +               .type           = EV_KEY,
32933 +               .code           = KEY_INFO,
32934 +               .ir_code        = 0xEF10916E
32935 +       },
32936 +       {       /* Like */
32937 +               .type           = EV_KEY,
32938 +               .code           = KEY_FN_F3,
32939 +               .ir_code        = 0xEE11916E
32940 +       },
32941 +       {       /* Dislike */
32942 +               .type           = EV_KEY,
32943 +               .code           = KEY_FN_F4,
32944 +               .ir_code        = 0xEB14916E
32945 +       },
32946 +       {
32947 +               .type           = EV_KEY,
32948 +               .code           = KEY_POWER,
32949 +               .ir_code        = 0xFD02916E
32950 +       },
32951 +};
32952 +
32953 +static struct ubicom32hid_platform_data ip7160dpf_ubicom32hid_platform_data = {
32954 +       .gpio_reset             = GPIO_RI_5,
32955 +       .gpio_reset_polarity    = 0,
32956 +       .type                   = UBICOM32HID_BL_TYPE_PWM,
32957 +       .invert                 = 0,
32958 +       .default_intensity      = 128,
32959 +       .buttons                = ip7160dpf_ubicom32hid_buttons,
32960 +       .nbuttons               = ARRAY_SIZE(ip7160dpf_ubicom32hid_buttons),
32961 +       .ircodes                = ip7160dpf_ubicom32hid_ircodes,
32962 +       .nircodes               = ARRAY_SIZE(ip7160dpf_ubicom32hid_ircodes),
32963 +};
32964 +
32965 +/*
32966 + * Devices on the I2C bus
32967 + *     This board has a "bus 2" which is isolated from the main bus by U47
32968 + *     and pin RI0.  It should be safe to always enable bus 2 by setting
32969 + *     RI0 to low, however, it should be noted that on all existing configurations
32970 + *     of this board, U49 and U51 are not populated.
32971 + */
32972 +static struct i2c_board_info __initdata ip7160dpf_i2c_board_info[] = {
32973 +       /*
32974 +        * U37, CS4350 DAC, address 0x4B, bus 2
32975 +        *      THIS ENTRY MUST BE FIRST
32976 +        */
32977 +       {
32978 +               .type           = "cs4350",
32979 +               .addr           = 0x4B,
32980 +       }
32981 +
32982 +       /*
32983 +        * U24, ubicom32hid
32984 +        */
32985 +       {
32986 +               .type           = "ubicom32hid",
32987 +               .addr           = 0x08,
32988 +               .platform_data  = &ip7160dpf_ubicom32hid_platform_data,
32989 +       },
32990 +
32991 +       /*
32992 +        * U49, ISL29001 Ambient Light Sensor, address 0x44, bus 2 (may not be stuffed)
32993 +        */
32994 +
32995 +       /*
32996 +        * U51, S35390A RTC, address 0x30, bus 2 (may not be stuffed)
32997 +        */
32998 +#ifdef CONFIG_RTC_DRV_S35390A
32999 +       {
33000 +               .type           = "s35390a",
33001 +               .addr           = 0x30,
33002 +       },
33003 +#endif
33004 +};
33005 +
33006 +/*
33007 + * I2C bus on the board, SDA PI1, SCL PI2
33008 + */
33009 +static struct i2c_gpio_platform_data ip7160dpf_i2c_data = {
33010 +       .sda_pin                = GPIO_RI_1,
33011 +       .scl_pin                = GPIO_RI_2,
33012 +       .sda_is_open_drain      = 0,
33013 +       .scl_is_open_drain      = 0,
33014 +       .scl_is_output_only     = 1,
33015 +       .udelay                 = 6,
33016 +};
33017 +
33018 +static struct platform_device ip7160dpf_i2c_device = {
33019 +       .name   = "i2c-gpio",
33020 +       .id     = 0,
33021 +       .dev    = {
33022 +               .platform_data = &ip7160dpf_i2c_data,
33023 +       },
33024 +};
33025 +
33026 +/*
33027 + * List of all devices in our system
33028 + */
33029 +static struct platform_device *ip7160dpf_devices[] __initdata = {
33030 +       &ip7160dpf_i2c_device,
33031 +};
33032 +
33033 +/*
33034 + * ip7160dpf_power_off
33035 + *     Called to turn the power off for this board
33036 + */
33037 +static void ip7160dpf_power_off(void)
33038 +{
33039 +       gpio_set_value(GPIO_RF_14, 0);
33040 +}
33041 +
33042 +/*
33043 + * ip7160dpf_init
33044 + *     Called to add the devices which we have on this board
33045 + */
33046 +static int __init ip7160dpf_init(void)
33047 +{
33048 +       int ret;
33049 +       struct platform_device *audio_dev;
33050 +
33051 +       ubi_gpio_init();
33052 +
33053 +       /*
33054 +        * Hold the POWER_HOLD line
33055 +        */
33056 +       ret = gpio_request(GPIO_RF_14, "POWER_HOLD");
33057 +       if (ret) {
33058 +               printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__);
33059 +       }
33060 +       gpio_direction_output(GPIO_RF_14, 0);
33061 +       mach_power_off = ip7160dpf_power_off;
33062 +
33063 +       /*
33064 +        * USB SEL_HOST_USB line
33065 +        */
33066 +       ret = gpio_request(GPIO_RI_13, "SEL_HOST_USB");
33067 +       if (ret) {
33068 +               printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
33069 +       }
33070 +       gpio_direction_output(GPIO_RI_13, 0);
33071 +
33072 +       /*
33073 +        * USB/DAC nRESET line
33074 +        */
33075 +       ret = gpio_request(GPIO_RI_3, "USB_DAC_nRESET");
33076 +       if (ret) {
33077 +               printk(KERN_ERR "%s: could not request USB_DAC_nRESET GPIO\n", __FUNCTION__);
33078 +       }
33079 +       gpio_direction_output(GPIO_RI_3, 0);
33080 +       udelay(1);
33081 +       gpio_direction_output(GPIO_RI_3, 1);
33082 +
33083 +       /*
33084 +        * I2C BUS2 Disable line
33085 +        */
33086 +       ret = gpio_request(GPIO_RI_0, "DISABLE_BUS2");
33087 +       if (ret) {
33088 +               printk(KERN_ERR "%s: could not request DISABLE_BUS2 GPIO\n", __FUNCTION__);
33089 +       }
33090 +       gpio_direction_output(GPIO_RI_0, 0);
33091 +
33092 +       vdc_tio_init();
33093 +
33094 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33095 +       platform_add_devices(ip7160dpf_devices, ARRAY_SIZE(ip7160dpf_devices));
33096 +
33097 +       /*
33098 +        * Allocate the audio driver if we can
33099 +        */
33100 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
33101 +       if (audio_dev) {
33102 +               ip7160dpf_i2c_board_info[0].platform_data = audio_dev;
33103 +       }
33104 +
33105 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
33106 +       i2c_register_board_info(0, ip7160dpf_i2c_board_info, ARRAY_SIZE(ip7160dpf_i2c_board_info));
33107 +
33108 +       return 0;
33109 +}
33110 +
33111 +arch_initcall(ip7160dpf_init);
33112 +
33113 --- /dev/null
33114 +++ b/arch/ubicom32/mach-ip7k/board-ip7160rgw.c
33115 @@ -0,0 +1,255 @@
33116 +/*
33117 + * arch/ubicom32/mach-ip7k/board-ip7160rgw.c
33118 + *   Platform initialization for ip7160rgw board.
33119 + *
33120 + * (C) Copyright 2009, Ubicom, Inc.
33121 + *
33122 + * This file is part of the Ubicom32 Linux Kernel Port.
33123 + *
33124 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33125 + * it and/or modify it under the terms of the GNU General Public License
33126 + * as published by the Free Software Foundation, either version 2 of the
33127 + * License, or (at your option) any later version.
33128 + *
33129 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33130 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33131 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33132 + * the GNU General Public License for more details.
33133 + *
33134 + * You should have received a copy of the GNU General Public License
33135 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33136 + * see <http://www.gnu.org/licenses/>.
33137 + *
33138 + * Ubicom32 implementation derived from (with many thanks):
33139 + *   arch/m68knommu
33140 + *   arch/blackfin
33141 + *   arch/parisc
33142 + */
33143 +#include <linux/device.h>
33144 +#include <linux/platform_device.h>
33145 +#include <linux/gpio.h>
33146 +#include <linux/leds.h>
33147 +#include <linux/delay.h>
33148 +#include <linux/input.h>
33149 +#include <linux/spi/spi.h>
33150 +
33151 +#include <asm/board.h>
33152 +#include <asm/machdep.h>
33153 +#include <asm/ubicom32input.h>
33154 +
33155 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33156 +#include <asm/ubicom32suart.h>
33157 +#endif
33158 +
33159 +#include <asm/ubicom32-spi-gpio.h>
33160 +#include <asm/switch-bcm539x.h>
33161 +
33162 +/*
33163 + * SPI bus over GPIO for Gigabit Ethernet Switch
33164 + *     U58:
33165 + *             MOSI    PE0
33166 + *             MISO    PE1
33167 + *             CLK     PE3
33168 + *             CS      PE2
33169 + */
33170 +static struct ubicom32_spi_gpio_platform_data ip7160rgw_spi_gpio_data = {
33171 +       .pin_mosi       = GPIO_RE_0,
33172 +       .pin_miso       = GPIO_RE_1,
33173 +       .pin_clk        = GPIO_RE_3,
33174 +       .bus_num        = 0,            // We'll call this SPI bus 0
33175 +       .num_chipselect = 1,            // only one device on this SPI bus 
33176 +       .clk_default    = 1,
33177 +};
33178 +
33179 +static struct platform_device ip7160rgw_spi_gpio_device = {
33180 +       .name   = "ubicom32-spi-gpio",
33181 +       .id     = 0,
33182 +       .dev    = {
33183 +               .platform_data = &ip7160rgw_spi_gpio_data,
33184 +       },
33185 +};
33186 +
33187 +static struct ubicom32_spi_gpio_controller_data ip7160rgw_bcm539x_controller_data = {
33188 +       .pin_cs = GPIO_RE_2,
33189 +};
33190 +
33191 +static struct switch_bcm539x_platform_data ip7160rgw_bcm539x_platform_data = {
33192 +       .flags          = SWITCH_BCM539X_FLAG_HW_RESET,
33193 +       .pin_cs         = GPIO_RE_2,
33194 +       .pin_reset      = GPIO_RE_4,
33195 +       .name           = "bcm539x",
33196 +};
33197 +
33198 +static struct spi_board_info ip7160rgw_spi_board_info[] = {
33199 +       {
33200 +               .modalias               = "bcm539x-spi",
33201 +               .bus_num                = 0,
33202 +               .chip_select            = 0,
33203 +               .max_speed_hz           = 2000000,
33204 +               .platform_data          = &ip7160rgw_bcm539x_platform_data,
33205 +               .controller_data        = &ip7160rgw_bcm539x_controller_data,
33206 +               .mode                   = SPI_MODE_3,
33207 +       }
33208 +};
33209 +
33210 +/*
33211 + * LEDs
33212 + *
33213 + * WLAN1               PD0     (PWM capable)
33214 + * WLAN2               PD1
33215 + * USB2.0              PD2
33216 + * Status              PD3
33217 + * WPS                 PD4
33218 + *
33219 + * TODO: check triggers, are they generic?
33220 + */
33221 +static struct gpio_led ip7160rgw_gpio_leds[] = {
33222 +       {
33223 +               .name                   = "d53:green:WLAN1",
33224 +               .default_trigger        = "WLAN1",
33225 +               .gpio                   = GPIO_RD_0,
33226 +               .active_low             = 1,
33227 +       },
33228 +       {
33229 +               .name                   = "d54:green:WLAN2",
33230 +               .default_trigger        = "WLAN2",
33231 +               .gpio                   = GPIO_RD_1,
33232 +               .active_low             = 1,
33233 +       },
33234 +       {
33235 +               .name                   = "d55:green:USB",
33236 +               .default_trigger        = "USB",
33237 +               .gpio                   = GPIO_RD_2,
33238 +               .active_low             = 1,
33239 +       },
33240 +       {
33241 +               .name                   = "d56:green:Status",
33242 +               .default_trigger        = "Status",
33243 +               .gpio                   = GPIO_RD_3,
33244 +               .active_low             = 1,
33245 +       },
33246 +       {
33247 +               .name                   = "d57:green:WPS",
33248 +               .default_trigger        = "WPS",
33249 +               .gpio                   = GPIO_RD_4,
33250 +               .active_low             = 1,
33251 +       },
33252 +};
33253 +
33254 +static struct gpio_led_platform_data ip7160rgw_gpio_led_platform_data = {
33255 +       .num_leds       = 5,
33256 +       .leds           = ip7160rgw_gpio_leds,
33257 +};
33258 +
33259 +static struct platform_device ip7160rgw_gpio_leds_device = {
33260 +       .name           = "leds-gpio",
33261 +       .id             = -1,
33262 +       .dev = {
33263 +               .platform_data = &ip7160rgw_gpio_led_platform_data,
33264 +       },
33265 +};
33266 +
33267 +/*
33268 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
33269 + *
33270 + * WPS                 PD5
33271 + * FACT_DEFAULT                PD6
33272 + *
33273 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
33274 + */
33275 +static struct ubicom32input_button ip7160rgw_ubicom32input_buttons[] = {
33276 +       {
33277 +               .type           = EV_KEY,
33278 +               .code           = KEY_FN_F1,
33279 +               .gpio           = GPIO_RD_5,
33280 +               .desc           = "WPS",
33281 +               .active_low     = 1,
33282 +       },
33283 +       {
33284 +               .type           = EV_KEY,
33285 +               .code           = KEY_FN_F2,
33286 +               .gpio           = GPIO_RD_6,
33287 +               .desc           = "Factory Default",
33288 +               .active_low     = 1,
33289 +       },
33290 +};
33291 +
33292 +static struct ubicom32input_platform_data ip7160rgw_ubicom32input_data = {
33293 +       .buttons        = ip7160rgw_ubicom32input_buttons,
33294 +       .nbuttons       = ARRAY_SIZE(ip7160rgw_ubicom32input_buttons),
33295 +};
33296 +
33297 +static struct platform_device ip7160rgw_ubicom32input_device = {
33298 +       .name   = "ubicom32input",
33299 +       .id     = -1,
33300 +       .dev    = {
33301 +               .platform_data = &ip7160rgw_ubicom32input_data,
33302 +       },
33303 +};
33304 +
33305 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33306 +static struct resource ip7160rgw_ubicom32_suart_resources[] = {
33307 +       {
33308 +               .start  = RE,
33309 +               .end    = RE,
33310 +               .flags  = IORESOURCE_MEM,
33311 +       },
33312 +       {
33313 +               .start  = PORT_OTHER_INT(RE),
33314 +               .end    = PORT_OTHER_INT(RE),
33315 +               .flags  = IORESOURCE_IRQ,
33316 +       },
33317 +       {
33318 +               .start  = 250000000,
33319 +               .end    = 250000000,
33320 +               .flags  = UBICOM32_SUART_IORESOURCE_CLOCK,
33321 +       },
33322 +};
33323 +
33324 +static struct platform_device ip7160rgw_ubicom32_suart_device = {
33325 +       .name           = "ubicom32suart",
33326 +       .id             = -1,
33327 +       .num_resources  = ARRAY_SIZE(ip7160rgw_ubicom32_suart_resources),
33328 +       .resource       = ip7160rgw_ubicom32_suart_resources,
33329 +};
33330 +#endif
33331 +
33332 +/*
33333 + * List of all devices in our system
33334 + */
33335 +static struct platform_device *ip7160rgw_devices[] __initdata = {
33336 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33337 +       &ip7160rgw_ubicom32_suart_device,
33338 +#endif
33339 +       &ip7160rgw_ubicom32input_device,
33340 +       &ip7160rgw_gpio_leds_device,
33341 +       &ip7160rgw_spi_gpio_device,
33342 +};
33343 +
33344 +/*
33345 + * ip7160rgw_init
33346 + *     Called to add the devices which we have on this board
33347 + */
33348 +static int __init ip7160rgw_init(void)
33349 +{
33350 +       board_init();
33351 +
33352 +       /*
33353 +        * Rev 1.2 boards have spi in a different place than 1.1/1.0
33354 +        */
33355 +       if (strcmp(board_get_revision(), "1.2") == 0) {
33356 +               ip7160rgw_spi_gpio_data.pin_mosi = GPIO_RD_7;
33357 +       }
33358 +
33359 +       ubi_gpio_init();
33360 +
33361 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33362 +       platform_add_devices(ip7160rgw_devices, ARRAY_SIZE(ip7160rgw_devices));
33363 +
33364 +       printk(KERN_INFO "%s: registering SPI resources\n", __FUNCTION__);
33365 +       spi_register_board_info(ip7160rgw_spi_board_info, ARRAY_SIZE(ip7160rgw_spi_board_info));
33366 +
33367 +       return 0;
33368 +}
33369 +
33370 +arch_initcall(ip7160rgw_init);
33371 --- /dev/null
33372 +++ b/arch/ubicom32/mach-ip7k/board-ip7500av.c
33373 @@ -0,0 +1,167 @@
33374 +/*
33375 + * arch/ubicom32/mach-ip7k/board-ip7500av.c
33376 + *   Support for IP7500 Audio Video Board + CPU module board.
33377 + *
33378 + * This file supports the IP7500 Audio Video Board:
33379 + *     8007-0810  Rev 1.0
33380 + * with one of the following CPU module boards:
33381 + *     8007-0510  Rev 1.0
33382 + *     8007-0510A Rev 1.0 (with ethernet)
33383 + *
33384 + * DIP Switch SW2 configuration: (*) default
33385 + *     POS 1: on(*) = PCI enabled, off = PCI disabled
33386 + *     POS 2: on(*) = TTYX => PA6, off = TTYX => PF12
33387 + *     POS 3: on(*) = TTYY => PA7, off = TTYY => PF15
33388 + *     POS 4: unused
33389 + *
33390 + * (C) Copyright 2009, Ubicom, Inc.
33391 + *
33392 + * This file is part of the Ubicom32 Linux Kernel Port.
33393 + *
33394 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33395 + * it and/or modify it under the terms of the GNU General Public License
33396 + * as published by the Free Software Foundation, either version 2 of the
33397 + * License, or (at your option) any later version.
33398 + *
33399 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33400 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33401 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33402 + * the GNU General Public License for more details.
33403 + *
33404 + * You should have received a copy of the GNU General Public License
33405 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33406 + * see <http://www.gnu.org/licenses/>.
33407 + */
33408 +
33409 +#include <linux/device.h>
33410 +#include <linux/platform_device.h>
33411 +#include <linux/gpio.h>
33412 +#include <linux/i2c.h>
33413 +#include <linux/i2c-gpio.h>
33414 +#include <asm/board.h>
33415 +#include <asm/machdep.h>
33416 +#include <asm/ring_tio.h>
33417 +#include <asm/vdc_tio.h>
33418 +#include <asm/audio_tio.h>
33419 +#include <asm/ubi32-cs4384.h>
33420 +
33421 +/******************************************************************************
33422 + * Devices on the I2C bus
33423 + *
33424 + * BEWARE of changing the order of things in this array as we depend on
33425 + * certain things to be in certain places.
33426 + */
33427 +static struct i2c_board_info __initdata ip7500av_i2c_board_info[] = {
33428 +       /*
33429 +        * U6, CS4384 DAC, address 0x19
33430 +        */
33431 +       {
33432 +               .type           = "cs4384",
33433 +               .addr           = 0x19,
33434 +       },
33435 +};
33436 +
33437 +/*
33438 + * I2C bus on the board, SDA PD1, SCL PD2
33439 + */
33440 +static struct i2c_gpio_platform_data ip7500av_i2c_data = {
33441 +       .sda_pin                = GPIO_RD_6,
33442 +       .scl_pin                = GPIO_RD_3,
33443 +       .sda_is_open_drain      = 0,
33444 +       .scl_is_open_drain      = 0,
33445 +       .udelay                 = 50,
33446 +};
33447 +
33448 +static struct platform_device ip7500av_i2c_device = {
33449 +       .name   = "i2c-gpio",
33450 +       .id     = 0,
33451 +       .dev    = {
33452 +               .platform_data = &ip7500av_i2c_data,
33453 +       },
33454 +};
33455 +
33456 +/*
33457 + * List of possible mclks we can generate.  This depends on the CPU frequency.
33458 + */
33459 +static struct ubi32_cs4384_mclk_entry ip7500av_cs4384_mclk_entries[] = {
33460 +       {
33461 +               .rate   =       12288000,
33462 +               .div    =       44,
33463 +       },
33464 +       {
33465 +               .rate   =       11289600,
33466 +               .div    =       48,
33467 +       },
33468 +};
33469 +
33470 +/*
33471 + * List of all devices in our system
33472 + */
33473 +static struct platform_device *ip7500av_devices[] __initdata = {
33474 +       &ip7500av_i2c_device,
33475 +};
33476 +
33477 +/*
33478 + * ip7500av_init
33479 + *     Called to add the devices which we have on this board
33480 + */
33481 +static int __init ip7500av_init(void)
33482 +{
33483 +       struct platform_device *audio_dev;
33484 +       struct platform_device *audio_dev2;
33485 +       struct ubi32_cs4384_platform_data *cs4384_pd;
33486 +
33487 +       board_init();
33488 +
33489 +       vdc_tio_init();
33490 +
33491 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33492 +       platform_add_devices(ip7500av_devices, ARRAY_SIZE(ip7500av_devices));
33493 +
33494 +       /*
33495 +        * CS4384 DAC
33496 +        */
33497 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4384", "audiotio-i2sout", 
33498 +                       sizeof(struct ubi32_cs4384_platform_data));
33499 +       if (audio_dev) {
33500 +               /*
33501 +                * Attempt to figure out a good divisor.  This will only work
33502 +                * assuming the core frequency is compatible.
33503 +                */
33504 +               int i;
33505 +               unsigned int freq = processor_frequency();
33506 +               for (i = 0; i < ARRAY_SIZE(ip7500av_cs4384_mclk_entries); i++) {
33507 +                       unsigned int div;
33508 +                       unsigned int rate = ip7500av_cs4384_mclk_entries[i].rate / 1000;
33509 +                       div = ((freq / rate) + 500) / 1000;
33510 +                       ip7500av_cs4384_mclk_entries[i].div = div;
33511 +                       printk("CS4384 mclk %d rate %u000Hz div %u act %u\n", i, rate, div, freq / div);
33512 +               }
33513 +
33514 +               cs4384_pd = audio_tio_priv(audio_dev);
33515 +               cs4384_pd->mclk_src = UBI32_CS4384_MCLK_PWM_0;
33516 +               cs4384_pd->n_mclk = ARRAY_SIZE(ip7500av_cs4384_mclk_entries);
33517 +               cs4384_pd->mclk_entries = ip7500av_cs4384_mclk_entries;
33518 +               ip7500av_i2c_board_info[0].platform_data = audio_dev;
33519 +       }
33520 +
33521 +       /*
33522 +        * SPDIF port
33523 +        */
33524 +       audio_dev2 = audio_tio_alloc("snd-ubi32-generic", "audiotio-spdifout", 0);
33525 +       if (audio_dev2) {
33526 +               platform_device_register(audio_dev2);
33527 +       }
33528 +
33529 +       /*
33530 +        * Register all of the devices which sit on the I2C bus
33531 +        */
33532 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
33533 +       i2c_register_board_info(0, ip7500av_i2c_board_info, ARRAY_SIZE(ip7500av_i2c_board_info));
33534 +
33535 +       ubi_gpio_init();
33536 +
33537 +       return 0;
33538 +}
33539 +arch_initcall(ip7500av_init);
33540 +
33541 --- /dev/null
33542 +++ b/arch/ubicom32/mach-ip7k/board-ip7500media.c
33543 @@ -0,0 +1,520 @@
33544 +/*
33545 + * arch/ubicom32/mach-ip7k/board-ip7500media.c
33546 + *   Board file for IP7500 media board.
33547 + *
33548 + * Supports the following configuration
33549 + *     CPU Module:
33550 + *             P/N 8007-0510 rev 1.0
33551 + *                     DIP Switch SW2 configuration: 
33552 + *                             POS 1: on  = PCI enabled
33553 + *                             POS 2: off = TTYX => PF12
33554 + *                             POS 3: off = TTYY => PF15
33555 + *                             POS 4: unused
33556 + *     Media Board:
33557 + *             P/N 8007-0610 rev 1.0
33558 + *
33559 + * (C) Copyright 2009, Ubicom, Inc.
33560 + *
33561 + * This file is part of the Ubicom32 Linux Kernel Port.
33562 + *
33563 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
33564 + * it and/or modify it under the terms of the GNU General Public License
33565 + * as published by the Free Software Foundation, either version 2 of the
33566 + * License, or (at your option) any later version.
33567 + *
33568 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
33569 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
33570 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
33571 + * the GNU General Public License for more details.
33572 + *
33573 + * You should have received a copy of the GNU General Public License
33574 + * along with the Ubicom32 Linux Kernel Port.  If not, 
33575 + * see <http://www.gnu.org/licenses/>.
33576 + *
33577 + * Ubicom32 implementation derived from (with many thanks):
33578 + *   arch/m68knommu
33579 + *   arch/blackfin
33580 + *   arch/parisc
33581 + */
33582 +#include <linux/device.h>
33583 +#include <linux/platform_device.h>
33584 +#include <linux/gpio.h>
33585 +
33586 +#include <linux/input.h>
33587 +
33588 +#include <linux/i2c.h>
33589 +#include <linux/i2c-gpio.h>
33590 +#include <linux/i2c/pca953x.h>
33591 +
33592 +#include <asm/board.h>
33593 +#include <asm/machdep.h>
33594 +#include <asm/ubicom32input_i2c.h>
33595 +#include <asm/ubicom32bl.h>
33596 +#include <asm/ubicom32lcd.h>
33597 +#include <asm/vdc_tio.h>
33598 +
33599 +#include <asm/ubicom32sd.h>
33600 +#include <asm/sd_tio.h>
33601 +#include <asm/devtree.h>
33602 +#include <asm/audio_tio.h>
33603 +
33604 +#include <asm/ring_tio.h>
33605 +
33606 +/******************************************************************************
33607 + * SD/IO Port F (Slot 1) platform data
33608 + */
33609 +static struct resource ip7500media_portf_sd_resources[] = {
33610 +       /*
33611 +        * Send IRQ
33612 +        */
33613 +       [0] = {
33614 +               /* 
33615 +                * The init routine will query the devtree and fill this in
33616 +                */
33617 +               .flags  = IORESOURCE_IRQ,
33618 +       },
33619 +
33620 +       /*
33621 +        * Receive IRQ
33622 +        */
33623 +       [1] = {
33624 +               /* 
33625 +                * The init routine will query the devtree and fill this in
33626 +                */
33627 +               .flags  = IORESOURCE_IRQ,
33628 +       },
33629 +
33630 +       /*
33631 +        * Memory Mapped Registers
33632 +        */
33633 +       [2] = {
33634 +               /* 
33635 +                * The init routine will query the devtree and fill this in
33636 +                */
33637 +               .flags  = IORESOURCE_MEM,
33638 +       },
33639 +};
33640 +
33641 +static struct ubicom32sd_card ip7500media_portf_sd_cards[] = {
33642 +       [0] = {
33643 +               .pin_wp         = IP7500MEDIA_IO16,
33644 +               .wp_polarity    = 1,
33645 +               .pin_pwr        = IP7500MEDIA_IO20,
33646 +               .pin_cd         = IP7500MEDIA_IO23,
33647 +       },
33648 +       [1] = {
33649 +               .pin_wp         = IP7500MEDIA_IO17,
33650 +               .wp_polarity    = 1,
33651 +               .pin_pwr        = IP7500MEDIA_IO21,
33652 +               .pin_cd         = IP7500MEDIA_IO24,
33653 +       },
33654 +};
33655 +
33656 +static struct ubicom32sd_platform_data ip7500media_portf_sd_platform_data = {
33657 +       .ncards         = 2,
33658 +       .cards          = ip7500media_portf_sd_cards, 
33659 +};
33660 +
33661 +static struct platform_device ip7500media_portf_sd_device = {
33662 +       .name           = "ubicom32sd",
33663 +       .id             = 0,
33664 +       .resource       = ip7500media_portf_sd_resources,
33665 +       .num_resources  = ARRAY_SIZE(ip7500media_portf_sd_resources),
33666 +       .dev            = {
33667 +                       .platform_data = &ip7500media_portf_sd_platform_data,
33668 +       },
33669 +
33670 +};
33671 +
33672 +/*
33673 + * ip7500media_portf_sd_init
33674 + */
33675 +static void ip7500media_portf_sd_init(void)
33676 +{
33677 +       /*
33678 +        * Check the device tree for the sd_tio
33679 +        */
33680 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
33681 +       if (!sd_node) {
33682 +               printk(KERN_INFO "PortF SDTIO not found\n");
33683 +               return;
33684 +       }
33685 +
33686 +       /*
33687 +        * Fill in the resources and platform data from devtree information
33688 +        */
33689 +       ip7500media_portf_sd_resources[0].start = sd_node->dn.sendirq;
33690 +       ip7500media_portf_sd_resources[1].start = sd_node->dn.recvirq;
33691 +       ip7500media_portf_sd_resources[2].start = (u32_t)&(sd_node->regs);
33692 +       ip7500media_portf_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
33693 +
33694 +       platform_device_register(&ip7500media_portf_sd_device);
33695 +}
33696 +
33697 +/******************************************************************************
33698 + * SD/IO Port B (Slot 2) platform data
33699 + */
33700 +static struct resource ip7500media_portb_sd_resources[] = {
33701 +       /*
33702 +        * Send IRQ
33703 +        */
33704 +       [0] = {
33705 +               /* 
33706 +                * The init routine will query the devtree and fill this in
33707 +                */
33708 +               .flags  = IORESOURCE_IRQ,
33709 +       },
33710 +
33711 +       /*
33712 +        * Receive IRQ
33713 +        */
33714 +       [1] = {
33715 +               /* 
33716 +                * The init routine will query the devtree and fill this in
33717 +                */
33718 +               .flags  = IORESOURCE_IRQ,
33719 +       },
33720 +
33721 +       /*
33722 +        * Memory Mapped Registers
33723 +        */
33724 +       [2] = {
33725 +               /* 
33726 +                * The init routine will query the devtree and fill this in
33727 +                */
33728 +               .flags  = IORESOURCE_MEM,
33729 +       },
33730 +};
33731 +
33732 +static struct ubicom32sd_card ip7500media_portb_sd_cards[] = {
33733 +       [0] = {
33734 +               .pin_wp         = IP7500MEDIA_IO19,
33735 +               .wp_polarity    = 1,
33736 +               .pin_pwr        = IP7500MEDIA_IO22,
33737 +               .pin_cd         = IP7500MEDIA_IO18,
33738 +       },
33739 +};
33740 +
33741 +static struct ubicom32sd_platform_data ip7500media_portb_sd_platform_data = {
33742 +       .ncards         = 1,
33743 +       .cards          = ip7500media_portb_sd_cards,
33744 +};
33745 +
33746 +static struct platform_device ip7500media_portb_sd_device = {
33747 +       .name           = "ubicom32sd",
33748 +       .id             = 1,
33749 +       .resource       = ip7500media_portb_sd_resources,
33750 +       .num_resources  = ARRAY_SIZE(ip7500media_portb_sd_resources),
33751 +       .dev            = {
33752 +                       .platform_data = &ip7500media_portb_sd_platform_data,
33753 +       },
33754 +
33755 +};
33756 +
33757 +/*
33758 + * ip7500media_portb_sd_init
33759 + */
33760 +static void ip7500media_portb_sd_init(void)
33761 +{
33762 +       /*
33763 +        * Check the device tree for the sd_tio
33764 +        */
33765 +       struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
33766 +       if (!sd_node) {
33767 +               printk(KERN_INFO "PortB SDTIO not found\n");
33768 +               return;
33769 +       }
33770 +
33771 +       /*
33772 +        * Fill in the resources and platform data from devtree information
33773 +        */
33774 +       ip7500media_portb_sd_resources[0].start = sd_node->dn.sendirq;
33775 +       ip7500media_portb_sd_resources[1].start = sd_node->dn.recvirq;
33776 +       ip7500media_portb_sd_resources[2].start = (u32_t)&(sd_node->regs);
33777 +       ip7500media_portb_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
33778 +
33779 +       platform_device_register(&ip7500media_portb_sd_device);
33780 +}
33781 +
33782 +/*
33783 + * ip7500media_u17_setup
33784 + *     Called by I2C to tell us that u17 is setup.
33785 + *
33786 + * This function is called by I2C to tell us that u17 has been setup.  All
33787 + * devices which rely on this chip being initialized (or even present) need to
33788 + * be initialized in this function otherwise they may get initialized too early.
33789 + *
33790 + * Currently the only device depending on u17 is the SDIO
33791 + */
33792 +static int __init ip7500media_u17_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
33793 +{
33794 +       /*
33795 +        * Initialize the Port F/Port B SD slots (only the enabled ports will init)
33796 +        */
33797 +       ip7500media_portf_sd_init();
33798 +       ip7500media_portb_sd_init();
33799 +
33800 +       return 0;
33801 +}
33802 +
33803 +/******************************************************************************
33804 + * LCD VGH on the board at PE6
33805 + */
33806 +static struct ubicom32lcd_platform_data ip7500media_lcd_data = {
33807 +       .vgh_gpio               = GPIO_RE_7,
33808 +       .vgh_polarity           = true,
33809 +};
33810 +
33811 +static struct platform_device ip7500media_lcd_device = {
33812 +       .name   = "ubicom32lcd",
33813 +       .id     = -1,
33814 +       .dev    = {
33815 +               .platform_data = &ip7500media_lcd_data,
33816 +       },
33817 +};
33818 +
33819 +/******************************************************************************
33820 + * Backlight on the board PD0, hardware PWM
33821 + */
33822 +static struct ubicom32bl_platform_data ip7500media_backlight_data = {
33823 +       .type                   = UBICOM32BL_TYPE_PWM,
33824 +       .pwm_channel            = 2,
33825 +       .pwm_prescale           = 15,
33826 +       .pwm_period             = 60,
33827 +       .default_intensity      = 0x80,
33828 +};
33829 +
33830 +static struct platform_device ip7500media_backlight_device = {
33831 +       .name   = "ubicom32bl",
33832 +       .id     = -1,
33833 +       .dev    = {
33834 +               .platform_data = &ip7500media_backlight_data,
33835 +       },
33836 +};
33837 +
33838 +/******************************************************************************
33839 + * Ubicom32Input on I2C, U15 MAX7310, address 0x18, 8 bits
33840 + */
33841 +static struct ubicom32input_i2c_button ip7500media_ubicom32input_i2c_u15_buttons[] = {
33842 +       {
33843 +               .type           = EV_KEY,
33844 +               .code           = KEY_LEFT,
33845 +               .bit            = 0,
33846 +               .active_low     = 1,
33847 +       },
33848 +       {
33849 +               .type           = EV_KEY,
33850 +               .code           = KEY_RIGHT,
33851 +               .bit            = 1,
33852 +               .active_low     = 1,
33853 +       },
33854 +       {
33855 +               .type           = EV_KEY,
33856 +               .code           = KEY_UP,
33857 +               .bit            = 2,
33858 +               .active_low     = 1,
33859 +       },
33860 +       {
33861 +               .type           = EV_KEY,
33862 +               .code           = KEY_DOWN,
33863 +               .bit            = 3,
33864 +               .active_low     = 1,
33865 +       },
33866 +       {
33867 +               .type           = EV_KEY,
33868 +               .code           = KEY_ENTER,
33869 +               .bit            = 4,
33870 +               .active_low     = 1,
33871 +       },
33872 +       {
33873 +               .type           = EV_KEY,
33874 +               .code           = KEY_MENU,
33875 +               .bit            = 5,
33876 +               .active_low     = 1,
33877 +       },
33878 +       {
33879 +               .type           = EV_KEY,
33880 +               .code           = KEY_ESC,
33881 +               .bit            = 6,
33882 +               .active_low     = 1,
33883 +       },
33884 +};
33885 +
33886 +static struct ubicom32input_i2c_platform_data ip7500media_ubicom32input_i2c_u15_platform_data = {
33887 +       .buttons        = ip7500media_ubicom32input_i2c_u15_buttons,
33888 +       .nbuttons       = ARRAY_SIZE(ip7500media_ubicom32input_i2c_u15_buttons),
33889 +       .name           = "Ubicom32 Input I2C U15",
33890 +};
33891 +
33892 +/******************************************************************************
33893 + * Additional GPIO chips
33894 + */
33895 +static struct pca953x_platform_data ip7500media_gpio_u16_platform_data = {
33896 +       .gpio_base = IP7500MEDIA_U16_BASE,
33897 +};
33898 +
33899 +static struct pca953x_platform_data ip7500media_gpio_u17_platform_data = {
33900 +       .gpio_base = IP7500MEDIA_U17_BASE,
33901 +       .setup = ip7500media_u17_setup,
33902 +};
33903 +
33904 +static struct pca953x_platform_data ip7500media_gpio_u18_platform_data = {
33905 +       .gpio_base = IP7500MEDIA_U18_BASE,
33906 +};
33907 +
33908 +/******************************************************************************
33909 + * Devices on the I2C bus
33910 + *
33911 + * BEWARE of changing the order of things in this array as we depend on
33912 + * certain things to be in certain places.
33913 + */
33914 +static struct i2c_board_info __initdata ip7500media_i2c_board_info[] = {
33915 +       /*
33916 +        * U6, CS4350 DAC, address 0x4B
33917 +        */
33918 +       {
33919 +               .type           = "cs4350",
33920 +               .addr           = 0x4B,
33921 +       },
33922 +
33923 +       /*
33924 +        * U14, S35390A RTC, address 0x30
33925 +        */
33926 +       {
33927 +               .type           = "s35390a",
33928 +               .addr           = 0x30,
33929 +       },
33930 +
33931 +       /*
33932 +        * U15, MAX7310 IO expander, 8 bits, address 0x18
33933 +        *      IO0: User I/O (J16-1) (Left)    IO4: User I/O (J16-5) (Enter)
33934 +        *      IO1: User I/O (J16-2) (Right)   IO5: User I/O (J16-6) (Menu)
33935 +        *      IO2: User I/O (J16-3) (Up)      IO6: User I/O (J16-7) (Back)
33936 +        *      IO3: User I/O (J16-4) (Down)    IO7: User I/O (J16-8)
33937 +        */
33938 +       {
33939 +               .type           = "ubicom32in_max7310",
33940 +               .addr           = 0x18,
33941 +               .platform_data  = &ip7500media_ubicom32input_i2c_u15_platform_data,
33942 +       },
33943 +
33944 +       /*
33945 +        * U16, MAX7310 IO expander, 8 bits, address 0x1C
33946 +        *      IO8 : User I/O (J16-9)          IO12: User I/O (J16-17)
33947 +        *      IO9 : User I/O (J16-10)         IO13: User I/O (J16-18)
33948 +        *      IO10: User I/O (J16-15)         IO14: User I/O (J16-19)
33949 +        *      IO11: User I/O (J16-16)         IO15: User I/O (J16-20)
33950 +        */
33951 +       {
33952 +               .type           = "max7310",
33953 +               .addr           = 0x1C,
33954 +               .platform_data  = &ip7500media_gpio_u16_platform_data,
33955 +       },
33956 +
33957 +       /*
33958 +        * U17, MAX7310 IO expander, 8 bits, address 0x1A
33959 +        *      IO16: SDIO1A_WP                 IO20: SD1A_PWREN
33960 +        *      IO17: SDIO1B_WP                 IO21: SD1B_PWREN
33961 +        *      IO18: SDIO2_CD                  IO22: SD2_PWREN
33962 +        *      IO19: SDIO2_WP                  IO23: SDIO1A_CD
33963 +        *      
33964 +        */
33965 +       {
33966 +               .type           = "max7310",
33967 +               .addr           = 0x1A,
33968 +               .platform_data  = &ip7500media_gpio_u17_platform_data,
33969 +       },
33970 +
33971 +       /*
33972 +        * U18, MAX7310 IOB expander, 8 bits, address 0x1E
33973 +        *      IO24: SDIO1B_CD                 IO28: User I/O TP6
33974 +        *      IO25: User I/O TP9              IO29: User I/O TP5
33975 +        *      IO26: User I/O TP8              IO30: User I/O TP4
33976 +        *      IO27: User I/O TP7              IO31: User I/O TP3
33977 +        */
33978 +       {
33979 +               .type           = "max7310",
33980 +               .addr           = 0x1E,
33981 +               .platform_data  = &ip7500media_gpio_u18_platform_data,
33982 +       },
33983 +};
33984 +
33985 +/*
33986 + * I2C bus on the board, SDA PE4, SCL PE5
33987 + */
33988 +static struct i2c_gpio_platform_data ip7500media_i2c_data = {
33989 +       .sda_pin                = GPIO_RE_4,
33990 +       .scl_pin                = GPIO_RE_5,
33991 +       .sda_is_open_drain      = 0,
33992 +       .scl_is_open_drain      = 0,
33993 +       .udelay                 = 50,
33994 +};
33995 +
33996 +static struct platform_device ip7500media_i2c_device = {
33997 +       .name   = "i2c-gpio",
33998 +       .id     = 0,
33999 +       .dev    = {
34000 +               .platform_data = &ip7500media_i2c_data,
34001 +       },
34002 +};
34003 +
34004 +/*
34005 + * List of all devices in our system
34006 + */
34007 +static struct platform_device *ip7500media_devices[] __initdata = {
34008 +       &ip7500media_i2c_device,
34009 +       &ip7500media_lcd_device,
34010 +       &ip7500media_backlight_device,
34011 +};
34012 +
34013 +/*
34014 + * ip7500media_init
34015 + *     Called to add the devices which we have on this board
34016 + */
34017 +static int __init ip7500media_init(void)
34018 +{
34019 +       struct platform_device *audio_dev;
34020 +
34021 +       board_init();
34022 +
34023 +       ubi_gpio_init();
34024 +
34025 +#ifdef CONFIG_UIO_UBICOM32RING
34026 +       ring_tio_init("decoder_ring");
34027 +#endif
34028 +
34029 +       /*
34030 +        * Start up the video driver first
34031 +        */
34032 +       vdc_tio_init();
34033 +
34034 +       /*
34035 +        * Register all of the devices we have on this board
34036 +        */
34037 +       printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
34038 +       platform_add_devices(ip7500media_devices, ARRAY_SIZE(ip7500media_devices));
34039 +
34040 +       /*
34041 +        * Allocate the audio driver if we can
34042 +        */
34043 +       audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
34044 +       if (audio_dev) {
34045 +               ip7500media_i2c_board_info[0].platform_data = audio_dev;
34046 +       }
34047 +
34048 +       /*
34049 +        * Register all of the devices which sit on the I2C bus
34050 +        */
34051 +       printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
34052 +       i2c_register_board_info(0, ip7500media_i2c_board_info, ARRAY_SIZE(ip7500media_i2c_board_info));
34053 +
34054 +       /*
34055 +        * We have to initialize the SDIO after the I2C IOB gets setup.  SDIO is initialized in 
34056 +        * ip7500media_u17_setup
34057 +        */
34058 +
34059 +       return 0;
34060 +}
34061 +
34062 +arch_initcall(ip7500media_init);
34063 +
34064 --- /dev/null
34065 +++ b/arch/ubicom32/mach-ip7k/board-ip7500module.c
34066 @@ -0,0 +1,60 @@
34067 +/*
34068 + * arch/ubicom32/mach-ip7k/board-ip7500module.c
34069 + *   Support for IP7500 CPU module board.
34070 + *
34071 + * This file supports the IP7500 CPU module board:
34072 + *     8007-0510  Rev 1.0
34073 + *     8007-0510A Rev 1.0 (with ethernet)
34074 + *
34075 + * DIP Switch SW2 configuration: (*) default
34076 + *     POS 1: on(*) = PCI enabled, off = PCI disabled
34077 + *     POS 2: on(*) = TTYX => PA6, off = TTYX => PF12
34078 + *     POS 3: on(*) = TTYY => PA7, off = TTYY => PF15
34079 + *     POS 4: unused
34080 + *
34081 + * (C) Copyright 2009, Ubicom, Inc.
34082 + *
34083 + * This file is part of the Ubicom32 Linux Kernel Port.
34084 + *
34085 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34086 + * it and/or modify it under the terms of the GNU General Public License
34087 + * as published by the Free Software Foundation, either version 2 of the
34088 + * License, or (at your option) any later version.
34089 + *
34090 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34091 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34092 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34093 + * the GNU General Public License for more details.
34094 + *
34095 + * You should have received a copy of the GNU General Public License
34096 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34097 + * see <http://www.gnu.org/licenses/>.
34098 + *
34099 + * Ubicom32 implementation derived from (with many thanks):
34100 + *   arch/m68knommu
34101 + *   arch/blackfin
34102 + *   arch/parisc
34103 + */
34104 +#include <linux/device.h>
34105 +#include <linux/platform_device.h>
34106 +#include <linux/gpio.h>
34107 +#include <asm/board.h>
34108 +#include <asm/machdep.h>
34109 +#include <asm/ring_tio.h>
34110 +#include <asm/vdc_tio.h>
34111 +
34112 +/*
34113 + * ip7500module_init
34114 + *     Called to add the devices which we have on this board
34115 + */
34116 +static int __init ip7500module_init(void)
34117 +{
34118 +       board_init();
34119 +
34120 +       ubi_gpio_init();
34121 +
34122 +       return 0;
34123 +}
34124 +
34125 +arch_initcall(ip7500module_init);
34126 +
34127 --- /dev/null
34128 +++ b/arch/ubicom32/mach-ip7k/Kconfig
34129 @@ -0,0 +1,132 @@
34130 +config IP7145DPF
34131 +       bool "IP7145DPF"
34132 +       select UBICOM32_V4
34133 +       select UBICOM_INPUT
34134 +       select UBICOM_INPUT_I2C
34135 +       select RTC_CLASS
34136 +       select RTC_DRV_S35390A
34137 +       select I2C
34138 +       select I2C_GPIO
34139 +       select GPIO_PCA953X
34140 +       select FB
34141 +       select FB_UBICOM32
34142 +       select BACKLIGHT_LCD_SUPPORT
34143 +       select LCD_CLASS_DEVICE
34144 +       select LCD_UBICOM32
34145 +       select BACKLIGHT_CLASS_DEVICE
34146 +       select BACKLIGHT_UBICOM32
34147 +       select SND_UBI32
34148 +       select MMC_UBICOM32
34149 +       select MMC
34150 +       select MMC_BLOCK
34151 +       select BRD_64MB
34152 +       help
34153 +               IP7145 Digital Picture Frame reference design, supports:
34154 +                       8007-0410 v1.0
34155 +
34156 +config IP7160RGW
34157 +       bool "IP7160RGW"
34158 +       select UBICOM32_V4
34159 +       select UBICOM_INPUT
34160 +       select NEW_LEDS
34161 +       select LEDS_CLASS
34162 +       select LEDS_GPIO
34163 +       select BRD_64MB
34164 +       select SPI
34165 +       select SPI_UBICOM32_GPIO
34166 +       select VLAN_8021Q
34167 +       select UBICOM_SWITCH
34168 +       select UBICOM_SWITCH_BCM539X
34169 +       help
34170 +               Ubicom IP7160 RGW Eval, supports:
34171 +                       8007-0110 v1.0
34172 +                       8007-0111 v1.1
34173 +                       8007-0112 v1.2
34174 +
34175 +config IP7160BRINGUP
34176 +       bool "IP7160BRINGUP"
34177 +       select UBICOM32_V4
34178 +       select NEW_LEDS
34179 +       select LEDS_CLASS
34180 +       select LEDS_GPIO
34181 +       select BRD_64MB
34182 +       help
34183 +               Ubicom IP7160 Bringup, supports:
34184 +                       8007-0010 v1.0
34185 +
34186 +config IP7160DPF
34187 +       bool "IP7160DPF"
34188 +       select UBICOM32_V4
34189 +       select I2C
34190 +       select I2C_GPIO
34191 +       select FB
34192 +       select FB_UBICOM32
34193 +       select BACKLIGHT_LCD_SUPPORT
34194 +       select BACKLIGHT_CLASS_DEVICE
34195 +       select SND_UBI32
34196 +       select SND_UBI32_AUDIO_CS4350
34197 +       select UBICOM_HID
34198 +       select BRD_64MB
34199 +       help
34200 +               IP7160 Digital Picture Frame board, supports:
34201 +                       8007-0211 Rev 1.1
34202 +
34203 +config IP7500MODULE
34204 +       bool "IP7500MODULE"
34205 +       select UBICOM32_V4
34206 +       select BRD_128MB
34207 +       help
34208 +               Ubicom IP7500 CPU Module board, supports:
34209 +                       8007-0510  v1.0
34210 +                       8007-0510A v1.0
34211 +
34212 +               Please see ip7500module.c for more details.
34213 +
34214 +config IP7500AV
34215 +       bool "IP7500AV"
34216 +       select UBICOM32_V4
34217 +       select BRD_128MB
34218 +       select I2C
34219 +       select I2C_GPIO
34220 +       select SND_UBI32
34221 +       select SND_UBI32_AUDIO_CS4384
34222 +       select FB
34223 +       select FB_UBICOM32
34224 +       help
34225 +               Ubicom IP7500 Audio Video board, supports:
34226 +                       8007-0810  v1.0
34227 +
34228 +               With Ubicom IP7500 CPU Module board:
34229 +                       8007-0510  v1.0 -or-
34230 +                       8007-0510A v1.0
34231 +
34232 +               Please see ip7500av.c for more details.
34233 +
34234 +config IP7500MEDIA
34235 +       bool "IP7500MEDIA"
34236 +       select UBICOM32_V4
34237 +       select UBICOM_INPUT_I2C
34238 +       select RTC_CLASS
34239 +       select RTC_DRV_S35390A
34240 +       select I2C
34241 +       select I2C_GPIO
34242 +       select GPIO_PCA953X
34243 +       select FB
34244 +       select FB_UBICOM32
34245 +       select BACKLIGHT_LCD_SUPPORT
34246 +       select LCD_CLASS_DEVICE
34247 +       select LCD_UBICOM32
34248 +       select BACKLIGHT_CLASS_DEVICE
34249 +       select BACKLIGHT_UBICOM32
34250 +       select SND_UBI32
34251 +       select SND_UBI32_AUDIO_CS4350
34252 +       select MMC_UBICOM32
34253 +       select MMC
34254 +       select MMC_BLOCK
34255 +       select BRD_128MB
34256 +       help
34257 +               IP7500 Media Board w/ IP7500 CPU Module board, supports:
34258 +                       8007-0610 v1.0 w/ 8007-0510 v1.0
34259 +
34260 +               Please see ip7500media.c for more details.
34261 +
34262 --- /dev/null
34263 +++ b/arch/ubicom32/mach-ip7k/Makefile
34264 @@ -0,0 +1,35 @@
34265 +#
34266 +# arch/ubicom32/mach-ip7k/Makefile
34267 +#      Makefile for ip7k based boards.
34268 +#
34269 +# (C) Copyright 2009, Ubicom, Inc.
34270 +#
34271 +# This file is part of the Ubicom32 Linux Kernel Port.
34272 +#
34273 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34274 +# it and/or modify it under the terms of the GNU General Public License
34275 +# as published by the Free Software Foundation, either version 2 of the
34276 +# License, or (at your option) any later version.
34277 +#
34278 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34279 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34280 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34281 +# the GNU General Public License for more details.
34282 +#
34283 +# You should have received a copy of the GNU General Public License
34284 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34285 +# see <http://www.gnu.org/licenses/>.
34286 +#
34287 +# Ubicom32 implementation derived from (with many thanks):
34288 +#   arch/m68knommu
34289 +#   arch/blackfin
34290 +#   arch/parisc
34291 +#
34292 +
34293 +obj-$(CONFIG_IP7145DPF)                += board-ip7145dpf.o
34294 +obj-$(CONFIG_IP7160RGW)                += board-ip7160rgw.o
34295 +obj-$(CONFIG_IP7160BRINGUP)    += board-ip7160bringup.o
34296 +obj-$(CONFIG_IP7160DPF)                += board-ip7160dpf.o
34297 +obj-$(CONFIG_IP7500MODULE)     += board-ip7500module.o
34298 +obj-$(CONFIG_IP7500MEDIA)      += board-ip7500media.o
34299 +obj-$(CONFIG_IP7500AV)         += board-ip7500av.o
34300 --- /dev/null
34301 +++ b/arch/ubicom32/Makefile
34302 @@ -0,0 +1,103 @@
34303 +#
34304 +# arch/ubicom32/Makefile
34305 +#      <TODO: Replace with short file description>
34306 +#
34307 +# (C) Copyright 2009, Ubicom, Inc.
34308 +#
34309 +# This file is part of the Ubicom32 Linux Kernel Port.
34310 +#
34311 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34312 +# it and/or modify it under the terms of the GNU General Public License
34313 +# as published by the Free Software Foundation, either version 2 of the
34314 +# License, or (at your option) any later version.
34315 +#
34316 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34317 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34318 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34319 +# the GNU General Public License for more details.
34320 +#
34321 +# You should have received a copy of the GNU General Public License
34322 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34323 +# see <http://www.gnu.org/licenses/>.
34324 +#
34325 +# Ubicom32 implementation derived from (with many thanks):
34326 +#   arch/m68knommu
34327 +#   arch/blackfin
34328 +#   arch/parisc
34329 +#
34330 +
34331 +KBUILD_DEFCONFIG := 
34332 +
34333 +# setup the machine name and machine dependent settings
34334 +machine-$(CONFIG_UBICOM32_V3)  := ip5k
34335 +machine-$(CONFIG_UBICOM32_V4)  := ip7k
34336 +MACHINE := $(machine-y)
34337 +export MACHINE
34338 +
34339 +model-$(CONFIG_RAMKERNEL)      := ram
34340 +model-$(CONFIG_ROMKERNEL)      := rom
34341 +MODEL := $(model-y)
34342 +export MODEL
34343 +
34344 +CPUCLASS := $(cpuclass-y)
34345 +
34346 +export CPUCLASS
34347 +
34348 +#
34349 +# We want the core kernel built using the fastcall ABI but modules need
34350 +# to be built using the slower calling convention because they could be
34351 +# loaded out of range for fast calls.
34352 +#
34353 +CFLAGS_KERNEL    += -mfastcall
34354 +CFLAGS_MODULE    += -mno-fastcall
34355 +
34356 +#
34357 +# Some CFLAG additions based on specific CPU type.
34358 +#
34359 +cflags-$(CONFIG_UBICOM32_V3)           := -march=ubicom32v3 -mno-fdpic -DIP5000
34360 +cflags-$(CONFIG_UBICOM32_V4)           := -march=ubicom32v4 -mno-fdpic -DIP7000
34361 +
34362 +ldflags-$(CONFIG_LINKER_RELAXATION)    := --relax
34363 +LDFLAGS_vmlinux := $(ldflags-y)
34364 +
34365 +GCCLIBDIR := $(dir $(shell $(CC) $(cflags-y) -print-libgcc-file-name))
34366 +
34367 +KBUILD_CFLAGS += $(cflags-y) -ffunction-sections
34368 +KBUILD_AFLAGS += $(cflags-y)
34369 +
34370 +KBUILD_CFLAGS += -D__linux__ -Dlinux
34371 +KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
34372 +
34373 +# include any machine specific directory
34374 +ifneq ($(machine-y),)
34375 +core-y += arch/$(ARCH)/mach-$(MACHINE)/
34376 +endif
34377 +
34378 +head-y := arch/$(ARCH)/kernel/head.o
34379 +
34380 +core-y += arch/$(ARCH)/kernel/ \
34381 +          arch/$(ARCH)/mm/ \
34382 +          arch/$(ARCH)/crypto/ \
34383 +          arch/$(ARCH)/mach-common/
34384 +
34385 +drivers-$(CONFIG_OPROFILE)     += arch/ubicom32/oprofile/
34386 +
34387 +libs-y += arch/$(ARCH)/lib/
34388 +
34389 +archclean:
34390 +
34391 +# make sure developer has selected a valid board
34392 +ifeq ($(CONFIG_NOBOARD),y)
34393 +# $(error have to select a valid board file $(CONFIG_NOBOARD), please run kernel config again)
34394 +_all: config_board_error
34395 +endif
34396 +
34397 +config_board_error:
34398 +       @echo "*************************************************"
34399 +       @echo "You have not selected a proper board."
34400 +       @echo "Please run menuconfig (or config) against your"
34401 +       @echo "kernel and choose your board under Processor"
34402 +       @echo "options"
34403 +       @echo "*************************************************"
34404 +       @exit 1
34405 +
34406 --- /dev/null
34407 +++ b/arch/ubicom32/mm/fault.c
34408 @@ -0,0 +1,81 @@
34409 +/*
34410 + * arch/ubicom32/mm/fault.c
34411 + *   Ubicom32 architecture page fault implementation.
34412 + *
34413 + * (C) Copyright 2009, Ubicom, Inc.
34414 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
34415 + *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
34416 + *
34417 + *  Based on:
34418 + *
34419 + *  linux/arch/m68k/mm/fault.c
34420 + *
34421 + *  Copyright (C) 1995  Hamish Macdonald
34422 + *
34423 + * This file is part of the Ubicom32 Linux Kernel Port.
34424 + *
34425 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34426 + * it and/or modify it under the terms of the GNU General Public License
34427 + * as published by the Free Software Foundation, either version 2 of the
34428 + * License, or (at your option) any later version.
34429 + *
34430 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34431 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34432 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34433 + * the GNU General Public License for more details.
34434 + *
34435 + * You should have received a copy of the GNU General Public License
34436 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34437 + * see <http://www.gnu.org/licenses/>.
34438 + *
34439 + * Ubicom32 implementation derived from (with many thanks):
34440 + *   arch/m68knommu
34441 + *   arch/blackfin
34442 + *   arch/parisc
34443 + */
34444 +
34445 +#include <linux/module.h>
34446 +#include <linux/mman.h>
34447 +#include <linux/mm.h>
34448 +#include <linux/kernel.h>
34449 +#include <linux/ptrace.h>
34450 +
34451 +#include <asm/system.h>
34452 +#include <asm/pgtable.h>
34453 +
34454 +extern void die_if_kernel(char *, struct pt_regs *, long);
34455 +
34456 +/*
34457 + * This routine handles page faults.  It determines the problem, and
34458 + * then passes it off to one of the appropriate routines.
34459 + *
34460 + * error_code:
34461 + *     bit 0 == 0 means no page found, 1 means protection fault
34462 + *     bit 1 == 0 means read, 1 means write
34463 + *
34464 + * If this routine detects a bad access, it returns 1, otherwise it
34465 + * returns 0.
34466 + */
34467 +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
34468 +                             unsigned long error_code)
34469 +{
34470 +#ifdef DEBUG
34471 +       printk (KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
34472 +               regs->sr, regs->pc, address, error_code);
34473 +#endif
34474 +
34475 +       /*
34476 +        * Oops. The kernel tried to access some bad page. We'll have to
34477 +        * terminate things with extreme prejudice.
34478 +        */
34479 +       if ((unsigned long) address < PAGE_SIZE) {
34480 +               printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
34481 +       } else
34482 +               printk(KERN_ALERT "Unable to handle kernel access");
34483 +       printk(KERN_ALERT " at virtual address %08lx\n",address);
34484 +       die_if_kernel("Oops", regs, error_code);
34485 +       do_exit(SIGKILL);
34486 +
34487 +       return 1;
34488 +}
34489 +
34490 --- /dev/null
34491 +++ b/arch/ubicom32/mm/init.c
34492 @@ -0,0 +1,261 @@
34493 +/*
34494 + * arch/ubicom32/mm/init.c
34495 + *   Ubicom32 architecture virtual memory initialization.
34496 + *
34497 + * (C) Copyright 2009, Ubicom, Inc.
34498 + *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
34499 + *                      Kenneth Albanowski <kjahds@kjahds.com>,
34500 + *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
34501 + *
34502 + *  Based on:
34503 + *
34504 + *  linux/arch/m68k/mm/init.c
34505 + *
34506 + *  Copyright (C) 1995  Hamish Macdonald
34507 + *
34508 + *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
34509 + *  DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
34510 + *
34511 + * This file is part of the Ubicom32 Linux Kernel Port.
34512 + *
34513 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34514 + * it and/or modify it under the terms of the GNU General Public License
34515 + * as published by the Free Software Foundation, either version 2 of the
34516 + * License, or (at your option) any later version.
34517 + *
34518 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34519 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34520 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34521 + * the GNU General Public License for more details.
34522 + *
34523 + * You should have received a copy of the GNU General Public License
34524 + * along with the Ubicom32 Linux Kernel Port.  If not,
34525 + * see <http://www.gnu.org/licenses/>.
34526 + *
34527 + * Ubicom32 implementation derived from (with many thanks):
34528 + *   arch/m68knommu
34529 + *   arch/blackfin
34530 + *   arch/parisc
34531 + */
34532 +
34533 +#include <linux/signal.h>
34534 +#include <linux/sched.h>
34535 +#include <linux/kernel.h>
34536 +#include <linux/errno.h>
34537 +#include <linux/string.h>
34538 +#include <linux/types.h>
34539 +#include <linux/ptrace.h>
34540 +#include <linux/mman.h>
34541 +#include <linux/mm.h>
34542 +#include <linux/swap.h>
34543 +#include <linux/init.h>
34544 +#include <linux/highmem.h>
34545 +#include <linux/pagemap.h>
34546 +#include <linux/bootmem.h>
34547 +#include <linux/slab.h>
34548 +
34549 +#include <asm/setup.h>
34550 +#include <asm/segment.h>
34551 +#include <asm/page.h>
34552 +#include <asm/pgtable.h>
34553 +#include <asm/system.h>
34554 +#include <asm/machdep.h>
34555 +#include <asm/ocm-alloc.h>
34556 +
34557 +#undef DEBUG
34558 +
34559 +extern void die_if_kernel(char *,struct pt_regs *,long);
34560 +extern void free_initmem(void);
34561 +
34562 +/*
34563 + * BAD_PAGE is the page that is used for page faults when linux
34564 + * is out-of-memory. Older versions of linux just did a
34565 + * do_exit(), but using this instead means there is less risk
34566 + * for a process dying in kernel mode, possibly leaving a inode
34567 + * unused etc..
34568 + *
34569 + * BAD_PAGETABLE is the accompanying page-table: it is initialized
34570 + * to point to BAD_PAGE entries.
34571 + *
34572 + * ZERO_PAGE is a special page that is used for zero-initialized
34573 + * data and COW.
34574 + */
34575 +static unsigned long empty_bad_page_table;
34576 +
34577 +static unsigned long empty_bad_page;
34578 +
34579 +unsigned long empty_zero_page;
34580 +
34581 +void show_mem(void)
34582 +{
34583 +    unsigned long i;
34584 +    int free = 0, total = 0, reserved = 0, shared = 0;
34585 +    int cached = 0;
34586 +
34587 +    printk(KERN_INFO "\nMem-info:\n");
34588 +    show_free_areas();
34589 +    i = max_mapnr;
34590 +    while (i-- > 0) {
34591 +       total++;
34592 +       if (PageReserved(mem_map+i))
34593 +           reserved++;
34594 +       else if (PageSwapCache(mem_map+i))
34595 +           cached++;
34596 +       else if (!page_count(mem_map+i))
34597 +           free++;
34598 +       else
34599 +           shared += page_count(mem_map+i) - 1;
34600 +    }
34601 +    printk(KERN_INFO "%d pages of RAM\n",total);
34602 +    printk(KERN_INFO "%d free pages\n",free);
34603 +    printk(KERN_INFO "%d reserved pages\n",reserved);
34604 +    printk(KERN_INFO "%d pages shared\n",shared);
34605 +    printk(KERN_INFO "%d pages swap cached\n",cached);
34606 +}
34607 +
34608 +extern unsigned long memory_start;
34609 +extern unsigned long memory_end;
34610 +extern char __ocm_free_begin;
34611 +extern char __ocm_free_end;
34612 +
34613 +/*
34614 + * paging_init() continues the virtual memory environment setup which
34615 + * was begun by the code in arch/head.S.
34616 + * The parameters are pointers to where to stick the starting and ending
34617 + * addresses of available kernel virtual memory.
34618 + */
34619 +void __init paging_init(void)
34620 +{
34621 +       /*
34622 +        * Make sure start_mem is page aligned, otherwise bootmem and
34623 +        * page_alloc get different views of the world.
34624 +        */
34625 +#ifdef DEBUG
34626 +       unsigned long start_mem = PAGE_ALIGN(memory_start);
34627 +#endif
34628 +       unsigned long end_mem   = memory_end & PAGE_MASK;
34629 +
34630 +#ifdef DEBUG
34631 +       printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
34632 +               start_mem, end_mem);
34633 +#endif
34634 +
34635 +       /*
34636 +        * Initialize the bad page table and bad page to point
34637 +        * to a couple of allocated pages.
34638 +        */
34639 +       empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34640 +       empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34641 +       empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
34642 +       memset((void *)empty_zero_page, 0, PAGE_SIZE);
34643 +
34644 +       /*
34645 +        * TODO: enable setting up for user memory management interface.
34646 +        */
34647 +
34648 +#ifdef DEBUG
34649 +       printk (KERN_DEBUG "before free_area_init\n");
34650 +
34651 +       printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
34652 +               start_mem, end_mem);
34653 +#endif
34654 +
34655 +       {
34656 +               unsigned long zones_size[MAX_NR_ZONES] = {0, };
34657 +#ifdef CONFIG_ZONE_DMA
34658 +               zones_size[ZONE_DMA] = OCMSIZE >> PAGE_SHIFT;
34659 +#endif
34660 +               zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
34661 +#ifdef CONFIG_HIGHMEM
34662 +               zones_size[ZONE_HIGHMEM] = 0;
34663 +#endif
34664 +               free_area_init(zones_size);
34665 +       }
34666 +}
34667 +
34668 +void __init mem_init(void)
34669 +{
34670 +       int codek = 0, datak = 0, initk = 0;
34671 +       unsigned long tmp;
34672 +       extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
34673 +       unsigned long len = CONFIG_RAMSIZE + OCMSIZE;
34674 +       unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
34675 +       unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
34676 +
34677 +#ifdef DEBUG
34678 +       printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
34679 +#endif
34680 +
34681 +       end_mem &= PAGE_MASK;
34682 +       high_memory = (void *) end_mem;
34683 +
34684 +       start_mem = PAGE_ALIGN(start_mem);
34685 +       max_mapnr = num_physpages = (((unsigned long) high_memory) - PAGE_OFFSET) >> PAGE_SHIFT;
34686 +
34687 +       /* this will put all memory onto the freelists */
34688 +#ifdef CONFIG_ZONE_DMA
34689 +       {
34690 +               unsigned long ocm_free_begin = (unsigned long)&__ocm_free_begin;
34691 +               unsigned long ocm_free_end = (unsigned long)&__ocm_free_end;
34692 +               unsigned long zone_dma_begin = (ocm_free_begin + PAGE_SIZE - 1) & PAGE_MASK;
34693 +               unsigned long zone_dma_end = ocm_free_end & PAGE_MASK;
34694 +               if (zone_dma_end > zone_dma_begin)
34695 +                       free_bootmem(zone_dma_begin, zone_dma_end-zone_dma_begin);
34696 +       }
34697 +#endif
34698 +       totalram_pages = free_all_bootmem();
34699 +
34700 +       codek = (&_etext - &_stext) >> 10;
34701 +       datak = (&_ebss - &_sdata) >> 10;
34702 +       initk = (&__init_begin - &__init_end) >> 10;
34703 +
34704 +       tmp = nr_free_pages() << PAGE_SHIFT;
34705 +       printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n",
34706 +              tmp >> 10,
34707 +              len >> 10,
34708 +              codek,
34709 +              datak
34710 +              );
34711 +
34712 +}
34713 +
34714 +#ifdef CONFIG_BLK_DEV_INITRD
34715 +void free_initrd_mem(unsigned long start, unsigned long end)
34716 +{
34717 +       int pages = 0;
34718 +       for (; start < end; start += PAGE_SIZE) {
34719 +               ClearPageReserved(virt_to_page(start));
34720 +               init_page_count(virt_to_page(start));
34721 +               free_page(start);
34722 +               totalram_pages++;
34723 +               pages++;
34724 +       }
34725 +       printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
34726 +}
34727 +#endif
34728 +
34729 +void
34730 +free_initmem()
34731 +{
34732 +#ifdef CONFIG_RAMKERNEL
34733 +       unsigned long addr;
34734 +       extern char __init_begin, __init_end;
34735 +       /*
34736 +        * The following code should be cool even if these sections
34737 +        * are not page aligned.
34738 +        */
34739 +       addr = PAGE_ALIGN((unsigned long)(&__init_begin));
34740 +       /* next to check that the page we free is not a partial page */
34741 +       for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
34742 +               ClearPageReserved(virt_to_page(addr));
34743 +               init_page_count(virt_to_page(addr));
34744 +               free_page(addr);
34745 +               totalram_pages++;
34746 +       }
34747 +       printk(KERN_NOTICE "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
34748 +                       (addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
34749 +                       (int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
34750 +                       (int)(addr - PAGE_SIZE));
34751 +#endif
34752 +}
34753 +
34754 --- /dev/null
34755 +++ b/arch/ubicom32/mm/kmap.c
34756 @@ -0,0 +1,79 @@
34757 +/*
34758 + * arch/ubicom32/mm/kmap.c
34759 + *   Ubicom32 architecture non-mmu ioremap and friends implementation.
34760 + *
34761 + * (C) Copyright 2009, Ubicom, Inc.
34762 + * Copyright (C) 2000 Lineo, <davidm@snapgear.com>
34763 + * Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
34764 + *
34765 + * This file is part of the Ubicom32 Linux Kernel Port.
34766 + *
34767 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34768 + * it and/or modify it under the terms of the GNU General Public License
34769 + * as published by the Free Software Foundation, either version 2 of the
34770 + * License, or (at your option) any later version.
34771 + *
34772 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34773 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34774 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34775 + * the GNU General Public License for more details.
34776 + *
34777 + * You should have received a copy of the GNU General Public License
34778 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34779 + * see <http://www.gnu.org/licenses/>.
34780 + *
34781 + * Ubicom32 implementation derived from (with many thanks):
34782 + *   arch/m68knommu
34783 + *   arch/blackfin
34784 + *   arch/parisc
34785 + */
34786 +
34787 +#include <linux/module.h>
34788 +#include <linux/mm.h>
34789 +#include <linux/kernel.h>
34790 +#include <linux/string.h>
34791 +#include <linux/types.h>
34792 +#include <linux/slab.h>
34793 +#include <linux/vmalloc.h>
34794 +
34795 +#include <asm/setup.h>
34796 +#include <asm/segment.h>
34797 +#include <asm/page.h>
34798 +#include <asm/pgalloc.h>
34799 +#include <asm/io.h>
34800 +#include <asm/system.h>
34801 +
34802 +#undef DEBUG
34803 +
34804 +/*
34805 + * Map some physical address range into the kernel address space.
34806 + */
34807 +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
34808 +{
34809 +       return (void *)physaddr;
34810 +}
34811 +
34812 +/*
34813 + * Unmap a ioremap()ed region again.
34814 + */
34815 +void iounmap(void *addr)
34816 +{
34817 +}
34818 +
34819 +/*
34820 + * __iounmap unmaps nearly everything, so be careful
34821 + * it doesn't free currently pointer/page tables anymore but it
34822 + * wans't used anyway and might be added later.
34823 + */
34824 +void __iounmap(void *addr, unsigned long size)
34825 +{
34826 +}
34827 +
34828 +/*
34829 + * Set new cache mode for some kernel address space.
34830 + * The caller must push data for that range itself, if such data may already
34831 + * be in the cache.
34832 + */
34833 +void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
34834 +{
34835 +}
34836 --- /dev/null
34837 +++ b/arch/ubicom32/mm/Makefile
34838 @@ -0,0 +1,32 @@
34839 +#
34840 +# arch/ubicom32/mm/Makefile
34841 +#      <TODO: Replace with short file description>
34842 +#
34843 +# (C) Copyright 2009, Ubicom, Inc.
34844 +#
34845 +# This file is part of the Ubicom32 Linux Kernel Port.
34846 +#
34847 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
34848 +# it and/or modify it under the terms of the GNU General Public License
34849 +# as published by the Free Software Foundation, either version 2 of the
34850 +# License, or (at your option) any later version.
34851 +#
34852 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
34853 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
34854 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34855 +# the GNU General Public License for more details.
34856 +#
34857 +# You should have received a copy of the GNU General Public License
34858 +# along with the Ubicom32 Linux Kernel Port.  If not, 
34859 +# see <http://www.gnu.org/licenses/>.
34860 +#
34861 +# Ubicom32 implementation derived from (with many thanks):
34862 +#   arch/m68knommu
34863 +#   arch/blackfin
34864 +#   arch/parisc
34865 +#
34866 +#
34867 +# Makefile for the linux m68knommu specific parts of the memory manager.
34868 +#
34869 +
34870 +obj-y += init.o fault.o memory.o kmap.o ocm-alloc.o
34871 --- /dev/null
34872 +++ b/arch/ubicom32/mm/memory.c
34873 @@ -0,0 +1,59 @@
34874 +/*
34875 + * arch/ubicom32/mm/memory.c
34876 + *   Ubicom32 architecture kernel_map() implementation.
34877 + *
34878 + * (C) Copyright 2009, Ubicom, Inc.
34879 + *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
34880 + *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
34881 + *
34882 + *  Based on:
34883 + *
34884 + *  linux/arch/m68k/mm/memory.c
34885 + *
34886 + *  Copyright (C) 1995  Hamish Macdonald
34887 + *
34888 + * This file is part of the Ubicom32 Linux Kernel Port.
34889 + *
34890 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34891 + * it and/or modify it under the terms of the GNU General Public License
34892 + * as published by the Free Software Foundation, either version 2 of the
34893 + * License, or (at your option) any later version.
34894 + *
34895 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34896 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34897 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34898 + * the GNU General Public License for more details.
34899 + *
34900 + * You should have received a copy of the GNU General Public License
34901 + * along with the Ubicom32 Linux Kernel Port.  If not, 
34902 + * see <http://www.gnu.org/licenses/>.
34903 + *
34904 + * Ubicom32 implementation derived from (with many thanks):
34905 + *   arch/m68knommu
34906 + *   arch/blackfin
34907 + *   arch/parisc
34908 + */
34909 +
34910 +#include <linux/module.h>
34911 +#include <linux/mm.h>
34912 +#include <linux/kernel.h>
34913 +#include <linux/string.h>
34914 +#include <linux/types.h>
34915 +#include <linux/slab.h>
34916 +
34917 +#include <asm/segment.h>
34918 +#include <asm/page.h>
34919 +#include <asm/pgtable.h>
34920 +#include <asm/system.h>
34921 +
34922 +/*
34923 + * Map some physical address range into the kernel address space.
34924 + * The code is copied and adapted from map_chunk().
34925 + */
34926 +
34927 +unsigned long kernel_map(unsigned long paddr, unsigned long size,
34928 +                        int nocacheflag, unsigned long *memavailp )
34929 +{
34930 +       return paddr;
34931 +}
34932 +
34933 --- /dev/null
34934 +++ b/arch/ubicom32/mm/ocm-alloc.c
34935 @@ -0,0 +1,439 @@
34936 +/*
34937 + * arch/ubicom32/mm/ocm-alloc.c
34938 + *     OCM allocator for Uibcom32 On-Chip memory
34939 + *
34940 + * (C) Copyright 2009, Ubicom, Inc.
34941 + *  Copyright 2004-2008 Analog Devices Inc.
34942 + *
34943 + *  Based on:
34944 + *
34945 + *  arch/blackfin/mm/sram-alloc.c
34946 + *
34947 + *
34948 + * This file is part of the Ubicom32 Linux Kernel Port.
34949 + *
34950 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
34951 + * it and/or modify it under the terms of the GNU General Public License
34952 + * as published by the Free Software Foundation, either version 2 of the
34953 + * License, or (at your option) any later version.
34954 + *
34955 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
34956 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
34957 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
34958 + * the GNU General Public License for more details.
34959 + *
34960 + * You should have received a copy of the GNU General Public License
34961 + * along with the Ubicom32 Linux Kernel Port.  If not,
34962 + * see <http://www.gnu.org/licenses/>.
34963 + *
34964 + * Ubicom32 implementation derived from (with many thanks):
34965 + *   arch/m68knommu
34966 + *   arch/blackfin
34967 + *   arch/parisc
34968 + */
34969 +
34970 +#include <linux/module.h>
34971 +#include <linux/kernel.h>
34972 +#include <linux/types.h>
34973 +#include <linux/miscdevice.h>
34974 +#include <linux/ioport.h>
34975 +#include <linux/fcntl.h>
34976 +#include <linux/init.h>
34977 +#include <linux/poll.h>
34978 +#include <linux/proc_fs.h>
34979 +#include <linux/mutex.h>
34980 +#include <linux/rtc.h>
34981 +#include <asm/ocm-alloc.h>
34982 +
34983 +#if 0
34984 +#define DEBUGP printk
34985 +#else
34986 +#define DEBUGP(fmt, a...)
34987 +#endif
34988 +/*
34989 + * the data structure for OCM heap pieces
34990 + */
34991 +struct ocm_piece {
34992 +       void *paddr;
34993 +       int size;
34994 +       pid_t pid;
34995 +       struct ocm_piece *next;
34996 +};
34997 +
34998 +/*
34999 + * struct ocm_heap
35000 + */
35001 +struct ocm_heap {
35002 +       struct ocm_piece free_head;
35003 +       struct ocm_piece used_head;
35004 +       struct mutex lock;
35005 +};
35006 +
35007 +static struct ocm_heap ocm_inst_heap;
35008 +
35009 +/*
35010 + * OCM area for storing code
35011 + */
35012 +extern asmlinkage void *__ocm_inst_heap_begin;
35013 +extern asmlinkage void *__ocm_inst_heap_end;
35014 +#define OCM_INST_HEAP_BEGIN ((unsigned int)&__ocm_inst_heap_begin)
35015 +#define OCM_INST_HEAP_END ((unsigned int)&__ocm_inst_heap_end)
35016 +#define OCM_INST_HEAP_LENGTH (OCM_INST_HEAP_END - OCM_INST_HEAP_BEGIN)
35017 +
35018 +static struct kmem_cache *ocm_piece_cache;
35019 +
35020 +/*
35021 + * _ocm_heap_init()
35022 + */
35023 +static int __init _ocm_heap_init(struct ocm_heap *ocmh,
35024 +                                 unsigned int start,
35025 +                                 unsigned int size)
35026 +{
35027 +       ocmh->free_head.next = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
35028 +
35029 +       if (!ocmh->free_head.next)
35030 +               return -1;
35031 +
35032 +       ocmh->free_head.next->paddr = (void *)start;
35033 +       ocmh->free_head.next->size = size;
35034 +       ocmh->free_head.next->pid = 0;
35035 +       ocmh->free_head.next->next = 0;
35036 +
35037 +       ocmh->used_head.next = NULL;
35038 +
35039 +       /* mutex initialize */
35040 +       mutex_init(&ocmh->lock);
35041 +
35042 +       return 0;
35043 +}
35044 +
35045 +/*
35046 + * _ocm_alloc_init()
35047 + *
35048 + * starts the ocm heap(s)
35049 + */
35050 +static int __init _ocm_alloc_init(void)
35051 +{
35052 +       if (OCM_INST_HEAP_LENGTH) {
35053 +               ocm_piece_cache = kmem_cache_create("ocm_piece_cache",
35054 +                                                   sizeof(struct ocm_piece),
35055 +                                                   0, SLAB_PANIC, NULL);
35056 +
35057 +               if (_ocm_heap_init(&ocm_inst_heap,
35058 +                                  OCM_INST_HEAP_BEGIN,
35059 +                                  OCM_INST_HEAP_LENGTH) == 0)
35060 +                       printk(KERN_INFO "OCM Instruction Heap %d KB\n",
35061 +                              OCM_INST_HEAP_LENGTH >> 10);
35062 +               else
35063 +                       printk(KERN_INFO "Failed to initialize OCM "
35064 +                              "Instruction Heap\n");
35065 +
35066 +       } else
35067 +               printk(KERN_INFO "No space available for OCM "
35068 +                      "Instruction Heap\n");
35069 +
35070 +       return 0;
35071 +}
35072 +pure_initcall(_ocm_alloc_init);
35073 +
35074 +/*
35075 + * _ocm_alloc()
35076 + *     generic alloc a block in the ocm heap, if successful
35077 + *     returns the pointer.
35078 + */
35079 +static void *_ocm_alloc(size_t size, pid_t pid, struct ocm_heap *ocmheap)
35080 +{
35081 +       struct ocm_piece *pslot, *plast, *pavail;
35082 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35083 +       struct ocm_piece *pused_head = &ocmheap->used_head;
35084 +
35085 +       if (size <= 0 || !pfree_head || !pused_head)
35086 +               return NULL;
35087 +
35088 +       /* Align the size */
35089 +       size = (size + 3) & ~3;
35090 +
35091 +       pslot = pfree_head->next;
35092 +       plast = pfree_head;
35093 +
35094 +       /*
35095 +        * search an available piece slot
35096 +        */
35097 +       while (pslot != NULL && size > pslot->size) {
35098 +               plast = pslot;
35099 +               pslot = pslot->next;
35100 +       }
35101 +
35102 +       if (!pslot)
35103 +               return NULL;
35104 +
35105 +       if (pslot->size == size) {
35106 +               /*
35107 +                * Unlink this block from the list
35108 +                */
35109 +               plast->next = pslot->next;
35110 +               pavail = pslot;
35111 +       } else {
35112 +               /*
35113 +                * Split this block in two.
35114 +                */
35115 +               pavail = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
35116 +
35117 +               if (!pavail)
35118 +                       return NULL;
35119 +
35120 +               pavail->paddr = pslot->paddr;
35121 +               pavail->size = size;
35122 +               pslot->paddr += size;
35123 +               pslot->size -= size;
35124 +       }
35125 +
35126 +       pavail->pid = pid;
35127 +
35128 +       pslot = pused_head->next;
35129 +       plast = pused_head;
35130 +
35131 +       /*
35132 +        * insert new piece into used piece list !!!
35133 +        */
35134 +       while (pslot != NULL && pavail->paddr < pslot->paddr) {
35135 +               plast = pslot;
35136 +               pslot = pslot->next;
35137 +       }
35138 +
35139 +       pavail->next = pslot;
35140 +       plast->next = pavail;
35141 +
35142 +       DEBUGP("_ocm_alloc %d bytes at %p from in %p",
35143 +              size, pavail->paddr, ocmheap);
35144 +
35145 +       return pavail->paddr;
35146 +}
35147 +
35148 +#if 0
35149 +/* Allocate the largest available block.  */
35150 +static void *_ocm_alloc_max(struct ocm_heap *ocmheap,
35151 +                            unsigned long *psize)
35152 +{
35153 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35154 +       struct ocm_piece *pslot, *pmax;
35155 +
35156 +       pmax = pslot = pfree_head->next;
35157 +
35158 +       /* search an available piece slot */
35159 +       while (pslot != NULL) {
35160 +               if (pslot->size > pmax->size)
35161 +                       pmax = pslot;
35162 +               pslot = pslot->next;
35163 +       }
35164 +
35165 +       if (!pmax)
35166 +               return NULL;
35167 +
35168 +       *psize = pmax->size;
35169 +
35170 +       return _ocm_alloc(*psize, ocmheap);
35171 +}
35172 +#endif
35173 +
35174 +/*
35175 + * _ocm_free()
35176 + *     generic free a block in the ocm heap, if successful
35177 + */
35178 +static int _ocm_free(const void *addr,
35179 +                    struct ocm_heap *ocmheap)
35180 +{
35181 +       struct ocm_piece *pslot, *plast, *pavail;
35182 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35183 +       struct ocm_piece *pused_head = &ocmheap->used_head;
35184 +
35185 +       /* search the relevant memory slot */
35186 +       pslot = pused_head->next;
35187 +       plast = pused_head;
35188 +
35189 +       /* search an available piece slot */
35190 +       while (pslot != NULL && pslot->paddr != addr) {
35191 +               plast = pslot;
35192 +               pslot = pslot->next;
35193 +       }
35194 +
35195 +       if (!pslot) {
35196 +               DEBUGP("_ocm_free %p  not found in %p", addr, ocmheap);
35197 +               return -1;
35198 +       }
35199 +       DEBUGP("_ocm_free %p from in %p", addr, ocmheap);
35200 +
35201 +       plast->next = pslot->next;
35202 +       pavail = pslot;
35203 +       pavail->pid = 0;
35204 +
35205 +       /* insert free pieces back to the free list */
35206 +       pslot = pfree_head->next;
35207 +       plast = pfree_head;
35208 +
35209 +       while (pslot != NULL && addr > pslot->paddr) {
35210 +               plast = pslot;
35211 +               pslot = pslot->next;
35212 +       }
35213 +
35214 +       if (plast != pfree_head &&
35215 +           plast->paddr + plast->size == pavail->paddr) {
35216 +               plast->size += pavail->size;
35217 +               kmem_cache_free(ocm_piece_cache, pavail);
35218 +       } else {
35219 +               pavail->next = plast->next;
35220 +               plast->next = pavail;
35221 +               plast = pavail;
35222 +       }
35223 +
35224 +       if (pslot && plast->paddr + plast->size == pslot->paddr) {
35225 +               plast->size += pslot->size;
35226 +               plast->next = pslot->next;
35227 +               kmem_cache_free(ocm_piece_cache, pslot);
35228 +       }
35229 +
35230 +       return 0;
35231 +}
35232 +
35233 +/*
35234 + * ocm_inst_alloc()
35235 + *
35236 + *     allocates a block of size in the ocm instrction heap, if
35237 + *     successful returns address allocated.
35238 + */
35239 +void *ocm_inst_alloc(size_t size, pid_t pid)
35240 +{
35241 +       void *addr;
35242 +
35243 +       if (!OCM_INST_HEAP_LENGTH)
35244 +               return NULL;
35245 +
35246 +
35247 +       mutex_lock(&ocm_inst_heap.lock);
35248 +
35249 +       addr = _ocm_alloc(size, pid, &ocm_inst_heap);
35250 +
35251 +       mutex_unlock(&ocm_inst_heap.lock);
35252 +
35253 +       return addr;
35254 +}
35255 +EXPORT_SYMBOL(ocm_inst_alloc);
35256 +
35257 +/*
35258 + * ocm_inst_free()
35259 + *     free a block in the ocm instrction heap, returns 0 if successful.
35260 + */
35261 +int ocm_inst_free(const void *addr)
35262 +{
35263 +       int ret;
35264 +
35265 +       if (!OCM_INST_HEAP_LENGTH)
35266 +               return -1;
35267 +
35268 +       mutex_lock(&ocm_inst_heap.lock);
35269 +
35270 +       ret = _ocm_free(addr, &ocm_inst_heap);
35271 +
35272 +       mutex_unlock(&ocm_inst_heap.lock);
35273 +
35274 +       return ret;
35275 +}
35276 +EXPORT_SYMBOL(ocm_inst_free);
35277 +
35278 +/*
35279 + * ocm_free()
35280 + *     free a block in one of the ocm heaps, returns 0 if successful.
35281 + */
35282 +int ocm_free(const void *addr)
35283 +{
35284 +       if (addr >= (void *)OCM_INST_HEAP_BEGIN
35285 +                && addr < (void *)(OCM_INST_HEAP_END))
35286 +               return ocm_inst_free(addr);
35287 +       else
35288 +               return -1;
35289 +}
35290 +EXPORT_SYMBOL(ocm_free);
35291 +
35292 +
35293 +#ifdef CONFIG_PROC_FS
35294 +/* Need to keep line of output the same.  Currently, that is 46 bytes
35295 + * (including newline).
35296 + */
35297 +static int _ocm_proc_read(char *buf, int *len, int count, const char *desc,
35298 +                          struct ocm_heap *ocmheap)
35299 +{
35300 +       struct ocm_piece *pslot;
35301 +       struct ocm_piece *pfree_head = &ocmheap->free_head;
35302 +       struct ocm_piece *pused_head = &ocmheap->used_head;
35303 +
35304 +       /* The format is the following
35305 +        * --- OCM 123456789012345 Size   PID State     \n
35306 +        * 12345678-12345678 1234567890 12345 1234567890\n
35307 +        */
35308 +       int l;
35309 +       l = sprintf(&buf[*len], "--- OCM %-15s Size   PID State     \n",
35310 +                   desc);
35311 +
35312 +       *len += l;
35313 +       count -= l;
35314 +
35315 +       mutex_lock(&ocm_inst_heap.lock);
35316 +
35317 +       /*
35318 +        * search the relevant memory slot
35319 +        */
35320 +       pslot = pused_head->next;
35321 +
35322 +       while (pslot != NULL && count > 46) {
35323 +               l = sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
35324 +                            pslot->paddr, pslot->paddr + pslot->size,
35325 +                            pslot->size, pslot->pid, "ALLOCATED");
35326 +
35327 +               *len += l;
35328 +               count -= l;
35329 +               pslot = pslot->next;
35330 +       }
35331 +
35332 +       pslot = pfree_head->next;
35333 +
35334 +       while (pslot != NULL && count > 46) {
35335 +               l = sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
35336 +                           pslot->paddr, pslot->paddr + pslot->size,
35337 +                           pslot->size, pslot->pid, "FREE");
35338 +
35339 +               *len += l;
35340 +               count -= l;
35341 +               pslot = pslot->next;
35342 +       }
35343 +
35344 +       mutex_unlock(&ocm_inst_heap.lock);
35345 +
35346 +       return 0;
35347 +}
35348 +static int ocm_proc_read(char *buf, char **start, off_t offset, int count,
35349 +               int *eof, void *data)
35350 +{
35351 +       int len = 0;
35352 +
35353 +       if (_ocm_proc_read(buf, &len, count - len, "Inst Heap",
35354 +                           &ocm_inst_heap))
35355 +               goto not_done;
35356 +       *eof = 1;
35357 + not_done:
35358 +       return len;
35359 +}
35360 +
35361 +static int __init sram_proc_init(void)
35362 +{
35363 +       struct proc_dir_entry *ptr;
35364 +       ptr = create_proc_entry("ocm", S_IFREG | S_IRUGO, NULL);
35365 +       if (!ptr) {
35366 +               printk(KERN_WARNING "unable to create /proc/ocm\n");
35367 +               return -1;
35368 +       }
35369 +       ptr->owner = THIS_MODULE;
35370 +       ptr->read_proc = ocm_proc_read;
35371 +       return 0;
35372 +}
35373 +late_initcall(sram_proc_init);
35374 +#endif
35375 --- /dev/null
35376 +++ b/arch/ubicom32/oprofile/ipProf.h
35377 @@ -0,0 +1,39 @@
35378 +#ifndef __IP_PROF_H__
35379 +#define __IP_PROF_H__
35380 +
35381 +/* This number MUST match what is used in the ultra configuration! */
35382 +#define IPPROFILETIO_MAX_SAMPLES       600
35383 +
35384 +/* Move to .h file used in both; avoid special types  */
35385 +struct profile_sample {
35386 +       unsigned int    pc;             /* PC value */
35387 +       unsigned int    parent;         /* a5 contents, to find the caller */
35388 +       unsigned char   cond_codes;     /* for branch prediction */
35389 +       unsigned char   thread;         /* I-blocked, D-blocked,
35390 +                                          4-bit thread number */
35391 +       unsigned short  active;         /* which threads are active -
35392 +                                          for accurate counting */
35393 +       unsigned short  blocked;        /* which threads are blocked due to
35394 +                                          I or D cache misses */
35395 +       unsigned int    latency;        /* CPU clocks since the last message
35396 +                                          dispatch in this thread
35397 +                                          (thread 0 only for now) */
35398 +};
35399 +
35400 +
35401 +struct profilenode {
35402 +       struct devtree_node dn;
35403 +       volatile unsigned char enabled; /* Is the tio enabled to
35404 +                                          take samples? */
35405 +       volatile unsigned char busy;    /* set when the samples
35406 +                                          are being read */
35407 +       volatile unsigned int mask;     /* Threads that change the MT_EN flag */
35408 +       volatile unsigned short rate;   /* What is the sampling rate? */
35409 +       volatile unsigned short head;   /* sample taker puts samples here */
35410 +       volatile unsigned short tail;   /* packet filler takes samples here */
35411 +       volatile unsigned short count;  /* number of valid samples */
35412 +       volatile unsigned short total;  /* Total samples */
35413 +       struct profile_sample samples[IPPROFILETIO_MAX_SAMPLES];
35414 +};
35415 +
35416 +#endif
35417 --- /dev/null
35418 +++ b/arch/ubicom32/oprofile/Makefile
35419 @@ -0,0 +1,37 @@
35420 +#
35421 +# arch/ubicom32/Makefile
35422 +#       Makefile for Oprofile support on Ubicom32
35423 +#
35424 +# (C) Copyright 2009, Ubicom, Inc.
35425 +#
35426 +# This file is part of the Ubicom32 Linux Kernel Port.
35427 +#
35428 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
35429 +# it and/or modify it under the terms of the GNU General Public License
35430 +# as published by the Free Software Foundation, either version 2 of the
35431 +# License, or (at your option) any later version.
35432 +#
35433 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
35434 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
35435 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35436 +# the GNU General Public License for more details.
35437 +#
35438 +# You should have received a copy of the GNU General Public License
35439 +# along with the Ubicom32 Linux Kernel Port.  If not,
35440 +# see <http://www.gnu.org/licenses/>.
35441 +#
35442 +# Ubicom32 implementation derived from (with many thanks):
35443 +#   arch/m68knommu
35444 +#   arch/blackfin
35445 +#   arch/parisc
35446 +#
35447 +
35448 +obj-$(CONFIG_OPROFILE) += oprofile.o
35449 +
35450 +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
35451 +               oprof.o cpu_buffer.o buffer_sync.o \
35452 +               event_buffer.o oprofile_files.o \
35453 +               oprofilefs.o oprofile_stats.o \
35454 +               timer_int.o )
35455 +
35456 +oprofile-y     := $(DRIVER_OBJS) profile.o
35457 --- /dev/null
35458 +++ b/arch/ubicom32/oprofile/profile.c
35459 @@ -0,0 +1,221 @@
35460 +/*
35461 + * arch/ubicom32/oprofile/profile.c
35462 + *     Oprofile support for arch Ubicom32
35463 + *
35464 + * (C) Copyright 2009, Ubicom, Inc.
35465 + *
35466 + * This file is part of the Ubicom32 Linux Kernel Port.
35467 + *
35468 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35469 + * it and/or modify it under the terms of the GNU General Public License
35470 + * as published by the Free Software Foundation, either version 2 of the
35471 + * License, or (at your option)
35472 + * any later version.
35473 + *
35474 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it will
35475 + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
35476 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35477 + * General Public License for more details.
35478 + *
35479 + * You should have received a copy of the GNU General Public License
35480 + * along with the Ubicom32 Linux Kernel Port.  If not, see
35481 + * <http://www.gnu.org/licenses/>.
35482 + *
35483 + * Ubicom32 implementation derived from (with many thanks):
35484 + *   arch/m68knommu
35485 + *   arch/blackfin
35486 + *   arch/parisc
35487 + */
35488 +
35489 +/**
35490 + * @file profile.c
35491 + *
35492 + * @remark Copyright 2002 OProfile authors
35493 + * @remark Read the file COPYING
35494 + *
35495 + * @author Hunyue Yau <hy@hy-research.com>
35496 + */
35497 +
35498 +#include <linux/oprofile.h>
35499 +#include <linux/init.h>
35500 +#include <linux/errno.h>
35501 +#include <linux/interrupt.h>
35502 +#include <linux/module.h>
35503 +#include <linux/kernel.h>
35504 +
35505 +#include <asm/devtree.h>
35506 +#include <asm/thread.h>
35507 +
35508 +/* For identifying userland vs kernel address */
35509 +#include <asm/stacktrace.h>
35510 +#include "ipProf.h"
35511 +
35512 +/* For communications with the backend */
35513 +static struct profilenode *profile_node;
35514 +
35515 +/* Bitmask containing all Linux threads - as seen by the ROSR reg */
35516 +static unsigned long th_all_mask;
35517 +
35518 +/* Lookup table to translate a hardware thread into a CPU identifier
35519 + * Table is indexed by the ROSR value which is assumed to be
35520 + * relatively small (0...15).
35521 + */
35522 +unsigned int cpu_map[THREAD_ARCHITECTURAL_MAX];
35523 +
35524 +static struct pt_regs regs;
35525 +
35526 +/*
35527 + * For each sample returned, checked to see if they are relevant to
35528 + * us. This is necessary as the ubicom32 architecture has other software
35529 + * running outside of Linux. Only then, put the sample into the relevant
35530 + * cpu bins.
35531 + *
35532 + * To minimize overhead, a global mask with all possible threads of in
35533 + * interest to us is used as a first check. Then a second mask identifying
35534 + * the thread is used to obtain an identifier for that "CPU".
35535 + */
35536 +
35537 +/*
35538 + * ubicom32_build_cpu_th_mask()
35539 + *
35540 + * Build a lookup table for translation between hardware thread
35541 + * "ROSR" values and Linux CPU ids
35542 + *
35543 + * *** This gets executed on all CPUs at once! ***
35544 + */
35545 +static void ubicom32_build_cpu_th_mask(void *mask)
35546 +{
35547 +       thread_t self = thread_get_self();
35548 +       unsigned long *th_m = mask;
35549 +
35550 +       BUG_ON(self <= 0 || self >= THREAD_ARCHITECTURAL_MAX);
35551 +       cpu_map[self] = smp_processor_id();
35552 +
35553 +       set_bit(self, th_m);
35554 +}
35555 +
35556 +/*
35557 + * profile_interrupt()
35558 + *
35559 + * Process samples returned from the profiler backend. The backend
35560 + * may return samples that are irrelevant to us or may even return
35561 + * multiple samples for the same CPU. Note that the sames may be
35562 + * for ANY cpu. At this time, this is unique and to support this requires
35563 + * Oprofile to expose an interface to accept the CPU that the same came
35564 + * frome.
35565 + */
35566 +static irqreturn_t profile_interrupt(int irq, void *arg)
35567 +{
35568 +       int i, buf_entry;
35569 +       int is_kernel;
35570 +       unsigned int bit_th;
35571 +       unsigned int th;
35572 +
35573 +       if (!(profile_node->enabled) || profile_node->count < 0) {
35574 +               printk(KERN_WARNING
35575 +                       "Unexpected interrupt, no samples or not enabled!\n");
35576 +               return IRQ_HANDLED;
35577 +       }
35578 +
35579 +       profile_node->busy = 1;         /* Keep backend out */
35580 +
35581 +       for (i = 0; i < profile_node->count; i++) {
35582 +               buf_entry = profile_node->tail;
35583 +               profile_node->tail++;
35584 +               profile_node->tail %= IPPROFILETIO_MAX_SAMPLES;
35585 +
35586 +               /* Note - the "thread" ID is only the lower 4 bits */
35587 +               th = (0x0f & profile_node->samples[buf_entry].thread);
35588 +               bit_th = (1 << th);
35589 +
35590 +               if ((bit_th & th_all_mask) == 0)
35591 +                       continue;
35592 +
35593 +               regs.pc = profile_node->samples[buf_entry].pc;
35594 +
35595 +               is_kernel = ubicom32_is_kernel(regs.pc);
35596 +
35597 +               oprofile_add_ext_sample_cpu(regs.pc, &regs, 0, is_kernel,
35598 +                                           cpu_map[th]);
35599 +       }
35600 +       profile_node->count = 0;
35601 +       profile_node->busy = 0;
35602 +
35603 +       return IRQ_HANDLED;
35604 +}
35605 +
35606 +/*
35607 + * profile_start()
35608 + *
35609 + * Notification from oprofile to start the profiler
35610 + */
35611 +static int profile_start(void)
35612 +{
35613 +       if (!profile_node)
35614 +               return -1;
35615 +
35616 +       profile_node->enabled = 1;
35617 +
35618 +       return 0;
35619 +}
35620 +
35621 +/*
35622 + * profile_stop()
35623 + *
35624 + * Notification from oprofile to stop the profiler
35625 + */
35626 +static void profile_stop(void)
35627 +{
35628 +       if (profile_node)
35629 +               profile_node->enabled = 0;
35630 +}
35631 +
35632 +/*
35633 + * oprofile_arch_init()
35634 + *
35635 + * Attach to Oprofile after qualify the availability of the backend
35636 + * profiler support.
35637 + */
35638 +int __init oprofile_arch_init(struct oprofile_operations *ops)
35639 +{
35640 +       int r = -ENODEV;
35641 +
35642 +       profile_node = (struct profilenode *)devtree_find_node("profiler");
35643 +
35644 +       if (profile_node == NULL) {
35645 +               printk(KERN_WARNING "Cannot find profiler node\n");
35646 +               return r;
35647 +       }
35648 +
35649 +       r = request_irq(profile_node->dn.recvirq, profile_interrupt,
35650 +                       IRQF_DISABLED, "profiler", NULL);
35651 +
35652 +       if (r < 0) {
35653 +               profile_node = NULL;
35654 +               printk(KERN_WARNING "Cannot get profiler IRQ\n");
35655 +               return r;
35656 +       }
35657 +
35658 +       ops->start = profile_start;
35659 +       ops->stop = profile_stop;
35660 +       ops->cpu_type = "timer";
35661 +
35662 +       memset(cpu_map, 0, sizeof(cpu_map));
35663 +
35664 +       on_each_cpu(ubicom32_build_cpu_th_mask, &th_all_mask, 1);
35665 +
35666 +       memset(&regs, 0, sizeof(regs));
35667 +
35668 +       return r;
35669 +}
35670 +
35671 +/*
35672 + * oprofile_arch_exit()
35673 + *
35674 + * External call to take outselves out.
35675 + * Make sure backend is not running.
35676 + */
35677 +void oprofile_arch_exit(void)
35678 +{
35679 +       BUG_ON(profile_node->enabled);
35680 +}
35681 --- a/drivers/char/hw_random/Kconfig
35682 +++ b/drivers/char/hw_random/Kconfig
35683 @@ -134,3 +134,16 @@ config HW_RANDOM_VIRTIO
35684  
35685           To compile this driver as a module, choose M here: the
35686           module will be called virtio-rng.  If unsure, say N.
35687 +
35688 +config HW_RANDOM_UBICOM32
35689 +       tristate "Ubicom32 HW Random Number Generator support"
35690 +       depends on HW_RANDOM && UBICOM32
35691 +       default HW_RANDOM
35692 +       ---help---
35693 +         This driver provides kernel-side support for the Random Number
35694 +         Generator hardware found on Ubicom32 processors.
35695 +
35696 +         To compile this driver as a module, choose M here: the
35697 +         module will be called pasemi-rng.
35698 +
35699 +         If unsure, say Y.
35700 --- a/drivers/char/hw_random/Makefile
35701 +++ b/drivers/char/hw_random/Makefile
35702 @@ -14,3 +14,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx
35703  obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
35704  obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
35705  obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
35706 +obj-$(CONFIG_HW_RANDOM_UBICOM32) += ubicom32-rng.o
35707 --- /dev/null
35708 +++ b/drivers/char/hw_random/ubicom32-rng.c
35709 @@ -0,0 +1,105 @@
35710 +/*
35711 + * drivers/net/ubi32-eth.c
35712 + *   Ubicom32 hardware random number generator driver.
35713 + *
35714 + * (C) Copyright 2009, Ubicom, Inc.
35715 + *
35716 + * This file is part of the Ubicom32 Linux Kernel Port.
35717 + *
35718 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35719 + * it and/or modify it under the terms of the GNU General Public License
35720 + * as published by the Free Software Foundation, either version 2 of the
35721 + * License, or (at your option) any later version.
35722 + *
35723 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
35724 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
35725 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35726 + * the GNU General Public License for more details.
35727 + *
35728 + * You should have received a copy of the GNU General Public License
35729 + * along with the Ubicom32 Linux Kernel Port.  If not,
35730 + * see <http://www.gnu.org/licenses/>.
35731 + *
35732 + * Ubicom32 implementation derived from (with many thanks):
35733 + *   arch/m68knommu
35734 + *   arch/blackfin
35735 + *   arch/parisc
35736 + */
35737 +
35738 +#include <linux/kernel.h>
35739 +#include <linux/module.h>
35740 +#include <linux/hw_random.h>
35741 +#include <linux/delay.h>
35742 +#include <asm/io.h>
35743 +#include <asm/ip5000.h>
35744 +
35745 +#define MODULE_NAME "ubicom32_rng"
35746 +
35747 +static int ubicom32_rng_data_present(struct hwrng *rng, int wait)
35748 +{
35749 +       int data, i;
35750 +
35751 +       for (i = 0; i < 20; i++) {
35752 +               data = *(int *)(TIMER_BASE + TIMER_TRN);
35753 +               if (data || !wait)
35754 +                       break;
35755 +               udelay(10);
35756 +       }
35757 +       return data;
35758 +}
35759 +
35760 +static int ubicom32_rng_data_read(struct hwrng *rng, u32 *data)
35761 +{
35762 +       *data = *(int *)(TIMER_BASE + TIMER_TRN);
35763 +       return 4;
35764 +}
35765 +
35766 +static int ubicom32_rng_init(struct hwrng *rng)
35767 +{
35768 +       printk(KERN_INFO "ubicom32 rng init\n");
35769 +       *(int *)(TIMER_BASE + TIMER_TRN_CFG) = TIMER_TRN_CFG_ENABLE_OSC;
35770 +       return 0;
35771 +}
35772 +
35773 +static void ubicom32_rng_cleanup(struct hwrng *rng)
35774 +{
35775 +       printk(KERN_INFO "ubicom32 rng cleanup\n");
35776 +       *(int *)(TIMER_BASE + TIMER_TRN_CFG) = 0;
35777 +}
35778 +
35779 +static struct hwrng ubicom32_rng = {
35780 +       .name           = MODULE_NAME,
35781 +       .init           = ubicom32_rng_init,
35782 +       .cleanup        = ubicom32_rng_cleanup,
35783 +       .data_present   = ubicom32_rng_data_present,
35784 +       .data_read      = ubicom32_rng_data_read,
35785 +       .priv           = 0,
35786 +};
35787 +
35788 +static int __init mod_init(void)
35789 +{
35790 +       int err;
35791 +
35792 +       printk(KERN_INFO "ubicom32 rng started\n");
35793 +       err = hwrng_register(&ubicom32_rng);
35794 +       if (err) {
35795 +               printk(KERN_ERR "ubicom32 rng register failed (%d)\n",
35796 +                       err);
35797 +       }
35798 +
35799 +       return err;
35800 +}
35801 +
35802 +static void __exit mod_exit(void)
35803 +{
35804 +       printk(KERN_INFO "ubicom32 rng stopped\n");
35805 +       hwrng_unregister(&ubicom32_rng);
35806 +}
35807 +
35808 +module_init(mod_init);
35809 +module_exit(mod_exit);
35810 +
35811 +MODULE_LICENSE("GPL");
35812 +MODULE_AUTHOR("Ubicom, Inc.");
35813 +MODULE_DESCRIPTION("H/W rng driver for ubicom32 processor");
35814 +MODULE_VERSION("1:1.0.a");
35815 --- a/drivers/crypto/Kconfig
35816 +++ b/drivers/crypto/Kconfig
35817 @@ -61,6 +61,40 @@ config CRYPTO_DEV_GEODE
35818           To compile this driver as a module, choose M here: the module
35819           will be called geode-aes.
35820  
35821 +config CRYPTO_UBICOM32
35822 +        bool "Ubicom32 Security Module"
35823 +        depends on UBICOM32
35824 +        help
35825 +          This is the ubicom32 hardware acceleration common code.
35826 +
35827 +config CRYPTO_AES_UBICOM32
35828 +        tristate "Ubicom32 AES implementation"
35829 +        depends on CRYPTO_UBICOM32
35830 +        select CRYPTO_ALGAPI
35831 +        help
35832 +          This is the ubicom32 hardware AES implementation.
35833 +
35834 +config CRYPTO_DES_UBICOM32
35835 +        tristate "Ubicom32 DES implementation"
35836 +        depends on CRYPTO_UBICOM32
35837 +        select CRYPTO_ALGAPI
35838 +        help
35839 +          This is the ubicom32 hardware DES and 3DES implementation.
35840 +
35841 +config CRYPTO_SHA1_UBICOM32
35842 +        tristate "Ubicom32 SHA1 implementation"
35843 +        depends on CRYPTO_UBICOM32
35844 +        select CRYPTO_ALGAPI
35845 +        help
35846 +          This is the ubicom32 hardware SHA1 implementation.
35847 +
35848 +config CRYPTO_MD5_UBICOM32
35849 +        tristate "Ubicom32 MD5 implementation"
35850 +        depends on CRYPTO_UBICOM32
35851 +        select CRYPTO_ALGAPI
35852 +        help
35853 +          This is the ubicom32 hardware MD5 implementation.
35854 +
35855  config ZCRYPT
35856         tristate "Support for PCI-attached cryptographic adapters"
35857         depends on S390
35858 --- a/drivers/mmc/host/Kconfig
35859 +++ b/drivers/mmc/host/Kconfig
35860 @@ -193,6 +193,13 @@ config MMC_TMIO
35861           This provides support for the SD/MMC cell found in TC6393XB,
35862           T7L66XB and also ipaq ASIC3
35863  
35864 +config MMC_UBICOM32
35865 +       tristate "Ubicom32 MMC/SD host controller"
35866 +       depends on UBICOM32
35867 +       help
35868 +         This provides support for the SD/MMC hardware found on Ubicom32 
35869 +         IP7K processors
35870 +
35871  config GPIOMMC
35872         tristate "MMC/SD over GPIO-based SPI"
35873         depends on MMC && MMC_SPI && (SPI_GPIO || SPI_GPIO_OLD)
35874 --- a/drivers/mmc/host/Makefile
35875 +++ b/drivers/mmc/host/Makefile
35876 @@ -22,5 +22,6 @@ obj-$(CONFIG_MMC_SPI)         += mmc_spi.o
35877  obj-$(CONFIG_MMC_S3C)          += s3cmci.o
35878  obj-$(CONFIG_MMC_SDRICOH_CS)   += sdricoh_cs.o
35879  obj-$(CONFIG_MMC_TMIO)         += tmio_mmc.o
35880 +obj-$(CONFIG_MMC_UBICOM32)     += ubicom32sd.o
35881  obj-$(CONFIG_GPIOMMC)          += gpiommc.o
35882  
35883 --- /dev/null
35884 +++ b/drivers/mmc/host/ubicom32sd.c
35885 @@ -0,0 +1,774 @@
35886 +/*
35887 + * drivers/mmc/host/ubicom32sd.c
35888 + *     Ubicom32 Secure Digital Host Controller Interface driver
35889 + *
35890 + * (C) Copyright 2009, Ubicom, Inc.
35891 + *
35892 + * This file is part of the Ubicom32 Linux Kernel Port.
35893 + *
35894 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
35895 + * it and/or modify it under the terms of the GNU General Public License
35896 + * as published by the Free Software Foundation, either version 2 of the
35897 + * License, or (at your option) any later version.
35898 + *
35899 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
35900 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
35901 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
35902 + * the GNU General Public License for more details.
35903 + *
35904 + * You should have received a copy of the GNU General Public License
35905 + * along with the Ubicom32 Linux Kernel Port.  If not, 
35906 + * see <http://www.gnu.org/licenses/>.
35907 + */
35908 +
35909 +#include <linux/module.h>
35910 +#include <linux/platform_device.h>
35911 +#include <linux/delay.h>
35912 +#include <linux/scatterlist.h>
35913 +#include <linux/leds.h>
35914 +#include <linux/gpio.h>
35915 +#include <linux/mmc/host.h>
35916 +
35917 +#include <asm/ubicom32sd.h>
35918 +
35919 +#define DRIVER_NAME "ubicom32sd"
35920 +
35921 +#define sd_printk(...)
35922 +//#define sd_printk printk
35923 +
35924 +#define SDTIO_VP_VERSION       3
35925 +
35926 +#define SDTIO_MAX_SG_BLOCKS    16
35927 +
35928 +enum sdtio_commands {
35929 +       SDTIO_COMMAND_NOP,
35930 +       SDTIO_COMMAND_SETUP,
35931 +       SDTIO_COMMAND_SETUP_SDIO,
35932 +       SDTIO_COMMAND_EXECUTE,
35933 +       SDTIO_COMMAND_RESET,
35934 +};
35935 +
35936 +#define SDTIO_COMMAND_SHIFT                    24
35937 +#define SDTIO_COMMAND_FLAG_STOP_RSP_CRC                (1 << 10)
35938 +#define SDTIO_COMMAND_FLAG_STOP_RSP_136                (1 << 9)
35939 +#define SDTIO_COMMAND_FLAG_STOP_RSP            (1 << 8)
35940 +#define SDTIO_COMMAND_FLAG_STOP_CMD            (1 << 7)
35941 +#define SDTIO_COMMAND_FLAG_DATA_STREAM         (1 << 6)
35942 +#define SDTIO_COMMAND_FLAG_DATA_RD             (1 << 5)
35943 +#define SDTIO_COMMAND_FLAG_DATA_WR             (1 << 4)
35944 +#define SDTIO_COMMAND_FLAG_CMD_RSP_CRC         (1 << 3)
35945 +#define SDTIO_COMMAND_FLAG_CMD_RSP_136         (1 << 2)
35946 +#define SDTIO_COMMAND_FLAG_CMD_RSP             (1 << 1)
35947 +#define SDTIO_COMMAND_FLAG_CMD                 (1 << 0)
35948 +
35949 +/*
35950 + * SDTIO_COMMAND_SETUP_SDIO
35951 + */
35952 +#define SDTIO_COMMAND_FLAG_SDIO_INT_EN         (1 << 0)
35953 +
35954 +/*
35955 + * SDTIO_COMMAND_SETUP
35956 + *      clock speed in arg
35957 + */
35958 +#define SDTIO_COMMAND_FLAG_4BIT                 (1 << 3)
35959 +#define SDTIO_COMMAND_FLAG_1BIT                 (1 << 2)
35960 +#define SDTIO_COMMAND_FLAG_SET_CLOCK            (1 << 1)
35961 +#define SDTIO_COMMAND_FLAG_SET_WIDTH            (1 << 0)
35962 +
35963 +#define SDTIO_COMMAND_FLAG_CMD_RSP_MASK                (SDTIO_COMMAND_FLAG_CMD_RSP | SDTIO_COMMAND_FLAG_CMD_RSP_136)
35964 +#define SDTIO_COMMAND_FLAG_STOP_RSP_MASK       (SDTIO_COMMAND_FLAG_STOP_RSP | SDTIO_COMMAND_FLAG_STOP_RSP_136)
35965 +#define SDTIO_COMMAND_FLAG_RSP_MASK            (SDTIO_COMMAND_FLAG_CMD_RSP_MASK | SDTIO_COMMAND_FLAG_STOP_RSP_MASK)
35966 +
35967 +struct sdtio_vp_sg {
35968 +       volatile void           *addr;
35969 +       volatile u32_t          len;
35970 +};
35971 +
35972 +#define SDTIO_VP_INT_STATUS_DONE               (1 << 31)
35973 +#define SDTIO_VP_INT_STATUS_SDIO_INT           (1 << 10)
35974 +#define SDTIO_VP_INT_STATUS_DATA_CRC_ERR       (1 << 9)
35975 +#define SDTIO_VP_INT_STATUS_DATA_PROG_ERR      (1 << 8)
35976 +#define SDTIO_VP_INT_STATUS_DATA_TIMEOUT       (1 << 7)
35977 +#define SDTIO_VP_INT_STATUS_STOP_RSP_CRC       (1 << 6)
35978 +#define SDTIO_VP_INT_STATUS_STOP_RSP_TIMEOUT   (1 << 5)
35979 +#define SDTIO_VP_INT_STATUS_CMD_RSP_CRC                (1 << 4)
35980 +#define SDTIO_VP_INT_STATUS_CMD_RSP_TIMEOUT    (1 << 3)
35981 +#define SDTIO_VP_INT_STATUS_CMD_TIMEOUT                (1 << 2)
35982 +#define SDTIO_VP_INT_STATUS_CARD1_INSERT       (1 << 1)
35983 +#define SDTIO_VP_INT_STATUS_CARD0_INSERT       (1 << 0)
35984 +
35985 +struct sdtio_vp_regs {
35986 +       u32_t                           version;
35987 +       u32_t                           f_max;
35988 +       u32_t                           f_min;
35989 +
35990 +       volatile u32_t                  int_status;
35991 +
35992 +       volatile u32_t                  command;
35993 +       volatile u32_t                  arg;
35994 +
35995 +       volatile u32_t                  cmd_opcode;
35996 +       volatile u32_t                  cmd_arg;
35997 +       volatile u32_t                  cmd_rsp0;
35998 +       volatile u32_t                  cmd_rsp1;
35999 +       volatile u32_t                  cmd_rsp2;
36000 +       volatile u32_t                  cmd_rsp3;
36001 +
36002 +       volatile u32_t                  stop_opcode;
36003 +       volatile u32_t                  stop_arg;
36004 +       volatile u32_t                  stop_rsp0;
36005 +       volatile u32_t                  stop_rsp1;
36006 +       volatile u32_t                  stop_rsp2;
36007 +       volatile u32_t                  stop_rsp3;
36008 +
36009 +       volatile u32_t                  data_timeout_ns;
36010 +       volatile u16_t                  data_blksz;
36011 +       volatile u16_t                  data_blkct;
36012 +       volatile u32_t                  data_bytes_transferred;
36013 +       volatile u32_t                  sg_len;
36014 +       struct sdtio_vp_sg              sg[SDTIO_MAX_SG_BLOCKS];
36015 +};
36016 +
36017 +struct ubicom32sd_data {
36018 +       const struct ubicom32sd_platform_data   *pdata;
36019 +
36020 +       struct mmc_host                         *mmc;
36021 +
36022 +       /*
36023 +        * Lock used to protect the data structure
36024 +       spinlock_t                              lock;
36025 +        */
36026 +       int     int_en;
36027 +       int     int_pend;
36028 +
36029 +       /*
36030 +        * Receive and transmit interrupts used for communicating 
36031 +        * with hardware
36032 +        */
36033 +       int                                     irq_tx;
36034 +       int                                     irq_rx;
36035 +
36036 +       /*
36037 +        * Current outstanding mmc request
36038 +        */
36039 +       struct mmc_request                      *mrq;
36040 +
36041 +       /*
36042 +        * Hardware registers
36043 +        */
36044 +       struct sdtio_vp_regs                    *regs;
36045 +};
36046 +
36047 +/*****************************************************************************\
36048 + *                                                                           *
36049 + * Suspend/resume                                                            *
36050 + *                                                                           *
36051 +\*****************************************************************************/
36052 +
36053 +#if 0//def CONFIG_PM
36054 +
36055 +int ubicom32sd_suspend_host(struct ubicom32sd_host *host, pm_message_t state)
36056 +{
36057 +       int ret;
36058 +
36059 +       ret = mmc_suspend_host(host->mmc, state);
36060 +       if (ret)
36061 +               return ret;
36062 +
36063 +       free_irq(host->irq, host);
36064 +
36065 +       return 0;
36066 +}
36067 +
36068 +EXPORT_SYMBOL_GPL(ubicom32sd_suspend_host);
36069 +
36070 +int ubicom32sd_resume_host(struct ubicom32sd_host *host)
36071 +{
36072 +       int ret;
36073 +
36074 +       if (host->flags & UBICOM32SD_USE_DMA) {
36075 +               if (host->ops->enable_dma)
36076 +                       host->ops->enable_dma(host);
36077 +       }
36078 +
36079 +       ret = request_irq(host->irq, ubicom32sd_irq, IRQF_SHARED,
36080 +                         mmc_hostname(host->mmc), host);
36081 +       if (ret)
36082 +               return ret;
36083 +
36084 +       ubicom32sd_init(host);
36085 +       mmiowb();
36086 +
36087 +       ret = mmc_resume_host(host->mmc);
36088 +       if (ret)
36089 +               return ret;
36090 +
36091 +       return 0;
36092 +}
36093 +
36094 +EXPORT_SYMBOL_GPL(ubicom32sd_resume_host);
36095 +
36096 +#endif /* CONFIG_PM */
36097 +
36098 +/*
36099 + * ubicom32sd_send_command_sync
36100 + */
36101 +static void ubicom32sd_send_command_sync(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
36102 +{
36103 +       ud->regs->command = command;
36104 +       ud->regs->arg = arg;
36105 +       ubicom32_set_interrupt(ud->irq_tx);
36106 +       while (ud->regs->command) {
36107 +               ndelay(100);
36108 +       }
36109 +}
36110 +
36111 +/*
36112 + * ubicom32sd_send_command
36113 + */
36114 +static void ubicom32sd_send_command(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
36115 +{
36116 +       ud->regs->command = command;
36117 +       ud->regs->arg = arg;
36118 +       ubicom32_set_interrupt(ud->irq_tx);
36119 +}
36120 +
36121 +/*
36122 + * ubicom32sd_reset
36123 + */
36124 +static void ubicom32sd_reset(struct ubicom32sd_data *ud)
36125 +{
36126 +       ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_RESET << SDTIO_COMMAND_SHIFT, 0);
36127 +       ud->regs->int_status = 0;
36128 +}
36129 +
36130 +/*
36131 + * ubicom32sd_mmc_request
36132 + */
36133 +static void ubicom32sd_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
36134 +{
36135 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36136 +       u32_t command = SDTIO_COMMAND_EXECUTE << SDTIO_COMMAND_SHIFT;
36137 +       int ret = 0;
36138 +
36139 +       WARN(ud->mrq != NULL, "ud->mrq still set to %p\n", ud->mrq);
36140 +       //pr_debug("send cmd %08x arg %08x flags %08x\n", cmd->opcode, cmd->arg, cmd->flags);
36141 +
36142 +       if (mrq->cmd) {
36143 +               struct mmc_command *cmd = mrq->cmd;
36144 +
36145 +               sd_printk("%s:\t\t\tsetup cmd %02d arg %08x flags %08x\n", mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags);
36146 +
36147 +               ud->regs->cmd_opcode = cmd->opcode;
36148 +               ud->regs->cmd_arg = cmd->arg;
36149 +
36150 +               command |= SDTIO_COMMAND_FLAG_CMD;
36151 +
36152 +               if (cmd->flags & MMC_RSP_PRESENT) {
36153 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP;
36154 +               }
36155 +
36156 +               if (cmd->flags & MMC_RSP_136) {
36157 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP_136;
36158 +               }
36159 +
36160 +               if (cmd->flags & MMC_RSP_CRC) {
36161 +                       command |= SDTIO_COMMAND_FLAG_CMD_RSP_CRC;
36162 +               }
36163 +       }
36164 +
36165 +       if (mrq->data) {
36166 +               struct mmc_data *data = mrq->data;
36167 +               struct scatterlist *sg = data->sg;
36168 +               int i;
36169 +
36170 +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);
36171 +
36172 +               sd_printk("%s:\t\t\tsetup data blksz %d num %d sglen=%d fl=%08x Tns=%u\n", 
36173 +                         mmc_hostname(mmc), data->blksz, data->blocks, data->sg_len, 
36174 +                         data->flags, data->timeout_ns);
36175 +
36176 +               if (data->sg_len > SDTIO_MAX_SG_BLOCKS) {
36177 +                       ret = -EINVAL;
36178 +                       data->error = -EINVAL;
36179 +                       goto fail;
36180 +               } 
36181 +
36182 +               ud->regs->data_timeout_ns = data->timeout_ns;
36183 +               ud->regs->data_blksz = data->blksz;
36184 +               ud->regs->data_blkct = data->blocks;
36185 +               ud->regs->sg_len = data->sg_len;
36186 +
36187 +               /*
36188 +                * Load all of our sg list into the driver sg buffer
36189 +                */
36190 +               for (i = 0; i < data->sg_len; i++) {
36191 +                       sd_printk("%s: sg %d = %p %d\n", mmc_hostname(mmc), i, sg_virt(sg), sg->length);
36192 +                       ud->regs->sg[i].addr = sg_virt(sg);
36193 +                       ud->regs->sg[i].len = sg->length;
36194 +                       if (((u32_t)ud->regs->sg[i].addr & 0x03) || (sg->length & 0x03)) {
36195 +                               sd_printk("%s: Need aligned buffers\n", mmc_hostname(mmc));
36196 +                               ret = -EINVAL;
36197 +                               data->error = -EINVAL;
36198 +                               goto fail;
36199 +                       }
36200 +                       sg++;
36201 +               }
36202 +               if (data->flags & MMC_DATA_READ) {
36203 +                       command |= SDTIO_COMMAND_FLAG_DATA_RD;
36204 +               } else if (data->flags & MMC_DATA_WRITE) {
36205 +                       command |= SDTIO_COMMAND_FLAG_DATA_WR;
36206 +               } else if (data->flags & MMC_DATA_STREAM) {
36207 +                       command |= SDTIO_COMMAND_FLAG_DATA_STREAM;
36208 +               }
36209 +       }
36210 +
36211 +       if (mrq->stop) {
36212 +               struct mmc_command *stop = mrq->stop;
36213 +               sd_printk("%s: \t\t\tsetup stop %02d arg %08x flags %08x\n", mmc_hostname(mmc), stop->opcode, stop->arg, stop->flags);
36214 +
36215 +               ud->regs->stop_opcode = stop->opcode;
36216 +               ud->regs->stop_arg = stop->arg;
36217 +
36218 +               command |= SDTIO_COMMAND_FLAG_STOP_CMD;
36219 +
36220 +               if (stop->flags & MMC_RSP_PRESENT) {
36221 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP;
36222 +               }
36223 +
36224 +               if (stop->flags & MMC_RSP_136) {
36225 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP_136;
36226 +               }
36227 +
36228 +               if (stop->flags & MMC_RSP_CRC) {
36229 +                       command |= SDTIO_COMMAND_FLAG_STOP_RSP_CRC;
36230 +               }
36231 +       }
36232 +
36233 +       ud->mrq = mrq;
36234 +
36235 +       sd_printk("%s: Sending command %08x\n", mmc_hostname(mmc), command);
36236 +
36237 +       ubicom32sd_send_command(ud, command, 0);
36238 +
36239 +       return;
36240 +fail:
36241 +       sd_printk("%s: mmcreq ret = %d\n", mmc_hostname(mmc), ret);
36242 +       mrq->cmd->error = ret;
36243 +       mmc_request_done(mmc, mrq);
36244 +}
36245 +
36246 +/*
36247 + * ubicom32sd_mmc_set_ios
36248 + */
36249 +static void ubicom32sd_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
36250 +{
36251 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36252 +       u32_t command = SDTIO_COMMAND_SETUP << SDTIO_COMMAND_SHIFT;
36253 +       u32_t arg = 0;
36254 +       sd_printk("%s: ios call bw:%u pm:%u clk:%u\n", mmc_hostname(mmc), 1 << ios->bus_width, ios->power_mode, ios->clock);
36255 +
36256 +       switch (ios->bus_width) {
36257 +       case MMC_BUS_WIDTH_1:
36258 +               command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_1BIT;
36259 +               break;
36260 +
36261 +       case MMC_BUS_WIDTH_4:
36262 +               command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_4BIT;
36263 +               break;
36264 +       }
36265 +
36266 +       if (ios->clock) {
36267 +               arg = ios->clock;
36268 +               command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
36269 +       }
36270 +
36271 +       switch (ios->power_mode) {
36272 +
36273 +       /*
36274 +        * Turn off the SD bus (power + clock)
36275 +        */
36276 +       case MMC_POWER_OFF:
36277 +               gpio_set_value(ud->pdata->cards[0].pin_pwr, !ud->pdata->cards[0].pwr_polarity);
36278 +               command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
36279 +               break;
36280 +
36281 +       /*
36282 +        * Turn on the power to the SD bus
36283 +        */
36284 +       case MMC_POWER_ON:
36285 +               gpio_set_value(ud->pdata->cards[0].pin_pwr, ud->pdata->cards[0].pwr_polarity);
36286 +               break;
36287 +
36288 +       /*
36289 +        * Turn on the clock to the SD bus
36290 +        */
36291 +       case MMC_POWER_UP:
36292 +               /*
36293 +                * Done above
36294 +                */
36295 +               break;
36296 +       }
36297 +
36298 +       ubicom32sd_send_command_sync(ud, command, arg);
36299 +
36300 +       /*
36301 +        * Let the power settle down
36302 +        */
36303 +       udelay(500);
36304 +}
36305 +
36306 +/*
36307 + * ubicom32sd_mmc_get_cd
36308 + */
36309 +static int ubicom32sd_mmc_get_cd(struct mmc_host *mmc)
36310 +{
36311 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36312 +       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));
36313 +
36314 +       return gpio_get_value(ud->pdata->cards[0].pin_cd) ? 
36315 +                               ud->pdata->cards[0].cd_polarity : 
36316 +                               !ud->pdata->cards[0].cd_polarity;
36317 +}
36318 +
36319 +/*
36320 + * ubicom32sd_mmc_get_ro
36321 + */
36322 +static int ubicom32sd_mmc_get_ro(struct mmc_host *mmc)
36323 +{
36324 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36325 +       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));
36326 +
36327 +       return gpio_get_value(ud->pdata->cards[0].pin_wp) ? 
36328 +                               ud->pdata->cards[0].wp_polarity :
36329 +                               !ud->pdata->cards[0].wp_polarity;
36330 +}
36331 +
36332 +/*
36333 + * ubicom32sd_mmc_enable_sdio_irq
36334 + */
36335 +static void ubicom32sd_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
36336 +{
36337 +       struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36338 +
36339 +       ud->int_en = enable;
36340 +       if (enable && ud->int_pend) {
36341 +               ud->int_pend = 0;
36342 +               mmc_signal_sdio_irq(mmc);
36343 +       }
36344 +}
36345 +
36346 +/*
36347 + * ubicom32sd_interrupt
36348 + */
36349 +static irqreturn_t ubicom32sd_interrupt(int irq, void *dev)
36350 +{
36351 +       struct mmc_host *mmc = (struct mmc_host *)dev;
36352 +       struct mmc_request *mrq;
36353 +       struct ubicom32sd_data *ud;
36354 +       u32_t int_status;
36355 +
36356 +       if (!mmc) {
36357 +               return IRQ_HANDLED;
36358 +       }
36359 +
36360 +       ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36361 +       if (!ud) {
36362 +               return IRQ_HANDLED;
36363 +       }
36364 +
36365 +       int_status = ud->regs->int_status;
36366 +       ud->regs->int_status &= ~int_status;
36367 +
36368 +       if (int_status & SDTIO_VP_INT_STATUS_SDIO_INT) {
36369 +               if (ud->int_en) {
36370 +                       ud->int_pend = 0;
36371 +                       mmc_signal_sdio_irq(mmc);
36372 +               } else {
36373 +                       ud->int_pend++;
36374 +               }
36375 +       }
36376 +
36377 +       if (!(int_status & SDTIO_VP_INT_STATUS_DONE)) {
36378 +               return IRQ_HANDLED;
36379 +       }
36380 +
36381 +       mrq = ud->mrq;
36382 +       if (!mrq) {
36383 +               sd_printk("%s: Spurious interrupt", mmc_hostname(mmc));
36384 +               return IRQ_HANDLED;
36385 +       }
36386 +       ud->mrq = NULL;
36387 +
36388 +       /*
36389 +        * SDTIO_VP_INT_DONE
36390 +        */
36391 +       if (mrq->cmd->flags & MMC_RSP_PRESENT) {
36392 +               struct mmc_command *cmd = mrq->cmd;
36393 +               cmd->error = 0;
36394 +
36395 +               if ((cmd->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_CRC)) {
36396 +                       cmd->error = -EILSEQ;
36397 +               } else if (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_TIMEOUT) {
36398 +                       cmd->error = -ETIMEDOUT;
36399 +                       goto done;
36400 +               } else if (cmd->flags & MMC_RSP_136) {
36401 +                       cmd->resp[0] = ud->regs->cmd_rsp0;
36402 +                       cmd->resp[1] = ud->regs->cmd_rsp1;
36403 +                       cmd->resp[2] = ud->regs->cmd_rsp2;
36404 +                       cmd->resp[3] = ud->regs->cmd_rsp3;
36405 +               } else {
36406 +                       cmd->resp[0] = ud->regs->cmd_rsp0;
36407 +               }
36408 +               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);
36409 +       }
36410 +
36411 +       if (mrq->data) {
36412 +               struct mmc_data *data = mrq->data;
36413 +
36414 +               if (int_status & SDTIO_VP_INT_STATUS_DATA_TIMEOUT) {
36415 +                       data->error = -ETIMEDOUT;
36416 +                       sd_printk("%s:\t\t\tData Timeout\n", mmc_hostname(mmc));
36417 +                       goto done;
36418 +               } else if (int_status & SDTIO_VP_INT_STATUS_DATA_CRC_ERR) {
36419 +                       data->error = -EILSEQ;
36420 +                       sd_printk("%s:\t\t\tData CRC\n", mmc_hostname(mmc));
36421 +                       goto done;
36422 +               } else if (int_status & SDTIO_VP_INT_STATUS_DATA_PROG_ERR) {
36423 +                       data->error = -EILSEQ;
36424 +                       sd_printk("%s:\t\t\tData Program Error\n", mmc_hostname(mmc));
36425 +                       goto done;
36426 +               } else {
36427 +                       data->error = 0;
36428 +                       data->bytes_xfered = ud->regs->data_bytes_transferred;
36429 +               }
36430 +       }
36431 +
36432 +       if (mrq->stop && (mrq->stop->flags & MMC_RSP_PRESENT)) {
36433 +               struct mmc_command *stop = mrq->stop;
36434 +               stop->error = 0;
36435 +
36436 +               if ((stop->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_CRC)) {
36437 +                       stop->error = -EILSEQ;
36438 +               } else if (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_TIMEOUT) {
36439 +                       stop->error = -ETIMEDOUT;
36440 +                       goto done;
36441 +               } else if (stop->flags & MMC_RSP_136) {
36442 +                       stop->resp[0] = ud->regs->stop_rsp0;
36443 +                       stop->resp[1] = ud->regs->stop_rsp1;
36444 +                       stop->resp[2] = ud->regs->stop_rsp2;
36445 +                       stop->resp[3] = ud->regs->stop_rsp3;
36446 +               } else {
36447 +                       stop->resp[0] = ud->regs->stop_rsp0;
36448 +               }
36449 +               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);
36450 +       }
36451 +
36452 +done:
36453 +       mmc_request_done(mmc, mrq);
36454 +
36455 +       return IRQ_HANDLED;
36456 +}
36457 +
36458 +static struct mmc_host_ops ubicom32sd_ops = {
36459 +       .request                = ubicom32sd_mmc_request,
36460 +       .set_ios                = ubicom32sd_mmc_set_ios,
36461 +       .get_ro                 = ubicom32sd_mmc_get_ro,
36462 +       .get_cd                 = ubicom32sd_mmc_get_cd,
36463 +       .enable_sdio_irq        = ubicom32sd_mmc_enable_sdio_irq,
36464 +};
36465 +
36466 +/*
36467 + * ubicom32sd_probe
36468 + */
36469 +static int __devinit ubicom32sd_probe(struct platform_device *pdev)
36470 +{
36471 +       struct ubicom32sd_platform_data *pdata = (struct ubicom32sd_platform_data *)pdev->dev.platform_data;
36472 +       struct mmc_host *mmc;
36473 +       struct ubicom32sd_data *ud;
36474 +       struct resource *res_regs;
36475 +       struct resource *res_irq_tx;
36476 +       struct resource *res_irq_rx;
36477 +       int ret;
36478 +
36479 +       /*
36480 +        * Get our resources, regs is the hardware driver base address
36481 +        * and the tx and rx irqs are used to communicate with the 
36482 +        * hardware driver.
36483 +        */
36484 +       res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
36485 +       res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
36486 +       res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
36487 +       if (!res_regs || !res_irq_tx || !res_irq_rx) {
36488 +               ret = -EINVAL;
36489 +               goto fail;
36490 +       }
36491 +
36492 +       /*
36493 +        * Reserve any gpios we need
36494 +        */
36495 +       ret = gpio_request(pdata->cards[0].pin_wp, "sd-wp");
36496 +       if (ret) {
36497 +               goto fail;
36498 +       }
36499 +       gpio_direction_input(pdata->cards[0].pin_wp);
36500 +
36501 +       ret = gpio_request(pdata->cards[0].pin_cd, "sd-cd");
36502 +       if (ret) {
36503 +               goto fail_cd;
36504 +       }
36505 +       gpio_direction_input(pdata->cards[0].pin_cd);
36506 +
36507 +       /*
36508 +        * HACK: for the dual port controller on port F, we don't support the second port right now
36509 +        */
36510 +       if (pdata->ncards > 1) {
36511 +               ret = gpio_request(pdata->cards[1].pin_pwr, "sd-pwr");
36512 +               gpio_direction_output(pdata->cards[1].pin_pwr, !pdata->cards[1].pwr_polarity);
36513 +               gpio_direction_output(pdata->cards[1].pin_pwr, pdata->cards[1].pwr_polarity);
36514 +       }
36515 +
36516 +       ret = gpio_request(pdata->cards[0].pin_pwr, "sd-pwr");
36517 +       if (ret) {
36518 +               goto fail_pwr;
36519 +       }
36520 +       gpio_direction_output(pdata->cards[0].pin_pwr, !pdata->cards[0].pwr_polarity);
36521 +
36522 +       /*
36523 +        * Allocate the MMC driver, it includes memory for our data.
36524 +        */
36525 +       mmc = mmc_alloc_host(sizeof(struct ubicom32sd_data), &pdev->dev);
36526 +       if (!mmc) {
36527 +               ret = -ENOMEM;
36528 +               goto fail_mmc;
36529 +       }
36530 +       ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36531 +       ud->mmc = mmc;
36532 +       ud->pdata = pdata;
36533 +       ud->regs = (struct sdtio_vp_regs *)res_regs->start;
36534 +       ud->irq_tx = res_irq_tx->start;
36535 +       ud->irq_rx = res_irq_rx->start;
36536 +       platform_set_drvdata(pdev, mmc);
36537 +
36538 +       ret = request_irq(ud->irq_rx, ubicom32sd_interrupt, IRQF_DISABLED, mmc_hostname(mmc), mmc);
36539 +       if (ret) {
36540 +               goto fail_mmc;
36541 +       }
36542 +
36543 +       /*
36544 +        * Fill in the mmc structure
36545 +        */
36546 +       mmc->ops = &ubicom32sd_ops;
36547 +       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ |
36548 +                   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
36549 +
36550 +       mmc->f_min = ud->regs->f_min;
36551 +       mmc->f_max = ud->regs->f_max;
36552 +       mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
36553 +
36554 +       /*
36555 +        * Setup some restrictions on transfers
36556 +        *
36557 +        * We allow up to SDTIO_MAX_SG_BLOCKS of data to DMA into, there are
36558 +        * not really any "max_seg_size", "max_req_size", or "max_blk_count"
36559 +        * restrictions (must be less than U32_MAX though), pick
36560 +        * something large?!...
36561 +        *
36562 +        * The hardware can do up to 4095 bytes per block, since the spec
36563 +        * only requires 2048, we'll set it to that and not worry about
36564 +        * potential weird blk lengths.
36565 +        */
36566 +       mmc->max_hw_segs = SDTIO_MAX_SG_BLOCKS;
36567 +       mmc->max_phys_segs = SDTIO_MAX_SG_BLOCKS;
36568 +       mmc->max_seg_size = 1024 * 1024;
36569 +       mmc->max_req_size = 1024 * 1024;
36570 +       mmc->max_blk_count = 1024;
36571 +
36572 +       mmc->max_blk_size = 2048;
36573 +
36574 +       ubicom32sd_reset(ud);
36575 +
36576 +       /*
36577 +        * enable interrupts
36578 +        */
36579 +       ud->int_en = 0;
36580 +       ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_SETUP_SDIO << SDTIO_COMMAND_SHIFT | SDTIO_COMMAND_FLAG_SDIO_INT_EN, 0);
36581 +
36582 +       mmc_add_host(mmc);
36583 +
36584 +       printk(KERN_INFO "%s at %p, irq %d/%d\n", mmc_hostname(mmc),
36585 +                       ud->regs, ud->irq_tx, ud->irq_rx);
36586 +       return 0;
36587 +
36588 +fail_mmc:
36589 +       gpio_free(pdata->cards[0].pin_pwr);
36590 +fail_pwr:
36591 +       gpio_free(pdata->cards[0].pin_cd);
36592 +fail_cd:
36593 +       gpio_free(pdata->cards[0].pin_wp);
36594 +fail:
36595 +       return ret;
36596 +}
36597 +
36598 +/*
36599 + * ubicom32sd_remove
36600 + */
36601 +static int __devexit ubicom32sd_remove(struct platform_device *pdev)
36602 +{
36603 +       struct mmc_host *mmc = platform_get_drvdata(pdev);
36604 +
36605 +       platform_set_drvdata(pdev, NULL);
36606 +
36607 +       if (mmc) {
36608 +               struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36609 +
36610 +               gpio_free(ud->pdata->cards[0].pin_pwr);
36611 +               gpio_free(ud->pdata->cards[0].pin_cd);
36612 +               gpio_free(ud->pdata->cards[0].pin_wp);
36613 +
36614 +               mmc_remove_host(mmc);
36615 +               mmc_free_host(mmc);
36616 +       }
36617 +
36618 +       /*
36619 +        * Note that our data is allocated as part of the mmc structure
36620 +        * so we don't need to free it.
36621 +        */
36622 +       return 0;
36623 +}
36624 +
36625 +static struct platform_driver ubicom32sd_driver = {
36626 +       .driver = {
36627 +               .name = DRIVER_NAME,
36628 +               .owner = THIS_MODULE,
36629 +       },
36630 +       .probe = ubicom32sd_probe,
36631 +       .remove = __devexit_p(ubicom32sd_remove),
36632 +#if 0
36633 +       .suspend = ubicom32sd_suspend,
36634 +       .resume = ubicom32sd_resume,
36635 +#endif
36636 +};
36637 +
36638 +/*
36639 + * ubicom32sd_init
36640 + */
36641 +static int __init ubicom32sd_init(void)
36642 +{
36643 +       return platform_driver_register(&ubicom32sd_driver);
36644 +}
36645 +module_init(ubicom32sd_init);
36646 +
36647 +/*
36648 + * ubicom32sd_exit
36649 + */
36650 +static void __exit ubicom32sd_exit(void)
36651 +{
36652 +    platform_driver_unregister(&ubicom32sd_driver);
36653 +}
36654 +module_exit(ubicom32sd_exit);
36655 +
36656 +MODULE_AUTHOR("Patrick Tjin");
36657 +MODULE_DESCRIPTION("Ubicom32 Secure Digital Host Controller Interface driver");
36658 +MODULE_LICENSE("GPL");
36659 +
36660 --- a/drivers/mtd/devices/Kconfig
36661 +++ b/drivers/mtd/devices/Kconfig
36662 @@ -104,6 +104,17 @@ config M25PXX_USE_FAST_READ
36663         help
36664           This option enables FAST_READ access supported by ST M25Pxx.
36665  
36666 +config MTD_UBI32_M25P80
36667 +       tristate "Ubicom processor support for most SPI Flash chips (AT26DF, M25P, W25X, ...)"
36668 +       depends on UBICOM32
36669 +       default y
36670 +       help
36671 +         This enables access to most modern SPI flash chips, used for
36672 +         program and data storage.   Series supported include Atmel AT26DF,
36673 +         Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X.  Other chips
36674 +         are supported as well.  See the driver source for the current list,
36675 +         or to add other chips.
36676 +
36677  config MTD_SLRAM
36678         tristate "Uncached system RAM"
36679         help
36680 --- a/drivers/mtd/devices/Makefile
36681 +++ b/drivers/mtd/devices/Makefile
36682 @@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_LART)                += lart.o
36683  obj-$(CONFIG_MTD_BLOCK2MTD)    += block2mtd.o
36684  obj-$(CONFIG_MTD_DATAFLASH)    += mtd_dataflash.o
36685  obj-$(CONFIG_MTD_M25P80)       += m25p80.o
36686 +obj-$(CONFIG_MTD_UBI32_M25P80) += ubi32-m25p80.o
36687 --- /dev/null
36688 +++ b/drivers/mtd/devices/ubi32-m25p80.c
36689 @@ -0,0 +1,1066 @@
36690 +/*
36691 + * drivers/mtd/devices/ubi32-m25p80.c
36692 + *   NOR flash driver, Ubicom processor internal SPI flash interface.
36693 + *
36694 + *   This code instantiates the serial flash that contains the
36695 + *   original bootcode.  The serial flash start at address 0x60000000
36696 + *   in both Ubicom32V3 and Ubicom32V4 ISAs.
36697 + *
36698 + *   This piece of flash is made to appear as a Memory Technology
36699 + *   Device (MTD) with this driver to allow Read/Write/Erase operations.
36700 + *
36701 + * (C) Copyright 2009, Ubicom, Inc.
36702 + *
36703 + * This file is part of the Ubicom32 Linux Kernel Port.
36704 + *
36705 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
36706 + * it and/or modify it under the terms of the GNU General Public License
36707 + * as published by the Free Software Foundation, either version 2 of the
36708 + * License, or (at your option) any later version.
36709 + *
36710 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
36711 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
36712 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
36713 + * the GNU General Public License for more details.
36714 + *
36715 + * You should have received a copy of the GNU General Public License
36716 + * along with the Ubicom32 Linux Kernel Port.  If not,
36717 + * see <http://www.gnu.org/licenses/>.
36718 + *
36719 + * Ubicom32 implementation derived from (with many thanks):
36720 + *   arch/m68knommu
36721 + *   arch/blackfin
36722 + *   arch/parisc
36723 + */
36724 +#include <linux/types.h>
36725 +#include <linux/device.h>
36726 +#include <linux/platform_device.h>
36727 +#include <linux/mtd/mtd.h>
36728 +#include <linux/mtd/partitions.h>
36729 +#include <linux/mtd/physmap.h>
36730 +#include <linux/spi/spi.h>
36731 +#include <linux/spi/flash.h>
36732 +
36733 +#include <linux/init.h>
36734 +#include <linux/module.h>
36735 +#include <linux/interrupt.h>
36736 +#include <linux/mutex.h>
36737 +
36738 +#include <asm/ip5000.h>
36739 +#include <asm/devtree.h>
36740 +
36741 +#define UBICOM32_FLASH_BASE    0x60000000
36742 +#define UBICOM32_FLASH_MAX_SIZE 0x01000000
36743 +#define UBICOM32_FLASH_START   0x00000000
36744 +#define UBICOM32_KERNEL_OFFSET 0x00010000 /* The kernel starts after Ubicom
36745 +                                           * .protect section. */
36746 +
36747 +static struct mtd_partition ubicom32_flash_partitions[] = {
36748 +       {
36749 +               .name   = "Bootloader",         /* Protected Section
36750 +                                                * Partition */
36751 +               .size   = 0x10000,
36752 +               .offset = UBICOM32_FLASH_START,
36753 +//             .mask_flags = MTD_WRITEABLE     /* Mark Read-only */
36754 +       },
36755 +       {
36756 +               .name   = "Kernel",             /* Kernel Partition. */
36757 +               .size   = 0,                    /* this will be set up during
36758 +                                                * probe stage. At that time we
36759 +                                                * will know end of linux image
36760 +                                                * in flash. */
36761 +               .offset = MTDPART_OFS_APPEND,   /* Starts right after Protected
36762 +                                                * section. */
36763 +//             .mask_flags = MTD_WRITEABLE     /* Mark Read-only */
36764 +       },
36765 +       {
36766 +               .name   = "Rest",               /* Rest of the flash. */
36767 +               .size   = 0x200000,             /* Use up what remains in the
36768 +                                                * flash. */
36769 +               .offset = MTDPART_OFS_NXTBLK,   /* Starts right after Protected
36770 +                                                * section. */
36771 +       }
36772 +};
36773 +
36774 +static struct flash_platform_data ubicom32_flash_data = {
36775 +       .name = "ubicom32_boot_flash",
36776 +       .parts = ubicom32_flash_partitions,
36777 +       .nr_parts = ARRAY_SIZE(ubicom32_flash_partitions),
36778 +};
36779 +
36780 +static struct resource ubicom32_flash_resource[] = {
36781 +       {
36782 +               .start  = UBICOM32_FLASH_BASE,
36783 +               .end    = UBICOM32_FLASH_BASE +
36784 +               UBICOM32_FLASH_MAX_SIZE - 1,
36785 +               .flags  = IORESOURCE_MEM,
36786 +       },
36787 +};
36788 +
36789 +static struct platform_device ubicom32_flash_device = {
36790 +       .name = "ubicom32flashdriver",
36791 +       .id = 0, /* Bus number */
36792 +       .num_resources = ARRAY_SIZE(ubicom32_flash_resource),
36793 +       .resource = ubicom32_flash_resource,
36794 +       .dev = {
36795 +               .platform_data = &ubicom32_flash_data,
36796 +       },
36797 +};
36798 +
36799 +static struct platform_device *ubicom32_flash_devices[] = {
36800 +       &ubicom32_flash_device,
36801 +};
36802 +
36803 +static int __init ubicom32_flash_init(void)
36804 +{
36805 +       printk(KERN_INFO "%s(): registering device resources\n",
36806 +              __FUNCTION__);
36807 +       platform_add_devices(ubicom32_flash_devices,
36808 +                            ARRAY_SIZE(ubicom32_flash_devices));
36809 +       return 0;
36810 +}
36811 +
36812 +arch_initcall(ubicom32_flash_init);
36813 +
36814 +/*
36815 + * MTD SPI driver for ST M25Pxx (and similar) serial flash chips through
36816 + * Ubicom32 SPI controller.
36817 + *
36818 + * Author: Mike Lavender, mike@steroidmicros.com
36819 + *
36820 + * Copyright (c) 2005, Intec Automation Inc.
36821 + *
36822 + * Some parts are based on lart.c by Abraham Van Der Merwe
36823 + *
36824 + * Cleaned up and generalized based on mtd_dataflash.c
36825 + *
36826 + * This code is free software; you can redistribute it and/or modify
36827 + * it under the terms of the GNU General Public License version 2 as
36828 + * published by the Free Software Foundation.
36829 + *
36830 + */
36831 +
36832 +#define FLASH_PAGESIZE         256
36833 +
36834 +/* Flash opcodes. */
36835 +#define        OPCODE_WREN             0x06    /* Write enable */
36836 +#define        OPCODE_RDSR             0x05    /* Read status register */
36837 +#define        OPCODE_READ             0x03    /* Read data bytes (low frequency) */
36838 +#define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
36839 +#define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
36840 +#define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
36841 +#define        OPCODE_BE_32K           0x52    /* Erase 32KiB block */
36842 +#define        OPCODE_SE               0xd8    /* Sector erase (usually 64KiB) */
36843 +#define        OPCODE_RDID             0x9f    /* Read JEDEC ID */
36844 +
36845 +/* Status Register bits. */
36846 +#define        SR_WIP                  1       /* Write in progress */
36847 +#define        SR_WEL                  2       /* Write enable latch */
36848 +/* meaning of other SR_* bits may differ between vendors */
36849 +#define        SR_BP0                  4       /* Block protect 0 */
36850 +#define        SR_BP1                  8       /* Block protect 1 */
36851 +#define        SR_BP2                  0x10    /* Block protect 2 */
36852 +#define        SR_SRWD                 0x80    /* SR write protect */
36853 +
36854 +/* Define max times to check status register before we give up. */
36855 +#define        MAX_READY_WAIT_COUNT    100000
36856 +
36857 +
36858 +#ifdef CONFIG_MTD_PARTITIONS
36859 +#define        mtd_has_partitions()    (1)
36860 +#else
36861 +#define        mtd_has_partitions()    (0)
36862 +#endif
36863 +
36864 +/*
36865 + * Ubicom32 FLASH Command Set
36866 + */
36867 +#define FLASH_FC_INST_CMD      0x00    /* for SPI command only transaction */
36868 +#define FLASH_FC_INST_WR       0x01    /* for SPI write transaction */
36869 +#define FLASH_FC_INST_RD       0x02    /* for SPI read transaction */
36870 +
36871 +#define ALIGN_DOWN(v, a) ((v) & ~((a) - 1))
36872 +#define ALIGN_UP(v, a) (((v) + ((a) - 1)) & ~((a) - 1))
36873 +
36874 +#define        FLASH_COMMAND_KICK_OFF(io)                                                      \
36875 +       asm volatile(                                                                   \
36876 +       "       bset    "D(IO_INT_CLR)"(%0), #0, #%%bit("D(IO_XFL_INT_DONE)")   \n\t"   \
36877 +       "       jmpt.t  .+4                                                     \n\t"   \
36878 +       "       bset    "D(IO_INT_SET)"(%0), #0, #%%bit("D(IO_XFL_INT_START)")  \n\t"   \
36879 +               :                                                                       \
36880 +               : "a" (io)                                                              \
36881 +               : "memory", "cc"                                                        \
36882 +       );
36883 +
36884 +#define        FLASH_COMMAND_WAIT_FOR_COMPLETION(io)                                           \
36885 +       asm volatile(                                                                   \
36886 +       "       btst    "D(IO_INT_STATUS)"(%0), #%%bit("D(IO_XFL_INT_DONE)")    \n\t"   \
36887 +       "       jmpeq.f .-4                                                     \n\t"   \
36888 +               :                                                                       \
36889 +               : "a" (io)                                                              \
36890 +               : "memory", "cc"                                                                        \
36891 +       );
36892 +
36893 +#define        FLASH_COMMAND_EXEC(io)                                                          \
36894 +       FLASH_COMMAND_KICK_OFF(io)                                                      \
36895 +       FLASH_COMMAND_WAIT_FOR_COMPLETION(io)
36896 +
36897 +
36898 +#define OSC1_FREQ 12000000
36899 +#define TEN_MICRO_SECONDS (OSC1_FREQ * 10 / 1000000)
36900 +
36901 +/*
36902 + * We will have to eventually replace this null definition with the real thing.
36903 + */
36904 +#define WATCHDOG_RESET()
36905 +
36906 +#define EXTFLASH_WRITE_FIFO_SIZE 32
36907 +#define EXTFLASH_WRITE_BLOCK_SIZE EXTFLASH_WRITE_FIFO_SIZE /* limit the size to
36908 +                                                           * FIFO capacity, so
36909 +                                                           * the thread can be
36910 +                                                           * suspended. */
36911 +
36912 +#define JFFS2_FILESYSTEM_SIZE 0x100000
36913 +
36914 +/****************************************************************************/
36915 +
36916 +struct m25p {
36917 +       struct platform_device  *plt_dev;
36918 +       struct mutex            lock;
36919 +       struct mtd_info         mtd;
36920 +       unsigned                partitioned:1;
36921 +       u8                      erase_opcode;
36922 +       u8                      command[4];
36923 +};
36924 +
36925 +static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
36926 +{
36927 +       return container_of(mtd, struct m25p, mtd);
36928 +}
36929 +
36930 +/****************************************************************************/
36931 +
36932 +/*
36933 + * Internal helper functions
36934 + */
36935 +
36936 +/*
36937 + * Read the status register, returning its value in the location
36938 + * Return the status register value.
36939 + * Returns negative if error occurred.
36940 + */
36941 +static int read_sr(struct m25p *flash)
36942 +{
36943 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36944 +
36945 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
36946 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
36947 +               IO_XFL_CTL1_FC_DATA(1);
36948 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDSR);
36949 +       FLASH_COMMAND_EXEC(io);
36950 +
36951 +       return io->status1 & 0xff;
36952 +}
36953 +
36954 +/*
36955 + * mem_flash_io_read_u32()
36956 + */
36957 +static u32 mem_flash_io_read_u32(u32 addr)
36958 +{
36959 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
36960 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
36961 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
36962 +               IO_XFL_CTL1_FC_DATA(4) | IO_XFL_CTL1_FC_DUMMY(1) |
36963 +               IO_XFL_CTL1_FC_ADDR;
36964 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_FAST_READ) |
36965 +               IO_XFL_CTL2_FC_ADDR(addr);
36966 +       FLASH_COMMAND_EXEC(io);
36967 +       return io->status1;
36968 +}
36969 +
36970 +/*
36971 + * mem_flash_read_u8()
36972 + */
36973 +static u8 mem_flash_read_u8(u32 addr)
36974 +{
36975 +       u32 tmp_addr = ALIGN_DOWN(addr, 4);
36976 +       u32 tmp_data = mem_flash_io_read_u32(tmp_addr);
36977 +       u8 *ptr = (u8 *)&tmp_data;
36978 +       return ptr[addr & 0x3];
36979 +}
36980 +
36981 +/*
36982 + * mem_flash_read()
36983 + *     No need to lock as read is implemented with ireads (same as normal flash
36984 + *     execution).
36985 + */
36986 +static void mem_flash_read(u32 addr, void *dst, size_t length)
36987 +{
36988 +       /*
36989 +        * Range check
36990 +        */
36991 +       /*
36992 +        * Fix source alignment.
36993 +        */
36994 +       while (addr & 0x03) {
36995 +               if (length == 0) {
36996 +                       return;
36997 +               }
36998 +               *((u8 *)dst) = mem_flash_read_u8(addr++);
36999 +               dst++;
37000 +               length--;
37001 +       }
37002 +
37003 +       while (length >= 4) {
37004 +               u32 tmp_data = mem_flash_io_read_u32(addr);
37005 +               addr += 4;
37006 +               length -= 4;
37007 +
37008 +               /*
37009 +                * Send the data to the destination.
37010 +                */
37011 +               memcpy((void *)dst, (void *)&tmp_data, 4);
37012 +               dst += 4;
37013 +       }
37014 +
37015 +       while (length--) {
37016 +               *((u8 *)dst) = mem_flash_read_u8(addr++);
37017 +               dst++;
37018 +       }
37019 +}
37020 +
37021 +/*
37022 + * mem_flash_wait_until_complete()
37023 + */
37024 +static void mem_flash_wait_until_complete(void)
37025 +{
37026 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37027 +
37028 +       do {
37029 +               /*
37030 +                * Put a delay here to deal with flash programming problem.
37031 +                */
37032 +               u32 mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
37033 +               while (UBICOM32_IO_TIMER->mptval < mptval)
37034 +                       ;
37035 +
37036 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
37037 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
37038 +                       IO_XFL_CTL1_FC_DATA(1);
37039 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDSR);
37040 +               FLASH_COMMAND_EXEC(io);
37041 +       } while (io->status1 & SR_WIP);
37042 +}
37043 +
37044 +/*
37045 + * mem_flash_write_next()
37046 + */
37047 +static size_t mem_flash_write_next(u32 addr, u8 *buf, size_t length)
37048 +{
37049 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37050 +       u32 data_start = addr;
37051 +       u32 data_end = addr + length;
37052 +       size_t count;
37053 +       u32 i, j;
37054 +
37055 +       /*
37056 +        * Top limit address.
37057 +        */
37058 +       u32 block_start = ALIGN_DOWN(data_start, 4);
37059 +       u32 block_end = block_start + EXTFLASH_WRITE_BLOCK_SIZE;
37060 +
37061 +       union {
37062 +               u8 byte[EXTFLASH_WRITE_BLOCK_SIZE];
37063 +               u32 word[EXTFLASH_WRITE_BLOCK_SIZE / 4];
37064 +       } write_buf;
37065 +
37066 +       u32 *flash_addr = (u32 *)block_start;
37067 +
37068 +       /*
37069 +        * The write block must be limited by FLASH internal buffer.
37070 +        */
37071 +       u32 block_end_align = ALIGN_DOWN(block_end, 256);
37072 +       bool write_needed;
37073 +
37074 +       block_end = (block_end_align > block_start)
37075 +               ? block_end_align : block_end;
37076 +       data_end = (data_end <= block_end) ? data_end : block_end;
37077 +       block_end = ALIGN_UP(data_end, 4);
37078 +       count = data_end - data_start;
37079 +
37080 +       /*
37081 +        * Transfer data to a buffer.
37082 +        */
37083 +       for (i = 0; i < (block_end - block_start) / 4; i++) {
37084 +               /*
37085 +                * The FLASH read can hold D-cache for a long time.
37086 +                * Use I/O operation to read FLASH to avoid starving other
37087 +                * threads, especially HRT.  (Do this for application only)
37088 +                */
37089 +               write_buf.word[i] = mem_flash_io_read_u32(
37090 +                       (u32)(&flash_addr[i]));
37091 +       }
37092 +
37093 +       write_needed = false;
37094 +       for (i = 0, j = (data_start - block_start);
37095 +            i < (data_end - data_start); i++, j++) {
37096 +               write_needed = write_needed || (write_buf.byte[j] != buf[i]);
37097 +               write_buf.byte[j] &= buf[i];
37098 +       }
37099 +
37100 +
37101 +       /*
37102 +        * If the data in FLASH is identical to what to be written. Then skip
37103 +        * it.
37104 +        */
37105 +       if (write_needed) {
37106 +               /*
37107 +                * Write to flash.
37108 +                */
37109 +               void *tmp __attribute__((unused));
37110 +               s32 extra_words;
37111 +
37112 +               asm volatile(
37113 +               "       move.4  %0, %2                                                                  \n\t"
37114 +               "       bset    "D(IO_INT_SET)"(%1), #0, #%%bit("D(IO_PORTX_INT_FIFO_TX_RESET)")        \n\t"
37115 +               "       pipe_flush 0                                                                    \n\t"
37116 +               "       .rept   "D(EXTFLASH_WRITE_FIFO_SIZE / 4)"                                       \n\t"
37117 +               "       move.4  "D(IO_TX_FIFO)"(%1), (%0)4++                                            \n\t"
37118 +               "       .endr                                                                           \n\t"
37119 +                       : "=&a" (tmp)
37120 +                       : "a" (io), "r" (&write_buf.word[0])
37121 +                       : "memory", "cc"
37122 +               );
37123 +
37124 +               /* Lock FLASH for write access. */
37125 +               io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
37126 +
37127 +               /* Command: WREN */
37128 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
37129 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD);
37130 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_WREN);
37131 +               FLASH_COMMAND_EXEC(io);
37132 +
37133 +               /* Command: BYTE PROGRAM */
37134 +               io->ctl1 &= ~IO_XFL_CTL1_MASK;
37135 +               io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_WR) |
37136 +                       IO_XFL_CTL1_FC_DATA(block_end - block_start) |
37137 +                       IO_XFL_CTL1_FC_ADDR;
37138 +               io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_PP) |
37139 +                       IO_XFL_CTL2_FC_ADDR(block_start);
37140 +               FLASH_COMMAND_KICK_OFF(io);
37141 +
37142 +               extra_words = (s32)(block_end - block_start -
37143 +                                   EXTFLASH_WRITE_FIFO_SIZE) / 4;
37144 +               if (extra_words > 0) {
37145 +                       asm volatile(
37146 +                       "       move.4          %0, %3                          \n\t"
37147 +                       "1:     cmpi            "D(IO_FIFO_LEVEL)"(%1), #4      \n\t"
37148 +                       "       jmpgt.s.t       1b                              \n\t"
37149 +                       "       move.4          "D(IO_TX_FIFO)"(%1), (%0)4++    \n\t"
37150 +                       "       add.4           %2, #-1, %2                     \n\t"
37151 +                       "       jmpgt.t         1b                              \n\t"
37152 +                               : "=&a" (tmp)
37153 +                               : "a" (io), "d" (extra_words),
37154 +                                 "r" (&write_buf.word[EXTFLASH_WRITE_FIFO_SIZE / 4])
37155 +                               : "memory", "cc"
37156 +                       );
37157 +               }
37158 +               FLASH_COMMAND_WAIT_FOR_COMPLETION(io);
37159 +
37160 +               mem_flash_wait_until_complete();
37161 +
37162 +
37163 +               /* Unlock FLASH for cache access. */
37164 +               io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
37165 +       }
37166 +
37167 +       /*
37168 +        * Complete.
37169 +        */
37170 +       return count;
37171 +}
37172 +
37173 +/*
37174 + * mem_flash_write()
37175 + */
37176 +static void mem_flash_write(u32 addr, const void *src, size_t length)
37177 +{
37178 +       /*
37179 +        * Write data
37180 +        */
37181 +       u8_t *ptr = (u8_t *)src;
37182 +       while (length) {
37183 +               size_t count = mem_flash_write_next(addr, ptr, length);
37184 +               addr += count;
37185 +               ptr += count;
37186 +               length -= count;
37187 +       }
37188 +}
37189 +
37190 +/*
37191 + * Service routine to read status register until ready, or timeout occurs.
37192 + * Returns non-zero if error.
37193 + */
37194 +static int wait_till_ready(struct m25p *flash)
37195 +{
37196 +       int count;
37197 +       int sr;
37198 +
37199 +       /* one chip guarantees max 5 msec wait here after page writes,
37200 +        * but potentially three seconds (!) after page erase.
37201 +        */
37202 +       for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
37203 +               u32 mptval;
37204 +               sr = read_sr(flash);
37205 +               if (sr < 0)
37206 +                       break;
37207 +               else if (!(sr & SR_WIP))
37208 +                       return 0;
37209 +
37210 +               /*
37211 +                * Put a 10us delay here to deal with flash programming problem.
37212 +                */
37213 +               mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
37214 +               while ((s32)(mptval - UBICOM32_IO_TIMER->mptval) > 0) {
37215 +                       WATCHDOG_RESET();
37216 +               }
37217 +               /* REVISIT sometimes sleeping would be best */
37218 +       }
37219 +
37220 +       return 1;
37221 +}
37222 +
37223 +/*
37224 + * mem_flash_erase_page()
37225 + */
37226 +static void mem_flash_erase_page(u32 addr)
37227 +{
37228 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37229 +
37230 +       /* Lock FLASH for write access. */
37231 +       io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
37232 +
37233 +       /* Command: WREN */
37234 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37235 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD);
37236 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_WREN);
37237 +       FLASH_COMMAND_EXEC(io);
37238 +
37239 +       /* Command: ERASE */
37240 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37241 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_CMD) |
37242 +               IO_XFL_CTL1_FC_ADDR;
37243 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_SE) |
37244 +               IO_XFL_CTL2_FC_ADDR(addr);
37245 +       FLASH_COMMAND_EXEC(io);
37246 +
37247 +       mem_flash_wait_until_complete();
37248 +
37249 +       /* Unlock FLASH for cache access. */
37250 +       io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
37251 +}
37252 +
37253 +/*
37254 + * mem_flash_erase()
37255 + */
37256 +static u32 mem_flash_erase(u32 addr, u32 length)
37257 +{
37258 +       /*
37259 +        * Calculate the endaddress to be the first address of the page
37260 +        * just beyond this erase section of pages.
37261 +        */
37262 +       u32 endaddr = addr + length;
37263 +
37264 +       /*
37265 +        * Erase.
37266 +        */
37267 +       while (addr < endaddr) {
37268 +               u32 test_addr = addr;
37269 +               mem_flash_erase_page(addr);
37270 +
37271 +               /*
37272 +                * Test how much was erased as actual flash page at this address
37273 +                * may be smaller than the expected page size.
37274 +                */
37275 +               while (test_addr < endaddr) {
37276 +                       /*
37277 +                        * The FLASH read can hold D-cache for a long time.  Use
37278 +                        * I/O operation to read FLASH to avoid starving other
37279 +                        * threads, especially HRT.  (Do this for application
37280 +                        * only)
37281 +                        */
37282 +                       if (mem_flash_io_read_u32(test_addr) != 0xFFFFFFFF) {
37283 +                               break;
37284 +                       }
37285 +                       test_addr += 4;
37286 +               }
37287 +               if (test_addr == addr) {
37288 +                       printk("erase failed at address 0x%x, skipping",
37289 +                              test_addr);
37290 +                       test_addr += 4;
37291 +                       return 1;
37292 +               }
37293 +               addr = test_addr;
37294 +       }
37295 +       return 0;
37296 +}
37297 +
37298 +
37299 +/****************************************************************************/
37300 +
37301 +/*
37302 + * MTD implementation
37303 + */
37304 +
37305 +/*
37306 + * Erase an address range on the flash chip.  The address range may extend
37307 + * one or more erase sectors.  Return an error is there is a problem erasing.
37308 + */
37309 +static int ubicom32_flash_driver_erase(struct mtd_info *mtd,
37310 +                                      struct erase_info *instr)
37311 +{
37312 +       struct m25p *flash = mtd_to_m25p(mtd);
37313 +       u32 addr, len;
37314 +
37315 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37316 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "at",
37317 +                       (u32)instr->addr, instr->len);
37318 +
37319 +       /* sanity checks */
37320 +       if (instr->addr + instr->len > flash->mtd.size)
37321 +               return -EINVAL;
37322 +       if ((instr->addr % mtd->erasesize) != 0
37323 +                       || (instr->len % mtd->erasesize) != 0) {
37324 +               return -EINVAL;
37325 +       }
37326 +
37327 +       addr = instr->addr + UBICOM32_FLASH_BASE;
37328 +       len = instr->len;
37329 +
37330 +       mutex_lock(&flash->lock);
37331 +
37332 +       /* REVISIT in some cases we could speed up erasing large regions
37333 +        * by using OPCODE_SE instead of OPCODE_BE_4K
37334 +        */
37335 +
37336 +       /* now erase those sectors */
37337 +       if (mem_flash_erase(addr, len)) {
37338 +               instr->state = MTD_ERASE_FAILED;
37339 +               mutex_unlock(&flash->lock);
37340 +               return -EIO;
37341 +       }
37342 +
37343 +       mutex_unlock(&flash->lock);
37344 +       instr->state = MTD_ERASE_DONE;
37345 +       mtd_erase_callback(instr);
37346 +       return 0;
37347 +}
37348 +
37349 +/*
37350 + * Read an address range from the flash chip.  The address range
37351 + * may be any size provided it is within the physical boundaries.
37352 + */
37353 +static int ubicom32_flash_driver_read(struct mtd_info *mtd, loff_t from,
37354 +                                     size_t len, size_t *retlen, u_char *buf)
37355 +{
37356 +       struct m25p *flash = mtd_to_m25p(mtd);
37357 +       u32 base_addr = UBICOM32_FLASH_BASE + from;
37358 +
37359 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37360 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "from",
37361 +             (u32)from, len);
37362 +
37363 +       /* sanity checks */
37364 +       if (!len)
37365 +               return 0;
37366 +
37367 +       if (from + len > flash->mtd.size)
37368 +               return -EINVAL;
37369 +
37370 +       /* Byte count starts at zero. */
37371 +       if (retlen)
37372 +               *retlen = 0;
37373 +
37374 +       mutex_lock(&flash->lock);
37375 +
37376 +       /* Wait till previous write/erase is done. */
37377 +       if (wait_till_ready(flash)) {
37378 +               /* REVISIT status return?? */
37379 +               mutex_unlock(&flash->lock);
37380 +               return 1;
37381 +       }
37382 +
37383 +       mem_flash_read(base_addr, (void *)buf, len);
37384 +
37385 +       if (retlen)
37386 +               *retlen = len;
37387 +
37388 +       mutex_unlock(&flash->lock);
37389 +
37390 +       return 0;
37391 +}
37392 +
37393 +/*
37394 + * Write an address range to the flash chip.  Data must be written in
37395 + * FLASH_PAGESIZE chunks.  The address range may be any size provided
37396 + * it is within the physical boundaries.
37397 + */
37398 +static int ubicom32_flash_driver_write(struct mtd_info *mtd, loff_t to,
37399 +                                      size_t len, size_t *retlen,
37400 +                                      const u_char *buf)
37401 +{
37402 +       struct m25p *flash = mtd_to_m25p(mtd);
37403 +       u32 base_addr = UBICOM32_FLASH_BASE + to;
37404 +       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37405 +                       flash->plt_dev->dev.bus_id, __FUNCTION__, "to",
37406 +                       (u32)to, len);
37407 +
37408 +       if (retlen)
37409 +               *retlen = 0;
37410 +
37411 +       /* sanity checks */
37412 +       if (!len)
37413 +               return 0;
37414 +
37415 +       if (to + len > flash->mtd.size)
37416 +               return -EINVAL;
37417 +
37418 +       mutex_lock(&flash->lock);
37419 +
37420 +       mem_flash_write(base_addr, (void *) buf, len);
37421 +
37422 +       /* Wait until finished previous write command. */
37423 +       if (wait_till_ready(flash)) {
37424 +               mutex_unlock(&flash->lock);
37425 +               return 1;
37426 +       }
37427 +
37428 +       if (retlen)
37429 +               *retlen = len;
37430 +
37431 +       mutex_unlock(&flash->lock);
37432 +       return 0;
37433 +}
37434 +
37435 +
37436 +/****************************************************************************/
37437 +
37438 +/*
37439 + * SPI device driver setup and teardown
37440 + */
37441 +
37442 +struct flash_info {
37443 +       char            *name;
37444 +
37445 +       /* JEDEC id zero means "no ID" (most older chips); otherwise it has
37446 +        * a high byte of zero plus three data bytes: the manufacturer id,
37447 +        * then a two byte device id.
37448 +        */
37449 +       u32             jedec_id;
37450 +
37451 +       /* The size listed here is what works with OPCODE_SE, which isn't
37452 +        * necessarily called a "sector" by the vendor.
37453 +        */
37454 +       unsigned        sector_size;
37455 +       u16             n_sectors;
37456 +
37457 +       u16             flags;
37458 +#define        SECT_4K         0x01            /* OPCODE_BE_4K works uniformly */
37459 +};
37460 +
37461 +
37462 +/* NOTE: double check command sets and memory organization when you add
37463 + * more flash chips.  This current list focusses on newer chips, which
37464 + * have been converging on command sets which including JEDEC ID.
37465 + */
37466 +static struct flash_info __devinitdata m25p_data[] = {
37467 +
37468 +       /* Atmel -- some are (confusingly) marketed as "DataFlash" */
37469 +       { "at25fs010",  0x1f6601, 32 * 1024, 4, SECT_4K, },
37470 +       { "at25fs040",  0x1f6604, 64 * 1024, 8, SECT_4K, },
37471 +
37472 +       { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
37473 +
37474 +       { "at26f004",   0x1f0400, 64 * 1024, 8, SECT_4K, },
37475 +       { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
37476 +       { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
37477 +       { "at26df321",  0x1f4701, 64 * 1024, 64, SECT_4K, },
37478 +
37479 +       /* Spansion -- single (large) sector size only, at least
37480 +        * for the chips listed here (without boot sectors).
37481 +        */
37482 +       { "s25sl004a", 0x010212, 64 * 1024, 8, },
37483 +       { "s25sl008a", 0x010213, 64 * 1024, 16, },
37484 +       { "s25sl016a", 0x010214, 64 * 1024, 32, },
37485 +       { "s25sl032a", 0x010215, 64 * 1024, 64, },
37486 +       { "s25sl064a", 0x010216, 64 * 1024, 128, },
37487 +
37488 +       /* SST -- large erase sizes are "overlays", "sectors" are 4K */
37489 +       { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
37490 +       { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
37491 +       { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
37492 +       { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
37493 +
37494 +       /* ST Microelectronics -- newer production may have feature updates */
37495 +       { "m25p05",  0x202010,  32 * 1024, 2, },
37496 +       { "m25p10",  0x202011,  32 * 1024, 4, },
37497 +       { "m25p20",  0x202012,  64 * 1024, 4, },
37498 +       { "m25p40",  0x202013,  64 * 1024, 8, },
37499 +       { "m25p80",         0,  64 * 1024, 16, },
37500 +       { "m25p16",  0x202015,  64 * 1024, 32, },
37501 +       { "m25p32",  0x202016,  64 * 1024, 64, },
37502 +       { "m25p64",  0x202017,  64 * 1024, 128, },
37503 +       { "m25p128", 0x202018, 256 * 1024, 64, },
37504 +
37505 +       { "m45pe80", 0x204014,  64 * 1024, 16, },
37506 +       { "m45pe16", 0x204015,  64 * 1024, 32, },
37507 +
37508 +       { "m25pe80", 0x208014,  64 * 1024, 16, },
37509 +       { "m25pe16", 0x208015,  64 * 1024, 32, SECT_4K, },
37510 +
37511 +       /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
37512 +       { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
37513 +       { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
37514 +       { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
37515 +       { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
37516 +       { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
37517 +       { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
37518 +       { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
37519 +
37520 +       /* Macronix -- mx25lxxx */ 
37521 +       { "mx25l32",  0xc22016, 64 * 1024,  64, }, 
37522 +       { "mx25l64",  0xc22017, 64 * 1024, 128, }, 
37523 +       { "mx25l128", 0xc22018, 64 * 1024, 256, },
37524 +
37525 +};
37526 +
37527 +struct flash_info *__devinit jedec_probe(struct platform_device *spi)
37528 +{
37529 +       int                     tmp;
37530 +       u32                     jedec;
37531 +       struct flash_info       *info;
37532 +       struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37533 +
37534 +       /*
37535 +        * Setup and run RDID command on the flash.
37536 +        */
37537 +       io->ctl1 &= ~IO_XFL_CTL1_MASK;
37538 +       io->ctl1 |= IO_XFL_CTL1_FC_INST(FLASH_FC_INST_RD) |
37539 +               IO_XFL_CTL1_FC_DATA(3);
37540 +       io->ctl2 = IO_XFL_CTL2_FC_CMD(OPCODE_RDID);
37541 +       FLASH_COMMAND_EXEC(io);
37542 +
37543 +       jedec = io->status1 & 0x00ffffff;
37544 +
37545 +       for (tmp = 0, info = m25p_data;
37546 +                       tmp < ARRAY_SIZE(m25p_data);
37547 +                       tmp++, info++) {
37548 +               if (info->jedec_id == jedec)
37549 +                       return info;
37550 +       }
37551 +       dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
37552 +       return NULL;
37553 +}
37554 +
37555 +
37556 +/*
37557 + * board specific setup should have ensured the SPI clock used here
37558 + * matches what the READ command supports, at least until this driver
37559 + * understands FAST_READ (for clocks over 25 MHz).
37560 + */
37561 +static int __devinit ubicom32_flash_probe(struct platform_device *spi)
37562 +{
37563 +       struct flash_platform_data      *data;
37564 +       struct m25p                     *flash;
37565 +       struct flash_info               *info;
37566 +       unsigned                        i;
37567 +
37568 +       /* Platform data helps sort out which chip type we have, as
37569 +        * well as how this board partitions it.  If we don't have
37570 +        * a chip ID, try the JEDEC id commands; they'll work for most
37571 +        * newer chips, even if we don't recognize the particular chip.
37572 +        */
37573 +       data = spi->dev.platform_data;
37574 +       if (data && data->type) {
37575 +               for (i = 0, info = m25p_data;
37576 +                               i < ARRAY_SIZE(m25p_data);
37577 +                               i++, info++) {
37578 +                       if (strcmp(data->type, info->name) == 0)
37579 +                               break;
37580 +               }
37581 +
37582 +               /* unrecognized chip? */
37583 +               if (i == ARRAY_SIZE(m25p_data)) {
37584 +                       DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
37585 +                                       spi->dev.bus_id, data->type);
37586 +                       info = NULL;
37587 +
37588 +               /* recognized; is that chip really what's there? */
37589 +               } else if (info->jedec_id) {
37590 +                       struct flash_info       *chip = jedec_probe(spi);
37591 +
37592 +                       if (!chip || chip != info) {
37593 +                               dev_warn(&spi->dev, "found %s, expected %s\n",
37594 +                                               chip ? chip->name : "UNKNOWN",
37595 +                                               info->name);
37596 +                               info = NULL;
37597 +                       }
37598 +               }
37599 +       } else
37600 +               info = jedec_probe(spi);
37601 +
37602 +       if (!info)
37603 +               return -ENODEV;
37604 +
37605 +       flash = kzalloc(sizeof *flash, GFP_KERNEL);
37606 +       if (!flash)
37607 +               return -ENOMEM;
37608 +
37609 +       flash->plt_dev = spi;
37610 +       mutex_init(&flash->lock);
37611 +       dev_set_drvdata(&spi->dev, flash);
37612 +
37613 +       if (data && data->name)
37614 +               flash->mtd.name = data->name;
37615 +       else
37616 +               flash->mtd.name = spi->dev.bus_id;
37617 +
37618 +       flash->mtd.type = MTD_NORFLASH;
37619 +       flash->mtd.writesize = 1;
37620 +       flash->mtd.flags = MTD_CAP_NORFLASH;
37621 +       flash->mtd.size = info->sector_size * info->n_sectors;
37622 +       flash->mtd.erase = ubicom32_flash_driver_erase;
37623 +       flash->mtd.read = ubicom32_flash_driver_read;
37624 +       flash->mtd.write = ubicom32_flash_driver_write;
37625 +
37626 +       /* prefer "small sector" erase if possible */
37627 +       /*
37628 +        * The Ubicom erase code does not use the opcode for smaller sectors,
37629 +        * so disable that functionality and keep erasesize == sector_size
37630 +        * so that the test in ubicom32_flash_driver_erase works properly.
37631 +        *
37632 +        * This was: `if (info->flags & SECT_4K) {' instead of `if (0) {'
37633 +        */
37634 +       if (0) {
37635 +               flash->erase_opcode = OPCODE_BE_4K;
37636 +               flash->mtd.erasesize = 4096;
37637 +       } else {
37638 +               flash->erase_opcode = OPCODE_SE;
37639 +               flash->mtd.erasesize = info->sector_size;
37640 +       }
37641 +
37642 +       dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
37643 +                       flash->mtd.size / 1024);
37644 +
37645 +       DEBUG(MTD_DEBUG_LEVEL2,
37646 +               "mtd .name = %s, .size = 0x%.8x (%uMiB) "
37647 +                       ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
37648 +               flash->mtd.name,
37649 +               flash->mtd.size, flash->mtd.size / (1024*1024),
37650 +               flash->mtd.erasesize, flash->mtd.erasesize / 1024,
37651 +               flash->mtd.numeraseregions);
37652 +
37653 +       if (flash->mtd.numeraseregions)
37654 +               for (i = 0; i < flash->mtd.numeraseregions; i++)
37655 +                       DEBUG(MTD_DEBUG_LEVEL2,
37656 +                               "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
37657 +                               ".erasesize = 0x%.8x (%uKiB), "
37658 +                               ".numblocks = %d }\n",
37659 +                               i, flash->mtd.eraseregions[i].offset,
37660 +                               flash->mtd.eraseregions[i].erasesize,
37661 +                               flash->mtd.eraseregions[i].erasesize / 1024,
37662 +                               flash->mtd.eraseregions[i].numblocks);
37663 +
37664 +
37665 +       /* partitions should match sector boundaries; and it may be good to
37666 +        * use readonly partitions for writeprotected sectors (BP2..BP0).
37667 +        */
37668 +       if (mtd_has_partitions()) {
37669 +               struct mtd_partition    *parts = NULL;
37670 +               int                     nr_parts = 0;
37671 +
37672 +#ifdef CONFIG_MTD_CMDLINE_PARTS
37673 +               static const char *part_probes[] = { "cmdlinepart", NULL, };
37674 +
37675 +               nr_parts = parse_mtd_partitions(&flash->mtd,
37676 +                               part_probes, &parts, 0);
37677 +#endif
37678 +
37679 +               if (nr_parts <= 0 && data && data->parts) {
37680 +                       parts = data->parts;
37681 +                       nr_parts = data->nr_parts;
37682 +                       if (nr_parts >= 2) {
37683 +                               /*
37684 +                                * Set last partition size to be 1M.
37685 +                                */
37686 +                               parts[1].size = flash->mtd.size - 
37687 +                                       parts[0].size - JFFS2_FILESYSTEM_SIZE;
37688 +                               parts[2].size = JFFS2_FILESYSTEM_SIZE;
37689 +                       }
37690 +               }
37691 +
37692 +               if (nr_parts > 0) {
37693 +                       for (i = 0; i < nr_parts; i++) {
37694 +                               DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
37695 +                                       "{.name = %s, .offset = 0x%.8x, "
37696 +                                               ".size = 0x%.8x (%uKiB) }\n",
37697 +                                       i, parts[i].name,
37698 +                                       parts[i].offset,
37699 +                                       parts[i].size,
37700 +                                       parts[i].size / 1024);
37701 +                       }
37702 +                       flash->partitioned = 1;
37703 +                       return add_mtd_partitions(&flash->mtd, parts, nr_parts);
37704 +               }
37705 +       } else if (data->nr_parts)
37706 +               dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
37707 +                               data->nr_parts, data->name);
37708 +
37709 +       return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
37710 +}
37711 +
37712 +
37713 +static int __devexit ubicom32_flash_remove(struct spi_device *spi)
37714 +{
37715 +       struct m25p     *flash = dev_get_drvdata(&spi->dev);
37716 +       int             status;
37717 +
37718 +       /* Clean up MTD stuff. */
37719 +       if (mtd_has_partitions() && flash->partitioned)
37720 +               status = del_mtd_partitions(&flash->mtd);
37721 +       else
37722 +               status = del_mtd_device(&flash->mtd);
37723 +       if (status == 0)
37724 +               kfree(flash);
37725 +       return 0;
37726 +}
37727 +
37728 +static struct platform_driver ubicom32_flash_driver = {
37729 +       .driver = {
37730 +               .name   = "ubicom32flashdriver",
37731 +               .bus    = &platform_bus_type,
37732 +               .owner  = THIS_MODULE,
37733 +       },
37734 +       .probe  = ubicom32_flash_probe,
37735 +       .remove = NULL,
37736 +};
37737 +
37738 +static int ubicom32_flash_driver_init(void)
37739 +{
37740 +       return platform_driver_register(&ubicom32_flash_driver);
37741 +}
37742 +
37743 +
37744 +static void ubicom32_flash_driver_exit(void)
37745 +{
37746 +       platform_driver_unregister(&ubicom32_flash_driver);
37747 +}
37748 +
37749 +
37750 +module_init(ubicom32_flash_driver_init);
37751 +module_exit(ubicom32_flash_driver_exit);
37752 +
37753 +MODULE_LICENSE("GPL");
37754 +MODULE_AUTHOR("Mike Lavender");
37755 +MODULE_DESCRIPTION("Ubicom32 MTD SPI driver for ST M25Pxx flash chips");
37756 --- a/drivers/net/Kconfig
37757 +++ b/drivers/net/Kconfig
37758 @@ -2463,6 +2463,25 @@ config JME
37759           To compile this driver as a module, choose M here. The module
37760           will be called jme.
37761  
37762 +config UBICOM32_GMAC
37763 +       tristate "Ubicom Gigabit Ethernet support (EXPERIMENTAL)"
37764 +       depends on UBICOM32
37765 +       help
37766 +         Gigabit Ethernet support for IP5K/IP7K
37767 +
37768 +config UBICOM32_NAPI
37769 +       bool  "USE NAPI (EXPERIMENTAL)"
37770 +       depends on UBICOM32_GMAC
37771 +       help
37772 +         Use NAPI for Ubicom's Ethernet driver
37773 +
37774 +config UBICOM32_OCM_FOR_SKB
37775 +        bool  "USE OCM for SKB (EXPERIMENTAL)"
37776 +        depends on UBICOM32_GMAC
37777 +       default n
37778 +        help
37779 +          Allocate skb from OCM for Ethernet Receive
37780 +
37781  endif # NETDEV_1000
37782  
37783  #
37784 --- a/drivers/net/Makefile
37785 +++ b/drivers/net/Makefile
37786 @@ -262,4 +262,4 @@ obj-$(CONFIG_NETXEN_NIC) += netxen/
37787  obj-$(CONFIG_NIU) += niu.o
37788  obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
37789  obj-$(CONFIG_SFC) += sfc/
37790 -
37791 +obj-$(CONFIG_UBICOM32_GMAC) += ubi32-eth.o
37792 --- /dev/null
37793 +++ b/drivers/net/ubi32-eth.c
37794 @@ -0,0 +1,699 @@
37795 +/*
37796 + * drivers/net/ubi32-eth.c
37797 + *   Ubicom32 ethernet TIO interface driver.
37798 + *
37799 + * (C) Copyright 2009, Ubicom, Inc.
37800 + *
37801 + * This file is part of the Ubicom32 Linux Kernel Port.
37802 + *
37803 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
37804 + * it and/or modify it under the terms of the GNU General Public License
37805 + * as published by the Free Software Foundation, either version 2 of the
37806 + * License, or (at your option) any later version.
37807 + *
37808 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
37809 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
37810 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
37811 + * the GNU General Public License for more details.
37812 + *
37813 + * You should have received a copy of the GNU General Public License
37814 + * along with the Ubicom32 Linux Kernel Port.  If not,
37815 + * see <http://www.gnu.org/licenses/>.
37816 + *
37817 + * Ubicom32 implementation derived from (with many thanks):
37818 + *   arch/m68knommu
37819 + *   arch/blackfin
37820 + *   arch/parisc
37821 + */
37822 +/*
37823 + * ubi32_eth.c
37824 + * Ethernet driver for Ip5k/Ip7K
37825 + */
37826 +
37827 +#include <linux/module.h>
37828 +#include <linux/init.h>
37829 +#include <linux/moduleparam.h>
37830 +
37831 +#include <linux/sched.h>
37832 +#include <linux/kernel.h>
37833 +#include <linux/slab.h>
37834 +#include <linux/errno.h>
37835 +#include <linux/types.h>
37836 +#include <linux/interrupt.h>
37837 +
37838 +#include <linux/in.h>
37839 +#include <linux/netdevice.h>
37840 +#include <linux/etherdevice.h>
37841 +#include <linux/if_vlan.h>
37842 +#include <linux/ip.h>
37843 +#include <linux/tcp.h>
37844 +#include <linux/skbuff.h>
37845 +#include <asm/checksum.h>
37846 +#include "ubi32-eth.h"
37847 +#include <asm/ip5000.h>
37848 +#include <asm/devtree.h>
37849 +#include <asm/system.h>
37850 +
37851 +/* #define USE_POLLING */
37852 +
37853 +/*
37854 + * TODO:
37855 + * mac address from flash
37856 + * multicast filter
37857 + * ethtool support
37858 + * sysfs support
37859 + * skb->nrfrag support
37860 + * ioctl
37861 + * monitor phy status
37862 + */
37863 +
37864 +static const char *eth_if_name[UBI32_ETH_NUM_OF_DEVICES] =
37865 +       {"eth_lan", "eth_wan", "eth_ultra"};
37866 +static struct net_device *ubi32_eth_devices[UBI32_ETH_NUM_OF_DEVICES] =
37867 +       {NULL, NULL, NULL};
37868 +static u8_t mac_addr[UBI32_ETH_NUM_OF_DEVICES][ETH_ALEN] = {
37869 +       {0x00, 0x03, 0x64, 'l', 'a', 'n'},
37870 +       {0x00, 0x03, 0x64, 'w', 'a', 'n'},
37871 +       {0x00, 0x03, 0x64, 'u', 'l', 't'}};
37872 +
37873 +int ubi32_eth_ocm_alloc;
37874 +int ubi32_eth_ddr_alloc;
37875 +
37876 +static inline struct sk_buff *ubi32_alloc_skb(struct net_device *dev, unsigned int length)
37877 +{
37878 +#if (defined(CONFIG_ZONE_DMA) && defined(CONFIG_UBICOM32_OCM_FOR_SKB))
37879 +       struct sk_buff *sk_buff;
37880 +
37881 +       if (dev != ubi32_eth_devices[0])
37882 +               return __dev_alloc_skb(length, GFP_ATOMIC);
37883 +
37884 +       sk_buff = __dev_alloc_skb(length, GFP_ATOMIC | __GFP_NOWARN | __GFP_NORETRY | GFP_DMA);
37885 +       if (sk_buff) {
37886 +               ubi32_eth_ocm_alloc++;
37887 +               return sk_buff;
37888 +       } else {
37889 +               ubi32_eth_ddr_alloc++;
37890 +               return __dev_alloc_skb(length, GFP_ATOMIC);
37891 +       }
37892 +#else
37893 +       return __dev_alloc_skb(length, GFP_ATOMIC);
37894 +#endif
37895 +}
37896 +
37897 +static void ubi32_eth_vp_rxtx_enable(struct net_device *dev)
37898 +{
37899 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37900 +       priv->regs->command = UBI32_ETH_VP_CMD_RX_ENABLE | UBI32_ETH_VP_CMD_TX_ENABLE;
37901 +       priv->regs->int_mask = (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
37902 +       ubicom32_set_interrupt(priv->vp_int_bit);
37903 +}
37904 +
37905 +static void ubi32_eth_vp_rxtx_stop(struct net_device *dev)
37906 +{
37907 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37908 +       priv->regs->command = 0;
37909 +       priv->regs->int_mask = 0;
37910 +       ubicom32_set_interrupt(priv->vp_int_bit);
37911 +
37912 +       /* Wait for graceful shutdown */
37913 +       while (priv->regs->status & (UBI32_ETH_VP_STATUS_RX_STATE | UBI32_ETH_VP_STATUS_TX_STATE));
37914 +}
37915 +
37916 +/*
37917 + * ubi32_eth_tx_done()
37918 + */
37919 +static int ubi32_eth_tx_done(struct net_device *dev)
37920 +{
37921 +       struct ubi32_eth_private *priv;
37922 +       struct sk_buff *skb;
37923 +       volatile void *pdata;
37924 +       struct ubi32_eth_dma_desc *desc;
37925 +       u32_t   count = 0;
37926 +
37927 +       priv = netdev_priv(dev);
37928 +
37929 +       priv->regs->int_status &= ~UBI32_ETH_VP_INT_TX;
37930 +       while (priv->tx_tail != priv->regs->tx_out) {
37931 +               pdata = priv->regs->tx_dma_ring[priv->tx_tail];
37932 +               BUG_ON(pdata == NULL);
37933 +
37934 +               skb = container_of((void *)pdata, struct sk_buff, cb);
37935 +               desc = (struct ubi32_eth_dma_desc *)pdata;
37936 +               if (unlikely(!(desc->status & UBI32_ETH_VP_TX_OK))) {
37937 +                       atomic_inc((atomic_t *)&priv->stats.tx_errors);
37938 +               } else {
37939 +                       priv->stats.tx_packets++;
37940 +                       priv->stats.tx_bytes += skb->len;
37941 +               }
37942 +               dev_kfree_skb_any(skb);
37943 +               priv->regs->tx_dma_ring[priv->tx_tail] = NULL;
37944 +               priv->tx_tail = (priv->tx_tail + 1) & TX_DMA_RING_MASK;
37945 +               count++;
37946 +       }
37947 +
37948 +       if (unlikely(priv->status & UBI32_ETH_PRIV_STATUS_TX_Q_FULL)) {
37949 +               spin_lock(&priv->lock);
37950 +               priv->status &= ~UBI32_ETH_PRIV_STATUS_TX_Q_FULL;
37951 +               netif_wake_queue(dev);
37952 +               spin_unlock(&priv->lock);
37953 +       }
37954 +       return count;
37955 +}
37956 +
37957 +/*
37958 + * ubi32_eth_receive()
37959 + *     To avoid locking overhead, this is called only
37960 + *     by tasklet when not using NAPI, or
37961 + *     by NAPI poll when using NAPI.
37962 + *     return number of frames processed
37963 + */
37964 +static int ubi32_eth_receive(struct net_device *dev, int quota)
37965 +{
37966 +       struct ubi32_eth_private *priv = netdev_priv(dev);
37967 +       unsigned short rx_in = priv->regs->rx_in;
37968 +       struct sk_buff *skb;
37969 +       struct ubi32_eth_dma_desc *desc = NULL;
37970 +       volatile void *pdata;
37971 +
37972 +       /* The number of NET_SKB_PAD bytes are already reserved by skb */
37973 +       int extra_reserve = UBI32_ETH_RESERVE_SPACE - NET_SKB_PAD + UBI32_ETH_RESERVE_EXTRA;
37974 +       int extra_alloc = extra_reserve + UBI32_ETH_TRASHED_MEMORY;
37975 +       int i, replenish_cnt, count = 0;
37976 +       int replenish_max = RX_DMA_MAX_QUEUE_SIZE;
37977 +#if (defined(CONFIG_ZONE_DMA) && defined(CONFIG_UBICOM32_OCM_FOR_SKB))
37978 +       if (dev == ubi32_eth_devices[0])
37979 +               replenish_max = 21;
37980 +#endif
37981 +       BUG_ON((extra_reserve & 3) != NET_IP_ALIGN);    /* Must provide NET_IP_ALIGN (0 or 2) */
37982 +
37983 +       if (unlikely(rx_in == priv->regs->rx_out))
37984 +               priv->vp_stats.rx_q_full_cnt++;
37985 +
37986 +       priv->regs->int_status &= ~UBI32_ETH_VP_INT_RX;
37987 +       while (priv->rx_tail != priv->regs->rx_out) {
37988 +               if (unlikely(count == quota)) {
37989 +                       /* There is still frame pending to be processed */
37990 +                       priv->vp_stats.rx_throttle++;
37991 +                       break;
37992 +               }
37993 +
37994 +               pdata = priv->regs->rx_dma_ring[priv->rx_tail];
37995 +               BUG_ON(pdata == NULL);
37996 +
37997 +               desc = (struct ubi32_eth_dma_desc *)pdata;
37998 +               skb = container_of((void *)pdata, struct sk_buff, cb);
37999 +               count++;
38000 +               priv->regs->rx_dma_ring[priv->rx_tail] = NULL;
38001 +               priv->rx_tail = ((priv->rx_tail + 1) & RX_DMA_RING_MASK);
38002 +
38003 +               /*
38004 +                * Check only RX_OK bit here.
38005 +                * The rest of status word is used as timestamp
38006 +                */
38007 +               if (unlikely(!(desc->status & UBI32_ETH_VP_RX_OK))) {
38008 +                       priv->stats.rx_errors++;
38009 +                       dev_kfree_skb_any(skb);
38010 +                       continue;
38011 +               }
38012 +
38013 +               skb_put(skb, desc->data_len);
38014 +               skb->dev = dev;
38015 +               skb->protocol = eth_type_trans(skb, dev);
38016 +               skb->ip_summed = CHECKSUM_NONE;
38017 +               priv->stats.rx_bytes += skb->len;
38018 +               priv->stats.rx_packets++;
38019 +#ifndef CONFIG_UBICOM32_NAPI
38020 +               netif_rx(skb);
38021 +#else
38022 +               netif_receive_skb(skb);
38023 +#endif
38024 +       }
38025 +
38026 +       /* fill in more descripor for VP*/
38027 +       replenish_cnt =  replenish_max -
38028 +               ((RX_DMA_RING_SIZE + rx_in - priv->rx_tail) & RX_DMA_RING_MASK);
38029 +       if (replenish_cnt > 0) {
38030 +               for (i = 0; i < replenish_cnt; i++) {
38031 +                       skb = ubi32_alloc_skb(dev, RX_BUF_SIZE + extra_alloc);
38032 +                       if (!skb) {
38033 +                               priv->vp_stats.rx_alloc_err++;
38034 +                               break;
38035 +                       }
38036 +                       /* set up dma descriptor */
38037 +                       desc = (struct ubi32_eth_dma_desc *)skb->cb;
38038 +                       skb_reserve(skb, extra_reserve);
38039 +                       BUG_ON((((u32)skb->data + ETH_HLEN) & (CACHE_LINE_SIZE - 1)) != 0);
38040 +                       desc->data_pointer = skb->data;
38041 +                       desc->buffer_len = RX_BUF_SIZE + UBI32_ETH_TRASHED_MEMORY;
38042 +                       desc->data_len = 0;
38043 +                       desc->status = 0;
38044 +                       priv->regs->rx_dma_ring[rx_in] = desc;
38045 +                       rx_in = (rx_in + 1) & RX_DMA_RING_MASK;
38046 +               }
38047 +               wmb();
38048 +               priv->regs->rx_in = rx_in;
38049 +               ubicom32_set_interrupt(priv->vp_int_bit);
38050 +       }
38051 +
38052 +       if (likely(count > 0)) {
38053 +               dev->last_rx = jiffies;
38054 +       }
38055 +       return count;
38056 +}
38057 +
38058 +#ifdef CONFIG_UBICOM32_NAPI
38059 +static int ubi32_eth_napi_poll(struct napi_struct *napi, int budget)
38060 +{
38061 +       struct ubi32_eth_private *priv = container_of(napi, struct ubi32_eth_private, napi);
38062 +       struct net_device *dev = priv->dev;
38063 +       u32_t count;
38064 +
38065 +       if (priv->tx_tail != priv->regs->tx_out) {
38066 +                ubi32_eth_tx_done(dev);
38067 +        }
38068 +
38069 +       count = ubi32_eth_receive(dev, budget);
38070 +
38071 +       priv->regs->int_mask |= (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
38072 +       if (count < budget) {
38073 +               netif_rx_complete(dev, napi);
38074 +               if ((priv->rx_tail != priv->regs->rx_out) || (priv->tx_tail != priv->regs->tx_out)) {
38075 +                       if (netif_rx_reschedule(dev, napi)) {
38076 +                               priv->regs->int_mask = 0;
38077 +                       }
38078 +               }
38079 +       }
38080 +       return count;
38081 +}
38082 +
38083 +#else
38084 +static void ubi32_eth_do_tasklet(unsigned long arg)
38085 +{
38086 +       struct net_device *dev = (struct net_device *)arg;
38087 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38088 +
38089 +       if (priv->tx_tail != priv->regs->tx_out) {
38090 +               ubi32_eth_tx_done(dev);
38091 +       }
38092 +
38093 +       /* always call receive to process new RX frame as well as replenish RX buffers */
38094 +       ubi32_eth_receive(dev, RX_BOUND);
38095 +
38096 +       priv->regs->int_mask |= (UBI32_ETH_VP_INT_RX | UBI32_ETH_VP_INT_TX);
38097 +       if ((priv->rx_tail != priv->regs->rx_out) || (priv->tx_tail != priv->regs->tx_out)) {
38098 +               priv->regs->int_mask = 0;
38099 +               tasklet_schedule(&priv->tsk);
38100 +       }
38101 +}
38102 +#endif
38103 +
38104 +#if defined(USE_POLLING)
38105 +static struct timer_list eth_poll_timer;
38106 +
38107 +static void ubi32_eth_poll(unsigned long arg)
38108 +{
38109 +       struct net_device *dev;
38110 +       struct ubi32_eth_private *priv;
38111 +       int i;
38112 +
38113 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38114 +               dev = ubi32_eth_devices[i];
38115 +               if (dev && (dev->flags & IFF_UP)) {
38116 +                       priv = netdev_priv(dev);
38117 +#ifdef CONFIG_UBICOM32_NAPI
38118 +                       netif_rx_schedule(dev, &priv->napi);
38119 +#else
38120 +                       tasklet_schedule(&priv->tsk);
38121 +#endif
38122 +               }
38123 +       }
38124 +
38125 +       eth_poll_timer.expires = jiffies + 2;
38126 +       add_timer(&eth_poll_timer);
38127 +}
38128 +
38129 +#else
38130 +static irqreturn_t ubi32_eth_interrupt(int irq, void *dev_id)
38131 +{
38132 +       struct ubi32_eth_private *priv;
38133 +
38134 +       struct net_device *dev = (struct net_device *)dev_id;
38135 +       BUG_ON(irq != dev->irq);
38136 +
38137 +       priv = netdev_priv(dev);
38138 +       if (unlikely(!(priv->regs->int_status & priv->regs->int_mask))) {
38139 +               return IRQ_NONE;
38140 +       }
38141 +
38142 +       /*
38143 +        * Disable port interrupt
38144 +        */
38145 +#ifdef CONFIG_UBICOM32_NAPI
38146 +       if (netif_rx_schedule_prep(dev, &priv->napi)) {
38147 +               priv->regs->int_mask = 0;
38148 +               __netif_rx_schedule(dev, &priv->napi);
38149 +       }
38150 +#else
38151 +       priv->regs->int_mask = 0;
38152 +       tasklet_schedule(&priv->tsk);
38153 +#endif
38154 +       return IRQ_HANDLED;
38155 +}
38156 +#endif
38157 +
38158 +/*
38159 + * ubi32_eth_open
38160 + */
38161 +static int ubi32_eth_open(struct net_device *dev)
38162 +{
38163 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38164 +       int err;
38165 +
38166 +       printk(KERN_INFO "eth open %s\n",dev->name);
38167 +#ifndef USE_POLLING
38168 +       /* request_region() */
38169 +       err = request_irq(dev->irq, ubi32_eth_interrupt, IRQF_DISABLED, dev->name, dev);
38170 +       if (err) {
38171 +               printk(KERN_WARNING "fail to request_irq %d\n",err);
38172 +                return -ENODEV;
38173 +       }
38174 +#endif
38175 +#ifdef  CONFIG_UBICOM32_NAPI
38176 +       napi_enable(&priv->napi);
38177 +#else
38178 +       tasklet_init(&priv->tsk, ubi32_eth_do_tasklet, (unsigned long)dev);
38179 +#endif
38180 +
38181 +       /* call receive to supply RX buffers */
38182 +       ubi32_eth_receive(dev, RX_DMA_MAX_QUEUE_SIZE);
38183 +
38184 +       /* check phy status and call netif_carrier_on */
38185 +       ubi32_eth_vp_rxtx_enable(dev);
38186 +       netif_start_queue(dev);
38187 +       return 0;
38188 +}
38189 +
38190 +static int ubi32_eth_close(struct net_device *dev)
38191 +{
38192 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38193 +       volatile void *pdata;
38194 +       struct sk_buff *skb;
38195 +
38196 +#ifndef USE_POLLING
38197 +       free_irq(dev->irq, dev);
38198 +#endif
38199 +       netif_stop_queue(dev); /* can't transmit any more */
38200 +#ifdef CONFIG_UBICOM32_NAPI
38201 +       napi_disable(&priv->napi);
38202 +#else
38203 +       tasklet_kill(&priv->tsk);
38204 +#endif
38205 +       ubi32_eth_vp_rxtx_stop(dev);
38206 +
38207 +       /*
38208 +        * RX clean up
38209 +        */
38210 +       while (priv->rx_tail != priv->regs->rx_in) {
38211 +               pdata = priv->regs->rx_dma_ring[priv->rx_tail];
38212 +               skb = container_of((void *)pdata, struct sk_buff, cb);
38213 +               priv->regs->rx_dma_ring[priv->rx_tail] = NULL;
38214 +               dev_kfree_skb_any(skb);
38215 +               priv->rx_tail = ((priv->rx_tail + 1) & RX_DMA_RING_MASK);
38216 +       }
38217 +       priv->regs->rx_in = 0;
38218 +       priv->regs->rx_out = priv->regs->rx_in;
38219 +       priv->rx_tail = priv->regs->rx_in;
38220 +
38221 +       /*
38222 +        * TX clean up
38223 +        */
38224 +       BUG_ON(priv->regs->tx_out != priv->regs->tx_in);
38225 +       ubi32_eth_tx_done(dev);
38226 +       BUG_ON(priv->tx_tail != priv->regs->tx_in);
38227 +       priv->regs->tx_in = 0;
38228 +       priv->regs->tx_out = priv->regs->tx_in;
38229 +       priv->tx_tail = priv->regs->tx_in;
38230 +
38231 +       return 0;
38232 +}
38233 +
38234 +/*
38235 + * ubi32_eth_set_config
38236 + */
38237 +static int ubi32_eth_set_config(struct net_device *dev, struct ifmap *map)
38238 +{
38239 +       /* if must to down to config it */
38240 +       printk(KERN_INFO "set_config %x\n", dev->flags);
38241 +       if (dev->flags & IFF_UP)
38242 +               return -EBUSY;
38243 +
38244 +       /* I/O and IRQ can not be changed */
38245 +       if (map->base_addr != dev->base_addr) {
38246 +               printk(KERN_WARNING "%s: Can't change I/O address\n", dev->name);
38247 +               return -EOPNOTSUPP;
38248 +       }
38249 +
38250 +#ifndef USE_POLLING
38251 +       if (map->irq != dev->irq) {
38252 +               printk(KERN_WARNING "%s: Can't change IRQ\n", dev->name);
38253 +               return -EOPNOTSUPP;
38254 +       }
38255 +#endif
38256 +
38257 +       /* ignore other fields */
38258 +       return 0;
38259 +}
38260 +
38261 +static int ubi32_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
38262 +{
38263 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38264 +       struct ubi32_eth_dma_desc *desc = NULL;
38265 +       unsigned short space, tx_in;
38266 +
38267 +       tx_in = priv->regs->tx_in;
38268 +
38269 +       dev->trans_start = jiffies; /* save the timestamp */
38270 +       space = TX_DMA_RING_MASK - ((TX_DMA_RING_SIZE + tx_in - priv->tx_tail) & TX_DMA_RING_MASK);
38271 +
38272 +       if (unlikely(space == 0)) {
38273 +               atomic_inc((atomic_t *)&priv->stats.tx_errors);
38274 +               if (!(priv->status & UBI32_ETH_PRIV_STATUS_TX_Q_FULL)) {
38275 +                       spin_lock(&priv->lock);
38276 +                       priv->status |= UBI32_ETH_PRIV_STATUS_TX_Q_FULL;
38277 +                       priv->vp_stats.tx_q_full_cnt++;
38278 +                       netif_stop_queue(dev);
38279 +                       spin_unlock(&priv->lock);
38280 +               }
38281 +
38282 +               /* give both HW and this driver an extra trigger */
38283 +               priv->regs->int_mask |= UBI32_ETH_VP_INT_TX;
38284 +#ifndef USE_POLLING
38285 +               ubicom32_set_interrupt(dev->irq);
38286 +#endif
38287 +               ubicom32_set_interrupt(priv->vp_int_bit);
38288 +
38289 +               return NETDEV_TX_BUSY;
38290 +       }
38291 +
38292 +       /*still have room */
38293 +       desc = (struct ubi32_eth_dma_desc *)skb->cb;
38294 +       desc->data_pointer = skb->data;
38295 +       desc->data_len = skb->len;
38296 +       priv->regs->tx_dma_ring[tx_in] = desc;
38297 +       tx_in = ((tx_in + 1) & TX_DMA_RING_MASK);
38298 +       wmb();
38299 +       priv->regs->tx_in = tx_in;
38300 +       /* kick the HRT */
38301 +       ubicom32_set_interrupt(priv->vp_int_bit);
38302 +
38303 +       return 0;
38304 +}
38305 +
38306 +/*
38307 + * Deal with a transmit timeout.
38308 + */
38309 +static void ubi32_eth_tx_timeout (struct net_device *dev)
38310 +{
38311 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38312 +       atomic_inc((atomic_t *)&priv->stats.tx_errors);
38313 +       priv->regs->int_mask |= UBI32_ETH_VP_INT_TX;
38314 +#ifndef USE_POLLING
38315 +       ubicom32_set_interrupt(dev->irq);
38316 +#endif
38317 +       ubicom32_set_interrupt(priv->vp_int_bit);
38318 +}
38319 +
38320 +static int ubi32_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
38321 +{
38322 +       printk(KERN_INFO "ioctl %s, %d\n", dev->name, cmd);
38323 +       return -EINVAL;
38324 +}
38325 +
38326 +/*
38327 + * Return statistics to the caller
38328 + */
38329 +static struct net_device_stats *ubi32_eth_get_stats(struct net_device *dev)
38330 +{
38331 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38332 +       return &priv->stats;
38333 +}
38334 +
38335 +
38336 +static int ubi32_eth_change_mtu(struct net_device *dev, int new_mtu)
38337 +{
38338 +       struct ubi32_eth_private *priv = netdev_priv(dev);
38339 +       unsigned long flags;
38340 +
38341 +       if ((new_mtu < 68) || (new_mtu > 1500))
38342 +               return -EINVAL;
38343 +
38344 +       spin_lock_irqsave(&priv->lock, flags);
38345 +       dev->mtu = new_mtu;
38346 +       spin_unlock_irqrestore(&priv->lock, flags);
38347 +       printk(KERN_INFO "set mtu to %d", new_mtu);
38348 +       return 0;
38349 +}
38350 +
38351 +/*
38352 + * ubi32_eth_cleanup: unload the module
38353 + */
38354 +void ubi32_eth_cleanup(void)
38355 +{
38356 +       struct ubi32_eth_private *priv;
38357 +       struct net_device *dev;
38358 +       int i;
38359 +
38360 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38361 +               dev = ubi32_eth_devices[i];
38362 +               if (dev) {
38363 +                       priv = netdev_priv(dev);
38364 +                       kfree(priv->regs->tx_dma_ring);
38365 +                       unregister_netdev(dev);
38366 +                       free_netdev(dev);
38367 +                       ubi32_eth_devices[i] = NULL;
38368 +               }
38369 +       }
38370 +}
38371 +
38372 +int ubi32_eth_init_module(void)
38373 +{
38374 +       struct ethtionode *eth_node;
38375 +       struct net_device *dev;
38376 +       struct ubi32_eth_private *priv;
38377 +       int i, err;
38378 +
38379 +       /*
38380 +        * Device allocation.
38381 +        */
38382 +       err = 0;
38383 +       for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38384 +               /*
38385 +                * See if the eth_vp is in the device tree.
38386 +                */
38387 +               eth_node = (struct ethtionode *)devtree_find_node(eth_if_name[i]);
38388 +               if (!eth_node) {
38389 +                       printk(KERN_INFO "%s does not exist\n", eth_if_name[i]);
38390 +                       continue;
38391 +               }
38392 +
38393 +               eth_node->tx_dma_ring = (struct ubi32_eth_dma_desc **)kmalloc(
38394 +                               sizeof(struct ubi32_eth_dma_desc *) *
38395 +                               (TX_DMA_RING_SIZE + RX_DMA_RING_SIZE), GFP_ATOMIC | __GFP_NOWARN | __GFP_NORETRY | GFP_DMA);
38396 +
38397 +               if (eth_node->tx_dma_ring == NULL) {
38398 +                       eth_node->tx_dma_ring = (struct ubi32_eth_dma_desc **)kmalloc(
38399 +                               sizeof(struct ubi32_eth_dma_desc *) *
38400 +                               (TX_DMA_RING_SIZE + RX_DMA_RING_SIZE), GFP_KERNEL);
38401 +                       printk(KERN_INFO "Failed to allocate from OCM\n");
38402 +               }
38403 +
38404 +               if (!eth_node->tx_dma_ring) {
38405 +                       err = -ENOMEM;
38406 +                       break;
38407 +               }
38408 +               eth_node->rx_dma_ring = eth_node->tx_dma_ring + TX_DMA_RING_SIZE;
38409 +               eth_node->tx_sz = TX_DMA_RING_SIZE - 1;
38410 +               eth_node->rx_sz = RX_DMA_RING_SIZE - 1;
38411 +
38412 +               dev = alloc_etherdev(sizeof(struct ubi32_eth_private));
38413 +               if (!dev) {
38414 +                       kfree(eth_node->tx_dma_ring);
38415 +                       err = -ENOMEM;
38416 +                       break;
38417 +               }
38418 +               priv = netdev_priv(dev);
38419 +               priv->dev = dev;
38420 +
38421 +               /*
38422 +                * FIX IT! get proper mac address
38423 +                */
38424 +               memcpy(dev->dev_addr, mac_addr[i], ETH_ALEN);
38425 +
38426 +               priv->regs = eth_node;
38427 +               priv->regs->command = 0;
38428 +               priv->regs->int_mask = 0;
38429 +               priv->regs->int_status = 0;
38430 +               priv->regs->tx_out = 0;
38431 +               priv->regs->rx_out = 0;
38432 +               priv->regs->tx_in = 0;
38433 +               priv->regs->rx_in = 0;
38434 +               priv->rx_tail = 0;
38435 +               priv->tx_tail = 0;
38436 +
38437 +               priv->vp_int_bit = eth_node->dn.sendirq;
38438 +               dev->irq = eth_node->dn.recvirq;
38439 +
38440 +               spin_lock_init(&priv->lock);
38441 +
38442 +               dev->open               = ubi32_eth_open;
38443 +               dev->stop               = ubi32_eth_close;
38444 +               dev->hard_start_xmit    = ubi32_eth_start_xmit;
38445 +               dev->tx_timeout         = ubi32_eth_tx_timeout;
38446 +               dev->watchdog_timeo     = UBI32_ETH_VP_TX_TIMEOUT;
38447 +
38448 +               dev->set_config         = ubi32_eth_set_config;
38449 +               dev->do_ioctl           = ubi32_eth_ioctl;
38450 +               dev->get_stats          = ubi32_eth_get_stats;
38451 +               dev->change_mtu         = ubi32_eth_change_mtu;
38452 +#ifdef CONFIG_UBICOM32_NAPI
38453 +               netif_napi_add(dev, &priv->napi, ubi32_eth_napi_poll, UBI32_ETH_NAPI_WEIGHT);
38454 +#endif
38455 +               err = register_netdev(dev);
38456 +               if (err) {
38457 +                       printk(KERN_WARNING "Failed to register netdev %s\n", eth_if_name[i]);
38458 +                       //release_region();
38459 +                       free_netdev(dev);
38460 +                       kfree(eth_node->tx_dma_ring);
38461 +                       break;
38462 +               }
38463 +
38464 +               ubi32_eth_devices[i] = dev;
38465 +               printk(KERN_INFO "%s vp_base:0x%p, tio_int:%d irq:%d\n",
38466 +                       dev->name, priv->regs, eth_node->dn.sendirq, dev->irq);
38467 +       }
38468 +
38469 +       if (err) {
38470 +               ubi32_eth_cleanup();
38471 +               return err;
38472 +       }
38473 +
38474 +       if (!ubi32_eth_devices[0] && !ubi32_eth_devices[1] && !ubi32_eth_devices[2]) {
38475 +               return -ENODEV;
38476 +       }
38477 +
38478 +#if defined(USE_POLLING)
38479 +       init_timer(&eth_poll_timer);
38480 +       eth_poll_timer.function = ubi32_eth_poll;
38481 +       eth_poll_timer.data = (unsigned long)0;
38482 +       eth_poll_timer.expires = jiffies + 2;
38483 +       add_timer(&eth_poll_timer);
38484 +#endif
38485 +
38486 +       return 0;
38487 +}
38488 +
38489 +module_init(ubi32_eth_init_module);
38490 +module_exit(ubi32_eth_cleanup);
38491 +
38492 +MODULE_AUTHOR("Kan Yan, Greg Ren");
38493 +MODULE_LICENSE("GPL");
38494 --- /dev/null
38495 +++ b/drivers/net/ubi32-eth.h
38496 @@ -0,0 +1,133 @@
38497 +/*
38498 + * drivers/net/ubi32-eth.h
38499 + *   Ubicom32 ethernet TIO interface driver definitions.
38500 + *
38501 + * (C) Copyright 2009, Ubicom, Inc.
38502 + *
38503 + * This file is part of the Ubicom32 Linux Kernel Port.
38504 + *
38505 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
38506 + * it and/or modify it under the terms of the GNU General Public License
38507 + * as published by the Free Software Foundation, either version 2 of the
38508 + * License, or (at your option) any later version.
38509 + *
38510 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
38511 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
38512 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
38513 + * the GNU General Public License for more details.
38514 + *
38515 + * You should have received a copy of the GNU General Public License
38516 + * along with the Ubicom32 Linux Kernel Port.  If not,
38517 + * see <http://www.gnu.org/licenses/>.
38518 + *
38519 + * Ubicom32 implementation derived from (with many thanks):
38520 + *   arch/m68knommu
38521 + *   arch/blackfin
38522 + *   arch/parisc
38523 + */
38524 +#ifndef _UBI32_ETH_H
38525 +#define _UBI32_ETH_H
38526 +
38527 +#include <asm/devtree.h>
38528 +
38529 +#define UBI32_ETH_NUM_OF_DEVICES 3
38530 +
38531 +/*
38532 + * Number of bytes trashed beyond the packet data.
38533 + */
38534 +#define UBI32_ETH_TRASHED_MEMORY       (CACHE_LINE_SIZE + ETH_HLEN - 1)
38535 +
38536 +/*
38537 + * Linux already reserves NET_SKB_PAD bytes of headroom in each sk_buff.
38538 + * We want to be able to reserve arbitrarily more space to align Ethernet
38539 + * and IP header to cache line.
38540 + * Note that the TIO expects a CACHE_LINE_SIZE - ETH_HLEN aligned Ethernet
38541 + * header, so the reserved space must be NET_SKB_PAD + NET_IP_ALIGN.
38542 + * (NET_SKB_PAD is 16, NET_IP_ALIGN is 2, CACHE_LINE_SIZE is 32).
38543 + * You can add more space by making UBI32_ETH_iRESERVE_EXTRA != 0.
38544 + */
38545 +#define UBI32_ETH_RESERVE_SPACE        (CACHE_LINE_SIZE - ETH_HLEN)
38546 +#define UBI32_ETH_RESERVE_EXTRA (1 * CACHE_LINE_SIZE)
38547 +
38548 +struct ubi32_eth_dma_desc {
38549 +       volatile void   *data_pointer;  /* pointer to the buffer */
38550 +       volatile u16    buffer_len;     /* the buffer size */
38551 +       volatile u16    data_len;       /* actual frame length */
38552 +       volatile u32    status;         /* bit0: status to be update by VP; bit[31:1] time stamp */
38553 +};
38554 +
38555 +#define TX_DMA_RING_SIZE (1<<8)
38556 +#define TX_DMA_RING_MASK (TX_DMA_RING_SIZE - 1)
38557 +#define RX_DMA_RING_SIZE (1<<8)
38558 +#define RX_DMA_RING_MASK (RX_DMA_RING_SIZE - 1)
38559 +
38560 +#define RX_DMA_MAX_QUEUE_SIZE (RX_DMA_RING_SIZE - 1)   /* no more than (RX_DMA_RING_SIZE - 1) */
38561 +#define RX_MAX_PKT_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN)
38562 +#define RX_MIN_PKT_SIZE        ETH_ZLEN
38563 +#define RX_BUF_SIZE (RX_MAX_PKT_SIZE + VLAN_HLEN)      /* allow double VLAN tag */
38564 +
38565 +#define UBI32_ETH_VP_TX_TIMEOUT (10*HZ)
38566 +
38567 +struct ubi32_eth_vp_stats {
38568 +       u32     rx_alloc_err;
38569 +       u32     tx_q_full_cnt;
38570 +       u32     rx_q_full_cnt;
38571 +       u32     rx_throttle;
38572 +};
38573 +
38574 +struct ubi32_eth_private {
38575 +       struct net_device *dev;
38576 +       struct net_device_stats stats;
38577 +       struct ubi32_eth_vp_stats vp_stats;
38578 +       int status;
38579 +       spinlock_t lock;
38580 +#ifdef CONFIG_UBICOM32_NAPI
38581 +       struct napi_struct napi;
38582 +#else
38583 +       struct tasklet_struct tsk;
38584 +#endif
38585 +       struct ethtionode *regs;
38586 +       u16     rx_tail;
38587 +       u16     tx_tail;
38588 +       u32     vp_int_bit;
38589 +};
38590 +
38591 +struct ethtionode {
38592 +       struct devtree_node dn;
38593 +       volatile u16    command;
38594 +       volatile u16    status;
38595 +       volatile u16    int_mask;       /* interrupt mask */
38596 +       volatile u16    int_status;     /* interrupt mask */
38597 +       volatile u16    tx_in;          /* owned by driver */
38598 +       volatile u16    tx_out;         /* owned by vp */
38599 +       volatile u16    rx_in;          /* owned by driver */
38600 +       volatile u16    rx_out;         /* owned by vp */
38601 +       u16             tx_sz;          /* owned by driver */
38602 +       u16             rx_sz;          /* owned by driver */
38603 +       struct ubi32_eth_dma_desc **tx_dma_ring;
38604 +       struct ubi32_eth_dma_desc **rx_dma_ring;
38605 +};
38606 +
38607 +#define UBI32_ETH_VP_STATUS_LINK       (1<<0)
38608 +#define UBI32_ETH_VP_STATUS_SPEED      (0x2<<1)
38609 +#define UBI32_ETH_VP_STATUS_DUPLEX     (0x1<<3)
38610 +#define UBI32_ETH_VP_STATUS_FLOW_CTRL  (0x1<<4)
38611 +
38612 +#define UBI32_ETH_VP_STATUS_RX_STATE   (0x1<<5)
38613 +#define UBI32_ETH_VP_STATUS_TX_STATE   (0x1<<6)
38614 +
38615 +#define UBI32_ETH_PRIV_STATUS_TX_Q_FULL        (1<<0)
38616 +
38617 +#define UBI32_ETH_VP_INT_RX    (1<<0)
38618 +#define UBI32_ETH_VP_INT_TX    (1<<1)
38619 +
38620 +#define UBI32_ETH_VP_CMD_RX_ENABLE     (1<<0)
38621 +#define UBI32_ETH_VP_CMD_TX_ENABLE     (1<<1)
38622 +
38623 +#define UBI32_ETH_VP_RX_OK             (1<<0)
38624 +#define UBI32_ETH_VP_TX_OK             (1<<1)
38625 +
38626 +#define TX_BOUND               TX_DMA_RING_SIZE
38627 +#define RX_BOUND               64
38628 +#define UBI32_ETH_NAPI_WEIGHT  64              /* for GigE */
38629 +#endif
38630 --- a/drivers/net/usb/asix.c
38631 +++ b/drivers/net/usb/asix.c
38632 @@ -318,14 +318,33 @@ static int asix_rx_fixup(struct usbnet *
38633                 /* get the packet length */
38634                 size = (u16) (header & 0x0000ffff);
38635  
38636 -               if ((skb->len) - ((size + 1) & 0xfffe) == 0)
38637 +               if ((skb->len) - ((size + 1) & 0xfffe) == 0) {
38638 +#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
38639 +                       if (((u32)packet & 0x02) == 0) {
38640 +                               memmove(packet - 2, packet, size);
38641 +                               skb->data -= 2;
38642 +                               skb->tail -= 2;
38643 +                       }
38644 +#endif
38645                         return 2;
38646 +               }
38647 +
38648                 if (size > ETH_FRAME_LEN) {
38649                         deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);
38650                         return 0;
38651                 }
38652                 ax_skb = skb_clone(skb, GFP_ATOMIC);
38653                 if (ax_skb) {
38654 +#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
38655 +                       if (((u32)packet & 0x02) == 0) {
38656 +                               memmove(packet - 2, packet, size);
38657 +                               ax_skb->data = packet - 2;
38658 +                       } else {
38659 +                               ax_skb->data = packet;
38660 +                       }
38661 +#else
38662 +                       ax_skb->data = packet;
38663 +#endif
38664                         ax_skb->len = size;
38665                         ax_skb->data = packet;
38666                         skb_set_tail_pointer(ax_skb, size);
38667 @@ -1102,13 +1121,19 @@ static int ax88178_link_reset(struct usb
38668         mode = AX88178_MEDIUM_DEFAULT;
38669  
38670         if (ecmd.speed == SPEED_1000)
38671 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38672                 mode |= AX_MEDIUM_GM;
38673 +#else
38674 +               mode |= AX_MEDIUM_GM | AX_MEDIUM_ENCK;
38675 +#endif
38676         else if (ecmd.speed == SPEED_100)
38677                 mode |= AX_MEDIUM_PS;
38678         else
38679                 mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
38680  
38681 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38682         mode |= AX_MEDIUM_ENCK;
38683 +#endif
38684  
38685         if (ecmd.duplex == DUPLEX_FULL)
38686                 mode |= AX_MEDIUM_FD;
38687 --- a/drivers/oprofile/cpu_buffer.c
38688 +++ b/drivers/oprofile/cpu_buffer.c
38689 @@ -240,10 +240,11 @@ static void oprofile_end_trace(struct op
38690         cpu_buf->tracing = 0;
38691  }
38692  
38693 -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38694 -                               unsigned long event, int is_kernel)
38695 +
38696 +void oprofile_add_ext_sample_cpu(unsigned long pc, struct pt_regs * const regs,
38697 +                               unsigned long event, int is_kernel, int cpu)
38698  {
38699 -       struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
38700 +       struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu);
38701  
38702         if (!backtrace_depth) {
38703                 log_sample(cpu_buf, pc, is_kernel, event);
38704 @@ -260,6 +261,13 @@ void oprofile_add_ext_sample(unsigned lo
38705         oprofile_end_trace(cpu_buf);
38706  }
38707  
38708 +void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38709 +                               unsigned long event, int is_kernel)
38710 +{
38711 +       oprofile_add_ext_sample_cpu(pc, regs, event,
38712 +                                       is_kernel, smp_processor_id());
38713 +}
38714 +
38715  void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
38716  {
38717         int is_kernel = !user_mode(regs);
38718 --- a/drivers/pci/Makefile
38719 +++ b/drivers/pci/Makefile
38720 @@ -42,8 +42,8 @@ obj-$(CONFIG_PPC) += setup-bus.o
38721  obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
38722  obj-$(CONFIG_X86_VISWS) += setup-irq.o
38723  obj-$(CONFIG_MN10300) += setup-bus.o
38724 +obj-$(CONFIG_UBICOM32) += setup-bus.o setup-irq.o
38725  
38726 -#
38727  # ACPI Related PCI FW Functions
38728  #
38729  obj-$(CONFIG_ACPI)    += pci-acpi.o
38730 --- a/drivers/serial/Kconfig
38731 +++ b/drivers/serial/Kconfig
38732 @@ -827,6 +827,57 @@ config SERIAL_UARTLITE_CONSOLE
38733           console (the system console is the device which receives all kernel
38734           messages and warnings and which allows logins in single user mode).
38735  
38736 +config SERIAL_UBI32_UARTTIO
38737 +        tristate "Ubicom UARTTIO support"
38738 +        depends on UBICOM32=y
38739 +        select SERIAL_CORE
38740 +       default y
38741 +        help
38742 +          Add support for the Ubicom virtual peripherial serial interface.
38743 +
38744 +config SERIAL_UBI32_UARTTIO_NR_UARTS
38745 +       int "Maximum number of UARTTIO virtual serial ports"
38746 +       depends on SERIAL_UBI32_UARTTIO
38747 +       default "4"
38748 +       help
38749 +         Set this to the maximum number of serial ports you want the driver to support.  
38750 +
38751 +config SERIAL_UBI32_UARTTIO_CONSOLE
38752 +        tristate "Ubicom UARTTIO console support"
38753 +        depends on SERIAL_UBI32_UARTTIO=y
38754 +        select SERIAL_CORE_CONSOLE
38755 +       default y
38756 +        help
38757 +          Add support for console on the Ubicom virtual peripherial serial interface.
38758 +
38759 +config SERIAL_UBI32_SERDES
38760 +        bool "Ubicom serial port support"
38761 +        depends on UBICOM32=y
38762 +        select SERIAL_CORE
38763 +       default y
38764 +        help
38765 +          Add support for the Ubicom serial interface.
38766 +
38767 +config SERIAL_UBI32_SERDES_CONSOLE
38768 +        bool "Ubicom serial console support"
38769 +        depends on SERIAL_UBI32_SERDES=y
38770 +        select SERIAL_CORE_CONSOLE
38771 +       default y
38772 +
38773 +config SERIAL_UBI32_MAILBOX
38774 +        bool "Ubicom mailbox support"
38775 +        depends on UBICOM32=y
38776 +        select SERIAL_CORE
38777 +       default n
38778 +        help
38779 +          Add support for the Ubicom mailbox interface.
38780 +
38781 +config SERIAL_UBI32_MAILBOX_CONSOLE
38782 +        bool "Ubicom mailbox console support"
38783 +        depends on SERIAL_UBI32_MAILBOX=y
38784 +        select SERIAL_CORE_CONSOLE
38785 +       default y
38786 +
38787  config SERIAL_SUNCORE
38788         bool
38789         depends on SPARC
38790 --- a/drivers/serial/Makefile
38791 +++ b/drivers/serial/Makefile
38792 @@ -73,3 +73,6 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_s
38793  obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
38794  obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
38795  obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
38796 +obj-$(CONFIG_SERIAL_UBI32_SERDES) += ubi32_serdes.o
38797 +obj-$(CONFIG_SERIAL_UBI32_UARTTIO) += ubi32_uarttio.o
38798 +obj-$(CONFIG_SERIAL_UBI32_MAILBOX) += ubi32_mailbox.o
38799 --- /dev/null
38800 +++ b/drivers/serial/ubi32_mailbox.c
38801 @@ -0,0 +1,928 @@
38802 +/*
38803 + * drivers/serial/ubi32_mailbox.c
38804 + *   Ubicom32 On-Chip Mailbox Driver
38805 + *
38806 + * (C) Copyright 2009, Ubicom, Inc.
38807 + *
38808 + * This file is part of the Ubicom32 Linux Kernel Port.
38809 + *
38810 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
38811 + * it and/or modify it under the terms of the GNU General Public License
38812 + * as published by the Free Software Foundation, either version 2 of the
38813 + * License, or (at your option) any later version.
38814 + *
38815 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
38816 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
38817 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
38818 + * the GNU General Public License for more details.
38819 + *
38820 + * You should have received a copy of the GNU General Public License
38821 + * along with the Ubicom32 Linux Kernel Port.  If not, 
38822 + * see <http://www.gnu.org/licenses/>.
38823 + *
38824 + * Ubicom32 implementation derived from (with many thanks):
38825 + *   arch/m68knommu
38826 + *   arch/blackfin
38827 + *   arch/parisc
38828 + */
38829 +#include <linux/module.h>
38830 +#include <linux/ioport.h>
38831 +#include <linux/init.h>
38832 +#include <linux/console.h>
38833 +#include <linux/sysrq.h>
38834 +#include <linux/platform_device.h>
38835 +#include <linux/tty.h>
38836 +#include <linux/tty_flip.h>
38837 +#include <linux/serial_core.h>
38838 +
38839 +#include <asm/ip5000.h>
38840 +
38841 +#define SERIAL_UBICOM_BAUDRATE 115200
38842 +#define SERIAL_UBICOM_DATA_BIT 8       /* Fixed parameter - do not change */
38843 +#define SERIAL_UBICOM_PAR_BIT  0       /* Fixed parameter - do not change */
38844 +#define SERIAL_UBICOM_STOP_BIT 1       /* Fixed parameter - do not change */
38845 +
38846 +/* UART name and device definitions */
38847 +#define UBI32_MAILBOX_NAME     "ttyUM" // XXX
38848 +#define UBI32_MAILBOX_MAJOR    207 // XXX
38849 +#define UBI32_MAILBOX_MINOR    64
38850 +
38851 +#define PORT_UBI32_MAILBOX     1235
38852 +#define NR_PORTS 1
38853 +
38854 +#define get_sclk() 0
38855 +
38856 +struct ubi32_mailbox_port {
38857 +       struct uart_port port;
38858 +       /*
38859 +        * NOTE (rkeller):
38860 +        * the uart port is wrapped in another structure in case we need to hold more state than 
38861 +        * what we can hold in the uart_port.
38862 +        * Not sure if we need this, I took over the concept from the blackfin driver.
38863 +        */
38864 +} ubi32_mailbox_ports[NR_PORTS];
38865 +
38866 +struct ubi32_mailbox_resource {
38867 +       int uart_base_addr;
38868 +       int uart_irq;
38869 +} ubi32_mailbox_resource[NR_PORTS] = {
38870 +       /*
38871 +        * uart_base_addr has to be non-NULL because it is put in the uart_port membase.
38872 +        * If membase if null the kernel skips the configuration and our port_type never gets set.
38873 +        */
38874 +       {ISD_MAILBOX_BASE, ISD_MAILBOX_INT}
38875 +};
38876 +
38877 +static volatile struct ubicom32_isd_mailbox {
38878 +       volatile u32_t in;
38879 +       volatile u32_t out;
38880 +       volatile u32_t status;
38881 +} *ubi32_mailbox = (struct ubicom32_isd_mailbox *)ISD_MAILBOX_BASE;
38882 +
38883 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart);
38884 +
38885 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart);
38886 +
38887 +#define TRUE 1
38888 +#define FALSE 0
38889 +
38890 +static int mailbox_console_flg = TRUE;
38891 +static int num_timeouts = 0;
38892 +
38893 +/*
38894 + * dummy functions and defined to be able to compile the Blackfin code
38895 + */
38896 +#define UART_GET_LSR(port) (1)
38897 +#define UART_PUT_LSR(port, bits)
38898 +#define UART_CLEAR_LSR(port) (1)
38899 +#define TEMT 1
38900 +#define TFI 1
38901 +#define BI 1
38902 +#define PE 1
38903 +#define OE 1
38904 +#define FE 1
38905 +#define THRE 1
38906 +#define DR 1
38907 +#define UART_GET_LCR(port) (1)
38908 +#define UART_PUT_LCR(port, bits)
38909 +#define SB 1
38910 +#define STB 1
38911 +#define PEN 1
38912 +#define EPS 1
38913 +#define STP 1
38914 +#define WLS(n) 0
38915 +#define UART_GET_IER(port) (1)
38916 +#define UART_SET_IER(port, bits)
38917 +#define UART_CLEAR_IER(port, bits)
38918 +#define ETBEI 0
38919 +#define ERBFI 0
38920 +#define UART_GET_CHAR(port) ubi32_mailbox_get_char()
38921 +#define UART_PUT_CHAR(port, ch) ubi32_mailbox_put_char(ch)
38922 +#define SSYNC()
38923 +#define UART_GET_DLL(port) 0
38924 +#define UART_PUT_DLL(port, ch)
38925 +#define UART_GET_DLH(port) 0
38926 +#define UART_PUT_DLH(port, ch)
38927 +#define UART_GET_GCTL(port) (0)
38928 +#define UART_PUT_GCTL(port, ch)
38929 +#define UCEN 1
38930 +
38931 +/*
38932 + * ubi32_mailbox_get_char_avail()
38933 + */
38934 +static int ubi32_mailbox_get_char_avail(void)
38935 +{
38936 +       return !(ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38937 +}
38938 +
38939 +/*
38940 + * ubi32_mailbox_get_char()
38941 + */
38942 +static u32_t ubi32_mailbox_get_char(void)
38943 +{
38944 +       if (mailbox_console_flg == TRUE) {
38945 +               /*
38946 +                * Mailbox console is connected.
38947 +                */
38948 +               while (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38949 +               return ubi32_mailbox->in & 0xff;
38950 +       }
38951 +
38952 +       /*
38953 +        * Mailbox console was not connected.
38954 +        */
38955 +       if (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY) {
38956 +               return 0xff;
38957 +       }
38958 +
38959 +       /*
38960 +        * Mailbox console is connecting.
38961 +        */
38962 +       mailbox_console_flg = TRUE;
38963 +       num_timeouts = 0;
38964 +       return ubi32_mailbox->in & 0xff;
38965 +}
38966 +
38967 +#define MAILBOX_MAX_ATTEMPTS 1000000
38968 +#define MAILBOX_MAX_TIMEOUTS 5
38969 +/*
38970 + * ubi32_mailbox_put_char()
38971 + */
38972 +static void ubi32_mailbox_put_char(u32_t v)
38973 +{
38974 +       /*
38975 +        * Wait to be able to output.
38976 +        */
38977 +       u32_t num_attempts = 0;
38978 +
38979 +       if(mailbox_console_flg == TRUE) {
38980 +               while(num_attempts++ < MAILBOX_MAX_ATTEMPTS) {
38981 +                       if(ubi32_mailbox->status & ISD_MAILBOX_STATUS_OUT_EMPTY) {
38982 +                               break;
38983 +                       }
38984 +               }
38985 +
38986 +               /*
38987 +                * If timed out more than 5 times on send, mailbox console is disconnected now.
38988 +                */
38989 +               if (num_attempts > MAILBOX_MAX_ATTEMPTS) {
38990 +                       if (num_timeouts++ > MAILBOX_MAX_TIMEOUTS) {
38991 +                               mailbox_console_flg = FALSE;
38992 +                       }
38993 +               }
38994 +       }
38995 +       
38996 +       asm volatile(
38997 +               "pipe_flush 0   \n\t"
38998 +               "pipe_flush 0   \n\t"
38999 +               "pipe_flush 0   \n\t"
39000 +               "pipe_flush 0   \n\t"
39001 +               "pipe_flush 0   \n\t"
39002 +               "pipe_flush 0   \n\t"
39003 +               "pipe_flush 0   \n\t"
39004 +       );
39005 +
39006 +       ubi32_mailbox->out = v & 0xff;
39007 +}
39008 +
39009 +static void ubi32_mailbox_hw_init(struct ubi32_mailbox_port *uart)
39010 +{
39011 +// NOTE: It does not do any good to do these here because we are running on the linux hardware thread,
39012 +//     and these have to be called on the ldsr thread.
39013 +//     ubicom32_clear_interrupt(ISD_MAILBOX_INT);
39014 +//     ubicom32_enable_interrupt(ISD_MAILBOX_INT);
39015 +}
39016 +
39017 +/*
39018 + * interrupts are disabled on entry
39019 + */
39020 +static void ubi32_mailbox_stop_tx(struct uart_port *port)
39021 +{
39022 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39023 +//     struct circ_buf *xmit = &uart->port.info->xmit;
39024 +
39025 +       while (!(UART_GET_LSR(uart) & TEMT))
39026 +               cpu_relax();
39027 +
39028 +       /* Clear TFI bit */
39029 +       UART_PUT_LSR(uart, TFI);
39030 +       UART_CLEAR_IER(uart, ETBEI);
39031 +}
39032 +
39033 +/*
39034 + * port is locked and interrupts are disabled
39035 + */
39036 +static void ubi32_mailbox_start_tx(struct uart_port *port)
39037 +{
39038 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39039 +
39040 +       UART_SET_IER(uart, ETBEI);
39041 +
39042 +       ubi32_mailbox_tx_chars(uart);
39043 +}
39044 +
39045 +/*
39046 + * Interrupts are enabled
39047 + */
39048 +static void ubi32_mailbox_stop_rx(struct uart_port *port)
39049 +{
39050 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39051 +       UART_CLEAR_IER(uart, ERBFI);
39052 +}
39053 +
39054 +/*
39055 + * Set the modem control timer to fire immediately.
39056 + */
39057 +static void ubi32_mailbox_enable_ms(struct uart_port *port)
39058 +{
39059 +}
39060 +
39061 +static void ubi32_mailbox_rx_chars(struct ubi32_mailbox_port *uart)
39062 +{
39063 +       struct uart_info *info = uart->port.info;
39064 +       struct tty_struct *tty = info->port.tty;
39065 +       unsigned int status, ch, flg;
39066 +
39067 +       status = 0; // XXX? UART_GET_LSR(uart);
39068 +       UART_CLEAR_LSR(uart);
39069 +
39070 +       ch = UART_GET_CHAR(uart);
39071 +
39072 +       if(ch == 0xff)
39073 +               return; 
39074 +
39075 +       uart->port.icount.rx++;
39076 +
39077 +       if (status & BI) {
39078 +               uart->port.icount.brk++;
39079 +               if (uart_handle_break(&uart->port))
39080 +                       goto ignore_char;
39081 +               status &= ~(PE | FE);
39082 +       }
39083 +       if (status & PE)
39084 +               uart->port.icount.parity++;
39085 +       if (status & OE)
39086 +               uart->port.icount.overrun++;
39087 +       if (status & FE)
39088 +               uart->port.icount.frame++;
39089 +
39090 +       status &= uart->port.read_status_mask;
39091 +
39092 +       if (status & BI)
39093 +               flg = TTY_BREAK;
39094 +       else if (status & PE)
39095 +               flg = TTY_PARITY;
39096 +       else if (status & FE)
39097 +               flg = TTY_FRAME;
39098 +       else
39099 +               flg = TTY_NORMAL;
39100 +
39101 +       if (uart_handle_sysrq_char(&uart->port, ch))
39102 +               goto ignore_char;
39103 +
39104 +       uart_insert_char(&uart->port, status, OE, ch, flg);
39105 +
39106 + ignore_char:
39107 +       tty_flip_buffer_push(tty);
39108 +}
39109 +
39110 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart)
39111 +{
39112 +       struct circ_buf *xmit = &uart->port.info->xmit;
39113 +
39114 +       if (uart->port.x_char) {
39115 +               UART_PUT_CHAR(uart, uart->port.x_char);
39116 +               uart->port.icount.tx++;
39117 +               uart->port.x_char = 0;
39118 +       }
39119 +       /*
39120 +        * Check the modem control lines before
39121 +        * transmitting anything.
39122 +        */
39123 +       ubi32_mailbox_mctrl_check(uart);
39124 +
39125 +       if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
39126 +               ubi32_mailbox_stop_tx(&uart->port);
39127 +               return;
39128 +       }
39129 +
39130 +       while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) {
39131 +               UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
39132 +               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
39133 +               uart->port.icount.tx++;
39134 +               SSYNC();
39135 +       }
39136 +
39137 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
39138 +               uart_write_wakeup(&uart->port);
39139 +
39140 +       if (uart_circ_empty(xmit))
39141 +               ubi32_mailbox_stop_tx(&uart->port);
39142 +}
39143 +
39144 +static irqreturn_t ubi32_mailbox_isr(int irq, void *dev_id)
39145 +{
39146 +       struct ubi32_mailbox_port *uart = dev_id;
39147 +
39148 +       spin_lock(&uart->port.lock);
39149 +
39150 +       //XXX?while (UART_GET_LSR(uart) & DR)
39151 +
39152 +       /*
39153 +        * RX process
39154 +        */
39155 +       while (ubi32_mailbox_get_char_avail()) {
39156 +               ubi32_mailbox_rx_chars(uart);
39157 +       }
39158 +
39159 +#if 0
39160 +       /*
39161 +        * TX process
39162 +        */
39163 +       if (this_uart.tx_in == this_uart.tx_out) {
39164 +               UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_mask &= ~IO_PORTX_INT_SERDES_TXBE;
39165 +       } else if (UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_status & IO_PORTX_INT_SERDES_TXBE) {
39166 +               uart_ubicom32_send(this_uart.tx_buf[this_uart.tx_out & (SERIAL_UBICOM_BUF_SIZE - 1)]);
39167 +               this_uart.tx_out++;
39168 +               UBICOM32_IO_PORT(SERIAL_UBICOM_PORT)->int_mask |= IO_PORTX_INT_SERDES_TXBE;
39169 +       }
39170 +#endif
39171 +
39172 +       spin_unlock(&uart->port.lock);
39173 +
39174 +       return IRQ_HANDLED;
39175 +}
39176 +#if 0
39177 +static irqreturn_t ubi32_mailbox_tx_int(int irq, void *dev_id)
39178 +{
39179 +       struct ubi32_mailbox_port *uart = dev_id;
39180 +
39181 +       spin_lock(&uart->port.lock);
39182 +       if (UART_GET_LSR(uart) & THRE)
39183 +               ubi32_mailbox_tx_chars(uart);
39184 +       spin_unlock(&uart->port.lock);
39185 +
39186 +       return IRQ_HANDLED;
39187 +}
39188 +#endif
39189 +
39190 +/*
39191 + * Return TIOCSER_TEMT when transmitter is not busy.
39192 + */
39193 +static unsigned int ubi32_mailbox_tx_empty(struct uart_port *port)
39194 +{
39195 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39196 +       unsigned short lsr;
39197 +
39198 +       lsr = UART_GET_LSR(uart);
39199 +       if (lsr & TEMT)
39200 +               return TIOCSER_TEMT;
39201 +       else
39202 +               return 0;
39203 +}
39204 +
39205 +static unsigned int ubi32_mailbox_get_mctrl(struct uart_port *port)
39206 +{
39207 +               return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
39208 +}
39209 +
39210 +static void ubi32_mailbox_set_mctrl(struct uart_port *port, unsigned int mctrl)
39211 +{
39212 +}
39213 +
39214 +/*
39215 + * Handle any change of modem status signal since we were last called.
39216 + */
39217 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart)
39218 +{
39219 +}
39220 +
39221 +/*
39222 + * Interrupts are always disabled.
39223 + */
39224 +static void ubi32_mailbox_break_ctl(struct uart_port *port, int break_state)
39225 +{
39226 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39227 +       u16 lcr = UART_GET_LCR(uart);
39228 +       if (break_state)
39229 +               lcr |= SB;
39230 +       else
39231 +               lcr &= ~SB;
39232 +       UART_PUT_LCR(uart, lcr);
39233 +       SSYNC();
39234 +}
39235 +
39236 +static int ubi32_mailbox_startup(struct uart_port *port)
39237 +{
39238 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39239 +
39240 +       if (request_irq(uart->port.irq, ubi32_mailbox_isr, IRQF_DISABLED,
39241 +            "UBI32_MAILBOX", uart)) {
39242 +               printk(KERN_NOTICE "Unable to attach Ubicom32 SERDES interrupt\n");
39243 +               return -EBUSY;
39244 +       }
39245 +
39246 +       UART_SET_IER(uart, ERBFI);
39247 +       return 0;
39248 +}
39249 +
39250 +static void ubi32_mailbox_shutdown(struct uart_port *port)
39251 +{
39252 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39253 +
39254 +       free_irq(uart->port.irq, uart);
39255 +}
39256 +
39257 +static void
39258 +ubi32_mailbox_set_termios(struct uart_port *port, struct ktermios *termios,
39259 +                  struct ktermios *old)
39260 +{
39261 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39262 +       unsigned long flags;
39263 +       unsigned int baud, quot;
39264 +       unsigned short val, ier, lsr, lcr = 0;
39265 +
39266 +       switch (termios->c_cflag & CSIZE) {
39267 +       case CS8:
39268 +               lcr = WLS(8);
39269 +               break;
39270 +       case CS7:
39271 +               lcr = WLS(7);
39272 +               break;
39273 +       case CS6:
39274 +               lcr = WLS(6);
39275 +               break;
39276 +       case CS5:
39277 +               lcr = WLS(5);
39278 +               break;
39279 +       default:
39280 +               printk(KERN_ERR "%s: word lengh not supported\n",
39281 +                       __FUNCTION__);
39282 +       }
39283 +
39284 +       if (termios->c_cflag & CSTOPB)
39285 +               lcr |= STB;
39286 +       if (termios->c_cflag & PARENB)
39287 +               lcr |= PEN;
39288 +       if (!(termios->c_cflag & PARODD))
39289 +               lcr |= EPS;
39290 +       if (termios->c_cflag & CMSPAR)
39291 +               lcr |= STP;
39292 +
39293 +       port->read_status_mask = OE;
39294 +       if (termios->c_iflag & INPCK)
39295 +               port->read_status_mask |= (FE | PE);
39296 +       if (termios->c_iflag & (BRKINT | PARMRK))
39297 +               port->read_status_mask |= BI;
39298 +
39299 +       /*
39300 +        * Characters to ignore
39301 +        */
39302 +       port->ignore_status_mask = 0;
39303 +       if (termios->c_iflag & IGNPAR)
39304 +               port->ignore_status_mask |= FE | PE;
39305 +       if (termios->c_iflag & IGNBRK) {
39306 +               port->ignore_status_mask |= BI;
39307 +               /*
39308 +                * If we're ignoring parity and break indicators,
39309 +                * ignore overruns too (for real raw support).
39310 +                */
39311 +               if (termios->c_iflag & IGNPAR)
39312 +                       port->ignore_status_mask |= OE;
39313 +       }
39314 +
39315 +       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
39316 +       quot = uart_get_divisor(port, baud);
39317 +       spin_lock_irqsave(&uart->port.lock, flags);
39318 +
39319 +       do {
39320 +               lsr = UART_GET_LSR(uart);
39321 +       } while (!(lsr & TEMT));
39322 +
39323 +       /* Disable UART */
39324 +       ier = UART_GET_IER(uart);
39325 +       UART_CLEAR_IER(uart, 0xF);
39326 +
39327 +       UART_PUT_DLL(uart, quot & 0xFF);
39328 +       SSYNC();
39329 +       UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
39330 +       SSYNC();
39331 +
39332 +       UART_PUT_LCR(uart, lcr);
39333 +
39334 +       /* Enable UART */
39335 +       UART_SET_IER(uart, ier);
39336 +
39337 +       val = UART_GET_GCTL(uart);
39338 +       val |= UCEN;
39339 +       UART_PUT_GCTL(uart, val);
39340 +
39341 +       spin_unlock_irqrestore(&uart->port.lock, flags);
39342 +}
39343 +
39344 +static const char *ubi32_mailbox_type(struct uart_port *port)
39345 +{
39346 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39347 +
39348 +       return uart->port.type == PORT_UBI32_MAILBOX ? "UBI32_MAILBOX" : NULL;
39349 +}
39350 +
39351 +/*
39352 + * Release the memory region(s) being used by 'port'.
39353 + */
39354 +static void ubi32_mailbox_release_port(struct uart_port *port)
39355 +{
39356 +}
39357 +
39358 +/*
39359 + * Request the memory region(s) being used by 'port'.
39360 + */
39361 +static int ubi32_mailbox_request_port(struct uart_port *port)
39362 +{
39363 +       return 0;
39364 +}
39365 +
39366 +/*
39367 + * Configure/autoconfigure the port.
39368 + */
39369 +static void ubi32_mailbox_config_port(struct uart_port *port, int flags)
39370 +{
39371 +       struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39372 +
39373 +       if (flags & UART_CONFIG_TYPE && ubi32_mailbox_request_port(&uart->port) == 0)
39374 +               uart->port.type = PORT_UBI32_MAILBOX;
39375 +}
39376 +
39377 +/*
39378 + * Verify the new serial_struct (for TIOCSSERIAL).
39379 + * The only change we allow are to the flags and type, and
39380 + * even then only between PORT_UBI32_MAILBOX and PORT_UNKNOWN
39381 + */
39382 +static int
39383 +ubi32_mailbox_verify_port(struct uart_port *port, struct serial_struct *ser)
39384 +{
39385 +       return 0;
39386 +}
39387 +
39388 +static struct uart_ops ubi32_mailbox_pops = {
39389 +       .tx_empty       = ubi32_mailbox_tx_empty,
39390 +       .set_mctrl      = ubi32_mailbox_set_mctrl,
39391 +       .get_mctrl      = ubi32_mailbox_get_mctrl,
39392 +       .stop_tx        = ubi32_mailbox_stop_tx,
39393 +       .start_tx       = ubi32_mailbox_start_tx,
39394 +       .stop_rx        = ubi32_mailbox_stop_rx,
39395 +       .enable_ms      = ubi32_mailbox_enable_ms,
39396 +       .break_ctl      = ubi32_mailbox_break_ctl,
39397 +       .startup        = ubi32_mailbox_startup,
39398 +       .shutdown       = ubi32_mailbox_shutdown,
39399 +       .set_termios    = ubi32_mailbox_set_termios,
39400 +       .type           = ubi32_mailbox_type,
39401 +       .release_port   = ubi32_mailbox_release_port,
39402 +       .request_port   = ubi32_mailbox_request_port,
39403 +       .config_port    = ubi32_mailbox_config_port,
39404 +       .verify_port    = ubi32_mailbox_verify_port,
39405 +};
39406 +
39407 +static void __init ubi32_mailbox_init_ports(void)
39408 +{
39409 +       static int first = 1;
39410 +       int i;
39411 +
39412 +       if (!first)
39413 +               return;
39414 +       first = 0;
39415 +
39416 +       for (i = 0; i < NR_PORTS; i++) {
39417 +               ubi32_mailbox_ports[i].port.uartclk   = get_sclk();
39418 +               ubi32_mailbox_ports[i].port.ops       = &ubi32_mailbox_pops;
39419 +               ubi32_mailbox_ports[i].port.line      = i;
39420 +               ubi32_mailbox_ports[i].port.iotype    = UPIO_MEM;
39421 +               ubi32_mailbox_ports[i].port.membase   =
39422 +                       (void __iomem *)ubi32_mailbox_resource[i].uart_base_addr;
39423 +               ubi32_mailbox_ports[i].port.mapbase   =
39424 +                       ubi32_mailbox_resource[i].uart_base_addr;
39425 +               ubi32_mailbox_ports[i].port.irq       =
39426 +                       ubi32_mailbox_resource[i].uart_irq;
39427 +               ubi32_mailbox_ports[i].port.flags     = UPF_BOOT_AUTOCONF;
39428 +               spin_lock_init(&ubi32_mailbox_ports[i].port.lock);
39429 +
39430 +               ubi32_mailbox_hw_init(&ubi32_mailbox_ports[i]);
39431 +       }
39432 +
39433 +}
39434 +
39435 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39436 +/*
39437 + * If the port was already initialised (eg, by a boot loader),
39438 + * try to determine the current setup.
39439 + */
39440 +static void __init
39441 +ubi32_mailbox_console_get_options(struct ubi32_mailbox_port *uart, int *baud,
39442 +                          int *parity, int *bits)
39443 +{
39444 +       unsigned short status;
39445 +
39446 +       status = UART_GET_IER(uart) & (ERBFI | ETBEI);
39447 +       if (status == (ERBFI | ETBEI)) {
39448 +               /* ok, the port was enabled */
39449 +               unsigned short lcr;
39450 +               unsigned short dlh, dll;
39451 +
39452 +               lcr = UART_GET_LCR(uart);
39453 +
39454 +               *parity = 'n';
39455 +               if (lcr & PEN) {
39456 +                       if (lcr & EPS)
39457 +                               *parity = 'e';
39458 +                       else
39459 +                               *parity = 'o';
39460 +               }
39461 +               switch (lcr & 0x03) {
39462 +                       case 0: *bits = 5; break;
39463 +                       case 1: *bits = 6; break;
39464 +                       case 2: *bits = 7; break;
39465 +                       case 3: *bits = 8; break;
39466 +               }
39467 +
39468 +               dll = UART_GET_DLL(uart);
39469 +               dlh = UART_GET_DLH(uart);
39470 +
39471 +               *baud = get_sclk() / (16*(dll | dlh << 8));
39472 +       }
39473 +       pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
39474 +}
39475 +#endif
39476 +
39477 +#if defined(CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
39478 +static struct uart_driver ubi32_mailbox_reg;
39479 +
39480 +static int __init
39481 +ubi32_mailbox_console_setup(struct console *co, char *options)
39482 +{
39483 +       struct ubi32_mailbox_port *uart;
39484 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39485 +       int baud = SERIAL_UBICOM_BAUDRATE;
39486 +       int bits = 8;
39487 +       int parity = 'n';
39488 +       int flow = 'n';
39489 +# endif
39490 +
39491 +       /*
39492 +        * Check whether an invalid uart number has been specified, and
39493 +        * if so, search for the first available port that does have
39494 +        * console support.
39495 +        */
39496 +       if (co->index == -1 || co->index >= NR_PORTS)
39497 +               co->index = 0;
39498 +       uart = &ubi32_mailbox_ports[co->index];
39499 +
39500 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39501 +       if (options)
39502 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
39503 +       else
39504 +               ubi32_mailbox_console_get_options(uart, &baud, &parity, &bits);
39505 +
39506 +       //JB return uart_set_options(&uart->port, co, baud, parity, bits, flow);
39507 +       return 0;
39508 +# else
39509 +       return 0;
39510 +# endif
39511 +}
39512 +#endif /* defined (CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) ||
39513 +                                defined (CONFIG_EARLY_PRINTK) */
39514 +
39515 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39516 +static void ubi32_mailbox_console_putchar(struct uart_port *port, int ch)
39517 +{
39518 +//     struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39519 +       while (!(UART_GET_LSR(uart) & THRE))
39520 +               barrier();
39521 +       UART_PUT_CHAR(uart, ch);
39522 +       SSYNC();
39523 +}
39524 +
39525 +/*
39526 + * Interrupts are disabled on entering
39527 + */
39528 +static void
39529 +ubi32_mailbox_console_write(struct console *co, const char *s, unsigned int count)
39530 +{
39531 +       struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[co->index];
39532 +       unsigned long flags = 0;
39533 +
39534 +       spin_lock_irqsave(&uart->port.lock, flags);
39535 +       uart_console_write(&uart->port, s, count, ubi32_mailbox_console_putchar);
39536 +       spin_unlock_irqrestore(&uart->port.lock, flags);
39537 +
39538 +}
39539 +
39540 +static struct console ubi32_mailbox_console = {
39541 +       .name           = UBI32_MAILBOX_NAME,
39542 +       .write          = ubi32_mailbox_console_write,
39543 +       .device         = uart_console_device,
39544 +       .setup          = ubi32_mailbox_console_setup,
39545 +       .flags          = CON_PRINTBUFFER,
39546 +       .index          = -1,
39547 +       .data           = &ubi32_mailbox_reg,
39548 +};
39549 +
39550 +static int __init ubi32_mailbox_console_init(void)
39551 +{
39552 +       ubi32_mailbox_init_ports();
39553 +       register_console(&ubi32_mailbox_console);
39554 +       return 0;
39555 +}
39556 +console_initcall(ubi32_mailbox_console_init);
39557 +
39558 +#define UBI32_MAILBOX_CONSOLE  &ubi32_mailbox_console
39559 +#else
39560 +#define UBI32_MAILBOX_CONSOLE  NULL
39561 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
39562 +
39563 +
39564 +#ifdef CONFIG_EARLY_PRINTK
39565 +static __init void ubi32_mailbox_early_putc(struct uart_port *port, int ch)
39566 +{
39567 +       UART_PUT_CHAR(uart, ch);
39568 +}
39569 +
39570 +static __init void ubi32_mailbox_early_write(struct console *con, const char *s,
39571 +                                       unsigned int n)
39572 +{
39573 +       struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[con->index];
39574 +       unsigned int i;
39575 +
39576 +       for (i = 0; i < n; i++, s++) {
39577 +               if (*s == '\n')
39578 +                       ubi32_mailbox_early_putc(&uart->port, '\r');
39579 +               ubi32_mailbox_early_putc(&uart->port, *s);
39580 +       }
39581 +}
39582 +
39583 +static struct __init console ubi32_mailbox_early_console = {
39584 +       .name = "early_UM",
39585 +       .write = ubi32_mailbox_early_write,
39586 +       .device = uart_console_device,
39587 +       .flags = CON_PRINTBUFFER,
39588 +       .setup = ubi32_mailbox_console_setup,
39589 +       .index = -1,
39590 +       .data  = &ubi32_mailbox_reg,
39591 +};
39592 +
39593 +/*
39594 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
39595 + */
39596 +struct console __init *ubi32_mailbox_early_init(unsigned int port,
39597 +                                               unsigned int cflag)
39598 +{
39599 +       struct ubi32_mailbox_port *uart;
39600 +       struct ktermios t;
39601 +
39602 +       if (port == -1 || port >= NR_PORTS)
39603 +               port = 0;
39604 +       ubi32_mailbox_init_ports();
39605 +       ubi32_mailbox_early_console.index = port;
39606 +       uart = &ubi32_mailbox_ports[port];
39607 +       t.c_cflag = cflag;
39608 +       t.c_iflag = 0;
39609 +       t.c_oflag = 0;
39610 +       t.c_lflag = ICANON;
39611 +       t.c_line = port;
39612 +       ubi32_mailbox_set_termios(&uart->port, &t, &t);
39613 +       return &ubi32_mailbox_early_console;
39614 +}
39615 +
39616 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
39617 +
39618 +static struct uart_driver ubi32_mailbox_reg = {
39619 +       .owner                  = THIS_MODULE,
39620 +       .driver_name            = "ubi32_mailbox",
39621 +       .dev_name               = UBI32_MAILBOX_NAME,
39622 +       .major                  = UBI32_MAILBOX_MAJOR,
39623 +       .minor                  = UBI32_MAILBOX_MINOR,
39624 +       .nr                     = NR_PORTS,
39625 +       .cons                   = UBI32_MAILBOX_CONSOLE,
39626 +};
39627 +
39628 +static int ubi32_mailbox_suspend(struct platform_device *dev, pm_message_t state)
39629 +{
39630 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39631 +
39632 +       if (uart)
39633 +               uart_suspend_port(&ubi32_mailbox_reg, &uart->port);
39634 +
39635 +       return 0;
39636 +}
39637 +
39638 +static int ubi32_mailbox_resume(struct platform_device *dev)
39639 +{
39640 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39641 +
39642 +       if (uart)
39643 +               uart_resume_port(&ubi32_mailbox_reg, &uart->port);
39644 +
39645 +       return 0;
39646 +}
39647 +
39648 +static int ubi32_mailbox_probe(struct platform_device *dev)
39649 +{
39650 +       struct resource *res = dev->resource;
39651 +       int i;
39652 +
39653 +       for (i = 0; i < dev->num_resources; i++, res++)
39654 +               if (res->flags & IORESOURCE_MEM)
39655 +                       break;
39656 +
39657 +       if (i < dev->num_resources) {
39658 +               for (i = 0; i < NR_PORTS; i++, res++) {
39659 +                       if (ubi32_mailbox_ports[i].port.mapbase != res->start)
39660 +                               continue;
39661 +                       ubi32_mailbox_ports[i].port.dev = &dev->dev;
39662 +                       uart_add_one_port(&ubi32_mailbox_reg, &ubi32_mailbox_ports[i].port);
39663 +                       platform_set_drvdata(dev, &ubi32_mailbox_ports[i]);
39664 +               }
39665 +       }
39666 +
39667 +       return 0;
39668 +}
39669 +
39670 +static int ubi32_mailbox_remove(struct platform_device *pdev)
39671 +{
39672 +       struct ubi32_mailbox_port *uart = platform_get_drvdata(pdev);
39673 +
39674 +       platform_set_drvdata(pdev, NULL);
39675 +
39676 +       if (uart)
39677 +               uart_remove_one_port(&ubi32_mailbox_reg, &uart->port);
39678 +
39679 +       return 0;
39680 +}
39681 +
39682 +static struct platform_driver ubi32_mailbox_driver = {
39683 +       .probe          = ubi32_mailbox_probe,
39684 +       .remove         = ubi32_mailbox_remove,
39685 +       .suspend        = ubi32_mailbox_suspend,
39686 +       .resume         = ubi32_mailbox_resume,
39687 +       .driver         = {
39688 +               .name   = "ubi32-mbox",
39689 +               .owner  = THIS_MODULE,
39690 +       },
39691 +};
39692 +
39693 +static int __init ubi32_mailbox_init(void)
39694 +{
39695 +       int ret;
39696 +
39697 +       pr_info("Serial: Ubicom32 mailbox serial driver.\n");
39698 +
39699 +       mailbox_console_flg = TRUE;
39700 +       num_timeouts = 0;
39701 +       ubi32_mailbox_init_ports();
39702 +
39703 +       ret = uart_register_driver(&ubi32_mailbox_reg);
39704 +       if (ret == 0) {
39705 +               ret = platform_driver_register(&ubi32_mailbox_driver);
39706 +               if (ret) {
39707 +                       pr_debug("uart register failed\n");
39708 +                       uart_unregister_driver(&ubi32_mailbox_reg);
39709 +               }
39710 +       }
39711 +
39712 +       /*
39713 +        * XXX HACK: currently probe does not get called, but the port needs to be added to work.
39714 +        */
39715 +       uart_add_one_port(&ubi32_mailbox_reg, &ubi32_mailbox_ports[0].port);
39716 +       return ret;
39717 +}
39718 +
39719 +static void __exit ubi32_mailbox_exit(void)
39720 +{
39721 +       platform_driver_unregister(&ubi32_mailbox_driver);
39722 +       uart_unregister_driver(&ubi32_mailbox_reg);
39723 +}
39724 +
39725 +module_init(ubi32_mailbox_init);
39726 +module_exit(ubi32_mailbox_exit);
39727 +
39728 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_MAILBOX_MAJOR);
39729 +MODULE_ALIAS("platform:ubi32_mailbox");
39730 --- /dev/null
39731 +++ b/drivers/serial/ubi32_serdes.c
39732 @@ -0,0 +1,817 @@
39733 +/*
39734 + * drivers/serial/ubi32_serdes.c
39735 + *   Ubicom32 On-Chip Serial Driver
39736 + *
39737 + * (C) Copyright 2009, Ubicom, Inc.
39738 + *
39739 + * This file is part of the Ubicom32 Linux Kernel Port.
39740 + *
39741 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
39742 + * it and/or modify it under the terms of the GNU General Public License
39743 + * as published by the Free Software Foundation, either version 2 of the
39744 + * License, or (at your option) any later version.
39745 + *
39746 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
39747 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
39748 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
39749 + * the GNU General Public License for more details.
39750 + *
39751 + * You should have received a copy of the GNU General Public License
39752 + * along with the Ubicom32 Linux Kernel Port.  If not, 
39753 + * see <http://www.gnu.org/licenses/>.
39754 + *
39755 + * Ubicom32 implementation derived from (with many thanks):
39756 + *   arch/m68knommu
39757 + *   arch/blackfin
39758 + *   arch/parisc
39759 + */
39760 +#include <linux/module.h>
39761 +#include <linux/ioport.h>
39762 +#include <linux/init.h>
39763 +#include <linux/console.h>
39764 +#include <linux/sysrq.h>
39765 +#include <linux/platform_device.h>
39766 +#include <linux/tty.h>
39767 +#include <linux/tty_flip.h>
39768 +#include <linux/serial_core.h>
39769 +
39770 +#include <asm/ip5000.h>
39771 +#include <asm/ubicom32suart.h>
39772 +
39773 +
39774 +#define SERIAL_UBICOM_PIN_RXD  (1 << 0)
39775 +#define SERIAL_UBICOM_PIN_TXD  (1 << 6)
39776 +#define SERIAL_UBICOM_CTL0     0x8b300000
39777 +#define SERIAL_UBICOM_CTL1     0x00000009
39778 +
39779 +#define SERIAL_UBICOM_DATA_BIT 8       /* Fixed parameter - do not change */
39780 +#define SERIAL_UBICOM_PAR_BIT  0       /* Fixed parameter - do not change */
39781 +#define SERIAL_UBICOM_STOP_BIT 1       /* Fixed parameter - do not change */
39782 +
39783 +/* UART name and device definitions */
39784 +#define UBI32_SERDES_NAME      "ttyUS" // XXX
39785 +#define UBI32_SERDES_MAJOR     206 // XXX
39786 +#define UBI32_SERDES_MINOR     64 // XXX
39787 +
39788 +#define PORT_UBI32_SERDES      1234
39789 +#define NR_PORTS 1
39790 +
39791 +struct uart_port ubi32_serdes_ports[NR_PORTS];
39792 +
39793 +struct ubi32_serdes_resource {
39794 +       void *uart_base_addr;
39795 +       int uart_irq;
39796 +       int uart_clock;
39797 +} ubi32_serdes_resource[NR_PORTS] = {
39798 +       /*
39799 +        * Get params from kernel command line (required for early printk)
39800 +        * or from platform resources.
39801 +        */
39802 +       {0, 0, 0}
39803 +};
39804 +
39805 +/*
39806 + * Can get overridden by 'serdes=' kernel command line.
39807 + */
39808 +static int ubi32_serdes_default_baud_rate = 115200;
39809 +
39810 +
39811 +#define IO_PORT(port) ((struct ubicom32_io_port *)port->membase)
39812 +#define IO_PORT_INT_STATUS(port) (IO_PORT(port)->int_status)
39813 +#define IO_PORT_INT_MASK(port) (IO_PORT(port)->int_mask)
39814 +#define IO_PORT_INT_CLR(port) (IO_PORT(port)->int_clr)
39815 +
39816 +
39817 +/*
39818 + * ubi32_serdes_get_char()
39819 + */
39820 +static u8_t ubi32_serdes_get_char(struct ubicom32_io_port *io_port)
39821 +{
39822 +       /*
39823 +        * Read from hardware (forced 32-bit atomic read).
39824 +        */
39825 +       u32_t data = 0;
39826 +
39827 +       if ( io_port ) {
39828 +               io_port->int_clr = IO_PORTX_INT_SERDES_RXBF;
39829 +               asm volatile (
39830 +                       "move.4         %0, %1          \n\t"
39831 +                       : "=r" (data)
39832 +                       : "m" (*(u32_t *)&(io_port->rx_fifo))
39833 +                       );
39834 +       }
39835 +
39836 +       return (u8_t)(data & 0x000000ff);
39837 +}
39838 +
39839 +/*
39840 + * ubi32_serdes_put_char()
39841 + */
39842 +static void ubi32_serdes_put_char(struct ubicom32_io_port *io_port, u8_t c)
39843 +{
39844 +       u32_t data = 0x0000fe00 | (c << 1);
39845 +
39846 +       if ( io_port ) {
39847 +               /*
39848 +                * Fixed data format: 
39849 +                * [LSB]1 start bit - 8 data bits - no parity - 1 stop bit[MSB]
39850 +                */
39851 +               io_port->int_clr = IO_PORTX_INT_SERDES_TXBE;
39852 +               io_port->ctl2 = data;
39853 +               io_port->int_set = IO_PORTX_INT_SERDES_TXBUF_VALID;
39854 +       }
39855 +}
39856 +
39857 +static void ubi32_serdes_hw_init(struct uart_port *port, int baud)
39858 +{
39859 +       struct ubicom32_io_port *io_port = IO_PORT(port);
39860 +
39861 +       if ( io_port ) {
39862 +               /*
39863 +                * Put port functions 1-4 into reset state.
39864 +                * Function 0 (GPIO) does not need or have a reset bit.
39865 +                *
39866 +                * Select SERDES function for restart below.
39867 +                */
39868 +               io_port->function =
39869 +                       IO_FUNC_FUNCTION_RESET(1) | IO_FUNC_FUNCTION_RESET(2) |
39870 +                       IO_FUNC_FUNCTION_RESET(3) | IO_FUNC_FUNCTION_RESET(4) |
39871 +                       IO_PORTX_FUNC_SERDES;
39872 +
39873 +               /*
39874 +                * Configure SERDES baudrate
39875 +                */
39876 +               if ( baud == 0 ) {
39877 +                       baud = ubi32_serdes_default_baud_rate;
39878 +               }
39879 +
39880 +               io_port->ctl0 =
39881 +                       SERIAL_UBICOM_CTL0 | 
39882 +                       ((port->uartclk / (16 * baud)) - 1);
39883 +
39884 +               io_port->ctl1 =
39885 +                       SERIAL_UBICOM_CTL1;
39886 +
39887 +               /*
39888 +                * don't interrupt until startup and start_tx
39889 +                */
39890 +               io_port->int_mask = 0;
39891 +
39892 +               /*
39893 +                * Set TXD pin output, RXD input and prevent GPIO
39894 +                * override on the TXD & RXD pins
39895 +                */
39896 +               io_port->gpio_ctl &= ~SERIAL_UBICOM_PIN_RXD;
39897 +               io_port->gpio_ctl |= SERIAL_UBICOM_PIN_TXD;
39898 +               io_port->gpio_mask &= ~(SERIAL_UBICOM_PIN_RXD | SERIAL_UBICOM_PIN_TXD);
39899 +
39900 +               /*
39901 +                * Restart (un-reset) the port's SERDES function.
39902 +                */
39903 +               io_port->function &= ~(IO_FUNC_FUNCTION_RESET(IO_PORTX_FUNC_SERDES));
39904 +       }
39905 +}
39906 +
39907 +#define ULITE_STATUS_RXVALID IO_PORTX_INT_SERDES_RXBF
39908 +#define ULITE_STATUS_OVERRUN 0
39909 +#define ULITE_STATUS_FRAME 0
39910 +#define ULITE_STATUS_PARITY 0
39911 +#define ULITE_STATUS_TXEMPTY IO_PORTX_INT_SERDES_TXBE
39912 +#define ULITE_STATUS_TXFULL 0
39913 +
39914 +static int ubi32_serdes_receive(struct uart_port *port, int stat)
39915 +{
39916 +       struct tty_struct *tty = port->info->port.tty;
39917 +       unsigned char ch = 0;
39918 +       char flag = TTY_NORMAL;
39919 +
39920 +       if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
39921 +                    | ULITE_STATUS_FRAME)) == 0)
39922 +               return 0;
39923 +
39924 +       /* stats */
39925 +       if (stat & ULITE_STATUS_RXVALID) {
39926 +               port->icount.rx++;
39927 +               ch = ubi32_serdes_get_char((struct ubicom32_io_port *)port->membase);
39928 +
39929 +               if (stat & ULITE_STATUS_PARITY)
39930 +                       port->icount.parity++;
39931 +       }
39932 +
39933 +       if (stat & ULITE_STATUS_OVERRUN)
39934 +               port->icount.overrun++;
39935 +
39936 +       if (stat & ULITE_STATUS_FRAME)
39937 +               port->icount.frame++;
39938 +
39939 +
39940 +       /* drop byte with parity error if IGNPAR specificed */
39941 +       if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY)
39942 +               stat &= ~ULITE_STATUS_RXVALID;
39943 +
39944 +       stat &= port->read_status_mask;
39945 +
39946 +       if (stat & ULITE_STATUS_PARITY)
39947 +               flag = TTY_PARITY;
39948 +
39949 +       stat &= ~port->ignore_status_mask;
39950 +
39951 +       if (stat & ULITE_STATUS_RXVALID)
39952 +               tty_insert_flip_char(tty, ch, flag);
39953 +
39954 +       if (stat & ULITE_STATUS_FRAME)
39955 +               tty_insert_flip_char(tty, 0, TTY_FRAME);
39956 +
39957 +       if (stat & ULITE_STATUS_OVERRUN)
39958 +               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
39959 +
39960 +       return 1;
39961 +}
39962 +
39963 +/*
39964 + * interrupts are disabled on entry
39965 + */
39966 +static void ubi32_serdes_stop_tx(struct uart_port *port)
39967 +{
39968 +       IO_PORT_INT_MASK(port) = IO_PORT_INT_MASK(port) & ~IO_PORTX_INT_SERDES_TXBE;
39969 +}
39970 +
39971 +static int ubi32_serdes_transmit(struct uart_port *port, int stat)
39972 +{
39973 +       struct circ_buf *xmit  = &port->info->xmit;
39974 +
39975 +       if (!(stat & IO_PORTX_INT_SERDES_TXBE))
39976 +               return 0;
39977 +
39978 +       if (port->x_char) {
39979 +               ubi32_serdes_put_char(IO_PORT(port), port->x_char);
39980 +               port->x_char = 0;
39981 +               port->icount.tx++;
39982 +               return 1;
39983 +       }
39984 +
39985 +       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
39986 +               ubi32_serdes_stop_tx(port);
39987 +               return 0;
39988 +       }
39989 +
39990 +       ubi32_serdes_put_char(IO_PORT(port), xmit->buf[xmit->tail]);
39991 +       xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
39992 +       port->icount.tx++;
39993 +
39994 +       /* wake up */
39995 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
39996 +               uart_write_wakeup(port);
39997 +
39998 +       if (uart_circ_empty(xmit))
39999 +               ubi32_serdes_stop_tx(port);
40000 +
40001 +       return 1;
40002 +}
40003 +
40004 +/*
40005 + * port is locked and interrupts are disabled
40006 + */
40007 +static void ubi32_serdes_start_tx(struct uart_port *port)
40008 +{
40009 +       IO_PORT_INT_MASK(port) = IO_PORT_INT_MASK(port) | IO_PORTX_INT_SERDES_TXBE;
40010 +       ubi32_serdes_transmit(port, IO_PORT_INT_STATUS(port));
40011 +}
40012 +
40013 +/*
40014 + * Interrupts are enabled
40015 + */
40016 +static void ubi32_serdes_stop_rx(struct uart_port *port)
40017 +{
40018 +       /* don't forward any more data (like !CREAD) */
40019 +       port->ignore_status_mask = IO_PORTX_INT_SERDES_RXBF;
40020 +}
40021 +
40022 +/*
40023 + * Set the modem control timer to fire immediately.
40024 + */
40025 +static void ubi32_serdes_enable_ms(struct uart_port *port)
40026 +{
40027 +       /* N/A */
40028 +}
40029 +
40030 +static irqreturn_t ubi32_serdes_isr(int irq, void *dev_id)
40031 +{
40032 +       struct uart_port *port = dev_id;
40033 +       int busy;
40034 +
40035 +       spin_lock(&port->lock);
40036 +
40037 +       do {
40038 +               int stat = IO_PORT_INT_STATUS(port);
40039 +               busy  = ubi32_serdes_receive(port, stat);
40040 +               busy |= ubi32_serdes_transmit(port, stat);
40041 +       } while (busy);
40042 +
40043 +       tty_flip_buffer_push(port->info->port.tty);
40044 +
40045 +       spin_unlock(&port->lock);
40046 +
40047 +       return IRQ_HANDLED;
40048 +}
40049 +
40050 +/*
40051 + * Return TIOCSER_TEMT when transmitter is not busy.
40052 + */
40053 +static unsigned int ubi32_serdes_tx_empty(struct uart_port *port)
40054 +{
40055 +       unsigned long flags;
40056 +       unsigned int ret;
40057 +
40058 +       spin_lock_irqsave(&port->lock, flags);
40059 +       ret = IO_PORT_INT_STATUS(port);
40060 +       spin_unlock_irqrestore(&port->lock, flags);
40061 +
40062 +       return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
40063 +}
40064 +
40065 +static unsigned int ubi32_serdes_get_mctrl(struct uart_port *port)
40066 +{
40067 +       return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
40068 +}
40069 +
40070 +static void ubi32_serdes_set_mctrl(struct uart_port *port, unsigned int mctrl)
40071 +{
40072 +       /* N/A */
40073 +}
40074 +
40075 +/*
40076 + * Interrupts are always disabled.
40077 + */
40078 +static void ubi32_serdes_break_ctl(struct uart_port *port, int break_state)
40079 +{
40080 +       /* N/A */
40081 +}
40082 +
40083 +static int ubi32_serdes_startup(struct uart_port *port)
40084 +{
40085 +       if (request_irq(port->irq, ubi32_serdes_isr, IRQF_DISABLED,
40086 +            "UBI32_SERDES", port)) {
40087 +               printk(KERN_NOTICE "Unable to attach port interrupt\n");
40088 +               return -EBUSY;
40089 +       }
40090 +
40091 +       IO_PORT_INT_CLR(port) = IO_PORTX_INT_SERDES_RXBF;
40092 +       IO_PORT_INT_MASK(port) = IO_PORTX_INT_SERDES_RXBF;
40093 +       return 0;
40094 +}
40095 +
40096 +static void ubi32_serdes_shutdown(struct uart_port *port)
40097 +{
40098 +       struct ubi32_serdes_port *uart = (struct ubi32_serdes_port *)port;
40099 +
40100 +       IO_PORT_INT_MASK(port) = 0;
40101 +       free_irq(port->irq, uart);
40102 +}
40103 +
40104 +static void
40105 +ubi32_serdes_set_termios(struct uart_port *port, struct ktermios *termios,
40106 +                  struct ktermios *old)
40107 +{
40108 +       unsigned long flags;
40109 +       unsigned int baud;
40110 +
40111 +       spin_lock_irqsave(&port->lock, flags);
40112 +
40113 +       port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
40114 +               | ULITE_STATUS_TXFULL;
40115 +
40116 +       if (termios->c_iflag & INPCK)
40117 +               port->read_status_mask |=
40118 +                       ULITE_STATUS_PARITY | ULITE_STATUS_FRAME;
40119 +
40120 +       port->ignore_status_mask = 0;
40121 +       if (termios->c_iflag & IGNPAR)
40122 +               port->ignore_status_mask |= ULITE_STATUS_PARITY
40123 +                       | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
40124 +
40125 +       /* ignore all characters if CREAD is not set */
40126 +       if ((termios->c_cflag & CREAD) == 0)
40127 +               port->ignore_status_mask |=
40128 +                       ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
40129 +                       | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
40130 +
40131 +       /* update timeout */
40132 +       baud = uart_get_baud_rate(port, termios, old, 0, 460800);
40133 +       uart_update_timeout(port, termios->c_cflag, baud);
40134 +
40135 +       IO_PORT(port)->ctl0 = SERIAL_UBICOM_CTL0 | 
40136 +                       ((port->uartclk / (16 * baud)) - 1);
40137 +
40138 +       spin_unlock_irqrestore(&port->lock, flags);
40139 +}
40140 +
40141 +static const char *ubi32_serdes_type(struct uart_port *port)
40142 +{
40143 +       return port->type == PORT_UBI32_SERDES ? "UBI32_SERDES" : NULL;
40144 +}
40145 +
40146 +/*
40147 + * Release the memory region(s) being used by 'port'.
40148 + */
40149 +static void ubi32_serdes_release_port(struct uart_port *port)
40150 +{
40151 +}
40152 +
40153 +/*
40154 + * Request the memory region(s) being used by 'port'.
40155 + */
40156 +static int ubi32_serdes_request_port(struct uart_port *port)
40157 +{
40158 +       return 0;
40159 +}
40160 +
40161 +/*
40162 + * Configure/autoconfigure the port.
40163 + */
40164 +static void ubi32_serdes_config_port(struct uart_port *port, int flags)
40165 +{
40166 +       if (flags & UART_CONFIG_TYPE &&
40167 +           ubi32_serdes_request_port(port) == 0)
40168 +               port->type = PORT_UBI32_SERDES;
40169 +}
40170 +
40171 +/*
40172 + * Verify the new serial_struct (for TIOCSSERIAL).
40173 + * The only change we allow are to the flags and type, and
40174 + * even then only between PORT_UBI32_SERDES and PORT_UNKNOWN
40175 + */
40176 +static int
40177 +ubi32_serdes_verify_port(struct uart_port *port, struct serial_struct *ser)
40178 +{
40179 +       return 0;
40180 +}
40181 +
40182 +static struct uart_ops ubi32_serdes_pops = {
40183 +       .tx_empty       = ubi32_serdes_tx_empty,
40184 +       .set_mctrl      = ubi32_serdes_set_mctrl,
40185 +       .get_mctrl      = ubi32_serdes_get_mctrl,
40186 +       .stop_tx        = ubi32_serdes_stop_tx,
40187 +       .start_tx       = ubi32_serdes_start_tx,
40188 +       .stop_rx        = ubi32_serdes_stop_rx,
40189 +       .enable_ms      = ubi32_serdes_enable_ms,
40190 +       .break_ctl      = ubi32_serdes_break_ctl,
40191 +       .startup        = ubi32_serdes_startup,
40192 +       .shutdown       = ubi32_serdes_shutdown,
40193 +       .set_termios    = ubi32_serdes_set_termios,
40194 +       .type           = ubi32_serdes_type,
40195 +       .release_port   = ubi32_serdes_release_port,
40196 +       .request_port   = ubi32_serdes_request_port,
40197 +       .config_port    = ubi32_serdes_config_port,
40198 +       .verify_port    = ubi32_serdes_verify_port,
40199 +};
40200 +
40201 +static void __init ubi32_serdes_init_ports(void)
40202 +{
40203 +       int i;
40204 +
40205 +       for (i = 0; i < NR_PORTS; i++) {
40206 +               ubi32_serdes_ports[i].uartclk   = ubi32_serdes_resource[i].uart_clock;
40207 +               ubi32_serdes_ports[i].ops       = &ubi32_serdes_pops;
40208 +               ubi32_serdes_ports[i].line      = i;
40209 +               ubi32_serdes_ports[i].iotype    = UPIO_MEM;
40210 +               ubi32_serdes_ports[i].membase   =
40211 +                       (void __iomem *)ubi32_serdes_resource[i].uart_base_addr;
40212 +               ubi32_serdes_ports[i].mapbase   =
40213 +                       (resource_size_t)ubi32_serdes_resource[i].uart_base_addr;
40214 +               ubi32_serdes_ports[i].irq       =
40215 +                       ubi32_serdes_resource[i].uart_irq;
40216 +               ubi32_serdes_ports[i].flags     = UPF_BOOT_AUTOCONF;
40217 +
40218 +               ubi32_serdes_hw_init(&ubi32_serdes_ports[i], 0);
40219 +       }
40220 +
40221 +}
40222 +
40223 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40224 +/*
40225 + * If the port was already initialised (eg, by a boot loader),
40226 + * try to determine the current setup.
40227 + */
40228 +static void __init
40229 +ubi32_serdes_console_get_options(struct uart_port *port, int *baud)
40230 +{
40231 +       u32 round_to = 1200;
40232 +       u32 real_baud;
40233 +
40234 +       /*
40235 +        * We might get called before platform init and with no
40236 +        * kernel command line options, so port might be NULL.
40237 +        */
40238 +       *baud = ubi32_serdes_default_baud_rate;;
40239 +       if ( IO_PORT(port) == 0 )
40240 +               return;
40241 +
40242 +       real_baud = port->uartclk 
40243 +               / (16 * ((IO_PORT(port)->ctl0 & ~SERIAL_UBICOM_CTL0) + 1));
40244 +
40245 +       *baud = ((real_baud + round_to - 1) / round_to) * round_to;
40246 +
40247 +       pr_debug("%s:baud = %d, real_baud = %d\n", __FUNCTION__, *baud, real_baud);
40248 +}
40249 +#endif
40250 +
40251 +#if defined(CONFIG_SERIAL_UBI32_SERDES_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
40252 +static struct uart_driver ubi32_serdes_reg;
40253 +
40254 +static int __init
40255 +ubi32_serdes_console_setup(struct console *co, char *options)
40256 +{
40257 +       struct uart_port *port;
40258 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40259 +       int baud = ubi32_serdes_default_baud_rate;
40260 +       int bits = 8;
40261 +       int parity = 'n';
40262 +       int flow = 'n';
40263 +#endif
40264 +
40265 +       /*
40266 +        * Check whether an invalid uart number has been specified, and
40267 +        * if so, search for the first available port that does have
40268 +        * console support.
40269 +        */
40270 +       if (co->index == -1 || co->index >= NR_PORTS)
40271 +               co->index = 0;
40272 +       port = &ubi32_serdes_ports[co->index];
40273 +
40274 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40275 +       if (options) {
40276 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
40277 +               ubi32_serdes_hw_init(port, baud);
40278 +       }
40279 +       else
40280 +               ubi32_serdes_console_get_options(port, &baud);
40281 +
40282 +       return uart_set_options(port, co, baud, parity, bits, flow);
40283 +#else
40284 +       return 0;
40285 +#endif
40286 +}
40287 +#endif /* defined (CONFIG_SERIAL_UBI32_SERDES_CONSOLE) ||
40288 +                                defined (CONFIG_EARLY_PRINTK) */
40289 +
40290 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40291 +static void 
40292 +ubi32_serdes_console_putchar(struct uart_port *port, int ch)
40293 +{
40294 +       if ( IO_PORT(port) ) {
40295 +               while (!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE))
40296 +                       barrier();
40297 +               ubi32_serdes_put_char(IO_PORT(port), ch);
40298 +       }
40299 +}
40300 +
40301 +/*
40302 + * Interrupts are disabled on entering
40303 + */
40304 +static void
40305 +ubi32_serdes_console_write(struct console *co, const char *s, unsigned int count)
40306 +{
40307 +       struct uart_port *port = &ubi32_serdes_ports[co->index];
40308 +       unsigned long flags = 0;
40309 +
40310 +       spin_lock_irqsave(&port->lock, flags);
40311 +       uart_console_write(port, s, count, ubi32_serdes_console_putchar);
40312 +       spin_unlock_irqrestore(&port->lock, flags);
40313 +
40314 +}
40315 +
40316 +static struct console ubi32_serdes_console = {
40317 +       .name           = UBI32_SERDES_NAME,
40318 +       .write          = ubi32_serdes_console_write,
40319 +       .device         = uart_console_device,
40320 +       .setup          = ubi32_serdes_console_setup,
40321 +       .flags          = CON_PRINTBUFFER,
40322 +       .index          = -1,
40323 +       .data           = &ubi32_serdes_reg,
40324 +};
40325 +
40326 +static int __init ubi32_serdes_console_init(void)
40327 +{
40328 +       ubi32_serdes_init_ports();
40329 +       register_console(&ubi32_serdes_console);
40330 +       return 0;
40331 +}
40332 +console_initcall(ubi32_serdes_console_init);
40333 +
40334 +#define UBI32_SERDES_CONSOLE   &ubi32_serdes_console
40335 +#else
40336 +#define UBI32_SERDES_CONSOLE   NULL
40337 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
40338 +
40339 +
40340 +#ifdef CONFIG_EARLY_PRINTK
40341 +static __init void ubi32_serdes_early_putc(struct uart_port *port, int ch)
40342 +{
40343 +       unsigned timeout = 0xffff;
40344 +
40345 +       while ((!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE)) && --timeout)
40346 +               cpu_relax();
40347 +       ubi32_serdes_put_char(IO_PORT(port), ch);
40348 +}
40349 +
40350 +static __init void ubi32_serdes_early_write(struct console *con, const char *s,
40351 +                                       unsigned int n)
40352 +{
40353 +       struct uart_port *port = &ubi32_serdes_ports[con->index];
40354 +       unsigned int i;
40355 +
40356 +       for (i = 0; i < n; i++, s++) {
40357 +               if (*s == '\n')
40358 +                       ubi32_serdes_early_putc(port, '\r');
40359 +               ubi32_serdes_early_putc(port, *s);
40360 +       }
40361 +}
40362 +
40363 +static struct __init console ubi32_serdes_early_console = {
40364 +       .name = "early_US",
40365 +       .write = ubi32_serdes_early_write,
40366 +       .device = uart_console_device,
40367 +       .flags = CON_PRINTBUFFER,
40368 +       .setup = ubi32_serdes_console_setup,
40369 +       .index = -1,
40370 +       .data  = &ubi32_serdes_reg,
40371 +};
40372 +
40373 +/*
40374 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
40375 + */
40376 +struct console __init *ubi32_serdes_early_init(unsigned int port_index,
40377 +                                               unsigned int cflag)
40378 +{
40379 +       struct uart_port *uart;
40380 +       struct ktermios t;
40381 +
40382 +       if (port_index == -1 || port_index >= NR_PORTS)
40383 +               port_index = 0;
40384 +       ubi32_serdes_init_ports();
40385 +       ubi32_serdes_early_console.index = port_index;
40386 +       uart = &ubi32_serdes_ports[port_index];
40387 +       t.c_cflag = cflag;
40388 +       t.c_iflag = 0;
40389 +       t.c_oflag = 0;
40390 +       t.c_lflag = ICANON;
40391 +       t.c_line = port_index;
40392 +       ubi32_serdes_set_termios(uart, &t, &t);
40393 +       return &ubi32_serdes_early_console;
40394 +}
40395 +
40396 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
40397 +
40398 +static struct uart_driver ubi32_serdes_reg = {
40399 +       .owner                  = THIS_MODULE,
40400 +       .driver_name            = "ubi32_serdes",
40401 +       .dev_name               = UBI32_SERDES_NAME,
40402 +       .major                  = UBI32_SERDES_MAJOR,
40403 +       .minor                  = UBI32_SERDES_MINOR,
40404 +       .nr                     = NR_PORTS,
40405 +       .cons                   = UBI32_SERDES_CONSOLE,
40406 +};
40407 +
40408 +static int ubi32_serdes_suspend(struct platform_device *dev, pm_message_t state)
40409 +{
40410 +       struct uart_port *port = platform_get_drvdata(dev);
40411 +
40412 +       if (port)
40413 +               uart_suspend_port(&ubi32_serdes_reg, port);
40414 +
40415 +       return 0;
40416 +}
40417 +
40418 +static int ubi32_serdes_resume(struct platform_device *dev)
40419 +{
40420 +       struct uart_port *port = platform_get_drvdata(dev);
40421 +
40422 +       if (port)
40423 +               uart_resume_port(&ubi32_serdes_reg, port);
40424 +
40425 +       return 0;
40426 +}
40427 +
40428 +static int ubi32_serdes_probe(struct platform_device *dev)
40429 +{
40430 +       struct resource *res = dev->resource;
40431 +       int i;
40432 +
40433 +       for (i = 0; i < dev->num_resources; i++, res++) {
40434 +               if (res->flags & IORESOURCE_MEM) {
40435 +                       ubi32_serdes_resource[0].uart_base_addr = (void *) res->start;
40436 +               }
40437 +               else if (res->flags & IORESOURCE_IRQ) {
40438 +                       ubi32_serdes_resource[0].uart_irq = res->start;
40439 +               }
40440 +               else if (res->flags & UBICOM32_SUART_IORESOURCE_CLOCK) {
40441 +                       ubi32_serdes_resource[0].uart_clock = res->start;
40442 +               }
40443 +       }
40444 +
40445 +       ubi32_serdes_init_ports();
40446 +
40447 +       return 0;
40448 +}
40449 +
40450 +static int ubi32_serdes_remove(struct platform_device *pdev)
40451 +{
40452 +       struct uart_port *port = platform_get_drvdata(pdev);
40453 +
40454 +       platform_set_drvdata(pdev, NULL);
40455 +
40456 +       if (port)
40457 +               uart_remove_one_port(&ubi32_serdes_reg, port);
40458 +
40459 +       return 0;
40460 +}
40461 +
40462 +static struct platform_driver ubi32_serdes_driver = {
40463 +       .remove         = ubi32_serdes_remove,
40464 +       .suspend        = ubi32_serdes_suspend,
40465 +       .resume         = ubi32_serdes_resume,
40466 +       .driver         = {
40467 +               .name   = "ubicom32suart",
40468 +               .owner  = THIS_MODULE,
40469 +       },
40470 +};
40471 +
40472 +
40473 +#ifndef MODULE
40474 +/*
40475 + * Called at boot time.
40476 + *
40477 + * You can specify IO base, IRQ, and clock for the serdes serial port
40478 + * using kernel command line "serdes=0xiobase,irq,clock".  Values
40479 + * specified will be overwritten by platform device data, if present.
40480 + */
40481 +static int __init ubi32_serdes_setup(char *str)
40482 +{
40483 +#define N_PARMS   (4+1)
40484 +       int ints[N_PARMS];
40485 +       int i;
40486 +
40487 +       str = get_options(str, ARRAY_SIZE(ints), ints);
40488 +
40489 +       for (i = 0; i < N_PARMS; i++) {
40490 +               if (i < ints[0]) {
40491 +                       if (i == 0) {
40492 +                               ubi32_serdes_resource[0].uart_base_addr = (void *) ints[i+1];
40493 +                       }
40494 +                       else if (i == 1) {
40495 +                               ubi32_serdes_resource[0].uart_irq = ints[i+1];
40496 +                       }
40497 +                       else if (i == 2) {
40498 +                               ubi32_serdes_resource[0].uart_clock = ints[i+1];
40499 +                       }
40500 +                       else if (i == 3) {
40501 +                               ubi32_serdes_default_baud_rate = ints[i+1];
40502 +                       }
40503 +               }
40504 +       }
40505 +       return 1;
40506 +}
40507 +
40508 +__setup("serdes=", ubi32_serdes_setup);
40509 +#endif
40510 +
40511 +static int __init ubi32_serdes_init(void)
40512 +{
40513 +       int ret;
40514 +
40515 +       pr_info("Serial: Ubicom32 serdes uart serial driver\n");
40516 +
40517 +       ret = platform_driver_probe(&ubi32_serdes_driver, ubi32_serdes_probe);
40518 +       if (ret != 0) {
40519 +               printk(KERN_INFO "serdes platform_driver_probe() failed: %d\n", ret);
40520 +               return ret;
40521 +       }
40522 +
40523 +       ubi32_serdes_init_ports();
40524 +
40525 +       ret = uart_register_driver(&ubi32_serdes_reg);
40526 +       if ( ret == 0 ) {
40527 +               ret = uart_add_one_port(&ubi32_serdes_reg, &ubi32_serdes_ports[0]);
40528 +               if ( ret != 0 ) {
40529 +                       uart_unregister_driver(&ubi32_serdes_reg);
40530 +               }
40531 +       }
40532 +
40533 +       return ret;
40534 +}
40535 +
40536 +static void __exit ubi32_serdes_exit(void)
40537 +{
40538 +       platform_driver_unregister(&ubi32_serdes_driver);
40539 +       uart_unregister_driver(&ubi32_serdes_reg);
40540 +}
40541 +
40542 +module_init(ubi32_serdes_init);
40543 +module_exit(ubi32_serdes_exit);
40544 +
40545 +MODULE_AUTHOR("Rainer Keller <rkeller@ubicom.com>");
40546 +MODULE_DESCRIPTION("Ubicom generic serial port driver");
40547 +MODULE_LICENSE("GPL");
40548 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_SERDES_MAJOR);
40549 +MODULE_ALIAS("platform:ubi32_serdes");
40550 --- /dev/null
40551 +++ b/drivers/serial/ubi32_uarttio.c
40552 @@ -0,0 +1,1171 @@
40553 +/*
40554 + * drivers/serial/ubi32_uarttio.c
40555 + *   Ubicom32 Serial Virtual Peripherial Driver
40556 + *
40557 + * (C) Copyright 2009, Ubicom, Inc.
40558 + *
40559 + * This file is part of the Ubicom32 Linux Kernel Port.
40560 + *
40561 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
40562 + * it and/or modify it under the terms of the GNU General Public License
40563 + * as published by the Free Software Foundation, either version 2 of the
40564 + * License, or (at your option) any later version.
40565 + *
40566 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
40567 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
40568 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
40569 + * the GNU General Public License for more details.
40570 + *
40571 + * You should have received a copy of the GNU General Public License
40572 + * along with the Ubicom32 Linux Kernel Port.  If not, 
40573 + * see <http://www.gnu.org/licenses/>.
40574 + */
40575 +
40576 +#include <linux/module.h>
40577 +#include <linux/ioport.h>
40578 +#include <linux/init.h>
40579 +#include <linux/console.h>
40580 +#include <linux/sysrq.h>
40581 +#include <linux/platform_device.h>
40582 +#include <linux/tty.h>
40583 +#include <linux/tty_flip.h>
40584 +#include <linux/serial_core.h>
40585 +
40586 +#include <asm/ip5000.h>
40587 +#include <asm/gpio.h>
40588 +#include <asm/thread.h>
40589 +#include <asm/uart_tio.h>
40590 +
40591 +#define DRIVER_NAME    "ubi32_uarttio"
40592 +
40593 +/*
40594 + * For storing the module parameters.
40595 + */
40596 +#define UBI32_UARTTIO_MAX_PARAM_LEN    80
40597 +static char utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN];
40598 +
40599 +/* 
40600 + * UART name and device definitions 
40601 + */
40602 +#define UBI32_UARTTIO_NAME     "ttyUV" // XXX
40603 +#define UBI32_UARTTIO_MAJOR    206 // XXX
40604 +#define UBI32_UARTTIO_MINOR    64 // XXX
40605 +
40606 +/*
40607 + * The following structures are allocated statically because the
40608 + * memory allocation subsystem is not initialized this early on
40609 + */
40610 +
40611 +/*
40612 + * Per port structure
40613 + */
40614 +struct ubi32_uarttio_port {
40615 +       struct uarttio_uart             *uart;
40616 +       unsigned int                    tx_pin;
40617 +       unsigned int                    rx_pin;
40618 +
40619 +       struct uart_port                port;
40620 +
40621 +       u8_t                            added;
40622 +
40623 +       /*
40624 +        * If this value is set, the port has had its direction set already
40625 +        */
40626 +       u8_t                            port_init;
40627 +};
40628 +static struct ubi32_uarttio_port uarttio_ports[CONFIG_SERIAL_UBI32_UARTTIO_NR_UARTS];
40629 +
40630 +/*
40631 + * Number of ports currently initialized
40632 + */
40633 +static int uarttio_nports;
40634 +
40635 +/*
40636 + * Per device structure
40637 + */
40638 +struct ubi32_uarttio_instance {
40639 +       struct uarttio_regs             *regs;
40640 +       struct ubi32_uarttio_port       *ports;
40641 +
40642 +       u8_t                            irq_requested;
40643 +       u8_t                            driver_registered;
40644 +       u8_t                            irq;
40645 +};
40646 +static struct ubi32_uarttio_instance uarttio_inst;
40647 +
40648 +#ifdef CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE
40649 +static struct console ubi32_uarttio_console;
40650 +#define UBI32_UARTTIO_CONSOLE  &ubi32_uarttio_console
40651 +#else
40652 +#define UBI32_UARTTIO_CONSOLE  NULL
40653 +#endif
40654 +
40655 +static struct uart_driver ubi32_uarttio_uart_driver = {
40656 +       .owner                  = THIS_MODULE,
40657 +       .driver_name            = DRIVER_NAME,
40658 +       .dev_name               = UBI32_UARTTIO_NAME,
40659 +       .major                  = UBI32_UARTTIO_MAJOR,
40660 +       .minor                  = UBI32_UARTTIO_MINOR,
40661 +       .cons                   = UBI32_UARTTIO_CONSOLE,
40662 +};
40663 +
40664 +#ifdef UBI32_UARTTIO_UNUSED
40665 +/*
40666 + * ubi32_uarttio_get_send_space
40667 + */
40668 +static int ubi32_uarttio_get_send_space(struct uarttio_uart *uart)
40669 +{
40670 +       int count = uart->tx_fifo_head - uart->tx_fifo_tail;
40671 +       if (count < 0) {
40672 +               count += uart->tx_fifo_size;
40673 +       }
40674 +       return uart->tx_fifo_size - count;
40675 +}
40676 +#endif
40677 +
40678 +/*
40679 + * ubi32_uarttio_get_recv_ready
40680 + */
40681 +static int ubi32_uarttio_get_recv_ready(struct uarttio_uart *uart)
40682 +{
40683 +       int count = uart->rx_fifo_head - uart->rx_fifo_tail;
40684 +       if (count < 0) {
40685 +               count += uart->rx_fifo_size;
40686 +       }
40687 +       return count;
40688 +}
40689 +
40690 +/*
40691 + * ubi32_uarttio_get_char()
40692 + */
40693 +static u8_t ubi32_uarttio_get_char(struct uarttio_uart *uart)
40694 +{
40695 +       /*
40696 +        * Retrieve byte
40697 +        */
40698 +       u32_t tail = uart->rx_fifo_tail;
40699 +       u8_t data = uart->rx_fifo[tail];
40700 +
40701 +       if (++tail == uart->rx_fifo_size) {
40702 +               tail = 0;
40703 +       }
40704 +       uart->rx_fifo_tail = tail;
40705 +
40706 +       return data;
40707 +}
40708 +
40709 +/*
40710 + * ubi32_uarttio_put_char()
40711 + */
40712 +static int ubi32_uarttio_put_char(struct uarttio_uart *uart, u8_t c)
40713 +{
40714 +       u32_t head = uart->tx_fifo_head;
40715 +       u32_t prev = head;
40716 +
40717 +       /*
40718 +        * Wrap
40719 +        */
40720 +       if (++head == uart->tx_fifo_size) {
40721 +               head = 0;
40722 +       }
40723 +
40724 +       /*
40725 +        * If there isn't any space, return EBUSY
40726 +        */
40727 +       if (head == uart->tx_fifo_tail) {
40728 +               return -EBUSY;
40729 +       }
40730 +
40731 +       /*
40732 +        * Put the character in the queue
40733 +        */
40734 +       uart->tx_fifo[prev] = c;
40735 +       uart->tx_fifo_head = head;
40736 +
40737 +       return 0;
40738 +}
40739 +
40740 +/*
40741 + * ubi32_uarttio_set_baud
40742 + */
40743 +static int ubi32_uarttio_set_baud(struct ubi32_uarttio_port *uup, unsigned int baud)
40744 +{
40745 +       if (uup->uart->current_baud_rate == baud) {
40746 +               return 0;
40747 +       }
40748 +
40749 +       uup->uart->baud_rate = baud;
40750 +       uup->uart->flags |= UARTTIO_UART_FLAG_SET_RATE;
40751 +       while (uup->uart->flags & UARTTIO_UART_FLAG_SET_RATE) {
40752 +               cpu_relax();
40753 +       }
40754 +
40755 +       if (uup->uart->current_baud_rate != baud) {
40756 +               /*
40757 +                * Failed to set baud rate
40758 +                */
40759 +               printk(KERN_WARNING "Invalid baud rate %u, running at %u\n", baud, uup->uart->current_baud_rate);
40760 +               return -EINVAL;
40761 +       }
40762 +
40763 +       return 0;
40764 +}
40765 +
40766 +/*
40767 + * ubi32_uarttio_handle_receive
40768 + */
40769 +static void ubi32_uarttio_handle_receive(struct ubi32_uarttio_port *uup, int stat)
40770 +{
40771 +       struct uarttio_uart *uart = uup->uart;
40772 +       struct uart_port *port = &uup->port;
40773 +       struct tty_struct *tty = port->info->port.tty;
40774 +       unsigned char ch = 0;
40775 +       char flag = TTY_NORMAL;
40776 +       int count;
40777 +
40778 +       if ((stat & (UARTTIO_UART_INT_RX | UARTTIO_UART_INT_RXFRAME | UARTTIO_UART_INT_RXOVF)) == 0) {
40779 +               return;
40780 +       }
40781 +
40782 +       if (stat & UARTTIO_UART_INT_RX) {
40783 +               count = ubi32_uarttio_get_recv_ready(uart);
40784 +               port->icount.rx += count;
40785 +       }
40786 +
40787 +       if (stat & UARTTIO_UART_INT_RXOVF) {
40788 +               port->icount.overrun++;
40789 +       }
40790 +
40791 +       if (stat & UARTTIO_UART_INT_RXFRAME) {
40792 +               port->icount.frame++;
40793 +       }
40794 +
40795 +       stat &= ~port->ignore_status_mask;
40796 +
40797 +       if (stat & UARTTIO_UART_INT_RX) {
40798 +               int i;
40799 +               for (i = 0; i < count; i++) {
40800 +                       ch = ubi32_uarttio_get_char(uart);
40801 +                       tty_insert_flip_char(tty, ch, flag);
40802 +               }
40803 +       }
40804 +
40805 +       if (stat & UARTTIO_UART_INT_RXFRAME) {
40806 +               tty_insert_flip_char(tty, 0, TTY_FRAME);
40807 +       }
40808 +
40809 +       if (stat & UARTTIO_UART_INT_RXOVF) {
40810 +               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
40811 +       }
40812 +}
40813 +
40814 +/*
40815 + * ubi32_uarttio_stop_tx
40816 + *     interrupts are disabled on entry
40817 + */
40818 +static void ubi32_uarttio_stop_tx(struct uart_port *port)
40819 +{
40820 +       struct ubi32_uarttio_port *uup = port->private_data;
40821 +
40822 +       uup->uart->int_mask &= ~UARTTIO_UART_INT_TXBE;
40823 +}
40824 +
40825 +/*
40826 + * ubi32_uarttio_handle_transmit
40827 + */
40828 +static void ubi32_uarttio_handle_transmit(struct ubi32_uarttio_port *uup, int stat)
40829 +{
40830 +       struct uarttio_uart *uart = uup->uart;
40831 +       struct uart_port *port = &uup->port;
40832 +       struct circ_buf *xmit  = &port->info->xmit;
40833 +
40834 +       if (!(stat & UARTTIO_UART_INT_TXBE)) {
40835 +               return;
40836 +       }
40837 +
40838 +       if (port->x_char) {
40839 +               if (ubi32_uarttio_put_char(uart, port->x_char)) {
40840 +                       return;
40841 +               }
40842 +               port->x_char = 0;
40843 +               port->icount.tx++;
40844 +               return;
40845 +       }
40846 +
40847 +       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
40848 +               ubi32_uarttio_stop_tx(port);
40849 +               return;
40850 +       }
40851 +
40852 +       /*
40853 +        * Send as many characters as we can
40854 +        */
40855 +       while (ubi32_uarttio_put_char(uart, xmit->buf[xmit->tail]) == 0) {
40856 +               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
40857 +               port->icount.tx++;
40858 +               if (uart_circ_empty(xmit)) {
40859 +                       break;
40860 +               }
40861 +       }
40862 +
40863 +       /* wake up */
40864 +       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
40865 +               uart_write_wakeup(port);
40866 +       }
40867 +
40868 +       if (uart_circ_empty(xmit)) {
40869 +               ubi32_uarttio_stop_tx(port);
40870 +       }
40871 +}
40872 +
40873 +/*
40874 + * ubi32_uarttio_start_tx
40875 + *     port is locked and interrupts are disabled
40876 + */
40877 +static void ubi32_uarttio_start_tx(struct uart_port *port)
40878 +{
40879 +       struct ubi32_uarttio_port *uup = port->private_data;
40880 +       struct uarttio_uart *uart = uup->uart;
40881 +
40882 +       uart->int_mask |= UARTTIO_UART_INT_TXBE;
40883 +}
40884 +
40885 +/*
40886 + * ubi32_uarttio_stop_rx
40887 + *     Interrupts are enabled
40888 + */
40889 +static void ubi32_uarttio_stop_rx(struct uart_port *port)
40890 +{
40891 +       struct ubi32_uarttio_port *uup = port->private_data;
40892 +       struct uarttio_uart *uart = uup->uart;
40893 +
40894 +       /* 
40895 +        * don't forward any more data (like !CREAD) 
40896 +        */
40897 +       uart->int_mask &= ~UARTTIO_UART_INT_RX;
40898 +       port->ignore_status_mask = UARTTIO_UART_INT_RX;
40899 +}
40900 +
40901 +/*
40902 + * ubi32_uarttio_enable_ms
40903 + *     Set the modem control timer to fire immediately.
40904 + */
40905 +static void ubi32_uarttio_enable_ms(struct uart_port *port)
40906 +{
40907 +       /* N/A */
40908 +}
40909 +
40910 +/*
40911 + * ubi32_uarttio_isr
40912 + */
40913 +static irqreturn_t ubi32_uarttio_isr(int irq, void *appdata)
40914 +{
40915 +       struct ubi32_uarttio_port *uup = uarttio_ports;
40916 +       int i;
40917 +
40918 +       /*
40919 +        * Service all of the ports
40920 +        */
40921 +       for (i = 0; i < uarttio_nports; i++) {
40922 +               unsigned int flags;
40923 +
40924 +               if (!(uup->uart->flags & UARTTIO_UART_FLAG_ENABLED)) {
40925 +                       uup++;
40926 +                       continue;
40927 +               }
40928 +
40929 +               spin_lock(&uup->port.lock);
40930 +
40931 +               flags = uup->uart->int_flags;
40932 +
40933 +               uup->uart->int_flags = 0;
40934 +
40935 +               ubi32_uarttio_handle_receive(uup, flags);
40936 +               ubi32_uarttio_handle_transmit(uup, flags);
40937 +
40938 +               tty_flip_buffer_push(uup->port.info->port.tty);
40939 +
40940 +               spin_unlock(&uup->port.lock);
40941 +
40942 +               uup++;
40943 +       }
40944 +
40945 +       return IRQ_HANDLED;
40946 +}
40947 +
40948 +/*
40949 + * ubi32_uarttio_tx_empty
40950 + *     Return TIOCSER_TEMT when transmitter is not busy.
40951 + */
40952 +static unsigned int ubi32_uarttio_tx_empty(struct uart_port *port)
40953 +{
40954 +       struct ubi32_uarttio_port *uup = port->private_data;
40955 +
40956 +       if (uup->uart->tx_fifo_head == uup->uart->tx_fifo_tail) {
40957 +               return TIOCSER_TEMT;
40958 +       }
40959 +
40960 +       return 0;
40961 +}
40962 +
40963 +/*
40964 + * ubi32_uarttio_get_mctrl
40965 + */
40966 +static unsigned int ubi32_uarttio_get_mctrl(struct uart_port *port)
40967 +{
40968 +       return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
40969 +}
40970 +
40971 +/*
40972 + * ubi32_uarttio_set_mctrl
40973 + */
40974 +static void ubi32_uarttio_set_mctrl(struct uart_port *port, unsigned int mctrl)
40975 +{
40976 +       /* N/A */
40977 +}
40978 +
40979 +/*
40980 + * ubi32_uarttio_break_ctl
40981 + */
40982 +static void ubi32_uarttio_break_ctl(struct uart_port *port, int break_state)
40983 +{
40984 +       /* N/A */
40985 +}
40986 +
40987 +/*
40988 + * ubi32_uarttio_startup
40989 + */
40990 +static int ubi32_uarttio_startup(struct uart_port *port)
40991 +{
40992 +       struct ubi32_uarttio_port *uup = port->private_data;
40993 +       struct uarttio_uart *uart = uup->uart;
40994 +
40995 +       uart->flags |= UARTTIO_UART_FLAG_ENABLED;
40996 +
40997 +       uart->int_mask |= UARTTIO_UART_INT_TXBE | UARTTIO_UART_INT_RX;
40998 +
40999 +       return 0;
41000 +}
41001 +
41002 +/*
41003 + * ubi32_uarttio_shutdown
41004 + */
41005 +static void ubi32_uarttio_shutdown(struct uart_port *port)
41006 +{
41007 +       struct ubi32_uarttio_port *uup = port->private_data;
41008 +       struct uarttio_uart *uart = uup->uart;
41009 +
41010 +       uart->int_mask = 0;
41011 +       uart->flags &= ~UARTTIO_UART_FLAG_ENABLED;
41012 +}
41013 +
41014 +/*
41015 + * ubi32_uarttio_set_termios
41016 + */
41017 +static void ubi32_uarttio_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
41018 +{
41019 +       struct ubi32_uarttio_port *uup = port->private_data;
41020 +       unsigned long flags;
41021 +       unsigned int baud;
41022 +
41023 +       spin_lock_irqsave(&port->lock, flags);
41024 +
41025 +#if 0
41026 +       port->read_status_mask = UBI32_UARTTIO_RX | UBI32_UARTTIO_RXOVF | UBI32_UARTTIO_TXOVF;
41027 +
41028 +       if (termios->c_iflag & INPCK) {
41029 +               port->read_status_mask |= UBI32_UARTTIO_RXFRAME;
41030 +       }
41031 +#endif
41032 +
41033 +       port->ignore_status_mask = 0;
41034 +       if (termios->c_iflag & IGNPAR) {
41035 +               port->ignore_status_mask |= UARTTIO_UART_INT_RXFRAME | 
41036 +                                           UARTTIO_UART_INT_RXOVF;
41037 +       }
41038 +
41039 +       /* 
41040 +        * ignore all characters if CREAD is not set 
41041 +        */
41042 +       if ((termios->c_cflag & CREAD) == 0) {
41043 +               port->ignore_status_mask |= UARTTIO_UART_INT_RX | 
41044 +                                           UARTTIO_UART_INT_RXFRAME | 
41045 +                                           UARTTIO_UART_INT_RXOVF;
41046 +       }
41047 +
41048 +       /* update timeout */
41049 +       baud = uart_get_baud_rate(port, termios, old, 0, 460800);
41050 +       uart_update_timeout(port, termios->c_cflag, baud);
41051 +
41052 +       ubi32_uarttio_set_baud(uup, baud);
41053 +       spin_unlock_irqrestore(&port->lock, flags);
41054 +}
41055 +
41056 +/*
41057 + * ubi32_uarttio_type
41058 + */
41059 +static const char *ubi32_uarttio_type(struct uart_port *port)
41060 +{
41061 +       return (port->type == PORT_UBI32_UARTTIO) ? "UBI32_UARTTIO" : NULL;
41062 +}
41063 +
41064 +/*
41065 + * ubi32_uarttio_release_port
41066 + *     Release the memory region(s) being used by 'port'.
41067 + */
41068 +static void ubi32_uarttio_release_port(struct uart_port *port)
41069 +{
41070 +}
41071 +
41072 +/*
41073 + * ubi32_uarttio_request_port
41074 + *     Request the memory region(s) being used by 'port'.
41075 + */
41076 +static int ubi32_uarttio_request_port(struct uart_port *port)
41077 +{
41078 +       return 0;
41079 +}
41080 +
41081 +/*
41082 + * ubi32_uarttio_config_port
41083 + *     Configure/autoconfigure the port.
41084 + */
41085 +static void ubi32_uarttio_config_port(struct uart_port *port, int flags)
41086 +{
41087 +       if ((flags & UART_CONFIG_TYPE) && (ubi32_uarttio_request_port(port) == 0)) {
41088 +               port->type = PORT_UBI32_UARTTIO;
41089 +       }
41090 +}
41091 +
41092 +/*
41093 + * ubi32_uarttio_verify_port
41094 + *     Verify the new serial_struct (for TIOCSSERIAL).
41095 + *
41096 + * The only change we allow are to the flags and type, and
41097 + * even then only between PORT_UBI32_UARTTIO and PORT_UNKNOWN
41098 + */
41099 +static int ubi32_uarttio_verify_port(struct uart_port *port, struct serial_struct *ser)
41100 +{
41101 +       return 0;
41102 +}
41103 +
41104 +static struct uart_ops ubi32_uarttio_pops = {
41105 +       .tx_empty       = ubi32_uarttio_tx_empty,
41106 +       .set_mctrl      = ubi32_uarttio_set_mctrl,
41107 +       .get_mctrl      = ubi32_uarttio_get_mctrl,
41108 +       .stop_tx        = ubi32_uarttio_stop_tx,
41109 +       .start_tx       = ubi32_uarttio_start_tx,
41110 +       .stop_rx        = ubi32_uarttio_stop_rx,
41111 +       .enable_ms      = ubi32_uarttio_enable_ms,
41112 +       .break_ctl      = ubi32_uarttio_break_ctl,
41113 +       .startup        = ubi32_uarttio_startup,
41114 +       .shutdown       = ubi32_uarttio_shutdown,
41115 +       .set_termios    = ubi32_uarttio_set_termios,
41116 +       .type           = ubi32_uarttio_type,
41117 +       .release_port   = ubi32_uarttio_release_port,
41118 +       .request_port   = ubi32_uarttio_request_port,
41119 +       .config_port    = ubi32_uarttio_config_port,
41120 +       .verify_port    = ubi32_uarttio_verify_port,
41121 +};
41122 +
41123 +/*
41124 + * ubi32_uarttio_add_ports
41125 + */
41126 +static int __init ubi32_uarttio_add_ports(void)
41127 +{
41128 +       int res = 0;
41129 +       struct ubi32_uarttio_port *uup = uarttio_ports;
41130 +       int i = 0;
41131 +
41132 +       for (i = 0; i < uarttio_nports; i++) {
41133 +               /*
41134 +                * Setup the GPIOs
41135 +                */
41136 +               res = gpio_request(uup->tx_pin, "ubi32_uarttio_tx");
41137 +               if (res) {
41138 +                       printk(KERN_WARNING "Failed to request GPIO %d\n", uup->tx_pin);
41139 +                       res = -EBUSY;
41140 +                       goto next;
41141 +               }
41142 +
41143 +               res = gpio_request(uup->rx_pin, "ubi32_uarttio_rx");
41144 +               if (res) {
41145 +                       gpio_free(uup->tx_pin);
41146 +                       printk(KERN_WARNING "Failed to request GPIO %d\n", uup->rx_pin);
41147 +                       res = -EBUSY;
41148 +                       goto next;
41149 +               }
41150 +
41151 +               res = uart_add_one_port(&ubi32_uarttio_uart_driver, &uup->port);
41152 +               if (res) {
41153 +                       gpio_free(uup->rx_pin);
41154 +                       gpio_free(uup->tx_pin);
41155 +                       res = -ENODEV;
41156 +                       printk(KERN_WARNING "Failed to add port %d,%d\n", uup->tx_pin, uup->rx_pin);
41157 +                       goto next;
41158 +               }
41159 +               uup->added = 1;
41160 +
41161 +               /*
41162 +                * Set the direction of the ports now, after we're sure that everything is ok
41163 +                */
41164 +               if (!uup->port_init) {
41165 +                       gpio_direction_output(uup->tx_pin, 1);
41166 +                       gpio_direction_input(uup->rx_pin);
41167 +               }
41168 +
41169 +next:
41170 +               uup++;
41171 +       }
41172 +       return res;
41173 +}
41174 +
41175 +/*
41176 + * ubi32_uarttio_cleanup
41177 + */
41178 +static void ubi32_uarttio_cleanup(void)
41179 +{
41180 +       struct ubi32_uarttio_port *uup;
41181 +       int i;
41182 +
41183 +       /*
41184 +        * Stop the hardware thread
41185 +        */
41186 +       if (uarttio_inst.regs) {
41187 +               thread_disable(uarttio_inst.regs->thread);
41188 +       }
41189 +       if (uarttio_inst.irq_requested) {
41190 +               free_irq(uarttio_inst.irq, NULL);
41191 +       }
41192 +
41193 +       /*
41194 +        * Get rid of the ports
41195 +        */
41196 +       uup = uarttio_inst.ports;
41197 +       for (i = 0; i < uarttio_nports; i++) {
41198 +               gpio_free(uup->tx_pin);
41199 +               gpio_free(uup->rx_pin);
41200 +               if (uup->added) {
41201 +                       uart_remove_one_port(&ubi32_uarttio_uart_driver, &uup->port);
41202 +               }
41203 +               uup++;
41204 +       }
41205 +
41206 +       if (uarttio_inst.driver_registered) {
41207 +               uart_unregister_driver(&ubi32_uarttio_uart_driver);
41208 +       }
41209 +}
41210 +
41211 +/*
41212 + * ubi32_uarttio_setup_port
41213 + *     Setup a port in the TIO registers
41214 + */
41215 +static int ubi32_uarttio_setup_port(int index,
41216 +                                   struct uarttio_uart *uart,
41217 +                                   unsigned int baud, unsigned int tx_pin, 
41218 +                                   unsigned int rx_pin)
41219 +{
41220 +       struct ubi32_uarttio_port *uup = &uarttio_ports[index];
41221 +       void *tx_port = ubi_gpio_get_port(tx_pin);
41222 +       void *rx_port = ubi_gpio_get_port(rx_pin);
41223 +
41224 +       /*
41225 +        * Verify the ports are on chip
41226 +        */
41227 +       if (!tx_port || !rx_port) {
41228 +               printk(KERN_WARNING "Invalid port(s) specified: %u or %u\n", tx_pin, rx_pin);
41229 +               return -EINVAL;
41230 +       }
41231 +
41232 +       uup->tx_pin = tx_pin;
41233 +       uup->rx_pin = rx_pin;
41234 +       uup->uart = uart;
41235 +
41236 +       /*
41237 +        * Setup the port structure
41238 +        */
41239 +       uup->port.ops           = &ubi32_uarttio_pops;
41240 +       uup->port.line          = index;
41241 +       uup->port.iotype        = UPIO_MEM;
41242 +       uup->port.flags         = UPF_BOOT_AUTOCONF;
41243 +       uup->port.fifosize      = uup->uart->tx_fifo_size;
41244 +       uup->port.private_data  = uup;
41245 +
41246 +       /*
41247 +        * We share this IRQ across all ports
41248 +        */
41249 +       uup->port.irq           = uarttio_inst.irq;
41250 +
41251 +       /*
41252 +        * We really don't have a mem/map base but without these variables
41253 +        * set, the serial_core won't startup.
41254 +        */
41255 +       uup->port.membase       = (void __iomem *)uup;
41256 +       uup->port.mapbase       = (resource_size_t)uup;
41257 +       spin_lock_init(&uup->port.lock);
41258 +
41259 +       /*
41260 +        * Set up the hardware
41261 +        */
41262 +       uart->flags = UARTTIO_UART_FLAG_SET_RATE | UARTTIO_UART_FLAG_RESET;
41263 +
41264 +       uart->tx_port = (unsigned int)tx_port;
41265 +       uart->tx_pin = gpio_pin_index(tx_pin);
41266 +       uart->tx_bits = 8;
41267 +       uart->tx_stop_bits = 1;
41268 +
41269 +       uart->rx_port = (unsigned int)rx_port;
41270 +       uart->rx_pin = gpio_pin_index(rx_pin);
41271 +       uart->rx_bits = 8;
41272 +       uart->rx_stop_bits = 1;
41273 +
41274 +       uart->baud_rate = baud;
41275 +
41276 +       return 0;
41277 +}
41278 +
41279 +enum ubi32_uarttio_parse_states {
41280 +       UBI32_UARTTIO_PARSE_STATE_BAUD,
41281 +       UBI32_UARTTIO_PARSE_STATE_TX_PIN,
41282 +       UBI32_UARTTIO_PARSE_STATE_RX_PIN,
41283 +       UBI32_UARTTIO_PARSE_STATE_HS,
41284 +       UBI32_UARTTIO_PARSE_STATE_CTS_PIN,
41285 +       UBI32_UARTTIO_PARSE_STATE_RTS_PIN,
41286 +};
41287 +
41288 +/*
41289 + * ubi32_uarttio_parse_param
41290 + */
41291 +static int ubi32_uarttio_parse_param(char *str)
41292 +{
41293 +       int res;
41294 +       int i;
41295 +       int baud = 0;
41296 +       int tx_pin = 0;
41297 +       int rx_pin = 0;
41298 +       int hs = 0;
41299 +       int cts_pin = 0;
41300 +       int rts_pin = 0;
41301 +       int nfound = 0;
41302 +       enum ubi32_uarttio_parse_states state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41303 +       struct uarttio_uart *uart = uarttio_inst.regs->uarts;
41304 +
41305 +       /*
41306 +        * Run though the options and generate the proper structures
41307 +        */
41308 +       res = get_option(&str, &i);
41309 +       while ((res == 2) || (res == 1)) {
41310 +               switch (state) {
41311 +               case UBI32_UARTTIO_PARSE_STATE_BAUD:
41312 +                       /*
41313 +                        * If we are here and nfound > 0 then create the port 
41314 +                        * based on the previous input
41315 +                        */
41316 +                       if (nfound) {
41317 +                               /*
41318 +                                * Create the port
41319 +                                */
41320 +                               if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41321 +                                       /*
41322 +                                        * Port was invalid
41323 +                                        */
41324 +                                       goto fail;
41325 +                               } else {
41326 +                                       printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41327 +                                       uart++;
41328 +                               }
41329 +                       }
41330 +
41331 +                       /*
41332 +                        * Reset the variables and go to the next state
41333 +                        */
41334 +                       hs = 0;
41335 +                       baud = i;
41336 +                       state = UBI32_UARTTIO_PARSE_STATE_TX_PIN;
41337 +                       break;
41338 +
41339 +               case UBI32_UARTTIO_PARSE_STATE_TX_PIN:
41340 +                       tx_pin = i;
41341 +                       state = UBI32_UARTTIO_PARSE_STATE_RX_PIN;
41342 +                       break;
41343 +
41344 +               case UBI32_UARTTIO_PARSE_STATE_RX_PIN:
41345 +                       rx_pin = i;
41346 +                       state = UBI32_UARTTIO_PARSE_STATE_HS;
41347 +                       break;
41348 +
41349 +               case UBI32_UARTTIO_PARSE_STATE_HS:
41350 +                       hs = i;
41351 +                       if (hs) {
41352 +                               state = UBI32_UARTTIO_PARSE_STATE_CTS_PIN;
41353 +                               break;
41354 +                       }
41355 +
41356 +                       if (nfound == uarttio_inst.regs->max_uarts) {
41357 +                               printk(KERN_WARNING "Maximum number of serial ports reached\n");
41358 +                               goto done;
41359 +                       }
41360 +                       nfound++;
41361 +                       state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41362 +                       break;
41363 +
41364 +               case UBI32_UARTTIO_PARSE_STATE_CTS_PIN:
41365 +                       cts_pin = i;
41366 +                       state = UBI32_UARTTIO_PARSE_STATE_RTS_PIN;
41367 +                       break;
41368 +
41369 +               case UBI32_UARTTIO_PARSE_STATE_RTS_PIN:
41370 +                       rts_pin = i;
41371 +
41372 +                       if (nfound == uarttio_inst.regs->max_uarts) {
41373 +                               printk(KERN_WARNING "Maximum number of serial ports reached\n");
41374 +                               goto done;
41375 +                       }
41376 +                       nfound++;
41377 +                       state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41378 +                       break;
41379 +               }
41380 +               res = get_option(&str, &i);
41381 +       }
41382 +
41383 +       if ((res > 2) || state != UBI32_UARTTIO_PARSE_STATE_BAUD) {
41384 +               printk(KERN_WARNING "Parameter syntax error.\n");
41385 +               res = -EINVAL;
41386 +               goto fail;
41387 +       }
41388 +
41389 +       /*
41390 +        * Create the final port
41391 +        */
41392 +       if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41393 +               goto fail;
41394 +       }
41395 +       printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41396 +
41397 +done:
41398 +       uarttio_nports = nfound;
41399 +
41400 +       return nfound ? 0 : -ENODEV;
41401 +
41402 +fail:
41403 +       /*
41404 +        * Reset the ports
41405 +        */
41406 +       uart = uarttio_inst.regs->uarts;
41407 +       for (i = 0; i < uarttio_inst.regs->max_uarts; i++) {
41408 +               uart->flags = 0;
41409 +               uart++;
41410 +       }
41411 +
41412 +       return res;
41413 +}
41414 +
41415 +/*
41416 + * ubi32_uarttio_probe
41417 + */
41418 +static int ubi32_uarttio_probe(void)
41419 +{
41420 +       int ret;
41421 +       struct uarttio_node *uart_node;
41422 +       char *str = utio_ports_param;
41423 +       static int probed;
41424 +
41425 +       /*
41426 +        * We only want to be probed once, we could be probed twice
41427 +        * for example if we are used as a console
41428 +        */
41429 +       if (probed) {
41430 +               return 0;
41431 +       }
41432 +       probed = 1;
41433 +
41434 +       /*
41435 +        * Extract the TIO name from the setup string
41436 +        */
41437 +       while (*str) {
41438 +               if (*str == ',') {
41439 +                       *str++ = 0;
41440 +                       break;
41441 +               }
41442 +               str++;
41443 +       }
41444 +
41445 +       if (!*str) {
41446 +               return -EINVAL;
41447 +       }
41448 +
41449 +       uart_node = (struct uarttio_node *)devtree_find_node(utio_ports_param);
41450 +       if (!uart_node) {
41451 +               return -ENODEV;
41452 +       }
41453 +
41454 +       uarttio_inst.irq = uart_node->dn.recvirq;
41455 +       uarttio_inst.regs = uart_node->regs;
41456 +
41457 +       /*
41458 +        * Parse module parameters.
41459 +        */
41460 +       ret = ubi32_uarttio_parse_param(str);
41461 +       if (ret != 0) {
41462 +               goto fail;
41463 +       }
41464 +
41465 +       ubi32_uarttio_uart_driver.nr = uarttio_nports;
41466 +
41467 +       return 0;
41468 +
41469 +fail:
41470 +       ubi32_uarttio_cleanup();
41471 +       return ret;
41472 +}
41473 +
41474 +#if defined(CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE)
41475 +/*
41476 + * ubi32_uarttio_console_setup
41477 + */
41478 +static int __init ubi32_uarttio_console_setup(struct console *co, char *options)
41479 +{
41480 +       int baud;
41481 +       int bits = 8;
41482 +       int parity = 'n';
41483 +       int flow = 'n';
41484 +       struct ubi32_uarttio_port *uup;
41485 +
41486 +       /*
41487 +        * Check whether an invalid uart number has been specified, and
41488 +        * if so, search for the first available port that does have
41489 +        * console support.
41490 +        */
41491 +       if (co->index == -1 || co->index >= uarttio_nports) {
41492 +               co->index = 0;
41493 +       }
41494 +       uup = &uarttio_ports[co->index];
41495 +       baud = uup->uart->baud_rate;
41496 +       uup->uart->flags |= UARTTIO_UART_FLAG_ENABLED;
41497 +
41498 +       /*
41499 +        * Setup the GPIOs
41500 +        *      We have to use the direct interface because the gpio
41501 +        *      subsystem is not available at this point.
41502 +        */
41503 +       uup->port_init = 1;
41504 +       UBICOM32_GPIO_SET_PIN_HIGH(uup->tx_pin);
41505 +       UBICOM32_GPIO_SET_PIN_OUTPUT(uup->tx_pin);
41506 +       UBICOM32_GPIO_SET_PIN_INPUT(uup->rx_pin);
41507 +
41508 +       /*
41509 +        * Start the thread
41510 +        */
41511 +       thread_enable(uarttio_inst.regs->thread);
41512 +
41513 +       /*
41514 +        * Process options
41515 +        */
41516 +       if (options) {
41517 +               uart_parse_options(options, &baud, &parity, &bits, &flow);
41518 +               if (ubi32_uarttio_set_baud(uup, baud)) {
41519 +                       baud = uup->uart->current_baud_rate;
41520 +               }
41521 +       }
41522 +
41523 +       return uart_set_options(&uup->port, co, baud, 'n', 8, 'n');
41524 +}
41525 +
41526 +/*
41527 + * ubi32_uarttio_console_putchar
41528 + */
41529 +static void ubi32_uarttio_console_putchar(struct uart_port *port, int ch)
41530 +{
41531 +       struct ubi32_uarttio_port *uup = port->private_data;
41532 +
41533 +       while (ubi32_uarttio_put_char(uup->uart, ch)) {
41534 +               cpu_relax();
41535 +       }
41536 +}
41537 +
41538 +/*
41539 + * ubi32_uarttio_console_write
41540 + *     Interrupts are disabled on entering
41541 + */
41542 +static void ubi32_uarttio_console_write(struct console *co, const char *s, unsigned int count)
41543 +{
41544 +       struct uart_port *port = &(uarttio_ports[co->index].port);
41545 +       unsigned long flags = 0;
41546 +
41547 +       spin_lock_irqsave(&port->lock, flags);
41548 +       uart_console_write(port, s, count, ubi32_uarttio_console_putchar);
41549 +       spin_unlock_irqrestore(&port->lock, flags);
41550 +}
41551 +
41552 +static struct console ubi32_uarttio_console = {
41553 +       .name           = UBI32_UARTTIO_NAME,
41554 +       .write          = ubi32_uarttio_console_write,
41555 +       .device         = uart_console_device,
41556 +       .setup          = ubi32_uarttio_console_setup,
41557 +       .flags          = CON_PRINTBUFFER,
41558 +       .index          = -1,
41559 +       .data           = &ubi32_uarttio_uart_driver,
41560 +};
41561 +
41562 +static int __init ubi32_uarttio_console_init(void)
41563 +{
41564 +       int res;
41565 +       
41566 +       res = ubi32_uarttio_probe();
41567 +       if (res) {
41568 +               return res;
41569 +       }
41570 +
41571 +       register_console(&ubi32_uarttio_console);
41572 +       return 0;
41573 +}
41574 +console_initcall(ubi32_uarttio_console_init);
41575 +#endif /* CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE */
41576 +
41577 +/*
41578 + * ubi32_serial_suspend
41579 + */
41580 +static int ubi32_uarttio_suspend(struct platform_device *pdev, pm_message_t state)
41581 +{
41582 +       int i;
41583 +       for (i = 0; i < uarttio_nports; i++) {
41584 +               uart_suspend_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41585 +       }
41586 +
41587 +       return 0;
41588 +}
41589 +
41590 +/*
41591 + * ubi32_serial_resume
41592 + */
41593 +static int ubi32_uarttio_resume(struct platform_device *pdev)
41594 +{
41595 +       int i;
41596 +       for (i = 0; i < uarttio_nports; i++) {
41597 +               uart_resume_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41598 +       }
41599 +
41600 +       return 0;
41601 +}
41602 +
41603 +/*
41604 + * ubi32_uarttio_remove
41605 + */
41606 +static int __devexit ubi32_uarttio_remove(struct platform_device *pdev)
41607 +{
41608 +       ubi32_uarttio_cleanup();
41609 +
41610 +       uart_unregister_driver(&ubi32_uarttio_uart_driver);
41611 +
41612 +       return 0;
41613 +}
41614 +
41615 +static struct platform_driver ubi32_uarttio_platform_driver = {
41616 +       .remove         = __devexit_p(ubi32_uarttio_remove),
41617 +       .suspend        = ubi32_uarttio_suspend,
41618 +       .resume         = ubi32_uarttio_resume,
41619 +       .driver         = {
41620 +               .name   = DRIVER_NAME,
41621 +               .owner  = THIS_MODULE,
41622 +       },
41623 +};
41624 +
41625 +#ifndef MODULE
41626 +/*
41627 + * Called at boot time.
41628 + *
41629 + * uarttio=TIONAME,(baud,tx_pin,rx_pin,handshake[,cts_pin,rts_pin],...)
41630 + *     TIONAME is the name of the devtree node which describes the UARTTIO
41631 + *     pin is the index of the pin, i.e. PA4 is 5 [(port * 32) + pin]
41632 + *     handshake = 1 to enable handshaking, provide cts_pin, rts_pin (UNSUPPORTED)
41633 + *     handshake = 0 to disable handshaking, do not provide cts_pin, rts_pin
41634 + *     Ex: uarttio=UARTTIO,57600,7,6,0,9600,8,9,0
41635 + */
41636 +static int __init ubi32_uarttio_setup(char *str)
41637 +{
41638 +       strncpy(utio_ports_param, str, UBI32_UARTTIO_MAX_PARAM_LEN);
41639 +       utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN - 1] = 0;
41640 +       return 1;
41641 +}
41642 +__setup("uarttio=", ubi32_uarttio_setup);
41643 +#endif
41644 +
41645 +/*
41646 + * ubi32_uarttio_init
41647 + */
41648 +static int __init ubi32_uarttio_init(void)
41649 +{
41650 +       int ret;
41651 +       int i;
41652 +
41653 +       ret = ubi32_uarttio_probe();
41654 +       if (ret) {
41655 +               return ret;
41656 +       }
41657 +
41658 +       /*
41659 +        * Request the IRQ (do it here since many ports share the same IRQ)
41660 +        */
41661 +       ret = request_irq(uarttio_inst.irq, ubi32_uarttio_isr, IRQF_DISABLED, DRIVER_NAME, NULL);
41662 +       if (ret != 0) {
41663 +               printk(KERN_WARNING "Could not request IRQ %d\n", uarttio_inst.irq);
41664 +               goto fail;
41665 +       }
41666 +       uarttio_inst.irq_requested = 1;
41667 +
41668 +       /*
41669 +        * Register the UART driver and add the ports
41670 +        */
41671 +       ret = uart_register_driver(&ubi32_uarttio_uart_driver);
41672 +       if (ret != 0) {
41673 +               goto fail;
41674 +       }
41675 +       uarttio_inst.driver_registered = 1;
41676 +
41677 +       ret = ubi32_uarttio_add_ports();
41678 +       if (ret != 0) {
41679 +               ubi32_uarttio_cleanup();
41680 +               return ret;
41681 +       }
41682 +
41683 +       /*
41684 +        * Start the thread
41685 +        */
41686 +       thread_enable(uarttio_inst.regs->thread);
41687 +
41688 +       for (i = 0; i < uarttio_nports; i++) {
41689 +               pr_info("Serial: Ubicom32 uarttio #%d: tx:%d rx:%d baud:%d\n", 
41690 +                       i, uarttio_ports[i].tx_pin, uarttio_ports[i].rx_pin,
41691 +                       uarttio_ports[i].uart->current_baud_rate);
41692 +       }
41693 +       pr_info("Serial: Ubicom32 uarttio started on thread:%d irq:%d\n", uarttio_inst.regs->thread, uarttio_inst.irq);
41694 +
41695 +       return ret;
41696 +
41697 +fail:
41698 +       ubi32_uarttio_cleanup();
41699 +       return ret;
41700 +}
41701 +module_init(ubi32_uarttio_init);
41702 +
41703 +/*
41704 + * ubi32_uarttio_exit
41705 + */
41706 +static void __exit ubi32_uarttio_exit(void)
41707 +{
41708 +       platform_driver_unregister(&ubi32_uarttio_platform_driver);
41709 +}
41710 +module_exit(ubi32_uarttio_exit);
41711 +
41712 +module_param_string(ports, utio_ports_param, sizeof(utio_ports_param), 0444);
41713 +MODULE_PARM_DESC(ports, "Sets the ports to allocate: ports=TIONAME,(baud,txpin,rxpin,handshake[,ctspin,rtspin],...)\n"
41714 +                       "     TIONAME is the name of the devtree node which describes the UARTTIO\n"
41715 +                       "     pin is the index of the pin, i.e. PA4 is 5 [(port * 32) + pin]\n"
41716 +                       "     handshake = 1 to enable handshaking, provide ctspin, rtspin (UNSUPPORTED)\n"
41717 +                       "     handshake = 0 to disable handshaking, do not provide ctspin, rtspin\n"
41718 +                       "     Ex: ports=UARTTIO,57600,7,6,0,9600,8,9,0\n");
41719 +MODULE_AUTHOR("Patrick Tjin <pat.tjin@ubicom.com>");
41720 +MODULE_DESCRIPTION("Ubicom serial virtual peripherial driver");
41721 +MODULE_LICENSE("GPL");
41722 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_UARTTIO_MAJOR);
41723 +MODULE_ALIAS("platform:" DRIVER_NAME);
41724 --- a/drivers/spi/Kconfig
41725 +++ b/drivers/spi/Kconfig
41726 @@ -196,6 +196,15 @@ config SPI_S3C24XX
41727         help
41728           SPI driver for Samsung S3C24XX series ARM SoCs
41729  
41730 +config SPI_UBICOM32_GPIO
41731 +       tristate "Ubicom32 SPI over GPIO"
41732 +       depends on SPI_MASTER && UBICOM32 && EXPERIMENTAL
41733 +       select SPI_BITBANG
41734 +       select HAS_DMA
41735 +       help
41736 +         SPI driver for the Ubicom32 architecture using
41737 +         GPIO lines to provide the SPI bus.
41738 +         
41739  config SPI_S3C24XX_GPIO
41740         tristate "Samsung S3C24XX series SPI by GPIO"
41741         depends on ARCH_S3C2410 && EXPERIMENTAL
41742 --- a/drivers/spi/Makefile
41743 +++ b/drivers/spi/Makefile
41744 @@ -27,6 +27,7 @@ obj-$(CONFIG_SPI_ORION)                       += orion_spi.o
41745  obj-$(CONFIG_SPI_MPC52xx_PSC)          += mpc52xx_psc_spi.o
41746  obj-$(CONFIG_SPI_MPC83xx)              += spi_mpc83xx.o
41747  obj-$(CONFIG_SPI_S3C24XX_GPIO)         += spi_s3c24xx_gpio.o
41748 +obj-$(CONFIG_SPI_UBICOM32_GPIO)                += spi_ubicom32_gpio.o
41749  obj-$(CONFIG_SPI_S3C24XX)              += spi_s3c24xx.o
41750  obj-$(CONFIG_SPI_TXX9)                 += spi_txx9.o
41751  obj-$(CONFIG_SPI_XILINX)               += xilinx_spi.o
41752 --- /dev/null
41753 +++ b/drivers/spi/spi_ubicom32_gpio.c
41754 @@ -0,0 +1,268 @@
41755 +/*
41756 + * drivers/spi_spi_ubicom32_gpio.c
41757 + *     Ubicom32 GPIO based SPI driver
41758 + *
41759 + * (C) Copyright 2009, Ubicom, Inc.
41760 + *
41761 + * This file is part of the Ubicom32 Linux Kernel Port.
41762 + *
41763 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
41764 + * it and/or modify it under the terms of the GNU General Public License
41765 + * as published by the Free Software Foundation, either version 2 of the
41766 + * License, or (at your option) any later version.
41767 + *
41768 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
41769 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
41770 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
41771 + * the GNU General Public License for more details.
41772 + *
41773 + * You should have received a copy of the GNU General Public License
41774 + * along with the Ubicom32 Linux Kernel Port.  If not,
41775 + * see <http://www.gnu.org/licenses/>.
41776 + *
41777 + * Ubicom32 implementation derived from (with many thanks):
41778 + *   arch/m68knommu
41779 + *   arch/blackfin
41780 + *   arch/parisc
41781 + */
41782 +#include <linux/kernel.h>
41783 +#include <linux/init.h>
41784 +#include <linux/delay.h>
41785 +#include <linux/spinlock.h>
41786 +#include <linux/workqueue.h>
41787 +#include <linux/platform_device.h>
41788 +
41789 +#include <linux/spi/spi.h>
41790 +#include <linux/spi/spi_bitbang.h>
41791 +
41792 +#include <linux/gpio.h>
41793 +
41794 +#include <asm/ip5000.h>
41795 +#include <asm/ubicom32-spi-gpio.h>
41796 +
41797 +#define DRIVER_NAME "ubicom32-spi-gpio"
41798 +
41799 +struct ubicom32_spi_gpio {
41800 +       struct spi_bitbang                       bitbang;
41801 +
41802 +       struct ubicom32_spi_gpio_platform_data  *pdata;
41803 +
41804 +       struct platform_device                  *dev;
41805 +};
41806 +
41807 +/*
41808 + * The following 4 functions are used by EXPAND_BITBANG_TXRX to bitbang the data out.
41809 + */
41810 +static inline void setsck(struct spi_device *dev, int on)
41811 +{
41812 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41813 +       gpio_set_value(usg->pdata->pin_clk, on ? 1 : 0);
41814 +}
41815 +
41816 +static inline void setmosi(struct spi_device *dev, int on)
41817 +{
41818 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41819 +       gpio_set_value(usg->pdata->pin_mosi, on ? 1 : 0);
41820 +}
41821 +
41822 +static inline u32 getmiso(struct spi_device *dev)
41823 +{
41824 +       struct ubicom32_spi_gpio *usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(dev->master);
41825 +       return gpio_get_value(usg->pdata->pin_miso) ? 1 : 0;
41826 +}
41827 +
41828 +#define spidelay(x) ndelay(x)
41829 +
41830 +#define        EXPAND_BITBANG_TXRX
41831 +#include <linux/spi/spi_bitbang.h>
41832 +
41833 +/*
41834 + * ubicom32_spi_gpio_txrx_mode0
41835 + */
41836 +static u32 ubicom32_spi_gpio_txrx_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41837 +{
41838 +       return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
41839 +}
41840 +
41841 +/*
41842 + * ubicom32_spi_gpio_txrx_mode1
41843 + */
41844 +static u32 ubicom32_spi_gpio_txrx_mode1(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41845 +{
41846 +       return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
41847 +}
41848 +
41849 +/*
41850 + * ubicom32_spi_gpio_txrx_mode2
41851 + */
41852 +static u32 ubicom32_spi_gpio_txrx_mode2(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41853 +{
41854 +       return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
41855 +}
41856 +
41857 +/*
41858 + * ubicom32_spi_gpio_txrx_mode3
41859 + */
41860 +static u32 ubicom32_spi_gpio_txrx_mode3(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41861 +{
41862 +       return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
41863 +}
41864 +
41865 +/*
41866 + * ubicom32_spi_gpio_chipselect
41867 + */
41868 +static void ubicom32_spi_gpio_chipselect(struct spi_device *dev, int value)
41869 +{
41870 +       struct ubicom32_spi_gpio_controller_data *cd = (struct ubicom32_spi_gpio_controller_data *)dev->controller_data;
41871 +       unsigned int cs_polarity = dev->mode & SPI_CS_HIGH ? 1 : 0;
41872 +
41873 +       if (value == BITBANG_CS_ACTIVE) {
41874 +               gpio_set_value(cd->pin_cs, cs_polarity);
41875 +               return;
41876 +       }
41877 +       gpio_set_value(cd->pin_cs, !cs_polarity);
41878 +}
41879 +
41880 +/*
41881 + * ubicom32_spi_gpio_probe
41882 + */
41883 +static int ubicom32_spi_gpio_probe(struct platform_device *dev)
41884 +{
41885 +       struct ubicom32_spi_gpio_platform_data *pdata;
41886 +       struct spi_master *master;
41887 +       struct ubicom32_spi_gpio *usg;
41888 +       int ret;
41889 +
41890 +       master = spi_alloc_master(&dev->dev, sizeof(struct ubicom32_spi_gpio));
41891 +       if (master == NULL) {
41892 +               dev_err(&dev->dev, "failed to allocate spi master\n");
41893 +               ret = -ENOMEM;
41894 +               goto err;
41895 +       }
41896 +
41897 +       usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(master);
41898 +
41899 +       platform_set_drvdata(dev, usg);
41900 +
41901 +       /* 
41902 +        * Copy in the platform data
41903 +        */
41904 +       pdata = dev->dev.platform_data;
41905 +       usg->pdata = dev->dev.platform_data;
41906 +
41907 +       /*
41908 +        * Request the GPIO lines
41909 +        */
41910 +       ret = gpio_request(pdata->pin_mosi, "spi-mosi");
41911 +       if (ret) {
41912 +               dev_err(&dev->dev, "Failed to allocate spi-mosi GPIO\n");
41913 +               goto err;
41914 +       }
41915 +
41916 +       ret = gpio_request(pdata->pin_miso, "spi-miso");
41917 +       if (ret) {
41918 +               dev_err(&dev->dev, "Failed to allocate spi-miso GPIO\n");
41919 +               goto err_nomiso;
41920 +       }
41921 +
41922 +       ret = gpio_request(pdata->pin_clk, "spi-clk");
41923 +       if (ret) {
41924 +               dev_err(&dev->dev, "Failed to allocate spi-clk GPIO\n");
41925 +               goto err_noclk;
41926 +       }
41927 +
41928 +       /*
41929 +        * Setup spi-bitbang adaptor
41930 +        */
41931 +       usg->bitbang.flags |= SPI_CS_HIGH;
41932 +       usg->bitbang.master = spi_master_get(master);
41933 +       usg->bitbang.master->bus_num = pdata->bus_num;
41934 +       usg->bitbang.master->num_chipselect = pdata->num_chipselect;
41935 +       usg->bitbang.chipselect = ubicom32_spi_gpio_chipselect;
41936 +
41937 +       usg->bitbang.txrx_word[SPI_MODE_0] = ubicom32_spi_gpio_txrx_mode0;
41938 +       usg->bitbang.txrx_word[SPI_MODE_1] = ubicom32_spi_gpio_txrx_mode1;
41939 +       usg->bitbang.txrx_word[SPI_MODE_2] = ubicom32_spi_gpio_txrx_mode2;
41940 +       usg->bitbang.txrx_word[SPI_MODE_3] = ubicom32_spi_gpio_txrx_mode3;
41941 +
41942 +       /*
41943 +        * Setup the GPIO pins
41944 +        */
41945 +       gpio_direction_output(pdata->pin_clk, pdata->clk_default);
41946 +       gpio_direction_output(pdata->pin_mosi, 0);
41947 +       gpio_direction_input(pdata->pin_miso);
41948 +
41949 +       /*
41950 +        * Ready to go
41951 +        */
41952 +       ret = spi_bitbang_start(&usg->bitbang);
41953 +       if (ret) {
41954 +               goto err_no_bitbang;
41955 +       }
41956 +
41957 +       return 0;
41958 +
41959 +err_no_bitbang:
41960 +       spi_master_put(usg->bitbang.master);
41961 +
41962 +       gpio_free(pdata->pin_clk);
41963 +
41964 +err_noclk:
41965 +       gpio_free(pdata->pin_miso);
41966 +
41967 +err_nomiso:
41968 +       gpio_free(pdata->pin_mosi);
41969 +
41970 +err:
41971 +       return ret;
41972 +}
41973 +
41974 +/*
41975 + * ubicom32_spi_gpio_remove
41976 + */
41977 +static int ubicom32_spi_gpio_remove(struct platform_device *dev)
41978 +{
41979 +       struct ubicom32_spi_gpio *sp = platform_get_drvdata(dev);
41980 +
41981 +       spi_bitbang_stop(&sp->bitbang);
41982 +       spi_master_put(sp->bitbang.master);
41983 +
41984 +       return 0;
41985 +}
41986 +
41987 +/*
41988 + * Work with hotplug and coldplug
41989 + */
41990 +MODULE_ALIAS("platform:ubicom32_spi_gpio");
41991 +
41992 +static struct platform_driver ubicom32_spi_gpio_drv = {
41993 +       .probe          = ubicom32_spi_gpio_probe,
41994 +        .remove                = ubicom32_spi_gpio_remove,
41995 +        .driver                = {
41996 +               .name   = DRIVER_NAME,
41997 +               .owner  = THIS_MODULE,
41998 +        },
41999 +};
42000 +
42001 +/*
42002 + * ubicom32_spi_gpio_init
42003 + */
42004 +static int __init ubicom32_spi_gpio_init(void)
42005 +{
42006 +        return platform_driver_register(&ubicom32_spi_gpio_drv);
42007 +}
42008 +
42009 +/*
42010 + * ubicom32_spi_gpio_exit
42011 + */
42012 +static void __exit ubicom32_spi_gpio_exit(void)
42013 +{
42014 +        platform_driver_unregister(&ubicom32_spi_gpio_drv);
42015 +}
42016 +
42017 +module_init(ubicom32_spi_gpio_init);
42018 +module_exit(ubicom32_spi_gpio_exit);
42019 +
42020 +MODULE_DESCRIPTION("Ubicom32 SPI-GPIO Driver");
42021 +MODULE_AUTHOR("Pat Tjin, <@ubicom.com>");
42022 +MODULE_LICENSE("GPL");
42023 --- a/drivers/uio/Kconfig
42024 +++ b/drivers/uio/Kconfig
42025 @@ -71,4 +71,12 @@ config UIO_SERCOS3
42026  
42027           If you compile this as a module, it will be called uio_sercos3.
42028  
42029 +config UIO_UBICOM32RING
42030 +       tristate "Ubicom32 Ring Buffer driver"
42031 +       default n
42032 +       help
42033 +         Userspace I/O interface for a Ubicom32 Ring Buffer.
42034 +
42035 +         If you compile this as a module, it will be called uio_ubicom32ring
42036 +
42037  endif
42038 --- a/drivers/uio/Makefile
42039 +++ b/drivers/uio/Makefile
42040 @@ -4,3 +4,4 @@ obj-$(CONFIG_UIO_PDRV)  += uio_pdrv.o
42041  obj-$(CONFIG_UIO_PDRV_GENIRQ)  += uio_pdrv_genirq.o
42042  obj-$(CONFIG_UIO_SMX)  += uio_smx.o
42043  obj-$(CONFIG_UIO_SERCOS3)      += uio_sercos3.o
42044 +obj-$(CONFIG_UIO_UBICOM32RING) += uio_ubicom32ring.o
42045 --- /dev/null
42046 +++ b/drivers/uio/uio_ubicom32ring.c
42047 @@ -0,0 +1,289 @@
42048 +/*
42049 + * drivers/uio/uio_ubicom32ring.c
42050 + *
42051 + * Userspace I/O platform driver for Ubicom32 ring buffers
42052 + *
42053 + * (C) Copyright 2009, Ubicom, Inc.
42054 + *
42055 + * This file is part of the Ubicom32 Linux Kernel Port.
42056 + *
42057 + * Based on uio_ubicom32ring.c by Magnus Damm
42058 + *
42059 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
42060 + * it and/or modify it under the terms of the GNU General Public License
42061 + * as published by the Free Software Foundation, either version 2 of the
42062 + * License, or (at your option) any later version.
42063 + *
42064 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
42065 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
42066 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
42067 + * the GNU General Public License for more details.
42068 + *
42069 + * You should have received a copy of the GNU General Public License
42070 + * along with the Ubicom32 Linux Kernel Port.  If not,
42071 + * see <http://www.gnu.org/licenses/>.
42072 + */
42073 +
42074 +#include <linux/platform_device.h>
42075 +#include <linux/uio_driver.h>
42076 +#include <linux/spinlock.h>
42077 +#include <linux/bitops.h>
42078 +#include <linux/interrupt.h>
42079 +#include <linux/stringify.h>
42080 +
42081 +#include <asm/ip5000.h>
42082 +#include <asm/ubicom32ring.h>
42083 +
42084 +#define DRIVER_NAME "uio_ubicom32ring"
42085 +
42086 +struct uio_ubicom32ring_data {
42087 +       struct uio_info                 *uioinfo;
42088 +
42089 +       struct uio_ubicom32ring_regs    *regs;
42090 +
42091 +       /*
42092 +        * IRQ used to kick the ring buffer
42093 +        */
42094 +       int                             irq_tx;
42095 +       int                             irq_rx;
42096 +
42097 +       spinlock_t                      lock;
42098 +
42099 +       unsigned long                   flags;
42100 +
42101 +       char                            name[0];
42102 +};
42103 +
42104 +static irqreturn_t uio_ubicom32ring_handler(int irq, struct uio_info *dev_info)
42105 +{
42106 +       struct uio_ubicom32ring_data *priv = dev_info->priv;
42107 +
42108 +       /* Just disable the interrupt in the interrupt controller, and
42109 +        * remember the state so we can allow user space to enable it later.
42110 +        */
42111 +
42112 +       if (!test_and_set_bit(0, &priv->flags))
42113 +               disable_irq_nosync(irq);
42114 +
42115 +       return IRQ_HANDLED;
42116 +}
42117 +
42118 +static int uio_ubicom32ring_irqcontrol(struct uio_info *dev_info, s32 irq_on)
42119 +{
42120 +       struct uio_ubicom32ring_data *priv = dev_info->priv;
42121 +       unsigned long flags;
42122 +
42123 +       /* Allow user space to enable and disable the interrupt
42124 +        * in the interrupt controller, but keep track of the
42125 +        * state to prevent per-irq depth damage.
42126 +        *
42127 +        * Serialize this operation to support multiple tasks.
42128 +        */
42129 +
42130 +       spin_lock_irqsave(&priv->lock, flags);
42131 +
42132 +       if (irq_on & 2) {
42133 +               /*
42134 +                * Kick the ring buffer (if we can)
42135 +                */
42136 +               if (priv->irq_tx != 0xFF) {
42137 +                       ubicom32_set_interrupt(priv->irq_tx);
42138 +               }
42139 +       }
42140 +       
42141 +       if (priv->irq_rx != 0xFF) {
42142 +               if (irq_on & 1) {
42143 +                       if (test_and_clear_bit(0, &priv->flags))
42144 +                               enable_irq(dev_info->irq);
42145 +               } else {
42146 +                       if (!test_and_set_bit(0, &priv->flags))
42147 +                               disable_irq(dev_info->irq);
42148 +               }
42149 +       }
42150 +
42151 +       spin_unlock_irqrestore(&priv->lock, flags);
42152 +
42153 +       return 0;
42154 +}
42155 +
42156 +static int uio_ubicom32ring_probe(struct platform_device *pdev)
42157 +{
42158 +       struct uio_info *uioinfo;
42159 +       struct uio_mem *uiomem;
42160 +       struct uio_ubicom32ring_data *priv;
42161 +       struct uio_ubicom32ring_regs *regs;
42162 +       struct resource *mem_resource;
42163 +       struct resource *irqtx_resource;
42164 +       struct resource *irqrx_resource;
42165 +       int ret = -EINVAL;
42166 +       int i;
42167 +
42168 +       uioinfo = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
42169 +       if (!uioinfo) {
42170 +               dev_err(&pdev->dev, "unable to kmalloc\n");
42171 +               return -ENOMEM;
42172 +       }
42173 +
42174 +       /*
42175 +        * Allocate private data with some string space after
42176 +        */
42177 +       i = sizeof(DRIVER_NAME) + 1;
42178 +       i += pdev->dev.platform_data ? strlen(pdev->dev.platform_data) : 0;
42179 +       priv = kzalloc(sizeof(struct uio_ubicom32ring_data) + i, GFP_KERNEL);
42180 +       if (!priv) {
42181 +               dev_err(&pdev->dev, "unable to kmalloc\n");
42182 +               kfree(uioinfo);
42183 +               return -ENOMEM;
42184 +       }
42185 +
42186 +       strcpy(priv->name, DRIVER_NAME ":");
42187 +       if (pdev->dev.platform_data) {
42188 +               strcat(priv->name, pdev->dev.platform_data);
42189 +       }
42190 +       uioinfo->priv = priv;
42191 +       uioinfo->name = priv->name;
42192 +       uioinfo->version = "0.1";
42193 +
42194 +       priv->uioinfo = uioinfo;
42195 +       spin_lock_init(&priv->lock);
42196 +       priv->flags = 0; /* interrupt is enabled to begin with */
42197 +
42198 +       /*
42199 +        * Get our resources, the IRQ_TX and IRQ_RX are optional.
42200 +        */
42201 +       priv->irq_tx = 0xFF;
42202 +       irqtx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
42203 +       if (irqtx_resource) {
42204 +               priv->irq_tx = irqtx_resource->start;
42205 +       }
42206 +
42207 +       uioinfo->irq = -1;
42208 +       priv->irq_rx = 0xFF;
42209 +       irqrx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
42210 +       if (irqrx_resource) {
42211 +               priv->irq_rx = irqrx_resource->start;
42212 +               uioinfo->irq = priv->irq_rx;
42213 +               uioinfo->handler = uio_ubicom32ring_handler;
42214 +       }
42215 +
42216 +       mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
42217 +       if (!mem_resource || !mem_resource->start) {
42218 +               dev_err(&pdev->dev, "No valid memory resource found\n");
42219 +               ret = -ENODEV;
42220 +               goto fail;
42221 +       }
42222 +       regs = (struct uio_ubicom32ring_regs *)mem_resource->start;
42223 +       priv->regs = regs;
42224 +
42225 +       if (regs->version != UIO_UBICOM32RING_REG_VERSION) {
42226 +               dev_err(&pdev->dev, "version %d not supported\n", regs->version);
42227 +               ret = -ENODEV;
42228 +               goto fail;
42229 +       }
42230 +
42231 +       /*
42232 +        * First range is the shared register space, if we have any
42233 +        */
42234 +       uiomem = &uioinfo->mem[0];
42235 +       if (regs->regs_size) {
42236 +               uiomem->memtype = UIO_MEM_PHYS;
42237 +               uiomem->addr = (u32_t)regs->regs;
42238 +               uiomem->size = regs->regs_size;
42239 +               ++uiomem;
42240 +               dev_info(&pdev->dev, "regs:%p (%u) / rings: %d found\n", regs->regs, regs->regs_size, regs->num_rings);
42241 +       } else {
42242 +               dev_info(&pdev->dev, "rings: %d found\n", regs->num_rings);
42243 +       }
42244 +
42245 +       /*
42246 +        * The rest of the range correspond to the rings
42247 +        */
42248 +       for (i = 0; i < regs->num_rings; i++) {
42249 +               dev_info(&pdev->dev, "\t%d: entries:%d ring:%p\n", 
42250 +                        i, regs->rings[i]->entries, &(regs->rings[i]->ring));
42251 +               if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
42252 +                       dev_warn(&pdev->dev, "device has more than "
42253 +                                       __stringify(MAX_UIO_MAPS)
42254 +                                       " I/O memory resources.\n");
42255 +                       break;
42256 +               }
42257 +
42258 +               uiomem->memtype = UIO_MEM_PHYS;
42259 +               uiomem->addr = (u32_t)&(regs->rings[i]->head);
42260 +               uiomem->size = (regs->rings[i]->entries * sizeof(u32_t)) + 
42261 +                               sizeof(struct uio_ubicom32ring_desc);
42262 +               ++uiomem;
42263 +       }
42264 +
42265 +       while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
42266 +               uiomem->size = 0;
42267 +               ++uiomem;
42268 +       }
42269 +
42270 +       /* This driver requires no hardware specific kernel code to handle
42271 +        * interrupts. Instead, the interrupt handler simply disables the
42272 +        * interrupt in the interrupt controller. User space is responsible
42273 +        * for performing hardware specific acknowledge and re-enabling of
42274 +        * the interrupt in the interrupt controller.
42275 +        *
42276 +        * Interrupt sharing is not supported.
42277 +        */
42278 +       uioinfo->irq_flags = IRQF_DISABLED;
42279 +       uioinfo->irqcontrol = uio_ubicom32ring_irqcontrol;
42280 +
42281 +       ret = uio_register_device(&pdev->dev, priv->uioinfo);
42282 +       if (ret) {
42283 +               dev_err(&pdev->dev, "unable to register uio device\n");
42284 +               goto fail;
42285 +       }
42286 +
42287 +       platform_set_drvdata(pdev, priv);
42288 +
42289 +       dev_info(&pdev->dev, "'%s' using irq: rx %d tx %d, regs %p\n", 
42290 +                priv->name, priv->irq_rx, priv->irq_tx, priv->regs);
42291 +
42292 +       return 0;
42293 +
42294 +fail:
42295 +       kfree(uioinfo);
42296 +       kfree(priv);
42297 +       return ret;
42298 +}
42299 +
42300 +static int uio_ubicom32ring_remove(struct platform_device *pdev)
42301 +{
42302 +       struct uio_ubicom32ring_data *priv = platform_get_drvdata(pdev);
42303 +
42304 +       uio_unregister_device(priv->uioinfo);
42305 +       kfree(priv->uioinfo);
42306 +       kfree(priv);
42307 +       return 0;
42308 +}
42309 +
42310 +static struct platform_driver uio_ubicom32ring = {
42311 +       .probe = uio_ubicom32ring_probe,
42312 +       .remove = uio_ubicom32ring_remove,
42313 +       .driver = {
42314 +               .name = DRIVER_NAME,
42315 +               .owner = THIS_MODULE,
42316 +       },
42317 +};
42318 +
42319 +static int __init uio_ubicom32ring_init(void)
42320 +{
42321 +       return platform_driver_register(&uio_ubicom32ring);
42322 +}
42323 +
42324 +static void __exit uio_ubicom32ring_exit(void)
42325 +{
42326 +       platform_driver_unregister(&uio_ubicom32ring);
42327 +}
42328 +
42329 +module_init(uio_ubicom32ring_init);
42330 +module_exit(uio_ubicom32ring_exit);
42331 +
42332 +MODULE_AUTHOR("Patrick Tjin");
42333 +MODULE_DESCRIPTION("Userspace I/O driver for Ubicom32 ring buffers");
42334 +MODULE_LICENSE("GPL v2");
42335 +MODULE_ALIAS("platform:" DRIVER_NAME);
42336 +
42337 --- a/drivers/usb/gadget/epautoconf.c
42338 +++ b/drivers/usb/gadget/epautoconf.c
42339 @@ -154,6 +154,10 @@ ep_matches (
42340                         /* configure your hardware with enough buffering!! */
42341                 }
42342                 break;
42343 +       
42344 +       case USB_ENDPOINT_XFER_BULK:
42345 +               if ((gadget->is_dualspeed) && (ep->maxpacket < 512))
42346 +                       return 0;
42347         }
42348  
42349         /* MATCH!! */
42350 @@ -174,7 +178,7 @@ ep_matches (
42351                         return 0;
42352                 desc->bEndpointAddress |= epnum;
42353         }
42354 -
42355 +       
42356         /* report (variable) full speed bulk maxpacket */
42357         if (USB_ENDPOINT_XFER_BULK == type) {
42358                 int size = ep->maxpacket;
42359 --- a/drivers/usb/Kconfig
42360 +++ b/drivers/usb/Kconfig
42361 @@ -22,6 +22,7 @@ config USB_ARCH_HAS_HCD
42362         default y if PCMCIA && !M32R                    # sl811_cs
42363         default y if ARM                                # SL-811
42364         default y if SUPERH                             # r8a66597-hcd
42365 +       default y if UBICOM32                           # Ubicom's onchip USB Duial role controller
42366         default PCI
42367  
42368  # many non-PCI SOC chips embed OHCI
42369 --- a/drivers/usb/musb/Kconfig
42370 +++ b/drivers/usb/musb/Kconfig
42371 @@ -11,7 +11,7 @@ config USB_MUSB_HDRC
42372         depends on (USB || USB_GADGET) && HAVE_CLK
42373         depends on !SUPERH
42374         select TWL4030_USB if MACH_OMAP_3430SDP
42375 -       tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
42376 +       tristate 'Inventra Highspeed Dual Role Controller (TI, Ubicom, ...)'
42377         help
42378           Say Y here if your system has a dual role high speed USB
42379           controller based on the Mentor Graphics silicon IP.  Then
42380 --- a/drivers/usb/musb/Makefile
42381 +++ b/drivers/usb/musb/Makefile
42382 @@ -22,6 +22,10 @@ ifeq ($(CONFIG_ARCH_OMAP3430),y)
42383         musb_hdrc-objs  += omap2430.o
42384  endif
42385  
42386 +ifeq ($(CONFIG_UBICOM32), y)
42387 +        musb_hdrc-objs  += ubi32_usb.o
42388 +endif
42389 +
42390  ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
42391         musb_hdrc-objs          += musb_gadget_ep0.o musb_gadget.o
42392  endif
42393 --- a/drivers/usb/musb/musb_core.c
42394 +++ b/drivers/usb/musb/musb_core.c
42395 @@ -105,6 +105,13 @@
42396  #include <asm/mach-types.h>
42397  #endif
42398  
42399 +#ifdef CONFIG_UBICOM32
42400 +#include <asm/ip5000.h>
42401 +#include <asm/ubicom32-tio.h>
42402 +extern void ubi32_usb_init(void);
42403 +extern void ubi32_usb_int_clr(void);
42404 +#endif
42405 +
42406  #include "musb_core.h"
42407  
42408  
42409 @@ -147,7 +154,7 @@ static inline struct musb *dev_to_musb(s
42410  }
42411  
42412  /*-------------------------------------------------------------------------*/
42413 -
42414 +#ifndef CONFIG_UBICOM32
42415  #ifndef CONFIG_USB_TUSB6010
42416  /*
42417   * Load an endpoint's FIFO
42418 @@ -226,8 +233,38 @@ void musb_read_fifo(struct musb_hw_ep *h
42419                 readsb(fifo, dst, len);
42420         }
42421  }
42422 +#endif /* T6010 */
42423 +#else /* UBICOM */
42424 +
42425 +/*
42426 + * Load an endpoint's FIFO
42427 + */
42428 +void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 wCount, const u8 *pSource)
42429 +{
42430 +       void __iomem *fifo = hw_ep->fifo;
42431 +
42432 +       prefetch((u8 *)pSource);
42433 +
42434 +       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
42435 +                       'T', hw_ep->epnum, fifo, wCount, pSource);
42436 +
42437 +       usb_tio_write_fifo((u32)fifo, (u32)pSource, wCount);
42438 +
42439 +}
42440  
42441 -#endif /* normal PIO */
42442 +
42443 +/*
42444 + * Unload an endpoint's FIFO
42445 + */
42446 +void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 wCount, u8 *pDest)
42447 +{
42448 +
42449 +       void __iomem *fifo = hw_ep->fifo;
42450 +       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
42451 +                       'R', hw_ep->epnum, fifo, wCount, pDest);
42452 +       usb_tio_read_fifo((u32)fifo, (u32)pDest, wCount);
42453 +}
42454 +#endif /* CONFIG_UBICOM32 */
42455  
42456  
42457  /*-------------------------------------------------------------------------*/
42458 @@ -872,12 +909,19 @@ void musb_start(struct musb *musb)
42459         musb_writeb(regs, MUSB_TESTMODE, 0);
42460  
42461         /* put into basic highspeed mode and start session */
42462 +#ifndef CONFIG_UBICOM32
42463         musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
42464                                                 | MUSB_POWER_SOFTCONN
42465                                                 | MUSB_POWER_HSENAB
42466                                                 /* ENSUSPEND wedges tusb */
42467                                                 /* | MUSB_POWER_ENSUSPEND */
42468                                                 );
42469 +#else
42470 +       musb_writeb(regs, MUSB_POWER,  MUSB_POWER_HSENAB
42471 +                                               /* ENSUSPEND wedges tusb */
42472 +                                               /* | MUSB_POWER_ENSUSPEND */
42473 +                                               );
42474 +#endif
42475  
42476         musb->is_active = 0;
42477         devctl = musb_readb(regs, MUSB_DEVCTL);
42478 @@ -1079,6 +1123,7 @@ static struct fifo_cfg __initdata mode_4
42479  };
42480  
42481  
42482 +#ifndef CONFIG_UBICOM32
42483  /*
42484   * configure a fifo; for non-shared endpoints, this may be called
42485   * once for a tx fifo and once for an rx fifo.
42486 @@ -1238,7 +1283,7 @@ static int __init ep_config_from_table(s
42487  
42488         return 0;
42489  }
42490 -
42491 +#endif /* CONFIG_UBICOM32 */
42492  
42493  /*
42494   * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
42495 @@ -1253,13 +1298,23 @@ static int __init ep_config_from_hw(stru
42496         DBG(2, "<== static silicon ep config\n");
42497  
42498         /* FIXME pick up ep0 maxpacket size */
42499 +#ifdef CONFIG_UBICOM32
42500 +       /* set ep0 to shared_fifo, otherwise urb will be put to out_qh but ep0_irq try to get the urb from in_qh*/
42501 +       hw_ep = musb->endpoints;
42502 +       hw_ep->is_shared_fifo = true;
42503 +#endif
42504  
42505         for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
42506                 musb_ep_select(mbase, epnum);
42507                 hw_ep = musb->endpoints + epnum;
42508  
42509                 /* read from core using indexed model */
42510 +#ifndef CONFIG_UBICOM32
42511                 reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
42512 +#else
42513 +               reg = musb_readb(musb->mregs, 0x10 + MUSB_FIFOSIZE);
42514 +#endif
42515 +
42516                 if (!reg) {
42517                         /* 0's returned when no more endpoints */
42518                         break;
42519 @@ -1272,8 +1327,10 @@ static int __init ep_config_from_hw(stru
42520                 /* shared TX/RX FIFO? */
42521                 if ((reg & 0xf0) == 0xf0) {
42522                         hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
42523 -                       hw_ep->is_shared_fifo = true;
42524 -                       continue;
42525 +                       hw_ep->is_shared_fifo = true;                   
42526 +#ifndef CONFIG_UBICOM32
42527 +                       continue; /* For ubicom processors, shared ep is all we get */
42528 +#endif
42529                 } else {
42530                         hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
42531                         hw_ep->is_shared_fifo = false;
42532 @@ -1290,17 +1347,30 @@ static int __init ep_config_from_hw(stru
42533                 /* REVISIT:  this algorithm is lazy, we should at least
42534                  * try to pick a double buffered endpoint.
42535                  */
42536 +#ifndef CONFIG_UBICOM32
42537                 if (musb->bulk_ep)
42538                         continue;
42539                 musb->bulk_ep = hw_ep;
42540 +#else
42541 +               if ((musb->bulk_ep_in) && (musb->bulk_ep_out))
42542 +                       continue;
42543 +               /* Save theEP with 1024 Bytes FIFO for ISO */
42544 +               if(hw_ep->max_packet_sz_tx == 512) {
42545 +                       if (!musb->bulk_ep_in) {
42546 +                               musb->bulk_ep_in = hw_ep;
42547 +                       } else if (!musb->bulk_ep_out) {
42548 +                               musb->bulk_ep_out = hw_ep;
42549 +                       }
42550 +               }
42551 +#endif /* CONFIG_UBICOM32 */
42552  #endif
42553         }
42554  
42555  #ifdef CONFIG_USB_MUSB_HDRC_HCD
42556 -       if (!musb->bulk_ep) {
42557 +       if ((!musb->bulk_ep_in) || (!musb->bulk_ep_out)) {
42558                 pr_debug("%s: missing bulk\n", musb_driver_name);
42559                 return -EINVAL;
42560 -       }
42561 +       }       
42562  #endif
42563  
42564         return 0;
42565 @@ -1408,12 +1478,16 @@ static int __init musb_core_init(u16 mus
42566         musb->epmask = 1;
42567  
42568         if (reg & MUSB_CONFIGDATA_DYNFIFO) {
42569 +#ifndef CONFIG_UBICOM32
42570                 if (musb->config->dyn_fifo)
42571                         status = ep_config_from_table(musb);
42572 -               else {
42573 +               else
42574 +#endif
42575 +               {
42576                         ERR("reconfigure software for Dynamic FIFOs\n");
42577                         status = -ENODEV;
42578                 }
42579 +
42580         } else {
42581                 if (!musb->config->dyn_fifo)
42582                         status = ep_config_from_hw(musb);
42583 @@ -1477,8 +1551,8 @@ static int __init musb_core_init(u16 mus
42584  
42585  /*-------------------------------------------------------------------------*/
42586  
42587 -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
42588 -
42589 +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_UBICOM32)
42590 +static u32_t musb_int_count = 0;
42591  static irqreturn_t generic_interrupt(int irq, void *__hci)
42592  {
42593         unsigned long   flags;
42594 @@ -1487,10 +1561,17 @@ static irqreturn_t generic_interrupt(int
42595  
42596         spin_lock_irqsave(&musb->lock, flags);
42597  
42598 +#ifndef CONFIG_UBICOM32
42599         musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
42600         musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
42601         musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
42602 +#else
42603 +       musb_read_int_status(&musb->int_usb, &musb->int_tx, &musb->int_rx);
42604 +       //ubi32_usb_int_clr();
42605 +       musb_int_count++;
42606 +#endif
42607  
42608 +       DBG(4, "usb %x, tx %x, rx %x", musb->int_usb, musb->int_tx, musb->int_rx);
42609         if (musb->int_usb || musb->int_tx || musb->int_rx)
42610                 retval = musb_interrupt(musb);
42611  
42612 @@ -2222,6 +2303,10 @@ static struct platform_driver musb_drive
42613  
42614  static int __init musb_init(void)
42615  {
42616 +#ifdef CONFIG_UBICOM32
42617 +       ubi32_usb_init();
42618 +#endif
42619 +
42620  #ifdef CONFIG_USB_MUSB_HDRC_HCD
42621         if (usb_disabled())
42622                 return 0;
42623 --- a/drivers/usb/musb/musb_core.h
42624 +++ b/drivers/usb/musb/musb_core.h
42625 @@ -326,7 +326,9 @@ struct musb {
42626          * queue until it completes or NAKs too much; then we try the next
42627          * endpoint.
42628          */
42629 -       struct musb_hw_ep       *bulk_ep;
42630 +       //struct musb_hw_ep     *bulk_ep;
42631 +       struct musb_hw_ep       *bulk_ep_in;    //ubicom
42632 +       struct musb_hw_ep       *bulk_ep_out;
42633  
42634         struct list_head        control;        /* of musb_qh */
42635         struct list_head        in_bulk;        /* of musb_qh */
42636 @@ -467,7 +469,7 @@ extern void musb_platform_disable(struct
42637  
42638  extern void musb_hnp_stop(struct musb *musb);
42639  
42640 -extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode);
42641 +extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
42642  
42643  #if defined(CONFIG_USB_TUSB6010) || \
42644         defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
42645 --- a/drivers/usb/musb/musb_gadget.c
42646 +++ b/drivers/usb/musb/musb_gadget.c
42647 @@ -421,7 +421,7 @@ void musb_g_tx(struct musb *musb, u8 epn
42648                  * probably rates reporting as a host error
42649                  */
42650                 if (csr & MUSB_TXCSR_P_SENTSTALL) {
42651 -                       csr |= MUSB_TXCSR_P_WZC_BITS;
42652 +                       csr &= ~(MUSB_TXCSR_P_WZC_BITS);
42653                         csr &= ~MUSB_TXCSR_P_SENTSTALL;
42654                         musb_writew(epio, MUSB_TXCSR, csr);
42655                         if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
42656 @@ -437,7 +437,7 @@ void musb_g_tx(struct musb *musb, u8 epn
42657  
42658                 if (csr & MUSB_TXCSR_P_UNDERRUN) {
42659                         /* we NAKed, no big deal ... little reason to care */
42660 -                       csr |= MUSB_TXCSR_P_WZC_BITS;
42661 +                       csr &= ~(MUSB_TXCSR_P_WZC_BITS);
42662                         csr &= ~(MUSB_TXCSR_P_UNDERRUN
42663                                         | MUSB_TXCSR_TXPKTRDY);
42664                         musb_writew(epio, MUSB_TXCSR, csr);
42665 @@ -573,10 +573,16 @@ static void rxstate(struct musb *musb, s
42666         u16                     csr = 0;
42667         const u8                epnum = req->epnum;
42668         struct usb_request      *request = &req->request;
42669 -       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
42670 +       struct musb_ep          *musb_ep = NULL;
42671         void __iomem            *epio = musb->endpoints[epnum].regs;
42672         u16                     fifo_count = 0;
42673 -       u16                     len = musb_ep->packet_sz;
42674 +       u16                     len = 0;
42675 +       
42676 +       if (musb->endpoints[epnum].is_shared_fifo)
42677 +               musb_ep = &musb->endpoints[epnum].ep_in;
42678 +       else
42679 +               musb_ep = &musb->endpoints[epnum].ep_out;
42680 +       len =  musb_ep->packet_sz;
42681  
42682         csr = musb_readw(epio, MUSB_RXCSR);
42683  
42684 @@ -715,7 +721,7 @@ static void rxstate(struct musb *musb, s
42685                          */
42686  
42687                         /* ack the read! */
42688 -                       csr |= MUSB_RXCSR_P_WZC_BITS;
42689 +                       csr &= ~MUSB_RXCSR_P_WZC_BITS;
42690                         csr &= ~MUSB_RXCSR_RXPKTRDY;
42691                         musb_writew(epio, MUSB_RXCSR, csr);
42692                 }
42693 @@ -734,10 +740,15 @@ void musb_g_rx(struct musb *musb, u8 epn
42694         u16                     csr;
42695         struct usb_request      *request;
42696         void __iomem            *mbase = musb->mregs;
42697 -       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
42698 +       struct musb_ep          *musb_ep = NULL;
42699         void __iomem            *epio = musb->endpoints[epnum].regs;
42700         struct dma_channel      *dma;
42701  
42702 +       if (musb->endpoints[epnum].is_shared_fifo)
42703 +               musb_ep = &musb->endpoints[epnum].ep_in;
42704 +       else
42705 +               musb_ep = &musb->endpoints[epnum].ep_out;
42706 +       
42707         musb_ep_select(mbase, epnum);
42708  
42709         request = next_request(musb_ep);
42710 @@ -1559,7 +1570,7 @@ init_peripheral_ep(struct musb *musb, st
42711         ep->is_in = is_in;
42712  
42713         INIT_LIST_HEAD(&ep->req_list);
42714 -
42715 +       
42716         sprintf(ep->name, "ep%d%s", epnum,
42717                         (!epnum || hw_ep->is_shared_fifo) ? "" : (
42718                                 is_in ? "in" : "out"));
42719 @@ -1758,7 +1769,9 @@ int usb_gadget_register_driver(struct us
42720                         }
42721                 }
42722         }
42723 -
42724 +#ifndef CONFIG_USB_MUSB_OTG
42725 +       musb_pullup(musb, 1);
42726 +#endif
42727         return retval;
42728  }
42729  EXPORT_SYMBOL(usb_gadget_register_driver);
42730 --- a/drivers/usb/musb/musb_gadget_ep0.c
42731 +++ b/drivers/usb/musb/musb_gadget_ep0.c
42732 @@ -240,14 +240,14 @@ __acquires(musb->lock)
42733                 case USB_REQ_SET_ADDRESS:
42734                         /* change it after the status stage */
42735                         musb->set_address = true;
42736 -                       musb->address = (u8) (ctrlrequest->wValue & 0x7f);
42737 +                       musb->address = (u8) (le16_to_cpu(ctrlrequest->wValue) & 0x7f);
42738                         handled = 1;
42739                         break;
42740  
42741                 case USB_REQ_CLEAR_FEATURE:
42742                         switch (recip) {
42743                         case USB_RECIP_DEVICE:
42744 -                               if (ctrlrequest->wValue
42745 +                               if (le16_to_cpu(ctrlrequest->wValue)
42746                                                 != USB_DEVICE_REMOTE_WAKEUP)
42747                                         break;
42748                                 musb->may_wakeup = 0;
42749 @@ -261,8 +261,8 @@ __acquires(musb->lock)
42750  
42751                                 if (num == 0
42752                                                 || num >= MUSB_C_NUM_EPS
42753 -                                               || ctrlrequest->wValue
42754 -                                                       != USB_ENDPOINT_HALT)
42755 +                                               || le16_to_cpu(ctrlrequest->wValue
42756 +                                                       != USB_ENDPOINT_HALT))
42757                                         break;
42758  
42759                                 if (ctrlrequest->wIndex & USB_DIR_IN)
42760 @@ -292,7 +292,7 @@ __acquires(musb->lock)
42761                         switch (recip) {
42762                         case USB_RECIP_DEVICE:
42763                                 handled = 1;
42764 -                               switch (ctrlrequest->wValue) {
42765 +                               switch (le16_to_cpu(ctrlrequest->wValue)) {
42766                                 case USB_DEVICE_REMOTE_WAKEUP:
42767                                         musb->may_wakeup = 1;
42768                                         break;
42769 @@ -374,8 +374,8 @@ stall:
42770  
42771                                 if (epnum == 0
42772                                                 || epnum >= MUSB_C_NUM_EPS
42773 -                                               || ctrlrequest->wValue
42774 -                                                       != USB_ENDPOINT_HALT)
42775 +                                               || le16_to_cpu(ctrlrequest->wValue
42776 +                                                       != USB_ENDPOINT_HALT))
42777                                         break;
42778  
42779                                 ep = musb->endpoints + epnum;
42780 --- a/drivers/usb/musb/musb_host.c
42781 +++ b/drivers/usb/musb/musb_host.c
42782 @@ -139,7 +139,11 @@ static inline void musb_h_tx_start(struc
42783         /* NOTE: no locks here; caller should lock and select EP */
42784         if (ep->epnum) {
42785                 txcsr = musb_readw(ep->regs, MUSB_TXCSR);
42786 -               txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS;
42787 +#ifndef CONFIG_UBICOM32
42788 +               txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS; 
42789 +#else
42790 +               txcsr |= (MUSB_TXCSR_TXPKTRDY & (~MUSB_TXCSR_H_WZC_BITS)); 
42791 +#endif
42792                 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
42793         } else {
42794                 txcsr = MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY;
42795 @@ -198,8 +202,11 @@ musb_start_urb(struct musb *musb, int is
42796                 len = urb->iso_frame_desc[0].length;
42797                 break;
42798         default:                /* bulk, interrupt */
42799 -               buf = urb->transfer_buffer;
42800 -               len = urb->transfer_buffer_length;
42801 +               /* actual_length may be nonzero on retry paths */
42802 +               if (urb->actual_length) 
42803 +                       DBG(3 ,"musb_start_urb: URB %p retried, len: %d\n", urb, urb->actual_length);
42804 +               buf = urb->transfer_buffer + urb->actual_length;
42805 +               len = urb->transfer_buffer_length - urb->actual_length;
42806         }
42807  
42808         DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
42809 @@ -318,13 +325,13 @@ musb_save_toggle(struct musb_hw_ep *ep, 
42810         if (!is_in) {
42811                 csr = musb_readw(epio, MUSB_TXCSR);
42812                 usb_settoggle(udev, qh->epnum, 1,
42813 -                       (csr & MUSB_TXCSR_H_DATATOGGLE)
42814 -                               ? 1 : 0);
42815 +                       ((csr & MUSB_TXCSR_H_DATATOGGLE)
42816 +                               ? 1 : 0));
42817         } else {
42818                 csr = musb_readw(epio, MUSB_RXCSR);
42819                 usb_settoggle(udev, qh->epnum, 0,
42820 -                       (csr & MUSB_RXCSR_H_DATATOGGLE)
42821 -                               ? 1 : 0);
42822 +                       ((csr & MUSB_RXCSR_H_DATATOGGLE)
42823 +                               ? 1 : 0));
42824         }
42825  }
42826  
42827 @@ -337,9 +344,11 @@ musb_giveback(struct musb_qh *qh, struct
42828         struct musb             *musb = ep->musb;
42829         int                     ready = qh->is_ready;
42830  
42831 +#ifndef CONFIG_UBICOM32 /* BUG! */
42832         if (ep->is_shared_fifo)
42833                 is_in = 1;
42834         else
42835 +#endif
42836                 is_in = usb_pipein(urb->pipe);
42837  
42838         /* save toggle eagerly, for paranoia */
42839 @@ -538,7 +547,11 @@ musb_host_packet_rx(struct musb *musb, s
42840         musb_read_fifo(hw_ep, length, buf);
42841  
42842         csr = musb_readw(epio, MUSB_RXCSR);
42843 +#ifndef CONFIG_UBICOM32
42844         csr |= MUSB_RXCSR_H_WZC_BITS;
42845 +#else
42846 +       csr &= ~MUSB_RXCSR_H_WZC_BITS;
42847 +#endif
42848         if (unlikely(do_flush))
42849                 musb_h_flush_rxfifo(hw_ep, csr);
42850         else {
42851 @@ -572,14 +585,24 @@ musb_rx_reinit(struct musb *musb, struct
42852  
42853         /* if programmed for Tx, put it in RX mode */
42854         if (ep->is_shared_fifo) {
42855 +#ifndef  CONFIG_UBICOM32
42856                 csr = musb_readw(ep->regs, MUSB_TXCSR);
42857                 if (csr & MUSB_TXCSR_MODE) {
42858                         musb_h_tx_flush_fifo(ep);
42859                         musb_writew(ep->regs, MUSB_TXCSR,
42860                                         MUSB_TXCSR_FRCDATATOG);
42861                 }
42862 +#else 
42863                 /* clear mode (and everything else) to enable Rx */
42864                 musb_writew(ep->regs, MUSB_TXCSR, 0);
42865 +               /* scrub all previous state, clearing toggle */
42866 +               csr = musb_readw(ep->regs, MUSB_RXCSR);
42867 +               if (csr & MUSB_RXCSR_RXPKTRDY)
42868 +                       WARNING("rx%d, packet/%d ready?\n", ep->epnum,
42869 +                               musb_readw(ep->regs, MUSB_RXCOUNT));
42870 +
42871 +               musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
42872 +#endif
42873  
42874         /* scrub all previous state, clearing toggle */
42875         } else {
42876 @@ -680,7 +703,7 @@ static void musb_ep_program(struct musb 
42877                         /* ASSERT:  TXCSR_DMAENAB was already cleared */
42878  
42879                         /* flush all old state, set default */
42880 -                       musb_h_tx_flush_fifo(hw_ep);
42881 +                               musb_h_tx_flush_fifo(hw_ep);
42882                         csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
42883                                         | MUSB_TXCSR_DMAMODE
42884                                         | MUSB_TXCSR_FRCDATATOG
42885 @@ -1169,8 +1192,18 @@ void musb_host_tx(struct musb *musb, u8 
42886         void __iomem            *mbase = musb->mregs;
42887         struct dma_channel      *dma;
42888  
42889 +#ifdef CONFIG_UBICOM32
42890 +       if (hw_ep->is_shared_fifo) {
42891 +               qh = hw_ep->in_qh;
42892 +       }
42893 +#ifdef CONFIG_USB_SERIAL_SIERRAWIRELESS
42894 +       printk(KERN_DEBUG "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr,
42895 +                       dma ? ", dma" : "");
42896 +#endif
42897 +#endif
42898         urb = next_urb(qh);
42899  
42900 +
42901         musb_ep_select(mbase, epnum);
42902         tx_csr = musb_readw(epio, MUSB_TXCSR);
42903  
42904 @@ -1210,9 +1243,14 @@ void musb_host_tx(struct musb *musb, u8 
42905                  * we have a candidate... NAKing is *NOT* an error
42906                  */
42907                 musb_ep_select(mbase, epnum);
42908 +#ifndef CONFIG_UBICOM32
42909                 musb_writew(epio, MUSB_TXCSR,
42910                                 MUSB_TXCSR_H_WZC_BITS
42911                                 | MUSB_TXCSR_TXPKTRDY);
42912 +#else
42913 +               musb_writew(epio, MUSB_TXCSR,
42914 +                                MUSB_TXCSR_TXPKTRDY);
42915 +#endif
42916                 goto finish;
42917         }
42918  
42919 @@ -1316,8 +1354,14 @@ void musb_host_tx(struct musb *musb, u8 
42920                 qh->segsize = wLength;
42921  
42922                 musb_ep_select(mbase, epnum);
42923 +#ifndef CONFIG_UBICOM32
42924                 musb_writew(epio, MUSB_TXCSR,
42925 -                               MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
42926 +                                MUSB_TXCSR_MODE | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
42927 +#else
42928 +        musb_writew(epio, MUSB_TXCSR,
42929 +                                 MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY);
42930 +#endif
42931 +
42932         } else
42933                 DBG(1, "not complete, but dma enabled?\n");
42934  
42935 @@ -1365,6 +1409,49 @@ finish:
42936  
42937  #endif
42938  
42939 +/* Schedule next QH from musb->in_bulk and move the current qh to
42940 + * the end; avoids starvation for other endpoints.
42941 + */
42942 +static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
42943 +{
42944 +       struct dma_channel      *dma;
42945 +       struct urb              *urb;
42946 +       void __iomem            *mbase = musb->mregs;
42947 +       void __iomem            *epio = ep->regs;
42948 +       struct musb_qh          *cur_qh, *next_qh;
42949 +       u16                     rx_csr;
42950 +
42951 +       musb_ep_select(mbase, ep->epnum);
42952 +       dma = is_dma_capable() ? ep->rx_channel : NULL;
42953 +       /* clear nak timeout bit */
42954 +       rx_csr = musb_readw(epio, MUSB_RXCSR);
42955 +       rx_csr &= ~MUSB_RXCSR_H_WZC_BITS;
42956 +       rx_csr &= ~MUSB_RXCSR_DATAERROR;
42957 +       musb_writew(epio, MUSB_RXCSR, rx_csr);
42958 +
42959 +       cur_qh = first_qh(&musb->in_bulk);
42960 +       if (cur_qh) {
42961 +               urb = next_urb(cur_qh);
42962 +               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
42963 +                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
42964 +                       musb->dma_controller->channel_abort(dma);
42965 +                       urb->actual_length += dma->actual_len;
42966 +                       dma->actual_len = 0L;
42967 +               }
42968 +               musb_save_toggle(ep, 1, urb);
42969 +
42970 +               /* move cur_qh to end of queue */
42971 +               list_move_tail(&cur_qh->ring, &musb->in_bulk);
42972 +
42973 +               /* get the next qh from musb->in_bulk */
42974 +               next_qh = first_qh(&musb->in_bulk);
42975 +
42976 +               /* set rx_reinit and schedule the next qh */
42977 +               ep->rx_reinit = 1;
42978 +               musb_start_urb(musb, 1, next_qh);
42979 +       }
42980 +}
42981 +
42982  /*
42983   * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
42984   * and high-bandwidth IN transfer cases.
42985 @@ -1383,7 +1470,7 @@ void musb_host_rx(struct musb *musb, u8 
42986         bool                    done = false;
42987         u32                     status;
42988         struct dma_channel      *dma;
42989 -
42990 +       
42991         musb_ep_select(mbase, epnum);
42992  
42993         urb = next_urb(qh);
42994 @@ -1407,6 +1494,13 @@ void musb_host_rx(struct musb *musb, u8 
42995  
42996         pipe = urb->pipe;
42997  
42998 +#ifdef CONFIG_UBICOM32
42999 +#ifdef CONFIG_USB_SERIAL_SIERRAWIRELESS
43000 +               printk(KERN_DEBUG  "RXCSR%d %04x, reqpkt, len %zu%s\n", epnum, rx_csr,
43001 +                               xfer_len, dma ? ", dma" : "");
43002 +#endif
43003 +#endif
43004 +
43005         DBG(5, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n",
43006                 epnum, rx_csr, urb->actual_length,
43007                 dma ? dma->actual_len : 0);
43008 @@ -1428,18 +1522,30 @@ void musb_host_rx(struct musb *musb, u8 
43009         } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
43010  
43011                 if (USB_ENDPOINT_XFER_ISOC != qh->type) {
43012 -                       /* NOTE this code path would be a good place to PAUSE a
43013 -                        * transfer, if there's some other (nonperiodic) rx urb
43014 -                        * that could use this fifo.  (dma complicates it...)
43015 +                       DBG(6, "RX end %d NAK timeout\n", epnum);
43016 +
43017 +                       /* NOTE: NAKing is *NOT* an error, so we want to
43018 +                        * continue.  Except ... if there's a request for
43019 +                        * another QH, use that instead of starving it.
43020                          *
43021 -                        * if (bulk && qh->ring.next != &musb->in_bulk), then
43022 -                        * we have a candidate... NAKing is *NOT* an error
43023 +                        * Devices like Ethernet and serial adapters keep
43024 +                        * reads posted at all times, which will starve
43025 +                        * other devices without this logic.
43026                          */
43027 -                       DBG(6, "RX end %d NAK timeout\n", epnum);
43028 +                       if (usb_pipebulk(urb->pipe)
43029 +                                       && qh->mux == 1
43030 +                                       && !list_is_singular(&musb->in_bulk)) {
43031 +                               musb_bulk_rx_nak_timeout(musb, hw_ep);
43032 +                               return;
43033 +                       }
43034                         musb_ep_select(mbase, epnum);
43035 +#ifndef CONFIG_UBICOM32
43036                         musb_writew(epio, MUSB_RXCSR,
43037                                         MUSB_RXCSR_H_WZC_BITS
43038                                         | MUSB_RXCSR_H_REQPKT);
43039 +#else
43040 +                       musb_writew(epio, MUSB_RXCSR, (~(MUSB_RXCSR_H_WZC_BITS))| MUSB_RXCSR_H_REQPKT);
43041 +#endif
43042  
43043                         goto finish;
43044                 } else {
43045 @@ -1495,8 +1601,13 @@ void musb_host_rx(struct musb *musb, u8 
43046                 rx_csr &= ~MUSB_RXCSR_H_REQPKT;
43047  
43048                 musb_ep_select(mbase, epnum);
43049 +#ifndef CONFIG_UBICOM32
43050                 musb_writew(epio, MUSB_RXCSR,
43051                                 MUSB_RXCSR_H_WZC_BITS | rx_csr);
43052 +#else
43053 +               musb_writew(epio, MUSB_RXCSR,
43054 +                               (~MUSB_RXCSR_H_WZC_BITS) & rx_csr);
43055 +#endif
43056         }
43057  #endif
43058         if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
43059 @@ -1526,7 +1637,7 @@ void musb_host_rx(struct musb *musb, u8 
43060                         else
43061                                 done = false;
43062  
43063 -               } else  {
43064 +               } else {
43065                 /* done if urb buffer is full or short packet is recd */
43066                 done = (urb->actual_length + xfer_len >=
43067                                 urb->transfer_buffer_length
43068 @@ -1743,8 +1854,12 @@ static int musb_schedule(
43069                 if (musb->periodic[epnum])
43070                         continue;
43071                 hw_ep = &musb->endpoints[epnum];
43072 +#ifndef CONFIG_UBICOM32
43073                 if (hw_ep == musb->bulk_ep)
43074 -                       continue;
43075 +#else
43076 +               if ((hw_ep == musb->bulk_ep_in) || (hw_ep == musb->bulk_ep_out)) /* Ubicom */   
43077 +#endif
43078 +                       continue; 
43079  
43080                 if (is_in)
43081                         diff = hw_ep->max_packet_sz_rx - qh->maxpacket;
43082 @@ -1756,7 +1871,14 @@ static int musb_schedule(
43083                         best_end = epnum;
43084                 }
43085         }
43086 +
43087 +#ifdef CONFIG_UBICOM32
43088 +       if (((best_diff >= qh->maxpacket)) && ((qh->type == USB_ENDPOINT_XFER_BULK) && (!is_in)))
43089 +               best_end = -1;
43090 +#endif
43091 +
43092         /* use bulk reserved ep1 if no other ep is free */
43093 +#ifndef CONFIG_UBICOM32
43094         if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
43095                 hw_ep = musb->bulk_ep;
43096                 if (is_in)
43097 @@ -1767,6 +1889,22 @@ static int musb_schedule(
43098         } else if (best_end < 0) {
43099                 return -ENOSPC;
43100         }
43101 +#else
43102 +       if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
43103 +               /* hw_ep = musb->bulk_ep; */
43104 +               if (is_in) {
43105 +                       head = &musb->in_bulk;
43106 +                       hw_ep = musb->bulk_ep_in; /* UBICOM */
43107 +               }
43108 +               else {
43109 +                       head = &musb->out_bulk;
43110 +                       hw_ep = musb->bulk_ep_out; /* UBICOM */
43111 +               }
43112 +               goto success;
43113 +       } else if (best_end < 0) {
43114 +               return -ENOSPC;
43115 +       }
43116 +#endif
43117  
43118         idle = 1;
43119         qh->mux = 0;
43120 @@ -1779,6 +1917,13 @@ success:
43121                 list_add_tail(&qh->ring, head);
43122                 qh->mux = 1;
43123         }
43124 +       /*
43125 +        * It's not make sense to set NAK timeout when qh->mux = 0,
43126 +        * There is nothing else to schedule
43127 +        */
43128 +       if ((qh->type == USB_ENDPOINT_XFER_BULK) && (qh->mux == 0))
43129 +               qh->intv_reg = 0;
43130 +
43131         qh->hw_ep = hw_ep;
43132         qh->hep->hcpriv = qh;
43133         if (idle)
43134 @@ -1884,6 +2029,15 @@ static int musb_urb_enqueue(
43135         case USB_ENDPOINT_XFER_ISOC:
43136                 /* iso always uses log encoding */
43137                 break;
43138 +#ifdef COMFIG_UBICOM32
43139 +       case USB_ENDPOINT_XFER_BULK:
43140 +                if (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
43141 +                       interval = (USB_SPEED_HIGH == urb->dev->speed) ? 16: 2;
43142 +                else
43143 +                       interval = 0;
43144 +                break;
43145 +#endif
43146 +       
43147         default:
43148                 /* REVISIT we actually want to use NAK limits, hinting to the
43149                  * transfer scheduling logic to try some other qh, e.g. try
43150 --- a/drivers/usb/musb/musb_io.h
43151 +++ b/drivers/usb/musb/musb_io.h
43152 @@ -56,6 +56,7 @@ static inline void writesb(const void __
43153  
43154  #endif
43155  
43156 +#ifndef CONFIG_UBICOM32
43157  /* NOTE:  these offsets are all in bytes */
43158  
43159  static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
43160 @@ -70,7 +71,37 @@ static inline void musb_writew(void __io
43161  
43162  static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
43163         { __raw_writel(data, addr + offset); }
43164 +#else
43165 +#include <asm/ubicom32-tio.h>
43166 +static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
43167 +{
43168 +        u16 data;
43169 +        usb_tio_read_u16((u32)(addr + offset), &data);
43170 +        return data;
43171 +}
43172  
43173 +static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43174 +{
43175 +        u8 data;
43176 +        usb_tio_read_u8((u32)(addr + offset), &data);
43177 +        return data;
43178 +}
43179 +
43180 +static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
43181 +{
43182 +        usb_tio_write_u16((u32)(addr + offset), data);
43183 +}
43184 +
43185 +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
43186 +{
43187 +        usb_tio_write_u8((u32)(addr + offset), data);
43188 +}
43189 +
43190 +static inline void  musb_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
43191 +{
43192 +       return usb_tio_read_int_status(int_usb, int_tx, int_rx);
43193 +}
43194 +#endif /* CONFIG_UBICOM32 */
43195  
43196  #ifdef CONFIG_USB_TUSB6010
43197  
43198 @@ -104,7 +135,7 @@ static inline void musb_writeb(void __io
43199         __raw_writew(tmp, addr + (offset & ~1));
43200  }
43201  
43202 -#else
43203 +#elif !defined(CONFIG_UBICOM32)
43204  
43205  static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43206         { return __raw_readb(addr + offset); }
43207 --- /dev/null
43208 +++ b/drivers/usb/musb/ubi32_usb.c
43209 @@ -0,0 +1,156 @@
43210 +/*
43211 + * drivers/usb/musb/ubi32_usb.c
43212 + *   Ubicom32 usb controller driver.
43213 + *
43214 + * (C) Copyright 2009, Ubicom, Inc.
43215 + * Copyright (C) 2005-2006 by Texas Instruments
43216 + *
43217 + * Derived from the Texas Instruments Inventra Controller Driver for Linux.
43218 + *
43219 + * This file is part of the Ubicom32 Linux Kernel Port.
43220 + *
43221 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43222 + * it and/or modify it under the terms of the GNU General Public License
43223 + * as published by the Free Software Foundation, either version 2 of the
43224 + * License, or (at your option) any later version.
43225 + *
43226 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43227 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43228 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43229 + * the GNU General Public License for more details.
43230 + *
43231 + * You should have received a copy of the GNU General Public License
43232 + * along with the Ubicom32 Linux Kernel Port.  If not, 
43233 + * see <http://www.gnu.org/licenses/>.
43234 + *
43235 + * Ubicom32 implementation derived from (with many thanks):
43236 + *   arch/m68knommu
43237 + *   arch/blackfin
43238 + *   arch/parisc
43239 + */
43240 +#include <linux/module.h>
43241 +#include <linux/kernel.h>
43242 +#include <linux/sched.h>
43243 +#include <linux/slab.h>
43244 +#include <linux/init.h>
43245 +#include <linux/list.h>
43246 +#include <linux/clk.h>
43247 +#include <linux/io.h>
43248 +
43249 +#include <asm/io.h>
43250 +#include <asm/ip5000.h>
43251 +#include "musb_core.h"
43252 +
43253 +void musb_platform_enable(struct musb *musb)
43254 +{
43255 +}
43256 +void musb_platform_disable(struct musb *musb)
43257 +{
43258 +}
43259 +
43260 +int musb_platform_set_mode(struct musb *musb, u8 musb_mode) {
43261 +       return 0;
43262 +}
43263 +
43264 +static void ip5k_usb_hcd_vbus_power(struct musb *musb, int is_on, int sleeping)
43265 +{
43266 +}
43267 +
43268 +static void ip5k_usb_hcd_set_vbus(struct musb *musb, int is_on)
43269 +{
43270 +       u8              devctl;
43271 +       /* HDRC controls CPEN, but beware current surges during device
43272 +        * connect.  They can trigger transient overcurrent conditions
43273 +        * that must be ignored.
43274 +        */
43275 +
43276 +       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
43277 +
43278 +       if (is_on) {
43279 +               musb->is_active = 1;
43280 +               musb->xceiv.default_a = 1;
43281 +               musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
43282 +               devctl |= MUSB_DEVCTL_SESSION;
43283 +
43284 +               MUSB_HST_MODE(musb);
43285 +       } else {
43286 +               musb->is_active = 0;
43287 +
43288 +               /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
43289 +                * jumping right to B_IDLE...
43290 +                */
43291 +
43292 +               musb->xceiv.default_a = 0;
43293 +               musb->xceiv.state = OTG_STATE_B_IDLE;
43294 +               devctl &= ~MUSB_DEVCTL_SESSION;
43295 +
43296 +               MUSB_DEV_MODE(musb);
43297 +       }
43298 +       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
43299 +
43300 +       DBG(1, "VBUS %s, devctl %02x "
43301 +               /* otg %3x conf %08x prcm %08x */ "\n",
43302 +               otg_state_string(musb),
43303 +               musb_readb(musb->mregs, MUSB_DEVCTL));
43304 +}
43305 +static int ip5k_usb_hcd_set_power(struct otg_transceiver *x, unsigned mA)
43306 +{
43307 +       return 0;
43308 +}
43309 +
43310 +static int musb_platform_resume(struct musb *musb);
43311 +
43312 +int __init musb_platform_init(struct musb *musb)
43313 +{
43314 +
43315 +#ifdef CONFIG_UBICOM32_V4
43316 +       u32_t chip_id;
43317 +       asm volatile (
43318 +                     "move.4   %0, CHIP_ID     \n\t"
43319 +                     : "=r" (chip_id)
43320 +       );
43321 +       if (chip_id == 0x30001) {
43322 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 30);
43323 +               udelay(1);
43324 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 31);
43325 +       } else {
43326 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 17);
43327 +               udelay(1);
43328 +               *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 14);
43329 +       }
43330 +#endif
43331 +
43332 +        *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_CFG)) |= ((1 << 14) | (1 <<15));
43333 +
43334 +       /* The i-clk is AUTO gated. Hence there is no need
43335 +        * to disable it until the driver is shutdown */
43336 +
43337 +       clk_enable(musb->clock);
43338 +       musb_platform_resume(musb);
43339 +
43340 +       ip5k_usb_hcd_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
43341 +
43342 +       if (is_host_enabled(musb))
43343 +               musb->board_set_vbus = ip5k_usb_hcd_set_vbus;
43344 +       if (is_peripheral_enabled(musb))
43345 +               musb->xceiv.set_power = ip5k_usb_hcd_set_power;
43346 +
43347 +       return 0;
43348 +}
43349 +
43350 +
43351 +int musb_platform_suspend(struct musb *musb)
43352 +{
43353 +       return 0;
43354 +}
43355 +int musb_platform_resume(struct musb *musb)
43356 +{
43357 +       return 0;
43358 +}
43359 +
43360 +int musb_platform_exit(struct musb *musb)
43361 +{
43362 +       ip5k_usb_hcd_vbus_power(musb, 0 /*off*/, 1);
43363 +       musb_platform_suspend(musb);
43364 +       return 0;
43365 +}
43366 --- a/drivers/video/backlight/Kconfig
43367 +++ b/drivers/video/backlight/Kconfig
43368 @@ -84,6 +84,14 @@ config LCD_TOSA
43369           If you have an Sharp SL-6000 Zaurus say Y to enable a driver
43370           for its LCD.
43371  
43372 +config LCD_UBICOM32
43373 +       tristate "Ubicom Backlight Driver"
43374 +       depends on LCD_CLASS_DEVICE && UBICOM32
43375 +       default n
43376 +       help
43377 +         If you have a Ubicom32 based system with an LCD panel, say Y to enable
43378 +         the power control driver for it.
43379 +
43380  #
43381  # Backlight
43382  #
43383 @@ -214,3 +222,11 @@ config BACKLIGHT_SAHARA
43384         help
43385           If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
43386           backlight driver.
43387 +
43388 +config BACKLIGHT_UBICOM32
43389 +       tristate "Ubicom Backlight Driver"
43390 +       depends on BACKLIGHT_CLASS_DEVICE && UBICOM32
43391 +       default n
43392 +       help
43393 +         If you have a Ubicom32 based system with a backlight say Y to enable the
43394 +         backlight driver.
43395 --- a/drivers/video/backlight/Makefile
43396 +++ b/drivers/video/backlight/Makefile
43397 @@ -8,6 +8,8 @@ obj-$(CONFIG_LCD_PLATFORM)         += platfor
43398  obj-$(CONFIG_LCD_VGG2432A4)       += vgg2432a4.o
43399  obj-$(CONFIG_LCD_TDO24M)          += tdo24m.o
43400  obj-$(CONFIG_LCD_TOSA)            += tosa_lcd.o
43401 +obj-$(CONFIG_LCD_LTV350QV)        += ltv350qv.o
43402 +obj-$(CONFIG_LCD_UBICOM32)        += ubicom32lcd.o
43403  
43404  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
43405  obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
43406 @@ -22,4 +24,4 @@ obj-$(CONFIG_BACKLIGHT_DA903X)        += da903x
43407  obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
43408  obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
43409  obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
43410 -
43411 +obj-$(CONFIG_BACKLIGHT_UBICOM32) += ubicom32bl.o
43412 --- /dev/null
43413 +++ b/drivers/video/backlight/ubicom32bl.c
43414 @@ -0,0 +1,378 @@
43415 +/*
43416 + * drivers/video/backlight/ubicom32bl.c
43417 + *     Backlight driver for the Ubicom32 platform
43418 + *
43419 + * (C) Copyright 2009, Ubicom, Inc.
43420 + *
43421 + * This file is part of the Ubicom32 Linux Kernel Port.
43422 + *
43423 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43424 + * it and/or modify it under the terms of the GNU General Public License
43425 + * as published by the Free Software Foundation, either version 2 of the
43426 + * License, or (at your option) any later version.
43427 + *
43428 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43429 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43430 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43431 + * the GNU General Public License for more details.
43432 + *
43433 + * You should have received a copy of the GNU General Public License
43434 + * along with the Ubicom32 Linux Kernel Port.  If not,
43435 + * see <http://www.gnu.org/licenses/>.
43436 + *
43437 + * Ubicom32 implementation derived from (with many thanks):
43438 + *   arch/m68knommu
43439 + *   arch/blackfin
43440 + *   arch/parisc
43441 + */
43442 +#include <linux/init.h>
43443 +#include <linux/kernel.h>
43444 +#include <linux/module.h>
43445 +#include <linux/platform_device.h>
43446 +#include <linux/backlight.h>
43447 +#include <linux/fb.h>
43448 +
43449 +#include <asm/ubicom32bl.h>
43450 +#include <asm/ip5000.h>
43451 +
43452 +#define DRIVER_NAME                    "ubicom32bl"
43453 +#define UBICOM32BL_MAX_BRIGHTNESS      255
43454 +
43455 +struct ubicom32bl_data {
43456 +       /*
43457 +        * Pointer to the platform data structure.  Keep this around since we need values
43458 +        * from it to set the backlight intensity.
43459 +        */
43460 +       const struct ubicom32bl_platform_data   *pdata;
43461 +
43462 +       /*
43463 +        * Backlight device, we have to save this for use when we remove ourselves.
43464 +        */
43465 +       struct backlight_device                 *bldev;
43466 +
43467 +       /*
43468 +        * Current intensity, used for get_intensity.
43469 +        */
43470 +       int                                     cur_intensity;
43471 +
43472 +       /*
43473 +        * Init function for PWM
43474 +        */
43475 +       int (*init_fn)(struct ubicom32bl_data *);
43476 +
43477 +       /*
43478 +        * Set intensity function depending on the backlight type
43479 +        */
43480 +       int (*set_intensity_fn)(struct ubicom32bl_data *, int);
43481 +};
43482 +
43483 +/*
43484 + * ubicom32bl_set_intensity_gpio
43485 + */
43486 +static int ubicom32bl_set_intensity_gpio(struct ubicom32bl_data *ud, int intensity)
43487 +{
43488 +       ud->cur_intensity = intensity ? 255 : 0;
43489 +
43490 +       if (intensity) {
43491 +               // set gpio
43492 +               return 0;
43493 +       }
43494 +
43495 +       // clear gpio
43496 +       return 0;
43497 +}
43498 +
43499 +/*
43500 + * ubicom32bl_set_intensity_hw
43501 + */
43502 +static int ubicom32bl_set_intensity_hw(struct ubicom32bl_data *ud, int intensity)
43503 +{
43504 +       u16_t period = ud->pdata->pwm_period;
43505 +       u16_t duty;
43506 +
43507 +       /*
43508 +        * Calculate the new duty cycle
43509 +        */
43510 +       duty = (period * intensity) / (UBICOM32BL_MAX_BRIGHTNESS + 1);
43511 +
43512 +       /*
43513 +        * Set the new duty cycle
43514 +        */
43515 +       switch (ud->pdata->pwm_channel) {
43516 +       case 0:
43517 +               /*
43518 +                * Channel 0 is in the lower half of PORT C ctl0 and ctl1
43519 +                */
43520 +               UBICOM32_IO_PORT(RC)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43521 +               break;
43522 +
43523 +       case 1:
43524 +               /*
43525 +                * Channel 1 is in the upper half of PORT C ctl0 and ctl2
43526 +                */
43527 +               UBICOM32_IO_PORT(RC)->ctl2 = (ud->pdata->pwm_period << 16) | duty;
43528 +               break;
43529 +
43530 +       case 2:
43531 +               /*
43532 +                * Channel 2 is in PORT H ctl0 and ctl1
43533 +                */
43534 +               UBICOM32_IO_PORT(RH)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43535 +               break;
43536 +       }
43537 +
43538 +       ud->cur_intensity = intensity;
43539 +
43540 +       return 0;
43541 +}
43542 +
43543 +/*
43544 + * ubicom32bl_set_intensity
43545 + */
43546 +static int ubicom32bl_set_intensity(struct backlight_device *bd)
43547 +{
43548 +       struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43549 +       int intensity = bd->props.brightness;
43550 +
43551 +       /*
43552 +        * If we're blanked the the intensity doesn't matter.
43553 +        */
43554 +       if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
43555 +               intensity = 0;
43556 +       }
43557 +
43558 +       /*
43559 +        * Check for inverted backlight.
43560 +        */
43561 +       if (ud->pdata->invert) {
43562 +               intensity = UBICOM32BL_MAX_BRIGHTNESS - intensity;
43563 +       }
43564 +
43565 +       if (ud->set_intensity_fn) {
43566 +               return ud->set_intensity_fn(ud, intensity);
43567 +       }
43568 +
43569 +       return -ENXIO;
43570 +}
43571 +
43572 +/*
43573 + * ubicom32bl_get_intensity
43574 + *     Return the current intensity of the backlight.
43575 + */
43576 +static int ubicom32bl_get_intensity(struct backlight_device *bd)
43577 +{
43578 +       struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43579 +
43580 +       return ud->cur_intensity;
43581 +}
43582 +
43583 +/*
43584 + * ubicom32bl_init_hw_pwm
43585 + *     Set the appropriate PWM registers
43586 + */
43587 +static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud)
43588 +{
43589 +       /*
43590 +        * bit 13: enable
43591 +        */
43592 +       u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ;
43593 +
43594 +       switch (ud->pdata->pwm_channel) {
43595 +       case 0:
43596 +               /*
43597 +                * Channel 0 is in the lower half of PORT C ctl0 and ctl1
43598 +                */
43599 +               UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF;
43600 +               UBICOM32_IO_PORT(RC)->ctl0 |= pwm_cfg;
43601 +               UBICOM32_IO_PORT(RC)->ctl1 = ud->pdata->pwm_period << 16;
43602 +               break;
43603 +
43604 +       case 1:
43605 +               /*
43606 +                * Channel 1 is in the upper half of PORT C ctl0 and ctl2
43607 +                */
43608 +               UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF0000;
43609 +               UBICOM32_IO_PORT(RC)->ctl0 |= (pwm_cfg << 16);
43610 +               UBICOM32_IO_PORT(RC)->ctl2 = ud->pdata->pwm_period << 16;
43611 +               break;
43612 +
43613 +       case 2:
43614 +               /*
43615 +                * Channel 2 is in PORT H ctl0 and ctl1
43616 +                */
43617 +               UBICOM32_IO_PORT(RH)->ctl0 &= ~0xFFFF0000;
43618 +               UBICOM32_IO_PORT(RH)->ctl0 = pwm_cfg;
43619 +               UBICOM32_IO_PORT(RH)->ctl1 = ud->pdata->pwm_period << 16;
43620 +               break;
43621 +       }
43622 +
43623 +       return 0;
43624 +}
43625 +
43626 +/*
43627 + * ubicom32bl_init_gpio
43628 + *     Allocate the appropriate GPIO
43629 + */
43630 +static int ubicom32bl_init_gpio(struct ubicom32bl_data *ud)
43631 +{
43632 +       return 0;
43633 +}
43634 +
43635 +static struct backlight_ops ubicom32bl_ops = {
43636 +       .get_brightness = ubicom32bl_get_intensity,
43637 +       .update_status  = ubicom32bl_set_intensity,
43638 +};
43639 +
43640 +/*
43641 + * ubicom32bl_probe
43642 + */
43643 +static int ubicom32bl_probe(struct platform_device *pdev)
43644 +{
43645 +       const struct ubicom32bl_platform_data *pdata = pdev->dev.platform_data;
43646 +       struct ubicom32bl_data *ud;
43647 +       struct backlight_device *bldev;
43648 +       int retval;
43649 +
43650 +       /*
43651 +        * Check to see if we have any platform data, if we don't then the backlight is not
43652 +        * configured on this device.
43653 +        */
43654 +       if (!pdata) {
43655 +               return -ENODEV;
43656 +       }
43657 +
43658 +       /*
43659 +        * Allocate our private data
43660 +        */
43661 +       ud = kzalloc(sizeof(struct ubicom32bl_data), GFP_KERNEL);
43662 +       if (!ud) {
43663 +               return -ENOMEM;
43664 +       }
43665 +
43666 +       ud->pdata = pdata;
43667 +
43668 +       /*
43669 +        * Check to see that the platform data is valid for this driver
43670 +        */
43671 +       switch (pdata->type) {
43672 +       case UBICOM32BL_TYPE_PWM: 
43673 +               {
43674 +                       /*
43675 +                        * Make sure we have a PWM peripheral
43676 +                        */
43677 +                       u32_t chipid;
43678 +                       asm volatile (
43679 +                               "move.4         %0, CHIP_ID     \n\t"
43680 +                               : "=r" (chipid)
43681 +                       );
43682 +                       if (chipid != 0x00030001) {
43683 +                               retval = -ENODEV;
43684 +                               goto fail;
43685 +                       }
43686 +
43687 +                       if (pdata->pwm_channel > 3) {
43688 +                               retval = -ENODEV;
43689 +                               goto fail;
43690 +                       }
43691 +                       if (pdata->pwm_prescale > 16) {
43692 +                               retval = -EINVAL;
43693 +                               goto fail;
43694 +                       }
43695 +
43696 +                       ud->init_fn = ubicom32bl_init_hw_pwm;
43697 +                       ud->set_intensity_fn = ubicom32bl_set_intensity_hw;
43698 +                       break;
43699 +               }
43700 +
43701 +       case UBICOM32BL_TYPE_PWM_HRT:
43702 +               // For now, PWM HRT devices are treated as binary lights.
43703 +
43704 +       case UBICOM32BL_TYPE_BINARY:
43705 +               ud->init_fn = ubicom32bl_init_gpio;
43706 +               ud->set_intensity_fn = ubicom32bl_set_intensity_gpio;
43707 +               break;
43708 +       }
43709 +
43710 +       /*
43711 +        * Register our backlight device
43712 +        */
43713 +       bldev = backlight_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32bl_ops);
43714 +       if (IS_ERR(bldev)) {
43715 +               retval = PTR_ERR(bldev);
43716 +               goto fail;
43717 +       }
43718 +
43719 +       ud->bldev = bldev;
43720 +       ud->cur_intensity = pdata->default_intensity;
43721 +       platform_set_drvdata(pdev, ud);
43722 +
43723 +       /* 
43724 +        * Start up the backlight at the prescribed default intensity
43725 +        */
43726 +       bldev->props.power = FB_BLANK_UNBLANK;
43727 +       bldev->props.max_brightness = UBICOM32BL_MAX_BRIGHTNESS;
43728 +       bldev->props.brightness = pdata->default_intensity;
43729 +
43730 +       if (ud->init_fn) {
43731 +               if (ud->init_fn(ud) != 0) {
43732 +                       retval = -ENODEV;
43733 +                       backlight_device_unregister(ud->bldev);
43734 +                       goto fail;
43735 +               }
43736 +       }
43737 +       ubicom32bl_set_intensity(bldev);
43738 +
43739 +       printk(KERN_INFO DRIVER_NAME ": Backlight driver started\n");
43740 +
43741 +       return 0;
43742 +
43743 +fail:
43744 +       platform_set_drvdata(pdev, NULL);
43745 +       kfree(ud);
43746 +       return retval;
43747 +}
43748 +
43749 +/*
43750 + * ubicom32bl_remove
43751 + */
43752 +static int __exit ubicom32bl_remove(struct platform_device *pdev)
43753 +{
43754 +       struct ubicom32bl_data *ud = platform_get_drvdata(pdev);
43755 +
43756 +       backlight_device_unregister(ud->bldev);
43757 +       platform_set_drvdata(pdev, NULL);
43758 +       kfree(ud);
43759 +
43760 +       return 0;
43761 +}
43762 +
43763 +static struct platform_driver ubicom32bl_driver = {
43764 +       .driver = {
43765 +               .name = DRIVER_NAME,
43766 +               .owner = THIS_MODULE,
43767 +       },
43768 +
43769 +       .remove = __exit_p(ubicom32bl_remove),
43770 +};
43771 +
43772 +/*
43773 + * ubicom32bl_init
43774 + */
43775 +static int __init ubicom32bl_init(void)
43776 +{
43777 +       return platform_driver_probe(&ubicom32bl_driver, ubicom32bl_probe);
43778 +}
43779 +module_init(ubicom32bl_init);
43780 +
43781 +/*
43782 + * ubicom32bl_exit
43783 + */
43784 +static void __exit ubicom32bl_exit(void)
43785 +{
43786 +       platform_driver_unregister(&ubicom32bl_driver);
43787 +}
43788 +module_exit(ubicom32bl_exit);
43789 +
43790 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
43791 +MODULE_DESCRIPTION("Ubicom32 backlight driver");
43792 +MODULE_LICENSE("GPL");
43793 --- /dev/null
43794 +++ b/drivers/video/backlight/ubicom32lcd.c
43795 @@ -0,0 +1,194 @@
43796 +/*
43797 + * drivers/vdeio/backlight/ubicom32lcd.c
43798 + *     LCD driver for the Ubicom32 platform
43799 + *
43800 + * (C) Copyright 2009, Ubicom, Inc.
43801 + *
43802 + * This file is part of the Ubicom32 Linux Kernel Port.
43803 + *
43804 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
43805 + * it and/or modify it under the terms of the GNU General Public License
43806 + * as published by the Free Software Foundation, either version 2 of the
43807 + * License, or (at your option) any later version.
43808 + *
43809 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
43810 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
43811 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
43812 + * the GNU General Public License for more details.
43813 + *
43814 + * You should have received a copy of the GNU General Public License
43815 + * along with the Ubicom32 Linux Kernel Port.  If not,
43816 + * see <http://www.gnu.org/licenses/>.
43817 + *
43818 + * Ubicom32 implementation derived from (with many thanks):
43819 + *   arch/m68knommu
43820 + *   arch/blackfin
43821 + *   arch/parisc
43822 + */
43823 +#include <linux/init.h>
43824 +#include <linux/kernel.h>
43825 +#include <linux/module.h>
43826 +#include <linux/platform_device.h>
43827 +#include <linux/lcd.h>
43828 +#include <linux/fb.h>
43829 +#include <linux/gpio.h>
43830 +
43831 +#include <asm/ubicom32lcd.h>
43832 +#include <asm/ip5000.h>
43833 +
43834 +#define DRIVER_NAME                    "ubicom32lcd"
43835 +
43836 +struct ubicom32lcd_data {
43837 +       /*
43838 +        * Pointer to the platform data structure.  Keep this around since we need values
43839 +        * from it to set the backlight intensity.
43840 +        */
43841 +       const struct ubicom32lcd_platform_data  *pdata;
43842 +
43843 +       /*
43844 +        * LCD device, we have to save this for use when we remove ourselves.
43845 +        */
43846 +       struct lcd_device                       *lcddev;
43847 +};
43848 +
43849 +/*
43850 + * ubicom32lcd_set_power
43851 + */
43852 +static int ubicom32lcd_set_power(struct lcd_device *ld, int power)
43853 +{
43854 +       struct ubicom32lcd_data *ud = (struct ubicom32lcd_data *)lcd_get_data(ld);
43855 +       if (power == FB_BLANK_UNBLANK) {
43856 +               gpio_direction_output(ud->pdata->vgh_gpio, ud->pdata->vgh_polarity);
43857 +               return 0;
43858 +       }
43859 +
43860 +       gpio_direction_output(ud->pdata->vgh_gpio, !ud->pdata->vgh_polarity);
43861 +       return 0;
43862 +}
43863 +
43864 +/*
43865 + * ubicom32lcd_get_power
43866 + */
43867 +static int ubicom32lcd_get_power(struct lcd_device *ld)
43868 +{
43869 +       struct ubicom32lcd_data *ud = (struct ubicom32lcd_data *)lcd_get_data(ld);
43870 +       int vgh = gpio_get_value(ud->pdata->vgh_gpio);
43871 +       if ((vgh && ud->pdata->vgh_polarity) || (!vgh && !ud->pdata->vgh_polarity)) {
43872 +               return 1;
43873 +       }
43874 +
43875 +       return 0;
43876 +}
43877 +
43878 +static struct lcd_ops ubicom32lcd_ops = {
43879 +       .get_power = ubicom32lcd_get_power,
43880 +       .set_power = ubicom32lcd_set_power,
43881 +};
43882 +
43883 +/*
43884 + * ubicom32lcd_probe
43885 + */
43886 +static int ubicom32lcd_probe(struct platform_device *pdev)
43887 +{
43888 +       const struct ubicom32lcd_platform_data *pdata = pdev->dev.platform_data;
43889 +       struct ubicom32lcd_data *ud;
43890 +       struct lcd_device *lcddev;
43891 +       int retval;
43892 +
43893 +       /*
43894 +        * Check to see if we have any platform data, if we don't have a LCD to control
43895 +        */
43896 +       if (!pdata) {
43897 +               return -ENODEV;
43898 +       }
43899 +
43900 +       /*
43901 +        * Allocate our private data
43902 +        */
43903 +       ud = kzalloc(sizeof(struct ubicom32lcd_data), GFP_KERNEL);
43904 +       if (!ud) {
43905 +               return -ENOMEM;
43906 +       }
43907 +
43908 +       ud->pdata = pdata;
43909 +
43910 +       /*
43911 +        * Request our GPIOs
43912 +        */
43913 +       retval = gpio_request(pdata->vgh_gpio, "vgh");
43914 +       if (retval) {
43915 +               dev_err(&pdev->dev, "Failed to allocate vgh GPIO\n");
43916 +               goto fail_gpio;
43917 +       }
43918 +
43919 +       /*
43920 +        * Register our lcd device
43921 +        */
43922 +       lcddev = lcd_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32lcd_ops);
43923 +       if (IS_ERR(lcddev)) {
43924 +               retval = PTR_ERR(lcddev);
43925 +               goto fail;
43926 +       }
43927 +
43928 +       ud->lcddev = lcddev;
43929 +       platform_set_drvdata(pdev, ud);
43930 +
43931 +       ubicom32lcd_set_power(lcddev, FB_BLANK_UNBLANK);
43932 +
43933 +       printk(KERN_INFO DRIVER_NAME ": LCD driver started\n");
43934 +
43935 +       return 0;
43936 +
43937 +fail:
43938 +       gpio_free(pdata->vgh_gpio);
43939 +
43940 +fail_gpio:
43941 +       platform_set_drvdata(pdev, NULL);
43942 +       kfree(ud);
43943 +       return retval;
43944 +}
43945 +
43946 +/*
43947 + * ubicom32lcd_remove
43948 + */
43949 +static int __exit ubicom32lcd_remove(struct platform_device *pdev)
43950 +{
43951 +       struct ubicom32lcd_data *ud = platform_get_drvdata(pdev);
43952 +
43953 +       lcd_device_unregister(ud->lcddev);
43954 +       platform_set_drvdata(pdev, NULL);
43955 +       kfree(ud);
43956 +
43957 +       return 0;
43958 +}
43959 +
43960 +static struct platform_driver ubicom32lcd_driver = {
43961 +       .driver = {
43962 +               .name = DRIVER_NAME,
43963 +               .owner = THIS_MODULE,
43964 +       },
43965 +
43966 +       .remove = __exit_p(ubicom32lcd_remove),
43967 +};
43968 +
43969 +/*
43970 + * ubicom32lcd_init
43971 + */
43972 +static int __init ubicom32lcd_init(void)
43973 +{
43974 +       return platform_driver_probe(&ubicom32lcd_driver, ubicom32lcd_probe);
43975 +}
43976 +module_init(ubicom32lcd_init);
43977 +
43978 +/*
43979 + * ubicom32lcd_exit
43980 + */
43981 +static void __exit ubicom32lcd_exit(void)
43982 +{
43983 +       platform_driver_unregister(&ubicom32lcd_driver);
43984 +}
43985 +module_exit(ubicom32lcd_exit);
43986 +
43987 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
43988 +MODULE_DESCRIPTION("Ubicom32 backlight driver");
43989 +MODULE_LICENSE("GPL");
43990 --- a/drivers/video/Kconfig
43991 +++ b/drivers/video/Kconfig
43992 @@ -609,6 +609,25 @@ config FB_BFIN_T350MCQB
43993          This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
43994          It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
43995  
43996 +config FB_UBICOM32
43997 +       tristate "Ubicom32 Frame Buffer driver"
43998 +       depends on FB && UBICOM32
43999 +       select FB_CFB_FILLRECT
44000 +       select FB_CFB_COPYAREA
44001 +       select FB_CFB_IMAGEBLIT
44002 +       select FONT_6x11 if FRAMEBUFFER_CONSOLE
44003 +       help
44004 +        This is the framebuffer device driver for the Ubicom32 architecture.
44005 +
44006 +config FB_UBICOM32_VIRTUAL
44007 +       tristate "Ubicom32 Virtual Frame Buffer driver"
44008 +       depends on FB && UBICOM32
44009 +       select FB_CFB_FILLRECT
44010 +       select FB_CFB_COPYAREA
44011 +       select FB_CFB_IMAGEBLIT
44012 +       select FONT_6x11 if FRAMEBUFFER_CONSOLE
44013 +       help
44014 +        This is a virtual framebuffer device driver for the Ubicom32 architecture.
44015  
44016  config FB_STI
44017         tristate "HP STI frame buffer device support"
44018 --- a/drivers/video/Makefile
44019 +++ b/drivers/video/Makefile
44020 @@ -132,6 +132,7 @@ obj-$(CONFIG_FB_VGA16)            += vga
44021  obj-$(CONFIG_FB_OF)               += offb.o
44022  obj-$(CONFIG_FB_BF54X_LQ043)     += bf54x-lq043fb.o
44023  obj-$(CONFIG_FB_BFIN_T350MCQB)   += bfin-t350mcqb-fb.o
44024 +obj-$(CONFIG_FB_UBICOM32)         += ubicom32fb.o
44025  
44026  # the test framebuffer is last
44027  obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
44028 --- /dev/null
44029 +++ b/drivers/video/ubicom32fb.c
44030 @@ -0,0 +1,777 @@
44031 +/*
44032 + * drivers/video/ubicom32fb.c
44033 + *     Ubicom32 frame buffer driver
44034 + *
44035 + * (C) Copyright 2009, Ubicom, Inc.
44036 + *
44037 + * This file is part of the Ubicom32 Linux Kernel Port.
44038 + *
44039 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
44040 + * it and/or modify it under the terms of the GNU General Public License
44041 + * as published by the Free Software Foundation, either version 2 of the
44042 + * License, or (at your option) any later version.
44043 + *
44044 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
44045 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
44046 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
44047 + * the GNU General Public License for more details.
44048 + *
44049 + * You should have received a copy of the GNU General Public License
44050 + * along with the Ubicom32 Linux Kernel Port.  If not,
44051 + * see <http://www.gnu.org/licenses/>.
44052 + *
44053 + * Ubicom32 implementation derived from (with many thanks):
44054 + *   arch/m68knommu
44055 + *   arch/blackfin
44056 + *   arch/parisc
44057 + */
44058 +
44059 +/*
44060 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
44061 + * Geert Uytterhoeven.
44062 + */
44063 +
44064 +#include <linux/device.h>
44065 +#include <linux/module.h>
44066 +#include <linux/kernel.h>
44067 +#include <linux/version.h>
44068 +#include <linux/errno.h>
44069 +#include <linux/string.h>
44070 +#include <linux/mm.h>
44071 +#include <linux/fb.h>
44072 +#include <linux/init.h>
44073 +#include <linux/dma-mapping.h>
44074 +#include <linux/platform_device.h>
44075 +#include <linux/device.h>
44076 +#include <linux/uaccess.h>
44077 +#include <linux/interrupt.h>
44078 +
44079 +#include <asm/io.h>
44080 +#include <asm/ip5000.h>
44081 +#include <asm/vdc_tio.h>
44082 +#include <asm/ubicom32fb.h>
44083 +
44084 +#define DRIVER_NAME            "ubicom32fb"
44085 +#define DRIVER_DESCRIPTION     "Ubicom32 frame buffer driver"
44086 +
44087 +#define PALETTE_ENTRIES_NO     16
44088 +
44089 +/*
44090 + * Option variables
44091 + *
44092 + * vram_size:  VRAM size in kilobytes, subject to alignment 
44093 + */
44094 +static int vram_size = 0;
44095 +module_param(vram_size, int, 0);
44096 +MODULE_PARM_DESC(vram, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment");
44097 +static int init_value = 0;
44098 +module_param(init_value, int, 0);
44099 +MODULE_PARM_DESC(init, "Initial value of the framebuffer (16-bit number).");
44100 +
44101 +/*
44102 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
44103 + */
44104 +static struct fb_fix_screeninfo ubicom32fb_fix = {
44105 +       .id =           "Ubicom32",
44106 +       .type =         FB_TYPE_PACKED_PIXELS,
44107 +       .visual =       FB_VISUAL_TRUECOLOR,
44108 +       .accel =        FB_ACCEL_NONE
44109 +};
44110 +
44111 +/*
44112 + * Filled in at probe time when we find out what the hardware supports
44113 + */
44114 +static struct fb_var_screeninfo ubicom32fb_var;
44115 +
44116 +/*
44117 + * Private data structure
44118 + */
44119 +struct ubicom32fb_drvdata {
44120 +       struct fb_info                  *fbinfo;
44121 +       bool                            cmap_alloc;
44122 +
44123 +       /*
44124 +        * The address of the framebuffer in memory
44125 +        */
44126 +       void                            *fb;
44127 +       void                            *fb_aligned;
44128 +
44129 +       /*
44130 +        * Total size of vram including alignment allowance
44131 +        */
44132 +       u32                             total_vram_size;
44133 +       
44134 +       /*
44135 +        * Interrupt to set when changing registers
44136 +        */
44137 +       u32                             vp_int;
44138 +
44139 +       /*
44140 +        * Optional: Interrupt used by TIO to signal us
44141 +        */
44142 +       u32                             rx_int;
44143 +       
44144 +       /*
44145 +        * Base address of the regs for VDC_TIO
44146 +        */
44147 +       volatile struct vdc_tio_vp_regs *regs;
44148 +
44149 +       /*
44150 +        * non-zero if we are in yuv mode
44151 +        */
44152 +       u8_t                            is_yuv;
44153 +
44154 +       /* 
44155 +        * Fake palette of 16 colors
44156 +        */
44157 +       u32                             pseudo_palette[PALETTE_ENTRIES_NO];
44158 +
44159 +       /*
44160 +        * Wait queue and lock used to block when we need to wait 
44161 +        * for something to happen.
44162 +        */
44163 +       wait_queue_head_t               waitq;
44164 +       struct mutex                    lock;
44165 +
44166 +};
44167 +
44168 +/*
44169 + * ubicom32fb_set_next_frame
44170 + *     Sets the next frame buffer to display
44171 + *
44172 + * if sync is TRUE then this function will block until the hardware 
44173 + * acknowledges the change
44174 + */
44175 +static inline void ubicom32fb_set_next_frame(struct ubicom32fb_drvdata *ud, void *fb, u8_t sync)
44176 +{
44177 +       ud->regs->next_frame_flags = ud->is_yuv ? VDCTIO_NEXT_FRAME_FLAG_YUV : 0;
44178 +       ud->regs->next_frame = (void *)((u32_t)fb | 1);
44179 +
44180 +       /*
44181 +        * If we have interrupts, then we can wait on it
44182 +        */
44183 +       if (ud->rx_int != -1) {
44184 +               DEFINE_WAIT(wait);
44185 +               unsigned long flags;
44186 +
44187 +               spin_lock_irqsave(&ud->lock, flags);
44188 +               prepare_to_wait(&ud->waitq, &wait, TASK_INTERRUPTIBLE);
44189 +               spin_unlock_irqrestore(&ud->lock, flags);
44190 +               schedule();
44191 +               finish_wait(&ud->waitq, &wait);
44192 +               return;
44193 +       }
44194 +
44195 +       /*
44196 +        * No interrupt, we will just spin here
44197 +        */
44198 +       while (sync && ((u32_t)ud->regs->next_frame & 1));
44199 +}
44200 +
44201 +/*
44202 + * ubicom32fb_send_command
44203 + *     Sends a command/data pair to the VDC
44204 + */
44205 +static inline void ubicom32fb_send_command(struct ubicom32fb_drvdata *ud, u16 command, u8_t block)
44206 +{
44207 +       ud->regs->command = command;
44208 +       ubicom32_set_interrupt(ud->vp_int);
44209 +       while (block && ud->regs->command);
44210 +}
44211 +
44212 +/*
44213 + * ubicom32fb_ioctl
44214 + *     Handles any ioctls sent to us
44215 + */
44216 +static int ubicom32fb_ioctl(struct fb_info *fbi, unsigned int cmd,
44217 +                      unsigned long arg)
44218 +{
44219 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
44220 +       void __user *argp = (void __user *)arg;
44221 +       int retval = -EFAULT;
44222 +
44223 +       switch (cmd) {
44224 +       case UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC:
44225 +               // check alignment, return -EINVAL if necessary
44226 +               ubicom32fb_set_next_frame(ud, argp, 1);
44227 +               retval = 0;
44228 +               break;
44229 +
44230 +       case UBICOM32FB_IOCTL_SET_NEXT_FRAME:
44231 +               // check alignment, return -EINVAL if necessary
44232 +               ubicom32fb_set_next_frame(ud, argp, 0);
44233 +               retval = 0;
44234 +               break;
44235 +
44236 +       case UBICOM32FB_IOCTL_SET_MODE:
44237 +               if (!(ud->regs->caps & VDCTIO_CAPS_SUPPORTS_SCALING)) {
44238 +                       break;
44239 +               } else {
44240 +                       struct ubicom32fb_mode mode;
44241 +                       volatile struct vdc_tio_vp_regs *regs = ud->regs;
44242 +                       u32_t flags = 0;
44243 +
44244 +                       if (copy_from_user(&mode, argp, sizeof(mode))) {
44245 +                               break;
44246 +                       }
44247 +                       
44248 +                       regs->x_in = mode.width;
44249 +                       regs->y_in = mode.height;
44250 +                       regs->x_out = regs->xres;
44251 +                       regs->y_out = regs->yres;
44252 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER) {
44253 +                               flags |= VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER;
44254 +                       }
44255 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER) {
44256 +                               flags |= VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER;
44257 +                       }
44258 +                       ud->is_yuv = mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV;
44259 +                       if (ud->is_yuv) {
44260 +                               flags |= VDCTIO_SCALE_FLAG_YUV;
44261 +                       }
44262 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255) {
44263 +                               flags |= VDCTIO_SCALE_FLAG_VRANGE_16_255;
44264 +                       }
44265 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255) {
44266 +                               flags |= VDCTIO_SCALE_FLAG_VRANGE_0_255;
44267 +                       }
44268 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB) {
44269 +                               flags |= VDCTIO_SCALE_FLAG_VSUB;
44270 +                       }
44271 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1) {
44272 +                               flags |= VDCTIO_SCALE_FLAG_HSUB_2_1;
44273 +                       }
44274 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1) {
44275 +                               flags |= VDCTIO_SCALE_FLAG_HSUB_1_1;
44276 +                       }
44277 +                       if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE) {
44278 +                               flags |= VDCTIO_SCALE_FLAG_ENABLE;
44279 +                       }
44280 +                       if (mode.next_frame) {
44281 +                               flags |= VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER;
44282 +                               regs->next_frame = mode.next_frame;
44283 +                       }
44284 +                       
44285 +                       regs->scale_flags = flags;
44286 +                       ubicom32fb_send_command(ud, VDCTIO_COMMAND_SET_SCALE_MODE, 1);
44287 +                       retval = 0;
44288 +                       break;
44289 +               }
44290 +
44291 +       default:
44292 +               retval = -ENOIOCTLCMD;
44293 +               break;
44294 +       }
44295 +
44296 +       return retval;
44297 +}
44298 +
44299 +/*
44300 + * ubicom32fb_interrupt
44301 + *     Called by the OS when the TIO has set the rx_int
44302 + */
44303 +static irqreturn_t ubicom32fb_interrupt(int vec, void *appdata)
44304 +{
44305 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)appdata;
44306 +
44307 +       spin_lock(&ud->lock);
44308 +       if (waitqueue_active(&ud->waitq)) {
44309 +               wake_up(&ud->waitq);
44310 +       }
44311 +       spin_unlock(&ud->lock);
44312 +
44313 +       return IRQ_HANDLED;
44314 +}
44315 +
44316 +/*
44317 + * ubicom32fb_pan_display
44318 + *     Pans the display to a given location.  Supports only y direction panning.
44319 + */
44320 +static int ubicom32fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44321 +{
44322 +       struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
44323 +       void *new_addr;
44324 +
44325 +       /*
44326 +        * Get the last y line that would be displayed.  Since we don't support YWRAP,
44327 +        * it must be less than our virtual y size.
44328 +        */
44329 +       u32 lasty = var->yoffset + var->yres;
44330 +       if (lasty > fbi->var.yres_virtual) {
44331 +               /*
44332 +                * We would fall off the end of our frame buffer if we panned here.
44333 +                */
44334 +               return -EINVAL;
44335 +       }
44336 +
44337 +       if (var->xoffset) {
44338 +               /*
44339 +                * We don't support panning in the x direction
44340 +                */
44341 +               return -EINVAL;
44342 +       }
44343 +
44344 +       /*
44345 +        * Everything looks sane, go ahead and pan
44346 +        *
44347 +        * We have to calculate a new address for the VDC to look at
44348 +        */
44349 +       new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44350 +
44351 +       /*
44352 +        * Send down the command.  The buffer will switch at the next vertical blank
44353 +        */
44354 +       ubicom32fb_set_next_frame(ud, (void *)new_addr, 0);
44355 +
44356 +       return 0;
44357 +}
44358 +
44359 +/*
44360 + * ubicom32fb_setcolreg
44361 + *     Sets a color in our virtual palette
44362 + */
44363 +static int ubicom32fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44364 +{
44365 +       u32 *palette = fbi->pseudo_palette;
44366 +
44367 +       if (regno >= PALETTE_ENTRIES_NO) {
44368 +               return -EINVAL;
44369 +       }
44370 +
44371 +       /*
44372 +        * We only use 8 bits from each color
44373 +        */
44374 +       red >>= 8;
44375 +       green >>= 8;
44376 +       blue >>= 8;
44377 +
44378 +       /*
44379 +        * Convert any grayscale values
44380 +        */
44381 +       if (fbi->var.grayscale) {
44382 +               u16 gray = red + green + blue;
44383 +               gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44384 +               gray >>= 2;
44385 +               if (gray > 255) {
44386 +                       gray = 255;
44387 +               }
44388 +               red = gray;
44389 +               blue = gray;
44390 +               green = gray;
44391 +       }
44392 +
44393 +       palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44394 +                        (blue << fbi->var.blue.offset);
44395 +
44396 +       return 0;
44397 +}
44398 +
44399 +/*
44400 + * ubicom32fb_mmap
44401 + */
44402 +static int ubicom32fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
44403 +{
44404 +       struct ubicom32fb_drvdata *drvdata = (struct ubicom32fb_drvdata *)info->par;
44405 +
44406 +       vma->vm_start = (unsigned long)(drvdata->fb_aligned);
44407 +
44408 +       vma->vm_end = vma->vm_start + info->fix.smem_len;
44409 +
44410 +       /* For those who don't understand how mmap works, go read
44411 +        *   Documentation/nommu-mmap.txt.
44412 +        * For those that do, you will know that the VM_MAYSHARE flag
44413 +        * must be set in the vma->vm_flags structure on noMMU
44414 +        *   Other flags can be set, and are documented in
44415 +        *   include/linux/mm.h
44416 +        */
44417 +
44418 +       vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
44419 +
44420 +       return 0;
44421 +}
44422 +
44423 +/*
44424 + * ubicom32fb_blank
44425 + */
44426 +static int ubicom32fb_blank(int blank_mode, struct fb_info *fbi)
44427 +{
44428 +       return 0;
44429 +#if 0
44430 +       struct ubicom32fb_drvdata *drvdata = to_ubicom32fb_drvdata(fbi);
44431 +
44432 +       switch (blank_mode) {
44433 +       case FB_BLANK_UNBLANK:
44434 +               /* turn on panel */
44435 +               ubicom32fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
44436 +               break;
44437 +
44438 +       case FB_BLANK_NORMAL:
44439 +       case FB_BLANK_VSYNC_SUSPEND:
44440 +       case FB_BLANK_HSYNC_SUSPEND:
44441 +       case FB_BLANK_POWERDOWN:
44442 +               /* turn off panel */
44443 +               ubicom32fb_out_be32(drvdata, REG_CTRL, 0);
44444 +       default:
44445 +               break;
44446 +
44447 +       }
44448 +       return 0; /* success */
44449 +#endif
44450 +}
44451 +
44452 +static struct fb_ops ubicom32fb_ops =
44453 +{
44454 +       .owner                  = THIS_MODULE,
44455 +       .fb_pan_display         = ubicom32fb_pan_display,
44456 +       .fb_setcolreg           = ubicom32fb_setcolreg,
44457 +       .fb_blank               = ubicom32fb_blank,
44458 +       .fb_mmap                = ubicom32fb_mmap,
44459 +       .fb_ioctl               = ubicom32fb_ioctl,
44460 +       .fb_fillrect            = cfb_fillrect,
44461 +       .fb_copyarea            = cfb_copyarea,
44462 +       .fb_imageblit           = cfb_imageblit,
44463 +};
44464 +
44465 +/*
44466 + * ubicom32fb_release
44467 + */
44468 +static int ubicom32fb_release(struct device *dev)
44469 +{
44470 +       struct ubicom32fb_drvdata *ud = dev_get_drvdata(dev);
44471 +
44472 +#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
44473 +       //ubicom32fb_blank(VESA_POWERDOWN, &drvdata->info);
44474 +#endif
44475 +
44476 +       unregister_framebuffer(ud->fbinfo);
44477 +
44478 +       if (ud->cmap_alloc) {
44479 +               fb_dealloc_cmap(&ud->fbinfo->cmap);
44480 +       }
44481 +
44482 +       if (ud->fb) {
44483 +               kfree(ud->fb);
44484 +       }
44485 +
44486 +       if (ud->rx_int != -1) {
44487 +               free_irq(ud->rx_int, ud);
44488 +       }
44489 +
44490 +       /* 
44491 +        * Turn off the display 
44492 +        */
44493 +       //ubicom32fb_out_be32(drvdata, REG_CTRL, 0);
44494 +       //iounmap(drvdata->regs);
44495 +
44496 +       framebuffer_release(ud->fbinfo);
44497 +       dev_set_drvdata(dev, NULL);
44498 +
44499 +       return 0;
44500 +}
44501 +
44502 +/*
44503 + * ubicom32fb_platform_probe
44504 + */
44505 +static int __init ubicom32fb_platform_probe(struct platform_device *pdev)
44506 +{
44507 +       struct ubicom32fb_drvdata *ud;
44508 +       struct resource *irq_resource_rx;
44509 +       struct resource *irq_resource_tx;
44510 +       struct resource *mem_resource;
44511 +       struct fb_info *fbinfo;
44512 +       int rc;
44513 +       size_t fbsize;
44514 +       struct device *dev = &pdev->dev;
44515 +       int offset;
44516 +       struct vdc_tio_vp_regs *regs;
44517 +
44518 +       /*
44519 +        * Get our resources
44520 +        */
44521 +       irq_resource_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
44522 +       if (!irq_resource_tx) {
44523 +               dev_err(dev, "No tx IRQ resource assigned\n");
44524 +               return -ENODEV;
44525 +       }
44526 +
44527 +       irq_resource_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
44528 +       if (!irq_resource_rx) {
44529 +               dev_err(dev, "No rx IRQ resource assigned\n");
44530 +               return -ENODEV;
44531 +       }
44532 +
44533 +       mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
44534 +       if (!mem_resource || !mem_resource->start) {
44535 +               dev_err(dev, "No mem resource assigned\n");
44536 +               return -ENODEV;
44537 +       }
44538 +       regs = (struct vdc_tio_vp_regs *)mem_resource->start;
44539 +       if (regs->version != VDCTIO_VP_VERSION) {
44540 +               dev_err(dev, "VDCTIO is not compatible with this driver tio:%x drv:%x\n", 
44541 +                       regs->version, VDCTIO_VP_VERSION);
44542 +               return -ENODEV;
44543 +       }
44544 +
44545 +       /*
44546 +        * This is the minimum VRAM size
44547 +        */
44548 +       fbsize = regs->xres * regs->yres * (regs->bpp / 8);
44549 +       if (!vram_size) {
44550 +               vram_size = (fbsize + 1023) / 1024;
44551 +       } else {
44552 +               if (fbsize > (vram_size * 1024)) {
44553 +                       dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize);
44554 +                       return -ENOMEM; // should be ebadparam?
44555 +               }
44556 +       }
44557 +
44558 +       /*
44559 +        * Allocate the framebuffer instance + our private data
44560 +        */
44561 +       fbinfo = framebuffer_alloc(sizeof(struct ubicom32fb_drvdata), &pdev->dev);
44562 +       if (!fbinfo) {
44563 +               dev_err(dev, "Not enough memory to allocate instance.\n");
44564 +               return -ENOMEM;
44565 +       }
44566 +
44567 +       /*
44568 +        * Fill in our private data.
44569 +        */
44570 +       ud = (struct ubicom32fb_drvdata *)fbinfo->par;
44571 +       ud->fbinfo = fbinfo;
44572 +       ud->regs = (struct vdc_tio_vp_regs *)(mem_resource->start);
44573 +       dev_set_drvdata(dev, ud);
44574 +
44575 +       ud->vp_int = irq_resource_tx->start;
44576 +
44577 +       /*
44578 +        * If we were provided an rx_irq then we need to init the appropriate
44579 +        * queues, locks, and functions.
44580 +        */
44581 +       ud->rx_int = -1;
44582 +       if (irq_resource_rx->start != DEVTREE_IRQ_NONE) {
44583 +               init_waitqueue_head(&ud->waitq);
44584 +               mutex_init(&ud->lock);
44585 +               if (request_irq(ud->rx_int, ubicom32fb_interrupt, IRQF_SHARED, "ubicom32fb_rx", ud)) {
44586 +                       dev_err(dev, "Couldn't request rx IRQ\n");
44587 +                       rc = -ENOMEM;
44588 +                       goto fail;
44589 +               }
44590 +               ud->rx_int = irq_resource_rx->start;
44591 +       }
44592 +
44593 +       /*
44594 +        * Allocate and align the requested amount of VRAM
44595 +        */
44596 +       ud->total_vram_size = (vram_size * 1024) + regs->fb_align;
44597 +       ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL);
44598 +       if (ud->fb == NULL) {
44599 +               dev_err(dev, "Couldn't allocate VRAM\n");
44600 +               rc = -ENOMEM;
44601 +               goto fail;
44602 +       }
44603 +
44604 +       offset = (u32_t)ud->fb & (regs->fb_align - 1);
44605 +       if (!offset) {
44606 +               ud->fb_aligned = ud->fb;
44607 +       } else {
44608 +               offset = regs->fb_align - offset;
44609 +               ud->fb_aligned = ud->fb + offset;
44610 +       }
44611 +
44612 +       /*
44613 +        * Clear the entire frame buffer
44614 +        */
44615 +       if (!init_value) {
44616 +               memset(ud->fb_aligned, 0, vram_size * 1024);
44617 +       } else {
44618 +               unsigned short *p = ud->fb_aligned;
44619 +               int i;
44620 +               for (i = 0; i < ((vram_size * 1024) / sizeof(u16_t)); i++) {
44621 +                       *p++ = init_value;
44622 +               }
44623 +       }
44624 +
44625 +       /*
44626 +        * Fill in the fb_var_screeninfo structure
44627 +        */
44628 +       memset(&ubicom32fb_var, 0, sizeof(ubicom32fb_var));
44629 +       ubicom32fb_var.bits_per_pixel = regs->bpp;
44630 +       ubicom32fb_var.red.offset = regs->rshift;
44631 +       ubicom32fb_var.green.offset = regs->gshift;
44632 +       ubicom32fb_var.blue.offset = regs->bshift;
44633 +       ubicom32fb_var.red.length = regs->rbits;
44634 +       ubicom32fb_var.green.length = regs->gbits;
44635 +       ubicom32fb_var.blue.length = regs->bbits;
44636 +       ubicom32fb_var.activate = FB_ACTIVATE_NOW;
44637 +
44638 +#if 0
44639 +       /* 
44640 +        * Turn on the display 
44641 +        */
44642 +       ud->reg_ctrl_default = REG_CTRL_ENABLE;
44643 +       if (regs->rotate_screen)
44644 +               ud->reg_ctrl_default |= REG_CTRL_ROTATE;
44645 +       ubicom32fb_out_be32(ud, REG_CTRL, ud->reg_ctrl_default);
44646 +#endif
44647 +
44648 +       /*
44649 +        * Fill in the fb_info structure
44650 +        */
44651 +       ud->fbinfo->device = dev;
44652 +       ud->fbinfo->screen_base = (void *)ud->fb_aligned;
44653 +       ud->fbinfo->fbops = &ubicom32fb_ops;
44654 +       ud->fbinfo->fix = ubicom32fb_fix;
44655 +       ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned;
44656 +       ud->fbinfo->fix.smem_len = fbsize;
44657 +       ud->fbinfo->fix.line_length = regs->xres * (regs->bpp / 8);
44658 +
44659 +       /*
44660 +        * We support panning in the y direction only
44661 +        */
44662 +       ud->fbinfo->fix.xpanstep = 0;
44663 +       ud->fbinfo->fix.ypanstep = 1;
44664 +
44665 +       ud->fbinfo->pseudo_palette = ud->pseudo_palette;
44666 +       ud->fbinfo->flags = FBINFO_DEFAULT;
44667 +       ud->fbinfo->var = ubicom32fb_var;
44668 +       ud->fbinfo->var.xres = regs->xres;
44669 +       ud->fbinfo->var.yres = regs->yres;
44670 +
44671 +       /*
44672 +        * We cannot pan in the X direction, so xres_virtual is regs->xres
44673 +        * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length
44674 +        */
44675 +       ud->fbinfo->var.xres_virtual = regs->xres;
44676 +       ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
44677 +
44678 +       //ud->fbinfo->var.height = regs->height_mm;
44679 +       //ud->fbinfo->var.width = regs->width_mm;
44680 +
44681 +       /* 
44682 +        * Allocate a color map
44683 +        */
44684 +       rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
44685 +       if (rc) {
44686 +               dev_err(dev, "Fail to allocate colormap (%d entries)\n",
44687 +                       PALETTE_ENTRIES_NO);
44688 +               goto fail;
44689 +       }
44690 +       ud->cmap_alloc = true;
44691 +
44692 +       /*
44693 +        * Register new frame buffer
44694 +        */
44695 +       rc = register_framebuffer(ud->fbinfo);
44696 +       if (rc) {
44697 +               dev_err(dev, "Could not register frame buffer\n");
44698 +               goto fail;
44699 +       }
44700 +
44701 +       /*
44702 +        * Start up the VDC
44703 +        */
44704 +       ud->regs->next_frame = ud->fb;
44705 +       ubicom32fb_send_command(ud, VDCTIO_COMMAND_START, 0);
44706 +
44707 +       /*
44708 +        * Tell the log we are here
44709 +        */
44710 +       dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u), regs=%p irqtx=%u irqrx=%u\n", 
44711 +               ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, 
44712 +               ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual, ud->regs,
44713 +               irq_resource_tx->start, irq_resource_rx->start);
44714 +
44715 +       /* 
44716 +        * Success 
44717 +        */
44718 +       return 0;
44719 +
44720 +fail:
44721 +       ubicom32fb_release(dev);
44722 +       return rc;
44723 +}
44724 +
44725 +/*
44726 + * ubicom32fb_platform_remove
44727 + */
44728 +static int ubicom32fb_platform_remove(struct platform_device *pdev)
44729 +{
44730 +       dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
44731 +       return ubicom32fb_release(&pdev->dev);
44732 +}
44733 +
44734 +static struct platform_driver ubicom32fb_platform_driver = {
44735 +       .probe          = ubicom32fb_platform_probe,
44736 +       .remove         = ubicom32fb_platform_remove,
44737 +       .driver = {
44738 +               .name = DRIVER_NAME,
44739 +               .owner = THIS_MODULE,
44740 +       },
44741 +};
44742 +
44743 +#ifndef MODULE
44744 +/*
44745 + * ubicom32fb_setup
44746 + *     Process kernel boot options
44747 + */
44748 +static int __init ubicom32fb_setup(char *options)
44749 +{
44750 +       char *this_opt;
44751 +
44752 +       if (!options || !*options) {
44753 +               return 0;
44754 +       }
44755 +
44756 +       while ((this_opt = strsep(&options, ",")) != NULL) {
44757 +               if (!*this_opt) {
44758 +                       continue;
44759 +               }
44760 +
44761 +               if (!strncmp(this_opt, "init_value=", 10)) {
44762 +                       init_value = simple_strtoul(this_opt + 11, NULL, 0);
44763 +                       continue;
44764 +               }
44765 +
44766 +               if (!strncmp(this_opt, "vram_size=", 10)) {
44767 +                       vram_size = simple_strtoul(this_opt + 10, NULL, 0);
44768 +                       continue;
44769 +               }
44770 +       }
44771 +       return 0;
44772 +}
44773 +#endif /* MODULE */
44774 +
44775 +/*
44776 + * ubicom32fb_init
44777 + */
44778 +static int __devinit ubicom32fb_init(void)
44779 +{
44780 +#ifndef MODULE
44781 +       /*
44782 +        * Get kernel boot options (in 'video=ubicom32fb:<options>')
44783 +        */
44784 +       char *option = NULL;
44785 +
44786 +       if (fb_get_options(DRIVER_NAME, &option)) {
44787 +               return -ENODEV;
44788 +       }
44789 +       ubicom32fb_setup(option);
44790 +#endif /* MODULE */
44791 +
44792 +       return platform_driver_register(&ubicom32fb_platform_driver);
44793 +}
44794 +module_init(ubicom32fb_init);
44795 +
44796 +/*
44797 + * ubicom32fb_exit
44798 + */
44799 +static void __exit ubicom32fb_exit(void)
44800 +{
44801 +       platform_driver_unregister(&ubicom32fb_platform_driver);
44802 +}
44803 +module_exit(ubicom32fb_exit);
44804 +
44805 +MODULE_LICENSE("GPL");
44806 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
44807 +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
44808 --- /dev/null
44809 +++ b/drivers/video/ubicom32vfb.c
44810 @@ -0,0 +1,492 @@
44811 +/*
44812 + * drivers/video/ubicom32vfb.c
44813 + *     Ubicom32 virtual frame buffer driver
44814 + *
44815 + * (C) Copyright 2009, Ubicom, Inc.
44816 + *
44817 + * This file is part of the Ubicom32 Linux Kernel Port.
44818 + *
44819 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
44820 + * it and/or modify it under the terms of the GNU General Public License
44821 + * as published by the Free Software Foundation, either version 2 of the
44822 + * License, or (at your option) any later version.
44823 + *
44824 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
44825 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
44826 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
44827 + * the GNU General Public License for more details.
44828 + *
44829 + * You should have received a copy of the GNU General Public License
44830 + * along with the Ubicom32 Linux Kernel Port.  If not,
44831 + * see <http://www.gnu.org/licenses/>.
44832 + */
44833 +
44834 +/*
44835 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
44836 + * Geert Uytterhoeven.
44837 + */
44838 +
44839 +#include <linux/device.h>
44840 +#include <linux/module.h>
44841 +#include <linux/kernel.h>
44842 +#include <linux/version.h>
44843 +#include <linux/errno.h>
44844 +#include <linux/string.h>
44845 +#include <linux/mm.h>
44846 +#include <linux/fb.h>
44847 +#include <linux/init.h>
44848 +#include <linux/dma-mapping.h>
44849 +#include <linux/platform_device.h>
44850 +#include <linux/device.h>
44851 +#include <linux/uaccess.h>
44852 +
44853 +#define DRIVER_NAME            "ubicom32vfb"
44854 +#define DRIVER_DESCRIPTION     "Ubicom32 virtual frame buffer driver"
44855 +
44856 +#define PALETTE_ENTRIES_NO     16
44857 +
44858 +/*
44859 + * Option variables
44860 + *
44861 + * vram_size:  VRAM size in kilobytes, subject to alignment 
44862 + */
44863 +static int vram_size = 0;
44864 +module_param(vram_size, int, 0);
44865 +MODULE_PARM_DESC(vram_size, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment");
44866 +
44867 +static int xres = 320;
44868 +module_param(xres, int, 0);
44869 +MODULE_PARM_DESC(xres, "x (horizontal) resolution");
44870 +
44871 +static int yres = 240;
44872 +module_param(yres, int, 0);
44873 +MODULE_PARM_DESC(yres, "y (vertical) resolution");
44874 +
44875 +static int bgr = 0;
44876 +module_param(bgr, int, 0);
44877 +MODULE_PARM_DESC(bgr, "display is BGR (Blue is MSB)");
44878 +
44879 +/*
44880 + * Buffer alignment, must not be 0
44881 + */
44882 +#define UBICOM32VFB_ALIGNMENT 4
44883 +
44884 +/*
44885 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
44886 + */
44887 +static struct fb_fix_screeninfo ubicom32vfb_fix = {
44888 +       .id =           "Ubicom32",
44889 +       .type =         FB_TYPE_PACKED_PIXELS,
44890 +       .visual =       FB_VISUAL_TRUECOLOR,
44891 +       .accel =        FB_ACCEL_NONE
44892 +};
44893 +
44894 +/*
44895 + * Filled in at probe time when we find out what the hardware supports
44896 + */
44897 +static struct fb_var_screeninfo ubicom32vfb_var;
44898 +
44899 +/*
44900 + * Private data structure
44901 + */
44902 +struct ubicom32vfb_drvdata {
44903 +       struct fb_info                  *fbinfo;
44904 +       bool                            cmap_alloc;
44905 +
44906 +       /*
44907 +        * The address of the framebuffer in memory
44908 +        */
44909 +       void                            *fb;
44910 +       void                            *fb_aligned;
44911 +
44912 +       /*
44913 +        * Total size of vram including alignment allowance
44914 +        */
44915 +       u32                             total_vram_size;
44916 +       
44917 +       /* 
44918 +        * Fake palette of 16 colors
44919 +        */
44920 +       u32                             pseudo_palette[PALETTE_ENTRIES_NO];
44921 +};
44922 +
44923 +/*
44924 + * ubicom32vfb_pan_display
44925 + *     Pans the display to a given location.  Supports only y direction panning.
44926 + */
44927 +static int ubicom32vfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44928 +{
44929 +       struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)fbi->par;
44930 +       void *new_addr;
44931 +
44932 +       /*
44933 +        * Get the last y line that would be displayed.  Since we don't support YWRAP,
44934 +        * it must be less than our virtual y size.
44935 +        */
44936 +       u32 lasty = var->yoffset + var->yres;
44937 +       if (lasty > fbi->var.yres_virtual) {
44938 +               /*
44939 +                * We would fall off the end of our frame buffer if we panned here.
44940 +                */
44941 +               return -EINVAL;
44942 +       }
44943 +
44944 +       if (var->xoffset) {
44945 +               /*
44946 +                * We don't support panning in the x direction
44947 +                */
44948 +               return -EINVAL;
44949 +       }
44950 +
44951 +       /*
44952 +        * Everything looks sane, go ahead and pan
44953 +        *
44954 +        * We have to calculate a new address for the VDC to look at
44955 +        */
44956 +       new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44957 +
44958 +       return 0;
44959 +}
44960 +
44961 +/*
44962 + * ubicom32vfb_setcolreg
44963 + *     Sets a color in our virtual palette
44964 + */
44965 +static int ubicom32vfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44966 +{
44967 +       u32 *palette = fbi->pseudo_palette;
44968 +
44969 +       if (regno >= PALETTE_ENTRIES_NO) {
44970 +               return -EINVAL;
44971 +       }
44972 +
44973 +       /*
44974 +        * We only use 8 bits from each color
44975 +        */
44976 +       red >>= 8;
44977 +       green >>= 8;
44978 +       blue >>= 8;
44979 +
44980 +       /*
44981 +        * Convert any grayscale values
44982 +        */
44983 +       if (fbi->var.grayscale) {
44984 +               u16 gray = red + green + blue;
44985 +               gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44986 +               gray >>= 2;
44987 +               if (gray > 255) {
44988 +                       gray = 255;
44989 +               }
44990 +               red = gray;
44991 +               blue = gray;
44992 +               green = gray;
44993 +       }
44994 +
44995 +       palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44996 +                        (blue << fbi->var.blue.offset);
44997 +
44998 +       return 0;
44999 +}
45000 +
45001 +/*
45002 + * ubicom32vfb_mmap
45003 + */
45004 +static int ubicom32vfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
45005 +{
45006 +       struct ubicom32vfb_drvdata *drvdata = (struct ubicom32vfb_drvdata *)info->par;
45007 +
45008 +       vma->vm_start = (unsigned long)(drvdata->fb_aligned);
45009 +
45010 +       vma->vm_end = vma->vm_start + info->fix.smem_len;
45011 +
45012 +       /* For those who don't understand how mmap works, go read
45013 +        *   Documentation/nommu-mmap.txt.
45014 +        * For those that do, you will know that the VM_MAYSHARE flag
45015 +        * must be set in the vma->vm_flags structure on noMMU
45016 +        *   Other flags can be set, and are documented in
45017 +        *   include/linux/mm.h
45018 +        */
45019 +
45020 +       vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
45021 +
45022 +       return 0;
45023 +}
45024 +
45025 +static struct fb_ops ubicom32vfb_ops =
45026 +{
45027 +       .owner                  = THIS_MODULE,
45028 +       .fb_pan_display         = ubicom32vfb_pan_display,
45029 +       .fb_setcolreg           = ubicom32vfb_setcolreg,
45030 +       .fb_mmap                = ubicom32vfb_mmap,
45031 +       .fb_fillrect            = cfb_fillrect,
45032 +       .fb_copyarea            = cfb_copyarea,
45033 +       .fb_imageblit           = cfb_imageblit,
45034 +};
45035 +
45036 +/*
45037 + * ubicom32vfb_release
45038 + */
45039 +static int ubicom32vfb_release(struct device *dev)
45040 +{
45041 +       struct ubicom32vfb_drvdata *ud = dev_get_drvdata(dev);
45042 +
45043 +       unregister_framebuffer(ud->fbinfo);
45044 +
45045 +       if (ud->cmap_alloc) {
45046 +               fb_dealloc_cmap(&ud->fbinfo->cmap);
45047 +       }
45048 +
45049 +       if (ud->fb) {
45050 +               kfree(ud->fb);
45051 +       }
45052 +
45053 +       framebuffer_release(ud->fbinfo);
45054 +       dev_set_drvdata(dev, NULL);
45055 +
45056 +       return 0;
45057 +}
45058 +
45059 +/*
45060 + * ubicom32vfb_platform_probe
45061 + */
45062 +static int __init ubicom32vfb_platform_probe(struct platform_device *pdev)
45063 +{
45064 +       struct ubicom32vfb_drvdata *ud;
45065 +       struct fb_info *fbinfo;
45066 +       int rc;
45067 +       size_t fbsize;
45068 +       struct device *dev = &pdev->dev;
45069 +       int offset;
45070 +
45071 +       /*
45072 +        * This is the minimum VRAM size
45073 +        */
45074 +       fbsize = xres * yres * 2;
45075 +       if (!vram_size) {
45076 +               vram_size = (fbsize + 1023) / 1024;
45077 +       } else {
45078 +               if (fbsize > (vram_size * 1024)) {
45079 +                       dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize);
45080 +                       return -ENOMEM; // should be ebadparam?
45081 +               }
45082 +       }
45083 +
45084 +       /*
45085 +        * Allocate the framebuffer instance + our private data
45086 +        */
45087 +       fbinfo = framebuffer_alloc(sizeof(struct ubicom32vfb_drvdata), &pdev->dev);
45088 +       if (!fbinfo) {
45089 +               dev_err(dev, "Not enough memory to allocate instance.\n");
45090 +               return -ENOMEM;
45091 +       }
45092 +
45093 +       /*
45094 +        * Fill in our private data.
45095 +        */
45096 +       ud = (struct ubicom32vfb_drvdata *)fbinfo->par;
45097 +       ud->fbinfo = fbinfo;
45098 +       dev_set_drvdata(dev, ud);
45099 +
45100 +       /*
45101 +        * Allocate and align the requested amount of VRAM
45102 +        */
45103 +       ud->total_vram_size = (vram_size * 1024) + UBICOM32VFB_ALIGNMENT;
45104 +       ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL);
45105 +       if (ud->fb == NULL) {
45106 +               dev_err(dev, "Couldn't allocate VRAM\n");
45107 +               rc = -ENOMEM;
45108 +               goto fail;
45109 +       }
45110 +
45111 +       offset = (u32_t)ud->fb & (UBICOM32VFB_ALIGNMENT - 1);
45112 +       if (!offset) {
45113 +               ud->fb_aligned = ud->fb;
45114 +       } else {
45115 +               offset =  UBICOM32VFB_ALIGNMENT - offset;
45116 +               ud->fb_aligned = ud->fb + offset;
45117 +       }
45118 +
45119 +       /*
45120 +        * Clear the entire frame buffer
45121 +        */
45122 +       memset(ud->fb_aligned, 0, vram_size * 1024);
45123 +
45124 +       /*
45125 +        * Fill in the fb_var_screeninfo structure
45126 +        */
45127 +       memset(&ubicom32vfb_var, 0, sizeof(ubicom32vfb_var));
45128 +       ubicom32vfb_var.bits_per_pixel = 16;
45129 +       ubicom32vfb_var.red.length = 5;
45130 +       ubicom32vfb_var.green.length = 6;
45131 +       ubicom32vfb_var.green.offset = 5;
45132 +       ubicom32vfb_var.blue.length = 5;
45133 +       ubicom32vfb_var.activate = FB_ACTIVATE_NOW;
45134 +
45135 +       if (bgr) {
45136 +               ubicom32vfb_var.red.offset = 0;
45137 +               ubicom32vfb_var.blue.offset = 11;
45138 +       } else {
45139 +               ubicom32vfb_var.red.offset = 11;
45140 +               ubicom32vfb_var.blue.offset = 0;
45141 +       }
45142 +
45143 +       /*
45144 +        * Fill in the fb_info structure
45145 +        */
45146 +       ud->fbinfo->device = dev;
45147 +       ud->fbinfo->screen_base = (void *)ud->fb_aligned;
45148 +       ud->fbinfo->fbops = &ubicom32vfb_ops;
45149 +       ud->fbinfo->fix = ubicom32vfb_fix;
45150 +       ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned;
45151 +       ud->fbinfo->fix.smem_len = fbsize;
45152 +       ud->fbinfo->fix.line_length = xres * 2;
45153 +
45154 +       /*
45155 +        * We support panning in the y direction only
45156 +        */
45157 +       ud->fbinfo->fix.xpanstep = 0;
45158 +       ud->fbinfo->fix.ypanstep = 1;
45159 +
45160 +       ud->fbinfo->pseudo_palette = ud->pseudo_palette;
45161 +       ud->fbinfo->flags = FBINFO_DEFAULT;
45162 +       ud->fbinfo->var = ubicom32vfb_var;
45163 +       ud->fbinfo->var.xres = xres;
45164 +       ud->fbinfo->var.yres = yres;
45165 +
45166 +       /*
45167 +        * We cannot pan in the X direction, so xres_virtual is xres
45168 +        * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length
45169 +        */
45170 +       ud->fbinfo->var.xres_virtual = xres;
45171 +       ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
45172 +
45173 +       /* 
45174 +        * Allocate a color map
45175 +        */
45176 +       rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
45177 +       if (rc) {
45178 +               dev_err(dev, "Fail to allocate colormap (%d entries)\n",
45179 +                       PALETTE_ENTRIES_NO);
45180 +               goto fail;
45181 +       }
45182 +       ud->cmap_alloc = true;
45183 +
45184 +       /*
45185 +        * Register new frame buffer
45186 +        */
45187 +       rc = register_framebuffer(ud->fbinfo);
45188 +       if (rc) {
45189 +               dev_err(dev, "Could not register frame buffer\n");
45190 +               goto fail;
45191 +       }
45192 +
45193 +       /*
45194 +        * Tell the log we are here
45195 +        */
45196 +       dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u)\n",
45197 +               ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, 
45198 +               ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual);
45199 +
45200 +       /* 
45201 +        * Success 
45202 +        */
45203 +       return 0;
45204 +
45205 +fail:
45206 +       ubicom32vfb_release(dev);
45207 +       return rc;
45208 +}
45209 +
45210 +/*
45211 + * ubicom32vfb_platform_remove
45212 + */
45213 +static int ubicom32vfb_platform_remove(struct platform_device *pdev)
45214 +{
45215 +       dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
45216 +       return ubicom32vfb_release(&pdev->dev);
45217 +}
45218 +
45219 +static struct platform_driver ubicom32vfb_platform_driver = {
45220 +       .probe          = ubicom32vfb_platform_probe,
45221 +       .remove         = ubicom32vfb_platform_remove,
45222 +       .driver = {
45223 +               .name = DRIVER_NAME,
45224 +               .owner = THIS_MODULE,
45225 +       },
45226 +};
45227 +
45228 +#ifndef MODULE
45229 +/*
45230 + * ubicom32vfb_setup
45231 + *     Process kernel boot options
45232 + */
45233 +static int __init ubicom32vfb_setup(char *options)
45234 +{
45235 +       char *this_opt;
45236 +
45237 +       if (!options || !*options) {
45238 +               return 0;
45239 +       }
45240 +
45241 +       while ((this_opt = strsep(&options, ",")) != NULL) {
45242 +               if (!*this_opt) {
45243 +                       continue;
45244 +               }
45245 +
45246 +               if (!strncmp(this_opt, "vram_size=", 10)) {
45247 +                       vram_size = simple_strtoul(this_opt + 10, NULL, 0);
45248 +                       continue;
45249 +               }
45250 +
45251 +               if (!strncmp(this_opt, "bgr=", 4)) {
45252 +                       bgr = simple_strtoul(this_opt + 4, NULL, 0);
45253 +                       continue;
45254 +               }
45255 +
45256 +               if (!strncmp(this_opt, "xres=", 5)) {
45257 +                       xres = simple_strtoul(this_opt + 5, NULL, 0);
45258 +                       continue;
45259 +               }
45260 +
45261 +               if (!strncmp(this_opt, "yres=", 5)) {
45262 +                       yres = simple_strtoul(this_opt + 5, NULL, 0);
45263 +                       continue;
45264 +               }
45265 +       }
45266 +       return 0;
45267 +}
45268 +#endif /* MODULE */
45269 +
45270 +/*
45271 + * ubicom32vfb_init
45272 + */
45273 +static int __devinit ubicom32vfb_init(void)
45274 +{
45275 +#ifndef MODULE
45276 +       /*
45277 +        * Get kernel boot options (in 'video=ubicom32vfb:<options>')
45278 +        */
45279 +       char *option = NULL;
45280 +
45281 +       if (fb_get_options(DRIVER_NAME, &option)) {
45282 +               return -ENODEV;
45283 +       }
45284 +       ubicom32vfb_setup(option);
45285 +#endif /* MODULE */
45286 +
45287 +       return platform_driver_register(&ubicom32vfb_platform_driver);
45288 +}
45289 +module_init(ubicom32vfb_init);
45290 +
45291 +/*
45292 + * ubicom32vfb_exit
45293 + */
45294 +static void __exit ubicom32vfb_exit(void)
45295 +{
45296 +       platform_driver_unregister(&ubicom32vfb_platform_driver);
45297 +}
45298 +module_exit(ubicom32vfb_exit);
45299 +
45300 +MODULE_LICENSE("GPL");
45301 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
45302 +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
45303 --- a/drivers/watchdog/Kconfig
45304 +++ b/drivers/watchdog/Kconfig
45305 @@ -856,6 +856,19 @@ config WATCHDOG_RIO
45306           machines.  The watchdog timeout period is normally one minute but
45307           can be changed with a boot-time parameter.
45308  
45309 +# Ubicom32
45310 +
45311 +config UBI32_WDT
45312 +       tristate "Ubicom32 Hardware Watchdog support"
45313 +       depends on UBICOM32
45314 +       ---help---
45315 +         If you say yes here you will get support for the Ubicom32 On-Chip
45316 +         Watchdog Timer. If you have one of these processors and wish to
45317 +         have watchdog support enabled, say Y, otherwise say N.
45318 +
45319 +         To compile this driver as a module, choose M here: the
45320 +         module will be called ubi32_wdt.
45321 +
45322  # XTENSA Architecture
45323  
45324  #
45325 --- a/drivers/watchdog/Makefile
45326 +++ b/drivers/watchdog/Makefile
45327 @@ -130,6 +130,9 @@ obj-$(CONFIG_SH_WDT) += shwdt.o
45328  obj-$(CONFIG_WATCHDOG_RIO)             += riowd.o
45329  obj-$(CONFIG_WATCHDOG_CP1XXX)          += cpwd.o
45330  
45331 +# Ubicom32 Architecture
45332 +obj-$(CONFIG_UBI32_WDT)                        += ubi32_wdt.o
45333 +
45334  # XTENSA Architecture
45335  
45336  # Architecture Independant
45337 --- /dev/null
45338 +++ b/drivers/watchdog/ubi32_wdt.c
45339 @@ -0,0 +1,630 @@
45340 +/*
45341 + * drivers/watchdog/ubi32_wdt.c
45342 + *   Ubicom32 Watchdog Driver
45343 + *
45344 + * Originally based on softdog.c
45345 + * Copyright 2006-2007 Analog Devices Inc.
45346 + * Copyright 2006-2007 Michele d'Amico
45347 + * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>
45348 + * (C) Copyright 2009, Ubicom, Inc.
45349 + *
45350 + * This file is part of the Ubicom32 Linux Kernel Port.
45351 + *
45352 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
45353 + * it and/or modify it under the terms of the GNU General Public License
45354 + * as published by the Free Software Foundation, either version 2 of the
45355 + * License, or (at your option) any later version.
45356 + *
45357 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
45358 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
45359 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
45360 + * the GNU General Public License for more details.
45361 + *
45362 + * You should have received a copy of the GNU General Public License
45363 + * along with the Ubicom32 Linux Kernel Port.  If not,
45364 + * see <http://www.gnu.org/licenses/>.
45365 + *
45366 + * Ubicom32 implementation derived from (with many thanks):
45367 + *   arch/m68knommu
45368 + *   arch/blackfin
45369 + *   arch/parisc
45370 + */
45371 +#include <linux/platform_device.h>
45372 +#include <linux/module.h>
45373 +#include <linux/moduleparam.h>
45374 +#include <linux/types.h>
45375 +#include <linux/timer.h>
45376 +#include <linux/miscdevice.h>
45377 +#include <linux/watchdog.h>
45378 +#include <linux/fs.h>
45379 +#include <linux/notifier.h>
45380 +#include <linux/reboot.h>
45381 +#include <linux/init.h>
45382 +#include <linux/interrupt.h>
45383 +#include <linux/uaccess.h>
45384 +#include <asm/ip5000.h>
45385 +
45386 +#define WATCHDOG_NAME "ubi32-wdt"
45387 +#define PFX WATCHDOG_NAME ": "
45388 +
45389 +#define OSC1_FREQ 12000000
45390 +#define WATCHDOG_SEC_TO_CYC(x) (OSC1_FREQ * (x))
45391 +#define WATCHDOG_MAX_SEC (0xffffffff / OSC1_FREQ)
45392 +
45393 +#define MIN_PROCESSOR_ADDRESS 0x03000000
45394 +
45395 +static DEFINE_SPINLOCK(ubi32_wdt_spinlock);
45396 +
45397 +#define WATCHDOG_TIMEOUT 20
45398 +
45399 +#if defined(CONFIG_WATCHDOG_NOWAYOUT)
45400 +#define WATCHDOG_NOWAYOUT 1
45401 +#else
45402 +#define WATCHDOG_NOWAYOUT 0
45403 +#endif
45404 +
45405 +static unsigned int timeout = WATCHDOG_TIMEOUT;
45406 +static int nowayout = WATCHDOG_NOWAYOUT;
45407 +static struct watchdog_info ubi32_wdt_info;
45408 +static unsigned long open_check;
45409 +static char expect_close;
45410 +
45411 +#if !defined(CONFIG_SMP)
45412 +#define UBI32_WDT_LOCK(lock, flags) local_irq_save(flags)
45413 +#define UBI32_WDT_UNLOCK(lock, flags) local_irq_restore(flags)
45414 +#define UBI32_WDT_LOCK_CHECK()
45415 +#else
45416 +#define UBI32_WDT_LOCK(lock, flags) spin_lock_irqsave((lock), (flags));
45417 +#define UBI32_WDT_UNLOCK(lock, flags) spin_unlock_irqrestore((lock), (flags));
45418 +#define UBI32_WDT_LOCK_CHECK() BUG_ON(!spin_is_locked(&ubi32_wdt_spinlock));
45419 +#endif
45420 +
45421 +/*
45422 + * ubi32_wdt_remaining()
45423 + *     Return the approximate number of seconds remaining
45424 + */
45425 +static int ubi32_wdt_remaining(void)
45426 +{
45427 +       int compare;
45428 +       int curr;
45429 +
45430 +       UBI32_WDT_LOCK_CHECK();
45431 +
45432 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45433 +       compare = ubicom32_read_reg(&UBICOM32_IO_TIMER->wdcom);
45434 +       curr = ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval);
45435 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45436 +       return (compare - curr) / OSC1_FREQ;
45437 +
45438 +}
45439 +
45440 +/*
45441 + * ubi32_wdt_keepalive()
45442 + *     Keep the Userspace Watchdog Alive
45443 + *
45444 + * The Userspace watchdog got a KeepAlive: schedule the next timeout.
45445 + */
45446 +static int ubi32_wdt_keepalive(void)
45447 +{
45448 +       UBI32_WDT_LOCK_CHECK();
45449 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45450 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcom,
45451 +                       ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval)
45452 +                       + WATCHDOG_SEC_TO_CYC(timeout));
45453 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45454 +       return 0;
45455 +}
45456 +
45457 +/*
45458 + * ubi32_wdt_stop()
45459 + *     Stop the on-chip Watchdog
45460 + */
45461 +static int ubi32_wdt_stop(void)
45462 +{
45463 +       UBI32_WDT_LOCK_CHECK();
45464 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45465 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcfg, TIMER_WATCHDOG_DISABLE);
45466 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45467 +       return 0;
45468 +}
45469 +
45470 +/*
45471 + * ubi32_wdt_start()
45472 + *     Start the on-chip Watchdog
45473 + */
45474 +static int ubi32_wdt_start(void)
45475 +{
45476 +       UBI32_WDT_LOCK_CHECK();
45477 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45478 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcom,
45479 +                       ubicom32_read_reg(&UBICOM32_IO_TIMER->mptval)
45480 +                       + WATCHDOG_SEC_TO_CYC(timeout));
45481 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->wdcfg, ~TIMER_WATCHDOG_DISABLE);
45482 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45483 +       return 0;
45484 +}
45485 +
45486 +/*
45487 + * ubi32_wdt_running()
45488 + *     Return true if the watchdog is configured
45489 + */
45490 +static int ubi32_wdt_running(void)
45491 +{
45492 +       int enabled;
45493 +
45494 +       UBI32_WDT_LOCK_CHECK();
45495 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, TIMER_TKEYVAL);
45496 +       enabled = ubicom32_read_reg(&UBICOM32_IO_TIMER->wdcfg) == ~TIMER_WATCHDOG_DISABLE;
45497 +       ubicom32_write_reg(&UBICOM32_IO_TIMER->tkey, 0);
45498 +       return enabled;
45499 +}
45500 +
45501 +/*
45502 + * ubi32_wdt_set_timeout()
45503 + *     Set the Userspace Watchdog timeout
45504 + *
45505 + * - @t: new timeout value (in seconds)
45506 + */
45507 +static int ubi32_wdt_set_timeout(unsigned long t)
45508 +{
45509 +       UBI32_WDT_LOCK_CHECK();
45510 +
45511 +       if (t > WATCHDOG_MAX_SEC) {
45512 +               printk(KERN_WARNING PFX "request to large: %ld [1-%d] sec)\n", t, WATCHDOG_MAX_SEC);
45513 +               return -EINVAL;
45514 +       }
45515 +
45516 +       /*
45517 +        * If we are running, then reset the time value so
45518 +        * that the new value has an immediate effect.
45519 +        */
45520 +       timeout = t;
45521 +       if (ubi32_wdt_running()) {
45522 +               ubi32_wdt_keepalive();
45523 +       }
45524 +       return 0;
45525 +}
45526 +
45527 +/*
45528 + * ubi32_wdt_open()
45529 + *     Open the Device
45530 + */
45531 +static int ubi32_wdt_open(struct inode *inode, struct file *file)
45532 +{
45533 +       unsigned long flags;
45534 +
45535 +       if (test_and_set_bit(0, &open_check))
45536 +               return -EBUSY;
45537 +
45538 +       if (nowayout)
45539 +               __module_get(THIS_MODULE);
45540 +
45541 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45542 +       ubi32_wdt_start();
45543 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45544 +
45545 +       return nonseekable_open(inode, file);
45546 +}
45547 +
45548 +/*
45549 + * ubi32_wdt_close()
45550 + *     Close the Device
45551 + */
45552 +static int ubi32_wdt_release(struct inode *inode, struct file *file)
45553 +{
45554 +       unsigned long flags;
45555 +
45556 +       /*
45557 +        * If we don't expect a close, then the watchdog continues
45558 +        * even though the device is closed.  The caller will have
45559 +        * a full timeout value to reopen the device and continue
45560 +        * stroking it.
45561 +        */
45562 +       if (expect_close != 42) {
45563 +               printk(KERN_CRIT PFX
45564 +                       "Unexpected close, not stopping watchdog!\n");
45565 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45566 +               ubi32_wdt_keepalive();
45567 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45568 +       } else {
45569 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45570 +               ubi32_wdt_stop();
45571 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45572 +       }
45573 +
45574 +       expect_close = 0;
45575 +       clear_bit(0, &open_check);
45576 +       return 0;
45577 +}
45578 +
45579 +/*
45580 + * ubi32_wdt_write()
45581 + *     Write to Device
45582 + *
45583 + * If the user writes nothing, nothing happens.
45584 + * If the user writes a V, then we expect a close and allow a release.
45585 + * If the user writes anything else, it is ignored.
45586 + */
45587 +static ssize_t ubi32_wdt_write(struct file *file, const char __user *data,
45588 +                                               size_t len, loff_t *ppos)
45589 +{
45590 +       size_t i;
45591 +       unsigned long flags;
45592 +
45593 +       /*
45594 +        * Every write resets the expect_close.  The last write
45595 +        * must be a V to allow shutdown on close.
45596 +        */
45597 +       expect_close = 0;
45598 +
45599 +       /*
45600 +        * Empty writes still ping.
45601 +        */
45602 +       if (!len) {
45603 +               goto ping;
45604 +       }
45605 +
45606 +       /*
45607 +        * If nowayout is set, it does not matter if the caller
45608 +        * is trying to send the magic 'V' we will not allow a
45609 +        * close to stop us.
45610 +        */
45611 +       if (nowayout) {
45612 +               goto ping;
45613 +       }
45614 +
45615 +       /*
45616 +        * See if the program wrote a 'V' and if so disable
45617 +        * the watchdog on release.
45618 +        */
45619 +       for (i = 0; i < len; i++) {
45620 +               char c;
45621 +               if (get_user(c, data + i)) {
45622 +                       return -EFAULT;
45623 +               }
45624 +
45625 +               if (c == 'V') {
45626 +                       expect_close = 42;
45627 +               }
45628 +       }
45629 +
45630 +ping:
45631 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45632 +       ubi32_wdt_keepalive();
45633 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45634 +       return len;
45635 +}
45636 +
45637 +/*
45638 + * ubi32_wdt_ioctl()
45639 + *     Query the watchdog device.
45640 + *
45641 + * Query basic information from the device or ping it, as outlined by the
45642 + * watchdog API.
45643 + */
45644 +static long ubi32_wdt_ioctl(struct file *file,
45645 +                               unsigned int cmd, unsigned long arg)
45646 +{
45647 +       void __user *argp = (void __user *)arg;
45648 +       int __user *p = argp;
45649 +
45650 +       switch (cmd) {
45651 +       case WDIOC_GETSUPPORT:
45652 +               if (copy_to_user(argp, &ubi32_wdt_info, sizeof(ubi32_wdt_info))) {
45653 +                       return -EFAULT;
45654 +               }
45655 +               return 0;
45656 +
45657 +       case WDIOC_GETSTATUS: {
45658 +               unsigned long flags;
45659 +               int running;
45660 +
45661 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45662 +               running = ubi32_wdt_running();
45663 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45664 +               return running;
45665 +       }
45666 +
45667 +       case WDIOC_GETBOOTSTATUS:
45668 +               return ubicom32_get_reset_reason();
45669 +
45670 +       case WDIOC_SETOPTIONS: {
45671 +               unsigned long flags;
45672 +               int options, ret = -EINVAL;
45673 +
45674 +               /*
45675 +                * The sample application does not pass a pointer
45676 +                * but directly passes a value of 1 or 2; however
45677 +                * all of the implementations (and thus probably
45678 +                * the real applications) pass a pointer to a value.
45679 +                *
45680 +                * It should be noted that  WDIOC_SETOPTIONS is defined as
45681 +                * _IOR(WATCHDOG_IOCTL_BASE, 4, int), which means
45682 +                * that it should be an int and NOT a pointer.
45683 +                *
45684 +                * TODO: Examine this code for future chips.
45685 +                * TODO: Report the sample code defect.
45686 +                */
45687 +               if ((int)p < MIN_PROCESSOR_ADDRESS) {
45688 +                       options = (int)p;
45689 +               } else {
45690 +                       if (get_user(options, p))
45691 +                       return -EFAULT;
45692 +               }
45693 +
45694 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45695 +               if (options & WDIOS_DISABLECARD) {
45696 +                       ubi32_wdt_stop();
45697 +                       ret = 0;
45698 +               }
45699 +               if (options & WDIOS_ENABLECARD) {
45700 +                       ubi32_wdt_start();
45701 +                       ret = 0;
45702 +               }
45703 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45704 +               return ret;
45705 +       }
45706 +
45707 +       case WDIOC_KEEPALIVE: {
45708 +               unsigned long flags;
45709 +
45710 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45711 +               ubi32_wdt_keepalive();
45712 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45713 +               return 0;
45714 +       }
45715 +
45716 +       case WDIOC_SETTIMEOUT: {
45717 +               int new_timeout;
45718 +               unsigned long flags;
45719 +               int ret  = 0;
45720 +
45721 +               if (get_user(new_timeout, p))
45722 +                       return -EFAULT;
45723 +
45724 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45725 +               ret = ubi32_wdt_set_timeout(new_timeout);
45726 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45727 +               return ret;
45728 +
45729 +       }
45730 +
45731 +       case WDIOC_GETTIMEOUT:
45732 +               return put_user(timeout, p);
45733 +
45734 +       case WDIOC_GETTIMELEFT: {
45735 +               unsigned long flags;
45736 +               int remaining = 0;
45737 +
45738 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45739 +               remaining = ubi32_wdt_remaining();
45740 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45741 +               return put_user(remaining, p);
45742 +       }
45743 +
45744 +       default:
45745 +               return -ENOTTY;
45746 +       }
45747 +}
45748 +
45749 +/*
45750 + * ubi32_wdt_notify_sys()
45751 + *     Notification callback function for system events.
45752 + *
45753 + * Turn off the watchdog during a SYS_DOWN or SYS_HALT.
45754 + */
45755 +static int ubi32_wdt_notify_sys(struct notifier_block *this,
45756 +                                       unsigned long code, void *unused)
45757 +{
45758 +       if (code == SYS_DOWN || code == SYS_HALT) {
45759 +               unsigned long flags;
45760 +
45761 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45762 +               ubi32_wdt_stop();
45763 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45764 +       }
45765 +
45766 +       return NOTIFY_DONE;
45767 +}
45768 +
45769 +#ifdef CONFIG_PM
45770 +static int state_before_suspend;
45771 +
45772 +/*
45773 + * ubi32_wdt_suspend()
45774 + *     suspend the watchdog
45775 + *
45776 + * Remember if the watchdog was running and stop it.
45777 + */
45778 +static int ubi32_wdt_suspend(struct platform_device *pdev, pm_message_t state)
45779 +{
45780 +       unsigned long flags;
45781 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45782 +       state_before_suspend = ubi32_wdt_running();
45783 +       ubi32_wdt_stop();
45784 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45785 +
45786 +       return 0;
45787 +}
45788 +
45789 +/*
45790 + * ubi32_wdt_resume()
45791 + *     Resume the watchdog
45792 + *
45793 + * If the watchdog was running, turn it back on.
45794 + */
45795 +static int ubi32_wdt_resume(struct platform_device *pdev)
45796 +{
45797 +       if (state_before_suspend) {
45798 +               unsigned long flags;
45799 +               spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45800 +               ubi32_wdt_set_timeout(timeout);
45801 +               ubi32_wdt_start();
45802 +               spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45803 +       }
45804 +
45805 +       return 0;
45806 +}
45807 +#else
45808 +# define ubi32_wdt_suspend NULL
45809 +# define ubi32_wdt_resume NULL
45810 +#endif
45811 +
45812 +static const struct file_operations ubi32_wdt_fops = {
45813 +       .owner          = THIS_MODULE,
45814 +       .llseek         = no_llseek,
45815 +       .write          = ubi32_wdt_write,
45816 +       .unlocked_ioctl = ubi32_wdt_ioctl,
45817 +       .open           = ubi32_wdt_open,
45818 +       .release        = ubi32_wdt_release,
45819 +};
45820 +
45821 +static struct miscdevice ubi32_wdt_miscdev = {
45822 +       .minor    = WATCHDOG_MINOR,
45823 +       .name     = "watchdog",
45824 +       .fops     = &ubi32_wdt_fops,
45825 +};
45826 +
45827 +static struct watchdog_info ubi32_wdt_info = {
45828 +       .identity = "Ubicom32 Watchdog",
45829 +       .options  = WDIOF_SETTIMEOUT |
45830 +                   WDIOF_KEEPALIVEPING |
45831 +                   WDIOF_MAGICCLOSE,
45832 +};
45833 +
45834 +static struct notifier_block ubi32_wdt_notifier = {
45835 +       .notifier_call = ubi32_wdt_notify_sys,
45836 +};
45837 +
45838 +/*
45839 + * ubi32_wdt_probe()
45840 + *     Probe/register the watchdog module
45841 + *
45842 + * Registers the misc device and notifier handler.  Actual device
45843 + * initialization is handled by ubi32_wdt_open().
45844 + */
45845 +static int __devinit ubi32_wdt_probe(struct platform_device *pdev)
45846 +{
45847 +       int ret;
45848 +
45849 +       ret = register_reboot_notifier(&ubi32_wdt_notifier);
45850 +       if (ret) {
45851 +               printk(KERN_ERR PFX
45852 +                       "cannot register reboot notifier (err=%d)\n", ret);
45853 +               return ret;
45854 +       }
45855 +
45856 +       ret = misc_register(&ubi32_wdt_miscdev);
45857 +       if (ret) {
45858 +               printk(KERN_ERR PFX
45859 +                       "cannot register miscdev on minor=%d (err=%d)\n",
45860 +                               WATCHDOG_MINOR, ret);
45861 +               unregister_reboot_notifier(&ubi32_wdt_notifier);
45862 +               return ret;
45863 +       }
45864 +
45865 +       printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
45866 +              timeout, nowayout);
45867 +
45868 +       return 0;
45869 +}
45870 +
45871 +/*
45872 + * ubi32_wdt_remove()
45873 + *     Uninstall the module
45874 + *
45875 + * Unregisters the misc device and notifier handler.  Actual device
45876 + * deinitialization is handled by ubi32_wdt_close().
45877 + */
45878 +static int __devexit ubi32_wdt_remove(struct platform_device *pdev)
45879 +{
45880 +       misc_deregister(&ubi32_wdt_miscdev);
45881 +       unregister_reboot_notifier(&ubi32_wdt_notifier);
45882 +       return 0;
45883 +}
45884 +
45885 +static struct platform_device *ubi32_wdt_device;
45886 +
45887 +static struct platform_driver ubi32_wdt_driver = {
45888 +       .probe     = ubi32_wdt_probe,
45889 +       .remove    = __devexit_p(ubi32_wdt_remove),
45890 +       .suspend   = ubi32_wdt_suspend,
45891 +       .resume    = ubi32_wdt_resume,
45892 +       .driver    = {
45893 +               .name  = WATCHDOG_NAME,
45894 +               .owner = THIS_MODULE,
45895 +       },
45896 +};
45897 +
45898 +/*
45899 + * ubi32_wdt_init()
45900 + *     Initialize the watchdog.
45901 + *
45902 + * Checks the module params and registers the platform device & driver.
45903 + * Real work is in the platform probe function.
45904 + */
45905 +static int __init ubi32_wdt_init(void)
45906 +{
45907 +       unsigned long flags;
45908 +       int ret;
45909 +
45910 +       /*
45911 +        * Check that the timeout value is within range
45912 +        */
45913 +       spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45914 +       ret = ubi32_wdt_set_timeout(timeout);
45915 +       spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45916 +       if (ret) {
45917 +               return ret;
45918 +       }
45919 +
45920 +       /*
45921 +        * Since this is an on-chip device and needs no board-specific
45922 +        * resources, we'll handle all the platform device stuff here.
45923 +        */
45924 +       ret = platform_driver_register(&ubi32_wdt_driver);
45925 +       if (ret) {
45926 +               printk(KERN_ERR PFX "unable to register driver\n");
45927 +               return ret;
45928 +       }
45929 +
45930 +       ubi32_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0);
45931 +       if (IS_ERR(ubi32_wdt_device)) {
45932 +               printk(KERN_ERR PFX "unable to register device\n");
45933 +               platform_driver_unregister(&ubi32_wdt_driver);
45934 +               return PTR_ERR(ubi32_wdt_device);
45935 +       }
45936 +
45937 +       return 0;
45938 +}
45939 +
45940 +/*
45941 + * ubi32_wdt_exit()
45942 + *     Deinitialize module
45943 + *
45944 + * Back out the platform device & driver steps.  Real work is in the
45945 + * platform remove function.
45946 + */
45947 +static void __exit ubi32_wdt_exit(void)
45948 +{
45949 +       platform_device_unregister(ubi32_wdt_device);
45950 +       platform_driver_unregister(&ubi32_wdt_driver);
45951 +}
45952 +
45953 +module_init(ubi32_wdt_init);
45954 +module_exit(ubi32_wdt_exit);
45955 +
45956 +MODULE_AUTHOR("Sol Kavy<sol@ubicom.com>");
45957 +MODULE_DESCRIPTION("Ubicom32 Watchdog Device Driver");
45958 +MODULE_LICENSE("GPL");
45959 +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
45960 +
45961 +module_param(timeout, uint, 0);
45962 +MODULE_PARM_DESC(timeout,
45963 +       "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default="
45964 +               __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
45965 +
45966 +module_param(nowayout, int, 0);
45967 +MODULE_PARM_DESC(nowayout,
45968 +       "Watchdog cannot be stopped once started (default="
45969 +               __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
45970 --- a/fs/binfmt_flat.c
45971 +++ b/fs/binfmt_flat.c
45972 @@ -54,6 +54,10 @@
45973  #define        DBG_FLT(a...)
45974  #endif
45975  
45976 +#ifndef ARCH_FLAT_ALIGN
45977 +#define ARCH_FLAT_ALIGN 0
45978 +#endif
45979 +
45980  #define RELOC_FAILED 0xff00ff01                /* Relocation incorrect somewhere */
45981  #define UNLOADED_LIB 0x7ff000ff                /* Placeholder for unused library */
45982  
45983 @@ -127,10 +131,10 @@ static unsigned long create_flat_tables(
45984                 --sp; put_user((unsigned long) argv, sp);
45985         }
45986  
45987 -       put_user(argc,--sp);
45988 +       --sp; put_user(argc,sp);
45989         current->mm->arg_start = (unsigned long) p;
45990         while (argc-->0) {
45991 -               put_user((unsigned long) p, argv++);
45992 +               put_user((unsigned long) p, argv); argv++;
45993                 do {
45994                         get_user(dummy, p); p++;
45995                 } while (dummy);
45996 @@ -425,6 +429,7 @@ static int load_flat_file(struct linux_b
45997         loff_t fpos;
45998         unsigned long start_code, end_code;
45999         int ret;
46000 +       int flush_happened = 0;
46001  
46002         hdr = ((struct flat_hdr *) bprm->buf);          /* exec-header */
46003         inode = bprm->file->f_path.dentry->d_inode;
46004 @@ -510,6 +515,7 @@ static int load_flat_file(struct linux_b
46005  
46006                 /* OK, This is the point of no return */
46007                 set_personality(PER_LINUX_32BIT);
46008 +               flush_happened = 1;
46009         }
46010  
46011         /*
46012 @@ -524,6 +530,12 @@ static int load_flat_file(struct linux_b
46013          * it all together.
46014          */
46015         if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {
46016 +
46017 +#ifdef ARCH_FLAT_ALIGN_TEXT
46018 +               printk("Unable to mmap rom with ARCH alignment requirements\n");
46019 +               ret = -ENOEXEC;
46020 +               goto err;
46021 +#endif
46022                 /*
46023                  * this should give us a ROM ptr,  but if it doesn't we don't
46024                  * really care
46025 @@ -542,7 +554,7 @@ static int load_flat_file(struct linux_b
46026                         goto err;
46027                 }
46028  
46029 -               len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
46030 +               len = data_len + extra + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
46031                 down_write(&current->mm->mmap_sem);
46032                 realdatastart = do_mmap(0, 0, len,
46033                         PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
46034 @@ -565,7 +577,7 @@ static int load_flat_file(struct linux_b
46035                         ret = realdatastart;
46036                         goto err;
46037                 }
46038 -               datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
46039 +               datapos = realdatastart + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
46040  
46041                 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
46042                                 (int)(data_len + bss_len + stack_len), (int)datapos);
46043 @@ -594,7 +606,11 @@ static int load_flat_file(struct linux_b
46044  
46045         } else {
46046  
46047 -               len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
46048 +               len = text_len + data_len + extra + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
46049 +#ifdef ARCH_FLAT_ALIGN_TEXT
46050 +               /* Reserve space for the text alignment. */
46051 +               len += ARCH_FLAT_ALIGN;
46052 +#endif
46053                 down_write(&current->mm->mmap_sem);
46054                 textpos = do_mmap(0, 0, len,
46055                         PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
46056 @@ -617,11 +633,14 @@ static int load_flat_file(struct linux_b
46057                         goto err;
46058                 }
46059  
46060 +               memp = textpos;
46061 +#ifdef ARCH_FLAT_ALIGN_TEXT
46062 +               textpos = ALIGN(textpos + sizeof(struct flat_hdr), ARCH_FLAT_ALIGN) - sizeof(struct flat_hdr);
46063 +#endif
46064                 realdatastart = textpos + ntohl(hdr->data_start);
46065 -               datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
46066 +               datapos = realdatastart + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
46067                 reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
46068 -                               MAX_SHARED_LIBS * sizeof(unsigned long));
46069 -               memp = textpos;
46070 +                                          ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN));
46071  
46072  #ifdef CONFIG_BINFMT_ZFLAT
46073                 /*
46074 @@ -657,7 +676,7 @@ static int load_flat_file(struct linux_b
46075                 }
46076                 if (result >= (unsigned long)-4096) {
46077                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
46078 -                       do_munmap(current->mm, textpos, text_len + data_len + extra +
46079 +                       do_munmap(current->mm, memp, text_len + data_len + extra +
46080                                 MAX_SHARED_LIBS * sizeof(unsigned long));
46081                         ret = result;
46082                         goto err;
46083 @@ -670,6 +689,9 @@ static int load_flat_file(struct linux_b
46084  
46085         /* The main program needs a little extra setup in the task structure */
46086         start_code = textpos + sizeof (struct flat_hdr);
46087 +#ifdef ARCH_FLAT_ALIGN_TEXT
46088 +       BUG_ON(ALIGN(start_code, ARCH_FLAT_ALIGN) != start_code);
46089 +#endif
46090         end_code = textpos + text_len;
46091         if (id == 0) {
46092                 current->mm->start_code = start_code;
46093 @@ -796,6 +818,13 @@ static int load_flat_file(struct linux_b
46094  
46095         return 0;
46096  err:
46097 +       if (flush_happened) {
46098 +               /*
46099 +                * The parent process has already started running. We cannot allow the child to return back to user space
46100 +                * as this child is still uning the parent stack and 2 will clobber each other. We are going to kill this child.
46101 +                */
46102 +               do_exit(SIGTERM);
46103 +       }
46104         return ret;
46105  }
46106  
46107 --- a/fs/Kconfig.binfmt
46108 +++ b/fs/Kconfig.binfmt
46109 @@ -30,7 +30,7 @@ config COMPAT_BINFMT_ELF
46110  config BINFMT_ELF_FDPIC
46111         bool "Kernel support for FDPIC ELF binaries"
46112         default y
46113 -       depends on (FRV || BLACKFIN || (SUPERH32 && !MMU))
46114 +       depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || UBICOM32)
46115         help
46116           ELF FDPIC binaries are based on ELF, but allow the individual load
46117           segments of a binary to be located in memory independently of each
46118 --- a/include/asm-generic/dma-mapping.h
46119 +++ b/include/asm-generic/dma-mapping.h
46120 @@ -255,7 +255,7 @@ dma_sync_sg_for_device(struct device *de
46121  }
46122  
46123  static inline int
46124 -dma_error(dma_addr_t dma_addr)
46125 +dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
46126  {
46127         return 0;
46128  }
46129 --- a/include/linux/elf-em.h
46130 +++ b/include/linux/elf-em.h
46131 @@ -41,6 +41,7 @@
46132   * up with a final number.
46133   */
46134  #define EM_ALPHA       0x9026
46135 +#define EM_UBICOM32            0xde3d  /* Ubicom32; no ABI */
46136  
46137  /* Bogus old v850 magic number, used by old tools. */
46138  #define EM_CYGNUS_V850 0x9080
46139 --- a/include/linux/oprofile.h
46140 +++ b/include/linux/oprofile.h
46141 @@ -100,6 +100,8 @@ void oprofile_add_sample(struct pt_regs 
46142   */
46143  void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
46144                                 unsigned long event, int is_kernel);
46145 +void oprofile_add_ext_sample_cpu(unsigned long pc, struct pt_regs * const regs,
46146 +                               unsigned long event, int is_kernel, int cpu);
46147  
46148  /* Use this instead when the PC value is not from the regs. Doesn't
46149   * backtrace. */
46150 --- a/include/linux/serial_core.h
46151 +++ b/include/linux/serial_core.h
46152 @@ -158,6 +158,9 @@
46153  /* SH-SCI */
46154  #define PORT_SCIFA     83
46155  
46156 +/* Ubicom32 */
46157 +#define PORT_UBI32_UARTTIO     84
46158 +
46159  #ifdef __KERNEL__
46160  
46161  #include <linux/compiler.h>
46162 --- a/kernel/module.c
46163 +++ b/kernel/module.c
46164 @@ -2624,6 +2624,9 @@ static int m_show(struct seq_file *m, vo
46165         /* Used by oprofile and other similar tools. */
46166         seq_printf(m, " 0x%p", mod->module_core);
46167  
46168 +#ifdef ARCH_PROC_MODULES_EXTRA
46169 +       ARCH_PROC_MODULES_EXTRA(m, mod);
46170 +#endif
46171         /* Taints info */
46172         if (mod->taints)
46173                 seq_printf(m, " %s", module_flags(mod, buf));
46174 --- a/kernel/sched_clock.c
46175 +++ b/kernel/sched_clock.c
46176 @@ -37,7 +37,7 @@
46177   */
46178  unsigned long long __attribute__((weak)) sched_clock(void)
46179  {
46180 -       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
46181 +       return (get_jiffies_64() - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
46182  }
46183  
46184  static __read_mostly int sched_clock_running;
46185 --- a/lib/Kconfig.debug
46186 +++ b/lib/Kconfig.debug
46187 @@ -549,7 +549,7 @@ config FRAME_POINTER
46188         bool "Compile the kernel with frame pointers"
46189         depends on DEBUG_KERNEL && \
46190                 (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || \
46191 -                AVR32 || SUPERH || BLACKFIN || MN10300)
46192 +                AVR32 || SUPERH || BLACKFIN || MN10300 || UBICOM32)
46193         default y if DEBUG_INFO && UML
46194         help
46195           If you say Y here the resulting kernel image will be slightly larger
46196 --- a/mm/Makefile
46197 +++ b/mm/Makefile
46198 @@ -34,3 +34,5 @@ obj-$(CONFIG_MIGRATION) += migrate.o
46199  obj-$(CONFIG_SMP) += allocpercpu.o
46200  obj-$(CONFIG_QUICKLIST) += quicklist.o
46201  obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
46202 +
46203 +CFLAGS_slab.o := $(PROFILING) -O2
46204 --- a/scripts/mod/file2alias.c
46205 +++ b/scripts/mod/file2alias.c
46206 @@ -753,6 +753,15 @@ void handle_moddevtable(struct module *m
46207                         + sym->st_value;
46208         }
46209  
46210 +       /*
46211 +        * somehow our gcc is not generating st_size correctly and set 0 for some symbols.
46212 +        * and 0 size will break do_table since it adjust size to (size - id_size)
46213 +        * this is to make sure st_size fall in range.
46214 +        */
46215 +       if (sym->st_size == 0 || sym->st_size > info->sechdrs[sym->st_shndx].sh_size) {
46216 +               sym->st_size = info->sechdrs[sym->st_shndx].sh_size;
46217 +       }
46218 +
46219         if (sym_is(symname, "__mod_pci_device_table"))
46220                 do_table(symval, sym->st_size,
46221                          sizeof(struct pci_device_id), "pci",
46222 --- a/sound/Kconfig
46223 +++ b/sound/Kconfig
46224 @@ -80,6 +80,8 @@ source "sound/parisc/Kconfig"
46225  
46226  source "sound/soc/Kconfig"
46227  
46228 +source "sound/ubicom32/Kconfig"
46229 +
46230  endif # SND
46231  
46232  menuconfig SOUND_PRIME
46233 --- a/sound/Makefile
46234 +++ b/sound/Makefile
46235 @@ -6,7 +6,7 @@ obj-$(CONFIG_SOUND_PRIME) += sound_firmw
46236  obj-$(CONFIG_SOUND_PRIME) += oss/
46237  obj-$(CONFIG_DMASOUND) += oss/
46238  obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
46239 -       sparc/ spi/ parisc/ pcmcia/ mips/ soc/
46240 +       sparc/ spi/ parisc/ pcmcia/ mips/ soc/ ubicom32/
46241  obj-$(CONFIG_SND_AOA) += aoa/
46242  
46243  # This one must be compilable even if sound is configured out
46244 --- /dev/null
46245 +++ b/sound/ubicom32/Kconfig
46246 @@ -0,0 +1,36 @@
46247 +# ALSA Ubicom32 drivers
46248 +
46249 +menuconfig SND_UBI32
46250 +       tristate "Ubicom32 sound devices"
46251 +       select SND_PCM
46252 +       default n
46253 +       help
46254 +         Say Y here to include support for audio on the Ubicom32 platform.
46255 +         To compile this driver as a module, say M here: the module will be
46256 +         called snd_ubi32.
46257 +         
46258 +if SND_UBI32
46259 +
46260 +config SND_UBI32_AUDIO_GENERIC
46261 +       bool "Generic Codec Support"
46262 +       default n
46263 +       help
46264 +         Generic codecs
46265 +
46266 +comment "I2C Based Codecs"
46267 +
46268 +config SND_UBI32_AUDIO_CS4350
46269 +       bool "Cirrus Logic CS4350 DAC"
46270 +       depends on I2C
46271 +       default n
46272 +       help
46273 +         Support for the Cirrus Logic CS4350 DAC.
46274 +
46275 +config SND_UBI32_AUDIO_CS4384
46276 +       bool "Cirrus Logic CS4384 DAC"
46277 +       depends on I2C
46278 +       default n
46279 +       help
46280 +         Support for the Cirrus Logic CS4384 DAC.
46281 +
46282 +endif #SND_UBI32
46283 --- /dev/null
46284 +++ b/sound/ubicom32/Makefile
46285 @@ -0,0 +1,39 @@
46286 +#
46287 +# sound/ubicom32/Makefile
46288 +#      Makefile for ALSA
46289 +#
46290 +# (C) Copyright 2009, Ubicom, Inc.
46291 +#
46292 +# This file is part of the Ubicom32 Linux Kernel Port.
46293 +#
46294 +# The Ubicom32 Linux Kernel Port is free software: you can redistribute
46295 +# it and/or modify it under the terms of the GNU General Public License
46296 +# as published by the Free Software Foundation, either version 2 of the
46297 +# License, or (at your option) any later version.
46298 +#
46299 +# The Ubicom32 Linux Kernel Port is distributed in the hope that it
46300 +# will be useful, but WITHOUT ANY WARRANTY; without even the implied
46301 +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46302 +# the GNU General Public License for more details.
46303 +#
46304 +# You should have received a copy of the GNU General Public License
46305 +# along with the Ubicom32 Linux Kernel Port.  If not, 
46306 +# see <http://www.gnu.org/licenses/>.
46307 +#
46308 +# Ubicom32 implementation derived from (with many thanks):
46309 +#   arch/m68knommu
46310 +#   arch/blackfin
46311 +#   arch/parisc
46312 +#
46313 +
46314 +CFLAGS_ubi32.o += -O2
46315 +snd-ubi32-pcm-objs := ubi32-pcm.o
46316 +snd-ubi32-generic-objs := ubi32-generic.o
46317 +snd-ubi32-cs4350-objs := ubi32-cs4350.o
46318 +snd-ubi32-cs4384-objs := ubi32-cs4384.o
46319 +
46320 +# Toplevel Module Dependency
46321 +obj-$(CONFIG_SND_UBI32) += snd-ubi32-pcm.o
46322 +obj-$(CONFIG_SND_UBI32_AUDIO_GENERIC) += snd-ubi32-generic.o
46323 +obj-$(CONFIG_SND_UBI32_AUDIO_CS4350) += snd-ubi32-cs4350.o
46324 +obj-$(CONFIG_SND_UBI32_AUDIO_CS4384) += snd-ubi32-cs4384.o
46325 --- /dev/null
46326 +++ b/sound/ubicom32/ubi32-cs4350.c
46327 @@ -0,0 +1,286 @@
46328 +/*
46329 + * sound/ubicom32/ubi32-cs4350.c
46330 + *     Interface to ubicom32 virtual audio peripheral - using CS4350 DAC
46331 + *
46332 + * (C) Copyright 2009, Ubicom, Inc.
46333 + *
46334 + * This file is part of the Ubicom32 Linux Kernel Port.
46335 + *
46336 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
46337 + * it and/or modify it under the terms of the GNU General Public License
46338 + * as published by the Free Software Foundation, either version 2 of the
46339 + * License, or (at your option) any later version.
46340 + *
46341 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
46342 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
46343 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46344 + * the GNU General Public License for more details.
46345 + *
46346 + * You should have received a copy of the GNU General Public License
46347 + * along with the Ubicom32 Linux Kernel Port.  If not,
46348 + * see <http://www.gnu.org/licenses/>.
46349 + */
46350 +
46351 +#include <linux/i2c.h>
46352 +#include <linux/module.h>
46353 +#include <linux/moduleparam.h>
46354 +#include <sound/core.h>
46355 +#include <sound/pcm.h>
46356 +#include <sound/initval.h>
46357 +#include "ubi32.h"
46358 +
46359 +#define DRIVER_NAME "snd-ubi32-cs4350"
46360 +
46361 +/*
46362 + * Module properties
46363 + */
46364 +static const struct i2c_device_id snd_ubi32_cs4350_id[] = {
46365 +       {"cs4350", 0 },
46366 +       { }
46367 +};
46368 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46369 +
46370 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46371 +
46372 +/*
46373 + * snd_ubi32_cs4350_free
46374 + *     Card private data free function
46375 + */
46376 +void snd_ubi32_cs4350_free(struct snd_card *card)
46377 +{
46378 +       //struct ubi32_snd_priv *ubi32_priv = card->private_data;
46379 +
46380 +       /*
46381 +        * Free all the fields in the snd_ubi32_priv struct
46382 +        */
46383 +       // Nothing to free at this time because ubi32_priv just maintains pointers
46384 +}
46385 +
46386 +/*
46387 + * snd_ubi32_cs4350_dac_init
46388 + */
46389 +static int snd_ubi32_cs4350_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
46390 +{
46391 +       int ret;
46392 +       char send[2];
46393 +       char recv[8];
46394 +
46395 +       /*
46396 +        * Initialize the CS4350 DAC over the I2C interface
46397 +        */
46398 +       snd_printk(KERN_INFO "Initializing CS4350 DAC\n");
46399 +
46400 +       /*
46401 +        * Register 0x01: device/revid
46402 +        */
46403 +       send[0] = 0x01;
46404 +       ret = i2c_master_send(client, send, 1);
46405 +       if (ret != 1) {
46406 +               snd_printk(KERN_ERR "Failed 1st attempt to write to CS4350 register 0x01\n");
46407 +               goto fail;
46408 +       }
46409 +       ret = i2c_master_recv(client, recv, 1);
46410 +       if (ret != 1) {
46411 +               snd_printk(KERN_ERR "Failed initial read of CS4350 registers\n");
46412 +               goto fail;
46413 +       }
46414 +       snd_printk(KERN_INFO "CS4350 DAC Device/Rev: %08x\n", recv[0]);
46415 +
46416 +       /*
46417 +        * Register 0x02: Mode control
46418 +        *      I2S DIF[2:0] = 001, no De-Emphasis, Auto speed mode
46419 +        */
46420 +       send[0] = 0x02;
46421 +       send[1] = 0x10;
46422 +       ret = i2c_master_send(client, send, 2);
46423 +       if (ret != 2) {
46424 +               snd_printk(KERN_ERR "Failed to set CS4350 to I2S mode\n");
46425 +               goto fail;
46426 +       }
46427 +
46428 +       /*
46429 +        * Register 0x05/0x06: Volume control
46430 +        *      Channel A volume set to -16 dB
46431 +        *      Channel B volume set to -16 dB
46432 +        */
46433 +       send[0] = 0x05;
46434 +       send[1] = 0x00;
46435 +       ret = i2c_master_send(client, send, 2);
46436 +       if (ret != 2) {
46437 +               snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46438 +               goto fail;
46439 +       }
46440 +
46441 +       send[0] = 0x06;
46442 +       send[1] = 0x00;
46443 +       ret = i2c_master_send(client, send, 2);
46444 +       if (ret != 2) {
46445 +               snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46446 +               goto fail;
46447 +       }
46448 +
46449 +       /*
46450 +        * Make sure the changes took place, this helps verify we are talking to
46451 +        * the correct chip.
46452 +        */
46453 +       send[0] = 0x81;
46454 +       ret = i2c_master_send(client, send, 1);
46455 +       if (ret != 1) {
46456 +               snd_printk(KERN_ERR "Failed to initiate readback\n");
46457 +               goto fail;
46458 +       }
46459 +
46460 +       ret = i2c_master_recv(client, recv, 8);
46461 +       if (ret != 8) {
46462 +               snd_printk(KERN_ERR "Failed second read of CS4350 registers\n");
46463 +               goto fail;
46464 +       }
46465 +
46466 +       if ((recv[1] != 0x10) || (recv[4] != 0x00) || (recv[5] != 0x00)) {
46467 +               snd_printk(KERN_ERR "Failed to initialize CS4350 DAC\n");
46468 +               goto fail;
46469 +       }
46470 +                      
46471 +       snd_printk(KERN_INFO "CS4350 DAC Initialized\n");
46472 +       return 0;
46473 +
46474 +fail:
46475 +       return -ENODEV;
46476 +}
46477 +
46478 +/*
46479 + * snd_ubi32_cs4350_i2c_probe
46480 + */
46481 +static int snd_ubi32_cs4350_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
46482 +{
46483 +       struct snd_card *card;
46484 +       struct ubi32_snd_priv *ubi32_priv;
46485 +       int err, ret;
46486 +       struct platform_device *pdev;
46487 +
46488 +       pdev = client->dev.platform_data;
46489 +       if (!pdev) {
46490 +               return -ENODEV;
46491 +       }
46492 +
46493 +       /*
46494 +        * Initialize the CS4350 DAC
46495 +        */
46496 +       ret = snd_ubi32_cs4350_dac_init(client, id);
46497 +       if (ret < 0) {
46498 +               /*
46499 +                * Initialization failed.  Propagate the error.
46500 +                */
46501 +               return ret;
46502 +       }
46503 +
46504 +       /*
46505 +        * Create a snd_card structure
46506 +        */
46507 +       card = snd_card_new(index, "Ubi32-CS4350", THIS_MODULE, sizeof(struct ubi32_snd_priv));
46508 +       if (card == NULL) {
46509 +               return -ENOMEM;
46510 +       }
46511 +
46512 +       card->private_free = snd_ubi32_cs4350_free; /* Not sure if correct */
46513 +       ubi32_priv = card->private_data;
46514 +
46515 +       /*
46516 +        * CS4350 DAC has a minimum sample rate of 30khz and an
46517 +        * upper limit of 216khz for it's auto-detect.
46518 +        */
46519 +       ubi32_priv->min_sample_rate = 30000;
46520 +       ubi32_priv->max_sample_rate = 216000;
46521 +
46522 +       /*
46523 +        * Initialize the snd_card's private data structure
46524 +        */
46525 +       ubi32_priv->card = card;
46526 +
46527 +       /*
46528 +        * Create the new PCM instance
46529 +        */
46530 +       err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
46531 +       if (err < 0) {
46532 +               snd_card_free(card);
46533 +               return err; /* What is err?  Need to include correct file */
46534 +       }
46535 +
46536 +       strcpy(card->driver, "Ubi32-CS4350");
46537 +       strcpy(card->shortname, "Ubi32-CS4350");
46538 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
46539 +
46540 +       snd_card_set_dev(card, &client->dev);
46541 +
46542 +       /*
46543 +        * Register the sound card 
46544 +        */
46545 +       if ((err = snd_card_register(card)) != 0) {
46546 +               snd_printk(KERN_INFO "snd_card_register error\n");
46547 +       }
46548 +
46549 +       /* 
46550 +        * Store card for access from other methods 
46551 +        */
46552 +       i2c_set_clientdata(client, card);
46553 +
46554 +       return 0;
46555 +}
46556 +
46557 +/*
46558 + * snd_ubi32_cs4350_i2c_remove
46559 + */
46560 +static int __devexit snd_ubi32_cs4350_i2c_remove(struct i2c_client *client)
46561 +{
46562 +       struct snd_card *card;
46563 +       struct ubi32_snd_priv *ubi32_priv;
46564 +
46565 +       card = i2c_get_clientdata(client);
46566 +
46567 +       ubi32_priv = card->private_data;
46568 +       snd_ubi32_pcm_remove(ubi32_priv);
46569 +
46570 +       snd_card_free(i2c_get_clientdata(client));
46571 +       i2c_set_clientdata(client, NULL);
46572 +
46573 +       return 0;
46574 +}
46575 +
46576 +/*
46577 + * I2C driver description
46578 + */
46579 +static struct i2c_driver snd_ubi32_cs4350_driver = {
46580 +       .driver = {
46581 +               .name = DRIVER_NAME,
46582 +               .owner = THIS_MODULE,
46583 +       },
46584 +       .id_table       = snd_ubi32_cs4350_id,
46585 +       .probe          = snd_ubi32_cs4350_i2c_probe,
46586 +       .remove         = __devexit_p(snd_ubi32_cs4350_i2c_remove),
46587 +};
46588 +
46589 +/*
46590 + * Driver init
46591 + */
46592 +static int __init snd_ubi32_cs4350_init(void)
46593 +{
46594 +       return i2c_add_driver(&snd_ubi32_cs4350_driver);
46595 +}
46596 +module_init(snd_ubi32_cs4350_init);
46597 +
46598 +/*
46599 + * snd_ubi32_cs4350_exit
46600 + */
46601 +static void __exit snd_ubi32_cs4350_exit(void)
46602 +{
46603 +       i2c_del_driver(&snd_ubi32_cs4350_driver);
46604 +}
46605 +module_exit(snd_ubi32_cs4350_exit);
46606 +
46607 +/*
46608 + * Module properties
46609 + */
46610 +MODULE_ALIAS("i2c:" DRIVER_NAME);
46611 +MODULE_AUTHOR("Patrick Tjin");
46612 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4350");
46613 +MODULE_LICENSE("GPL");
46614 --- /dev/null
46615 +++ b/sound/ubicom32/ubi32-cs4384.c
46616 @@ -0,0 +1,982 @@
46617 +/*
46618 + * sound/ubicom32/ubi32-cs4384.c
46619 + *     Interface to ubicom32 virtual audio peripheral - using CS4384 DAC
46620 + *
46621 + * (C) Copyright 2009, Ubicom, Inc.
46622 + *
46623 + * This file is part of the Ubicom32 Linux Kernel Port.
46624 + *
46625 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
46626 + * it and/or modify it under the terms of the GNU General Public License
46627 + * as published by the Free Software Foundation, either version 2 of the
46628 + * License, or (at your option) any later version.
46629 + *
46630 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
46631 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
46632 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
46633 + * the GNU General Public License for more details.
46634 + *
46635 + * You should have received a copy of the GNU General Public License
46636 + * along with the Ubicom32 Linux Kernel Port.  If not,
46637 + * see <http://www.gnu.org/licenses/>.
46638 + */
46639 +
46640 +#include <linux/i2c.h>
46641 +#include <linux/module.h>
46642 +#include <linux/moduleparam.h>
46643 +#include <linux/delay.h>
46644 +#include <sound/core.h>
46645 +#include <sound/tlv.h>
46646 +#include <sound/control.h>
46647 +#include <sound/pcm.h>
46648 +#include <sound/initval.h>
46649 +#include <asm/ip5000.h>
46650 +#include <asm/gpio.h>
46651 +#include <asm/audio_tio.h>
46652 +#include <asm/ubi32-cs4384.h>
46653 +#include "ubi32.h"
46654 +
46655 +#define DRIVER_NAME "snd-ubi32-cs4384"
46656 +
46657 +/*
46658 + * Module properties
46659 + */
46660 +static const struct i2c_device_id snd_ubi32_cs4384_id[] = {
46661 +       {"cs4384", 0 },
46662 +       { }
46663 +};
46664 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46665 +
46666 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46667 +
46668 +/*
46669 + * Mixer properties
46670 + */
46671 +enum {
46672 +       /*
46673 +        * Be careful of changing the order of these IDs, they
46674 +        * are used to index the volume array.
46675 +        */
46676 +       SND_UBI32_CS4384_FRONT_ID,
46677 +       SND_UBI32_CS4384_SURROUND_ID,
46678 +       SND_UBI32_CS4384_CENTER_ID,
46679 +       SND_UBI32_CS4384_LFE_ID,
46680 +       SND_UBI32_CS4384_REAR_ID,
46681 +
46682 +       /*
46683 +        * This should be the last ID
46684 +        */
46685 +       SND_UBI32_CS4384_LAST_ID,
46686 +};
46687 +static const u8_t snd_ubi32_cs4384_ch_ofs[] = {0, 2, 4, 5, 6};
46688 +
46689 +static const DECLARE_TLV_DB_SCALE(snd_ubi32_cs4384_db, -12750, 50, 0);
46690 +
46691 +#define snd_ubi32_cs4384_info_mute     snd_ctl_boolean_stereo_info
46692 +#define snd_ubi32_cs4384_info_mute_mono        snd_ctl_boolean_mono_info
46693 +
46694 +/*
46695 + * Mixer controls
46696 + */
46697 +static int snd_ubi32_cs4384_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
46698 +static int snd_ubi32_cs4384_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46699 +static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46700 +static int snd_ubi32_cs4384_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46701 +static int snd_ubi32_cs4384_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
46702 +
46703 +/*
46704 + * Make sure to update these if the structure below is changed
46705 + */
46706 +#define SND_UBI32_MUTE_CTL_START       5
46707 +#define SND_UBI32_MUTE_CTL_END         9
46708 +static struct snd_kcontrol_new snd_ubi32_cs4384_controls[] __devinitdata = {
46709 +       {
46710 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46711 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46712 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46713 +               .name = "Front Playback Volume",
46714 +               .info = snd_ubi32_cs4384_info_volume,
46715 +               .get = snd_ubi32_cs4384_get_volume,
46716 +               .put = snd_ubi32_cs4384_put_volume,
46717 +               .private_value = SND_UBI32_CS4384_FRONT_ID,
46718 +               .tlv = {
46719 +                       .p = snd_ubi32_cs4384_db,
46720 +               },
46721 +       },
46722 +       {
46723 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46724 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46725 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46726 +               .name = "Surround Playback Volume",
46727 +               .info = snd_ubi32_cs4384_info_volume,
46728 +               .get = snd_ubi32_cs4384_get_volume,
46729 +               .put = snd_ubi32_cs4384_put_volume,
46730 +               .private_value = SND_UBI32_CS4384_SURROUND_ID,
46731 +               .tlv = {
46732 +                       .p = snd_ubi32_cs4384_db,
46733 +               },
46734 +       },
46735 +       {
46736 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46737 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46738 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46739 +               .name = "Center Playback Volume",
46740 +               .info = snd_ubi32_cs4384_info_volume,
46741 +               .get = snd_ubi32_cs4384_get_volume,
46742 +               .put = snd_ubi32_cs4384_put_volume,
46743 +               .private_value = SND_UBI32_CS4384_CENTER_ID,
46744 +               .tlv = {
46745 +                       .p = snd_ubi32_cs4384_db,
46746 +               },
46747 +       },
46748 +       {
46749 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46750 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46751 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46752 +               .name = "LFE Playback Volume",
46753 +               .info = snd_ubi32_cs4384_info_volume,
46754 +               .get = snd_ubi32_cs4384_get_volume,
46755 +               .put = snd_ubi32_cs4384_put_volume,
46756 +               .private_value = SND_UBI32_CS4384_LFE_ID,
46757 +               .tlv = {
46758 +                       .p = snd_ubi32_cs4384_db,
46759 +               },
46760 +       },
46761 +       {
46762 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46763 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46764 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46765 +               .name = "Rear Playback Volume",
46766 +               .info = snd_ubi32_cs4384_info_volume,
46767 +               .get = snd_ubi32_cs4384_get_volume,
46768 +               .put = snd_ubi32_cs4384_put_volume,
46769 +               .private_value = SND_UBI32_CS4384_REAR_ID,
46770 +               .tlv = {
46771 +                       .p = snd_ubi32_cs4384_db,
46772 +               },
46773 +       },
46774 +       {
46775 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46776 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46777 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46778 +               .name = "Front Playback Switch",
46779 +               .info = snd_ubi32_cs4384_info_mute,
46780 +               .get = snd_ubi32_cs4384_get_mute,
46781 +               .put = snd_ubi32_cs4384_put_mute,
46782 +               .private_value = SND_UBI32_CS4384_FRONT_ID,
46783 +       },
46784 +       {
46785 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46786 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46787 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46788 +               .name = "Surround Playback Switch",
46789 +               .info = snd_ubi32_cs4384_info_mute,
46790 +               .get = snd_ubi32_cs4384_get_mute,
46791 +               .put = snd_ubi32_cs4384_put_mute,
46792 +               .private_value = SND_UBI32_CS4384_SURROUND_ID,
46793 +       },
46794 +       {
46795 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46796 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46797 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46798 +               .name = "Center Playback Switch",
46799 +               .info = snd_ubi32_cs4384_info_mute_mono,
46800 +               .get = snd_ubi32_cs4384_get_mute,
46801 +               .put = snd_ubi32_cs4384_put_mute,
46802 +               .private_value = SND_UBI32_CS4384_CENTER_ID,
46803 +       },
46804 +       {
46805 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46806 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46807 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46808 +               .name = "LFE Playback Switch",
46809 +               .info = snd_ubi32_cs4384_info_mute_mono,
46810 +               .get = snd_ubi32_cs4384_get_mute,
46811 +               .put = snd_ubi32_cs4384_put_mute,
46812 +               .private_value = SND_UBI32_CS4384_LFE_ID,
46813 +       },
46814 +       {
46815 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
46816 +               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
46817 +                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
46818 +               .name = "Rear Playback Switch",
46819 +               .info = snd_ubi32_cs4384_info_mute,
46820 +               .get = snd_ubi32_cs4384_get_mute,
46821 +               .put = snd_ubi32_cs4384_put_mute,
46822 +               .private_value = SND_UBI32_CS4384_REAR_ID,
46823 +       },
46824 +};
46825 +
46826 +/*
46827 + * Our private data
46828 + */
46829 +struct snd_ubi32_cs4384_priv {
46830 +       /*
46831 +        * Array of current volumes
46832 +        *      (L, R, SL, SR, C, LFE, RL, RR)
46833 +        */
46834 +       uint8_t volume[8];
46835 +
46836 +       /*
46837 +        * Bitmask of mutes
46838 +        *      MSB (RR, RL, LFE, C, SR, SL, R, L) LSB
46839 +        */
46840 +       uint8_t mute;
46841 +
46842 +       /*
46843 +        * Array of controls
46844 +        */
46845 +       struct snd_kcontrol *kctls[ARRAY_SIZE(snd_ubi32_cs4384_controls)];
46846 +
46847 +       /*
46848 +        * Lock to protect our card
46849 +        */
46850 +       spinlock_t lock;
46851 +};
46852 +
46853 +/*
46854 + * snd_ubi32_cs4384_info_volume
46855 + */
46856 +static int snd_ubi32_cs4384_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
46857 +{
46858 +       unsigned int id = (unsigned int)kcontrol->private_value;
46859 +
46860 +       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
46861 +       uinfo->count = 1;
46862 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
46863 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
46864 +               uinfo->count = 2;
46865 +       }
46866 +       uinfo->value.integer.min = 0;
46867 +       uinfo->value.integer.max = 255;
46868 +       return 0;
46869 +}
46870 +
46871 +/*
46872 + * snd_ubi32_cs4384_get_volume
46873 + */
46874 +static int snd_ubi32_cs4384_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46875 +{
46876 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46877 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46878 +       unsigned int id = (unsigned int)kcontrol->private_value;
46879 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46880 +       unsigned long flags;
46881 +
46882 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46883 +               return -EINVAL;
46884 +       }
46885 +
46886 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46887 +
46888 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46889 +
46890 +       ucontrol->value.integer.value[0] = cs4384_priv->volume[ch];
46891 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
46892 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
46893 +               ch++;
46894 +               ucontrol->value.integer.value[1] = cs4384_priv->volume[ch];
46895 +       }
46896 +
46897 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46898 +
46899 +       return 0;
46900 +}
46901 +
46902 +/*
46903 + * snd_ubi32_cs4384_put_volume
46904 + */
46905 +static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46906 +{
46907 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46908 +       struct i2c_client *client = (struct i2c_client *)priv->client;
46909 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46910 +       unsigned int id = (unsigned int)kcontrol->private_value;
46911 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46912 +       unsigned long flags;
46913 +       unsigned char send[3];
46914 +       int nch;
46915 +       int ret = -EINVAL;
46916 +
46917 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46918 +               return -EINVAL;
46919 +       }
46920 +
46921 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
46922 +
46923 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
46924 +
46925 +       send[0] = 0;
46926 +       switch (id) {
46927 +       case SND_UBI32_CS4384_REAR_ID:
46928 +               send[0] = 0x06;
46929 +
46930 +               /*
46931 +                * Fall through
46932 +                */
46933 +
46934 +       case SND_UBI32_CS4384_SURROUND_ID:
46935 +               send[0] += 0x03;
46936 +
46937 +               /*
46938 +                * Fall through
46939 +                */
46940 +
46941 +       case SND_UBI32_CS4384_FRONT_ID:
46942 +               send[0] += 0x8B;
46943 +               nch = 2;
46944 +               send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF);
46945 +               send[2] = 255 - (ucontrol->value.integer.value[1] & 0xFF);
46946 +               cs4384_priv->volume[ch++] = send[1];
46947 +               cs4384_priv->volume[ch] = send[2];
46948 +               break;
46949 +
46950 +       case SND_UBI32_CS4384_LFE_ID:
46951 +               send[0] = 0x81;
46952 +
46953 +               /*
46954 +                * Fall through
46955 +                */
46956 +
46957 +       case SND_UBI32_CS4384_CENTER_ID:
46958 +               send[0] += 0x11;
46959 +               nch = 1;
46960 +               send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF);
46961 +               cs4384_priv->volume[ch] = send[1];
46962 +               break;
46963 +
46964 +       default:
46965 +               spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46966 +               goto done;
46967 +
46968 +       }
46969 +
46970 +       /*
46971 +        * Send the volume to the chip
46972 +        */
46973 +       nch++;
46974 +       ret = i2c_master_send(client, send, nch);
46975 +       if (ret != nch) {
46976 +               snd_printk(KERN_ERR "Failed to set volume on CS4384\n");
46977 +       }
46978 +
46979 +done:
46980 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46981 +
46982 +       return ret;
46983 +}
46984 +
46985 +/*
46986 + * snd_ubi32_cs4384_get_mute
46987 + */
46988 +static int snd_ubi32_cs4384_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
46989 +{
46990 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
46991 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
46992 +       unsigned int id = (unsigned int)kcontrol->private_value;
46993 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
46994 +       unsigned long flags;
46995 +
46996 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
46997 +               return -EINVAL;
46998 +       }
46999 +
47000 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
47001 +
47002 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
47003 +
47004 +       ucontrol->value.integer.value[0] = !(cs4384_priv->mute & (1 << ch));
47005 +
47006 +       if ((id != SND_UBI32_CS4384_LFE_ID) && 
47007 +           (id != SND_UBI32_CS4384_CENTER_ID)) {
47008 +               ch++;
47009 +               ucontrol->value.integer.value[1] = !(cs4384_priv->mute & (1 << ch));
47010 +       }
47011 +
47012 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47013 +
47014 +       return 0;
47015 +}
47016 +
47017 +/*
47018 + * snd_ubi32_cs4384_put_mute
47019 + */
47020 +static int snd_ubi32_cs4384_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
47021 +{
47022 +       struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol);
47023 +       struct i2c_client *client = (struct i2c_client *)priv->client;
47024 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47025 +       unsigned int id = (unsigned int)kcontrol->private_value;
47026 +       int ch = snd_ubi32_cs4384_ch_ofs[id];
47027 +       unsigned long flags;
47028 +       unsigned char send[2];
47029 +       int ret = -EINVAL;
47030 +
47031 +       if (id >= SND_UBI32_CS4384_LAST_ID) {
47032 +               return -EINVAL;
47033 +       }
47034 +
47035 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
47036 +
47037 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
47038 +
47039 +       if (ucontrol->value.integer.value[0]) {
47040 +               cs4384_priv->mute &= ~(1 << ch);
47041 +       } else {
47042 +               cs4384_priv->mute |= (1 << ch);
47043 +       }
47044 +
47045 +       if ((id != SND_UBI32_CS4384_LFE_ID) && (id != SND_UBI32_CS4384_CENTER_ID)) {
47046 +               ch++;
47047 +               if (ucontrol->value.integer.value[1]) {
47048 +                       cs4384_priv->mute &= ~(1 << ch);
47049 +               } else {
47050 +                       cs4384_priv->mute |= (1 << ch);
47051 +               }
47052 +       }
47053 +
47054 +       /*
47055 +        * Update the chip's mute reigster
47056 +        */
47057 +       send[0] = 0x09;
47058 +       send[1] = cs4384_priv->mute;
47059 +       ret = i2c_master_send(client, send, 2);
47060 +       if (ret != 2) {
47061 +               snd_printk(KERN_ERR "Failed to set mute on CS4384\n");
47062 +       }
47063 +
47064 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47065 +
47066 +       return ret;
47067 +}
47068 +
47069 +/*
47070 + * snd_ubi32_cs4384_mixer
47071 + *     Setup the mixer controls
47072 + */
47073 +static int __devinit snd_ubi32_cs4384_mixer(struct ubi32_snd_priv *priv)
47074 +{
47075 +       struct snd_card *card = priv->card;
47076 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47077 +       int i;
47078 +       
47079 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
47080 +       for (i = 0; i < ARRAY_SIZE(snd_ubi32_cs4384_controls); i++) {
47081 +               int err;
47082 +
47083 +               cs4384_priv->kctls[i] = snd_ctl_new1(&snd_ubi32_cs4384_controls[i], priv);
47084 +               err = snd_ctl_add(card, cs4384_priv->kctls[i]);
47085 +               if (err) {
47086 +                       snd_printk(KERN_WARNING "Failed to add control %d\n", i);
47087 +                       return err;
47088 +               }
47089 +       }
47090 +       return 0;
47091 +}
47092 +
47093 +/*
47094 + * snd_ubi32_cs4384_free
47095 + *     Card private data free function
47096 + */
47097 +void snd_ubi32_cs4384_free(struct snd_card *card)
47098 +{
47099 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47100 +       struct ubi32_snd_priv *ubi32_priv;
47101 +       
47102 +       ubi32_priv = card->private_data;
47103 +       cs4384_priv = snd_ubi32_priv_get_drv(ubi32_priv);
47104 +       if (cs4384_priv) {
47105 +               kfree(cs4384_priv);
47106 +       }
47107 +}
47108 +
47109 +/*
47110 + * snd_ubi32_cs4384_setup_mclk
47111 + */
47112 +static int snd_ubi32_cs4384_setup_mclk(struct ubi32_cs4384_platform_data *pdata)
47113 +{
47114 +       struct ubicom32_io_port *ioa = (struct ubicom32_io_port *)RA;
47115 +       struct ubicom32_io_port *ioc = (struct ubicom32_io_port *)RC;
47116 +       struct ubicom32_io_port *ioh = (struct ubicom32_io_port *)RH;
47117 +       unsigned int ctl0;
47118 +       unsigned int ctlx;
47119 +       unsigned int div;
47120 +
47121 +       div = pdata->mclk_entries[0].div;
47122 +
47123 +       ctl0 = (1 << 13);
47124 +       ctlx = ((div - 1) << 16) | (div / 2);
47125 +
47126 +       switch (pdata->mclk_src) {
47127 +       case UBI32_CS4384_MCLK_PWM_0:
47128 +               ioc->function |= 2;
47129 +               ioc->ctl0 |= ctl0;
47130 +               ioc->ctl1 = ctlx;
47131 +               return 0;
47132 +
47133 +       case UBI32_CS4384_MCLK_PWM_1:
47134 +               ioc->function |= 2;
47135 +               ioc->ctl0 |= ctl0 << 16;
47136 +               ioc->ctl2 = ctlx;
47137 +               return 0;
47138 +
47139 +       case UBI32_CS4384_MCLK_PWM_2:
47140 +               ioh->ctl0 |= ctl0;
47141 +               ioh->ctl1 = ctlx;
47142 +               return 0;
47143 +
47144 +       case UBI32_CS4384_MCLK_CLKDIV_1:
47145 +               ioa->gpio_mask &= (1 << 7);
47146 +               ioa->ctl1 &= ~(0x7F << 14);
47147 +               ioa->ctl1 |= ((div - 1) << 14);
47148 +               return 0;
47149 +
47150 +       case UBI32_CS4384_MCLK_OTHER:
47151 +               return 0;
47152 +       }
47153 +
47154 +       return 1;
47155 +}
47156 +
47157 +/*
47158 + * snd_ubi32_cs4384_set_rate
47159 + */
47160 +static int snd_ubi32_cs4384_set_rate(struct ubi32_snd_priv *priv, int rate)
47161 +{
47162 +       struct ubi32_cs4384_platform_data *cpd = priv->pdata->priv_data;
47163 +       struct ubicom32_io_port *ioa = (struct ubicom32_io_port *)RA;
47164 +       struct ubicom32_io_port *ioc = (struct ubicom32_io_port *)RC;
47165 +       struct ubicom32_io_port *ioh = (struct ubicom32_io_port *)RH;
47166 +       unsigned int ctl;
47167 +       unsigned int div = 0;
47168 +       const u16_t mult[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024};
47169 +       int i;
47170 +       int j;
47171 +       
47172 +
47173 +       for (i = 0; i < sizeof(mult) / sizeof(u16_t); i++) {
47174 +               for (j = 0; j < cpd->n_mclk; j++) {
47175 +                       if (((unsigned int)rate * (unsigned int)mult[i]) == 
47176 +                            cpd->mclk_entries[j].rate) {
47177 +                               div = cpd->mclk_entries[j].div;
47178 +                               break;
47179 +                       }
47180 +               }
47181 +       }
47182 +
47183 +       ctl = ((div - 1) << 16) | (div / 2);
47184 +
47185 +       switch (cpd->mclk_src) {
47186 +       case UBI32_CS4384_MCLK_PWM_0:
47187 +               ioc->ctl1 = ctl;
47188 +               return 0;
47189 +
47190 +       case UBI32_CS4384_MCLK_PWM_1:
47191 +               ioc->ctl2 = ctl;
47192 +               return 0;
47193 +
47194 +       case UBI32_CS4384_MCLK_PWM_2:
47195 +               ioh->ctl1 = ctl;
47196 +               return 0;
47197 +
47198 +       case UBI32_CS4384_MCLK_CLKDIV_1:
47199 +               ioa->ctl1 &= ~(0x7F << 14);
47200 +               ioa->ctl1 |= ((div - 1) << 14);
47201 +               return 0;
47202 +
47203 +       case UBI32_CS4384_MCLK_OTHER:
47204 +               return 0;
47205 +       }
47206 +
47207 +       return 1;
47208 +}
47209 +
47210 +/*
47211 + * snd_ubi32_cs4384_set_channels
47212 + *     Mute unused channels
47213 + */
47214 +static int snd_ubi32_cs4384_set_channels(struct ubi32_snd_priv *priv, int channels)
47215 +{
47216 +       struct i2c_client *client = (struct i2c_client *)priv->client;
47217 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47218 +       unsigned char send[2];
47219 +       int ret;
47220 +       int i;
47221 +       unsigned long flags;
47222 +
47223 +       /*
47224 +        * Only support 0, 2, 4, 6, 8 channels
47225 +        */
47226 +       if ((channels > 8) || (channels & 1)) {
47227 +               return -EINVAL;
47228 +       }
47229 +
47230 +       cs4384_priv = snd_ubi32_priv_get_drv(priv);
47231 +       spin_lock_irqsave(&cs4384_priv->lock, flags);
47232 +
47233 +       /*
47234 +        * Address 09h, Mute control
47235 +        */
47236 +       send[0] = 0x09;
47237 +       send[1] = (unsigned char)(0xFF << channels);
47238 +
47239 +       ret = i2c_master_send(client, send, 2);
47240 +
47241 +       spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47242 +
47243 +       /*
47244 +        * Notify the system that we changed the mutes
47245 +        */
47246 +       cs4384_priv->mute = (unsigned char)(0xFF << channels);
47247 +
47248 +       for (i = SND_UBI32_MUTE_CTL_START; i < SND_UBI32_MUTE_CTL_END; i++) {
47249 +               snd_ctl_notify(priv->card, SNDRV_CTL_EVENT_MASK_VALUE,
47250 +                              &cs4384_priv->kctls[i]->id);
47251 +       }
47252 +
47253 +       if (ret != 2) {
47254 +               return -ENXIO;
47255 +       }
47256 +
47257 +       return 0;
47258 +}
47259 +
47260 +/*
47261 + * snd_ubi32_cs4384_dac_init
47262 + */
47263 +static int snd_ubi32_cs4384_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
47264 +{
47265 +       int ret;
47266 +       unsigned char send[2];
47267 +       unsigned char recv[2];
47268 +
47269 +       /*
47270 +        * Initialize the CS4384 DAC over the I2C interface
47271 +        */
47272 +       snd_printk(KERN_INFO "Initializing CS4384 DAC\n");
47273 +
47274 +       /*
47275 +        * Register 0x01: device/revid
47276 +        */
47277 +       send[0] = 0x01;
47278 +       ret = i2c_master_send(client, send, 1);
47279 +       if (ret != 1) {
47280 +               snd_printk(KERN_ERR "Failed 1st attempt to write to CS4384 register 0x01\n");
47281 +               goto fail;
47282 +       }
47283 +       ret = i2c_master_recv(client, recv, 1);
47284 +       if (ret != 1) {
47285 +               snd_printk(KERN_ERR "Failed initial read of CS4384 registers\n");
47286 +               goto fail;
47287 +       }
47288 +       snd_printk(KERN_INFO "CS4384 DAC Device/Rev: %08x\n", recv[0]);
47289 +
47290 +       /*
47291 +        * Register 0x02: Mode Control 1
47292 +        *      Control Port Enable, PCM, All DACs enabled, Power Down
47293 +        */
47294 +       send[0] = 0x02;
47295 +       send[1] = 0x81;
47296 +       ret = i2c_master_send(client, send, 2);
47297 +       if (ret != 2) {
47298 +               snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47299 +               goto fail;
47300 +       }
47301 +
47302 +       /*
47303 +        * Register 0x08: Ramp and Mute
47304 +        *      RMP_UP, RMP_DN, PAMUTE, DAMUTE
47305 +        */
47306 +       send[0] = 0x08;
47307 +       send[1] = 0xBC;
47308 +       ret = i2c_master_send(client, send, 2);
47309 +       if (ret != 2) {
47310 +               snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47311 +               goto fail;
47312 +       }
47313 +
47314 +       /*
47315 +        * Register 0x03: PCM Control
47316 +        *      I2S DIF[3:0] = 0001, no De-Emphasis, Auto speed mode
47317 +        */
47318 +       send[0] = 0x03;
47319 +       send[1] = 0x13;
47320 +       ret = i2c_master_send(client, send, 2);
47321 +       if (ret != 2) {
47322 +               snd_printk(KERN_ERR "Failed to set CS4384 to I2S mode\n");
47323 +               goto fail;
47324 +       }
47325 +
47326 +       /*
47327 +        * Register 0x0B/0x0C: Volume control A1/B1
47328 +        * Register 0x0E/0x0F: Volume control A2/B2
47329 +        * Register 0x11/0x12: Volume control A3/B3
47330 +        * Register 0x14/0x15: Volume control A4/B4
47331 +        */
47332 +       send[0] = 0x80 | 0x0B;
47333 +       send[1] = 0x00;
47334 +       send[2] = 0x00;
47335 +       ret = i2c_master_send(client, send, 3);
47336 +       if (ret != 3) {
47337 +               snd_printk(KERN_ERR "Failed to set ch1 volume on CS4384\n");
47338 +               goto fail;
47339 +       }
47340 +
47341 +       send[0] = 0x80 | 0x0E;
47342 +       send[1] = 0x00;
47343 +       send[2] = 0x00;
47344 +       ret = i2c_master_send(client, send, 3);
47345 +       if (ret != 3) {
47346 +               snd_printk(KERN_ERR "Failed to set ch2 volume on CS4384\n");
47347 +               goto fail;
47348 +       }
47349 +
47350 +       send[0] = 0x80 | 0x11;
47351 +       send[1] = 0x00;
47352 +       send[2] = 0x00;
47353 +       ret = i2c_master_send(client, send, 3);
47354 +       if (ret != 3) {
47355 +               snd_printk(KERN_ERR "Failed to set ch3 volume on CS4384\n");
47356 +               goto fail;
47357 +       }
47358 +
47359 +       send[0] = 0x80 | 0x14;
47360 +       send[1] = 0x00;
47361 +       send[2] = 0x00;
47362 +       ret = i2c_master_send(client, send, 3);
47363 +       if (ret != 3) {
47364 +               snd_printk(KERN_ERR "Failed to set ch4 volume on CS4384\n");
47365 +               goto fail;
47366 +       }
47367 +
47368 +       /*
47369 +        * Register 09h: Mute control
47370 +        *      Mute all (we will unmute channels as needed)
47371 +        */
47372 +       send[0] = 0x09;
47373 +       send[1] = 0xFF;
47374 +       ret = i2c_master_send(client, send, 2);
47375 +       if (ret != 2) {
47376 +               snd_printk(KERN_ERR "Failed to power up CS4384\n");
47377 +               goto fail;
47378 +       }
47379 +
47380 +       /*
47381 +        * Register 0x02: Mode Control 1
47382 +        *      Control Port Enable, PCM, All DACs enabled, Power Up
47383 +        */
47384 +       send[0] = 0x02;
47385 +       send[1] = 0x80;
47386 +       ret = i2c_master_send(client, send, 2);
47387 +       if (ret != 2) {
47388 +               snd_printk(KERN_ERR "Failed to power up CS4384\n");
47389 +               goto fail;
47390 +       }
47391 +
47392 +       /*
47393 +        * Make sure the changes took place, this helps verify we are talking to
47394 +        * the correct chip.
47395 +        */
47396 +       send[0] = 0x80 | 0x03;
47397 +       ret = i2c_master_send(client, send, 1);
47398 +       if (ret != 1) {
47399 +               snd_printk(KERN_ERR "Failed to initiate readback\n");
47400 +               goto fail;
47401 +       }
47402 +
47403 +       ret = i2c_master_recv(client, recv, 1);
47404 +       if (ret != 1) {
47405 +               snd_printk(KERN_ERR "Failed second read of CS4384 registers\n");
47406 +               goto fail;
47407 +       }
47408 +
47409 +       if (recv[0] != 0x13) {
47410 +               snd_printk(KERN_ERR "Failed to initialize CS4384 DAC\n");
47411 +               goto fail;
47412 +       }
47413 +                      
47414 +       snd_printk(KERN_INFO "CS4384 DAC Initialized\n");
47415 +       return 0;
47416 +
47417 +fail:
47418 +       return -ENODEV;
47419 +}
47420 +
47421 +/*
47422 + * snd_ubi32_cs4384_i2c_probe
47423 + */
47424 +static int snd_ubi32_cs4384_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
47425 +{
47426 +       struct snd_card *card;
47427 +       struct ubi32_snd_priv *ubi32_priv;
47428 +       int err, ret;
47429 +       struct platform_device *pdev;
47430 +       struct ubi32_cs4384_platform_data *pdata;
47431 +       struct snd_ubi32_cs4384_priv *cs4384_priv;
47432 +
47433 +       /*
47434 +        * pdev is audio_tio
47435 +        */
47436 +       pdev = client->dev.platform_data;
47437 +       if (!pdev) {
47438 +               return -ENODEV;
47439 +       }
47440 +
47441 +       /*
47442 +        * pdev->dev.platform_data is ubi32-pcm platform_data
47443 +        */
47444 +       pdata = audio_tio_priv(pdev);
47445 +       if (!pdata) {
47446 +               return -ENODEV;
47447 +       }
47448 +
47449 +       /*
47450 +        * Initialize the CS4384 DAC
47451 +        */
47452 +       ret = snd_ubi32_cs4384_dac_init(client, id);
47453 +       if (ret < 0) {
47454 +               /*
47455 +                * Initialization failed.  Propagate the error.
47456 +                */
47457 +               return ret;
47458 +       }
47459 +
47460 +       if (snd_ubi32_cs4384_setup_mclk(pdata)) {
47461 +               return -EINVAL;
47462 +       }
47463 +
47464 +       /*
47465 +        * Create a snd_card structure
47466 +        */
47467 +       card = snd_card_new(index, "Ubi32-CS4384", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47468 +       if (card == NULL) {
47469 +               return -ENOMEM;
47470 +       }
47471 +
47472 +       card->private_free = snd_ubi32_cs4384_free;
47473 +       ubi32_priv = card->private_data;
47474 +
47475 +       /*
47476 +        * Initialize the snd_card's private data structure
47477 +        */
47478 +       ubi32_priv->card = card;
47479 +       ubi32_priv->client = client;
47480 +       ubi32_priv->set_channels = snd_ubi32_cs4384_set_channels;
47481 +       ubi32_priv->set_rate = snd_ubi32_cs4384_set_rate;
47482 +
47483 +       /*
47484 +        * CS4384 DAC has a minimum sample rate of 4khz and an
47485 +        * upper limit of 216khz for it's auto-detect.
47486 +        */
47487 +       ubi32_priv->min_sample_rate = 4000;
47488 +       ubi32_priv->max_sample_rate = 216000;
47489 +
47490 +       /*
47491 +        * Create our private data (to manage volume, etc)
47492 +        */
47493 +       cs4384_priv = kzalloc(sizeof(struct snd_ubi32_cs4384_priv), GFP_KERNEL);
47494 +       if (!cs4384_priv) {
47495 +               snd_card_free(card);
47496 +               return -ENOMEM;
47497 +       }
47498 +       snd_ubi32_priv_set_drv(ubi32_priv, cs4384_priv);
47499 +       spin_lock_init(&cs4384_priv->lock);
47500 +
47501 +       /*
47502 +        * We start off all muted and max volume
47503 +        */
47504 +       cs4384_priv->mute = 0xFF;
47505 +       memset(cs4384_priv->volume, 0xFF, 8);
47506 +
47507 +       /*
47508 +        * Create the new PCM instance
47509 +        */
47510 +       err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
47511 +       if (err < 0) {
47512 +               snd_card_free(card);
47513 +               return err; /* What is err?  Need to include correct file */
47514 +       }
47515 +
47516 +       strcpy(card->driver, "Ubi32-CS4384");
47517 +       strcpy(card->shortname, "Ubi32-CS4384");
47518 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
47519 +
47520 +       snd_card_set_dev(card, &client->dev);
47521 +
47522 +       /*
47523 +        * Set up the mixer
47524 +        */
47525 +       snd_ubi32_cs4384_mixer(ubi32_priv);
47526 +
47527 +       /*
47528 +        * Register the sound card 
47529 +        */
47530 +       if ((err = snd_card_register(card)) != 0) {
47531 +               snd_printk(KERN_INFO "snd_card_register error\n");
47532 +       }
47533 +
47534 +       /* 
47535 +        * Store card for access from other methods 
47536 +        */
47537 +       i2c_set_clientdata(client, card);
47538 +
47539 +       return 0;
47540 +}
47541 +
47542 +/*
47543 + * snd_ubi32_cs4384_i2c_remove
47544 + */
47545 +static int __devexit snd_ubi32_cs4384_i2c_remove(struct i2c_client *client)
47546 +{
47547 +       struct snd_card *card;
47548 +       struct ubi32_snd_priv *ubi32_priv;
47549 +
47550 +       card = i2c_get_clientdata(client);
47551 +
47552 +       ubi32_priv = card->private_data;
47553 +       snd_ubi32_pcm_remove(ubi32_priv);
47554 +
47555 +       snd_card_free(i2c_get_clientdata(client));
47556 +       i2c_set_clientdata(client, NULL);
47557 +
47558 +       return 0;
47559 +}
47560 +
47561 +/*
47562 + * I2C driver description
47563 + */
47564 +static struct i2c_driver snd_ubi32_cs4384_driver = {
47565 +       .driver = {
47566 +               .name = DRIVER_NAME,
47567 +               .owner = THIS_MODULE,
47568 +       },
47569 +       .id_table       = snd_ubi32_cs4384_id,
47570 +       .probe          = snd_ubi32_cs4384_i2c_probe,
47571 +       .remove         = __devexit_p(snd_ubi32_cs4384_i2c_remove),
47572 +};
47573 +
47574 +/*
47575 + * Driver init
47576 + */
47577 +static int __init snd_ubi32_cs4384_init(void)
47578 +{
47579 +       return i2c_add_driver(&snd_ubi32_cs4384_driver);
47580 +}
47581 +module_init(snd_ubi32_cs4384_init);
47582 +
47583 +/*
47584 + * snd_ubi32_cs4384_exit
47585 + */
47586 +static void __exit snd_ubi32_cs4384_exit(void)
47587 +{
47588 +       i2c_del_driver(&snd_ubi32_cs4384_driver);
47589 +}
47590 +module_exit(snd_ubi32_cs4384_exit);
47591 +
47592 +/*
47593 + * Module properties
47594 + */
47595 +MODULE_ALIAS("i2c:" DRIVER_NAME);
47596 +MODULE_AUTHOR("Patrick Tjin");
47597 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4384");
47598 +MODULE_LICENSE("GPL");
47599 --- /dev/null
47600 +++ b/sound/ubicom32/ubi32-generic.c
47601 @@ -0,0 +1,165 @@
47602 +/*
47603 + * sound/ubicom32/ubi32-generic.c
47604 + *     Interface to ubicom32 virtual audio peripheral
47605 + *
47606 + * (C) Copyright 2009, Ubicom, Inc.
47607 + *
47608 + * This file is part of the Ubicom32 Linux Kernel Port.
47609 + *
47610 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47611 + * it and/or modify it under the terms of the GNU General Public License
47612 + * as published by the Free Software Foundation, either version 2 of the
47613 + * License, or (at your option) any later version.
47614 + *
47615 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47616 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47617 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47618 + * the GNU General Public License for more details.
47619 + *
47620 + * You should have received a copy of the GNU General Public License
47621 + * along with the Ubicom32 Linux Kernel Port.  If not,
47622 + * see <http://www.gnu.org/licenses/>.
47623 + *
47624 + * Ubicom32 implementation derived from (with many thanks):
47625 + *   arch/m68knommu
47626 + *   arch/blackfin
47627 + *   arch/parisc
47628 + */
47629 +
47630 +#include <linux/platform_device.h>
47631 +#include <linux/module.h>
47632 +#include <linux/moduleparam.h>
47633 +#include <sound/core.h>
47634 +#include <sound/pcm.h>
47635 +#include <sound/initval.h>
47636 +#include "ubi32.h"
47637 +
47638 +#define DRIVER_NAME "snd-ubi32-generic"
47639 +
47640 +/*
47641 + * Module properties
47642 + */
47643 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
47644 +
47645 +/*
47646 + * Card private data free function
47647 + */
47648 +void snd_ubi32_generic_free(struct snd_card *card)
47649 +{
47650 +       //struct ubi32_snd_priv *ubi32_priv = card->private_data;
47651 +
47652 +       /*
47653 +        * Free all the fields in the snd_ubi32_priv struct
47654 +        */
47655 +       // Nothing to free at this time because ubi32_priv just maintains pointers
47656 +}
47657 +
47658 +/*
47659 + * Ubicom audio driver probe() method.  Args change depending on whether we use
47660 + * platform_device or i2c_device.
47661 + */
47662 +static int snd_ubi32_generic_probe(struct platform_device *dev)
47663 +{
47664 +       struct snd_card *card;
47665 +       struct ubi32_snd_priv *ubi32_priv;
47666 +       int err;
47667 +
47668 +       /*
47669 +        * Create a snd_card structure
47670 +        */
47671 +       card = snd_card_new(index, "Ubi32-Generic", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47672 +
47673 +       if (card == NULL) {
47674 +               return -ENOMEM;
47675 +       }
47676 +
47677 +       card->private_free = snd_ubi32_generic_free; /* Not sure if correct */
47678 +       ubi32_priv = card->private_data;
47679 +
47680 +       /*
47681 +        * Initialize the snd_card's private data structure
47682 +        */
47683 +       ubi32_priv->card = card;
47684 +
47685 +       /*
47686 +        * Create the new PCM instance
47687 +        */
47688 +       err = snd_ubi32_pcm_probe(ubi32_priv, dev);
47689 +       if (err < 0) {
47690 +               snd_card_free(card);
47691 +               return err;
47692 +       }
47693 +
47694 +       strcpy(card->driver, "Ubi32-Generic");
47695 +       strcpy(card->shortname, "Ubi32-Generic");
47696 +       sprintf(card->longname, "%s at sendirq=%d recvirq=%d", card->shortname, ubi32_priv->tx_irq, ubi32_priv->rx_irq);
47697 +
47698 +       snd_card_set_dev(card, &dev->dev);
47699 +
47700 +       /* Register the sound card */
47701 +       if ((err = snd_card_register(card)) != 0) {
47702 +               snd_printk(KERN_INFO "snd_card_register error\n");
47703 +       }
47704 +
47705 +       /* Store card for access from other methods */
47706 +       platform_set_drvdata(dev, card);
47707 +
47708 +       return 0;
47709 +}
47710 +
47711 +/*
47712 + * Ubicom audio driver remove() method
47713 + */
47714 +static int __devexit snd_ubi32_generic_remove(struct platform_device *dev)
47715 +{
47716 +       struct snd_card *card;
47717 +       struct ubi32_snd_priv *ubi32_priv;
47718 +
47719 +       card = platform_get_drvdata(dev);
47720 +       ubi32_priv = card->private_data;
47721 +       snd_ubi32_pcm_remove(ubi32_priv);
47722 +
47723 +       snd_card_free(platform_get_drvdata(dev));
47724 +       platform_set_drvdata(dev, NULL);
47725 +       return 0;
47726 +}
47727 +
47728 +/*
47729 + * Platform driver definition
47730 + */
47731 +static struct platform_driver snd_ubi32_generic_driver = {
47732 +       .driver = {
47733 +               .name = DRIVER_NAME,
47734 +               .owner = THIS_MODULE,
47735 +       },
47736 +       .probe = snd_ubi32_generic_probe,
47737 +       .remove = __devexit_p(snd_ubi32_generic_remove),
47738 +};
47739 +
47740 +/*
47741 + * snd_ubi32_generic_init
47742 + */
47743 +static int __init snd_ubi32_generic_init(void)
47744 +{
47745 +       return platform_driver_register(&snd_ubi32_generic_driver);
47746 +}
47747 +module_init(snd_ubi32_generic_init);
47748 +
47749 +/*
47750 + * snd_ubi32_generic_exit
47751 + */
47752 +static void __exit snd_ubi32_generic_exit(void)
47753 +{
47754 +       platform_driver_unregister(&snd_ubi32_generic_driver);
47755 +}
47756 +module_exit(snd_ubi32_generic_exit);
47757 +
47758 +/*
47759 + * Module properties
47760 + */
47761 +//#if defined(CONFIG_SND_UBI32_AUDIO_I2C)
47762 +//MODULE_ALIAS("i2c:snd-ubi32");
47763 +//#endif
47764 +MODULE_AUTHOR("Aaron Jow, Patrick Tjin");
47765 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices");
47766 +MODULE_LICENSE("GPL");
47767 --- /dev/null
47768 +++ b/sound/ubicom32/ubi32.h
47769 @@ -0,0 +1,96 @@
47770 +/*
47771 + * sound/ubicom32/ubi32.h
47772 + *     Common header file for all ubi32- sound drivers
47773 + *
47774 + * (C) Copyright 2009, Ubicom, Inc.
47775 + *
47776 + * This file is part of the Ubicom32 Linux Kernel Port.
47777 + *
47778 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47779 + * it and/or modify it under the terms of the GNU General Public License
47780 + * as published by the Free Software Foundation, either version 2 of the
47781 + * License, or (at your option) any later version.
47782 + *
47783 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47784 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47785 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47786 + * the GNU General Public License for more details.
47787 + *
47788 + * You should have received a copy of the GNU General Public License
47789 + * along with the Ubicom32 Linux Kernel Port.  If not,
47790 + * see <http://www.gnu.org/licenses/>.
47791 + */
47792 +
47793 +#ifndef _UBI32_H
47794 +#define _UBI32_H
47795 +
47796 +#define SND_UBI32_DEBUG 0 // Debug flag
47797 +
47798 +#include <linux/platform_device.h>
47799 +#include <asm/devtree.h>
47800 +#include <asm/audio_tio.h>
47801 +#include <asm/ubi32-pcm.h>
47802 +
47803 +struct ubi32_snd_priv;
47804 +
47805 +typedef int (*set_channels_t)(struct ubi32_snd_priv *priv, int channels);
47806 +typedef int (*set_rate_t)(struct ubi32_snd_priv *priv, int rate);
47807 +
47808 +struct ubi32_snd_priv {
47809 +       /*
47810 +        * Any variables that are needed locally here but NOT in
47811 +        * the VP itself should go in here.
47812 +        */
47813 +       struct snd_card *card;
47814 +       struct snd_pcm *pcm;
47815 +
47816 +       /*
47817 +        * DAC parameters.  These are the parameters for the specific
47818 +        * DAC we are driving.  The I2S component can run at a range
47819 +        * of frequencies, but the DAC may be limited.  We may want
47820 +        * to make this an array of some sort in the future?
47821 +        *
47822 +        * min/max_sample_rate if set to 0 are ignored.
47823 +        */
47824 +       int max_sample_rate;
47825 +       int min_sample_rate;
47826 +
47827 +       /*
47828 +        * The size a period (group) of audio samples.  The VP does
47829 +        * not need to know this; each DMA transfer is made to be
47830 +        * one period.
47831 +        */
47832 +       u32_t period_size;
47833 +
47834 +       spinlock_t ubi32_lock;
47835 +
47836 +       struct audiotioregs *regs;
47837 +       u8 tx_irq;
47838 +       u8 rx_irq;
47839 +
47840 +       void *client;
47841 +
47842 +       /*
47843 +        * Operations which the base DAC driver can implement
47844 +        */
47845 +       set_channels_t set_channels;
47846 +       set_rate_t set_rate;
47847 +
47848 +       /*
47849 +        * platform data
47850 +        */
47851 +       struct ubi32pcm_platform_data *pdata;
47852 +
47853 +       /*
47854 +        * Private driver data (used for DAC driver control, etc)
47855 +        */
47856 +       void *drvdata;
47857 +};
47858 +
47859 +#define snd_ubi32_priv_get_drv(priv) ((priv)->drvdata)
47860 +#define snd_ubi32_priv_set_drv(priv, data) (((priv)->drvdata) = (void *)(data))
47861 +
47862 +extern int snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev);
47863 +extern void snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv);
47864 +
47865 +#endif
47866 --- /dev/null
47867 +++ b/sound/ubicom32/ubi32-pcm.c
47868 @@ -0,0 +1,680 @@
47869 +/*
47870 + * sound/ubicom32/ubi32-pcm.c
47871 + *     Interface to ubicom32 virtual audio peripheral
47872 + *
47873 + * (C) Copyright 2009, Ubicom, Inc.
47874 + *
47875 + * This file is part of the Ubicom32 Linux Kernel Port.
47876 + *
47877 + * The Ubicom32 Linux Kernel Port is free software: you can redistribute
47878 + * it and/or modify it under the terms of the GNU General Public License
47879 + * as published by the Free Software Foundation, either version 2 of the
47880 + * License, or (at your option) any later version.
47881 + *
47882 + * The Ubicom32 Linux Kernel Port is distributed in the hope that it
47883 + * will be useful, but WITHOUT ANY WARRANTY; without even the implied
47884 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
47885 + * the GNU General Public License for more details.
47886 + *
47887 + * You should have received a copy of the GNU General Public License
47888 + * along with the Ubicom32 Linux Kernel Port.  If not,
47889 + * see <http://www.gnu.org/licenses/>.
47890 + *
47891 + * Ubicom32 implementation derived from (with many thanks):
47892 + *   arch/m68knommu
47893 + *   arch/blackfin
47894 + *   arch/parisc
47895 + */
47896 +
47897 +#include <linux/interrupt.h>
47898 +#include <sound/core.h>
47899 +#include <sound/pcm.h>
47900 +#include <sound/pcm_params.h>
47901 +#include <asm/ip5000.h>
47902 +#include <asm/ubi32-pcm.h>
47903 +#include <linux/dma-mapping.h>
47904 +#include <linux/delay.h>
47905 +#include "ubi32.h"
47906 +
47907 +struct ubi32_snd_runtime_data {
47908 +       dma_addr_t dma_buffer;          /* Physical address of DMA buffer */
47909 +       dma_addr_t dma_buffer_end;      /* First address beyond end of DMA buffer */
47910 +       size_t period_size;
47911 +       dma_addr_t period_ptr;          /* Physical address of next period */
47912 +       unsigned int flags;
47913 +};
47914 +
47915 +static void snd_ubi32_vp_int_set(struct snd_pcm *pcm)
47916 +{
47917 +       struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
47918 +       ubicom32_set_interrupt(ubi32_priv->tx_irq);
47919 +}
47920 +
47921 +static snd_pcm_uframes_t snd_ubi32_playback_pointer(struct snd_pcm_substream *substream)
47922 +{
47923 +       struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
47924 +       struct audiotioregs *regs = ubi32_priv->regs;
47925 +       struct snd_pcm_runtime *runtime = substream->runtime;
47926 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47927 +
47928 +       dma_addr_t read_pos;
47929 +
47930 +       snd_pcm_uframes_t frames;
47931 +       if (!regs->current_read_pos) {
47932 +               /*
47933 +                * If current_read_pos is NULL (e.g. right after the HW is started or
47934 +                * when the HW is stopped), then handle this case separately.
47935 +                */
47936 +               return 0;
47937 +       }
47938 +
47939 +       read_pos = (dma_addr_t)regs->current_read_pos;
47940 +       frames = bytes_to_frames(runtime, read_pos - ubi32_rd->dma_buffer);
47941 +       if (frames == runtime->buffer_size) {
47942 +               frames = 0;
47943 +       }
47944 +       return frames;
47945 +}
47946 +
47947 +/*
47948 + * Audio trigger
47949 + */
47950 +static int snd_ubi32_playback_trigger(struct snd_pcm_substream *substream, int cmd)
47951 +{
47952 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
47953 +       struct audiotioregs *regs = ubi32_priv->regs;
47954 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
47955 +       int ret = 0;
47956 +
47957 +#if SND_UBI32_DEBUG
47958 +       snd_printk(KERN_INFO "snd_ubi32_playback_trigger cmd=%d=", cmd);
47959 +#endif
47960 +
47961 +       if (regs->command != UBI32_AUDIO_CMD_NONE) {
47962 +               snd_printk(KERN_WARNING "Can't send command to audio device at this time\n");
47963 +               // Set a timer to call this function back later.  How to do this?
47964 +               return 0;
47965 +       }
47966 +
47967 +       /*
47968 +        * Set interrupt flag to indicate that we interrupted audio device
47969 +        * to send a command
47970 +        */
47971 +       //regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47972 +
47973 +       switch (cmd) {
47974 +       case SNDRV_PCM_TRIGGER_START:
47975 +
47976 +#if SND_UBI32_DEBUG
47977 +               snd_printk(KERN_INFO "START\n");
47978 +#endif
47979 +               /*
47980 +                * Ready the DMA transfer
47981 +                */
47982 +               ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
47983 +
47984 +#if SND_UBI32_DEBUG
47985 +               snd_printk(KERN_INFO "trigger period_ptr=%lx\n", (unsigned long)ubi32_rd->period_ptr);
47986 +#endif
47987 +               regs->playback_xfer_requests[0].ptr = (void *)ubi32_rd->period_ptr;
47988 +               regs->playback_xfer_requests[0].ctr = ubi32_rd->period_size;
47989 +               regs->playback_xfer_requests[0].active = 1;
47990 +
47991 +#if SND_UBI32_DEBUG
47992 +               snd_printk(KERN_INFO "xfer_request 0 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
47993 +#endif
47994 +
47995 +               ubi32_rd->period_ptr += ubi32_rd->period_size;
47996 +               regs->playback_xfer_requests[1].ptr = (void *)ubi32_rd->period_ptr;
47997 +               regs->playback_xfer_requests[1].ctr = ubi32_rd->period_size;
47998 +               regs->playback_xfer_requests[1].active = 1;
47999 +
48000 +#if SND_UBI32_DEBUG
48001 +               snd_printk(KERN_INFO "xfer_request 1 ptr=0x%x ctr=%u\n", ubi32_rd->period_ptr, ubi32_rd->period_size);
48002 +#endif
48003 +
48004 +               /*
48005 +                * Tell the VP that we want to begin playback by filling in the
48006 +                * command field and then interrupting the audio VP
48007 +                */
48008 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48009 +               regs->command = UBI32_AUDIO_CMD_START;
48010 +               snd_ubi32_vp_int_set(substream->pcm);
48011 +               break;
48012 +
48013 +       case SNDRV_PCM_TRIGGER_STOP:
48014 +
48015 +#if SND_UBI32_DEBUG
48016 +               snd_printk(KERN_INFO "STOP\n");
48017 +#endif
48018 +
48019 +               /*
48020 +                * Tell the VP that we want to stop playback by filling in the
48021 +                * command field and then interrupting the audio VP
48022 +                */
48023 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48024 +               regs->command = UBI32_AUDIO_CMD_STOP;
48025 +               snd_ubi32_vp_int_set(substream->pcm);
48026 +               break;
48027 +
48028 +       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
48029 +
48030 +#if SND_UBI32_DEBUG
48031 +               snd_printk(KERN_INFO "PAUSE_PUSH\n");
48032 +#endif
48033 +
48034 +               /*
48035 +                * Tell the VP that we want to pause playback by filling in the
48036 +                * command field and then interrupting the audio VP
48037 +                */
48038 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48039 +               regs->command = UBI32_AUDIO_CMD_PAUSE;
48040 +               snd_ubi32_vp_int_set(substream->pcm);
48041 +               break;
48042 +
48043 +       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
48044 +
48045 +#if SND_UBI32_DEBUG
48046 +               snd_printk(KERN_INFO "PAUSE_RELEASE\n");
48047 +#endif
48048 +               /*
48049 +                * Tell the VP that we want to resume paused playback by filling
48050 +                * in the command field and then interrupting the audio VP
48051 +                */
48052 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48053 +               regs->command = UBI32_AUDIO_CMD_RESUME;
48054 +               snd_ubi32_vp_int_set(substream->pcm);
48055 +               break;
48056 +
48057 +       default:
48058 +               snd_printk(KERN_WARNING "Unhandled trigger\n");
48059 +               ret = -EINVAL;
48060 +               break;
48061 +       }
48062 +
48063 +       return ret;
48064 +}
48065 +
48066 +/*
48067 + * Prepare to transfer an audio stream to the codec
48068 + */
48069 +static int snd_ubi32_playback_prepare(struct snd_pcm_substream *substream)
48070 +{
48071 +       /*
48072 +        * Configure registers and setup the runtime instance for DMA transfers
48073 +        */
48074 +       //struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48075 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
48076 +       struct audiotioregs *regs = ubi32_priv->regs;
48077 +
48078 +#if SND_UBI32_DEBUG
48079 +       snd_printk(KERN_INFO "snd_ubi32_playback_prepare: sending STOP command to audio device\n");
48080 +#endif
48081 +
48082 +       /*
48083 +        * Make sure the audio device is stopped
48084 +        */
48085 +
48086 +       /*
48087 +        * Set interrupt flag to indicate that we interrupted audio device
48088 +        * to send a command
48089 +        */
48090 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48091 +       regs->command = UBI32_AUDIO_CMD_STOP;
48092 +       snd_ubi32_vp_int_set(substream->pcm);
48093 +
48094 +       return 0;
48095 +}
48096 +
48097 +/*
48098 + * Allocate DMA buffers from preallocated memory.
48099 + * Preallocation was done in snd_ubi32_pcm_new()
48100 + */
48101 +static int snd_ubi32_playback_hw_params(struct snd_pcm_substream *substream,
48102 +                                       struct snd_pcm_hw_params *hw_params)
48103 +{
48104 +       struct snd_pcm_runtime *runtime = substream->runtime;
48105 +       struct ubi32_snd_priv *ubi32_priv = substream->pcm->private_data;
48106 +       struct audiotioregs *regs = ubi32_priv->regs;
48107 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48108 +
48109 +       /*
48110 +        * Use pre-allocated memory from ubi32_snd_pcm_new() to satisfy
48111 +        * this memory request.
48112 +        */
48113 +       int ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
48114 +
48115 +#if SND_UBI32_DEBUG
48116 +       snd_printk(KERN_INFO "snd_ubi32_playback_hw_params\n");
48117 +#endif
48118 +
48119 +       if (!(regs->channel_mask & (1 << params_channels(hw_params)))) {
48120 +               snd_printk(KERN_INFO "snd_ubi32_playback_hw_params unsupported number of channels %d mask %08x\n", params_channels(hw_params), regs->channel_mask);
48121 +               return -EINVAL;
48122 +       }
48123 +
48124 +       if (ubi32_priv->set_channels) {
48125 +               int ret = ubi32_priv->set_channels(ubi32_priv, params_channels(hw_params));
48126 +               if (ret) {
48127 +                       snd_printk(KERN_WARNING "Unable to set channels to %d, ret=%d\n", params_channels(hw_params), ret);
48128 +                       return ret;
48129 +               }
48130 +       }
48131 +
48132 +       if (ubi32_priv->set_rate) {
48133 +               int ret = ubi32_priv->set_rate(ubi32_priv, params_rate(hw_params));
48134 +               if (ret) {
48135 +                       snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
48136 +                       return ret;
48137 +               }
48138 +       }
48139 +
48140 +       if (ubi32_priv->pdata->set_rate) {
48141 +               int ret = ubi32_priv->pdata->set_rate(ubi32_priv->pdata->appdata, params_rate(hw_params));
48142 +               if (ret) {
48143 +                       snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
48144 +                       return ret;
48145 +               }
48146 +       }
48147 +
48148 +       if (regs->command != UBI32_AUDIO_CMD_NONE) {
48149 +               snd_printk(KERN_WARNING "snd_ubi32_playback_hw_params: tio busy\n");
48150 +               return -EAGAIN;
48151 +       }
48152 +
48153 +       if (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) {
48154 +               regs->flags |= UBI32_CMD_SETUP_FLAG_LE;
48155 +       } else {
48156 +               regs->flags &= ~UBI32_CMD_SETUP_FLAG_LE;
48157 +       }
48158 +       regs->channels = params_channels(hw_params);
48159 +       regs->sample_rate = params_rate(hw_params);
48160 +       regs->command = UBI32_AUDIO_CMD_SETUP;
48161 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48162 +       snd_ubi32_vp_int_set(substream->pcm);
48163 +
48164 +       /*
48165 +        * Wait for the command to complete
48166 +        */
48167 +       while (regs->command != UBI32_AUDIO_CMD_NONE) {
48168 +               udelay(1);
48169 +       }
48170 +
48171 +       //snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
48172 +       //runtime->dma_bytes = params_buffer_bytes(hw_params);
48173 +
48174 +       /*
48175 +        * Put the DMA info into the DMA descriptor that we will
48176 +        * use to do transfers to our audio VP "hardware"
48177 +        */
48178 +
48179 +       /*
48180 +        * Mark both DMA transfers as not ready/inactive
48181 +        */
48182 +       regs->playback_xfer_requests[0].active = 0;
48183 +       regs->playback_xfer_requests[1].active = 0;
48184 +
48185 +       /*
48186 +        * Put the location of the buffer into the runtime data instance
48187 +        */
48188 +       ubi32_rd->dma_buffer = (dma_addr_t)runtime->dma_area;
48189 +       ubi32_rd->dma_buffer_end = (dma_addr_t)(runtime->dma_area + runtime->dma_bytes);
48190 +
48191 +       /*
48192 +        * Get the period size
48193 +        */
48194 +       ubi32_rd->period_size = params_period_bytes(hw_params);
48195 +
48196 +#if SND_UBI32_DEBUG
48197 +       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);
48198 +       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);
48199 +#endif
48200 +
48201 +       return ret;
48202 +}
48203 +
48204 +/*
48205 + * This is the reverse of snd_ubi32_playback_hw_params
48206 + */
48207 +static int snd_ubi32_playback_hw_free(struct snd_pcm_substream *substream)
48208 +{
48209 +#if SND_UBI32_DEBUG
48210 +       snd_printk(KERN_INFO "snd_ubi32_playback_hw_free\n");
48211 +#endif
48212 +       return snd_pcm_lib_free_pages(substream);
48213 +}
48214 +
48215 +/*
48216 + * Audio virtual peripheral capabilities
48217 + */
48218 +static struct snd_pcm_hardware snd_ubi32_playback_hw =
48219 +{
48220 +       /* FILL IN THIS STRUCT WITH HW PARAMS SPECIFIC TO IPI2SOUT */
48221 +       // This is defined in include/sound/asound.h or
48222 +       // include/sound/pcm.h
48223 +       .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
48224 +                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), // NOT SURE ABOUT THIS
48225 +       //.info                 = (SNDRV_PCM_INFO_INTERLEAVED |
48226 +       //                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
48227 +       //                         SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
48228 +       //                         SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
48229 +       .buffer_bytes_max = (64*1024), // NOT SURE ABOUT THIS
48230 +       .period_bytes_min       = 64,
48231 +       .period_bytes_max       = 8184,//8184,//8176,
48232 +       .periods_min = 2,
48233 +       .periods_max = 255, // THIS WILL ALMOST CERTAINLY NEED TO BE CHANGED
48234 +       .fifo_size = 0, // THIS IS IGNORED BY ALSA
48235 +};
48236 +
48237 +/*
48238 + * We fill this in later
48239 + */
48240 +static struct snd_pcm_hw_constraint_list ubi32_playback_rates;
48241 +
48242 +static int snd_ubi32_playback_close(struct snd_pcm_substream *substream)
48243 +{
48244 +       /* Disable codec, stop DMA, free private data structures */
48245 +       //struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
48246 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48247 +
48248 +#if SND_UBI32_DEBUG
48249 +       snd_printk(KERN_INFO "snd_ubi32_playback_close\n");
48250 +#endif
48251 +
48252 +       substream->runtime->private_data = NULL;
48253 +
48254 +       kfree(ubi32_rd);
48255 +       
48256 +       return 0;
48257 +}
48258 +
48259 +static int snd_ubi32_playback_open(struct snd_pcm_substream *substream)
48260 +{
48261 +       //struct ubi32_snd_priv *ubi32_priv = snd_pcm_substream_chip(substream);
48262 +       struct snd_pcm_runtime *runtime = substream->runtime;
48263 +       struct ubi32_snd_runtime_data *ubi32_rd;
48264 +       int ret = 0;
48265 +
48266 +#if SND_UBI32_DEBUG
48267 +       snd_printk(KERN_INFO "ubi32 playback open\n");
48268 +#endif
48269 +
48270 +       /* Associate capabilities with component */
48271 +       runtime->hw = snd_ubi32_playback_hw;
48272 +
48273 +       /*
48274 +        * Inform ALSA about constraints of the audio device
48275 +        */
48276 +       ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &ubi32_playback_rates);
48277 +       if (ret < 0) {
48278 +               snd_printk(KERN_INFO "invalid rate\n");
48279 +               goto out;
48280 +       }
48281 +
48282 +       /* Force the buffer size to be an integer multiple of period size */
48283 +       ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
48284 +       if (ret < 0) {
48285 +               snd_printk(KERN_INFO "invalid period\n");
48286 +               goto out;
48287 +       }
48288 +       /* Initialize structures/registers */
48289 +       ubi32_rd = kzalloc(sizeof(struct ubi32_snd_runtime_data), GFP_KERNEL);
48290 +       if (ubi32_rd == NULL) {
48291 +               ret = -ENOMEM;
48292 +               goto out;
48293 +       }
48294 +
48295 +       runtime->private_data = ubi32_rd;
48296 +
48297 +#if SND_UBI32_DEBUG
48298 +       snd_printk(KERN_INFO "snd_ubi32_playback_open returned 0\n");
48299 +#endif
48300 +
48301 +       return 0;
48302 +out:
48303 +#if SND_UBI32_DEBUG
48304 +       snd_printk(KERN_INFO "snd_ubi32_playback_open returned %d\n", ret);
48305 +#endif
48306 +
48307 +       return ret;
48308 +}
48309 +
48310 +static struct snd_pcm_ops snd_ubi32_playback_ops = {
48311 +       .open =         snd_ubi32_playback_open, /* Open */
48312 +       .close =        snd_ubi32_playback_close, /* Close */
48313 +       .ioctl =        snd_pcm_lib_ioctl, /* Generic IOCTL handler */
48314 +       .hw_params =    snd_ubi32_playback_hw_params, /* Hardware parameters/capabilities */
48315 +       .hw_free =      snd_ubi32_playback_hw_free, /* Free function for hw_params */
48316 +       .prepare =      snd_ubi32_playback_prepare,
48317 +       .trigger =      snd_ubi32_playback_trigger,
48318 +       .pointer =      snd_ubi32_playback_pointer,
48319 +};
48320 +
48321 +/*
48322 + * Interrupt handler that gets called when the audio device
48323 + * interrupts Linux
48324 + */
48325 +static irqreturn_t snd_ubi32_pcm_interrupt(int irq, void *appdata)
48326 +{
48327 +       struct snd_pcm *pcm = (struct snd_pcm *)appdata;
48328 +       struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
48329 +       struct audiotioregs *regs = ubi32_priv->regs;
48330 +
48331 +       // Only one substream exists because our VP does not mix
48332 +       // streams.  Therefore we don't have to search through
48333 +       // substreams like the at91 driver does.
48334 +       struct snd_pcm_substream *substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
48335 +       struct ubi32_snd_runtime_data *ubi32_rd = substream->runtime->private_data;
48336 +       int dma_to_fill = 0;
48337 +
48338 +#if SND_UBI32_DEBUG
48339 +       snd_printk(KERN_INFO "Ubi32 ALSA interrupt\n");
48340 +#endif
48341 +
48342 +       if (!pcm) {
48343 +               snd_printk(KERN_WARNING "pcm does not exist\n");
48344 +               return IRQ_HANDLED;
48345 +       }
48346 +
48347 +       if (ubi32_rd == NULL) {
48348 +               snd_printk(KERN_WARNING "No runtime data\n");
48349 +               return IRQ_HANDLED;
48350 +       }
48351 +       // Check interrupt cause
48352 +       if (0) {
48353 +               // Handle the underflow case
48354 +       } else if ((regs->status & UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST) ||
48355 +                  (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST)) {
48356 +               if (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST) {
48357 +                       dma_to_fill = 0;
48358 +                       regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST;
48359 +               } else if (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST) {
48360 +                       dma_to_fill = 1;
48361 +                       regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST;
48362 +               }   
48363 +               ubi32_rd->period_ptr += ubi32_rd->period_size;
48364 +               if (ubi32_rd->period_ptr >= ubi32_rd->dma_buffer_end) {
48365 +                       ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
48366 +               }
48367 +               regs->playback_xfer_requests[dma_to_fill].ptr = (void *)ubi32_rd->period_ptr;
48368 +               regs->playback_xfer_requests[dma_to_fill].ctr = ubi32_rd->period_size;
48369 +               regs->playback_xfer_requests[dma_to_fill].active = 1;
48370 +#if SND_UBI32_DEBUG
48371 +               snd_printk(KERN_INFO "xfer_request %d ptr=0x%x ctr=%u\n", dma_to_fill, ubi32_rd->period_ptr, ubi32_rd->period_size);
48372 +#endif
48373 +               regs->int_flags |= UBI32_AUDIO_INT_FLAG_MORE_SAMPLES;
48374 +               snd_ubi32_vp_int_set(substream->pcm);
48375 +       }
48376 +       // If we are interrupted by the VP, that means we completed
48377 +       // processing one period of audio.  We need to inform the upper
48378 +       // layers of ALSA of this.
48379 +       snd_pcm_period_elapsed(substream);
48380 +
48381 +       return IRQ_HANDLED;
48382 +}
48383 +
48384 +void __devexit snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv)
48385 +{
48386 +       struct snd_pcm *pcm = ubi32_priv->pcm;
48387 +       free_irq(ubi32_priv->rx_irq, pcm);
48388 +}
48389 +
48390 +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
48391 +#error "Change this table to match pcm.h"
48392 +#endif
48393 +static unsigned int rates[] __initdata = {5512, 8000, 11025, 16000, 22050, 
48394 +                                         32000, 44100, 48000, 64000, 88200, 
48395 +                                         96000, 176400, 192000};
48396 +
48397 +/*
48398 + * snd_ubi32_pcm_probe
48399 + */
48400 +int __devinit snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev)
48401 +{
48402 +       struct snd_pcm *pcm;
48403 +       int ret, err;
48404 +       int i;
48405 +       int j;
48406 +       int nrates;
48407 +       unsigned int rate_max = 0;
48408 +       unsigned int rate_min = 0xFFFFFFFF;
48409 +       unsigned int rate_mask = 0;
48410 +       struct audiotioregs *regs;
48411 +       struct resource *res_regs;
48412 +       struct resource *res_irq_tx;
48413 +       struct resource *res_irq_rx;
48414 +       struct ubi32pcm_platform_data *pdata;
48415 +
48416 +       pdata = pdev->dev.platform_data;
48417 +       if (!pdata) {
48418 +               return -ENODEV;
48419 +       }
48420 +
48421 +       /*
48422 +        * Get our resources, regs is the hardware driver base address
48423 +        * and the tx and rx irqs are used to communicate with the
48424 +        * hardware driver.
48425 +        */
48426 +       res_regs = platform_get_resource(pdev, IORESOURCE_MEM, AUDIOTIO_MEM_RESOURCE);
48427 +       res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIOTIO_TX_IRQ_RESOURCE);
48428 +       res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, AUDIOTIO_RX_IRQ_RESOURCE);
48429 +       if (!res_regs || !res_irq_tx || !res_irq_rx) {
48430 +               snd_printk(KERN_WARNING "Could not get resources");
48431 +               return -ENODEV;
48432 +       }
48433 +
48434 +       ubi32_priv->regs = (struct audiotioregs *)res_regs->start;
48435 +       ubi32_priv->tx_irq = res_irq_tx->start;
48436 +       ubi32_priv->rx_irq = res_irq_rx->start;
48437 +
48438 +       /*
48439 +        * Check the version
48440 +        */
48441 +       regs = ubi32_priv->regs;
48442 +       if (regs->version != AUDIOTIOREGS_VERSION) {
48443 +               snd_printk(KERN_WARNING "This audiotioreg is not compatible with this driver\n");
48444 +               return -ENODEV;
48445 +       }
48446 +
48447 +       /*
48448 +        * Find out the standard rates, also find max and min rates
48449 +        */
48450 +       for (i = 0; i < ARRAY_SIZE(rates); i++) {
48451 +               int found = 0;
48452 +               for (j = 0; j < regs->n_sample_rates; j++) {
48453 +                       if (rates[i] == regs->sample_rates[j]) {
48454 +                               /*
48455 +                                * Check to see if it is supported by the dac
48456 +                                */
48457 +                               if ((rates[i] >= ubi32_priv->min_sample_rate) &&
48458 +                                   (!ubi32_priv->max_sample_rate || 
48459 +                                    (ubi32_priv->max_sample_rate && (rates[i] <= ubi32_priv->max_sample_rate)))) {
48460 +                                       found = 1;
48461 +                                       rate_mask |= (1 << i);
48462 +                                       nrates++;
48463 +                                       if (rates[i] < rate_min) {
48464 +                                               rate_min = rates[i];
48465 +                                       }
48466 +                                       if (rates[i] > rate_max) {
48467 +                                               rate_max = rates[i];
48468 +                                       }
48469 +                                       break;
48470 +                               }
48471 +                       }
48472 +               }
48473 +               if (!found) {
48474 +                       rate_mask |= SNDRV_PCM_RATE_KNOT;
48475 +               }
48476 +       }
48477 +
48478 +       snd_ubi32_playback_hw.rates = rate_mask;
48479 +       snd_ubi32_playback_hw.rate_min = rate_min;
48480 +       snd_ubi32_playback_hw.rate_max = rate_max;
48481 +       ubi32_playback_rates.count = regs->n_sample_rates;
48482 +       ubi32_playback_rates.list = regs->sample_rates;
48483 +       ubi32_playback_rates.mask = 0;
48484 +
48485 +       for (i = 0; i < 32; i++) {
48486 +               if (regs->channel_mask & (1 << i)) {
48487 +                       if (!snd_ubi32_playback_hw.channels_min) {
48488 +                               snd_ubi32_playback_hw.channels_min = i;
48489 +                       }
48490 +                       snd_ubi32_playback_hw.channels_max = i;
48491 +               }
48492 +       }
48493 +       snd_printk(KERN_INFO "Ubi32PCM: channels_min:%u channels_max:%u\n",
48494 +                  snd_ubi32_playback_hw.channels_min,
48495 +                  snd_ubi32_playback_hw.channels_max);
48496 +
48497 +       if (regs->caps & AUDIOTIONODE_CAP_BE) {
48498 +               snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_BE;
48499 +       }
48500 +       if (regs->caps & AUDIOTIONODE_CAP_LE) {
48501 +               snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
48502 +       }
48503 +       snd_printk(KERN_INFO "Ubi32PCM: rates:%08x min:%u max:%u count:%d fmts:%016llx\n",
48504 +                  snd_ubi32_playback_hw.rates,
48505 +                  snd_ubi32_playback_hw.rate_min,
48506 +                  snd_ubi32_playback_hw.rate_max,
48507 +                  ubi32_playback_rates.count,
48508 +                  snd_ubi32_playback_hw.formats);
48509 +
48510 +       ret = snd_pcm_new(ubi32_priv->card, "Ubi32 PCM", 0, 1, 0, &pcm);
48511 +       if (ret < 0) {
48512 +               return ret;
48513 +       }
48514 +
48515 +       pcm->private_data = ubi32_priv;
48516 +       ubi32_priv->pcm = pcm;
48517 +       ubi32_priv->pdata = pdata;
48518 +
48519 +       pcm->info_flags = 0; // What is this for?  Just copied from other drivers
48520 +
48521 +       strcpy(pcm->name, "Ubi32-PCM");
48522 +
48523 +       // How do we allocate the buffer for non PCI devices?
48524 +       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
48525 +                                             snd_dma_continuous_data(GFP_KERNEL),
48526 +                                             45*1024, 64*1024); //NOT SURE ABOUT SIZE, CHECK LATER
48527 +
48528 +       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ubi32_playback_ops);
48529 +
48530 +       /*
48531 +        * Start up the TIO
48532 +        */
48533 +       regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48534 +       regs->command = UBI32_AUDIO_CMD_ENABLE;
48535 +       snd_ubi32_vp_int_set(pcm);
48536 +
48537 +       /* 
48538 +        * Request IRQ
48539 +        */
48540 +       err = request_irq(ubi32_priv->rx_irq, snd_ubi32_pcm_interrupt, IRQF_DISABLED, pcm->name, pcm);
48541 +       if (err) {
48542 +               snd_printk(KERN_WARNING "request_irq failed: irq=%d err=%d\n", ubi32_priv->rx_irq, err);
48543 +               return -ENODEV;
48544 +       }
48545 +
48546 +       return ret;
48547 +
48548 +}
48549 --- /dev/null
48550 +++ b/arch/ubicom32/lib/ashldi3.c
48551 @@ -0,0 +1,62 @@
48552 +/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
48553 +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
48554 +
48555 +This file is part of GNU CC.
48556 +
48557 +GNU CC is free software; you can redistribute it and/or modify
48558 +it under the terms of the GNU General Public License as published by
48559 +the Free Software Foundation; either version 2, or (at your option)
48560 +any later version.
48561 +
48562 +GNU CC is distributed in the hope that it will be useful,
48563 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48564 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48565 +GNU General Public License for more details.
48566 +
48567 +You should have received a copy of the GNU General Public License
48568 +along with GNU CC; see the file COPYING.  If not, write to
48569 +the Free Software Foundation, 59 Temple Place - Suite 330,
48570 +Boston, MA 02111-1307, USA.  */
48571 +
48572 +#define BITS_PER_UNIT 8
48573 +
48574 +typedef                 int SItype     __attribute__ ((mode (SI)));
48575 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48576 +typedef                 int DItype     __attribute__ ((mode (DI)));
48577 +typedef int word_type __attribute__ ((mode (__word__)));
48578 +
48579 +struct DIstruct {SItype high, low;};
48580 +
48581 +typedef union
48582 +{
48583 +  struct DIstruct s;
48584 +  DItype ll;
48585 +} DIunion;
48586 +
48587 +DItype
48588 +__ashldi3 (DItype u, word_type b)
48589 +{
48590 +  DIunion w;
48591 +  word_type bm;
48592 +  DIunion uu;
48593 +
48594 +  if (b == 0)
48595 +    return u;
48596 +
48597 +  uu.ll = u;
48598 +
48599 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48600 +  if (bm <= 0)
48601 +    {
48602 +      w.s.low = 0;
48603 +      w.s.high = (USItype)uu.s.low << -bm;
48604 +    }
48605 +  else
48606 +    {
48607 +      USItype carries = (USItype)uu.s.low >> bm;
48608 +      w.s.low = (USItype)uu.s.low << b;
48609 +      w.s.high = ((USItype)uu.s.high << b) | carries;
48610 +    }
48611 +
48612 +  return w.ll;
48613 +}
48614 --- /dev/null
48615 +++ b/arch/ubicom32/lib/ashrdi3.c
48616 @@ -0,0 +1,63 @@
48617 +/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
48618 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48619 +
48620 +This file is part of GNU CC.
48621 +
48622 +GNU CC is free software; you can redistribute it and/or modify
48623 +it under the terms of the GNU General Public License as published by
48624 +the Free Software Foundation; either version 2, or (at your option)
48625 +any later version.
48626 +
48627 +GNU CC is distributed in the hope that it will be useful,
48628 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48629 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48630 +GNU General Public License for more details.
48631 +
48632 +You should have received a copy of the GNU General Public License
48633 +along with GNU CC; see the file COPYING.  If not, write to
48634 +the Free Software Foundation, 59 Temple Place - Suite 330,
48635 +Boston, MA 02111-1307, USA.  */
48636 +
48637 +#define BITS_PER_UNIT 8
48638 +
48639 +typedef                 int SItype     __attribute__ ((mode (SI)));
48640 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48641 +typedef                 int DItype     __attribute__ ((mode (DI)));
48642 +typedef int word_type __attribute__ ((mode (__word__)));
48643 +
48644 +struct DIstruct {SItype high, low;};
48645 +
48646 +typedef union
48647 +{
48648 +  struct DIstruct s;
48649 +  DItype ll;
48650 +} DIunion;
48651 +
48652 +DItype
48653 +__ashrdi3 (DItype u, word_type b)
48654 +{
48655 +  DIunion w;
48656 +  word_type bm;
48657 +  DIunion uu;
48658 +
48659 +  if (b == 0)
48660 +    return u;
48661 +
48662 +  uu.ll = u;
48663 +
48664 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48665 +  if (bm <= 0)
48666 +    {
48667 +      /* w.s.high = 1..1 or 0..0 */
48668 +      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
48669 +      w.s.low = uu.s.high >> -bm;
48670 +    }
48671 +  else
48672 +    {
48673 +      USItype carries = (USItype)uu.s.high << bm;
48674 +      w.s.high = uu.s.high >> b;
48675 +      w.s.low = ((USItype)uu.s.low >> b) | carries;
48676 +    }
48677 +
48678 +  return w.ll;
48679 +}
48680 --- /dev/null
48681 +++ b/arch/ubicom32/lib/divmod.c
48682 @@ -0,0 +1,85 @@
48683 +unsigned long
48684 +udivmodsi4(unsigned long num, unsigned long den, int modwanted)
48685 +{
48686 +  unsigned long bit = 1;
48687 +  unsigned long res = 0;
48688 +
48689 +  while (den < num && bit && !(den & (1L<<31)))
48690 +    {
48691 +      den <<=1;
48692 +      bit <<=1;
48693 +    }
48694 +  while (bit)
48695 +    {
48696 +      if (num >= den)
48697 +       {
48698 +         num -= den;
48699 +         res |= bit;
48700 +       }
48701 +      bit >>=1;
48702 +      den >>=1;
48703 +    }
48704 +  if (modwanted) return num;
48705 +  return res;
48706 +}
48707 +
48708 +long
48709 +__udivsi3 (long a, long b)
48710 +{
48711 +  return udivmodsi4 (a, b, 0);
48712 +}
48713 +
48714 +long
48715 +__umodsi3 (long a, long b)
48716 +{
48717 +  return udivmodsi4 (a, b, 1);
48718 +}
48719 +
48720 +long
48721 +__divsi3 (long a, long b)
48722 +{
48723 +  int neg = 0;
48724 +  long res;
48725 +
48726 +  if (a < 0)
48727 +    {
48728 +      a = -a;
48729 +      neg = !neg;
48730 +    }
48731 +
48732 +  if (b < 0)
48733 +    {
48734 +      b = -b;
48735 +      neg = !neg;
48736 +    }
48737 +
48738 +  res = udivmodsi4 (a, b, 0);
48739 +
48740 +  if (neg)
48741 +    res = -res;
48742 +
48743 +  return res;
48744 +}
48745 +
48746 +long
48747 +__modsi3 (long a, long b)
48748 +{
48749 +  int neg = 0;
48750 +  long res;
48751 +
48752 +  if (a < 0)
48753 +    {
48754 +      a = -a;
48755 +      neg = 1;
48756 +    }
48757 +
48758 +  if (b < 0)
48759 +    b = -b;
48760 +
48761 +  res = udivmodsi4 (a, b, 1);
48762 +
48763 +  if (neg)
48764 +    res = -res;
48765 +
48766 +  return res;
48767 +}
48768 --- /dev/null
48769 +++ b/arch/ubicom32/lib/lshrdi3.c
48770 @@ -0,0 +1,62 @@
48771 +/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
48772 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48773 +
48774 +This file is part of GNU CC.
48775 +
48776 +GNU CC is free software; you can redistribute it and/or modify
48777 +it under the terms of the GNU General Public License as published by
48778 +the Free Software Foundation; either version 2, or (at your option)
48779 +any later version.
48780 +
48781 +GNU CC is distributed in the hope that it will be useful,
48782 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48783 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48784 +GNU General Public License for more details.
48785 +
48786 +You should have received a copy of the GNU General Public License
48787 +along with GNU CC; see the file COPYING.  If not, write to
48788 +the Free Software Foundation, 59 Temple Place - Suite 330,
48789 +Boston, MA 02111-1307, USA.  */
48790 +
48791 +#define BITS_PER_UNIT 8
48792 +
48793 +typedef                 int SItype     __attribute__ ((mode (SI)));
48794 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48795 +typedef                 int DItype     __attribute__ ((mode (DI)));
48796 +typedef int word_type __attribute__ ((mode (__word__)));
48797 +
48798 +struct DIstruct {SItype high, low;};
48799 +
48800 +typedef union
48801 +{
48802 +  struct DIstruct s;
48803 +  DItype ll;
48804 +} DIunion;
48805 +
48806 +DItype
48807 +__lshrdi3 (DItype u, word_type b)
48808 +{
48809 +  DIunion w;
48810 +  word_type bm;
48811 +  DIunion uu;
48812 +
48813 +  if (b == 0)
48814 +    return u;
48815 +
48816 +  uu.ll = u;
48817 +
48818 +  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48819 +  if (bm <= 0)
48820 +    {
48821 +      w.s.high = 0;
48822 +      w.s.low = (USItype)uu.s.high >> -bm;
48823 +    }
48824 +  else
48825 +    {
48826 +      USItype carries = (USItype)uu.s.high << bm;
48827 +      w.s.high = (USItype)uu.s.high >> b;
48828 +      w.s.low = ((USItype)uu.s.low >> b) | carries;
48829 +    }
48830 +
48831 +  return w.ll;
48832 +}
48833 --- /dev/null
48834 +++ b/arch/ubicom32/lib/muldi3.c
48835 @@ -0,0 +1,87 @@
48836 +/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
48837 +                          gcc-2.7.2.3/longlong.h which is: */
48838 +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
48839 +
48840 +This file is part of GNU CC.
48841 +
48842 +GNU CC is free software; you can redistribute it and/or modify
48843 +it under the terms of the GNU General Public License as published by
48844 +the Free Software Foundation; either version 2, or (at your option)
48845 +any later version.
48846 +
48847 +GNU CC is distributed in the hope that it will be useful,
48848 +but WITHOUT ANY WARRANTY; without even the implied warranty of
48849 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48850 +GNU General Public License for more details.
48851 +
48852 +You should have received a copy of the GNU General Public License
48853 +along with GNU CC; see the file COPYING.  If not, write to
48854 +the Free Software Foundation, 59 Temple Place - Suite 330,
48855 +Boston, MA 02111-1307, USA.  */
48856 +
48857 +#define UWtype          USItype
48858 +#define UHWtype         USItype
48859 +#define W_TYPE_SIZE     32
48860 +#define __BITS4 (W_TYPE_SIZE / 4)
48861 +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
48862 +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
48863 +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
48864 +
48865 +#define umul_ppmm(w1, w0, u, v)                                         \
48866 +  do {                                                                  \
48867 +    UWtype __x0, __x1, __x2, __x3;                                      \
48868 +    UHWtype __ul, __vl, __uh, __vh;                                     \
48869 +                                                                        \
48870 +    __ul = __ll_lowpart (u);                                            \
48871 +    __uh = __ll_highpart (u);                                           \
48872 +    __vl = __ll_lowpart (v);                                            \
48873 +    __vh = __ll_highpart (v);                                           \
48874 +                                                                        \
48875 +    __x0 = (UWtype) __ul * __vl;                                        \
48876 +    __x1 = (UWtype) __ul * __vh;                                        \
48877 +    __x2 = (UWtype) __uh * __vl;                                        \
48878 +    __x3 = (UWtype) __uh * __vh;                                        \
48879 +                                                                        \
48880 +    __x1 += __ll_highpart (__x0);/* this can't give carry */            \
48881 +    __x1 += __x2;               /* but this indeed can */               \
48882 +    if (__x1 < __x2)            /* did we get it? */                    \
48883 +      __x3 += __ll_B;           /* yes, add it in the proper pos.  */   \
48884 +                                                                        \
48885 +    (w1) = __x3 + __ll_highpart (__x1);                                 \
48886 +    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);          \
48887 +  } while (0)
48888 +
48889 +
48890 +#define __umulsidi3(u, v) \
48891 +  ({DIunion __w;                                                       \
48892 +    umul_ppmm (__w.s.high, __w.s.low, u, v);                           \
48893 +    __w.ll; })
48894 +
48895 +typedef                 int SItype     __attribute__ ((mode (SI)));
48896 +typedef unsigned int USItype   __attribute__ ((mode (SI)));
48897 +typedef                 int DItype     __attribute__ ((mode (DI)));
48898 +typedef int word_type __attribute__ ((mode (__word__)));
48899 +
48900 +struct DIstruct {SItype high, low;};
48901 +
48902 +typedef union
48903 +{
48904 +  struct DIstruct s;
48905 +  DItype ll;
48906 +} DIunion;
48907 +
48908 +DItype
48909 +__muldi3 (DItype u, DItype v)
48910 +{
48911 +  DIunion w;
48912 +  DIunion uu, vv;
48913 +
48914 +  uu.ll = u,
48915 +  vv.ll = v;
48916 +
48917 +  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
48918 +  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
48919 +              + (USItype) uu.s.high * (USItype) vv.s.low);
48920 +
48921 +  return w.ll;
48922 +}