reset.c 1.7 KB

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