kirkwood-pm.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 "kirkwood.h"
  20. #include "kirkwood-pm.h"
  21. static void __iomem *ddr_operation_base;
  22. static void __iomem *memory_pm_ctrl;
  23. static void kirkwood_low_power(void)
  24. {
  25. u32 mem_pm_ctrl;
  26. mem_pm_ctrl = readl(memory_pm_ctrl);
  27. /* Set peripherals to low-power mode */
  28. writel_relaxed(~0, memory_pm_ctrl);
  29. /* Set DDR in self-refresh */
  30. writel_relaxed(0x7, ddr_operation_base);
  31. /*
  32. * Set CPU in wait-for-interrupt state.
  33. * This disables the CPU core clocks,
  34. * the array clocks, and also the L2 controller.
  35. */
  36. cpu_do_idle();
  37. writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
  38. }
  39. static int kirkwood_suspend_enter(suspend_state_t state)
  40. {
  41. switch (state) {
  42. case PM_SUSPEND_STANDBY:
  43. kirkwood_low_power();
  44. break;
  45. default:
  46. return -EINVAL;
  47. }
  48. return 0;
  49. }
  50. static int kirkwood_pm_valid_standby(suspend_state_t state)
  51. {
  52. return state == PM_SUSPEND_STANDBY;
  53. }
  54. static const struct platform_suspend_ops kirkwood_suspend_ops = {
  55. .enter = kirkwood_suspend_enter,
  56. .valid = kirkwood_pm_valid_standby,
  57. };
  58. void __init kirkwood_pm_init(void)
  59. {
  60. ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
  61. memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
  62. suspend_set_ops(&kirkwood_suspend_ops);
  63. }