reset.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 <linux/io.h>
  11. #include <asm/proc-fns.h>
  12. #include <mach/regs-ost.h>
  13. #include <mach/reset.h>
  14. unsigned int reset_status;
  15. EXPORT_SYMBOL(reset_status);
  16. static void do_hw_reset(void);
  17. static int reset_gpio = -1;
  18. int init_gpio_reset(int gpio, int output, int level)
  19. {
  20. int rc;
  21. rc = gpio_request(gpio, "reset generator");
  22. if (rc) {
  23. printk(KERN_ERR "Can't request reset_gpio\n");
  24. goto out;
  25. }
  26. if (output)
  27. rc = gpio_direction_output(gpio, level);
  28. else
  29. rc = gpio_direction_input(gpio);
  30. if (rc) {
  31. printk(KERN_ERR "Can't configure reset_gpio\n");
  32. gpio_free(gpio);
  33. goto out;
  34. }
  35. out:
  36. if (!rc)
  37. reset_gpio = gpio;
  38. return rc;
  39. }
  40. /*
  41. * Trigger GPIO reset.
  42. * This covers various types of logic connecting gpio pin
  43. * to RESET pins (nRESET or GPIO_RESET):
  44. */
  45. static void do_gpio_reset(void)
  46. {
  47. BUG_ON(reset_gpio == -1);
  48. /* drive it low */
  49. gpio_direction_output(reset_gpio, 0);
  50. mdelay(2);
  51. /* rising edge or drive high */
  52. gpio_set_value(reset_gpio, 1);
  53. mdelay(2);
  54. /* falling edge */
  55. gpio_set_value(reset_gpio, 0);
  56. /* give it some time */
  57. mdelay(10);
  58. WARN_ON(1);
  59. /* fallback */
  60. do_hw_reset();
  61. }
  62. static void do_hw_reset(void)
  63. {
  64. /* Initialize the watchdog and let it fire */
  65. OWER = OWER_WME;
  66. OSSR = OSSR_M3;
  67. OSMR3 = OSCR + 368640; /* ... in 100 ms */
  68. }
  69. void arch_reset(char mode, const char *cmd)
  70. {
  71. clear_reset_status(RESET_STATUS_ALL);
  72. switch (mode) {
  73. case 's':
  74. /* Jump into ROM at address 0 */
  75. cpu_reset(0);
  76. break;
  77. case 'g':
  78. do_gpio_reset();
  79. break;
  80. case 'h':
  81. default:
  82. do_hw_reset();
  83. break;
  84. }
  85. }