[BACK]Return to s3c2xx0_intr.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / s3c2xx0

Annotation of sys/arch/arm/s3c2xx0/s3c2xx0_intr.c, Revision 1.1.1.1

1.1       nbrk        1: /* $NetBSD: s3c2xx0_intr.c,v 1.11 2006/11/24 21:20:05 wiz Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002, 2003 Fujitsu Component Limited
                      5:  * Copyright (c) 2002, 2003 Genetec Corporation
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. Neither the name of The Fujitsu Component Limited nor the name of
                     17:  *    Genetec corporation may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
                     21:  * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     22:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
                     23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     24:  * DISCLAIMED.  IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC
                     25:  * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     26:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
                     27:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
                     28:  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
                     29:  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     30:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
                     31:  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
                     36:  * Common part of IRQ handlers for Samsung S3C2800/2400/2410 processors.
                     37:  * derived from i80321_icu.c
                     38:  */
                     39:
                     40: /*
                     41:  * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
                     42:  * All rights reserved.
                     43:  *
                     44:  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
                     45:  *
                     46:  * Redistribution and use in source and binary forms, with or without
                     47:  * modification, are permitted provided that the following conditions
                     48:  * are met:
                     49:  * 1. Redistributions of source code must retain the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer.
                     51:  * 2. Redistributions in binary form must reproduce the above copyright
                     52:  *    notice, this list of conditions and the following disclaimer in the
                     53:  *    documentation and/or other materials provided with the distribution.
                     54:  * 3. All advertising materials mentioning features or use of this software
                     55:  *    must display the following acknowledgement:
                     56:  *     This product includes software developed for the NetBSD Project by
                     57:  *     Wasabi Systems, Inc.
                     58:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     59:  *    or promote products derived from this software without specific prior
                     60:  *    written permission.
                     61:  *
                     62:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     63:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     64:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     65:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     66:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     67:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     68:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     69:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     70:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     71:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     72:  * POSSIBILITY OF SUCH DAMAGE.
                     73:  */
                     74:
                     75: #include <sys/cdefs.h>
                     76: __KERNEL_RCSID(0, "$NetBSD: s3c2xx0_intr.c,v 1.11 2006/11/24 21:20:05 wiz Exp $");
                     77:
                     78: #include <sys/param.h>
                     79: #include <sys/systm.h>
                     80: #include <sys/malloc.h>
                     81: #include <uvm/uvm_extern.h>
                     82: #include <machine/bus.h>
                     83: #include <machine/intr.h>
                     84: #include <arm/cpufunc.h>
                     85:
                     86: #include <arm/s3c2xx0/s3c2xx0reg.h>
                     87: #include <arm/s3c2xx0/s3c2xx0var.h>
                     88:
                     89: volatile uint32_t *s3c2xx0_intr_mask_reg;
                     90:
                     91: static inline void
                     92: __raise(int ipl)
                     93: {
                     94:        if (current_spl_level < ipl) {
                     95:                s3c2xx0_setipl(ipl);
                     96:        }
                     97: }
                     98: /*
                     99:  * modify interrupt mask table for SPL levels
                    100:  */
                    101: void
                    102: s3c2xx0_update_intr_masks(int irqno, int level)
                    103: {
                    104:        int mask = 1 << irqno;
                    105:        int i;
                    106:
                    107:
                    108:        s3c2xx0_ilevel[irqno] = level;
                    109:
                    110:        for (i = 0; i < level; ++i)
                    111:                s3c2xx0_imask[i] |= mask;       /* Enable interrupt at lower
                    112:                                                 * level */
                    113:        for (; i < NIPL - 1; ++i)
                    114:                s3c2xx0_imask[i] &= ~mask;      /* Disable itnerrupt at upper
                    115:                                                 * level */
                    116:
                    117:        /*
                    118:         * Enforce a hierarchy that gives "slow" device (or devices with
                    119:         * limited input buffer space/"real-time" requirements) a better
                    120:         * chance at not dropping data.
                    121:         */
                    122:        s3c2xx0_imask[IPL_BIO] &= s3c2xx0_imask[IPL_SOFTNET];
                    123:        s3c2xx0_imask[IPL_NET] &= s3c2xx0_imask[IPL_BIO];
                    124:        s3c2xx0_imask[IPL_SOFTSERIAL] &= s3c2xx0_imask[IPL_NET];
                    125:        s3c2xx0_imask[IPL_TTY] &= s3c2xx0_imask[IPL_SOFTSERIAL];
                    126:
                    127:        /*
                    128:         * splvm() blocks all interrupts that use the kernel memory
                    129:         * allocation facilities.
                    130:         */
                    131:        s3c2xx0_imask[IPL_VM] &= s3c2xx0_imask[IPL_TTY];
                    132:
                    133:        /*
                    134:         * Audio devices are not allowed to perform memory allocation
                    135:         * in their interrupt routines, and they have fairly "real-time"
                    136:         * requirements, so give them a high interrupt priority.
                    137:         */
                    138:        s3c2xx0_imask[IPL_AUDIO] &= s3c2xx0_imask[IPL_VM];
                    139:
                    140:        /*
                    141:         * splclock() must block anything that uses the scheduler.
                    142:         */
                    143:        s3c2xx0_imask[IPL_CLOCK] &= s3c2xx0_imask[IPL_AUDIO];
                    144:
                    145:        /*
                    146:         * splhigh() must block "everything".
                    147:         */
                    148:        s3c2xx0_imask[IPL_HIGH] &= s3c2xx0_imask[IPL_STATCLOCK];
                    149:
                    150:        /*
                    151:         * XXX We need serial drivers to run at the absolute highest priority
                    152:         * in order to avoid overruns, so serial > high.
                    153:         */
                    154:        s3c2xx0_imask[IPL_SERIAL] &= s3c2xx0_imask[IPL_HIGH];
                    155:
                    156: }
                    157:
                    158: void
                    159: s3c2xx0_do_pending(int enable_int)
                    160: {
                    161:        static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED;
                    162:        int oldirqstate, irqstate, spl_save;
                    163:
                    164:        if (__cpu_simple_lock_try(&processing) == 0)
                    165:                return;
                    166:
                    167:        spl_save = current_spl_level;
                    168:
                    169:        oldirqstate = irqstate = disable_interrupts(I32_bit);
                    170:
                    171:        if (enable_int)
                    172:                irqstate &= ~I32_bit;
                    173:
                    174:
                    175: #define        DO_SOFTINT(si,ipl)                                              \
                    176:        if (get_pending_softint() & SI_TO_IRQBIT(si)) {                 \
                    177:                softint_pending &= ~SI_TO_IRQBIT(si);                   \
                    178:                 __raise(ipl);                                           \
                    179:                restore_interrupts(irqstate);                           \
                    180:                softintr_dispatch(si);                                  \
                    181:                disable_interrupts(I32_bit);                            \
                    182:                s3c2xx0_setipl(spl_save);                               \
                    183:        }
                    184:
                    185:        do {
                    186:                DO_SOFTINT(SI_SOFTSERIAL, IPL_SOFTSERIAL);
                    187:                DO_SOFTINT(SI_SOFTNET, IPL_SOFTNET);
                    188:                DO_SOFTINT(SI_SOFTCLOCK, IPL_SOFTCLOCK);
                    189:                DO_SOFTINT(SI_SOFT, IPL_SOFT);
                    190:        } while (get_pending_softint());
                    191:
                    192:        __cpu_simple_unlock(&processing);
                    193:
                    194:        restore_interrupts(oldirqstate);
                    195: }
                    196:
                    197:
                    198: static int
                    199: stray_interrupt(void *cookie)
                    200: {
                    201:        int save;
                    202:        int irqno = (int) cookie;
                    203:        printf("stray interrupt %d\n", irqno);
                    204:
                    205:        save = disable_interrupts(I32_bit);
                    206:        *s3c2xx0_intr_mask_reg &= ~(1U << irqno);
                    207:        restore_interrupts(save);
                    208:
                    209:        return 0;
                    210: }
                    211: /*
                    212:  * Initialize interrupt dispatcher.
                    213:  */
                    214: void
                    215: s3c2xx0_intr_init(struct s3c2xx0_intr_dispatch * dispatch_table, int icu_len)
                    216: {
                    217:        int i;
                    218:
                    219:        for (i = 0; i < icu_len; ++i) {
                    220:                dispatch_table[i].func = stray_interrupt;
                    221:                dispatch_table[i].cookie = (void *) (i);
                    222:                dispatch_table[i].level = IPL_BIO;
                    223:        }
                    224:
                    225:        global_intr_mask = ~0;          /* no intr is globally blocked. */
                    226:
                    227:        _splraise(IPL_SERIAL);
                    228:        enable_interrupts(I32_bit);
                    229: }
                    230:
                    231: /*
                    232:  * initialize variables so that splfoo() doesn't touch illegal address.
                    233:  * called during bootstrap.
                    234:  */
                    235: void
                    236: s3c2xx0_intr_bootstrap(vaddr_t icureg)
                    237: {
                    238:        s3c2xx0_intr_mask_reg = (volatile uint32_t *)(icureg + INTCTL_INTMSK);
                    239: }
                    240:
                    241:
                    242:
                    243: #undef splx
                    244: void
                    245: splx(int ipl)
                    246: {
                    247:        s3c2xx0_splx(ipl);
                    248: }
                    249:
                    250: #undef _splraise
                    251: int
                    252: _splraise(int ipl)
                    253: {
                    254:        return s3c2xx0_splraise(ipl);
                    255: }
                    256:
                    257: #undef _spllower
                    258: int
                    259: _spllower(int ipl)
                    260: {
                    261:        return s3c2xx0_spllower(ipl);
                    262: }
                    263:
                    264: #undef _setsoftintr
                    265: void
                    266: _setsoftintr(int si)
                    267: {
                    268:        return s3c2xx0_setsoftintr(si);
                    269: }

CVSweb