Add suspend/resume state saving for OpenPIC on PowerMac. It's likely this
can be used on the others (cpcht and psim), but that has not been tested.
This commit is contained in:
parent
ccdfa3b5f1
commit
9a2edf0198
@ -99,6 +99,7 @@
|
||||
*/
|
||||
|
||||
/* interrupt vector/priority reg */
|
||||
#define OPENPIC_SRC_VECTOR_COUNT 64
|
||||
#ifndef OPENPIC_SRC_VECTOR
|
||||
#define OPENPIC_SRC_VECTOR(irq) (0x10000 + (irq) * 0x20)
|
||||
#endif
|
||||
|
@ -32,6 +32,14 @@
|
||||
|
||||
#define OPENPIC_IRQMAX 256 /* h/w allows more */
|
||||
|
||||
/* Names match the macros in openpicreg.h. */
|
||||
struct openpic_timer {
|
||||
uint32_t tcnt;
|
||||
uint32_t tbase;
|
||||
uint32_t tvec;
|
||||
uint32_t tdst;
|
||||
};
|
||||
|
||||
struct openpic_softc {
|
||||
device_t sc_dev;
|
||||
struct resource *sc_memr;
|
||||
@ -45,6 +53,14 @@ struct openpic_softc {
|
||||
u_int sc_ncpu;
|
||||
u_int sc_nirq;
|
||||
int sc_psim;
|
||||
|
||||
/* Saved states. */
|
||||
uint32_t sc_saved_config;
|
||||
uint32_t sc_saved_ipis[4];
|
||||
uint32_t sc_saved_prios[4];
|
||||
struct openpic_timer sc_saved_timers[OPENPIC_TIMERS];
|
||||
uint32_t sc_saved_vectors[OPENPIC_SRC_VECTOR_COUNT];
|
||||
|
||||
};
|
||||
|
||||
extern devclass_t openpic_devclass;
|
||||
@ -66,4 +82,7 @@ void openpic_ipi(device_t, u_int);
|
||||
void openpic_mask(device_t, u_int);
|
||||
void openpic_unmask(device_t, u_int);
|
||||
|
||||
int openpic_suspend(device_t dev);
|
||||
int openpic_resume(device_t dev);
|
||||
|
||||
#endif /* _POWERPC_OPENPICVAR_H_ */
|
||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/openpicreg.h>
|
||||
#include <machine/openpicvar.h>
|
||||
|
||||
#include "pic_if.h"
|
||||
@ -68,6 +69,8 @@ static device_method_t openpic_ofw_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, openpic_ofw_probe),
|
||||
DEVMETHOD(device_attach, openpic_ofw_attach),
|
||||
DEVMETHOD(device_suspend, openpic_suspend),
|
||||
DEVMETHOD(device_resume, openpic_resume),
|
||||
|
||||
/* PIC interface */
|
||||
DEVMETHOD(pic_bind, openpic_bind),
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/openpicreg.h>
|
||||
#include <machine/openpicvar.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/resource.h>
|
||||
|
@ -380,3 +380,64 @@ openpic_unmask(device_t dev, u_int irq)
|
||||
openpic_write(sc, OPENPIC_IPI_VECTOR(0), x);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
openpic_suspend(device_t dev)
|
||||
{
|
||||
struct openpic_softc *sc;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_saved_config = bus_read_4(sc->sc_memr, OPENPIC_CONFIG);
|
||||
for (i = 0; i < 4; i++) {
|
||||
sc->sc_saved_ipis[i] = bus_read_4(sc->sc_memr, OPENPIC_IPI_VECTOR(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
sc->sc_saved_prios[i] = bus_read_4(sc->sc_memr, OPENPIC_PCPU_TPR(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < OPENPIC_TIMERS; i++) {
|
||||
sc->sc_saved_timers[i].tcnt = bus_read_4(sc->sc_memr, OPENPIC_TCNT(i));
|
||||
sc->sc_saved_timers[i].tbase = bus_read_4(sc->sc_memr, OPENPIC_TBASE(i));
|
||||
sc->sc_saved_timers[i].tvec = bus_read_4(sc->sc_memr, OPENPIC_TVEC(i));
|
||||
sc->sc_saved_timers[i].tdst = bus_read_4(sc->sc_memr, OPENPIC_TDST(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < OPENPIC_SRC_VECTOR_COUNT; i++)
|
||||
sc->sc_saved_vectors[i] =
|
||||
bus_read_4(sc->sc_memr, OPENPIC_SRC_VECTOR(i)) & ~OPENPIC_ACTIVITY;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
openpic_resume(device_t dev)
|
||||
{
|
||||
struct openpic_softc *sc;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_saved_config = bus_read_4(sc->sc_memr, OPENPIC_CONFIG);
|
||||
for (i = 0; i < 4; i++) {
|
||||
bus_write_4(sc->sc_memr, OPENPIC_IPI_VECTOR(i), sc->sc_saved_ipis[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
bus_write_4(sc->sc_memr, OPENPIC_PCPU_TPR(i), sc->sc_saved_prios[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < OPENPIC_TIMERS; i++) {
|
||||
bus_write_4(sc->sc_memr, OPENPIC_TCNT(i), sc->sc_saved_timers[i].tcnt);
|
||||
bus_write_4(sc->sc_memr, OPENPIC_TBASE(i), sc->sc_saved_timers[i].tbase);
|
||||
bus_write_4(sc->sc_memr, OPENPIC_TVEC(i), sc->sc_saved_timers[i].tvec);
|
||||
bus_write_4(sc->sc_memr, OPENPIC_TDST(i), sc->sc_saved_timers[i].tdst);
|
||||
}
|
||||
|
||||
for (i = 0; i < OPENPIC_SRC_VECTOR_COUNT; i++)
|
||||
bus_write_4(sc->sc_memr, OPENPIC_SRC_VECTOR(i), sc->sc_saved_vectors[i]);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/openpicreg.h>
|
||||
#include <machine/openpicvar.h>
|
||||
#include <powerpc/psim/iobusvar.h>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user