[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] xen/rpi4: implement watchdog-based reset
On Wed, Jun 03, 2020 at 03:31:56PM -0700, Stefano Stabellini wrote: > Touching the watchdog is required to be able to reboot the board. > > The implementation is based on > drivers/watchdog/bcm2835_wdt.c:__bcm2835_restart in Linux. Ah, I was looking at this just today, as it had been annoying me greatly. This works for me, so: Tested-by: Corey Minyard <cminyard@xxxxxxxxxx> However, I was wondering if it might be better to handle this by failing the operation in xen and passing it back to dom0 to do. On the Pi you send a firmware message to reboot, and that seems like too much to do in Xen, but it would seem possible to send this back to dom0. Just a thought, as it might be a more general fix for other devices in the same situation. Thanks, -corey > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> > --- > xen/arch/arm/platforms/brcm-raspberry-pi.c | 60 ++++++++++++++++++++++ > 1 file changed, 60 insertions(+) > > diff --git a/xen/arch/arm/platforms/brcm-raspberry-pi.c > b/xen/arch/arm/platforms/brcm-raspberry-pi.c > index f5ae58a7d5..0214ae2b3c 100644 > --- a/xen/arch/arm/platforms/brcm-raspberry-pi.c > +++ b/xen/arch/arm/platforms/brcm-raspberry-pi.c > @@ -18,6 +18,10 @@ > */ > > #include <asm/platform.h> > +#include <xen/delay.h> > +#include <xen/mm.h> > +#include <xen/vmap.h> > +#include <asm/io.h> > > static const char *const rpi4_dt_compat[] __initconst = > { > @@ -37,12 +41,68 @@ static const struct dt_device_match rpi4_blacklist_dev[] > __initconst = > * The aux peripheral also shares a page with the aux UART. > */ > DT_MATCH_COMPATIBLE("brcm,bcm2835-aux"), > + /* Special device used for rebooting */ > + DT_MATCH_COMPATIBLE("brcm,bcm2835-pm"), > { /* sentinel */ }, > }; > > + > +#define PM_PASSWORD 0x5a000000 > +#define PM_RSTC 0x1c > +#define PM_WDOG 0x24 > +#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 > +#define PM_RSTC_WRCFG_CLR 0xffffffcf > + > +static void __iomem *rpi4_map_watchdog(void) > +{ > + void __iomem *base; > + struct dt_device_node *node; > + paddr_t start, len; > + int ret; > + > + node = dt_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm"); > + if ( !node ) > + return NULL; > + > + ret = dt_device_get_address(node, 0, &start, &len); > + if ( ret ) > + { > + dprintk(XENLOG_ERR, "Cannot read watchdog register address\n"); > + return NULL; > + } > + > + base = ioremap_nocache(start & PAGE_MASK, PAGE_SIZE); > + if ( !base ) > + { > + dprintk(XENLOG_ERR, "Unable to map watchdog register!\n"); > + return NULL; > + } > + > + return base; > +} > + > +static void rpi4_reset(void) > +{ > + u32 val; > + void __iomem *base = rpi4_map_watchdog(); > + if ( !base ) > + return; > + > + /* use a timeout of 10 ticks (~150us) */ > + writel(10 | PM_PASSWORD, base + PM_WDOG); > + val = readl(base + PM_RSTC); > + val &= PM_RSTC_WRCFG_CLR; > + val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET; > + writel(val, base + PM_RSTC); > + > + /* No sleeping, possibly atomic. */ > + mdelay(1); > +} > + > PLATFORM_START(rpi4, "Raspberry Pi 4") > .compatible = rpi4_dt_compat, > .blacklist_dev = rpi4_blacklist_dev, > + .reset = rpi4_reset, > .dma_bitsize = 30, > PLATFORM_END > > -- > 2.17.1 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |