/*
* Copyright (c) 2002, 2003, 2005 Genetec corp. All rights reserved.
* Written by Hiroyuki Bessho for Genetec corp.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec corp. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORP.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
static int
obio_spurious(void *arg)
{
int irqno = (int)arg;
printf("Spurious interrupt %d on On-board peripheral", irqno);
return 1;
}
/*
* interrupt handler for GPIO0 (on-board peripherals)
*
* On G4250ebx, 10 interrupts are ORed through on-board logic,
* and routed to GPIO0 of PXA250 processor.
*/
static int
obio_intr(void *arg)
{
int irqno, pending;
struct obio_softc *sc = (struct obio_softc *)arg;
int n=0;
/* reset pending bit */
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh,
G42XXEB_INTSTS1, ~(1<<irqno));
#if 0
if (sc->sc_handler[irqno].level > saved_spl_level) {
int spl_save = _splraise(sc->sc_handler[irqno].level);
(* sc->sc_handler[irqno].func)(
sc->sc_handler[irqno].arg);
splx(spl_save);
}
else
#endif
{
int psw = disable_interrupts(I32_bit); /* XXX */
/* mask this interrupt until software
interrupt is handled. */
sc->sc_intr_pending |= (1U<<irqno);
obio_update_intrmask(sc);
restore_interrupts(psw);
++n;
}
#ifdef DIAGNOSTIC
if (n > 1000)
panic("obio_intr: stayed too long");
#endif
}
if (n > 0) {
/* handle it later */
softint_schedule(sc->sc_si);
}
/* GPIO interrupt is edge triggered. make a pulse
to let Cotulla notice when other interrupts are
still pending */
bus_space_write_2(sc->sc_iot, sc->sc_obioreg_ioh,
G42XXEB_INTMASK, 0xffff);
obio_update_intrmask(sc);
return 1;
}
static void
obio_softint(void *arg)
{
struct obio_softc *sc = (struct obio_softc *)arg;
int irqno;
int spl_save = curcpl();
int psw;
/* tweak memory access timing for CS3.
the value set by redboot is too slow */
if (bus_space_map(iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0,
&sc->sc_memctl_ioh))
goto fail;
bus_space_write_4(iot, sc->sc_memctl_ioh, MEMCTL_MSC1,
(0xffff & bus_space_read_4(iot, sc->sc_memctl_ioh, MEMCTL_MSC1))
| (0x6888 << 16));
/*
* Mask all interrupts.
* They are later unmasked at each device's attach routine.
*/
sc->sc_intr_mask = 0xffff;
bus_space_write_2(iot, sc->sc_obioreg_ioh, G42XXEB_INTMASK,
sc->sc_intr_mask );