-/* $OpenBSD: apldog.c,v 1.2 2021/11/13 23:24:24 kettenis Exp $ */
+/* $OpenBSD: apldog.c,v 1.3 2022/01/13 08:59:10 kettenis Exp $ */
/*
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
*
HWRITE4(sc, WDT_SYS_CTL, 0);
apldog_sc = sc;
- cpuresetfn = apldog_reset;
+ if (cpuresetfn == NULL)
+ cpuresetfn = apldog_reset;
}
void
-/* $OpenBSD: aplpmu.c,v 1.2 2021/05/27 08:10:12 kettenis Exp $ */
+/* $OpenBSD: aplpmu.c,v 1.3 2022/01/13 08:59:10 kettenis Exp $ */
/*
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
*
#include <dev/ofw/openfirm.h>
#include <dev/ofw/fdt.h>
+extern void (*cpuresetfn)(void);
+extern void (*powerdownfn)(void);
+
/*
* This driver is based on preliminary device tree bindings and will
* almost certainly need changes once the official bindings land in
#define SERA_TIME_OFFSET 0xd100
#define SERA_TIME_LEN 6
+#define SERA_POWERDOWN 0x9f0f
+#define SERA_POWERDOWN_MAGIC 0x08
+
struct aplpmu_softc {
struct device sc_dev;
spmi_tag_t sc_tag;
uint64_t sc_offset;
};
+struct aplpmu_softc *aplpmu_sc;
+
int aplpmu_match(struct device *, void *, void *);
void aplpmu_attach(struct device *, struct device *, void *);
int aplpmu_gettime(struct todr_chip_handle *, struct timeval *);
int aplpmu_settime(struct todr_chip_handle *, struct timeval *);
+void aplpmu_powerdown(void);
int
aplpmu_match(struct device *parent, void *match, void *aux)
sc->sc_todr.todr_gettime = aplpmu_gettime;
sc->sc_todr.todr_settime = aplpmu_settime;
todr_attach(&sc->sc_todr);
+
+ aplpmu_sc = sc;
+ powerdownfn = aplpmu_powerdown;
}
int
return spmi_cmd_write(sc->sc_tag, sc->sc_sid, SPMI_CMD_EXT_WRITEL,
SERA_TIME_OFFSET, &data, SERA_TIME_LEN);
}
+
+void
+aplpmu_powerdown(void)
+{
+ struct aplpmu_softc *sc = aplpmu_sc;
+ uint8_t data = SERA_POWERDOWN_MAGIC;
+
+ spmi_cmd_write(sc->sc_tag, sc->sc_sid, SPMI_CMD_EXT_WRITEL,
+ SERA_POWERDOWN, &data, sizeof(data));
+
+ cpuresetfn();
+}
-/* $OpenBSD: aplsmc.c,v 1.5 2022/01/12 15:05:38 robert Exp $ */
+/* $OpenBSD: aplsmc.c,v 1.6 2022/01/13 08:59:10 kettenis Exp $ */
/*
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
*
#include "apm.h"
+extern void (*cpuresetfn)(void);
+
#define SMC_EP 32
#define SMC_READ_KEY 0x10
struct ksensor sc_sensors[APLSMC_MAX_SENSORS];
int sc_nsensors;
struct ksensordev sc_sensordev;
-} *aplsmc_sc;
+};
+
+struct aplsmc_softc *aplsmc_sc;
struct aplsmc_sensor aplsmc_sensors[] = {
{ "ACDI", "ui16", SENSOR_INDICATOR, 1, "power supply" },
int aplsmc_wait_cmd(struct aplsmc_softc *sc);
int aplsmc_read_key(struct aplsmc_softc *, uint32_t, void *, size_t);
void aplsmc_refresh_sensors(void *);
+void aplsmc_reset(void);
int
aplsmc_match(struct device *parent, void *match, void *aux)
sensor_task_register(sc, aplsmc_refresh_sensors, 5);
aplsmc_sc = sc;
+ cpuresetfn = aplsmc_reset;
#if NAPM > 0
apm_setinfohook(aplsmc_apminfo);
hw_power = (value > 0);
}
}
+
+void
+aplsmc_reset(void)
+{
+ struct aplsmc_softc *sc = aplsmc_sc;
+ uint32_t key = SMC_KEY("MBSE");
+ uint32_t data = SMC_KEY("off1");
+
+ bus_space_write_region_1(sc->sc_iot, sc->sc_sram_ioh, 0,
+ (uint8_t *)&data, sizeof(data));
+ bus_space_barrier(sc->sc_iot, sc->sc_sram_ioh, 0, sizeof(data),
+ BUS_SPACE_BARRIER_WRITE);
+ aplsmc_send_cmd(sc, SMC_WRITE_KEY, key, sizeof(data));
+ aplsmc_wait_cmd(sc);
+}