reset.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * This program is free software; you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License version 2 as published
  4. * by the Free Software Foundation.
  5. *
  6. * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  7. */
  8. #include <linux/init.h>
  9. #include <linux/io.h>
  10. #include <linux/ioport.h>
  11. #include <linux/pm.h>
  12. #include <linux/export.h>
  13. #include <asm/reboot.h>
  14. #include <lantiq_soc.h>
  15. #define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
  16. #define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
  17. /* register definitions */
  18. #define LTQ_RCU_RST 0x0010
  19. #define LTQ_RCU_RST_ALL 0x40000000
  20. #define LTQ_RCU_RST_STAT 0x0014
  21. #define LTQ_RCU_STAT_SHIFT 26
  22. static struct resource ltq_rcu_resource = {
  23. .name = "rcu",
  24. .start = LTQ_RCU_BASE_ADDR,
  25. .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
  26. .flags = IORESOURCE_MEM,
  27. };
  28. /* remapped base addr of the reset control unit */
  29. static void __iomem *ltq_rcu_membase;
  30. /* This function is used by the watchdog driver */
  31. int ltq_reset_cause(void)
  32. {
  33. u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
  34. return val >> LTQ_RCU_STAT_SHIFT;
  35. }
  36. EXPORT_SYMBOL_GPL(ltq_reset_cause);
  37. static void ltq_machine_restart(char *command)
  38. {
  39. pr_notice("System restart\n");
  40. local_irq_disable();
  41. ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
  42. unreachable();
  43. }
  44. static void ltq_machine_halt(void)
  45. {
  46. pr_notice("System halted.\n");
  47. local_irq_disable();
  48. unreachable();
  49. }
  50. static void ltq_machine_power_off(void)
  51. {
  52. pr_notice("Please turn off the power now.\n");
  53. local_irq_disable();
  54. unreachable();
  55. }
  56. static int __init mips_reboot_setup(void)
  57. {
  58. /* insert and request the memory region */
  59. if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
  60. panic("Failed to insert rcu memory");
  61. if (request_mem_region(ltq_rcu_resource.start,
  62. resource_size(&ltq_rcu_resource), "rcu") < 0)
  63. panic("Failed to request rcu memory");
  64. /* remap rcu register range */
  65. ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
  66. resource_size(&ltq_rcu_resource));
  67. if (!ltq_rcu_membase)
  68. panic("Failed to remap rcu memory");
  69. _machine_restart = ltq_machine_restart;
  70. _machine_halt = ltq_machine_halt;
  71. pm_power_off = ltq_machine_power_off;
  72. return 0;
  73. }
  74. arch_initcall(mips_reboot_setup);