Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/kernel.h>
0003 #include <linux/module.h>
0004 #include <linux/delay.h>
0005 #include <linux/gpio.h>
0006 #include <linux/io.h>
0007 #include <asm/proc-fns.h>
0008 #include <asm/system_misc.h>
0009 
0010 #include "regs-ost.h"
0011 #include "reset.h"
0012 #include "smemc.h"
0013 
0014 static void do_hw_reset(void);
0015 
0016 static int reset_gpio = -1;
0017 
0018 int init_gpio_reset(int gpio, int output, int level)
0019 {
0020     int rc;
0021 
0022     rc = gpio_request(gpio, "reset generator");
0023     if (rc) {
0024         printk(KERN_ERR "Can't request reset_gpio\n");
0025         goto out;
0026     }
0027 
0028     if (output)
0029         rc = gpio_direction_output(gpio, level);
0030     else
0031         rc = gpio_direction_input(gpio);
0032     if (rc) {
0033         printk(KERN_ERR "Can't configure reset_gpio\n");
0034         gpio_free(gpio);
0035         goto out;
0036     }
0037 
0038 out:
0039     if (!rc)
0040         reset_gpio = gpio;
0041 
0042     return rc;
0043 }
0044 
0045 /*
0046  * Trigger GPIO reset.
0047  * This covers various types of logic connecting gpio pin
0048  * to RESET pins (nRESET or GPIO_RESET):
0049  */
0050 static void do_gpio_reset(void)
0051 {
0052     BUG_ON(reset_gpio == -1);
0053 
0054     /* drive it low */
0055     gpio_direction_output(reset_gpio, 0);
0056     mdelay(2);
0057     /* rising edge or drive high */
0058     gpio_set_value(reset_gpio, 1);
0059     mdelay(2);
0060     /* falling edge */
0061     gpio_set_value(reset_gpio, 0);
0062 
0063     /* give it some time */
0064     mdelay(10);
0065 
0066     WARN_ON(1);
0067     /* fallback */
0068     do_hw_reset();
0069 }
0070 
0071 static void do_hw_reset(void)
0072 {
0073     /* Initialize the watchdog and let it fire */
0074     writel_relaxed(OWER_WME, OWER);
0075     writel_relaxed(OSSR_M3, OSSR);
0076     /* ... in 100 ms */
0077     writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
0078     /*
0079      * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
0080      * we put SDRAM into self-refresh to prevent that
0081      */
0082     while (1)
0083         writel_relaxed(MDREFR_SLFRSH, MDREFR);
0084 }
0085 
0086 void pxa_restart(enum reboot_mode mode, const char *cmd)
0087 {
0088     local_irq_disable();
0089     local_fiq_disable();
0090 
0091     clear_reset_status(RESET_STATUS_ALL);
0092 
0093     switch (mode) {
0094     case REBOOT_SOFT:
0095         /* Jump into ROM at address 0 */
0096         soft_restart(0);
0097         break;
0098     case REBOOT_GPIO:
0099         do_gpio_reset();
0100         break;
0101     case REBOOT_HARD:
0102     default:
0103         do_hw_reset();
0104         break;
0105     }
0106 }