pm.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Power Management driver for Marvell Kirkwood SoCs
  3. *
  4. * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
  5. * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License,
  9. * version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/suspend.h>
  18. #include <linux/io.h>
  19. #include <mach/bridge-regs.h>
  20. static void __iomem *ddr_operation_base;
  21. static void kirkwood_low_power(void)
  22. {
  23. u32 mem_pm_ctrl;
  24. mem_pm_ctrl = readl(MEMORY_PM_CTRL);
  25. /* Set peripherals to low-power mode */
  26. writel_relaxed(~0, MEMORY_PM_CTRL);
  27. /* Set DDR in self-refresh */
  28. writel_relaxed(0x7, ddr_operation_base);
  29. /*
  30. * Set CPU in wait-for-interrupt state.
  31. * This disables the CPU core clocks,
  32. * the array clocks, and also the L2 controller.
  33. */
  34. cpu_do_idle();
  35. writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL);
  36. }
  37. static int kirkwood_suspend_enter(suspend_state_t state)
  38. {
  39. switch (state) {
  40. case PM_SUSPEND_STANDBY:
  41. kirkwood_low_power();
  42. break;
  43. default:
  44. return -EINVAL;
  45. }
  46. return 0;
  47. }
  48. static int kirkwood_pm_valid_standby(suspend_state_t state)
  49. {
  50. return state == PM_SUSPEND_STANDBY;
  51. }
  52. static const struct platform_suspend_ops kirkwood_suspend_ops = {
  53. .enter = kirkwood_suspend_enter,
  54. .valid = kirkwood_pm_valid_standby,
  55. };
  56. int __init kirkwood_pm_init(void)
  57. {
  58. ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
  59. suspend_set_ops(&kirkwood_suspend_ops);
  60. return 0;
  61. }