/drivers/staging/tidspbridge/rmgr/pwr.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 176 lines · 121 code · 17 blank · 38 comment · 23 complexity · a6f9d37ef83e67bba08268610eb8d827 MD5 · raw file

  1. /*
  2. * pwr.c
  3. *
  4. * DSP-BIOS Bridge driver support functions for TI OMAP processors.
  5. *
  6. * PWR API for controlling DSP power states.
  7. *
  8. * Copyright (C) 2005-2006 Texas Instruments, Inc.
  9. *
  10. * This package is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  16. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17. */
  18. /* ----------------------------------- Host OS */
  19. #include <dspbridge/host_os.h>
  20. /* ----------------------------------- This */
  21. #include <dspbridge/pwr.h>
  22. /* ----------------------------------- Resource Manager */
  23. #include <dspbridge/devdefs.h>
  24. #include <dspbridge/drv.h>
  25. /* ----------------------------------- Platform Manager */
  26. #include <dspbridge/dev.h>
  27. /* ----------------------------------- Link Driver */
  28. #include <dspbridge/dspioctl.h>
  29. /*
  30. * ======== pwr_sleep_dsp ========
  31. * Send command to DSP to enter sleep state.
  32. */
  33. int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout)
  34. {
  35. struct bridge_drv_interface *intf_fxns;
  36. struct bridge_dev_context *dw_context;
  37. int status = -EPERM;
  38. struct dev_object *hdev_obj = NULL;
  39. u32 ioctlcode = 0;
  40. u32 arg = timeout;
  41. for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  42. hdev_obj != NULL;
  43. hdev_obj =
  44. (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) {
  45. if (dev_get_bridge_context(hdev_obj,
  46. (struct bridge_dev_context **)
  47. &dw_context)) {
  48. continue;
  49. }
  50. if (dev_get_intf_fxns(hdev_obj,
  51. (struct bridge_drv_interface **)
  52. &intf_fxns)) {
  53. continue;
  54. }
  55. if (sleep_code == PWR_DEEPSLEEP)
  56. ioctlcode = BRDIOCTL_DEEPSLEEP;
  57. else if (sleep_code == PWR_EMERGENCYDEEPSLEEP)
  58. ioctlcode = BRDIOCTL_EMERGENCYSLEEP;
  59. else
  60. status = -EINVAL;
  61. if (status != -EINVAL) {
  62. status = (*intf_fxns->dev_cntrl) (dw_context,
  63. ioctlcode,
  64. (void *)&arg);
  65. }
  66. }
  67. return status;
  68. }
  69. /*
  70. * ======== pwr_wake_dsp ========
  71. * Send command to DSP to wake it from sleep.
  72. */
  73. int pwr_wake_dsp(const u32 timeout)
  74. {
  75. struct bridge_drv_interface *intf_fxns;
  76. struct bridge_dev_context *dw_context;
  77. int status = -EPERM;
  78. struct dev_object *hdev_obj = NULL;
  79. u32 arg = timeout;
  80. for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  81. hdev_obj != NULL;
  82. hdev_obj = (struct dev_object *)drv_get_next_dev_object
  83. ((u32) hdev_obj)) {
  84. if (!(dev_get_bridge_context(hdev_obj,
  85. (struct bridge_dev_context
  86. **)&dw_context))) {
  87. if (!(dev_get_intf_fxns(hdev_obj,
  88. (struct bridge_drv_interface **)&intf_fxns))) {
  89. status =
  90. (*intf_fxns->dev_cntrl) (dw_context,
  91. BRDIOCTL_WAKEUP,
  92. (void *)&arg);
  93. }
  94. }
  95. }
  96. return status;
  97. }
  98. /*
  99. * ======== pwr_pm_pre_scale========
  100. * Sends pre-notification message to DSP.
  101. */
  102. int pwr_pm_pre_scale(u16 voltage_domain, u32 level)
  103. {
  104. struct bridge_drv_interface *intf_fxns;
  105. struct bridge_dev_context *dw_context;
  106. int status = -EPERM;
  107. struct dev_object *hdev_obj = NULL;
  108. u32 arg[2];
  109. arg[0] = voltage_domain;
  110. arg[1] = level;
  111. for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  112. hdev_obj != NULL;
  113. hdev_obj = (struct dev_object *)drv_get_next_dev_object
  114. ((u32) hdev_obj)) {
  115. if (!(dev_get_bridge_context(hdev_obj,
  116. (struct bridge_dev_context
  117. **)&dw_context))) {
  118. if (!(dev_get_intf_fxns(hdev_obj,
  119. (struct bridge_drv_interface **)&intf_fxns))) {
  120. status =
  121. (*intf_fxns->dev_cntrl) (dw_context,
  122. BRDIOCTL_PRESCALE_NOTIFY,
  123. (void *)&arg);
  124. }
  125. }
  126. }
  127. return status;
  128. }
  129. /*
  130. * ======== pwr_pm_post_scale========
  131. * Sends post-notification message to DSP.
  132. */
  133. int pwr_pm_post_scale(u16 voltage_domain, u32 level)
  134. {
  135. struct bridge_drv_interface *intf_fxns;
  136. struct bridge_dev_context *dw_context;
  137. int status = -EPERM;
  138. struct dev_object *hdev_obj = NULL;
  139. u32 arg[2];
  140. arg[0] = voltage_domain;
  141. arg[1] = level;
  142. for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  143. hdev_obj != NULL;
  144. hdev_obj = (struct dev_object *)drv_get_next_dev_object
  145. ((u32) hdev_obj)) {
  146. if (!(dev_get_bridge_context(hdev_obj,
  147. (struct bridge_dev_context
  148. **)&dw_context))) {
  149. if (!(dev_get_intf_fxns(hdev_obj,
  150. (struct bridge_drv_interface **)&intf_fxns))) {
  151. status =
  152. (*intf_fxns->dev_cntrl) (dw_context,
  153. BRDIOCTL_POSTSCALE_NOTIFY,
  154. (void *)&arg);
  155. }
  156. }
  157. }
  158. return status;
  159. }