connectTheSignalSlot.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * linux/arch/arm/mach-omap1/pm.c
  3. *
  4. * OMAP Power Management Routines
  5. *
  6. * Original code for the SA11x0:
  7. * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
  8. *
  9. * Modified for the PXA250 by Nicolas Pitre:
  10. * Copyright (c) 2002 Monta Vista Software, Inc.
  11. *
  12. * Modified for the OMAP1510 by David Singleton:
  13. * Copyright (c) 2002 Monta Vista Software, Inc.
  14. *
  15. * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
  16. *
  17. * This program is free software; you can redistribute it and/or modify it
  18. * under the terms of the GNU General Public License as published by the
  19. * Free Software Foundation; either version 2 of the License, or (at your
  20. * option) any later version.
  21. *
  22. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  23. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  25. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  28. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. *
  33. * You should have received a copy of the GNU General Public License along
  34. * with this program; if not, write to the Free Software Foundation, Inc.,
  35. * 675 Mass Ave, Cambridge, MA 02139, USA.
  36. */
  37. #include <linux/suspend.h>
  38. #include <linux/sched.h>
  39. #include <linux/proc_fs.h>
  40. #include <linux/interrupt.h>
  41. #include <linux/sysfs.h>
  42. #include <linux/module.h>
  43. #include <linux/io.h>
  44. #include <linux/atomic.h>
  45. #include <asm/fncpy.h>
  46. #include <asm/system_misc.h>
  47. #include <asm/irq.h>
  48. #include <asm/mach/time.h>
  49. #include <asm/mach/irq.h>
  50. #include <mach/tc.h>
  51. #include <mach/mux.h>
  52. #include <linux/omap-dma.h>
  53. #include <plat/dmtimer.h>
  54. #include <mach/irqs.h>
  55. #include "iomap.h"
  56. #include "clock.h"
  57. #include "pm.h"
  58. #include "sram.h"
  59. static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
  60. static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
  61. static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
  62. static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
  63. static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
  64. static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
  65. #ifdef CONFIG_OMAP_32K_TIMER
  66. static unsigned short enable_dyn_sleep = 1;
  67. static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
  68. char *buf)
  69. {
  70. return sprintf(buf, "%hu\n", enable_dyn_sleep);
  71. }
  72. static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
  73. const char * buf, size_t n)
  74. {
  75. unsigned short value;
  76. if (sscanf(buf, "%hu", &value) != 1 ||
  77. (value != 0 && value != 1)) {
  78. printk(KERN_ERR "idle_sleep_store: Invalid value\n");
  79. return -EINVAL;
  80. }
  81. enable_dyn_sleep = value;
  82. return n;
  83. }
  84. static struct kobj_attribute sleep_while_idle_attr =
  85. __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
  86. #endif
  87. static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
  88. /*
  89. * Let's power down on idle, but only if we are really
  90. * idle, because once we start down the path of
  91. * going idle we continue to do idle even if we get
  92. * a clock tick interrupt . .
  93. */
  94. void omap1_pm_idle(void)
  95. {
  96. extern __u32 arm_idlect1_mask;
  97. __u32 use_idlect1 = arm_idlect1_mask;
  98. int do_sleep = 0;
  99. local_fiq_disable();
  100. #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
  101. #warning Enable 32kHz OS timer in order to allow sleep states in idle
  102. use_idlect1 = use_idlect1 & ~(1 << 9);
  103. #else
  104. while (enable_dyn_sleep) {
  105. #ifdef CONFIG_CBUS_TAHVO_USB
  106. extern int vbus_active;
  107. /* Clock requirements? */
  108. if (vbus_active)
  109. break;
  110. #endif
  111. do_sleep = 1;
  112. break;
  113. }
  114. #endif
  115. #ifdef CONFIG_OMAP_DM_TIMER
  116. use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
  117. #endif
  118. if (omap_dma_running())
  119. use_idlect1 &= ~(1 << 6);
  120. /* We should be able to remove the do_sleep variable and multiple
  121. * tests above as soon as drivers, timer and DMA code have been fixed.
  122. * Even the sleep block count should become obsolete. */
  123. if ((use_idlect1 != ~0) || !do_sleep) {
  124. __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
  125. if (cpu_is_omap15xx())
  126. use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
  127. else
  128. use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
  129. omap_writel(use_idlect1, ARM_IDLECT1);
  130. __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
  131. omap_writel(saved_idlect1, ARM_IDLECT1);
  132. local_fiq_enable();
  133. return;
  134. }
  135. omap_sram_suspend(omap_readl(ARM_IDLECT1),
  136. omap_readl(ARM_IDLECT2));
  137. local_fiq_enable();
  138. }
  139. /*
  140. * Configuration of the wakeup event is board specific. For the
  141. * moment we put it into this helper function. Later it may move
  142. * to board specific files.
  143. */
  144. static void omap_pm_wakeup_setup(void)
  145. {
  146. u32 level1_wake = 0;
  147. u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
  148. /*
  149. * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
  150. * and the L2 wakeup interrupts: keypad and UART2. Note that the
  151. * drivers must still separately call omap_set_gpio_wakeup() to
  152. * wake up to a GPIO interrupt.
  153. */
  154. if (cpu_is_omap7xx())
  155. level1_wake = OMAP_IRQ_BIT(INT_7XX_GPIO_BANK1) |
  156. OMAP_IRQ_BIT(INT_7XX_IH2_IRQ);
  157. else if (cpu_is_omap15xx())
  158. level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
  159. OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
  160. else if (cpu_is_omap16xx())
  161. level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
  162. OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
  163. omap_writel(~level1_wake, OMAP_IH1_MIR);
  164. if (cpu_is_omap7xx()) {
  165. omap_writel(~level2_wake, OMAP_IH2_0_MIR);
  166. omap_writel(~(OMAP_IRQ_BIT(INT_7XX_WAKE_UP_REQ) |
  167. OMAP_IRQ_BIT(INT_7XX_MPUIO_KEYPAD)),
  168. OMAP_IH2_1_MIR);
  169. } else if (cpu_is_omap15xx()) {
  170. level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
  171. omap_writel(~level2_wake, OMAP_IH2_MIR);
  172. } else if (cpu_is_omap16xx()) {
  173. level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
  174. omap_writel(~level2_wake, OMAP_IH2_0_MIR);
  175. /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */