diff options
author | imp <imp@FreeBSD.org> | 2012-06-15 08:37:50 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2012-06-15 08:37:50 +0000 |
commit | 88f68062a5f9d1e85489c6f104cc59e12b41c7bb (patch) | |
tree | 9c000993641ecca80a8e61c6a9d90d36c19c762c /sys/arm/at91/at91_rst.c | |
parent | 968a30af3f039378ca81b54c0f3ba5cdd06dcb58 (diff) | |
download | FreeBSD-src-88f68062a5f9d1e85489c6f104cc59e12b41c7bb.zip FreeBSD-src-88f68062a5f9d1e85489c6f104cc59e12b41c7bb.tar.gz |
Make it possible to link together a sam and an rm kernel. The results
aren't very pretty yet, but this takes DELAY and cpu_reset and makes
them pointers.
# I worry that these are set too late in the boot, especially cpu_reset.
Diffstat (limited to 'sys/arm/at91/at91_rst.c')
-rw-r--r-- | sys/arm/at91/at91_rst.c | 107 |
1 files changed, 51 insertions, 56 deletions
diff --git a/sys/arm/at91/at91_rst.c b/sys/arm/at91/at91_rst.c index 76cc43c..dbd041b 100644 --- a/sys/arm/at91/at91_rst.c +++ b/sys/arm/at91/at91_rst.c @@ -42,50 +42,70 @@ __FBSDID("$FreeBSD$"); #define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */ #define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */ -static int rst_intr(void *arg); +static int at91rst_intr(void *arg); -static struct rst_softc { +static struct at91rst_softc { struct resource *mem_res; /* Memory resource */ struct resource *irq_res; /* IRQ resource */ void *intrhand; /* Interrupt handle */ struct callout tick_ch; /* Tick callout */ device_t sc_dev; u_int shutdown; /* Shutdown in progress */ -} *rst_sc; +} *at91rst_sc; static inline uint32_t -RD4(struct rst_softc *sc, bus_size_t off) +RD4(struct at91rst_softc *sc, bus_size_t off) { return (bus_read_4(sc->mem_res, off)); } static inline void -WR4(struct rst_softc *sc, bus_size_t off, uint32_t val) +WR4(struct at91rst_softc *sc, bus_size_t off, uint32_t val) { bus_write_4(sc->mem_res, off, val); } -static int -at91_rst_probe(device_t dev) +void cpu_reset_sam9g20(void) __attribute__((weak)); +void cpu_reset_sam9g20(void) {} + +static void +at91rst_cpu_reset(void) { - if (at91_is_sam9() || at91_is_sam9xe()) { - device_set_desc(dev, "AT91SAM9 Reset Controller"); - return (0); + if (at91rst_sc) { + cpu_reset_sam9g20(); /* May be null */ + + WR4(at91rst_sc, RST_MR, + RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY); + + WR4(at91rst_sc, RST_CR, + RST_CR_PROCRST | + RST_CR_PERRST | + RST_CR_EXTRST | + RST_CR_KEY); } - return (ENXIO); + while(1) + continue; +} + +static int +at91rst_probe(device_t dev) +{ + + device_set_desc(dev, "AT91SAM9 Reset Controller"); + return (0); } static int -at91_rst_attach(device_t dev) +at91rst_attach(device_t dev) { - struct rst_softc *sc; + struct at91rst_softc *sc; const char *cause; int rid, err; - rst_sc = sc = device_get_softc(dev); + at91rst_sc = sc = device_get_softc(dev); sc->sc_dev = dev; callout_init(&sc->tick_ch, 0); @@ -109,11 +129,11 @@ at91_rst_attach(device_t dev) /* Activate the interrupt. */ err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, - rst_intr, NULL, sc, &sc->intrhand); + at91rst_intr, NULL, sc, &sc->intrhand); if (err) device_printf(dev, "could not establish interrupt handler.\n"); - WR4(rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY); + WR4(at91rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY); switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) { case RST_SR_RST_POW: @@ -137,16 +157,15 @@ at91_rst_attach(device_t dev) } device_printf(dev, "Reset cause: %s.\n", cause); - /* cpu_reset_addr = cpu_reset; */ - + soc_data.reset = at91rst_cpu_reset; out: return (err); } static void -rst_tick(void *argp) +at91rst_tick(void *argp) { - struct rst_softc *sc = argp; + struct at91rst_softc *sc = argp; if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) { /* User released the button in morre than RST_TIMEOUT */ @@ -157,60 +176,36 @@ rst_tick(void *argp) device_printf(sc->sc_dev, "shutting down...\n"); shutdown_nice(0); } else { - callout_reset(&sc->tick_ch, hz/RST_TICK, rst_tick, sc); + callout_reset(&sc->tick_ch, hz/RST_TICK, at91rst_tick, sc); } } static int -rst_intr(void *argp) +at91rst_intr(void *argp) { - struct rst_softc *sc = argp; + struct at91rst_softc *sc = argp; if (RD4(sc, RST_SR) & RST_SR_URSTS) { if (sc->shutdown == 0) - callout_reset(&sc->tick_ch, hz/RST_TICK, rst_tick, sc); + callout_reset(&sc->tick_ch, hz/RST_TICK, at91rst_tick, sc); return (FILTER_HANDLED); } return (FILTER_STRAY); } -static device_method_t at91_rst_methods[] = { - DEVMETHOD(device_probe, at91_rst_probe), - DEVMETHOD(device_attach, at91_rst_attach), +static device_method_t at91rst_methods[] = { + DEVMETHOD(device_probe, at91rst_probe), + DEVMETHOD(device_attach, at91rst_attach), DEVMETHOD_END }; -static driver_t at91_rst_driver = { +static driver_t at91rst_driver = { "at91_rst", - at91_rst_methods, - sizeof(struct rst_softc), + at91rst_methods, + sizeof(struct at91rst_softc), }; -static devclass_t at91_rst_devclass; +static devclass_t at91rst_devclass; -DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, NULL, +DRIVER_MODULE(at91_rst, atmelarm, at91rst_driver, at91rst_devclass, NULL, NULL); - -void cpu_reset_sam9g20(void) __attribute__((weak)); -void cpu_reset_sam9g20(void) {} - -void -cpu_reset(void) -{ - - if (rst_sc) { - cpu_reset_sam9g20(); /* May be null */ - - WR4(rst_sc, RST_MR, - RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY); - - WR4(rst_sc, RST_CR, - RST_CR_PROCRST | - RST_CR_PERRST | - RST_CR_EXTRST | - RST_CR_KEY); - } - - for(;;) - ; -} |