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