linux/arch/arm/mach-pxa/reset.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/kernel.h>
   3#include <linux/module.h>
   4#include <linux/delay.h>
   5#include <linux/gpio.h>
   6#include <linux/io.h>
   7#include <asm/proc-fns.h>
   8#include <asm/system_misc.h>
   9
  10#include <mach/regs-ost.h>
  11#include <mach/reset.h>
  12#include <mach/smemc.h>
  13
  14unsigned int reset_status;
  15EXPORT_SYMBOL(reset_status);
  16
  17static void do_hw_reset(void);
  18
  19static int reset_gpio = -1;
  20
  21int init_gpio_reset(int gpio, int output, int level)
  22{
  23        int rc;
  24
  25        rc = gpio_request(gpio, "reset generator");
  26        if (rc) {
  27                printk(KERN_ERR "Can't request reset_gpio\n");
  28                goto out;
  29        }
  30
  31        if (output)
  32                rc = gpio_direction_output(gpio, level);
  33        else
  34                rc = gpio_direction_input(gpio);
  35        if (rc) {
  36                printk(KERN_ERR "Can't configure reset_gpio\n");
  37                gpio_free(gpio);
  38                goto out;
  39        }
  40
  41out:
  42        if (!rc)
  43                reset_gpio = gpio;
  44
  45        return rc;
  46}
  47
  48/*
  49 * Trigger GPIO reset.
  50 * This covers various types of logic connecting gpio pin
  51 * to RESET pins (nRESET or GPIO_RESET):
  52 */
  53static void do_gpio_reset(void)
  54{
  55        BUG_ON(reset_gpio == -1);
  56
  57        /* drive it low */
  58        gpio_direction_output(reset_gpio, 0);
  59        mdelay(2);
  60        /* rising edge or drive high */
  61        gpio_set_value(reset_gpio, 1);
  62        mdelay(2);
  63        /* falling edge */
  64        gpio_set_value(reset_gpio, 0);
  65
  66        /* give it some time */
  67        mdelay(10);
  68
  69        WARN_ON(1);
  70        /* fallback */
  71        do_hw_reset();
  72}
  73
  74static void do_hw_reset(void)
  75{
  76        /* Initialize the watchdog and let it fire */
  77        writel_relaxed(OWER_WME, OWER);
  78        writel_relaxed(OSSR_M3, OSSR);
  79        /* ... in 100 ms */
  80        writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
  81        /*
  82         * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
  83         * we put SDRAM into self-refresh to prevent that
  84         */
  85        while (1)
  86                writel_relaxed(MDREFR_SLFRSH, MDREFR);
  87}
  88
  89void pxa_restart(enum reboot_mode mode, const char *cmd)
  90{
  91        local_irq_disable();
  92        local_fiq_disable();
  93
  94        clear_reset_status(RESET_STATUS_ALL);
  95
  96        switch (mode) {
  97        case REBOOT_SOFT:
  98                /* Jump into ROM at address 0 */
  99                soft_restart(0);
 100                break;
 101        case REBOOT_GPIO:
 102                do_gpio_reset();
 103                break;
 104        case REBOOT_HARD:
 105        default:
 106                do_hw_reset();
 107                break;
 108        }
 109}
 110