2 +++ b/arch/ubicom32/crypto/aes_ubicom32.c
5 + * arch/ubicom32/crypto/aes_ubicom32.c
6 + * Ubicom32 implementation of the AES Cipher Algorithm.
8 + * (C) Copyright 2009, Ubicom, Inc.
10 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26 + * Ubicom32 implementation derived from (with many thanks):
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>
40 +struct ubicom32_aes_ctx {
41 + u8 key[AES_MAX_KEY_SIZE];
46 +static inline void aes_hw_set_key(const u8 *key, u8 key_len)
49 + * switch case has more overhead than 4 move.4 instructions, so just copy 256 bits
51 + SEC_SET_KEY_256(key);
54 +static inline void aes_hw_set_iv(const u8 *iv)
59 +static inline void aes_hw_cipher(u8 *out, const u8 *in)
61 + SEC_SET_INPUT_4W(in);
64 + " ; start AES by writing 0x40(SECURITY_BASE) \n\t"
65 + " move.4 0x40(%0), #0x01 \n\t"
66 + " pipe_flush 0 \n\t"
68 + " ; wait for the module to calculate the output \n\t"
69 + " btst 0x04(%0), #0 \n\t"
76 + SEC_GET_OUTPUT_4W(out);
79 +static int __ocm_text aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
80 + unsigned int key_len)
82 + struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
84 + uctx->key_len = key_len;
85 + memcpy(uctx->key, in_key, key_len);
88 + * leave out HASH_ALG (none = 0), CBC (no = 0), DIR (unknown) yet
90 + switch (uctx->key_len) {
92 + uctx->ctrl = SEC_KEY_128_BITS | SEC_ALG_AES;
95 + uctx->ctrl = SEC_KEY_192_BITS | SEC_ALG_AES;
98 + uctx->ctrl = SEC_KEY_256_BITS | SEC_ALG_AES;
105 +static inline void aes_cipher(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
107 + const struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
111 + hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
113 + aes_hw_set_key(uctx->key, uctx->key_len);
114 + aes_hw_cipher(out, in);
116 + hw_crypto_unlock();
119 +static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
121 + aes_cipher(tfm, out, in, SEC_DIR_ENCRYPT);
124 +static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
126 + aes_cipher(tfm, out, in, SEC_DIR_DECRYPT);
129 +static struct crypto_alg aes_alg = {
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),
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,
150 +static void __ocm_text ecb_aes_crypt_loop(u8 *out, u8 *in, unsigned int n)
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;
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)
163 + const struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
166 + struct blkcipher_walk walk;
167 + blkcipher_walk_init(&walk, dst, src, nbytes);
168 + ret = blkcipher_walk_virt(desc, &walk);
176 + hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
177 + aes_hw_set_key(uctx->key, uctx->key_len);
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;
185 + /* finish n/16 blocks */
186 + ecb_aes_crypt_loop(out, in, n);
188 + nbytes &= AES_BLOCK_SIZE - 1;
189 + ret = blkcipher_walk_done(desc, &walk, nbytes);
192 + hw_crypto_unlock();
196 +static int ecb_aes_encrypt(struct blkcipher_desc *desc,
197 + struct scatterlist *dst, struct scatterlist *src,
198 + unsigned int nbytes)
200 + return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT);
203 +static int ecb_aes_decrypt(struct blkcipher_desc *desc,
204 + struct scatterlist *dst, struct scatterlist *src,
205 + unsigned int nbytes)
207 + return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT);
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),
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,
232 +#if CRYPTO_UBICOM32_LOOP_ASM
233 +void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
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"
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"
250 + "; kickoff hw \n\t"
251 + " move.4 0x40(%0), %2 \n\t"
253 + "; update n & flush \n\t"
254 + " add.4 %4, #-16, %4 \n\t"
255 + " pipe_flush 0 \n\t"
257 + "; while (n): work on 2nd block \n\t"
258 + " 1: lsl.4 d15, %4, #0x0 \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"
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"
271 + "; wait for the previous output \n\t"
272 + " btst 0x04(%0), #0 \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"
281 + "; kick off hw for 2nd input \n\t"
282 + " move.4 0x40(%0), %2 \n\t"
284 + "; update out asap \n\t"
285 + " move.4 d15, 16(%1)++ \n\t"
287 + "; go back to loop \n\t"
290 + "; wait for last output \n\t"
291 + " 5: btst 0x04(%0), #0 \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"
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"
307 + : "a" (SEC_BASE), "a" (out), "a" (in), "a" (iv), "d" (n)
314 +static void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
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;
323 + SEC_COPY_4W(iv, out - AES_BLOCK_SIZE);
328 +static void __ocm_text cbc_aes_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
330 + while (likely(n)) {
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;
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)
344 + struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
347 + struct blkcipher_walk walk;
348 + blkcipher_walk_init(&walk, dst, src, nbytes);
349 + ret = blkcipher_walk_virt(desc, &walk);
350 + if (unlikely(ret)) {
357 + hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
358 + aes_hw_set_key(uctx->key, uctx->key_len);
360 + while (likely((nbytes = walk.nbytes))) {
361 + /* only use complete blocks */
362 + unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
364 + u8 *out = walk.dst.virt.addr;
365 + u8 *in = walk.src.virt.addr;
367 + if (extra_flags & SEC_DIR_ENCRYPT) {
368 + cbc_aes_encrypt_loop(out, in, walk.iv, n);
370 + cbc_aes_decrypt_loop(out, in, walk.iv, n);
374 + nbytes &= AES_BLOCK_SIZE - 1;
375 + ret = blkcipher_walk_done(desc, &walk, nbytes);
377 + hw_crypto_unlock();
382 +static int __ocm_text cbc_aes_encrypt(struct blkcipher_desc *desc,
383 + struct scatterlist *dst, struct scatterlist *src,
384 + unsigned int nbytes)
386 + return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT | SEC_CBC_SET);
389 +static int __ocm_text cbc_aes_decrypt(struct blkcipher_desc *desc,
390 + struct scatterlist *dst, struct scatterlist *src,
391 + unsigned int nbytes)
393 + return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT | SEC_CBC_SET);
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),
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,
419 +static int __init aes_init(void)
425 + ret = crypto_register_alg(&aes_alg);
429 + ret = crypto_register_alg(&ecb_aes_alg);
433 + ret = crypto_register_alg(&cbc_aes_alg);
441 + crypto_unregister_alg(&ecb_aes_alg);
443 + crypto_unregister_alg(&aes_alg);
448 +static void __exit aes_fini(void)
450 + crypto_unregister_alg(&cbc_aes_alg);
451 + crypto_unregister_alg(&ecb_aes_alg);
452 + crypto_unregister_alg(&aes_alg);
455 +module_init(aes_init);
456 +module_exit(aes_fini);
458 +MODULE_ALIAS("aes");
460 +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
461 +MODULE_LICENSE("GPL");
463 +++ b/arch/ubicom32/crypto/crypto_des.h
466 + * arch/ubicom32/crypto/crypto_des.h
467 + * Function for checking keys for the DES and Triple DES Encryption
470 + * (C) Copyright 2009, Ubicom, Inc.
472 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
488 + * Ubicom32 implementation derived from (with many thanks):
493 +#ifndef __CRYPTO_DES_H__
494 +#define __CRYPTO_DES_H__
496 +extern int crypto_des_check_key(const u8*, unsigned int, u32*);
498 +#endif /* __CRYPTO_DES_H__ */
500 +++ b/arch/ubicom32/crypto/crypto_ubicom32.c
503 + * arch/ubicom32/crypto/crypto_ubicom32.c
504 + * Generic code to support ubicom32 hardware crypto accelerator
506 + * (C) Copyright 2009, Ubicom, Inc.
508 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
524 + * Ubicom32 implementation derived from (with many thanks):
529 +#include "crypto_ubicom32.h"
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;
536 +struct timer_list crypto_ubicom32_ps_timer;
537 +void crypto_ubicom32_ps_check(unsigned long data)
539 + unsigned long idle_time = msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS);
541 + BUG_ON(!crypto_ubicom32_on);
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);
549 + /* keep monitoring */
550 + hw_crypto_ps_start();
553 +++ b/arch/ubicom32/crypto/crypto_ubicom32.h
556 + * arch/ubicom32/crypto/crypto_ubicom32.h
557 + * Support for Ubicom32 cryptographic instructions.
559 + * (C) Copyright 2009, Ubicom, Inc.
561 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
577 + * Ubicom32 implementation derived from (with many thanks):
582 +#ifndef _CRYPTO_ARCH_UBICOM32_CRYPT_H
583 +#define _CRYPTO_ARCH_UBICOM32_CRYPT_H
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>
592 +#include <asm/ip5000.h>
594 +#define CRYPTO_UBICOM32_LOOP_ASM 1
595 +#define CRYPTO_UBICOM32_ALIGNMENT 4
596 +#define SEC_ALIGNED(p) (((u32)p & 3) == 0)
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)
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)
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
612 +#define SEC_CBC_SET SECURITY_CTRL_CBC
613 +#define SEC_CBC_NONE 0
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
620 +#define SEC_DIR_ENCRYPT SECURITY_CTRL_ENCIPHER
621 +#define SEC_DIR_DECRYPT 0
623 +#define CRYPTO_UBICOM32_PRIORITY 300
624 +#define CRYPTO_UBICOM32_COMPOSITE_PRIORITY 400
626 +#define HW_CRYPTO_PS_MAX_IDLE_MS 100 /* idle time (ms) before shuting down sm */
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);
635 +#define SEC_COPY_2W(t, s) \
637 + " move.4 0(%0), 0(%1) \n\t" \
638 + " move.4 4(%0), 4(%1) \n\t" \
641 + : "a" (t), "a" (s) \
644 +#define SEC_COPY_4W(t, s) \
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" \
651 + : "a" (t), "a" (s) \
654 +#define SEC_COPY_5W(t, s) \
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" \
662 + : "a" (t), "a" (s) \
665 +#define SEC_SET_KEY_2W(x) \
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" \
671 + : "a" (SECURITY_BASE), "a" (x) \
674 +#define SEC_SET_KEY_4W(x) \
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" \
682 + : "a"(SECURITY_BASE), "a"(x) \
685 +#define SEC_SET_KEY_6W(x) \
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" \
695 + : "a" (SECURITY_BASE), "a" (x) \
698 +#define SEC_SET_KEY_8W(x) \
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" \
710 + : "a" (SECURITY_BASE), "a" (x) \
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)
718 +#define DES_SET_KEY(x) SEC_SET_KEY_64(x)
719 +#define DES3_SET_KEY(x) SEC_SET_KEY_192(x)
721 +#define SEC_SET_INPUT_2W(x) \
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" \
727 + : "a" (SECURITY_BASE), "a" (x) \
730 +#define SEC_GET_OUTPUT_2W(x) \
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" \
736 + : "a" (SECURITY_BASE), "a" (x) \
739 +#define SEC_SET_INPUT_4W(x) \
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" \
747 + : "a" (SECURITY_BASE), "a" (x) \
750 +#define SEC_GET_OUTPUT_4W(x) \
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" \
758 + : "a" (SECURITY_BASE), "a" (x) \
761 +#define SEC_SET_IV_4W(x) \
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" \
769 + : "a" (SECURITY_BASE), "a" (x) \
772 +#define SEC_PIPE_FLUSH() asm volatile ( " pipe_flush 0 \n\t" )
774 +static inline void hw_crypto_set_ctrl(uint32_t c)
777 + " move.4 0(%0), %1 \n\t"
779 + : "a" (SECURITY_BASE + SECURITY_CTRL), "d" (c)
783 +static inline void hw_crypto_ps_start(void)
785 + crypto_ubicom32_ps_timer.expires = jiffies + msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS >> 1);
786 + add_timer(&crypto_ubicom32_ps_timer);
789 +static inline void hw_crypto_turn_on(void)
792 + " moveai A4, %0 \n\t"
793 + " bset 0x0(A4), 0x0(A4), %1 \n\t"
796 + : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)
799 + crypto_ubicom32_on = true;
802 +static inline void hw_crypto_turn_off(void)
805 + " moveai A4, %0 \n\t"
806 + " bclr 0x0(A4), 0x0(A4), %1 \n\t"
808 + : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)
811 + crypto_ubicom32_on = false;
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.
819 +static inline void hw_crypto_check(void)
821 + if (likely(crypto_ubicom32_on)) {
824 + crypto_ubicom32_last_use = jiffies;
825 + hw_crypto_turn_on();
826 + hw_crypto_ps_start();
830 + * hw_crypto_ps_init
831 + * Init power save timer
833 +static inline void hw_crypto_ps_init(void)
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;
842 + * Initialize OCP security module lock and disables its clock.
844 +static inline void hw_crypto_init(void)
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();
856 + * Locks the OCP security module and enables its clock.
858 +static inline void hw_crypto_lock(void)
860 + spin_lock_bh(&crypto_ubicom32_lock);
864 + * hw_crypto_unlock()
865 + * Unlocks the OCP security module and disables its clock.
867 +static inline void hw_crypto_unlock(void)
869 + crypto_ubicom32_last_use = jiffies;
870 + spin_unlock_bh(&crypto_ubicom32_lock);
873 +#define CONFIG_CRYPTO_UBICOM32_DEBUG 1
875 +#ifdef CONFIG_CRYPTO_UBICOM32_DEBUG
876 +static inline void hex_dump(void *buf, int b_size, const char *msg)
881 + printk("%s:\t", msg);
884 + for (i=0; i < b_size; i++) {
885 + printk("%02x ", b[i]);
886 + if ((i & 3) == 3) {
889 + if ((i & 31) == 31) {
895 +#define UBICOM32_SEC_DUMP(a, b, c) hex_dump(a, b, c)
897 +#define UBICOM32_SEC_DUMP(a, b, c)
900 +#endif /* _CRYPTO_ARCH_UBICOM32_CRYPT_H */
902 +++ b/arch/ubicom32/crypto/des_check_key.c
905 + * arch/ubicom32/crypto/des_check_key.c
906 + * Ubicom32 architecture function for checking keys for the DES and
907 + * Tripple DES Encryption algorithms.
909 + * (C) Copyright 2009, Ubicom, Inc.
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.
917 + * Copyright IBM Corp. 2003
918 + * Author(s): Thomas Spatzier
919 + * Jan Glauber (jan.glauber@de.ibm.com)
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>
928 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
944 + * Ubicom32 implementation derived from (with many thanks):
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"
955 +#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o))
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,
969 + * RFC2451: Weak key checks SHOULD be performed.
972 +crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags)
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]];
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;
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;
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;
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;
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;
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;
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;
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;
1044 + *flags |= CRYPTO_TFM_RES_WEAK_KEY;
1048 +EXPORT_SYMBOL(crypto_des_check_key);
1050 +MODULE_LICENSE("GPL");
1051 +MODULE_DESCRIPTION("Key Check function for DES & DES3 Cipher Algorithms");
1053 +++ b/arch/ubicom32/crypto/des_ubicom32.c
1056 + * arch/ubicom32/crypto/des_ubicom32.c
1057 + * Ubicom32 implementation of the DES Cipher Algorithm.
1059 + * (C) Copyright 2009, Ubicom, Inc.
1061 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
1077 + * Ubicom32 implementation derived from (with many thanks):
1082 +#include <crypto/algapi.h>
1083 +#include <linux/init.h>
1084 +#include <linux/module.h>
1086 +#include "crypto_ubicom32.h"
1087 +extern int crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags);
1089 +#define DES_BLOCK_SIZE 8
1090 +#define DES_KEY_SIZE 8
1092 +#define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE)
1093 +#define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE
1095 +#define DES3_SUB_KEY(key, i) (((u8 *)key) + (i * DES_KEY_SIZE))
1110 +struct ubicom32_des_ctx {
1111 + u8 key[3 * DES_KEY_SIZE];
1116 +static inline void des_hw_set_key(const u8 *key, u8 key_len)
1119 + * HW 3DES is not tested yet, use DES just as ipOS
1124 +static inline void des_hw_cipher(u8 *out, const u8 *in)
1126 + SEC_SET_INPUT_2W(in);
1129 + " ; start DES by writing 0x38(SECURITY_BASE) \n\t"
1130 + " move.4 0x38(%0), #0x01 \n\t"
1131 + " pipe_flush 0 \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"
1141 + SEC_GET_OUTPUT_2W(out);
1145 +static void inline des3_hw_ede_encrypt(u8 *keys, u8 *out, const u8 *in)
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);
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);
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);
1160 +static void inline des3_hw_ede_decrypt(u8 *keys, u8 *out, const u8 *in)
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);
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);
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);
1176 +static void inline des3_hw_eee_encrypt(u8 *keys, u8 *out, const u8 *in)
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);
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);
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);
1191 +static void inline des3_hw_eee_decrypt(u8 *keys, u8 *out, const u8 *in)
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);
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);
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);
1207 +static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
1208 + unsigned int keylen)
1210 + struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
1211 + u32 *flags = &tfm->crt_flags;
1214 + /* test if key is valid (not a weak key) */
1215 + ret = crypto_des_check_key(key, keylen, flags);
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;
1226 +static inline void des_cipher_1b(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
1228 + const struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1231 + hw_crypto_check();
1232 + hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
1234 + des_hw_set_key(uctx->key, uctx->key_len);
1235 + des_hw_cipher(out, in);
1237 + hw_crypto_unlock();
1240 +static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1242 + des_cipher_1b(tfm, out, in, SEC_DIR_ENCRYPT);
1245 +static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1247 + des_cipher_1b(tfm, out, in, SEC_DIR_DECRYPT);
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),
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,
1272 +static void ecb_des_ciper_loop(u8 *out, u8 *in, unsigned int n)
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;
1282 +static void ecb_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1284 + while (likely(n)) {
1285 + des3_hw_ede_encrypt(keys, out, in);
1287 + out += DES_BLOCK_SIZE;
1288 + in += DES_BLOCK_SIZE;
1289 + n -= DES_BLOCK_SIZE;
1293 +static void ecb_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1295 + while (likely(n)) {
1296 + des3_hw_ede_decrypt(keys, out, in);
1298 + out += DES_BLOCK_SIZE;
1299 + in += DES_BLOCK_SIZE;
1300 + n -= DES_BLOCK_SIZE;
1305 +static void ecb_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1307 + while (likely(n)) {
1308 + des3_hw_eee_encrypt(keys, out, in);
1310 + out += DES_BLOCK_SIZE;
1311 + in += DES_BLOCK_SIZE;
1312 + n -= DES_BLOCK_SIZE;
1316 +static void ecb_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
1318 + while (likely(n)) {
1319 + des3_hw_eee_decrypt(keys, out, in);
1321 + out += DES_BLOCK_SIZE;
1322 + in += DES_BLOCK_SIZE;
1323 + n -= DES_BLOCK_SIZE;
1328 +static inline void ecb_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, unsigned int n)
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);
1339 + case DES3_EDE_ENCRYPT:
1340 + ecb_des3_ede_encrypt_loop(uctx->key, out, in, n);
1343 + case DES3_EDE_DECRYPT:
1344 + ecb_des3_ede_decrypt_loop(uctx->key, out, in, n);
1348 + case DES3_EEE_ENCRYPT:
1349 + ecb_des3_eee_encrypt_loop(uctx->key, out, in, n);
1352 + case DES3_EEE_DECRYPT:
1353 + ecb_des3_eee_decrypt_loop(uctx->key, out, in, n);
1359 +static inline void des_xor_2w(u32 *data, u32 *iv)
1365 +static void cbc_des_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
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;
1377 +static void cbc_des_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
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);
1386 + out += DES_BLOCK_SIZE;
1387 + in += DES_BLOCK_SIZE;
1388 + n -= DES_BLOCK_SIZE;
1392 +static void cbc_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
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);
1399 + out += DES_BLOCK_SIZE;
1400 + in += DES_BLOCK_SIZE;
1401 + n -= DES_BLOCK_SIZE;
1405 +static void cbc_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
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);
1414 + out += DES_BLOCK_SIZE;
1415 + in += DES_BLOCK_SIZE;
1416 + n -= DES_BLOCK_SIZE;
1421 +static void cbc_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
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);
1428 + out += DES_BLOCK_SIZE;
1429 + in += DES_BLOCK_SIZE;
1430 + n -= DES_BLOCK_SIZE;
1434 +static void cbc_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
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);
1443 + out += DES_BLOCK_SIZE;
1444 + in += DES_BLOCK_SIZE;
1445 + n -= DES_BLOCK_SIZE;
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)
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);
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);
1466 + case DES3_EDE_ENCRYPT:
1467 + cbc_des3_ede_encrypt_loop(uctx->key, out, in, iv, n);
1470 + case DES3_EDE_DECRYPT:
1471 + cbc_des3_ede_decrypt_loop(uctx->key, out, in, iv, n);
1475 + case DES3_EEE_ENCRYPT:
1476 + cbc_des3_eee_encrypt_loop(uctx->key, out, in, iv, n);
1479 + case DES3_EEE_DECRYPT:
1480 + cbc_des3_eee_decrypt_loop(uctx->key, out, in, iv, n);
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)
1489 + struct ubicom32_des_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
1492 + struct blkcipher_walk walk;
1493 + blkcipher_walk_init(&walk, dst, src, nbytes);
1494 + ret = blkcipher_walk_virt(desc, &walk);
1500 + hw_crypto_check();
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;
1508 + /* finish n/16 blocks */
1509 + if (extra_flags & SEC_CBC_SET) {
1510 + cbc_des_cipher_n(uctx, op, out, in, walk.iv, n);
1512 + ecb_des_cipher_n(uctx, op, out, in, n);
1515 + nbytes &= DES_BLOCK_SIZE - 1;
1516 + ret = blkcipher_walk_done(desc, &walk, nbytes);
1519 + hw_crypto_unlock();
1523 +static int ecb_des_encrypt(struct blkcipher_desc *desc,
1524 + struct scatterlist *dst, struct scatterlist *src,
1525 + unsigned int nbytes)
1527 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_ENCRYPT);
1530 +static int ecb_des_decrypt(struct blkcipher_desc *desc,
1531 + struct scatterlist *dst, struct scatterlist *src,
1532 + unsigned int nbytes)
1534 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_DECRYPT);
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),
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,
1559 +static int cbc_des_encrypt(struct blkcipher_desc *desc,
1560 + struct scatterlist *dst, struct scatterlist *src,
1561 + unsigned int nbytes)
1563 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_ENCRYPT);
1566 +static int cbc_des_decrypt(struct blkcipher_desc *desc,
1567 + struct scatterlist *dst, struct scatterlist *src,
1568 + unsigned int nbytes)
1570 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_DECRYPT);
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),
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,
1599 + * For DES-EDE3, there is no known need to reject weak or
1600 + * complementation keys. Any weakness is obviated by the use of
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
1609 +static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
1610 + unsigned int keylen)
1613 + struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
1614 + const u8 *temp_key = key;
1615 + u32 *flags = &tfm->crt_flags;
1617 + if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
1618 + memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
1621 + *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
1624 + for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
1625 + ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
1629 + memcpy(dctx->key, key, keylen);
1630 + dctx->ctrl = SEC_ALG_DES; //hw 3DES not working yet
1631 + dctx->key_len = keylen;
1635 +static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1637 + struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1640 + hw_crypto_check();
1642 + des3_hw_ede_encrypt(uctx->key, dst, src);
1644 + hw_crypto_unlock();
1647 +static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1649 + struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
1652 + hw_crypto_check();
1654 + des3_hw_ede_decrypt(uctx->key, dst, src);
1656 + hw_crypto_unlock();
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),
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,
1680 +static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
1681 + struct scatterlist *dst,
1682 + struct scatterlist *src, unsigned int nbytes)
1684 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_ENCRYPT);
1687 +static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
1688 + struct scatterlist *dst,
1689 + struct scatterlist *src, unsigned int nbytes)
1691 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_DECRYPT);
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),
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,
1717 +static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
1718 + struct scatterlist *dst,
1719 + struct scatterlist *src, unsigned int nbytes)
1721 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_ENCRYPT);
1724 +static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
1725 + struct scatterlist *dst,
1726 + struct scatterlist *src, unsigned int nbytes)
1728 + return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_DECRYPT);
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),
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,
1755 +static int init(void)
1761 + ret = crypto_register_alg(&des_alg);
1764 + ret = crypto_register_alg(&ecb_des_alg);
1767 + ret = crypto_register_alg(&cbc_des_alg);
1771 + ret = crypto_register_alg(&des3_192_alg);
1773 + goto des3_192_err;
1774 + ret = crypto_register_alg(&ecb_des3_192_alg);
1776 + goto ecb_des3_192_err;
1777 + ret = crypto_register_alg(&cbc_des3_192_alg);
1779 + goto cbc_des3_192_err;
1785 + crypto_unregister_alg(&ecb_des3_192_alg);
1787 + crypto_unregister_alg(&des3_192_alg);
1789 + crypto_unregister_alg(&cbc_des_alg);
1791 + crypto_unregister_alg(&ecb_des_alg);
1793 + crypto_unregister_alg(&des_alg);
1798 +static void __exit fini(void)
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);
1811 +MODULE_ALIAS("des");
1812 +MODULE_ALIAS("des3_ede");
1814 +MODULE_LICENSE("GPL");
1815 +MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
1817 +++ b/arch/ubicom32/crypto/Makefile
1820 +# arch/ubicom32/crypto/Makefile
1821 +# <TODO: Replace with short file description>
1823 +# (C) Copyright 2009, Ubicom, Inc.
1825 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
1841 +# Ubicom32 implementation derived from (with many thanks):
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
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
1856 +++ b/arch/ubicom32/crypto/md5_ubicom32_asm.S
1859 + * arch/ubicom32/crypto/md5_ubicom32_asm.S
1860 + * MD5 (Message Digest 5) support for Ubicom32 v3 architecture
1862 + * (C) Copyright 2009, Ubicom, Inc.
1864 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
1880 + * Ubicom32 implementation derived from (with many thanks):
1887 +#include <asm/ip5000.h>
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)
1900 +;*****************************************************************************************
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.
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.
1910 +;*****************************************************************************************
1912 +;*****************************************************************************************
1915 +;*****************************************************************************************
1916 +; An: Address Registers
1917 +;*****************************************************************************************
1918 +#define an_digest A3
1919 +#define an_data_input A3
1920 +#define an_security_block A4
1922 +;*****************************************************************************************
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
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)
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)
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)
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)
1955 +;*****************************************************************************************
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
1965 +;*****************************************************************************************
1966 +; void md5_ip5k_init(void)
1967 +; initialize the output registers of the hash module
1969 + ;.section .text.md5_ip5k_init,"ax",@progbits
1971 + .global _md5_ip5k_init
1972 + .func md5_ip5k_init, _md5_ip5k_init
1975 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
1977 + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
1978 + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
1980 + movei hash_output_0, #%hi(HASH_MD5_IN0)
1981 + movei hash_output_0_low, #%lo(HASH_MD5_IN0)
1983 + movei hash_output_1, #%hi(HASH_MD5_IN1)
1984 + movei hash_output_1_low, #%lo(HASH_MD5_IN1)
1986 + movei hash_output_2, #%hi(HASH_MD5_IN2)
1987 + movei hash_output_2_low, #%lo(HASH_MD5_IN2)
1989 + movei hash_output_3, #%hi(HASH_MD5_IN3)
1990 + movei hash_output_3_low, #%lo(HASH_MD5_IN3)
1996 +;*****************************************************************************************
1997 +; void md5_ip5k_init_digest(u32_t *hash_input)
1998 +; initialize the output registers of the hash module
2000 + ;.section .text.md5_ip5k_init_digest,"ax",@progbits
2002 + .global _md5_ip5k_init_digest
2003 + .func md5_ip5k_init_digest, _md5_ip5k_init_digest
2005 +_md5_ip5k_init_digest:
2006 + movea an_data_input, D0
2008 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2010 + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
2011 + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
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++
2021 +;*****************************************************************************************
2022 +; void md5_ip5k_transform(u32_t *data_input)
2023 +; performs intermediate transformation step for the hash calculation
2025 + ;.sect .text.md5_ip5k_transform,"ax",@progbits
2027 + .global _md5_ip5k_transform
2028 + .func md5_ip5k_transform, _md5_ip5k_transform
2030 +_md5_ip5k_transform:
2031 + movea an_data_input, D0
2033 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
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
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
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
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
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
2070 +;*****************************************************************************************
2071 +; void md5_ip5k_get_digest(u32_t *digest)
2072 +; Return the hash of the input data
2074 + ;.sect .text.md5_get_digest,"ax",@progbits
2076 + .global _md5_ip5k_get_digest
2077 + .func md5_ip5k_get_digest, _md5_ip5k_get_digest
2079 +_md5_ip5k_get_digest:
2080 + movea an_digest, D0
2082 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
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
2094 +++ b/arch/ubicom32/crypto/md5_ubicom32.c
2097 + * arch/ubicom32/crypto/md5_ubicom32.c
2098 + * Ubicom32 implementation of the MD5 Secure Hash Algorithm
2100 + * (C) Copyright 2009, Ubicom, Inc.
2102 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
2118 + * Ubicom32 implementation derived from (with many thanks):
2123 +#include <linux/init.h>
2124 +#include <linux/module.h>
2125 +#include <linux/crypto.h>
2127 +#include "crypto_ubicom32.h"
2129 +#define MD5_DIGEST_SIZE 16
2130 +#define MD5_BLOCK_SIZE 64
2131 +#define MD5_HASH_WORDS 4
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);
2137 +struct ubicom32_md5_ctx {
2138 + u64 count; /* message length */
2139 + u32 state[MD5_HASH_WORDS];
2140 + u8 buf[2 * MD5_BLOCK_SIZE];
2143 +static void md5_init(struct crypto_tfm *tfm)
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;
2154 +static inline void _md5_process(u32 *digest, const u8 *data)
2156 + _md5_ip5k_transform((u32 *)data);
2159 +static void md5_update(struct crypto_tfm *tfm, const u8 *data,
2162 + struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
2165 + /* how much is already in the buffer? */
2166 + index = mctx->count & 0x3f;
2168 + mctx->count += len;
2170 + if (index + len < MD5_BLOCK_SIZE) {
2175 + hw_crypto_check();
2177 + /* init digest set ctrl register too */
2178 + _md5_ip5k_init_digest(mctx->state);
2180 + if (unlikely(index == 0 && SEC_ALIGNED(data))) {
2182 + while (len >= MD5_BLOCK_SIZE) {
2183 + _md5_process(mctx->state, data);
2184 + data += MD5_BLOCK_SIZE;
2185 + len -= MD5_BLOCK_SIZE;
2190 + /* process one stored block */
2192 + clen = MD5_BLOCK_SIZE - index;
2193 + memcpy(mctx->buf + index, data, clen);
2194 + _md5_process(mctx->state, mctx->buf);
2200 + if (likely(SEC_ALIGNED(data))) {
2201 + goto fast_process;
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;
2213 + _md5_ip5k_get_digest(mctx->state);
2214 + hw_crypto_unlock();
2217 + /* anything left? */
2219 + memcpy(mctx->buf + index , data, len);
2222 +/* Add padding and return the message digest. */
2223 +static void md5_final(struct crypto_tfm *tfm, u8 *out)
2225 + struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
2227 + unsigned int index, end;
2229 + /* must perform manual padding */
2230 + index = mctx->count & 0x3f;
2231 + end = (index < 56) ? MD5_BLOCK_SIZE : (2 * MD5_BLOCK_SIZE);
2233 + /* start pad with 1 */
2234 + mctx->buf[index] = 0x80;
2236 + /* pad with zeros */
2238 + memset(mctx->buf + index, 0x00, end - index - 8);
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);
2246 + memcpy(mctx->buf + end - 8, &bits, sizeof(bits));
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);
2252 + /* copy digest to out */
2253 + memcpy(out, mctx->state, MD5_DIGEST_SIZE);
2255 + /* wipe context */
2256 + memset(mctx, 0, sizeof *mctx);
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),
2270 + .dia_digestsize = MD5_DIGEST_SIZE,
2271 + .dia_init = md5_init,
2272 + .dia_update = md5_update,
2273 + .dia_final = md5_final,
2278 +static int __init init(void)
2281 + return crypto_register_alg(&alg);
2284 +static void __exit fini(void)
2286 + crypto_unregister_alg(&alg);
2292 +MODULE_ALIAS("md5");
2294 +MODULE_LICENSE("GPL");
2295 +MODULE_DESCRIPTION("MD5 Secure Hash Algorithm");
2297 +++ b/arch/ubicom32/crypto/sha1_ubicom32_asm.S
2300 + * arch/ubicom32/crypto/sha1_ubicom32_asm.S
2301 + * SHA1 hash support for Ubicom32 architecture V3.
2303 + * (C) Copyright 2009, Ubicom, Inc.
2305 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
2321 + * Ubicom32 implementation derived from (with many thanks):
2328 +#include <asm/ip5000.h>
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)
2341 +;*****************************************************************************************
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.
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.
2351 +;*****************************************************************************************
2353 +;*****************************************************************************************
2356 +;*****************************************************************************************
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
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)
2368 +;*****************************************************************************************
2369 +; An: Address Registers
2370 +;*****************************************************************************************
2371 +#define an_digest a4
2372 +#define an_data_input a4
2373 +#define an_security_block a3
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)
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)
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)
2399 +;*****************************************************************************************
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
2408 +;*****************************************************************************************
2409 +; void sha1_ip5k_init(void)
2410 +; initialize the output registers of the hash module
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
2418 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2420 + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2421 + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2423 + movei hash_output_0, #%hi(HASH_SHA1_IN0)
2424 + movei hash_output_0_low, #%lo(HASH_SHA1_IN0)
2426 + movei hash_output_1, #%hi(HASH_SHA1_IN1)
2427 + movei hash_output_1_low, #%lo(HASH_SHA1_IN1)
2429 + movei hash_output_2, #%hi(HASH_SHA1_IN2)
2430 + movei hash_output_2_low, #%lo(HASH_SHA1_IN2)
2432 + movei hash_output_3, #%hi(HASH_SHA1_IN3)
2433 + movei hash_output_3_low, #%lo(HASH_SHA1_IN3)
2435 + movei hash_output_4, #%hi(HASH_SHA1_IN4)
2436 + movei hash_output_4_low, #%lo(HASH_SHA1_IN4)
2441 +;*****************************************************************************************
2442 +; void sha1_ip5k_init_digest(u32_t *hash_input)
2443 +; initialize the output registers of the hash module
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
2450 +_sha1_ip5k_init_digest:
2451 + movea an_data_input, D0
2453 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
2455 + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
2456 + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
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++
2467 +;*****************************************************************************************
2468 +; void sha1_ip5k_transform(u32_t *data_input)
2469 +; performs intermediate transformation step for the hash calculation
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
2476 +_sha1_ip5k_transform:
2477 + movea an_data_input, D0
2479 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
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
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
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
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
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
2516 +;*****************************************************************************************
2517 +; void sha1_ip5k_output(u32_t *digest)
2518 +; Return the hash of the input data
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
2526 + movea an_digest, D0
2528 + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
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
2540 +;*****************************************************************************************
2541 +;END ;End of program code
2542 +;*****************************************************************************************
2544 +++ b/arch/ubicom32/crypto/sha1_ubicom32.c
2547 + * arch/ubicom32/crypto/sha1_ubicom32.c
2548 + * Ubicom32 implementation of the SHA1 Secure Hash Algorithm.
2550 + * (C) Copyright 2009, Ubicom, Inc.
2552 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
2568 + * Ubicom32 implementation derived from (with many thanks):
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>
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)
2583 +struct ubicom32_sha1_ctx {
2584 + u64 count; /* message length */
2586 + u8 buf[2 * SHA1_BLOCK_SIZE];
2589 +static inline void sha1_clear_2ws(u8 *buf, int wc)
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"
2597 + : "a" (buf), "d" (wc)
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)
2605 +static inline void sha1_init_digest(u32 *digest)
2607 + hw_crypto_set_ctrl(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1);
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"
2616 + : "a" (SEC_BASE), "a" (digest)
2620 +static inline void sha1_transform_feed(const u8 *in)
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"
2649 + : "a"(SEC_BASE), "a"(in)
2653 +static inline void sha1_transform_wait(void)
2656 + " btst 0x04(%0), #0 \n\t"
2657 + " jmpne.f -4 \n\t"
2664 +static inline void sha1_output_digest(u32 *digest)
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"
2673 + : "a" (SEC_BASE), "a" (digest)
2677 +static __ocm_text void sha1_init(struct crypto_tfm *tfm)
2679 + struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
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;
2689 +static void __ocm_text sha1_update(struct crypto_tfm *tfm, const u8 *data,
2692 + struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
2695 + /* how much is already in the buffer? */
2696 + index = sctx->count & 0x3f;
2698 + sctx->count += len;
2700 + if (index + len < SHA1_BLOCK_SIZE) {
2705 + hw_crypto_check();
2707 + /* init digest set ctrl register too */
2708 + sha1_init_digest(sctx->state);
2710 + if (unlikely(index == 0 && SEC_ALIGNED(data))) {
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;
2718 + /* cnt is pre-decremented in the loop */
2720 + "; while (--loop): work on 2nd block \n\t"
2721 + "1: add.4 %2, #-1, %2 \n\t"
2722 + " jmpeq.f 5f \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"
2732 + " btst 0x04(%1), #0 \n\t"
2733 + " jmpne.f -4 \n\t"
2735 + " ; tell hw to load 1st 16 bytes \n\t"
2736 + " move.4 0x40(%1), %2 \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"
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"
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"
2759 + "; no need flush, enough insts \n\t"
2760 + "; before next hw wait \n\t"
2762 + "; go back to loop \n\t"
2765 + "; wait hw for last block \n\t"
2766 + "5: btst 0x04(%1), #0 \n\t"
2767 + " jmpne.f -4 \n\t"
2770 + : "a"( SEC_BASE), "d" (cnt)
2774 + len = len & (64 - 1);
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();
2787 + /* process one stored block */
2789 + clen = SHA1_BLOCK_SIZE - index;
2790 + memcpy(sctx->buf + index, data, clen);
2791 + sha1_transform_feed(sctx->buf);
2795 + sha1_transform_wait();
2798 + if (likely(SEC_ALIGNED(data))) {
2799 + goto fast_process;
2802 + /* process as many blocks as possible */
2803 + if (likely(len >= SHA1_BLOCK_SIZE)) {
2804 + memcpy(sctx->buf, data, SHA1_BLOCK_SIZE);
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();
2814 + /* it is the last block */
2815 + sha1_transform_wait();
2821 + sha1_output_digest(sctx->state);
2822 + hw_crypto_unlock();
2825 + /* anything left? */
2827 + memcpy(sctx->buf + index , data, len);
2830 +/* Add padding and return the message digest. */
2831 +static void __ocm_text sha1_final(struct crypto_tfm *tfm, u8 *out)
2833 + struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
2835 + unsigned int index, end;
2837 + /* must perform manual padding */
2838 + index = sctx->count & 0x3f;
2839 + end = (index < 56) ? SHA1_BLOCK_SIZE : (2 * SHA1_BLOCK_SIZE);
2841 + /* start pad with 1 */
2842 + sctx->buf[index] = 0x80;
2844 + /* pad with zeros */
2846 + memset(sctx->buf + index, 0x00, end - index - 8);
2848 + /* append message length */
2849 + bits = sctx->count << 3 ;
2850 + SEC_COPY_2W(sctx->buf + end - 8, &bits);
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);
2856 + /* copy digest to out */
2857 + SEC_COPY_5W(out, sctx->state);
2859 + /* wipe context */
2860 + sha1_wipe_out(sctx);
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),
2874 + .dia_digestsize = SHA1_DIGEST_SIZE,
2875 + .dia_init = sha1_init,
2876 + .dia_update = sha1_update,
2877 + .dia_final = sha1_final,
2882 +static int __init init(void)
2885 + return crypto_register_alg(&alg);
2888 +static void __exit fini(void)
2890 + crypto_unregister_alg(&alg);
2896 +MODULE_ALIAS("sha1");
2898 +MODULE_LICENSE("GPL");
2899 +MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
2901 +++ b/arch/ubicom32/include/asm/a.out.h
2904 + * arch/ubicom32/include/asm/a.out.h
2905 + * Definitions for Ubicom32 a.out executable format.
2907 + * (C) Copyright 2009, Ubicom, Inc.
2909 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
2925 + * Ubicom32 implementation derived from (with many thanks):
2930 +#ifndef _ASM_UBICOM32_A_OUT_H
2931 +#define _ASM_UBICOM32_A_OUT_H
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 */
2945 +#define N_TRSIZE(a) ((a).a_trsize)
2946 +#define N_DRSIZE(a) ((a).a_drsize)
2947 +#define N_SYMSIZE(a) ((a).a_syms)
2949 +#endif /* _ASM_UBICOM32_A_OUT_H */
2951 +++ b/arch/ubicom32/include/asm/atomic.h
2954 + * arch/ubicom32/include/asm/atomic.h
2955 + * Atomic operations definitions for Ubicom32 architecture.
2957 + * (C) Copyright 2009, Ubicom, Inc.
2959 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
2975 + * Ubicom32 implementation derived from (with many thanks):
2980 +#ifndef _ASM_UBICOM32_ATOMIC_H
2981 +#define _ASM_UBICOM32_ATOMIC_H
2983 +#include <asm/system.h>
2984 +#include <asm/ubicom32-common.h>
2985 +#include <asm/types.h>
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.
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
2999 + * Do not attempt to disable interrupts while holding the atomic operations
3000 + * lock or you will DEADLOCK the system.
3004 + volatile int counter;
3007 +#define ATOMIC_INIT(i) { (i) }
3011 + * Add i to v and return the result.
3013 +static inline void __atomic_add(int i, atomic_t *v)
3017 + __atomic_lock_acquire();
3019 + __atomic_lock_release();
3024 + * Subtract i from v and return the result.
3026 +static inline void __atomic_sub(int i, atomic_t *v)
3030 + __atomic_lock_acquire();
3032 + __atomic_lock_release();
3036 + * __atomic_add_return()
3037 + * Add i to v and return the result.
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!
3048 + * At the worst we save one instruction inside the atomic lock.
3050 +static inline int __atomic_add_return(int i, atomic_t *v)
3055 + __atomic_lock_acquire();
3056 + ret = vt->counter;
3057 + vt->counter = ret + i;
3058 + __atomic_lock_release();
3064 + * __atomic_sub_return()
3065 + * Subtract i from v and return the result.
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!
3076 + * At the worst we save one instruction inside the atomic lock.
3078 +static inline int __atomic_sub_return(int i, atomic_t *v)
3083 + __atomic_lock_acquire();
3084 + ret = vt->counter;
3085 + vt->counter = ret - i;
3086 + __atomic_lock_release();
3092 + * PUBLIC API FOR ATOMIC!
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)
3109 + * Acquire the atomic lock and read the variable.
3111 +static inline int atomic_read(const atomic_t *v)
3114 + const atomic_t *vt = v;
3116 + __atomic_lock_acquire();
3117 + ret = vt->counter;
3118 + __atomic_lock_release();
3125 + * Acquire the atomic lock and set the variable.
3127 +static inline void atomic_set(atomic_t *v, int i)
3131 + __atomic_lock_acquire();
3133 + __atomic_lock_release();
3138 + * Acquire the atomic lock and exchange if current == old.
3140 +static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
3145 + __atomic_lock_acquire();
3146 + prev = vt->counter;
3147 + if (prev == old) {
3148 + vt->counter = new;
3150 + __atomic_lock_release();
3157 + * Acquire the atomic lock and exchange values.
3159 +static inline int atomic_xchg(atomic_t *v, int new)
3164 + __atomic_lock_acquire();
3165 + prev = vt->counter;
3166 + vt->counter = new;
3167 + __atomic_lock_release();
3173 + * atomic_add_unless()
3174 + * Acquire the atomic lock and add a unless the value is u.
3176 +static inline int atomic_add_unless(atomic_t *v, int a, int u)
3181 + __atomic_lock_acquire();
3182 + prev = vt->counter;
3185 + __atomic_lock_release();
3189 + __atomic_lock_release();
3193 +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
3195 +#include <asm-generic/atomic.h>
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.
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).
3207 +extern void __xchg_called_with_bad_pointer(void) __attribute__((noreturn));
3211 + * Xchange *ptr for x atomically.
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.
3216 +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
3218 + unsigned long ret;
3220 + __atomic_lock_acquire();
3224 + ret = *(volatile unsigned char *)ptr;
3225 + *(volatile unsigned char *)ptr = x;
3229 + ret = *(volatile unsigned short *)ptr;
3230 + *(volatile unsigned short *)ptr = x;
3234 + ret = *(volatile unsigned int *)ptr;
3235 + *(volatile unsigned int *)ptr = x;
3239 + __xchg_called_with_bad_pointer();
3242 + __atomic_lock_release();
3246 +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
3250 + * Compare and Xchange *ptr for x atomically.
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.
3255 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long next, int size)
3257 + unsigned long prev;
3259 + __atomic_lock_acquire();
3262 + prev = *(u8 *)ptr;
3263 + if (prev == old) {
3264 + *(u8 *)ptr = (u8)next;
3269 + prev = *(u16 *)ptr;
3270 + if (prev == old) {
3271 + *(u16 *)ptr = (u16)next;
3276 + prev = *(u32 *)ptr;
3277 + if (prev == old) {
3278 + *(u32 *)ptr = (u32)next;
3283 + __xchg_called_with_bad_pointer();
3286 + __atomic_lock_release();
3291 + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
3294 +#define cmpxchg_local(ptr, o, n) \
3295 + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
3297 +#define cmpxchg(ptr, o, n) __cmpxchg((ptr), (o), (n), sizeof(*(ptr)))
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")
3304 +#endif /* _ASM_UBICOM32_ATOMIC_H */
3306 +++ b/arch/ubicom32/include/asm/audio_tio.h
3309 + * arch/ubicom32/include/asm/audio_tio.h
3310 + * AudioTIO include file
3312 + * (C) Copyright 2009, Ubicom, Inc.
3314 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3331 +#ifndef _AUDIO_TIO_H
3332 +#define _AUDIO_TIO_H
3334 +#include <asm/devtree.h>
3335 +#include <asm/ubi32-pcm.h>
3337 +#define UBI32_AUDIO_INT_FLAG_MORE_SAMPLES 0x00000001
3338 +#define UBI32_AUDIO_INT_FLAG_COMMAND 0x00000002
3341 + * Commands the Primary OS sends to the audio device
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,
3357 + * Flag bits passed in the registers
3359 +#define UBI32_CMD_SETUP_FLAG_LE (1 << 0) /* Use Little Endian Mode */
3362 + * Status bits that audio device can set to indicate reason
3363 + * for interrupting the Primary OS
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 */
3368 +struct ubi32_audio_dma {
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.
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
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 */
3385 +#define AUDIOTIONODE_CAP_BE (1 << 0)
3386 +#define AUDIOTIONODE_CAP_LE (1 << 1)
3389 + * Resource indices used to access IRQs via platform_get_resource
3391 +#define AUDIOTIO_MEM_RESOURCE 0
3392 +#define AUDIOTIO_TX_IRQ_RESOURCE 0
3393 +#define AUDIOTIO_RX_IRQ_RESOURCE 1
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;
3402 +#define AUDIOTIOREGS_VERSION 3
3403 +struct audiotioregs {
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 */
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.
3422 + * NOTE: The active bit shall always be SET by the producer and
3423 + * CLEARED by the consumer, NEVER the other way around.
3425 + struct ubi32_audio_dma playback_xfer_requests[2];
3428 +extern struct platform_device * __init audio_tio_alloc(const char *driver_name, const char *node_name, int priv_size);
3430 +#define audio_tio_priv(pdev) (((struct ubi32pcm_platform_data *)(((struct platform_device *)(pdev))->dev.platform_data))->priv_data)
3433 +++ b/arch/ubicom32/include/asm/auxvec.h
3436 + * arch/ubicom32/include/asm/auxvec.h
3437 + * Symbolic values for the entries in the auxiliary table
3438 + * put on the initial stack.
3440 + * (C) Copyright 2009, Ubicom, Inc.
3442 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3458 + * Ubicom32 implementation derived from (with many thanks):
3463 +#ifndef _ASM_UBICOM32_AUXVEC_H
3464 +#define _ASM_UBICOM32_AUXVEC_H
3466 +#endif /* _ASM_UBICOM32_AUXVEC_H */
3468 +++ b/arch/ubicom32/include/asm/bitops.h
3471 + * arch/ubicom32/include/asm/bitops.h
3472 + * Bit manipulation definitions for Ubicom32 architecture.
3474 + * (C) Copyright 2009, Ubicom, Inc.
3476 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3492 + * Ubicom32 implementation derived from (with many thanks):
3497 +#ifndef _ASM_UBICOM32_BITOPS_H
3498 +#define _ASM_UBICOM32_BITOPS_H
3501 + * Copyright 1992, Linus Torvalds.
3504 +#include <linux/compiler.h>
3505 +#include <asm/byteorder.h> /* swab32 */
3509 +#ifndef _LINUX_BITOPS_H
3510 +#error only <linux/bitops.h> can be included directly
3513 +#include <asm-generic/bitops/ffs.h>
3514 +#include <asm-generic/bitops/__ffs.h>
3516 +#include <asm-generic/bitops/sched.h>
3517 +#include <asm-generic/bitops/ffz.h>
3519 +#include <asm/ubicom32-common.h>
3521 +static inline void set_bit(int bit, volatile unsigned long *p)
3523 + unsigned long mask = 1UL << (bit & 31);
3527 + __atomic_lock_acquire();
3529 + __atomic_lock_release();
3532 +static inline void clear_bit(int bit, volatile unsigned long *p)
3534 + unsigned long mask = 1UL << (bit & 31);
3538 + __atomic_lock_acquire();
3540 + __atomic_lock_release();
3544 + * clear_bit() doesn't provide any barrier for the compiler.
3546 +#define smp_mb__before_clear_bit() barrier()
3547 +#define smp_mb__after_clear_bit() barrier()
3549 +static inline void change_bit(int bit, volatile unsigned long *p)
3551 + unsigned long mask = 1UL << (bit & 31);
3555 + __atomic_lock_acquire();
3557 + __atomic_lock_release();
3560 +static inline int test_and_set_bit(int bit, volatile unsigned long *p)
3563 + unsigned long mask = 1UL << (bit & 31);
3567 + __atomic_lock_acquire();
3570 + __atomic_lock_release();
3572 + return res & mask;
3575 +static inline int test_and_clear_bit(int bit, volatile unsigned long *p)
3578 + unsigned long mask = 1UL << (bit & 31);
3582 + __atomic_lock_acquire();
3585 + __atomic_lock_release();
3587 + return res & mask;
3590 +static inline int test_and_change_bit(int bit, volatile unsigned long *p)
3593 + unsigned long mask = 1UL << (bit & 31);
3597 + __atomic_lock_acquire();
3600 + __atomic_lock_release();
3602 + return res & mask;
3605 +#include <asm-generic/bitops/non-atomic.h>
3608 + * This routine doesn't need to be atomic.
3610 +static inline int __constant_test_bit(int nr, const volatile unsigned long *addr)
3612 + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
3615 +static inline int __test_bit(int nr, const volatile unsigned long *addr)
3617 + int * a = (int *) addr;
3621 + mask = 1 << (nr & 0x1f);
3622 + return ((mask & *a) != 0);
3625 +#define test_bit(nr,addr) (__builtin_constant_p(nr) ? __constant_test_bit((nr),(addr)) : __test_bit((nr),(addr)))
3627 +#include <asm-generic/bitops/find.h>
3628 +#include <asm-generic/bitops/hweight.h>
3629 +#include <asm-generic/bitops/lock.h>
3631 +#include <asm-generic/bitops/ext2-non-atomic.h>
3632 +#include <asm-generic/bitops/ext2-atomic.h>
3633 +#include <asm-generic/bitops/minix.h>
3635 +#endif /* __KERNEL__ */
3637 +#include <asm-generic/bitops/fls.h>
3638 +#include <asm-generic/bitops/fls64.h>
3640 +#endif /* _ASM_UBICOM32_BITOPS_H */
3642 +++ b/arch/ubicom32/include/asm/board.h
3645 + * arch/ubicom32/include/asm/board.h
3646 + * Board init and revision definitions for Ubicom32 architecture.
3648 + * (C) Copyright 2009, Ubicom, Inc.
3650 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3666 + * Ubicom32 implementation derived from (with many thanks):
3671 +#ifndef _ASM_UBICOM32_BOARD_H
3672 +#define _ASM_UBICOM32_BOARD_H
3674 +extern const char *board_get_revision(void);
3675 +extern void __init board_init(void);
3677 +#endif /* _ASM_UBICOM32_BOARD_H */
3679 +++ b/arch/ubicom32/include/asm/bootargs.h
3682 + * arch/ubicom32/include/asm/bootargs.h
3683 + * Kernel command line via the devtree API.
3685 + * (C) Copyright 2009, Ubicom, Inc.
3687 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3703 + * Ubicom32 implementation derived from (with many thanks):
3708 +#ifndef _ASM_UBICOM32_BOOTARGS_H
3709 +#define _ASM_UBICOM32_BOOTARGS_H
3711 +extern const char *bootargs_get_cmdline(void);
3712 +extern void __init bootargs_init(void);
3714 +#endif /* _ASM_UBICOM32_BOOTARGS_H */
3716 +++ b/arch/ubicom32/include/asm/bootinfo.h
3719 + * arch/ubicom32/include/asm/bootinfo.h
3720 + * Definitions of firmware boot parameters passed to the kernel.
3722 + * (C) Copyright 2009, Ubicom, Inc.
3724 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3740 + * Ubicom32 implementation derived from (with many thanks):
3746 +#ifndef _ASM_UBICOM32_BOOTINFO_H
3747 +#define _ASM_UBICOM32_BOOTINFO_H
3749 +/* Nothing for ubicom32 */
3751 +#endif /* _ASM_UBICOM32_BOOTINFO_H */
3753 +++ b/arch/ubicom32/include/asm/bug.h
3756 + * arch/ubicom32/include/asm/bug.h
3757 + * Generic bug.h for Ubicom32 architecture.
3759 + * (C) Copyright 2009, Ubicom, Inc.
3761 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3777 + * Ubicom32 implementation derived from (with many thanks):
3782 +#ifndef _ASM_UBICOM32_BUG_H
3783 +#define _ASM_UBICOM32_BUG_H
3785 +#include <linux/kernel.h>
3786 +#include <asm/thread.h>
3788 +#if defined(CONFIG_STOP_ON_BUG)
3791 + * Stall all threads to enable debugging.
3793 +static inline void __BUG_ON(unsigned long c)
3795 + if (unlikely(c)) {
3801 +#define BUG_ON(c) __BUG_ON((unsigned long)(c))
3802 +#define HAVE_ARCH_BUG_ON
3805 +#include <asm-generic/bug.h>
3807 +#endif /* _ASM_UBICOM32_BUG_H */
3809 +++ b/arch/ubicom32/include/asm/bugs.h
3812 + * arch/ubicom32/include/asm/bugs.h
3813 + * Definition of check_bugs() for Ubicom32 architecture.
3815 + * (C) Copyright 2009, Ubicom, Inc.
3816 + * Copyright (C) 1994 Linus Torvalds
3818 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3834 + * Ubicom32 implementation derived from (with many thanks):
3841 + * This is included by init/main.c to check for architecture-dependent bugs.
3844 + * void check_bugs(void);
3847 +#ifndef _ASM_UBICOM32_BUGS_H
3848 +#define _ASM_UBICOM32_BUGS_H
3850 +static void check_bugs(void)
3854 +#endif /* _ASM_UBICOM32_BUGS_H */
3856 +++ b/arch/ubicom32/include/asm/byteorder.h
3859 + * arch/ubicom32/include/asm/byteorder.h
3860 + * Byte order swapping utility routines.
3862 + * (C) Copyright 2009, Ubicom, Inc.
3864 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3880 + * Ubicom32 implementation derived from (with many thanks):
3885 +#ifndef _ASM_UBICOM32_BYTEORDER_H
3886 +#define _ASM_UBICOM32_BYTEORDER_H
3888 +#include <linux/types.h>
3890 +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
3891 +# define __BYTEORDER_HAS_U64__
3892 +# define __SWAB_64_THRU_32__
3895 +#if defined(IP7000) || defined(IP7000_REV2)
3897 +#define __arch__swab16 __builtin_ubicom32_swapb_2
3898 +#define __arch__swab32 __builtin_ubicom32_swapb_4
3900 +#endif /* IP7000 */
3902 +#include <linux/byteorder/big_endian.h>
3904 +#endif /* _ASM_UBICOM32_BYTEORDER_H */
3907 +++ b/arch/ubicom32/include/asm/cachectl.h
3910 + * arch/ubicom32/include/asm/cachectl.h
3911 + * Ubicom32 cache control definitions.
3913 + * (C) Copyright 2009, Ubicom, Inc.
3915 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3931 + * Ubicom32 implementation derived from (with many thanks):
3936 +#ifndef _ASM_UBICOM32_CACHECTL_H
3937 +#define _ASM_UBICOM32_CACHECTL_H
3939 +#include <asm/ip5000.h>
3942 + * mem_cache_control()
3943 + * Special cache control operation
3945 +extern void mem_cache_control(unsigned long cc, unsigned long begin_addr, unsigned long end_addr, unsigned long op);
3947 +#endif /* _ASM_UBICOM32_CACHECTL_H */
3949 +++ b/arch/ubicom32/include/asm/cacheflush.h
3952 + * arch/ubicom32/include/asm/cacheflush.h
3953 + * Cache flushing definitions for Ubicom32 architecture.
3955 + * (C) Copyright 2009, Ubicom, Inc.
3957 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
3973 + * Ubicom32 implementation derived from (with many thanks):
3978 +#ifndef _ASM_UBICOM32_CACHEFLUSH_H
3979 +#define _ASM_UBICOM32_CACHEFLUSH_H
3982 + * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
3984 +#include <linux/mm.h>
3985 +#include <asm/cachectl.h>
3986 +#include <asm/ip5000.h>
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)
3997 +#define flush_dcache_range(start, end) \
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(); \
4006 +#define flush_icache_range(start, end) \
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(); \
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)
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)
4026 + * Cache handling for IP5000
4028 +extern inline void mem_cache_invalidate_all(unsigned long cc)
4031 + " bset "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)" \n\t"
4033 + " bclr "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)" \n\t"
4034 + " pipe_flush 0 \n\t"
4041 +static inline void __flush_cache_all(void)
4046 + mem_cache_invalidate_all(ICCR_BASE);
4051 + mem_cache_invalidate_all(DCCR_BASE);
4054 +#endif /* _ASM_UBICOM32_CACHEFLUSH_H */
4056 +++ b/arch/ubicom32/include/asm/cache.h
4059 + * arch/ubicom32/include/asm/cache.h
4060 + * Cache line definitions for Ubicom32 architecture.
4062 + * (C) Copyright 2009, Ubicom, Inc.
4064 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4080 + * Ubicom32 implementation derived from (with many thanks):
4085 +#ifndef _ASM_UBICOM32_CACHE_H
4086 +#define _ASM_UBICOM32_CACHE_H
4089 + * bytes per L1 cache line
4091 +#define L1_CACHE_SHIFT 5
4092 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
4094 +#define __cacheline_aligned
4095 +#define ____cacheline_aligned
4097 +#endif /* _ASM_UBICOM32_CACHE_H */
4099 +++ b/arch/ubicom32/include/asm/checksum.h
4102 + * arch/ubicom32/include/asm/checksum.h
4103 + * Checksum utilities for Ubicom32 architecture.
4105 + * (C) Copyright 2009, Ubicom, Inc.
4107 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4123 + * Ubicom32 implementation derived from (with many thanks):
4128 +#ifndef _ASM_UBICOM32_CHECKSUM_H
4129 +#define _ASM_UBICOM32_CHECKSUM_H
4131 +#include <linux/in6.h>
4134 + * computes the checksum of a memory block at buff, length len,
4135 + * and adds in "sum" (32-bit)
4137 + * returns a 32-bit number suitable for feeding into itself
4138 + * or csum_tcpudp_magic
4140 + * this function must be called with even lengths, except
4141 + * for the last fragment, which may be odd
4143 + * it's best to have buff aligned on a 32-bit boundary
4145 +__wsum csum_partial(const void *buff, int len, __wsum sum);
4148 + * the same as csum_partial, but copies from src while it
4151 + * here even more important to align src and dst on a 32-bit (or even
4152 + * better 64-bit) boundary
4155 +__wsum csum_partial_copy_nocheck(const void *src, void *dst,
4156 + int len, __wsum sum);
4160 + * the same as csum_partial_copy, but copies from user space.
4162 + * here even more important to align src and dst on a 32-bit (or even
4163 + * better 64-bit) boundary
4166 +extern __wsum csum_partial_copy_from_user(const void __user *src,
4167 + void *dst, int len, __wsum sum, int *csum_err);
4169 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
4172 + * Fold a partial checksum
4175 +static inline __sum16 csum_fold(__wsum sum)
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"
4188 + return (__force __sum16)~sum;
4193 + * computes the checksum of the TCP/UDP pseudo-header
4194 + * returns a 16-bit checksum, already complemented
4197 +static inline __wsum
4198 +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
4199 + unsigned short proto, __wsum sum)
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"
4208 + : "0"(sum), "r" (saddr), "r" (daddr), "r" (len), "r"(proto)
4213 +static inline __sum16
4214 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
4215 + unsigned short proto, __wsum sum)
4217 + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
4221 + * this routine is used for miscellaneous IP-like checksums, mainly
4224 +extern __sum16 ip_compute_csum(const void *buff, int len);
4226 +#define _HAVE_ARCH_IPV6_CSUM
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)
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"
4244 + : "0" (sum), "a" (saddr), "a" (daddr), "d" (len + proto)
4246 + return csum_fold(sum);
4249 +#endif /* _ASM_UBICOM32_CHECKSUM_H */
4251 +++ b/arch/ubicom32/include/asm/cpu.h
4254 + * arch/ubicom32/include/asm/cpu.h
4255 + * CPU definitions for Ubicom32 architecture.
4257 + * (C) Copyright 2009, Ubicom, Inc.
4258 + * Copyright (C) 2004-2005 ARM Ltd.
4260 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4276 + * Ubicom32 implementation derived from (with many thanks):
4281 +#ifndef _ASM_UBICOM32_CPU_H
4282 +#define _ASM_UBICOM32_CPU_H
4284 +#include <linux/percpu.h>
4286 +struct cpuinfo_ubicom32 {
4287 + unsigned long tid; /* Hardware thread number */
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 */
4295 +DECLARE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
4297 +#endif /* _ASM_UBICOM32_CPU_H */
4299 +++ b/arch/ubicom32/include/asm/cputime.h
4302 + * arch/ubicom32/include/asm/cputime.h
4303 + * Generic cputime.h for Ubicom32 architecture.
4305 + * (C) Copyright 2009, Ubicom, Inc.
4307 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4323 + * Ubicom32 implementation derived from (with many thanks):
4328 +#ifndef _ASM_UBICOM32_CPUTIME_H
4329 +#define _ASM_UBICOM32_CPUTIME_H
4331 +#include <asm-generic/cputime.h>
4333 +#endif /* _ASM_UBICOM32_CPUTIME_H */
4335 +++ b/arch/ubicom32/include/asm/current.h
4338 + * arch/ubicom32/include/asm/current.h
4339 + * Definition of get_current() for Ubicom32 architecture.
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)
4345 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4361 + * Ubicom32 implementation derived from (with many thanks):
4366 +#ifndef _ASM_UBICOM32_CURRENT_H
4367 +#define _ASM_UBICOM32_CURRENT_H
4369 +#include <linux/thread_info.h>
4371 +struct task_struct;
4373 +static inline struct task_struct *get_current(void)
4375 + return(current_thread_info()->task);
4378 +#define current get_current()
4380 +#endif /* _ASM_UBICOM32_CURRENT_H */
4382 +++ b/arch/ubicom32/include/asm/delay.h
4385 + * arch/ubicom32/include/asm/delay.h
4386 + * Definition of delay routines for Ubicom32 architecture.
4388 + * (C) Copyright 2009, Ubicom, Inc.
4390 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4406 + * Ubicom32 implementation derived from (with many thanks):
4411 +#ifndef _ASM_UBICOM32_DELAY_H
4412 +#define _ASM_UBICOM32_DELAY_H
4414 +#include <asm/param.h>
4415 +#include <asm/ip5000.h>
4417 +static inline void __delay(unsigned long loops)
4424 + "1: add.4 %0, #-1, %0 \n\t"
4425 + " jmpne.t 1b \n\t"
4431 + * Ubicom32 processor uses fixed 12MHz external OSC.
4432 + * So we use that as reference to count 12 cycles/us
4435 +extern unsigned long loops_per_jiffy;
4437 +static inline void _udelay(unsigned long usecs)
4439 +#if defined(CONFIG_UBICOM32_V4) || defined(CONFIG_UBICOM32_V3)
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"
4445 + : "a"(TIMER_BASE + TIMER_MPTVAL), "d"(usecs * (12000000/1000000))
4454 + * Moved the udelay() function into library code, no longer inlined.
4456 +extern void udelay(unsigned long usecs);
4458 +#endif /* _ASM_UBICOM32_DELAY_H */
4460 +++ b/arch/ubicom32/include/asm/device.h
4463 + * arch/ubicom32/include/asm/device.h
4464 + * Generic device.h for Ubicom32 architecture.
4466 + * Used for arch specific extensions to struct device
4468 + * (C) Copyright 2009, Ubicom, Inc.
4470 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4486 + * Ubicom32 implementation derived from (with many thanks):
4491 +#ifndef _ASM_UBICOM32_DEVICE_H
4492 +#define _ASM_UBICOM32_DEVICE_H
4494 +#include <asm-generic/device.h>
4496 +#endif /* _ASM_UBICOM32_DEVICE_H */
4498 +++ b/arch/ubicom32/include/asm/devtree.h
4501 + * arch/ubicom32/include/asm/devtree.h
4502 + * Device Tree Header File (Shared between ultra and the Host OS)
4504 + * (C) Copyright 2009, Ubicom, Inc.
4506 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4522 + * Ubicom32 implementation derived from (with many thanks):
4528 +#ifndef _ASM_UBICOM32_DEVTREE_H
4529 +#define _ASM_UBICOM32_DEVTREE_H
4531 +#define DEVTREE_MAX_NAME 32
4532 +#define DEVTREE_IRQ_NONE 0xff
4533 +#define DEVTREE_IRQ_DONTCARE 0xff
4534 +#define DEVTREE_NODE_MAGIC 0x10203040
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;
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);
4551 +#endif /* _ASM_UBICOM32_DEVTREE_H */
4553 +++ b/arch/ubicom32/include/asm/div64.h
4556 + * arch/ubicom32/include/asm/div64.h
4557 + * Generic div64.h for Ubicom32 architecture.
4559 + * (C) Copyright 2009, Ubicom, Inc.
4561 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4577 + * Ubicom32 implementation derived from (with many thanks):
4582 +#ifndef _ASM_UBICOM32_DIV64_H
4583 +#define _ASM_UBICOM32_DIV64_H
4585 +#include <asm-generic/div64.h>
4587 +#endif /* _ASM_UBICOM32_DIV64_H */
4589 +++ b/arch/ubicom32/include/asm/dma.h
4592 + * arch/ubicom32/include/asm/dma.h
4593 + * DMA definitions for Ubicom32 architecture.
4595 + * (C) Copyright 2009, Ubicom, Inc.
4597 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4613 + * Ubicom32 implementation derived from (with many thanks):
4618 +#ifndef _ASM_UBICOM32_DMA_H
4619 +#define _ASM_UBICOM32_DMA_H
4621 +/* Nothing so far */
4622 +#define MAX_DMA_ADDRESS 0x00 /* This is quite suspicious */
4624 +#endif /* _ASM_UBICOM32_DMA_H */
4626 +++ b/arch/ubicom32/include/asm/dma-mapping.h
4629 + * arch/ubicom32/include/asm/dma-mapping.h
4630 + * Generic dma-mapping.h for Ubicom32 architecture.
4632 + * (C) Copyright 2009, Ubicom, Inc.
4634 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4650 + * Ubicom32 implementation derived from (with many thanks):
4655 +#ifndef _ASM_UBICOM32_DMA_MAPPING_H
4656 +#define _ASM_UBICOM32_DMA_MAPPING_H
4658 +#include <linux/scatterlist.h>
4659 +#include <asm-generic/dma-mapping.h>
4661 +#endif /* _ASM_UBICOM32_DMA_MAPPING_H */
4663 +++ b/arch/ubicom32/include/asm/elf.h
4666 + * arch/ubicom32/include/asm/elf.h
4667 + * Definitions for elf executable format for Ubicom32 architecture.
4669 + * (C) Copyright 2009, Ubicom, Inc.
4671 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4687 + * Ubicom32 implementation derived from (with many thanks):
4692 +#ifndef _ASM_UBICOM32_ELF_H
4693 +#define _ASM_UBICOM32_ELF_H
4696 + * ELF register definitions..
4699 +#include <asm/ptrace.h>
4700 +#include <asm/user.h>
4703 + * Processor specific flags for the ELF header e_flags field.
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 */
4711 + * Ubicom32 ELF relocation types
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
4755 +typedef unsigned long elf_greg_t;
4757 +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
4758 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
4760 +typedef struct user_ubicom32fp_struct elf_fpregset_t;
4763 + * This is used to ensure we don't load something for the wrong architecture.
4765 +#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
4767 +#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
4769 +#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
4772 + * These are used to set parameters in the core dumps.
4774 +#define ELF_CLASS ELFCLASS32
4775 +#define ELF_DATA ELFDATA2MSB
4776 +#define ELF_ARCH EM_UBICOM32
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
4783 +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, \
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 */ \
4792 +#define USE_ELF_CORE_DUMP
4793 +#define ELF_EXEC_PAGESIZE 4096
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)
4801 +#error Unknown/Unsupported ubicom32 architecture.
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. */
4810 +#define ELF_ET_DYN_BASE 0xD0000000UL
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.
4818 +/* This yields a mask that user programs can use to figure out what
4819 + instruction set this cpu supports. */
4821 +#define ELF_HWCAP (0)
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. */
4827 +#define ELF_PLATFORM (NULL)
4829 +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
4831 +#endif /* _ASM_UBICOM32_ELF_H */
4833 +++ b/arch/ubicom32/include/asm/elf.h~
4836 + * arch/ubicom32/include/asm/elf.h
4837 + * Definitions for elf executable format for Ubicom32 architecture.
4839 + * (C) Copyright 2009, Ubicom, Inc.
4841 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
4857 + * Ubicom32 implementation derived from (with many thanks):
4862 +#ifndef _ASM_UBICOM32_ELF_H
4863 +#define _ASM_UBICOM32_ELF_H
4866 + * ELF register definitions..
4869 +#include <asm/ptrace.h>
4870 +#include <asm/user.h>
4873 + * Processor specific flags for the ELF header e_flags field.
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 */
4881 + * Ubicom32 ELF relocation types
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
4925 +typedef unsigned long elf_greg_t;
4927 +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
4928 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
4930 +typedef struct user_ubicom32fp_struct elf_fpregset_t;
4933 + * This is used to ensure we don't load something for the wrong architecture.
4935 +#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
4937 +#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
4939 +#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
4942 + * These are used to set parameters in the core dumps.
4944 +#define ELF_CLASS ELFCLASS32
4945 +#define ELF_DATA ELFDATA2MSB
4946 +#define ELF_ARCH EM_UBICOM32
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
4953 +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, \
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 */ \
4962 +#define USE_ELF_CORE_DUMP
4963 +#define ELF_EXEC_PAGESIZE 4096
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)
4970 +#error Unknown/Unsupported ubicom32 architecture.
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. */
4978 +#define ELF_ET_DYN_BASE 0xD0000000UL
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.
4986 +/* This yields a mask that user programs can use to figure out what
4987 + instruction set this cpu supports. */
4989 +#define ELF_HWCAP (0)
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. */
4995 +#define ELF_PLATFORM (NULL)
4997 +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
4999 +#endif /* _ASM_UBICOM32_ELF_H */
5001 +++ b/arch/ubicom32/include/asm/emergency-restart.h
5004 + * arch/ubicom32/include/asm/emergency-restart.h
5005 + * Generic emergency-restart.h for Ubicom32 architecture.
5007 + * (C) Copyright 2009, Ubicom, Inc.
5009 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5025 + * Ubicom32 implementation derived from (with many thanks):
5030 +#ifndef _ASM_UBICOM32_EMERGENCY_RESTART_H
5031 +#define _ASM_UBICOM32_EMERGENCY_RESTART_H
5033 +#include <asm-generic/emergency-restart.h>
5035 +#endif /* _ASM_UBICOM32_EMERGENCY_RESTART_H */
5037 +++ b/arch/ubicom32/include/asm/entry.h
5040 + * arch/ubicom32/include/asm/entry.h
5041 + * Entry register/stack definitions for Ubicom32 architecture.
5043 + * (C) Copyright 2009, Ubicom, Inc.
5045 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5061 + * Ubicom32 implementation derived from (with many thanks):
5066 +#ifndef _ASM_UBICOM32_ENTRY_H
5067 +#define _ASM_UBICOM32_ENTRY_H
5069 +#include <asm/setup.h>
5070 +#include <asm/page.h>
5072 +#endif /* _ASM_UBICOM32_ENTRY_H */
5074 +++ b/arch/ubicom32/include/asm/errno.h
5077 + * arch/ubicom32/include/asm/errno.h
5078 + * Generic errno.h for Ubicom32 architecture.
5080 + * (C) Copyright 2009, Ubicom, Inc.
5082 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5098 + * Ubicom32 implementation derived from (with many thanks):
5103 +#ifndef _ASM_UBICOM32_ERRNO_H
5104 +#define _ASM_UBICOM32_ERRNO_H
5106 +#include <asm-generic/errno.h>
5108 +#endif /* _ASM_UBICOM32_ERRNO_H */
5110 +++ b/arch/ubicom32/include/asm/fb.h
5113 + * arch/ubicom32/include/asm/fb.h
5114 + * Definition of fb_is_primary_device() for Ubicom32 architecture.
5116 + * (C) Copyright 2009, Ubicom, Inc.
5118 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5134 + * Ubicom32 implementation derived from (with many thanks):
5139 +#ifndef _ASM_UBICOM32_FB_H
5140 +#define _ASM_UBICOM32_FB_H
5141 +#include <linux/fb.h>
5143 +#define fb_pgprotect(...) do {} while (0)
5145 +static inline int fb_is_primary_device(struct fb_info *info)
5150 +#endif /* _ASM_UBICOM32_FB_H */
5152 +++ b/arch/ubicom32/include/asm/fcntl.h
5155 + * arch/ubicom32/include/asm/fcntl.h
5156 + * File control bit definitions for Ubicom32 architecture.
5158 + * (C) Copyright 2009, Ubicom, Inc.
5160 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5176 + * Ubicom32 implementation derived from (with many thanks):
5181 +#ifndef _ASM_UBICOM32_FCNTL_H
5182 +#define _ASM_UBICOM32_FCNTL_H
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
5189 +#include <asm-generic/fcntl.h>
5191 +#endif /* _ASM_UBICOM32_FCNTL_H */
5193 +++ b/arch/ubicom32/include/asm/flat.h
5196 + * arch/ubicom32/include/asm/flat.h
5197 + * Definitions to support flat-format executables.
5199 + * (C) Copyright 2009, Ubicom, Inc.
5201 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5217 + * Ubicom32 implementation derived from (with many thanks):
5223 +#ifndef _ASM_UBICOM32_FLAT_H
5224 +#define _ASM_UBICOM32_FLAT_H
5226 +#define ARCH_FLAT_ALIGN 0x80
5227 +#define ARCH_FLAT_ALIGN_TEXT 1
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
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);
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))
5251 +static inline int flat_set_persistent(unsigned int relval, unsigned long *p)
5256 + if ((relval >> 27) != R_UBICOM32_32) {
5258 + * Something other than UBICOM32_32. The next entry has the relocation.
5267 +#endif /* _ASM_UBICOM32_FLAT_H */
5269 +++ b/arch/ubicom32/include/asm/fpu.h
5272 + * arch/ubicom32/include/asm/fpu.h
5273 + * Floating point state definitions for Ubicom32 architecture.
5275 + * (C) Copyright 2009, Ubicom, Inc.
5277 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5293 + * Ubicom32 implementation derived from (with many thanks):
5298 +#ifndef _ASM_UBICOM32_FPU_H
5299 +#define _ASM_UBICOM32_FPU_H
5302 + * MAX floating point unit state size (FSAVE/FRESTORE)
5304 +/* No FP unit present then... */
5305 +#define FPSTATESIZE (2) /* dummy size */
5307 +#endif /* _ASM_UBICOM32_FPU_H */
5309 +++ b/arch/ubicom32/include/asm/futex.h
5312 + * arch/ubicom32/include/asm/futex.h
5313 + * Generic futex.h for Ubicom32 architecture.
5315 + * (C) Copyright 2009, Ubicom, Inc.
5317 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5333 + * Ubicom32 implementation derived from (with many thanks):
5338 +#ifndef _ASM_UBICOM32_FUTEX_H
5339 +#define _ASM_UBICOM32_FUTEX_H
5341 +#include <asm-generic/futex.h>
5343 +#endif /* _ASM_UBICOM32_FUTEX_H */
5345 +++ b/arch/ubicom32/include/asm/.gitignore
5349 +++ b/arch/ubicom32/include/asm/gpio.h
5352 + * arch/ubicom32/include/asm/gpio.h
5353 + * Definitions for GPIO operations on Ubicom32 architecture.
5355 + * (C) Copyright 2009, Ubicom, Inc.
5357 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5373 + * Ubicom32 implementation derived from (with many thanks):
5378 +#ifndef _ASM_UBICOM32_GPIO_H
5379 +#define _ASM_UBICOM32_GPIO_H
5381 +#include <linux/compiler.h>
5382 +#include <asm/irq.h>
5384 +#include <asm/ip5000.h>
5386 +#define ARCH_NR_GPIOS 512
5387 +#define MAX_UBICOM_ONCHIP_GPIO (9 * 32)
5390 + * Macros for manipulating GPIO numbers
5392 +#define gpio_bit(gn) (1 << (gn & 0x1f))
5393 +#define gpio_bank(gn) (gn >> 5)
5395 +#define gpio_pin_index(gn) (gn & 0x1f)
5396 +#define gpio_port_index(gn) (gn >> 5)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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).
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.
5568 +#ifdef CONFIG_IP7500MEDIA
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)
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)
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)
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)
5622 +#ifdef CONFIG_IP7145DPF
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)
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)
5650 +#include <asm-generic/gpio.h>
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.
5662 + * These operations must be done in one instruction to prevent clobbering
5663 + * other thread's accesses to the same port.
5665 +#define UBICOM32_GPIO_ENABLE(pin) \
5667 + asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t" \
5669 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask), \
5670 + [mask] "d" (gpio_bit(pin)) \
5671 + : "cc", "memory" \
5675 +#define UBICOM32_GPIO_DISABLE(pin) \
5677 + asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t" \
5679 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask), \
5680 + [mask] "d" (~gpio_bit(pin)) \
5681 + : "cc", "memory" \
5685 +#define UBICOM32_GPIO_SET_PIN_INPUT(pin) \
5687 + asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t" \
5689 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl), \
5690 + [mask] "d" (~gpio_bit(pin)) \
5691 + : "cc", "memory" \
5695 +#define UBICOM32_GPIO_SET_PIN_OUTPUT(pin) \
5697 + asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t" \
5699 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl), \
5700 + [mask] "d" (gpio_bit(pin)) \
5701 + : "cc", "memory" \
5705 +#define UBICOM32_GPIO_SET_PIN_TOGGLE(pin) \
5707 + asm volatile ("xor.4 (%[port]), (%[port]), %[mask]\n\t" \
5709 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out), \
5710 + [mask] "d" (gpio_bit(pin)) \
5711 + : "cc", "memory" \
5715 +#define UBICOM32_GPIO_SET_PIN_HIGH(pin) \
5717 + asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t" \
5719 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out), \
5720 + [mask] "d" (gpio_bit(pin)) \
5721 + : "cc", "memory" \
5725 +#define UBICOM32_GPIO_SET_PIN_LOW(pin) \
5727 + asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t" \
5729 + : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out), \
5730 + [mask] "d" (~gpio_bit(pin)) \
5731 + : "cc", "memory" \
5735 +#define UBICOM32_GPIO_SET_PIN(pin, val) \
5737 + UBICOM32_GPIO_SET_PIN_HIGH(pin); \
5739 + UBICOM32_GPIO_SET_PIN_LOW(pin); \
5742 +#define UBICOM32_GPIO_GET_PIN(pin) \
5743 + (0 != (UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_in \
5747 +static inline int gpio_get_value(unsigned gpio)
5749 + if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5750 + return UBICOM32_GPIO_GET_PIN(gpio);
5752 + return __gpio_get_value(gpio);
5755 +static inline void gpio_set_value(unsigned gpio, int value)
5757 + if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
5759 + UBICOM32_GPIO_SET_PIN(gpio, value);
5763 + __gpio_set_value(gpio, value);
5767 +static inline int gpio_cansleep(unsigned gpio)
5769 + return __gpio_cansleep(gpio);
5772 +static inline int gpio_to_irq(unsigned gpio)
5774 +#if defined(IP5000) || defined(IP5000_REV2)
5775 + if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5780 +#elif defined(IP7000) || defined(IP7000_REV2)
5781 + if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
5782 + return 44 + (gpio - GPIO_RA_4);
5792 +static inline int irq_to_gpio(unsigned gpio)
5797 +extern struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio);
5799 +extern int __init ubi_gpio_init(void);
5801 +#endif /* _ASM_UBICOM32_GPIO_H */
5803 +++ b/arch/ubicom32/include/asm/hardirq.h
5806 + * arch/ubicom32/include/asm/hardirq.h
5807 + * Definition of ack_bad_irq() for Ubicom32 architecture.
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.
5814 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5830 + * Ubicom32 implementation derived from (with many thanks):
5835 +#ifndef _ASM_UBICOM32_HARDIRQ_H
5836 +#define _ASM_UBICOM32_HARDIRQ_H
5838 +#include <linux/threads.h>
5839 +#include <linux/irq.h>
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.
5846 +#define HARDIRQ_BITS 6
5847 +#if (1 << HARDIRQ_BITS) < NR_IRQS
5848 +# error HARDIRQ_BITS is too low!
5852 + unsigned int __softirq_pending;
5853 +} ____cacheline_aligned irq_cpustat_t;
5855 +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
5857 +extern void ack_bad_irq(unsigned int irq);
5859 +#endif /* _ASM_UBICOM32_HARDIRQ_H */
5861 +++ b/arch/ubicom32/include/asm/hw_irq.h
5864 + * arch/ubicom32/include/asm/hw_irq.h
5865 + * Ubicom32 architecture APIC support.
5867 + * (C) Copyright 2009, Ubicom, Inc.
5869 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5885 + * Ubicom32 implementation derived from (with many thanks):
5890 +#ifndef _ASM_UBICOM32_HW_IRQ_H
5891 +#define _ASM_UBICOM32_HW_IRQ_H
5893 +#endif /* _ASM_UBICOM32_HW_IRQ_H */
5895 +++ b/arch/ubicom32/include/asm/ioctl.h
5898 + * arch/ubicom32/include/asm/ioctl.h
5899 + * Generic ioctl.h for Ubicom32 architecture.
5901 + * (C) Copyright 2009, Ubicom, Inc.
5903 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5919 + * Ubicom32 implementation derived from (with many thanks):
5924 +#ifndef _ASM_UBICOM32_IOCTL_H
5925 +#define _ASM_UBICOM32_IOCTL_H
5927 +#include <asm-generic/ioctl.h>
5929 +#endif /* _ASM_UBICOM32_IOCTL_H */
5931 +++ b/arch/ubicom32/include/asm/ioctls.h
5934 + * arch/ubicom32/include/asm/ioctls.h
5935 + * Definitions of ioctls for Ubicom32 architecture.
5937 + * (C) Copyright 2009, Ubicom, Inc.
5939 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
5955 + * Ubicom32 implementation derived from (with many thanks):
5960 +#ifndef _ASM_UBICOM32_IOCTLS_H
5961 +#define _ASM_UBICOM32_IOCTLS_H
5963 +#include <asm/ioctl.h>
5965 +/* 0x54 is just a magic number to make these relatively unique ('T') */
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 */
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 */
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
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
6041 +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
6043 +#endif /* _ASM_UBICOM32_IOCTLS_H */
6045 +++ b/arch/ubicom32/include/asm/io.h
6048 + * arch/ubicom32/include/asm/io.h
6049 + * I/O memory accessor functions for Ubicom32 architecture.
6051 + * (C) Copyright 2009, Ubicom, Inc.
6053 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
6069 + * Ubicom32 implementation derived from (with many thanks):
6074 +#ifndef _ASM_UBICOM32_IO_H
6075 +#define _ASM_UBICOM32_IO_H
6078 +#include <linux/string.h>
6079 +#include <linux/compiler.h>
6081 +static inline unsigned short _swapw(volatile unsigned short v)
6083 + return ((v << 8) | (v >> 8));
6086 +static inline unsigned int _swapl(volatile unsigned long v)
6088 + return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
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; })
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 */
6104 +#define PCI_CPU_REG_BASE (0x00000000UL) /* taking lower 2GB space */
6105 +#define PCI_DEV_REG_BASE (0x80000000UL)
6107 +#if PCI_CPU_REG_BASE > PCI_DEV_REG_BASE
6108 +#define IS_PCI_ADDRESS(x) (((unsigned int)(x)&(PCI_CPU_REG_BASE)) == 0)
6110 +#define IS_PCI_ADDRESS(x) ((unsigned int)(x)&(PCI_DEV_REG_BASE))
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);
6120 +static inline unsigned char readb(const volatile void __iomem *addr)
6122 + if (IS_PCI_ADDRESS(addr))
6123 + return ubi32_pci_read_u8(addr);
6125 + return (unsigned char)(*(volatile unsigned char *)addr);
6127 +static inline unsigned short readw(const volatile void __iomem *addr)
6129 + if (IS_PCI_ADDRESS(addr))
6130 + return ubi32_pci_read_u16(addr);
6132 + return (unsigned short)(*(volatile unsigned short *)addr);
6135 +static inline unsigned int readl(const volatile void __iomem *addr)
6137 + if (IS_PCI_ADDRESS(addr))
6138 + return ubi32_pci_read_u32(addr);
6140 + return (unsigned int)(*(volatile unsigned int *)addr);
6143 +static inline void writel(unsigned int val, volatile void __iomem *addr)
6145 + if (IS_PCI_ADDRESS(addr))
6146 + ubi32_pci_write_u32(val, addr);
6148 + *(volatile unsigned int *)addr = val;
6151 +static inline void writew(unsigned short val, volatile void __iomem *addr)
6153 + if (IS_PCI_ADDRESS(addr))
6154 + ubi32_pci_write_u16(val, addr);
6156 + *(volatile unsigned short *)addr = val;
6159 +static inline void writeb(unsigned char val, volatile void __iomem *addr)
6161 + if (IS_PCI_ADDRESS(addr))
6162 + ubi32_pci_write_u8(val, addr);
6164 + *(volatile unsigned char *)addr = val;
6168 +#define readb_relaxed(addr) readb(addr)
6169 +#define readw_relaxed(addr) readw(addr)
6170 +#define readl_relaxed(addr) readl(addr)
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
6180 +static inline void io_outsb(unsigned int addr, const void *buf, int len)
6182 + volatile unsigned char *ap = (volatile unsigned char *) addr;
6183 + unsigned char *bp = (unsigned char *) buf;
6188 +static inline void io_outsw(unsigned int addr, const void *buf, int len)
6190 + volatile unsigned short *ap = (volatile unsigned short *) addr;
6191 + unsigned short *bp = (unsigned short *) buf;
6193 + *ap = _swapw(*bp++);
6196 +static inline void io_outsl(unsigned int addr, const void *buf, int len)
6198 + volatile unsigned int *ap = (volatile unsigned int *) addr;
6199 + unsigned int *bp = (unsigned int *) buf;
6201 + *ap = _swapl(*bp++);
6204 +static inline void io_insb(unsigned int addr, void *buf, int len)
6206 + volatile unsigned char *ap = (volatile unsigned char *) addr;
6207 + unsigned char *bp = (unsigned char *) buf;
6212 +static inline void io_insw(unsigned int addr, void *buf, int len)
6214 + volatile unsigned short *ap = (volatile unsigned short *) addr;
6215 + unsigned short *bp = (unsigned short *) buf;
6217 + *bp++ = _swapw(*ap);
6220 +static inline void io_insl(unsigned int addr, void *buf, int len)
6222 + volatile unsigned int *ap = (volatile unsigned int *) addr;
6223 + unsigned int *bp = (unsigned int *) buf;
6225 + *bp++ = _swapl(*ap);
6231 + * make the short names macros so specific devices
6232 + * can override them as required
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))
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);
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))
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)
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)
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)
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)
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);
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 */
6299 +#define IO_SPACE_LIMIT 0xffff
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
6307 +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
6308 +extern void __iounmap(void *addr, unsigned long size);
6310 +static inline void *ioremap(unsigned long physaddr, unsigned long size)
6312 + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6314 +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
6316 + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
6318 +static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
6320 + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
6322 +static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
6324 + return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
6327 +extern void iounmap(void *addr);
6329 +#define ioport_map(port, nr) ((void __iomem*)(port))
6330 +#define ioport_unmap(addr)
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)
6338 + * Macros used for converting between virtual and physical mappings.
6340 +#define phys_to_virt(vaddr) ((void *) (vaddr))
6341 +#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
6343 +#define virt_to_bus virt_to_phys
6344 +#define bus_to_virt phys_to_virt
6347 + * Convert a physical pointer to a virtual kernel pointer for /dev/mem
6350 +#define xlate_dev_mem_ptr(p) __va(p)
6353 + * Convert a virtual cached pointer to an uncached pointer
6355 +#define xlate_dev_kmem_ptr(p) p
6357 +#endif /* __KERNEL__ */
6359 +#endif /* _ASM_UBICOM32_IO_H */
6361 +++ b/arch/ubicom32/include/asm/ip5000-asm.h
6364 + * arch/ubicom32/include/asm/ip5000-asm.h
6365 + * Instruction macros for the IP5000.
6367 + * (C) Copyright 2009, Ubicom, Inc.
6369 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
6385 + * Ubicom32 implementation derived from (with many thanks):
6391 +#ifndef _ASM_UBICOM32_IP5000_ASM_H
6392 +#define _ASM_UBICOM32_IP5000_ASM_H
6394 +#if !defined(__LINKER__)
6396 +#if defined(__ASSEMBLY__)
6397 +.macro cycles quant
6401 +.if (((\quant) + 3) / 8) > 0
6402 +.rept (((\quant) + 3) / 8)
6406 +.if ((((\quant) + 3) % 8) / 4) > 0
6413 + * Same macro as above just in C inline asm
6416 +.macro cycles quant \n\
6417 +.if (\\quant) == 1 \n\
6420 +.if (((\\quant) + 3) / 8) > 0 \n\
6421 +.rept (((\\quant) + 3) / 8) \n\
6425 +.if ((((\\quant) + 3) % 8) / 4) > 0 \n\
6434 +#if defined(__ASSEMBLY__)
6435 +.macro pipe_flush cyc
6436 + cycles 11 - (\cyc)
6440 + * Same macro as above just in C inline asm
6443 +.macro pipe_flush cyc \n\
6444 + cycles 11 - (\\cyc) \n\
6450 +#if defined(__ASSEMBLY__)
6451 +.macro setcsr_flush cyc
6456 + * Same macro as above just in C inline asm
6459 +.macro setcsr_flush cyc \n\
6460 + cycles 5 - (\\cyc) \n\
6466 + * Macros for prefetch (using miss-aligned memory write)
6468 +#if defined(__ASSEMBLY__)
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
6478 + .if (\length > 64)
6479 + move.4 64(\Ascratch), #0
6481 + .if (\length > 96)
6482 + move.4 96(\Ascratch), #0
6484 + .if (\length > 128)
6485 + invalid_instruction ; maximum pre-fetch size is 4 cache lines
6487 + bset MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
6492 + * Same macro as above just in C inline asm
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\
6503 + .if (\\length > 64) \n\
6504 + move.4 64(\\Ascratch), #0 \n\
6506 + .if (\\length > 96) \n\
6507 + move.4 96(\\Ascratch), #0 \n\
6509 + .if (\\length > 128) \n\
6510 + invalid_instruction ; maximum pre-fetch size is 4 cache lines \n\
6512 + bset MT_TRAP_EN, MT_TRAP_EN, #(\\thread_num) \n\
6517 +#endif /* !defined(__LINKER__) */
6518 +#endif /* defined _ASM_UBICOM32_IP5000_ASM_H */
6520 +++ b/arch/ubicom32/include/asm/ip5000.h
6523 + * arch/ubicom32/include/asm/ip5000.h
6524 + * Specific details for the Ubicom IP5000 processor.
6526 + * (C) Copyright 2009, Ubicom, Inc.
6528 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
6544 + * Ubicom32 implementation derived from (with many thanks):
6550 +#ifndef _ASM_UBICOM32_IP5000_H
6551 +#define _ASM_UBICOM32_IP5000_H
6554 + * Inline assembly define
6556 +#define S(arg) #arg
6557 +#define D(arg) S(arg)
6560 + * Assembler include file
6562 +#include <asm/ip5000-asm.h>
6567 +#define JMPT_PENALTY 3
6568 +#define JMPF_PENALTY 7
6569 +#define RET_PENALTY 7
6574 +#if defined(IP5000) || defined(IP5000_REV2)
6575 +#define THREAD_COUNT 10
6576 +#elif defined(IP7000) || defined(IP7000_REV2)
6577 +#define THREAD_COUNT 12
6579 +#error "Unknown IP5K silicon"
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
6590 +#error "Unknown IP5K silicon"
6596 +#define OCM_SECTOR_SIZE 0x00008000 /* 32K */
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 */
6603 +#error "Unknown IP5K silicon"
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
6614 +#define ROSR_INT (1 << 0)
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))
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.
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.
6635 +#define LOCK_INT(thread) INT_CHIP(0, (thread))
6636 +#define THREAD_INT(thread) INT_CHIP(0, (thread))
6639 + * The SYSTEM_INT and DSR_INT are sharing the same set of SW interrupt resource.
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.
6646 +#define SYSTEM_INT(thread) INT_CHIP(0, THREAD_COUNT + (thread))
6647 +#define DSR_INT(thread) INT_CHIP(0, THREAD_COUNT + (thread))
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)
6659 +#define HRT_TABLE0_BASE 0x0800
6660 +#define HRT_TABLE1_BASE 0x0900
6661 +#define HRT_TABLE_SIZE 64
6664 + * Break Point Trap Register
6666 +#define ASYNCERROR_INT INT_CHIP(0, 31)
6667 +#define BREAKPOINT_INT INT_CHIP(1, 31)
6671 + * The non-existing FIFO INTs are mapped to INT2 for the ports.
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))))))))))
6709 + * On Chip Peripherals Base.
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 */
6726 + * General Configuration Registers (PLL)
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
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)
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)
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)
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
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
6808 +#ifndef __ASSEMBLY__
6810 + * ubicom32_io_timer
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;
6825 +#define UBICOM32_IO_TIMER ((struct ubicom32_io_timer *)TIMER_BASE)
6828 +#define UBICOM32_VECTOR_TO_TIMER_INDEX(vector) (vector - TIMER_INT(0))
6831 + * OCP-Debug Module (Mailbox)
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
6838 +#define ISD_MAILBOX_INT INT_CHIP(1, 30)
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)
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)
6873 +#define ICCR_BASE (OCP_BASE + OCP_ICCR)
6874 +#define ICACHE_TOTAL_SIZE 16384 /* in bytes */
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 */
6886 +#if defined(IP5000) || defined(IP5000_REV2) || defined(IP7000) || defined(IP7000_REV2)
6887 +#define DCACHE_WRITE_QUEUE_LENGTH 6
6889 +#error "Unknown IP5K silicon"
6892 +#define CACHE_LINE_SIZE 32 /* in bytes */
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
6900 +#define CCR_STAT_MCBE 0
6901 +#define CCR_STAT_WIDEL 1 /* D-cache only */
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 */
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 */
6925 +#define OCMC_BANK_PROG(n) ((1<<(n))-1)
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)
6933 +#define OCMC_BIST_READY (1 << 3)
6934 +#define OCMC_BIST_FAIL (1 << 2)
6939 +#define STATISTICS_BASE (OCP_BASE + OCP_STATISTICS)
6940 +#define STAT_COUNTER_CTRL(n) ((n)*8)
6941 +#define STAT_COUNTER(n) ((n)*8 + 4)
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
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
6976 + * OCP_MCFG (IP7000 only)
6978 +#define MCFG_BASE (OCP_BASE + OCP_MCFG)
6979 +#define MCFG_CTRL 0x00
6980 +#define MCFG_WCFG 0x04
6981 +#define MCFG_RCFG 0x08
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
7001 + * General I/O Register Map (per port)
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
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)
7030 + * External interrupt pins.
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))
7039 +#define IO_XFL_BASE RA
7041 +#define IO_XFL_INT_START (1 << 16)
7042 +#define IO_XFL_INT_ERR (1 << 8)
7043 +#define IO_XFL_INT_DONE (1 << 0)
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)
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)
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 */
7064 +#define IO_XFL_STATUS0_MCB_ACTIVE (1 << 0)
7065 +#define IO_XFL_STATUS0_IOPCS_ACTIVE (1 << 1)
7070 +#define IO_SDRAM_DATA_BASE RG
7071 +#define IO_SDRAM_CNTL_BASE RH
7073 +#define IO_SDRAM_CTRL0_EN_REF (1 << 0)
7076 + * Port function code (common fucntion codes for all I/O ports)
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
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
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
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
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
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
7131 +#define IO_PORT5_FUNC_GPIO IO_PORTX_FUNC_GPIO
7132 +#define IO_PORT5_FUNC_GMII IO_PORTX_FUNC_GMII
7137 +#define IO_PORT6_FUNC_GPIO IO_PORTX_FUNC_GPIO
7138 +#define IO_PORT6_FUNC_DDR IO_PORTX_FUNC_DDR
7143 +#define IO_PORT7_FUNC_GPIO IO_PORTX_FUNC_GPIO
7144 +#define IO_PORT7_FUNC_DDR IO_PORTX_FUNC_DDR
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
7157 +#define IO_PORT9_FUNC_USB2_0 IO_PORTX_FUNC_USB2_0
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)
7169 +#define IO_PORTX_FUNC_FIFO_TX_WM(n) ((n) << 16)
7170 +#define IO_PORTX_FUNC_FIFO_RX_WM(n) ((n) << 0)
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)
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)
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;
7226 +#define UBICOM32_IO_PORT(port) ((struct ubicom32_io_port *)((port)))
7229 +#ifndef __ASSEMBLY__
7231 + * ubicom32_set_interrupt()
7233 +extern inline void ubicom32_set_interrupt(u8_t interrupt)
7235 + u32_t ibit = INT_BIT_MASK(interrupt);
7237 + if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7239 + "move.4 "D(INT_SET(INT_CHIP(0, 0)))", %0\n\t"
7248 + "move.4 "D(INT_SET(INT_CHIP(1, 0)))", %0\n\t"
7255 + * ubicom32_clear_interrupt()
7257 +extern inline void ubicom32_clear_interrupt(u8_t interrupt)
7259 + u32_t ibit = INT_BIT_MASK(interrupt);
7261 + if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7263 + "move.4 "D(INT_CLR(INT_CHIP(0, 0)))", %0\n\t"
7272 + "move.4 "D(INT_CLR(INT_CHIP(1, 0)))", %0\n\t"
7279 + * ubicom32_enable_interrupt()
7281 +extern inline void ubicom32_enable_interrupt(u8_t interrupt)
7283 + u32_t ibit = INT_BIT_MASK(interrupt);
7285 + if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7287 + "or.4 "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7296 + "or.4 "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7303 + * ubicom32_disable_interrupt()
7305 +extern inline void ubicom32_disable_interrupt(u8_t interrupt)
7307 + u32_t ibit = ~INT_BIT_MASK(interrupt);
7309 + if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
7311 + "and.4 "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
7320 + "and.4 "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
7327 + * ubicom32_enable_global_interrupts()
7329 +extern inline void ubicom32_enable_global_interrupts(void)
7332 + "bset GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7337 + * ubicom32_disable_global_interrupts()
7339 +extern inline void ubicom32_disable_global_interrupts(void)
7342 + "bclr GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
7347 + * ubicom32_get_reset_reason()
7349 +extern inline u32_t ubicom32_get_reset_reason(void)
7351 + return *(u32_t *)(GENERAL_CFG_BASE + GEN_RESET_REASON);
7355 + * ubicom32_read_reg()
7357 +extern inline u32_t ubicom32_read_reg(volatile void *reg)
7361 + "move.4 %[dest], %[src] \n\t"
7363 + : [src] "m" (*(u32_t *)reg)
7369 + * ubicom32_write_reg()
7371 +extern inline void ubicom32_write_reg(volatile void *reg, u32_t v)
7374 + "move.4 %[dest], %[src] \n\t"
7376 + : [src] "r" (v), [dest] "m" (*(u32_t *)reg)
7380 +#endif /* __ASSEMBLY__ */
7381 +#endif /* _ASM_UBICOM32_IP5000_H */
7383 +++ b/arch/ubicom32/include/asm/ipcbuf.h
7386 + * arch/ubicom32/include/asm/ipcbuf.h
7387 + * Definition of ipc64_perm struct for Ubicom32 architecture.
7389 + * (C) Copyright 2009, Ubicom, Inc.
7391 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7407 + * Ubicom32 implementation derived from (with many thanks):
7412 +#ifndef _ASM_UBICOM32_IPCBUF_H
7413 +#define _ASM_UBICOM32_IPCBUF_H
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.
7420 + * Pad space is left for:
7421 + * - 32-bit mode_t and seq
7422 + * - 2 miscellaneous 32-bit values
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;
7439 +#endif /* _ASM_UBICOM32_IPCBUF_H */
7441 +++ b/arch/ubicom32/include/asm/irqflags.h
7444 + * arch/ubicom32/include/asm/irqflags.h
7445 + * Raw implementation of local IRQ functions.
7447 + * (C) Copyright 2009, Ubicom, Inc.
7449 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7465 + * Ubicom32 implementation derived from (with many thanks):
7470 +#ifndef _ASM_UBICOM32_IRQFLAGS_H
7471 +#define _ASM_UBICOM32_IRQFLAGS_H
7473 +#include <linux/thread_info.h>
7474 +#include <asm/ubicom32-common.h>
7475 +#include <asm/smp.h>
7476 +#include <asm/ldsr.h>
7478 +#if defined(CONFIG_PREEMPT)
7479 +#error Not supported by Ubicom32 irq handling, yet!
7483 + * raw_local_irq_enable()
7484 + * Enable interrupts for this thread.
7486 +static inline void raw_local_irq_enable(void)
7488 + ldsr_local_irq_enable();
7492 + * raw_local_irq_disable()
7493 + * Disable interrupts for this thread.
7495 +static inline void raw_local_irq_disable(void)
7497 + ldsr_local_irq_disable();
7501 + * raw_local_save_flags()
7502 + * Get the current IRQ state.
7504 +#define raw_local_save_flags(flags) \
7506 + (flags) = ldsr_local_irq_is_disabled(); \
7510 + * raw_local_irq_save()
7511 + * Save the current interrupt state and disable interrupts.
7513 +#define raw_local_irq_save(flags) \
7515 + (flags) = ldsr_local_irq_save(); \
7519 + * raw_local_irq_restore()
7520 + * Restore the IRQ state back to flags.
7522 +static inline void raw_local_irq_restore(unsigned long flags)
7524 + ldsr_local_irq_restore(flags);
7528 + * raw_irqs_disabled_flags()
7529 + * Return true if the flags indicate that IRQ(s) are disabled.
7531 +static inline int raw_irqs_disabled_flags(unsigned long flags)
7536 +#endif /* _ASM_UBICOM32_IRQFLAGS_H */
7538 +++ b/arch/ubicom32/include/asm/irq.h
7541 + * arch/ubicom32/include/asm/irq.h
7542 + * IRQ definitions for Ubicom32 architecture.
7544 + * (C) Copyright 2009, Ubicom, Inc.
7546 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7562 + * Ubicom32 implementation derived from (with many thanks):
7567 +#ifndef _ASM_UBICOM32_IRQ_H
7568 +#define _ASM_UBICOM32_IRQ_H
7570 +#include <asm/irqflags.h>
7573 + * We setup the IRQS to cover the full range of interrupt registers in
7578 +#define irq_canonicalize(irq) (irq)
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);
7584 +#endif /* _ASM_UBICOM32_IRQ_H */
7586 +++ b/arch/ubicom32/include/asm/irq_regs.h
7589 + * arch/ubicom32/include/asm/irq_regs.h
7590 + * Generic irq_regs.h for Ubicom32 architecture.
7592 + * (C) Copyright 2009, Ubicom, Inc.
7594 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7610 + * Ubicom32 implementation derived from (with many thanks):
7615 +#ifndef _ASM_UBICOM32_IRQ_REGS_H
7616 +#define _ASM_UBICOM32_IRQ_REGS_H
7618 +#include <asm-generic/irq_regs.h>
7620 +#endif /* _ASM_UBICOM32_IRQ_REGS_H */
7622 +++ b/arch/ubicom32/include/asm/Kbuild
7624 +include include/asm-generic/Kbuild.asm
7626 +++ b/arch/ubicom32/include/asm/kdebug.h
7629 + * arch/ubicom32/include/asm/kdebug.h
7630 + * Generic kdebug.h for Ubicom32 architecture.
7632 + * (C) Copyright 2009, Ubicom, Inc.
7634 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7650 + * Ubicom32 implementation derived from (with many thanks):
7655 +#ifndef _ASM_UBICOM32_KDEBUG_H
7656 +#define _ASM_UBICOM32_KDEBUG_H
7658 +#include <asm-generic/kdebug.h>
7660 +#endif /* _ASM_UBICOM32_KDEBUG_H */
7662 +++ b/arch/ubicom32/include/asm/kmap_types.h
7665 + * arch/ubicom32/include/asm/kmap_types.h
7666 + * Definition of km_type's for Ubicom32 architecture.
7668 + * (C) Copyright 2009, Ubicom, Inc.
7670 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7686 + * Ubicom32 implementation derived from (with many thanks):
7691 +#ifndef _ASM_UBICOM32_KMAP_TYPES_H
7692 +#define _ASM_UBICOM32_KMAP_TYPES_H
7696 + KM_SKB_SUNRPC_DATA,
7697 + KM_SKB_DATA_SOFTIRQ,
7711 +#endif /* _ASM_UBICOM32_KMAP_TYPES_H */
7713 +++ b/arch/ubicom32/include/asm/ldsr.h
7716 + * arch/ubicom32/include/asm/ldsr.h
7717 + * Ubicom32 LDSR interface definitions.
7719 + * (C) Copyright 2009, Ubicom, Inc.
7721 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7737 + * Ubicom32 implementation derived from (with many thanks):
7742 +#ifndef _ASM_UBICOM32_LDSR_H
7743 +#define _ASM_UBICOM32_LDSR_H
7745 +#include <asm/ubicom32-common.h>
7746 +#include <asm/types.h>
7747 +#include <asm/thread.h>
7749 +extern unsigned int ldsr_soft_irq_mask;
7752 + * ldsr_local_irq_is_disabled()
7753 + * Test if interrupts are disabled for this thread?
7755 +static inline int ldsr_local_irq_is_disabled(void)
7758 + thread_t self = thread_get_self();
7759 + unsigned int mask = (1 << self);
7762 + " and.4 %0, scratchpad1, %1 \n\t"
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.
7773 + return ret >> self;
7777 + * ldsr_local_irq_save()
7778 + * Get the current interrupt state and disable interrupts.
7780 +static inline unsigned int ldsr_local_irq_save(void)
7783 + thread_t self = thread_get_self();
7784 + unsigned int mask = (1 << self);
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
7794 + " and.4 %0, scratchpad1, %1 \n\t"
7795 + " or.4 scratchpad1, scratchpad1, %1 \n\t"
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.
7806 + return ret >> self;
7810 + * ldsr_local_irq_restore()
7811 + * Restore this cpu's interrupt enable/disable state.
7813 + * Note: flags is either 0 or 1.
7815 +static inline void ldsr_local_irq_restore(unsigned int flags)
7817 + unsigned int temp;
7818 + thread_t self = thread_get_self();
7819 + unsigned int mask = (1 << self);
7820 + flags = (flags << self);
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
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.
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"
7840 + : "d"(flags), "r"(mask), "r"(ldsr_soft_irq_mask)
7846 + * ldsr_local_irq_disable_interrupt()
7847 + * Disable ints for this thread.
7849 +static inline void ldsr_local_irq_disable(void)
7851 + unsigned int mask = (1 << thread_get_self());
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
7861 + " or.4 scratchpad1, scratchpad1, %0 \n\t"
7869 + * ldsr_local_irq_enable_interrupt
7870 + * Enable ints for this thread.
7872 +static inline void ldsr_local_irq_enable(void)
7874 + unsigned int mask = (1 << thread_get_self());
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
7884 + " and.4 scratchpad1, scratchpad1, %0 \n\t"
7885 + " move.4 int_set0, %1 \n\t"
7887 + : "d" (~mask), "r" (ldsr_soft_irq_mask)
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);
7900 +#endif /* _ASM_UBICOM32_LDSR_H */
7902 +++ b/arch/ubicom32/include/asm/linkage.h
7905 + * arch/ubicom32/include/asm/linkage.h
7906 + * Definition of Ubicom32 architecture specific linkage types.
7908 + * (C) Copyright 2009, Ubicom, Inc.
7910 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7926 + * Ubicom32 implementation derived from (with many thanks):
7931 +#ifndef _ASM_UBICOM32_LINKAGE_H
7932 +#define _ASM_UBICOM32_LINKAGE_H
7934 +#define __ocm_text __section(.ocm_text)
7935 +#define __ocm_data __section(.ocm_data)
7937 +#endif /* _ASM_UBICOM32_LINKAGE_H */
7939 +++ b/arch/ubicom32/include/asm/local.h
7942 + * arch/ubicom32/include/asm/local.h
7943 + * Generic local.h for Ubicom32 architecture.
7945 + * (C) Copyright 2009, Ubicom, Inc.
7947 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7963 + * Ubicom32 implementation derived from (with many thanks):
7968 +#ifndef _ASM_UBICOM32_LOCAL_H
7969 +#define _ASM_UBICOM32_LOCAL_H
7971 +#include <asm-generic/local.h>
7973 +#endif /* _ASM_UBICOM32_LOCAL_H */
7975 +++ b/arch/ubicom32/include/asm/machdep.h
7978 + * arch/ubicom32/include/asm/machdep.h
7979 + * Machine dependent utility routines.
7981 + * (C) Copyright 2009, Ubicom, Inc.
7983 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
7999 + * Ubicom32 implementation derived from (with many thanks):
8004 +#ifndef _ASM_UBICOM32_MACHDEP_H
8005 +#define _ASM_UBICOM32_MACHDEP_H
8007 +#include <linux/interrupt.h>
8009 +/* Hardware clock functions */
8010 +extern unsigned long hw_timer_offset(void);
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);
8017 +extern void config_BSP(char *command, int len);
8019 +#endif /* _ASM_UBICOM32_MACHDEP_H */
8021 +++ b/arch/ubicom32/include/asm/mc146818rtc.h
8024 + * arch/ubicom32/include/asm/mc146818rtc.h
8025 + * Generic mc146818rtc.h for Ubicom32 architecture.
8027 + * (C) Copyright 2009, Ubicom, Inc.
8029 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8045 + * Ubicom32 implementation derived from (with many thanks):
8051 + * Machine dependent access functions for RTC registers.
8053 +#ifndef _ASM_UBICOM32_MC146818RTC_H
8054 +#define _ASM_UBICOM32_MC146818RTC_H
8056 +/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
8058 +#endif /* _ASM_UBICOM32_MC146818RTC_H */
8060 +++ b/arch/ubicom32/include/asm/mman.h
8063 + * arch/ubicom32/include/asm/mman.h
8064 + * Memory mapping definitions for Ubicom32 architecture.
8066 + * (C) Copyright 2009, Ubicom, Inc.
8068 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8084 + * Ubicom32 implementation derived from (with many thanks):
8089 +#ifndef _ASM_UBICOM32_MMAN_H
8090 +#define _ASM_UBICOM32_MMAN_H
8092 +#include <asm-generic/mman.h>
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 */
8102 +#define MCL_CURRENT 1 /* lock all current mappings */
8103 +#define MCL_FUTURE 2 /* lock all future mappings */
8105 +#endif /* _ASM_UBICOM32_MMAN_H */
8107 +++ b/arch/ubicom32/include/asm/mmu_context.h
8110 + * arch/ubicom32/include/asm/mmu_context.h
8111 + * MMU context definitions for Ubicom32 architecture.
8113 + * (C) Copyright 2009, Ubicom, Inc.
8114 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.
8116 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8132 + * Ubicom32 implementation derived from (with many thanks):
8138 +#ifndef _ASM_UBICOM32_MMU_CONTEXT_H
8139 +#define _ASM_UBICOM32_MMU_CONTEXT_H
8141 +#include <asm/setup.h>
8142 +#include <asm/page.h>
8143 +#include <asm/pgalloc.h>
8145 +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
8150 +init_new_context(struct task_struct *tsk, struct mm_struct *mm)
8152 + // mm->context = virt_to_phys(mm->pgd);
8156 +#define destroy_context(mm) do { } while(0)
8158 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
8162 +#define deactivate_mm(tsk,mm) do { } while (0)
8164 +extern inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
8168 +#endif /* _ASM_UBICOM32_MMU_CONTEXT_H */
8170 +++ b/arch/ubicom32/include/asm/mmu.h
8173 + * arch/ubicom32/include/asm/mmu.h
8174 + * Definition of mm_context_t struct for Ubicom32 architecture.
8176 + * (C) Copyright 2009, Ubicom, Inc.
8177 + * Copyright (C) 2002, David McCullough <davidm@snapgear.com>
8179 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8195 + * Ubicom32 implementation derived from (with many thanks):
8200 +#ifndef _ASM_UBICOM32_MMU_H
8201 +#define _ASM_UBICOM32_MMU_H
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;
8212 +#endif /* _ASM_UBICOM32_MMU_H */
8214 +++ b/arch/ubicom32/include/asm/module.h
8217 + * arch/ubicom32/include/asm/module.h
8218 + * Ubicom32 architecture specific module definitions.
8220 + * (C) Copyright 2009, Ubicom, Inc.
8222 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8238 + * Ubicom32 implementation derived from (with many thanks):
8243 +#ifndef _ASM_UBICOM32_MODULE_H
8244 +#define _ASM_UBICOM32_MODULE_H
8246 +struct mod_arch_specific {
8248 + int ocm_inst_size;
8251 +#define Elf_Shdr Elf32_Shdr
8252 +#define Elf_Sym Elf32_Sym
8253 +#define Elf_Ehdr Elf32_Ehdr
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)
8259 +#endif /* _ASM_UBICOM32_MODULE_H */
8261 +++ b/arch/ubicom32/include/asm/msgbuf.h
8264 + * arch/ubicom32/include/asm/msgbuf.h
8265 + * Definition of msqid64_ds struct for Ubicom32 architecture.
8267 + * (C) Copyright 2009, Ubicom, Inc.
8269 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8285 + * Ubicom32 implementation derived from (with many thanks):
8290 +#ifndef _ASM_UBICOM32_MSGBUF_H
8291 +#define _ASM_UBICOM32_MSGBUF_H
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.
8298 + * Pad space is left for:
8299 + * - 64-bit time_t to solve y2038 problem
8300 + * - 2 miscellaneous 32-bit values
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;
8320 +#endif /* _ASM_UBICOM32_MSGBUF_H */
8322 +++ b/arch/ubicom32/include/asm/mutex.h
8325 + * arch/ubicom32/include/asm/mutex.h
8326 + * Generic mutex.h for Ubicom32 architecture.
8328 + * (C) Copyright 2009, Ubicom, Inc.
8330 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8346 + * Ubicom32 implementation derived from (with many thanks):
8352 + * Pull in the generic implementation for the mutex fastpath.
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)
8359 +#ifndef _ASM_UBICOM32_MUTEX_H
8360 +#define _ASM_UBICOM32_MUTEX_H
8362 +#include <asm-generic/mutex-dec.h>
8364 +#endif /* _ASM_UBICOM32_MUTEX_H */
8366 +++ b/arch/ubicom32/include/asm/namei.h
8369 + * arch/ubicom32/include/asm/namei.h
8370 + * Definition of __emul_prefix() for Ubicom32 architecture.
8372 + * (C) Copyright 2009, Ubicom, Inc.
8374 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8390 + * Ubicom32 implementation derived from (with many thanks):
8395 +#ifndef _ASM_UBICOM32_NAMEI_H
8396 +#define _ASM_UBICOM32_NAMEI_H
8398 +/* This dummy routine maybe changed to something useful
8399 + * for /usr/gnemul/ emulation stuff.
8400 + * Look at asm-sparc/namei.h for details.
8403 +#define __emul_prefix() NULL
8405 +#endif /* _ASM_UBICOM32_NAMEI_H */
8407 +++ b/arch/ubicom32/include/asm/ocm-alloc.h
8410 + * arch/ubicom32/include/asm/ocm-alloc.h
8411 + * Ubicom32 architecture specific ocm definitions.
8413 + * (C) Copyright 2009, Ubicom, Inc.
8415 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8431 + * Ubicom32 implementation derived from (with many thanks):
8436 +#ifndef _ASM_UBICOM32_OCM_ALLOC_H
8437 +#define _ASM_UBICOM32_OCM_ALLOC_H
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);
8444 +#endif /* _ASM_UBICOM32_OCM_ALLOC_H */
8446 +++ b/arch/ubicom32/include/asm/ocm_size.h
8448 +#define APP_OCM_CODE_SIZE (0x3ffc2e00-0x3ffc0000)
8449 +#define APP_OCM_DATA_SIZE (0x3ffd3500-0x3ffc8000)
8451 +++ b/arch/ubicom32/include/asm/ocm_text.lds.inc
8454 + * arch/ubicom32/include/asm/ocm_text.lds.inc
8455 + * <TODO: Replace with short file description>
8457 + * (C) Copyright 2009, Ubicom, Inc.
8459 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8475 + * Ubicom32 implementation derived from (with many thanks):
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)
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)
8500 +*(.text.pfifo_fast_enqueue)
8501 +*(.text.ipv4_confirm)
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)
8510 +*(.text.skb_checksum)
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)
8521 +*(.text.eth_type_trans)
8522 +*(.text.__alloc_skb)
8524 +*(.text.nf_ip_checksum)
8525 +*(.text.__skb_checksum_complete_head)
8526 +*(.text.ipv4_conntrack_defrag)
8527 +*(.text.tcp_pkt_to_tuple)
8529 +*(.text.tcp_manip_pkt)
8531 +*(.text.nf_ct_get_tuple)
8533 +*(.text.ubi32_eth_start_xmit)
8534 +*(.text.free_block)
8536 +*(.text.kmem_cache_free)
8537 +*(.text.skb_pull_rcsum)
8538 +*(.text.cache_alloc_refill)
8539 +*(.text.skb_release_head_state)
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)
8552 +*(.text.__find_vlan_dev)
8553 +*(.text.ldsr_ctxsw_thread)
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)
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)
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)
8581 +*(.text.ubi32_eth_do_tasklet)
8582 +*(.text.__napi_schedule)
8584 +*(.text.run_timer_softirq)
8585 +*(.text.ldsr_mask_vector)
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)
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)
8603 +*(.text.irq_end_vector)
8604 +*(.text.pci_read_u32)
8605 +*(.text.udivmodsi4)
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)
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)
8629 +++ b/arch/ubicom32/include/asm/page.h
8632 + * arch/ubicom32/include/asm/page.h
8633 + * Memory page related operations and definitions.
8635 + * (C) Copyright 2009, Ubicom, Inc.
8637 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8653 + * Ubicom32 implementation derived from (with many thanks):
8658 +#ifndef _ASM_UBICOM32_PAGE_H
8659 +#define _ASM_UBICOM32_PAGE_H
8661 +/* PAGE_SHIFT determines the page size */
8663 +#define PAGE_SHIFT 12
8664 +#define PAGE_SIZE (1 << PAGE_SHIFT)
8665 +#define PAGE_MASK (~(PAGE_SIZE-1))
8667 +#include <asm/setup.h>
8669 +#ifndef __ASSEMBLY__
8671 +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
8672 +#define free_user_page(page, addr) free_page(addr)
8674 +#define clear_page(page) memset((page), 0, PAGE_SIZE)
8675 +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
8677 +#define clear_user_page(page, vaddr, pg) clear_page(page)
8678 +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
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
8685 + * These are used to make use of C type-checking..
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;
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)
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) } )
8703 +extern unsigned long memory_start;
8704 +extern unsigned long memory_end;
8706 +#endif /* !__ASSEMBLY__ */
8708 +#include <asm/page_offset.h>
8710 +#define PAGE_OFFSET (PAGE_OFFSET_RAW)
8712 +#ifndef __ASSEMBLY__
8714 +#define __pa(vaddr) virt_to_phys((void *)(vaddr))
8715 +#define __va(paddr) phys_to_virt((unsigned long)(paddr))
8717 +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
8718 +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
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)
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)
8727 +#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
8728 + ((void *)(kaddr) < (void *)memory_end))
8730 +#endif /* __ASSEMBLY__ */
8733 +#include <asm-generic/page.h>
8736 +#endif /* _ASM_UBICOM32_PAGE_H */
8738 +++ b/arch/ubicom32/include/asm/page_offset.h
8741 + * arch/ubicom32/include/asm/page_offset.h
8742 + * Definition of PAGE_OFFSET_RAW for Ubicom32 architecture.
8744 + * (C) Copyright 2009, Ubicom, Inc.
8746 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8762 + * Ubicom32 implementation derived from (with many thanks):
8768 +#ifndef _ASM_UBICOM32_PAGE_OFFSET_H
8769 +#define _ASM_UBICOM32_PAGE_OFFSET_H
8771 +/* This handles the memory map.. */
8772 +#define PAGE_OFFSET_RAW 0x3ffc0000
8774 +#endif /* _ASM_UBICOM32_PAGE_OFFSET_H */
8776 +++ b/arch/ubicom32/include/asm/param.h
8779 + * arch/ubicom32/include/asm/param.h
8780 + * Definition of miscellaneous constants, including HZ.
8782 + * (C) Copyright 2009, Ubicom, Inc.
8784 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8800 + * Ubicom32 implementation derived from (with many thanks):
8805 +#ifndef _ASM_UBICOM32_PARAM_H
8806 +#define _ASM_UBICOM32_PARAM_H
8809 +#define HZ CONFIG_HZ
8811 +#define CLOCKS_PER_SEC (USER_HZ)
8818 +#define EXEC_PAGESIZE 4096
8821 +#define NOGROUP (-1)
8824 +#define MAXHOSTNAMELEN 64 /* max length of hostname */
8826 +#endif /* _ASM_UBICOM32_PARAM_H */
8828 +++ b/arch/ubicom32/include/asm/pci.h
8831 + * arch/ubicom32/include/asm/pci.h
8832 + * Definitions of PCI operations for Ubicom32 architecture.
8834 + * (C) Copyright 2009, Ubicom, Inc.
8836 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
8852 + * Ubicom32 implementation derived from (with many thanks):
8857 +#ifndef _ASM_UBICOM32_PCI_H
8858 +#define _ASM_UBICOM32_PCI_H
8860 +#include <asm/io.h>
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.
8866 +#define PCI_DMA_BUS_IS_PHYS (1)
8871 + * Perform a master read/write to the PCI bus.
8872 + * These functions return a PCI_RESP_xxx code.
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);
8882 +#define PCIBIOS_MIN_IO 0x100
8883 +#define PCIBIOS_MIN_MEM 0x10000000
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);
8890 +extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
8891 + struct pci_bus_region *region);
8893 +struct pci_sys_data;
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);
8908 + * Per-controller structure
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 *);
8920 + int (*map_irq)(struct pci_dev *, u8, u8);
8921 + struct hw_pci *hw;
8924 +static inline struct resource *
8925 +pcibios_select_root(struct pci_dev *pdev, struct resource *res)
8927 + struct resource *root = NULL;
8929 + if (res->flags & IORESOURCE_IO)
8930 + root = &ioport_resource;
8931 + if (res->flags & IORESOURCE_MEM)
8932 + root = &iomem_resource;
8937 +static inline void pcibios_set_master(struct pci_dev *dev)
8939 + /* No special bus mastering setup handling */
8941 +#define HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE 1
8942 +#define HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY 1
8945 +static inline void * pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
8946 + dma_addr_t *dma_handle)
8948 + void *vaddr = kmalloc(size, GFP_KERNEL);
8949 + if(vaddr != NULL) {
8950 + *dma_handle = virt_to_phys(vaddr);
8955 +static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
8960 +static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
8961 + void *cpu_addr, dma_addr_t dma_handle)
8967 +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
8968 + size_t size, int direction)
8970 + return virt_to_phys(ptr);
8973 +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
8974 + size_t size, int direction)
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)
8983 + return pci_map_single(hwdev, page_address(page) + offset, size, (int)direction);
8987 +pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
8988 + size_t size, int direction)
8990 + pci_unmap_single(hwdev, dma_address, size, direction);
8994 +pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
8995 + int nents, int direction)
9001 +pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
9002 + int nents, int direction)
9007 +pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
9008 + int nelems, int direction)
9013 +pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
9014 + int nelems, int direction)
9019 +pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
9020 + size_t size, int direction)
9025 +pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
9026 + size_t size, int direction)
9031 +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
9033 + return dma_addr == 0;
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 *);
9039 +#endif /* _ASM_UBICOM32_PCI_H */
9041 +++ b/arch/ubicom32/include/asm/percpu.h
9044 + * arch/ubicom32/include/asm/percpu.h
9045 + * Generic percpu.h for the Ubicom32 architecture.
9047 + * (C) Copyright 2009, Ubicom, Inc.
9049 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9065 + * Ubicom32 implementation derived from (with many thanks):
9070 +#ifndef _ASM_UBICOM32_PERCPU_H
9071 +#define _ASM_UBICOM32_PERCPU_H
9073 +#include <asm-generic/percpu.h>
9075 +#endif /* _ASM_UBICOM32_PERCPU_H */
9077 +++ b/arch/ubicom32/include/asm/pgalloc.h
9080 + * arch/ubicom32/include/asm/pgalloc.h
9081 + * Page table allocation definitions.
9083 + * (C) Copyright 2009, Ubicom, Inc.
9085 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9101 + * Ubicom32 implementation derived from (with many thanks):
9106 +#ifndef _ASM_UBICOM32_PGALLOC_H
9107 +#define _ASM_UBICOM32_PGALLOC_H
9109 +#include <linux/mm.h>
9110 +#include <asm/setup.h>
9112 +#define check_pgt_cache() do { } while (0)
9114 +#endif /* _ASM_UBICOM32_PGALLOC_H */
9116 +++ b/arch/ubicom32/include/asm/pgtable.h
9119 + * arch/ubicom32/include/asm/pgtable.h
9120 + * Ubicom32 pseudo page table definitions and operations.
9122 + * (C) Copyright 2009, Ubicom, Inc.
9123 + * Copyright (C) 2004 Microtronix Datacom Ltd
9125 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9141 + * Ubicom32 implementation derived from (with many thanks):
9145 + * and various works, Alpha, ix86, M68K, Sparc, ...et al
9147 +#ifndef _ASM_UBICOM32_PGTABLE_H
9148 +#define _ASM_UBICOM32_PGTABLE_H
9150 +#include <asm-generic/4level-fixup.h>
9152 +//vic - this bit copied from m68knommu version
9153 +#include <asm/setup.h>
9154 +#include <asm/io.h>
9155 +#include <linux/sched.h>
9157 +typedef pte_t *pte_addr_t;
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)
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
9173 +extern void paging_init(void);
9174 +#define swapper_pg_dir ((pgd_t *) 0)
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 })
9183 + * pgprot_noncached() is only for infiniband pci support, and a real
9184 + * implementation for RAM would be more complicated.
9186 +#define pgprot_noncached(prot) (prot)
9188 +static inline int pte_file(pte_t pte) { return 0; }
9191 + * ZERO_PAGE is a global shared page that is always zero: used
9192 + * for zero-mapped memory areas etc..
9194 +#define ZERO_PAGE(vaddr) (virt_to_page(0))
9196 +extern unsigned int kobjsize(const void *objp);
9197 +extern int is_in_rom(unsigned long);
9200 + * No page table caches to initialise
9202 +#define pgtable_cache_init() do { } while (0)
9204 +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
9205 + remap_pfn_range(vma, vaddr, pfn, size, prot)
9207 +extern inline void flush_cache_mm(struct mm_struct *mm)
9211 +extern inline void flush_cache_range(struct mm_struct *mm,
9212 + unsigned long start,
9213 + unsigned long end)
9217 +/* Push the page at kernel virtual address and clear the icache */
9218 +extern inline void flush_page_to_ram (unsigned long address)
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)
9228 + * All 32bit addresses are effectively valid for vmalloc...
9229 + * Sort of meaningless for non-VM targets.
9231 +#define VMALLOC_START 0
9232 +#define VMALLOC_END 0xffffffff
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)
9241 +#endif /* _ASM_UBICOM32_PGTABLE_H */
9243 +++ b/arch/ubicom32/include/asm/poll.h
9246 + * arch/ubicom32/include/asm/poll.h
9247 + * Ubicom32 specific poll() related flags definitions.
9249 + * (C) Copyright 2009, Ubicom, Inc.
9251 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9267 + * Ubicom32 implementation derived from (with many thanks):
9272 +#ifndef _ASM_UBICOM32_POLL_H
9273 +#define _ASM_UBICOM32_POLL_H
9275 +#define POLLWRNORM POLLOUT
9276 +#define POLLWRBAND 0x0100
9278 +#include <asm-generic/poll.h>
9280 +#endif /* _ASM_UBICOM32_POLL_H */
9282 +++ b/arch/ubicom32/include/asm/posix_types.h
9285 + * arch/ubicom32/include/asm/posix_types.h
9286 + * Ubicom32 architecture posix types.
9288 + * (C) Copyright 2009, Ubicom, Inc.
9289 + * Copyright (C) 2004 Microtronix Datacom Ltd
9291 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9307 + * Ubicom32 implementation derived from (with many thanks):
9312 +#ifndef __ARCH_UBICOM32_POSIX_TYPES_H
9313 +#define __ARCH_UBICOM32_POSIX_TYPES_H
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.
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;
9344 +typedef unsigned short __kernel_old_uid_t;
9345 +typedef unsigned short __kernel_old_gid_t;
9346 +typedef unsigned short __kernel_old_dev_t;
9349 +typedef long long __kernel_loff_t;
9353 +#if defined(__KERNEL__) || defined(__USE_ALL)
9355 +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9357 +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
9360 +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
9363 +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
9366 +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
9369 +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
9372 +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
9374 +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
9378 +++ b/arch/ubicom32/include/asm/processor.h
9381 + * arch/ubicom32/include/asm/processor.h
9382 + * Thread related definitions for Ubicom32 architecture.
9384 + * (C) Copyright 2009, Ubicom, Inc.
9385 + * Copyright (C) 1995 Hamish Macdonald
9387 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9403 + * Ubicom32 implementation derived from (with many thanks):
9409 +#ifndef _ASM_UBICOM32_PROCESSOR_H
9410 +#define _ASM_UBICOM32_PROCESSOR_H
9413 + * Default implementation of macro that returns current
9414 + * instruction pointer ("program counter").
9416 +#define current_text_addr() ({ __label__ _l; _l: &&_l;})
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>
9427 +#if defined(CONFIG_UBICOM32_V3)
9428 + #define CPU "IP5K"
9430 +#if defined(CONFIG_UBICOM32_V4)
9431 + #define CPU "IP7K"
9434 + #define CPU "UNKNOWN"
9438 + * User space process size: 1st byte beyond user address space.
9440 +extern unsigned long memory_end;
9441 +#define TASK_SIZE (memory_end)
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
9447 +#define TASK_UNMAPPED_BASE 0
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.
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. */
9468 +#define INIT_THREAD { \
9469 + 0, 0, 0, 0, 0, 0, 0, 0, \
9470 + sizeof(init_stack) + (unsigned long) init_stack - 8, \
9474 + * Do necessary setup to start up a newly executed thread.
9476 + * pass the data segment into user programs if it exists,
9477 + * it can't hurt anything as far as I can tell
9480 + * Do necessary setup to start up a newly executed thread.
9482 +#define start_thread(regs, new_pc, new_sp) \
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; \
9492 +/* Forward declaration, a strange C thing */
9493 +struct task_struct;
9495 +/* Free all resources held by a thread. */
9496 +static inline void release_thread(struct task_struct *dead_task)
9500 +/* Prepare to copy thread state - unlazy all lazy status */
9501 +#define prepare_to_copy(tsk) do { } while (0)
9503 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
9506 + * Free current thread data structures etc..
9508 +static inline void exit_thread(void)
9512 +unsigned long thread_saved_pc(struct task_struct *tsk);
9513 +unsigned long get_wchan(struct task_struct *p);
9515 +#define KSTK_EIP(tsk) (tsk->thread.a5)
9516 +#define KSTK_ESP(tsk) (tsk->thread.sp)
9518 +#define cpu_relax() barrier()
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);
9528 +#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
9529 +#define KSTK_TOP(info) \
9531 + unsigned long *__ptr = (unsigned long *)(info); \
9532 + (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
9535 +#define task_pt_regs(task) \
9537 + struct pt_regs *__regs__; \
9538 + __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
9542 +#endif /* _ASM_UBICOM32_PROCESSOR_H */
9544 +++ b/arch/ubicom32/include/asm/ptrace.h
9547 + * arch/ubicom32/include/asm/ptrace.h
9548 + * Ubicom32 architecture ptrace support.
9550 + * (C) Copyright 2009, Ubicom, Inc.
9552 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9568 + * Ubicom32 implementation derived from (with many thanks):
9573 +#ifndef _ASM_UBICOM32_PTRACE_H
9574 +#define _ASM_UBICOM32_PTRACE_H
9576 +#ifndef __ASSEMBLY__
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.
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
9616 +#define PT_DUMMY_UNUSED 128
9617 +#define PT_INT_MASK0 132
9618 +#define PT_INT_MASK1 136
9619 +#define PT_TRAP_CAUSE 140
9621 +#define PT_ORIGINAL_D0 148
9622 +#define PT_FRAME_TYPE 152
9625 + * The following 'registers' are not registers at all but are used
9626 + * locate the relocated sections.
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
9635 + * This struct defines the way the registers are stored on the
9636 + * stack during a system call.
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. */
9654 + unsigned long dn[16];
9657 + * Address Registers
9659 + unsigned long an[8];
9662 + * Per thread misc registers.
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;
9675 + unsigned long original_dn_0;
9678 + * Frame type. Syscall frames are -1. For other types look above.
9680 + unsigned long frame_type;
9683 + * These fields are not exposed to ptrace.
9685 + unsigned long previous_pc;
9686 + long nesting_level; /* When the kernel in in user space this
9688 + unsigned long thread_type; /* This indicates if this is a kernel
9693 + * This is the extended stack used by signal handlers and the context
9694 + * switcher: it's pushed after the normal "struct pt_regs".
9696 +struct switch_stack {
9697 + unsigned long dummy;
9702 +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
9703 +#define PTRACE_GETREGS 12
9704 +#define PTRACE_SETREGS 13
9707 +#define PS_S (0x2000)
9708 +#define PS_M (0x1000)
9711 +extern int __user_mode(unsigned long sp);
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__ */
9720 +#endif /* __ASSEMBLY__ */
9722 +#endif /* _ASM_UBICOM32_PTRACE_H */
9724 +++ b/arch/ubicom32/include/asm/range-protect-asm.h
9727 + * arch/ubicom32/include/asm/range-protect-asm.h
9728 + * Assembly macros for enabling memory protection.
9730 + * (C) Copyright 2009, Ubicom, Inc.
9732 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9748 + * Ubicom32 implementation derived from (with many thanks):
9754 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9755 +#define _ASM_UBICOM32_RANGE_PROTECT_ASM_H
9757 +#if defined(__ASSEMBLY__)
9759 +#include <asm/thread-asm.h>
9762 + * You should only use the enable/disable ranges when you have the atomic lock,
9763 + * if you do not there will be problems.
9767 + * enable_kernel_ranges
9768 + * Enable the kernel ranges (disabling protection) for thread,
9769 + * where thread == (1 << thread number)
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
9780 + * enable_kernel_ranges_for_current
9781 + * Enable the kernel ranges (disabling protection) for this thread
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
9791 + * disable_kernel_ranges
9792 + * Disables the kernel ranges (enabling protection) for thread
9793 + * where thread == (1 << thread number)
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
9805 + * disable_kernel_ranges_for_current
9806 + * Disable kernel ranges (enabling protection) for this thread
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
9816 +#endif /* _ASM_UBICOM32_RANGE_PROTECT_ASM_H */
9818 +++ b/arch/ubicom32/include/asm/range-protect.h
9821 + * arch/ubicom32/include/asm/range-protect.h
9822 + * Assembly macros declared in C for enabling memory protection.
9824 + * (C) Copyright 2009, Ubicom, Inc.
9826 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9842 + * Ubicom32 implementation derived from (with many thanks):
9848 +#ifndef _ASM_UBICOM32_RANGE_PROTECT_H
9849 +#define _ASM_UBICOM32_RANGE_PROTECT_H
9851 +#if !defined(__ASSEMBLY__)
9852 +#include <asm/thread.h>
9854 + * The following macros should be the identical to the ones in
9855 + * range-protect-asm.h
9857 + * You should only use the enable/disable ranges when you have the atomic lock,
9858 + * if you do not there will be problems.
9862 + * enable_kernel_ranges
9863 + * Enable the kernel ranges (disabling protection) for thread,
9864 + * where thread == (1 << thread number)
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"
9876 +#else /* __ASSEMBLY__ */
9878 +#include <asm/range-protect-asm.h>
9881 +#endif /* _ASM_UBICOM32_RANGE_PROTECT_H */
9883 +++ b/arch/ubicom32/include/asm/resource.h
9886 + * arch/ubicom32/include/asm/resource.h
9887 + * Generic definitions for Ubicom32 architecture.
9889 + * (C) Copyright 2009, Ubicom, Inc.
9891 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9907 + * Ubicom32 implementation derived from (with many thanks):
9912 +#ifndef _ASM_UBICOM32_RESOURCE_H
9913 +#define _ASM_UBICOM32_RESOURCE_H
9915 +#include <asm-generic/resource.h>
9917 +#endif /* _ASM_UBICOM32_RESOURCE_H */
9919 +++ b/arch/ubicom32/include/asm/ring_tio.h
9922 + * arch/ubicom32/include/asm/ring_tio.h
9923 + * Ubicom32 architecture Ring TIO definitions.
9925 + * (C) Copyright 2009, Ubicom, Inc.
9927 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9943 +#ifndef _ASM_UBICOM32_RING_TIO_H
9944 +#define _ASM_UBICOM32_RING_TIO_H
9946 +#include <asm/devtree.h>
9948 +#define RING_TIO_NODE_VERSION 2
9951 + * Devtree node for ring
9953 +struct ring_tio_node {
9954 + struct devtree_node dn;
9960 +extern void ring_tio_init(const char *node_name);
9962 +#endif /* _ASM_UBICOM32_RING_TIO_H */
9964 +++ b/arch/ubicom32/include/asm/scatterlist.h
9967 + * arch/ubicom32/include/asm/scatterlist.h
9968 + * Definitions of struct scatterlist for Ubicom32 architecture.
9970 + * (C) Copyright 2009, Ubicom, Inc.
9972 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
9988 + * Ubicom32 implementation derived from (with many thanks):
9993 +#ifndef _ASM_UBICOM32_SCATTERLIST_H
9994 +#define _ASM_UBICOM32_SCATTERLIST_H
9996 +#include <linux/mm.h>
9997 +#include <asm/types.h>
9999 +struct scatterlist {
10000 +#ifdef CONFIG_DEBUG_SG
10001 + unsigned long sg_magic;
10003 + unsigned long page_link;
10004 + unsigned int offset;
10005 + dma_addr_t dma_address;
10006 + unsigned int length;
10009 +#define sg_dma_address(sg) ((sg)->dma_address)
10010 +#define sg_dma_len(sg) ((sg)->length)
10012 +#define ISA_DMA_THRESHOLD (0xffffffff)
10014 +#endif /* _ASM_UBICOM32_SCATTERLIST_H */
10016 +++ b/arch/ubicom32/include/asm/sd_tio.h
10019 + * arch/ubicom32/include/asm/sd_tio.h
10020 + * SD TIO definitions
10022 + * (C) Copyright 2009, Ubicom, Inc.
10024 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10040 +#ifndef _ASM_UBICOM32_SD_TIO_H
10041 +#define _ASM_UBICOM32_SD_TIO_H
10043 +#include <asm/devtree.h>
10046 + * Devtree node for SD
10048 +struct sd_tio_node {
10049 + struct devtree_node dn;
10053 +#endif /* _ASM_UBICOM32_SD_TIO_H */
10055 +++ b/arch/ubicom32/include/asm/sections.h
10058 + * arch/ubicom32/include/asm/sections.h
10059 + * Generic sections.h definitions for Ubicom32 architecture.
10061 + * (C) Copyright 2009, Ubicom, Inc.
10063 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10079 + * Ubicom32 implementation derived from (with many thanks):
10084 +#ifndef _ASM_UBICOM32_SECTIONS_H
10085 +#define _ASM_UBICOM32_SECTIONS_H
10087 +#include <asm-generic/sections.h>
10089 +#endif /* _ASM_UBICOM32_SECTIONS_H */
10091 +++ b/arch/ubicom32/include/asm/segment.h
10094 + * arch/ubicom32/include/asm/segment.h
10095 + * Memory segment definitions for Ubicom32 architecture.
10097 + * (C) Copyright 2009, Ubicom, Inc.
10099 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10115 + * Ubicom32 implementation derived from (with many thanks):
10120 +#ifndef _ASM_UBICOM32_SEGMENT_H
10121 +#define _ASM_UBICOM32_SEGMENT_H
10123 +/* define constants */
10124 +/* Address spaces (FC0-FC2) */
10125 +#define USER_DATA (1)
10127 +#define __USER_DS (USER_DATA)
10129 +#define USER_PROGRAM (2)
10130 +#define SUPER_DATA (5)
10131 +#ifndef __KERNEL_DS
10132 +#define __KERNEL_DS (SUPER_DATA)
10134 +#define SUPER_PROGRAM (6)
10135 +#define CPU_SPACE (7)
10137 +#ifndef __ASSEMBLY__
10140 + unsigned long seg;
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)
10148 + * Get/set the SFC/DFC registers for MOVES instructions
10151 +static inline mm_segment_t get_fs(void)
10156 +static inline mm_segment_t get_ds(void)
10158 + /* return the supervisor data space code */
10159 + return KERNEL_DS;
10162 +static inline void set_fs(mm_segment_t val)
10166 +#define segment_eq(a,b) ((a).seg == (b).seg)
10168 +#endif /* __ASSEMBLY__ */
10170 +#endif /* _ASM_UBICOM32_SEGMENT_H */
10172 +++ b/arch/ubicom32/include/asm/semaphore.h
10175 + * arch/ubicom32/include/asm/semaphore.h
10176 + * Interrupt-safe semaphores for Ubicom32 architecture.
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
10183 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10199 + * Ubicom32 implementation derived from (with many thanks):
10204 +#ifndef _ASM_UBICOM32_SEMAPHORE_H
10205 +#define _ASM_UBICOM32_SEMAPHORE_H
10207 +#define RW_LOCK_BIAS 0x01000000
10209 +#ifndef __ASSEMBLY__
10211 +#include <linux/linkage.h>
10212 +#include <linux/wait.h>
10213 +#include <linux/spinlock.h>
10214 +#include <linux/rwsem.h>
10216 +#include <asm/system.h>
10217 +#include <asm/atomic.h>
10219 +struct semaphore {
10222 + wait_queue_head_t wait;
10225 +#define __SEMAPHORE_INITIALIZER(name, n) \
10227 + .count = ATOMIC_INIT(n), \
10228 + .waking = ATOMIC_INIT(0), \
10229 + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
10232 +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
10233 + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
10235 +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
10236 +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
10238 +static inline void sema_init (struct semaphore *sem, int val)
10240 + *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
10243 +static inline void init_MUTEX (struct semaphore *sem)
10245 + sema_init(sem, 1);
10248 +static inline void init_MUTEX_LOCKED (struct semaphore *sem)
10250 + sema_init(sem, 0);
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 */);
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);
10263 +extern spinlock_t semaphore_wake_lock;
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.
10270 +static inline void down(struct semaphore * sem)
10274 + if (atomic_dec_return(&sem->count) < 0)
10278 +static inline int down_interruptible(struct semaphore * sem)
10285 + if(atomic_dec_return(&sem->count) < 0)
10286 + ret = __down_interruptible(sem);
10290 +static inline int down_trylock(struct semaphore * sem)
10294 + if (atomic_dec_return (&sem->count) < 0)
10295 + ret = __down_trylock(sem);
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().
10305 +static inline void up(struct semaphore * sem)
10307 + if (atomic_inc_return(&sem->count) <= 0)
10311 +#endif /* __ASSEMBLY__ */
10313 +#endif /* _ASM_UBICOM32_SEMAPHORE_H */
10315 +++ b/arch/ubicom32/include/asm/semaphore-helper.h
10318 + * arch/ubicom32/include/asm/semaphore-helper.h
10319 + * Semaphore related definitions for Ubicom32 architecture.
10321 + * (C) Copyright 2009, Ubicom, Inc.
10323 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10339 + * Ubicom32 implementation derived from (with many thanks):
10344 +#ifndef _ASM_UBICOM32_SEMAPHORE_HELPER_H
10345 +#define _ASM_UBICOM32_SEMAPHORE_HELPER_H
10348 + * SMP- and interrupt-safe semaphores helper functions.
10350 + * (C) Copyright 1996 Linus Torvalds
10352 + * m68k version by Andreas Schwab
10357 + * These two _must_ execute atomically wrt each other.
10359 +static inline void wake_one_more(struct semaphore * sem)
10361 + atomic_inc(&sem->waking);
10364 +static inline int waking_non_zero(struct semaphore *sem)
10367 + unsigned long flags;
10369 + spin_lock_irqsave(&semaphore_wake_lock, flags);
10371 + if (atomic_read(&sem->waking) > 0) {
10372 + atomic_dec(&sem->waking);
10375 + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10380 + * waking_non_zero_interruptible:
10383 + * -EINTR interrupted
10385 +static inline int waking_non_zero_interruptible(struct semaphore *sem,
10386 + struct task_struct *tsk)
10389 + unsigned long flags;
10391 + spin_lock_irqsave(&semaphore_wake_lock, flags);
10393 + if (atomic_read(&sem->waking) > 0) {
10394 + atomic_dec(&sem->waking);
10396 + } else if (signal_pending(tsk)) {
10397 + atomic_inc(&sem->count);
10400 + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10405 + * waking_non_zero_trylock:
10406 + * 1 failed to lock
10409 +static inline int waking_non_zero_trylock(struct semaphore *sem)
10412 + unsigned long flags;
10414 + spin_lock_irqsave(&semaphore_wake_lock, flags);
10416 + if (atomic_read(&sem->waking) > 0) {
10417 + atomic_dec(&sem->waking);
10420 + atomic_inc(&sem->count);
10421 + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
10425 +#endif /* _ASM_UBICOM32_SEMAPHORE_HELPER_H */
10427 +++ b/arch/ubicom32/include/asm/sembuf.h
10430 + * arch/ubicom32/include/asm/sembuf.h
10431 + * The semid64_ds structure for Ubicom32 architecture.
10433 + * (C) Copyright 2009, Ubicom, Inc.
10435 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10451 + * Ubicom32 implementation derived from (with many thanks):
10456 +#ifndef _ASM_UBICOM32_SEMBUF_H
10457 +#define _ASM_UBICOM32_SEMBUF_H
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.
10464 + * Pad space is left for:
10465 + * - 64-bit time_t to solve y2038 problem
10466 + * - 2 miscellaneous 32-bit values
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;
10480 +#endif /* _ASM_UBICOM32_SEMBUF_H */
10482 +++ b/arch/ubicom32/include/asm/setup.h
10485 + * arch/ubicom32/include/asm/setup.h
10486 + * Kernel command line length definition.
10488 + * (C) Copyright 2009, Ubicom, Inc.
10489 + * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.
10491 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10507 + * Ubicom32 implementation derived from (with many thanks):
10513 +#ifndef _ASM_UBICOM32_SETUP_H
10514 +#define _ASM_UBICOM32_SETUP_H
10516 +#define COMMAND_LINE_SIZE 512
10518 +#endif /* _ASM_UBICOM32_SETUP_H */
10520 +++ b/arch/ubicom32/include/asm/shmbuf.h
10523 + * arch/ubicom32/include/asm/shmbuf.h
10524 + * The shmid64_ds structure for the Ubicom32 architecture.
10526 + * (C) Copyright 2009, Ubicom, Inc.
10528 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10544 + * Ubicom32 implementation derived from (with many thanks):
10549 +#ifndef _ASM_UBICOM32_SHMBUF_H
10550 +#define _ASM_UBICOM32_SHMBUF_H
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.
10557 + * Pad space is left for:
10558 + * - 64-bit time_t to solve y2038 problem
10559 + * - 2 miscellaneous 32-bit values
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;
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;
10590 +#endif /* _ASM_UBICOM32_SHMBUF_H */
10592 +++ b/arch/ubicom32/include/asm/shmparam.h
10595 + * arch/ubicom32/include/asm/shmparam.h
10596 + * Shared memory definitions for Ubicom32 architecture.
10598 + * (C) Copyright 2009, Ubicom, Inc.
10599 + * Copyright (C) 2004 Microtronix Datacom Ltd
10601 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10617 + * Ubicom32 implementation derived from (with many thanks):
10621 + * Alpha, ix86, M68K, Sparc, ...et al
10623 +#ifndef _ASM_UBICOM32_SHMPARAM_H
10624 +#define _ASM_UBICOM32_SHMPARAM_H
10626 +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
10628 +#endif /* _ASM_UBICOM32_SHMPARAM_H */
10630 +++ b/arch/ubicom32/include/asm/sigcontext.h
10633 + * arch/ubicom32/include/asm/sigcontext.h
10634 + * Definition of sigcontext struct for Ubicom32 architecture.
10636 + * (C) Copyright 2009, Ubicom, Inc.
10638 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10654 + * Ubicom32 implementation derived from (with many thanks):
10659 +#ifndef _ASM_UBICOM32_SIGCONTEXT_H
10660 +#define _ASM_UBICOM32_SIGCONTEXT_H
10662 +#include <asm/ptrace.h>
10664 +struct sigcontext {
10665 + struct pt_regs sc_regs;
10668 +#endif /* _ASM_UBICOM32_SIGCONTEXT_H */
10670 +++ b/arch/ubicom32/include/asm/siginfo.h
10673 + * arch/ubicom32/include/asm/siginfo.h
10674 + * Generic siginfo.h definitions for Ubicom32 architecture.
10676 + * (C) Copyright 2009, Ubicom, Inc.
10678 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10694 + * Ubicom32 implementation derived from (with many thanks):
10699 +#ifndef _ASM_UBICOM32_SIGINFO_H
10700 +#define _ASM_UBICOM32_SIGINFO_H
10702 +#include <asm-generic/siginfo.h>
10704 +#endif /* _ASM_UBICOM32_SIGINFO_H */
10706 +++ b/arch/ubicom32/include/asm/signal.h
10709 + * arch/ubicom32/include/asm/signal.h
10710 + * Signal related definitions for Ubicom32 architecture.
10712 + * (C) Copyright 2009, Ubicom, Inc.
10714 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10730 + * Ubicom32 implementation derived from (with many thanks):
10735 +#ifndef _ASM_UBICOM32_SIGNAL_H
10736 +#define _ASM_UBICOM32_SIGNAL_H
10738 +#include <linux/types.h>
10740 +/* Avoid too many header ordering problems. */
10744 +/* Most things should be clean enough to redefine this at will, if care
10745 + is taken to make libc match. */
10748 +#define _NSIG_BPW 32
10749 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
10751 +typedef unsigned long old_sigset_t; /* at least 32 bits */
10754 + unsigned long sig[_NSIG_WORDS];
10757 +#endif /* __KERNEL__ */
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
10783 +#define SIGXCPU 24
10784 +#define SIGXFSZ 25
10785 +#define SIGVTALRM 26
10786 +#define SIGPROF 27
10787 +#define SIGWINCH 28
10789 +#define SIGPOLL SIGIO
10791 +#define SIGLOST 29
10795 +#define SIGUNUSED 31
10797 +/* These should not be considered constants from userland. */
10798 +#define SIGRTMIN 32
10799 +#define SIGRTMAX _NSIG
10802 + * SA_FLAGS values:
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.
10811 + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
10812 + * Unix names RESETHAND and NODEFER respectively.
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
10822 +#define SA_NOMASK SA_NODEFER
10823 +#define SA_ONESHOT SA_RESETHAND
10826 + * sigaltstack controls
10828 +#define SS_ONSTACK 1
10829 +#define SS_DISABLE 2
10831 +#define MINSIGSTKSZ 2048
10832 +#define SIGSTKSZ 8192
10834 +#include <asm-generic/signal.h>
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);
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 */
10851 +struct k_sigaction {
10852 + struct sigaction sa;
10855 +/* Here we must cater to libcs that poke about in kernel headers. */
10857 +struct sigaction {
10859 + __sighandler_t _sa_handler;
10860 + void (*_sa_sigaction)(int, struct siginfo *, void *);
10862 + sigset_t sa_mask;
10863 + unsigned long sa_flags;
10864 + void (*sa_restorer)(void);
10867 +#define sa_handler _u._sa_handler
10868 +#define sa_sigaction _u._sa_sigaction
10870 +#endif /* __KERNEL__ */
10872 +typedef struct sigaltstack {
10880 +#include <asm/sigcontext.h>
10881 +#undef __HAVE_ARCH_SIG_BITOPS
10883 +#define ptrace_signal_deliver(regs, cookie) do { } while (0)
10885 +#endif /* __KERNEL__ */
10887 +#endif /* _ASM_UBICOM32_SIGNAL_H */
10889 +++ b/arch/ubicom32/include/asm/smp.h
10892 + * arch/ubicom32/include/asm/smp.h
10893 + * SMP definitions for Ubicom32 architecture.
10895 + * (C) Copyright 2009, Ubicom, Inc.
10897 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10913 + * Ubicom32 implementation derived from (with many thanks):
10918 +#ifndef _ASM_UBICOM32_SMP_H
10919 +#define _ASM_UBICOM32_SMP_H
10922 +#include <linux/bitops.h>
10923 +#include <linux/threads.h>
10924 +#include <linux/cpumask.h>
10925 +#include <asm/ip5000.h>
10927 +typedef unsigned long address_t;
10928 +extern cpumask_t cpu_online_map;
10929 +extern unsigned int smp_ipi_irq;
10932 + * This magic constant controls our willingness to transfer
10933 + * a process across CPUs.
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.
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 */
10944 +#define raw_smp_processor_id() (current_thread_info()->cpu)
10945 +#endif /* CONFIG_SMP */
10947 +static inline int __cpu_disable (void)
10952 +static inline void __cpu_die (unsigned int cpu)
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);
10966 + * TODO: Once these are fully tested, we should turn them into
10967 + * inline macros for performance.
10969 +extern unsigned long smp_get_affinity(unsigned int irq, int *all);
10970 +extern void smp_reset_ipi(unsigned long mask);
10972 +#endif /* !ASSEMBLY */
10973 +#endif /* _ASM_UBICOM32_SMP_H */
10975 +++ b/arch/ubicom32/include/asm/socket.h
10978 + * arch/ubicom32/include/asm/socket.h
10979 + * Socket options definitions for Ubicom32 architecture.
10981 + * (C) Copyright 2009, Ubicom, Inc.
10983 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
10999 + * Ubicom32 implementation derived from (with many thanks):
11004 +#ifndef _ASM_UBICOM32_SOCKET_H
11005 +#define _ASM_UBICOM32_SOCKET_H
11007 +#include <asm/sockios.h>
11009 +/* For setsockopt(2) */
11010 +#define SOL_SOCKET 1
11012 +#define SO_DEBUG 1
11013 +#define SO_REUSEADDR 2
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
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
11041 +#define SO_BINDTODEVICE 25
11043 +/* Socket filtering */
11044 +#define SO_ATTACH_FILTER 26
11045 +#define SO_DETACH_FILTER 27
11047 +#define SO_PEERNAME 28
11048 +#define SO_TIMESTAMP 29
11049 +#define SCM_TIMESTAMP SO_TIMESTAMP
11051 +#define SO_ACCEPTCONN 30
11053 +#define SO_PEERSEC 31
11054 +#define SO_PASSSEC 34
11055 +#define SO_TIMESTAMPNS 35
11056 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
11058 +#define SO_MARK 36
11060 +#endif /* _ASM_UBICOM32_SOCKET_H */
11062 +++ b/arch/ubicom32/include/asm/sockios.h
11065 + * arch/ubicom32/include/asm/sockios.h
11066 + * Socket-level ioctl definitions for Ubicom32 architecture.
11068 + * (C) Copyright 2009, Ubicom, Inc.
11070 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11086 + * Ubicom32 implementation derived from (with many thanks):
11091 +#ifndef _ASM_UBICOM32_SOCKIOS_H
11092 +#define _ASM_UBICOM32_SOCKIOS_H
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) */
11103 +#endif /* _ASM_UBICOM32_SOCKIOS_H */
11105 +++ b/arch/ubicom32/include/asm/spinlock.h
11108 + * arch/ubicom32/include/asm/spinlock.h
11109 + * Spinlock related definitions for Ubicom32 architecture.
11111 + * (C) Copyright 2009, Ubicom, Inc.
11113 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11129 + * Ubicom32 implementation derived from (with many thanks):
11134 +#ifndef _ASM_UBICOM32_SPINLOCK_H
11135 +#define _ASM_UBICOM32_SPINLOCK_H
11137 +#include <asm/system.h>
11138 +#include <asm/processor.h>
11139 +#include <asm/spinlock_types.h>
11142 + * __raw_spin_lock()
11145 +static inline void __raw_spin_lock(raw_spinlock_t *x)
11148 + "1: bset %0, %0, #0 \n\t"
11149 + " jmpne.f 1b \n\t"
11150 + : "+U4" (x->lock)
11157 + * __raw_spin_unlock()
11158 + * Unlock the lock.
11160 +static inline void __raw_spin_unlock(raw_spinlock_t *x)
11163 + " bclr %0, %0, #0 \n\t"
11164 + : "+U4" (x->lock)
11171 + * __raw_spin_is_locked()
11172 + * Test if the lock is locked.
11174 +static inline int __raw_spin_is_locked(raw_spinlock_t *x)
11180 + * __raw_spin_unlock_wait()
11181 + * Wait for the lock to be unlocked.
11183 + * Note: the caller has not guarantee that the lock will not
11184 + * be acquired before they get to it.
11186 +static inline void __raw_spin_unlock_wait(raw_spinlock_t *x)
11190 + } while (__raw_spin_is_locked(x));
11194 + * __raw_spin_trylock()
11195 + * Try the lock, return 0 on failure, 1 on success.
11197 +static inline int __raw_spin_trylock(raw_spinlock_t *x)
11202 + " bset %1, %1, #0 \n\t"
11203 + " jmpne.f 1f \n\t"
11204 + " move.4 %0, #1 \n\t"
11206 + : "+r" (ret), "+U4" (x->lock)
11215 + * __raw_spin_lock_flags()
11216 + * Spin waiting for the lock (enabling IRQ(s))
11218 +static inline void __raw_spin_lock_flags(raw_spinlock_t *x, unsigned long flags)
11221 + while (!__raw_spin_trylock(x)) {
11223 + * If the flags from the IRQ are set, interrupts are disabled and we
11224 + * need to re-enable them.
11229 + raw_local_irq_enable();
11231 + raw_local_irq_disable();
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.
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.
11250 + * __raw_read_lock()
11251 + * Increment the counter in the rwlock.
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
11256 +static inline void __raw_read_lock(raw_rwlock_t *rw)
11258 + unsigned long flags;
11259 + raw_local_irq_save(flags);
11260 + __raw_spin_lock_flags(&rw->lock, flags);
11262 + __raw_spin_unlock(&rw->lock);
11263 + raw_local_irq_restore(flags);
11267 + * __raw_read_unlock()
11268 + * Decrement the counter.
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
11273 +static inline void __raw_read_unlock(raw_rwlock_t *rw)
11275 + unsigned long flags;
11276 + raw_local_irq_save(flags);
11277 + __raw_spin_lock_flags(&rw->lock, flags);
11279 + __raw_spin_unlock(&rw->lock);
11280 + raw_local_irq_restore(flags);
11284 + * __raw_read_trylock()
11285 + * Increment the counter if we can.
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
11290 +static inline int __raw_read_trylock(raw_rwlock_t *rw)
11292 + unsigned long flags;
11294 + raw_local_irq_save(flags);
11295 + if (__raw_spin_trylock(&rw->lock)) {
11297 + __raw_spin_unlock(&rw->lock);
11298 + raw_local_irq_restore(flags);
11302 + raw_local_irq_restore(flags);
11305 + * If write-locked, we fail to acquire the lock
11307 + if (rw->counter < 0) {
11312 + * Wait until we have a realistic chance at the lock
11314 + while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0) {
11322 + * __raw_write_lock()
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
11327 +static inline void __raw_write_lock(raw_rwlock_t *rw)
11329 + unsigned long flags;
11331 + raw_local_irq_save(flags);
11332 + __raw_spin_lock_flags(&rw->lock, flags);
11334 + if (rw->counter != 0) {
11335 + __raw_spin_unlock(&rw->lock);
11336 + raw_local_irq_restore(flags);
11338 + while (rw->counter != 0)
11344 + rw->counter = -1; /* mark as write-locked */
11346 + raw_local_irq_restore(flags);
11349 +static inline void __raw_write_unlock(raw_rwlock_t *rw)
11352 + __raw_spin_unlock(&rw->lock);
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)
11359 + unsigned long flags;
11362 + raw_local_irq_save(flags);
11363 + if (__raw_spin_trylock(&rw->lock)) {
11364 + if (rw->counter == 0) {
11365 + rw->counter = -1;
11368 + /* Read-locked. Oh well. */
11369 + __raw_spin_unlock(&rw->lock);
11372 + raw_local_irq_restore(flags);
11378 + * read_can_lock - would read_trylock() succeed?
11379 + * @lock: the rwlock in question.
11381 +static inline int __raw_read_can_lock(raw_rwlock_t *rw)
11383 + return rw->counter >= 0;
11387 + * write_can_lock - would write_trylock() succeed?
11388 + * @lock: the rwlock in question.
11390 +static inline int __raw_write_can_lock(raw_rwlock_t *rw)
11392 + return !rw->counter;
11395 +#define _raw_spin_relax(lock) cpu_relax()
11396 +#define _raw_read_relax(lock) cpu_relax()
11397 +#define _raw_write_relax(lock) cpu_relax()
11399 +#endif /* _ASM_UBICOM32_SPINLOCK_H */
11401 +++ b/arch/ubicom32/include/asm/spinlock_types.h
11404 + * arch/ubicom32/include/asm/spinlock_types.h
11405 + * Spinlock related structure definitions for Ubicom32 architecture.
11407 + * (C) Copyright 2009, Ubicom, Inc.
11409 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11425 + * Ubicom32 implementation derived from (with many thanks):
11430 +#ifndef _ASM_UBICOM32_SPINLOCK_TYPES_H
11431 +#define _ASM_UBICOM32_SPINLOCK_TYPES_H
11434 + volatile unsigned int lock;
11438 + raw_spinlock_t lock;
11439 + volatile int counter;
11442 +#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
11443 +#define __RAW_RW_LOCK_UNLOCKED { __RAW_SPIN_LOCK_UNLOCKED, 0 }
11445 +#endif /* _ASM_UBICOM32_SPINLOCK_TYPES_H */
11447 +++ b/arch/ubicom32/include/asm/stacktrace.h
11450 + * arch/ubicom32/include/asm/stacktrace.h
11451 + * Stacktrace functions for the Ubicom32 architecture.
11453 + * (C) Copyright 2009, Ubicom, Inc.
11455 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11471 + * Ubicom32 implementation derived from (with many thanks):
11476 +#ifndef _ASM_UBICOM32_STACKTRACE_H
11477 +#define _ASM_UBICOM32_STACKTRACE_H
11479 +#define between(a, b, c) (( \
11480 + ((unsigned long) a) >= ((unsigned long) b)) && \
11481 + (((unsigned long)a) <= ((unsigned long)c)))
11484 + * These symbols are filled in by the linker.
11486 +extern unsigned long _stext;
11487 +extern unsigned long _etext;
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;
11493 +/* Account for OCM case - see stacktrace.c maybe combine(also trap.c) */
11495 + * ubicom32_is_kernel()
11497 + * Check to see if the given address belongs to the kernel.
11498 + * NOMMU does not permit any other means.
11500 +static inline int ubicom32_is_kernel(unsigned long addr)
11502 + int is_kernel = between(addr, &_stext, &_etext) || \
11503 + between(addr, &__ocm_text_run_begin, &__data_begin);
11505 +#ifdef CONFIG_MODULES
11507 + is_kernel = is_module_address(addr);
11509 + return is_kernel;
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);
11520 +#endif /* _ASM_UBICOM32_STACKTRACE_H */
11522 +++ b/arch/ubicom32/include/asm/statfs.h
11525 + * arch/ubicom32/include/asm/statfs.h
11526 + * Generic statfs.h definitions
11528 + * (C) Copyright 2009, Ubicom, Inc.
11530 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11546 + * Ubicom32 implementation derived from (with many thanks):
11551 +#ifndef _ASM_UBICOM32_STATFS_H
11552 +#define _ASM_UBICOM32_STATFS_H
11554 +#include <asm-generic/statfs.h>
11556 +#endif /* _ASM_UBICOM32_STATFS_H */
11558 +++ b/arch/ubicom32/include/asm/stat.h
11561 + * arch/ubicom32/include/asm/stat.h
11562 + * File status definitions for Ubicom32 architecture.
11564 + * (C) Copyright 2009, Ubicom, Inc.
11566 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11582 + * Ubicom32 implementation derived from (with many thanks):
11587 +#ifndef _ASM_UBICOM32_STAT_H
11588 +#define _ASM_UBICOM32_STAT_H
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;
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;
11627 +/* This matches struct stat64 in glibc2.1, hence the absolutely
11628 + * insane amounts of padding around dev_t's.
11631 + unsigned long long st_dev;
11632 + unsigned char __pad1[2];
11634 +#define STAT64_HAS_BROKEN_ST_INO 1
11635 + unsigned long __st_ino;
11637 + unsigned int st_mode;
11638 + unsigned int st_nlink;
11640 + unsigned long st_uid;
11641 + unsigned long st_gid;
11643 + unsigned long long st_rdev;
11644 + unsigned char __pad3[2];
11646 + long long st_size;
11647 + unsigned long st_blksize;
11649 + unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
11651 + unsigned long st_atime;
11652 + unsigned long st_atime_nsec;
11654 + unsigned long st_mtime;
11655 + unsigned long st_mtime_nsec;
11657 + unsigned long st_ctime;
11658 + unsigned long st_ctime_nsec;
11660 + unsigned long long st_ino;
11663 +#endif /* _ASM_UBICOM32_STAT_H */
11665 +++ b/arch/ubicom32/include/asm/string.h
11668 + * arch/ubicom32/include/asm/string.h
11669 + * String operation definitions for Ubicom32 architecture.
11671 + * (C) Copyright 2009, Ubicom, Inc.
11673 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11689 + * Ubicom32 implementation derived from (with many thanks):
11694 +#ifndef _ASM_UBICOM32_STRING_H
11695 +#define _ASM_UBICOM32_STRING_H
11697 +#define __HAVE_ARCH_MEMSET
11698 +extern void *memset(void *b, int c, size_t len);
11700 +#define __HAVE_ARCH_MEMCPY
11701 +extern void *memcpy(void *to, const void *from, size_t len);
11703 +#endif /* _ASM_UBICOM32_STRING_H */
11705 +++ b/arch/ubicom32/include/asm/switch-bcm539x.h
11708 + * arch/ubicom32/include/asm/switch-bcm539x.h
11709 + * Broadcom bcm539x platform data definitions for Ubicom32 architecture.
11711 + * (C) Copyright 2009, Ubicom, Inc.
11713 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11729 + * Ubicom32 implementation derived from (with many thanks):
11734 +#ifndef _ASM_UBICOM32_SWITCH_BCM539X_H
11735 +#define _ASM_UBICOM32_SWITCH_BCM539X_H
11737 +#define SWITCH_BCM539X_FLAG_HW_RESET 0x01
11738 +#define SWITCH_BCM539X_FLAG_SW_RESET 0x02
11740 +struct switch_bcm539x_platform_data {
11742 + * See flags above
11747 + * GPIO to use for nReset
11753 + * GPIO to use for chip select
11758 + * Name of this switch
11760 + const char *name;
11763 +#endif /* _ASM_UBICOM32_SWITCH_BCM539X_H */
11765 +++ b/arch/ubicom32/include/asm/system.h
11768 + * arch/ubicom32/include/asm/system.h
11769 + * Low level switching definitions.
11771 + * (C) Copyright 2009, Ubicom, Inc.
11773 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11789 + * Ubicom32 implementation derived from (with many thanks):
11794 +#ifndef _ASM_UBICOM32_SYSTEM_H
11795 +#define _ASM_UBICOM32_SYSTEM_H
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>
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.
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);
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.
11820 +#define switch_to(prev,next,last) \
11823 + _last = (void *) \
11824 + __switch_to(prev, &prev->thread, &next->thread); \
11825 + (last) = _last; \
11829 + * Force strict CPU ordering.
11830 + * Not really required on ubicom32...
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(); })
11839 +#define smp_mb() mb()
11840 +#define smp_rmb() rmb()
11841 +#define smp_wmb() wmb()
11842 +#define smp_read_barrier_depends() read_barrier_depends()
11844 +#define smp_mb() mb()
11845 +#define smp_rmb() rmb()
11846 +#define smp_wmb() wmb()
11847 +#define smp_read_barrier_depends() do { } while(0)
11850 +#define read_barrier_depends() ((void)0)
11853 + * The following defines change how the scheduler calls the switch_to()
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.
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.
11864 +// #define __ARCH_WANT_UNLOCKED_CTXSW
11865 +// #define __ARCH_WANT_INTERRUPTS_ON_CTXSW
11867 +#endif /* _ASM_UBICOM32_SYSTEM_H */
11869 +++ b/arch/ubicom32/include/asm/termbits.h
11872 + * arch/ubicom32/include/asm/termbits.h
11873 + * Terminal/serial port definitions for Ubicom32 architecture.
11875 + * (C) Copyright 2009, Ubicom, Inc.
11877 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
11893 + * Ubicom32 implementation derived from (with many thanks):
11898 +#ifndef _ASM_UBICOM32_TERMBITS_H
11899 +#define _ASM_UBICOM32_TERMBITS_H
11901 +#include <linux/posix_types.h>
11903 +typedef unsigned char cc_t;
11904 +typedef unsigned int speed_t;
11905 +typedef unsigned int tcflag_t;
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 */
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 */
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 */
11939 +/* c_cc characters */
11952 +#define VREPRINT 12
11953 +#define VDISCARD 13
11954 +#define VWERASE 14
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
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
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 */
12061 +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
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
12081 +/* tcflow() and TCXONC use these */
12087 +/* tcflush() and TCFLSH use these */
12088 +#define TCIFLUSH 0
12089 +#define TCOFLUSH 1
12090 +#define TCIOFLUSH 2
12092 +/* tcsetattr uses these */
12094 +#define TCSADRAIN 1
12095 +#define TCSAFLUSH 2
12097 +#endif /* _ASM_UBICOM32_TERMBITS_H */
12099 +++ b/arch/ubicom32/include/asm/termios.h
12102 + * arch/ubicom32/include/asm/termios.h
12103 + * Ubicom32 termio definitions.
12105 + * (C) Copyright 2009, Ubicom, Inc.
12107 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12123 + * Ubicom32 implementation derived from (with many thanks):
12128 +#ifndef _ASM_UBICOM32_TERMIOS_H
12129 +#define _ASM_UBICOM32_TERMIOS_H
12131 +#include <asm/termbits.h>
12132 +#include <asm/ioctls.h>
12135 + unsigned short ws_row;
12136 + unsigned short ws_col;
12137 + unsigned short ws_xpixel;
12138 + unsigned short ws_ypixel;
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 */
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
12158 +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
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
12177 +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
12182 + * Translate a "termio" structure into a "termios". Ugh.
12184 +#define user_termio_to_kernel_termios(termios, termio) \
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); \
12200 + * Translate a "termios" structure into a "termio". Ugh.
12202 +#define kernel_termios_to_user_termio(termio, termios) \
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); \
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))
12217 +#endif /* __KERNEL__ */
12219 +#endif /* _ASM_UBICOM32_TERMIOS_H */
12221 +++ b/arch/ubicom32/include/asm/thread-asm.h
12224 + * arch/ubicom32/include/asm/thread-asm.h
12225 + * Ubicom32 architecture specific thread definitions.
12227 + * (C) Copyright 2009, Ubicom, Inc.
12229 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12245 + * Ubicom32 implementation derived from (with many thanks):
12250 +#ifndef _ASM_UBICOM32_THREAD_ASM_H
12251 +#define _ASM_UBICOM32_THREAD_ASM_H
12254 + * thread_get_self
12255 + * Read and shift the current thread into reg
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 */
12263 + * thread_get_self_mask
12264 + * Read and shift the current thread mask into reg
12266 +.macro thread_get_self_mask reg
12267 + lsr.4 \reg, ROSR, #2
12268 + lsl.4 \reg, #1, \reg /* Thread bit */
12271 +#endif /* _ASM_UBICOM32_THREAD_ASM_H */
12273 +++ b/arch/ubicom32/include/asm/thread.h
12276 + * arch/ubicom32/include/asm/thread.h
12277 + * Ubicom32 architecture specific thread definitions.
12279 + * (C) Copyright 2009, Ubicom, Inc.
12281 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12297 + * Ubicom32 implementation derived from (with many thanks):
12302 +#ifndef _ASM_UBICOM32_THREAD_H
12303 +#define _ASM_UBICOM32_THREAD_H
12305 +#if !defined(__ASSEMBLY__)
12307 +#include <asm/ptrace.h>
12308 +#include <asm/ubicom32-common.h>
12310 +typedef int thread_t;
12311 +typedef unsigned char thread_type_t;
12312 +typedef void (*thread_exec_fn_t)(void *arg);
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)
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.
12324 +#define THREAD_ARCHITECTURAL_MAX 16
12327 + * TODO: Rename this at some point to be thread_
12329 +extern unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
12333 + * thread_get_self()
12335 +static inline thread_t thread_get_self(void)
12339 + "lsr.4 %0, ROSR, #2 \n\t"
12344 + return result & 31;
12348 + * thread_suspend()
12350 +static inline void thread_suspend(void)
12360 + * thread_resume()
12362 +static inline void thread_resume(thread_t thread)
12365 + "move.4 MT_ACTIVE_SET, %0 \n\t"
12366 + "pipe_flush 0 \n\t"
12367 + "pipe_flush 0 \n\t"
12369 + : "d" (1 << thread)
12376 + * thread_enable_mask()
12377 + * Enable all threads in the mask.
12379 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12381 +static inline void thread_enable_mask(unsigned int mask)
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,
12391 + UBICOM32_LOCK(MT_EN_LOCK_BIT);
12393 + "or.4 MT_EN, MT_EN, %0 \n\t"
12394 + "pipe_flush 0 \n\t"
12395 + "pipe_flush 0 \n\t"
12400 + UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12404 + * thread_enable()
12406 +static inline void thread_enable(thread_t thread)
12408 + thread_enable_mask(1 << thread);
12412 + * thread_disable_mask()
12413 + * Disable all threads in the mask.
12415 + * All writes to MT_EN must be protected by the MT_EN_LOCK bit
12417 +static inline void thread_disable_mask(unsigned int mask)
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,
12427 + UBICOM32_LOCK(MT_EN_LOCK_BIT);
12429 + "and.4 MT_EN, MT_EN, %0 \n\t"
12430 + "pipe_flush 0 \n\t"
12431 + "pipe_flush 0 \n\t"
12436 + UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
12440 + * thread_disable()
12442 +static inline void thread_disable(thread_t thread)
12444 + thread_disable_mask(1 << thread);
12448 + * thread_disable_others()
12449 + * Disable all other threads
12451 +static inline void thread_disable_others(void)
12453 + thread_t self = thread_get_self();
12454 + thread_disable_mask(~(1 << self));
12458 + * thread_is_trapped()
12459 + * Is the specified tid trapped?
12461 +static inline int thread_is_trapped(thread_t tid)
12463 + int thread_mask = (1 << tid);
12467 + "move.4 %0, MT_TRAP \n\t"
12468 + : "=d" (trap_thread)
12471 + return (trap_thread & thread_mask);
12475 + * thread_is_enabled()
12476 + * Is the specified tid enabled?
12478 +static inline int thread_is_enabled(thread_t tid)
12480 + int thread_mask = (1 << tid);
12481 + int enabled_threads;
12484 + "move.4 %0, MT_EN \n\t"
12485 + : "=d" (enabled_threads)
12488 + return (enabled_threads & thread_mask);
12492 + * thread_get_instruction_count()
12494 +static inline unsigned int thread_get_instruction_count(void)
12496 + unsigned int result;
12498 + "move.4 %0, INST_CNT \n\t"
12505 + * thread_get_pc()
12506 + * pc could point to a speculative and cancelled instruction unless thread is disabled
12508 +static inline void *thread_get_pc(thread_t thread)
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"
12518 + : "r" ((thread << 9) | (1 << 8))
12524 + * thread_get_trap_cause()
12525 + * This should be called only when the thread is not running
12527 +static inline unsigned int thread_get_trap_cause(thread_t thread)
12529 + unsigned int result;
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"
12537 + : "r" ((thread << 9) | (1 << 8))
12543 + * THREAD_STALL macro.
12545 +#define THREAD_STALL \
12547 + "move.4 mt_dbg_active_clr, #-1 \n\t" \
12548 + "pipe_flush 0 \n\t" \
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);
12563 + * thread_get_self
12564 + * Read and shift the current thread into reg
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
12573 + * thread_get_self_mask
12574 + * Read and shift the current thread mask into reg
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 */
12582 +#else /* __ASSEMBLY__ */
12584 +#include <asm/thread-asm.h>
12586 +#endif /* __ASSEMBLY__ */
12587 +#endif /* _ASM_UBICOM32_THREAD_H */
12589 +++ b/arch/ubicom32/include/asm/thread_info.h
12592 + * arch/ubicom32/include/asm/thread_info.h
12593 + * Ubicom32 architecture low-level thread information.
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
12600 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12616 + * Ubicom32 implementation derived from (with many thanks):
12622 +#ifndef _ASM_UBICOM32_THREAD_INFO_H
12623 +#define _ASM_UBICOM32_THREAD_INFO_H
12625 +#include <asm/page.h>
12628 + * Size of kernel stack for each process. This must be a power of 2...
12630 +#ifdef CONFIG_4KSTACKS
12631 +#define THREAD_SIZE_ORDER (0)
12633 +#define THREAD_SIZE_ORDER (1)
12637 + * for asm files, THREAD_SIZE is now generated by asm-offsets.c
12639 +#define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
12643 +#ifndef __ASSEMBLY__
12646 + * low level task data.
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;
12659 + * macros/functions for gaining access to the thread information structure
12661 +#define INIT_THREAD_INFO(tsk) \
12664 + .exec_domain = &default_exec_domain, \
12667 + .interrupt_nesting = 0, \
12668 + .restart_block = { \
12669 + .fn = do_no_restart_syscall, \
12673 +#define init_thread_info (init_thread_union.thread_info)
12674 +#define init_stack (init_thread_union.stack)
12677 +/* how to get the thread information struct from C */
12678 +static inline struct thread_info *current_thread_info(void)
12680 + struct thread_info *ti;
12683 + "and.4 %0, sp, %1\n\t"
12685 + : "d" (~(THREAD_SIZE-1))
12692 +#define STACK_WARN (THREAD_SIZE / 8)
12694 +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 1
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__ */
12702 +#define PREEMPT_ACTIVE 0x4000000
12705 + * thread information flag bit numbers
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
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)
12720 +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
12722 +#endif /* __KERNEL__ */
12724 +#endif /* _ASM_UBICOM32_THREAD_INFO_H */
12726 +++ b/arch/ubicom32/include/asm/timex.h
12729 + * arch/ubicom32/include/asm/timex.h
12730 + * Ubicom32 architecture timex specifications.
12732 + * (C) Copyright 2009, Ubicom, Inc.
12734 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12750 + * Ubicom32 implementation derived from (with many thanks):
12755 +#ifndef _ASM_UBICOM32_TIMEX_H
12756 +#define _ASM_UBICOM32_TIMEX_H
12758 +#define CLOCK_TICK_RATE 266000000
12760 +// #define ARCH_HAS_READ_CURRENT_TIMER
12762 +typedef unsigned long cycles_t;
12764 +static inline cycles_t get_cycles(void)
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);
12775 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12776 +extern void local_timer_interrupt(void);
12779 +#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
12780 +extern int local_timer_setup(unsigned int cpu);
12783 +#endif /* _ASM_UBICOM32_TIMEX_H */
12785 +++ b/arch/ubicom32/include/asm/tlbflush.h
12788 + * arch/ubicom32/include/asm/tlbflush.h
12789 + * TLB operations for Ubicom32 architecture.
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>
12795 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12811 + * Ubicom32 implementation derived from (with many thanks):
12816 +#ifndef _ASM_UBICOM32_TLB_FLUSH_H
12817 +#define _ASM_UBICOM32_TLB_FLUSH_H
12819 +#include <asm/setup.h>
12822 + * flush all user-space atc entries.
12824 +static inline void __flush_tlb(void)
12829 +static inline void __flush_tlb_one(unsigned long addr)
12834 +#define flush_tlb() __flush_tlb()
12837 + * flush all atc entries (both kernel and user-space entries).
12839 +static inline void flush_tlb_all(void)
12844 +static inline void flush_tlb_mm(struct mm_struct *mm)
12849 +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
12854 +static inline void flush_tlb_range(struct mm_struct *mm,
12855 + unsigned long start, unsigned long end)
12860 +static inline void flush_tlb_kernel_page(unsigned long addr)
12865 +#endif /* _ASM_UBICOM32_TLB_FLUSH_H */
12867 +++ b/arch/ubicom32/include/asm/tlb.h
12870 + * arch/ubicom32/include/asm/tlb.h
12871 + * Ubicom32 architecture TLB operations.
12873 + * (C) Copyright 2009, Ubicom, Inc.
12875 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12891 + * Ubicom32 implementation derived from (with many thanks):
12896 +#ifndef _ASM_UBICOM32_TLB_H
12897 +#define _ASM_UBICOM32_TLB_H
12900 + * ubicom32 doesn't need any special per-pte or
12901 + * per-vma handling..
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)
12908 + * .. because we flush the whole mm when it
12911 +#define tlb_flush(tlb)
12913 +#include <asm-generic/tlb.h>
12915 +#endif /* _ASM_UBICOM32_TLB_H */
12917 +++ b/arch/ubicom32/include/asm/topology.h
12920 + * arch/ubicom32/include/asm/topology.h
12921 + * Generic topology.h definitions for Ubicom32 architecture.
12923 + * (C) Copyright 2009, Ubicom, Inc.
12925 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12941 + * Ubicom32 implementation derived from (with many thanks):
12946 +#ifndef _ASM_UBICOM32_TOPOLOGY_H
12947 +#define _ASM_UBICOM32_TOPOLOGY_H
12949 +#include <asm-generic/topology.h>
12951 +#endif /* _ASM_UBICOM32_TOPOLOGY_H */
12953 +++ b/arch/ubicom32/include/asm/traps.h
12956 + * arch/ubicom32/include/asm/traps.h
12957 + * Trap related definitions for Ubicom32 architecture.
12959 + * (C) Copyright 2009, Ubicom, Inc.
12961 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
12977 + * Ubicom32 implementation derived from (with many thanks):
12983 +#ifndef _ASM_UBICOM32_TRAPS_H
12984 +#define _ASM_UBICOM32_TRAPS_H
12987 + * Trap causes passed from ultra to Host OS
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
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);
13009 +#endif /* _ASM_UBICOM32_TRAPS_H */
13011 +++ b/arch/ubicom32/include/asm/types.h
13014 + * arch/ubicom32/include/asm/types.h
13015 + * Date type definitions for Ubicom32 architecture.
13017 + * (C) Copyright 2009, Ubicom, Inc.
13019 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13035 + * Ubicom32 implementation derived from (with many thanks):
13040 +#ifndef _ASM_UBICOM32_TYPES_H
13041 +#define _ASM_UBICOM32_TYPES_H
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.
13051 +#include <asm-generic/int-ll64.h>
13053 +#ifndef __ASSEMBLY__
13055 +typedef unsigned short umode_t;
13057 +#endif /* __ASSEMBLY__ */
13060 + * These aren't exported outside the kernel to avoid name space clashes
13064 +#define BITS_PER_LONG 32
13066 +#ifndef __ASSEMBLY__
13068 +/* DMA addresses are always 32-bits wide */
13070 +typedef u32 dma_addr_t;
13071 +typedef u32 dma64_addr_t;
13074 + * XXX These are "Ubicom style" typedefs. They should be removed in all files used by linux.
13076 +typedef u32 u32_t;
13077 +typedef s32 s32_t;
13078 +typedef u16 u16_t;
13079 +typedef s16 s16_t;
13083 +#endif /* __ASSEMBLY__ */
13085 +#endif /* __KERNEL__ */
13087 +#endif /* _ASM_UBICOM32_TYPES_H */
13089 +++ b/arch/ubicom32/include/asm/uaccess.h
13092 + * arch/ubicom32/include/asm/uaccess.h
13093 + * User space memory access functions for Ubicom32 architecture.
13095 + * (C) Copyright 2009, Ubicom, Inc.
13097 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13113 + * Ubicom32 implementation derived from (with many thanks):
13119 +#ifndef _ASM_UBICOM32_UACCESS_H
13120 +#define _ASM_UBICOM32_UACCESS_H
13123 + * User space memory access functions
13125 +#include <linux/sched.h>
13126 +#include <linux/mm.h>
13127 +#include <linux/string.h>
13129 +#include <asm/segment.h>
13131 +#define VERIFY_READ 0
13132 +#define VERIFY_WRITE 1
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
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.
13146 +struct exception_table_entry
13148 + unsigned long insn, fixup;
13152 + * Ubicom32 does not currently support the exception table handling.
13154 +extern unsigned long search_exception_table(unsigned long);
13157 +#if defined(CONFIG_ACCESS_OK_CHECKS_ENABLED)
13158 +extern int __access_ok(unsigned long addr, unsigned long size);
13160 +static inline int __access_ok(unsigned long addr, unsigned long size)
13165 +#define access_ok(type, addr, size) \
13166 + likely(__access_ok((unsigned long)(addr), (size)))
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.
13173 +extern int __put_user_bad(void);
13174 +extern int __get_user_bad(void);
13177 + * __put_user_no_check()
13178 + * Put the requested data into the user space verifying the address
13181 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13182 + * (b) require any knowledge of processes at this stage
13184 +#define __put_user_no_check(x, ptr, size) \
13186 + int __pu_err = 0; \
13187 + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
13188 + switch (size) { \
13193 + *__pu_addr = (__typeof__(*(ptr)))x; \
13196 + __pu_err = __put_user_bad(); \
13203 + * __put_user_check()
13204 + * Put the requested data into the user space verifying the address
13207 + * (a) re-use the arguments for side effects (sizeof/typeof is ok)
13208 + * (b) require any knowledge of processes at this stage
13210 + * If requested, access_ok() will verify that ptr is a valid user
13213 +#define __put_user_check(x, ptr, size) \
13215 + int __pu_err = -EFAULT; \
13216 + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
13217 + if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \
13219 + switch (size) { \
13224 + *__pu_addr = (__typeof__(*(ptr)))x; \
13227 + __pu_err = __put_user_bad(); \
13235 + * __get_user_no_check()
13236 + * Read the value at ptr into x.
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.
13242 +#define __get_user_no_check(x, ptr, size) \
13244 + int __gu_err = 0; \
13245 + __typeof__((x)) __gu_val = 0; \
13246 + const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
13247 + switch (size) { \
13252 + __gu_val = (__typeof__((x)))*(__gu_addr); \
13255 + __gu_err = __get_user_bad(); \
13259 + (x) = __gu_val; \
13264 + * __get_user_check()
13265 + * Read the value at ptr into x.
13267 + * If requested, access_ok() will verify that ptr is a valid user
13270 +#define __get_user_check(x, ptr, size) \
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)) { \
13277 + switch (size) { \
13282 + __gu_val = (__typeof__((x)))*(__gu_addr); \
13285 + __gu_err = __get_user_bad(); \
13290 + (x) = __gu_val; \
13295 + * The "xxx" versions are allowed to perform some amount of address
13296 + * space checking. See access_ok().
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)))
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()")
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)))
13314 + * __copy_tofrom_user_no_check()
13315 + * Copy the data either to or from user space.
13317 + * Return the number of bytes NOT copied.
13319 +static inline unsigned long
13320 +__copy_tofrom_user_no_check(void *to, const void *from, unsigned long n)
13322 + memcpy(to, from, n);
13328 + * Copy the kernel data to user space.
13330 + * Return the number of bytes that were copied.
13332 +static inline unsigned long
13333 +copy_to_user(void __user *to, const void *from, unsigned long n)
13335 + if (!access_ok(VERIFY_WRITE, to, n)) {
13338 + return __copy_tofrom_user_no_check((__force void *)to, from, n);
13342 + * copy_from_user()
13343 + * Copy the user data to kernel space.
13345 + * Return the number of bytes that were copied. On error, we zero
13346 + * out the destination.
13348 +static inline unsigned long
13349 +copy_from_user(void *to, const void __user *from, unsigned long n)
13351 + if (!access_ok(VERIFY_READ, from, n)) {
13354 + return __copy_tofrom_user_no_check(to, (__force void *)from, n);
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)
13366 +#define copy_to_user_ret(to, from, n, retval) \
13367 + ({ if (copy_to_user(to, from, n)) return retval; })
13369 +#define copy_from_user_ret(to, from, n, retval) \
13370 + ({ if (copy_from_user(to, from, n)) return retval; })
13373 + * strncpy_from_user()
13374 + * Copy a null terminated string from userspace.
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).
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.
13385 +static inline long strncpy_from_user(char *dst, const __user char *src, long count)
13388 + if (!access_ok(VERIFY_READ, src, 1)) {
13392 + strncpy(dst, src, count);
13393 + for (tmp = dst; *tmp && count > 0; tmp++, count--) {
13396 + return(tmp - dst);
13401 + * Return the size of a string (including the ending 0)
13403 + * Return -EFAULT on exception, a value greater than <n> if too long
13405 +static inline long strnlen_user(const __user char *src, long n)
13407 + if (!access_ok(VERIFY_READ, src, 1)) {
13410 + return(strlen(src) + 1);
13413 +#define strlen_user(str) strnlen_user(str, 32767)
13419 +static inline unsigned long __clear_user(__user void *to, unsigned long n)
13421 + memset(to, 0, n);
13427 + * Zero user space (check for valid addresses)
13429 +static inline unsigned long clear_user(__user void *to, unsigned long n)
13431 + if (!access_ok(VERIFY_WRITE, to, n)) {
13434 + return __clear_user(to, n);
13437 +#endif /* _ASM_UBICOM32_UACCESS_H */
13439 +++ b/arch/ubicom32/include/asm/ubi32-cs4384.h
13442 + * arch/ubicom32/include/asm/ubi32-cs4384.h
13443 + * Ubicom32 architecture CS4384 driver platform data definitions.
13445 + * (C) Copyright 2009, Ubicom, Inc.
13447 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13463 +#ifndef _ASM_UBICOM32_UBI32_CS4384_H
13464 +#define _ASM_UBICOM32_UBI32_CS4384_H
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,
13474 +struct ubi32_cs4384_mclk_entry {
13476 + * Rate, in Hz, of this entry
13481 + * The divider to program to get the rate
13486 +struct ubi32_cs4384_platform_data {
13487 + enum ubi32_cs4384_mclk_source mclk_src;
13490 + struct ubi32_cs4384_mclk_entry *mclk_entries;
13492 +#endif /* _ASM_UBICOM32_UBI32_CS4384_H */
13495 +++ b/arch/ubicom32/include/asm/ubi32-pcm.h
13498 + * arch/ubicom32/include/asm/ubi32-pcm.h
13499 + * Ubicom32 architecture PCM driver platform data definitions.
13501 + * (C) Copyright 2009, Ubicom, Inc.
13503 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13519 +#ifndef _ASM_UBICOM32_UBI32_PCM_H
13520 +#define _ASM_UBICOM32_UBI32_PCM_H
13523 + * This function is called when the sample rate has changed
13525 +typedef int (*ubi32_pcm_set_rate_fn_t)(void *appdata, int rate);
13527 +struct ubi32pcm_platform_data {
13529 + * Name of the audiotio node
13531 + const char *node_name;
13534 + * Application specific data provided when calling functions
13539 + * Functions called when various things happen
13541 + ubi32_pcm_set_rate_fn_t set_rate;
13544 + * Pointer to optional upper layer data (i.e. DAC config, etc)
13548 +#endif /* _ASM_UBICOM32_UBI32_PCM_H */
13551 +++ b/arch/ubicom32/include/asm/ubicom32bl.h
13554 + * arch/ubicom32/include/asm/ubicom32bl.h
13555 + * Ubicom32 architecture backlight driver platform data definitions.
13557 + * (C) Copyright 2009, Ubicom, Inc.
13559 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13575 + * Ubicom32 implementation derived from (with many thanks):
13580 +#ifndef _ASM_UBICOM32_UBICOM32_BL_H
13581 +#define _ASM_UBICOM32_UBICOM32_BL_H
13584 + * Different backlight control mechanisms
13586 +enum ubicom32bl_pwm_types {
13588 + * PWM controlled backlight
13590 + UBICOM32BL_TYPE_PWM,
13593 + * HRT based PWM backlight
13595 + UBICOM32BL_TYPE_PWM_HRT,
13598 + * No dimming, just on or off
13600 + UBICOM32BL_TYPE_BINARY,
13603 +struct ubicom32bl_platform_data {
13605 + * Default intensity of the backlight 0-255
13607 + u8_t default_intensity;
13610 + * TRUE if the backlight sense is active low. (inverted)
13611 + * FALSE if the backlight sense is active high.
13616 + * Type of the backlight
13618 + enum ubicom32bl_pwm_types type;
13621 + * GPIO of the backlight if UBICOM32BL_TYPE_PWM_HRT, UBICOM32BL_TYPE_BINARY
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.
13631 + u32_t pwm_channel;
13632 + u8_t pwm_prescale;
13633 + u16_t pwm_period;
13636 +#endif /* _ASM_UBICOM32_UBICOM32_BL_H */
13638 +++ b/arch/ubicom32/include/asm/ubicom32-common-asm.h
13641 + * arch/ubicom32/include/asm/ubicom32-common-asm.h
13642 + * Ubicom32 atomic lock operations.
13644 + * (C) Copyright 2009, Ubicom, Inc.
13646 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13662 + * Ubicom32 implementation derived from (with many thanks):
13668 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13669 +#define _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
13672 + * atomic_lock_acquire macro
13673 + * Equivalent to __atomic_lock_acquire()
13675 +.macro atomic_lock_acquire
13676 + bset scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13681 + * atomic_lock_release macro
13682 + * Equivalent to __atomic_lock_release()
13684 +.macro atomic_lock_release
13685 + bclr scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
13688 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_ASM_H */
13690 +++ b/arch/ubicom32/include/asm/ubicom32-common.h
13693 + * arch/ubicom32/include/asm/ubicom32-common.h
13694 + * Ubicom32 atomic lock operations.
13696 + * (C) Copyright 2009, Ubicom, Inc.
13698 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13714 + * Ubicom32 implementation derived from (with many thanks):
13720 +#ifndef _ASM_UBICOM32_UBICOM32_COMMON_H
13721 +#define _ASM_UBICOM32_UBICOM32_COMMON_H
13723 +#define S(arg) #arg
13724 +#define D(arg) S(arg)
13726 + * scratchpad1 is owned by the LDSR.
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.
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.
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.
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
13749 +#if !defined(__ASSEMBLY__)
13751 +#define UBICOM32_TRYLOCK(bit) \
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" \
13760 + : "cc", "memory" \
13763 +#define UBICOM32_UNLOCK(bit) \
13765 + " bclr scratchpad1, scratchpad1, #"D(bit)" \n\t" \
13768 + : "cc", "memory" \
13771 +#define UBICOM32_LOCK(bit) \
13773 + "1: bset scratchpad1, scratchpad1, #"D(bit)" \n\t" \
13774 + " jmpne.f 1b \n\t" \
13777 + : "cc", "memory" \
13781 + * __atomic_lock_trylock()
13782 + * Attempt to acquire the lock, return TRUE if acquired.
13784 +static inline int __atomic_lock_trylock(void)
13787 + UBICOM32_TRYLOCK(ATOMIC_LOCK_BIT);
13792 + * __atomic_lock_release()
13793 + * Release the global atomic lock.
13795 + * Note: no one is suspended waiting since this lock is a spinning lock.
13797 +static inline void __atomic_lock_release(void)
13799 + UBICOM32_UNLOCK(ATOMIC_LOCK_BIT);
13803 + * __atomic_lock_acquire()
13804 + * Acquire the global atomic lock, spin if not available.
13806 +static inline void __atomic_lock_acquire(void)
13808 + UBICOM32_LOCK(ATOMIC_LOCK_BIT);
13810 +#else /* __ASSEMBLY__ */
13812 +#include <asm/ubicom32-common-asm.h>
13814 +#endif /* __ASSEMBLY__ */
13815 +#endif /* _ASM_UBICOM32_UBICOM32_COMMON_H */
13817 +++ b/arch/ubicom32/include/asm/ubicom32fb.h
13820 + * arch/ubicom32/include/asm/ubicom32fb.h
13821 + * Ubicom32 architecture video frame buffer definitions.
13823 + * (C) Copyright 2009, Ubicom, Inc.
13825 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13841 +#ifndef _ASM_UBICOM32_UBICOM32FB_H
13842 +#define _ASM_UBICOM32_UBICOM32FB_H
13844 +#include <linux/ioctl.h>
13849 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME _IOW('r', 1, void *)
13850 +#define UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC _IOW('r', 2, void *)
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;
13862 +#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER (1 << 8)
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)
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)
13874 +#endif /* _ASM_UBICOM32_UBICOM32FB_H */
13876 +++ b/arch/ubicom32/include/asm/ubicom32hid.h
13879 + * arch/ubicom32/include/asm/ubicom32hid.h
13880 + * Ubicom32 architecture HID driver platform data definitions.
13882 + * (C) Copyright 2009, Ubicom, Inc.
13884 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
13900 + * Ubicom32 implementation derived from (with many thanks):
13905 +#ifndef _ASM_UBICOM32_UBICOM32_HID_H
13906 +#define _ASM_UBICOM32_UBICOM32_HID_H
13908 +enum ubicom32hid_bl_types {
13910 + * On or off, using command SET_BL_EN, PB4
13912 + UBICOM32HID_BL_TYPE_BINARY,
13915 + * Dimmable, using command SET_PWM, PB3
13917 + UBICOM32HID_BL_TYPE_PWM,
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.
13925 +struct ubicom32hid_ir {
13927 + * Input event code (KEY_*, SW_*, etc)
13932 + * Input event type (EV_KEY, EV_SW, etc)
13937 + * The IR code of this button.
13939 + uint32_t ir_code;
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.
13947 +struct ubicom32hid_button {
13949 + * Input event code (KEY_*, SW_*, etc)
13954 + * Input event type (EV_KEY, EV_SW, etc)
13959 + * Bit number of this button.
13964 +struct ubicom32hid_platform_data {
13966 + * Default intensity of the backlight 0-255
13968 + u8_t default_intensity;
13971 + * GPIO number of the reset line and its polarity.
13973 + unsigned gpio_reset;
13974 + int gpio_reset_polarity;
13977 + * TRUE if the backlight sense is active low. (inverted)
13978 + * FALSE if the backlight sense is active high.
13983 + * Type of the backlight we are controlling
13985 + enum ubicom32hid_bl_types type;
13988 + * Optional polling rate for input, in ms, defaults to 100ms
13990 + int poll_interval;
13993 + * Optional name to register as input device
13995 + const char *input_name;
13998 + * Button mapping array
14000 + const struct ubicom32hid_button *buttons;
14004 + * IR mapping array
14006 + const struct ubicom32hid_ir *ircodes;
14010 +#endif /* _ASM_UBICOM32_UBICOM32_HID_H */
14012 +++ b/arch/ubicom32/include/asm/ubicom32input.h
14015 + * arch/ubicom32/include/asm/ubicom32input.h
14016 + * Ubicom32 Input driver, based on gpio-keys
14018 + * (C) Copyright 2009, Ubicom, Inc.
14020 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14036 + * Ubicom32 implementation derived from (with many thanks):
14041 + * TODO: add groups for inputs which can be sampled together
14044 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_H
14045 +#define _ASM_UBICOM32_UBICOM32_INPUT_H
14047 +struct ubicom32input_button {
14049 + * Input event code (KEY_*, SW_*, etc)
14054 + * Input event type (EV_KEY, EV_SW, etc)
14064 + * 1 for active low, 0 for active high
14069 + * Description, used for reserving GPIOs
14071 + const char *desc;
14074 +struct ubicom32input_platform_data {
14075 + struct ubicom32input_button *buttons;
14079 + * Optional poll interval, in ms, defaults to 50ms
14081 + int poll_interval;
14084 + * Option Name of this driver
14086 + const char *name;
14089 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_H */
14091 +++ b/arch/ubicom32/include/asm/ubicom32input_i2c.h
14094 + * arch/ubicom32/include/asm/ubicom32input_i2c.h
14095 + * Ubicom32 architecture Input driver over I2C platform data definitions.
14097 + * (C) Copyright 2009, Ubicom, Inc.
14099 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14115 + * Ubicom32 implementation derived from (with many thanks):
14120 + * TODO: add groups for inputs which can be sampled together
14123 +#ifndef _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
14124 +#define _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
14126 +struct ubicom32input_i2c_button {
14128 + * Input event code (KEY_*, SW_*, etc)
14133 + * Input event type (EV_KEY, EV_SW, etc)
14138 + * Bit number of this button. (0 - ngpio)
14143 + * 1 for active low, 0 for active high
14148 +struct ubicom32input_i2c_platform_data {
14149 + struct ubicom32input_i2c_button *buttons;
14153 + * Optional poll interval, in ms, defaults to 100ms
14155 + int poll_interval;
14158 + * Option Name of this driver
14160 + const char *name;
14163 +#endif /* _ASM_UBICOM32_UBICOM32_INPUT_I2C_H */
14165 +++ b/arch/ubicom32/include/asm/ubicom32lcd.h
14168 + * arch/ubicom32/include/asm/ubicom32lcd.h
14169 + * Ubicom32 architecture LCD driver platform data definitions.
14171 + * (C) Copyright 2009, Ubicom, Inc.
14173 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14189 + * Ubicom32 implementation derived from (with many thanks):
14194 +#ifndef _ASM_UBICOM32_UBICOM32_LCD_H
14195 +#define _ASM_UBICOM32_UBICOM32_LCD_H
14197 +struct ubicom32lcd_platform_data {
14199 + * GPIO and polarity for VGH signal. A FALSE polarity is active low, TRUE is active high.
14202 + bool vgh_polarity;
14205 +#endif /* _ASM_UBICOM32_UBICOM32_LCD_H */
14207 +++ b/arch/ubicom32/include/asm/ubicom32ring.h
14210 + * arch/ubicom32/include/asm/ubicom32ring.h
14211 + * Userspace I/O platform driver for Ubicom32 ring buffers
14213 + * (C) Copyright 2009, Ubicom, Inc.
14215 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14232 +#ifndef _ASM_UBICOM32_UBICOM32RING_H
14233 +#define _ASM_UBICOM32_UBICOM32RING_H
14235 +#define UIO_UBICOM32RING_REG_VERSION 2
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];
14244 +struct uio_ubicom32ring_regs {
14245 + unsigned int version;
14248 + * Magic type used to identify the ring set. Each driver will
14249 + * have a different magic value.
14251 + unsigned int magic;
14254 + * Registers defined by the driver
14256 + unsigned int regs_size;
14260 + * The locations of the rings
14262 + * DO NOT ADD ANYTHING BELOW THIS LINE
14264 + unsigned int num_rings;
14265 + struct uio_ubicom32ring_desc *rings[0];
14269 + * ringtio_ring_flush
14271 +static inline void ringtio_ring_flush(struct uio_ubicom32ring_desc *rd)
14273 + rd->head = rd->tail = 0;
14277 + * ringtio_ring_get
14279 +static inline int ringtio_ring_get(struct uio_ubicom32ring_desc *rd, void **val)
14281 + if (rd->head == rd->tail) {
14285 + *val = (void *)rd->ring[rd->head++];
14286 + if (rd->head == rd->entries) {
14293 + * ringtio_ring_put
14295 +static inline int ringtio_ring_put(struct uio_ubicom32ring_desc *rd, void *val)
14297 + unsigned int newtail = rd->tail + 1;
14298 + if (newtail == rd->entries) {
14302 + if (newtail == rd->head) {
14306 + rd->ring[rd->tail] = (unsigned int)val;
14307 + rd->tail = newtail;
14311 +#endif /* _ASM_UBICOM32_UBICOM32RING_H */
14313 +++ b/arch/ubicom32/include/asm/ubicom32sd.h
14316 + * arch/ubicom32/include/asm/ubicom32sd.h
14317 + * Ubicom32SD public include file
14319 + * (C) Copyright 2009, Ubicom, Inc.
14321 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14337 +#ifndef _ASM_UBICOM32_UBICOM32_SD_H
14338 +#define _ASM_UBICOM32_UBICOM32_SD_H
14340 +struct ubicom32sd_card {
14342 + * GPIOs of PWR, WP and CD lines.
14343 + * Polarity is 1 for active high and 0 for active low
14346 + bool pwr_polarity;
14348 + bool wp_polarity;
14350 + bool cd_polarity;
14353 +struct ubicom32sd_platform_data {
14356 + struct ubicom32sd_card *cards;
14359 +#endif /* _ASM_UBICOM32_UBICOM32_SD_H */
14361 +++ b/arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14364 + * arch/ubicom32/include/asm/ubicom32-spi-gpio.h
14365 + * Platform driver data definitions for GPIO based SPI driver.
14367 + * (C) Copyright 2009, Ubicom, Inc.
14369 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14385 + * Ubicom32 implementation derived from (with many thanks):
14390 +#ifndef _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14391 +#define _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
14393 +struct ubicom32_spi_gpio_platform_data {
14395 + * GPIO to use for MOSI, MISO, CLK
14402 + * Default state of CLK line
14407 + * Number of chip selects on this bus
14409 + int num_chipselect;
14412 + * The bus number of this chip
14417 +struct ubicom32_spi_gpio_controller_data {
14419 + * GPIO to use for chip select
14424 +#endif /* _ASM_UBICOM32_UBICOM32_SPI_GPIO_H */
14426 +++ b/arch/ubicom32/include/asm/ubicom32suart.h
14429 + * arch/ubicom32/include/asm/ubicom32suart.h
14430 + * <TODO: Replace with short file description>
14432 + * (C) Copyright 2009, Ubicom, Inc.
14434 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14450 + * Ubicom32 implementation derived from (with many thanks):
14455 +#ifndef _ASM_UBICOM32_UBICOM32_SUART_H
14456 +#define _ASM_UBICOM32_UBICOM32_SUART_H
14459 + * Platform resource id for serdes uart clock parameter
14461 +#define UBICOM32_SUART_IORESOURCE_CLOCK (1)
14463 +#endif /* _ASM_UBICOM32_UBICOM32_SUART_H */
14465 +++ b/arch/ubicom32/include/asm/ubicom32-tio.h
14468 + * arch/ubicom32/include/asm/ubicom32-tio.h
14469 + * Threaded I/O interface definitions.
14471 + * (C) Copyright 2009, Ubicom, Inc.
14473 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14489 + * Ubicom32 implementation derived from (with many thanks):
14494 +#ifndef _ASM_UBICOM32_UBICOM32_TIO_H
14495 +#define _ASM_UBICOM32_UBICOM32_TIO_H
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);
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);
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);
14508 +#endif /* _ASM_UBICOM32_UBICOM32_TIO_H */
14510 +++ b/arch/ubicom32/include/asm/ucontext.h
14513 + * arch/ubicom32/include/asm/ucontext.h
14514 + * Definition of ucontext structure for Ubicom32 architecture.
14516 + * (C) Copyright 2009, Ubicom, Inc.
14518 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14534 + * Ubicom32 implementation derived from (with many thanks):
14539 +#ifndef _ASM_UBICOM32_UCONTEXT_H
14540 +#define _ASM_UBICOM32_UCONTEXT_H
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 */
14550 +#endif /* _ASM_UBICOM32_UCONTEXT_H */
14552 +++ b/arch/ubicom32/include/asm/unaligned.h
14555 + * arch/ubicom32/include/asm/unaligned.h
14556 + * Ubicom32 architecture unaligned memory access definitions.
14558 + * (C) Copyright 2009, Ubicom, Inc.
14560 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14576 + * Ubicom32 implementation derived from (with many thanks):
14581 + * TODO: This is a copy of arm unaligned handling that probably needs
14582 + * to be optimized for UBICOM32, but it works for now.
14585 +#ifndef _ASM_UBICOM32_UNALIGNED_H
14586 +#define _ASM_UBICOM32_UNALIGNED_H
14588 +#include <asm/types.h>
14590 +#include <linux/unaligned/le_byteshift.h>
14591 +#include <linux/unaligned/be_byteshift.h>
14592 +#include <linux/unaligned/generic.h>
14594 +#define get_unaligned __get_unaligned_be
14595 +#define put_unaligned __put_unaligned_be
14597 +#endif /* _ASM_UBICOM32_UNALIGNED_H */
14599 +++ b/arch/ubicom32/include/asm/unistd.h
14602 + * arch/ubicom32/include/asm/unistd.h
14603 + * Ubicom32 architecture syscall definitions.
14605 + * (C) Copyright 2009, Ubicom, Inc.
14607 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
14623 + * Ubicom32 implementation derived from (with many thanks):
14628 +#ifndef _ASM_UBICOM32_UNISTD_H
14629 +#define _ASM_UBICOM32_UNISTD_H
14632 + * This file contains the system call numbers.
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
14965 +#define NR_syscalls 329
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
14991 + * "Conditional" syscalls
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
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__ */
15000 +#endif /* _ASM_UBICOM32_UNISTD_H */
15002 +++ b/arch/ubicom32/include/asm/user.h
15005 + * arch/ubicom32/include/asm/user.h
15006 + * Ubicom32 architecture core file definitions.
15008 + * (C) Copyright 2009, Ubicom, Inc.
15010 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
15026 + * Ubicom32 implementation derived from (with many thanks):
15031 +#ifndef _ASM_UBICOM32_USER_H
15032 +#define _ASM_UBICOM32_USER_H
15034 +#include <asm/ptrace.h>
15035 +#include <asm/page.h>
15037 + * Adapted from <asm-powerpc/user.h>
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:
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.
15062 +struct user_ubicom32fp_struct {
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 */
15079 +#define NBPG PAGE_SIZE
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)
15085 +#endif /* _ASM_UBICOM32_USER_H */
15087 +++ b/arch/ubicom32/include/asm/vdc_tio.h
15090 + * arch/ubicom32/include/asm/vdc_tio.h
15091 + * Ubicom32 architecture VDC TIO definitions.
15093 + * (C) Copyright 2009, Ubicom, Inc.
15095 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
15111 + * Ubicom32 implementation derived from (with many thanks):
15116 +#ifndef _ASM_UBICOM32_VDC_TIO_H
15117 +#define _ASM_UBICOM32_VDC_TIO_H
15119 +#include <asm/devtree.h>
15121 +#define VDCTIO_VP_VERSION 5
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)
15134 +#define VDCTIO_NEXT_FRAME_FLAG_YUV_BIT 0
15135 +#define VDCTIO_NEXT_FRAME_FLAG_YUV (1 << (VDCTIO_NEXT_FRAME_FLAG_YUV_BIT))
15137 +#define VDCTIO_CAPS_SUPPORTS_SCALING (1 << 0)
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)
15145 + * Command / Data registers to access the VDC
15147 +struct vdc_tio_vp_regs {
15149 + * Version of this TIO register map
15153 + volatile u32_t command;
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.
15159 + void *next_frame;
15160 + u32_t next_frame_flags;
15163 + * These map directly into the PIXP registers 0x20-0x80.
15164 + * DO NOT change the order of these three variables.
15166 + u32_t red_lut[6];
15167 + u32_t blue_lut[6];
15168 + u32_t green_lut[13];
15171 + * These map directly into the PIXP registers 0x04, 0x08
15177 + * There are used to set the scaling parameters
15183 + u32_t scale_flags;
15186 + * Current frame number, monotonically increasing number
15188 + u32_t frame_number;
15191 + * These variables tell the guest OS what the underlying hardware looks like
15207 + * Devtree node for VDC
15209 +struct vdc_tio_node {
15210 + struct devtree_node dn;
15212 + struct vdc_tio_vp_regs *regs;
15215 +extern void vdc_tio_init(void);
15217 +#endif /* _ASM_UBICOM32_VDC_TIO_H */
15219 +++ b/arch/ubicom32/include/asm/vga.h
15222 + * arch/ubicom32/include/asm/vga.h
15223 + * Ubicom32 low level VGA/frame buffer definitions.
15225 + * (C) Copyright 2009, Ubicom, Inc.
15226 + * (c) 1998 Martin Mares <mj@ucw.cz>
15228 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
15244 + * Ubicom32 implementation derived from (with many thanks):
15250 +#ifndef _ASM_UBICOM32_VGA_H
15251 +#define _ASM_UBICOM32_VGA_H
15253 +#include <asm/byteorder.h>
15256 + * On the PC, we can just recalculate addresses and then
15257 + * access the videoram directly without any black magic.
15260 +#define VGA_MAP_MEM(x, s) (0xb0000000L + (unsigned long)(x))
15262 +#define vga_readb(x) (*(x))
15263 +#define vga_writeb(x, y) (*(y) = (x))
15265 +#define VT_BUF_HAVE_RW
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.
15276 +static inline void scr_writew(u16 val, volatile u16 *addr)
15278 + *addr = cpu_to_le16(val);
15281 +static inline u16 scr_readw(volatile const u16 *addr)
15283 + return le16_to_cpu(*addr);
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
15291 +#endif /* _ASM_UBICOM32_VGA_H */
15293 +++ b/arch/ubicom32/include/asm/xor.h
15296 + * arch/ubicom32/include/asm/xor.h
15297 + * Generic xor.h definitions for Ubicom32 architecture.
15299 + * (C) Copyright 2009, Ubicom, Inc.
15301 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
15317 + * Ubicom32 implementation derived from (with many thanks):
15322 +#ifndef _ASM_UBICOM32_XOR_H
15323 +#define _ASM_UBICOM32_XOR_H
15325 +#include <asm-generic/xor.h>
15327 +#endif /* _ASM_UBICOM32_XOR_H */
15329 +++ b/arch/ubicom32/Kconfig
15332 +# For a description of the syntax of this configuration file,
15333 +# see Documentation/kbuild/kconfig-language.txt.
15336 +mainmenu "uClinux/ubicom32 (w/o MMU) Kernel Configuration"
15340 + default "0x40000000"
15342 + Define the address that RAM starts at.
15346 + select HAVE_OPROFILE
15353 +config CPU_BIG_ENDIAN
15357 +config FORCE_MAX_ZONEORDER
15377 +config RWSEM_GENERIC_SPINLOCK
15381 +config RWSEM_XCHGADD_ALGORITHM
15385 +config ARCH_HAS_ILOG2_U32
15389 +config ARCH_HAS_ILOG2_U64
15393 +config GENERIC_FIND_NEXT_BIT
15397 +config GENERIC_GPIO
15405 +config GENERIC_HWEIGHT
15409 +config GENERIC_HARDIRQS
15413 +config STACKTRACE_SUPPORT
15417 +config LOCKDEP_SUPPORT
15421 +config GENERIC_CALIBRATE_DELAY
15425 +config GENERIC_TIME
15429 +config TIME_LOW_RES
15433 +config GENERIC_CLOCKEVENTS
15437 +config GENERIC_CLOCKEVENTS_BROADCAST
15439 + depends on GENERIC_CLOCKEVENTS
15440 + default y if SMP && !LOCAL_TIMERS
15445 +config ARCH_SUPPORTS_AOUT
15448 +config IRQ_PER_CPU
15452 +config SCHED_NO_NO_OMIT_FRAME_POINTER
15456 +menu "Processor type and features"
15460 + depends on IP5160EVAL
15462 + Board has 32MB of RAM on it. It is a hidden option used to select default for size of RAM
15467 + depends on IP7145DPF || IP7160RGW || IP7160BRINGUP || IP7160DPF || IP5170DPF || IP5160DEV
15469 + Board has 64MB of RAM on it. It is a hidden option used to select default for size of RAM
15474 + depends on IP7500MODULE || IP7500AV || IP7500MEDIA
15476 + Board has 128MB of RAM on it. It is a hidden option used to select default for size of RAM
15479 +comment "Processor type will be selected by Board"
15481 +config UBICOM32_V3
15484 + Ubicom IP5xxx series processor support.
15486 +config UBICOM32_V4
15489 + Ubicom IP7xxx series processor support.
15493 + prompt "Board type"
15495 + Select your board.
15498 + bool "No board selected"
15500 + Default. Don't select any board specific config. Will not build unless you change!
15502 +# Add your boards here
15503 +source "arch/ubicom32/mach-ip5k/Kconfig"
15504 +source "arch/ubicom32/mach-ip7k/Kconfig"
15508 +comment "Kernel Options"
15510 + bool "Symmetric multi-processing support"
15511 + select USE_GENERIC_SMP_HELPERS
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.
15518 + If you do not know what to do here, say N.
15521 + int "Number of configured CPUs"
15526 + Upper bound on the number of CPUs. Space is reserved
15527 + at compile time for this many CPUs.
15529 +config LOCAL_TIMERS
15530 + bool "Use local timer interrupts"
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
15540 +config TIMER_EXTRA_ALLOC
15541 + int "Number of additional physical timer events to create"
15542 + depends on GENERIC_CLOCKEVENTS
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.
15552 + bool "Create separate stacks for interrupt handling"
15555 + Selecting this causes interrupts to be created on a separate
15556 + stack instead of nesting the interrupts on the kernel stack.
15558 +config IRQSTACKS_USEOCM
15559 + bool "Use OCM for interrupt stacks"
15561 + depends on IRQSTACKS
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
15567 +menu "OCM Instruction Heap"
15569 +config OCM_MODULES_RESERVATION
15570 + int "OCM Instruction heap reservation. 0-192 kB"
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
15579 +config OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
15580 + bool "Give all unused ocm code space to the ocm instruction heap."
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.
15587 +config OCM_MODULES_FALLBACK_TO_DDR
15588 + bool "Loadable Modules requiring OCM may fallback to use DDR."
15591 + If a module cannot get the OCM code it requires allow DDR to
15596 + int "Frequency of 'jiffies' (for polling)"
15599 + 100 is common for embedded systems, but 1000 allows
15600 + you to do more drivers without actually having
15601 + interrupts working properly.
15603 +comment "RAM configuration"
15608 + hex "Size of RAM (in bytes)"
15609 + range 0x00000000 0x02000000
15610 + default "0x02000000"
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.
15621 + hex "Size of RAM (in bytes)"
15622 + range 0x00000000 0x04000000
15623 + default "0x04000000"
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.
15634 + hex "Size of RAM (in bytes)"
15635 + range 0x00000000 0x08000000
15636 + default "0x08000000"
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.
15645 + hex "Address of the base of kernel code"
15646 + default "0x40400000"
15648 + For the time being we are going to start the Kernel at a 4 meg offset.
15650 +comment "Build options"
15651 +config LINKER_RELAXATION
15652 + bool "Linker Relaxation"
15655 + Turns on linker relaxation that will produce smaller
15656 + faster code. Increases link time.
15658 +comment "Driver options"
15664 + Enable/Disable PCI bus
15665 + source "drivers/pci/Kconfig"
15668 +config PCI_DEV0_IDSEL
15669 + hex "slot 0 address"
15671 + default "0x01000000"
15673 + Slot 0 address. This address should correspond to the address line
15674 + which the IDSEL bit for this slot is connected to.
15676 +config PCI_DEV1_IDSEL
15677 + hex "slot 1 address"
15679 + default "0x02000000"
15681 + Slot 1 address. This address should correspond to the address line
15682 + which the IDSEL bit for this slot is connected to.
15686 +menu "Input devices"
15687 +config UBICOM_INPUT
15688 + bool "Ubicom polled GPIO input driver"
15690 + select INPUT_POLLDEV
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.
15696 +config UBICOM_INPUT_I2C
15697 + bool "Ubicom polled GPIO input driver over I2C"
15699 + select INPUT_POLLDEV
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.
15708 +menu "Misc devices"
15710 + bool "Ubicom HID driver"
15712 + select INPUT_POLLDEV
15713 + select LCD_CLASS_DEVICE
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.
15722 +config CMDLINE_BOOL
15723 + bool "Built-in kernel command line"
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.)
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.
15736 + Systems with fully functional boot loaders (i.e. non-embedded)
15737 + should leave this option set to 'N'.
15740 + string "Built-in kernel command string"
15741 + depends on CMDLINE_BOOL
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.
15749 + However, you can use the CONFIG_CMDLINE_OVERRIDE option to
15750 + change this behavior.
15752 + In most cases, the command line (whether built-in or provided
15753 + by the boot loader) should specify the device for the root
15756 +config CMDLINE_OVERRIDE
15757 + bool "Built-in command line overrides boot loader arguments"
15759 + depends on CMDLINE_BOOL
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.
15764 + This is used to work around broken boot loaders. This should
15765 + be set to 'N' under normal conditions.
15768 +# End Processor type and features
15770 +source "arch/ubicom32/Kconfig.debug"
15772 +menu "Executable file formats"
15773 +source "fs/Kconfig.binfmt"
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"
15787 +++ b/arch/ubicom32/Kconfig.debug
15789 +menu "Kernel hacking"
15791 +config TRACE_IRQFLAGS_SUPPORT
15794 +config PROTECT_KERNEL
15796 + bool 'Enable Kernel range register Protection'
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
15803 +config NO_KERNEL_MSG
15804 + bool "Suppress Kernel BUG Messages"
15806 + Do not output any debug BUG messages within the kernel.
15808 +config EARLY_PRINTK
15809 + bool "Use the driver that you selected as console also for early printk (to debug kernel bootup)."
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:
15816 + serdes=ioportaddr,irq,clockrate,baud
15818 + For an IP7160RGW eval board, you could use this:
15820 + serdes=0x2004000,61,250000000,57600
15822 + which will let you see early printk output at 57600 baud.
15824 +config STOP_ON_TRAP
15825 + bool "Enable stopping at the LDSR for all traps"
15828 + Cause the LDSR to stop all threads whenever a trap is about to be serviced
15830 +config STOP_ON_BUG
15831 + bool "Enable stopping on failed BUG_ON()"
15834 + Cause all BUG_ON failures to stop all threads
15836 +config DEBUG_IRQMEASURE
15837 + bool "Enable IRQ handler measurements"
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.
15844 +config DEBUG_PCIMEASURE
15845 + bool "Enable PCI transaction measurements"
15848 + When enabled the system will measure the min/avg/max timer for each PCI transactions.
15849 + See /proc/pci_measurements.
15851 +config ACCESS_OK_CHECKS_ENABLED
15852 + bool "Enable user space access checks"
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
15865 + prompt "Unaligned Access Support"
15866 + default UNALIGNED_ACCESS_ENABLED
15868 + Kernel / Userspace unaligned access handling.
15870 +config UNALIGNED_ACCESS_ENABLED
15871 + bool "Kernel and Userspace"
15874 +config UNALIGNED_ACCESS_USERSPACE_ONLY
15875 + bool "Userspace Only"
15878 +config UNALIGNED_ACCESS_DISABLED
15884 +config DEBUG_STACKOVERFLOW
15885 + bool "Check for stack overflows"
15887 + depends on DEBUG_KERNEL
15889 + This option will cause messages to be printed if free kernel stack space
15890 + drops below a certain limit (THREAD_SIZE /8).
15892 +config DEBUG_STACK_USAGE
15893 + bool "Stack utilization instrumentation"
15895 + depends on DEBUG_KERNEL
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.
15900 + This option will slow down process creation somewhat.
15902 +source "lib/Kconfig.debug"
15907 +++ b/arch/ubicom32/kernel/asm-offsets.c
15910 + * arch/ubicom32/kernel/asm-offsets.c
15911 + * Ubicom32 architecture definitions needed by assembly language modules.
15913 + * (C) Copyright 2009, Ubicom, Inc.
15915 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
15931 + * Ubicom32 implementation derived from (with many thanks):
15937 + * This program is used to generate definitions needed by
15938 + * assembly language modules.
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.
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>
15956 +#define DEFINE(sym, val) \
15957 + asm volatile("\n->" #sym " %0 " #val : : "i" (val))
15959 +#define BLANK() asm volatile("\n->" : : )
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));
15973 + /* offsets into the kernel_stat struct */
15974 + DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
15976 + /* offsets into the irq_cpustat_t struct */
15977 + DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
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));
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]));
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));
16021 + DEFINE(PT_ACC1HI, offsetof(struct pt_regs, acc1[0]));
16022 + DEFINE(PT_ACC1LO, offsetof(struct pt_regs, acc1[1]));
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));
16029 + DEFINE(PT_INT_MASK0, offsetof(struct pt_regs, int_mask0));
16030 + DEFINE(PT_INT_MASK1, offsetof(struct pt_regs, int_mask1));
16032 + DEFINE(PT_PC, offsetof(struct pt_regs, pc));
16034 + DEFINE(PT_TRAP_CAUSE, offsetof(struct pt_regs, trap_cause));
16036 + DEFINE(PT_SIZE, sizeof(struct pt_regs));
16038 + DEFINE(PT_FRAME_TYPE, offsetof(struct pt_regs, frame_type));
16040 + DEFINE(PT_ORIGINAL_D0, offsetof(struct pt_regs, original_dn_0));
16041 + DEFINE(PT_PREVIOUS_PC, offsetof(struct pt_regs, previous_pc));
16043 + /* offsets into the kernel_stat struct */
16044 + DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
16046 + /* signal defines */
16047 + DEFINE(SIGSEGV, SIGSEGV);
16048 + //DEFINE(SEGV_MAPERR, SEGV_MAPERR);
16049 + DEFINE(SIGTRAP, SIGTRAP);
16050 + //DEFINE(TRAP_TRACE, TRAP_TRACE);
16052 + DEFINE(PT_PTRACED, PT_PTRACED);
16053 + DEFINE(PT_DTRACE, PT_DTRACE);
16055 + DEFINE(ASM_THREAD_SIZE, THREAD_SIZE);
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);
16068 + DEFINE(ASM_RAM_END, (CONFIG_RAMBASE + CONFIG_RAMSIZE));
16072 +++ b/arch/ubicom32/kernel/devtree.c
16075 + * arch/ubicom32/kernel/devtree.c
16076 + * Ubicom32 architecture device tree implementation.
16078 + * (C) Copyright 2009, Ubicom, Inc.
16080 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16096 + * Ubicom32 implementation derived from (with many thanks):
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>
16109 + * The device tree.
16111 +struct devtree_node *devtree;
16114 + * devtree_print()
16115 + * Print the device tree.
16117 +void devtree_print(void)
16119 + struct devtree_node *p = devtree;
16120 + printk(KERN_INFO "Device Tree:\n");
16122 + if (p->magic != DEVTREE_NODE_MAGIC) {
16123 + printk(KERN_EMERG
16124 + "device tree has improper node: %p\n", p);
16127 + printk(KERN_INFO "\t%p: sendirq=%03d, recvirq=%03d, "
16128 + " name=%s\n", p, p->sendirq, p->recvirq, p->name);
16132 +EXPORT_SYMBOL(devtree_print);
16136 + * Return the IRQ(s) associated with devtree node.
16138 +int devtree_irq(struct devtree_node *dn,
16139 + unsigned char *sendirq,
16140 + unsigned char *recvirq)
16142 + if (dn->magic != DEVTREE_NODE_MAGIC) {
16143 + printk(KERN_EMERG "improper node: %p\n", dn);
16145 + *sendirq = DEVTREE_IRQ_NONE;
16148 + *recvirq = DEVTREE_IRQ_NONE;
16154 + * Copy the devtree irq(s) to the output parameters.
16157 + *sendirq = dn->sendirq;
16160 + *recvirq = dn->recvirq;
16164 +EXPORT_SYMBOL(devtree_irq);
16167 + * devtree_find_next()
16168 + * Provide an iterator for walking the device tree.
16170 +struct devtree_node *devtree_find_next(struct devtree_node **cur)
16172 + struct devtree_node *p = *cur;
16183 + * devtree_find_by_irq()
16184 + * Return the node associated with a given irq.
16186 +struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq)
16188 + struct devtree_node *p = devtree;
16190 + if (sendirq == recvirq) {
16191 + printk(KERN_EMERG "identical request makes no sense sendirq = "
16192 + "%d, recvirq= %d\n", sendirq, recvirq);
16197 + if (p->magic != DEVTREE_NODE_MAGIC) {
16198 + printk(KERN_EMERG
16199 + "device tree has improper node: %p\n", p);
16204 + * See if we can find a match on the IRQ(s) specified.
16206 + if ((sendirq == p->sendirq) && (recvirq == p->recvirq)) {
16210 + if ((sendirq == DEVTREE_IRQ_DONTCARE) &&
16211 + (p->recvirq == recvirq)) {
16215 + if ((recvirq == DEVTREE_IRQ_DONTCARE) &&
16216 + (p->sendirq == sendirq)) {
16224 +EXPORT_SYMBOL(devtree_find_by_irq);
16227 + * devtree_find_node()
16228 + * Find a node in the device tree by name.
16230 +struct devtree_node *devtree_find_node(const char *str)
16232 + struct devtree_node *p = devtree;
16234 + if (p->magic != DEVTREE_NODE_MAGIC) {
16235 + printk(KERN_EMERG
16236 + "device tree has improper node: %p\n", p);
16239 + if (strcmp(p->name, str) == 0) {
16246 +EXPORT_SYMBOL(devtree_find_node);
16248 +++ b/arch/ubicom32/kernel/dma.c
16251 + * arch/ubicom32/kernel/dma.c
16252 + * Ubicom32 architecture dynamic DMA mapping support.
16254 + * (C) Copyright 2009, Ubicom, Inc.
16256 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16272 + * Ubicom32 implementation derived from (with many thanks):
16277 + * We never have any address translations to worry about, so this
16278 + * is just alloc/free.
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>
16287 +void *dma_alloc_coherent(struct device *dev, size_t size,
16288 + dma_addr_t *dma_handle, int gfp)
16291 + /* ignore region specifiers */
16292 + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
16294 + if (dev == NULL || (*dev->dma_mask < 0xffffffff))
16296 + ret = (void *)__get_free_pages(gfp, get_order(size));
16298 + if (ret != NULL) {
16299 + memset(ret, 0, size);
16300 + *dma_handle = virt_to_phys(ret);
16305 +void dma_free_coherent(struct device *dev, size_t size,
16306 + void *vaddr, dma_addr_t dma_handle)
16308 + free_pages((unsigned long)vaddr, get_order(size));
16311 +++ b/arch/ubicom32/kernel/flat.c
16314 + * arch/ubicom32/kernel/flat.c
16315 + * Ubicom32 architecture flat executable format support.
16317 + * (C) Copyright 2009, Ubicom, Inc.
16319 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16335 + * Ubicom32 implementation derived from (with many thanks):
16340 +#include <linux/module.h>
16341 +#include <linux/types.h>
16342 +#include <linux/flat.h>
16344 +unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp,
16347 + unsigned long *persistent)
16349 + u32_t relval_reloc_type = relval >> 27;
16350 + u32_t insn = *rp;
16352 + if (*persistent) {
16354 + * relval holds the relocation that has to be adjusted.
16356 + if (relval == 0) {
16363 + if (relval_reloc_type == R_UBICOM32_32) {
16365 + * insn holds the relocation
16371 + * We don't know this one.
16376 +void ubicom32_flat_put_addr_at_rp(unsigned long *rp,
16379 + unsigned long *persistent)
16381 + u32_t reloc_type = (relval >> 27) & 0x1f;
16382 + u32_t insn = *rp;
16385 + * If persistent is set then it contains the relocation type.
16387 + if (*persistent) {
16389 + * If persistent is set then it contains the relocation type.
16391 + reloc_type = (*persistent >> 27) & 0x1f;
16394 + switch (reloc_type) {
16395 + case R_UBICOM32_32:
16397 + * Store the 32 bits as is.
16401 + case R_UBICOM32_HI24:
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.
16409 + * - Bits 7 - 27 of the relocation are encoded into bits
16410 + * 0 - 20 of the instruction.
16412 + * - Bits 28 - 30 of the relocation are encoded into bit
16413 + * 24 - 26 of the instruction.
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);
16422 + insn |= upper_3_bits;
16426 + case R_UBICOM32_LO7_S:
16427 + case R_UBICOM32_LO7_2_S:
16428 + case R_UBICOM32_LO7_4_S:
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.
16436 + u32_t mask = 0x1f | (0x3 << 8);
16437 + u32_t bottom, top;
16439 + if (reloc_type == R_UBICOM32_LO7_2_S) {
16441 + } else if (reloc_type == R_UBICOM32_LO7_4_S) {
16445 + bottom = val & 0x1f;
16449 + insn |= (top << 8);
16450 + BUG_ON(*rp != insn);
16454 + case R_UBICOM32_LO7_D:
16455 + case R_UBICOM32_LO7_2_D:
16456 + case R_UBICOM32_LO7_4_D:
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.
16464 + u32_t mask = (0x1f | (0x3 << 8)) << 16;
16465 + u32_t bottom, top;
16467 + if (reloc_type == R_UBICOM32_LO7_2_D) {
16469 + } else if (reloc_type == R_UBICOM32_LO7_4_D) {
16472 + bottom = (val & 0x1f) << 16;
16473 + top = (val >> 5) << 16;
16476 + insn |= (top << 8);
16477 + BUG_ON(*rp != insn);
16481 + case R_UBICOM32_LO7_CALLI:
16482 + case R_UBICOM32_LO16_CALLI:
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.
16491 + if (reloc_type == R_UBICOM32_LO7_CALLI) {
16499 + insn &= ~0x071f071f;
16500 + insn |= (val & 0x1f) << 0;
16502 + insn |= (val & 0x07) << 8;
16504 + insn |= (val & 0x1f) << 16;
16506 + insn |= (val & 0x07) << 24;
16507 + if (reloc_type == R_UBICOM32_LO7_CALLI) {
16508 + BUG_ON(*rp != insn);
16515 + if (*persistent) {
16520 +++ b/arch/ubicom32/kernel/head.S
16523 + * arch/ubicom32/kernel/head.S
16524 + * <TODO: Replace with short file description>
16526 + * (C) Copyright 2009, Ubicom, Inc.
16528 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16544 + * Ubicom32 implementation derived from (with many thanks):
16549 +#include <linux/sys.h>
16550 +#include <linux/linkage.h>
16551 +#include <asm/asm-offsets.h>
16552 +#include <asm/page_offset.h>
16554 +#include <asm/ip5000.h>
16560 +#define PARAM_DN D0
16561 +#define TMP_DN D15
16562 +#define TMP2_DN D14
16565 + * The following code is placed at the start of the Linux section of memory.
16566 + * This is the primary entry point for Linux.
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
16574 + * Linux Memory Map (see vlinux.lds.S):
16575 + * 0x40400000 - Primary Entry Point for Linux (jump around code below).
16576 + * 0x40400010 - Syscall Entry Point.
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)
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.
16590 +.long (_os_node - CONFIG_KERNELBASE)
16597 + * This is the start of the Linux kernel.
16600 + move.4 SCRATCHPAD1, #0
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
16608 + * D_RANGE0 - io block (set up by loaded)
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
16617 + * I_RANGE4, D_RANGE3, D_RANGE3 - unused.
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
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
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
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
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.
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
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
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
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
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
16675 +; If __ocm_free_begin is smaller than __ocm_free_end the
16676 +; setup OCM text and data ram banks properly
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
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
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)
16706 +1: move.4 (DST_AN)4++, (SRC_AN)4++
16708 +2: sub.4 #0, DST_AN, TMP_DN
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)
16722 +1: move.4 (DST_AN)4++, (SRC_AN)4++
16724 +2: sub.4 #0, DST_AN, TMP_DN
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)
16735 +1: move.4 (DST_AN)4++, #0
16737 +2: sub.4 #0, DST_AN, TMP_DN
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
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
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:
16760 + move.4 mt_dbg_active_clr,#-1
16761 +;; stalling the threads isn't instantaneous.. need to flush the pipe.
16765 +_jump_to_start_kernel:
16766 + moveai SRC_AN, #%hi(start_kernel)
16767 + lea.4 SRC_AN, %lo(start_kernel)(SRC_AN)
16770 +++ b/arch/ubicom32/kernel/init_task.c
16773 + * arch/ubicom32/kernel/init_task.c
16774 + * Ubicom32 architecture task initialization implementation.
16776 + * (C) Copyright 2009, Ubicom, Inc.
16778 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16794 + * Ubicom32 implementation derived from (with many thanks):
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>
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);
16816 + * Initial task structure.
16818 + * All other task structs will be allocated on slabs in fork.c
16820 +struct task_struct init_task = INIT_TASK(init_task);
16822 +EXPORT_SYMBOL(init_task);
16825 + * Initial thread structure.
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..
16831 +union thread_union init_thread_union
16832 + __attribute__((__section__(".data.init_task"))) =
16833 + { INIT_THREAD_INFO(init_task) };
16835 +++ b/arch/ubicom32/kernel/irq.c
16838 + * arch/ubicom32/kernel/irq.c
16839 + * Ubicom32 architecture IRQ support.
16841 + * (C) Copyright 2009, Ubicom, Inc.
16842 + * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
16844 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
16860 + * Ubicom32 implementation derived from (with many thanks):
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>
16883 +unsigned int irq_soft_avail;
16884 +static struct irqaction ubicom32_reserve_action[NR_IRQS];
16886 +#if !defined(CONFIG_DEBUG_IRQMEASURE)
16887 +#define IRQ_DECLARE_MEASUREMENT
16888 +#define IRQ_MEASUREMENT_START()
16889 +#define IRQ_MEASUREMENT_END(irq)
16891 +#define IRQ_DECLARE_MEASUREMENT \
16893 + unsigned int __tstart;
16895 +#define IRQ_MEASUREMENT_START() \
16896 + __tstart = UBICOM32_IO_TIMER->sysval;
16898 +#define IRQ_MEASUREMENT_END(irq) \
16899 + __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
16900 + irq_measurement_update((irq), __diff);
16903 + * We keep track of the time spent in both irq_enter()
16904 + * and irq_exit().
16906 +#define IRQ_WEIGHT 32
16908 +struct irq_measurement {
16909 + volatile unsigned int min;
16910 + volatile unsigned int avg;
16911 + volatile unsigned int max;
16914 +static DEFINE_SPINLOCK(irq_measurement_lock);
16917 + * Add 1 in for softirq (irq_exit());
16919 +static struct irq_measurement irq_measurements[NR_IRQS + 1];
16922 + * irq_measurement_update()
16923 + * Update an entry in the measurement array for this irq.
16925 +static void irq_measurement_update(int irq, int sample)
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;
16932 + if (im->max < sample) {
16933 + im->max = sample;
16935 + im->avg = ((im->avg * (IRQ_WEIGHT - 1)) + sample) / IRQ_WEIGHT;
16936 + spin_unlock(&irq_measurement_lock);
16941 + * irq_kernel_stack_check()
16942 + * See if the kernel stack is within STACK_WARN of the end.
16944 +static void irq_kernel_stack_check(int irq, struct pt_regs *regs)
16946 +#ifdef CONFIG_DEBUG_STACKOVERFLOW
16947 + unsigned long sp;
16950 + * Make sure that we are not close to the top of the stack and thus
16951 + * can not really service this interrupt.
16954 + "and.4 %0, SP, %1 \n\t"
16956 + : "d" (THREAD_SIZE - 1)
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);
16968 + if (sp < (sizeof(struct thread_info) + 16)) {
16976 + * Get the LSB set in value
16978 +static int irq_get_lsb(unsigned int value)
16980 + static unsigned char irq_bits[8] = {
16981 + 3, 0, 1, 0, 2, 0, 1, 0
16983 + u32_t nextbit = 0;
16985 + value = (value >> nextbit) | (value << ((sizeof(value) * 8) - nextbit));
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.
16992 + if (!(value & 0xffff)) {
16997 + if (!(value & 0xff)) {
17002 + if (!(value & 0xf)) {
17007 + nextbit += irq_bits[value & 0x7];
17008 + if (nextbit > 63) {
17009 + panic("nextbit out of range: %d\n", nextbit);
17015 + * ubicom32_reserve_handler()
17016 + * Bogus handler associated with pre-reserved IRQ(s).
17018 +static irqreturn_t ubicom32_reserve_handler(int irq, void *dev_id)
17021 + return IRQ_HANDLED;
17025 + * __irq_disable_vector()
17026 + * Disable the interrupt by clearing the appropriate bit in the
17027 + * LDSR Mask Register.
17029 +static void __irq_disable_vector(unsigned int irq)
17031 + ldsr_disable_vector(irq);
17035 + * __irq_ack_vector()
17036 + * Acknowledge the specific interrupt by clearing the associate bit in
17039 +static void __irq_ack_vector(unsigned int irq)
17042 + asm volatile ("move.4 INT_CLR0, %0" : : "d" (1 << irq));
17044 + asm volatile ("move.4 INT_CLR1, %0" : : "d" (1 << (irq - 32)));
17049 + * __irq_enable_vector()
17050 + * Clean and then enable the interrupt by setting the appropriate bit in
17051 + * the LDSR Mask Register.
17053 +static void __irq_enable_vector(unsigned int irq)
17056 + * Acknowledge, really clear the vector.
17058 + __irq_ack_vector(irq);
17059 + ldsr_enable_vector(irq);
17063 + * __irq_mask_vector()
17065 +static void __irq_mask_vector(unsigned int irq)
17067 + ldsr_mask_vector(irq);
17071 + * __irq_unmask_vector()
17073 +static void __irq_unmask_vector(unsigned int irq)
17075 + ldsr_unmask_vector(irq);
17079 + * __irq_end_vector()
17080 + * Called once an interrupt is completed (reset the LDSR mask).
17082 +static void __irq_end_vector(unsigned int irq)
17084 + ldsr_unmask_vector(irq);
17087 +#if defined(CONFIG_SMP)
17089 + * __irq_set_affinity()
17090 + * Set the cpu affinity for this interrupt.
17092 +static void __irq_set_affinity(unsigned int irq, cpumask_t dest)
17094 + smp_set_affinity(irq, dest);
17095 + irq_desc[irq].affinity = dest;
17100 + * On-Chip Generic Interrupt function handling.
17102 +static struct irq_chip ubicom32_irq_chip = {
17103 + .name = "Ubicom32",
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,
17119 + * Primary interface for handling IRQ() requests.
17121 +asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
17123 + struct pt_regs *oldregs;
17124 + struct thread_info *ti;
17125 + unsigned long sp;
17127 + IRQ_DECLARE_MEASUREMENT;
17129 + oldregs = set_irq_regs(regs);
17132 + * Before we call the handler and potentially enable
17133 + * interrupts, track the nesting level.
17136 + "and.4 %0, SP, %1 \n\t"
17138 + : "d" (~(THREAD_SIZE - 1))
17141 + ti = (struct thread_info *)sp;
17142 + ti->interrupt_nesting++;
17145 + * Check for possible stack overflow on the kernel stack.
17147 + irq_kernel_stack_check(irq, regs);
17150 + * Execute the IRQ handler and any pending SoftIRQ requests.
17152 + BUG_ON(!irqs_disabled());
17155 + BUG_ON(!irqs_disabled());
17156 + IRQ_MEASUREMENT_START();
17158 + IRQ_MEASUREMENT_END(irq);
17159 + BUG_ON(!irqs_disabled());
17161 + IRQ_MEASUREMENT_START();
17163 + IRQ_MEASUREMENT_END(NR_IRQS);
17164 + BUG_ON(!irqs_disabled());
17166 + set_irq_regs(oldregs);
17167 + ti->interrupt_nesting--;
17171 + * irq_soft_alloc()
17172 + * Allocate a soft IRQ.
17174 +int irq_soft_alloc(unsigned int *soft)
17176 + if (irq_soft_avail == 0) {
17177 + printk(KERN_NOTICE "no soft irqs to allocate\n");
17181 + *soft = irq_get_lsb(irq_soft_avail);
17182 + irq_soft_avail &= ~(1 << *soft);
17188 + * Called to handle an bad irq request.
17190 +void ack_bad_irq(unsigned int irq)
17192 + printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
17193 + __irq_end_vector(irq);
17197 + * show_interrupts()
17198 + * Return a string that displays the state of each of the interrupts.
17200 +int show_interrupts(struct seq_file *p, void *v)
17202 + struct irqaction *ap;
17203 + int irq = *((loff_t *) v);
17206 + if (irq >= NR_IRQS) {
17211 + seq_puts(p, " ");
17212 + for_each_online_cpu(j) {
17213 + seq_printf(p, "CPU%d ", j);
17215 + seq_putc(p, '\n');
17218 + ap = irq_desc[irq].action;
17220 + seq_printf(p, "%3d: ", irq);
17221 + for_each_online_cpu(j) {
17222 + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
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);
17229 + seq_putc(p, '\n');
17234 +#if defined(CONFIG_DEBUG_IRQMEASURE)
17235 +static unsigned int irq_cycles_to_micro(unsigned int cycles, unsigned int frequency)
17237 + unsigned int micro = (cycles / (frequency / 1000000));
17242 + * irq_measurement_show()
17243 + * Print out the min, avg, max values for each IRQ
17245 + * By request, the max value is reset after each dump.
17247 +static int irq_measurement_show(struct seq_file *p, void *v)
17249 + struct irqaction *ap;
17250 + unsigned int freq = processor_frequency();
17251 + int irq = *((loff_t *) v);
17255 + seq_puts(p, "\tmin\tavg\tmax\t(micro-seconds)\n");
17258 + if (irq > NR_IRQS) {
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);
17274 + ap = irq_desc[irq].action;
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);
17288 +static void *irq_measurement_start(struct seq_file *f, loff_t *pos)
17290 + return (*pos <= NR_IRQS) ? pos : NULL;
17293 +static void *irq_measurement_next(struct seq_file *f, void *v, loff_t *pos)
17296 + if (*pos > NR_IRQS)
17301 +static void irq_measurement_stop(struct seq_file *f, void *v)
17303 + /* Nothing to do */
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,
17313 +static int irq_measurement_open(struct inode *inode, struct file *filp)
17315 + return seq_open(filp, &irq_measurement_seq_ops);
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,
17325 +static int __init irq_measurement_init(void)
17327 + proc_create("irq_measurements", 0, NULL, &irq_measurement_fops);
17330 +module_init(irq_measurement_init);
17335 + * Initialize the on-chip IRQ subsystem.
17337 +void __init init_IRQ(void)
17340 + struct devtree_node *p = NULL;
17341 + struct devtree_node *iter = NULL;
17342 + unsigned int mask = 0;
17343 + unsigned int reserved = 0;
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.
17350 + irq_soft_avail = 0;
17351 + if (processor_interrupts(&irq_soft_avail, NULL) < 0) {
17352 + printk(KERN_WARNING "No Soft IRQ(s) available\n");
17354 + irq_soft_avail &= ((1 << 24) - 1);
17357 + * Initialize all of the on-chip interrupt handling
17358 + * to use a common set of interrupt functions.
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);
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.
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
17377 + p = devtree_find_next(&iter);
17379 + unsigned char sendirq, recvirq;
17380 + devtree_irq(p, &sendirq, &recvirq);
17383 + * If the sendirq is valid, mark that irq as taken by the
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);
17396 + * Track the relevant recieve IRQ(s)
17398 + if (recvirq < 24) {
17399 + mask |= (1 << recvirq);
17403 + * Move to the next node.
17405 + p = devtree_find_next(&iter);
17409 + * Remove these bits from the irq_soft_avail list and then use the
17410 + * result as the list of pre-reserved IRQ(s).
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];
17423 + * Initialize the LDSR which is the Ubicom32 programmable
17424 + * interrupt controller.
17429 + * The Ubicom trap code needs a 2nd init after IRQ(s) are setup.
17431 + trap_init_interrupt();
17434 +++ b/arch/ubicom32/kernel/ldsr.c
17437 + * arch/ubicom32/kernel/ldsr.c
17438 + * Ubicom32 architecture Linux Device Services Driver Interface
17440 + * (C) Copyright 2009, Ubicom, Inc.
17442 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
17458 + * Ubicom32 implementation derived from (with many thanks):
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.
17470 + * Because traps are treated as just a special class of interrupts, the LDSR
17471 + * also handles the processing of traps.
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.
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>
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.
17502 +// #define DEBUG_LDSR 1
17503 +#if defined(DEBUG_LDSR)
17504 +#define DEBUG_ASSERT(cond) \
17509 +#define DEBUG_ASSERT(cond)
17513 + * Make global so that we can use it in the RFI code in assembly.
17515 +unsigned int ldsr_soft_irq_mask;
17516 +EXPORT_SYMBOL(ldsr_soft_irq_mask);
17518 +static unsigned int ldsr_suspend_mask;
17519 +static unsigned int ldsr_soft_irq;
17520 +static unsigned int ldsr_stack_space[1024];
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;
17533 + * Which thread/cpu are we?
17535 +static int ldsr_tid = -1;
17537 +#if defined(CONFIG_IRQSTACKS)
17539 + * per-CPU IRQ stacks (thread information and stack)
17541 + * NOTE: Do not use DEFINE_PER_CPU() as it makes it harder
17542 + * to find the location of ctx from assembly language.
17545 + struct thread_info tinfo;
17546 + u32 stack[THREAD_SIZE/sizeof(u32)];
17548 +static union irq_ctx *percpu_irq_ctxs[NR_CPUS];
17551 + * Storage for the interrupt stack.
17553 +#if !defined(CONFIG_IRQSTACKS_USEOCM)
17554 +static char percpu_irq_stacks[(NR_CPUS * THREAD_SIZE) + (THREAD_SIZE - 1)];
17557 + * For OCM, the linker will ensure that space is allocated for the stack
17558 + * see (vmlinux.lds.S)
17560 +static char percpu_irq_stacks[];
17566 + * Save trap IRQ because we need to un-suspend if it gets set.
17568 +static unsigned int ldsr_trap_irq_mask;
17569 +static unsigned int ldsr_trap_irq;
17572 + * ret_from_interrupt_to_kernel
17573 + * Just restore the context and do nothing else.
17575 +asmlinkage void ret_from_interrupt_to_kernel(void)__attribute__((naked));
17578 + * ret_from_interrupt_to_user
17579 + * Call scheduler if needed. Just restore the context.
17581 +asmlinkage void ret_from_interrupt_to_user(void)__attribute__((naked));
17584 +u32_t old_sp, old_pc, old_a0, old_a5, old_a3;
17585 +struct pt_regs copy_regs, *copy_save_area;
17588 +int __user_mode(unsigned long sp)
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()]) {
17595 + * On the interrupt stack.
17601 + if (!(u32_t)current) {
17604 + return saved_stack_base != ((u32_t)current->stack);
17608 + * ldsr_lock_release()
17609 + * Release the LDSR lock.
17611 +static void ldsr_lock_release(void)
17613 + UBICOM32_UNLOCK(LDSR_LOCK_BIT);
17617 + * ldsr_lock_acquire()
17618 + * Acquire the LDSR lock, spin if not available.
17620 +static void ldsr_lock_acquire(void)
17622 + UBICOM32_LOCK(LDSR_LOCK_BIT);
17626 + * ldsr_thread_irq_disable()
17627 + * Disable interrupts for the specified thread.
17629 +static void ldsr_thread_irq_disable(unsigned int tid)
17631 + unsigned int mask = (1 << tid);
17634 + " or.4 scratchpad1, scratchpad1, %0 \n\t"
17642 + * ldsr_thread_get_interrupts()
17643 + * Get the interrupt state for all threads.
17645 +static unsigned long ldsr_thread_get_interrupts(void)
17647 + unsigned long ret = 0;
17649 + " move.4 %0, scratchpad1 \n\t"
17657 + * ldsr_emulate_and_run()
17658 + * Emulate the instruction and then set the thread to run.
17660 +static void ldsr_emulate_and_run(unsigned int tid)
17662 + unsigned int thread_mask = (1 << tid);
17663 + u32_t write_csr = (tid << 15) | (1 << 14);
17666 + * Emulate the unaligned access.
17668 + unaligned_emulate(tid);
17671 + * Get the thread back in a running state.
17674 + " setcsr %0 \n\t"
17675 + " setcsr_flush 0 \n\t"
17676 + " move.4 trap_cause, #0 \n\t" /* Clear the trap cause
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
17685 + : "r" (write_csr), "d" (thread_mask)
17688 + thread_enable_mask(thread_mask);
17692 + * ldsr_preemptive_context_save()
17693 + * save thread context from another hardware thread. The other thread must
17696 +static inline void ldsr_preemptive_context_save(u32_t thread,
17697 + struct pt_regs *regs)
17700 + * Save the current state of the specified thread
17703 + " move.4 a3, %0 \n\t"
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"
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"
17753 + : "r" (regs->dn), "d" ((thread << 9) | (1 << 8))
17759 + * ldsr_rotate_threads()
17760 + * Simple round robin algorithm for choosing the next cpu
17762 +static int ldsr_rotate_threads(unsigned long cpus)
17764 + static unsigned char ldsr_bits[8] = {
17765 + 3, 0, 1, 0, 2, 0, 1, 0
17768 + static int nextbit;
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.
17776 + cpus = (cpus >> nextbit) | (cpus << ((sizeof(cpus) * 8) - nextbit));
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.
17782 + if (!(cpus & 0xffff)) {
17787 + if (!(cpus & 0xff)) {
17792 + if (!(cpus & 0xf)) {
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);
17805 + * ldsr_rotate_interrupts()
17806 + * Get rotating next set bit value.
17808 +static int ldsr_rotate_interrupts(unsigned long long interrupts)
17810 + static unsigned char ldsr_bits[8] = {
17811 + 3, 0, 1, 0, 2, 0, 1, 0
17814 + static int nextbit;
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.
17822 + interrupts = (interrupts >> nextbit) |
17823 + (interrupts << ((sizeof(interrupts) * 8) - nextbit));
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.
17829 + if (!(interrupts & 0xffffffff)) {
17831 + interrupts >>= 32;
17834 + if (!(interrupts & 0xffff)) {
17836 + interrupts >>= 16;
17839 + if (!(interrupts & 0xff)) {
17841 + interrupts >>= 8;
17844 + if (!(interrupts & 0xf)) {
17846 + interrupts >>= 4;
17849 + nextbit += ldsr_bits[interrupts & 0x7];
17850 + thisbit = (nextbit & ((sizeof(interrupts) * 8) - 1));
17851 + nextbit = (thisbit + 1) & ((sizeof(interrupts) * 8) - 1);
17853 + DEBUG_ASSERT(thisbit < (sizeof(interrupts) * 8));
17858 + * ldsr_backout_or_irq()
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
17865 +static void ldsr_backout_of_irq(int vector, unsigned long tid_mask)
17867 +#if defined(CONFIG_SMP)
17868 + if (unlikely(vector == smp_ipi_irq)) {
17869 + smp_reset_ipi(tid_mask);
17872 + ldsr_unmask_vector(vector);
17873 + ldsr_interrupt.backout++;
17876 +#if defined(CONFIG_IRQSTACKS)
17878 + * ldsr_choose_savearea_and_returnvec()
17879 + * Test our current state (user, kernel, interrupt) and set things up.
17881 + * This version of the function uses 3 stacks and nests interrupts
17882 + * on the interrupt stack.
17884 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
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];
17890 +#if defined(CONFIG_SMP)
17891 + union irq_ctx *icp = percpu_irq_ctxs[tid];
17893 + union irq_ctx *icp = percpu_irq_ctxs[0];
17896 + if (masked_linux_sp == (u32_t)icp) {
17898 + * Fault/Interrupt occurred while on the interrupt stack.
17900 + save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17901 + *pvec = (u32_t)(&ret_from_interrupt_to_kernel);
17904 + * Fault/Interrupt occurred while on user/kernel stack. This is a new
17905 + * first use of the interrupt stack.
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);
17911 + *pvec = (u32_t)(&ret_from_interrupt_to_user);
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
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;
17927 + save_area->nesting_level = icp->tinfo.interrupt_nesting;
17928 + return save_area;
17933 + * ldsr_choose_savearea_and_returnvec()
17934 + * Test our current state (user, kernel, interrupt) and set things up.
17936 + * The version of the function uses just the user & kernel stack and
17937 + * nests interrupts on the existing kernel stack.
17939 +static struct pt_regs *ldsr_choose_savearea_and_returnvec(thread_t tid, u32_t linux_sp, u32_t *pvec)
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];
17945 + if (masked_linux_sp == (u32_t)ti) {
17947 + * Fault/Interrupt occurred while on the kernel stack.
17949 + save_area = (struct pt_regs *)((char *)linux_sp - sizeof(struct pt_regs) - 8);
17950 + *pvec = (u32_t) (&ret_from_interrupt_to_kernel);
17953 + * Fault/Interrupt occurred while on user stack.
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);
17959 + save_area->nesting_level = ti->interrupt_nesting;
17960 + return save_area;
17965 + * ldsr_ctxsw_thread()
17966 + * Context switch a mainline thread to execute do_IRQ() for the specified
17969 +static void ldsr_ctxsw_thread(int vector, thread_t tid)
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);
17979 + unsigned int frame_type = UBICOM32_FRAME_TYPE_INTERRUPT;
17982 + DEBUG_ASSERT(!thread_is_enabled(tid));
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.
17989 + if (unlikely(thread_is_trapped(tid))) {
17991 + * Read the trap cause, the sp and clear the MT_TRAP bits.
17993 + unsigned int cause;
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)
18008 + ldsr_backout_of_irq(vector, (1 << tid));
18010 +#if !defined(CONFIG_UNALIGNED_ACCESS_DISABLED)
18012 + * See if the unaligned trap handler can deal with this.
18013 + * If so, emulate the instruction and then just restart
18016 + if (unaligned_only(cause)) {
18017 +#if defined(CONFIG_UNALIGNED_ACCESS_USERSPACE_ONLY)
18019 + * Check if this is a kernel stack if so we will not
18020 + * handle the trap
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);
18029 + ldsr_emulate_and_run(tid);
18036 + interrupt_vector = (u32_t)(&trap_handler);
18037 + frame_type = UBICOM32_FRAME_TYPE_TRAP;
18040 + * Read the target thread's SP
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)
18055 + * We are delivering an interrupt, count it.
18057 + ldsr_interrupt.total++;
18060 + * At this point, we will definitely force this thread to
18061 + * a new context, show its interrupts as disabled.
18063 + ldsr_thread_irq_disable(tid);
18066 + * Test our current state (user, kernel, interrupt). Save the
18067 + * appropriate data and setup for the return.
18069 + save_area = ldsr_choose_savearea_and_returnvec(tid, linux_sp, &return_vector);
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.
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;
18081 + * Preserve the context of the Linux thread.
18083 + ldsr_preemptive_context_save(tid, save_area);
18086 + * Load the fram_type into the save_area.
18088 + save_area->frame_type = frame_type;
18090 +#ifdef CONFIG_STOP_ON_TRAP
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.
18098 + if (frame_type == UBICOM32_FRAME_TYPE_TRAP) {
18104 + copy_regs = *save_area;
18105 + copy_save_area = save_area;
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;
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.
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
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
18139 + : "r" (write_csr), "r" (save_area),
18140 + "r" (return_vector), "r" (interrupt_vector),
18141 + "d" (thread_mask), "r" (vector)
18144 + thread_enable_mask(thread_mask);
18148 + * ldsr_deliver_interrupt()
18149 + * Deliver the interrupt to one of the threads or all of the threads.
18151 +static void ldsr_deliver_interrupt(int vector,
18152 + unsigned long deliver_to,
18155 + unsigned long disabled_threads;
18156 + unsigned long possible_threads;
18157 + unsigned long trapped_threads;
18158 + unsigned long global_locks;
18161 + * Disable all of the threads that we might want to send
18162 + * this interrupt to.
18165 + DEBUG_ASSERT(deliver_to);
18166 + thread_disable_mask(deliver_to);
18169 + * If any threads are in the trap state, we have to service the
18170 + * trap for those threads first.
18173 + "move.4 %0, MT_TRAP \n\t"
18174 + : "=r" (trapped_threads)
18178 + trapped_threads &= deliver_to;
18179 + if (unlikely(trapped_threads)) {
18181 + * all traps will be handled, so clear the trap bit before restarting any threads
18183 + ubicom32_clear_interrupt(ldsr_trap_irq);
18186 + * Let the remaining untrapped threads, continue.
18188 + deliver_to &= ~trapped_threads;
18189 + if (deliver_to) {
18190 + thread_enable_mask(deliver_to);
18194 + * For the trapped threads force them to handle
18197 + while (trapped_threads) {
18198 + unsigned long which = ffz(~trapped_threads);
18199 + trapped_threads &= ~(1 << which);
18200 + ldsr_ctxsw_thread(vector, which);
18206 + * Can we deliver an interrupt to any of the threads?
18208 + disabled_threads = ldsr_thread_get_interrupts();
18209 + possible_threads = deliver_to & ~disabled_threads;
18210 + if (unlikely(!possible_threads)) {
18211 +#if defined(CONFIG_SMP)
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
18219 + thread_enable_mask(deliver_to);
18220 + ldsr_backout_of_irq(vector, deliver_to);
18224 + * In the UP case, we have nothing to do so we should wait.
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.
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
18234 + unsigned int scratch = 0;
18235 + thread_enable_mask(deliver_to);
18237 + " move.4 INT_MASK0, %1 \n\t"
18238 + " move.4 INT_MASK1, #0 \n\t"
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"
18245 + " move.4 INT_CLR0, %2 \n\t"
18247 + : "d" (ldsr_suspend_mask), "r" (ldsr_soft_irq_mask)
18252 + * This delay is sized to coincide with the time it takes a
18253 + * thread to complete the exit (see return_from_interrupt).
18255 + ldsr_interrupt.retry++;
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.
18268 + "move.4 %0, scratchpad1 \n\t"
18269 + : "=r" (global_locks)
18272 + if (unlikely(global_locks & 0xffff0000)) {
18273 + thread_enable_mask(deliver_to);
18276 + * This delay is sized to coincide with the average time it
18277 + * takes a thread to release a global lock.
18279 + ldsr_interrupt.retry++;
18285 + * Deliver to one cpu.
18289 + * Find our victim and then enable everyone else.
18291 + unsigned long victim = ldsr_rotate_threads(possible_threads);
18292 + DEBUG_ASSERT((deliver_to & (1 << victim)));
18293 + DEBUG_ASSERT((possible_threads & (1 << victim)));
18295 + deliver_to &= ~(1 << victim);
18296 + if (deliver_to) {
18297 + thread_enable_mask(deliver_to);
18299 + ldsr_ctxsw_thread(vector, victim);
18304 + * If we can't deliver to some threads, wake them
18305 + * back up and reset things to deliver to them.
18307 + deliver_to &= ~possible_threads;
18308 + if (unlikely(deliver_to)) {
18309 + thread_enable_mask(deliver_to);
18310 + ldsr_backout_of_irq(vector, deliver_to);
18314 + * Deliver to all possible threads(s).
18316 + while (possible_threads) {
18317 + unsigned long victim = ffz(~possible_threads);
18318 + possible_threads &= ~(1 << victim);
18319 + ldsr_ctxsw_thread(vector, victim);
18325 + * This thread acts as the interrupt controller for Linux.
18327 +static void ldsr_thread(void *arg)
18333 + long long interrupts;
18334 + unsigned long cpus;
18336 +#if !defined(CONFIG_SMP)
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
18344 + * In the SMP case, we will use the cpu(s) map to determine which cpu(s)
18345 + * are valid to send interrupts to.
18348 + unsigned int mainline = thread_get_mainline();
18349 + if (mainline == 0) {
18350 + panic("no mainline Linux threads to interrupt");
18353 + victim = ffz(~mainline);
18354 + cpus = (1 << victim);
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
18364 + ldsr_lock_acquire();
18366 + " move.4 INT_MASK0, %0 \n\t"
18367 + " move.4 INT_MASK1, %1 \n\t"
18369 + : "U4" (ldsr_interrupt.mask0), "U4" (ldsr_interrupt.mask1)
18371 + ldsr_lock_release();
18372 + thread_suspend();
18375 + * Read the interrupt status registers
18378 + "move.4 %0, INT_STAT0 \n\t"
18379 + "move.4 %1, INT_STAT1 \n\t"
18380 + : "=r" (stat0), "=r" (stat1)
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.
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();
18397 + * For each interrupt in the "snapshot" we will mask the
18398 + * interrupt handle the interrupt (typically calling do_IRQ()).
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
18404 + interrupts = ((unsigned long long)interrupt1 << 32) |
18406 + while (interrupts) {
18408 + int vector = ldsr_rotate_interrupts(interrupts);
18409 + interrupts &= ~((unsigned long long)1 << vector);
18412 + * Now mask off this vector so that the LDSR ignores
18413 + * it until it is acknowledged.
18415 + ldsr_mask_vector(vector);
18416 +#if !defined(CONFIG_SMP)
18417 + ldsr_deliver_interrupt(vector, cpus, all);
18419 + cpus = smp_get_affinity(vector, &all);
18421 + ldsr_deliver_interrupt(vector, cpus, all);
18431 + * ldsr_mask_vector()
18432 + * Temporarily mask the interrupt vector, turn off the bit in the mask
18435 +void ldsr_mask_vector(unsigned int vector)
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);
18447 + mask = ~(1 << (vector - 32));
18448 + ldsr_lock_acquire();
18449 + ldsr_interrupt.mask1 &= mask;
18450 + ldsr_lock_release();
18451 + thread_resume(ldsr_tid);
18455 + * ldsr_unmask_vector()
18456 + * Unmask the interrupt vector so that it can be used, turn on the bit in
18457 + * the mask register.
18459 + * Because it is legal for the interrupt path to disable an interrupt,
18460 + * the unmasking code must ensure that disabled interrupts are not
18463 +void ldsr_unmask_vector(unsigned int vector)
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);
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);
18483 + * ldsr_enable_vector()
18484 + * The LDSR implements an interrupt controller and has a local (to the
18485 + * LDSR) copy of its interrupt mask.
18487 +void ldsr_enable_vector(unsigned int vector)
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);
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);
18509 + * ldsr_disable_vector()
18510 + * The LDSR implements an interrupt controller and has a local (to the
18511 + * LDSR) copy of its interrupt mask.
18513 +void ldsr_disable_vector(unsigned int vector)
18515 + unsigned int mask;
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);
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);
18536 + * ldsr_get_threadid()
18537 + * Return the threadid of the LDSR thread.
18539 +thread_t ldsr_get_threadid(void)
18545 + * ldsr_set_trap_irq()
18546 + * Save away the trap Soft IRQ
18548 + * See the per thread lock suspend code above for an explination.
18550 +void ldsr_set_trap_irq(unsigned int irq)
18552 + ldsr_trap_irq = irq;
18553 + ldsr_trap_irq_mask = (1 << irq);
18554 + ldsr_suspend_mask |= ldsr_trap_irq_mask;
18559 + * Initialize the LDSR (Interrupt Controller)
18561 +void ldsr_init(void)
18563 +#if defined(CONFIG_IRQSTACKS)
18565 + union irq_ctx *icp;
18568 + void *stack_high = (void *)ldsr_stack_space;
18569 + stack_high += sizeof(ldsr_stack_space);
18574 + * Obtain a soft IRQ to use
18576 + if (irq_soft_alloc(&ldsr_soft_irq) < 0) {
18577 + panic("no software IRQ is available\n");
18580 + ldsr_soft_irq_mask |= (1 << ldsr_soft_irq);
18581 + ldsr_suspend_mask |= ldsr_soft_irq_mask;
18584 + * Now allocate and start the LDSR thread.
18586 + ldsr_tid = thread_alloc();
18587 + if (ldsr_tid < 0) {
18588 + panic("no thread available to run LDSR");
18592 +#if defined(CONFIG_IRQSTACKS)
18594 + * Initialize the per-cpu irq thread_info structure that
18595 + * is at the top of each per-cpu irq stack.
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);
18602 + ti->exec_domain = NULL;
18604 + ti->preempt_count = 0;
18605 + ti->interrupt_nesting = 0;
18606 + percpu_irq_ctxs[i] = icp++;
18609 + thread_start(ldsr_tid, ldsr_thread, NULL,
18610 + stack_high, THREAD_TYPE_NORMAL);
18613 +++ b/arch/ubicom32/kernel/Makefile
18616 +# arch/ubicom32/kernel/Makefile
18617 +# Main Makefile for the Ubicom32 arch directory.
18619 +# (C) Copyright 2009, Ubicom, Inc.
18621 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
18637 +# Ubicom32 implementation derived from (with many thanks):
18643 +extra-y := head.o vmlinux.lds
18664 + ubicom32_context_switch.o \
18665 + ubicom32_ksyms.o \
18666 + ubicom32_syscall.o \
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
18676 +ifndef CONFIG_GENERIC_CLOCKEVENTS
18677 +obj-y += timer_tick.o
18680 +++ b/arch/ubicom32/kernel/module.c
18683 + * arch/ubicom32/kernel/module.c
18684 + * Ubicom32 architecture loadable module support.
18686 + * (C) Copyright 2009, Ubicom, Inc.
18688 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
18704 + * Ubicom32 implementation derived from (with many thanks):
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>
18719 +#define DEBUGP printk
18721 +#define DEBUGP(fmt...)
18724 +static void _module_free_ocm(struct module *mod)
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);
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;
18737 +void *module_alloc(unsigned long size)
18741 + return vmalloc(size);
18745 +/* Free memory returned from module_alloc */
18746 +void module_free(struct module *mod, void *module_region)
18748 + vfree(module_region);
18749 + /* FIXME: If module_region == mod->init_region, trim exception
18750 + table entries. */
18753 + * This is expected to be final module free, use this to prune the
18756 + if (module_region && module_region == mod->module_core)
18757 + _module_free_ocm(mod);
18762 + * module_frob_arch_sections()
18763 + * Called from kernel/module.c allowing arch specific handling of
18764 + * sections/headers.
18766 +int module_frob_arch_sections(Elf_Ehdr *hdr,
18767 + Elf_Shdr *sechdrs,
18768 + char *secstrings,
18769 + struct module *mod)
18771 + Elf_Shdr *s, *sechdrs_end;
18772 + void *ocm_inst = NULL;
18773 + int ocm_inst_size = 0;
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.
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);
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);
18795 +#error Unknown/Unsupported ubicom32 architecture.
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.
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;
18811 + if (!ocm_inst_size)
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);
18823 + "module %s: OCM instruction memory allocation of %d"
18824 + "failed.\n", mod->name, ocm_inst_size);
18829 + mod->arch.ocm_inst = ocm_inst;
18830 + mod->arch.ocm_inst_size = ocm_inst_size;
18833 + "module %s: OCM instruction memory allocation of %d @%p\n",
18834 + mod->name, mod->arch.ocm_inst_size, mod->arch.ocm_inst);
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;
18848 +int apply_relocate(Elf32_Shdr *sechdrs,
18849 + const char *strtab,
18850 + unsigned int symindex,
18851 + unsigned int relsec,
18852 + struct module *me)
18854 + DEBUGP("Invalid Applying relocate section %u to %u\n", relsec,
18855 + sechdrs[relsec].sh_info);
18859 +int apply_relocate_add(Elf32_Shdr *sechdrs,
18860 + const char *strtab,
18861 + unsigned int symindex,
18862 + unsigned int relsec,
18863 + struct module *me)
18866 + Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
18868 + uint32_t *location;
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++) {
18875 + const int elf32_rtype = ELF32_R_TYPE(rel[i].r_info);
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);
18885 + v = rel[i].r_addend + sym->st_value;
18888 + switch (elf32_rtype) {
18889 + case R_UBICOM32_32:
18892 + * Store the 32 bit relocation as is.
18897 + case R_UBICOM32_HI24:
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.
18905 + * - Bits 7 - 27 of the relocation are encoded into bits
18906 + * 0 - 20 of the instruction.
18908 + * - Bits 28 - 30 of the relocation are encoded into
18909 + * bit 24 - 26 of the instruction.
18911 + uint32_t valid24 = (v >> 7) & 0xffffff;
18912 + insn = *location;
18914 + insn &= ~(0x1fffff | (0x7 << 24));
18915 + insn |= (valid24 & 0x1fffff);
18916 + insn |= ((valid24 & 0xe00000) << 3);
18917 + *location = insn;
18920 + case R_UBICOM32_LO7_S:
18921 + case R_UBICOM32_LO7_2_S:
18922 + case R_UBICOM32_LO7_4_S:
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.
18930 + uint32_t valid7 = v & 0x7f;
18931 + insn = *location;
18933 + if (elf32_rtype == R_UBICOM32_LO7_2_S) {
18935 + } else if (elf32_rtype == R_UBICOM32_LO7_4_S) {
18939 + insn &= ~(0x1f | (0x3 << 8));
18940 + insn |= (valid7 & 0x1f);
18941 + insn |= ((valid7 & 0x60) << 3);
18942 + *location = insn;
18945 + case R_UBICOM32_LO7_D:
18946 + case R_UBICOM32_LO7_2_D:
18947 + case R_UBICOM32_LO7_4_D:
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.
18955 + uint32_t valid7 = v & 0x7f;
18956 + insn = *location;
18958 + if (elf32_rtype == R_UBICOM32_LO7_2_D) {
18960 + } else if (elf32_rtype == R_UBICOM32_LO7_4_D) {
18964 + insn &= ~((0x1f | (0x3 << 8)) << 16);
18965 + insn |= ((valid7 & 0x1f) << 16);
18966 + insn |= ((valid7 & 0x60) << 19);
18967 + *location = insn;
18970 + case R_UBICOM32_LO7_CALLI:
18971 + case R_UBICOM32_LO16_CALLI:
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.
18981 + if (elf32_rtype == R_UBICOM32_LO7_CALLI) {
18984 + val = v & 0x3ffff;
18989 + insn = *location;
18991 + insn &= ~0x071f071f;
18992 + insn |= (val & 0x1f) << 0;
18994 + insn |= (val & 0x07) << 8;
18996 + insn |= (val & 0x1f) << 16;
18998 + insn |= (val & 0x07) << 24;
18999 + *location = insn;
19002 + case R_UBICOM32_24_PCREL:
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.
19010 + int32_t val = v - (int32_t)location;
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.
19017 + if (((uint32_t)val & 0xFE000000) != 0xFE000000 &&
19018 + ((uint32_t)val & 0xFE000000) != 0x0) {
19020 + * The relocation is beyond our addressable
19021 + * range with a 26 bit call.
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);
19031 + val = (val & 0x3ffffff) >> 2;
19032 + insn = *location;
19033 + insn = insn & 0xf8e00000;
19035 + insn |= (val >> 21) << 24;
19036 + insn |= (val & 0x1fffff);
19037 + *location = insn;
19040 + case R_UBICOM32_LO16:
19041 + case R_UBICOM32_HI16:
19044 + * 16 bit immediate value that is encoded into bit 0 -
19045 + * 15 of the instruction.
19049 + if (elf32_rtype == R_UBICOM32_LO16) {
19050 + val = v & 0xffff;
19052 + val = (v >> 16) & 0xffff;
19055 + insn = *location;
19056 + insn &= 0xffff0000;
19059 + *location = insn;
19062 + case R_UBICOM32_21_PCREL:
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.
19070 + int32_t val = v - (int32_t)location;
19072 + val = (val & 0x7fffff) >> 2;
19073 + insn = *location;
19074 + insn = insn & 0xffe00000;
19076 + insn |= (val >> 21) << 24;
19078 + *location = insn;
19083 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
19084 + me->name, elf32_rtype);
19091 +int module_finalize(const Elf_Ehdr *hdr,
19092 + const Elf_Shdr *sechdrs,
19093 + struct module *mod)
19095 + unsigned int i, strindex = 0, symindex = 0;
19096 + char *secstrings;
19099 + err = module_bug_finalize(hdr, sechdrs, mod);
19103 + if (!mod->arch.ocm_inst) {
19105 + * No OCM code, so nothing more to do.
19110 + secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
19112 + for (i = 1; i < hdr->e_shnum; i++) {
19113 + /* Internal symbols and strings. */
19114 + if (sechdrs[i].sh_type == SHT_SYMTAB) {
19116 + strindex = sechdrs[i].sh_link;
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;
19124 + /* Not a valid relocation section? */
19125 + if (info >= hdr->e_shnum)
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);
19141 +void module_arch_cleanup(struct module *mod)
19143 + module_bug_cleanup(mod);
19146 +++ b/arch/ubicom32/kernel/os_node.c
19149 + * arch/ubicom32/kernel/os_node.c
19150 + * <TODO: Replace with short file description>
19152 + * (C) Copyright 2009, Ubicom, Inc.
19154 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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>
19180 +extern asmlinkage void *_start;
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.
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;
19203 + * The os_node is only referenced by head.S and should never be modified at
19206 +asmlinkage const struct os_node _os_node = {
19209 + .name = { "OS" },
19210 + .magic = 0x10203040,
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,
19218 + .expected_ocm_code_start = OCMEND,
19219 + .expected_ocm_data_end = OCMEND,
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
19229 +++ b/arch/ubicom32/kernel/process.c
19232 + * arch/ubicom32/kernel/process.c
19233 + * Ubicom32 architecture-dependent process handling.
19235 + * (C) Copyright 2009, Ubicom, Inc.
19236 + * Copyright (C) 1995 Hamish Macdonald
19238 + * 68060 fixes by Jesper Skov
19240 + * uClinux changes
19241 + * Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
19243 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
19259 + * Ubicom32 implementation derived from (with many thanks):
19266 + * This file handles the architecture-dependent parts of process handling..
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>
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>
19296 +asmlinkage void ret_from_fork(void);
19298 +void (*pm_power_off)(void) = machine_power_off;
19299 +EXPORT_SYMBOL(pm_power_off);
19301 +/* machine-dependent / hardware-specific power functions */
19302 +void (*mach_reset)(void);
19303 +void (*mach_halt)(void);
19304 +void (*mach_power_off)(void);
19308 + * The idle thread.
19310 + * Our idle loop suspends and is woken up by a timer interrupt.
19312 +void cpu_idle(void)
19315 + local_irq_disable();
19316 + while (!need_resched()) {
19317 + local_irq_enable();
19318 + thread_suspend();
19319 + local_irq_disable();
19321 + local_irq_enable();
19322 + preempt_enable_no_resched();
19324 + preempt_disable();
19331 + * Fill in the fpu structure for a core dump. (just a stub as we don't have
19334 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
19340 + * machine_restart()
19341 + * Resets the system.
19343 +void machine_restart(char *__unused)
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.
19351 + thread_disable_others();
19354 + * Call the hardware-specific machine reset function.
19356 + if (mach_reset) {
19360 + printk(KERN_EMERG "System Restarting\n");
19363 + * Set watchdog to trigger (after 1ms delay) (12 Mhz is the fixed OSC)
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;
19372 + * Wait for watchdog
19375 + " move.4 MT_EN, #0 \n\t"
19376 + " pipe_flush 0 \n\t"
19379 + local_irq_disable();
19381 + thread_suspend();
19387 + * Halt the machine.
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.
19393 +void machine_halt(void)
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.
19401 + thread_disable_others();
19404 + * Call the hardware-specific machine halt function.
19410 + printk(KERN_EMERG "System Halted, OK to turn off power\n");
19411 + local_irq_disable();
19413 + thread_suspend();
19418 + * machine_power_off()
19419 + * Turn the power off, if a power off handler is defined, otherwise, spin
19422 +void machine_power_off(void)
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.
19430 + thread_disable_others();
19433 + * Call the hardware-specific machine power off function.
19435 + if (mach_power_off) {
19436 + mach_power_off();
19439 + printk(KERN_EMERG "System Halted, OK to turn off power\n");
19440 + local_irq_disable();
19442 + thread_suspend();
19448 + * Print out all of the registers.
19450 +void show_regs(struct pt_regs *regs)
19454 + printk(KERN_NOTICE "regs: %p, tid: %d\n",
19456 + thread_get_self());
19458 + printk(KERN_NOTICE "pc: %08x, previous_pc: %08x\n\n",
19459 + (unsigned int)regs->pc,
19460 + (unsigned int)regs->previous_pc);
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) {
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) {
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]);
19486 + printk(KERN_NOTICE "mac_rc16: %08x, source3: %08x\n",
19487 + (unsigned int)regs->mac_rc16,
19488 + (unsigned int)regs->source3);
19490 + printk(KERN_NOTICE "inst_cnt: %08x, csr: %08x\n",
19491 + (unsigned int)regs->inst_cnt,
19492 + (unsigned int)regs->csr);
19494 + printk(KERN_NOTICE "int_mask0: %08x, int_mask1: %08x\n",
19495 + (unsigned int)regs->int_mask0,
19496 + (unsigned int)regs->int_mask1);
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);
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
19512 +asmlinkage void kernel_thread_helper(void);
19515 + * kernel_thread()
19516 + * Create a kernel thread
19518 +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
19520 + struct pt_regs regs;
19522 + memset(®s, 0, sizeof(regs));
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;
19532 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
19533 + 0, ®s, 0, NULL, NULL);
19535 +EXPORT_SYMBOL(kernel_thread);
19541 +void flush_thread(void)
19548 + * Not implemented on no-mmu.
19550 +asmlinkage int sys_fork(struct pt_regs *regs)
19552 + /* fork almost works, enough to trick you into looking elsewhere :-( */
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).
19562 +asmlinkage int sys_vfork(struct pt_regs *regs)
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;
19570 + * Read the old retrun address from the stack.
19572 + if (copy_from_user(&old_return_address,
19573 + (void *)old_sp, sizeof(unsigned long))) {
19574 + force_sig(SIGSEGV, current);
19579 + * Pop the vfork call frame by setting a5 and pc to the old_return
19580 + * address and incrementing the stack pointer by 4.
19582 + regs->an[5] = old_return_address;
19583 + regs->pc = old_return_address;
19584 + regs->an[7] += 4;
19586 + do_fork_return = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
19587 + regs->an[7], regs, 0, NULL, NULL);
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
19595 + if ((unsigned long)(do_fork_return) >= (unsigned long)(-125)) {
19597 + * Error case. We need to restore the frame.
19599 + regs->an[5] = old_a5;
19600 + regs->pc = old_a5;
19601 + regs->an[7] = old_sp;
19604 + return do_fork_return;
19609 + * creates a child thread.
19611 +asmlinkage int sys_clone(unsigned long clone_flags,
19612 + unsigned long newsp,
19613 + struct pt_regs *regs)
19616 + newsp = regs->an[7];
19617 + return do_fork(clone_flags, newsp, regs, 0,
19623 + * low level thread copy, only used by do_fork in kernel/fork.c
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)
19629 + struct pt_regs *childregs;
19631 + childregs = (struct pt_regs *)
19632 + (task_stack_page(p) + THREAD_SIZE - 8) - 1;
19634 + *childregs = *regs;
19637 + * Set return value for child to be 0.
19639 + childregs->dn[0] = 0;
19642 + childregs->an[7] = usp;
19644 + childregs->an[7] = (unsigned long)task_stack_page(p) +
19648 + * Set up the switch_to frame to return to "ret_from_fork"
19650 + p->thread.a5 = (unsigned long)ret_from_fork;
19651 + p->thread.sp = (unsigned long)childregs;
19658 + * executes a new program.
19660 +asmlinkage int sys_execve(char *name, char **argv,
19661 + char **envp, struct pt_regs *regs)
19667 + filename = getname(name);
19668 + error = PTR_ERR(filename);
19669 + if (IS_ERR(filename))
19671 + error = do_execve(filename, argv, envp, regs);
19672 + putname(filename);
19673 + asm (" .global sys_execve_complete\n"
19674 + " sys_execve_complete:");
19681 + * Return saved PC of a blocked thread.
19683 +unsigned long thread_saved_pc(struct task_struct *tsk)
19685 + return tsk->thread.a5;
19689 +unsigned long get_wchan(struct task_struct *p)
19691 + unsigned long pc;
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
19698 + if (!p || p == current || p->state == TASK_RUNNING)
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.
19706 + pc = thread_saved_pc(p);
19707 + if (in_sched_functions(pc))
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
19721 +asmlinkage void *__switch_to(struct task_struct *prev,
19722 + struct thread_struct *prev_switch,
19723 + struct thread_struct *next_switch)
19724 + __attribute__((naked));
19726 +++ b/arch/ubicom32/kernel/processor.c
19729 + * arch/ubicom32/kernel/processor.c
19730 + * Ubicom32 architecture processor info implementation.
19732 + * (C) Copyright 2009, Ubicom, Inc.
19734 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
19750 + * Ubicom32 implementation derived from (with many thanks):
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>
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;
19784 +struct procnode *pn;
19787 + * show_processorinfo()
19788 + * Print the actual processor information.
19790 +static void show_processorinfo(struct seq_file *m)
19792 + char *cpu, *mmu, *fpu;
19793 + unsigned int clockfreq;
19794 + unsigned int chipid;
19801 + "move.4 %0, CHIP_ID \n\t"
19806 + * General Processor Information.
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));
19816 + * Now compute the clock frequency in Mhz.
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));
19830 + * Get CPU information for use by the procfs.
19832 +static int show_cpuinfo(struct seq_file *m, void *v)
19834 + unsigned long n = (unsigned long)v - 1;
19836 +#if defined(CONFIG_SMP)
19837 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, n);
19841 + * Print the general processor information on the first
19845 + show_processorinfo(m);
19848 +#if defined(CONFIG_SMP)
19850 + * For each hwthread, print if this hwthread is running Linux
19851 + * or is an I/O thread.
19853 + if (cpu_isset(n, cpu_online_map)) {
19854 + seq_printf(m, "cpu[%02lu]:\tthread id - %lu\n", n, p->tid);
19856 + seq_printf(m, "cpu[%02lu]:\toff-line\n", n);
19863 +static void *c_start(struct seq_file *m, loff_t *pos)
19865 + unsigned long i = *pos;
19867 + return i < NR_CPUS ? (void *)(i + 1) : NULL;
19870 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
19873 + return c_start(m, pos);
19876 +static void c_stop(struct seq_file *m, void *v)
19880 +const struct seq_operations cpuinfo_op = {
19881 + .start = c_start,
19884 + .show = show_cpuinfo,
19888 + * processor_timers()
19889 + * Returns the timers available to Linux.
19891 +unsigned int processor_timers(void)
19896 + return pn->timers;
19900 + * processor_threads()
19901 + * Returns the threads available to Linux.
19903 +unsigned int processor_threads(void)
19908 + return pn->threads;
19912 + * processor_frequency()
19913 + * Returns the frequency of the system clock.
19915 +unsigned int processor_frequency(void)
19920 + return pn->frequency;
19922 +EXPORT_SYMBOL(processor_frequency);
19925 + * processor_interrupts()
19926 + * Return the interrupts that are setup at boot time.
19928 +int processor_interrupts(unsigned int *int0, unsigned int *int1)
19935 + *int0 = pn->interrupt0;
19939 + *int1 = pn->interrupt1;
19945 + * processor_ocm()
19946 + * Returns the OCM available to Linux.
19948 +int processor_ocm(void **socm, void **eocm)
19954 + *socm = pn->socm;
19955 + *eocm = pn->eocm;
19960 + * processor_dram()
19961 + * Returns the dram available to Linux.
19963 +int processor_dram(void **sdram, void **edram)
19969 + *sdram = pn->sdram;
19970 + *edram = pn->edram;
19974 +void __init processor_init(void)
19977 + * If we do not have a trap node in the device tree, we leave the fault
19978 + * handling to the underlying hardware.
19980 + pn = (struct procnode *)devtree_find_node("processor");
19982 + printk(KERN_WARNING "processor node not found\n");
19987 +++ b/arch/ubicom32/kernel/ptrace.c
19990 + * arch/ubicom32/kernel/ptrace.c
19991 + * Ubicom32 architecture ptrace implementation.
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
19998 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
20014 + * Ubicom32 implementation derived from (with many thanks):
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>
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>
20038 + * ptrace_getregs()
20040 + * Get all user integer registers.
20042 +static inline int ptrace_getregs(struct task_struct *task, void __user *uregs)
20044 + struct pt_regs *regs = task_pt_regs(task);
20045 + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
20049 + * ptrace_get_reg()
20051 + * Get contents of register REGNO in task TASK.
20053 +static unsigned long ptrace_get_reg(struct task_struct *task, int regno)
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);
20064 + * ptrace_put_reg()
20065 + * Write contents of register REGNO in task TASK.
20067 +static int ptrace_put_reg(struct task_struct *task, int regno,
20068 + unsigned long data)
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;
20079 + * ptrace_disable_single_step()
20080 + * Disable Single Step
20082 +static int ptrace_disable_single_step(struct task_struct *task)
20085 + * Single Step not yet implemented, so must always be disabled
20091 + * ptrace_disable()
20092 + * Make sure the single step bit is not set.
20093 + * Called by kernel/ptrace.c when detaching..
20095 +void ptrace_disable(struct task_struct *child)
20097 + ptrace_disable_single_step(child);
20102 + * architecture specific ptrace routine.
20104 +long arch_ptrace(struct task_struct *child, long request, long addr, long data)
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);
20114 + /* read the word at location addr in the USER area. */
20115 + case PTRACE_PEEKUSR: {
20116 + unsigned long tmp;
20119 + if (((unsigned long) addr > PT_INTERP_FDPIC_LOADMAP)
20123 + tmp = 0; /* Default return condition */
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;
20138 + } else if (addr == PT_INTERP_FDPIC_LOADMAP) {
20139 +#ifdef CONFIG_BINFMT_ELF_FDPIC
20140 + tmp = child->mm->context.interp_fdpic_loadmap;
20146 + ret = put_user(tmp, (unsigned long *)data);
20150 + case PTRACE_POKETEXT: /* write the word at location addr. */
20151 + case PTRACE_POKEDATA:
20152 + ret = generic_ptrace_pokedata(child, addr, data);
20155 + * If we just changed some code so we need to
20156 + * correct the caches
20158 + if (request == PTRACE_POKETEXT && ret == 0) {
20159 + flush_icache_range(addr, addr + 4);
20163 + case PTRACE_POKEUSR: /* write the word at location addr
20164 + * in the USER area */
20167 + if (((unsigned long) addr > PT_DATA_ADDR) || (addr & 3))
20170 + if (addr < sizeof(struct pt_regs)) {
20171 + ret = ptrace_put_reg(child, addr, data);
20175 + case PTRACE_SYSCALL: /* continue and stop at next (return from)
20177 + case PTRACE_CONT: { /* restart after signal. */
20180 + if (!valid_signal(data))
20182 + if (request == PTRACE_SYSCALL)
20183 + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
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);
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.
20198 + case PTRACE_KILL: {
20200 + if (child->exit_state == EXIT_ZOMBIE) /* already dead */
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);
20209 + case PTRACE_DETACH: /* detach a process that was attached. */
20210 + ret = ptrace_detach(child, data);
20213 + case PTRACE_GETREGS: /* Get all gp regs from the child. */
20214 + ptrace_getregs(child, (unsigned long *)data);
20218 + case PTRACE_SETREGS: { /* Set all gp regs in the child. */
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)) {
20227 + ptrace_put_reg(child, sizeof(unsigned long) * i, tmp);
20228 + data += sizeof(long);
20235 + return ptrace_request(child, request, addr, data);
20243 + * called by syscall enter/exit when the TIF_SYSCALL_TRACE bit is set.
20245 +asmlinkage void syscall_trace(void)
20247 + struct task_struct *cur = current;
20248 + if (!test_thread_flag(TIF_SYSCALL_TRACE))
20250 + if (!(cur->ptrace & PT_PTRACED))
20252 + ptrace_notify(SIGTRAP | ((cur->ptrace & PT_TRACESYSGOOD)
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
20259 + if (cur->exit_code) {
20260 + send_sig(cur->exit_code, current, 1);
20261 + current->exit_code = 0;
20265 +++ b/arch/ubicom32/kernel/semaphore.c
20268 + * arch/ubicom32/kernel/semaphore.c
20269 + * Ubicom32 architecture semaphore implementation.
20271 + * (C) Copyright 2009, Ubicom, Inc.
20273 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
20289 + * Ubicom32 implementation derived from (with many thanks):
20295 + * Generic semaphore code. Buyer beware. Do your own
20296 + * specific changes in <asm/semaphore-helper.h>
20299 +#include <linux/sched.h>
20300 +#include <linux/err.h>
20301 +#include <linux/init.h>
20302 +#include <asm/semaphore-helper.h>
20304 +#ifndef CONFIG_RMW_INSNS
20305 +spinlock_t semaphore_wake_lock;
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
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.
20320 + * waking_non_zero() (from asm/semaphore.h) must execute
20323 + * When __up() is called, the count was negative before
20324 + * incrementing it, and we need to wake up somebody.
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
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.
20338 +void __up(struct semaphore *sem)
20340 + wake_one_more(sem);
20341 + wake_up(&sem->wait);
20345 + * Perform the "down" function. Return zero for semaphore acquired,
20346 + * return negative for signalled out of the function.
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
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
20358 + * Either form may be used in conjunction with "up()".
20363 +#define DOWN_HEAD(task_state) \
20366 + current->state = (task_state); \
20367 + add_wait_queue(&sem->wait, &wait); \
20370 + * Ok, we're set up. sem->count is known to be less than zero \
20371 + * so we must wait. \
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. \
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. \
20381 + * Multiple waiters contend for the semaphore lock to see \
20382 + * who gets to gate through and who has to wait some more. \
20386 +#define DOWN_TAIL(task_state) \
20387 + current->state = (task_state); \
20389 + current->state = TASK_RUNNING; \
20390 + remove_wait_queue(&sem->wait, &wait);
20392 +void __sched __down(struct semaphore *sem)
20394 + DECLARE_WAITQUEUE(wait, current);
20396 + DOWN_HEAD(TASK_UNINTERRUPTIBLE)
20397 + if (waking_non_zero(sem))
20400 + DOWN_TAIL(TASK_UNINTERRUPTIBLE)
20403 +int __sched __down_interruptible(struct semaphore *sem)
20405 + DECLARE_WAITQUEUE(wait, current);
20408 + DOWN_HEAD(TASK_INTERRUPTIBLE)
20410 + ret = waking_non_zero_interruptible(sem, current);
20413 + /* ret != 0 only if we get interrupted -arca */
20418 + DOWN_TAIL(TASK_INTERRUPTIBLE)
20422 +int __down_trylock(struct semaphore *sem)
20424 + return waking_non_zero_trylock(sem);
20427 +++ b/arch/ubicom32/kernel/setup.c
20430 + * arch/ubicom32/kernel/setup.c
20431 + * Ubicom32 architecture-dependent parts of system setup.
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>
20443 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
20459 + * Ubicom32 implementation derived from (with many thanks):
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>
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>
20489 +unsigned long memory_start;
20490 +EXPORT_SYMBOL(memory_start);
20492 +unsigned long memory_end;
20493 +EXPORT_SYMBOL(memory_end);
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;
20500 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
20504 + * Setup the architecture dependent portions of the system.
20506 +void __init setup_arch(char **cmdline_p)
20508 + int bootmap_size;
20510 + processor_init();
20514 + * TODO: The memory regions should really come from the
20515 + * processor node.
20517 + memory_start = PAGE_ALIGN(((unsigned long)&_end));
20518 + memory_end = CONFIG_RAMBASE+CONFIG_RAMSIZE;
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;
20525 + strlcpy(boot_command_line, bootargs_get_cmdline(), COMMAND_LINE_SIZE);
20527 +#ifdef CONFIG_CMDLINE_BOOL
20528 +#ifdef CONFIG_CMDLINE_OVERRIDE
20529 + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
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);
20540 + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
20541 + *cmdline_p = command_line;
20543 + parse_early_param();
20545 + printk(KERN_INFO "%s Processor, Ubicom, Inc. <www.ubicom.com>\n", CPU);
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);
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;
20563 + if (strlen(*cmdline_p))
20564 + printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
20567 +#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
20568 + conswitchp = &dummy_con;
20572 + * If we have a device tree, see if we have the nodes we need.
20579 + * From the arm initialization comment:
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.
20585 + * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
20586 + * the system, not the maximum PFN.
20588 + max_pfn = max_low_pfn = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
20591 + * Give all the memory to the bootmap allocator, tell it to put the
20592 + * boot mem_map at the start of memory.
20594 + bootmap_size = init_bootmem_node(
20596 + memory_start >> PAGE_SHIFT, /* map goes here */
20597 + PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
20598 + memory_end >> PAGE_SHIFT);
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 :-)
20603 + free_bootmem(memory_start, memory_end - memory_start);
20604 + reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
20607 + * Get kmalloc into gear.
20612 + * Fix up the thread_info structure, indicate this is a mainline Linux
20613 + * thread and setup the sw_ksp().
20615 + sw_ksp[thread_get_self()] = (unsigned int) current_thread_info();
20616 + thread_set_mainline(thread_get_self());
20619 +++ b/arch/ubicom32/kernel/signal.c
20622 + * arch/ubicom32/kernel/signal.c
20623 + * Ubicom32 architecture signal handling implementation.
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
20633 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
20649 + * Ubicom32 implementation derived from (with many thanks):
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)
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!
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>
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>
20687 +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
20690 + * asm signal return handlers.
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);
20697 + * Common signal suspend implementation
20699 +static int signal_suspend(sigset_t *saveset, struct pt_regs *regs)
20701 + regs->dn[0] = -EINTR;
20703 + current->state = TASK_INTERRUPTIBLE;
20705 + if (!do_signal(saveset, regs)) {
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.
20713 + if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) {
20714 + return regs->dn[0];
20719 + * Should never get here
20726 + * Atomically swap in the new signal mask, and wait for a signal.
20728 +asmlinkage int do_sigsuspend(struct pt_regs *regs)
20730 + old_sigset_t mask = regs->dn[0];
20731 + sigset_t saveset;
20733 + mask &= _BLOCKABLE;
20734 + spin_lock_irq(¤t->sighand->siglock);
20735 + saveset = current->blocked;
20736 + siginitset(¤t->blocked, mask);
20737 + recalc_sigpending();
20738 + spin_unlock_irq(¤t->sighand->siglock);
20741 + * Call common handler
20743 + return signal_suspend(&saveset, regs);
20747 +do_rt_sigsuspend(struct pt_regs *regs)
20749 + sigset_t *unewset = (sigset_t *)regs->dn[0];
20750 + size_t sigsetsize = (size_t)regs->dn[1];
20751 + sigset_t saveset, newset;
20753 + /* XXX: Don't preclude handling different sized sigset_t's. */
20754 + if (sigsetsize != sizeof(sigset_t))
20757 + if (copy_from_user(&newset, unewset, sizeof(newset)))
20759 + sigdelsetmask(&newset, ~_BLOCKABLE);
20761 + spin_lock_irq(¤t->sighand->siglock);
20762 + saveset = current->blocked;
20763 + current->blocked = newset;
20764 + recalc_sigpending();
20765 + spin_unlock_irq(¤t->sighand->siglock);
20768 + * Call common handler
20770 + return signal_suspend(&saveset, regs);
20774 +sys_sigaction(int sig, const struct old_sigaction *act,
20775 + struct old_sigaction *oact)
20777 + struct k_sigaction new_ka, old_ka;
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))
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);
20791 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
20798 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
20799 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
20806 +do_sys_sigaltstack(struct pt_regs *regs)
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]);
20814 + * fdpic_func_descriptor describes sa_handler when the application is FDPIC
20816 +struct fdpic_func_descriptor {
20817 + unsigned long text;
20818 + unsigned long GOT;
20822 + * rt_sigframe is stored on the user stack immediately before (above)
20823 + * the signal handlers stack.
20825 +struct rt_sigframe
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. */
20831 + struct ucontext uc;
20837 + * Do a signal return; undo the signal stack.
20839 +asmlinkage int do_sigreturn(unsigned long __unused)
20845 +asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
20847 + unsigned long usp = regs->an[7];
20848 + struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
20851 + if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
20853 + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
20856 + sigdelsetmask(&set, ~_BLOCKABLE);
20857 + spin_lock_irq(¤t->sighand->siglock);
20858 + current->blocked = set;
20859 + recalc_sigpending();
20860 + spin_unlock_irq(¤t->sighand->siglock);
20862 + if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs)))
20864 + return regs->dn[0];
20867 + force_sig(SIGSEGV, current);
20871 +static inline void *
20872 +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
20874 + unsigned long usp;
20876 + /* Default to using normal stack. */
20877 + usp = regs->an[7];
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;
20884 + return (void *)((usp - frame_size) & ~0x3);
20888 + * signal_trampoline: Defined in ubicom32_syscall.S
20890 +asmlinkage void signal_trampoline(void)__attribute__((naked));
20892 +static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
20893 + sigset_t *set, struct pt_regs *regs)
20895 + struct rt_sigframe *frame;
20898 + frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame));
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.
20905 + err |= __put_user( ( (current_thread_info()->exec_domain)
20906 + && (current_thread_info()->exec_domain->signal_invmap)
20908 + ? current_thread_info()->exec_domain->signal_invmap[sig]
20909 + : sig, &frame->sig);
20910 + err |= __put_user(info, &frame->info);
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);
20925 + err |= __put_user(0, &frame->restore_all_regs);
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));
20931 + goto give_sigsegv;
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.
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;
20946 + * If this is FDPIC then the signal handler is actually a function
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);
20955 + goto give_sigsegv;
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
20962 + regs->an[3] = (unsigned long) funcptr;
20965 + regs->dn[3] = (unsigned long)ka->sa.sa_handler;
20969 + regs->frame_type = UBICOM32_FRAME_TYPE_SIGTRAMP;
20974 + /* user space exception */
20975 + force_sigsegv(sig, current);
20978 +static inline void
20979 +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
20981 + switch (regs->dn[0]) {
20982 + case -ERESTARTNOHAND:
20983 + if (!has_handler)
20985 + regs->dn[0] = -EINTR;
20988 + case -ERESTARTSYS:
20989 + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
20990 + regs->dn[0] = -EINTR;
20993 + /* fallthrough */
20994 + case -ERESTARTNOINTR:
20996 + regs->dn[0] = regs->original_dn_0;
20998 + regs->an[5] -= 8;
21004 + * OK, we're invoking a handler
21007 +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
21008 + sigset_t *oldset, struct pt_regs *regs)
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);
21015 + /* set up the stack frame */
21016 + setup_rt_frame(sig, ka, info, oldset, regs);
21018 + if (ka->sa.sa_flags & SA_ONESHOT)
21019 + ka->sa.sa_handler = SIG_DFL;
21021 + spin_lock_irq(¤t->sighand->siglock);
21022 + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
21023 + if (!(ka->sa.sa_flags & SA_NODEFER))
21024 + sigaddset(¤t->blocked,sig);
21025 + recalc_sigpending();
21026 + spin_unlock_irq(¤t->sighand->siglock);
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
21034 +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
21036 + struct k_sigaction ka;
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
21046 + if (!user_mode(regs))
21050 + oldset = ¤t->blocked;
21052 + signr = get_signal_to_deliver(&info, &ka, regs, NULL);
21054 + /* Whee! Actually deliver the signal. */
21055 + handle_signal(signr, &ka, &info, oldset, regs);
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);
21069 + * sys_sigreturn()
21070 + * Return handler for signal clean-up.
21072 + * NOTE: Ubicom32 does not use this syscall. Instead we rely
21073 + * on do_rt_sigreturn().
21075 +asmlinkage long sys_sigreturn(void)
21080 +++ b/arch/ubicom32/kernel/smp.c
21083 + * arch/ubicom32/kernel/smp.c
21084 + * SMP implementation for Ubicom32 processors.
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>
21091 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
21107 + * Ubicom32 implementation derived from (with many thanks):
21113 +#include <linux/types.h>
21114 +#include <linux/spinlock.h>
21115 +#include <linux/slab.h>
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>
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>
21150 + * Mask the debug printout for IPI because they are too verbose
21151 + * for regular debugging.
21154 +// #define DEBUG_SMP 1
21155 +#if !defined(DEBUG_SMP)
21156 +#define smp_debug(lvl, ...)
21158 +static unsigned int smp_debug_lvl = 50;
21159 +#define smp_debug(lvl, printargs...) \
21160 + if (lvl >= smp_debug_lvl) { \
21161 + printk(printargs); \
21165 +#if !defined(DEBUG_SMP)
21166 +#define DEBUG_ASSERT(cond)
21168 +#define DEBUG_ASSERT(cond) \
21175 + * List of IPI Commands (more than one can be set at a time).
21177 +enum ipi_message_type {
21181 + IPI_CALL_FUNC_SINGLE,
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.
21190 +cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */
21191 +EXPORT_SYMBOL(cpu_online_map);
21193 +cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */
21194 +EXPORT_SYMBOL(cpu_possible_map);
21197 + * We maintain a hardware thread oriented view of online threads
21198 + * and those involved or needing IPI.
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];
21206 + * What do we need to track on a per cpu/thread basis?
21208 +DEFINE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
21211 + * Each thread cpuinfo IPI information is guarded by a lock
21212 + * that is kept local to this file.
21214 +DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
21217 + * The IPI(s) are based on a software IRQ through the LDSR.
21219 +unsigned int smp_ipi_irq;
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.
21225 +DEFINE_SPINLOCK(smp_ipi_lock);
21228 + * smp_halt_processor()
21229 + * Halt this hardware thread.
21231 +static void smp_halt_processor(void)
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);
21239 + thread_suspend();
21244 + * ipi_interrupt()
21245 + * Handle an Interprocessor Interrupt.
21247 +static irqreturn_t ipi_interrupt(int irq, void *dev_id)
21249 + int cpuid = smp_processor_id();
21250 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21251 + unsigned long ops;
21254 + * Count this now; we may make a call that never returns.
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.
21267 + spin_lock(&smp_ipi_lock);
21268 + smp_needs_ipi &= ~p->tid;
21269 + spin_unlock(&smp_ipi_lock);
21273 + * Read the set of IPI commands we should handle.
21275 + spinlock_t *lock = &per_cpu(ipi_lock, cpuid);
21277 + ops = p->ipi_pending;
21278 + p->ipi_pending = 0;
21279 + spin_unlock(lock);
21282 + * If we have no IPI commands to execute, break out.
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.
21294 + unsigned long which = ffz(~ops);
21295 + ops &= ~(1 << which);
21297 + BUG_ON(!irqs_disabled());
21300 + smp_debug(100, KERN_INFO "cpu[%d]: "
21301 + "IPI_NOP\n", cpuid);
21304 + case IPI_RESCHEDULE:
21306 + * Reschedule callback. Everything to be
21307 + * done is done by the interrupt return path.
21309 + smp_debug(200, KERN_INFO "cpu[%d]: "
21310 + "IPI_RESCHEDULE\n", cpuid);
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();
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();
21325 + case IPI_CPU_STOP:
21326 + smp_debug(100, KERN_INFO "cpu[%d]: "
21327 + "IPI_CPU_STOP\n", cpuid);
21328 + smp_halt_processor();
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();
21338 + update_process_times(user_mode(get_irq_regs()));
21339 + profile_tick(CPU_PROFILING);
21345 + printk(KERN_CRIT "cpu[%d]: "
21346 + "Unknown IPI: %lu\n", cpuid, which);
21352 + * Let in any pending interrupts
21354 + BUG_ON(!irqs_disabled());
21355 + local_irq_enable();
21356 + local_irq_disable();
21359 + return IRQ_HANDLED;
21364 + * Send an Interprocessor Interrupt.
21366 +static void ipi_send(int cpu, enum ipi_message_type op)
21368 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21369 + spinlock_t *lock = &per_cpu(ipi_lock, cpu);
21370 + unsigned long flags;
21373 + * We protect the setting of the ipi_pending field and ensure
21374 + * that the ipi delivery mechanism and interrupt are atomically
21377 + spin_lock_irqsave(lock, flags);
21378 + p->ipi_pending |= 1 << op;
21379 + spin_unlock_irqrestore(lock, flags);
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);
21389 + * Send an IPI to each cpu in mask.
21391 +static inline void ipi_send_mask(unsigned int op, cpumask_t mask)
21394 + for_each_cpu_mask(cpu, mask) {
21395 + ipi_send(cpu, op);
21400 + * ipi_send_allbutself()
21401 + * Send an IPI to all threads but ourselves.
21403 +static inline void ipi_send_allbutself(unsigned int op)
21405 + int self = smp_processor_id();
21406 + cpumask_t result = cpu_online_map;
21407 + cpu_clear(self, result);
21408 + ipi_send_mask(op, result);
21412 + * smp_enable_vector()
21414 +static void smp_enable_vector(unsigned int irq)
21416 + ubicom32_clear_interrupt(smp_ipi_irq);
21417 + ldsr_enable_vector(irq);
21421 + * smp_disable_vector()
21422 + * Disable the interrupt by clearing the appropriate bit in the
21423 + * LDSR Mask Register.
21425 +static void smp_disable_vector(unsigned int irq)
21427 + ldsr_disable_vector(irq);
21431 + * smp_mask_vector()
21433 +static void smp_mask_vector(unsigned int irq)
21435 + ldsr_mask_vector(irq);
21439 + * smp_unmask_vector()
21441 +static void smp_unmask_vector(unsigned int irq)
21443 + ldsr_unmask_vector(irq);
21447 + * smp_end_vector()
21448 + * Called once an interrupt is completed (reset the LDSR mask).
21450 +static void smp_end_vector(unsigned int irq)
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);
21459 + spin_unlock(&smp_ipi_lock);
21460 + ldsr_unmask_vector(irq);
21464 + * Special hanlder functions for SMP.
21466 +static struct irq_chip ubicom32_smp_chip = {
21467 + .name = "UbicoIPI",
21469 + .shutdown = NULL,
21470 + .enable = smp_enable_vector,
21471 + .disable = smp_disable_vector,
21473 + .mask = smp_mask_vector,
21474 + .unmask = smp_unmask_vector,
21475 + .end = smp_end_vector,
21479 + * smp_reset_ipi()
21480 + * None of these cpu(s) got their IPI, turn it back on.
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.
21487 +void smp_reset_ipi(unsigned long mask)
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);
21497 + * smp_get_affinity()
21498 + * Choose the thread affinity for this interrupt.
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.
21505 +unsigned long smp_get_affinity(unsigned int irq, int *all)
21507 + unsigned long mask = 0;
21510 + * Most IRQ(s) are delivered in a round robin fashion.
21512 + if (irq != smp_ipi_irq) {
21513 + unsigned long result = smp_irq_affinity[irq] & smp_online_threads;
21514 + DEBUG_ASSERT(result);
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.
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;
21532 + __raw_spin_unlock(&smp_ipi_lock.raw_lock);
21538 + * smp_set_affinity()
21539 + * Set the affinity for this irq but store the value in tid(s).
21541 +void smp_set_affinity(unsigned int irq, cpumask_t dest)
21544 + unsigned long *paffinity = &smp_irq_affinity[irq];
21547 + * If none specified, all cpus are allowed.
21549 + if (cpus_empty(dest)) {
21550 + *paffinity = 0xffffffff;
21555 + * Make sure to clear the old value before setting up the
21559 + for_each_cpu_mask(cpuid, dest) {
21560 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21561 + *paffinity |= (1 << p->tid);
21566 + * smp_send_stop()
21567 + * Send a stop request to all CPU but this one.
21569 +void smp_send_stop(void)
21571 + ipi_send_allbutself(IPI_CPU_STOP);
21575 + * smp_send_timer_all()
21576 + * Send all cpu(s) but this one, a request to update times.
21578 +void smp_send_timer_all(void)
21580 + ipi_send_allbutself(IPI_CPU_TIMER);
21584 + * smp_timer_broadcast()
21585 + * Use an IPI to broadcast a timer message
21587 +void smp_timer_broadcast(cpumask_t mask)
21589 + ipi_send_mask(IPI_CPU_TIMER, mask);
21593 + * smp_send_reschedule()
21594 + * Send a reschedule request to the specified cpu.
21596 +void smp_send_reschedule(int cpu)
21598 + ipi_send(cpu, IPI_RESCHEDULE);
21602 + * arch_send_call_function_ipi()
21603 + * Cause each cpu in the mask to call the generic function handler.
21605 +void arch_send_call_function_ipi(cpumask_t mask)
21608 + for_each_cpu_mask(cpu, mask) {
21609 + ipi_send(cpu, IPI_CALL_FUNC);
21614 + * arch_send_call_function_single_ipi()
21615 + * Cause the specified cpu to call the generic function handler.
21617 +void arch_send_call_function_single_ipi(int cpu)
21619 + ipi_send(cpu, IPI_CALL_FUNC_SINGLE);
21623 + * smp_mainline_start()
21624 + * Start a slave thread executing a mainline Linux context.
21626 +static void __init smp_mainline_start(void *arg)
21628 + int cpuid = smp_processor_id();
21629 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid);
21631 + BUG_ON(p->tid != thread_get_self());
21634 + * Well, support 2.4 linux scheme as well.
21636 + if (cpu_test_and_set(cpuid, cpu_online_map)) {
21637 + printk(KERN_CRIT "cpu[%d]: already initialized!\n", cpuid);
21638 + smp_halt_processor();
21643 + * Initialise the idle task for this CPU
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();
21655 + * TODO: X86 does this prior to calling notify, try to understand why?
21657 + preempt_disable();
21659 +#if defined(CONFIG_GENERIC_CLOCKEVENTS)
21661 + * Setup a local timer event so that this cpu will get timer interrupts
21663 + if (local_timer_setup(cpuid) == -1) {
21664 + printk(KERN_CRIT "cpu[%d]: timer alloc failed\n", cpuid);
21665 + smp_halt_processor();
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).
21676 + notify_cpu_starting(cpuid);
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.
21684 + cpu_set(cpuid, cpu_online_map);
21685 + cpu_set(cpuid, cpu_present_map);
21688 + * Maintain a thread mapping in addition to the cpu mapping.
21690 + smp_online_threads |= (1 << p->tid);
21693 + * Enable interrupts for this thread.
21695 + local_irq_enable();
21698 + * Enter the idle loop and wait for a timer to schedule some work.
21700 + printk(KERN_INFO "cpu[%d]: entering cpu_idle()\n", cpuid);
21703 + /* Not Reached */
21707 + * smp_cpus_done()
21708 + * Called once the kernel_init() has brought up all cpu(s).
21710 +void smp_cpus_done(unsigned int cpu_max)
21717 + * Called to startup a sepcific cpu.
21719 +int __cpuinit __cpu_up(unsigned int cpu)
21721 + struct task_struct *idle;
21722 + unsigned int *stack;
21724 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpu);
21727 + * Create an idle task for this CPU.
21729 + idle = fork_idle(cpu);
21730 + if (IS_ERR(idle)) {
21731 + panic("cpu[%d]: fork failed\n", cpu);
21734 + task_thread_info(idle)->cpu = cpu;
21737 + * Setup the sw_ksp[] to point to this new task.
21739 + sw_ksp[p->tid] = (unsigned int)idle->stack;
21740 + stack = (unsigned int *)(sw_ksp[p->tid] + PAGE_SIZE - 8);
21743 + * Cause the specified thread to execute our smp_mainline_start
21744 + * function as a TYPE_NORMAL thread.
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);
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.
21758 + for (timeout = 0; timeout < 10000; timeout++) {
21759 + if (cpu_online(cpu)) {
21768 + if (!cpu_online(cpu)) {
21769 + printk(KERN_CRIT "cpu[%d]: failed to live after %ld us\n",
21770 + cpu, timeout * 100);
21774 + printk(KERN_INFO "cpu[%d]: came alive after %ld us\n",
21775 + cpu, timeout * 100);
21780 + * Data used by setup_irq for the IPI.
21782 +static struct irqaction ipi_irq = {
21784 + .flags = IRQF_DISABLED | IRQF_PERCPU,
21785 + .handler = ipi_interrupt,
21789 + * smp_prepare_cpus()
21790 + * Mark threads that are available to Linux as possible cpus(s).
21792 +void __init smp_prepare_cpus(unsigned int max_cpus)
21797 + * We will need a software IRQ to send IPI(s). We will use
21798 + * a single software IRQ for all IPI(s).
21800 + if (irq_soft_alloc(&smp_ipi_irq) < 0) {
21801 + panic("no software IRQ is available\n");
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.
21810 + * Next, Register the IPI interrupt function against the soft IRQ.
21812 + set_irq_chip(smp_ipi_irq, &ubicom32_smp_chip);
21813 + setup_irq(smp_ipi_irq, &ipi_irq);
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.
21820 + * We need to do this very early in the SMP case
21821 + * because the Linux init code uses the cpu_present_map.
21823 + for_each_possible_cpu(i) {
21825 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, i);
21828 + * Skip the bootstrap cpu
21835 + * If we have a free thread left in the mask,
21836 + * indicate that the cpu is present.
21838 + tid = thread_alloc();
21839 + if (tid == (thread_t)-1) {
21844 + * Save the hardware thread id for this cpu.
21847 + cpu_set(i, cpu_present_map);
21848 + printk(KERN_INFO "cpu[%d]: added to cpu_present_map - tid: %d\n", i, tid);
21853 + * smp_prepare_boot_cpu()
21854 + * Copy the per_cpu data into the appropriate spot for the bootstrap cpu.
21856 + * The code in boot_cpu_init() has already set the boot cpu's
21857 + * state in the possible, present, and online maps.
21859 +void __devinit smp_prepare_boot_cpu(void)
21861 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
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);
21869 + * smp_setup_processor_id()
21870 + * Set the current_thread_info() structure cpu value.
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
21875 +void __init smp_setup_processor_id(void)
21877 + struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, 0);
21878 + current_thread_info()->cpu = 0;
21879 + p->tid = thread_get_self();
21883 + * setup_profiling_timer()
21884 + * Dummy function created to keep Oprofile happy in the SMP case.
21886 +int setup_profiling_timer(unsigned int multiplier)
21891 +++ b/arch/ubicom32/kernel/stacktrace.c
21894 + * arch/ubicom32/kernel/stacktrace.c
21895 + * Ubicom32 architecture stack back trace implementation.
21897 + * (C) Copyright 2009, Ubicom, Inc.
21899 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
21915 + * Ubicom32 implementation derived from (with many thanks):
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>
21927 + * These symbols are filled in by the linker.
21929 +extern unsigned long _stext;
21930 +extern unsigned long _etext;
21932 +extern unsigned long __ocm_text_run_begin;
21933 +extern unsigned long __data_begin;
21936 + * stacktrace_iterate()
21937 + * Walk the stack looking for call and calli instructions on an aligned
21940 + * Trace must point to the top of the current stack frame.
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)
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;
21957 + * Exclude the current thread from being monitored for traps.
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)
21972 + while (limit++ < 256) {
21974 + * See if we have a valid stack.
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);
21989 + * Get the value off the stack and back up 4 bytes to what
21990 + * should be the address of a call or calli.
21992 + address = (*sp++) - 4;
21995 + * If the address is not within the text segment, skip this
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);
22015 + * If the address is not on an aligned boundary it can not be a
22016 + * return address.
22018 + if (address & 0x3) {
22023 + * Read the probable instruction.
22025 + instruction = *(unsigned int *)address;
22028 + * Is this a call instruction?
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);
22037 + result = address;
22042 + * Is this a calli instruction?
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);
22051 + result = address;
22057 + * Restore the current thread to be monitored for traps.
22059 + if (thread_trap_en) {
22061 + " thread_get_self_mask d15 \n\t"
22062 + " or.4 MT_TRAP_EN, MT_TRAP_EN, d15 \n\t"
22071 +#ifdef CONFIG_STACKTRACE
22073 + * stacktrace_save_entries()
22074 + * Save stack back trace information into the provided trace structure.
22076 +void stacktrace_save_entries(struct task_struct *tsk,
22077 + struct stack_trace *trace,
22078 + unsigned long sp)
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;
22090 + handle = (unsigned long *)stack;
22091 + while (idx < trace->max_entries) {
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) {
22108 + * save_stack_trace()
22109 + * Save the specified amount of the kernel stack trace information
22110 + * for the current task.
22112 +void save_stack_trace(struct stack_trace *trace)
22114 + unsigned long sp = 0;
22116 + " move.4 %0, SP \n\t"
22119 + stacktrace_save_entries(current, trace, sp);
22121 +EXPORT_SYMBOL_GPL(save_stack_trace);
22124 + * save_stack_trace_tsk()
22125 + * Save the specified amount of the kernel stack trace information
22126 + * for the specified task.
22128 + * Note: We assume the specified task is not currently running.
22130 +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
22132 + stacktrace_save_entries(tsk, trace, tsk->thread.sp);
22134 +EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
22135 +#endif /* CONFIG_STACKTRACE */
22137 +++ b/arch/ubicom32/kernel/syscalltable.S
22140 + * arch/ubicom32/kernel/syscalltable.S
22141 + * <TODO: Replace with short file description>
22143 + * (C) Copyright 2009, Ubicom, Inc.
22145 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
22161 + * Ubicom32 implementation derived from (with many thanks):
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
22174 +#include <linux/sys.h>
22175 +#include <linux/linkage.h>
22176 +#include <asm/unistd.h>
22180 + .global sys_call_table
22182 + .long sys_ni_syscall /* 0 - old "setup()" system call*/
22187 + .long sys_open /* 5 */
22189 + .long sys_waitpid
22192 + .long sys_unlink /* 10 */
22193 + .long execve_intercept
22197 + .long sys_chmod /* 15 */
22198 + .long sys_chown16
22199 + .long sys_ni_syscall /* old break syscall holder */
22202 + .long sys_getpid /* 20 */
22204 + .long sys_oldumount
22205 + .long sys_setuid16
22206 + .long sys_getuid16
22207 + .long sys_stime /* 25 */
22212 + .long sys_utime /* 30 */
22213 + .long sys_ni_syscall /* old stty syscall holder */
22214 + .long sys_ni_syscall /* old gtty syscall holder */
22217 + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
22222 + .long sys_rmdir /* 40 */
22226 + .long sys_ni_syscall /* old prof syscall holder */
22227 + .long sys_brk /* 45 */
22228 + .long sys_setgid16
22229 + .long sys_getgid16
22231 + .long sys_geteuid16
22232 + .long sys_getegid16 /* 50 */
22234 + .long sys_umount /* recycled never used phys() */
22235 + .long sys_ni_syscall /* old lock syscall holder */
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 */
22246 + .long sys_getppid
22247 + .long sys_getpgrp /* 65 */
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
22265 + .long sys_symlink
22267 + .long sys_readlink /* 85 */
22269 + .long sys_ni_syscall /* _sys_swapon */
22271 + .long sys_old_readdir
22272 + .long old_mmap /* 90 */
22274 + .long sys_truncate
22275 + .long sys_ftruncate
22277 + .long sys_fchown16 /* 95 */
22278 + .long sys_getpriority
22279 + .long sys_setpriority
22280 + .long sys_ni_syscall /* old profil syscall holder */
22282 + .long sys_fstatfs /* 100 */
22283 + .long sys_ni_syscall /* ioperm for i386 */
22284 + .long sys_socketcall
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 */
22297 + .long sys_ni_syscall /* 115 */ /* _sys_swapoff */
22298 + .long sys_sysinfo
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
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
22326 + .long sys_ni_syscall /* _sys_msync */
22327 + .long sys_readv /* 145 */
22330 + .long sys_fdatasync
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" */
22351 + .long sys_ni_syscall /* _sys_nfsservctl */
22352 + .long sys_setresgid16 /* 170 */
22353 + .long sys_getresgid16
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
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
22375 + .long sys_truncate64
22376 + .long sys_ftruncate64
22377 + .long sys_stat64 /* 195 */
22378 + .long sys_lstat64
22379 + .long sys_fstat64
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
22390 + .long sys_setresuid
22391 + .long sys_getresuid
22392 + .long sys_setresgid /* 210 */
22393 + .long sys_getresgid
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 */
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 */
22449 + .long sys_fadvise64_64
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
22460 + .long sys_ni_syscall /* for _sys_vserver */
22461 + .long sys_add_key
22462 + .long sys_request_key /* 280 */
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
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 */
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 */
22489 + .long sys_sync_file_range
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
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 */
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
22517 +++ b/arch/ubicom32/kernel/sys_ubicom32.c
22520 + * arch/ubicom32/kernel/sys_ubicom32.c
22521 + * Ubicom32 architecture system call support implementation.
22523 + * (C) Copyright 2009, Ubicom, Inc.
22525 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
22541 + * Ubicom32 implementation derived from (with many thanks):
22546 + * This file contains various random system calls that
22547 + * have a non-standard calling sequence on the Linux/ubicom32
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>
22569 +#include <asm/setup.h>
22570 +#include <asm/traps.h>
22571 +#include <asm/cacheflush.h>
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)
22579 + int error = -EBADF;
22580 + struct file *file = NULL;
22582 + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22583 + if (!(flags & MAP_ANONYMOUS)) {
22589 + down_write(¤t->mm->mmap_sem);
22590 + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
22591 + up_write(¤t->mm->mmap_sem);
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)
22603 + return do_mmap2(addr, len, prot, flags, fd, pgoff);
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..
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;
22622 +asmlinkage int old_mmap(struct mmap_arg_struct *arg)
22624 + struct mmap_arg_struct a;
22625 + int error = -EFAULT;
22627 + if (copy_from_user(&a, arg, sizeof(a)))
22631 + if (a.offset & ~PAGE_MASK)
22634 + a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
22636 + error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd,
22637 + a.offset >> PAGE_SHIFT);
22642 +struct sel_arg_struct {
22644 + fd_set *inp, *outp, *exp;
22645 + struct timeval *tvp;
22648 +asmlinkage int old_select(struct sel_arg_struct *arg)
22650 + struct sel_arg_struct a;
22652 + if (copy_from_user(&a, arg, sizeof(a)))
22654 + /* sys_select() does the appropriate kernel locking */
22655 + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
22659 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
22661 + * This is really horribly ugly.
22663 +asmlinkage int sys_ipc(uint call, int first, int second,
22664 + int third, void *ptr, long fifth)
22666 + int version, ret;
22668 + version = call >> 16; /* hack for backward compatibility */
22671 + if (call <= SEMCTL)
22674 + return sys_semop(first, (struct sembuf *)ptr, second);
22676 + return sys_semget(first, second, third);
22678 + union semun fourth;
22681 + if (get_user(fourth.__pad, (void **) ptr))
22683 + return sys_semctl(first, second, third, fourth);
22688 + if (call <= MSGCTL)
22691 + return sys_msgsnd(first, (struct msgbuf *) ptr,
22694 + switch (version) {
22696 + struct ipc_kludge tmp;
22699 + if (copy_from_user(&tmp,
22700 + (struct ipc_kludge *)ptr,
22703 + return sys_msgrcv(first, tmp.msgp, second,
22704 + tmp.msgtyp, third);
22707 + return sys_msgrcv(first,
22708 + (struct msgbuf *) ptr,
22709 + second, fifth, third);
22712 + return sys_msgget((key_t) first, second);
22714 + return sys_msgctl(first, second,
22715 + (struct msqid_ds *) ptr);
22719 + if (call <= SHMCTL)
22722 + switch (version) {
22725 + ret = do_shmat(first, ptr, second, &raddr);
22728 + return put_user(raddr, (ulong __user *) third);
22732 + return sys_shmdt(ptr);
22734 + return sys_shmget(first, second, third);
22736 + return sys_shmctl(first, second, ptr);
22744 +/* sys_cacheflush -- flush (part of) the processor cache. */
22746 +sys_cacheflush(unsigned long addr, int scope, int cache, unsigned long len)
22748 + flush_cache_all();
22752 +asmlinkage int sys_getpagesize(void)
22754 + return PAGE_SIZE;
22757 +++ b/arch/ubicom32/kernel/thread.c
22760 + * arch/ubicom32/kernel/thread.c
22761 + * Ubicom32 architecture hardware thread support.
22763 + * (C) Copyright 2009, Ubicom, Inc.
22765 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
22781 + * Ubicom32 implementation derived from (with many thanks):
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>
22802 + * TODO: At some point change the name here to be thread_ksp
22804 +unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
22806 +static unsigned int thread_mask = -1;
22807 +static unsigned int thread_mainline_mask;
22811 + * Returning from the called function will disable the thread.
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.
22817 +static void thread_entry(void *arg, thread_exec_fn_t exec)
22820 + * Call thread function
22825 + * Complete => Disable self
22827 + thread_disable(thread_get_self());
22832 + * Start the specified function on the specified hardware thread.
22834 +thread_t thread_start(thread_t thread,
22835 + thread_exec_fn_t exec,
22837 + unsigned int *sp_high,
22838 + thread_type_t type)
22843 + unsigned int enabled, mask, csr;
22845 + "move.4 %0, MT_EN\n\t"
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;
22856 + * Update thread state
22858 + csr = (thread << 15) | (1 << 14);
22861 + "setcsr_flush 0 \n\t"
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 */
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"
22889 + "move.4 INT_MASK0, #0 \n\t"
22890 + "move.4 INT_MASK1, #0 \n\t"
22891 + "move.4 PC, %1 \n\t"
22893 + "setcsr_flush 0 \n\t"
22895 + : "r" (csr), "r" (thread_entry), "r" (exec),
22896 + "r" (arg), "r" (sp_high)
22900 + * Apply HRT state
22902 + if (type & THREAD_TYPE_HRT) {
22904 + "or.4 MT_HRT, MT_HRT, %0\n\t"
22911 + "and.4 MT_HRT, MT_HRT, %0\n\t"
22922 + "or.4 MT_HPRI, MT_HPRI, %0\n\t"
22932 + "move.4 MT_ACTIVE_SET, %0 \n\t"
22936 + thread_enable_mask(mask);
22941 + * thread_get_mainline()
22942 + * Return a mask of those threads that are Linux mainline threads.
22944 +unsigned int thread_get_mainline(void)
22946 + return thread_mainline_mask;
22950 + * thread_set_mainline()
22951 + * Indicate that the specified thread is a Linux mainline thread.
22953 +void thread_set_mainline(thread_t tid)
22955 + thread_mainline_mask |= (1 << tid);
22960 + * Allocate an unused hardware thread.
22962 +thread_t thread_alloc(void)
22967 + * If this is the first time we are here get the list of unused
22968 + * threads from the processor device tree node.
22970 + if (thread_mask == -1) {
22971 + thread_mask = processor_threads();
22974 + if (!thread_mask) {
22975 + return (thread_t)-1;
22978 + tid = ffs(thread_mask);
22981 + thread_mask &= ~(1 << tid);
22985 + return (thread_t)-1;
22988 +++ b/arch/ubicom32/kernel/time.c
22991 + * arch/ubicom32/kernel/time.c
22992 + * Initialize the timer list and start the appropriate timers.
22994 + * (C) Copyright 2009, Ubicom, Inc.
22995 + * Copyright (C) 1991, 1992, 1995 Linus Torvalds
22997 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23013 + * Ubicom32 implementation derived from (with many thanks):
23019 +#include <linux/profile.h>
23020 +#include <linux/smp.h>
23021 +#include <asm/ip5000.h>
23022 +#include <asm/machdep.h>
23025 + * A bitmap of the timers on the processor indicates
23026 + * that the timer is free or in-use.
23028 +static unsigned int timers;
23032 + * Init the specified compare register to go off <n> cycles from now.
23034 +void timer_set(int timervector, unsigned int cycles)
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);
23044 + * Set/reset the timer to go off again.
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.
23050 + * Returns the number of ticks that transpired since the last event.
23052 +int timer_reset(int timervector, unsigned int cycles)
23055 + * Reset the timer in the LDSR thread to go off appropriately.
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.
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;
23069 + * If the difference is negative, we have missed at least one
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.
23078 + * Set our future time first.
23080 + UBICOM32_IO_TIMER->syscom[timer_index] = next;
23083 + * Then check if we are really set time in the futrue.
23085 + diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
23091 + * Oops, we are too slow. Playing catch up.
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
23098 + asm volatile ("move.4 %0, scratchpad3"
23099 + : "=r" (scratchpad3));
23100 + if ((scratchpad3 & 0x1) == 0) {
23102 + * No debugger attached, print to the console
23104 + printk(KERN_EMERG "diff: %d, timer has lost %u "
23105 + "ticks [rounded up]\n",
23107 + (unsigned int)((-diff + cycles - 1) / cycles));
23112 + diff = (int)next - (int)UBICOM32_IO_TIMER->sysval;
23114 + } while (diff < 0);
23121 + * Returns current time in nano-second units.
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.
23134 +unsigned long long sched_clock(void)
23136 + unsigned long long my_jiffies;
23137 + unsigned long jiffies_top;
23138 + unsigned long jiffies_bottom;
23141 + jiffies_top = jiffies_64 >> 32;
23142 + jiffies_bottom = jiffies_64 & 0xffffffff;
23143 + } while (unlikely(jiffies_top != (unsigned long)(jiffies_64 >> 32)));
23145 + my_jiffies = ((unsigned long long)jiffies_top << 32) | (jiffies_bottom);
23146 + return (my_jiffies - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
23151 + * Free a hardware timer.
23153 +void timer_free(int interrupt)
23155 + unsigned int bit = interrupt - TIMER_INT(0);
23158 + * The timer had not been allocated.
23160 + BUG_ON(timers & (1 << bit));
23161 + timers |= (1 << bit);
23166 + * Allocate a hardware timer.
23168 +int timer_alloc(void)
23170 + unsigned int bit = find_first_bit((unsigned long *)&timers, 32);
23172 + printk(KERN_WARNING "no more free timers\n");
23176 + timers &= ~(1 << bit);
23177 + return bit + TIMER_INT(0);
23182 + * Time init function.
23184 +void time_init(void)
23187 + * Find the processor node and determine what timers are
23188 + * available for us.
23190 + timers = processor_timers();
23191 + if (timers == 0) {
23192 + printk(KERN_WARNING "no timers are available for Linux\n");
23196 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
23197 + timer_device_init();
23199 + timer_tick_init();
23203 +++ b/arch/ubicom32/kernel/timer_broadcast.c
23206 + * arch/ubicom32/kernel/timer_broadcast.c
23207 + * Implements a dummy clock event for each cpu.
23209 + * Copyright (C) 2008 Paul Mundt
23210 + * (C) Copyright 2009, Ubicom, Inc.
23212 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23228 + * Ubicom32 implementation derived from (with many thanks):
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>
23245 +static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
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.
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"
23257 + * local_timer_interrupt()
23258 + * Used on SMP for local timer interrupt sent via an IPI.
23260 +void local_timer_interrupt(void)
23262 + struct clock_event_device *dev = &__get_cpu_var(local_clockevent);
23264 + dev->event_handler(dev);
23268 + * dummy_timer_set_next_event()
23269 + * Cause the timer to go off "cycles" from now.
23271 +static int dummy_timer_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23277 + * dummy_timer_set_mode()
23280 +static void dummy_timer_set_mode(enum clock_event_mode mode,
23281 + struct clock_event_device *clk)
23286 + * local_timer_setup()
23287 + * Adds a clock event for the specified cpu.
23289 +int __cpuinit local_timer_setup(unsigned int cpu)
23291 + struct clock_event_device *dev = &per_cpu(local_clockevent, cpu);
23293 + dev->name = "timer-dummy";
23294 + dev->features = CLOCK_EVT_FEAT_DUMMY;
23295 + dev->rating = 200;
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);
23302 + printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
23304 + clockevents_register_device(dev);
23308 +++ b/arch/ubicom32/kernel/timer_device.c
23311 + * arch/ubicom32/kernel/timer_device.c
23312 + * Implements a Ubicom32 clock device and event devices.
23314 + * (C) Copyright 2009, Ubicom, Inc.
23316 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23332 + * Ubicom32 implementation derived from (with many thanks):
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>
23344 +#if defined(CONFIG_SMP)
23345 +#include <asm/smp.h>
23348 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23349 +#define MAX_TIMERS (2 + CONFIG_TIMER_EXTRA_ALLOC)
23351 +#define MAX_TIMERS (NR_CPUS + CONFIG_TIMER_EXTRA_ALLOC)
23354 +#if (MAX_TIMERS > 10)
23355 +#error "Ubicom32 only has 10 timers"
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;
23363 +DEFINE_SPINLOCK(timer_device_lock);
23366 + * timer_device_set_next_event()
23367 + * Cause the timer to go off "cycles" from now.
23369 +static int timer_device_set_next_event(unsigned long cycles, struct clock_event_device *dev)
23371 + timer_set(dev->irq, cycles);
23376 + * timer_device_set_mode()
23377 + * Handle the mode switch for a clock event device.
23379 +static void timer_device_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
23382 + case CLOCK_EVT_MODE_SHUTDOWN:
23384 + * Make sure the vector is disabled
23385 + * until the next event is set.
23387 + printk(KERN_NOTICE "timer[%d]: shutdown\n", dev->irq);
23388 + ldsr_disable_vector(dev->irq);
23391 + case CLOCK_EVT_MODE_ONESHOT:
23393 + * Make sure the vector is disabled
23394 + * until the next event is set.
23396 + printk(KERN_NOTICE "timer[%d]: oneshot\n", dev->irq);
23397 + ldsr_disable_vector(dev->irq);
23400 + case CLOCK_EVT_MODE_PERIODIC:
23402 + * The periodic request is 1 per jiffies
23404 + printk(KERN_NOTICE "timer[%d]: periodic: %d cycles\n",
23405 + dev->irq, frequency / CONFIG_HZ);
23406 + timer_set(dev->irq, frequency / CONFIG_HZ);
23409 + case CLOCK_EVT_MODE_UNUSED:
23410 + case CLOCK_EVT_MODE_RESUME:
23411 + printk(KERN_WARNING "timer[%d]: unimplemented mode: %d\n",
23418 + * timer_device_event()
23419 + * Call the device's event handler.
23421 + * The pointer is initialized by the generic Linux code
23422 + * to the function to be called.
23424 +static irqreturn_t timer_device_event(int irq, void *dev_id)
23426 + struct clock_event_device *dev = (struct clock_event_device *)dev_id;
23428 + if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
23430 + * The periodic request is 1 per jiffies
23432 + timer_reset(dev->irq, frequency / CONFIG_HZ);
23435 + * The timer will go off again at the rollover
23436 + * point. We must disable the IRQ to prevent
23437 + * getting a spurious interrupt.
23439 + ldsr_disable_vector(dev->irq);
23442 + if (!dev->event_handler) {
23443 + printk(KERN_CRIT "no registered event handler\n");
23444 + return IRQ_HANDLED;
23447 + dev->event_handler(dev);
23448 + return IRQ_HANDLED;
23452 + * timer_device_clockbase_read()
23453 + * Provide a primary clocksource around the sysval timer.
23455 +static cycle_t timer_device_clockbase_read(void)
23457 + return (cycle_t)UBICOM32_IO_TIMER->sysval;
23461 + * Primary Clock Source Description
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.
23467 +static struct clocksource timer_device_clockbase = {
23468 + .name = "sysval",
23470 + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
23471 + .mask = CLOCKSOURCE_MASK(32),
23474 + .read = timer_device_clockbase_read,
23478 + * timer_device_alloc_event()
23479 + * Allocate a timer device event.
23481 +static int timer_device_alloc_event(const char *name, int cpuid, cpumask_t mask)
23483 + struct clock_event_device *dev;
23484 + struct irqaction *action;
23487 + * Are we out of configured timers?
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");
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);
23501 + * Now allocate a timer to ourselves.
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");
23513 + * Init the IRQ action structure. Make sure
23514 + * this in place before you register the clock
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);
23527 + * init clock dev structure.
23529 + * The min_delta_ns is chosen to ensure that setting next
23530 + * event will never be requested with too small of value.
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);
23545 + * Now register the device.
23547 + clockevents_register_device(dev);
23551 +#if defined(CONFIG_LOCAL_TIMERS)
23553 + * local_timer_setup()
23554 + * Allocation function for creating a per cpu local timer.
23556 +int __cpuinit local_timer_setup(unsigned int cpu)
23558 + return timer_device_alloc_event("timer-cpu", cpu, cpumask_of_cpu(cpu));
23563 + * timer_device_init()
23564 + * Create and init a generic clock driver for Ubicom32.
23566 +void timer_device_init(void)
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.
23575 + frequency = processor_frequency();
23576 + if (frequency == 0) {
23577 + frequency = CLOCK_TICK_RATE;
23581 + * Setup the primary clock source around sysval. Linux does not
23582 + * supply a Mhz multiplier so convert down to khz.
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");
23593 + * Always allocate a primary timer.
23595 + timer_device_alloc_event("timer-primary", -1, CPU_MASK_ALL);
23597 +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
23599 + * If BROADCAST is selected we need to add a broadcast timer.
23601 + timer_device_alloc_event("timer-broadcast", -1, CPU_MASK_ALL);
23605 + * Allocate extra timers that are requested.
23607 + for (i = 0; i < CONFIG_TIMER_EXTRA_ALLOC; i++) {
23608 + timer_device_alloc_event("timer-extra", -1, CPU_MASK_ALL);
23613 +++ b/arch/ubicom32/kernel/timer_tick.c
23616 + * arch/ubicom32/kernel/timer_tick.c
23617 + * Impelemets a perodic timer.
23619 + * (C) Copyright 2009, Ubicom, Inc.
23620 + * Copyright (C) 1991, 1992, 1995 Linus Torvalds
23622 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23638 + * Ubicom32 implementation derived from (with many thanks):
23644 +#include <linux/profile.h>
23646 +#include <asm/ip5000.h>
23647 +#include <asm/machdep.h>
23648 +#if defined(CONFIG_SMP)
23649 +#include <asm/smp.h>
23652 +static unsigned int timervector;
23653 +static unsigned int frequency;
23657 + * Kernel system timer support. Needs to keep up the real-time clock,
23658 + * as well as call the "do_timer()" routine every clocktick.
23660 +static irqreturn_t timer_tick(int irq, void *dummy)
23664 + BUG_ON(!irqs_disabled());
23665 + ticks = timer_reset(timervector, frequency);
23667 + write_seqlock(&xtime_lock);
23669 + write_sequnlock(&xtime_lock);
23671 + update_process_times(user_mode(get_irq_regs()));
23672 + profile_tick(CPU_PROFILING);
23674 +#if defined(CONFIG_SMP)
23675 + smp_send_timer_all();
23677 + return(IRQ_HANDLED);
23681 + * Data used by setup_irq for the timer.
23683 +static struct irqaction timer_irq = {
23685 + .flags = IRQF_DISABLED | IRQF_TIMER,
23686 + .handler = timer_tick,
23690 + * timer_tick_init()
23691 + * Implements a periodic timer
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.
23697 +void timer_tick_init(void)
23700 + * Now allocate a timer to ourselves.
23702 + timervector = timer_alloc();
23703 + if (timervector == -1) {
23704 + printk(KERN_WARNING "where did the timer go?\n");
23708 + setup_irq(timervector, &timer_irq);
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.
23715 + frequency = processor_frequency();
23716 + if (frequency == 0) {
23717 + frequency = CLOCK_TICK_RATE;
23719 + frequency /= CONFIG_HZ;
23721 + printk(KERN_NOTICE "timer will interrupt every: %d cycles\n", frequency);
23722 + timer_set(timervector, frequency);
23725 +++ b/arch/ubicom32/kernel/topology.c
23728 + * arch/ubicom32/kernel/topology.c
23729 + * Ubicom32 architecture sysfs topology information.
23731 + * (C) Copyright 2009, Ubicom, Inc.
23733 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23749 + * Ubicom32 implementation derived from (with many thanks):
23755 +#include <linux/init.h>
23756 +#include <linux/smp.h>
23757 +#include <linux/cpu.h>
23758 +#include <linux/cache.h>
23760 +static struct cpu cpu_devices[NR_CPUS] __read_mostly;
23762 +static int __init topology_init(void)
23766 + for_each_present_cpu(num) {
23767 + cpu_devices[num].hotpluggable = 0;
23768 + register_cpu(&cpu_devices[num], num);
23773 +subsys_initcall(topology_init);
23775 +++ b/arch/ubicom32/kernel/traps.c
23778 + * arch/ubicom32/kernel/traps.c
23779 + * Ubicom32 architecture trap handling support.
23781 + * (C) Copyright 2009, Ubicom, Inc.
23783 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
23799 + * Ubicom32 implementation derived from (with many thanks):
23806 + * Sets up all exception vectors
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>
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>
23838 +#define TRAP_MAX_STACK_DEPTH 20
23841 + * These symbols are filled in by the linker.
23843 +extern unsigned long _stext;
23844 +extern unsigned long _etext;
23846 +extern unsigned long __ocm_text_run_begin;
23847 +extern unsigned long __data_begin;
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",
23866 + * The device tree trap node definition.
23869 + struct devtree_node dn;
23870 + unsigned int intthread;
23873 +static struct trapnode *tn;;
23876 + * trap_interrupt_handler()
23877 + * Software Interrupt to ensure that a trap is serviced.
23879 +static irqreturn_t trap_interrupt_handler(int irq, void *dummy)
23882 + return IRQ_HANDLED;
23886 + * Data used by setup_irq for the timer.
23888 +static struct irqaction trap_irq = {
23890 + .flags = IRQF_DISABLED,
23891 + .handler = trap_interrupt_handler,
23895 + * trap_cause_to_str()
23896 + * Convert a trap_cause into a series of printk
23898 +static void trap_cause_to_str(long status)
23902 + if ((status & ((1 << TRAP_CAUSE_TOTAL) - 1)) == 0) {
23903 + printk(KERN_NOTICE "decode: UNKNOWN CAUSES\n");
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]);
23916 + * trap_print_information()
23917 + * Print the cause of the trap and additional info.
23919 +static void trap_print_information(const char *str, struct pt_regs *regs)
23921 + printk(KERN_WARNING "\n");
23924 + printk(KERN_WARNING "Process %s (pid: %d)\n",
23925 + current->comm, current->pid);
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);
23941 + printk(KERN_WARNING "%s: Causes: 0x%08x\n", str,
23942 + (unsigned int)regs->trap_cause);
23943 + trap_cause_to_str(regs->trap_cause);
23945 + show_stack(NULL, (unsigned long *)regs->an[7]);
23946 + printk(KERN_NOTICE "--- End Trap --- \n");
23951 + * Dump the stack of the current task.
23953 +void dump_stack(void)
23955 + show_stack(NULL, NULL);
23957 +EXPORT_SYMBOL(dump_stack);
23961 + * Print out information from the current stack.
23963 +void show_stack(struct task_struct *task, unsigned long *sp)
23966 + * Allocate just enough entries on the stack.
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;
23978 + * Which task are we talking about.
23985 + * Find the stack for the task if one was not specified. Otherwise
23986 + * use the specified stack.
23989 + if (task != current) {
23990 + stack = task->thread.sp;
23991 + stack_end = (unsigned long)task->stack + THREAD_SIZE - 8;
23994 + "move.4 %0, SP \n\t"
24000 + printk(KERN_NOTICE "Starting backtrace: PID %d '%s'\n",
24001 + task->pid, task->comm);
24004 + * We do 2 passes the first pass is Kernel stack is the second
24007 + while (kernel_stack) {
24008 + unsigned long *handle;
24009 + unsigned int i, idx = 0;
24010 + struct pt_regs *pt = task_pt_regs(task);
24013 + * If the task is in user mode, reset the start
24014 + * and end values for text.
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;
24022 + printk(KERN_NOTICE " User Stack (fdpic):\n");
24025 + stack_end = task->mm->start_stack;
24026 + ocm_code_end = ocm_code_start = 0;
24027 + kernel_stack = 0;
24029 + printk(KERN_NOTICE " Kernel Stack:\n");
24033 + * Collect the stack back trace information.
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);
24040 + printk("\n stack[0x%lx-0x%lx]\n", stack, stack_end);
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) {
24055 + * Now print out the data.
24057 + printk(KERN_NOTICE " CALL && CALLI on stack:");
24058 + for (i = 0; i < idx; i++) {
24059 + printk("%s0x%x, ", (i & 0x3) == 0 ? "\n " : "",
24062 + printk(idx == TRAP_MAX_STACK_DEPTH ? "...\n" : "\n");
24065 + * If we are doing user stack we are done
24067 + if (!kernel_stack) {
24072 + * Does this kernel stack have a mm (i.e. is it user)
24075 + printk("No mm for userspace stack.\n");
24079 + * Get the user-mode stack (if any)
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)) {
24091 + * die_if_kernel()
24092 + * Determine if we are in kernel mode and if so print stuff out and die.
24094 +void die_if_kernel(char *str, struct pt_regs *regs, long trap_cause)
24096 + unsigned int s3value;
24098 + if (user_mode(regs)) {
24102 + console_verbose();
24103 + trap_print_information(str, regs);
24106 + * If the debugger is attached via the hardware mailbox protocol,
24107 + * go into an infinite loop and the debugger will figure things out.
24110 + "move.4 %0, scratchpad3"
24114 + asm volatile("1: jmpt.t 1b");
24118 + * Set the debug taint value.
24120 + add_taint(TAINT_DIE);
24121 + do_exit(SIGSEGV);
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.
24132 + * This function is directly called by the LDSR.
24134 +void trap_handler(int irq, struct pt_regs *regs)
24136 + int sig = SIGSEGV;
24138 + unsigned int trap_cause = regs->trap_cause;
24140 + BUG_ON(!irqs_disabled());
24143 + * test if in kernel and die.
24145 + die_if_kernel("Kernel Trap", regs, trap_cause);
24148 + * User process problem, setup a signal for this process
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))) {
24154 + info.si_code = SEGV_MAPERR;
24155 + } else if ((trap_cause & (1 << TRAP_CAUSE_DST_MISALIGNED)) ||
24156 + (trap_cause & (1 << TRAP_CAUSE_SRC1_MISALIGNED))) {
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))) {
24162 + info.si_code = ILL_ILLOPN;
24163 + } else if ((trap_cause & (1 << TRAP_CAUSE_ILLEGAL_INST))) {
24165 + * Check for software break point and if found signal trap
24166 + * not illegal instruction.
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) {
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
24179 + if ((instruction == 0xfabbccdd) ||
24180 + (instruction == 0xaabbccdd)) {
24182 + info.si_code = TRAP_BRKPT;
24183 + goto send_signal;
24187 + info.si_code = ILL_ILLOPC;
24188 + } else if ((trap_cause & (1 << TRAP_CAUSE_I_DECODE_ERR))) {
24190 + info.si_code = ILL_ILLOPC;
24191 + } else if ((trap_cause & (1 << TRAP_CAUSE_DCAPT))) {
24193 + info.si_code = TRAP_TRACE;
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.
24201 + trap_print_information("User Trap", regs);
24205 + force_sig_info(sig, &info, current);
24208 + * Interrupts are disabled, re-enable them now.
24210 + if (!irqs_disabled()) {
24211 + printk(KERN_EMERG "interrupts enabled on exit, irq=%d, regs=%p",
24218 + * trap_init_interrupt()
24219 + * We need a 2nd trap handling init that will occur after init_IRQ().
24221 +void __init trap_init_interrupt(void)
24224 + unsigned char tirq;
24225 + struct devtree_node *dn = (struct devtree_node *)tn;
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.
24232 + printk(KERN_WARNING "trap_init_interrupt skipped.\n");
24236 + err = devtree_irq(dn, NULL, &tirq);
24238 + printk(KERN_WARNING "error obtaining trap irq value: %d\n",
24243 + if (tirq == DEVTREE_IRQ_NONE) {
24244 + printk(KERN_WARNING "trap irq not available: %d\n", tirq);
24248 + err = setup_irq(tirq, &trap_irq);
24250 + printk(KERN_WARNING "trap irq setup failed: %d\n", err);
24255 + * Let ultra know which thread is handling the traps and
24256 + * what the interrupt to use is.
24258 + tn->intthread = ldsr_get_threadid();
24261 + * Tell the LDSR about our IRQ so that it will unsuspend
24262 + * if one occurs while waiting for the per thread lock.
24264 + ldsr_set_trap_irq(tirq);
24269 + * init trap handling
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.
24275 +void __init trap_init(void)
24278 + * If we do not have a trap node in the device tree, we leave the fault
24279 + * handling to the underlying hardware.
24281 + tn = (struct trapnode *)devtree_find_node("traps");
24283 + printk(KERN_WARNING "traps are not handled by linux\n");
24288 +++ b/arch/ubicom32/kernel/uaccess.c
24291 + * arch/ubicom32/include/asm/uaccess.c
24292 + * User space memory access functions for Ubicom32 architecture.
24294 + * (C) Copyright 2009, Ubicom, Inc.
24296 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
24312 + * Ubicom32 implementation derived from (with many thanks):
24318 +#include <linux/sched.h>
24319 +#include <linux/mm.h>
24320 +#include <linux/string.h>
24321 +#include <linux/module.h>
24323 +#include <asm/segment.h>
24324 +#include <asm/uaccess.h>
24326 +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
24330 + * Check that the address is in the current processes.
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.
24336 +int __access_ok(unsigned long addr, unsigned long size)
24338 + // struct vm_area_struct *vma;
24341 + * Don't do anything if we are not a running system yet.
24343 + if (system_state != SYSTEM_RUNNING) {
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.
24353 + if ((!current) || (!current->mm)) {
24358 + * We perform some basic checks on the address to ensure that it
24359 + * is at least within the range of DRAM.
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);
24370 + * For nommu Linux we can check this by looking at the allowed
24371 + * memory map for the process.
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.
24377 + if (!down_read_trylock(¤t->mm->mmap_sem)) {
24380 + vma = find_vma(current->mm, addr);
24382 + up_read(¤t->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);
24387 + if ((addr + size) > vma->vm_end) {
24388 + up_read(¤t->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);
24393 + up_read(¤t->mm->mmap_sem);
24398 +EXPORT_SYMBOL(__access_ok);
24400 +++ b/arch/ubicom32/kernel/ubicom32_context_switch.S
24403 + * arch/ubicom32/kernel/ubicom32_context_switch.S
24404 + * Implements context switch and return functions.
24406 + * (C) Copyright 2009, Ubicom, Inc.
24408 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
24424 + * Ubicom32 implementation derived from (with many thanks):
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>
24437 + * restore_context()
24438 + * Restore the full context from sp (struct pt_reg *)
24440 + * Note: Recovered PC and CSR are saved on the stack and are to be popped off
24441 + * before returning.
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)
24482 + * ldsr_thread_enable_interrupts()
24483 + * An assembly version of the enable interrupts function.
24485 + * The stack is fair game but all registers MUST be preserved.
24488 +.macro ldsr_thread_enable_interrupts
24489 + move.4 -4(sp)++, d3 ; Push d3
24490 + move.4 -4(sp)++, a3 ; Push a3
24493 + * Read the ROSR and obtain ~(1 << tid)
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)
24500 + * Get the value of the ldsr_soft_irq_mask
24502 + moveai a3, #%hi(ldsr_soft_irq_mask)
24503 + move.4 a3, %lo(ldsr_soft_irq_mask)(a3)
24506 + * Now re-enable interrupts for this thread and then
24507 + * wakeup the LDSR.
24509 + and.4 scratchpad1, scratchpad1, d3
24510 + move.4 int_set0, a3
24513 + * Restore the registers.
24515 + move.4 a3, (sp)4++
24516 + move.4 d3, (sp)4++
24520 + * ret_from_interrupt_to_kernel()
24521 + * RFI function that is where do_IRQ() returns to if the thread was in kernel space.
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
24534 + * ret_from_interrupt_to_user()
24535 + * RFI function that is where do_IRQ() returns to if the thread was in user space.
24537 + * TODO: Do we really need the ciritical section handling in this code?
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
24548 + * Test if the scheduler needs to be called.
24550 + btst TI_FLAGS(a3), #ASM_TIF_NEED_RESCHED
24552 + moveai a5, #%hi(schedule)
24553 + calli a5, %lo(schedule)(a5) ; Call the scheduler. I will come back here.
24556 + * See if we have pending signals and call do_signal
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?
24568 + * Now call do_signal()
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()
24577 + * Back from do_signal(), re-enter critical section.
24579 + atomic_lock_acquire ; Enter critical section
24581 +1: move.4 a1, (sp)4++ ; pop A1 off the stack
24583 + disable_kernel_ranges_for_current d15 ; disable kernel ranges
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
24591 + * restore_all_registers()
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.
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
24607 + * ret_from_fork()
24608 + * Called on the child's return from fork system call.
24610 + .section .ret_from_fork.text
24611 + .global 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)
24618 + atomic_lock_acquire ; Enter critical section
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.
24637 + disable_kernel_ranges_for_current d15
24638 + atomic_lock_release ; Leave critical section
24639 + calli a4, 0(a4) ; Return.
24645 + * void *__switch_to(struct task_struct *prev, struct thread_struct *prev_switch,
24646 + * struct thread_struct *next_switch)
24648 + .global __switch_to
24652 + * Set up register a3 to point to save area.
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
24666 + * Set up register a3 to point to restore area.
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++
24680 + * Load the sw_ksp with the proper thread_info pointer.
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..
24691 + * We are done with context switch. Time to return..
24697 + * ubicom32_emulate_insn()
24698 + * Emulates the instruction.
24701 + * unsigned int ubicom32_emulate_insn(int source1, int source2, int source3, int *save_acc, int *save_csr);
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)
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
24728 +++ b/arch/ubicom32/kernel/ubicom32_ksyms.c
24731 + * arch/ubicom32/kernel/ubicom32_ksyms.c
24732 + * Ubicom32 architecture compiler support and misc symbols.
24734 + * (C) Copyright 2009, Ubicom, Inc.
24736 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
24752 + * Ubicom32 implementation derived from (with many thanks):
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>
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>
24776 +/* platform dependent support */
24778 +EXPORT_SYMBOL(__ioremap);
24779 +EXPORT_SYMBOL(iounmap);
24781 +EXPORT_SYMBOL(ip_fast_csum);
24784 +/* Networking helper routines. */
24785 +EXPORT_SYMBOL(csum_partial_copy_nocheck);
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);
24794 +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4
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).
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);
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);
24819 +extern void __libgcc_udivmodsi(void);
24820 +extern void __libgcc_divmodsi(void);
24822 +EXPORT_SYMBOL(__libgcc_udivmodsi);
24823 +EXPORT_SYMBOL(__libgcc_divmodsi);
24826 +++ b/arch/ubicom32/kernel/ubicom32_syscall.S
24829 + * arch/ubicom32/kernel/ubicom32_syscall.S
24830 + * <TODO: Replace with short file description>
24832 + * (C) Copyright 2009, Ubicom, Inc.
24834 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
24850 + * Ubicom32 implementation derived from (with many thanks):
24855 +#include <linux/sys.h>
24856 +#include <linux/linkage.h>
24857 +#include <linux/unistd.h>
24859 +#include <asm/ubicom32-common.h>
24860 +#include <asm/thread_info.h>
24861 +#include <asm/asm-offsets.h>
24862 +#include <asm/range-protect.h>
24867 + .section .syscall_entry.text
24868 + .global system_call
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.
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.
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.
24883 + * For the user case the kernel stack will have the following layout.
24885 + * a3 ksp[0] +-----------------------+
24886 + * | Thread info area |
24887 + * | struct thread_info |
24888 + * +-----------------------+
24890 + * | Kernel Stack Area |
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] +-----------------------+
24900 + * For kernel syscalls the layout is as follows.
24902 + * a3 ksp[0] +-----------------------+
24903 + * | Thread info area |
24904 + * | struct thread_info |
24905 + * +-----------------------+
24907 + * | Kernel Stack Area |
24909 + * a4 / sp >>> +-----------------------+
24910 + * | Context save area |
24911 + * | struct pt_reg |
24912 + * sp at syscall entry +-----------------------+
24913 + * | Callers Kernel Stack |
24916 + * Once the context is saved we optionally call syscall_trace and setup
24917 + * the exit routine and jump to the syscall.
24921 + * load the base address for sw_ksp into a3
24922 + * Note.. we cannot access it just yet as protection is still on.
24924 + moveai a3, #%hi(sw_ksp)
24925 + lea.1 a3, %lo(sw_ksp)(a3)
24928 + * Enter critical section .
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.
24935 + atomic_lock_acquire
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
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.
24947 + move.4 a3, (a3, d15) ; a3 = sw_ksp[d15]
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.
24953 + movei d9, #(~(ASM_THREAD_SIZE-1)) ; load mask
24954 + and.4 d9, sp, d9 ; apply mask
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
24964 + * if d9 and a3 are not equal. We are usespace and have to shift to
24970 + * Kernel Syscall.
24972 + * The kernel has called this routine. We have to pdec space for pt_regs
24975 + pdec a4, PT_SIZE(sp) ; a4 = ksp - PT_SIZE
24979 + * Userspace Syscall.
24981 + * Add THREAD_SIZE and subtract PT_SIZE to create the proper ksp
24983 +1: movei d15, #(ASM_THREAD_SIZE - 8 - PT_SIZE)
24984 + lea.1 a4, (a3, d15) ; a4 = ksp + d15
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
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.
24995 + * We are now officially back in the kernel!
24999 + * Now that we are on the ksp we can leave the critical section
25001 + atomic_lock_release
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.
25008 + move.4 PT_A0(sp), a0 ; Save A0 on kernel stack
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)
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
25026 + * Now save the syscall parameters
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
25039 + * Test if syscalls are being traced and if they are jump to syscall
25040 + * trace (it will comeback here)
25042 + btst TI_FLAGS(a3), #ASM_TIF_SYSCALL_TRACE
25043 + jmpne.f .Lsystem_call__trace
25044 +.Lsystem_call__trace_complete:
25046 + * Check for a valid call number [ 0 <= syscall_number < NR_syscalls ]
25050 + cmpi d8, #NR_syscalls
25054 + * They have passed an invalid number. Call sys_ni_syscall staring by
25055 + * load a4 with the base address of sys_ni_syscall
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
25062 + * Validated syscall, load the syscall table base address into a3 and
25063 + * read the syscall ptr out.
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]
25070 + * Before calling the syscall, setup a5 so that syscall_exit is called
25071 + * on return from syscall
25073 +5: moveai a5, #%hi(syscall_exit) ; Setup return address
25074 + lea.1 a5, %lo(syscall_exit)(a5) ; from system call
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
25081 + cmpi d8, #__NR_rt_sigreturn
25085 + * Launch system call (it will return through a5 - syscall_exit)
25090 + * System call is rt_sigreturn. Test d1. If it is 1 we have to
25091 + * change the return address to restore_all_registers
25096 + moveai a5, #%hi(restore_all_registers) ; Setup return address
25097 + lea.1 a5, %lo(restore_all_registers)(a5) ; to restore_all_registers.
25100 + * Launch system call (it will return through a5)
25102 +7: calli a3, 0(a4) ; Launch system call
25104 +.Lsystem_call__trace:
25106 + * Syscalls are being traced.
25107 + * Call syscall_trace, (return here)
25109 + moveai a4, #%hi(syscall_trace)
25110 + calli a5, %lo(syscall_trace)(a4)
25113 + * Restore syscall state (it would have been discarded during the
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
25126 + * return to syscall
25128 + jmpt.t .Lsystem_call__trace_complete
25129 + .size system_call, . - system_call
25134 + .section .syscall_exit.text
25135 + .global syscall_exit
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.
25147 + * Save d0 to pt_regs
25149 + move.4 PT_D0(sp), d0 ; Save d0 into the kernel stack
25152 + * load the thread_info structure by masking off the THREAD_SIZE
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.
25158 + movei d9, #(~(ASM_THREAD_SIZE-1))
25162 + * Are any interesting bits set on TI flags, if there are jump
25163 + * aside to post_processing.
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:
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
25188 + * this is only for debug, and could be removed for production builds
25190 + move.4 PT_FRAME_TYPE(sp), #0 ; invalidate frame_type
25192 +#ifdef CONFIG_PROTECT_KERNEL
25194 + * Enter critical section
25196 + atomic_lock_acquire
25197 + disable_kernel_ranges_for_current d15
25200 + * Lastly restore userspace stack ptr
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.
25206 + move.4 a7, PT_A7(sp) ; Restore A7 from kernel stack
25209 + * We are now officially back in userspace!
25212 +#ifdef CONFIG_PROTECT_KERNEL
25214 + * Leave critical section and return to user space.
25216 + atomic_lock_release
25218 + calli a5, 0(a5) ; Back to userspace code.
25220 + bkpt #-1 ; we will never get here
25223 + * Post syscall processing. (unlikely part of syscall_exit)
25225 + * Are we tracing syscalls. If TIF_SYSCALL_TRACE is set, call
25226 + * syscall_trace routine and return here.
25228 +.Lsyscall_exit__post_processing:
25229 + btst TI_FLAGS(a1), #ASM_TIF_SYSCALL_TRACE
25231 + moveai a5, #%hi(syscall_trace)
25232 + calli a5, %lo(syscall_trace)(a5)
25235 + * Do we need to resched ie call schedule. If TIF_NEED_RESCHED is set,
25236 + * call the scheduler, it will come back here.
25238 +1: btst TI_FLAGS(a1), #ASM_TIF_NEED_RESCHED
25240 + moveai a5, #%hi(schedule)
25241 + calli a5, %lo(schedule)(a5)
25244 + * Do we need to post a signal, if TIF_SIGPENDING is set call the
25247 +2: btst TI_FLAGS(a1), #ASM_TIF_SIGPENDING
25248 + jmpeq.t .Lsyscall_exit__post_processing_complete
25251 + * setup the do signal call
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)
25258 + jmpt.t .Lsyscall_exit__post_processing_complete
25260 + .size syscall_exit, . - syscall_exit
25263 + * kernel_execve()
25264 + * kernel_execv is called when we the kernel is starting a
25265 + * userspace application.
25267 + .section .kernel_unprotected
25268 + .global kernel_execve
25270 + move.4 -4(sp)++, a5 ; Save return address
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++
25280 + * protection was enabled again at syscall exit, but we want
25281 + * to return to kernel so we enable it again.
25283 +#ifdef CONFIG_PROTECT_KERNEL
25285 + * We are entering the kernel so we need to disable the protection.
25286 + * Enter critical section, disable ranges and leave critical section.
25288 + atomic_lock_acquire ; Enter critical section
25289 + enable_kernel_ranges_for_current d15
25290 + atomic_lock_release ; Leave critical section
25292 + ret a5 ; jump back to the kernel
25294 + .size kernel_execve, . - kernel_execve
25297 + * signal_trampoline()
25299 + * Deals with transitioning from to userspace signal handlers and returning
25300 + * to userspace, only called from the kernel.
25303 + .section .kernel_unprotected
25304 + .global signal_trampoline
25305 +signal_trampoline:
25307 + * signal_trampoline is called when we are jumping from the kernel to
25308 + * the userspace signal handler.
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
25319 +#ifdef CONFIG_PROTECT_KERNEL
25321 + * We are leaving the kernel so we need to enable the protection.
25322 + * Enter critical section, disable ranges and leave critical section.
25324 + atomic_lock_acquire ; Enter critical section
25325 + disable_kernel_ranges_for_current d15 ; disable kernel ranges
25326 + atomic_lock_release ; Leave critical section
25329 + * The signal handler pointer is in register d3 so tranfer it to a4 and
25332 + movea a4, d3 ; signal handler
25336 + * Return to userspace through rt_syscall which is stored on top of the
25337 + * stack d1 contains ret_via_interrupt status.
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)
25344 + bkpt -1 ; will never get here.
25345 + .size signal_trampoline, . - signal_trampoline
25348 + * kernel_thread_helper()
25350 + * Entry point for kernel threads (only referenced by kernel_thread()).
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.
25357 + * On return from fork the child thread d0 will be 0. We call this dummy
25358 + * function which in turn loads the argument
25360 + .section .kernel_unprotected
25361 + .global kernel_thread_helper
25362 +kernel_thread_helper:
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.
25369 +#ifdef CONFIG_PROTECT_KERNEL
25371 + * We are entering the kernel so we need to disable the protection.
25372 + * Enter critical section, disable ranges and leave critical section.
25374 + atomic_lock_acquire ; Enter critical section
25375 + enable_kernel_ranges_for_current d0
25376 + atomic_lock_release ; Leave critical section
25379 + * Move argument for kernel function into d0, and set a5 return address
25380 + * (a5) to do_exit and return through a2
25382 + move.4 d0, d1 ; d0 = arg
25383 + move.4 a5, d3 ; a5 = do_exit
25384 + ret d2 ; call function ptr in d2
25386 + .size kernel_thread_helper, . - kernel_thread_helper
25389 + * execve_intercept()
25392 + .global execve_intercept
25394 + move.4 d3, sp ; Save retrun address
25395 + moveai a3, #%hi(sys_execve)
25396 + calli a3, %lo(sys_execve)(a3)
25398 + .size execve_intercept, . - execve_intercept
25401 + * vfork_intercept()
25404 + .global vfork_intercept
25406 + move.4 d0, sp ; Save pt_regs address
25407 + moveai a3, #%hi(sys_vfork)
25408 + calli a3, %lo(sys_vfork)(a3)
25410 + .size vfork_intercept, . - vfork_intercept
25413 + * clone_intercept()
25416 + .global clone_intercept
25418 + move.4 d2, sp ; Save pt_regs address
25419 + moveai a3, #%hi(sys_clone)
25420 + calli a3, %lo(sys_clone)(a3)
25422 + .size clone_intercept, . - clone_intercept
25425 + * sys_sigsuspend()
25428 + .global 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)
25434 + .size sys_sigsuspend, . - sys_sigsuspend
25437 + * sys_rt_sigsuspend()
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)
25446 + .size sys_rt_sigsuspend, . - sys_rt_sigsuspend
25449 + * sys_rt_sigreturn()
25452 + .global 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)
25458 + .size sys_rt_sigreturn, . - sys_rt_sigreturn
25461 + * sys_sigaltstack()
25464 + .global 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)
25470 + .size sys_sigaltstack, . - sys_sigaltstack
25472 +++ b/arch/ubicom32/kernel/unaligned_trap.c
25475 + * arch/ubicom32/kernel/unaligned_trap.c
25476 + * Handle unaligned traps in both user or kernel space.
25478 + * (C) Copyright 2009, Ubicom, Inc.
25480 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
25496 + * Ubicom32 implementation derived from (with many thanks):
25502 +#include <linux/types.h>
25503 +#include <linux/kernel.h>
25504 +#include <asm/cacheflush.h>
25505 +#include <asm/traps.h>
25510 +/* no possible trap */
25512 +/* possible source operand trap */
25515 +/* possible destination operand trap */
25518 +/* can be either source or destination or both */
25520 +#define TWO_OP_2 6
25522 +/* TODO: What is the real value here, put something in to make it compile for
25524 +#define MOVE_2 0x0d
25525 +#define LSL_2 0x11
25526 +#define LSR_2 0x13
25527 +#define MOVEI 0x19
25530 +static int op_format[32] =
25532 + TWO_OP, /* 0x00 */
25536 + TWO_OP, /* 0x04 */
25540 + TWO_OP_2, /* 0x08 */
25544 + TWO_OP_2, /* 0x0C */
25548 + TWO_OP, /* 0x10 */
25552 + UNUSED, /* 0x14 */
25556 + SRC_2, /* 0x18 */
25560 + UNUSED, /* 0x1C */
25562 + UNUSED, /* unaligned CALLI will not be fixed. */
25566 +static int op_0_format[32] =
25568 + UNUSED, /* 0x00 */
25572 + UNUSED, /* 0x04 - ret don't fix - bad ret is always wrong */
25576 + UNUSED, /* 0x08 */
25580 + TWO_OP, /* 0x0c */
25583 + UNUSED, /* .1 can't trap */
25584 + UNUSED, /* 0x10 */
25588 + UNUSED, /* 0x14 */
25592 + UNUSED, /* 0x18 */
25599 + DEST, /* all lea have 32-bit destination */
25602 +static int op_2_format[32] =
25604 + UNUSED, /* 0x00 */
25608 + UNUSED, /* 0x04 */
25612 + UNUSED, /* 0x08 crcgen is .1 */
25616 + UNUSED, /* 0x0c */
25628 + UNUSED, /* 0x18 */
25638 +static int op_6_format[32] =
25640 + SRC_2, /* 0x00 */
25644 + SRC_2, /* 0x04 */
25648 + SRC, /* 0x08 MULS.4 */
25652 + UNUSED, /* 0x0c */
25660 + UNUSED, /* 0x14 */
25664 + UNUSED, /* 0x18 */
25668 + UNUSED, /* 0x1c */
25675 + * unaligned_get_address()
25676 + * get an address using save_an and save_dn registers, and updates save_an
25677 + * with side effects
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)
25683 + unsigned char *address;
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)) {
25694 + if (specifier & 0x10) {
25695 + address = (unsigned char *)(save_an[areg] + offset);
25697 + address = (unsigned char *)save_an[areg];
25699 + save_an[areg] = save_an[areg] + offset;
25702 + * Let caller know An registers have been modified.
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));
25711 + address = (unsigned char *)(save_an[areg] +
25712 + (save_dn[dreg] << 1));
25715 + int offset = ((specifier >> 3) & 0x60) | (specifier & 0x1f);
25716 + if (likely(four_byte)) {
25717 + address = (unsigned char *)(save_an[areg] +
25720 + address = (unsigned char *)(save_an[areg] +
25728 +static int save_dn[16];
25729 +static int save_an[8];
25730 +static int save_acc[5];
25733 + * unaligned_emulate()
25734 + * emulate the instruction at thread's pc that has taken an unaligned data
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
25741 + * TODO: Protection is handled outside of this function
25742 + * TODO: handling simultaneous unaligned and memory protection traps
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)
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
25753 + * (2 bytes, with or without sign extension, or 4 bytes)
25754 + * modify emulate_inst to use d0 as source
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
25769 + * restore thread's implicit results (modified address registers, CSR,
25770 + * accumulators) add 4 to thread's pc
25772 +void unaligned_emulate(unsigned int thread)
25775 + unsigned int inst;
25777 + unsigned int subop;
25779 + unsigned int emulate_inst;
25781 + int src_operand, dest_operand;
25784 + unsigned int source1;
25785 + unsigned int source_data;
25786 + unsigned char *dest_address = NULL;
25788 + unsigned int result;
25789 + unsigned int write_back_an = 0;
25790 + unsigned int chip_id_copy;
25792 + extern unsigned int trap_emulate;
25793 + extern unsigned int ubicom32_emulate_insn(int source1, int source2,
25794 + int source3, int *save_acc,
25798 + * get the chip_id
25801 + " move.4 %0, chip_id \n\t" /* get chip_id. */
25802 + : "=r"(chip_id_copy)
25810 + " move.4 CSR, %1 \n\t" /* set source thread in
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"
25817 + : "d" ((1 << 8) | (thread << 9))
25821 + inst = *((unsigned int *)pc);
25823 + if (unlikely(op == 2 || op == 6)) {
25824 + subop = (inst >> 21) & 0x1f;
25826 + subop = (inst >> 11) & 0x1f;
25828 + format = op_format[op];
25829 + emulate_inst = inst;
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];
25839 + if (unlikely(format == UNUSED)) {
25841 + * We are not going to emulate this. Bump PC by 4 and move on.
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"
25850 + : "d"((1 << 14) | (thread << 15)), "d"(pc + 4)
25856 + four_byte = (format == TWO_OP || format == DEST || format == SRC);
25859 + * source or destination memory operand needs emulation
25861 + src_operand = (format == SRC ||
25862 + format == SRC_2 ||
25863 + format == TWO_OP ||
25864 + format == TWO_OP_2) &&
25865 + ((inst >> 8) & 7) > 1;
25867 + dest_operand = (format == DEST ||
25868 + format == DEST_2 ||
25869 + format == TWO_OP ||
25870 + format == TWO_OP_2) &&
25871 + ((inst >> 24) & 7) > 1;
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
25879 + " move.4 CSR, %2 \n\t" /* set source thread in
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)
25923 + * turn off thread select bits if they were on
25925 + BUG_ON((save_csr & 0x04100) != 0);
25926 + if (unlikely(save_csr & 0x04100)) {
25928 + * Things are in funny state as thread select bits are on in
25931 + panic("In unaligned trap handler. Trap thread CSR has thread "
25932 + "select bits on.\n");
25935 + save_csr = save_csr & 0x1000ff;
25938 + * get the source1 operand
25941 + if (src_operand) {
25942 + unsigned char *src_address;
25945 + * source1 comes from memory
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);
25954 + * get data (possibly unaligned)
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;
25963 + source1 = *src_address << 8 |
25964 + *(src_address + 1);
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
25972 + if ((!(op == 2 && subop == MOVE_2)) &&
25973 + (!((chip_id_copy >= 0x30000) &&
25974 + (subop == LSL_2 || subop == LSR_2)))) {
25976 + * Have to sign extend the .2 entry.
25978 + source1 = ((unsigned int)
25980 + ((signed short) source1)));
25983 + } else if (likely(op != MOVEI)) {
25985 + * source1 comes from a register, using move.4 d0, src1
25986 + * unaligned_emulate_get_source is pointer to code to insert remulated instruction
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);
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"
26003 + : "d" ((1 << 8) | (thread << 9))
26009 + * get the destination address
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);
26020 + if (write_back_an) {
26022 + * restore any modified An registers
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"
26038 + : "d" ((1 << 14) | (thread << 15)), "a" (save_an)
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
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];
26053 + * force the emulated instruction to use d1 for source2 operand
26055 + emulate_inst = (emulate_inst & 0xffff07ff) | 0x800;
26058 + if (likely(op != MOVEI)) {
26060 + * change emulated instruction source1 to d0
26062 + emulate_inst &= ~0x7ff;
26063 + emulate_inst |= 1 << 8;
26066 + if (unlikely(op == 6 || op == 2)) {
26068 + * Set destination to d0
26070 + emulate_inst &= ~(0xf << 16);
26071 + } else if (likely(op != CMPI)) {
26073 + * Set general destination field to d0.
26075 + emulate_inst &= ~(0x7ff << 16);
26076 + emulate_inst |= 1 << 24;
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
26084 + *((unsigned int *)&trap_emulate) = emulate_inst;
26085 + flush_dcache_range((unsigned long)(&trap_emulate),
26086 + (unsigned long)(&trap_emulate) + 4);
26088 + result = ubicom32_emulate_insn(source1, source2, source3,
26089 + save_acc, &save_csr);
26092 + * set the result value
26094 + if (dest_operand) {
26096 + * copy result to memory
26099 + *dest_address++ =
26100 + (unsigned char)((result >> 24) & 0xff);
26101 + *dest_address++ =
26102 + (unsigned char)((result >> 16) & 0xff);
26104 + *dest_address++ = (unsigned char)((result >> 8) & 0xff);
26105 + *dest_address = (unsigned char)(result & 0xff);
26106 + } else if (likely(op != CMPI)) {
26108 + * copy result to a register, using move.4 dest, result
26110 + extern unsigned int unaligned_trap_set_result;
26111 + *((unsigned int *)&unaligned_trap_set_result) &= ~0x7ff0000;
26113 + if (op == 2 || op == 6) {
26114 + *((unsigned int *)&unaligned_trap_set_result) |=
26115 + ((inst & 0x000f0000) | 0x01000000);
26117 + *((unsigned int *)&unaligned_trap_set_result) |=
26118 + (inst & 0x7ff0000);
26120 + flush_dcache_range((unsigned long)&unaligned_trap_set_result,
26121 + ((unsigned long)(&unaligned_trap_set_result) + 4));
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"
26132 + : "d"(result), "d" ((1 << 14) | (thread << 15))
26138 + * bump PC in thread and restore implicit register changes
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"
26153 + : "d"((1 << 14) | (thread << 15)),
26154 + "d"(pc + 4), "d"(save_csr), "a"(save_acc)
26160 + * unaligned_only()
26161 + * Return true if either of the unaligned causes are set (and no others).
26163 +int unaligned_only(unsigned int cause)
26165 + unsigned int unaligned_cause_mask =
26166 + (1 << TRAP_CAUSE_DST_MISALIGNED) |
26167 + (1 << TRAP_CAUSE_SRC1_MISALIGNED);
26169 + BUG_ON(cause == 0);
26170 + return (cause & unaligned_cause_mask) == cause;
26173 +++ b/arch/ubicom32/kernel/vmlinux.lds.S
26176 + * arch/ubicom32/kernel/vmlinux.lds.S
26177 + * vmlinux primary linker script
26179 + * (C) Copyright 2009, Ubicom, Inc.
26181 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26197 + * Ubicom32 implementation derived from (with many thanks):
26202 +#include <asm-generic/vmlinux.lds.h>
26203 +#include <asm/ocm_size.h>
26204 +#include <asm/thread_info.h>
26205 +#include <linux/threads.h>
26208 + * Sanity checks to prevent errors later on that are much harder to understand
26210 +#if !defined APP_OCM_CODE_SIZE
26211 +#error APP_OCM_CODE_SIZE has not been defined in ocm_size.h
26214 +#if !defined APP_OCM_DATA_SIZE
26215 +#error APP_OCM_DATA_SIZE has not been defined in ocm_size.h
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.
26225 +#define OCM_SECTOR_SIZE 0x00008000 /* 32K */
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 */
26232 +#error "Unknown IP5K silicon"
26235 +#define OCMSTART 0x3ffc0000 /* alias from 0x03000000 for easy jump to/from SDRAM */
26236 +#define OCMEND (OCMSTART + OCMSIZE)
26239 + * The `free' ocm area that ultra does not use.
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)
26245 +#define OCM_FREE_START OCMEND
26246 +#define OCM_FREE_LENGTH 0
26249 + * If you want to limit OCM use for text/data or completely disable it you can change these values.
26251 +#define OCM_TEXT_LENGTH OCM_FREE_LENGTH
26252 +#define OCM_DATA_LENGTH OCM_FREE_LENGTH
26254 +#define RAM_START CONFIG_KERNELBASE
26255 +#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
26265 +OUTPUT_ARCH(ubicom32)
26269 + ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
26270 + ocm : ORIGIN = OCM_FREE_START, LENGTH = OCM_FREE_LENGTH
26273 +jiffies = jiffies_64 + 4;
26276 + * Fixed locations required by gdb coredumps.
26278 + * Note that the names are what gdb is expecting so renaming will break
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;
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 = .;
26300 + . = _begin + SIZEOF(.fixed_text) ;
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
26308 + *(.spinlock.text)
26309 +#include <asm/ocm_text.lds.inc>
26312 + __ocm_text_run_end = .;
26313 + __data_begin = ALIGN(OCM_SECTOR_SIZE);
26314 + } > ocm /* .ocm_text */
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);
26324 + __ocm_inst_heap_end = .;
26325 + /* update __data_begin */
26326 + __data_begin = ALIGN(OCM_SECTOR_SIZE);
26327 + } > ocm /* .ocm_module_text */
26329 + . = __ocm_text_load_begin + __ocm_text_run_end - __ocm_text_run_begin ;
26330 + __ocm_text_load_end = .;
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;
26342 + __ocm_data_run_end = .;
26344 + . = __ocm_data_load_begin + __ocm_data_run_end - __ocm_data_run_begin ;
26346 + __ocm_data_run_end = __ocm_data_run_begin;
26348 + __ocm_data_load_end = .;
26350 + __ocm_free_begin = __ocm_data_run_end;
26351 + __ocm_free_end = OCM_FREE_START + OCM_FREE_LENGTH;
26353 + .text __ocm_data_load_end : AT(__ocm_data_load_end) {
26361 + *(.text.__libgcc_udivmodsi)
26362 + *(.text.__libgcc_divmodsi)
26363 + *(.text.__libgcc_muldi3)
26364 + *(.text.__libgcc_udivmoddi)
26365 + *(.text.__libgcc_divmoddi)
26367 +#if OCM_TEXT_LENGTH == 0
26370 + *(.spinlock.text)
26372 + . = ALIGN(16); /* Exception table */
26373 + __start___ex_table = .;
26375 + __stop___ex_table = .;
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
26400 + .data DATA_ADDR : {
26404 +#if OCM_DATA_LENGTH == 0
26407 + . = ALIGN(8192) ;
26408 + _data_protection_end = .;
26409 + *(.data.init_task)
26416 + __init_begin = .;
26423 + __setup_start = .;
26426 + __initcall_start = .;
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
26437 + __initramfs_start = .;
26439 + __initramfs_end = .;
26442 + __per_cpu_start = .;
26444 + *(.data.percpu.shared_aligned)
26445 + __per_cpu_end = .;
26453 + PROVIDE (___eh_frame_begin = .);
26456 + PROVIDE (___eh_frame_end = .);
26472 + *(.exitcall.exit)
26479 +++ b/arch/ubicom32/lib/checksum.c
26482 + * arch/ubicom32/lib/checksum.c
26483 + * Optimized checksum utilities for IP.
26485 + * (C) Copyright 2009, Ubicom, Inc.
26487 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26503 + * Ubicom32 implementation derived from (with many thanks):
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.
26513 + * IP/TCP/UDP checksumming routines
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.
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.
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.
26538 +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
26539 + of the assembly has to go. */
26541 +#include <linux/module.h>
26542 +#include <net/checksum.h>
26544 +static unsigned long do_csum(const unsigned char * buff, int len)
26547 + unsigned long result = 0;
26550 + * The following optimized assembly code cannot handle data length less than 7 bytes!
26552 + if (likely(len >= 7)) {
26553 + len -= (4 - (int)buff) & 3;
26554 + count = len >> 2;
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)
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"
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"
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"
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"
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"
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"
26604 +#if defined(IP7000) || defined(IP7000_REV2)
26605 + "300: swapb.2 %1, %1 \n\t"
26607 + "300: shmrg.2 %1, %1, %1 \n\t"
26608 + " lsr.4 %1, %1, #8 \n\t"
26609 + " bfextu %1, %1, #16 \n\t"
26611 + " jmpt.w.t 3f \n\t"
26613 + "1: add.4 %1, (%0)4++, %1 \n\t" // first add without C
26615 + " addc %1, (%0)4++, %1 \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"
26621 + " and.4 %3, #3, %3 \n\t" // check n
26622 + " jmpne.w.f 200b \n\t"
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"
26629 + " btst d14, #3 \n\t" // start from odd address (<< 3)?
26630 + " jmpne.w.f 300b \n\t"
26633 + : "+a"(buff), "+d"(result), "+d"(count), "+d"(len)
26635 + : "d15", "d14", "a3", "cc"
26642 + * handle a few bytes and fold result into 16-bit
26644 + while (len-- > 0) {
26645 + result += (*buff++ << 8);
26647 + result += *buff++;
26653 + " lsr.4 d15, %0, #16 \n\t"
26654 + " bfextu %0, %0, #16 \n\t"
26655 + " add.4 %0, d15, %0 \n\t"
26666 + * This is a version of ip_compute_csum() optimized for IP headers,
26667 + * which always checksum on 4 octet boundaries.
26669 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
26671 + return (__force __sum16)~do_csum(iph,ihl*4);
26675 + * computes the checksum of a memory block at buff, length len,
26676 + * and adds in "sum" (32-bit)
26678 + * returns a 32-bit number suitable for feeding into itself
26679 + * or csum_tcpudp_magic
26681 + * this function must be called with even lengths, except
26682 + * for the last fragment, which may be odd
26684 + * it's best to have buff aligned on a 32-bit boundary
26686 +__wsum csum_partial(const void *buff, int len, __wsum sum)
26688 + unsigned int result = do_csum(buff, len);
26690 + /* add in old sum, and carry.. */
26691 + result += (__force u32)sum;
26692 + if ((__force u32)sum > result)
26694 + return (__force __wsum)result;
26697 +EXPORT_SYMBOL(csum_partial);
26700 + * this routine is used for miscellaneous IP-like checksums, mainly
26703 +__sum16 ip_compute_csum(const void *buff, int len)
26705 + return (__force __sum16)~do_csum(buff,len);
26709 + * copy from fs while checksumming, otherwise like csum_partial
26713 +csum_partial_copy_from_user(const void __user *src, void *dst,
26714 + int len, __wsum sum, int *csum_err)
26716 + if (csum_err) *csum_err = 0;
26717 + memcpy(dst, (__force const void *)src, len);
26718 + return csum_partial(dst, len, sum);
26722 + * copy from ds while checksumming, otherwise like csum_partial
26726 +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
26728 + memcpy(dst, src, len);
26729 + return csum_partial(dst, len, sum);
26732 +++ b/arch/ubicom32/lib/delay.c
26735 + * arch/ubicom32/lib/delay.c
26736 + * Ubicom32 implementation of udelay()
26738 + * (C) Copyright 2009, Ubicom, Inc.
26740 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26756 + * Ubicom32 implementation derived from (with many thanks):
26762 +#include <linux/module.h>
26763 +#include <asm/param.h>
26764 +#include <asm/delay.h>
26765 +#include <asm/ip5000.h>
26768 + * read_current_timer()
26769 + * Return the current value of sysval.
26771 +int __devinit read_current_timer(unsigned long *timer_val)
26773 + *timer_val = (long)(UBICOM32_IO_TIMER->sysval);
26778 +void udelay(unsigned long usecs)
26782 +EXPORT_SYMBOL(udelay);
26784 +++ b/arch/ubicom32/lib/Makefile
26787 +# arch/ubicom32/lib/Makefile
26788 +# <TODO: Replace with short file description>
26790 +# (C) Copyright 2009, Ubicom, Inc.
26792 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26808 +# Ubicom32 implementation derived from (with many thanks):
26814 +# Makefile for m68knommu specific library files..
26817 +lib-y := checksum.o delay.o mem_ubicom32.o muldi3.o lshrdi3.o ashldi3.o ashrdi3.o divmod.o
26819 +++ b/arch/ubicom32/lib/mem_ubicom32.c
26822 + * arch/ubicom32/lib/mem_ubicom32.c
26823 + * String functions.
26825 + * (C) Copyright 2009, Ubicom, Inc.
26827 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
26843 + * Ubicom32 implementation derived from (with many thanks):
26849 +#include <linux/module.h>
26850 +#include <linux/types.h>
26851 +#include <linux/compiler.h>
26853 +#define LIKELY likely
26854 +#define UNLIKELY unlikely
26856 +typedef u32_t addr_t;
26861 +void *memcpy(void *dest, const void *src, size_t n)
26863 + void *dest_ret = dest;
26865 + if (LIKELY((((addr_t)dest ^ (addr_t)src) & 3) == 0) && LIKELY(n > 6)) {
26867 + n -= (4 - (addr_t)dest) & 0x03;
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"
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
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
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"
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"
26897 + "1: .rept 25 \n\t"
26898 + " movea (%0)4++, (%1)4++ \n\t"
26901 + " move.4 (%0)4++, (%1)4++ \n\t"
26903 + " add.4 %2, #-32, %2 \n\t"
26904 + " jmpgt.w.f 1b \n\t"
26906 + " and.4 %3, #3, %3 \n\t" // check n
26907 + " jmpne.w.f 200b \n\t"
26909 + : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26911 + : "d15", "a3", "memory", "cc"
26917 + if (LIKELY((((addr_t)dest ^ (addr_t)src) & 1) == 0) && LIKELY(n > 2)) {
26919 + n -= (addr_t)dest & 0x01;
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"
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
26932 + "100: move.1 (%0)1++, (%1)1++ \n\t"
26933 + " calli a3, 0(a3) \n\t"
26935 + "200: move.1 (%0)1++, (%1)1++ \n\t"
26936 + " jmpt.w.t 2f \n\t"
26938 + "1: .rept 32 \n\t"
26939 + " move.2 (%0)2++, (%1)2++ \n\t"
26941 + " add.4 %2, #-32, %2 \n\t"
26942 + " jmpgt.w.f 1b \n\t"
26944 + " and.4 %3, #1, %3 \n\t" // check n
26945 + " jmpne.w.f 200b \n\t"
26948 + : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
26950 + : "d15", "a3", "memory", "cc"
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"
26965 + "1: .rept 16 \n\t"
26966 + " move.1 (%0)1++, (%1)1++ \n\t"
26968 + " add.4 %2, #-16, %2 \n\t"
26969 + " jmpgt.w.f 1b \n\t"
26972 + : "+a" (dest), "+a" (src), "+d" (n)
26974 + : "d15", "a3", "memory", "cc"
26983 +void *memset(void *s, int c, size_t n)
26987 + if (LIKELY(n > 6)) {
26989 + n -= (4 - (addr_t)s) & 0x03;
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"
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
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
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"
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"
27021 + "1: .rept 25 \n\t"
27022 + " movea (%0)4++, %1 \n\t"
27025 + " move.4 (%0)4++, %1 \n\t"
27027 + " add.4 %2, #-32, %2 \n\t"
27028 + " jmpgt.w.f 1b \n\t"
27030 + " and.4 %3, #3, %3 \n\t" // test bit 1 of n
27031 + " jmpne.w.f 200b \n\t"
27034 + : "+a" (s), "+d" (c), "+d" (m), "+d" (n)
27036 + : "d15", "a3", "memory", "cc"
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"
27051 + "1: .rept 8 \n\t"
27052 + " move.1 (%0)1++, %1 \n\t"
27056 + : "+a" (s), "+d" (c), "+d" (n)
27058 + : "d15", "a3", "memory", "cc"
27064 +++ b/arch/ubicom32/mach-common/audio_tio.c
27067 + * arch/ubicom32/mach-common/audio_tio.c
27068 + * Generic initialization for Ubicom32 Audio
27070 + * (C) Copyright 2009, Ubicom, Inc.
27072 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27089 +#include <linux/platform_device.h>
27090 +#include <linux/types.h>
27092 +#include <asm/devtree.h>
27093 +#include <asm/audio_tio.h>
27094 +#include <asm/ubi32-pcm.h>
27097 + * The number of audio_tio's currently allocated, used for .id
27099 +static int __initdata audio_tio_count;
27102 + * The maximum number of resources that the audio_tio will have.
27103 + * Currently 3, a register space, and up to 2 interrupts.
27105 +#define AUDIO_TIO_MAX_RESOURCES 3
27108 + * audio_tio_alloc
27109 + * Checks the device tree and allocates a platform_device if found
27111 +struct platform_device * __init audio_tio_alloc(const char *driver_name,
27112 + const char *node_name, int priv_bytes)
27114 + struct platform_device *pdev;
27115 + struct resource *res;
27116 + struct audiotionode *audio_node;
27117 + struct ubi32pcm_platform_data *pdata;
27120 + * Check the device tree for the audio_tio
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);
27128 + if (audio_node->version != AUDIOTIONODE_VERSION) {
27129 + printk(KERN_WARNING "audio_tio not compatible\n");
27134 + * Dynamically create the platform_device structure and resources
27136 + pdev = kzalloc(sizeof(struct platform_device) +
27137 + sizeof(struct ubi32pcm_platform_data) +
27138 + priv_bytes , GFP_KERNEL);
27140 + printk(KERN_WARNING "audio_tio could not alloc pdev\n");
27144 + res = kzalloc(sizeof(struct resource) * AUDIO_TIO_MAX_RESOURCES,
27148 + printk(KERN_WARNING "audio_tio could not alloc res\n");
27152 + pdev->name = driver_name;
27153 + pdev->id = audio_tio_count++;
27154 + pdev->resource = res;
27157 + * Fill in the resources and platform data from devtree information
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;
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;
27182 +++ b/arch/ubicom32/mach-common/board.c
27185 + * arch/ubicom32/mach-common/board.c
27186 + * Board init and support code.
27188 + * (C) Copyright 2009, Ubicom, Inc.
27190 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27206 + * Ubicom32 implementation derived from (with many thanks):
27211 +#include <linux/module.h>
27212 +#include <linux/types.h>
27213 +#include <linux/cpu.h>
27214 +#include <asm/devtree.h>
27216 +struct boardnode {
27217 + struct devtree_node dn;
27218 + const char *revision;
27221 +static const struct boardnode *bn;
27224 + * board_get_revision()
27225 + * Returns revision string of the board.
27227 +const char *board_get_revision(void)
27233 + return bn->revision;
27239 +void __init board_init(void)
27241 + bn = (struct boardnode *)devtree_find_node("board");
27243 + printk(KERN_WARNING "board node not found\n");
27248 +++ b/arch/ubicom32/mach-common/bootargs.c
27251 + * arch/ubicom32/mach-common/bootargs.c
27252 + * Board init and support code.
27254 + * (C) Copyright 2009, Ubicom, Inc.
27256 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27272 + * Ubicom32 implementation derived from (with many thanks):
27277 +#include <linux/module.h>
27278 +#include <linux/types.h>
27279 +#include <linux/cpu.h>
27280 +#include <asm/devtree.h>
27282 +struct bootargsnode {
27283 + struct devtree_node dn;
27284 + const char cmdline[512];
27287 +static const struct bootargsnode *ban;
27290 + * bootargs_get_cmdline()
27291 + * Returns kernel boot arguments set by the bootloader.
27293 +const char *bootargs_get_cmdline(void)
27299 + return ban->cmdline;
27305 +void __init bootargs_init(void)
27307 + ban = (struct bootargsnode *)devtree_find_node("bootargs");
27309 + printk(KERN_WARNING "bootargs node not found\n");
27314 +++ b/arch/ubicom32/mach-common/cachectl.c
27317 + * arch/ubicom32/mach-common/cachectl.c
27318 + * Architecture cache control support
27320 + * (C) Copyright 2009, Ubicom, Inc.
27322 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27338 + * Ubicom32 implementation derived from (with many thanks):
27344 +#include <linux/types.h>
27345 +#include <linux/module.h>
27346 +#include <asm/cachectl.h>
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.
27355 +#define CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE \
27356 + ALIGN(sizeof(int) * (DCACHE_WRITE_QUEUE_LENGTH + 1), CACHE_LINE_SIZE)
27358 +static char cache_write_queue_flush_area[CACHE_WRITE_QUEUE_FLUSH_AREA_SIZE]
27359 + __attribute__((aligned(CACHE_LINE_SIZE)));
27362 + * ONE_CCR_ADDR_OP is a helper macro that executes a single CCR operation.
27364 +#define ONE_CCR_ADDR_OP(cc, op_addr, op) \
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" \
27376 + : "a"(cc), "r"(op_addr), "r"(op & 0xff) \
27382 + * mem_cache_control()
27383 + * Special cache control operation
27385 +void mem_cache_control(unsigned long cc, unsigned long begin_addr,
27386 + unsigned long end_addr, unsigned long op)
27388 + unsigned long op_addr;
27390 + if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
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.
27399 + int *flush_area = (int *)cache_write_queue_flush_area;
27401 + " .rept "D(DCACHE_WRITE_QUEUE_LENGTH + 1)" \n\t"
27402 + " move.4 (%0)4++, d0 \n\t"
27404 + : "+a"(flush_area)
27409 + * Calculate the cache lines we need to operate on that include
27410 + * begin_addr though end_addr.
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;
27417 + ONE_CCR_ADDR_OP(cc, op_addr, op);
27418 + op_addr += CACHE_LINE_SIZE;
27419 + } while (likely(op_addr < end_addr));
27421 + if (cc == DCCR_BASE && op == CCR_CTRL_FLUSH_ADDR) {
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.
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.
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
27437 + ONE_CCR_ADDR_OP(cc, cache_write_queue_flush_area, op);
27440 +EXPORT_SYMBOL(mem_cache_control);
27442 +++ b/arch/ubicom32/mach-common/common.c
27445 + * arch/ubicom32/mach-common/common.c
27446 + * Common platform support.
27448 + * (C) Copyright 2009, Ubicom, Inc.
27450 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27466 + * Ubicom32 implementation derived from (with many thanks):
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>
27484 +/* Minimum CLK support */
27486 +struct clk *clk_get(struct device *dev, const char *id)
27488 + return ERR_PTR(-ENOENT);
27490 +EXPORT_SYMBOL(clk_get);
27492 +void clk_put(struct clk *clk)
27495 +EXPORT_SYMBOL(clk_put);
27497 +int clk_enable(struct clk *clk)
27501 +EXPORT_SYMBOL(clk_enable);
27504 +void clk_disable(struct clk *clk)
27507 +EXPORT_SYMBOL(clk_disable);
27509 +++ b/arch/ubicom32/mach-common/io.c
27512 + * arch/ubicom32/mach-common/io.c
27513 + * PCI I/O memory read/write support functions.
27515 + * (C) Copyright 2009, Ubicom, Inc.
27517 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27533 + * Ubicom32 implementation derived from (with many thanks):
27538 +#include <linux/module.h>
27539 +#include <linux/kernel.h>
27540 +#include <linux/io.h>
27543 +unsigned char ioread8(void __iomem *addr)
27545 + if (IS_PCI_ADDRESS(addr))
27546 + return ubi32_pci_read_u8(addr);
27548 + return (unsigned char)(*(volatile unsigned char *)addr);
27550 +EXPORT_SYMBOL(ioread8);
27552 +unsigned short ioread16(void __iomem *addr)
27554 + if (IS_PCI_ADDRESS(addr))
27555 + return ubi32_pci_read_u16(addr);
27557 + return (unsigned short)(*(volatile unsigned short *)addr);
27559 +EXPORT_SYMBOL(ioread16);
27561 +unsigned int ioread32(void __iomem *addr)
27563 + if (IS_PCI_ADDRESS(addr))
27564 + return ubi32_pci_read_u32(addr);
27566 + return (unsigned int)(*(volatile unsigned int *)addr);
27568 +EXPORT_SYMBOL(ioread32);
27570 +void iowrite32(unsigned int val, void __iomem *addr)
27572 + if (IS_PCI_ADDRESS(addr))
27573 + ubi32_pci_write_u32(val, addr);
27575 + *(volatile unsigned int *)addr = val;
27577 +EXPORT_SYMBOL(iowrite32);
27579 +void iowrite16(unsigned short val, void __iomem *addr)
27581 + if (IS_PCI_ADDRESS(addr))
27582 + ubi32_pci_write_u16(val, addr);
27584 + *(volatile unsigned short *)addr = val;
27586 +EXPORT_SYMBOL(iowrite16);
27588 +void iowrite8(unsigned char val, void __iomem *addr)
27590 + if (IS_PCI_ADDRESS(addr))
27591 + ubi32_pci_write_u8(val, addr);
27593 + *(volatile unsigned char *)addr = val;
27595 +EXPORT_SYMBOL(iowrite8);
27597 +void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
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);
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);
27618 + *(u8_t *)to = ubi32_pci_read_u8(from);
27624 + memcpy(to, (void *)from, len);
27626 +EXPORT_SYMBOL(memcpy_fromio);
27628 +void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
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);
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);
27649 + ubi32_pci_write_u8(*(u8_t *)from, to);
27655 + memcpy((void *)to, from, len);
27658 +EXPORT_SYMBOL(memcpy_toio);
27660 +void memset_io(volatile void __iomem *addr, int val, size_t len)
27662 + if (IS_PCI_ADDRESS(addr)) {
27664 + ubi32_pci_write_u8((unsigned char)val, addr);
27669 + memset((void *)addr, val, len);
27672 +EXPORT_SYMBOL(memset_io);
27674 +void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
27676 + if (IS_PCI_ADDRESS(port)) {
27678 + *(u8_t *)buf = ioread8(port);
27683 + insb((unsigned int)port, buf, count);
27687 +EXPORT_SYMBOL(ioread8_rep);
27689 +void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
27691 + if (IS_PCI_ADDRESS(port)) {
27693 + *(u16_t *)buf = ioread16(port);
27698 + insw((unsigned int)port, buf, count);
27701 +EXPORT_SYMBOL(ioread16_rep);
27703 +void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
27705 + if (IS_PCI_ADDRESS(port)) {
27707 + *(u32_t *)buf = ioread32(port);
27712 + insl((unsigned int)port, buf, count);
27715 +EXPORT_SYMBOL(ioread32_rep);
27717 +void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
27719 + if (IS_PCI_ADDRESS(port)) {
27721 + iowrite8(*(u8_t *)buf, port);
27726 + outsb((unsigned int)port, buf, count);
27730 +EXPORT_SYMBOL(iowrite8_rep);
27732 +void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
27734 + if (IS_PCI_ADDRESS(port)) {
27736 + iowrite16(*(u16_t *)buf, port);
27741 + outsw((unsigned int)port, buf, count);
27744 +EXPORT_SYMBOL(iowrite16_rep);
27746 +void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
27748 + if (IS_PCI_ADDRESS(port)) {
27750 + iowrite32(*(u32_t *)buf, port);
27755 + outsl((unsigned int)port, buf, count);
27758 +EXPORT_SYMBOL(iowrite32_rep);
27760 +#endif /* CONFIG_PCI */
27762 +++ b/arch/ubicom32/mach-common/Makefile
27765 +# arch/ubicom32/mach-common/Makefile
27766 +# Makefile for Ubicom32 generic drivers/code.
27768 +# (C) Copyright 2009, Ubicom, Inc.
27770 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27786 +# Ubicom32 implementation derived from (with many thanks):
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
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
27803 +++ b/arch/ubicom32/mach-common/pci.c
27806 + * arch/ubicom32/mach-common/pci.c
27807 + * PCI interface management.
27809 + * (C) Copyright 2009, Ubicom, Inc.
27811 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
27827 + * Ubicom32 implementation derived from (with many thanks):
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>
27842 +#include <asm/devtree.h>
27843 +#include <asm/ip5000.h>
27844 +#include <asm/ubicom32-common.h>
27846 +static int debug_pci = 1 ;
27848 +/* #define PCI_USE_INTERNAL_LOCK 1 */
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)
27858 +#define PCI_LOCK(lock, irqflag) local_irq_save(irqflag)
27859 +#define PCI_UNLOCK(lock, irqflag) local_irq_restore(irqflag)
27862 +#define PCI_DEV0_IDSEL CONFIG_PCI_DEV0_IDSEL
27863 +#define PCI_DEV1_IDSEL CONFIG_PCI_DEV1_IDSEL
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 */
27881 + * Status codes, returned by pci_read_u32() and pci_write_u32()
27883 +#define PCI_RESP_IN_PROGRESS 0xff /* request still in queue */
27884 +#define PCI_RESP_OK 0
27886 + * The following codes indicate that the request has completed
27888 +#define PCI_RESP_NO_DEVSEL 1 /* timeout before target asserted
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
27894 +#define PCI_RESP_NO_TRDY 4 /* timeout before target asserted
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 */
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 */
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;
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;
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;
27947 +#if !defined(CONFIG_DEBUG_PCIMEASURE)
27948 +#define PCI_DECLARE_MEASUREMENT
27949 +#define PCI_MEASUREMENT_START()
27950 +#define PCI_MEASUREMENT_END(idx)
27952 +#define PCI_DECLARE_MEASUREMENT \
27954 + unsigned int __tstart;
27956 +#define PCI_MEASUREMENT_START() \
27957 + __tstart = UBICOM32_IO_TIMER->sysval;
27959 +#define PCI_MEASUREMENT_END(idx) \
27960 + __diff = (int)UBICOM32_IO_TIMER->sysval - (int)__tstart; \
27961 + pci_measurement_update((idx), __diff);
27963 +#define PCI_WEIGHT 32
27965 +struct pci_measurement {
27966 + volatile unsigned int min;
27967 + volatile unsigned int avg;
27968 + volatile unsigned int max;
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,
27981 +static const char *pci_measurement_name_list[PCI_MEASUREMENT_LAST] = {
27989 +static struct pci_measurement pci_measurements[PCI_MEASUREMENT_LAST];
27992 + * pci_measurement_update()
27993 + * Update an entry in the measurement array for this idx.
27995 +static void pci_measurement_update(int idx, int sample)
27997 + struct pci_measurement *pm = &pci_measurements[idx];
27998 + if ((pm->min == 0) || (pm->min > sample)) {
27999 + pm->min = sample;
28001 + if (pm->max < sample) {
28002 + pm->max = sample;
28004 + pm->avg = ((pm->avg * (PCI_WEIGHT - 1)) + sample) / PCI_WEIGHT;
28008 +#if defined(PCI_USE_INTERNAL_LOCK)
28010 + * pci_lock_release()
28011 + * Release the PCI lock.
28013 +static void pci_lock_release(unsigned long irqflag)
28015 + UBICOM32_UNLOCK(PCI_LOCK_BIT);
28019 + * pci_lock_acquire()
28020 + * Acquire the PCI lock, spin if not available.
28022 +static void pci_lock_acquire(unsigned long irqflag)
28024 + UBICOM32_LOCK(PCI_LOCK_BIT);
28029 + * pci_set_hrt_interrupt()
28031 +static inline void pci_set_hrt_interrupt(struct pci_devnode *pci_node)
28033 + ubicom32_set_interrupt(pci_node->dn.sendirq);
28038 + * Synchronously read 32 bits from PCI space.
28040 +u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data)
28043 + unsigned long irqflag;
28047 + * Fill in the request.
28049 + volatile struct pci_master_request lreq;
28050 + PCI_DECLARE_MEASUREMENT;
28052 + lreq.pci_address = address;
28053 + lreq.cmd = pci_cmd;
28054 + lreq.byte_valid = 0xf; /* enable all bytes */
28057 + * Wait for any previous request to complete and then make this request.
28059 + PCI_MEASUREMENT_START();
28060 + PCI_LOCK(&pci_master_lock, irqflag);
28061 + while (unlikely(pci_node->req == &req))
28063 + pci_node->req = &lreq;
28064 + pci_set_hrt_interrupt(pci_node);
28065 + PCI_UNLOCK(&pci_master_lock, irqflag);
28068 + * Wait for the result to show up.
28070 + while (unlikely(pci_node->req == &lreq))
28072 + status = lreq.status;
28073 + if (likely(status == PCI_RESP_OK))
28074 + *data = le32_to_cpu(lreq.data);
28077 + PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ32);
28082 + * pci_write_u32()
28083 + * Asyncrhnously or synchronously write 32 bits to PCI master space.
28085 +u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data)
28087 + unsigned long irqflag;
28088 + PCI_DECLARE_MEASUREMENT;
28091 + * Wait for any previous write or pending read to complete.
28093 + * We use a global data block because once we write the request
28094 + * we do not wait for it to complete before exiting.
28096 + PCI_MEASUREMENT_START();
28097 + PCI_LOCK(&pci_master_lock, irqflag);
28098 + while (unlikely(pci_node->req == &req))
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;
28113 + * Synchronously read 16 bits from PCI space.
28115 +u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data)
28118 + unsigned long irqflag;
28121 + * Fill in the request.
28123 + volatile struct pci_master_request lreq;
28124 + PCI_DECLARE_MEASUREMENT;
28126 + lreq.pci_address = address & ~2;
28127 + lreq.cmd = pci_cmd;
28128 + lreq.byte_valid = (address & 2) ? 0xc : 0x3;
28131 + * Wait for any previous request to complete and then make this request.
28133 + PCI_MEASUREMENT_START();
28134 + PCI_LOCK(&pci_master_lock, irqflag);
28135 + while (unlikely(pci_node->req == &req))
28137 + pci_node->req = &lreq;
28138 + pci_set_hrt_interrupt(pci_node);
28139 + PCI_UNLOCK(&pci_master_lock, irqflag);
28142 + * Wait for the result to show up.
28144 + while (unlikely(pci_node->req == &lreq))
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);
28152 + PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ16);
28157 + * pci_write_u16()
28158 + * Asyncrhnously or synchronously write 16 bits to PCI master space.
28160 +u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data)
28162 + unsigned long irqflag;
28163 + PCI_DECLARE_MEASUREMENT;
28166 + * Wait for any previous write or pending read to complete.
28168 + * We use a global data block because once we write the request
28169 + * we do not wait for it to complete before exiting.
28171 + PCI_MEASUREMENT_START();
28172 + PCI_LOCK(&pci_master_lock, irqflag);
28173 + while (unlikely(pci_node->req == &req))
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;
28189 + * Synchronously read 8 bits from PCI space.
28191 +u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data)
28194 + unsigned long irqflag;
28197 + * Fill in the request.
28199 + volatile struct pci_master_request lreq;
28200 + PCI_DECLARE_MEASUREMENT;
28202 + lreq.pci_address = address & ~3;
28203 + lreq.cmd = pci_cmd;
28204 + lreq.byte_valid = 1 << (address & 0x3);
28207 + * Wait for any previous request to complete and then make this request.
28209 + PCI_MEASUREMENT_START();
28210 + PCI_LOCK(&pci_master_lock, irqflag);
28211 + while (unlikely(pci_node->req == &req))
28213 + pci_node->req = &lreq;
28214 + pci_set_hrt_interrupt(pci_node);
28215 + PCI_UNLOCK(&pci_master_lock, irqflag);
28218 + * Wait for the result to show up.
28220 + while (unlikely(pci_node->req == &lreq))
28222 + status = lreq.status;
28223 + if (likely(status == PCI_RESP_OK)) {
28224 + *data = (u8)(lreq.data >> (24 - ((address & 0x3) << 3)));
28227 + PCI_MEASUREMENT_END(PCI_MEASUREMENT_READ8);
28233 + * Asyncrhnously or synchronously write 8 bits to PCI master space.
28235 +u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data)
28237 + unsigned long irqflag;
28238 + PCI_DECLARE_MEASUREMENT;
28241 + * Wait for any previous write or pending read to complete.
28243 + * We use a global data block because once we write the request
28244 + * we do not wait for it to complete before exiting.
28246 + PCI_MEASUREMENT_START();
28247 + PCI_LOCK(&pci_master_lock, irqflag);
28248 + while (unlikely(pci_node->req == &req))
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;
28261 +unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr)
28263 + unsigned int data;
28264 + pci_read_u32(PCI_CMD_MEM_READ, (u32)addr, &data);
28267 +EXPORT_SYMBOL(ubi32_pci_read_u32);
28269 +unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr)
28271 + unsigned short data;
28272 + pci_read_u16(PCI_CMD_MEM_READ, (u32)addr, &data);
28275 +EXPORT_SYMBOL(ubi32_pci_read_u16);
28277 +unsigned char ubi32_pci_read_u8(const volatile void __iomem *addr)
28279 + unsigned char data;
28280 + pci_read_u8(PCI_CMD_MEM_READ, (u32)addr, &data);
28283 +EXPORT_SYMBOL(ubi32_pci_read_u8);
28285 +void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr)
28287 + pci_write_u32(PCI_CMD_MEM_WRITE, (u32)addr, val);
28289 +EXPORT_SYMBOL(ubi32_pci_write_u32);
28291 +void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr)
28293 + pci_write_u16(PCI_CMD_MEM_WRITE, (u32)addr, val);
28295 +EXPORT_SYMBOL(ubi32_pci_write_u16);
28297 +void ubi32_pci_write_u8(unsigned char val, const void volatile __iomem *addr)
28299 + pci_write_u8(PCI_CMD_MEM_WRITE, (u32)addr, val);
28301 +EXPORT_SYMBOL(ubi32_pci_write_u8);
28303 +#if defined(CONFIG_DEBUG_PCIMEASURE)
28304 +static unsigned int pci_cycles_to_nano(unsigned int cycles, unsigned int frequency)
28306 + unsigned int nano = ((cycles * 1000) / (frequency / 1000000));
28311 + * pci_measurement_show()
28312 + * Print out the min, avg, max values for each PCI transaction type.
28314 + * By request, the max value is reset after each dump.
28316 +static int pci_measurement_show(struct seq_file *p, void *v)
28318 + unsigned int min, avg, max;
28319 + unsigned int freq = processor_frequency();
28320 + int trans = *((loff_t *) v);
28322 + if (trans == 0) {
28323 + seq_puts(p, "min\tavg\tmax\t(nano-seconds)\n");
28326 + if (trans >= PCI_MEASUREMENT_LAST) {
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]);
28338 +static void *pci_measurement_start(struct seq_file *f, loff_t *pos)
28340 + return (*pos < PCI_MEASUREMENT_LAST) ? pos : NULL;
28343 +static void *pci_measurement_next(struct seq_file *f, void *v, loff_t *pos)
28346 + if (*pos >= PCI_MEASUREMENT_LAST)
28351 +static void pci_measurement_stop(struct seq_file *f, void *v)
28353 + /* Nothing to do */
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,
28363 +static int pci_measurement_open(struct inode *inode, struct file *filp)
28365 + return seq_open(filp, &pci_measurement_seq_ops);
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,
28375 +static int __init pci_measurement_init(void)
28377 + proc_create("pci_measurements", 0, NULL, &pci_measurement_fops);
28380 +module_init(pci_measurement_init);
28383 +static int ubi32_pci_read_config(struct pci_bus *bus, unsigned int devfn,
28384 + int where, int size, u32 *value)
28391 + u8 slot = PCI_SLOT(devfn);
28392 + u8 fn = PCI_FUNC(devfn);
28395 + return PCIBIOS_DEVICE_NOT_FOUND;
28396 + } else if (slot == 0) {
28397 + addr = PCI_DEV0_IDSEL + where;
28399 + addr = PCI_DEV1_IDSEL + where;
28402 + addr += (fn << 8);
28404 + cmd = PCI_CMD_CFG_READ;
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;
28412 + pci_read_u32(cmd, addr, value);
28415 + return PCIBIOS_SUCCESSFUL;
28418 +static int ubi32_pci_write_config(struct pci_bus *bus, unsigned int devfn,
28419 + int where, int size, u32 value)
28423 + u8 slot = PCI_SLOT(devfn);
28424 + u8 fn = PCI_FUNC(devfn);
28427 + return PCIBIOS_DEVICE_NOT_FOUND;
28428 + } else if (slot == 0) {
28429 + addr = PCI_DEV0_IDSEL + where;
28431 + addr = PCI_DEV1_IDSEL + where;
28434 + addr += (fn << 8);
28436 + cmd = PCI_CMD_CFG_WRITE;
28438 + pci_write_u8(cmd, addr, (u8)value);
28439 + } else if (size == 2) {
28440 + pci_write_u16(cmd, addr, (u16)value);
28442 + pci_write_u32(cmd, addr, value);
28445 + return PCIBIOS_SUCCESSFUL;
28448 +int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
28452 +EXPORT_SYMBOL(pci_set_dma_max_seg_size);
28454 +int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
28458 +EXPORT_SYMBOL(pci_set_dma_seg_boundary);
28460 +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
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);
28466 + if (!len || !start) {
28470 + if (maxlen && len > maxlen) {
28474 + if (flags & IORESOURCE_IO) {
28475 + return ioport_map(start, len);
28478 + if (flags & IORESOURCE_MEM) {
28479 + if (flags & IORESOURCE_CACHEABLE) {
28480 + return ioremap(start, len);
28482 + return ioremap_nocache(start, len);
28486 +EXPORT_SYMBOL(pci_iomap);
28488 +void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
28490 + if ((unsigned long)addr >= VMALLOC_START &&
28491 + (unsigned long)addr < VMALLOC_END) {
28495 +EXPORT_SYMBOL(pci_iounmap);
28498 + * From arch/arm/kernel/bios32.c
28500 + * PCI bios-type initialisation for PCI machines
28502 + * Bits taken from various places.
28504 +static void __init pcibios_init_hw(struct hw_pci *hw)
28506 + struct pci_sys_data *sys = NULL;
28510 + for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
28511 + sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
28513 + panic("PCI: unable to allocate sys data!");
28516 + sys->busnr = busnr;
28517 + sys->map_irq = hw->map_irq;
28518 + sys->resource[0] = &ioport_resource;
28519 + sys->resource[1] = &iomem_resource;
28521 + ret = hw->setup(nr, sys);
28524 + sys->bus = hw->scan(nr, sys);
28527 + panic("PCI: unable to scan bus!");
28529 + busnr = sys->bus->subordinate + 1;
28531 + list_add(&sys->node, &hw->buses);
28541 + * Swizzle the device pin each time we cross a bridge.
28542 + * This might update pin and returns the slot number.
28544 +static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin)
28546 + struct pci_sys_data *sys = dev->sysdata;
28547 + int slot = 0, oldpin = *pin;
28549 + if (sys->swizzle)
28550 + slot = sys->swizzle(dev, pin);
28553 + printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
28554 + pci_name(dev), oldpin, *pin, slot);
28559 + * Map a slot/pin to an IRQ.
28561 +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28563 + struct pci_sys_data *sys = dev->sysdata;
28566 + if (sys->map_irq)
28567 + irq = sys->map_irq(dev, slot, pin);
28570 + printk("PCI: %s mapping slot %d pin %d => irq %d\n",
28571 + pci_name(dev), slot, pin, irq);
28576 +void __init pci_common_init(struct hw_pci *hw)
28578 + struct pci_sys_data *sys;
28580 + INIT_LIST_HEAD(&hw->buses);
28584 + pcibios_init_hw(hw);
28585 + if (hw->postinit)
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;
28592 + * Size the bridge windows.
28594 + pci_bus_size_bridges(bus);
28596 + * Assign resources.
28598 + pci_bus_assign_resources(bus);
28601 + * Tell drivers about devices found.
28603 + pci_bus_add_devices(bus);
28607 +char * __init pcibios_setup(char *str)
28609 + if (!strcmp(str, "debug")) {
28617 + * From arch/i386/kernel/pci-i386.c:
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
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..
28631 +void pcibios_align_resource(void *data, struct resource *res,
28632 + resource_size_t size, resource_size_t align)
28634 + resource_size_t start = res->start;
28636 + if (res->flags & IORESOURCE_IO && start & 0x300)
28637 + start = (start + 0x3ff) & ~0x3ff;
28639 + res->start = (start + align - 1) & ~(align - 1);
28643 +void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
28646 + printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
28647 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
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.
28654 +static inline int pdev_bad_for_parity(struct pci_dev *dev)
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);
28665 + * Adjust the device resources from bus-centric to Linux-centric.
28667 +static void __devinit
28668 +pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
28670 + resource_size_t offset;
28673 + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
28674 + if (dev->resource[i].start == 0)
28676 + if (dev->resource[i].flags & IORESOURCE_MEM)
28677 + offset = root->mem_offset;
28679 + offset = root->io_offset;
28681 + dev->resource[i].start += offset;
28682 + dev->resource[i].end += offset;
28686 +static void __devinit
28687 +pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
28689 + struct pci_dev *dev = bus->self;
28694 + * Assign root bus resources.
28696 + for (i = 0; i < 3; i++)
28697 + bus->resource[i] = root->resource[i];
28702 + * pcibios_fixup_bus - Called after each bus is probed,
28703 + * but before its children are examined.
28705 +void pcibios_fixup_bus(struct pci_bus *bus)
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;
28712 + pbus_assign_bus_resources(bus, root);
28715 + * Walk the devices on this bus, working out what we can
28716 + * and can't support.
28718 + list_for_each_entry(dev, &bus->devices, bus_list) {
28721 + pdev_fixup_device_resources(root, dev);
28723 + pci_read_config_word(dev, PCI_STATUS, &status);
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.
28731 + if (!(status & PCI_STATUS_FAST_BACK))
28732 + features &= ~PCI_COMMAND_FAST_BACK;
28734 + if (pdev_bad_for_parity(dev))
28735 + features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
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);
28747 + case PCI_CLASS_BRIDGE_CARDBUS:
28748 + pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28750 + status |= PCI_CB_BRIDGE_CTL_PARITY |
28751 + PCI_CB_BRIDGE_CTL_MASTER_ABORT;
28752 + pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL,
28759 + * Now walk the devices again, this time setting them up.
28761 + list_for_each_entry(dev, &bus->devices, bus_list) {
28764 + pci_read_config_word(dev, PCI_COMMAND, &cmd);
28766 + pci_write_config_word(dev, PCI_COMMAND, cmd);
28768 + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
28769 + L1_CACHE_BYTES >> 2);
28773 + * Propagate the flags to the PCI bridge.
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;
28783 + * Report what we did for this bus
28785 + printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
28786 + bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
28789 + * Convert from Linux-centric to bus-centric addresses for bridge devices.
28792 +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
28793 + struct resource *res)
28795 + struct pci_sys_data *root = dev->sysdata;
28796 + unsigned long offset = 0;
28798 + if (res->flags & IORESOURCE_IO)
28799 + offset = root->io_offset;
28800 + if (res->flags & IORESOURCE_MEM)
28801 + offset = root->mem_offset;
28803 + region->start = res->start - offset;
28804 + region->end = res->end - offset;
28808 +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
28809 + struct pci_bus_region *region)
28811 + struct pci_sys_data *root = dev->sysdata;
28812 + unsigned long offset = 0;
28814 + if (res->flags & IORESOURCE_IO)
28815 + offset = root->io_offset;
28816 + if (res->flags & IORESOURCE_MEM)
28817 + offset = root->mem_offset;
28819 + res->start = region->start + offset;
28820 + res->end = region->end + offset;
28823 +#ifdef CONFIG_HOTPLUG
28824 +EXPORT_SYMBOL(pcibios_fixup_bus);
28825 +EXPORT_SYMBOL(pcibios_resource_to_bus);
28826 +EXPORT_SYMBOL(pcibios_bus_to_resource);
28830 + * pcibios_enable_device - Enable I/O and memory.
28831 + * @dev: PCI device to be enabled
28833 +int pcibios_enable_device(struct pci_dev *dev, int mask)
28835 + u16 cmd, old_cmd;
28837 + struct resource *r;
28839 + pci_read_config_word(dev, PCI_COMMAND, &cmd);
28841 + for (idx = 0; idx < 6; idx++) {
28842 + /* Only set up the requested stuff */
28843 + if (!(mask & (1 << idx)))
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));
28852 + if (r->flags & IORESOURCE_IO)
28853 + cmd |= PCI_COMMAND_IO;
28854 + if (r->flags & IORESOURCE_MEM)
28855 + cmd |= PCI_COMMAND_MEMORY;
28859 + * Bridges (eg, cardbus bridges) need to be fully enabled
28861 + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
28862 + cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
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);
28873 +struct pci_ops ubi32_pci_ops = {
28874 + .read = ubi32_pci_read_config,
28875 + .write = ubi32_pci_write_config,
28878 +static struct pci_bus *ubi32_pci_scan_bus(int nr, struct pci_sys_data *sys)
28880 + return pci_scan_bus(sys->busnr, &ubi32_pci_ops, sys);
28883 +#define UBI32_PCI_MEM_BASE PCI_DEV_REG_BASE
28884 +#define UBI32_PCI_MEM_LEN 0x80000000
28886 +#define UBI32_PCI_IO_BASE 0x0
28887 +#define UBI32_PCI_IO_END 0x0
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,
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,
28903 +static int __init ubi32_pci_setup(int nr, struct pci_sys_data *sys)
28908 + request_resource(&iomem_resource, &ubi32_pci_mem);
28909 + request_resource(&ioport_resource, &ubi32_pci_io);
28911 + sys->resource[0] = &ubi32_pci_io;
28912 + sys->resource[1] = &ubi32_pci_mem;
28913 + sys->resource[2] = NULL;
28918 +static void __init ubi32_pci_preinit(void)
28922 +static int __init ubi32_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
28924 + return pci_node->dn.recvirq;
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,
28935 +static int __init ubi32_pci_init(void)
28937 + pci_node = (struct pci_devnode *)devtree_find_node("pci");
28938 + if (pci_node == NULL) {
28939 + printk(KERN_WARNING "PCI init failed\n");
28942 + pci_common_init(&ubi32_pci);
28946 +subsys_initcall(ubi32_pci_init);
28949 + * workaround for dual PCI card interrupt
28951 +#define PCI_COMMON_INT_BIT (1 << 19)
28952 +void ubi32_pci_int_wr(void)
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))
28958 + ubicom32_set_interrupt(pci_node->dn.recvirq);
28961 +EXPORT_SYMBOL(ubi32_pci_int_wr);
28963 +++ b/arch/ubicom32/mach-common/ring_tio.c
28966 + * arch/ubicom32/mach-common/ring_tio.c
28967 + * Generic initialization for UIO Ubicom32 Ring
28969 + * (C) Copyright 2009, Ubicom, Inc.
28971 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
28988 +#include <linux/platform_device.h>
28989 +#include <linux/types.h>
28991 +#include <asm/devtree.h>
28992 +#include <asm/ring_tio.h>
28994 +static const char *ring_tio_driver_name = "uio_ubicom32ring";
28997 + * The number of ring_tio's currently allocated, used for .id
28999 +static int __initdata ring_tio_count;
29002 + * The maximum number of resources that the ring_tio will have.
29003 + * Currently 3, a register space, and up to 2 interrupts.
29005 +#define RING_TIO_MAX_RESOURCES 3
29009 + * Checks the device tree and instantiates the driver if found
29011 +void __init ring_tio_init(const char *node_name)
29013 + struct platform_device *pdev;
29014 + struct resource *res;
29015 + int resource_idx = 0;
29016 + struct ring_tio_node *ring_node;
29019 + * Check the device tree for the ring_tio
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);
29027 + if (ring_node->version != RING_TIO_NODE_VERSION) {
29028 + printk(KERN_WARNING "ring_tio not compatible\n");
29033 + * Dynamically create the platform_device structure and resources
29035 + pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
29037 + printk(KERN_WARNING "ring_tio could not alloc pdev\n");
29041 + res = kzalloc(sizeof(struct resource) * RING_TIO_MAX_RESOURCES,
29045 + printk(KERN_WARNING "ring_tio could not alloc res\n");
29049 + pdev->name = ring_tio_driver_name;
29050 + pdev->id = ring_tio_count++;
29051 + pdev->resource = res;
29054 + * Fill in the resources and platform data from devtree information
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;
29061 + if (ring_node->dn.sendirq != 0xFF) {
29062 + res[resource_idx].start = ring_node->dn.sendirq;
29063 + res[resource_idx].flags = IORESOURCE_IRQ;
29067 + if (ring_node->dn.recvirq != 0xFF) {
29068 + res[resource_idx].start = ring_node->dn.recvirq;
29069 + res[resource_idx].flags = IORESOURCE_IRQ;
29072 + pdev->num_resources = resource_idx;
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);
29079 + * Try to get the device registered
29081 + pdev->dev.platform_data = (void *)node_name;
29082 + if (platform_device_register(pdev) < 0) {
29083 + printk(KERN_WARNING "Ring failed to register\n");
29089 +++ b/arch/ubicom32/mach-common/ubi32-gpio.c
29092 + * arch/ubicom32/mach-common/ubi32-gpio.c
29093 + * Ubicom gpio driver
29095 + * (C) Copyright 2009, Ubicom, Inc.
29097 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
29113 + * Ubicom32 implementation derived from (with many thanks):
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>
29128 +#if defined(CONFIG_PROC_FS)
29129 +#include <linux/proc_fs.h>
29132 +#include <linux/io.h>
29133 +#include <asm/ip5000.h>
29134 +#include <linux/gpio.h>
29136 +#define UBI_GPIO_CHECK_RANGE 0 /* !0 enables range checking */
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.
29154 + * NOTE: This driver uses the bit-by-bit GPIO function assignment
29155 + * exclusively and *never* sets the port function registers to the
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.
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
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.
29180 +#define MAX_UBICOM_GPIOS (9 * 32) /* ARCH_NR_GPIOS */
29181 +#define NUM_GPIO_PORTS (gpio_bank(MAX_UBICOM_GPIOS))
29184 +/* GPIO reservation bit map array */
29185 +static int reserved_gpio_map[NUM_GPIO_PORTS];
29188 +/* Array of hardware io_port addresses */
29189 +static struct ubicom32_io_port *gpio_bank_addr[NUM_GPIO_PORTS] =
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)
29203 +struct ubi_gpio_chip {
29205 + * Right now, nothing else lives here.
29207 + struct gpio_chip gpio_chip;
29211 +#if UBI_GPIO_CHECK_RANGE
29212 +inline int check_gpio(unsigned gpio)
29214 + if (gpio >= MAX_UBICOM_GPIOS)
29219 +#define check_gpio(n) (0)
29223 + * ubi_gpio_get_port
29224 + * Get the IO port associated with a certain gpio
29226 +struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio)
29228 + if (gpio_bank(gpio) > NUM_GPIO_PORTS) {
29231 + return gpio_bank_addr[gpio_bank(gpio)];
29235 + * ubi_gpio_error()
29237 +static void ubi_gpio_error(unsigned gpio)
29239 + printk(KERN_ERR "ubicom-gpio: GPIO %d wasn't requested!\n", gpio);
29243 + * ubi_port_setup()
29245 +static void ubi_port_setup(unsigned gpio, unsigned short usage)
29247 + if (!check_gpio(gpio)) {
29249 + UBICOM32_GPIO_ENABLE(gpio);
29251 + UBICOM32_GPIO_DISABLE(gpio);
29257 + * ubi_gpio_request()
29259 +static int ubi_gpio_request(struct gpio_chip *chip, unsigned gpio)
29261 + unsigned long flags;
29263 + if (check_gpio(gpio) < 0)
29266 + local_irq_save(flags);
29268 + if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29269 + printk(KERN_ERR "ubi-gpio: GPIO %d is already reserved!\n",
29271 + local_irq_restore(flags);
29275 + reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
29277 + ubi_port_setup(gpio, 1);
29279 + local_irq_restore(flags);
29285 + * ubi_gpio_free()
29287 +static void ubi_gpio_free(struct gpio_chip *chip, unsigned gpio)
29289 + unsigned long flags;
29291 + if (check_gpio(gpio) < 0)
29294 + local_irq_save(flags);
29296 + if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
29297 + ubi_gpio_error(gpio);
29298 + local_irq_restore(flags);
29302 + /* Assert the pin is no longer claimed */
29303 + reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
29305 + /* Revert port bit to use specified by port->function */
29306 + ubi_port_setup(gpio, 0);
29308 + local_irq_restore(flags);
29312 + * ubi_gpio_direction_input()
29314 +static int ubi_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
29316 + unsigned long flags;
29318 + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29319 + ubi_gpio_error(gpio);
29323 + local_irq_save(flags);
29325 + /* Configure pin as gpio */
29326 + ubi_port_setup(gpio, 1);
29328 + /* Assert pin is an input */
29329 + UBICOM32_GPIO_SET_PIN_INPUT(gpio);
29331 + local_irq_restore(flags);
29338 + * ubi_gpio_direction_output()
29340 +static int ubi_gpio_direction_output(struct gpio_chip *chip,
29341 + unsigned gpio, int value)
29343 + unsigned long flags;
29345 + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
29346 + ubi_gpio_error(gpio);
29350 + local_irq_save(flags);
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
29356 + ubi_port_setup(gpio, 1);
29358 + UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29360 + UBICOM32_GPIO_SET_PIN_LOW(gpio);
29363 + /* Enable the pin as an output */
29364 + UBICOM32_GPIO_SET_PIN_OUTPUT(gpio);
29366 + local_irq_restore(flags);
29373 + * ubi_gpio_get_value()
29375 +static int ubi_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
29377 + return 0 != (gpio_bank_addr[gpio_bank(gpio)]->gpio_in & gpio_bit(gpio));
29382 + * ubi_gpio_set_value()
29384 +static void ubi_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
29387 + unsigned long flags;
29388 + local_irq_save(flags);
29391 + UBICOM32_GPIO_SET_PIN_HIGH(gpio);
29393 + UBICOM32_GPIO_SET_PIN_LOW(gpio);
29396 + local_irq_restore(flags);
29401 + * ubi_gpio_to_irq()
29403 +static int ubi_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
29405 + return gpio_to_irq(gpio);
29410 + * ubi_gpio_init()
29412 +int __init ubi_gpio_init(void)
29416 + struct ubi_gpio_chip *chip;
29417 + struct gpio_chip *gc;
29419 + printk(KERN_INFO "Ubicom GPIO Controller\n");
29421 + chip = kzalloc(sizeof(struct ubi_gpio_chip), GFP_KERNEL);
29422 + if (chip == NULL)
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;
29435 + gc->ngpio = MAX_UBICOM_GPIOS; /* ARCH_NR_GPIOS - 1 */
29436 + gc->label = "ubi_gpio";
29438 + status = gpiochip_add(gc);
29439 + if (status != 0) {
29444 + /* Assert all pins are free */
29445 + for (k = 0; k < NUM_GPIO_PORTS; k++) {
29446 + reserved_gpio_map[k] = 0;
29452 +#if defined(CONFIG_PROC_FS)
29454 + * ubi_get_gpio_dir()
29456 +static int ubi_get_gpio_dir(unsigned gpio)
29458 + if (gpio_bank_addr[gpio_bank(gpio)]->gpio_ctl & gpio_bit(gpio))
29465 + * gpio_proc_read()
29467 +static int ubi_gpio_proc_read(char *buf, char **start, off_t offset,
29468 + int len, int *unused_i, void *unused_v)
29470 + int c, outlen = 0;
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");
29488 + * ubi_gpio_register_proc()
29490 +static __init int ubi_gpio_register_proc(void)
29492 + struct proc_dir_entry *proc_gpio;
29494 + proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
29496 + proc_gpio->read_proc = ubi_gpio_proc_read;
29498 + return proc_gpio != NULL;
29500 +device_initcall(ubi_gpio_register_proc);
29503 +++ b/arch/ubicom32/mach-common/ubicom32hid.c
29506 + * arch/ubicom32/mach-common/ubicom32hid.c
29507 + * I2C driver for HID coprocessor found on some DPF implementations.
29509 + * (C) Copyright 2009, Ubicom, Inc.
29511 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
29527 + * Ubicom32 implementation derived from (with many thanks):
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>
29544 +#include <asm/ubicom32hid.h>
29546 +#define DRIVER_NAME "ubicom32hid"
29549 +static int ubicom32hid_debug;
29552 +static const struct i2c_device_id ubicom32hid_id[] = {
29553 + { DRIVER_NAME, },
29556 +MODULE_DEVICE_TABLE(i2c, ubicom32hid_id);
29559 + * Define this to make IR checking strict, in general, it's not needed
29561 +#undef UBICOM32HID_STRICT_IR_CHECK
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
29576 +#define UBICOM32HID_MAX_BRIGHTNESS_PWM 255
29579 + * Data structure returned by the HID device
29581 +struct ubicom32hid_input_data {
29583 + uint8_t sw_state;
29584 + uint8_t sw_changed;
29588 + * Our private data
29590 +struct ubicom32hid_data {
29592 + * Pointer to the platform data structure, we need the settings.
29594 + const struct ubicom32hid_platform_data *pdata;
29597 + * Backlight device
29599 + struct backlight_device *bldev;
29602 + * I2C client, for sending messages to the HID device
29604 + struct i2c_client *client;
29607 + * Current intensity, used for get_intensity.
29609 + int cur_intensity;
29612 + * Input subsystem
29613 + * We won't register an input subsystem if there are no mappings.
29615 + struct input_polled_dev *poll_dev;
29620 + * ubicom32hid_set_intensity
29622 +static int ubicom32hid_set_intensity(struct backlight_device *bd)
29624 + struct ubicom32hid_data *ud =
29625 + (struct ubicom32hid_data *)bl_get_data(bd);
29626 + int intensity = bd->props.brightness;
29632 + * If we're blanked the the intensity doesn't matter.
29634 + if ((bd->props.power != FB_BLANK_UNBLANK) ||
29635 + (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
29640 + * Set the brightness based on the type of backlight
29642 + if (ud->pdata->type == UBICOM32HID_BL_TYPE_BINARY) {
29643 + reg = UBICOM32HID_CMD_SET_BL_EN;
29645 + val = ud->pdata->invert
29646 + ? UBICOM32HID_BL_EN_LOW : UBICOM32HID_BL_EN_HI;
29648 + val = ud->pdata->invert
29649 + ? UBICOM32HID_BL_EN_HI : UBICOM32HID_BL_EN_LOW;
29652 + reg = UBICOM32HID_CMD_SET_PWM;
29653 + val = ud->pdata->invert
29654 + ? (UBICOM32HID_MAX_BRIGHTNESS_PWM - intensity) :
29659 + * Send the command
29661 + ret = i2c_smbus_write_byte_data(ud->client, reg, val);
29663 + dev_warn(&ud->client->dev, "Unable to write backlight err=%d\n",
29668 + ud->cur_intensity = intensity;
29674 + * ubicom32hid_get_intensity
29675 + * Return the current intensity of the backlight.
29677 +static int ubicom32hid_get_intensity(struct backlight_device *bd)
29679 + struct ubicom32hid_data *ud =
29680 + (struct ubicom32hid_data *)bl_get_data(bd);
29682 + return ud->cur_intensity;
29686 + * ubicom32hid_verify_data
29687 + * Verify the data to see if there is any action to be taken
29689 + * Returns 0 if no action is to be taken, non-zero otherwise
29691 +static int ubicom32hid_verify_data(struct ubicom32hid_data *ud,
29692 + struct ubicom32hid_input_data *data)
29694 + uint8_t *ircmd = (uint8_t *)&(data->ircmd);
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.
29701 + if (data->ircmd == 0xDEADBEEF) {
29702 + return data->sw_changed != 0;
29706 + * We have an ircmd which is not empty:
29707 + * Data[1] should be the complement of Data[0]
29709 + if (ircmd[0] != (u8_t)~ircmd[1]) {
29713 +#ifdef UBICOM32HID_STRICT_IR_CHECK
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]
29719 + if (ircmd[2] == (u8_t)~ircmd[3]) {
29724 + * For non-compliant remotes, check the system code according to what
29727 + if ((ircmd[2] != UBICOM32HID_IR_SYSTEM_CODE_CHECK) ||
29728 + (ircmd[3] != UBICOM32HID_IR_SYSTEM_CODE)) {
29734 + * Data checks out, process
29740 + * ubicom32hid_poll_input
29741 + * Poll the input from the HID device.
29743 +static void ubicom32hid_poll_input(struct input_polled_dev *dev)
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;
29750 + int sync_needed = 0;
29755 + * Flush the queue
29757 + cmd = UBICOM32HID_CMD_FLUSH;
29758 + ret = i2c_master_send(ud->client, &cmd, 1);
29763 + ret = i2c_smbus_read_i2c_block_data(
29764 + ud->client, UBICOM32HID_CMD_GET_IR_SWITCH, 6, (void *)&data);
29770 + * Verify the data to see if there is any action to be taken
29772 + if (!ubicom32hid_verify_data(ud, &data)) {
29777 + if (ubicom32hid_debug) {
29778 + printk("Polled ircmd=%8x swstate=%2x swchanged=%2x\n",
29779 + data.ircmd, data.sw_state, data.sw_changed);
29784 + * Process changed switches
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)) {
29795 + input_event(id, ub->type, ub->code,
29796 + (data.sw_state & mask) ? 1 : 0);
29799 + if (sync_needed) {
29804 + * Process ir codes
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) {
29811 + * Simulate a up/down event
29813 + input_event(id, ui->type, ui->code, 1);
29815 + input_event(id, ui->type, ui->code, 0);
29826 +static struct backlight_ops ubicom32hid_blops = {
29827 + .get_brightness = ubicom32hid_get_intensity,
29828 + .update_status = ubicom32hid_set_intensity,
29832 + * ubicom32hid_probe
29834 +static int ubicom32hid_probe(struct i2c_client *client,
29835 + const struct i2c_device_id *id)
29837 + struct ubicom32hid_platform_data *pdata;
29838 + struct ubicom32hid_data *ud;
29844 + pdata = client->dev.platform_data;
29845 + if (pdata == NULL) {
29850 + * See if we even have a device available before allocating memory.
29852 + * Hard reset the device
29854 + ret = gpio_request(pdata->gpio_reset, "ubicom32hid-reset");
29858 + gpio_direction_output(pdata->gpio_reset, pdata->gpio_reset_polarity);
29860 + gpio_set_value(pdata->gpio_reset, !pdata->gpio_reset_polarity);
29864 + * soft reset the device. It sometimes takes a while to do this.
29866 + for (i = 0; i < 50; i++) {
29867 + buf[0] = UBICOM32HID_CMD_RESET;
29868 + ret = i2c_master_send(client, buf, 1);
29875 + dev_warn(&client->dev, "Unable to reset device\n");
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]);
29886 + ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_VERSION);
29888 + dev_warn(&client->dev, "Unable to get version\n");
29891 + version[0] = ret;
29893 + ret = i2c_smbus_read_byte_data(client, UBICOM32HID_CMD_GET_REVISION);
29895 + dev_warn(&client->dev, "Unable to get revision\n");
29898 + version[1] = ret;
29901 + * Allocate our private data
29903 + ud = kzalloc(sizeof(struct ubicom32hid_data), GFP_KERNEL);
29908 + ud->pdata = pdata;
29909 + ud->client = client;
29912 + * Register our backlight device
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);
29920 + platform_set_drvdata(client, ud);
29923 + * Start up the backlight with the requested intensity
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;
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;
29937 + ubicom32hid_set_intensity(ud->bldev);
29940 + * Check to see if we have any inputs
29942 + if (!pdata->nbuttons && !pdata->nircodes) {
29947 + * We have buttons or codes, we must register an input device
29949 + ud->poll_dev = input_allocate_polled_device();
29950 + if (!ud->poll_dev) {
29956 + * Setup the polling to default to 100ms
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;
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;
29970 + * Set the capabilities by running through the buttons and ir codes
29972 + for (i = 0; i < pdata->nbuttons; i++) {
29973 + const struct ubicom32hid_button *ub = &pdata->buttons[i];
29975 + input_set_capability(ud->poll_dev->input,
29976 + ub->type ? ub->type : EV_KEY, ub->code);
29979 + for (i = 0; i < pdata->nircodes; i++) {
29980 + const struct ubicom32hid_ir *ui = &pdata->ircodes[i];
29982 + input_set_capability(ud->poll_dev->input,
29983 + ui->type ? ui->type : EV_KEY, ui->code);
29986 + ret = input_register_polled_device(ud->poll_dev);
29992 + printk(KERN_INFO DRIVER_NAME ": enabled, version=%02x.%02x\n",
29993 + version[0], version[1]);
29998 + gpio_free(ud->pdata->gpio_reset);
29999 + backlight_device_unregister(ud->bldev);
30003 + gpio_free(pdata->gpio_reset);
30008 + * ubicom32hid_remove
30010 +static int ubicom32hid_remove(struct i2c_client *client)
30012 + struct ubicom32hid_data *ud =
30013 + (struct ubicom32hid_data *)platform_get_drvdata(client);
30015 + gpio_free(ud->pdata->gpio_reset);
30017 + backlight_device_unregister(ud->bldev);
30019 + if (ud->poll_dev) {
30020 + input_unregister_polled_device(ud->poll_dev);
30021 + input_free_polled_device(ud->poll_dev);
30024 + platform_set_drvdata(client, NULL);
30031 +static struct i2c_driver ubicom32hid_driver = {
30033 + .name = DRIVER_NAME,
30034 + .owner = THIS_MODULE,
30036 + .probe = ubicom32hid_probe,
30037 + .remove = __exit_p(ubicom32hid_remove),
30038 + .id_table = ubicom32hid_id,
30042 + * ubicom32hid_init
30044 +static int __init ubicom32hid_init(void)
30046 + return i2c_add_driver(&ubicom32hid_driver);
30048 +module_init(ubicom32hid_init);
30051 + * ubicom32hid_exit
30053 +static void __exit ubicom32hid_exit(void)
30055 + i2c_del_driver(&ubicom32hid_driver);
30057 +module_exit(ubicom32hid_exit);
30059 +MODULE_AUTHOR("Pat Tjin <@ubicom.com>")
30060 +MODULE_DESCRIPTION("Ubicom HID driver");
30061 +MODULE_LICENSE("GPL");
30063 +++ b/arch/ubicom32/mach-common/ubicom32input.c
30066 + * arch/ubicom32/mach-common/ubicom32input.c
30067 + * Ubicom32 Input driver
30069 + * based on gpio-keys
30071 + * (C) Copyright 2009, Ubicom, Inc.
30073 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
30089 + * Ubicom32 implementation derived from (with many thanks):
30095 + * TODO: add groups for inputs which can be sampled together (i.e. I2C)
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>
30106 +#include <asm/ubicom32input.h>
30108 +struct ubicom32input_data {
30109 + struct ubicom32input_platform_data *pdata;
30111 + struct input_polled_dev *poll_dev;
30114 + * collection of previous states for buttons
30116 + u8 prev_state[0];
30120 + * ubicom32input_poll
30122 +static void ubicom32input_poll(struct input_polled_dev *dev)
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;
30129 + int sync_needed = 0;
30131 + for (i = 0; i < pdata->nbuttons; i++) {
30132 + const struct ubicom32input_button *ub = &pdata->buttons[i];
30135 + int val = gpio_get_value(ub->gpio);
30138 + * Check to see if the state changed from the last time we
30141 + if (val == ud->prev_state[i]) {
30146 + * The state has changed, determine if we are "up" or "down"
30148 + ud->prev_state[i] = val;
30150 + if ((!val && ub->active_low) || (val && !ub->active_low)) {
30154 + input_event(id, ub->type, ub->code, state);
30158 + if (sync_needed) {
30164 + * ubicom32input_probe
30166 +static int __devinit ubicom32input_probe(struct platform_device *pdev)
30169 + struct ubicom32input_data *ud;
30170 + struct input_polled_dev *poll_dev;
30171 + struct input_dev *input_dev;
30172 + struct ubicom32input_platform_data *pdata;
30175 + pdata = pdev->dev.platform_data;
30180 + ud = kzalloc(sizeof(struct ubicom32input_data) +
30181 + pdata->nbuttons, GFP_KERNEL);
30185 + ud->pdata = pdata;
30187 + poll_dev = input_allocate_polled_device();
30193 + platform_set_drvdata(pdev, ud);
30195 + ud->poll_dev = poll_dev;
30196 + poll_dev->private = ud;
30197 + poll_dev->poll = ubicom32input_poll;
30200 + * Set the poll interval requested, default to 50 msec
30202 + if (pdata->poll_interval) {
30203 + poll_dev->poll_interval = pdata->poll_interval;
30205 + poll_dev->poll_interval = 50;
30209 + * Setup the input device
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;
30218 + * Reserve the GPIOs
30220 + for (i = 0; i < pdata->nbuttons; i++) {
30221 + const struct ubicom32input_button *ub = &pdata->buttons[i];
30223 + ret = gpio_request(ub->gpio,
30224 + ub->desc ? ub->desc : "ubicom32input");
30226 + pr_err("ubicom32input: failed to request "
30227 + "GPIO %d ret=%d\n", ub->gpio, ret);
30231 + ret = gpio_direction_input(ub->gpio);
30233 + pr_err("ubicom32input: failed to set "
30234 + "GPIO %d to input ret=%d\n", ub->gpio, ret);
30239 + * Set the previous state to the non-active stae
30241 + ud->prev_state[i] = ub->active_low;
30243 + input_set_capability(input_dev,
30244 + ub->type ? ub->type : EV_KEY, ub->code);
30250 + ret = input_register_polled_device(ud->poll_dev);
30259 + * release the GPIOs we have already requested.
30261 + while (--i >= 0) {
30262 + gpio_free(pdata->buttons[i].gpio);
30266 + printk(KERN_ERR "Ubicom32Input: Failed to register driver %d", ret);
30267 + platform_set_drvdata(pdev, NULL);
30268 + input_free_polled_device(poll_dev);
30274 + * ubicom32input_remove
30276 +static int __devexit ubicom32input_remove(struct platform_device *dev)
30278 + struct ubicom32input_data *ud =
30279 + (struct ubicom32input_data *)platform_get_drvdata(dev);
30285 + for (i = 0; i < ud->pdata->nbuttons; i++) {
30286 + gpio_free(ud->pdata->buttons[i].gpio);
30289 + platform_set_drvdata(dev, NULL);
30290 + input_unregister_polled_device(ud->poll_dev);
30291 + input_free_polled_device(ud->poll_dev);
30298 +static struct platform_driver ubicom32input_driver = {
30300 + .name = "ubicom32input",
30301 + .owner = THIS_MODULE,
30303 + .probe = ubicom32input_probe,
30304 + .remove = __devexit_p(ubicom32input_remove),
30308 + * ubicom32input_init
30310 +static int __devinit ubicom32input_init(void)
30312 + return platform_driver_register(&ubicom32input_driver);
30316 + * ubicom32input_exit
30318 +static void __exit ubicom32input_exit(void)
30320 + platform_driver_unregister(&ubicom32input_driver);
30323 +module_init(ubicom32input_init);
30324 +module_exit(ubicom32input_exit);
30326 +MODULE_AUTHOR("Pat Tjin <pattjin@ubicom.com>");
30327 +MODULE_DESCRIPTION("Ubicom32 Input Driver");
30328 +MODULE_LICENSE("GPL");
30329 +MODULE_ALIAS("platform:ubicom32-input");
30331 +++ b/arch/ubicom32/mach-common/ubicom32input_i2c.c
30334 + * arch/ubicom32/mach-common/ubicom32input_i2c.c
30335 + * Ubicom32 Input driver for I2C
30336 + * Supports PCA953x and family
30338 + * We hog the I2C device, turning it all to input.
30340 + * Based on gpio-keys, pca953x
30342 + * (C) Copyright 2009, Ubicom, Inc.
30344 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
30360 + * Ubicom32 implementation derived from (with many thanks):
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>
30372 +#include <asm/ubicom32input_i2c.h>
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
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, },
30392 +MODULE_DEVICE_TABLE(i2c, ubicom32input_i2c_id);
30394 +struct ubicom32input_i2c_data {
30395 + struct ubicom32input_i2c_platform_data *pdata;
30397 + struct i2c_client *client;
30399 + struct input_polled_dev *poll_dev;
30402 + * collection of previous states for buttons
30404 + uint16_t prev_state;
30410 + * ubicom32input_i2c_write_reg
30411 + * writes a register to the I2C device.
30413 +static int ubicom32input_i2c_write_reg(struct ubicom32input_i2c_data *ud,
30414 + int reg, uint16_t val)
30418 + if (ud->ngpios <= 8) {
30419 + ret = i2c_smbus_write_byte_data(ud->client, reg, val);
30421 + ret = i2c_smbus_write_word_data(ud->client, reg << 1, val);
30432 + * ubicom32input_i2c_read_reg
30433 + * reads a register from the I2C device.
30435 +static int ubicom32input_i2c_read_reg(struct ubicom32input_i2c_data *ud,
30436 + int reg, uint16_t *val)
30440 + if (ud->ngpios <= 8) {
30441 + ret = i2c_smbus_read_byte_data(ud->client, reg);
30443 + ret = i2c_smbus_read_word_data(ud->client, reg);
30450 + *val = (uint16_t)ret;
30456 + * ubicom32input_i2c_poll
30458 +static void ubicom32input_i2c_poll(struct input_polled_dev *dev)
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;
30465 + int sync_needed = 0;
30467 + uint16_t change_mask;
30470 + * Try to get the input status, if we fail, bail out, maybe we can do it
30473 + if (ubicom32input_i2c_read_reg(ud, UBICOM32INPUT_I2C_REG_INPUT, &val)) {
30478 + * see if anything changed by using XOR
30480 + change_mask = ud->prev_state ^ val;
30481 + ud->prev_state = val;
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;
30489 + * Check to see if the state changed from the last time we
30492 + if (!(change_mask & mask)) {
30495 + input_event(id, ub->type, ub->code, state);
30499 + if (sync_needed) {
30505 + * ubicom32input_i2c_probe
30507 +static int __devinit ubicom32input_i2c_probe(struct i2c_client *client,
30508 + const struct i2c_device_id *id)
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;
30516 + uint16_t invert_mask = 0;
30518 + pdata = client->dev.platform_data;
30523 + ud = kzalloc(sizeof(struct ubicom32input_i2c_data), GFP_KERNEL);
30527 + ud->pdata = pdata;
30528 + ud->client = client;
30529 + ud->ngpios = id->driver_data;
30531 + poll_dev = input_allocate_polled_device();
30537 + ud->poll_dev = poll_dev;
30538 + poll_dev->private = ud;
30539 + poll_dev->poll = ubicom32input_i2c_poll;
30542 + * Set the poll interval requested, default to 100 msec
30544 + if (pdata->poll_interval) {
30545 + poll_dev->poll_interval = pdata->poll_interval;
30547 + poll_dev->poll_interval = 100;
30551 + * Setup the input device
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;
30560 + * Set the capabilities
30562 + for (i = 0; i < pdata->nbuttons; i++) {
30563 + const struct ubicom32input_i2c_button *ub = &pdata->buttons[i];
30565 + if (ub->active_low) {
30566 + invert_mask |= (1 << ub->bit);
30569 + input_set_capability(input_dev,
30570 + ub->type ? ub->type : EV_KEY, ub->code);
30574 + * Setup the device (all inputs)
30576 + ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_DIRECTION,
30582 + ret = ubicom32input_i2c_write_reg(ud, UBICOM32INPUT_I2C_REG_INVERT,
30591 + ret = input_register_polled_device(ud->poll_dev);
30596 + i2c_set_clientdata(client, ud);
30601 + printk(KERN_ERR "ubicom32input_i2c: Failed to register driver %d\n",
30603 + input_free_polled_device(poll_dev);
30609 + * ubicom32input_i2c_remove
30611 +static int __devexit ubicom32input_i2c_remove(struct i2c_client *client)
30613 + struct ubicom32input_i2c_data *ud =
30614 + (struct ubicom32input_i2c_data *)i2c_get_clientdata(client);
30616 + i2c_set_clientdata(client, NULL);
30617 + input_unregister_polled_device(ud->poll_dev);
30618 + input_free_polled_device(ud->poll_dev);
30625 +static struct i2c_driver ubicom32input_i2c_driver = {
30627 + .name = "ubicom32input_i2c",
30628 + .owner = THIS_MODULE,
30630 + .remove = __devexit_p(ubicom32input_i2c_remove),
30631 + .id_table = ubicom32input_i2c_id,
30632 + .probe = ubicom32input_i2c_probe,
30636 + * ubicom32input_i2c_init
30638 +static int __devinit ubicom32input_i2c_init(void)
30640 + return i2c_add_driver(&ubicom32input_i2c_driver);
30644 + * ubicom32input_i2c_exit
30646 +static void __exit ubicom32input_i2c_exit(void)
30648 + i2c_del_driver(&ubicom32input_i2c_driver);
30651 +module_init(ubicom32input_i2c_init);
30652 +module_exit(ubicom32input_i2c_exit);
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");
30659 +++ b/arch/ubicom32/mach-common/usb.c
30662 + * arch/ubicom32/mach-common/ip5k_usb.c
30663 + * Ubicom32 architecture usb support.
30665 + * (C) Copyright 2009, Ubicom, Inc.
30666 + * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
30667 + * Author: Kevin Hilman
30669 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
30685 + * Ubicom32 implementation derived from (with many thanks):
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"
30701 +struct usbtionode *unode = NULL;
30703 +static struct resource usb_resources[] = {
30705 + .start = RJ + 0x800,
30706 + .end = RJ + 0x1000,
30707 + .flags = IORESOURCE_MEM,
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,
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, },
30729 +static struct musb_hdrc_config musb_config = {
30730 + .multipoint = true,
30731 + .dyn_fifo = false,
30732 + .soft_con = true,
30736 + .dma_channels = 0,
30738 + .eps_bits = musb_eps,
30741 +static struct musb_hdrc_platform_data usb_data = {
30742 +#ifdef CONFIG_USB_MUSB_OTG
30743 + .mode = MUSB_OTG,
30745 +#ifdef CONFIG_USB_MUSB_HDRC_HCD
30746 + .mode = MUSB_HOST,
30748 +#ifdef CONFIG_USB_GADGET_MUSB_HDRC
30749 + .mode = MUSB_PERIPHERAL,
30754 + .set_clock = NULL,
30755 + .config = &musb_config,
30758 +static struct platform_device musb_device = {
30759 + .name = "musb_hdrc",
30762 + .platform_data = &usb_data,
30763 + .dma_mask = NULL,
30764 + .coherent_dma_mask = 0,
30766 + .resource = usb_resources,
30767 + .num_resources = ARRAY_SIZE(usb_resources),
30770 +struct usbtio_node *usb_node = NULL;
30771 +void ubi32_usb_init(void)
30774 + * See if the usbtio is in the device tree.
30776 + usb_node = (struct usbtio_node *)devtree_find_node("usbtio");
30778 + printk(KERN_WARNING "usb init failed\n");
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");
30789 +void ubi32_usb_int_clr(void)
30791 + UBICOM32_IO_PORT(RJ)->int_clr = (1 << 3);
30795 +++ b/arch/ubicom32/mach-common/usb_tio.c
30798 + * arch/ubicom32/mach-common/usb_tio.c
30799 + * Linux side Ubicom USB TIO driver
30801 + * (C) Copyright 2009, Ubicom, Inc.
30803 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
30819 + * Ubicom32 implementation derived from (with many thanks):
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"
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)
30836 +#define USB_TIO_LOCK(lock, flag) local_irq_save(flag)
30837 +#define USB_TIO_UNLOCK(lock, flag) local_irq_restore(flag)
30840 +spinlock_t usb_tio_lock;
30843 + * usb_tio_set_hrt_interrupt()
30845 +static inline void usb_tio_set_hrt_interrupt(void)
30847 + ubicom32_set_interrupt(usb_node->dn.sendirq);
30850 +static inline void usb_tio_wait_hrt(void)
30852 + while (unlikely(usb_node->pdesc));
30855 +#if defined(USB_TIO_DEBUG)
30856 +static void usb_tio_request_verify_magic(volatile struct usb_tio_request *req)
30858 + BUG_ON(req->magic != USB_TIO_REQUEST_MAGIC2);
30861 +static void usb_tio_request_clear_magic(volatile struct usb_tio_request *req)
30867 +static void usb_tio_request_set_magic(volatile struct usb_tio_request *req)
30869 + req->magic = USB_TIO_REQUEST_MAGIC1;
30873 + * usb_tio_commit_request()
30875 +static inline void usb_tio_commit_request(volatile struct usb_tio_request *request)
30878 + usb_node->pdesc = request;
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
30885 + usb_tio_set_hrt_interrupt();
30889 + * usb_tio_read_u16()
30890 + * Synchronously read 16 bits.
30892 +u8_t usb_tio_read_u16(u32_t address, u16_t *data)
30894 + volatile struct usb_tio_request *tio_req = &usb_node->request;
30895 + unsigned long flag;
30898 + * Wait for any previous request to complete and then make this request.
30900 + USB_TIO_LOCK(&tio_lock, flag);
30901 + usb_tio_wait_hrt();
30904 + * Fill in the request.
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);
30912 + * Wait for the result to show up.
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;
30923 + * usb_tio_read_u8()
30924 + * Synchronously read 16 bits.
30926 +u8_t usb_tio_read_u8(u32_t address, u8_t *data)
30928 + volatile struct usb_tio_request *tio_req = &usb_node->request;
30929 + unsigned long flag;
30932 + * Wait for any previous request to complete and then make this request.
30934 + USB_TIO_LOCK(&tio_lock, flag);
30935 + usb_tio_wait_hrt();
30938 + * Fill in the request.
30940 + tio_req->address = address;
30941 + tio_req->cmd = USB_TIO_READ8_SYNC;
30942 + USB_TIO_REQUEST_SET_MAGIC(tio_req);
30945 + * commit the request
30947 + usb_tio_commit_request(tio_req);
30950 + * Wait for the result to show up.
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;
30961 + * usb_tio_write_u16()
30962 + * Asynchronously write 16 bits.
30964 +u8_t usb_tio_write_u16(u32_t address, u16_t data)
30966 + volatile struct usb_tio_request *tio_req = &usb_node->request;
30967 + unsigned long flag;
30970 + * Wait for any previous write or pending read to complete.
30972 + USB_TIO_LOCK(&tio_lock, flag);
30973 + usb_tio_wait_hrt();
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);
30981 + * commit the request
30983 + usb_tio_commit_request(tio_req);
30984 + USB_TIO_UNLOCK(&tio_lock, flag);
30985 + return USB_TIO_OK;
30989 + * usb_tio_write_u8()
30990 + * Asynchronously write 8 bits.
30992 +u8_t usb_tio_write_u8(u32_t address, u8_t data)
30994 + volatile struct usb_tio_request *tio_req = &usb_node->request;
30995 + unsigned long flag;
30998 + * Wait for any previous write or pending read to complete.
31000 + USB_TIO_LOCK(&tio_lock, flag);
31001 + usb_tio_wait_hrt();
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);
31009 + * commit the request
31011 + usb_tio_commit_request(tio_req);
31012 + USB_TIO_UNLOCK(&tio_lock, flag);
31013 + return USB_TIO_OK;
31017 + * usb_tio_read_fifo()
31018 + * Synchronously read FIFO.
31020 +u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes)
31022 + volatile struct usb_tio_request *tio_req = &usb_node->request;
31023 + unsigned long flag;
31026 + * Wait for any previous request to complete and then make this request.
31028 + USB_TIO_LOCK(&tio_lock, flag);
31029 + usb_tio_wait_hrt();
31032 + * Fill in the request.
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);
31041 + * commit the request
31043 + usb_tio_commit_request(tio_req);
31046 + * Wait for the result to show up.
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;
31056 + * usb_tio_write_fifo()
31057 + * Synchronously write 32 bits.
31059 +u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes)
31061 + volatile struct usb_tio_request *tio_req = &usb_node->request;
31062 + unsigned long flag;
31064 + USB_TIO_LOCK(&tio_lock, flag);
31065 + usb_tio_wait_hrt();
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);
31073 + * commit the request
31075 + usb_tio_commit_request(tio_req);
31078 + * Wait for the result to show up.
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;
31088 + * usb_tio_write_fifo_async()
31089 + * Asynchronously write 32 bits.
31091 +u8_t usb_tio_write_fifo_async(u32_t address, u32_t buffer, u32_t bytes)
31093 + volatile struct usb_tio_request *tio_req = &usb_node->request;
31094 + unsigned long flag;
31096 + USB_TIO_LOCK(&tio_lock, flag);
31097 + usb_tio_wait_hrt();
31099 + tio_req->address = address;
31102 + * Is it necessary to make a local copy of the buffer? Any chance the URB is aborted before TIO finished the FIFO write?
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);
31109 + * commit the request
31111 + usb_tio_commit_request(tio_req);
31112 + USB_TIO_UNLOCK(&tio_lock, flag);
31113 + return USB_TIO_OK;
31117 + * usb_tio_read_int_status()
31118 + * read and clear the interrupt status registers
31120 +void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
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
31128 + "1: bset (%0), (%0), #0 \n\t" \
31129 + " jmpne.f 1b \n\t" \
31131 + : "a" (&usb_node->usb_vp_control)
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);
31139 + //printk(KERN_INFO "int read %x, %x, %x\n", *int_usb, *int_tx, *int_rx);
31142 + * The interrupt status register is read-clean, so clear it now
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;
31149 + * release the lock bit
31151 + usb_node->usb_vp_control &= 0xfffe;
31154 +++ b/arch/ubicom32/mach-common/usb_tio.h
31157 + * arch/ubicom32/mach-common/usb_tio.h
31158 + * Definitions for usb_tio.c
31160 + * (C) Copyright 2009, Ubicom, Inc.
31162 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31178 + * Ubicom32 implementation derived from (with many thanks):
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>
31192 +#ifndef _USB_TIO_H
31193 +#define _USB_TIO_H
31195 +#undef USB_TIO_DEBUG
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)
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)
31209 +enum USB_TIO_status {
31212 + USB_TIO_ERROR_COMMIT,
31215 +enum USB_TIO_cmds {
31216 + USB_TIO_READ16_SYNC,
31217 + USB_TIO_READ8_SYNC,
31218 + USB_TIO_READ_FIFO_SYNC,
31220 + USB_TIO_WRITE16_ASYNC,
31221 + USB_TIO_WRITE8_ASYNC,
31222 + USB_TIO_WRITE_FIFO_ASYNC,
31224 + USB_TIO_WRITE16_SYNC,
31225 + USB_TIO_WRITE8_SYNC,
31226 + USB_TIO_WRITE_FIFO_SYNC,
31230 +enum USB_TIO_state {
31232 + USB_TIO_DMA_SETUP,
31235 +struct usb_tio_request {
31236 + volatile u32_t address;
31238 + volatile u32_t data;
31239 + volatile u32_t buffer;
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;
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;
31264 +extern struct usbtio_node *usb_node;
31265 +extern void ubi32_usb_init(void);
31268 +++ b/arch/ubicom32/mach-common/vdc_tio.c
31271 + * arch/ubicom32/mach-common/vdc_tio.c
31272 + * Generic initialization for VDC
31274 + * (C) Copyright 2009, Ubicom, Inc.
31276 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31292 + * Ubicom32 implementation derived from (with many thanks):
31298 +#include <linux/platform_device.h>
31299 +#include <linux/types.h>
31301 +#include <asm/devtree.h>
31302 +#include <asm/vdc_tio.h>
31305 + * Resources that this driver uses
31307 +static struct resource vdc_tio_resources[] = {
31313 + * The init routine will query the devtree and fill this in
31315 + .flags = IORESOURCE_IRQ,
31319 + * Receive IRQ (optional)
31323 + * The init routine will query the devtree and fill this in
31325 + .flags = IORESOURCE_IRQ,
31329 + * Memory Mapped Registers
31333 + * The init routine will query the devtree and fill this in
31335 + .flags = IORESOURCE_MEM,
31340 + * The platform_device structure which is passed to the driver
31342 +static struct platform_device vdc_tio_platform_device = {
31343 + .name = "ubicom32fb",
31345 + .resource = vdc_tio_resources,
31346 + .num_resources = ARRAY_SIZE(vdc_tio_resources),
31351 + * Checks the device tree and instantiates the driver if found
31353 +void __init vdc_tio_init(void)
31356 + * Check the device tree for the vdc_tio
31358 + struct vdc_tio_node *vdc_node =
31359 + (struct vdc_tio_node *)devtree_find_node("vdctio");
31361 + printk(KERN_WARNING "No vdc_tio found\n");
31366 + * Fill in the resources and platform data from devtree information
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);
31375 + * Try to get the device registered
31377 + if (platform_device_register(&vdc_tio_platform_device) < 0) {
31378 + printk(KERN_WARNING "VDC failed to register\n");
31382 +++ b/arch/ubicom32/mach-ip5k/board-ip5160dev.c
31385 + * arch/ubicom32/mach-ip5k/board-ip5160dev.c
31386 + * Platform initialization for ip5160dev board.
31388 + * (C) Copyright 2009, Ubicom, Inc.
31390 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31406 + * Ubicom32 implementation derived from (with many thanks):
31411 +#include <linux/device.h>
31412 +#include <linux/platform_device.h>
31413 +#include <linux/gpio.h>
31415 +#include <asm/board.h>
31416 +#include <asm/machdep.h>
31417 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31418 +#include <asm/ubicom32suart.h>
31422 + * Factory Default Button on the board at PXn
31423 + * TODO: This is just a placeholder and it needs to include proper header files
31425 +struct ubicom32fdb_platform_data {
31427 + bool fdb_polarity;
31430 +static struct ubicom32fdb_platform_data ip5160dev_fdb_data = {
31432 + .fdb_polarity = true,
31435 +static struct platform_device ip5160dev_fdb_device = {
31436 + .name = "ubicom32fdb",
31439 + .platform_data = &ip5160dev_fdb_data,
31443 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31444 +static struct resource ip5160dev_ubicom32_suart_resources[] = {
31448 + .flags = IORESOURCE_MEM,
31451 + .start = PORT_OTHER_INT(RD),
31452 + .end = PORT_OTHER_INT(RD),
31453 + .flags = IORESOURCE_IRQ,
31456 + .start = 240000000,
31457 + .end = 240000000,
31458 + .flags = UBICOM32_SUART_IORESOURCE_CLOCK,
31462 +static struct platform_device ip5160dev_ubicom32_suart_device = {
31463 + .name = "ubicom32suart",
31465 + .num_resources = ARRAY_SIZE(ip5160dev_ubicom32_suart_resources),
31466 + .resource = ip5160dev_ubicom32_suart_resources,
31471 + * List of all devices in our system
31473 +static struct platform_device *ip5160dev_devices[] __initdata = {
31474 +#ifdef CONFIG_SERIAL_UBI32_SERDES
31475 + &ip5160dev_ubicom32_suart_device,
31477 + &ip5160dev_fdb_device,
31482 + * Called to add the devices which we have on this board
31484 +static int __init ip5160dev_init(void)
31487 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31488 + platform_add_devices(ip5160dev_devices, ARRAY_SIZE(ip5160dev_devices));
31492 +arch_initcall(ip5160dev_init);
31495 +++ b/arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31498 + * arch/ubicom32/mach-ip5k/board-ip5160rgw.c
31499 + * Platform initialization for ip5160rgw board.
31501 + * (C) Copyright 2009, Ubicom, Inc.
31503 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31519 + * Ubicom32 implementation derived from (with many thanks):
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>
31531 + * Factory Default Button on the board at PXn
31532 + * TODO: This is just a placeholder and it needs to include proper header files
31534 +struct ubicom32fdb_platform_data {
31536 + bool fdb_polarity;
31539 +static struct ubicom32fdb_platform_data ip5160rgw_fdb_data = {
31541 + .fdb_polarity = true,
31544 +static struct platform_device ip5160rgw_fdb_device = {
31545 + .name = "ubicom32fdb",
31548 + .platform_data = &ip5160rgw_fdb_data,
31553 + * List of all devices in our system
31555 +static struct platform_device *ip5160rgw_devices[] __initdata = {
31556 + &ip5160rgw_fdb_device,
31561 + * Called to add the devices which we have on this board
31563 +static int __init ip5160rgw_init(void)
31566 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31567 + platform_add_devices(ip5160rgw_devices, ARRAY_SIZE(ip5160rgw_devices));
31571 +arch_initcall(ip5160rgw_init);
31574 +++ b/arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31577 + * arch/ubicom32/mach-ip5k/board-ip5170dpf.c
31578 + * Platform initialization for ip5160dpf board.
31580 + * (C) Copyright 2009, Ubicom, Inc.
31582 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31598 + * Ubicom32 implementation derived from (with many thanks):
31603 +#include <linux/device.h>
31604 +#include <linux/platform_device.h>
31605 +#include <linux/gpio.h>
31606 +#include <linux/leds.h>
31608 +#include <linux/i2c.h>
31609 +#include <linux/i2c-gpio.h>
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>
31620 + * WLAN PD9 (Note this is shared with MISO, but we don't use it)
31623 + * TODO: check triggers, are they generic?
31625 +static struct gpio_led ip5170dpf_gpio_leds[] = {
31627 + .name = "d31:green:WLAN1",
31628 + .default_trigger = "WLAN1",
31629 + .gpio = GPIO_RD_9,
31633 + .name = "d30:green:WPS",
31634 + .default_trigger = "WPS",
31635 + .gpio = GPIO_RD_8,
31640 +static struct gpio_led_platform_data ip5170dpf_gpio_led_platform_data = {
31642 + .leds = ip5170dpf_gpio_leds,
31645 +static struct platform_device ip5170dpf_gpio_leds_device = {
31646 + .name = "leds-gpio",
31649 + .platform_data = &ip5170dpf_gpio_led_platform_data,
31654 + * Backlight on the board PD0, hardware PWM
31656 +static const struct ubicom32hid_button ip5170dpf_ubicom32hid_buttons[] = {
31664 + .code = KEY_LEFT,
31669 + .code = KEY_RIGHT,
31674 + .code = KEY_DOWN,
31679 + .code = KEY_ENTER,
31684 + .code = KEY_MENU,
31694 +static const struct ubicom32hid_ir ip5170dpf_ubicom32hid_ircodes[] = {
31698 + .ir_code = 0xF807916E
31702 + .code = KEY_DOWN,
31703 + .ir_code = 0xF20D916E
31707 + .code = KEY_LEFT,
31708 + .ir_code = 0xF609916E
31712 + .code = KEY_RIGHT,
31713 + .ir_code = 0xF40B916E
31717 + .code = KEY_ENTER,
31718 + .ir_code = 0xF50A916E
31722 + .code = KEY_FN_F1,
31723 + .ir_code = 0xF906916E
31727 + .code = KEY_MENU,
31728 + .ir_code = 0xF708916E
31730 + { /* font size */
31732 + .code = KEY_FN_F2,
31733 + .ir_code = 0xF30C916E
31738 + .ir_code = 0xF10E916E
31742 + .code = KEY_VOLUMEUP,
31743 + .ir_code = 0xF00F916E
31747 + .code = KEY_VOLUMEDOWN,
31748 + .ir_code = 0xED12916E
31752 + .code = KEY_MUTE,
31753 + .ir_code = 0xEA15916E
31757 + .code = KEY_INFO,
31758 + .ir_code = 0xEF10916E
31762 + .code = KEY_FN_F3,
31763 + .ir_code = 0xEE11916E
31767 + .code = KEY_FN_F4,
31768 + .ir_code = 0xEB14916E
31772 + .code = KEY_POWER,
31773 + .ir_code = 0xFD02916E
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,
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),
31790 + * Devices on the I2C bus
31792 +static struct i2c_board_info __initdata ip5170dpf_i2c_board_info[] = {
31794 + * U24, ubicom32hid
31797 + .type = "ubicom32hid",
31799 + .platform_data = &ip5170dpf_ubicom32hid_platform_data,
31803 + * U14, CS4350 DAC, address 0x4B
31808 + * I2C bus on the board, SDA PF13, SCL PF14
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,
31819 +static struct platform_device ip5170dpf_i2c_device = {
31820 + .name = "i2c-gpio",
31823 + .platform_data = &ip5170dpf_i2c_data,
31828 + * List of all devices in our system
31830 +static struct platform_device *ip5170dpf_devices[] __initdata = {
31831 + &ip5170dpf_i2c_device,
31832 + &ip5170dpf_gpio_leds_device,
31837 + * Called to add the devices which we have on this board
31839 +static int __init ip5170dpf_init(void)
31845 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
31846 + platform_add_devices(ip5170dpf_devices, ARRAY_SIZE(ip5170dpf_devices));
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));
31854 +arch_initcall(ip5170dpf_init);
31857 +++ b/arch/ubicom32/mach-ip5k/Kconfig
31862 + select UBICOM32_V3
31866 + select FB_UBICOM32
31867 + select BACKLIGHT_LCD_SUPPORT
31868 + select BACKLIGHT_CLASS_DEVICE
31869 + select UBICOM_HID
31871 + select LEDS_CLASS
31875 + IP5170 Digital Picture Frame board, 8005-1113, IP5K-BEV-0011-13 v1.3
31878 + bool "IP5160Dev_Ver1Dot1"
31879 + select UBICOM32_V3
31882 + Ubicom StreamEngine 5000 Development Board, IP5K-BDV-0004-11 v1.1
31885 + bool "IP5160RGWEval_Ver2Rev2"
31886 + select UBICOM32_V3
31889 + Ubicom StreamEngine 5000 RGW Evaluation Board, IP5K-RGW-0004-11 v2.2
31892 +++ b/arch/ubicom32/mach-ip5k/Makefile
31895 +# arch/ubicom32/mach-ip5k/Makefile
31896 +# Makefile for boards which have an ip5k on them.
31898 +# (C) Copyright 2009, Ubicom, Inc.
31900 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31916 +# Ubicom32 implementation derived from (with many thanks):
31922 +obj-$(CONFIG_IP5170DPF) += board-ip5170dpf.o
31923 +obj-$(CONFIG_IP5160DEV) += board-ip5160dev.o
31924 +obj-$(CONFIG_IP5160EVAL) += board-ip5160rgw.o
31927 +++ b/arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31930 + * arch/ubicom32/mach-ip7k/board-ip7145dpf.c
31931 + * Board file for IP7145DPF, rev 1.0, P/N 8007-0410
31933 + * (C) Copyright 2009, Ubicom, Inc.
31935 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
31951 + * Ubicom32 implementation derived from (with many thanks):
31956 +#include <linux/device.h>
31957 +#include <linux/platform_device.h>
31958 +#include <linux/gpio.h>
31960 +#include <linux/input.h>
31962 +#include <linux/i2c.h>
31963 +#include <linux/i2c-gpio.h>
31964 +#include <linux/i2c/pca953x.h>
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>
31974 +#include <asm/ubicom32sd.h>
31975 +#include <asm/sd_tio.h>
31976 +#include <asm/devtree.h>
31977 +#include <asm/audio_tio.h>
31979 +#include <asm/ring_tio.h>
31981 +/******************************************************************************
31982 + * SD/IO Port F (Slot 1) platform data
31984 +static struct resource ip7145dpf_portf_sd_resources[] = {
31990 + * The init routine will query the devtree and fill this in
31992 + .flags = IORESOURCE_IRQ,
32000 + * The init routine will query the devtree and fill this in
32002 + .flags = IORESOURCE_IRQ,
32006 + * Memory Mapped Registers
32010 + * The init routine will query the devtree and fill this in
32012 + .flags = IORESOURCE_MEM,
32016 +static struct ubicom32sd_card ip7145dpf_portf_sd_cards[] = {
32018 + .pin_wp = IP7145DPF_IOB0,
32019 + .wp_polarity = 1,
32020 + .pin_pwr = IP7145DPF_IOB4,
32021 + .pin_cd = GPIO_RA_4,
32024 + .pin_wp = IP7145DPF_IOB1,
32025 + .wp_polarity = 1,
32026 + .pin_pwr = IP7145DPF_IOB5,
32027 + .pin_cd = GPIO_RA_6,
32031 +static struct ubicom32sd_platform_data ip7145dpf_portf_sd_platform_data = {
32033 + .cards = ip7145dpf_portf_sd_cards,
32036 +static struct platform_device ip7145dpf_portf_sd_device = {
32037 + .name = "ubicom32sd",
32039 + .resource = ip7145dpf_portf_sd_resources,
32040 + .num_resources = ARRAY_SIZE(ip7145dpf_portf_sd_resources),
32042 + .platform_data = &ip7145dpf_portf_sd_platform_data,
32048 + * ip7145dpf_portf_sd_init
32050 +static void ip7145dpf_portf_sd_init(void)
32053 + * Check the device tree for the sd_tio
32055 + struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
32057 + printk(KERN_INFO "PortF SDTIO not found\n");
32062 + * Fill in the resources and platform data from devtree information
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);
32069 + platform_device_register(&ip7145dpf_portf_sd_device);
32072 +/******************************************************************************
32073 + * SD/IO Port B (Slot 2) platform data
32075 +static struct resource ip7145dpf_portb_sd_resources[] = {
32081 + * The init routine will query the devtree and fill this in
32083 + .flags = IORESOURCE_IRQ,
32091 + * The init routine will query the devtree and fill this in
32093 + .flags = IORESOURCE_IRQ,
32097 + * Memory Mapped Registers
32101 + * The init routine will query the devtree and fill this in
32103 + .flags = IORESOURCE_MEM,
32107 +static struct ubicom32sd_card ip7145dpf_portb_sd_cards[] = {
32109 + .pin_wp = IP7145DPF_IOB2,
32110 + .wp_polarity = 1,
32111 + .pin_pwr = IP7145DPF_IOB6,
32112 + .pin_cd = IP7145DPF_IOB3,
32116 +static struct ubicom32sd_platform_data ip7145dpf_portb_sd_platform_data = {
32118 + .cards = ip7145dpf_portb_sd_cards,
32121 +static struct platform_device ip7145dpf_portb_sd_device = {
32122 + .name = "ubicom32sd",
32124 + .resource = ip7145dpf_portb_sd_resources,
32125 + .num_resources = ARRAY_SIZE(ip7145dpf_portb_sd_resources),
32127 + .platform_data = &ip7145dpf_portb_sd_platform_data,
32133 + * ip7145dpf_portb_sd_init
32135 +static void ip7145dpf_portb_sd_init(void)
32138 + * Check the device tree for the sd_tio
32140 + struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
32142 + printk(KERN_INFO "PortB SDTIO not found\n");
32147 + * Fill in the resources and platform data from devtree information
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);
32154 + platform_device_register(&ip7145dpf_portb_sd_device);
32158 +#ifdef IP7145DPF_USE_MMC_SPI
32159 +/******************************************************************************
32160 + * SPI over GPIO (MMC_SPI)
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>
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
32173 + * SPI bus over GPIO (for SD card)
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
32183 +static struct platform_device ip7145dpf_spi_gpio_device = {
32184 + .name = "ubicom32-spi-gpio",
32187 + .platform_data = &ip7145dpf_spi_gpio_data,
32192 + * ip7145dpf_mmc_spi_setpower_slot_a
32193 + * Set the power state for slot A
32195 +static void ip7145dpf_mmc_spi_setpower_slot_a(struct device *dev, unsigned int vdd)
32197 + struct mmc_spi_platform_data *pd = dev->platform_data;
32200 + * Power is inverted, we could tell the IOB to do it, but it's cleaner this way.
32202 + if ((1 << vdd) & pd->ocr_mask) {
32203 + gpio_set_value(MMC_PWR, 0);
32206 + gpio_set_value(MMC_PWR, 1);
32210 + * ip7145dpf_mmc_spi_get_cd_slot_a
32211 + * Get the CD bit for slot A
32213 +static int ip7145dpf_mmc_spi_get_cd_slot_a(struct device *dev)
32216 + * Note that the sense of the GPIO is inverted
32218 + return !gpio_get_value(MMC_CD);
32222 + * ip7145dpf_mmc_spi_get_ro_slot_a
32223 + * Get the WP bit for slot A
32225 +static int ip7145dpf_mmc_spi_get_ro_slot_a(struct device *dev)
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.
32231 + return !gpio_get_value(MMC_WP);
32235 + * ip7145dpf_mmc_spi_exit_slot_a
32236 + * Free the appropriate GPIOs for slot A SD slot.
32238 +static void ip7145dpf_mmc_spi_exit_slot_a(struct device *dev, void *appdata)
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);
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
32253 +static int ip7145dpf_mmc_spi_init_slot_a(void)
32255 + int ret = gpio_request(MMC_CD, "mmc-a-cd");
32257 + printk(KERN_ERR "%s: could not request mmc-a-cd pin\n", __FUNCTION__);
32260 + gpio_direction_input(MMC_CD);
32262 + ret = gpio_request(MMC_CS, "mmc-a-cs");
32264 + printk(KERN_ERR "%s: could not request mmc-a-cs pin\n", __FUNCTION__);
32267 + gpio_direction_output(MMC_CS, 0);
32269 + ret = gpio_request(MMC_WP, "mmc-a-wp");
32271 + printk(KERN_ERR "%s: could not request mmc-a-wp pin\n", __FUNCTION__);
32274 + gpio_direction_input(MMC_WP);
32277 + * Start off with power off
32279 + ret = gpio_request(MMC_PWR, "mmc-a-pwr");
32281 + printk(KERN_ERR "%s: could not request mmc-a-pwr pin\n", __FUNCTION__);
32284 + ret = gpio_direction_output(MMC_PWR, 1);
32289 + gpio_free(MMC_WP);
32292 + gpio_free(MMC_CS);
32295 + gpio_free(MMC_CD);
32300 + * MMC_SPI driver (currently bitbang)
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,
32308 + .setpower = ip7145dpf_mmc_spi_setpower_slot_a,
32309 + .powerup_msecs = 500,
32311 + .detect_delay = 100,
32313 + .caps = MMC_CAP_NEEDS_POLL,
32316 +static struct ubicom32_spi_gpio_controller_data ip7145dpf_mmc_controller_data = {
32317 + .pin_cs = MMC_CS,
32320 +static struct spi_board_info ip7145dpf_spi_board_info[] = {
32322 + .modalias = "mmc_spi",
32324 + .chip_select = 0,
32325 + .max_speed_hz = 2000000,
32326 + .platform_data = &ip7145dpf_mmc_platform_data,
32327 + .controller_data = &ip7145dpf_mmc_controller_data,
32330 +#endif /* IP7145DPF_USE_MMC_SPI */
32333 + * ip7145dpf_u72_setup
32334 + * Called by I2C to tell us that u72 is setup.
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.
32340 + * Currently the only device depending on u72 is the SPI
32342 +static int __init ip7145dpf_u72_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
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__);
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);
32354 + * Initialize the Port F/Port B SD slots
32356 + ip7145dpf_portf_sd_init();
32357 + ip7145dpf_portb_sd_init();
32362 +/******************************************************************************
32363 + * LCD VGH on the board at PE6
32365 +static struct ubicom32lcd_platform_data ip7145dpf_lcd_data = {
32366 + .vgh_gpio = GPIO_RE_6,
32367 + .vgh_polarity = true,
32370 +static struct platform_device ip7145dpf_lcd_device = {
32371 + .name = "ubicom32lcd",
32374 + .platform_data = &ip7145dpf_lcd_data,
32378 +/******************************************************************************
32379 + * Backlight on the board PD0, hardware PWM
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,
32389 +static struct platform_device ip7145dpf_backlight_device = {
32390 + .name = "ubicom32bl",
32393 + .platform_data = &ip7145dpf_backlight_data,
32397 +/******************************************************************************
32398 + * Ubicom32Input on I2C, U48 MAX7310, address 0x18, 8 bits
32400 +static struct ubicom32input_i2c_button ip7145dpf_ubicom32input_i2c_u48_buttons[] = {
32409 + .code = KEY_LEFT,
32415 + .code = KEY_RIGHT,
32421 + .code = KEY_DOWN,
32427 + .code = KEY_ENTER,
32433 + .code = KEY_MENU,
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",
32451 +/******************************************************************************
32452 + * Additional GPIO chips
32454 +static struct pca953x_platform_data ip7145dpf_gpio_u72_platform_data = {
32455 + .gpio_base = IP7145DPF_U72_BASE,
32456 + .setup = ip7145dpf_u72_setup,
32459 +/******************************************************************************
32460 + * Devices on the I2C bus
32462 +static struct i2c_board_info __initdata ip7145dpf_i2c_board_info[] = {
32464 + * U51, S35390A RTC, address 0x30
32467 + .type = "s35390a",
32472 + * U48, MAX7310 IO expander, 8 bits, address 0x18
32475 + .type = "ubicom32in_max7310",
32477 + .platform_data = &ip7145dpf_ubicom32input_i2c_u48_platform_data,
32481 + * U72, MAX7310 IOB expander, 8 bits, address 0x19
32484 + .type = "max7310",
32486 + .platform_data = &ip7145dpf_gpio_u72_platform_data,
32491 + * I2C bus on the board, SDA PE1, SCL PE2
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,
32500 +static struct platform_device ip7145dpf_i2c_device = {
32501 + .name = "i2c-gpio",
32504 + .platform_data = &ip7145dpf_i2c_data,
32508 +/******************************************************************************
32509 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32512 + * FACT_DEFAULT PF13
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.
32518 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32520 +static struct ubicom32input_button ip7145dpf_ubicom32input_buttons[] = {
32523 + .code = KEY_FN_F1,
32524 + .gpio = GPIO_RF_12,
32530 + .code = KEY_FN_F2,
32531 + .gpio = GPIO_RF_13,
32532 + .desc = "Factory Default",
32537 + .code = KEY_POWER,
32538 + .gpio = GPIO_RE_4,
32544 +static struct ubicom32input_platform_data ip7145dpf_ubicom32input_data = {
32545 + .buttons = ip7145dpf_ubicom32input_buttons,
32546 + .nbuttons = ARRAY_SIZE(ip7145dpf_ubicom32input_buttons),
32549 +static struct platform_device ip7145dpf_ubicom32input_device = {
32550 + .name = "ubicom32input",
32553 + .platform_data = &ip7145dpf_ubicom32input_data,
32558 + * List of all devices in our system
32560 +static struct platform_device *ip7145dpf_devices[] __initdata = {
32561 + &ip7145dpf_i2c_device,
32562 + &ip7145dpf_lcd_device,
32563 + &ip7145dpf_backlight_device,
32564 + &ip7145dpf_ubicom32input_device,
32568 + * ip7145dpf_power_off
32569 + * Called to turn the power off for this board
32571 +static void ip7145dpf_power_off(void)
32573 + gpio_set_value(GPIO_RE_5, 0);
32578 + * Called to add the devices which we have on this board
32580 +static int __init ip7145dpf_init(void)
32583 + struct platform_device *audio_dev;
32587 +#ifdef CONFIG_UIO_UBICOM32RING
32588 + ring_tio_init("decoder_ring");
32592 + * Start up the video driver first
32597 + * Take over holding of the power from the system
32599 + ret = gpio_request(GPIO_RE_5, "power_hold");
32601 + printk(KERN_ERR "%s: could not request power hold GPIO\n", __FUNCTION__);
32603 + gpio_direction_output(GPIO_RE_5, 1);
32604 + mach_power_off = ip7145dpf_power_off;
32607 + * USB SEL_HOST_USB line
32609 + ret = gpio_request(GPIO_RF_11, "SEL_HOST_USB");
32611 + printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
32613 + gpio_direction_output(GPIO_RF_11, 0);
32618 + audio_dev = audio_tio_alloc("snd-ubi32-generic", "audiotio-i2sout", 0);
32620 + platform_device_register(audio_dev);
32624 + * Register all of the devices we have on this board
32626 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32627 + platform_add_devices(ip7145dpf_devices, ARRAY_SIZE(ip7145dpf_devices));
32630 + * Register all of the devices which sit on the I2C bus
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));
32636 + * We have to initialize the SPI after the I2C IOB gets setup. SPI is initialized in
32637 + * ip7145dpf_u72_setup
32643 +arch_initcall(ip7145dpf_init);
32646 +++ b/arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32649 + * arch/ubicom32/mach-ip7k/board-ip7160bringup.c
32650 + * Support for the IP7160 bringup board.
32652 + * (C) Copyright 2009, Ubicom, Inc.
32654 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
32670 + * Ubicom32 implementation derived from (with many thanks):
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>
32682 +#include <asm/board.h>
32683 +#include <asm/machdep.h>
32684 +#include <asm/ubicom32input.h>
32686 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32687 +#include <asm/ubicom32suart.h>
32691 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
32694 + * FACT_DEFAULT PD6
32696 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
32698 +static struct ubicom32input_button ip7160bringup_ubicom32input_buttons[] = {
32701 + .code = KEY_FN_F1,
32702 + .gpio = GPIO_RD_5,
32708 + .code = KEY_FN_F2,
32709 + .gpio = GPIO_RD_6,
32710 + .desc = "Factory Default",
32715 +static struct ubicom32input_platform_data ip7160bringup_ubicom32input_data = {
32716 + .buttons = ip7160bringup_ubicom32input_buttons,
32717 + .nbuttons = ARRAY_SIZE(ip7160bringup_ubicom32input_buttons),
32720 +static struct platform_device ip7160bringup_ubicom32input_device = {
32721 + .name = "ubicom32input",
32724 + .platform_data = &ip7160bringup_ubicom32input_data,
32728 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32729 +static struct resource ip7160bringup_ubicom32_suart_resources[] = {
32733 + .flags = IORESOURCE_MEM,
32736 + .start = PORT_OTHER_INT(RE),
32737 + .end = PORT_OTHER_INT(RE),
32738 + .flags = IORESOURCE_IRQ,
32741 + .start = 250000000,
32742 + .end = 250000000,
32743 + .flags = UBICOM32_SUART_IORESOURCE_CLOCK,
32747 +static struct platform_device ip7160bringup_ubicom32_suart_device = {
32748 + .name = "ubicom32suart",
32750 + .num_resources = ARRAY_SIZE(ip7160bringup_ubicom32_suart_resources),
32751 + .resource = ip7160bringup_ubicom32_suart_resources,
32756 + * List of all devices in our system
32758 +static struct platform_device *ip7160bringup_devices[] __initdata = {
32759 +#ifdef CONFIG_SERIAL_UBI32_SERDES
32760 + &ip7160bringup_ubicom32_suart_device,
32762 + &ip7160bringup_ubicom32input_device,
32766 + * ip7160bringup_init
32767 + * Called to add the devices which we have on this board
32769 +static int __init ip7160bringup_init(void)
32775 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
32776 + platform_add_devices(ip7160bringup_devices, ARRAY_SIZE(ip7160bringup_devices));
32781 +arch_initcall(ip7160bringup_init);
32784 +++ b/arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32787 + * arch/ubicom32/mach-ip7k/board-ip7160dpf.c
32788 + * Platform initialization for ip7160dpf board.
32790 + * (C) Copyright 2009, Ubicom, Inc.
32792 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
32808 + * Ubicom32 implementation derived from (with many thanks):
32813 +#include <linux/device.h>
32814 +#include <linux/platform_device.h>
32815 +#include <linux/delay.h>
32816 +#include <linux/gpio.h>
32818 +#include <linux/i2c.h>
32819 +#include <linux/i2c-gpio.h>
32821 +#include <linux/input.h>
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>
32830 + * Backlight on the board PD0, hardware PWM
32832 +static const struct ubicom32hid_button ip7160dpf_ubicom32hid_buttons[] = {
32840 + .code = KEY_LEFT,
32845 + .code = KEY_RIGHT,
32850 + .code = KEY_DOWN,
32855 + .code = KEY_ENTER,
32860 + .code = KEY_MENU,
32870 +static const struct ubicom32hid_ir ip7160dpf_ubicom32hid_ircodes[] = {
32874 + .ir_code = 0xF807916E
32878 + .code = KEY_DOWN,
32879 + .ir_code = 0xF20D916E
32883 + .code = KEY_LEFT,
32884 + .ir_code = 0xF609916E
32888 + .code = KEY_RIGHT,
32889 + .ir_code = 0xF40B916E
32893 + .code = KEY_ENTER,
32894 + .ir_code = 0xF50A916E
32898 + .code = KEY_FN_F1,
32899 + .ir_code = 0xF906916E
32903 + .code = KEY_MENU,
32904 + .ir_code = 0xF708916E
32906 + { /* font size */
32908 + .code = KEY_FN_F2,
32909 + .ir_code = 0xF30C916E
32914 + .ir_code = 0xF10E916E
32918 + .code = KEY_VOLUMEUP,
32919 + .ir_code = 0xF00F916E
32923 + .code = KEY_VOLUMEDOWN,
32924 + .ir_code = 0xED12916E
32928 + .code = KEY_MUTE,
32929 + .ir_code = 0xEA15916E
32933 + .code = KEY_INFO,
32934 + .ir_code = 0xEF10916E
32938 + .code = KEY_FN_F3,
32939 + .ir_code = 0xEE11916E
32943 + .code = KEY_FN_F4,
32944 + .ir_code = 0xEB14916E
32948 + .code = KEY_POWER,
32949 + .ir_code = 0xFD02916E
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,
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),
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.
32972 +static struct i2c_board_info __initdata ip7160dpf_i2c_board_info[] = {
32974 + * U37, CS4350 DAC, address 0x4B, bus 2
32975 + * THIS ENTRY MUST BE FIRST
32978 + .type = "cs4350",
32983 + * U24, ubicom32hid
32986 + .type = "ubicom32hid",
32988 + .platform_data = &ip7160dpf_ubicom32hid_platform_data,
32992 + * U49, ISL29001 Ambient Light Sensor, address 0x44, bus 2 (may not be stuffed)
32996 + * U51, S35390A RTC, address 0x30, bus 2 (may not be stuffed)
32998 +#ifdef CONFIG_RTC_DRV_S35390A
33000 + .type = "s35390a",
33007 + * I2C bus on the board, SDA PI1, SCL PI2
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,
33018 +static struct platform_device ip7160dpf_i2c_device = {
33019 + .name = "i2c-gpio",
33022 + .platform_data = &ip7160dpf_i2c_data,
33027 + * List of all devices in our system
33029 +static struct platform_device *ip7160dpf_devices[] __initdata = {
33030 + &ip7160dpf_i2c_device,
33034 + * ip7160dpf_power_off
33035 + * Called to turn the power off for this board
33037 +static void ip7160dpf_power_off(void)
33039 + gpio_set_value(GPIO_RF_14, 0);
33044 + * Called to add the devices which we have on this board
33046 +static int __init ip7160dpf_init(void)
33049 + struct platform_device *audio_dev;
33054 + * Hold the POWER_HOLD line
33056 + ret = gpio_request(GPIO_RF_14, "POWER_HOLD");
33058 + printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__);
33060 + gpio_direction_output(GPIO_RF_14, 0);
33061 + mach_power_off = ip7160dpf_power_off;
33064 + * USB SEL_HOST_USB line
33066 + ret = gpio_request(GPIO_RI_13, "SEL_HOST_USB");
33068 + printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
33070 + gpio_direction_output(GPIO_RI_13, 0);
33073 + * USB/DAC nRESET line
33075 + ret = gpio_request(GPIO_RI_3, "USB_DAC_nRESET");
33077 + printk(KERN_ERR "%s: could not request USB_DAC_nRESET GPIO\n", __FUNCTION__);
33079 + gpio_direction_output(GPIO_RI_3, 0);
33081 + gpio_direction_output(GPIO_RI_3, 1);
33084 + * I2C BUS2 Disable line
33086 + ret = gpio_request(GPIO_RI_0, "DISABLE_BUS2");
33088 + printk(KERN_ERR "%s: could not request DISABLE_BUS2 GPIO\n", __FUNCTION__);
33090 + gpio_direction_output(GPIO_RI_0, 0);
33094 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33095 + platform_add_devices(ip7160dpf_devices, ARRAY_SIZE(ip7160dpf_devices));
33098 + * Allocate the audio driver if we can
33100 + audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
33102 + ip7160dpf_i2c_board_info[0].platform_data = audio_dev;
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));
33111 +arch_initcall(ip7160dpf_init);
33114 +++ b/arch/ubicom32/mach-ip7k/board-ip7160rgw.c
33117 + * arch/ubicom32/mach-ip7k/board-ip7160rgw.c
33118 + * Platform initialization for ip7160rgw board.
33120 + * (C) Copyright 2009, Ubicom, Inc.
33122 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
33138 + * Ubicom32 implementation derived from (with many thanks):
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>
33151 +#include <asm/board.h>
33152 +#include <asm/machdep.h>
33153 +#include <asm/ubicom32input.h>
33155 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33156 +#include <asm/ubicom32suart.h>
33159 +#include <asm/ubicom32-spi-gpio.h>
33160 +#include <asm/switch-bcm539x.h>
33163 + * SPI bus over GPIO for Gigabit Ethernet Switch
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,
33179 +static struct platform_device ip7160rgw_spi_gpio_device = {
33180 + .name = "ubicom32-spi-gpio",
33183 + .platform_data = &ip7160rgw_spi_gpio_data,
33187 +static struct ubicom32_spi_gpio_controller_data ip7160rgw_bcm539x_controller_data = {
33188 + .pin_cs = GPIO_RE_2,
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",
33198 +static struct spi_board_info ip7160rgw_spi_board_info[] = {
33200 + .modalias = "bcm539x-spi",
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,
33213 + * WLAN1 PD0 (PWM capable)
33219 + * TODO: check triggers, are they generic?
33221 +static struct gpio_led ip7160rgw_gpio_leds[] = {
33223 + .name = "d53:green:WLAN1",
33224 + .default_trigger = "WLAN1",
33225 + .gpio = GPIO_RD_0,
33229 + .name = "d54:green:WLAN2",
33230 + .default_trigger = "WLAN2",
33231 + .gpio = GPIO_RD_1,
33235 + .name = "d55:green:USB",
33236 + .default_trigger = "USB",
33237 + .gpio = GPIO_RD_2,
33241 + .name = "d56:green:Status",
33242 + .default_trigger = "Status",
33243 + .gpio = GPIO_RD_3,
33247 + .name = "d57:green:WPS",
33248 + .default_trigger = "WPS",
33249 + .gpio = GPIO_RD_4,
33254 +static struct gpio_led_platform_data ip7160rgw_gpio_led_platform_data = {
33256 + .leds = ip7160rgw_gpio_leds,
33259 +static struct platform_device ip7160rgw_gpio_leds_device = {
33260 + .name = "leds-gpio",
33263 + .platform_data = &ip7160rgw_gpio_led_platform_data,
33268 + * Use ubicom32input driver to monitor the various pushbuttons on this board.
33271 + * FACT_DEFAULT PD6
33273 + * TODO: pick some ubicom understood EV_xxx define for WPS and Fact Default
33275 +static struct ubicom32input_button ip7160rgw_ubicom32input_buttons[] = {
33278 + .code = KEY_FN_F1,
33279 + .gpio = GPIO_RD_5,
33285 + .code = KEY_FN_F2,
33286 + .gpio = GPIO_RD_6,
33287 + .desc = "Factory Default",
33292 +static struct ubicom32input_platform_data ip7160rgw_ubicom32input_data = {
33293 + .buttons = ip7160rgw_ubicom32input_buttons,
33294 + .nbuttons = ARRAY_SIZE(ip7160rgw_ubicom32input_buttons),
33297 +static struct platform_device ip7160rgw_ubicom32input_device = {
33298 + .name = "ubicom32input",
33301 + .platform_data = &ip7160rgw_ubicom32input_data,
33305 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33306 +static struct resource ip7160rgw_ubicom32_suart_resources[] = {
33310 + .flags = IORESOURCE_MEM,
33313 + .start = PORT_OTHER_INT(RE),
33314 + .end = PORT_OTHER_INT(RE),
33315 + .flags = IORESOURCE_IRQ,
33318 + .start = 250000000,
33319 + .end = 250000000,
33320 + .flags = UBICOM32_SUART_IORESOURCE_CLOCK,
33324 +static struct platform_device ip7160rgw_ubicom32_suart_device = {
33325 + .name = "ubicom32suart",
33327 + .num_resources = ARRAY_SIZE(ip7160rgw_ubicom32_suart_resources),
33328 + .resource = ip7160rgw_ubicom32_suart_resources,
33333 + * List of all devices in our system
33335 +static struct platform_device *ip7160rgw_devices[] __initdata = {
33336 +#ifdef CONFIG_SERIAL_UBI32_SERDES
33337 + &ip7160rgw_ubicom32_suart_device,
33339 + &ip7160rgw_ubicom32input_device,
33340 + &ip7160rgw_gpio_leds_device,
33341 + &ip7160rgw_spi_gpio_device,
33346 + * Called to add the devices which we have on this board
33348 +static int __init ip7160rgw_init(void)
33353 + * Rev 1.2 boards have spi in a different place than 1.1/1.0
33355 + if (strcmp(board_get_revision(), "1.2") == 0) {
33356 + ip7160rgw_spi_gpio_data.pin_mosi = GPIO_RD_7;
33361 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33362 + platform_add_devices(ip7160rgw_devices, ARRAY_SIZE(ip7160rgw_devices));
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));
33370 +arch_initcall(ip7160rgw_init);
33372 +++ b/arch/ubicom32/mach-ip7k/board-ip7500av.c
33375 + * arch/ubicom32/mach-ip7k/board-ip7500av.c
33376 + * Support for IP7500 Audio Video Board + CPU module board.
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)
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
33390 + * (C) Copyright 2009, Ubicom, Inc.
33392 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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>
33421 +/******************************************************************************
33422 + * Devices on the I2C bus
33424 + * BEWARE of changing the order of things in this array as we depend on
33425 + * certain things to be in certain places.
33427 +static struct i2c_board_info __initdata ip7500av_i2c_board_info[] = {
33429 + * U6, CS4384 DAC, address 0x19
33432 + .type = "cs4384",
33438 + * I2C bus on the board, SDA PD1, SCL PD2
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,
33448 +static struct platform_device ip7500av_i2c_device = {
33449 + .name = "i2c-gpio",
33452 + .platform_data = &ip7500av_i2c_data,
33457 + * List of possible mclks we can generate. This depends on the CPU frequency.
33459 +static struct ubi32_cs4384_mclk_entry ip7500av_cs4384_mclk_entries[] = {
33461 + .rate = 12288000,
33465 + .rate = 11289600,
33471 + * List of all devices in our system
33473 +static struct platform_device *ip7500av_devices[] __initdata = {
33474 + &ip7500av_i2c_device,
33479 + * Called to add the devices which we have on this board
33481 +static int __init ip7500av_init(void)
33483 + struct platform_device *audio_dev;
33484 + struct platform_device *audio_dev2;
33485 + struct ubi32_cs4384_platform_data *cs4384_pd;
33491 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
33492 + platform_add_devices(ip7500av_devices, ARRAY_SIZE(ip7500av_devices));
33497 + audio_dev = audio_tio_alloc("snd-ubi32-cs4384", "audiotio-i2sout",
33498 + sizeof(struct ubi32_cs4384_platform_data));
33501 + * Attempt to figure out a good divisor. This will only work
33502 + * assuming the core frequency is compatible.
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);
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;
33524 + audio_dev2 = audio_tio_alloc("snd-ubi32-generic", "audiotio-spdifout", 0);
33525 + if (audio_dev2) {
33526 + platform_device_register(audio_dev2);
33530 + * Register all of the devices which sit on the I2C bus
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));
33539 +arch_initcall(ip7500av_init);
33542 +++ b/arch/ubicom32/mach-ip7k/board-ip7500media.c
33545 + * arch/ubicom32/mach-ip7k/board-ip7500media.c
33546 + * Board file for IP7500 media board.
33548 + * Supports the following configuration
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
33557 + * P/N 8007-0610 rev 1.0
33559 + * (C) Copyright 2009, Ubicom, Inc.
33561 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
33577 + * Ubicom32 implementation derived from (with many thanks):
33582 +#include <linux/device.h>
33583 +#include <linux/platform_device.h>
33584 +#include <linux/gpio.h>
33586 +#include <linux/input.h>
33588 +#include <linux/i2c.h>
33589 +#include <linux/i2c-gpio.h>
33590 +#include <linux/i2c/pca953x.h>
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>
33599 +#include <asm/ubicom32sd.h>
33600 +#include <asm/sd_tio.h>
33601 +#include <asm/devtree.h>
33602 +#include <asm/audio_tio.h>
33604 +#include <asm/ring_tio.h>
33606 +/******************************************************************************
33607 + * SD/IO Port F (Slot 1) platform data
33609 +static struct resource ip7500media_portf_sd_resources[] = {
33615 + * The init routine will query the devtree and fill this in
33617 + .flags = IORESOURCE_IRQ,
33625 + * The init routine will query the devtree and fill this in
33627 + .flags = IORESOURCE_IRQ,
33631 + * Memory Mapped Registers
33635 + * The init routine will query the devtree and fill this in
33637 + .flags = IORESOURCE_MEM,
33641 +static struct ubicom32sd_card ip7500media_portf_sd_cards[] = {
33643 + .pin_wp = IP7500MEDIA_IO16,
33644 + .wp_polarity = 1,
33645 + .pin_pwr = IP7500MEDIA_IO20,
33646 + .pin_cd = IP7500MEDIA_IO23,
33649 + .pin_wp = IP7500MEDIA_IO17,
33650 + .wp_polarity = 1,
33651 + .pin_pwr = IP7500MEDIA_IO21,
33652 + .pin_cd = IP7500MEDIA_IO24,
33656 +static struct ubicom32sd_platform_data ip7500media_portf_sd_platform_data = {
33658 + .cards = ip7500media_portf_sd_cards,
33661 +static struct platform_device ip7500media_portf_sd_device = {
33662 + .name = "ubicom32sd",
33664 + .resource = ip7500media_portf_sd_resources,
33665 + .num_resources = ARRAY_SIZE(ip7500media_portf_sd_resources),
33667 + .platform_data = &ip7500media_portf_sd_platform_data,
33673 + * ip7500media_portf_sd_init
33675 +static void ip7500media_portf_sd_init(void)
33678 + * Check the device tree for the sd_tio
33680 + struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
33682 + printk(KERN_INFO "PortF SDTIO not found\n");
33687 + * Fill in the resources and platform data from devtree information
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);
33694 + platform_device_register(&ip7500media_portf_sd_device);
33697 +/******************************************************************************
33698 + * SD/IO Port B (Slot 2) platform data
33700 +static struct resource ip7500media_portb_sd_resources[] = {
33706 + * The init routine will query the devtree and fill this in
33708 + .flags = IORESOURCE_IRQ,
33716 + * The init routine will query the devtree and fill this in
33718 + .flags = IORESOURCE_IRQ,
33722 + * Memory Mapped Registers
33726 + * The init routine will query the devtree and fill this in
33728 + .flags = IORESOURCE_MEM,
33732 +static struct ubicom32sd_card ip7500media_portb_sd_cards[] = {
33734 + .pin_wp = IP7500MEDIA_IO19,
33735 + .wp_polarity = 1,
33736 + .pin_pwr = IP7500MEDIA_IO22,
33737 + .pin_cd = IP7500MEDIA_IO18,
33741 +static struct ubicom32sd_platform_data ip7500media_portb_sd_platform_data = {
33743 + .cards = ip7500media_portb_sd_cards,
33746 +static struct platform_device ip7500media_portb_sd_device = {
33747 + .name = "ubicom32sd",
33749 + .resource = ip7500media_portb_sd_resources,
33750 + .num_resources = ARRAY_SIZE(ip7500media_portb_sd_resources),
33752 + .platform_data = &ip7500media_portb_sd_platform_data,
33758 + * ip7500media_portb_sd_init
33760 +static void ip7500media_portb_sd_init(void)
33763 + * Check the device tree for the sd_tio
33765 + struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
33767 + printk(KERN_INFO "PortB SDTIO not found\n");
33772 + * Fill in the resources and platform data from devtree information
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);
33779 + platform_device_register(&ip7500media_portb_sd_device);
33783 + * ip7500media_u17_setup
33784 + * Called by I2C to tell us that u17 is setup.
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.
33790 + * Currently the only device depending on u17 is the SDIO
33792 +static int __init ip7500media_u17_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context)
33795 + * Initialize the Port F/Port B SD slots (only the enabled ports will init)
33797 + ip7500media_portf_sd_init();
33798 + ip7500media_portb_sd_init();
33803 +/******************************************************************************
33804 + * LCD VGH on the board at PE6
33806 +static struct ubicom32lcd_platform_data ip7500media_lcd_data = {
33807 + .vgh_gpio = GPIO_RE_7,
33808 + .vgh_polarity = true,
33811 +static struct platform_device ip7500media_lcd_device = {
33812 + .name = "ubicom32lcd",
33815 + .platform_data = &ip7500media_lcd_data,
33819 +/******************************************************************************
33820 + * Backlight on the board PD0, hardware PWM
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,
33830 +static struct platform_device ip7500media_backlight_device = {
33831 + .name = "ubicom32bl",
33834 + .platform_data = &ip7500media_backlight_data,
33838 +/******************************************************************************
33839 + * Ubicom32Input on I2C, U15 MAX7310, address 0x18, 8 bits
33841 +static struct ubicom32input_i2c_button ip7500media_ubicom32input_i2c_u15_buttons[] = {
33844 + .code = KEY_LEFT,
33850 + .code = KEY_RIGHT,
33862 + .code = KEY_DOWN,
33868 + .code = KEY_ENTER,
33874 + .code = KEY_MENU,
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",
33892 +/******************************************************************************
33893 + * Additional GPIO chips
33895 +static struct pca953x_platform_data ip7500media_gpio_u16_platform_data = {
33896 + .gpio_base = IP7500MEDIA_U16_BASE,
33899 +static struct pca953x_platform_data ip7500media_gpio_u17_platform_data = {
33900 + .gpio_base = IP7500MEDIA_U17_BASE,
33901 + .setup = ip7500media_u17_setup,
33904 +static struct pca953x_platform_data ip7500media_gpio_u18_platform_data = {
33905 + .gpio_base = IP7500MEDIA_U18_BASE,
33908 +/******************************************************************************
33909 + * Devices on the I2C bus
33911 + * BEWARE of changing the order of things in this array as we depend on
33912 + * certain things to be in certain places.
33914 +static struct i2c_board_info __initdata ip7500media_i2c_board_info[] = {
33916 + * U6, CS4350 DAC, address 0x4B
33919 + .type = "cs4350",
33924 + * U14, S35390A RTC, address 0x30
33927 + .type = "s35390a",
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)
33939 + .type = "ubicom32in_max7310",
33941 + .platform_data = &ip7500media_ubicom32input_i2c_u15_platform_data,
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)
33952 + .type = "max7310",
33954 + .platform_data = &ip7500media_gpio_u16_platform_data,
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
33966 + .type = "max7310",
33968 + .platform_data = &ip7500media_gpio_u17_platform_data,
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
33979 + .type = "max7310",
33981 + .platform_data = &ip7500media_gpio_u18_platform_data,
33986 + * I2C bus on the board, SDA PE4, SCL PE5
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,
33996 +static struct platform_device ip7500media_i2c_device = {
33997 + .name = "i2c-gpio",
34000 + .platform_data = &ip7500media_i2c_data,
34005 + * List of all devices in our system
34007 +static struct platform_device *ip7500media_devices[] __initdata = {
34008 + &ip7500media_i2c_device,
34009 + &ip7500media_lcd_device,
34010 + &ip7500media_backlight_device,
34014 + * ip7500media_init
34015 + * Called to add the devices which we have on this board
34017 +static int __init ip7500media_init(void)
34019 + struct platform_device *audio_dev;
34025 +#ifdef CONFIG_UIO_UBICOM32RING
34026 + ring_tio_init("decoder_ring");
34030 + * Start up the video driver first
34035 + * Register all of the devices we have on this board
34037 + printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
34038 + platform_add_devices(ip7500media_devices, ARRAY_SIZE(ip7500media_devices));
34041 + * Allocate the audio driver if we can
34043 + audio_dev = audio_tio_alloc("snd-ubi32-cs4350", "audiotio-i2sout", 0);
34045 + ip7500media_i2c_board_info[0].platform_data = audio_dev;
34049 + * Register all of the devices which sit on the I2C bus
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));
34055 + * We have to initialize the SDIO after the I2C IOB gets setup. SDIO is initialized in
34056 + * ip7500media_u17_setup
34062 +arch_initcall(ip7500media_init);
34065 +++ b/arch/ubicom32/mach-ip7k/board-ip7500module.c
34068 + * arch/ubicom32/mach-ip7k/board-ip7500module.c
34069 + * Support for IP7500 CPU module board.
34071 + * This file supports the IP7500 CPU module board:
34072 + * 8007-0510 Rev 1.0
34073 + * 8007-0510A Rev 1.0 (with ethernet)
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
34081 + * (C) Copyright 2009, Ubicom, Inc.
34083 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34099 + * Ubicom32 implementation derived from (with many thanks):
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>
34113 + * ip7500module_init
34114 + * Called to add the devices which we have on this board
34116 +static int __init ip7500module_init(void)
34125 +arch_initcall(ip7500module_init);
34128 +++ b/arch/ubicom32/mach-ip7k/Kconfig
34132 + select UBICOM32_V4
34133 + select UBICOM_INPUT
34134 + select UBICOM_INPUT_I2C
34136 + select RTC_DRV_S35390A
34139 + select GPIO_PCA953X
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
34148 + select MMC_UBICOM32
34153 + IP7145 Digital Picture Frame reference design, supports:
34158 + select UBICOM32_V4
34159 + select UBICOM_INPUT
34161 + select LEDS_CLASS
34165 + select SPI_UBICOM32_GPIO
34166 + select VLAN_8021Q
34167 + select UBICOM_SWITCH
34168 + select UBICOM_SWITCH_BCM539X
34170 + Ubicom IP7160 RGW Eval, supports:
34175 +config IP7160BRINGUP
34176 + bool "IP7160BRINGUP"
34177 + select UBICOM32_V4
34179 + select LEDS_CLASS
34183 + Ubicom IP7160 Bringup, supports:
34188 + select UBICOM32_V4
34192 + select FB_UBICOM32
34193 + select BACKLIGHT_LCD_SUPPORT
34194 + select BACKLIGHT_CLASS_DEVICE
34196 + select SND_UBI32_AUDIO_CS4350
34197 + select UBICOM_HID
34200 + IP7160 Digital Picture Frame board, supports:
34201 + 8007-0211 Rev 1.1
34203 +config IP7500MODULE
34204 + bool "IP7500MODULE"
34205 + select UBICOM32_V4
34208 + Ubicom IP7500 CPU Module board, supports:
34212 + Please see ip7500module.c for more details.
34216 + select UBICOM32_V4
34221 + select SND_UBI32_AUDIO_CS4384
34223 + select FB_UBICOM32
34225 + Ubicom IP7500 Audio Video board, supports:
34228 + With Ubicom IP7500 CPU Module board:
34229 + 8007-0510 v1.0 -or-
34232 + Please see ip7500av.c for more details.
34234 +config IP7500MEDIA
34235 + bool "IP7500MEDIA"
34236 + select UBICOM32_V4
34237 + select UBICOM_INPUT_I2C
34239 + select RTC_DRV_S35390A
34242 + select GPIO_PCA953X
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
34251 + select SND_UBI32_AUDIO_CS4350
34252 + select MMC_UBICOM32
34257 + IP7500 Media Board w/ IP7500 CPU Module board, supports:
34258 + 8007-0610 v1.0 w/ 8007-0510 v1.0
34260 + Please see ip7500media.c for more details.
34263 +++ b/arch/ubicom32/mach-ip7k/Makefile
34266 +# arch/ubicom32/mach-ip7k/Makefile
34267 +# Makefile for ip7k based boards.
34269 +# (C) Copyright 2009, Ubicom, Inc.
34271 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34287 +# Ubicom32 implementation derived from (with many thanks):
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
34301 +++ b/arch/ubicom32/Makefile
34304 +# arch/ubicom32/Makefile
34305 +# <TODO: Replace with short file description>
34307 +# (C) Copyright 2009, Ubicom, Inc.
34309 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34325 +# Ubicom32 implementation derived from (with many thanks):
34331 +KBUILD_DEFCONFIG :=
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)
34339 +model-$(CONFIG_RAMKERNEL) := ram
34340 +model-$(CONFIG_ROMKERNEL) := rom
34341 +MODEL := $(model-y)
34344 +CPUCLASS := $(cpuclass-y)
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.
34353 +CFLAGS_KERNEL += -mfastcall
34354 +CFLAGS_MODULE += -mno-fastcall
34357 +# Some CFLAG additions based on specific CPU type.
34359 +cflags-$(CONFIG_UBICOM32_V3) := -march=ubicom32v3 -mno-fdpic -DIP5000
34360 +cflags-$(CONFIG_UBICOM32_V4) := -march=ubicom32v4 -mno-fdpic -DIP7000
34362 +ldflags-$(CONFIG_LINKER_RELAXATION) := --relax
34363 +LDFLAGS_vmlinux := $(ldflags-y)
34365 +GCCLIBDIR := $(dir $(shell $(CC) $(cflags-y) -print-libgcc-file-name))
34367 +KBUILD_CFLAGS += $(cflags-y) -ffunction-sections
34368 +KBUILD_AFLAGS += $(cflags-y)
34370 +KBUILD_CFLAGS += -D__linux__ -Dlinux
34371 +KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
34373 +# include any machine specific directory
34374 +ifneq ($(machine-y),)
34375 +core-y += arch/$(ARCH)/mach-$(MACHINE)/
34378 +head-y := arch/$(ARCH)/kernel/head.o
34380 +core-y += arch/$(ARCH)/kernel/ \
34381 + arch/$(ARCH)/mm/ \
34382 + arch/$(ARCH)/crypto/ \
34383 + arch/$(ARCH)/mach-common/
34385 +drivers-$(CONFIG_OPROFILE) += arch/ubicom32/oprofile/
34387 +libs-y += arch/$(ARCH)/lib/
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
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"
34403 + @echo "*************************************************"
34407 +++ b/arch/ubicom32/mm/fault.c
34410 + * arch/ubicom32/mm/fault.c
34411 + * Ubicom32 architecture page fault implementation.
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)
34419 + * linux/arch/m68k/mm/fault.c
34421 + * Copyright (C) 1995 Hamish Macdonald
34423 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34439 + * Ubicom32 implementation derived from (with many thanks):
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>
34451 +#include <asm/system.h>
34452 +#include <asm/pgtable.h>
34454 +extern void die_if_kernel(char *, struct pt_regs *, long);
34457 + * This routine handles page faults. It determines the problem, and
34458 + * then passes it off to one of the appropriate routines.
34461 + * bit 0 == 0 means no page found, 1 means protection fault
34462 + * bit 1 == 0 means read, 1 means write
34464 + * If this routine detects a bad access, it returns 1, otherwise it
34467 +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
34468 + unsigned long error_code)
34471 + printk (KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
34472 + regs->sr, regs->pc, address, error_code);
34476 + * Oops. The kernel tried to access some bad page. We'll have to
34477 + * terminate things with extreme prejudice.
34479 + if ((unsigned long) address < PAGE_SIZE) {
34480 + printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
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);
34491 +++ b/arch/ubicom32/mm/init.c
34494 + * arch/ubicom32/mm/init.c
34495 + * Ubicom32 architecture virtual memory initialization.
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)
34504 + * linux/arch/m68k/mm/init.c
34506 + * Copyright (C) 1995 Hamish Macdonald
34508 + * JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
34509 + * DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
34511 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34527 + * Ubicom32 implementation derived from (with many thanks):
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>
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>
34559 +extern void die_if_kernel(char *,struct pt_regs *,long);
34560 +extern void free_initmem(void);
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
34569 + * BAD_PAGETABLE is the accompanying page-table: it is initialized
34570 + * to point to BAD_PAGE entries.
34572 + * ZERO_PAGE is a special page that is used for zero-initialized
34575 +static unsigned long empty_bad_page_table;
34577 +static unsigned long empty_bad_page;
34579 +unsigned long empty_zero_page;
34581 +void show_mem(void)
34584 + int free = 0, total = 0, reserved = 0, shared = 0;
34587 + printk(KERN_INFO "\nMem-info:\n");
34588 + show_free_areas();
34590 + while (i-- > 0) {
34592 + if (PageReserved(mem_map+i))
34594 + else if (PageSwapCache(mem_map+i))
34596 + else if (!page_count(mem_map+i))
34599 + shared += page_count(mem_map+i) - 1;
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);
34608 +extern unsigned long memory_start;
34609 +extern unsigned long memory_end;
34610 +extern char __ocm_free_begin;
34611 +extern char __ocm_free_end;
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.
34619 +void __init paging_init(void)
34622 + * Make sure start_mem is page aligned, otherwise bootmem and
34623 + * page_alloc get different views of the world.
34626 + unsigned long start_mem = PAGE_ALIGN(memory_start);
34628 + unsigned long end_mem = memory_end & PAGE_MASK;
34631 + printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
34632 + start_mem, end_mem);
34636 + * Initialize the bad page table and bad page to point
34637 + * to a couple of allocated pages.
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);
34645 + * TODO: enable setting up for user memory management interface.
34649 + printk (KERN_DEBUG "before free_area_init\n");
34651 + printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
34652 + start_mem, end_mem);
34656 + unsigned long zones_size[MAX_NR_ZONES] = {0, };
34657 +#ifdef CONFIG_ZONE_DMA
34658 + zones_size[ZONE_DMA] = OCMSIZE >> PAGE_SHIFT;
34660 + zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
34661 +#ifdef CONFIG_HIGHMEM
34662 + zones_size[ZONE_HIGHMEM] = 0;
34664 + free_area_init(zones_size);
34668 +void __init mem_init(void)
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 */
34678 + printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
34681 + end_mem &= PAGE_MASK;
34682 + high_memory = (void *) end_mem;
34684 + start_mem = PAGE_ALIGN(start_mem);
34685 + max_mapnr = num_physpages = (((unsigned long) high_memory) - PAGE_OFFSET) >> PAGE_SHIFT;
34687 + /* this will put all memory onto the freelists */
34688 +#ifdef CONFIG_ZONE_DMA
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);
34698 + totalram_pages = free_all_bootmem();
34700 + codek = (&_etext - &_stext) >> 10;
34701 + datak = (&_ebss - &_sdata) >> 10;
34702 + initk = (&__init_begin - &__init_end) >> 10;
34704 + tmp = nr_free_pages() << PAGE_SHIFT;
34705 + printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n",
34714 +#ifdef CONFIG_BLK_DEV_INITRD
34715 +void free_initrd_mem(unsigned long start, unsigned long end)
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++;
34725 + printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
34732 +#ifdef CONFIG_RAMKERNEL
34733 + unsigned long addr;
34734 + extern char __init_begin, __init_end;
34736 + * The following code should be cool even if these sections
34737 + * are not page aligned.
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));
34745 + totalram_pages++;
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));
34755 +++ b/arch/ubicom32/mm/kmap.c
34758 + * arch/ubicom32/mm/kmap.c
34759 + * Ubicom32 architecture non-mmu ioremap and friends implementation.
34761 + * (C) Copyright 2009, Ubicom, Inc.
34762 + * Copyright (C) 2000 Lineo, <davidm@snapgear.com>
34763 + * Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
34765 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34781 + * Ubicom32 implementation derived from (with many thanks):
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>
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>
34805 + * Map some physical address range into the kernel address space.
34807 +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
34809 + return (void *)physaddr;
34813 + * Unmap a ioremap()ed region again.
34815 +void iounmap(void *addr)
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.
34824 +void __iounmap(void *addr, unsigned long size)
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.
34833 +void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
34837 +++ b/arch/ubicom32/mm/Makefile
34840 +# arch/ubicom32/mm/Makefile
34841 +# <TODO: Replace with short file description>
34843 +# (C) Copyright 2009, Ubicom, Inc.
34845 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34861 +# Ubicom32 implementation derived from (with many thanks):
34867 +# Makefile for the linux m68knommu specific parts of the memory manager.
34870 +obj-y += init.o fault.o memory.o kmap.o ocm-alloc.o
34872 +++ b/arch/ubicom32/mm/memory.c
34875 + * arch/ubicom32/mm/memory.c
34876 + * Ubicom32 architecture kernel_map() implementation.
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)
34884 + * linux/arch/m68k/mm/memory.c
34886 + * Copyright (C) 1995 Hamish Macdonald
34888 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34904 + * Ubicom32 implementation derived from (with many thanks):
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>
34917 +#include <asm/segment.h>
34918 +#include <asm/page.h>
34919 +#include <asm/pgtable.h>
34920 +#include <asm/system.h>
34923 + * Map some physical address range into the kernel address space.
34924 + * The code is copied and adapted from map_chunk().
34927 +unsigned long kernel_map(unsigned long paddr, unsigned long size,
34928 + int nocacheflag, unsigned long *memavailp )
34934 +++ b/arch/ubicom32/mm/ocm-alloc.c
34937 + * arch/ubicom32/mm/ocm-alloc.c
34938 + * OCM allocator for Uibcom32 On-Chip memory
34940 + * (C) Copyright 2009, Ubicom, Inc.
34941 + * Copyright 2004-2008 Analog Devices Inc.
34945 + * arch/blackfin/mm/sram-alloc.c
34948 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
34964 + * Ubicom32 implementation derived from (with many thanks):
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>
34984 +#define DEBUGP printk
34986 +#define DEBUGP(fmt, a...)
34989 + * the data structure for OCM heap pieces
34991 +struct ocm_piece {
34995 + struct ocm_piece *next;
34999 + * struct ocm_heap
35002 + struct ocm_piece free_head;
35003 + struct ocm_piece used_head;
35004 + struct mutex lock;
35007 +static struct ocm_heap ocm_inst_heap;
35010 + * OCM area for storing code
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)
35018 +static struct kmem_cache *ocm_piece_cache;
35021 + * _ocm_heap_init()
35023 +static int __init _ocm_heap_init(struct ocm_heap *ocmh,
35024 + unsigned int start,
35025 + unsigned int size)
35027 + ocmh->free_head.next = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
35029 + if (!ocmh->free_head.next)
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;
35037 + ocmh->used_head.next = NULL;
35039 + /* mutex initialize */
35040 + mutex_init(&ocmh->lock);
35046 + * _ocm_alloc_init()
35048 + * starts the ocm heap(s)
35050 +static int __init _ocm_alloc_init(void)
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);
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);
35063 + printk(KERN_INFO "Failed to initialize OCM "
35064 + "Instruction Heap\n");
35067 + printk(KERN_INFO "No space available for OCM "
35068 + "Instruction Heap\n");
35072 +pure_initcall(_ocm_alloc_init);
35076 + * generic alloc a block in the ocm heap, if successful
35077 + * returns the pointer.
35079 +static void *_ocm_alloc(size_t size, pid_t pid, struct ocm_heap *ocmheap)
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;
35085 + if (size <= 0 || !pfree_head || !pused_head)
35088 + /* Align the size */
35089 + size = (size + 3) & ~3;
35091 + pslot = pfree_head->next;
35092 + plast = pfree_head;
35095 + * search an available piece slot
35097 + while (pslot != NULL && size > pslot->size) {
35099 + pslot = pslot->next;
35105 + if (pslot->size == size) {
35107 + * Unlink this block from the list
35109 + plast->next = pslot->next;
35113 + * Split this block in two.
35115 + pavail = kmem_cache_alloc(ocm_piece_cache, GFP_KERNEL);
35120 + pavail->paddr = pslot->paddr;
35121 + pavail->size = size;
35122 + pslot->paddr += size;
35123 + pslot->size -= size;
35126 + pavail->pid = pid;
35128 + pslot = pused_head->next;
35129 + plast = pused_head;
35132 + * insert new piece into used piece list !!!
35134 + while (pslot != NULL && pavail->paddr < pslot->paddr) {
35136 + pslot = pslot->next;
35139 + pavail->next = pslot;
35140 + plast->next = pavail;
35142 + DEBUGP("_ocm_alloc %d bytes at %p from in %p",
35143 + size, pavail->paddr, ocmheap);
35145 + return pavail->paddr;
35149 +/* Allocate the largest available block. */
35150 +static void *_ocm_alloc_max(struct ocm_heap *ocmheap,
35151 + unsigned long *psize)
35153 + struct ocm_piece *pfree_head = &ocmheap->free_head;
35154 + struct ocm_piece *pslot, *pmax;
35156 + pmax = pslot = pfree_head->next;
35158 + /* search an available piece slot */
35159 + while (pslot != NULL) {
35160 + if (pslot->size > pmax->size)
35162 + pslot = pslot->next;
35168 + *psize = pmax->size;
35170 + return _ocm_alloc(*psize, ocmheap);
35176 + * generic free a block in the ocm heap, if successful
35178 +static int _ocm_free(const void *addr,
35179 + struct ocm_heap *ocmheap)
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;
35185 + /* search the relevant memory slot */
35186 + pslot = pused_head->next;
35187 + plast = pused_head;
35189 + /* search an available piece slot */
35190 + while (pslot != NULL && pslot->paddr != addr) {
35192 + pslot = pslot->next;
35196 + DEBUGP("_ocm_free %p not found in %p", addr, ocmheap);
35199 + DEBUGP("_ocm_free %p from in %p", addr, ocmheap);
35201 + plast->next = pslot->next;
35205 + /* insert free pieces back to the free list */
35206 + pslot = pfree_head->next;
35207 + plast = pfree_head;
35209 + while (pslot != NULL && addr > pslot->paddr) {
35211 + pslot = pslot->next;
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);
35219 + pavail->next = plast->next;
35220 + plast->next = pavail;
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);
35234 + * ocm_inst_alloc()
35236 + * allocates a block of size in the ocm instrction heap, if
35237 + * successful returns address allocated.
35239 +void *ocm_inst_alloc(size_t size, pid_t pid)
35243 + if (!OCM_INST_HEAP_LENGTH)
35247 + mutex_lock(&ocm_inst_heap.lock);
35249 + addr = _ocm_alloc(size, pid, &ocm_inst_heap);
35251 + mutex_unlock(&ocm_inst_heap.lock);
35255 +EXPORT_SYMBOL(ocm_inst_alloc);
35258 + * ocm_inst_free()
35259 + * free a block in the ocm instrction heap, returns 0 if successful.
35261 +int ocm_inst_free(const void *addr)
35265 + if (!OCM_INST_HEAP_LENGTH)
35268 + mutex_lock(&ocm_inst_heap.lock);
35270 + ret = _ocm_free(addr, &ocm_inst_heap);
35272 + mutex_unlock(&ocm_inst_heap.lock);
35276 +EXPORT_SYMBOL(ocm_inst_free);
35280 + * free a block in one of the ocm heaps, returns 0 if successful.
35282 +int ocm_free(const void *addr)
35284 + if (addr >= (void *)OCM_INST_HEAP_BEGIN
35285 + && addr < (void *)(OCM_INST_HEAP_END))
35286 + return ocm_inst_free(addr);
35290 +EXPORT_SYMBOL(ocm_free);
35293 +#ifdef CONFIG_PROC_FS
35294 +/* Need to keep line of output the same. Currently, that is 46 bytes
35295 + * (including newline).
35297 +static int _ocm_proc_read(char *buf, int *len, int count, const char *desc,
35298 + struct ocm_heap *ocmheap)
35300 + struct ocm_piece *pslot;
35301 + struct ocm_piece *pfree_head = &ocmheap->free_head;
35302 + struct ocm_piece *pused_head = &ocmheap->used_head;
35304 + /* The format is the following
35305 + * --- OCM 123456789012345 Size PID State \n
35306 + * 12345678-12345678 1234567890 12345 1234567890\n
35309 + l = sprintf(&buf[*len], "--- OCM %-15s Size PID State \n",
35315 + mutex_lock(&ocm_inst_heap.lock);
35318 + * search the relevant memory slot
35320 + pslot = pused_head->next;
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");
35329 + pslot = pslot->next;
35332 + pslot = pfree_head->next;
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");
35341 + pslot = pslot->next;
35344 + mutex_unlock(&ocm_inst_heap.lock);
35348 +static int ocm_proc_read(char *buf, char **start, off_t offset, int count,
35349 + int *eof, void *data)
35353 + if (_ocm_proc_read(buf, &len, count - len, "Inst Heap",
35361 +static int __init sram_proc_init(void)
35363 + struct proc_dir_entry *ptr;
35364 + ptr = create_proc_entry("ocm", S_IFREG | S_IRUGO, NULL);
35366 + printk(KERN_WARNING "unable to create /proc/ocm\n");
35369 + ptr->owner = THIS_MODULE;
35370 + ptr->read_proc = ocm_proc_read;
35373 +late_initcall(sram_proc_init);
35376 +++ b/arch/ubicom32/oprofile/ipProf.h
35378 +#ifndef __IP_PROF_H__
35379 +#define __IP_PROF_H__
35381 +/* This number MUST match what is used in the ultra configuration! */
35382 +#define IPPROFILETIO_MAX_SAMPLES 600
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) */
35401 +struct profilenode {
35402 + struct devtree_node dn;
35403 + volatile unsigned char enabled; /* Is the tio enabled to
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];
35418 +++ b/arch/ubicom32/oprofile/Makefile
35421 +# arch/ubicom32/Makefile
35422 +# Makefile for Oprofile support on Ubicom32
35424 +# (C) Copyright 2009, Ubicom, Inc.
35426 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
35442 +# Ubicom32 implementation derived from (with many thanks):
35448 +obj-$(CONFIG_OPROFILE) += oprofile.o
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 \
35456 +oprofile-y := $(DRIVER_OBJS) profile.o
35458 +++ b/arch/ubicom32/oprofile/profile.c
35461 + * arch/ubicom32/oprofile/profile.c
35462 + * Oprofile support for arch Ubicom32
35464 + * (C) Copyright 2009, Ubicom, Inc.
35466 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
35483 + * Ubicom32 implementation derived from (with many thanks):
35490 + * @file profile.c
35492 + * @remark Copyright 2002 OProfile authors
35493 + * @remark Read the file COPYING
35495 + * @author Hunyue Yau <hy@hy-research.com>
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>
35505 +#include <asm/devtree.h>
35506 +#include <asm/thread.h>
35508 +/* For identifying userland vs kernel address */
35509 +#include <asm/stacktrace.h>
35510 +#include "ipProf.h"
35512 +/* For communications with the backend */
35513 +static struct profilenode *profile_node;
35515 +/* Bitmask containing all Linux threads - as seen by the ROSR reg */
35516 +static unsigned long th_all_mask;
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).
35522 +unsigned int cpu_map[THREAD_ARCHITECTURAL_MAX];
35524 +static struct pt_regs regs;
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
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".
35538 + * ubicom32_build_cpu_th_mask()
35540 + * Build a lookup table for translation between hardware thread
35541 + * "ROSR" values and Linux CPU ids
35543 + * *** This gets executed on all CPUs at once! ***
35545 +static void ubicom32_build_cpu_th_mask(void *mask)
35547 + thread_t self = thread_get_self();
35548 + unsigned long *th_m = mask;
35550 + BUG_ON(self <= 0 || self >= THREAD_ARCHITECTURAL_MAX);
35551 + cpu_map[self] = smp_processor_id();
35553 + set_bit(self, th_m);
35557 + * profile_interrupt()
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
35566 +static irqreturn_t profile_interrupt(int irq, void *arg)
35568 + int i, buf_entry;
35570 + unsigned int bit_th;
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;
35579 + profile_node->busy = 1; /* Keep backend out */
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;
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);
35590 + if ((bit_th & th_all_mask) == 0)
35593 + regs.pc = profile_node->samples[buf_entry].pc;
35595 + is_kernel = ubicom32_is_kernel(regs.pc);
35597 + oprofile_add_ext_sample_cpu(regs.pc, ®s, 0, is_kernel,
35600 + profile_node->count = 0;
35601 + profile_node->busy = 0;
35603 + return IRQ_HANDLED;
35607 + * profile_start()
35609 + * Notification from oprofile to start the profiler
35611 +static int profile_start(void)
35613 + if (!profile_node)
35616 + profile_node->enabled = 1;
35624 + * Notification from oprofile to stop the profiler
35626 +static void profile_stop(void)
35628 + if (profile_node)
35629 + profile_node->enabled = 0;
35633 + * oprofile_arch_init()
35635 + * Attach to Oprofile after qualify the availability of the backend
35636 + * profiler support.
35638 +int __init oprofile_arch_init(struct oprofile_operations *ops)
35642 + profile_node = (struct profilenode *)devtree_find_node("profiler");
35644 + if (profile_node == NULL) {
35645 + printk(KERN_WARNING "Cannot find profiler node\n");
35649 + r = request_irq(profile_node->dn.recvirq, profile_interrupt,
35650 + IRQF_DISABLED, "profiler", NULL);
35653 + profile_node = NULL;
35654 + printk(KERN_WARNING "Cannot get profiler IRQ\n");
35658 + ops->start = profile_start;
35659 + ops->stop = profile_stop;
35660 + ops->cpu_type = "timer";
35662 + memset(cpu_map, 0, sizeof(cpu_map));
35664 + on_each_cpu(ubicom32_build_cpu_th_mask, &th_all_mask, 1);
35666 + memset(®s, 0, sizeof(regs));
35672 + * oprofile_arch_exit()
35674 + * External call to take outselves out.
35675 + * Make sure backend is not running.
35677 +void oprofile_arch_exit(void)
35679 + BUG_ON(profile_node->enabled);
35681 --- a/drivers/char/hw_random/Kconfig
35682 +++ b/drivers/char/hw_random/Kconfig
35683 @@ -134,3 +134,16 @@ config HW_RANDOM_VIRTIO
35685 To compile this driver as a module, choose M here: the
35686 module will be called virtio-rng. If unsure, say N.
35688 +config HW_RANDOM_UBICOM32
35689 + tristate "Ubicom32 HW Random Number Generator support"
35690 + depends on HW_RANDOM && UBICOM32
35691 + default HW_RANDOM
35693 + This driver provides kernel-side support for the Random Number
35694 + Generator hardware found on Ubicom32 processors.
35696 + To compile this driver as a module, choose M here: the
35697 + module will be called pasemi-rng.
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
35708 +++ b/drivers/char/hw_random/ubicom32-rng.c
35711 + * drivers/net/ubi32-eth.c
35712 + * Ubicom32 hardware random number generator driver.
35714 + * (C) Copyright 2009, Ubicom, Inc.
35716 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
35732 + * Ubicom32 implementation derived from (with many thanks):
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>
35745 +#define MODULE_NAME "ubicom32_rng"
35747 +static int ubicom32_rng_data_present(struct hwrng *rng, int wait)
35751 + for (i = 0; i < 20; i++) {
35752 + data = *(int *)(TIMER_BASE + TIMER_TRN);
35753 + if (data || !wait)
35760 +static int ubicom32_rng_data_read(struct hwrng *rng, u32 *data)
35762 + *data = *(int *)(TIMER_BASE + TIMER_TRN);
35766 +static int ubicom32_rng_init(struct hwrng *rng)
35768 + printk(KERN_INFO "ubicom32 rng init\n");
35769 + *(int *)(TIMER_BASE + TIMER_TRN_CFG) = TIMER_TRN_CFG_ENABLE_OSC;
35773 +static void ubicom32_rng_cleanup(struct hwrng *rng)
35775 + printk(KERN_INFO "ubicom32 rng cleanup\n");
35776 + *(int *)(TIMER_BASE + TIMER_TRN_CFG) = 0;
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,
35788 +static int __init mod_init(void)
35792 + printk(KERN_INFO "ubicom32 rng started\n");
35793 + err = hwrng_register(&ubicom32_rng);
35795 + printk(KERN_ERR "ubicom32 rng register failed (%d)\n",
35802 +static void __exit mod_exit(void)
35804 + printk(KERN_INFO "ubicom32 rng stopped\n");
35805 + hwrng_unregister(&ubicom32_rng);
35808 +module_init(mod_init);
35809 +module_exit(mod_exit);
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.
35821 +config CRYPTO_UBICOM32
35822 + bool "Ubicom32 Security Module"
35823 + depends on UBICOM32
35825 + This is the ubicom32 hardware acceleration common code.
35827 +config CRYPTO_AES_UBICOM32
35828 + tristate "Ubicom32 AES implementation"
35829 + depends on CRYPTO_UBICOM32
35830 + select CRYPTO_ALGAPI
35832 + This is the ubicom32 hardware AES implementation.
35834 +config CRYPTO_DES_UBICOM32
35835 + tristate "Ubicom32 DES implementation"
35836 + depends on CRYPTO_UBICOM32
35837 + select CRYPTO_ALGAPI
35839 + This is the ubicom32 hardware DES and 3DES implementation.
35841 +config CRYPTO_SHA1_UBICOM32
35842 + tristate "Ubicom32 SHA1 implementation"
35843 + depends on CRYPTO_UBICOM32
35844 + select CRYPTO_ALGAPI
35846 + This is the ubicom32 hardware SHA1 implementation.
35848 +config CRYPTO_MD5_UBICOM32
35849 + tristate "Ubicom32 MD5 implementation"
35850 + depends on CRYPTO_UBICOM32
35851 + select CRYPTO_ALGAPI
35853 + This is the ubicom32 hardware MD5 implementation.
35856 tristate "Support for PCI-attached cryptographic adapters"
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
35864 +config MMC_UBICOM32
35865 + tristate "Ubicom32 MMC/SD host controller"
35866 + depends on UBICOM32
35868 + This provides support for the SD/MMC hardware found on Ubicom32
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
35884 +++ b/drivers/mmc/host/ubicom32sd.c
35887 + * drivers/mmc/host/ubicom32sd.c
35888 + * Ubicom32 Secure Digital Host Controller Interface driver
35890 + * (C) Copyright 2009, Ubicom, Inc.
35892 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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>
35917 +#include <asm/ubicom32sd.h>
35919 +#define DRIVER_NAME "ubicom32sd"
35921 +#define sd_printk(...)
35922 +//#define sd_printk printk
35924 +#define SDTIO_VP_VERSION 3
35926 +#define SDTIO_MAX_SG_BLOCKS 16
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,
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)
35950 + * SDTIO_COMMAND_SETUP_SDIO
35952 +#define SDTIO_COMMAND_FLAG_SDIO_INT_EN (1 << 0)
35955 + * SDTIO_COMMAND_SETUP
35956 + * clock speed in arg
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)
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)
35967 +struct sdtio_vp_sg {
35968 + volatile void *addr;
35969 + volatile u32_t len;
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)
35985 +struct sdtio_vp_regs {
35990 + volatile u32_t int_status;
35992 + volatile u32_t command;
35993 + volatile u32_t arg;
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;
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;
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];
36017 +struct ubicom32sd_data {
36018 + const struct ubicom32sd_platform_data *pdata;
36020 + struct mmc_host *mmc;
36023 + * Lock used to protect the data structure
36030 + * Receive and transmit interrupts used for communicating
36037 + * Current outstanding mmc request
36039 + struct mmc_request *mrq;
36042 + * Hardware registers
36044 + struct sdtio_vp_regs *regs;
36047 +/*****************************************************************************\
36049 + * Suspend/resume *
36051 +\*****************************************************************************/
36053 +#if 0//def CONFIG_PM
36055 +int ubicom32sd_suspend_host(struct ubicom32sd_host *host, pm_message_t state)
36059 + ret = mmc_suspend_host(host->mmc, state);
36063 + free_irq(host->irq, host);
36068 +EXPORT_SYMBOL_GPL(ubicom32sd_suspend_host);
36070 +int ubicom32sd_resume_host(struct ubicom32sd_host *host)
36074 + if (host->flags & UBICOM32SD_USE_DMA) {
36075 + if (host->ops->enable_dma)
36076 + host->ops->enable_dma(host);
36079 + ret = request_irq(host->irq, ubicom32sd_irq, IRQF_SHARED,
36080 + mmc_hostname(host->mmc), host);
36084 + ubicom32sd_init(host);
36087 + ret = mmc_resume_host(host->mmc);
36094 +EXPORT_SYMBOL_GPL(ubicom32sd_resume_host);
36096 +#endif /* CONFIG_PM */
36099 + * ubicom32sd_send_command_sync
36101 +static void ubicom32sd_send_command_sync(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
36103 + ud->regs->command = command;
36104 + ud->regs->arg = arg;
36105 + ubicom32_set_interrupt(ud->irq_tx);
36106 + while (ud->regs->command) {
36112 + * ubicom32sd_send_command
36114 +static void ubicom32sd_send_command(struct ubicom32sd_data *ud, u32_t command, u32_t arg)
36116 + ud->regs->command = command;
36117 + ud->regs->arg = arg;
36118 + ubicom32_set_interrupt(ud->irq_tx);
36122 + * ubicom32sd_reset
36124 +static void ubicom32sd_reset(struct ubicom32sd_data *ud)
36126 + ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_RESET << SDTIO_COMMAND_SHIFT, 0);
36127 + ud->regs->int_status = 0;
36131 + * ubicom32sd_mmc_request
36133 +static void ubicom32sd_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
36135 + struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36136 + u32_t command = SDTIO_COMMAND_EXECUTE << SDTIO_COMMAND_SHIFT;
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);
36143 + struct mmc_command *cmd = mrq->cmd;
36145 + sd_printk("%s:\t\t\tsetup cmd %02d arg %08x flags %08x\n", mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags);
36147 + ud->regs->cmd_opcode = cmd->opcode;
36148 + ud->regs->cmd_arg = cmd->arg;
36150 + command |= SDTIO_COMMAND_FLAG_CMD;
36152 + if (cmd->flags & MMC_RSP_PRESENT) {
36153 + command |= SDTIO_COMMAND_FLAG_CMD_RSP;
36156 + if (cmd->flags & MMC_RSP_136) {
36157 + command |= SDTIO_COMMAND_FLAG_CMD_RSP_136;
36160 + if (cmd->flags & MMC_RSP_CRC) {
36161 + command |= SDTIO_COMMAND_FLAG_CMD_RSP_CRC;
36166 + struct mmc_data *data = mrq->data;
36167 + struct scatterlist *sg = data->sg;
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);
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);
36176 + if (data->sg_len > SDTIO_MAX_SG_BLOCKS) {
36178 + data->error = -EINVAL;
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;
36188 + * Load all of our sg list into the driver sg buffer
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));
36197 + data->error = -EINVAL;
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;
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);
36215 + ud->regs->stop_opcode = stop->opcode;
36216 + ud->regs->stop_arg = stop->arg;
36218 + command |= SDTIO_COMMAND_FLAG_STOP_CMD;
36220 + if (stop->flags & MMC_RSP_PRESENT) {
36221 + command |= SDTIO_COMMAND_FLAG_STOP_RSP;
36224 + if (stop->flags & MMC_RSP_136) {
36225 + command |= SDTIO_COMMAND_FLAG_STOP_RSP_136;
36228 + if (stop->flags & MMC_RSP_CRC) {
36229 + command |= SDTIO_COMMAND_FLAG_STOP_RSP_CRC;
36235 + sd_printk("%s: Sending command %08x\n", mmc_hostname(mmc), command);
36237 + ubicom32sd_send_command(ud, command, 0);
36241 + sd_printk("%s: mmcreq ret = %d\n", mmc_hostname(mmc), ret);
36242 + mrq->cmd->error = ret;
36243 + mmc_request_done(mmc, mrq);
36247 + * ubicom32sd_mmc_set_ios
36249 +static void ubicom32sd_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
36251 + struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36252 + u32_t command = SDTIO_COMMAND_SETUP << SDTIO_COMMAND_SHIFT;
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);
36256 + switch (ios->bus_width) {
36257 + case MMC_BUS_WIDTH_1:
36258 + command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_1BIT;
36261 + case MMC_BUS_WIDTH_4:
36262 + command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_4BIT;
36266 + if (ios->clock) {
36267 + arg = ios->clock;
36268 + command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
36271 + switch (ios->power_mode) {
36274 + * Turn off the SD bus (power + clock)
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;
36282 + * Turn on the power to the SD bus
36284 + case MMC_POWER_ON:
36285 + gpio_set_value(ud->pdata->cards[0].pin_pwr, ud->pdata->cards[0].pwr_polarity);
36289 + * Turn on the clock to the SD bus
36291 + case MMC_POWER_UP:
36298 + ubicom32sd_send_command_sync(ud, command, arg);
36301 + * Let the power settle down
36307 + * ubicom32sd_mmc_get_cd
36309 +static int ubicom32sd_mmc_get_cd(struct mmc_host *mmc)
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));
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;
36320 + * ubicom32sd_mmc_get_ro
36322 +static int ubicom32sd_mmc_get_ro(struct mmc_host *mmc)
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));
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;
36333 + * ubicom32sd_mmc_enable_sdio_irq
36335 +static void ubicom32sd_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
36337 + struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36339 + ud->int_en = enable;
36340 + if (enable && ud->int_pend) {
36341 + ud->int_pend = 0;
36342 + mmc_signal_sdio_irq(mmc);
36347 + * ubicom32sd_interrupt
36349 +static irqreturn_t ubicom32sd_interrupt(int irq, void *dev)
36351 + struct mmc_host *mmc = (struct mmc_host *)dev;
36352 + struct mmc_request *mrq;
36353 + struct ubicom32sd_data *ud;
36354 + u32_t int_status;
36357 + return IRQ_HANDLED;
36360 + ud = (struct ubicom32sd_data *)mmc_priv(mmc);
36362 + return IRQ_HANDLED;
36365 + int_status = ud->regs->int_status;
36366 + ud->regs->int_status &= ~int_status;
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);
36377 + if (!(int_status & SDTIO_VP_INT_STATUS_DONE)) {
36378 + return IRQ_HANDLED;
36383 + sd_printk("%s: Spurious interrupt", mmc_hostname(mmc));
36384 + return IRQ_HANDLED;
36389 + * SDTIO_VP_INT_DONE
36391 + if (mrq->cmd->flags & MMC_RSP_PRESENT) {
36392 + struct mmc_command *cmd = mrq->cmd;
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;
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;
36406 + cmd->resp[0] = ud->regs->cmd_rsp0;
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);
36412 + struct mmc_data *data = mrq->data;
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));
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));
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));
36428 + data->bytes_xfered = ud->regs->data_bytes_transferred;
36432 + if (mrq->stop && (mrq->stop->flags & MMC_RSP_PRESENT)) {
36433 + struct mmc_command *stop = mrq->stop;
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;
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;
36447 + stop->resp[0] = ud->regs->stop_rsp0;
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);
36453 + mmc_request_done(mmc, mrq);
36455 + return IRQ_HANDLED;
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,
36467 + * ubicom32sd_probe
36469 +static int __devinit ubicom32sd_probe(struct platform_device *pdev)
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;
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.
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) {
36493 + * Reserve any gpios we need
36495 + ret = gpio_request(pdata->cards[0].pin_wp, "sd-wp");
36499 + gpio_direction_input(pdata->cards[0].pin_wp);
36501 + ret = gpio_request(pdata->cards[0].pin_cd, "sd-cd");
36505 + gpio_direction_input(pdata->cards[0].pin_cd);
36508 + * HACK: for the dual port controller on port F, we don't support the second port right now
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);
36516 + ret = gpio_request(pdata->cards[0].pin_pwr, "sd-pwr");
36520 + gpio_direction_output(pdata->cards[0].pin_pwr, !pdata->cards[0].pwr_polarity);
36523 + * Allocate the MMC driver, it includes memory for our data.
36525 + mmc = mmc_alloc_host(sizeof(struct ubicom32sd_data), &pdev->dev);
36530 + ud = (struct ubicom32sd_data *)mmc_priv(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);
36538 + ret = request_irq(ud->irq_rx, ubicom32sd_interrupt, IRQF_DISABLED, mmc_hostname(mmc), mmc);
36544 + * Fill in the mmc structure
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;
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;
36555 + * Setup some restrictions on transfers
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?!...
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.
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;
36572 + mmc->max_blk_size = 2048;
36574 + ubicom32sd_reset(ud);
36577 + * enable interrupts
36580 + ubicom32sd_send_command_sync(ud, SDTIO_COMMAND_SETUP_SDIO << SDTIO_COMMAND_SHIFT | SDTIO_COMMAND_FLAG_SDIO_INT_EN, 0);
36582 + mmc_add_host(mmc);
36584 + printk(KERN_INFO "%s at %p, irq %d/%d\n", mmc_hostname(mmc),
36585 + ud->regs, ud->irq_tx, ud->irq_rx);
36589 + gpio_free(pdata->cards[0].pin_pwr);
36591 + gpio_free(pdata->cards[0].pin_cd);
36593 + gpio_free(pdata->cards[0].pin_wp);
36599 + * ubicom32sd_remove
36601 +static int __devexit ubicom32sd_remove(struct platform_device *pdev)
36603 + struct mmc_host *mmc = platform_get_drvdata(pdev);
36605 + platform_set_drvdata(pdev, NULL);
36608 + struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
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);
36614 + mmc_remove_host(mmc);
36615 + mmc_free_host(mmc);
36619 + * Note that our data is allocated as part of the mmc structure
36620 + * so we don't need to free it.
36625 +static struct platform_driver ubicom32sd_driver = {
36627 + .name = DRIVER_NAME,
36628 + .owner = THIS_MODULE,
36630 + .probe = ubicom32sd_probe,
36631 + .remove = __devexit_p(ubicom32sd_remove),
36633 + .suspend = ubicom32sd_suspend,
36634 + .resume = ubicom32sd_resume,
36639 + * ubicom32sd_init
36641 +static int __init ubicom32sd_init(void)
36643 + return platform_driver_register(&ubicom32sd_driver);
36645 +module_init(ubicom32sd_init);
36648 + * ubicom32sd_exit
36650 +static void __exit ubicom32sd_exit(void)
36652 + platform_driver_unregister(&ubicom32sd_driver);
36654 +module_exit(ubicom32sd_exit);
36656 +MODULE_AUTHOR("Patrick Tjin");
36657 +MODULE_DESCRIPTION("Ubicom32 Secure Digital Host Controller Interface driver");
36658 +MODULE_LICENSE("GPL");
36660 --- a/drivers/mtd/devices/Kconfig
36661 +++ b/drivers/mtd/devices/Kconfig
36662 @@ -104,6 +104,17 @@ config M25PXX_USE_FAST_READ
36664 This option enables FAST_READ access supported by ST M25Pxx.
36666 +config MTD_UBI32_M25P80
36667 + tristate "Ubicom processor support for most SPI Flash chips (AT26DF, M25P, W25X, ...)"
36668 + depends on UBICOM32
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.
36678 tristate "Uncached system RAM"
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
36688 +++ b/drivers/mtd/devices/ubi32-m25p80.c
36691 + * drivers/mtd/devices/ubi32-m25p80.c
36692 + * NOR flash driver, Ubicom processor internal SPI flash interface.
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.
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.
36701 + * (C) Copyright 2009, Ubicom, Inc.
36703 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
36719 + * Ubicom32 implementation derived from (with many thanks):
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>
36733 +#include <linux/init.h>
36734 +#include <linux/module.h>
36735 +#include <linux/interrupt.h>
36736 +#include <linux/mutex.h>
36738 +#include <asm/ip5000.h>
36739 +#include <asm/devtree.h>
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. */
36747 +static struct mtd_partition ubicom32_flash_partitions[] = {
36749 + .name = "Bootloader", /* Protected Section
36752 + .offset = UBICOM32_FLASH_START,
36753 +// .mask_flags = MTD_WRITEABLE /* Mark Read-only */
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
36761 + .offset = MTDPART_OFS_APPEND, /* Starts right after Protected
36763 +// .mask_flags = MTD_WRITEABLE /* Mark Read-only */
36766 + .name = "Rest", /* Rest of the flash. */
36767 + .size = 0x200000, /* Use up what remains in the
36769 + .offset = MTDPART_OFS_NXTBLK, /* Starts right after Protected
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),
36780 +static struct resource ubicom32_flash_resource[] = {
36782 + .start = UBICOM32_FLASH_BASE,
36783 + .end = UBICOM32_FLASH_BASE +
36784 + UBICOM32_FLASH_MAX_SIZE - 1,
36785 + .flags = IORESOURCE_MEM,
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,
36795 + .platform_data = &ubicom32_flash_data,
36799 +static struct platform_device *ubicom32_flash_devices[] = {
36800 + &ubicom32_flash_device,
36803 +static int __init ubicom32_flash_init(void)
36805 + printk(KERN_INFO "%s(): registering device resources\n",
36807 + platform_add_devices(ubicom32_flash_devices,
36808 + ARRAY_SIZE(ubicom32_flash_devices));
36812 +arch_initcall(ubicom32_flash_init);
36815 + * MTD SPI driver for ST M25Pxx (and similar) serial flash chips through
36816 + * Ubicom32 SPI controller.
36818 + * Author: Mike Lavender, mike@steroidmicros.com
36820 + * Copyright (c) 2005, Intec Automation Inc.
36822 + * Some parts are based on lart.c by Abraham Van Der Merwe
36824 + * Cleaned up and generalized based on mtd_dataflash.c
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.
36832 +#define FLASH_PAGESIZE 256
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 */
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 */
36854 +/* Define max times to check status register before we give up. */
36855 +#define MAX_READY_WAIT_COUNT 100000
36858 +#ifdef CONFIG_MTD_PARTITIONS
36859 +#define mtd_has_partitions() (1)
36861 +#define mtd_has_partitions() (0)
36865 + * Ubicom32 FLASH Command Set
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 */
36871 +#define ALIGN_DOWN(v, a) ((v) & ~((a) - 1))
36872 +#define ALIGN_UP(v, a) (((v) + ((a) - 1)) & ~((a) - 1))
36874 +#define FLASH_COMMAND_KICK_OFF(io) \
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" \
36881 + : "memory", "cc" \
36884 +#define FLASH_COMMAND_WAIT_FOR_COMPLETION(io) \
36886 + " btst "D(IO_INT_STATUS)"(%0), #%%bit("D(IO_XFL_INT_DONE)") \n\t" \
36887 + " jmpeq.f .-4 \n\t" \
36890 + : "memory", "cc" \
36893 +#define FLASH_COMMAND_EXEC(io) \
36894 + FLASH_COMMAND_KICK_OFF(io) \
36895 + FLASH_COMMAND_WAIT_FOR_COMPLETION(io)
36898 +#define OSC1_FREQ 12000000
36899 +#define TEN_MICRO_SECONDS (OSC1_FREQ * 10 / 1000000)
36902 + * We will have to eventually replace this null definition with the real thing.
36904 +#define WATCHDOG_RESET()
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
36912 +#define JFFS2_FILESYSTEM_SIZE 0x100000
36914 +/****************************************************************************/
36917 + struct platform_device *plt_dev;
36918 + struct mutex lock;
36919 + struct mtd_info mtd;
36920 + unsigned partitioned:1;
36925 +static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
36927 + return container_of(mtd, struct m25p, mtd);
36930 +/****************************************************************************/
36933 + * Internal helper functions
36937 + * Read the status register, returning its value in the location
36938 + * Return the status register value.
36939 + * Returns negative if error occurred.
36941 +static int read_sr(struct m25p *flash)
36943 + struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
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);
36951 + return io->status1 & 0xff;
36955 + * mem_flash_io_read_u32()
36957 +static u32 mem_flash_io_read_u32(u32 addr)
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;
36971 + * mem_flash_read_u8()
36973 +static u8 mem_flash_read_u8(u32 addr)
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];
36982 + * mem_flash_read()
36983 + * No need to lock as read is implemented with ireads (same as normal flash
36986 +static void mem_flash_read(u32 addr, void *dst, size_t length)
36992 + * Fix source alignment.
36994 + while (addr & 0x03) {
36995 + if (length == 0) {
36998 + *((u8 *)dst) = mem_flash_read_u8(addr++);
37003 + while (length >= 4) {
37004 + u32 tmp_data = mem_flash_io_read_u32(addr);
37009 + * Send the data to the destination.
37011 + memcpy((void *)dst, (void *)&tmp_data, 4);
37015 + while (length--) {
37016 + *((u8 *)dst) = mem_flash_read_u8(addr++);
37022 + * mem_flash_wait_until_complete()
37024 +static void mem_flash_wait_until_complete(void)
37026 + struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37030 + * Put a delay here to deal with flash programming problem.
37032 + u32 mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
37033 + while (UBICOM32_IO_TIMER->mptval < mptval)
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);
37045 + * mem_flash_write_next()
37047 +static size_t mem_flash_write_next(u32 addr, u8 *buf, size_t length)
37049 + struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37050 + u32 data_start = addr;
37051 + u32 data_end = addr + length;
37056 + * Top limit address.
37058 + u32 block_start = ALIGN_DOWN(data_start, 4);
37059 + u32 block_end = block_start + EXTFLASH_WRITE_BLOCK_SIZE;
37062 + u8 byte[EXTFLASH_WRITE_BLOCK_SIZE];
37063 + u32 word[EXTFLASH_WRITE_BLOCK_SIZE / 4];
37066 + u32 *flash_addr = (u32 *)block_start;
37069 + * The write block must be limited by FLASH internal buffer.
37071 + u32 block_end_align = ALIGN_DOWN(block_end, 256);
37072 + bool write_needed;
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;
37081 + * Transfer data to a buffer.
37083 + for (i = 0; i < (block_end - block_start) / 4; i++) {
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)
37089 + write_buf.word[i] = mem_flash_io_read_u32(
37090 + (u32)(&flash_addr[i]));
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];
37102 + * If the data in FLASH is identical to what to be written. Then skip
37105 + if (write_needed) {
37107 + * Write to flash.
37109 + void *tmp __attribute__((unused));
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"
37120 + : "a" (io), "r" (&write_buf.word[0])
37124 + /* Lock FLASH for write access. */
37125 + io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
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);
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);
37142 + extra_words = (s32)(block_end - block_start -
37143 + EXTFLASH_WRITE_FIFO_SIZE) / 4;
37144 + if (extra_words > 0) {
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"
37153 + : "a" (io), "d" (extra_words),
37154 + "r" (&write_buf.word[EXTFLASH_WRITE_FIFO_SIZE / 4])
37158 + FLASH_COMMAND_WAIT_FOR_COMPLETION(io);
37160 + mem_flash_wait_until_complete();
37163 + /* Unlock FLASH for cache access. */
37164 + io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
37174 + * mem_flash_write()
37176 +static void mem_flash_write(u32 addr, const void *src, size_t length)
37181 + u8_t *ptr = (u8_t *)src;
37183 + size_t count = mem_flash_write_next(addr, ptr, length);
37191 + * Service routine to read status register until ready, or timeout occurs.
37192 + * Returns non-zero if error.
37194 +static int wait_till_ready(struct m25p *flash)
37199 + /* one chip guarantees max 5 msec wait here after page writes,
37200 + * but potentially three seconds (!) after page erase.
37202 + for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
37204 + sr = read_sr(flash);
37207 + else if (!(sr & SR_WIP))
37211 + * Put a 10us delay here to deal with flash programming problem.
37213 + mptval = UBICOM32_IO_TIMER->mptval + TEN_MICRO_SECONDS;
37214 + while ((s32)(mptval - UBICOM32_IO_TIMER->mptval) > 0) {
37215 + WATCHDOG_RESET();
37217 + /* REVISIT sometimes sleeping would be best */
37224 + * mem_flash_erase_page()
37226 +static void mem_flash_erase_page(u32 addr)
37228 + struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37230 + /* Lock FLASH for write access. */
37231 + io->ctl0 |= IO_XFL_CTL0_MCB_LOCK;
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);
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);
37247 + mem_flash_wait_until_complete();
37249 + /* Unlock FLASH for cache access. */
37250 + io->ctl0 &= ~IO_XFL_CTL0_MCB_LOCK;
37254 + * mem_flash_erase()
37256 +static u32 mem_flash_erase(u32 addr, u32 length)
37259 + * Calculate the endaddress to be the first address of the page
37260 + * just beyond this erase section of pages.
37262 + u32 endaddr = addr + length;
37267 + while (addr < endaddr) {
37268 + u32 test_addr = addr;
37269 + mem_flash_erase_page(addr);
37272 + * Test how much was erased as actual flash page at this address
37273 + * may be smaller than the expected page size.
37275 + while (test_addr < endaddr) {
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
37282 + if (mem_flash_io_read_u32(test_addr) != 0xFFFFFFFF) {
37287 + if (test_addr == addr) {
37288 + printk("erase failed at address 0x%x, skipping",
37293 + addr = test_addr;
37299 +/****************************************************************************/
37302 + * MTD implementation
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.
37309 +static int ubicom32_flash_driver_erase(struct mtd_info *mtd,
37310 + struct erase_info *instr)
37312 + struct m25p *flash = mtd_to_m25p(mtd);
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);
37319 + /* sanity checks */
37320 + if (instr->addr + instr->len > flash->mtd.size)
37322 + if ((instr->addr % mtd->erasesize) != 0
37323 + || (instr->len % mtd->erasesize) != 0) {
37327 + addr = instr->addr + UBICOM32_FLASH_BASE;
37328 + len = instr->len;
37330 + mutex_lock(&flash->lock);
37332 + /* REVISIT in some cases we could speed up erasing large regions
37333 + * by using OPCODE_SE instead of OPCODE_BE_4K
37336 + /* now erase those sectors */
37337 + if (mem_flash_erase(addr, len)) {
37338 + instr->state = MTD_ERASE_FAILED;
37339 + mutex_unlock(&flash->lock);
37343 + mutex_unlock(&flash->lock);
37344 + instr->state = MTD_ERASE_DONE;
37345 + mtd_erase_callback(instr);
37350 + * Read an address range from the flash chip. The address range
37351 + * may be any size provided it is within the physical boundaries.
37353 +static int ubicom32_flash_driver_read(struct mtd_info *mtd, loff_t from,
37354 + size_t len, size_t *retlen, u_char *buf)
37356 + struct m25p *flash = mtd_to_m25p(mtd);
37357 + u32 base_addr = UBICOM32_FLASH_BASE + from;
37359 + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
37360 + flash->plt_dev->dev.bus_id, __FUNCTION__, "from",
37363 + /* sanity checks */
37367 + if (from + len > flash->mtd.size)
37370 + /* Byte count starts at zero. */
37374 + mutex_lock(&flash->lock);
37376 + /* Wait till previous write/erase is done. */
37377 + if (wait_till_ready(flash)) {
37378 + /* REVISIT status return?? */
37379 + mutex_unlock(&flash->lock);
37383 + mem_flash_read(base_addr, (void *)buf, len);
37388 + mutex_unlock(&flash->lock);
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.
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)
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",
37411 + /* sanity checks */
37415 + if (to + len > flash->mtd.size)
37418 + mutex_lock(&flash->lock);
37420 + mem_flash_write(base_addr, (void *) buf, len);
37422 + /* Wait until finished previous write command. */
37423 + if (wait_till_ready(flash)) {
37424 + mutex_unlock(&flash->lock);
37431 + mutex_unlock(&flash->lock);
37436 +/****************************************************************************/
37439 + * SPI device driver setup and teardown
37442 +struct flash_info {
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.
37451 + /* The size listed here is what works with OPCODE_SE, which isn't
37452 + * necessarily called a "sector" by the vendor.
37454 + unsigned sector_size;
37458 +#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
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.
37466 +static struct flash_info __devinitdata m25p_data[] = {
37468 + /* Atmel -- some are (confusingly) marketed as "DataFlash" */
37469 + { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, },
37470 + { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, },
37472 + { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
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, },
37479 + /* Spansion -- single (large) sector size only, at least
37480 + * for the chips listed here (without boot sectors).
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, },
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, },
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, },
37505 + { "m45pe80", 0x204014, 64 * 1024, 16, },
37506 + { "m45pe16", 0x204015, 64 * 1024, 32, },
37508 + { "m25pe80", 0x208014, 64 * 1024, 16, },
37509 + { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, },
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, },
37520 + /* Macronix -- mx25lxxx */
37521 + { "mx25l32", 0xc22016, 64 * 1024, 64, },
37522 + { "mx25l64", 0xc22017, 64 * 1024, 128, },
37523 + { "mx25l128", 0xc22018, 64 * 1024, 256, },
37527 +struct flash_info *__devinit jedec_probe(struct platform_device *spi)
37531 + struct flash_info *info;
37532 + struct ubicom32_io_port *io = (struct ubicom32_io_port *)RA;
37535 + * Setup and run RDID command on the flash.
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);
37543 + jedec = io->status1 & 0x00ffffff;
37545 + for (tmp = 0, info = m25p_data;
37546 + tmp < ARRAY_SIZE(m25p_data);
37548 + if (info->jedec_id == jedec)
37551 + dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
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).
37561 +static int __devinit ubicom32_flash_probe(struct platform_device *spi)
37563 + struct flash_platform_data *data;
37564 + struct m25p *flash;
37565 + struct flash_info *info;
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.
37573 + data = spi->dev.platform_data;
37574 + if (data && data->type) {
37575 + for (i = 0, info = m25p_data;
37576 + i < ARRAY_SIZE(m25p_data);
37578 + if (strcmp(data->type, info->name) == 0)
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);
37588 + /* recognized; is that chip really what's there? */
37589 + } else if (info->jedec_id) {
37590 + struct flash_info *chip = jedec_probe(spi);
37592 + if (!chip || chip != info) {
37593 + dev_warn(&spi->dev, "found %s, expected %s\n",
37594 + chip ? chip->name : "UNKNOWN",
37600 + info = jedec_probe(spi);
37605 + flash = kzalloc(sizeof *flash, GFP_KERNEL);
37609 + flash->plt_dev = spi;
37610 + mutex_init(&flash->lock);
37611 + dev_set_drvdata(&spi->dev, flash);
37613 + if (data && data->name)
37614 + flash->mtd.name = data->name;
37616 + flash->mtd.name = spi->dev.bus_id;
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;
37626 + /* prefer "small sector" erase if possible */
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.
37632 + * This was: `if (info->flags & SECT_4K) {' instead of `if (0) {'
37635 + flash->erase_opcode = OPCODE_BE_4K;
37636 + flash->mtd.erasesize = 4096;
37638 + flash->erase_opcode = OPCODE_SE;
37639 + flash->mtd.erasesize = info->sector_size;
37642 + dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
37643 + flash->mtd.size / 1024);
37645 + DEBUG(MTD_DEBUG_LEVEL2,
37646 + "mtd .name = %s, .size = 0x%.8x (%uMiB) "
37647 + ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
37649 + flash->mtd.size, flash->mtd.size / (1024*1024),
37650 + flash->mtd.erasesize, flash->mtd.erasesize / 1024,
37651 + flash->mtd.numeraseregions);
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);
37665 + /* partitions should match sector boundaries; and it may be good to
37666 + * use readonly partitions for writeprotected sectors (BP2..BP0).
37668 + if (mtd_has_partitions()) {
37669 + struct mtd_partition *parts = NULL;
37670 + int nr_parts = 0;
37672 +#ifdef CONFIG_MTD_CMDLINE_PARTS
37673 + static const char *part_probes[] = { "cmdlinepart", NULL, };
37675 + nr_parts = parse_mtd_partitions(&flash->mtd,
37676 + part_probes, &parts, 0);
37679 + if (nr_parts <= 0 && data && data->parts) {
37680 + parts = data->parts;
37681 + nr_parts = data->nr_parts;
37682 + if (nr_parts >= 2) {
37684 + * Set last partition size to be 1M.
37686 + parts[1].size = flash->mtd.size -
37687 + parts[0].size - JFFS2_FILESYSTEM_SIZE;
37688 + parts[2].size = JFFS2_FILESYSTEM_SIZE;
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,
37700 + parts[i].size / 1024);
37702 + flash->partitioned = 1;
37703 + return add_mtd_partitions(&flash->mtd, parts, nr_parts);
37705 + } else if (data->nr_parts)
37706 + dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
37707 + data->nr_parts, data->name);
37709 + return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
37713 +static int __devexit ubicom32_flash_remove(struct spi_device *spi)
37715 + struct m25p *flash = dev_get_drvdata(&spi->dev);
37718 + /* Clean up MTD stuff. */
37719 + if (mtd_has_partitions() && flash->partitioned)
37720 + status = del_mtd_partitions(&flash->mtd);
37722 + status = del_mtd_device(&flash->mtd);
37728 +static struct platform_driver ubicom32_flash_driver = {
37730 + .name = "ubicom32flashdriver",
37731 + .bus = &platform_bus_type,
37732 + .owner = THIS_MODULE,
37734 + .probe = ubicom32_flash_probe,
37738 +static int ubicom32_flash_driver_init(void)
37740 + return platform_driver_register(&ubicom32_flash_driver);
37744 +static void ubicom32_flash_driver_exit(void)
37746 + platform_driver_unregister(&ubicom32_flash_driver);
37750 +module_init(ubicom32_flash_driver_init);
37751 +module_exit(ubicom32_flash_driver_exit);
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.
37762 +config UBICOM32_GMAC
37763 + tristate "Ubicom Gigabit Ethernet support (EXPERIMENTAL)"
37764 + depends on UBICOM32
37766 + Gigabit Ethernet support for IP5K/IP7K
37768 +config UBICOM32_NAPI
37769 + bool "USE NAPI (EXPERIMENTAL)"
37770 + depends on UBICOM32_GMAC
37772 + Use NAPI for Ubicom's Ethernet driver
37774 +config UBICOM32_OCM_FOR_SKB
37775 + bool "USE OCM for SKB (EXPERIMENTAL)"
37776 + depends on UBICOM32_GMAC
37779 + Allocate skb from OCM for Ethernet Receive
37781 endif # NETDEV_1000
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/
37791 +obj-$(CONFIG_UBICOM32_GMAC) += ubi32-eth.o
37793 +++ b/drivers/net/ubi32-eth.c
37796 + * drivers/net/ubi32-eth.c
37797 + * Ubicom32 ethernet TIO interface driver.
37799 + * (C) Copyright 2009, Ubicom, Inc.
37801 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
37817 + * Ubicom32 implementation derived from (with many thanks):
37824 + * Ethernet driver for Ip5k/Ip7K
37827 +#include <linux/module.h>
37828 +#include <linux/init.h>
37829 +#include <linux/moduleparam.h>
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>
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>
37851 +/* #define USE_POLLING */
37855 + * mac address from flash
37856 + * multicast filter
37857 + * ethtool support
37859 + * skb->nrfrag support
37861 + * monitor phy status
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'}};
37873 +int ubi32_eth_ocm_alloc;
37874 +int ubi32_eth_ddr_alloc;
37876 +static inline struct sk_buff *ubi32_alloc_skb(struct net_device *dev, unsigned int length)
37878 +#if (defined(CONFIG_ZONE_DMA) && defined(CONFIG_UBICOM32_OCM_FOR_SKB))
37879 + struct sk_buff *sk_buff;
37881 + if (dev != ubi32_eth_devices[0])
37882 + return __dev_alloc_skb(length, GFP_ATOMIC);
37884 + sk_buff = __dev_alloc_skb(length, GFP_ATOMIC | __GFP_NOWARN | __GFP_NORETRY | GFP_DMA);
37886 + ubi32_eth_ocm_alloc++;
37889 + ubi32_eth_ddr_alloc++;
37890 + return __dev_alloc_skb(length, GFP_ATOMIC);
37893 + return __dev_alloc_skb(length, GFP_ATOMIC);
37897 +static void ubi32_eth_vp_rxtx_enable(struct net_device *dev)
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);
37905 +static void ubi32_eth_vp_rxtx_stop(struct net_device *dev)
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);
37912 + /* Wait for graceful shutdown */
37913 + while (priv->regs->status & (UBI32_ETH_VP_STATUS_RX_STATE | UBI32_ETH_VP_STATUS_TX_STATE));
37917 + * ubi32_eth_tx_done()
37919 +static int ubi32_eth_tx_done(struct net_device *dev)
37921 + struct ubi32_eth_private *priv;
37922 + struct sk_buff *skb;
37923 + volatile void *pdata;
37924 + struct ubi32_eth_dma_desc *desc;
37927 + priv = netdev_priv(dev);
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);
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);
37939 + priv->stats.tx_packets++;
37940 + priv->stats.tx_bytes += skb->len;
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;
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);
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
37964 +static int ubi32_eth_receive(struct net_device *dev, int quota)
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;
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;
37981 + BUG_ON((extra_reserve & 3) != NET_IP_ALIGN); /* Must provide NET_IP_ALIGN (0 or 2) */
37983 + if (unlikely(rx_in == priv->regs->rx_out))
37984 + priv->vp_stats.rx_q_full_cnt++;
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++;
37994 + pdata = priv->regs->rx_dma_ring[priv->rx_tail];
37995 + BUG_ON(pdata == NULL);
37997 + desc = (struct ubi32_eth_dma_desc *)pdata;
37998 + skb = container_of((void *)pdata, struct sk_buff, cb);
38000 + priv->regs->rx_dma_ring[priv->rx_tail] = NULL;
38001 + priv->rx_tail = ((priv->rx_tail + 1) & RX_DMA_RING_MASK);
38004 + * Check only RX_OK bit here.
38005 + * The rest of status word is used as timestamp
38007 + if (unlikely(!(desc->status & UBI32_ETH_VP_RX_OK))) {
38008 + priv->stats.rx_errors++;
38009 + dev_kfree_skb_any(skb);
38013 + skb_put(skb, desc->data_len);
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
38022 + netif_receive_skb(skb);
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);
38033 + priv->vp_stats.rx_alloc_err++;
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;
38048 + priv->regs->rx_in = rx_in;
38049 + ubicom32_set_interrupt(priv->vp_int_bit);
38052 + if (likely(count > 0)) {
38053 + dev->last_rx = jiffies;
38058 +#ifdef CONFIG_UBICOM32_NAPI
38059 +static int ubi32_eth_napi_poll(struct napi_struct *napi, int budget)
38061 + struct ubi32_eth_private *priv = container_of(napi, struct ubi32_eth_private, napi);
38062 + struct net_device *dev = priv->dev;
38065 + if (priv->tx_tail != priv->regs->tx_out) {
38066 + ubi32_eth_tx_done(dev);
38069 + count = ubi32_eth_receive(dev, budget);
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;
38084 +static void ubi32_eth_do_tasklet(unsigned long arg)
38086 + struct net_device *dev = (struct net_device *)arg;
38087 + struct ubi32_eth_private *priv = netdev_priv(dev);
38089 + if (priv->tx_tail != priv->regs->tx_out) {
38090 + ubi32_eth_tx_done(dev);
38093 + /* always call receive to process new RX frame as well as replenish RX buffers */
38094 + ubi32_eth_receive(dev, RX_BOUND);
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);
38104 +#if defined(USE_POLLING)
38105 +static struct timer_list eth_poll_timer;
38107 +static void ubi32_eth_poll(unsigned long arg)
38109 + struct net_device *dev;
38110 + struct ubi32_eth_private *priv;
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);
38120 + tasklet_schedule(&priv->tsk);
38125 + eth_poll_timer.expires = jiffies + 2;
38126 + add_timer(ð_poll_timer);
38130 +static irqreturn_t ubi32_eth_interrupt(int irq, void *dev_id)
38132 + struct ubi32_eth_private *priv;
38134 + struct net_device *dev = (struct net_device *)dev_id;
38135 + BUG_ON(irq != dev->irq);
38137 + priv = netdev_priv(dev);
38138 + if (unlikely(!(priv->regs->int_status & priv->regs->int_mask))) {
38143 + * Disable port interrupt
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);
38151 + priv->regs->int_mask = 0;
38152 + tasklet_schedule(&priv->tsk);
38154 + return IRQ_HANDLED;
38161 +static int ubi32_eth_open(struct net_device *dev)
38163 + struct ubi32_eth_private *priv = netdev_priv(dev);
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);
38171 + printk(KERN_WARNING "fail to request_irq %d\n",err);
38175 +#ifdef CONFIG_UBICOM32_NAPI
38176 + napi_enable(&priv->napi);
38178 + tasklet_init(&priv->tsk, ubi32_eth_do_tasklet, (unsigned long)dev);
38181 + /* call receive to supply RX buffers */
38182 + ubi32_eth_receive(dev, RX_DMA_MAX_QUEUE_SIZE);
38184 + /* check phy status and call netif_carrier_on */
38185 + ubi32_eth_vp_rxtx_enable(dev);
38186 + netif_start_queue(dev);
38190 +static int ubi32_eth_close(struct net_device *dev)
38192 + struct ubi32_eth_private *priv = netdev_priv(dev);
38193 + volatile void *pdata;
38194 + struct sk_buff *skb;
38196 +#ifndef USE_POLLING
38197 + free_irq(dev->irq, dev);
38199 + netif_stop_queue(dev); /* can't transmit any more */
38200 +#ifdef CONFIG_UBICOM32_NAPI
38201 + napi_disable(&priv->napi);
38203 + tasklet_kill(&priv->tsk);
38205 + ubi32_eth_vp_rxtx_stop(dev);
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);
38217 + priv->regs->rx_in = 0;
38218 + priv->regs->rx_out = priv->regs->rx_in;
38219 + priv->rx_tail = priv->regs->rx_in;
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;
38235 + * ubi32_eth_set_config
38237 +static int ubi32_eth_set_config(struct net_device *dev, struct ifmap *map)
38239 + /* if must to down to config it */
38240 + printk(KERN_INFO "set_config %x\n", dev->flags);
38241 + if (dev->flags & IFF_UP)
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;
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;
38257 + /* ignore other fields */
38261 +static int ubi32_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
38263 + struct ubi32_eth_private *priv = netdev_priv(dev);
38264 + struct ubi32_eth_dma_desc *desc = NULL;
38265 + unsigned short space, tx_in;
38267 + tx_in = priv->regs->tx_in;
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);
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);
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);
38287 + ubicom32_set_interrupt(priv->vp_int_bit);
38289 + return NETDEV_TX_BUSY;
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);
38299 + priv->regs->tx_in = tx_in;
38300 + /* kick the HRT */
38301 + ubicom32_set_interrupt(priv->vp_int_bit);
38307 + * Deal with a transmit timeout.
38309 +static void ubi32_eth_tx_timeout (struct net_device *dev)
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);
38317 + ubicom32_set_interrupt(priv->vp_int_bit);
38320 +static int ubi32_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
38322 + printk(KERN_INFO "ioctl %s, %d\n", dev->name, cmd);
38327 + * Return statistics to the caller
38329 +static struct net_device_stats *ubi32_eth_get_stats(struct net_device *dev)
38331 + struct ubi32_eth_private *priv = netdev_priv(dev);
38332 + return &priv->stats;
38336 +static int ubi32_eth_change_mtu(struct net_device *dev, int new_mtu)
38338 + struct ubi32_eth_private *priv = netdev_priv(dev);
38339 + unsigned long flags;
38341 + if ((new_mtu < 68) || (new_mtu > 1500))
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);
38352 + * ubi32_eth_cleanup: unload the module
38354 +void ubi32_eth_cleanup(void)
38356 + struct ubi32_eth_private *priv;
38357 + struct net_device *dev;
38360 + for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38361 + dev = ubi32_eth_devices[i];
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;
38372 +int ubi32_eth_init_module(void)
38374 + struct ethtionode *eth_node;
38375 + struct net_device *dev;
38376 + struct ubi32_eth_private *priv;
38380 + * Device allocation.
38383 + for (i = 0; i < UBI32_ETH_NUM_OF_DEVICES; i++) {
38385 + * See if the eth_vp is in the device tree.
38387 + eth_node = (struct ethtionode *)devtree_find_node(eth_if_name[i]);
38389 + printk(KERN_INFO "%s does not exist\n", eth_if_name[i]);
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);
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");
38404 + if (!eth_node->tx_dma_ring) {
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;
38412 + dev = alloc_etherdev(sizeof(struct ubi32_eth_private));
38414 + kfree(eth_node->tx_dma_ring);
38418 + priv = netdev_priv(dev);
38422 + * FIX IT! get proper mac address
38424 + memcpy(dev->dev_addr, mac_addr[i], ETH_ALEN);
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;
38437 + priv->vp_int_bit = eth_node->dn.sendirq;
38438 + dev->irq = eth_node->dn.recvirq;
38440 + spin_lock_init(&priv->lock);
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;
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);
38455 + err = register_netdev(dev);
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);
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);
38470 + ubi32_eth_cleanup();
38474 + if (!ubi32_eth_devices[0] && !ubi32_eth_devices[1] && !ubi32_eth_devices[2]) {
38478 +#if defined(USE_POLLING)
38479 + init_timer(ð_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(ð_poll_timer);
38489 +module_init(ubi32_eth_init_module);
38490 +module_exit(ubi32_eth_cleanup);
38492 +MODULE_AUTHOR("Kan Yan, Greg Ren");
38493 +MODULE_LICENSE("GPL");
38495 +++ b/drivers/net/ubi32-eth.h
38498 + * drivers/net/ubi32-eth.h
38499 + * Ubicom32 ethernet TIO interface driver definitions.
38501 + * (C) Copyright 2009, Ubicom, Inc.
38503 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
38519 + * Ubicom32 implementation derived from (with many thanks):
38524 +#ifndef _UBI32_ETH_H
38525 +#define _UBI32_ETH_H
38527 +#include <asm/devtree.h>
38529 +#define UBI32_ETH_NUM_OF_DEVICES 3
38532 + * Number of bytes trashed beyond the packet data.
38534 +#define UBI32_ETH_TRASHED_MEMORY (CACHE_LINE_SIZE + ETH_HLEN - 1)
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.
38545 +#define UBI32_ETH_RESERVE_SPACE (CACHE_LINE_SIZE - ETH_HLEN)
38546 +#define UBI32_ETH_RESERVE_EXTRA (1 * CACHE_LINE_SIZE)
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 */
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)
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 */
38565 +#define UBI32_ETH_VP_TX_TIMEOUT (10*HZ)
38567 +struct ubi32_eth_vp_stats {
38568 + u32 rx_alloc_err;
38569 + u32 tx_q_full_cnt;
38570 + u32 rx_q_full_cnt;
38574 +struct ubi32_eth_private {
38575 + struct net_device *dev;
38576 + struct net_device_stats stats;
38577 + struct ubi32_eth_vp_stats vp_stats;
38580 +#ifdef CONFIG_UBICOM32_NAPI
38581 + struct napi_struct napi;
38583 + struct tasklet_struct tsk;
38585 + struct ethtionode *regs;
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;
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)
38612 +#define UBI32_ETH_VP_STATUS_RX_STATE (0x1<<5)
38613 +#define UBI32_ETH_VP_STATUS_TX_STATE (0x1<<6)
38615 +#define UBI32_ETH_PRIV_STATUS_TX_Q_FULL (1<<0)
38617 +#define UBI32_ETH_VP_INT_RX (1<<0)
38618 +#define UBI32_ETH_VP_INT_TX (1<<1)
38620 +#define UBI32_ETH_VP_CMD_RX_ENABLE (1<<0)
38621 +#define UBI32_ETH_VP_CMD_TX_ENABLE (1<<1)
38623 +#define UBI32_ETH_VP_RX_OK (1<<0)
38624 +#define UBI32_ETH_VP_TX_OK (1<<1)
38626 +#define TX_BOUND TX_DMA_RING_SIZE
38627 +#define RX_BOUND 64
38628 +#define UBI32_ETH_NAPI_WEIGHT 64 /* for GigE */
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);
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);
38648 if (size > ETH_FRAME_LEN) {
38649 deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);
38652 ax_skb = skb_clone(skb, GFP_ATOMIC);
38654 +#ifndef HAVE_EFFICIENT_UNALIGNED_ACCESS
38655 + if (((u32)packet & 0x02) == 0) {
38656 + memmove(packet - 2, packet, size);
38657 + ax_skb->data = packet - 2;
38659 + ax_skb->data = packet;
38662 + ax_skb->data = packet;
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;
38670 if (ecmd.speed == SPEED_1000)
38671 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38672 mode |= AX_MEDIUM_GM;
38674 + mode |= AX_MEDIUM_GM | AX_MEDIUM_ENCK;
38676 else if (ecmd.speed == SPEED_100)
38677 mode |= AX_MEDIUM_PS;
38679 mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
38681 +#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
38682 mode |= AX_MEDIUM_ENCK;
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;
38693 -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38694 - unsigned long event, int is_kernel)
38696 +void oprofile_add_ext_sample_cpu(unsigned long pc, struct pt_regs * const regs,
38697 + unsigned long event, int is_kernel, int cpu)
38699 - struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
38700 + struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu);
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);
38708 +void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
38709 + unsigned long event, int is_kernel)
38711 + oprofile_add_ext_sample_cpu(pc, regs, event,
38712 + is_kernel, smp_processor_id());
38715 void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
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
38727 # ACPI Related PCI FW Functions
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).
38736 +config SERIAL_UBI32_UARTTIO
38737 + tristate "Ubicom UARTTIO support"
38738 + depends on UBICOM32=y
38739 + select SERIAL_CORE
38742 + Add support for the Ubicom virtual peripherial serial interface.
38744 +config SERIAL_UBI32_UARTTIO_NR_UARTS
38745 + int "Maximum number of UARTTIO virtual serial ports"
38746 + depends on SERIAL_UBI32_UARTTIO
38749 + Set this to the maximum number of serial ports you want the driver to support.
38751 +config SERIAL_UBI32_UARTTIO_CONSOLE
38752 + tristate "Ubicom UARTTIO console support"
38753 + depends on SERIAL_UBI32_UARTTIO=y
38754 + select SERIAL_CORE_CONSOLE
38757 + Add support for console on the Ubicom virtual peripherial serial interface.
38759 +config SERIAL_UBI32_SERDES
38760 + bool "Ubicom serial port support"
38761 + depends on UBICOM32=y
38762 + select SERIAL_CORE
38765 + Add support for the Ubicom serial interface.
38767 +config SERIAL_UBI32_SERDES_CONSOLE
38768 + bool "Ubicom serial console support"
38769 + depends on SERIAL_UBI32_SERDES=y
38770 + select SERIAL_CORE_CONSOLE
38773 +config SERIAL_UBI32_MAILBOX
38774 + bool "Ubicom mailbox support"
38775 + depends on UBICOM32=y
38776 + select SERIAL_CORE
38779 + Add support for the Ubicom mailbox interface.
38781 +config SERIAL_UBI32_MAILBOX_CONSOLE
38782 + bool "Ubicom mailbox console support"
38783 + depends on SERIAL_UBI32_MAILBOX=y
38784 + select SERIAL_CORE_CONSOLE
38787 config SERIAL_SUNCORE
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
38800 +++ b/drivers/serial/ubi32_mailbox.c
38803 + * drivers/serial/ubi32_mailbox.c
38804 + * Ubicom32 On-Chip Mailbox Driver
38806 + * (C) Copyright 2009, Ubicom, Inc.
38808 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
38824 + * Ubicom32 implementation derived from (with many thanks):
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>
38839 +#include <asm/ip5000.h>
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 */
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
38851 +#define PORT_UBI32_MAILBOX 1235
38852 +#define NR_PORTS 1
38854 +#define get_sclk() 0
38856 +struct ubi32_mailbox_port {
38857 + struct uart_port port;
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.
38864 +} ubi32_mailbox_ports[NR_PORTS];
38866 +struct ubi32_mailbox_resource {
38867 + int uart_base_addr;
38869 +} ubi32_mailbox_resource[NR_PORTS] = {
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.
38874 + {ISD_MAILBOX_BASE, ISD_MAILBOX_INT}
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;
38883 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart);
38885 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart);
38890 +static int mailbox_console_flg = TRUE;
38891 +static int num_timeouts = 0;
38894 + * dummy functions and defined to be able to compile the Blackfin code
38896 +#define UART_GET_LSR(port) (1)
38897 +#define UART_PUT_LSR(port, bits)
38898 +#define UART_CLEAR_LSR(port) (1)
38907 +#define UART_GET_LCR(port) (1)
38908 +#define UART_PUT_LCR(port, bits)
38915 +#define UART_GET_IER(port) (1)
38916 +#define UART_SET_IER(port, bits)
38917 +#define UART_CLEAR_IER(port, bits)
38920 +#define UART_GET_CHAR(port) ubi32_mailbox_get_char()
38921 +#define UART_PUT_CHAR(port, ch) ubi32_mailbox_put_char(ch)
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)
38932 + * ubi32_mailbox_get_char_avail()
38934 +static int ubi32_mailbox_get_char_avail(void)
38936 + return !(ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38940 + * ubi32_mailbox_get_char()
38942 +static u32_t ubi32_mailbox_get_char(void)
38944 + if (mailbox_console_flg == TRUE) {
38946 + * Mailbox console is connected.
38948 + while (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY);
38949 + return ubi32_mailbox->in & 0xff;
38953 + * Mailbox console was not connected.
38955 + if (ubi32_mailbox->status & ISD_MAILBOX_STATUS_IN_EMPTY) {
38960 + * Mailbox console is connecting.
38962 + mailbox_console_flg = TRUE;
38963 + num_timeouts = 0;
38964 + return ubi32_mailbox->in & 0xff;
38967 +#define MAILBOX_MAX_ATTEMPTS 1000000
38968 +#define MAILBOX_MAX_TIMEOUTS 5
38970 + * ubi32_mailbox_put_char()
38972 +static void ubi32_mailbox_put_char(u32_t v)
38975 + * Wait to be able to output.
38977 + u32_t num_attempts = 0;
38979 + if(mailbox_console_flg == TRUE) {
38980 + while(num_attempts++ < MAILBOX_MAX_ATTEMPTS) {
38981 + if(ubi32_mailbox->status & ISD_MAILBOX_STATUS_OUT_EMPTY) {
38987 + * If timed out more than 5 times on send, mailbox console is disconnected now.
38989 + if (num_attempts > MAILBOX_MAX_ATTEMPTS) {
38990 + if (num_timeouts++ > MAILBOX_MAX_TIMEOUTS) {
38991 + mailbox_console_flg = FALSE;
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"
39006 + ubi32_mailbox->out = v & 0xff;
39009 +static void ubi32_mailbox_hw_init(struct ubi32_mailbox_port *uart)
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);
39018 + * interrupts are disabled on entry
39020 +static void ubi32_mailbox_stop_tx(struct uart_port *port)
39022 +// struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39023 +// struct circ_buf *xmit = &uart->port.info->xmit;
39025 + while (!(UART_GET_LSR(uart) & TEMT))
39028 + /* Clear TFI bit */
39029 + UART_PUT_LSR(uart, TFI);
39030 + UART_CLEAR_IER(uart, ETBEI);
39034 + * port is locked and interrupts are disabled
39036 +static void ubi32_mailbox_start_tx(struct uart_port *port)
39038 + struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39040 + UART_SET_IER(uart, ETBEI);
39042 + ubi32_mailbox_tx_chars(uart);
39046 + * Interrupts are enabled
39048 +static void ubi32_mailbox_stop_rx(struct uart_port *port)
39050 +// struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39051 + UART_CLEAR_IER(uart, ERBFI);
39055 + * Set the modem control timer to fire immediately.
39057 +static void ubi32_mailbox_enable_ms(struct uart_port *port)
39061 +static void ubi32_mailbox_rx_chars(struct ubi32_mailbox_port *uart)
39063 + struct uart_info *info = uart->port.info;
39064 + struct tty_struct *tty = info->port.tty;
39065 + unsigned int status, ch, flg;
39067 + status = 0; // XXX? UART_GET_LSR(uart);
39068 + UART_CLEAR_LSR(uart);
39070 + ch = UART_GET_CHAR(uart);
39075 + uart->port.icount.rx++;
39077 + if (status & BI) {
39078 + uart->port.icount.brk++;
39079 + if (uart_handle_break(&uart->port))
39080 + goto ignore_char;
39081 + status &= ~(PE | FE);
39084 + uart->port.icount.parity++;
39086 + uart->port.icount.overrun++;
39088 + uart->port.icount.frame++;
39090 + status &= uart->port.read_status_mask;
39094 + else if (status & PE)
39095 + flg = TTY_PARITY;
39096 + else if (status & FE)
39099 + flg = TTY_NORMAL;
39101 + if (uart_handle_sysrq_char(&uart->port, ch))
39102 + goto ignore_char;
39104 + uart_insert_char(&uart->port, status, OE, ch, flg);
39107 + tty_flip_buffer_push(tty);
39110 +static void ubi32_mailbox_tx_chars(struct ubi32_mailbox_port *uart)
39112 + struct circ_buf *xmit = &uart->port.info->xmit;
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;
39120 + * Check the modem control lines before
39121 + * transmitting anything.
39123 + ubi32_mailbox_mctrl_check(uart);
39125 + if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
39126 + ubi32_mailbox_stop_tx(&uart->port);
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++;
39137 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
39138 + uart_write_wakeup(&uart->port);
39140 + if (uart_circ_empty(xmit))
39141 + ubi32_mailbox_stop_tx(&uart->port);
39144 +static irqreturn_t ubi32_mailbox_isr(int irq, void *dev_id)
39146 + struct ubi32_mailbox_port *uart = dev_id;
39148 + spin_lock(&uart->port.lock);
39150 + //XXX?while (UART_GET_LSR(uart) & DR)
39155 + while (ubi32_mailbox_get_char_avail()) {
39156 + ubi32_mailbox_rx_chars(uart);
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;
39172 + spin_unlock(&uart->port.lock);
39174 + return IRQ_HANDLED;
39177 +static irqreturn_t ubi32_mailbox_tx_int(int irq, void *dev_id)
39179 + struct ubi32_mailbox_port *uart = dev_id;
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);
39186 + return IRQ_HANDLED;
39191 + * Return TIOCSER_TEMT when transmitter is not busy.
39193 +static unsigned int ubi32_mailbox_tx_empty(struct uart_port *port)
39195 +// struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39196 + unsigned short lsr;
39198 + lsr = UART_GET_LSR(uart);
39200 + return TIOCSER_TEMT;
39205 +static unsigned int ubi32_mailbox_get_mctrl(struct uart_port *port)
39207 + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
39210 +static void ubi32_mailbox_set_mctrl(struct uart_port *port, unsigned int mctrl)
39215 + * Handle any change of modem status signal since we were last called.
39217 +static void ubi32_mailbox_mctrl_check(struct ubi32_mailbox_port *uart)
39222 + * Interrupts are always disabled.
39224 +static void ubi32_mailbox_break_ctl(struct uart_port *port, int break_state)
39226 +// struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39227 + u16 lcr = UART_GET_LCR(uart);
39232 + UART_PUT_LCR(uart, lcr);
39236 +static int ubi32_mailbox_startup(struct uart_port *port)
39238 + struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
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");
39246 + UART_SET_IER(uart, ERBFI);
39250 +static void ubi32_mailbox_shutdown(struct uart_port *port)
39252 + struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39254 + free_irq(uart->port.irq, uart);
39258 +ubi32_mailbox_set_termios(struct uart_port *port, struct ktermios *termios,
39259 + struct ktermios *old)
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;
39266 + switch (termios->c_cflag & CSIZE) {
39280 + printk(KERN_ERR "%s: word lengh not supported\n",
39284 + if (termios->c_cflag & CSTOPB)
39286 + if (termios->c_cflag & PARENB)
39288 + if (!(termios->c_cflag & PARODD))
39290 + if (termios->c_cflag & CMSPAR)
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;
39300 + * Characters to ignore
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;
39308 + * If we're ignoring parity and break indicators,
39309 + * ignore overruns too (for real raw support).
39311 + if (termios->c_iflag & IGNPAR)
39312 + port->ignore_status_mask |= OE;
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);
39320 + lsr = UART_GET_LSR(uart);
39321 + } while (!(lsr & TEMT));
39323 + /* Disable UART */
39324 + ier = UART_GET_IER(uart);
39325 + UART_CLEAR_IER(uart, 0xF);
39327 + UART_PUT_DLL(uart, quot & 0xFF);
39329 + UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
39332 + UART_PUT_LCR(uart, lcr);
39334 + /* Enable UART */
39335 + UART_SET_IER(uart, ier);
39337 + val = UART_GET_GCTL(uart);
39339 + UART_PUT_GCTL(uart, val);
39341 + spin_unlock_irqrestore(&uart->port.lock, flags);
39344 +static const char *ubi32_mailbox_type(struct uart_port *port)
39346 + struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39348 + return uart->port.type == PORT_UBI32_MAILBOX ? "UBI32_MAILBOX" : NULL;
39352 + * Release the memory region(s) being used by 'port'.
39354 +static void ubi32_mailbox_release_port(struct uart_port *port)
39359 + * Request the memory region(s) being used by 'port'.
39361 +static int ubi32_mailbox_request_port(struct uart_port *port)
39367 + * Configure/autoconfigure the port.
39369 +static void ubi32_mailbox_config_port(struct uart_port *port, int flags)
39371 + struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39373 + if (flags & UART_CONFIG_TYPE && ubi32_mailbox_request_port(&uart->port) == 0)
39374 + uart->port.type = PORT_UBI32_MAILBOX;
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
39383 +ubi32_mailbox_verify_port(struct uart_port *port, struct serial_struct *ser)
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,
39407 +static void __init ubi32_mailbox_init_ports(void)
39409 + static int first = 1;
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);
39430 + ubi32_mailbox_hw_init(&ubi32_mailbox_ports[i]);
39435 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39437 + * If the port was already initialised (eg, by a boot loader),
39438 + * try to determine the current setup.
39440 +static void __init
39441 +ubi32_mailbox_console_get_options(struct ubi32_mailbox_port *uart, int *baud,
39442 + int *parity, int *bits)
39444 + unsigned short status;
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;
39452 + lcr = UART_GET_LCR(uart);
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;
39468 + dll = UART_GET_DLL(uart);
39469 + dlh = UART_GET_DLH(uart);
39471 + *baud = get_sclk() / (16*(dll | dlh << 8));
39473 + pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
39477 +#if defined(CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
39478 +static struct uart_driver ubi32_mailbox_reg;
39481 +ubi32_mailbox_console_setup(struct console *co, char *options)
39483 + struct ubi32_mailbox_port *uart;
39484 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39485 + int baud = SERIAL_UBICOM_BAUDRATE;
39487 + int parity = 'n';
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.
39496 + if (co->index == -1 || co->index >= NR_PORTS)
39498 + uart = &ubi32_mailbox_ports[co->index];
39500 +# ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39502 + uart_parse_options(options, &baud, &parity, &bits, &flow);
39504 + ubi32_mailbox_console_get_options(uart, &baud, &parity, &bits);
39506 + //JB return uart_set_options(&uart->port, co, baud, parity, bits, flow);
39512 +#endif /* defined (CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE) ||
39513 + defined (CONFIG_EARLY_PRINTK) */
39515 +#ifdef CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE
39516 +static void ubi32_mailbox_console_putchar(struct uart_port *port, int ch)
39518 +// struct ubi32_mailbox_port *uart = (struct ubi32_mailbox_port *)port;
39519 + while (!(UART_GET_LSR(uart) & THRE))
39521 + UART_PUT_CHAR(uart, ch);
39526 + * Interrupts are disabled on entering
39529 +ubi32_mailbox_console_write(struct console *co, const char *s, unsigned int count)
39531 + struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[co->index];
39532 + unsigned long flags = 0;
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);
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,
39547 + .data = &ubi32_mailbox_reg,
39550 +static int __init ubi32_mailbox_console_init(void)
39552 + ubi32_mailbox_init_ports();
39553 + register_console(&ubi32_mailbox_console);
39556 +console_initcall(ubi32_mailbox_console_init);
39558 +#define UBI32_MAILBOX_CONSOLE &ubi32_mailbox_console
39560 +#define UBI32_MAILBOX_CONSOLE NULL
39561 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
39564 +#ifdef CONFIG_EARLY_PRINTK
39565 +static __init void ubi32_mailbox_early_putc(struct uart_port *port, int ch)
39567 + UART_PUT_CHAR(uart, ch);
39570 +static __init void ubi32_mailbox_early_write(struct console *con, const char *s,
39573 + struct ubi32_mailbox_port *uart = &ubi32_mailbox_ports[con->index];
39576 + for (i = 0; i < n; i++, s++) {
39578 + ubi32_mailbox_early_putc(&uart->port, '\r');
39579 + ubi32_mailbox_early_putc(&uart->port, *s);
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,
39590 + .data = &ubi32_mailbox_reg,
39594 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
39596 +struct console __init *ubi32_mailbox_early_init(unsigned int port,
39597 + unsigned int cflag)
39599 + struct ubi32_mailbox_port *uart;
39600 + struct ktermios t;
39602 + if (port == -1 || port >= NR_PORTS)
39604 + ubi32_mailbox_init_ports();
39605 + ubi32_mailbox_early_console.index = port;
39606 + uart = &ubi32_mailbox_ports[port];
39607 + t.c_cflag = cflag;
39610 + t.c_lflag = ICANON;
39612 + ubi32_mailbox_set_termios(&uart->port, &t, &t);
39613 + return &ubi32_mailbox_early_console;
39616 +#endif /* CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE */
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,
39625 + .cons = UBI32_MAILBOX_CONSOLE,
39628 +static int ubi32_mailbox_suspend(struct platform_device *dev, pm_message_t state)
39630 + struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39633 + uart_suspend_port(&ubi32_mailbox_reg, &uart->port);
39638 +static int ubi32_mailbox_resume(struct platform_device *dev)
39640 + struct ubi32_mailbox_port *uart = platform_get_drvdata(dev);
39643 + uart_resume_port(&ubi32_mailbox_reg, &uart->port);
39648 +static int ubi32_mailbox_probe(struct platform_device *dev)
39650 + struct resource *res = dev->resource;
39653 + for (i = 0; i < dev->num_resources; i++, res++)
39654 + if (res->flags & IORESOURCE_MEM)
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)
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]);
39670 +static int ubi32_mailbox_remove(struct platform_device *pdev)
39672 + struct ubi32_mailbox_port *uart = platform_get_drvdata(pdev);
39674 + platform_set_drvdata(pdev, NULL);
39677 + uart_remove_one_port(&ubi32_mailbox_reg, &uart->port);
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,
39688 + .name = "ubi32-mbox",
39689 + .owner = THIS_MODULE,
39693 +static int __init ubi32_mailbox_init(void)
39697 + pr_info("Serial: Ubicom32 mailbox serial driver.\n");
39699 + mailbox_console_flg = TRUE;
39700 + num_timeouts = 0;
39701 + ubi32_mailbox_init_ports();
39703 + ret = uart_register_driver(&ubi32_mailbox_reg);
39705 + ret = platform_driver_register(&ubi32_mailbox_driver);
39707 + pr_debug("uart register failed\n");
39708 + uart_unregister_driver(&ubi32_mailbox_reg);
39713 + * XXX HACK: currently probe does not get called, but the port needs to be added to work.
39715 + uart_add_one_port(&ubi32_mailbox_reg, &ubi32_mailbox_ports[0].port);
39719 +static void __exit ubi32_mailbox_exit(void)
39721 + platform_driver_unregister(&ubi32_mailbox_driver);
39722 + uart_unregister_driver(&ubi32_mailbox_reg);
39725 +module_init(ubi32_mailbox_init);
39726 +module_exit(ubi32_mailbox_exit);
39728 +MODULE_ALIAS_CHARDEV_MAJOR(UBI32_MAILBOX_MAJOR);
39729 +MODULE_ALIAS("platform:ubi32_mailbox");
39731 +++ b/drivers/serial/ubi32_serdes.c
39734 + * drivers/serial/ubi32_serdes.c
39735 + * Ubicom32 On-Chip Serial Driver
39737 + * (C) Copyright 2009, Ubicom, Inc.
39739 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
39755 + * Ubicom32 implementation derived from (with many thanks):
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>
39770 +#include <asm/ip5000.h>
39771 +#include <asm/ubicom32suart.h>
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
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 */
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
39788 +#define PORT_UBI32_SERDES 1234
39789 +#define NR_PORTS 1
39791 +struct uart_port ubi32_serdes_ports[NR_PORTS];
39793 +struct ubi32_serdes_resource {
39794 + void *uart_base_addr;
39797 +} ubi32_serdes_resource[NR_PORTS] = {
39799 + * Get params from kernel command line (required for early printk)
39800 + * or from platform resources.
39806 + * Can get overridden by 'serdes=' kernel command line.
39808 +static int ubi32_serdes_default_baud_rate = 115200;
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)
39818 + * ubi32_serdes_get_char()
39820 +static u8_t ubi32_serdes_get_char(struct ubicom32_io_port *io_port)
39823 + * Read from hardware (forced 32-bit atomic read).
39828 + io_port->int_clr = IO_PORTX_INT_SERDES_RXBF;
39830 + "move.4 %0, %1 \n\t"
39832 + : "m" (*(u32_t *)&(io_port->rx_fifo))
39836 + return (u8_t)(data & 0x000000ff);
39840 + * ubi32_serdes_put_char()
39842 +static void ubi32_serdes_put_char(struct ubicom32_io_port *io_port, u8_t c)
39844 + u32_t data = 0x0000fe00 | (c << 1);
39848 + * Fixed data format:
39849 + * [LSB]1 start bit - 8 data bits - no parity - 1 stop bit[MSB]
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;
39857 +static void ubi32_serdes_hw_init(struct uart_port *port, int baud)
39859 + struct ubicom32_io_port *io_port = IO_PORT(port);
39863 + * Put port functions 1-4 into reset state.
39864 + * Function 0 (GPIO) does not need or have a reset bit.
39866 + * Select SERDES function for restart below.
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;
39874 + * Configure SERDES baudrate
39876 + if ( baud == 0 ) {
39877 + baud = ubi32_serdes_default_baud_rate;
39881 + SERIAL_UBICOM_CTL0 |
39882 + ((port->uartclk / (16 * baud)) - 1);
39885 + SERIAL_UBICOM_CTL1;
39888 + * don't interrupt until startup and start_tx
39890 + io_port->int_mask = 0;
39893 + * Set TXD pin output, RXD input and prevent GPIO
39894 + * override on the TXD & RXD pins
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);
39901 + * Restart (un-reset) the port's SERDES function.
39903 + io_port->function &= ~(IO_FUNC_FUNCTION_RESET(IO_PORTX_FUNC_SERDES));
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
39914 +static int ubi32_serdes_receive(struct uart_port *port, int stat)
39916 + struct tty_struct *tty = port->info->port.tty;
39917 + unsigned char ch = 0;
39918 + char flag = TTY_NORMAL;
39920 + if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
39921 + | ULITE_STATUS_FRAME)) == 0)
39925 + if (stat & ULITE_STATUS_RXVALID) {
39926 + port->icount.rx++;
39927 + ch = ubi32_serdes_get_char((struct ubicom32_io_port *)port->membase);
39929 + if (stat & ULITE_STATUS_PARITY)
39930 + port->icount.parity++;
39933 + if (stat & ULITE_STATUS_OVERRUN)
39934 + port->icount.overrun++;
39936 + if (stat & ULITE_STATUS_FRAME)
39937 + port->icount.frame++;
39940 + /* drop byte with parity error if IGNPAR specificed */
39941 + if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY)
39942 + stat &= ~ULITE_STATUS_RXVALID;
39944 + stat &= port->read_status_mask;
39946 + if (stat & ULITE_STATUS_PARITY)
39947 + flag = TTY_PARITY;
39949 + stat &= ~port->ignore_status_mask;
39951 + if (stat & ULITE_STATUS_RXVALID)
39952 + tty_insert_flip_char(tty, ch, flag);
39954 + if (stat & ULITE_STATUS_FRAME)
39955 + tty_insert_flip_char(tty, 0, TTY_FRAME);
39957 + if (stat & ULITE_STATUS_OVERRUN)
39958 + tty_insert_flip_char(tty, 0, TTY_OVERRUN);
39964 + * interrupts are disabled on entry
39966 +static void ubi32_serdes_stop_tx(struct uart_port *port)
39968 + IO_PORT_INT_MASK(port) = IO_PORT_INT_MASK(port) & ~IO_PORTX_INT_SERDES_TXBE;
39971 +static int ubi32_serdes_transmit(struct uart_port *port, int stat)
39973 + struct circ_buf *xmit = &port->info->xmit;
39975 + if (!(stat & IO_PORTX_INT_SERDES_TXBE))
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++;
39985 + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
39986 + ubi32_serdes_stop_tx(port);
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++;
39995 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
39996 + uart_write_wakeup(port);
39998 + if (uart_circ_empty(xmit))
39999 + ubi32_serdes_stop_tx(port);
40005 + * port is locked and interrupts are disabled
40007 +static void ubi32_serdes_start_tx(struct uart_port *port)
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));
40014 + * Interrupts are enabled
40016 +static void ubi32_serdes_stop_rx(struct uart_port *port)
40018 + /* don't forward any more data (like !CREAD) */
40019 + port->ignore_status_mask = IO_PORTX_INT_SERDES_RXBF;
40023 + * Set the modem control timer to fire immediately.
40025 +static void ubi32_serdes_enable_ms(struct uart_port *port)
40030 +static irqreturn_t ubi32_serdes_isr(int irq, void *dev_id)
40032 + struct uart_port *port = dev_id;
40035 + spin_lock(&port->lock);
40038 + int stat = IO_PORT_INT_STATUS(port);
40039 + busy = ubi32_serdes_receive(port, stat);
40040 + busy |= ubi32_serdes_transmit(port, stat);
40043 + tty_flip_buffer_push(port->info->port.tty);
40045 + spin_unlock(&port->lock);
40047 + return IRQ_HANDLED;
40051 + * Return TIOCSER_TEMT when transmitter is not busy.
40053 +static unsigned int ubi32_serdes_tx_empty(struct uart_port *port)
40055 + unsigned long flags;
40056 + unsigned int ret;
40058 + spin_lock_irqsave(&port->lock, flags);
40059 + ret = IO_PORT_INT_STATUS(port);
40060 + spin_unlock_irqrestore(&port->lock, flags);
40062 + return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
40065 +static unsigned int ubi32_serdes_get_mctrl(struct uart_port *port)
40067 + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
40070 +static void ubi32_serdes_set_mctrl(struct uart_port *port, unsigned int mctrl)
40076 + * Interrupts are always disabled.
40078 +static void ubi32_serdes_break_ctl(struct uart_port *port, int break_state)
40083 +static int ubi32_serdes_startup(struct uart_port *port)
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");
40091 + IO_PORT_INT_CLR(port) = IO_PORTX_INT_SERDES_RXBF;
40092 + IO_PORT_INT_MASK(port) = IO_PORTX_INT_SERDES_RXBF;
40096 +static void ubi32_serdes_shutdown(struct uart_port *port)
40098 + struct ubi32_serdes_port *uart = (struct ubi32_serdes_port *)port;
40100 + IO_PORT_INT_MASK(port) = 0;
40101 + free_irq(port->irq, uart);
40105 +ubi32_serdes_set_termios(struct uart_port *port, struct ktermios *termios,
40106 + struct ktermios *old)
40108 + unsigned long flags;
40109 + unsigned int baud;
40111 + spin_lock_irqsave(&port->lock, flags);
40113 + port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
40114 + | ULITE_STATUS_TXFULL;
40116 + if (termios->c_iflag & INPCK)
40117 + port->read_status_mask |=
40118 + ULITE_STATUS_PARITY | ULITE_STATUS_FRAME;
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;
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;
40131 + /* update timeout */
40132 + baud = uart_get_baud_rate(port, termios, old, 0, 460800);
40133 + uart_update_timeout(port, termios->c_cflag, baud);
40135 + IO_PORT(port)->ctl0 = SERIAL_UBICOM_CTL0 |
40136 + ((port->uartclk / (16 * baud)) - 1);
40138 + spin_unlock_irqrestore(&port->lock, flags);
40141 +static const char *ubi32_serdes_type(struct uart_port *port)
40143 + return port->type == PORT_UBI32_SERDES ? "UBI32_SERDES" : NULL;
40147 + * Release the memory region(s) being used by 'port'.
40149 +static void ubi32_serdes_release_port(struct uart_port *port)
40154 + * Request the memory region(s) being used by 'port'.
40156 +static int ubi32_serdes_request_port(struct uart_port *port)
40162 + * Configure/autoconfigure the port.
40164 +static void ubi32_serdes_config_port(struct uart_port *port, int flags)
40166 + if (flags & UART_CONFIG_TYPE &&
40167 + ubi32_serdes_request_port(port) == 0)
40168 + port->type = PORT_UBI32_SERDES;
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
40177 +ubi32_serdes_verify_port(struct uart_port *port, struct serial_struct *ser)
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,
40201 +static void __init ubi32_serdes_init_ports(void)
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;
40218 + ubi32_serdes_hw_init(&ubi32_serdes_ports[i], 0);
40223 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40225 + * If the port was already initialised (eg, by a boot loader),
40226 + * try to determine the current setup.
40228 +static void __init
40229 +ubi32_serdes_console_get_options(struct uart_port *port, int *baud)
40231 + u32 round_to = 1200;
40235 + * We might get called before platform init and with no
40236 + * kernel command line options, so port might be NULL.
40238 + *baud = ubi32_serdes_default_baud_rate;;
40239 + if ( IO_PORT(port) == 0 )
40242 + real_baud = port->uartclk
40243 + / (16 * ((IO_PORT(port)->ctl0 & ~SERIAL_UBICOM_CTL0) + 1));
40245 + *baud = ((real_baud + round_to - 1) / round_to) * round_to;
40247 + pr_debug("%s:baud = %d, real_baud = %d\n", __FUNCTION__, *baud, real_baud);
40251 +#if defined(CONFIG_SERIAL_UBI32_SERDES_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
40252 +static struct uart_driver ubi32_serdes_reg;
40255 +ubi32_serdes_console_setup(struct console *co, char *options)
40257 + struct uart_port *port;
40258 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40259 + int baud = ubi32_serdes_default_baud_rate;
40261 + int parity = 'n';
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.
40270 + if (co->index == -1 || co->index >= NR_PORTS)
40272 + port = &ubi32_serdes_ports[co->index];
40274 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40276 + uart_parse_options(options, &baud, &parity, &bits, &flow);
40277 + ubi32_serdes_hw_init(port, baud);
40280 + ubi32_serdes_console_get_options(port, &baud);
40282 + return uart_set_options(port, co, baud, parity, bits, flow);
40287 +#endif /* defined (CONFIG_SERIAL_UBI32_SERDES_CONSOLE) ||
40288 + defined (CONFIG_EARLY_PRINTK) */
40290 +#ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
40292 +ubi32_serdes_console_putchar(struct uart_port *port, int ch)
40294 + if ( IO_PORT(port) ) {
40295 + while (!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE))
40297 + ubi32_serdes_put_char(IO_PORT(port), ch);
40302 + * Interrupts are disabled on entering
40305 +ubi32_serdes_console_write(struct console *co, const char *s, unsigned int count)
40307 + struct uart_port *port = &ubi32_serdes_ports[co->index];
40308 + unsigned long flags = 0;
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);
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,
40323 + .data = &ubi32_serdes_reg,
40326 +static int __init ubi32_serdes_console_init(void)
40328 + ubi32_serdes_init_ports();
40329 + register_console(&ubi32_serdes_console);
40332 +console_initcall(ubi32_serdes_console_init);
40334 +#define UBI32_SERDES_CONSOLE &ubi32_serdes_console
40336 +#define UBI32_SERDES_CONSOLE NULL
40337 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
40340 +#ifdef CONFIG_EARLY_PRINTK
40341 +static __init void ubi32_serdes_early_putc(struct uart_port *port, int ch)
40343 + unsigned timeout = 0xffff;
40345 + while ((!(IO_PORT_INT_STATUS(port) & IO_PORTX_INT_SERDES_TXBE)) && --timeout)
40347 + ubi32_serdes_put_char(IO_PORT(port), ch);
40350 +static __init void ubi32_serdes_early_write(struct console *con, const char *s,
40353 + struct uart_port *port = &ubi32_serdes_ports[con->index];
40356 + for (i = 0; i < n; i++, s++) {
40358 + ubi32_serdes_early_putc(port, '\r');
40359 + ubi32_serdes_early_putc(port, *s);
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,
40370 + .data = &ubi32_serdes_reg,
40374 + * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
40376 +struct console __init *ubi32_serdes_early_init(unsigned int port_index,
40377 + unsigned int cflag)
40379 + struct uart_port *uart;
40380 + struct ktermios t;
40382 + if (port_index == -1 || port_index >= NR_PORTS)
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;
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;
40396 +#endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
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,
40405 + .cons = UBI32_SERDES_CONSOLE,
40408 +static int ubi32_serdes_suspend(struct platform_device *dev, pm_message_t state)
40410 + struct uart_port *port = platform_get_drvdata(dev);
40413 + uart_suspend_port(&ubi32_serdes_reg, port);
40418 +static int ubi32_serdes_resume(struct platform_device *dev)
40420 + struct uart_port *port = platform_get_drvdata(dev);
40423 + uart_resume_port(&ubi32_serdes_reg, port);
40428 +static int ubi32_serdes_probe(struct platform_device *dev)
40430 + struct resource *res = dev->resource;
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;
40437 + else if (res->flags & IORESOURCE_IRQ) {
40438 + ubi32_serdes_resource[0].uart_irq = res->start;
40440 + else if (res->flags & UBICOM32_SUART_IORESOURCE_CLOCK) {
40441 + ubi32_serdes_resource[0].uart_clock = res->start;
40445 + ubi32_serdes_init_ports();
40450 +static int ubi32_serdes_remove(struct platform_device *pdev)
40452 + struct uart_port *port = platform_get_drvdata(pdev);
40454 + platform_set_drvdata(pdev, NULL);
40457 + uart_remove_one_port(&ubi32_serdes_reg, port);
40462 +static struct platform_driver ubi32_serdes_driver = {
40463 + .remove = ubi32_serdes_remove,
40464 + .suspend = ubi32_serdes_suspend,
40465 + .resume = ubi32_serdes_resume,
40467 + .name = "ubicom32suart",
40468 + .owner = THIS_MODULE,
40475 + * Called at boot time.
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.
40481 +static int __init ubi32_serdes_setup(char *str)
40483 +#define N_PARMS (4+1)
40484 + int ints[N_PARMS];
40487 + str = get_options(str, ARRAY_SIZE(ints), ints);
40489 + for (i = 0; i < N_PARMS; i++) {
40490 + if (i < ints[0]) {
40492 + ubi32_serdes_resource[0].uart_base_addr = (void *) ints[i+1];
40494 + else if (i == 1) {
40495 + ubi32_serdes_resource[0].uart_irq = ints[i+1];
40497 + else if (i == 2) {
40498 + ubi32_serdes_resource[0].uart_clock = ints[i+1];
40500 + else if (i == 3) {
40501 + ubi32_serdes_default_baud_rate = ints[i+1];
40508 +__setup("serdes=", ubi32_serdes_setup);
40511 +static int __init ubi32_serdes_init(void)
40515 + pr_info("Serial: Ubicom32 serdes uart serial driver\n");
40517 + ret = platform_driver_probe(&ubi32_serdes_driver, ubi32_serdes_probe);
40519 + printk(KERN_INFO "serdes platform_driver_probe() failed: %d\n", ret);
40523 + ubi32_serdes_init_ports();
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);
40536 +static void __exit ubi32_serdes_exit(void)
40538 + platform_driver_unregister(&ubi32_serdes_driver);
40539 + uart_unregister_driver(&ubi32_serdes_reg);
40542 +module_init(ubi32_serdes_init);
40543 +module_exit(ubi32_serdes_exit);
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");
40551 +++ b/drivers/serial/ubi32_uarttio.c
40554 + * drivers/serial/ubi32_uarttio.c
40555 + * Ubicom32 Serial Virtual Peripherial Driver
40557 + * (C) Copyright 2009, Ubicom, Inc.
40559 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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>
40586 +#include <asm/ip5000.h>
40587 +#include <asm/gpio.h>
40588 +#include <asm/thread.h>
40589 +#include <asm/uart_tio.h>
40591 +#define DRIVER_NAME "ubi32_uarttio"
40594 + * For storing the module parameters.
40596 +#define UBI32_UARTTIO_MAX_PARAM_LEN 80
40597 +static char utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN];
40600 + * UART name and device definitions
40602 +#define UBI32_UARTTIO_NAME "ttyUV" // XXX
40603 +#define UBI32_UARTTIO_MAJOR 206 // XXX
40604 +#define UBI32_UARTTIO_MINOR 64 // XXX
40607 + * The following structures are allocated statically because the
40608 + * memory allocation subsystem is not initialized this early on
40612 + * Per port structure
40614 +struct ubi32_uarttio_port {
40615 + struct uarttio_uart *uart;
40616 + unsigned int tx_pin;
40617 + unsigned int rx_pin;
40619 + struct uart_port port;
40624 + * If this value is set, the port has had its direction set already
40628 +static struct ubi32_uarttio_port uarttio_ports[CONFIG_SERIAL_UBI32_UARTTIO_NR_UARTS];
40631 + * Number of ports currently initialized
40633 +static int uarttio_nports;
40636 + * Per device structure
40638 +struct ubi32_uarttio_instance {
40639 + struct uarttio_regs *regs;
40640 + struct ubi32_uarttio_port *ports;
40642 + u8_t irq_requested;
40643 + u8_t driver_registered;
40646 +static struct ubi32_uarttio_instance uarttio_inst;
40648 +#ifdef CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE
40649 +static struct console ubi32_uarttio_console;
40650 +#define UBI32_UARTTIO_CONSOLE &ubi32_uarttio_console
40652 +#define UBI32_UARTTIO_CONSOLE NULL
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,
40664 +#ifdef UBI32_UARTTIO_UNUSED
40666 + * ubi32_uarttio_get_send_space
40668 +static int ubi32_uarttio_get_send_space(struct uarttio_uart *uart)
40670 + int count = uart->tx_fifo_head - uart->tx_fifo_tail;
40672 + count += uart->tx_fifo_size;
40674 + return uart->tx_fifo_size - count;
40679 + * ubi32_uarttio_get_recv_ready
40681 +static int ubi32_uarttio_get_recv_ready(struct uarttio_uart *uart)
40683 + int count = uart->rx_fifo_head - uart->rx_fifo_tail;
40685 + count += uart->rx_fifo_size;
40691 + * ubi32_uarttio_get_char()
40693 +static u8_t ubi32_uarttio_get_char(struct uarttio_uart *uart)
40698 + u32_t tail = uart->rx_fifo_tail;
40699 + u8_t data = uart->rx_fifo[tail];
40701 + if (++tail == uart->rx_fifo_size) {
40704 + uart->rx_fifo_tail = tail;
40710 + * ubi32_uarttio_put_char()
40712 +static int ubi32_uarttio_put_char(struct uarttio_uart *uart, u8_t c)
40714 + u32_t head = uart->tx_fifo_head;
40715 + u32_t prev = head;
40720 + if (++head == uart->tx_fifo_size) {
40725 + * If there isn't any space, return EBUSY
40727 + if (head == uart->tx_fifo_tail) {
40732 + * Put the character in the queue
40734 + uart->tx_fifo[prev] = c;
40735 + uart->tx_fifo_head = head;
40741 + * ubi32_uarttio_set_baud
40743 +static int ubi32_uarttio_set_baud(struct ubi32_uarttio_port *uup, unsigned int baud)
40745 + if (uup->uart->current_baud_rate == baud) {
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) {
40755 + if (uup->uart->current_baud_rate != baud) {
40757 + * Failed to set baud rate
40759 + printk(KERN_WARNING "Invalid baud rate %u, running at %u\n", baud, uup->uart->current_baud_rate);
40767 + * ubi32_uarttio_handle_receive
40769 +static void ubi32_uarttio_handle_receive(struct ubi32_uarttio_port *uup, int stat)
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;
40778 + if ((stat & (UARTTIO_UART_INT_RX | UARTTIO_UART_INT_RXFRAME | UARTTIO_UART_INT_RXOVF)) == 0) {
40782 + if (stat & UARTTIO_UART_INT_RX) {
40783 + count = ubi32_uarttio_get_recv_ready(uart);
40784 + port->icount.rx += count;
40787 + if (stat & UARTTIO_UART_INT_RXOVF) {
40788 + port->icount.overrun++;
40791 + if (stat & UARTTIO_UART_INT_RXFRAME) {
40792 + port->icount.frame++;
40795 + stat &= ~port->ignore_status_mask;
40797 + if (stat & UARTTIO_UART_INT_RX) {
40799 + for (i = 0; i < count; i++) {
40800 + ch = ubi32_uarttio_get_char(uart);
40801 + tty_insert_flip_char(tty, ch, flag);
40805 + if (stat & UARTTIO_UART_INT_RXFRAME) {
40806 + tty_insert_flip_char(tty, 0, TTY_FRAME);
40809 + if (stat & UARTTIO_UART_INT_RXOVF) {
40810 + tty_insert_flip_char(tty, 0, TTY_OVERRUN);
40815 + * ubi32_uarttio_stop_tx
40816 + * interrupts are disabled on entry
40818 +static void ubi32_uarttio_stop_tx(struct uart_port *port)
40820 + struct ubi32_uarttio_port *uup = port->private_data;
40822 + uup->uart->int_mask &= ~UARTTIO_UART_INT_TXBE;
40826 + * ubi32_uarttio_handle_transmit
40828 +static void ubi32_uarttio_handle_transmit(struct ubi32_uarttio_port *uup, int stat)
40830 + struct uarttio_uart *uart = uup->uart;
40831 + struct uart_port *port = &uup->port;
40832 + struct circ_buf *xmit = &port->info->xmit;
40834 + if (!(stat & UARTTIO_UART_INT_TXBE)) {
40838 + if (port->x_char) {
40839 + if (ubi32_uarttio_put_char(uart, port->x_char)) {
40842 + port->x_char = 0;
40843 + port->icount.tx++;
40847 + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
40848 + ubi32_uarttio_stop_tx(port);
40853 + * Send as many characters as we can
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)) {
40864 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
40865 + uart_write_wakeup(port);
40868 + if (uart_circ_empty(xmit)) {
40869 + ubi32_uarttio_stop_tx(port);
40874 + * ubi32_uarttio_start_tx
40875 + * port is locked and interrupts are disabled
40877 +static void ubi32_uarttio_start_tx(struct uart_port *port)
40879 + struct ubi32_uarttio_port *uup = port->private_data;
40880 + struct uarttio_uart *uart = uup->uart;
40882 + uart->int_mask |= UARTTIO_UART_INT_TXBE;
40886 + * ubi32_uarttio_stop_rx
40887 + * Interrupts are enabled
40889 +static void ubi32_uarttio_stop_rx(struct uart_port *port)
40891 + struct ubi32_uarttio_port *uup = port->private_data;
40892 + struct uarttio_uart *uart = uup->uart;
40895 + * don't forward any more data (like !CREAD)
40897 + uart->int_mask &= ~UARTTIO_UART_INT_RX;
40898 + port->ignore_status_mask = UARTTIO_UART_INT_RX;
40902 + * ubi32_uarttio_enable_ms
40903 + * Set the modem control timer to fire immediately.
40905 +static void ubi32_uarttio_enable_ms(struct uart_port *port)
40911 + * ubi32_uarttio_isr
40913 +static irqreturn_t ubi32_uarttio_isr(int irq, void *appdata)
40915 + struct ubi32_uarttio_port *uup = uarttio_ports;
40919 + * Service all of the ports
40921 + for (i = 0; i < uarttio_nports; i++) {
40922 + unsigned int flags;
40924 + if (!(uup->uart->flags & UARTTIO_UART_FLAG_ENABLED)) {
40929 + spin_lock(&uup->port.lock);
40931 + flags = uup->uart->int_flags;
40933 + uup->uart->int_flags = 0;
40935 + ubi32_uarttio_handle_receive(uup, flags);
40936 + ubi32_uarttio_handle_transmit(uup, flags);
40938 + tty_flip_buffer_push(uup->port.info->port.tty);
40940 + spin_unlock(&uup->port.lock);
40945 + return IRQ_HANDLED;
40949 + * ubi32_uarttio_tx_empty
40950 + * Return TIOCSER_TEMT when transmitter is not busy.
40952 +static unsigned int ubi32_uarttio_tx_empty(struct uart_port *port)
40954 + struct ubi32_uarttio_port *uup = port->private_data;
40956 + if (uup->uart->tx_fifo_head == uup->uart->tx_fifo_tail) {
40957 + return TIOCSER_TEMT;
40964 + * ubi32_uarttio_get_mctrl
40966 +static unsigned int ubi32_uarttio_get_mctrl(struct uart_port *port)
40968 + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
40972 + * ubi32_uarttio_set_mctrl
40974 +static void ubi32_uarttio_set_mctrl(struct uart_port *port, unsigned int mctrl)
40980 + * ubi32_uarttio_break_ctl
40982 +static void ubi32_uarttio_break_ctl(struct uart_port *port, int break_state)
40988 + * ubi32_uarttio_startup
40990 +static int ubi32_uarttio_startup(struct uart_port *port)
40992 + struct ubi32_uarttio_port *uup = port->private_data;
40993 + struct uarttio_uart *uart = uup->uart;
40995 + uart->flags |= UARTTIO_UART_FLAG_ENABLED;
40997 + uart->int_mask |= UARTTIO_UART_INT_TXBE | UARTTIO_UART_INT_RX;
41003 + * ubi32_uarttio_shutdown
41005 +static void ubi32_uarttio_shutdown(struct uart_port *port)
41007 + struct ubi32_uarttio_port *uup = port->private_data;
41008 + struct uarttio_uart *uart = uup->uart;
41010 + uart->int_mask = 0;
41011 + uart->flags &= ~UARTTIO_UART_FLAG_ENABLED;
41015 + * ubi32_uarttio_set_termios
41017 +static void ubi32_uarttio_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
41019 + struct ubi32_uarttio_port *uup = port->private_data;
41020 + unsigned long flags;
41021 + unsigned int baud;
41023 + spin_lock_irqsave(&port->lock, flags);
41026 + port->read_status_mask = UBI32_UARTTIO_RX | UBI32_UARTTIO_RXOVF | UBI32_UARTTIO_TXOVF;
41028 + if (termios->c_iflag & INPCK) {
41029 + port->read_status_mask |= UBI32_UARTTIO_RXFRAME;
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;
41040 + * ignore all characters if CREAD is not set
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;
41048 + /* update timeout */
41049 + baud = uart_get_baud_rate(port, termios, old, 0, 460800);
41050 + uart_update_timeout(port, termios->c_cflag, baud);
41052 + ubi32_uarttio_set_baud(uup, baud);
41053 + spin_unlock_irqrestore(&port->lock, flags);
41057 + * ubi32_uarttio_type
41059 +static const char *ubi32_uarttio_type(struct uart_port *port)
41061 + return (port->type == PORT_UBI32_UARTTIO) ? "UBI32_UARTTIO" : NULL;
41065 + * ubi32_uarttio_release_port
41066 + * Release the memory region(s) being used by 'port'.
41068 +static void ubi32_uarttio_release_port(struct uart_port *port)
41073 + * ubi32_uarttio_request_port
41074 + * Request the memory region(s) being used by 'port'.
41076 +static int ubi32_uarttio_request_port(struct uart_port *port)
41082 + * ubi32_uarttio_config_port
41083 + * Configure/autoconfigure the port.
41085 +static void ubi32_uarttio_config_port(struct uart_port *port, int flags)
41087 + if ((flags & UART_CONFIG_TYPE) && (ubi32_uarttio_request_port(port) == 0)) {
41088 + port->type = PORT_UBI32_UARTTIO;
41093 + * ubi32_uarttio_verify_port
41094 + * Verify the new serial_struct (for TIOCSSERIAL).
41096 + * The only change we allow are to the flags and type, and
41097 + * even then only between PORT_UBI32_UARTTIO and PORT_UNKNOWN
41099 +static int ubi32_uarttio_verify_port(struct uart_port *port, struct serial_struct *ser)
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,
41124 + * ubi32_uarttio_add_ports
41126 +static int __init ubi32_uarttio_add_ports(void)
41129 + struct ubi32_uarttio_port *uup = uarttio_ports;
41132 + for (i = 0; i < uarttio_nports; i++) {
41134 + * Setup the GPIOs
41136 + res = gpio_request(uup->tx_pin, "ubi32_uarttio_tx");
41138 + printk(KERN_WARNING "Failed to request GPIO %d\n", uup->tx_pin);
41143 + res = gpio_request(uup->rx_pin, "ubi32_uarttio_rx");
41145 + gpio_free(uup->tx_pin);
41146 + printk(KERN_WARNING "Failed to request GPIO %d\n", uup->rx_pin);
41151 + res = uart_add_one_port(&ubi32_uarttio_uart_driver, &uup->port);
41153 + gpio_free(uup->rx_pin);
41154 + gpio_free(uup->tx_pin);
41156 + printk(KERN_WARNING "Failed to add port %d,%d\n", uup->tx_pin, uup->rx_pin);
41162 + * Set the direction of the ports now, after we're sure that everything is ok
41164 + if (!uup->port_init) {
41165 + gpio_direction_output(uup->tx_pin, 1);
41166 + gpio_direction_input(uup->rx_pin);
41176 + * ubi32_uarttio_cleanup
41178 +static void ubi32_uarttio_cleanup(void)
41180 + struct ubi32_uarttio_port *uup;
41184 + * Stop the hardware thread
41186 + if (uarttio_inst.regs) {
41187 + thread_disable(uarttio_inst.regs->thread);
41189 + if (uarttio_inst.irq_requested) {
41190 + free_irq(uarttio_inst.irq, NULL);
41194 + * Get rid of the ports
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);
41206 + if (uarttio_inst.driver_registered) {
41207 + uart_unregister_driver(&ubi32_uarttio_uart_driver);
41212 + * ubi32_uarttio_setup_port
41213 + * Setup a port in the TIO registers
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)
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);
41225 + * Verify the ports are on chip
41227 + if (!tx_port || !rx_port) {
41228 + printk(KERN_WARNING "Invalid port(s) specified: %u or %u\n", tx_pin, rx_pin);
41232 + uup->tx_pin = tx_pin;
41233 + uup->rx_pin = rx_pin;
41234 + uup->uart = uart;
41237 + * Setup the port structure
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;
41247 + * We share this IRQ across all ports
41249 + uup->port.irq = uarttio_inst.irq;
41252 + * We really don't have a mem/map base but without these variables
41253 + * set, the serial_core won't startup.
41255 + uup->port.membase = (void __iomem *)uup;
41256 + uup->port.mapbase = (resource_size_t)uup;
41257 + spin_lock_init(&uup->port.lock);
41260 + * Set up the hardware
41262 + uart->flags = UARTTIO_UART_FLAG_SET_RATE | UARTTIO_UART_FLAG_RESET;
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;
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;
41274 + uart->baud_rate = baud;
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,
41289 + * ubi32_uarttio_parse_param
41291 +static int ubi32_uarttio_parse_param(char *str)
41302 + enum ubi32_uarttio_parse_states state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41303 + struct uarttio_uart *uart = uarttio_inst.regs->uarts;
41306 + * Run though the options and generate the proper structures
41308 + res = get_option(&str, &i);
41309 + while ((res == 2) || (res == 1)) {
41311 + case UBI32_UARTTIO_PARSE_STATE_BAUD:
41313 + * If we are here and nfound > 0 then create the port
41314 + * based on the previous input
41318 + * Create the port
41320 + if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41322 + * Port was invalid
41326 + printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41332 + * Reset the variables and go to the next state
41336 + state = UBI32_UARTTIO_PARSE_STATE_TX_PIN;
41339 + case UBI32_UARTTIO_PARSE_STATE_TX_PIN:
41341 + state = UBI32_UARTTIO_PARSE_STATE_RX_PIN;
41344 + case UBI32_UARTTIO_PARSE_STATE_RX_PIN:
41346 + state = UBI32_UARTTIO_PARSE_STATE_HS;
41349 + case UBI32_UARTTIO_PARSE_STATE_HS:
41352 + state = UBI32_UARTTIO_PARSE_STATE_CTS_PIN;
41356 + if (nfound == uarttio_inst.regs->max_uarts) {
41357 + printk(KERN_WARNING "Maximum number of serial ports reached\n");
41361 + state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41364 + case UBI32_UARTTIO_PARSE_STATE_CTS_PIN:
41366 + state = UBI32_UARTTIO_PARSE_STATE_RTS_PIN;
41369 + case UBI32_UARTTIO_PARSE_STATE_RTS_PIN:
41372 + if (nfound == uarttio_inst.regs->max_uarts) {
41373 + printk(KERN_WARNING "Maximum number of serial ports reached\n");
41377 + state = UBI32_UARTTIO_PARSE_STATE_BAUD;
41380 + res = get_option(&str, &i);
41383 + if ((res > 2) || state != UBI32_UARTTIO_PARSE_STATE_BAUD) {
41384 + printk(KERN_WARNING "Parameter syntax error.\n");
41390 + * Create the final port
41392 + if (ubi32_uarttio_setup_port(nfound - 1, uart, baud, tx_pin, rx_pin)) {
41395 + printk(KERN_INFO "Serial port %d: tx=%d:rx=%d @ %d\n", nfound, tx_pin, rx_pin, baud);
41398 + uarttio_nports = nfound;
41400 + return nfound ? 0 : -ENODEV;
41404 + * Reset the ports
41406 + uart = uarttio_inst.regs->uarts;
41407 + for (i = 0; i < uarttio_inst.regs->max_uarts; i++) {
41416 + * ubi32_uarttio_probe
41418 +static int ubi32_uarttio_probe(void)
41421 + struct uarttio_node *uart_node;
41422 + char *str = utio_ports_param;
41423 + static int probed;
41426 + * We only want to be probed once, we could be probed twice
41427 + * for example if we are used as a console
41435 + * Extract the TIO name from the setup string
41438 + if (*str == ',') {
41449 + uart_node = (struct uarttio_node *)devtree_find_node(utio_ports_param);
41450 + if (!uart_node) {
41454 + uarttio_inst.irq = uart_node->dn.recvirq;
41455 + uarttio_inst.regs = uart_node->regs;
41458 + * Parse module parameters.
41460 + ret = ubi32_uarttio_parse_param(str);
41465 + ubi32_uarttio_uart_driver.nr = uarttio_nports;
41470 + ubi32_uarttio_cleanup();
41474 +#if defined(CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE)
41476 + * ubi32_uarttio_console_setup
41478 +static int __init ubi32_uarttio_console_setup(struct console *co, char *options)
41482 + int parity = 'n';
41484 + struct ubi32_uarttio_port *uup;
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.
41491 + if (co->index == -1 || co->index >= uarttio_nports) {
41494 + uup = &uarttio_ports[co->index];
41495 + baud = uup->uart->baud_rate;
41496 + uup->uart->flags |= UARTTIO_UART_FLAG_ENABLED;
41499 + * Setup the GPIOs
41500 + * We have to use the direct interface because the gpio
41501 + * subsystem is not available at this point.
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);
41509 + * Start the thread
41511 + thread_enable(uarttio_inst.regs->thread);
41514 + * Process 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;
41523 + return uart_set_options(&uup->port, co, baud, 'n', 8, 'n');
41527 + * ubi32_uarttio_console_putchar
41529 +static void ubi32_uarttio_console_putchar(struct uart_port *port, int ch)
41531 + struct ubi32_uarttio_port *uup = port->private_data;
41533 + while (ubi32_uarttio_put_char(uup->uart, ch)) {
41539 + * ubi32_uarttio_console_write
41540 + * Interrupts are disabled on entering
41542 +static void ubi32_uarttio_console_write(struct console *co, const char *s, unsigned int count)
41544 + struct uart_port *port = &(uarttio_ports[co->index].port);
41545 + unsigned long flags = 0;
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);
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,
41559 + .data = &ubi32_uarttio_uart_driver,
41562 +static int __init ubi32_uarttio_console_init(void)
41566 + res = ubi32_uarttio_probe();
41571 + register_console(&ubi32_uarttio_console);
41574 +console_initcall(ubi32_uarttio_console_init);
41575 +#endif /* CONFIG_SERIAL_UBI32_UARTTIO_CONSOLE */
41578 + * ubi32_serial_suspend
41580 +static int ubi32_uarttio_suspend(struct platform_device *pdev, pm_message_t state)
41583 + for (i = 0; i < uarttio_nports; i++) {
41584 + uart_suspend_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41591 + * ubi32_serial_resume
41593 +static int ubi32_uarttio_resume(struct platform_device *pdev)
41596 + for (i = 0; i < uarttio_nports; i++) {
41597 + uart_resume_port(&ubi32_uarttio_uart_driver, &uarttio_ports[i].port);
41604 + * ubi32_uarttio_remove
41606 +static int __devexit ubi32_uarttio_remove(struct platform_device *pdev)
41608 + ubi32_uarttio_cleanup();
41610 + uart_unregister_driver(&ubi32_uarttio_uart_driver);
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,
41620 + .name = DRIVER_NAME,
41621 + .owner = THIS_MODULE,
41627 + * Called at boot time.
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
41636 +static int __init ubi32_uarttio_setup(char *str)
41638 + strncpy(utio_ports_param, str, UBI32_UARTTIO_MAX_PARAM_LEN);
41639 + utio_ports_param[UBI32_UARTTIO_MAX_PARAM_LEN - 1] = 0;
41642 +__setup("uarttio=", ubi32_uarttio_setup);
41646 + * ubi32_uarttio_init
41648 +static int __init ubi32_uarttio_init(void)
41653 + ret = ubi32_uarttio_probe();
41659 + * Request the IRQ (do it here since many ports share the same IRQ)
41661 + ret = request_irq(uarttio_inst.irq, ubi32_uarttio_isr, IRQF_DISABLED, DRIVER_NAME, NULL);
41663 + printk(KERN_WARNING "Could not request IRQ %d\n", uarttio_inst.irq);
41666 + uarttio_inst.irq_requested = 1;
41669 + * Register the UART driver and add the ports
41671 + ret = uart_register_driver(&ubi32_uarttio_uart_driver);
41675 + uarttio_inst.driver_registered = 1;
41677 + ret = ubi32_uarttio_add_ports();
41679 + ubi32_uarttio_cleanup();
41684 + * Start the thread
41686 + thread_enable(uarttio_inst.regs->thread);
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);
41693 + pr_info("Serial: Ubicom32 uarttio started on thread:%d irq:%d\n", uarttio_inst.regs->thread, uarttio_inst.irq);
41698 + ubi32_uarttio_cleanup();
41701 +module_init(ubi32_uarttio_init);
41704 + * ubi32_uarttio_exit
41706 +static void __exit ubi32_uarttio_exit(void)
41708 + platform_driver_unregister(&ubi32_uarttio_platform_driver);
41710 +module_exit(ubi32_uarttio_exit);
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
41728 SPI driver for Samsung S3C24XX series ARM SoCs
41730 +config SPI_UBICOM32_GPIO
41731 + tristate "Ubicom32 SPI over GPIO"
41732 + depends on SPI_MASTER && UBICOM32 && EXPERIMENTAL
41733 + select SPI_BITBANG
41736 + SPI driver for the Ubicom32 architecture using
41737 + GPIO lines to provide the SPI bus.
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
41753 +++ b/drivers/spi/spi_ubicom32_gpio.c
41756 + * drivers/spi_spi_ubicom32_gpio.c
41757 + * Ubicom32 GPIO based SPI driver
41759 + * (C) Copyright 2009, Ubicom, Inc.
41761 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
41777 + * Ubicom32 implementation derived from (with many thanks):
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>
41789 +#include <linux/spi/spi.h>
41790 +#include <linux/spi/spi_bitbang.h>
41792 +#include <linux/gpio.h>
41794 +#include <asm/ip5000.h>
41795 +#include <asm/ubicom32-spi-gpio.h>
41797 +#define DRIVER_NAME "ubicom32-spi-gpio"
41799 +struct ubicom32_spi_gpio {
41800 + struct spi_bitbang bitbang;
41802 + struct ubicom32_spi_gpio_platform_data *pdata;
41804 + struct platform_device *dev;
41808 + * The following 4 functions are used by EXPAND_BITBANG_TXRX to bitbang the data out.
41810 +static inline void setsck(struct spi_device *dev, int on)
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);
41816 +static inline void setmosi(struct spi_device *dev, int on)
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);
41822 +static inline u32 getmiso(struct spi_device *dev)
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;
41828 +#define spidelay(x) ndelay(x)
41830 +#define EXPAND_BITBANG_TXRX
41831 +#include <linux/spi/spi_bitbang.h>
41834 + * ubicom32_spi_gpio_txrx_mode0
41836 +static u32 ubicom32_spi_gpio_txrx_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41838 + return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
41842 + * ubicom32_spi_gpio_txrx_mode1
41844 +static u32 ubicom32_spi_gpio_txrx_mode1(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41846 + return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
41850 + * ubicom32_spi_gpio_txrx_mode2
41852 +static u32 ubicom32_spi_gpio_txrx_mode2(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41854 + return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
41858 + * ubicom32_spi_gpio_txrx_mode3
41860 +static u32 ubicom32_spi_gpio_txrx_mode3(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
41862 + return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
41866 + * ubicom32_spi_gpio_chipselect
41868 +static void ubicom32_spi_gpio_chipselect(struct spi_device *dev, int value)
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;
41873 + if (value == BITBANG_CS_ACTIVE) {
41874 + gpio_set_value(cd->pin_cs, cs_polarity);
41877 + gpio_set_value(cd->pin_cs, !cs_polarity);
41881 + * ubicom32_spi_gpio_probe
41883 +static int ubicom32_spi_gpio_probe(struct platform_device *dev)
41885 + struct ubicom32_spi_gpio_platform_data *pdata;
41886 + struct spi_master *master;
41887 + struct ubicom32_spi_gpio *usg;
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");
41897 + usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(master);
41899 + platform_set_drvdata(dev, usg);
41902 + * Copy in the platform data
41904 + pdata = dev->dev.platform_data;
41905 + usg->pdata = dev->dev.platform_data;
41908 + * Request the GPIO lines
41910 + ret = gpio_request(pdata->pin_mosi, "spi-mosi");
41912 + dev_err(&dev->dev, "Failed to allocate spi-mosi GPIO\n");
41916 + ret = gpio_request(pdata->pin_miso, "spi-miso");
41918 + dev_err(&dev->dev, "Failed to allocate spi-miso GPIO\n");
41922 + ret = gpio_request(pdata->pin_clk, "spi-clk");
41924 + dev_err(&dev->dev, "Failed to allocate spi-clk GPIO\n");
41929 + * Setup spi-bitbang adaptor
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;
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;
41943 + * Setup the GPIO pins
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);
41952 + ret = spi_bitbang_start(&usg->bitbang);
41954 + goto err_no_bitbang;
41960 + spi_master_put(usg->bitbang.master);
41962 + gpio_free(pdata->pin_clk);
41965 + gpio_free(pdata->pin_miso);
41968 + gpio_free(pdata->pin_mosi);
41975 + * ubicom32_spi_gpio_remove
41977 +static int ubicom32_spi_gpio_remove(struct platform_device *dev)
41979 + struct ubicom32_spi_gpio *sp = platform_get_drvdata(dev);
41981 + spi_bitbang_stop(&sp->bitbang);
41982 + spi_master_put(sp->bitbang.master);
41988 + * Work with hotplug and coldplug
41990 +MODULE_ALIAS("platform:ubicom32_spi_gpio");
41992 +static struct platform_driver ubicom32_spi_gpio_drv = {
41993 + .probe = ubicom32_spi_gpio_probe,
41994 + .remove = ubicom32_spi_gpio_remove,
41996 + .name = DRIVER_NAME,
41997 + .owner = THIS_MODULE,
42002 + * ubicom32_spi_gpio_init
42004 +static int __init ubicom32_spi_gpio_init(void)
42006 + return platform_driver_register(&ubicom32_spi_gpio_drv);
42010 + * ubicom32_spi_gpio_exit
42012 +static void __exit ubicom32_spi_gpio_exit(void)
42014 + platform_driver_unregister(&ubicom32_spi_gpio_drv);
42017 +module_init(ubicom32_spi_gpio_init);
42018 +module_exit(ubicom32_spi_gpio_exit);
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
42027 If you compile this as a module, it will be called uio_sercos3.
42029 +config UIO_UBICOM32RING
42030 + tristate "Ubicom32 Ring Buffer driver"
42033 + Userspace I/O interface for a Ubicom32 Ring Buffer.
42035 + If you compile this as a module, it will be called uio_ubicom32ring
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
42046 +++ b/drivers/uio/uio_ubicom32ring.c
42049 + * drivers/uio/uio_ubicom32ring.c
42051 + * Userspace I/O platform driver for Ubicom32 ring buffers
42053 + * (C) Copyright 2009, Ubicom, Inc.
42055 + * This file is part of the Ubicom32 Linux Kernel Port.
42057 + * Based on uio_ubicom32ring.c by Magnus Damm
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.
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.
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/>.
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>
42081 +#include <asm/ip5000.h>
42082 +#include <asm/ubicom32ring.h>
42084 +#define DRIVER_NAME "uio_ubicom32ring"
42086 +struct uio_ubicom32ring_data {
42087 + struct uio_info *uioinfo;
42089 + struct uio_ubicom32ring_regs *regs;
42092 + * IRQ used to kick the ring buffer
42099 + unsigned long flags;
42104 +static irqreturn_t uio_ubicom32ring_handler(int irq, struct uio_info *dev_info)
42106 + struct uio_ubicom32ring_data *priv = dev_info->priv;
42108 + /* Just disable the interrupt in the interrupt controller, and
42109 + * remember the state so we can allow user space to enable it later.
42112 + if (!test_and_set_bit(0, &priv->flags))
42113 + disable_irq_nosync(irq);
42115 + return IRQ_HANDLED;
42118 +static int uio_ubicom32ring_irqcontrol(struct uio_info *dev_info, s32 irq_on)
42120 + struct uio_ubicom32ring_data *priv = dev_info->priv;
42121 + unsigned long flags;
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.
42127 + * Serialize this operation to support multiple tasks.
42130 + spin_lock_irqsave(&priv->lock, flags);
42132 + if (irq_on & 2) {
42134 + * Kick the ring buffer (if we can)
42136 + if (priv->irq_tx != 0xFF) {
42137 + ubicom32_set_interrupt(priv->irq_tx);
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);
42146 + if (!test_and_set_bit(0, &priv->flags))
42147 + disable_irq(dev_info->irq);
42151 + spin_unlock_irqrestore(&priv->lock, flags);
42156 +static int uio_ubicom32ring_probe(struct platform_device *pdev)
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;
42168 + uioinfo = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
42170 + dev_err(&pdev->dev, "unable to kmalloc\n");
42175 + * Allocate private data with some string space after
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);
42181 + dev_err(&pdev->dev, "unable to kmalloc\n");
42186 + strcpy(priv->name, DRIVER_NAME ":");
42187 + if (pdev->dev.platform_data) {
42188 + strcat(priv->name, pdev->dev.platform_data);
42190 + uioinfo->priv = priv;
42191 + uioinfo->name = priv->name;
42192 + uioinfo->version = "0.1";
42194 + priv->uioinfo = uioinfo;
42195 + spin_lock_init(&priv->lock);
42196 + priv->flags = 0; /* interrupt is enabled to begin with */
42199 + * Get our resources, the IRQ_TX and IRQ_RX are optional.
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;
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;
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");
42222 + regs = (struct uio_ubicom32ring_regs *)mem_resource->start;
42223 + priv->regs = regs;
42225 + if (regs->version != UIO_UBICOM32RING_REG_VERSION) {
42226 + dev_err(&pdev->dev, "version %d not supported\n", regs->version);
42232 + * First range is the shared register space, if we have any
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;
42240 + dev_info(&pdev->dev, "regs:%p (%u) / rings: %d found\n", regs->regs, regs->regs_size, regs->num_rings);
42242 + dev_info(&pdev->dev, "rings: %d found\n", regs->num_rings);
42246 + * The rest of the range correspond to the rings
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");
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);
42265 + while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
42266 + uiomem->size = 0;
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.
42276 + * Interrupt sharing is not supported.
42278 + uioinfo->irq_flags = IRQF_DISABLED;
42279 + uioinfo->irqcontrol = uio_ubicom32ring_irqcontrol;
42281 + ret = uio_register_device(&pdev->dev, priv->uioinfo);
42283 + dev_err(&pdev->dev, "unable to register uio device\n");
42287 + platform_set_drvdata(pdev, priv);
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);
42300 +static int uio_ubicom32ring_remove(struct platform_device *pdev)
42302 + struct uio_ubicom32ring_data *priv = platform_get_drvdata(pdev);
42304 + uio_unregister_device(priv->uioinfo);
42305 + kfree(priv->uioinfo);
42310 +static struct platform_driver uio_ubicom32ring = {
42311 + .probe = uio_ubicom32ring_probe,
42312 + .remove = uio_ubicom32ring_remove,
42314 + .name = DRIVER_NAME,
42315 + .owner = THIS_MODULE,
42319 +static int __init uio_ubicom32ring_init(void)
42321 + return platform_driver_register(&uio_ubicom32ring);
42324 +static void __exit uio_ubicom32ring_exit(void)
42326 + platform_driver_unregister(&uio_ubicom32ring);
42329 +module_init(uio_ubicom32ring_init);
42330 +module_exit(uio_ubicom32ring_exit);
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);
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!! */
42344 + case USB_ENDPOINT_XFER_BULK:
42345 + if ((gadget->is_dualspeed) && (ep->maxpacket < 512))
42350 @@ -174,7 +178,7 @@ ep_matches (
42352 desc->bEndpointAddress |= epnum;
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
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
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, ...)'
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
42386 +ifeq ($(CONFIG_UBICOM32), y)
42387 + musb_hdrc-objs += ubi32_usb.o
42390 ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
42391 musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o
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>
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);
42406 #include "musb_core.h"
42409 @@ -147,7 +154,7 @@ static inline struct musb *dev_to_musb(s
42412 /*-------------------------------------------------------------------------*/
42414 +#ifndef CONFIG_UBICOM32
42415 #ifndef CONFIG_USB_TUSB6010
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);
42422 +#endif /* T6010 */
42423 +#else /* UBICOM */
42426 + * Load an endpoint's FIFO
42428 +void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 wCount, const u8 *pSource)
42430 + void __iomem *fifo = hw_ep->fifo;
42432 + prefetch((u8 *)pSource);
42434 + DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
42435 + 'T', hw_ep->epnum, fifo, wCount, pSource);
42437 + usb_tio_write_fifo((u32)fifo, (u32)pSource, wCount);
42441 -#endif /* normal PIO */
42444 + * Unload an endpoint's FIFO
42446 +void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 wCount, u8 *pDest)
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);
42454 +#endif /* CONFIG_UBICOM32 */
42457 /*-------------------------------------------------------------------------*/
42458 @@ -872,12 +909,19 @@ void musb_start(struct musb *musb)
42459 musb_writeb(regs, MUSB_TESTMODE, 0);
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 */
42470 + musb_writeb(regs, MUSB_POWER, MUSB_POWER_HSENAB
42471 + /* ENSUSPEND wedges tusb */
42472 + /* | MUSB_POWER_ENSUSPEND */
42476 musb->is_active = 0;
42477 devctl = musb_readb(regs, MUSB_DEVCTL);
42478 @@ -1079,6 +1123,7 @@ static struct fifo_cfg __initdata mode_4
42482 +#ifndef CONFIG_UBICOM32
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
42491 +#endif /* CONFIG_UBICOM32 */
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");
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;
42505 for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
42506 musb_ep_select(mbase, epnum);
42507 hw_ep = musb->endpoints + epnum;
42509 /* read from core using indexed model */
42510 +#ifndef CONFIG_UBICOM32
42511 reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
42513 + reg = musb_readb(musb->mregs, 0x10 + MUSB_FIFOSIZE);
42517 /* 0's returned when no more endpoints */
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;
42525 + hw_ep->is_shared_fifo = true;
42526 +#ifndef CONFIG_UBICOM32
42527 + continue; /* For ubicom processors, shared ep is all we get */
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.
42536 +#ifndef CONFIG_UBICOM32
42539 musb->bulk_ep = hw_ep;
42541 + if ((musb->bulk_ep_in) && (musb->bulk_ep_out))
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;
42551 +#endif /* CONFIG_UBICOM32 */
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);
42565 @@ -1408,12 +1478,16 @@ static int __init musb_core_init(u16 mus
42568 if (reg & MUSB_CONFIGDATA_DYNFIFO) {
42569 +#ifndef CONFIG_UBICOM32
42570 if (musb->config->dyn_fifo)
42571 status = ep_config_from_table(musb);
42576 ERR("reconfigure software for Dynamic FIFOs\n");
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
42585 /*-------------------------------------------------------------------------*/
42587 -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
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)
42593 unsigned long flags;
42594 @@ -1487,10 +1561,17 @@ static irqreturn_t generic_interrupt(int
42596 spin_lock_irqsave(&musb->lock, flags);
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);
42603 + musb_read_int_status(&musb->int_usb, &musb->int_tx, &musb->int_rx);
42604 + //ubi32_usb_int_clr();
42605 + musb_int_count++;
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);
42612 @@ -2222,6 +2303,10 @@ static struct platform_driver musb_drive
42614 static int __init musb_init(void)
42616 +#ifdef CONFIG_UBICOM32
42617 + ubi32_usb_init();
42620 #ifdef CONFIG_USB_MUSB_HDRC_HCD
42621 if (usb_disabled())
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
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;
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
42638 extern void musb_hnp_stop(struct musb *musb);
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);
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
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
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
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;
42676 + if (musb->endpoints[epnum].is_shared_fifo)
42677 + musb_ep = &musb->endpoints[epnum].ep_in;
42679 + musb_ep = &musb->endpoints[epnum].ep_out;
42680 + len = musb_ep->packet_sz;
42682 csr = musb_readw(epio, MUSB_RXCSR);
42684 @@ -715,7 +721,7 @@ static void rxstate(struct musb *musb, s
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);
42693 @@ -734,10 +740,15 @@ void musb_g_rx(struct musb *musb, u8 epn
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;
42702 + if (musb->endpoints[epnum].is_shared_fifo)
42703 + musb_ep = &musb->endpoints[epnum].ep_in;
42705 + musb_ep = &musb->endpoints[epnum].ep_out;
42707 musb_ep_select(mbase, epnum);
42709 request = next_request(musb_ep);
42710 @@ -1559,7 +1570,7 @@ init_peripheral_ep(struct musb *musb, st
42713 INIT_LIST_HEAD(&ep->req_list);
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
42724 +#ifndef CONFIG_USB_MUSB_OTG
42725 + musb_pullup(musb, 1);
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);
42741 case USB_REQ_CLEAR_FEATURE:
42743 case USB_RECIP_DEVICE:
42744 - if (ctrlrequest->wValue
42745 + if (le16_to_cpu(ctrlrequest->wValue)
42746 != USB_DEVICE_REMOTE_WAKEUP)
42748 musb->may_wakeup = 0;
42749 @@ -261,8 +261,8 @@ __acquires(musb->lock)
42752 || num >= MUSB_C_NUM_EPS
42753 - || ctrlrequest->wValue
42754 - != USB_ENDPOINT_HALT)
42755 + || le16_to_cpu(ctrlrequest->wValue
42756 + != USB_ENDPOINT_HALT))
42759 if (ctrlrequest->wIndex & USB_DIR_IN)
42760 @@ -292,7 +292,7 @@ __acquires(musb->lock)
42762 case USB_RECIP_DEVICE:
42764 - switch (ctrlrequest->wValue) {
42765 + switch (le16_to_cpu(ctrlrequest->wValue)) {
42766 case USB_DEVICE_REMOTE_WAKEUP:
42767 musb->may_wakeup = 1;
42769 @@ -374,8 +374,8 @@ stall:
42772 || epnum >= MUSB_C_NUM_EPS
42773 - || ctrlrequest->wValue
42774 - != USB_ENDPOINT_HALT)
42775 + || le16_to_cpu(ctrlrequest->wValue
42776 + != USB_ENDPOINT_HALT))
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 */
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;
42790 + txcsr |= (MUSB_TXCSR_TXPKTRDY & (~MUSB_TXCSR_H_WZC_BITS));
42792 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
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;
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;
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,
42811 csr = musb_readw(epio, MUSB_TXCSR);
42812 usb_settoggle(udev, qh->epnum, 1,
42813 - (csr & MUSB_TXCSR_H_DATATOGGLE)
42815 + ((csr & MUSB_TXCSR_H_DATATOGGLE)
42818 csr = musb_readw(epio, MUSB_RXCSR);
42819 usb_settoggle(udev, qh->epnum, 0,
42820 - (csr & MUSB_RXCSR_H_DATATOGGLE)
42822 + ((csr & MUSB_RXCSR_H_DATATOGGLE)
42827 @@ -337,9 +344,11 @@ musb_giveback(struct musb_qh *qh, struct
42828 struct musb *musb = ep->musb;
42829 int ready = qh->is_ready;
42831 +#ifndef CONFIG_UBICOM32 /* BUG! */
42832 if (ep->is_shared_fifo)
42836 is_in = usb_pipein(urb->pipe);
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);
42842 csr = musb_readw(epio, MUSB_RXCSR);
42843 +#ifndef CONFIG_UBICOM32
42844 csr |= MUSB_RXCSR_H_WZC_BITS;
42846 + csr &= ~MUSB_RXCSR_H_WZC_BITS;
42848 if (unlikely(do_flush))
42849 musb_h_flush_rxfifo(hw_ep, csr);
42851 @@ -572,14 +585,24 @@ musb_rx_reinit(struct musb *musb, struct
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);
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));
42871 + musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
42874 /* scrub all previous state, clearing toggle */
42876 @@ -680,7 +703,7 @@ static void musb_ep_program(struct musb
42877 /* ASSERT: TXCSR_DMAENAB was already cleared */
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;
42889 +#ifdef CONFIG_UBICOM32
42890 + if (hw_ep->is_shared_fifo) {
42891 + qh = hw_ep->in_qh;
42893 +#ifdef CONFIG_USB_SERIAL_SIERRAWIRELESS
42894 + printk(KERN_DEBUG "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr,
42895 + dma ? ", dma" : "");
42898 urb = next_urb(qh);
42901 musb_ep_select(mbase, epnum);
42902 tx_csr = musb_readw(epio, MUSB_TXCSR);
42904 @@ -1210,9 +1243,14 @@ void musb_host_tx(struct musb *musb, u8
42905 * we have a candidate... NAKing is *NOT* an error
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);
42913 + musb_writew(epio, MUSB_TXCSR,
42914 + MUSB_TXCSR_TXPKTRDY);
42919 @@ -1316,8 +1354,14 @@ void musb_host_tx(struct musb *musb, u8
42920 qh->segsize = wLength;
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);
42928 + musb_writew(epio, MUSB_TXCSR,
42929 + MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY);
42933 DBG(1, "not complete, but dma enabled?\n");
42935 @@ -1365,6 +1409,49 @@ finish:
42939 +/* Schedule next QH from musb->in_bulk and move the current qh to
42940 + * the end; avoids starvation for other endpoints.
42942 +static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
42944 + struct dma_channel *dma;
42946 + void __iomem *mbase = musb->mregs;
42947 + void __iomem *epio = ep->regs;
42948 + struct musb_qh *cur_qh, *next_qh;
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);
42959 + cur_qh = first_qh(&musb->in_bulk);
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;
42968 + musb_save_toggle(ep, 1, urb);
42970 + /* move cur_qh to end of queue */
42971 + list_move_tail(&cur_qh->ring, &musb->in_bulk);
42973 + /* get the next qh from musb->in_bulk */
42974 + next_qh = first_qh(&musb->in_bulk);
42976 + /* set rx_reinit and schedule the next qh */
42977 + ep->rx_reinit = 1;
42978 + musb_start_urb(musb, 1, next_qh);
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
42988 struct dma_channel *dma;
42991 musb_ep_select(mbase, epnum);
42993 urb = next_urb(qh);
42994 @@ -1407,6 +1494,13 @@ void musb_host_rx(struct musb *musb, u8
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" : "");
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) {
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);
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.
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.
43027 - DBG(6, "RX end %d NAK timeout\n", epnum);
43028 + if (usb_pipebulk(urb->pipe)
43030 + && !list_is_singular(&musb->in_bulk)) {
43031 + musb_bulk_rx_nak_timeout(musb, hw_ep);
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);
43040 + musb_writew(epio, MUSB_RXCSR, (~(MUSB_RXCSR_H_WZC_BITS))| MUSB_RXCSR_H_REQPKT);
43045 @@ -1495,8 +1601,13 @@ void musb_host_rx(struct musb *musb, u8
43046 rx_csr &= ~MUSB_RXCSR_H_REQPKT;
43048 musb_ep_select(mbase, epnum);
43049 +#ifndef CONFIG_UBICOM32
43050 musb_writew(epio, MUSB_RXCSR,
43051 MUSB_RXCSR_H_WZC_BITS | rx_csr);
43053 + musb_writew(epio, MUSB_RXCSR,
43054 + (~MUSB_RXCSR_H_WZC_BITS) & rx_csr);
43058 if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
43059 @@ -1526,7 +1637,7 @@ void musb_host_rx(struct musb *musb, u8
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])
43071 hw_ep = &musb->endpoints[epnum];
43072 +#ifndef CONFIG_UBICOM32
43073 if (hw_ep == musb->bulk_ep)
43076 + if ((hw_ep == musb->bulk_ep_in) || (hw_ep == musb->bulk_ep_out)) /* Ubicom */
43081 diff = hw_ep->max_packet_sz_rx - qh->maxpacket;
43082 @@ -1756,7 +1871,14 @@ static int musb_schedule(
43087 +#ifdef CONFIG_UBICOM32
43088 + if (((best_diff >= qh->maxpacket)) && ((qh->type == USB_ENDPOINT_XFER_BULK) && (!is_in)))
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;
43097 @@ -1767,6 +1889,22 @@ static int musb_schedule(
43098 } else if (best_end < 0) {
43102 + if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
43103 + /* hw_ep = musb->bulk_ep; */
43105 + head = &musb->in_bulk;
43106 + hw_ep = musb->bulk_ep_in; /* UBICOM */
43109 + head = &musb->out_bulk;
43110 + hw_ep = musb->bulk_ep_out; /* UBICOM */
43113 + } else if (best_end < 0) {
43120 @@ -1779,6 +1917,13 @@ success:
43121 list_add_tail(&qh->ring, head);
43125 + * It's not make sense to set NAK timeout when qh->mux = 0,
43126 + * There is nothing else to schedule
43128 + if ((qh->type == USB_ENDPOINT_XFER_BULK) && (qh->mux == 0))
43129 + qh->intv_reg = 0;
43132 qh->hep->hcpriv = qh;
43134 @@ -1884,6 +2029,15 @@ static int musb_urb_enqueue(
43135 case USB_ENDPOINT_XFER_ISOC:
43136 /* iso always uses log encoding */
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;
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 __
43156 +#ifndef CONFIG_UBICOM32
43157 /* NOTE: these offsets are all in bytes */
43159 static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
43160 @@ -70,7 +71,37 @@ static inline void musb_writew(void __io
43162 static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
43163 { __raw_writel(data, addr + offset); }
43165 +#include <asm/ubicom32-tio.h>
43166 +static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
43169 + usb_tio_read_u16((u32)(addr + offset), &data);
43173 +static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43176 + usb_tio_read_u8((u32)(addr + offset), &data);
43180 +static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
43182 + usb_tio_write_u16((u32)(addr + offset), data);
43185 +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
43187 + usb_tio_write_u8((u32)(addr + offset), data);
43190 +static inline void musb_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx)
43192 + return usb_tio_read_int_status(int_usb, int_tx, int_rx);
43194 +#endif /* CONFIG_UBICOM32 */
43196 #ifdef CONFIG_USB_TUSB6010
43198 @@ -104,7 +135,7 @@ static inline void musb_writeb(void __io
43199 __raw_writew(tmp, addr + (offset & ~1));
43203 +#elif !defined(CONFIG_UBICOM32)
43205 static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
43206 { return __raw_readb(addr + offset); }
43208 +++ b/drivers/usb/musb/ubi32_usb.c
43211 + * drivers/usb/musb/ubi32_usb.c
43212 + * Ubicom32 usb controller driver.
43214 + * (C) Copyright 2009, Ubicom, Inc.
43215 + * Copyright (C) 2005-2006 by Texas Instruments
43217 + * Derived from the Texas Instruments Inventra Controller Driver for Linux.
43219 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
43235 + * Ubicom32 implementation derived from (with many thanks):
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>
43249 +#include <asm/io.h>
43250 +#include <asm/ip5000.h>
43251 +#include "musb_core.h"
43253 +void musb_platform_enable(struct musb *musb)
43256 +void musb_platform_disable(struct musb *musb)
43260 +int musb_platform_set_mode(struct musb *musb, u8 musb_mode) {
43264 +static void ip5k_usb_hcd_vbus_power(struct musb *musb, int is_on, int sleeping)
43268 +static void ip5k_usb_hcd_set_vbus(struct musb *musb, int is_on)
43271 + /* HDRC controls CPEN, but beware current surges during device
43272 + * connect. They can trigger transient overcurrent conditions
43273 + * that must be ignored.
43276 + devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
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;
43284 + MUSB_HST_MODE(musb);
43286 + musb->is_active = 0;
43288 + /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
43289 + * jumping right to B_IDLE...
43292 + musb->xceiv.default_a = 0;
43293 + musb->xceiv.state = OTG_STATE_B_IDLE;
43294 + devctl &= ~MUSB_DEVCTL_SESSION;
43296 + MUSB_DEV_MODE(musb);
43298 + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
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));
43305 +static int ip5k_usb_hcd_set_power(struct otg_transceiver *x, unsigned mA)
43310 +static int musb_platform_resume(struct musb *musb);
43312 +int __init musb_platform_init(struct musb *musb)
43315 +#ifdef CONFIG_UBICOM32_V4
43318 + "move.4 %0, CHIP_ID \n\t"
43321 + if (chip_id == 0x30001) {
43322 + *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 30);
43324 + *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 31);
43326 + *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 17);
43328 + *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_TEST)) &= ~(1 << 14);
43332 + *((u32_t *)(GENERAL_CFG_BASE + GEN_USB_PHY_CFG)) |= ((1 << 14) | (1 <<15));
43334 + /* The i-clk is AUTO gated. Hence there is no need
43335 + * to disable it until the driver is shutdown */
43337 + clk_enable(musb->clock);
43338 + musb_platform_resume(musb);
43340 + ip5k_usb_hcd_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
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;
43351 +int musb_platform_suspend(struct musb *musb)
43355 +int musb_platform_resume(struct musb *musb)
43360 +int musb_platform_exit(struct musb *musb)
43362 + ip5k_usb_hcd_vbus_power(musb, 0 /*off*/, 1);
43363 + musb_platform_suspend(musb);
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
43372 +config LCD_UBICOM32
43373 + tristate "Ubicom Backlight Driver"
43374 + depends on LCD_CLASS_DEVICE && UBICOM32
43377 + If you have a Ubicom32 based system with an LCD panel, say Y to enable
43378 + the power control driver for it.
43383 @@ -214,3 +222,11 @@ config BACKLIGHT_SAHARA
43385 If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
43388 +config BACKLIGHT_UBICOM32
43389 + tristate "Ubicom Backlight Driver"
43390 + depends on BACKLIGHT_CLASS_DEVICE && UBICOM32
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
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
43411 +obj-$(CONFIG_BACKLIGHT_UBICOM32) += ubicom32bl.o
43413 +++ b/drivers/video/backlight/ubicom32bl.c
43416 + * drivers/video/backlight/ubicom32bl.c
43417 + * Backlight driver for the Ubicom32 platform
43419 + * (C) Copyright 2009, Ubicom, Inc.
43421 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
43437 + * Ubicom32 implementation derived from (with many thanks):
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>
43449 +#include <asm/ubicom32bl.h>
43450 +#include <asm/ip5000.h>
43452 +#define DRIVER_NAME "ubicom32bl"
43453 +#define UBICOM32BL_MAX_BRIGHTNESS 255
43455 +struct ubicom32bl_data {
43457 + * Pointer to the platform data structure. Keep this around since we need values
43458 + * from it to set the backlight intensity.
43460 + const struct ubicom32bl_platform_data *pdata;
43463 + * Backlight device, we have to save this for use when we remove ourselves.
43465 + struct backlight_device *bldev;
43468 + * Current intensity, used for get_intensity.
43470 + int cur_intensity;
43473 + * Init function for PWM
43475 + int (*init_fn)(struct ubicom32bl_data *);
43478 + * Set intensity function depending on the backlight type
43480 + int (*set_intensity_fn)(struct ubicom32bl_data *, int);
43484 + * ubicom32bl_set_intensity_gpio
43486 +static int ubicom32bl_set_intensity_gpio(struct ubicom32bl_data *ud, int intensity)
43488 + ud->cur_intensity = intensity ? 255 : 0;
43500 + * ubicom32bl_set_intensity_hw
43502 +static int ubicom32bl_set_intensity_hw(struct ubicom32bl_data *ud, int intensity)
43504 + u16_t period = ud->pdata->pwm_period;
43508 + * Calculate the new duty cycle
43510 + duty = (period * intensity) / (UBICOM32BL_MAX_BRIGHTNESS + 1);
43513 + * Set the new duty cycle
43515 + switch (ud->pdata->pwm_channel) {
43518 + * Channel 0 is in the lower half of PORT C ctl0 and ctl1
43520 + UBICOM32_IO_PORT(RC)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43525 + * Channel 1 is in the upper half of PORT C ctl0 and ctl2
43527 + UBICOM32_IO_PORT(RC)->ctl2 = (ud->pdata->pwm_period << 16) | duty;
43532 + * Channel 2 is in PORT H ctl0 and ctl1
43534 + UBICOM32_IO_PORT(RH)->ctl1 = (ud->pdata->pwm_period << 16) | duty;
43538 + ud->cur_intensity = intensity;
43544 + * ubicom32bl_set_intensity
43546 +static int ubicom32bl_set_intensity(struct backlight_device *bd)
43548 + struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43549 + int intensity = bd->props.brightness;
43552 + * If we're blanked the the intensity doesn't matter.
43554 + if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
43559 + * Check for inverted backlight.
43561 + if (ud->pdata->invert) {
43562 + intensity = UBICOM32BL_MAX_BRIGHTNESS - intensity;
43565 + if (ud->set_intensity_fn) {
43566 + return ud->set_intensity_fn(ud, intensity);
43573 + * ubicom32bl_get_intensity
43574 + * Return the current intensity of the backlight.
43576 +static int ubicom32bl_get_intensity(struct backlight_device *bd)
43578 + struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd);
43580 + return ud->cur_intensity;
43584 + * ubicom32bl_init_hw_pwm
43585 + * Set the appropriate PWM registers
43587 +static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud)
43592 + u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ;
43594 + switch (ud->pdata->pwm_channel) {
43597 + * Channel 0 is in the lower half of PORT C ctl0 and ctl1
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;
43606 + * Channel 1 is in the upper half of PORT C ctl0 and ctl2
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;
43615 + * Channel 2 is in PORT H ctl0 and ctl1
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;
43627 + * ubicom32bl_init_gpio
43628 + * Allocate the appropriate GPIO
43630 +static int ubicom32bl_init_gpio(struct ubicom32bl_data *ud)
43635 +static struct backlight_ops ubicom32bl_ops = {
43636 + .get_brightness = ubicom32bl_get_intensity,
43637 + .update_status = ubicom32bl_set_intensity,
43641 + * ubicom32bl_probe
43643 +static int ubicom32bl_probe(struct platform_device *pdev)
43645 + const struct ubicom32bl_platform_data *pdata = pdev->dev.platform_data;
43646 + struct ubicom32bl_data *ud;
43647 + struct backlight_device *bldev;
43651 + * Check to see if we have any platform data, if we don't then the backlight is not
43652 + * configured on this device.
43659 + * Allocate our private data
43661 + ud = kzalloc(sizeof(struct ubicom32bl_data), GFP_KERNEL);
43666 + ud->pdata = pdata;
43669 + * Check to see that the platform data is valid for this driver
43671 + switch (pdata->type) {
43672 + case UBICOM32BL_TYPE_PWM:
43675 + * Make sure we have a PWM peripheral
43679 + "move.4 %0, CHIP_ID \n\t"
43682 + if (chipid != 0x00030001) {
43683 + retval = -ENODEV;
43687 + if (pdata->pwm_channel > 3) {
43688 + retval = -ENODEV;
43691 + if (pdata->pwm_prescale > 16) {
43692 + retval = -EINVAL;
43696 + ud->init_fn = ubicom32bl_init_hw_pwm;
43697 + ud->set_intensity_fn = ubicom32bl_set_intensity_hw;
43701 + case UBICOM32BL_TYPE_PWM_HRT:
43702 + // For now, PWM HRT devices are treated as binary lights.
43704 + case UBICOM32BL_TYPE_BINARY:
43705 + ud->init_fn = ubicom32bl_init_gpio;
43706 + ud->set_intensity_fn = ubicom32bl_set_intensity_gpio;
43711 + * Register our backlight device
43713 + bldev = backlight_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32bl_ops);
43714 + if (IS_ERR(bldev)) {
43715 + retval = PTR_ERR(bldev);
43719 + ud->bldev = bldev;
43720 + ud->cur_intensity = pdata->default_intensity;
43721 + platform_set_drvdata(pdev, ud);
43724 + * Start up the backlight at the prescribed default intensity
43726 + bldev->props.power = FB_BLANK_UNBLANK;
43727 + bldev->props.max_brightness = UBICOM32BL_MAX_BRIGHTNESS;
43728 + bldev->props.brightness = pdata->default_intensity;
43730 + if (ud->init_fn) {
43731 + if (ud->init_fn(ud) != 0) {
43732 + retval = -ENODEV;
43733 + backlight_device_unregister(ud->bldev);
43737 + ubicom32bl_set_intensity(bldev);
43739 + printk(KERN_INFO DRIVER_NAME ": Backlight driver started\n");
43744 + platform_set_drvdata(pdev, NULL);
43750 + * ubicom32bl_remove
43752 +static int __exit ubicom32bl_remove(struct platform_device *pdev)
43754 + struct ubicom32bl_data *ud = platform_get_drvdata(pdev);
43756 + backlight_device_unregister(ud->bldev);
43757 + platform_set_drvdata(pdev, NULL);
43763 +static struct platform_driver ubicom32bl_driver = {
43765 + .name = DRIVER_NAME,
43766 + .owner = THIS_MODULE,
43769 + .remove = __exit_p(ubicom32bl_remove),
43773 + * ubicom32bl_init
43775 +static int __init ubicom32bl_init(void)
43777 + return platform_driver_probe(&ubicom32bl_driver, ubicom32bl_probe);
43779 +module_init(ubicom32bl_init);
43782 + * ubicom32bl_exit
43784 +static void __exit ubicom32bl_exit(void)
43786 + platform_driver_unregister(&ubicom32bl_driver);
43788 +module_exit(ubicom32bl_exit);
43790 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
43791 +MODULE_DESCRIPTION("Ubicom32 backlight driver");
43792 +MODULE_LICENSE("GPL");
43794 +++ b/drivers/video/backlight/ubicom32lcd.c
43797 + * drivers/vdeio/backlight/ubicom32lcd.c
43798 + * LCD driver for the Ubicom32 platform
43800 + * (C) Copyright 2009, Ubicom, Inc.
43802 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
43818 + * Ubicom32 implementation derived from (with many thanks):
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>
43831 +#include <asm/ubicom32lcd.h>
43832 +#include <asm/ip5000.h>
43834 +#define DRIVER_NAME "ubicom32lcd"
43836 +struct ubicom32lcd_data {
43838 + * Pointer to the platform data structure. Keep this around since we need values
43839 + * from it to set the backlight intensity.
43841 + const struct ubicom32lcd_platform_data *pdata;
43844 + * LCD device, we have to save this for use when we remove ourselves.
43846 + struct lcd_device *lcddev;
43850 + * ubicom32lcd_set_power
43852 +static int ubicom32lcd_set_power(struct lcd_device *ld, int power)
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);
43860 + gpio_direction_output(ud->pdata->vgh_gpio, !ud->pdata->vgh_polarity);
43865 + * ubicom32lcd_get_power
43867 +static int ubicom32lcd_get_power(struct lcd_device *ld)
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)) {
43878 +static struct lcd_ops ubicom32lcd_ops = {
43879 + .get_power = ubicom32lcd_get_power,
43880 + .set_power = ubicom32lcd_set_power,
43884 + * ubicom32lcd_probe
43886 +static int ubicom32lcd_probe(struct platform_device *pdev)
43888 + const struct ubicom32lcd_platform_data *pdata = pdev->dev.platform_data;
43889 + struct ubicom32lcd_data *ud;
43890 + struct lcd_device *lcddev;
43894 + * Check to see if we have any platform data, if we don't have a LCD to control
43901 + * Allocate our private data
43903 + ud = kzalloc(sizeof(struct ubicom32lcd_data), GFP_KERNEL);
43908 + ud->pdata = pdata;
43911 + * Request our GPIOs
43913 + retval = gpio_request(pdata->vgh_gpio, "vgh");
43915 + dev_err(&pdev->dev, "Failed to allocate vgh GPIO\n");
43920 + * Register our lcd device
43922 + lcddev = lcd_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32lcd_ops);
43923 + if (IS_ERR(lcddev)) {
43924 + retval = PTR_ERR(lcddev);
43928 + ud->lcddev = lcddev;
43929 + platform_set_drvdata(pdev, ud);
43931 + ubicom32lcd_set_power(lcddev, FB_BLANK_UNBLANK);
43933 + printk(KERN_INFO DRIVER_NAME ": LCD driver started\n");
43938 + gpio_free(pdata->vgh_gpio);
43941 + platform_set_drvdata(pdev, NULL);
43947 + * ubicom32lcd_remove
43949 +static int __exit ubicom32lcd_remove(struct platform_device *pdev)
43951 + struct ubicom32lcd_data *ud = platform_get_drvdata(pdev);
43953 + lcd_device_unregister(ud->lcddev);
43954 + platform_set_drvdata(pdev, NULL);
43960 +static struct platform_driver ubicom32lcd_driver = {
43962 + .name = DRIVER_NAME,
43963 + .owner = THIS_MODULE,
43966 + .remove = __exit_p(ubicom32lcd_remove),
43970 + * ubicom32lcd_init
43972 +static int __init ubicom32lcd_init(void)
43974 + return platform_driver_probe(&ubicom32lcd_driver, ubicom32lcd_probe);
43976 +module_init(ubicom32lcd_init);
43979 + * ubicom32lcd_exit
43981 +static void __exit ubicom32lcd_exit(void)
43983 + platform_driver_unregister(&ubicom32lcd_driver);
43985 +module_exit(ubicom32lcd_exit);
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.
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
44004 + This is the framebuffer device driver for the Ubicom32 architecture.
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
44014 + This is a virtual framebuffer device driver for the Ubicom32 architecture.
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
44026 # the test framebuffer is last
44027 obj-$(CONFIG_FB_VIRTUAL) += vfb.o
44029 +++ b/drivers/video/ubicom32fb.c
44032 + * drivers/video/ubicom32fb.c
44033 + * Ubicom32 frame buffer driver
44035 + * (C) Copyright 2009, Ubicom, Inc.
44037 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
44053 + * Ubicom32 implementation derived from (with many thanks):
44060 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
44061 + * Geert Uytterhoeven.
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>
44079 +#include <asm/io.h>
44080 +#include <asm/ip5000.h>
44081 +#include <asm/vdc_tio.h>
44082 +#include <asm/ubicom32fb.h>
44084 +#define DRIVER_NAME "ubicom32fb"
44085 +#define DRIVER_DESCRIPTION "Ubicom32 frame buffer driver"
44087 +#define PALETTE_ENTRIES_NO 16
44090 + * Option variables
44092 + * vram_size: VRAM size in kilobytes, subject to alignment
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).");
44102 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
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
44112 + * Filled in at probe time when we find out what the hardware supports
44114 +static struct fb_var_screeninfo ubicom32fb_var;
44117 + * Private data structure
44119 +struct ubicom32fb_drvdata {
44120 + struct fb_info *fbinfo;
44124 + * The address of the framebuffer in memory
44127 + void *fb_aligned;
44130 + * Total size of vram including alignment allowance
44132 + u32 total_vram_size;
44135 + * Interrupt to set when changing registers
44140 + * Optional: Interrupt used by TIO to signal us
44145 + * Base address of the regs for VDC_TIO
44147 + volatile struct vdc_tio_vp_regs *regs;
44150 + * non-zero if we are in yuv mode
44155 + * Fake palette of 16 colors
44157 + u32 pseudo_palette[PALETTE_ENTRIES_NO];
44160 + * Wait queue and lock used to block when we need to wait
44161 + * for something to happen.
44163 + wait_queue_head_t waitq;
44164 + struct mutex lock;
44169 + * ubicom32fb_set_next_frame
44170 + * Sets the next frame buffer to display
44172 + * if sync is TRUE then this function will block until the hardware
44173 + * acknowledges the change
44175 +static inline void ubicom32fb_set_next_frame(struct ubicom32fb_drvdata *ud, void *fb, u8_t sync)
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);
44181 + * If we have interrupts, then we can wait on it
44183 + if (ud->rx_int != -1) {
44184 + DEFINE_WAIT(wait);
44185 + unsigned long flags;
44187 + spin_lock_irqsave(&ud->lock, flags);
44188 + prepare_to_wait(&ud->waitq, &wait, TASK_INTERRUPTIBLE);
44189 + spin_unlock_irqrestore(&ud->lock, flags);
44191 + finish_wait(&ud->waitq, &wait);
44196 + * No interrupt, we will just spin here
44198 + while (sync && ((u32_t)ud->regs->next_frame & 1));
44202 + * ubicom32fb_send_command
44203 + * Sends a command/data pair to the VDC
44205 +static inline void ubicom32fb_send_command(struct ubicom32fb_drvdata *ud, u16 command, u8_t block)
44207 + ud->regs->command = command;
44208 + ubicom32_set_interrupt(ud->vp_int);
44209 + while (block && ud->regs->command);
44213 + * ubicom32fb_ioctl
44214 + * Handles any ioctls sent to us
44216 +static int ubicom32fb_ioctl(struct fb_info *fbi, unsigned int cmd,
44217 + unsigned long arg)
44219 + struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
44220 + void __user *argp = (void __user *)arg;
44221 + int retval = -EFAULT;
44224 + case UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC:
44225 + // check alignment, return -EINVAL if necessary
44226 + ubicom32fb_set_next_frame(ud, argp, 1);
44230 + case UBICOM32FB_IOCTL_SET_NEXT_FRAME:
44231 + // check alignment, return -EINVAL if necessary
44232 + ubicom32fb_set_next_frame(ud, argp, 0);
44236 + case UBICOM32FB_IOCTL_SET_MODE:
44237 + if (!(ud->regs->caps & VDCTIO_CAPS_SUPPORTS_SCALING)) {
44240 + struct ubicom32fb_mode mode;
44241 + volatile struct vdc_tio_vp_regs *regs = ud->regs;
44244 + if (copy_from_user(&mode, argp, sizeof(mode))) {
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;
44255 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER) {
44256 + flags |= VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER;
44258 + ud->is_yuv = mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV;
44259 + if (ud->is_yuv) {
44260 + flags |= VDCTIO_SCALE_FLAG_YUV;
44262 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255) {
44263 + flags |= VDCTIO_SCALE_FLAG_VRANGE_16_255;
44265 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255) {
44266 + flags |= VDCTIO_SCALE_FLAG_VRANGE_0_255;
44268 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB) {
44269 + flags |= VDCTIO_SCALE_FLAG_VSUB;
44271 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1) {
44272 + flags |= VDCTIO_SCALE_FLAG_HSUB_2_1;
44274 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1) {
44275 + flags |= VDCTIO_SCALE_FLAG_HSUB_1_1;
44277 + if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE) {
44278 + flags |= VDCTIO_SCALE_FLAG_ENABLE;
44280 + if (mode.next_frame) {
44281 + flags |= VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER;
44282 + regs->next_frame = mode.next_frame;
44285 + regs->scale_flags = flags;
44286 + ubicom32fb_send_command(ud, VDCTIO_COMMAND_SET_SCALE_MODE, 1);
44292 + retval = -ENOIOCTLCMD;
44300 + * ubicom32fb_interrupt
44301 + * Called by the OS when the TIO has set the rx_int
44303 +static irqreturn_t ubicom32fb_interrupt(int vec, void *appdata)
44305 + struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)appdata;
44307 + spin_lock(&ud->lock);
44308 + if (waitqueue_active(&ud->waitq)) {
44309 + wake_up(&ud->waitq);
44311 + spin_unlock(&ud->lock);
44313 + return IRQ_HANDLED;
44317 + * ubicom32fb_pan_display
44318 + * Pans the display to a given location. Supports only y direction panning.
44320 +static int ubicom32fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44322 + struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par;
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.
44329 + u32 lasty = var->yoffset + var->yres;
44330 + if (lasty > fbi->var.yres_virtual) {
44332 + * We would fall off the end of our frame buffer if we panned here.
44337 + if (var->xoffset) {
44339 + * We don't support panning in the x direction
44345 + * Everything looks sane, go ahead and pan
44347 + * We have to calculate a new address for the VDC to look at
44349 + new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44352 + * Send down the command. The buffer will switch at the next vertical blank
44354 + ubicom32fb_set_next_frame(ud, (void *)new_addr, 0);
44360 + * ubicom32fb_setcolreg
44361 + * Sets a color in our virtual palette
44363 +static int ubicom32fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44365 + u32 *palette = fbi->pseudo_palette;
44367 + if (regno >= PALETTE_ENTRIES_NO) {
44372 + * We only use 8 bits from each color
44379 + * Convert any grayscale values
44381 + if (fbi->var.grayscale) {
44382 + u16 gray = red + green + blue;
44383 + gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44385 + if (gray > 255) {
44393 + palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44394 + (blue << fbi->var.blue.offset);
44400 + * ubicom32fb_mmap
44402 +static int ubicom32fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
44404 + struct ubicom32fb_drvdata *drvdata = (struct ubicom32fb_drvdata *)info->par;
44406 + vma->vm_start = (unsigned long)(drvdata->fb_aligned);
44408 + vma->vm_end = vma->vm_start + info->fix.smem_len;
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
44418 + vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
44424 + * ubicom32fb_blank
44426 +static int ubicom32fb_blank(int blank_mode, struct fb_info *fbi)
44430 + struct ubicom32fb_drvdata *drvdata = to_ubicom32fb_drvdata(fbi);
44432 + switch (blank_mode) {
44433 + case FB_BLANK_UNBLANK:
44434 + /* turn on panel */
44435 + ubicom32fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
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);
44448 + return 0; /* success */
44452 +static struct fb_ops ubicom32fb_ops =
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,
44466 + * ubicom32fb_release
44468 +static int ubicom32fb_release(struct device *dev)
44470 + struct ubicom32fb_drvdata *ud = dev_get_drvdata(dev);
44472 +#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
44473 + //ubicom32fb_blank(VESA_POWERDOWN, &drvdata->info);
44476 + unregister_framebuffer(ud->fbinfo);
44478 + if (ud->cmap_alloc) {
44479 + fb_dealloc_cmap(&ud->fbinfo->cmap);
44486 + if (ud->rx_int != -1) {
44487 + free_irq(ud->rx_int, ud);
44491 + * Turn off the display
44493 + //ubicom32fb_out_be32(drvdata, REG_CTRL, 0);
44494 + //iounmap(drvdata->regs);
44496 + framebuffer_release(ud->fbinfo);
44497 + dev_set_drvdata(dev, NULL);
44503 + * ubicom32fb_platform_probe
44505 +static int __init ubicom32fb_platform_probe(struct platform_device *pdev)
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;
44514 + struct device *dev = &pdev->dev;
44516 + struct vdc_tio_vp_regs *regs;
44519 + * Get our resources
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");
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");
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");
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);
44546 + * This is the minimum VRAM size
44548 + fbsize = regs->xres * regs->yres * (regs->bpp / 8);
44549 + if (!vram_size) {
44550 + vram_size = (fbsize + 1023) / 1024;
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?
44559 + * Allocate the framebuffer instance + our private data
44561 + fbinfo = framebuffer_alloc(sizeof(struct ubicom32fb_drvdata), &pdev->dev);
44563 + dev_err(dev, "Not enough memory to allocate instance.\n");
44568 + * Fill in our private data.
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);
44575 + ud->vp_int = irq_resource_tx->start;
44578 + * If we were provided an rx_irq then we need to init the appropriate
44579 + * queues, locks, and functions.
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");
44590 + ud->rx_int = irq_resource_rx->start;
44594 + * Allocate and align the requested amount of VRAM
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");
44604 + offset = (u32_t)ud->fb & (regs->fb_align - 1);
44606 + ud->fb_aligned = ud->fb;
44608 + offset = regs->fb_align - offset;
44609 + ud->fb_aligned = ud->fb + offset;
44613 + * Clear the entire frame buffer
44615 + if (!init_value) {
44616 + memset(ud->fb_aligned, 0, vram_size * 1024);
44618 + unsigned short *p = ud->fb_aligned;
44620 + for (i = 0; i < ((vram_size * 1024) / sizeof(u16_t)); i++) {
44621 + *p++ = init_value;
44626 + * Fill in the fb_var_screeninfo structure
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;
44640 + * Turn on the display
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);
44649 + * Fill in the fb_info structure
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);
44660 + * We support panning in the y direction only
44662 + ud->fbinfo->fix.xpanstep = 0;
44663 + ud->fbinfo->fix.ypanstep = 1;
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;
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
44675 + ud->fbinfo->var.xres_virtual = regs->xres;
44676 + ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
44678 + //ud->fbinfo->var.height = regs->height_mm;
44679 + //ud->fbinfo->var.width = regs->width_mm;
44682 + * Allocate a color map
44684 + rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
44686 + dev_err(dev, "Fail to allocate colormap (%d entries)\n",
44687 + PALETTE_ENTRIES_NO);
44690 + ud->cmap_alloc = true;
44693 + * Register new frame buffer
44695 + rc = register_framebuffer(ud->fbinfo);
44697 + dev_err(dev, "Could not register frame buffer\n");
44702 + * Start up the VDC
44704 + ud->regs->next_frame = ud->fb;
44705 + ubicom32fb_send_command(ud, VDCTIO_COMMAND_START, 0);
44708 + * Tell the log we are here
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);
44721 + ubicom32fb_release(dev);
44726 + * ubicom32fb_platform_remove
44728 +static int ubicom32fb_platform_remove(struct platform_device *pdev)
44730 + dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
44731 + return ubicom32fb_release(&pdev->dev);
44734 +static struct platform_driver ubicom32fb_platform_driver = {
44735 + .probe = ubicom32fb_platform_probe,
44736 + .remove = ubicom32fb_platform_remove,
44738 + .name = DRIVER_NAME,
44739 + .owner = THIS_MODULE,
44745 + * ubicom32fb_setup
44746 + * Process kernel boot options
44748 +static int __init ubicom32fb_setup(char *options)
44752 + if (!options || !*options) {
44756 + while ((this_opt = strsep(&options, ",")) != NULL) {
44757 + if (!*this_opt) {
44761 + if (!strncmp(this_opt, "init_value=", 10)) {
44762 + init_value = simple_strtoul(this_opt + 11, NULL, 0);
44766 + if (!strncmp(this_opt, "vram_size=", 10)) {
44767 + vram_size = simple_strtoul(this_opt + 10, NULL, 0);
44773 +#endif /* MODULE */
44776 + * ubicom32fb_init
44778 +static int __devinit ubicom32fb_init(void)
44782 + * Get kernel boot options (in 'video=ubicom32fb:<options>')
44784 + char *option = NULL;
44786 + if (fb_get_options(DRIVER_NAME, &option)) {
44789 + ubicom32fb_setup(option);
44790 +#endif /* MODULE */
44792 + return platform_driver_register(&ubicom32fb_platform_driver);
44794 +module_init(ubicom32fb_init);
44797 + * ubicom32fb_exit
44799 +static void __exit ubicom32fb_exit(void)
44801 + platform_driver_unregister(&ubicom32fb_platform_driver);
44803 +module_exit(ubicom32fb_exit);
44805 +MODULE_LICENSE("GPL");
44806 +MODULE_AUTHOR("Patrick Tjin <@ubicom.com>");
44807 +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
44809 +++ b/drivers/video/ubicom32vfb.c
44812 + * drivers/video/ubicom32vfb.c
44813 + * Ubicom32 virtual frame buffer driver
44815 + * (C) Copyright 2009, Ubicom, Inc.
44817 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
44835 + * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by
44836 + * Geert Uytterhoeven.
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>
44853 +#define DRIVER_NAME "ubicom32vfb"
44854 +#define DRIVER_DESCRIPTION "Ubicom32 virtual frame buffer driver"
44856 +#define PALETTE_ENTRIES_NO 16
44859 + * Option variables
44861 + * vram_size: VRAM size in kilobytes, subject to alignment
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");
44867 +static int xres = 320;
44868 +module_param(xres, int, 0);
44869 +MODULE_PARM_DESC(xres, "x (horizontal) resolution");
44871 +static int yres = 240;
44872 +module_param(yres, int, 0);
44873 +MODULE_PARM_DESC(yres, "y (vertical) resolution");
44875 +static int bgr = 0;
44876 +module_param(bgr, int, 0);
44877 +MODULE_PARM_DESC(bgr, "display is BGR (Blue is MSB)");
44880 + * Buffer alignment, must not be 0
44882 +#define UBICOM32VFB_ALIGNMENT 4
44885 + * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in.
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
44895 + * Filled in at probe time when we find out what the hardware supports
44897 +static struct fb_var_screeninfo ubicom32vfb_var;
44900 + * Private data structure
44902 +struct ubicom32vfb_drvdata {
44903 + struct fb_info *fbinfo;
44907 + * The address of the framebuffer in memory
44910 + void *fb_aligned;
44913 + * Total size of vram including alignment allowance
44915 + u32 total_vram_size;
44918 + * Fake palette of 16 colors
44920 + u32 pseudo_palette[PALETTE_ENTRIES_NO];
44924 + * ubicom32vfb_pan_display
44925 + * Pans the display to a given location. Supports only y direction panning.
44927 +static int ubicom32vfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
44929 + struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)fbi->par;
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.
44936 + u32 lasty = var->yoffset + var->yres;
44937 + if (lasty > fbi->var.yres_virtual) {
44939 + * We would fall off the end of our frame buffer if we panned here.
44944 + if (var->xoffset) {
44946 + * We don't support panning in the x direction
44952 + * Everything looks sane, go ahead and pan
44954 + * We have to calculate a new address for the VDC to look at
44956 + new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length);
44962 + * ubicom32vfb_setcolreg
44963 + * Sets a color in our virtual palette
44965 +static int ubicom32vfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
44967 + u32 *palette = fbi->pseudo_palette;
44969 + if (regno >= PALETTE_ENTRIES_NO) {
44974 + * We only use 8 bits from each color
44981 + * Convert any grayscale values
44983 + if (fbi->var.grayscale) {
44984 + u16 gray = red + green + blue;
44985 + gray += (gray >> 2) + (gray >> 3) - (gray >> 7);
44987 + if (gray > 255) {
44995 + palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) |
44996 + (blue << fbi->var.blue.offset);
45002 + * ubicom32vfb_mmap
45004 +static int ubicom32vfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
45006 + struct ubicom32vfb_drvdata *drvdata = (struct ubicom32vfb_drvdata *)info->par;
45008 + vma->vm_start = (unsigned long)(drvdata->fb_aligned);
45010 + vma->vm_end = vma->vm_start + info->fix.smem_len;
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
45020 + vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
45025 +static struct fb_ops ubicom32vfb_ops =
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,
45037 + * ubicom32vfb_release
45039 +static int ubicom32vfb_release(struct device *dev)
45041 + struct ubicom32vfb_drvdata *ud = dev_get_drvdata(dev);
45043 + unregister_framebuffer(ud->fbinfo);
45045 + if (ud->cmap_alloc) {
45046 + fb_dealloc_cmap(&ud->fbinfo->cmap);
45053 + framebuffer_release(ud->fbinfo);
45054 + dev_set_drvdata(dev, NULL);
45060 + * ubicom32vfb_platform_probe
45062 +static int __init ubicom32vfb_platform_probe(struct platform_device *pdev)
45064 + struct ubicom32vfb_drvdata *ud;
45065 + struct fb_info *fbinfo;
45068 + struct device *dev = &pdev->dev;
45072 + * This is the minimum VRAM size
45074 + fbsize = xres * yres * 2;
45075 + if (!vram_size) {
45076 + vram_size = (fbsize + 1023) / 1024;
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?
45085 + * Allocate the framebuffer instance + our private data
45087 + fbinfo = framebuffer_alloc(sizeof(struct ubicom32vfb_drvdata), &pdev->dev);
45089 + dev_err(dev, "Not enough memory to allocate instance.\n");
45094 + * Fill in our private data.
45096 + ud = (struct ubicom32vfb_drvdata *)fbinfo->par;
45097 + ud->fbinfo = fbinfo;
45098 + dev_set_drvdata(dev, ud);
45101 + * Allocate and align the requested amount of VRAM
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");
45111 + offset = (u32_t)ud->fb & (UBICOM32VFB_ALIGNMENT - 1);
45113 + ud->fb_aligned = ud->fb;
45115 + offset = UBICOM32VFB_ALIGNMENT - offset;
45116 + ud->fb_aligned = ud->fb + offset;
45120 + * Clear the entire frame buffer
45122 + memset(ud->fb_aligned, 0, vram_size * 1024);
45125 + * Fill in the fb_var_screeninfo structure
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;
45136 + ubicom32vfb_var.red.offset = 0;
45137 + ubicom32vfb_var.blue.offset = 11;
45139 + ubicom32vfb_var.red.offset = 11;
45140 + ubicom32vfb_var.blue.offset = 0;
45144 + * Fill in the fb_info structure
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;
45155 + * We support panning in the y direction only
45157 + ud->fbinfo->fix.xpanstep = 0;
45158 + ud->fbinfo->fix.ypanstep = 1;
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;
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
45170 + ud->fbinfo->var.xres_virtual = xres;
45171 + ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length;
45174 + * Allocate a color map
45176 + rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0);
45178 + dev_err(dev, "Fail to allocate colormap (%d entries)\n",
45179 + PALETTE_ENTRIES_NO);
45182 + ud->cmap_alloc = true;
45185 + * Register new frame buffer
45187 + rc = register_framebuffer(ud->fbinfo);
45189 + dev_err(dev, "Could not register frame buffer\n");
45194 + * Tell the log we are here
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);
45206 + ubicom32vfb_release(dev);
45211 + * ubicom32vfb_platform_remove
45213 +static int ubicom32vfb_platform_remove(struct platform_device *pdev)
45215 + dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n");
45216 + return ubicom32vfb_release(&pdev->dev);
45219 +static struct platform_driver ubicom32vfb_platform_driver = {
45220 + .probe = ubicom32vfb_platform_probe,
45221 + .remove = ubicom32vfb_platform_remove,
45223 + .name = DRIVER_NAME,
45224 + .owner = THIS_MODULE,
45230 + * ubicom32vfb_setup
45231 + * Process kernel boot options
45233 +static int __init ubicom32vfb_setup(char *options)
45237 + if (!options || !*options) {
45241 + while ((this_opt = strsep(&options, ",")) != NULL) {
45242 + if (!*this_opt) {
45246 + if (!strncmp(this_opt, "vram_size=", 10)) {
45247 + vram_size = simple_strtoul(this_opt + 10, NULL, 0);
45251 + if (!strncmp(this_opt, "bgr=", 4)) {
45252 + bgr = simple_strtoul(this_opt + 4, NULL, 0);
45256 + if (!strncmp(this_opt, "xres=", 5)) {
45257 + xres = simple_strtoul(this_opt + 5, NULL, 0);
45261 + if (!strncmp(this_opt, "yres=", 5)) {
45262 + yres = simple_strtoul(this_opt + 5, NULL, 0);
45268 +#endif /* MODULE */
45271 + * ubicom32vfb_init
45273 +static int __devinit ubicom32vfb_init(void)
45277 + * Get kernel boot options (in 'video=ubicom32vfb:<options>')
45279 + char *option = NULL;
45281 + if (fb_get_options(DRIVER_NAME, &option)) {
45284 + ubicom32vfb_setup(option);
45285 +#endif /* MODULE */
45287 + return platform_driver_register(&ubicom32vfb_platform_driver);
45289 +module_init(ubicom32vfb_init);
45292 + * ubicom32vfb_exit
45294 +static void __exit ubicom32vfb_exit(void)
45296 + platform_driver_unregister(&ubicom32vfb_platform_driver);
45298 +module_exit(ubicom32vfb_exit);
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.
45312 + tristate "Ubicom32 Hardware Watchdog support"
45313 + depends on UBICOM32
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.
45319 + To compile this driver as a module, choose M here: the
45320 + module will be called ubi32_wdt.
45322 # XTENSA Architecture
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
45331 +# Ubicom32 Architecture
45332 +obj-$(CONFIG_UBI32_WDT) += ubi32_wdt.o
45334 # XTENSA Architecture
45336 # Architecture Independant
45338 +++ b/drivers/watchdog/ubi32_wdt.c
45341 + * drivers/watchdog/ubi32_wdt.c
45342 + * Ubicom32 Watchdog Driver
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.
45350 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
45366 + * Ubicom32 implementation derived from (with many thanks):
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>
45386 +#define WATCHDOG_NAME "ubi32-wdt"
45387 +#define PFX WATCHDOG_NAME ": "
45389 +#define OSC1_FREQ 12000000
45390 +#define WATCHDOG_SEC_TO_CYC(x) (OSC1_FREQ * (x))
45391 +#define WATCHDOG_MAX_SEC (0xffffffff / OSC1_FREQ)
45393 +#define MIN_PROCESSOR_ADDRESS 0x03000000
45395 +static DEFINE_SPINLOCK(ubi32_wdt_spinlock);
45397 +#define WATCHDOG_TIMEOUT 20
45399 +#if defined(CONFIG_WATCHDOG_NOWAYOUT)
45400 +#define WATCHDOG_NOWAYOUT 1
45402 +#define WATCHDOG_NOWAYOUT 0
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;
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()
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));
45422 + * ubi32_wdt_remaining()
45423 + * Return the approximate number of seconds remaining
45425 +static int ubi32_wdt_remaining(void)
45430 + UBI32_WDT_LOCK_CHECK();
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;
45441 + * ubi32_wdt_keepalive()
45442 + * Keep the Userspace Watchdog Alive
45444 + * The Userspace watchdog got a KeepAlive: schedule the next timeout.
45446 +static int ubi32_wdt_keepalive(void)
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);
45458 + * ubi32_wdt_stop()
45459 + * Stop the on-chip Watchdog
45461 +static int ubi32_wdt_stop(void)
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);
45471 + * ubi32_wdt_start()
45472 + * Start the on-chip Watchdog
45474 +static int ubi32_wdt_start(void)
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);
45487 + * ubi32_wdt_running()
45488 + * Return true if the watchdog is configured
45490 +static int ubi32_wdt_running(void)
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);
45502 + * ubi32_wdt_set_timeout()
45503 + * Set the Userspace Watchdog timeout
45505 + * - @t: new timeout value (in seconds)
45507 +static int ubi32_wdt_set_timeout(unsigned long t)
45509 + UBI32_WDT_LOCK_CHECK();
45511 + if (t > WATCHDOG_MAX_SEC) {
45512 + printk(KERN_WARNING PFX "request to large: %ld [1-%d] sec)\n", t, WATCHDOG_MAX_SEC);
45517 + * If we are running, then reset the time value so
45518 + * that the new value has an immediate effect.
45521 + if (ubi32_wdt_running()) {
45522 + ubi32_wdt_keepalive();
45528 + * ubi32_wdt_open()
45529 + * Open the Device
45531 +static int ubi32_wdt_open(struct inode *inode, struct file *file)
45533 + unsigned long flags;
45535 + if (test_and_set_bit(0, &open_check))
45539 + __module_get(THIS_MODULE);
45541 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45542 + ubi32_wdt_start();
45543 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45545 + return nonseekable_open(inode, file);
45549 + * ubi32_wdt_close()
45550 + * Close the Device
45552 +static int ubi32_wdt_release(struct inode *inode, struct file *file)
45554 + unsigned long flags;
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
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);
45569 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45570 + ubi32_wdt_stop();
45571 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45574 + expect_close = 0;
45575 + clear_bit(0, &open_check);
45580 + * ubi32_wdt_write()
45581 + * Write to Device
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.
45587 +static ssize_t ubi32_wdt_write(struct file *file, const char __user *data,
45588 + size_t len, loff_t *ppos)
45591 + unsigned long flags;
45594 + * Every write resets the expect_close. The last write
45595 + * must be a V to allow shutdown on close.
45597 + expect_close = 0;
45600 + * Empty writes still ping.
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.
45616 + * See if the program wrote a 'V' and if so disable
45617 + * the watchdog on release.
45619 + for (i = 0; i < len; i++) {
45621 + if (get_user(c, data + i)) {
45626 + expect_close = 42;
45631 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45632 + ubi32_wdt_keepalive();
45633 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45638 + * ubi32_wdt_ioctl()
45639 + * Query the watchdog device.
45641 + * Query basic information from the device or ping it, as outlined by the
45644 +static long ubi32_wdt_ioctl(struct file *file,
45645 + unsigned int cmd, unsigned long arg)
45647 + void __user *argp = (void __user *)arg;
45648 + int __user *p = argp;
45651 + case WDIOC_GETSUPPORT:
45652 + if (copy_to_user(argp, &ubi32_wdt_info, sizeof(ubi32_wdt_info))) {
45657 + case WDIOC_GETSTATUS: {
45658 + unsigned long flags;
45661 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45662 + running = ubi32_wdt_running();
45663 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45667 + case WDIOC_GETBOOTSTATUS:
45668 + return ubicom32_get_reset_reason();
45670 + case WDIOC_SETOPTIONS: {
45671 + unsigned long flags;
45672 + int options, ret = -EINVAL;
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.
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.
45684 + * TODO: Examine this code for future chips.
45685 + * TODO: Report the sample code defect.
45687 + if ((int)p < MIN_PROCESSOR_ADDRESS) {
45688 + options = (int)p;
45690 + if (get_user(options, p))
45694 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45695 + if (options & WDIOS_DISABLECARD) {
45696 + ubi32_wdt_stop();
45699 + if (options & WDIOS_ENABLECARD) {
45700 + ubi32_wdt_start();
45703 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45707 + case WDIOC_KEEPALIVE: {
45708 + unsigned long flags;
45710 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45711 + ubi32_wdt_keepalive();
45712 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45716 + case WDIOC_SETTIMEOUT: {
45718 + unsigned long flags;
45721 + if (get_user(new_timeout, p))
45724 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45725 + ret = ubi32_wdt_set_timeout(new_timeout);
45726 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45731 + case WDIOC_GETTIMEOUT:
45732 + return put_user(timeout, p);
45734 + case WDIOC_GETTIMELEFT: {
45735 + unsigned long flags;
45736 + int remaining = 0;
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);
45750 + * ubi32_wdt_notify_sys()
45751 + * Notification callback function for system events.
45753 + * Turn off the watchdog during a SYS_DOWN or SYS_HALT.
45755 +static int ubi32_wdt_notify_sys(struct notifier_block *this,
45756 + unsigned long code, void *unused)
45758 + if (code == SYS_DOWN || code == SYS_HALT) {
45759 + unsigned long flags;
45761 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45762 + ubi32_wdt_stop();
45763 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45766 + return NOTIFY_DONE;
45770 +static int state_before_suspend;
45773 + * ubi32_wdt_suspend()
45774 + * suspend the watchdog
45776 + * Remember if the watchdog was running and stop it.
45778 +static int ubi32_wdt_suspend(struct platform_device *pdev, pm_message_t state)
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);
45790 + * ubi32_wdt_resume()
45791 + * Resume the watchdog
45793 + * If the watchdog was running, turn it back on.
45795 +static int ubi32_wdt_resume(struct platform_device *pdev)
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);
45808 +# define ubi32_wdt_suspend NULL
45809 +# define ubi32_wdt_resume NULL
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,
45821 +static struct miscdevice ubi32_wdt_miscdev = {
45822 + .minor = WATCHDOG_MINOR,
45823 + .name = "watchdog",
45824 + .fops = &ubi32_wdt_fops,
45827 +static struct watchdog_info ubi32_wdt_info = {
45828 + .identity = "Ubicom32 Watchdog",
45829 + .options = WDIOF_SETTIMEOUT |
45830 + WDIOF_KEEPALIVEPING |
45831 + WDIOF_MAGICCLOSE,
45834 +static struct notifier_block ubi32_wdt_notifier = {
45835 + .notifier_call = ubi32_wdt_notify_sys,
45839 + * ubi32_wdt_probe()
45840 + * Probe/register the watchdog module
45842 + * Registers the misc device and notifier handler. Actual device
45843 + * initialization is handled by ubi32_wdt_open().
45845 +static int __devinit ubi32_wdt_probe(struct platform_device *pdev)
45849 + ret = register_reboot_notifier(&ubi32_wdt_notifier);
45851 + printk(KERN_ERR PFX
45852 + "cannot register reboot notifier (err=%d)\n", ret);
45856 + ret = misc_register(&ubi32_wdt_miscdev);
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);
45865 + printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
45866 + timeout, nowayout);
45872 + * ubi32_wdt_remove()
45873 + * Uninstall the module
45875 + * Unregisters the misc device and notifier handler. Actual device
45876 + * deinitialization is handled by ubi32_wdt_close().
45878 +static int __devexit ubi32_wdt_remove(struct platform_device *pdev)
45880 + misc_deregister(&ubi32_wdt_miscdev);
45881 + unregister_reboot_notifier(&ubi32_wdt_notifier);
45885 +static struct platform_device *ubi32_wdt_device;
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,
45893 + .name = WATCHDOG_NAME,
45894 + .owner = THIS_MODULE,
45899 + * ubi32_wdt_init()
45900 + * Initialize the watchdog.
45902 + * Checks the module params and registers the platform device & driver.
45903 + * Real work is in the platform probe function.
45905 +static int __init ubi32_wdt_init(void)
45907 + unsigned long flags;
45911 + * Check that the timeout value is within range
45913 + spin_lock_irqsave(&ubi32_wdt_spinlock, flags);
45914 + ret = ubi32_wdt_set_timeout(timeout);
45915 + spin_unlock_irqrestore(&ubi32_wdt_spinlock, flags);
45921 + * Since this is an on-chip device and needs no board-specific
45922 + * resources, we'll handle all the platform device stuff here.
45924 + ret = platform_driver_register(&ubi32_wdt_driver);
45926 + printk(KERN_ERR PFX "unable to register driver\n");
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);
45941 + * ubi32_wdt_exit()
45942 + * Deinitialize module
45944 + * Back out the platform device & driver steps. Real work is in the
45945 + * platform remove function.
45947 +static void __exit ubi32_wdt_exit(void)
45949 + platform_device_unregister(ubi32_wdt_device);
45950 + platform_driver_unregister(&ubi32_wdt_driver);
45953 +module_init(ubi32_wdt_init);
45954 +module_exit(ubi32_wdt_exit);
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);
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) ")");
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
45973 #define DBG_FLT(a...)
45976 +#ifndef ARCH_FLAT_ALIGN
45977 +#define ARCH_FLAT_ALIGN 0
45980 #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
45981 #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
45983 @@ -127,10 +131,10 @@ static unsigned long create_flat_tables(
45984 --sp; put_user((unsigned long) argv, sp);
45987 - put_user(argc,--sp);
45988 + --sp; put_user(argc,sp);
45989 current->mm->arg_start = (unsigned long) p;
45991 - put_user((unsigned long) p, argv++);
45992 + put_user((unsigned long) p, argv); argv++;
45994 get_user(dummy, p); p++;
45996 @@ -425,6 +429,7 @@ static int load_flat_file(struct linux_b
45998 unsigned long start_code, end_code;
46000 + int flush_happened = 0;
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
46006 /* OK, This is the point of no return */
46007 set_personality(PER_LINUX_32BIT);
46008 + flush_happened = 1;
46012 @@ -524,6 +530,12 @@ static int load_flat_file(struct linux_b
46015 if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {
46017 +#ifdef ARCH_FLAT_ALIGN_TEXT
46018 + printk("Unable to mmap rom with ARCH alignment requirements\n");
46023 * this should give us a ROM ptr, but if it doesn't we don't
46025 @@ -542,7 +554,7 @@ static int load_flat_file(struct linux_b
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(¤t->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;
46038 - datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
46039 + datapos = realdatastart + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN);
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
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;
46053 down_write(¤t->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
46061 +#ifdef ARCH_FLAT_ALIGN_TEXT
46062 + textpos = ALIGN(textpos + sizeof(struct flat_hdr), ARCH_FLAT_ALIGN) - sizeof(struct flat_hdr);
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));
46070 + ALIGN(MAX_SHARED_LIBS * sizeof(unsigned long), ARCH_FLAT_ALIGN));
46072 #ifdef CONFIG_BINFMT_ZFLAT
46074 @@ -657,7 +676,7 @@ static int load_flat_file(struct linux_b
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));
46083 @@ -670,6 +689,9 @@ static int load_flat_file(struct linux_b
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);
46090 end_code = textpos + text_len;
46092 current->mm->start_code = start_code;
46093 @@ -796,6 +818,13 @@ static int load_flat_file(struct linux_b
46097 + if (flush_happened) {
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.
46102 + do_exit(SIGTERM);
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"
46113 - depends on (FRV || BLACKFIN || (SUPERH32 && !MMU))
46114 + depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || UBICOM32)
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
46124 -dma_error(dma_addr_t dma_addr)
46125 +dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
46129 --- a/include/linux/elf-em.h
46130 +++ b/include/linux/elf-em.h
46132 * up with a final number.
46134 #define EM_ALPHA 0x9026
46135 +#define EM_UBICOM32 0xde3d /* Ubicom32; no ABI */
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
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);
46148 /* Use this instead when the PC value is not from the regs. Doesn't
46150 --- a/include/linux/serial_core.h
46151 +++ b/include/linux/serial_core.h
46152 @@ -158,6 +158,9 @@
46154 #define PORT_SCIFA 83
46157 +#define PORT_UBI32_UARTTIO 84
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);
46168 +#ifdef ARCH_PROC_MODULES_EXTRA
46169 + ARCH_PROC_MODULES_EXTRA(m, mod);
46173 seq_printf(m, " %s", module_flags(mod, buf));
46174 --- a/kernel/sched_clock.c
46175 +++ b/kernel/sched_clock.c
46178 unsigned long long __attribute__((weak)) sched_clock(void)
46180 - return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
46181 + return (get_jiffies_64() - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ);
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
46195 If you say Y here the resulting kernel image will be slightly larger
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
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
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.
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;
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"
46226 source "sound/soc/Kconfig"
46228 +source "sound/ubicom32/Kconfig"
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/
46243 # This one must be compilable even if sound is configured out
46245 +++ b/sound/ubicom32/Kconfig
46247 +# ALSA Ubicom32 drivers
46249 +menuconfig SND_UBI32
46250 + tristate "Ubicom32 sound devices"
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.
46260 +config SND_UBI32_AUDIO_GENERIC
46261 + bool "Generic Codec Support"
46266 +comment "I2C Based Codecs"
46268 +config SND_UBI32_AUDIO_CS4350
46269 + bool "Cirrus Logic CS4350 DAC"
46273 + Support for the Cirrus Logic CS4350 DAC.
46275 +config SND_UBI32_AUDIO_CS4384
46276 + bool "Cirrus Logic CS4384 DAC"
46280 + Support for the Cirrus Logic CS4384 DAC.
46284 +++ b/sound/ubicom32/Makefile
46287 +# sound/ubicom32/Makefile
46288 +# Makefile for ALSA
46290 +# (C) Copyright 2009, Ubicom, Inc.
46292 +# This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
46308 +# Ubicom32 implementation derived from (with many thanks):
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
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
46326 +++ b/sound/ubicom32/ubi32-cs4350.c
46329 + * sound/ubicom32/ubi32-cs4350.c
46330 + * Interface to ubicom32 virtual audio peripheral - using CS4350 DAC
46332 + * (C) Copyright 2009, Ubicom, Inc.
46334 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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"
46359 +#define DRIVER_NAME "snd-ubi32-cs4350"
46362 + * Module properties
46364 +static const struct i2c_device_id snd_ubi32_cs4350_id[] = {
46368 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46370 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46373 + * snd_ubi32_cs4350_free
46374 + * Card private data free function
46376 +void snd_ubi32_cs4350_free(struct snd_card *card)
46378 + //struct ubi32_snd_priv *ubi32_priv = card->private_data;
46381 + * Free all the fields in the snd_ubi32_priv struct
46383 + // Nothing to free at this time because ubi32_priv just maintains pointers
46387 + * snd_ubi32_cs4350_dac_init
46389 +static int snd_ubi32_cs4350_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
46396 + * Initialize the CS4350 DAC over the I2C interface
46398 + snd_printk(KERN_INFO "Initializing CS4350 DAC\n");
46401 + * Register 0x01: device/revid
46404 + ret = i2c_master_send(client, send, 1);
46406 + snd_printk(KERN_ERR "Failed 1st attempt to write to CS4350 register 0x01\n");
46409 + ret = i2c_master_recv(client, recv, 1);
46411 + snd_printk(KERN_ERR "Failed initial read of CS4350 registers\n");
46414 + snd_printk(KERN_INFO "CS4350 DAC Device/Rev: %08x\n", recv[0]);
46417 + * Register 0x02: Mode control
46418 + * I2S DIF[2:0] = 001, no De-Emphasis, Auto speed mode
46422 + ret = i2c_master_send(client, send, 2);
46424 + snd_printk(KERN_ERR "Failed to set CS4350 to I2S mode\n");
46429 + * Register 0x05/0x06: Volume control
46430 + * Channel A volume set to -16 dB
46431 + * Channel B volume set to -16 dB
46435 + ret = i2c_master_send(client, send, 2);
46437 + snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46443 + ret = i2c_master_send(client, send, 2);
46445 + snd_printk(KERN_ERR "Failed to set channel A volume on CS4350\n");
46450 + * Make sure the changes took place, this helps verify we are talking to
46451 + * the correct chip.
46454 + ret = i2c_master_send(client, send, 1);
46456 + snd_printk(KERN_ERR "Failed to initiate readback\n");
46460 + ret = i2c_master_recv(client, recv, 8);
46462 + snd_printk(KERN_ERR "Failed second read of CS4350 registers\n");
46466 + if ((recv[1] != 0x10) || (recv[4] != 0x00) || (recv[5] != 0x00)) {
46467 + snd_printk(KERN_ERR "Failed to initialize CS4350 DAC\n");
46471 + snd_printk(KERN_INFO "CS4350 DAC Initialized\n");
46479 + * snd_ubi32_cs4350_i2c_probe
46481 +static int snd_ubi32_cs4350_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
46483 + struct snd_card *card;
46484 + struct ubi32_snd_priv *ubi32_priv;
46486 + struct platform_device *pdev;
46488 + pdev = client->dev.platform_data;
46494 + * Initialize the CS4350 DAC
46496 + ret = snd_ubi32_cs4350_dac_init(client, id);
46499 + * Initialization failed. Propagate the error.
46505 + * Create a snd_card structure
46507 + card = snd_card_new(index, "Ubi32-CS4350", THIS_MODULE, sizeof(struct ubi32_snd_priv));
46508 + if (card == NULL) {
46512 + card->private_free = snd_ubi32_cs4350_free; /* Not sure if correct */
46513 + ubi32_priv = card->private_data;
46516 + * CS4350 DAC has a minimum sample rate of 30khz and an
46517 + * upper limit of 216khz for it's auto-detect.
46519 + ubi32_priv->min_sample_rate = 30000;
46520 + ubi32_priv->max_sample_rate = 216000;
46523 + * Initialize the snd_card's private data structure
46525 + ubi32_priv->card = card;
46528 + * Create the new PCM instance
46530 + err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
46532 + snd_card_free(card);
46533 + return err; /* What is err? Need to include correct file */
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);
46540 + snd_card_set_dev(card, &client->dev);
46543 + * Register the sound card
46545 + if ((err = snd_card_register(card)) != 0) {
46546 + snd_printk(KERN_INFO "snd_card_register error\n");
46550 + * Store card for access from other methods
46552 + i2c_set_clientdata(client, card);
46558 + * snd_ubi32_cs4350_i2c_remove
46560 +static int __devexit snd_ubi32_cs4350_i2c_remove(struct i2c_client *client)
46562 + struct snd_card *card;
46563 + struct ubi32_snd_priv *ubi32_priv;
46565 + card = i2c_get_clientdata(client);
46567 + ubi32_priv = card->private_data;
46568 + snd_ubi32_pcm_remove(ubi32_priv);
46570 + snd_card_free(i2c_get_clientdata(client));
46571 + i2c_set_clientdata(client, NULL);
46577 + * I2C driver description
46579 +static struct i2c_driver snd_ubi32_cs4350_driver = {
46581 + .name = DRIVER_NAME,
46582 + .owner = THIS_MODULE,
46584 + .id_table = snd_ubi32_cs4350_id,
46585 + .probe = snd_ubi32_cs4350_i2c_probe,
46586 + .remove = __devexit_p(snd_ubi32_cs4350_i2c_remove),
46592 +static int __init snd_ubi32_cs4350_init(void)
46594 + return i2c_add_driver(&snd_ubi32_cs4350_driver);
46596 +module_init(snd_ubi32_cs4350_init);
46599 + * snd_ubi32_cs4350_exit
46601 +static void __exit snd_ubi32_cs4350_exit(void)
46603 + i2c_del_driver(&snd_ubi32_cs4350_driver);
46605 +module_exit(snd_ubi32_cs4350_exit);
46608 + * Module properties
46610 +MODULE_ALIAS("i2c:" DRIVER_NAME);
46611 +MODULE_AUTHOR("Patrick Tjin");
46612 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4350");
46613 +MODULE_LICENSE("GPL");
46615 +++ b/sound/ubicom32/ubi32-cs4384.c
46618 + * sound/ubicom32/ubi32-cs4384.c
46619 + * Interface to ubicom32 virtual audio peripheral - using CS4384 DAC
46621 + * (C) Copyright 2009, Ubicom, Inc.
46623 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
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"
46655 +#define DRIVER_NAME "snd-ubi32-cs4384"
46658 + * Module properties
46660 +static const struct i2c_device_id snd_ubi32_cs4384_id[] = {
46664 +MODULE_DEVICE_TABLE(i2c, ubicom32audio_id);
46666 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
46669 + * Mixer properties
46673 + * Be careful of changing the order of these IDs, they
46674 + * are used to index the volume array.
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,
46683 + * This should be the last ID
46685 + SND_UBI32_CS4384_LAST_ID,
46687 +static const u8_t snd_ubi32_cs4384_ch_ofs[] = {0, 2, 4, 5, 6};
46689 +static const DECLARE_TLV_DB_SCALE(snd_ubi32_cs4384_db, -12750, 50, 0);
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
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);
46704 + * Make sure to update these if the structure below is changed
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 = {
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,
46719 + .p = snd_ubi32_cs4384_db,
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,
46732 + .p = snd_ubi32_cs4384_db,
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,
46745 + .p = snd_ubi32_cs4384_db,
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,
46758 + .p = snd_ubi32_cs4384_db,
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,
46771 + .p = snd_ubi32_cs4384_db,
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,
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,
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,
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,
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,
46827 + * Our private data
46829 +struct snd_ubi32_cs4384_priv {
46831 + * Array of current volumes
46832 + * (L, R, SL, SR, C, LFE, RL, RR)
46834 + uint8_t volume[8];
46837 + * Bitmask of mutes
46838 + * MSB (RR, RL, LFE, C, SR, SL, R, L) LSB
46843 + * Array of controls
46845 + struct snd_kcontrol *kctls[ARRAY_SIZE(snd_ubi32_cs4384_controls)];
46848 + * Lock to protect our card
46854 + * snd_ubi32_cs4384_info_volume
46856 +static int snd_ubi32_cs4384_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
46858 + unsigned int id = (unsigned int)kcontrol->private_value;
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;
46866 + uinfo->value.integer.min = 0;
46867 + uinfo->value.integer.max = 255;
46872 + * snd_ubi32_cs4384_get_volume
46874 +static int snd_ubi32_cs4384_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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;
46882 + if (id >= SND_UBI32_CS4384_LAST_ID) {
46886 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
46888 + spin_lock_irqsave(&cs4384_priv->lock, flags);
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)) {
46894 + ucontrol->value.integer.value[1] = cs4384_priv->volume[ch];
46897 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46903 + * snd_ubi32_cs4384_put_volume
46905 +static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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];
46915 + int ret = -EINVAL;
46917 + if (id >= SND_UBI32_CS4384_LAST_ID) {
46921 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
46923 + spin_lock_irqsave(&cs4384_priv->lock, flags);
46927 + case SND_UBI32_CS4384_REAR_ID:
46934 + case SND_UBI32_CS4384_SURROUND_ID:
46941 + case SND_UBI32_CS4384_FRONT_ID:
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];
46950 + case SND_UBI32_CS4384_LFE_ID:
46957 + case SND_UBI32_CS4384_CENTER_ID:
46960 + send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF);
46961 + cs4384_priv->volume[ch] = send[1];
46965 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46971 + * Send the volume to the chip
46974 + ret = i2c_master_send(client, send, nch);
46975 + if (ret != nch) {
46976 + snd_printk(KERN_ERR "Failed to set volume on CS4384\n");
46980 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
46986 + * snd_ubi32_cs4384_get_mute
46988 +static int snd_ubi32_cs4384_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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;
46996 + if (id >= SND_UBI32_CS4384_LAST_ID) {
47000 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
47002 + spin_lock_irqsave(&cs4384_priv->lock, flags);
47004 + ucontrol->value.integer.value[0] = !(cs4384_priv->mute & (1 << ch));
47006 + if ((id != SND_UBI32_CS4384_LFE_ID) &&
47007 + (id != SND_UBI32_CS4384_CENTER_ID)) {
47009 + ucontrol->value.integer.value[1] = !(cs4384_priv->mute & (1 << ch));
47012 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47018 + * snd_ubi32_cs4384_put_mute
47020 +static int snd_ubi32_cs4384_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
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;
47031 + if (id >= SND_UBI32_CS4384_LAST_ID) {
47035 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
47037 + spin_lock_irqsave(&cs4384_priv->lock, flags);
47039 + if (ucontrol->value.integer.value[0]) {
47040 + cs4384_priv->mute &= ~(1 << ch);
47042 + cs4384_priv->mute |= (1 << ch);
47045 + if ((id != SND_UBI32_CS4384_LFE_ID) && (id != SND_UBI32_CS4384_CENTER_ID)) {
47047 + if (ucontrol->value.integer.value[1]) {
47048 + cs4384_priv->mute &= ~(1 << ch);
47050 + cs4384_priv->mute |= (1 << ch);
47055 + * Update the chip's mute reigster
47058 + send[1] = cs4384_priv->mute;
47059 + ret = i2c_master_send(client, send, 2);
47061 + snd_printk(KERN_ERR "Failed to set mute on CS4384\n");
47064 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47070 + * snd_ubi32_cs4384_mixer
47071 + * Setup the mixer controls
47073 +static int __devinit snd_ubi32_cs4384_mixer(struct ubi32_snd_priv *priv)
47075 + struct snd_card *card = priv->card;
47076 + struct snd_ubi32_cs4384_priv *cs4384_priv;
47079 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
47080 + for (i = 0; i < ARRAY_SIZE(snd_ubi32_cs4384_controls); i++) {
47083 + cs4384_priv->kctls[i] = snd_ctl_new1(&snd_ubi32_cs4384_controls[i], priv);
47084 + err = snd_ctl_add(card, cs4384_priv->kctls[i]);
47086 + snd_printk(KERN_WARNING "Failed to add control %d\n", i);
47094 + * snd_ubi32_cs4384_free
47095 + * Card private data free function
47097 +void snd_ubi32_cs4384_free(struct snd_card *card)
47099 + struct snd_ubi32_cs4384_priv *cs4384_priv;
47100 + struct ubi32_snd_priv *ubi32_priv;
47102 + ubi32_priv = card->private_data;
47103 + cs4384_priv = snd_ubi32_priv_get_drv(ubi32_priv);
47104 + if (cs4384_priv) {
47105 + kfree(cs4384_priv);
47110 + * snd_ubi32_cs4384_setup_mclk
47112 +static int snd_ubi32_cs4384_setup_mclk(struct ubi32_cs4384_platform_data *pdata)
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;
47121 + div = pdata->mclk_entries[0].div;
47123 + ctl0 = (1 << 13);
47124 + ctlx = ((div - 1) << 16) | (div / 2);
47126 + switch (pdata->mclk_src) {
47127 + case UBI32_CS4384_MCLK_PWM_0:
47128 + ioc->function |= 2;
47129 + ioc->ctl0 |= ctl0;
47130 + ioc->ctl1 = ctlx;
47133 + case UBI32_CS4384_MCLK_PWM_1:
47134 + ioc->function |= 2;
47135 + ioc->ctl0 |= ctl0 << 16;
47136 + ioc->ctl2 = ctlx;
47139 + case UBI32_CS4384_MCLK_PWM_2:
47140 + ioh->ctl0 |= ctl0;
47141 + ioh->ctl1 = ctlx;
47144 + case UBI32_CS4384_MCLK_CLKDIV_1:
47145 + ioa->gpio_mask &= (1 << 7);
47146 + ioa->ctl1 &= ~(0x7F << 14);
47147 + ioa->ctl1 |= ((div - 1) << 14);
47150 + case UBI32_CS4384_MCLK_OTHER:
47158 + * snd_ubi32_cs4384_set_rate
47160 +static int snd_ubi32_cs4384_set_rate(struct ubi32_snd_priv *priv, int rate)
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};
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;
47183 + ctl = ((div - 1) << 16) | (div / 2);
47185 + switch (cpd->mclk_src) {
47186 + case UBI32_CS4384_MCLK_PWM_0:
47190 + case UBI32_CS4384_MCLK_PWM_1:
47194 + case UBI32_CS4384_MCLK_PWM_2:
47198 + case UBI32_CS4384_MCLK_CLKDIV_1:
47199 + ioa->ctl1 &= ~(0x7F << 14);
47200 + ioa->ctl1 |= ((div - 1) << 14);
47203 + case UBI32_CS4384_MCLK_OTHER:
47211 + * snd_ubi32_cs4384_set_channels
47212 + * Mute unused channels
47214 +static int snd_ubi32_cs4384_set_channels(struct ubi32_snd_priv *priv, int channels)
47216 + struct i2c_client *client = (struct i2c_client *)priv->client;
47217 + struct snd_ubi32_cs4384_priv *cs4384_priv;
47218 + unsigned char send[2];
47221 + unsigned long flags;
47224 + * Only support 0, 2, 4, 6, 8 channels
47226 + if ((channels > 8) || (channels & 1)) {
47230 + cs4384_priv = snd_ubi32_priv_get_drv(priv);
47231 + spin_lock_irqsave(&cs4384_priv->lock, flags);
47234 + * Address 09h, Mute control
47237 + send[1] = (unsigned char)(0xFF << channels);
47239 + ret = i2c_master_send(client, send, 2);
47241 + spin_unlock_irqrestore(&cs4384_priv->lock, flags);
47244 + * Notify the system that we changed the mutes
47246 + cs4384_priv->mute = (unsigned char)(0xFF << channels);
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);
47261 + * snd_ubi32_cs4384_dac_init
47263 +static int snd_ubi32_cs4384_dac_init(struct i2c_client *client, const struct i2c_device_id *id)
47266 + unsigned char send[2];
47267 + unsigned char recv[2];
47270 + * Initialize the CS4384 DAC over the I2C interface
47272 + snd_printk(KERN_INFO "Initializing CS4384 DAC\n");
47275 + * Register 0x01: device/revid
47278 + ret = i2c_master_send(client, send, 1);
47280 + snd_printk(KERN_ERR "Failed 1st attempt to write to CS4384 register 0x01\n");
47283 + ret = i2c_master_recv(client, recv, 1);
47285 + snd_printk(KERN_ERR "Failed initial read of CS4384 registers\n");
47288 + snd_printk(KERN_INFO "CS4384 DAC Device/Rev: %08x\n", recv[0]);
47291 + * Register 0x02: Mode Control 1
47292 + * Control Port Enable, PCM, All DACs enabled, Power Down
47296 + ret = i2c_master_send(client, send, 2);
47298 + snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47303 + * Register 0x08: Ramp and Mute
47304 + * RMP_UP, RMP_DN, PAMUTE, DAMUTE
47308 + ret = i2c_master_send(client, send, 2);
47310 + snd_printk(KERN_ERR "Failed to set CPEN CS4384\n");
47315 + * Register 0x03: PCM Control
47316 + * I2S DIF[3:0] = 0001, no De-Emphasis, Auto speed mode
47320 + ret = i2c_master_send(client, send, 2);
47322 + snd_printk(KERN_ERR "Failed to set CS4384 to I2S mode\n");
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
47332 + send[0] = 0x80 | 0x0B;
47335 + ret = i2c_master_send(client, send, 3);
47337 + snd_printk(KERN_ERR "Failed to set ch1 volume on CS4384\n");
47341 + send[0] = 0x80 | 0x0E;
47344 + ret = i2c_master_send(client, send, 3);
47346 + snd_printk(KERN_ERR "Failed to set ch2 volume on CS4384\n");
47350 + send[0] = 0x80 | 0x11;
47353 + ret = i2c_master_send(client, send, 3);
47355 + snd_printk(KERN_ERR "Failed to set ch3 volume on CS4384\n");
47359 + send[0] = 0x80 | 0x14;
47362 + ret = i2c_master_send(client, send, 3);
47364 + snd_printk(KERN_ERR "Failed to set ch4 volume on CS4384\n");
47369 + * Register 09h: Mute control
47370 + * Mute all (we will unmute channels as needed)
47374 + ret = i2c_master_send(client, send, 2);
47376 + snd_printk(KERN_ERR "Failed to power up CS4384\n");
47381 + * Register 0x02: Mode Control 1
47382 + * Control Port Enable, PCM, All DACs enabled, Power Up
47386 + ret = i2c_master_send(client, send, 2);
47388 + snd_printk(KERN_ERR "Failed to power up CS4384\n");
47393 + * Make sure the changes took place, this helps verify we are talking to
47394 + * the correct chip.
47396 + send[0] = 0x80 | 0x03;
47397 + ret = i2c_master_send(client, send, 1);
47399 + snd_printk(KERN_ERR "Failed to initiate readback\n");
47403 + ret = i2c_master_recv(client, recv, 1);
47405 + snd_printk(KERN_ERR "Failed second read of CS4384 registers\n");
47409 + if (recv[0] != 0x13) {
47410 + snd_printk(KERN_ERR "Failed to initialize CS4384 DAC\n");
47414 + snd_printk(KERN_INFO "CS4384 DAC Initialized\n");
47422 + * snd_ubi32_cs4384_i2c_probe
47424 +static int snd_ubi32_cs4384_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
47426 + struct snd_card *card;
47427 + struct ubi32_snd_priv *ubi32_priv;
47429 + struct platform_device *pdev;
47430 + struct ubi32_cs4384_platform_data *pdata;
47431 + struct snd_ubi32_cs4384_priv *cs4384_priv;
47434 + * pdev is audio_tio
47436 + pdev = client->dev.platform_data;
47442 + * pdev->dev.platform_data is ubi32-pcm platform_data
47444 + pdata = audio_tio_priv(pdev);
47450 + * Initialize the CS4384 DAC
47452 + ret = snd_ubi32_cs4384_dac_init(client, id);
47455 + * Initialization failed. Propagate the error.
47460 + if (snd_ubi32_cs4384_setup_mclk(pdata)) {
47465 + * Create a snd_card structure
47467 + card = snd_card_new(index, "Ubi32-CS4384", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47468 + if (card == NULL) {
47472 + card->private_free = snd_ubi32_cs4384_free;
47473 + ubi32_priv = card->private_data;
47476 + * Initialize the snd_card's private data structure
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;
47484 + * CS4384 DAC has a minimum sample rate of 4khz and an
47485 + * upper limit of 216khz for it's auto-detect.
47487 + ubi32_priv->min_sample_rate = 4000;
47488 + ubi32_priv->max_sample_rate = 216000;
47491 + * Create our private data (to manage volume, etc)
47493 + cs4384_priv = kzalloc(sizeof(struct snd_ubi32_cs4384_priv), GFP_KERNEL);
47494 + if (!cs4384_priv) {
47495 + snd_card_free(card);
47498 + snd_ubi32_priv_set_drv(ubi32_priv, cs4384_priv);
47499 + spin_lock_init(&cs4384_priv->lock);
47502 + * We start off all muted and max volume
47504 + cs4384_priv->mute = 0xFF;
47505 + memset(cs4384_priv->volume, 0xFF, 8);
47508 + * Create the new PCM instance
47510 + err = snd_ubi32_pcm_probe(ubi32_priv, pdev);
47512 + snd_card_free(card);
47513 + return err; /* What is err? Need to include correct file */
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);
47520 + snd_card_set_dev(card, &client->dev);
47523 + * Set up the mixer
47525 + snd_ubi32_cs4384_mixer(ubi32_priv);
47528 + * Register the sound card
47530 + if ((err = snd_card_register(card)) != 0) {
47531 + snd_printk(KERN_INFO "snd_card_register error\n");
47535 + * Store card for access from other methods
47537 + i2c_set_clientdata(client, card);
47543 + * snd_ubi32_cs4384_i2c_remove
47545 +static int __devexit snd_ubi32_cs4384_i2c_remove(struct i2c_client *client)
47547 + struct snd_card *card;
47548 + struct ubi32_snd_priv *ubi32_priv;
47550 + card = i2c_get_clientdata(client);
47552 + ubi32_priv = card->private_data;
47553 + snd_ubi32_pcm_remove(ubi32_priv);
47555 + snd_card_free(i2c_get_clientdata(client));
47556 + i2c_set_clientdata(client, NULL);
47562 + * I2C driver description
47564 +static struct i2c_driver snd_ubi32_cs4384_driver = {
47566 + .name = DRIVER_NAME,
47567 + .owner = THIS_MODULE,
47569 + .id_table = snd_ubi32_cs4384_id,
47570 + .probe = snd_ubi32_cs4384_i2c_probe,
47571 + .remove = __devexit_p(snd_ubi32_cs4384_i2c_remove),
47577 +static int __init snd_ubi32_cs4384_init(void)
47579 + return i2c_add_driver(&snd_ubi32_cs4384_driver);
47581 +module_init(snd_ubi32_cs4384_init);
47584 + * snd_ubi32_cs4384_exit
47586 +static void __exit snd_ubi32_cs4384_exit(void)
47588 + i2c_del_driver(&snd_ubi32_cs4384_driver);
47590 +module_exit(snd_ubi32_cs4384_exit);
47593 + * Module properties
47595 +MODULE_ALIAS("i2c:" DRIVER_NAME);
47596 +MODULE_AUTHOR("Patrick Tjin");
47597 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices CS4384");
47598 +MODULE_LICENSE("GPL");
47600 +++ b/sound/ubicom32/ubi32-generic.c
47603 + * sound/ubicom32/ubi32-generic.c
47604 + * Interface to ubicom32 virtual audio peripheral
47606 + * (C) Copyright 2009, Ubicom, Inc.
47608 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
47624 + * Ubicom32 implementation derived from (with many thanks):
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"
47638 +#define DRIVER_NAME "snd-ubi32-generic"
47641 + * Module properties
47643 +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
47646 + * Card private data free function
47648 +void snd_ubi32_generic_free(struct snd_card *card)
47650 + //struct ubi32_snd_priv *ubi32_priv = card->private_data;
47653 + * Free all the fields in the snd_ubi32_priv struct
47655 + // Nothing to free at this time because ubi32_priv just maintains pointers
47659 + * Ubicom audio driver probe() method. Args change depending on whether we use
47660 + * platform_device or i2c_device.
47662 +static int snd_ubi32_generic_probe(struct platform_device *dev)
47664 + struct snd_card *card;
47665 + struct ubi32_snd_priv *ubi32_priv;
47669 + * Create a snd_card structure
47671 + card = snd_card_new(index, "Ubi32-Generic", THIS_MODULE, sizeof(struct ubi32_snd_priv));
47673 + if (card == NULL) {
47677 + card->private_free = snd_ubi32_generic_free; /* Not sure if correct */
47678 + ubi32_priv = card->private_data;
47681 + * Initialize the snd_card's private data structure
47683 + ubi32_priv->card = card;
47686 + * Create the new PCM instance
47688 + err = snd_ubi32_pcm_probe(ubi32_priv, dev);
47690 + snd_card_free(card);
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);
47698 + snd_card_set_dev(card, &dev->dev);
47700 + /* Register the sound card */
47701 + if ((err = snd_card_register(card)) != 0) {
47702 + snd_printk(KERN_INFO "snd_card_register error\n");
47705 + /* Store card for access from other methods */
47706 + platform_set_drvdata(dev, card);
47712 + * Ubicom audio driver remove() method
47714 +static int __devexit snd_ubi32_generic_remove(struct platform_device *dev)
47716 + struct snd_card *card;
47717 + struct ubi32_snd_priv *ubi32_priv;
47719 + card = platform_get_drvdata(dev);
47720 + ubi32_priv = card->private_data;
47721 + snd_ubi32_pcm_remove(ubi32_priv);
47723 + snd_card_free(platform_get_drvdata(dev));
47724 + platform_set_drvdata(dev, NULL);
47729 + * Platform driver definition
47731 +static struct platform_driver snd_ubi32_generic_driver = {
47733 + .name = DRIVER_NAME,
47734 + .owner = THIS_MODULE,
47736 + .probe = snd_ubi32_generic_probe,
47737 + .remove = __devexit_p(snd_ubi32_generic_remove),
47741 + * snd_ubi32_generic_init
47743 +static int __init snd_ubi32_generic_init(void)
47745 + return platform_driver_register(&snd_ubi32_generic_driver);
47747 +module_init(snd_ubi32_generic_init);
47750 + * snd_ubi32_generic_exit
47752 +static void __exit snd_ubi32_generic_exit(void)
47754 + platform_driver_unregister(&snd_ubi32_generic_driver);
47756 +module_exit(snd_ubi32_generic_exit);
47759 + * Module properties
47761 +//#if defined(CONFIG_SND_UBI32_AUDIO_I2C)
47762 +//MODULE_ALIAS("i2c:snd-ubi32");
47764 +MODULE_AUTHOR("Aaron Jow, Patrick Tjin");
47765 +MODULE_DESCRIPTION("Driver for Ubicom32 audio devices");
47766 +MODULE_LICENSE("GPL");
47768 +++ b/sound/ubicom32/ubi32.h
47771 + * sound/ubicom32/ubi32.h
47772 + * Common header file for all ubi32- sound drivers
47774 + * (C) Copyright 2009, Ubicom, Inc.
47776 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
47796 +#define SND_UBI32_DEBUG 0 // Debug flag
47798 +#include <linux/platform_device.h>
47799 +#include <asm/devtree.h>
47800 +#include <asm/audio_tio.h>
47801 +#include <asm/ubi32-pcm.h>
47803 +struct ubi32_snd_priv;
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);
47808 +struct ubi32_snd_priv {
47810 + * Any variables that are needed locally here but NOT in
47811 + * the VP itself should go in here.
47813 + struct snd_card *card;
47814 + struct snd_pcm *pcm;
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?
47822 + * min/max_sample_rate if set to 0 are ignored.
47824 + int max_sample_rate;
47825 + int min_sample_rate;
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
47832 + u32_t period_size;
47834 + spinlock_t ubi32_lock;
47836 + struct audiotioregs *regs;
47843 + * Operations which the base DAC driver can implement
47845 + set_channels_t set_channels;
47846 + set_rate_t set_rate;
47851 + struct ubi32pcm_platform_data *pdata;
47854 + * Private driver data (used for DAC driver control, etc)
47859 +#define snd_ubi32_priv_get_drv(priv) ((priv)->drvdata)
47860 +#define snd_ubi32_priv_set_drv(priv, data) (((priv)->drvdata) = (void *)(data))
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);
47867 +++ b/sound/ubicom32/ubi32-pcm.c
47870 + * sound/ubicom32/ubi32-pcm.c
47871 + * Interface to ubicom32 virtual audio peripheral
47873 + * (C) Copyright 2009, Ubicom, Inc.
47875 + * This file is part of the Ubicom32 Linux Kernel Port.
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.
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.
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/>.
47891 + * Ubicom32 implementation derived from (with many thanks):
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"
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;
47915 +static void snd_ubi32_vp_int_set(struct snd_pcm *pcm)
47917 + struct ubi32_snd_priv *ubi32_priv = pcm->private_data;
47918 + ubicom32_set_interrupt(ubi32_priv->tx_irq);
47921 +static snd_pcm_uframes_t snd_ubi32_playback_pointer(struct snd_pcm_substream *substream)
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;
47928 + dma_addr_t read_pos;
47930 + snd_pcm_uframes_t frames;
47931 + if (!regs->current_read_pos) {
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.
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) {
47950 +static int snd_ubi32_playback_trigger(struct snd_pcm_substream *substream, int cmd)
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;
47957 +#if SND_UBI32_DEBUG
47958 + snd_printk(KERN_INFO "snd_ubi32_playback_trigger cmd=%d=", cmd);
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?
47968 + * Set interrupt flag to indicate that we interrupted audio device
47969 + * to send a command
47971 + //regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
47974 + case SNDRV_PCM_TRIGGER_START:
47976 +#if SND_UBI32_DEBUG
47977 + snd_printk(KERN_INFO "START\n");
47980 + * Ready the DMA transfer
47982 + ubi32_rd->period_ptr = ubi32_rd->dma_buffer;
47984 +#if SND_UBI32_DEBUG
47985 + snd_printk(KERN_INFO "trigger period_ptr=%lx\n", (unsigned long)ubi32_rd->period_ptr);
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;
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);
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;
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);
48005 + * Tell the VP that we want to begin playback by filling in the
48006 + * command field and then interrupting the audio VP
48008 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48009 + regs->command = UBI32_AUDIO_CMD_START;
48010 + snd_ubi32_vp_int_set(substream->pcm);
48013 + case SNDRV_PCM_TRIGGER_STOP:
48015 +#if SND_UBI32_DEBUG
48016 + snd_printk(KERN_INFO "STOP\n");
48020 + * Tell the VP that we want to stop playback by filling in the
48021 + * command field and then interrupting the audio VP
48023 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48024 + regs->command = UBI32_AUDIO_CMD_STOP;
48025 + snd_ubi32_vp_int_set(substream->pcm);
48028 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
48030 +#if SND_UBI32_DEBUG
48031 + snd_printk(KERN_INFO "PAUSE_PUSH\n");
48035 + * Tell the VP that we want to pause playback by filling in the
48036 + * command field and then interrupting the audio VP
48038 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48039 + regs->command = UBI32_AUDIO_CMD_PAUSE;
48040 + snd_ubi32_vp_int_set(substream->pcm);
48043 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
48045 +#if SND_UBI32_DEBUG
48046 + snd_printk(KERN_INFO "PAUSE_RELEASE\n");
48049 + * Tell the VP that we want to resume paused playback by filling
48050 + * in the command field and then interrupting the audio VP
48052 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48053 + regs->command = UBI32_AUDIO_CMD_RESUME;
48054 + snd_ubi32_vp_int_set(substream->pcm);
48058 + snd_printk(KERN_WARNING "Unhandled trigger\n");
48067 + * Prepare to transfer an audio stream to the codec
48069 +static int snd_ubi32_playback_prepare(struct snd_pcm_substream *substream)
48072 + * Configure registers and setup the runtime instance for DMA transfers
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;
48078 +#if SND_UBI32_DEBUG
48079 + snd_printk(KERN_INFO "snd_ubi32_playback_prepare: sending STOP command to audio device\n");
48083 + * Make sure the audio device is stopped
48087 + * Set interrupt flag to indicate that we interrupted audio device
48088 + * to send a command
48090 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48091 + regs->command = UBI32_AUDIO_CMD_STOP;
48092 + snd_ubi32_vp_int_set(substream->pcm);
48098 + * Allocate DMA buffers from preallocated memory.
48099 + * Preallocation was done in snd_ubi32_pcm_new()
48101 +static int snd_ubi32_playback_hw_params(struct snd_pcm_substream *substream,
48102 + struct snd_pcm_hw_params *hw_params)
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;
48110 + * Use pre-allocated memory from ubi32_snd_pcm_new() to satisfy
48111 + * this memory request.
48113 + int ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
48115 +#if SND_UBI32_DEBUG
48116 + snd_printk(KERN_INFO "snd_ubi32_playback_hw_params\n");
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);
48124 + if (ubi32_priv->set_channels) {
48125 + int ret = ubi32_priv->set_channels(ubi32_priv, params_channels(hw_params));
48127 + snd_printk(KERN_WARNING "Unable to set channels to %d, ret=%d\n", params_channels(hw_params), ret);
48132 + if (ubi32_priv->set_rate) {
48133 + int ret = ubi32_priv->set_rate(ubi32_priv, params_rate(hw_params));
48135 + snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
48140 + if (ubi32_priv->pdata->set_rate) {
48141 + int ret = ubi32_priv->pdata->set_rate(ubi32_priv->pdata->appdata, params_rate(hw_params));
48143 + snd_printk(KERN_WARNING "Unable to set rate to %d, ret=%d\n", params_rate(hw_params), ret);
48148 + if (regs->command != UBI32_AUDIO_CMD_NONE) {
48149 + snd_printk(KERN_WARNING "snd_ubi32_playback_hw_params: tio busy\n");
48153 + if (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) {
48154 + regs->flags |= UBI32_CMD_SETUP_FLAG_LE;
48156 + regs->flags &= ~UBI32_CMD_SETUP_FLAG_LE;
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);
48165 + * Wait for the command to complete
48167 + while (regs->command != UBI32_AUDIO_CMD_NONE) {
48171 + //snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
48172 + //runtime->dma_bytes = params_buffer_bytes(hw_params);
48175 + * Put the DMA info into the DMA descriptor that we will
48176 + * use to do transfers to our audio VP "hardware"
48180 + * Mark both DMA transfers as not ready/inactive
48182 + regs->playback_xfer_requests[0].active = 0;
48183 + regs->playback_xfer_requests[1].active = 0;
48186 + * Put the location of the buffer into the runtime data instance
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);
48192 + * Get the period size
48194 + ubi32_rd->period_size = params_period_bytes(hw_params);
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);
48205 + * This is the reverse of snd_ubi32_playback_hw_params
48207 +static int snd_ubi32_playback_hw_free(struct snd_pcm_substream *substream)
48209 +#if SND_UBI32_DEBUG
48210 + snd_printk(KERN_INFO "snd_ubi32_playback_hw_free\n");
48212 + return snd_pcm_lib_free_pages(substream);
48216 + * Audio virtual peripheral capabilities
48218 +static struct snd_pcm_hardware snd_ubi32_playback_hw =
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
48238 + * We fill this in later
48240 +static struct snd_pcm_hw_constraint_list ubi32_playback_rates;
48242 +static int snd_ubi32_playback_close(struct snd_pcm_substream *substream)
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;
48248 +#if SND_UBI32_DEBUG
48249 + snd_printk(KERN_INFO "snd_ubi32_playback_close\n");
48252 + substream->runtime->private_data = NULL;
48259 +static int snd_ubi32_playback_open(struct snd_pcm_substream *substream)
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;
48266 +#if SND_UBI32_DEBUG
48267 + snd_printk(KERN_INFO "ubi32 playback open\n");
48270 + /* Associate capabilities with component */
48271 + runtime->hw = snd_ubi32_playback_hw;
48274 + * Inform ALSA about constraints of the audio device
48276 + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &ubi32_playback_rates);
48278 + snd_printk(KERN_INFO "invalid rate\n");
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);
48285 + snd_printk(KERN_INFO "invalid period\n");
48288 + /* Initialize structures/registers */
48289 + ubi32_rd = kzalloc(sizeof(struct ubi32_snd_runtime_data), GFP_KERNEL);
48290 + if (ubi32_rd == NULL) {
48295 + runtime->private_data = ubi32_rd;
48297 +#if SND_UBI32_DEBUG
48298 + snd_printk(KERN_INFO "snd_ubi32_playback_open returned 0\n");
48303 +#if SND_UBI32_DEBUG
48304 + snd_printk(KERN_INFO "snd_ubi32_playback_open returned %d\n", ret);
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,
48322 + * Interrupt handler that gets called when the audio device
48323 + * interrupts Linux
48325 +static irqreturn_t snd_ubi32_pcm_interrupt(int irq, void *appdata)
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;
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;
48338 +#if SND_UBI32_DEBUG
48339 + snd_printk(KERN_INFO "Ubi32 ALSA interrupt\n");
48343 + snd_printk(KERN_WARNING "pcm does not exist\n");
48344 + return IRQ_HANDLED;
48347 + if (ubi32_rd == NULL) {
48348 + snd_printk(KERN_WARNING "No runtime data\n");
48349 + return IRQ_HANDLED;
48351 + // Check interrupt cause
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) {
48358 + regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST;
48359 + } else if (regs->status & UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST) {
48361 + regs->status &= ~UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST;
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;
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);
48373 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_MORE_SAMPLES;
48374 + snd_ubi32_vp_int_set(substream->pcm);
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);
48381 + return IRQ_HANDLED;
48384 +void __devexit snd_ubi32_pcm_remove(struct ubi32_snd_priv *ubi32_priv)
48386 + struct snd_pcm *pcm = ubi32_priv->pcm;
48387 + free_irq(ubi32_priv->rx_irq, pcm);
48390 +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
48391 +#error "Change this table to match pcm.h"
48393 +static unsigned int rates[] __initdata = {5512, 8000, 11025, 16000, 22050,
48394 + 32000, 44100, 48000, 64000, 88200,
48395 + 96000, 176400, 192000};
48398 + * snd_ubi32_pcm_probe
48400 +int __devinit snd_ubi32_pcm_probe(struct ubi32_snd_priv *ubi32_priv, struct platform_device *pdev)
48402 + struct snd_pcm *pcm;
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;
48416 + pdata = pdev->dev.platform_data;
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.
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");
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;
48439 + * Check the version
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");
48448 + * Find out the standard rates, also find max and min rates
48450 + for (i = 0; i < ARRAY_SIZE(rates); i++) {
48452 + for (j = 0; j < regs->n_sample_rates; j++) {
48453 + if (rates[i] == regs->sample_rates[j]) {
48455 + * Check to see if it is supported by the dac
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)))) {
48461 + rate_mask |= (1 << i);
48463 + if (rates[i] < rate_min) {
48464 + rate_min = rates[i];
48466 + if (rates[i] > rate_max) {
48467 + rate_max = rates[i];
48474 + rate_mask |= SNDRV_PCM_RATE_KNOT;
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;
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;
48490 + snd_ubi32_playback_hw.channels_max = i;
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);
48497 + if (regs->caps & AUDIOTIONODE_CAP_BE) {
48498 + snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_BE;
48500 + if (regs->caps & AUDIOTIONODE_CAP_LE) {
48501 + snd_ubi32_playback_hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
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);
48510 + ret = snd_pcm_new(ubi32_priv->card, "Ubi32 PCM", 0, 1, 0, &pcm);
48515 + pcm->private_data = ubi32_priv;
48516 + ubi32_priv->pcm = pcm;
48517 + ubi32_priv->pdata = pdata;
48519 + pcm->info_flags = 0; // What is this for? Just copied from other drivers
48521 + strcpy(pcm->name, "Ubi32-PCM");
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
48528 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ubi32_playback_ops);
48531 + * Start up the TIO
48533 + regs->int_flags |= UBI32_AUDIO_INT_FLAG_COMMAND;
48534 + regs->command = UBI32_AUDIO_CMD_ENABLE;
48535 + snd_ubi32_vp_int_set(pcm);
48540 + err = request_irq(ubi32_priv->rx_irq, snd_ubi32_pcm_interrupt, IRQF_DISABLED, pcm->name, pcm);
48542 + snd_printk(KERN_WARNING "request_irq failed: irq=%d err=%d\n", ubi32_priv->rx_irq, err);
48550 +++ b/arch/ubicom32/lib/ashldi3.c
48552 +/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
48553 +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
48555 +This file is part of GNU CC.
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.
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.
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. */
48572 +#define BITS_PER_UNIT 8
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__)));
48579 +struct DIstruct {SItype high, low;};
48583 + struct DIstruct s;
48588 +__ashldi3 (DItype u, word_type b)
48599 + bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48603 + w.s.high = (USItype)uu.s.low << -bm;
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;
48615 +++ b/arch/ubicom32/lib/ashrdi3.c
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.
48620 +This file is part of GNU CC.
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.
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.
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. */
48637 +#define BITS_PER_UNIT 8
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__)));
48644 +struct DIstruct {SItype high, low;};
48648 + struct DIstruct s;
48653 +__ashrdi3 (DItype u, word_type b)
48664 + bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
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;
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;
48681 +++ b/arch/ubicom32/lib/divmod.c
48684 +udivmodsi4(unsigned long num, unsigned long den, int modwanted)
48686 + unsigned long bit = 1;
48687 + unsigned long res = 0;
48689 + while (den < num && bit && !(den & (1L<<31)))
48704 + if (modwanted) return num;
48709 +__udivsi3 (long a, long b)
48711 + return udivmodsi4 (a, b, 0);
48715 +__umodsi3 (long a, long b)
48717 + return udivmodsi4 (a, b, 1);
48721 +__divsi3 (long a, long b)
48738 + res = udivmodsi4 (a, b, 0);
48747 +__modsi3 (long a, long b)
48761 + res = udivmodsi4 (a, b, 1);
48769 +++ b/arch/ubicom32/lib/lshrdi3.c
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.
48774 +This file is part of GNU CC.
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.
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.
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. */
48791 +#define BITS_PER_UNIT 8
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__)));
48798 +struct DIstruct {SItype high, low;};
48802 + struct DIstruct s;
48807 +__lshrdi3 (DItype u, word_type b)
48818 + bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
48822 + w.s.low = (USItype)uu.s.high >> -bm;
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;
48834 +++ b/arch/ubicom32/lib/muldi3.c
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.
48840 +This file is part of GNU CC.
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.
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.
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. */
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))
48865 +#define umul_ppmm(w1, w0, u, v) \
48867 + UWtype __x0, __x1, __x2, __x3; \
48868 + UHWtype __ul, __vl, __uh, __vh; \
48870 + __ul = __ll_lowpart (u); \
48871 + __uh = __ll_highpart (u); \
48872 + __vl = __ll_lowpart (v); \
48873 + __vh = __ll_highpart (v); \
48875 + __x0 = (UWtype) __ul * __vl; \
48876 + __x1 = (UWtype) __ul * __vh; \
48877 + __x2 = (UWtype) __uh * __vl; \
48878 + __x3 = (UWtype) __uh * __vh; \
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. */ \
48885 + (w1) = __x3 + __ll_highpart (__x1); \
48886 + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
48890 +#define __umulsidi3(u, v) \
48892 + umul_ppmm (__w.s.high, __w.s.low, u, v); \
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__)));
48900 +struct DIstruct {SItype high, low;};
48904 + struct DIstruct s;
48909 +__muldi3 (DItype u, DItype v)
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);