|
@@ -0,0 +1,95 @@
|
|
|
+/*
|
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
|
+ * published by the Free Software Foundation.
|
|
|
+ */
|
|
|
+#include <linux/kernel.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/delay.h>
|
|
|
+#include <linux/gpio.h>
|
|
|
+#include <asm/io.h>
|
|
|
+#include <asm/proc-fns.h>
|
|
|
+
|
|
|
+#include <asm/arch/pxa-regs.h>
|
|
|
+
|
|
|
+static void do_hw_reset(void);
|
|
|
+
|
|
|
+static int reset_gpio = -1;
|
|
|
+
|
|
|
+int init_gpio_reset(int gpio)
|
|
|
+{
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = gpio_request(gpio, "reset generator");
|
|
|
+ if (rc) {
|
|
|
+ printk(KERN_ERR "Can't request reset_gpio\n");
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = gpio_direction_input(gpio);
|
|
|
+ if (rc) {
|
|
|
+ printk(KERN_ERR "Can't configure reset_gpio for input\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 */
|
|
|
+ OWER = OWER_WME;
|
|
|
+ OSSR = OSSR_M3;
|
|
|
+ OSMR3 = OSCR + 368640; /* ... in 100 ms */
|
|
|
+}
|
|
|
+
|
|
|
+void arch_reset(char mode)
|
|
|
+{
|
|
|
+ if (cpu_is_pxa2xx())
|
|
|
+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
|
|
+
|
|
|
+ switch (mode) {
|
|
|
+ case 's':
|
|
|
+ /* Jump into ROM at address 0 */
|
|
|
+ cpu_reset(0);
|
|
|
+ break;
|
|
|
+ case 'h':
|
|
|
+ do_hw_reset();
|
|
|
+ break;
|
|
|
+ case 'g':
|
|
|
+ do_gpio_reset();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|