linux/arch/arm/mach-picoxcell/common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
   4 *
   5 * All enquiries to support@picochip.com
   6 */
   7#include <linux/delay.h>
   8#include <linux/of.h>
   9#include <linux/of_address.h>
  10#include <linux/reboot.h>
  11
  12#include <asm/mach/arch.h>
  13#include <asm/mach/map.h>
  14
  15#define PHYS_TO_IO(x)                   (((x) & 0x00ffffff) | 0xfe000000)
  16#define PICOXCELL_PERIPH_BASE           0x80000000
  17#define PICOXCELL_PERIPH_LENGTH         SZ_4M
  18
  19#define WDT_CTRL_REG_EN_MASK            (1 << 0)
  20#define WDT_CTRL_REG_OFFS               (0x00)
  21#define WDT_TIMEOUT_REG_OFFS            (0x04)
  22static void __iomem *wdt_regs;
  23
  24/*
  25 * The machine restart method can be called from an atomic context so we won't
  26 * be able to ioremap the regs then.
  27 */
  28static void picoxcell_setup_restart(void)
  29{
  30        struct device_node *np = of_find_compatible_node(NULL, NULL,
  31                                                         "snps,dw-apb-wdg");
  32        if (WARN(!np, "unable to setup watchdog restart"))
  33                return;
  34
  35        wdt_regs = of_iomap(np, 0);
  36        WARN(!wdt_regs, "failed to remap watchdog regs");
  37}
  38
  39static struct map_desc io_map __initdata = {
  40        .virtual        = PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
  41        .pfn            = __phys_to_pfn(PICOXCELL_PERIPH_BASE),
  42        .length         = PICOXCELL_PERIPH_LENGTH,
  43        .type           = MT_DEVICE,
  44};
  45
  46static void __init picoxcell_map_io(void)
  47{
  48        iotable_init(&io_map, 1);
  49}
  50
  51static void __init picoxcell_init_machine(void)
  52{
  53        picoxcell_setup_restart();
  54}
  55
  56static const char *picoxcell_dt_match[] = {
  57        "picochip,pc3x2",
  58        "picochip,pc3x3",
  59        NULL
  60};
  61
  62static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd)
  63{
  64        /*
  65         * Configure the watchdog to reset with the shortest possible timeout
  66         * and give it chance to do the reset.
  67         */
  68        if (wdt_regs) {
  69                writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS);
  70                writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS);
  71                /* No sleeping, possibly atomic. */
  72                mdelay(500);
  73        }
  74}
  75
  76DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
  77        .map_io         = picoxcell_map_io,
  78        .init_machine   = picoxcell_init_machine,
  79        .dt_compat      = picoxcell_dt_match,
  80        .restart        = picoxcell_wdt_restart,
  81MACHINE_END
  82