diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-02-27 08:39:26 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-02-27 08:39:26 +0000 |
commit | 06db312fe197a84b656374ff8be1c633c2fc8667 (patch) | |
tree | 671120a2f030dc58f45924b5fc5e7431043adf88 /sys/dev | |
parent | fdad1e41aeb95bf6d512c3b547bad7bc0abf35d3 (diff) |
Add support for the older generation spec of PSCI, which supports
shutdown and reset only if the function id is explicitly provided
in the device tree. For the newer implementations we are supposed
to be using the specified function ids only.
With and ok jsg@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/fdt/psci.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/sys/dev/fdt/psci.c b/sys/dev/fdt/psci.c index fceafd0e9ba..b24613a275c 100644 --- a/sys/dev/fdt/psci.c +++ b/sys/dev/fdt/psci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psci.c,v 1.1 2017/01/25 10:14:40 jsg Exp $ */ +/* $OpenBSD: psci.c,v 1.2 2017/02/27 08:39:25 patrick Exp $ */ /* * Copyright (c) 2016 Jonathan Gray <jsg@openbsd.org> @@ -35,6 +35,8 @@ extern void (*powerdownfn)(void); struct psci_softc { struct device sc_dev; void (*callfn)(uint32_t, uint32_t, uint32_t, uint32_t); + int sc_system_off; + int sc_system_reset; }; struct psci_softc *psci_sc; @@ -60,8 +62,9 @@ psci_match(struct device *parent, void *match, void *aux) { struct fdt_attach_args *faa = aux; - /* reset and shutdown added in 0.2 */ - return OF_is_compatible(faa->fa_node, "arm,psci-0.2"); + return OF_is_compatible(faa->fa_node, "arm,psci") || + OF_is_compatible(faa->fa_node, "arm,psci-0.2") || + OF_is_compatible(faa->fa_node, "arm,psci-1.0"); } void @@ -78,11 +81,29 @@ psci_attach(struct device *parent, struct device *self, void *aux) sc->callfn = smc_call; } + /* + * The function IDs are only to be parsed for the old specification + * (as in version 0.1). All newer implementations are supposed to + * use the specified values. + */ + if (OF_is_compatible(faa->fa_node, "arm,psci-0.2") || + OF_is_compatible(faa->fa_node, "arm,psci-1.0")) { + sc->sc_system_off = SYSTEM_OFF; + sc->sc_system_reset = SYSTEM_RESET; + } else if (OF_is_compatible(faa->fa_node, "arm,psci")) { + sc->sc_system_off = OF_getpropint(faa->fa_node, + "system_off", 0); + sc->sc_system_reset = OF_getpropint(faa->fa_node, + "system_reset", 0); + } + printf("\n"); psci_sc = sc; - cpuresetfn = psci_reset; - powerdownfn = psci_powerdown; + if (sc->sc_system_off != 0) + powerdownfn = psci_powerdown; + if (sc->sc_system_reset != 0) + cpuresetfn = psci_reset; } void @@ -90,7 +111,7 @@ psci_reset(void) { struct psci_softc *sc = psci_sc; if (sc->callfn) - (*sc->callfn)(SYSTEM_RESET, 0, 0, 0); + (*sc->callfn)(sc->sc_system_reset, 0, 0, 0); } void @@ -98,5 +119,5 @@ psci_powerdown(void) { struct psci_softc *sc = psci_sc; if (sc->callfn) - (*sc->callfn)(SYSTEM_OFF, 0, 0, 0); + (*sc->callfn)(sc->sc_system_off, 0, 0, 0); } |