0001
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
0047
0048
0049
0050 static void do_gpio_reset(void)
0051 {
0052 BUG_ON(reset_gpio == -1);
0053
0054
0055 gpio_direction_output(reset_gpio, 0);
0056 mdelay(2);
0057
0058 gpio_set_value(reset_gpio, 1);
0059 mdelay(2);
0060
0061 gpio_set_value(reset_gpio, 0);
0062
0063
0064 mdelay(10);
0065
0066 WARN_ON(1);
0067
0068 do_hw_reset();
0069 }
0070
0071 static void do_hw_reset(void)
0072 {
0073
0074 writel_relaxed(OWER_WME, OWER);
0075 writel_relaxed(OSSR_M3, OSSR);
0076
0077 writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
0078
0079
0080
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
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 }