reset.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License version 2 as
  4. * published by the Free Software Foundation.
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/delay.h>
  9. #include <linux/gpio.h>
  10. #include <asm/io.h>
  11. #include <asm/proc-fns.h>
  12. #include <asm/arch/pxa-regs.h>
  13. #include <asm/arch/pxa2xx-regs.h>
  14. #include <asm/arch/reset.h>
  15. static void do_hw_reset(void);
  16. static int reset_gpio = -1;
  17. int init_gpio_reset(int gpio)
  18. {
  19. int rc;
  20. rc = gpio_request(gpio, "reset generator");
  21. if (rc) {
  22. printk(KERN_ERR "Can't request reset_gpio\n");
  23. goto out;
  24. }
  25. rc = gpio_direction_input(gpio);
  26. if (rc) {
  27. printk(KERN_ERR "Can't configure reset_gpio for input\n");
  28. gpio_free(gpio);
  29. goto out;
  30. }
  31. out:
  32. if (!rc)
  33. reset_gpio = gpio;
  34. return rc;
  35. }
  36. /*
  37. * Trigger GPIO reset.
  38. * This covers various types of logic connecting gpio pin
  39. * to RESET pins (nRESET or GPIO_RESET):
  40. */
  41. static void do_gpio_reset(void)
  42. {
  43. BUG_ON(reset_gpio == -1);
  44. /* drive it low */
  45. gpio_direction_output(reset_gpio, 0);
  46. mdelay(2);
  47. /* rising edge or drive high */
  48. gpio_set_value(reset_gpio, 1);
  49. mdelay(2);
  50. /* falling edge */
  51. gpio_set_value(reset_gpio, 0);
  52. /* give it some time */
  53. mdelay(10);
  54. WARN_ON(1);
  55. /* fallback */
  56. do_hw_reset();
  57. }
  58. static void do_hw_reset(void)
  59. {
  60. /* Initialize the watchdog and let it fire */
  61. OWER = OWER_WME;
  62. OSSR = OSSR_M3;
  63. OSMR3 = OSCR + 368640; /* ... in 100 ms */
  64. }
  65. void arch_reset(char mode)
  66. {
  67. if (cpu_is_pxa2xx())
  68. RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
  69. switch (mode) {
  70. case 's':
  71. /* Jump into ROM at address 0 */
  72. cpu_reset(0);
  73. break;
  74. case 'h':
  75. do_hw_reset();
  76. break;
  77. case 'g':
  78. do_gpio_reset();
  79. break;
  80. }
  81. }