reset.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/delay.h>
  5. #include <linux/gpio.h>
  6. #include <linux/io.h>
  7. #include <asm/proc-fns.h>
  8. #include <asm/system_misc.h>
  9. #include "regs-ost.h"
  10. #include "reset.h"
  11. #include "smemc.h"
  12. static void do_hw_reset(void);
  13. static int reset_gpio = -1;
  14. int init_gpio_reset(int gpio, int output, int level)
  15. {
  16. int rc;
  17. rc = gpio_request(gpio, "reset generator");
  18. if (rc) {
  19. printk(KERN_ERR "Can't request reset_gpio\n");
  20. goto out;
  21. }
  22. if (output)
  23. rc = gpio_direction_output(gpio, level);
  24. else
  25. rc = gpio_direction_input(gpio);
  26. if (rc) {
  27. printk(KERN_ERR "Can't configure reset_gpio\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. writel_relaxed(OWER_WME, OWER);
  62. writel_relaxed(OSSR_M3, OSSR);
  63. /* ... in 100 ms */
  64. writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
  65. /*
  66. * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
  67. * we put SDRAM into self-refresh to prevent that
  68. */
  69. while (1)
  70. writel_relaxed(MDREFR_SLFRSH, MDREFR);
  71. }
  72. void pxa_restart(enum reboot_mode mode, const char *cmd)
  73. {
  74. local_irq_disable();
  75. local_fiq_disable();
  76. clear_reset_status(RESET_STATUS_ALL);
  77. switch (mode) {
  78. case REBOOT_SOFT:
  79. /* Jump into ROM at address 0 */
  80. soft_restart(0);
  81. break;
  82. case REBOOT_GPIO:
  83. do_gpio_reset();
  84. break;
  85. case REBOOT_HARD:
  86. default:
  87. do_hw_reset();
  88. break;
  89. }
  90. }