Commit 92105bb70634abacc08bbe12bf6f888fbd7dad38

Authored by Tony Lindgren
Committed by Russell King
1 parent 7efb833d64

[ARM] 2887/1: OMAP 2/4: Update files common to omap1 and omap2, take 2

Patch from Tony Lindgren

This patch syncs the mainline kernel with linux-omap tree.
The highlights of the patch are:
- Clock updates by Tuukka Tikkanen, Juha Yrjola,
  Daniel Petrini and Tony Lindgren
- DMA fixes by Imre Deak, Juha Yrjola and Daniel Petrini
- Add support to dual-mode hardware timers by Lauri Leukkunen
- GPIO support for 24xx by Paul Mundt
- GPIO wake-up support by Tony Lindgren
- Better GPIO interrupt handler to not lose interrupts by
  Ralph Walden and Ladislav Michl
- Power Management updates by Tuukka Tikkanen
- Make Power Management code use new SRAM functions by
  Tony Lindgren

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 16 changed files with 1115 additions and 307 deletions Side-by-side Diff

arch/arm/plat-omap/Kconfig
... ... @@ -91,6 +91,13 @@
91 91 Kernel internal timer frequency should be a divisor of 32768,
92 92 such as 64 or 128.
93 93  
  94 +config OMAP_DM_TIMER
  95 + bool "Use dual-mode timer"
  96 + default n
  97 + depends on ARCH_OMAP16XX
  98 + help
  99 + Select this option if you want to use OMAP Dual-Mode timers.
  100 +
94 101 choice
95 102 prompt "Low-level debug console UART"
96 103 depends on ARCH_OMAP
... ... @@ -106,6 +113,15 @@
106 113 bool "UART3"
107 114  
108 115 endchoice
  116 +
  117 +config OMAP_SERIAL_WAKE
  118 + bool "Enable wake-up events for serial ports"
  119 + depends OMAP_MUX
  120 + default y
  121 + help
  122 + Select this option if you want to have your system wake up
  123 + to data on the serial RX line. This allows you to wake the
  124 + system from serial console.
109 125  
110 126 endmenu
111 127  
arch/arm/plat-omap/Makefile
... ... @@ -3,7 +3,7 @@
3 3 #
4 4  
5 5 # Common support
6   -obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o
  6 +obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
7 7 obj-m :=
8 8 obj-n :=
9 9 obj- :=
... ... @@ -15,4 +15,5 @@
15 15 obj-$(CONFIG_PM) += pm.o sleep.o
16 16  
17 17 obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
  18 +obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
arch/arm/plat-omap/clock.c
... ... @@ -21,6 +21,7 @@
21 21 #include <asm/arch/usb.h>
22 22  
23 23 #include "clock.h"
  24 +#include "sram.h"
24 25  
25 26 static LIST_HEAD(clocks);
26 27 static DECLARE_MUTEX(clocks_sem);
... ... @@ -141,7 +142,7 @@
141 142 static struct clk armper_ck = {
142 143 .name = "armper_ck",
143 144 .parent = &ck_dpll1,
144   - .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
  145 + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
145 146 RATE_CKCTL,
146 147 .enable_reg = ARM_IDLECT2,
147 148 .enable_bit = EN_PERCK,
... ... @@ -385,7 +386,8 @@
385 386 .name = "uart2_ck",
386 387 /* Direct from ULPD, no parent */
387 388 .rate = 12000000,
388   - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT,
  389 + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT |
  390 + ALWAYS_ENABLED,
389 391 .enable_reg = MOD_CONF_CTRL_0,
390 392 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
391 393 .set_rate = &set_uart_rate,
... ... @@ -443,6 +445,15 @@
443 445 .enable_bit = 8 /* UHOST_EN */,
444 446 };
445 447  
  448 +static struct clk usb_dc_ck = {
  449 + .name = "usb_dc_ck",
  450 + /* Direct from ULPD, no parent */
  451 + .rate = 48000000,
  452 + .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
  453 + .enable_reg = SOFT_REQ_REG,
  454 + .enable_bit = 4,
  455 +};
  456 +
446 457 static struct clk mclk_1510 = {
447 458 .name = "mclk",
448 459 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
... ... @@ -552,6 +563,7 @@
552 563 &uart3_16xx,
553 564 &usb_clko,
554 565 &usb_hhc_ck1510, &usb_hhc_ck16xx,
  566 + &usb_dc_ck,
555 567 &mclk_1510, &mclk_16xx,
556 568 &bclk_1510, &bclk_16xx,
557 569 &mmc1_ck,
558 570  
... ... @@ -946,14 +958,13 @@
946 958 if (!ptr->rate)
947 959 return -EINVAL;
948 960  
949   - if (!ptr->rate)
950   - return -EINVAL;
  961 + /*
  962 + * In most cases we should not need to reprogram DPLL.
  963 + * Reprogramming the DPLL is tricky, it must be done from SRAM.
  964 + */
  965 + omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
951 966  
952   - if (unlikely(ck_dpll1.rate == 0)) {
953   - omap_writew(ptr->dpllctl_val, DPLL_CTL);
954   - ck_dpll1.rate = ptr->pll_rate;
955   - }
956   - omap_writew(ptr->ckctl_val, ARM_CKCTL);
  967 + ck_dpll1.rate = ptr->pll_rate;
957 968 propagate_rate(&ck_dpll1);
958 969 return 0;
959 970 }
960 971  
... ... @@ -1224,9 +1235,11 @@
1224 1235 #endif
1225 1236 /* Cache rates for clocks connected to ck_ref (not dpll1) */
1226 1237 propagate_rate(&ck_ref);
1227   - printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n",
  1238 + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
  1239 + "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
1228 1240 ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
1229   - ck_dpll1.rate, arm_ck.rate);
  1241 + ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
  1242 + arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
1230 1243  
1231 1244 #ifdef CONFIG_MACH_OMAP_PERSEUS2
1232 1245 /* Select slicer output as OMAP input clock */
... ... @@ -1271,7 +1284,9 @@
1271 1284 struct clk *p;
1272 1285 __u32 regval32;
1273 1286  
1274   - omap_writew(0, SOFT_REQ_REG);
  1287 + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
  1288 + regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
  1289 + omap_writew(regval32, SOFT_REQ_REG);
1275 1290 omap_writew(0, SOFT_REQ_REG2);
1276 1291  
1277 1292 list_for_each_entry(p, &clocks, node) {
arch/arm/plat-omap/common.c
... ... @@ -26,6 +26,7 @@
26 26 #include <asm/hardware/clock.h>
27 27 #include <asm/io.h>
28 28 #include <asm/mach-types.h>
  29 +#include <asm/setup.h>
29 30  
30 31 #include <asm/arch/board.h>
31 32 #include <asm/arch/mux.h>
32 33  
... ... @@ -35,11 +36,11 @@
35 36  
36 37 #define NO_LENGTH_CHECK 0xffffffff
37 38  
38   -extern int omap_bootloader_tag_len;
39   -extern u8 omap_bootloader_tag[];
  39 +unsigned char omap_bootloader_tag[512];
  40 +int omap_bootloader_tag_len;
40 41  
41 42 struct omap_board_config_kernel *omap_board_config;
42   -int omap_board_config_size = 0;
  43 +int omap_board_config_size;
43 44  
44 45 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
45 46 {
arch/arm/plat-omap/dma.c
... ... @@ -425,7 +425,7 @@
425 425 dma_chan[ch + 6].saved_csr = csr >> 7;
426 426 csr &= 0x7f;
427 427 }
428   - if (!csr)
  428 + if ((csr & 0x3f) == 0)
429 429 return 0;
430 430 if (unlikely(dma_chan[ch].dev_id == -1)) {
431 431 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
432 432  
... ... @@ -890,11 +890,11 @@
890 890 w |= 1 << 8;
891 891 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
892 892  
  893 + lcd_dma.active = 1;
  894 +
893 895 w = omap_readw(OMAP1610_DMA_LCD_CCR);
894 896 w |= 1 << 7;
895 897 omap_writew(w, OMAP1610_DMA_LCD_CCR);
896   -
897   - lcd_dma.active = 1;
898 898 }
899 899  
900 900 void omap_setup_lcd_dma(void)
... ... @@ -965,8 +965,8 @@
965 965 */
966 966 dma_addr_t omap_get_dma_src_pos(int lch)
967 967 {
968   - return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
969   - (OMAP_DMA_CSSA_U(lch) << 16));
  968 + return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) |
  969 + (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16));
970 970 }
971 971  
972 972 /*
973 973  
... ... @@ -979,10 +979,20 @@
979 979 */
980 980 dma_addr_t omap_get_dma_dst_pos(int lch)
981 981 {
982   - return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
983   - (OMAP_DMA_CDSA_U(lch) << 16));
  982 + return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) |
  983 + (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16));
984 984 }
985 985  
  986 +/*
  987 + * Returns current source transfer counting for the given DMA channel.
  988 + * Can be used to monitor the progress of a transfer inside a block.
  989 + * It must be called with disabled interrupts.
  990 + */
  991 +int omap_get_dma_src_addr_counter(int lch)
  992 +{
  993 + return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch));
  994 +}
  995 +
986 996 int omap_dma_running(void)
987 997 {
988 998 int lch;
... ... @@ -1076,6 +1086,7 @@
1076 1086  
1077 1087 EXPORT_SYMBOL(omap_get_dma_src_pos);
1078 1088 EXPORT_SYMBOL(omap_get_dma_dst_pos);
  1089 +EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
1079 1090 EXPORT_SYMBOL(omap_clear_dma);
1080 1091 EXPORT_SYMBOL(omap_set_dma_priority);
1081 1092 EXPORT_SYMBOL(omap_request_dma);
arch/arm/plat-omap/dmtimer.c
  1 +/*
  2 + * linux/arch/arm/plat-omap/dmtimer.c
  3 + *
  4 + * OMAP Dual-Mode Timers
  5 + *
  6 + * Copyright (C) 2005 Nokia Corporation
  7 + * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify it
  10 + * under the terms of the GNU General Public License as published by the
  11 + * Free Software Foundation; either version 2 of the License, or (at your
  12 + * option) any later version.
  13 + *
  14 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  15 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  16 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  17 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22 + *
  23 + * You should have received a copy of the GNU General Public License along
  24 + * with this program; if not, write to the Free Software Foundation, Inc.,
  25 + * 675 Mass Ave, Cambridge, MA 02139, USA.
  26 + */
  27 +
  28 +#include <linux/init.h>
  29 +#include <asm/arch/hardware.h>
  30 +#include <asm/arch/dmtimer.h>
  31 +#include <asm/io.h>
  32 +#include <asm/arch/irqs.h>
  33 +#include <linux/spinlock.h>
  34 +#include <linux/list.h>
  35 +
  36 +#define OMAP_TIMER_COUNT 8
  37 +
  38 +#define OMAP_TIMER_ID_REG 0x00
  39 +#define OMAP_TIMER_OCP_CFG_REG 0x10
  40 +#define OMAP_TIMER_SYS_STAT_REG 0x14
  41 +#define OMAP_TIMER_STAT_REG 0x18
  42 +#define OMAP_TIMER_INT_EN_REG 0x1c
  43 +#define OMAP_TIMER_WAKEUP_EN_REG 0x20
  44 +#define OMAP_TIMER_CTRL_REG 0x24
  45 +#define OMAP_TIMER_COUNTER_REG 0x28
  46 +#define OMAP_TIMER_LOAD_REG 0x2c
  47 +#define OMAP_TIMER_TRIGGER_REG 0x30
  48 +#define OMAP_TIMER_WRITE_PEND_REG 0x34
  49 +#define OMAP_TIMER_MATCH_REG 0x38
  50 +#define OMAP_TIMER_CAPTURE_REG 0x3c
  51 +#define OMAP_TIMER_IF_CTRL_REG 0x40
  52 +
  53 +
  54 +static struct dmtimer_info_struct {
  55 + struct list_head unused_timers;
  56 + struct list_head reserved_timers;
  57 +} dm_timer_info;
  58 +
  59 +static struct omap_dm_timer dm_timers[] = {
  60 + { .base=0xfffb1400, .irq=INT_1610_GPTIMER1 },
  61 + { .base=0xfffb1c00, .irq=INT_1610_GPTIMER2 },
  62 + { .base=0xfffb2400, .irq=INT_1610_GPTIMER3 },
  63 + { .base=0xfffb2c00, .irq=INT_1610_GPTIMER4 },
  64 + { .base=0xfffb3400, .irq=INT_1610_GPTIMER5 },
  65 + { .base=0xfffb3c00, .irq=INT_1610_GPTIMER6 },
  66 + { .base=0xfffb4400, .irq=INT_1610_GPTIMER7 },
  67 + { .base=0xfffb4c00, .irq=INT_1610_GPTIMER8 },
  68 + { .base=0x0 },
  69 +};
  70 +
  71 +
  72 +static spinlock_t dm_timer_lock;
  73 +
  74 +
  75 +inline void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
  76 +{
  77 + omap_writel(value, timer->base + reg);
  78 + while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
  79 + ;
  80 +}
  81 +
  82 +u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
  83 +{
  84 + return omap_readl(timer->base + reg);
  85 +}
  86 +
  87 +int omap_dm_timers_active(void)
  88 +{
  89 + struct omap_dm_timer *timer;
  90 +
  91 + for (timer = &dm_timers[0]; timer->base; ++timer)
  92 + if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
  93 + OMAP_TIMER_CTRL_ST)
  94 + return 1;
  95 +
  96 + return 0;
  97 +}
  98 +
  99 +
  100 +void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
  101 +{
  102 + int n = (timer - dm_timers) << 1;
  103 + u32 l;
  104 +
  105 + l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
  106 + l |= source << n;
  107 + omap_writel(l, MOD_CONF_CTRL_1);
  108 +}
  109 +
  110 +
  111 +static void omap_dm_timer_reset(struct omap_dm_timer *timer)
  112 +{
  113 + /* Reset and set posted mode */
  114 + omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
  115 + omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, 0x02);
  116 +
  117 + omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_ARMXOR);
  118 +}
  119 +
  120 +
  121 +
  122 +struct omap_dm_timer * omap_dm_timer_request(void)
  123 +{
  124 + struct omap_dm_timer *timer = NULL;
  125 + unsigned long flags;
  126 +
  127 + spin_lock_irqsave(&dm_timer_lock, flags);
  128 + if (!list_empty(&dm_timer_info.unused_timers)) {
  129 + timer = (struct omap_dm_timer *)
  130 + dm_timer_info.unused_timers.next;
  131 + list_move_tail((struct list_head *)timer,
  132 + &dm_timer_info.reserved_timers);
  133 + }
  134 + spin_unlock_irqrestore(&dm_timer_lock, flags);
  135 +
  136 + return timer;
  137 +}
  138 +
  139 +
  140 +void omap_dm_timer_free(struct omap_dm_timer *timer)
  141 +{
  142 + unsigned long flags;
  143 +
  144 + omap_dm_timer_reset(timer);
  145 +
  146 + spin_lock_irqsave(&dm_timer_lock, flags);
  147 + list_move_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
  148 + spin_unlock_irqrestore(&dm_timer_lock, flags);
  149 +}
  150 +
  151 +void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
  152 + unsigned int value)
  153 +{
  154 + omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
  155 +}
  156 +
  157 +unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
  158 +{
  159 + return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
  160 +}
  161 +
  162 +void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
  163 +{
  164 + omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
  165 +}
  166 +
  167 +void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer)
  168 +{
  169 + u32 l;
  170 + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
  171 + l |= OMAP_TIMER_CTRL_AR;
  172 + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
  173 +}
  174 +
  175 +void omap_dm_timer_trigger(struct omap_dm_timer *timer)
  176 +{
  177 + omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1);
  178 +}
  179 +
  180 +void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value)
  181 +{
  182 + u32 l;
  183 +
  184 + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
  185 + l |= value & 0x3;
  186 + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
  187 +}
  188 +
  189 +void omap_dm_timer_start(struct omap_dm_timer *timer)
  190 +{
  191 + u32 l;
  192 +
  193 + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
  194 + l |= OMAP_TIMER_CTRL_ST;
  195 + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
  196 +}
  197 +
  198 +void omap_dm_timer_stop(struct omap_dm_timer *timer)
  199 +{
  200 + u32 l;
  201 +
  202 + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
  203 + l &= ~0x1;
  204 + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
  205 +}
  206 +
  207 +unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
  208 +{
  209 + return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
  210 +}
  211 +
  212 +void omap_dm_timer_reset_counter(struct omap_dm_timer *timer)
  213 +{
  214 + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 0);
  215 +}
  216 +
  217 +void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load)
  218 +{
  219 + omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
  220 +}
  221 +
  222 +void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match)
  223 +{
  224 + omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
  225 +}
  226 +
  227 +void omap_dm_timer_enable_compare(struct omap_dm_timer *timer)
  228 +{
  229 + u32 l;
  230 +
  231 + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
  232 + l |= OMAP_TIMER_CTRL_CE;
  233 + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
  234 +}
  235 +
  236 +
  237 +static inline void __dm_timer_init(void)
  238 +{
  239 + struct omap_dm_timer *timer;
  240 +
  241 + spin_lock_init(&dm_timer_lock);
  242 + INIT_LIST_HEAD(&dm_timer_info.unused_timers);
  243 + INIT_LIST_HEAD(&dm_timer_info.reserved_timers);
  244 +
  245 + timer = &dm_timers[0];
  246 + while (timer->base) {
  247 + list_add_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
  248 + omap_dm_timer_reset(timer);
  249 + timer++;
  250 + }
  251 +}
  252 +
  253 +static int __init omap_dm_timer_init(void)
  254 +{
  255 + if (cpu_is_omap16xx())
  256 + __dm_timer_init();
  257 + return 0;
  258 +}
  259 +
  260 +arch_initcall(omap_dm_timer_init);
arch/arm/plat-omap/gpio.c
... ... @@ -3,7 +3,7 @@
3 3 *
4 4 * Support functions for OMAP GPIO
5 5 *
6   - * Copyright (C) 2003 Nokia Corporation
  6 + * Copyright (C) 2003-2005 Nokia Corporation
7 7 * Written by Juha Yrjรถlรค <juha.yrjola@nokia.com>
8 8 *
9 9 * This program is free software; you can redistribute it and/or modify
10 10  
... ... @@ -17,8 +17,11 @@
17 17 #include <linux/sched.h>
18 18 #include <linux/interrupt.h>
19 19 #include <linux/ptrace.h>
  20 +#include <linux/sysdev.h>
  21 +#include <linux/err.h>
20 22  
21 23 #include <asm/hardware.h>
  24 +#include <asm/hardware/clock.h>
22 25 #include <asm/irq.h>
23 26 #include <asm/arch/irqs.h>
24 27 #include <asm/arch/gpio.h>
... ... @@ -29,7 +32,7 @@
29 32 /*
30 33 * OMAP1510 GPIO registers
31 34 */
32   -#define OMAP1510_GPIO_BASE 0xfffce000
  35 +#define OMAP1510_GPIO_BASE (void __iomem *)0xfffce000
33 36 #define OMAP1510_GPIO_DATA_INPUT 0x00
34 37 #define OMAP1510_GPIO_DATA_OUTPUT 0x04
35 38 #define OMAP1510_GPIO_DIR_CONTROL 0x08
36 39  
37 40  
38 41  
39 42  
... ... @@ -43,34 +46,37 @@
43 46 /*
44 47 * OMAP1610 specific GPIO registers
45 48 */
46   -#define OMAP1610_GPIO1_BASE 0xfffbe400
47   -#define OMAP1610_GPIO2_BASE 0xfffbec00
48   -#define OMAP1610_GPIO3_BASE 0xfffbb400
49   -#define OMAP1610_GPIO4_BASE 0xfffbbc00
  49 +#define OMAP1610_GPIO1_BASE (void __iomem *)0xfffbe400
  50 +#define OMAP1610_GPIO2_BASE (void __iomem *)0xfffbec00
  51 +#define OMAP1610_GPIO3_BASE (void __iomem *)0xfffbb400
  52 +#define OMAP1610_GPIO4_BASE (void __iomem *)0xfffbbc00
50 53 #define OMAP1610_GPIO_REVISION 0x0000
51 54 #define OMAP1610_GPIO_SYSCONFIG 0x0010
52 55 #define OMAP1610_GPIO_SYSSTATUS 0x0014
53 56 #define OMAP1610_GPIO_IRQSTATUS1 0x0018
54 57 #define OMAP1610_GPIO_IRQENABLE1 0x001c
  58 +#define OMAP1610_GPIO_WAKEUPENABLE 0x0028
55 59 #define OMAP1610_GPIO_DATAIN 0x002c
56 60 #define OMAP1610_GPIO_DATAOUT 0x0030
57 61 #define OMAP1610_GPIO_DIRECTION 0x0034
58 62 #define OMAP1610_GPIO_EDGE_CTRL1 0x0038
59 63 #define OMAP1610_GPIO_EDGE_CTRL2 0x003c
60 64 #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
  65 +#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8
61 66 #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
62 67 #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
  68 +#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8
63 69 #define OMAP1610_GPIO_SET_DATAOUT 0x00f0
64 70  
65 71 /*
66 72 * OMAP730 specific GPIO registers
67 73 */
68   -#define OMAP730_GPIO1_BASE 0xfffbc000
69   -#define OMAP730_GPIO2_BASE 0xfffbc800
70   -#define OMAP730_GPIO3_BASE 0xfffbd000
71   -#define OMAP730_GPIO4_BASE 0xfffbd800
72   -#define OMAP730_GPIO5_BASE 0xfffbe000
73   -#define OMAP730_GPIO6_BASE 0xfffbe800
  74 +#define OMAP730_GPIO1_BASE (void __iomem *)0xfffbc000
  75 +#define OMAP730_GPIO2_BASE (void __iomem *)0xfffbc800
  76 +#define OMAP730_GPIO3_BASE (void __iomem *)0xfffbd000
  77 +#define OMAP730_GPIO4_BASE (void __iomem *)0xfffbd800
  78 +#define OMAP730_GPIO5_BASE (void __iomem *)0xfffbe000
  79 +#define OMAP730_GPIO6_BASE (void __iomem *)0xfffbe800
74 80 #define OMAP730_GPIO_DATA_INPUT 0x00
75 81 #define OMAP730_GPIO_DATA_OUTPUT 0x04
76 82 #define OMAP730_GPIO_DIR_CONTROL 0x08
77 83  
78 84  
79 85  
... ... @@ -78,14 +84,43 @@
78 84 #define OMAP730_GPIO_INT_MASK 0x10
79 85 #define OMAP730_GPIO_INT_STATUS 0x14
80 86  
  87 +/*
  88 + * omap24xx specific GPIO registers
  89 + */
  90 +#define OMAP24XX_GPIO1_BASE (void __iomem *)0x48018000
  91 +#define OMAP24XX_GPIO2_BASE (void __iomem *)0x4801a000
  92 +#define OMAP24XX_GPIO3_BASE (void __iomem *)0x4801c000
  93 +#define OMAP24XX_GPIO4_BASE (void __iomem *)0x4801e000
  94 +#define OMAP24XX_GPIO_REVISION 0x0000
  95 +#define OMAP24XX_GPIO_SYSCONFIG 0x0010
  96 +#define OMAP24XX_GPIO_SYSSTATUS 0x0014
  97 +#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
  98 +#define OMAP24XX_GPIO_IRQENABLE1 0x001c
  99 +#define OMAP24XX_GPIO_CTRL 0x0030
  100 +#define OMAP24XX_GPIO_OE 0x0034
  101 +#define OMAP24XX_GPIO_DATAIN 0x0038
  102 +#define OMAP24XX_GPIO_DATAOUT 0x003c
  103 +#define OMAP24XX_GPIO_LEVELDETECT0 0x0040
  104 +#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
  105 +#define OMAP24XX_GPIO_RISINGDETECT 0x0048
  106 +#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
  107 +#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
  108 +#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
  109 +#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
  110 +#define OMAP24XX_GPIO_SETWKUENA 0x0084
  111 +#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
  112 +#define OMAP24XX_GPIO_SETDATAOUT 0x0094
  113 +
81 114 #define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
82 115  
83 116 struct gpio_bank {
84   - u32 base;
  117 + void __iomem *base;
85 118 u16 irq;
86 119 u16 virtual_irq_start;
87   - u8 method;
  120 + int method;
88 121 u32 reserved_map;
  122 + u32 suspend_wakeup;
  123 + u32 saved_wakeup;
89 124 spinlock_t lock;
90 125 };
91 126  
92 127  
... ... @@ -93,8 +128,9 @@
93 128 #define METHOD_GPIO_1510 1
94 129 #define METHOD_GPIO_1610 2
95 130 #define METHOD_GPIO_730 3
  131 +#define METHOD_GPIO_24XX 4
96 132  
97   -#if defined(CONFIG_ARCH_OMAP16XX)
  133 +#ifdef CONFIG_ARCH_OMAP16XX
98 134 static struct gpio_bank gpio_bank_1610[5] = {
99 135 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
100 136 { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
... ... @@ -123,6 +159,15 @@
123 159 };
124 160 #endif
125 161  
  162 +#ifdef CONFIG_ARCH_OMAP24XX
  163 +static struct gpio_bank gpio_bank_24xx[4] = {
  164 + { OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX },
  165 + { OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX },
  166 + { OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX },
  167 + { OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX },
  168 +};
  169 +#endif
  170 +
126 171 static struct gpio_bank *gpio_bank;
127 172 static int gpio_bank_count;
128 173  
129 174  
130 175  
... ... @@ -149,14 +194,23 @@
149 194 return &gpio_bank[1 + (gpio >> 5)];
150 195 }
151 196 #endif
  197 +#ifdef CONFIG_ARCH_OMAP24XX
  198 + if (cpu_is_omap24xx())
  199 + return &gpio_bank[gpio >> 5];
  200 +#endif
152 201 }
153 202  
154 203 static inline int get_gpio_index(int gpio)
155 204 {
  205 +#ifdef CONFIG_ARCH_OMAP730
156 206 if (cpu_is_omap730())
157 207 return gpio & 0x1f;
158   - else
159   - return gpio & 0x0f;
  208 +#endif
  209 +#ifdef CONFIG_ARCH_OMAP24XX
  210 + if (cpu_is_omap24xx())
  211 + return gpio & 0x1f;
  212 +#endif
  213 + return gpio & 0x0f;
160 214 }
161 215  
162 216 static inline int gpio_valid(int gpio)
... ... @@ -180,6 +234,10 @@
180 234 if (cpu_is_omap730() && gpio < 192)
181 235 return 0;
182 236 #endif
  237 +#ifdef CONFIG_ARCH_OMAP24XX
  238 + if (cpu_is_omap24xx() && gpio < 128)
  239 + return 0;
  240 +#endif
183 241 return -1;
184 242 }
185 243  
... ... @@ -195,7 +253,7 @@
195 253  
196 254 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
197 255 {
198   - u32 reg = bank->base;
  256 + void __iomem *reg = bank->base;
199 257 u32 l;
200 258  
201 259 switch (bank->method) {
... ... @@ -211,6 +269,9 @@
211 269 case METHOD_GPIO_730:
212 270 reg += OMAP730_GPIO_DIR_CONTROL;
213 271 break;
  272 + case METHOD_GPIO_24XX:
  273 + reg += OMAP24XX_GPIO_OE;
  274 + break;
214 275 }
215 276 l = __raw_readl(reg);
216 277 if (is_input)
... ... @@ -234,7 +295,7 @@
234 295  
235 296 static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
236 297 {
237   - u32 reg = bank->base;
  298 + void __iomem *reg = bank->base;
238 299 u32 l = 0;
239 300  
240 301 switch (bank->method) {
... ... @@ -269,6 +330,13 @@
269 330 else
270 331 l &= ~(1 << gpio);
271 332 break;
  333 + case METHOD_GPIO_24XX:
  334 + if (enable)
  335 + reg += OMAP24XX_GPIO_SETDATAOUT;
  336 + else
  337 + reg += OMAP24XX_GPIO_CLEARDATAOUT;
  338 + l = 1 << gpio;
  339 + break;
272 340 default:
273 341 BUG();
274 342 return;
... ... @@ -291,7 +359,7 @@
291 359 int omap_get_gpio_datain(int gpio)
292 360 {
293 361 struct gpio_bank *bank;
294   - u32 reg;
  362 + void __iomem *reg;
295 363  
296 364 if (check_gpio(gpio) < 0)
297 365 return -1;
298 366  
299 367  
300 368  
301 369  
302 370  
303 371  
304 372  
305 373  
306 374  
307 375  
308 376  
309 377  
310 378  
311 379  
312 380  
313 381  
314 382  
315 383  
316 384  
317 385  
318 386  
319 387  
320 388  
321 389  
322 390  
323 391  
324 392  
... ... @@ -310,109 +378,132 @@
310 378 case METHOD_GPIO_730:
311 379 reg += OMAP730_GPIO_DATA_INPUT;
312 380 break;
  381 + case METHOD_GPIO_24XX:
  382 + reg += OMAP24XX_GPIO_DATAIN;
  383 + break;
313 384 default:
314 385 BUG();
315 386 return -1;
316 387 }
317   - return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
  388 + return (__raw_readl(reg)
  389 + & (1 << get_gpio_index(gpio))) != 0;
318 390 }
319 391  
320   -static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
  392 +#define MOD_REG_BIT(reg, bit_mask, set) \
  393 +do { \
  394 + int l = __raw_readl(base + reg); \
  395 + if (set) l |= bit_mask; \
  396 + else l &= ~bit_mask; \
  397 + __raw_writel(l, base + reg); \
  398 +} while(0)
  399 +
  400 +static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger)
321 401 {
322   - u32 reg = bank->base;
323   - u32 l;
  402 + u32 gpio_bit = 1 << gpio;
324 403  
  404 + MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
  405 + trigger & IRQT_LOW);
  406 + MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
  407 + trigger & IRQT_HIGH);
  408 + MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
  409 + trigger & IRQT_RISING);
  410 + MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
  411 + trigger & IRQT_FALLING);
  412 + /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
  413 + * triggering requested. */
  414 +}
  415 +
  416 +static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
  417 +{
  418 + void __iomem *reg = bank->base;
  419 + u32 l = 0;
  420 +
325 421 switch (bank->method) {
326 422 case METHOD_MPUIO:
327 423 reg += OMAP_MPUIO_GPIO_INT_EDGE;
328 424 l = __raw_readl(reg);
329   - if (edge == OMAP_GPIO_RISING_EDGE)
  425 + if (trigger == IRQT_RISING)
330 426 l |= 1 << gpio;
331   - else
  427 + else if (trigger == IRQT_FALLING)
332 428 l &= ~(1 << gpio);
333   - __raw_writel(l, reg);
  429 + else
  430 + goto bad;
334 431 break;
335 432 case METHOD_GPIO_1510:
336 433 reg += OMAP1510_GPIO_INT_CONTROL;
337 434 l = __raw_readl(reg);
338   - if (edge == OMAP_GPIO_RISING_EDGE)
  435 + if (trigger == IRQT_RISING)
339 436 l |= 1 << gpio;
340   - else
  437 + else if (trigger == IRQT_FALLING)
341 438 l &= ~(1 << gpio);
342   - __raw_writel(l, reg);
  439 + else
  440 + goto bad;
343 441 break;
344 442 case METHOD_GPIO_1610:
345   - edge &= 0x03;
346 443 if (gpio & 0x08)
347 444 reg += OMAP1610_GPIO_EDGE_CTRL2;
348 445 else
349 446 reg += OMAP1610_GPIO_EDGE_CTRL1;
350 447 gpio &= 0x07;
  448 + /* We allow only edge triggering, i.e. two lowest bits */
  449 + if (trigger & ~IRQT_BOTHEDGE)
  450 + BUG();
  451 + /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
  452 + trigger &= 0x03;
351 453 l = __raw_readl(reg);
352 454 l &= ~(3 << (gpio << 1));
353   - l |= edge << (gpio << 1);
354   - __raw_writel(l, reg);
  455 + l |= trigger << (gpio << 1);
355 456 break;
356 457 case METHOD_GPIO_730:
357 458 reg += OMAP730_GPIO_INT_CONTROL;
358 459 l = __raw_readl(reg);
359   - if (edge == OMAP_GPIO_RISING_EDGE)
  460 + if (trigger == IRQT_RISING)
360 461 l |= 1 << gpio;
361   - else
  462 + else if (trigger == IRQT_FALLING)
362 463 l &= ~(1 << gpio);
363   - __raw_writel(l, reg);
  464 + else
  465 + goto bad;
364 466 break;
  467 + case METHOD_GPIO_24XX:
  468 + set_24xx_gpio_triggering(reg, gpio, trigger);
  469 + break;
365 470 default:
366 471 BUG();
367   - return;
  472 + goto bad;
368 473 }
  474 + __raw_writel(l, reg);
  475 + return 0;
  476 +bad:
  477 + return -EINVAL;
369 478 }
370 479  
371   -void omap_set_gpio_edge_ctrl(int gpio, int edge)
  480 +static int gpio_irq_type(unsigned irq, unsigned type)
372 481 {
373 482 struct gpio_bank *bank;
  483 + unsigned gpio;
  484 + int retval;
374 485  
  486 + if (irq > IH_MPUIO_BASE)
  487 + gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
  488 + else
  489 + gpio = irq - IH_GPIO_BASE;
  490 +
375 491 if (check_gpio(gpio) < 0)
376   - return;
  492 + return -EINVAL;
  493 +
  494 + if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
  495 + return -EINVAL;
  496 +
377 497 bank = get_gpio_bank(gpio);
378 498 spin_lock(&bank->lock);
379   - _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge);
  499 + retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
380 500 spin_unlock(&bank->lock);
  501 + return retval;
381 502 }
382 503  
383   -
384   -static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
385   -{
386   - u32 reg = bank->base, l;
387   -
388   - switch (bank->method) {
389   - case METHOD_MPUIO:
390   - l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
391   - return (l & (1 << gpio)) ?
392   - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
393   - case METHOD_GPIO_1510:
394   - l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
395   - return (l & (1 << gpio)) ?
396   - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
397   - case METHOD_GPIO_1610:
398   - if (gpio & 0x08)
399   - reg += OMAP1610_GPIO_EDGE_CTRL2;
400   - else
401   - reg += OMAP1610_GPIO_EDGE_CTRL1;
402   - return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
403   - case METHOD_GPIO_730:
404   - l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
405   - return (l & (1 << gpio)) ?
406   - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
407   - default:
408   - BUG();
409   - return -1;
410   - }
411   -}
412   -
413 504 static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
414 505 {
415   - u32 reg = bank->base;
  506 + void __iomem *reg = bank->base;
416 507  
417 508 switch (bank->method) {
418 509 case METHOD_MPUIO:
... ... @@ -428,6 +519,9 @@
428 519 case METHOD_GPIO_730:
429 520 reg += OMAP730_GPIO_INT_STATUS;
430 521 break;
  522 + case METHOD_GPIO_24XX:
  523 + reg += OMAP24XX_GPIO_IRQSTATUS1;
  524 + break;
431 525 default:
432 526 BUG();
433 527 return;
... ... @@ -442,7 +536,7 @@
442 536  
443 537 static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
444 538 {
445   - u32 reg = bank->base;
  539 + void __iomem *reg = bank->base;
446 540 u32 l;
447 541  
448 542 switch (bank->method) {
... ... @@ -477,6 +571,13 @@
477 571 else
478 572 l |= gpio_mask;
479 573 break;
  574 + case METHOD_GPIO_24XX:
  575 + if (enable)
  576 + reg += OMAP24XX_GPIO_SETIRQENABLE1;
  577 + else
  578 + reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
  579 + l = gpio_mask;
  580 + break;
480 581 default:
481 582 BUG();
482 583 return;
... ... @@ -489,6 +590,50 @@
489 590 _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
490 591 }
491 592  
  593 +/*
  594 + * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register.
  595 + * 1510 does not seem to have a wake-up register. If JTAG is connected
  596 + * to the target, system will wake up always on GPIO events. While
  597 + * system is running all registered GPIO interrupts need to have wake-up
  598 + * enabled. When system is suspended, only selected GPIO interrupts need
  599 + * to have wake-up enabled.
  600 + */
  601 +static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
  602 +{
  603 + switch (bank->method) {
  604 + case METHOD_GPIO_1610:
  605 + case METHOD_GPIO_24XX:
  606 + spin_lock(&bank->lock);
  607 + if (enable)
  608 + bank->suspend_wakeup |= (1 << gpio);
  609 + else
  610 + bank->suspend_wakeup &= ~(1 << gpio);
  611 + spin_unlock(&bank->lock);
  612 + return 0;
  613 + default:
  614 + printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
  615 + bank->method);
  616 + return -EINVAL;
  617 + }
  618 +}
  619 +
  620 +/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
  621 +static int gpio_wake_enable(unsigned int irq, unsigned int enable)
  622 +{
  623 + unsigned int gpio = irq - IH_GPIO_BASE;
  624 + struct gpio_bank *bank;
  625 + int retval;
  626 +
  627 + if (check_gpio(gpio) < 0)
  628 + return -ENODEV;
  629 + bank = get_gpio_bank(gpio);
  630 + spin_lock(&bank->lock);
  631 + retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
  632 + spin_unlock(&bank->lock);
  633 +
  634 + return retval;
  635 +}
  636 +
492 637 int omap_request_gpio(int gpio)
493 638 {
494 639 struct gpio_bank *bank;
495 640  
496 641  
497 642  
... ... @@ -505,15 +650,33 @@
505 650 return -1;
506 651 }
507 652 bank->reserved_map |= (1 << get_gpio_index(gpio));
  653 +
  654 + /* Set trigger to none. You need to enable the trigger after request_irq */
  655 + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
  656 +
508 657 #ifdef CONFIG_ARCH_OMAP1510
509 658 if (bank->method == METHOD_GPIO_1510) {
510   - u32 reg;
  659 + void __iomem *reg;
511 660  
512   - /* Claim the pin for the ARM */
  661 + /* Claim the pin for MPU */
513 662 reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
514 663 __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
515 664 }
516 665 #endif
  666 +#ifdef CONFIG_ARCH_OMAP16XX
  667 + if (bank->method == METHOD_GPIO_1610) {
  668 + /* Enable wake-up during idle for dynamic tick */
  669 + void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
  670 + __raw_writel(1 << get_gpio_index(gpio), reg);
  671 + }
  672 +#endif
  673 +#ifdef CONFIG_ARCH_OMAP24XX
  674 + if (bank->method == METHOD_GPIO_24XX) {
  675 + /* Enable wake-up during idle for dynamic tick */
  676 + void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA;
  677 + __raw_writel(1 << get_gpio_index(gpio), reg);
  678 + }
  679 +#endif
517 680 spin_unlock(&bank->lock);
518 681  
519 682 return 0;
... ... @@ -533,6 +696,20 @@
533 696 spin_unlock(&bank->lock);
534 697 return;
535 698 }
  699 +#ifdef CONFIG_ARCH_OMAP16XX
  700 + if (bank->method == METHOD_GPIO_1610) {
  701 + /* Disable wake-up during idle for dynamic tick */
  702 + void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
  703 + __raw_writel(1 << get_gpio_index(gpio), reg);
  704 + }
  705 +#endif
  706 +#ifdef CONFIG_ARCH_OMAP24XX
  707 + if (bank->method == METHOD_GPIO_24XX) {
  708 + /* Disable wake-up during idle for dynamic tick */
  709 + void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
  710 + __raw_writel(1 << get_gpio_index(gpio), reg);
  711 + }
  712 +#endif
536 713 bank->reserved_map &= ~(1 << get_gpio_index(gpio));
537 714 _set_gpio_direction(bank, get_gpio_index(gpio), 1);
538 715 _set_gpio_irqenable(bank, gpio, 0);
... ... @@ -552,7 +729,7 @@
552 729 static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
553 730 struct pt_regs *regs)
554 731 {
555   - u32 isr_reg = 0;
  732 + void __iomem *isr_reg = NULL;
556 733 u32 isr;
557 734 unsigned int gpio_irq;
558 735 struct gpio_bank *bank;
559 736  
560 737  
561 738  
... ... @@ -574,24 +751,30 @@
574 751 if (bank->method == METHOD_GPIO_730)
575 752 isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
576 753 #endif
  754 +#ifdef CONFIG_ARCH_OMAP24XX
  755 + if (bank->method == METHOD_GPIO_24XX)
  756 + isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
  757 +#endif
577 758  
578   - isr = __raw_readl(isr_reg);
579   - _enable_gpio_irqbank(bank, isr, 0);
580   - _clear_gpio_irqbank(bank, isr);
581   - _enable_gpio_irqbank(bank, isr, 1);
582   - desc->chip->unmask(irq);
  759 + while(1) {
  760 + isr = __raw_readl(isr_reg);
  761 + _enable_gpio_irqbank(bank, isr, 0);
  762 + _clear_gpio_irqbank(bank, isr);
  763 + _enable_gpio_irqbank(bank, isr, 1);
  764 + desc->chip->unmask(irq);
583 765  
584   - if (unlikely(!isr))
585   - return;
  766 + if (!isr)
  767 + break;
586 768  
587   - gpio_irq = bank->virtual_irq_start;
588   - for (; isr != 0; isr >>= 1, gpio_irq++) {
589   - struct irqdesc *d;
590   - if (!(isr & 1))
591   - continue;
592   - d = irq_desc + gpio_irq;
593   - desc_handle_irq(gpio_irq, d, regs);
594   - }
  769 + gpio_irq = bank->virtual_irq_start;
  770 + for (; isr != 0; isr >>= 1, gpio_irq++) {
  771 + struct irqdesc *d;
  772 + if (!(isr & 1))
  773 + continue;
  774 + d = irq_desc + gpio_irq;
  775 + desc_handle_irq(gpio_irq, d, regs);
  776 + }
  777 + }
595 778 }
596 779  
597 780 static void gpio_ack_irq(unsigned int irq)
598 781  
... ... @@ -613,14 +796,10 @@
613 796 static void gpio_unmask_irq(unsigned int irq)
614 797 {
615 798 unsigned int gpio = irq - IH_GPIO_BASE;
  799 + unsigned int gpio_idx = get_gpio_index(gpio);
616 800 struct gpio_bank *bank = get_gpio_bank(gpio);
617 801  
618   - if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) {
619   - printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n",
620   - gpio);
621   - _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE);
622   - }
623   - _set_gpio_irqenable(bank, gpio, 1);
  802 + _set_gpio_irqenable(bank, gpio_idx, 1);
624 803 }
625 804  
626 805 static void mpuio_ack_irq(unsigned int irq)
... ... @@ -645,9 +824,11 @@
645 824 }
646 825  
647 826 static struct irqchip gpio_irq_chip = {
648   - .ack = gpio_ack_irq,
649   - .mask = gpio_mask_irq,
650   - .unmask = gpio_unmask_irq,
  827 + .ack = gpio_ack_irq,
  828 + .mask = gpio_mask_irq,
  829 + .unmask = gpio_unmask_irq,
  830 + .set_type = gpio_irq_type,
  831 + .set_wake = gpio_wake_enable,
651 832 };
652 833  
653 834 static struct irqchip mpuio_irq_chip = {
... ... @@ -657,6 +838,7 @@
657 838 };
658 839  
659 840 static int initialized = 0;
  841 +static struct clk * gpio_ck = NULL;
660 842  
661 843 static int __init _omap_gpio_init(void)
662 844 {
... ... @@ -665,6 +847,14 @@
665 847  
666 848 initialized = 1;
667 849  
  850 + if (cpu_is_omap1510()) {
  851 + gpio_ck = clk_get(NULL, "arm_gpio_ck");
  852 + if (IS_ERR(gpio_ck))
  853 + printk("Could not get arm_gpio_ck\n");
  854 + else
  855 + clk_use(gpio_ck);
  856 + }
  857 +
668 858 #ifdef CONFIG_ARCH_OMAP1510
669 859 if (cpu_is_omap1510()) {
670 860 printk(KERN_INFO "OMAP1510 GPIO hardware\n");
... ... @@ -674,7 +864,7 @@
674 864 #endif
675 865 #if defined(CONFIG_ARCH_OMAP16XX)
676 866 if (cpu_is_omap16xx()) {
677   - int rev;
  867 + u32 rev;
678 868  
679 869 gpio_bank_count = 5;
680 870 gpio_bank = gpio_bank_1610;
... ... @@ -690,6 +880,17 @@
690 880 gpio_bank = gpio_bank_730;
691 881 }
692 882 #endif
  883 +#ifdef CONFIG_ARCH_OMAP24XX
  884 + if (cpu_is_omap24xx()) {
  885 + int rev;
  886 +
  887 + gpio_bank_count = 4;
  888 + gpio_bank = gpio_bank_24xx;
  889 + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
  890 + printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n",
  891 + (rev >> 4) & 0x0f, rev & 0x0f);
  892 + }
  893 +#endif
693 894 for (i = 0; i < gpio_bank_count; i++) {
694 895 int j, gpio_count = 16;
695 896  
... ... @@ -710,6 +911,7 @@
710 911 if (bank->method == METHOD_GPIO_1610) {
711 912 __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
712 913 __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
  914 + __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
713 915 }
714 916 #endif
715 917 #ifdef CONFIG_ARCH_OMAP730
... ... @@ -720,6 +922,14 @@
720 922 gpio_count = 32; /* 730 has 32-bit GPIOs */
721 923 }
722 924 #endif
  925 +#ifdef CONFIG_ARCH_OMAP24XX
  926 + if (bank->method == METHOD_GPIO_24XX) {
  927 + __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
  928 + __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
  929 +
  930 + gpio_count = 32;
  931 + }
  932 +#endif
723 933 for (j = bank->virtual_irq_start;
724 934 j < bank->virtual_irq_start + gpio_count; j++) {
725 935 if (bank->method == METHOD_MPUIO)
726 936  
... ... @@ -735,12 +945,97 @@
735 945  
736 946 /* Enable system clock for GPIO module.
737 947 * The CAM_CLK_CTRL *is* really the right place. */
738   - if (cpu_is_omap1610() || cpu_is_omap1710())
  948 + if (cpu_is_omap16xx())
739 949 omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
740 950  
741 951 return 0;
742 952 }
743 953  
  954 +#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
  955 +static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
  956 +{
  957 + int i;
  958 +
  959 + if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
  960 + return 0;
  961 +
  962 + for (i = 0; i < gpio_bank_count; i++) {
  963 + struct gpio_bank *bank = &gpio_bank[i];
  964 + void __iomem *wake_status;
  965 + void __iomem *wake_clear;
  966 + void __iomem *wake_set;
  967 +
  968 + switch (bank->method) {
  969 + case METHOD_GPIO_1610:
  970 + wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
  971 + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
  972 + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
  973 + break;
  974 + case METHOD_GPIO_24XX:
  975 + wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
  976 + wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
  977 + wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
  978 + break;
  979 + default:
  980 + continue;
  981 + }
  982 +
  983 + spin_lock(&bank->lock);
  984 + bank->saved_wakeup = __raw_readl(wake_status);
  985 + __raw_writel(0xffffffff, wake_clear);
  986 + __raw_writel(bank->suspend_wakeup, wake_set);
  987 + spin_unlock(&bank->lock);
  988 + }
  989 +
  990 + return 0;
  991 +}
  992 +
  993 +static int omap_gpio_resume(struct sys_device *dev)
  994 +{
  995 + int i;
  996 +
  997 + if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
  998 + return 0;
  999 +
  1000 + for (i = 0; i < gpio_bank_count; i++) {
  1001 + struct gpio_bank *bank = &gpio_bank[i];
  1002 + void __iomem *wake_clear;
  1003 + void __iomem *wake_set;
  1004 +
  1005 + switch (bank->method) {
  1006 + case METHOD_GPIO_1610:
  1007 + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
  1008 + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
  1009 + break;
  1010 + case METHOD_GPIO_24XX:
  1011 + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
  1012 + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
  1013 + break;
  1014 + default:
  1015 + continue;
  1016 + }
  1017 +
  1018 + spin_lock(&bank->lock);
  1019 + __raw_writel(0xffffffff, wake_clear);
  1020 + __raw_writel(bank->saved_wakeup, wake_set);
  1021 + spin_unlock(&bank->lock);
  1022 + }
  1023 +
  1024 + return 0;
  1025 +}
  1026 +
  1027 +static struct sysdev_class omap_gpio_sysclass = {
  1028 + set_kset_name("gpio"),
  1029 + .suspend = omap_gpio_suspend,
  1030 + .resume = omap_gpio_resume,
  1031 +};
  1032 +
  1033 +static struct sys_device omap_gpio_device = {
  1034 + .id = 0,
  1035 + .cls = &omap_gpio_sysclass,
  1036 +};
  1037 +#endif
  1038 +
744 1039 /*
745 1040 * This may get called early from board specific init
746 1041 */
747 1042  
748 1043  
... ... @@ -752,12 +1047,31 @@
752 1047 return 0;
753 1048 }
754 1049  
  1050 +static int __init omap_gpio_sysinit(void)
  1051 +{
  1052 + int ret = 0;
  1053 +
  1054 + if (!initialized)
  1055 + ret = _omap_gpio_init();
  1056 +
  1057 +#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
  1058 + if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
  1059 + if (ret == 0) {
  1060 + ret = sysdev_class_register(&omap_gpio_sysclass);
  1061 + if (ret == 0)
  1062 + ret = sysdev_register(&omap_gpio_device);
  1063 + }
  1064 + }
  1065 +#endif
  1066 +
  1067 + return ret;
  1068 +}
  1069 +
755 1070 EXPORT_SYMBOL(omap_request_gpio);
756 1071 EXPORT_SYMBOL(omap_free_gpio);
757 1072 EXPORT_SYMBOL(omap_set_gpio_direction);
758 1073 EXPORT_SYMBOL(omap_set_gpio_dataout);
759 1074 EXPORT_SYMBOL(omap_get_gpio_datain);
760   -EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
761 1075  
762   -arch_initcall(omap_gpio_init);
  1076 +arch_initcall(omap_gpio_sysinit);
arch/arm/plat-omap/mcbsp.c
... ... @@ -27,6 +27,7 @@
27 27 #include <asm/arch/dma.h>
28 28 #include <asm/arch/mux.h>
29 29 #include <asm/arch/irqs.h>
  30 +#include <asm/arch/dsp_common.h>
30 31 #include <asm/arch/mcbsp.h>
31 32  
32 33 #include <asm/hardware/clock.h>
... ... @@ -187,9 +188,6 @@
187 188 return -1;
188 189 }
189 190  
190   -#define EN_XORPCK 1
191   -#define DSP_RSTCT2 0xe1008014
192   -
193 191 static void omap_mcbsp_dsp_request(void)
194 192 {
195 193 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
... ... @@ -198,6 +196,11 @@
198 196  
199 197 /* enable 12MHz clock to mcbsp 1 & 3 */
200 198 clk_use(mcbsp_dspxor_ck);
  199 +
  200 + /*
  201 + * DSP external peripheral reset
  202 + * FIXME: This should be moved to dsp code
  203 + */
201 204 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
202 205 DSP_RSTCT2);
203 206 }
arch/arm/plat-omap/mux.c
... ... @@ -48,6 +48,9 @@
48 48 pull_orig = 0, pull = 0;
49 49 unsigned int mask, warn = 0;
50 50  
  51 + if (cpu_is_omap7xx())
  52 + return 0;
  53 +
51 54 if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
52 55 printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
53 56 return -EINVAL;
arch/arm/plat-omap/ocpi.c
... ... @@ -25,6 +25,7 @@
25 25  
26 26 #include <linux/config.h>
27 27 #include <linux/module.h>
  28 +#include <linux/version.h>
28 29 #include <linux/types.h>
29 30 #include <linux/errno.h>
30 31 #include <linux/kernel.h>
arch/arm/plat-omap/pm.c
... ... @@ -39,24 +39,32 @@
39 39 #include <linux/sched.h>
40 40 #include <linux/proc_fs.h>
41 41 #include <linux/pm.h>
  42 +#include <linux/interrupt.h>
42 43  
43 44 #include <asm/io.h>
  45 +#include <asm/irq.h>
44 46 #include <asm/mach/time.h>
45   -#include <asm/mach-types.h>
  47 +#include <asm/mach/irq.h>
46 48  
47   -#include <asm/arch/omap16xx.h>
  49 +#include <asm/mach-types.h>
  50 +#include <asm/arch/irqs.h>
  51 +#include <asm/arch/tc.h>
48 52 #include <asm/arch/pm.h>
49 53 #include <asm/arch/mux.h>
50   -#include <asm/arch/tc.h>
51 54 #include <asm/arch/tps65010.h>
  55 +#include <asm/arch/dsp_common.h>
52 56  
53 57 #include "clock.h"
  58 +#include "sram.h"
54 59  
55 60 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
56 61 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
57 62 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
58 63 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
59 64  
  65 +static void (*omap_sram_idle)(void) = NULL;
  66 +static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
  67 +
60 68 /*
61 69 * Let's power down on idle, but only if we are really
62 70 * idle, because once we start down the path of
... ... @@ -65,7 +73,6 @@
65 73 */
66 74 void omap_pm_idle(void)
67 75 {
68   - int (*func_ptr)(void) = 0;
69 76 unsigned int mask32 = 0;
70 77  
71 78 /*
... ... @@ -84,6 +91,13 @@
84 91 mask32 = omap_readl(ARM_SYSST);
85 92  
86 93 /*
  94 + * Prevent the ULPD from entering low power state by setting
  95 + * POWER_CTRL_REG:4 = 0
  96 + */
  97 + omap_writew(omap_readw(ULPD_POWER_CTRL) &
  98 + ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL);
  99 +
  100 + /*
87 101 * Since an interrupt may set up a timer, we don't want to
88 102 * reprogram the hardware timer with interrupts enabled.
89 103 * Re-enable interrupts only after returning from idle.
90 104  
... ... @@ -92,18 +106,9 @@
92 106  
93 107 if ((mask32 & DSP_IDLE) == 0) {
94 108 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
95   - } else {
  109 + } else
  110 + omap_sram_idle();
96 111  
97   - if (cpu_is_omap1510()) {
98   - func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
99   - } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
100   - func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
101   - } else if (cpu_is_omap5912()) {
102   - func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
103   - }
104   -
105   - func_ptr();
106   - }
107 112 local_fiq_enable();
108 113 local_irq_enable();
109 114 }
110 115  
111 116  
112 117  
113 118  
114 119  
115 120  
116 121  
117 122  
118 123  
119 124  
120 125  
121 126  
122 127  
123 128  
124 129  
... ... @@ -115,58 +120,55 @@
115 120 */
116 121 static void omap_pm_wakeup_setup(void)
117 122 {
118   - /*
119   - * Enable ARM XOR clock and release peripheral from reset by
120   - * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
121   - * for UART configuration to use UART2 to wake up.
122   - */
  123 + u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
  124 + u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
123 125  
124   - omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
125   - omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
126   - omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
127   -
128 126 /*
129   - * Turn off all interrupts except L1-2nd level cascade,
130   - * and the L2 wakeup interrupts: keypad and UART2.
  127 + * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
  128 + * and the L2 wakeup interrupts: keypad and UART2. Note that the
  129 + * drivers must still separately call omap_set_gpio_wakeup() to
  130 + * wake up to a GPIO interrupt.
131 131 */
  132 + if (cpu_is_omap1510() || cpu_is_omap16xx())
  133 + level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1);
  134 + else if (cpu_is_omap730())
  135 + level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1);
132 136  
133   - omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
  137 + omap_writel(~level1_wake, OMAP_IH1_MIR);
134 138  
135   - if (cpu_is_omap1510()) {
136   - omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR);
137   - }
  139 + if (cpu_is_omap1510())
  140 + omap_writel(~level2_wake, OMAP_IH2_MIR);
138 141  
  142 + /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
139 143 if (cpu_is_omap16xx()) {
140   - omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
141   -
142   - omap_writel(~0x0, OMAP_IH2_1_MIR);
  144 + omap_writel(~level2_wake, OMAP_IH2_0_MIR);
  145 + omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
143 146 omap_writel(~0x0, OMAP_IH2_2_MIR);
144 147 omap_writel(~0x0, OMAP_IH2_3_MIR);
145 148 }
146 149  
147   - /* New IRQ agreement */
  150 + /* New IRQ agreement, recalculate in cascade order */
  151 + omap_writel(1, OMAP_IH2_CONTROL);
148 152 omap_writel(1, OMAP_IH1_CONTROL);
149   -
150   - /* external PULL to down, bit 22 = 0 */
151   - omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
152 153 }
153 154  
154 155 void omap_pm_suspend(void)
155 156 {
156   - unsigned int mask32 = 0;
157 157 unsigned long arg0 = 0, arg1 = 0;
158   - int (*func_ptr)(unsigned short, unsigned short) = 0;
159   - unsigned short save_dsp_idlect2;
160 158  
161   - printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
  159 + printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
162 160  
  161 + omap_serial_wake_trigger(1);
  162 +
163 163 if (machine_is_omap_osk()) {
164 164 /* Stop LED1 (D9) blink */
165 165 tps65010_set_led(LED1, OFF);
166 166 }
167 167  
  168 + omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
  169 +
168 170 /*
169   - * Step 1: turn off interrupts
  171 + * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
170 172 */
171 173  
172 174 local_irq_disable();
... ... @@ -207,6 +209,8 @@
207 209 ARM_SAVE(ARM_CKCTL);
208 210 ARM_SAVE(ARM_IDLECT1);
209 211 ARM_SAVE(ARM_IDLECT2);
  212 + if (!(cpu_is_omap1510()))
  213 + ARM_SAVE(ARM_IDLECT3);
210 214 ARM_SAVE(ARM_EWUPCT);
211 215 ARM_SAVE(ARM_RSTCT1);
212 216 ARM_SAVE(ARM_RSTCT2);
213 217  
214 218  
215 219  
... ... @@ -214,43 +218,13 @@
214 218 ULPD_SAVE(ULPD_CLOCK_CTRL);
215 219 ULPD_SAVE(ULPD_STATUS_REQ);
216 220  
217   - /*
218   - * Step 3: LOW_PWR signal enabling
219   - *
220   - * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
221   - */
222   - if (cpu_is_omap1510()) {
223   - /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
224   - omap_writew(omap_readw(ULPD_POWER_CTRL) |
225   - OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
226   - } else if (cpu_is_omap16xx()) {
227   - /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
228   - omap_writew(omap_readw(ULPD_POWER_CTRL) |
229   - OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
230   - }
  221 + /* (Step 3 removed - we now allow deep sleep by default) */
231 222  
232   - /* configure LOW_PWR pin */
233   - omap_cfg_reg(T20_1610_LOW_PWR);
234   -
235 223 /*
236 224 * Step 4: OMAP DSP Shutdown
237 225 */
238 226  
239   - /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
240   - omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
241   - ARM_RSTCT1);
242 227  
243   - /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
244   - omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
245   -
246   - /* Set EN_DSPCK = 0, stop DSP block clock */
247   - omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
248   -
249   - /* Stop any DSP domain clocks */
250   - omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
251   - save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
252   - __raw_writew(0, DSP_IDLECT2);
253   -
254 228 /*
255 229 * Step 5: Wakeup Event Setup
256 230 */
257 231  
... ... @@ -258,24 +232,9 @@
258 232 omap_pm_wakeup_setup();
259 233  
260 234 /*
261   - * Step 6a: ARM and Traffic controller shutdown
262   - *
263   - * Step 6 starts here with clock and watchdog disable
  235 + * Step 6: ARM and Traffic controller shutdown
264 236 */
265 237  
266   - /* stop clocks */
267   - mask32 = omap_readl(ARM_IDLECT2);
268   - mask32 &= ~(1<<EN_WDTCK); /* bit 0 -> 0 (WDT clock) */
269   - mask32 |= (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
270   - mask32 &= ~(1<<EN_PERCK); /* bit 2 -> 0 (MPUPER_CK clock) */
271   - mask32 &= ~(1<<EN_LCDCK); /* bit 3 -> 0 (LCDC clock) */
272   - mask32 &= ~(1<<EN_LBCK); /* bit 4 -> 0 (local bus clock) */
273   - mask32 |= (1<<EN_APICK); /* bit 6 -> 1 (MPUI clock) */
274   - mask32 &= ~(1<<EN_TIMCK); /* bit 7 -> 0 (MPU timer clock) */
275   - mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
276   - mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
277   - omap_writel(mask32, ARM_IDLECT2);
278   -
279 238 /* disable ARM watchdog */
280 239 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
281 240 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
282 241  
283 242  
284 243  
285 244  
... ... @@ -295,47 +254,24 @@
295 254 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
296 255 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
297 256  
298   - if (cpu_is_omap1510()) {
299   - func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
300   - } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
301   - func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
302   - } else if (cpu_is_omap5912()) {
303   - func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
304   - }
305   -
306 257 /*
307 258 * Step 6c: ARM and Traffic controller shutdown
308 259 *
309 260 * Jump to assembly code. The processor will stay there
310 261 * until wake up.
311 262 */
  263 + omap_sram_suspend(arg0, arg1);
312 264  
313   - func_ptr(arg0, arg1);
314   -
315 265 /*
316 266 * If we are here, processor is woken up!
317 267 */
318 268  
319   - if (cpu_is_omap1510()) {
320   - /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
321   - omap_writew(omap_readw(ULPD_POWER_CTRL) &
322   - ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
323   - } else if (cpu_is_omap16xx()) {
324   - /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
325   - omap_writew(omap_readw(ULPD_POWER_CTRL) &
326   - ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
327   - }
328   -
329   -
330   - /* Restore DSP clocks */
331   - omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
332   - __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
333   - ARM_RESTORE(ARM_IDLECT2);
334   -
335 269 /*
336 270 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
337 271 */
338 272  
  273 + if (!(cpu_is_omap1510()))
  274 + ARM_RESTORE(ARM_IDLECT3);
339 275 ARM_RESTORE(ARM_CKCTL);
340 276 ARM_RESTORE(ARM_EWUPCT);
341 277 ARM_RESTORE(ARM_RSTCT1);
... ... @@ -366,6 +302,8 @@
366 302 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
367 303 }
368 304  
  305 + omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
  306 +
369 307 /*
370 308 * Reenable interrupts
371 309 */
... ... @@ -373,6 +311,8 @@
373 311 local_irq_enable();
374 312 local_fiq_enable();
375 313  
  314 + omap_serial_wake_trigger(0);
  315 +
376 316 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
377 317  
378 318 if (machine_is_omap_osk()) {
... ... @@ -401,6 +341,8 @@
401 341 ARM_SAVE(ARM_CKCTL);
402 342 ARM_SAVE(ARM_IDLECT1);
403 343 ARM_SAVE(ARM_IDLECT2);
  344 + if (!(cpu_is_omap1510()))
  345 + ARM_SAVE(ARM_IDLECT3);
404 346 ARM_SAVE(ARM_EWUPCT);
405 347 ARM_SAVE(ARM_RSTCT1);
406 348 ARM_SAVE(ARM_RSTCT2);
... ... @@ -436,6 +378,7 @@
436 378 "ARM_CKCTL_REG: 0x%-8x \n"
437 379 "ARM_IDLECT1_REG: 0x%-8x \n"
438 380 "ARM_IDLECT2_REG: 0x%-8x \n"
  381 + "ARM_IDLECT3_REG: 0x%-8x \n"
439 382 "ARM_EWUPCT_REG: 0x%-8x \n"
440 383 "ARM_RSTCT1_REG: 0x%-8x \n"
441 384 "ARM_RSTCT2_REG: 0x%-8x \n"
... ... @@ -449,6 +392,7 @@
449 392 ARM_SHOW(ARM_CKCTL),
450 393 ARM_SHOW(ARM_IDLECT1),
451 394 ARM_SHOW(ARM_IDLECT2),
  395 + ARM_SHOW(ARM_IDLECT3),
452 396 ARM_SHOW(ARM_EWUPCT),
453 397 ARM_SHOW(ARM_RSTCT1),
454 398 ARM_SHOW(ARM_RSTCT2),
... ... @@ -507,7 +451,7 @@
507 451  
508 452 entry = create_proc_read_entry("driver/omap_pm",
509 453 S_IWUSR | S_IRUGO, NULL,
510   - omap_pm_read_proc, 0);
  454 + omap_pm_read_proc, NULL);
511 455 }
512 456  
513 457 #endif /* DEBUG && CONFIG_PROC_FS */
... ... @@ -580,7 +524,21 @@
580 524 }
581 525  
582 526  
583   -struct pm_ops omap_pm_ops ={
  527 +static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
  528 + struct pt_regs * regs)
  529 +{
  530 + return IRQ_HANDLED;
  531 +}
  532 +
  533 +static struct irqaction omap_wakeup_irq = {
  534 + .name = "peripheral wakeup",
  535 + .flags = SA_INTERRUPT,
  536 + .handler = omap_wakeup_interrupt
  537 +};
  538 +
  539 +
  540 +
  541 +static struct pm_ops omap_pm_ops ={
584 542 .pm_disk_mode = 0,
585 543 .prepare = omap_pm_prepare,
586 544 .enter = omap_pm_enter,
587 545  
588 546  
589 547  
590 548  
... ... @@ -590,41 +548,60 @@
590 548 static int __init omap_pm_init(void)
591 549 {
592 550 printk("Power Management for TI OMAP.\n");
593   - pm_idle = omap_pm_idle;
594 551 /*
595 552 * We copy the assembler sleep/wakeup routines to SRAM.
596 553 * These routines need to be in SRAM as that's the only
597 554 * memory the MPU can see when it wakes up.
598 555 */
599   -
600   -#ifdef CONFIG_ARCH_OMAP1510
601 556 if (cpu_is_omap1510()) {
602   - memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
603   - omap1510_idle_loop_suspend,
604   - omap1510_idle_loop_suspend_sz);
605   - memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
606   - omap1510_cpu_suspend_sz);
607   - } else
608   -#endif
609   - if (cpu_is_omap1610() || cpu_is_omap1710()) {
610   - memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
611   - omap1610_idle_loop_suspend,
612   - omap1610_idle_loop_suspend_sz);
613   - memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
614   - omap1610_cpu_suspend_sz);
615   - } else if (cpu_is_omap5912()) {
616   - memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
617   - omap1610_idle_loop_suspend,
618   - omap1610_idle_loop_suspend_sz);
619   - memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
620   - omap1610_cpu_suspend_sz);
  557 + omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
  558 + omap1510_idle_loop_suspend_sz);
  559 + omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
  560 + omap1510_cpu_suspend_sz);
  561 + } else if (cpu_is_omap16xx()) {
  562 + omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
  563 + omap1610_idle_loop_suspend_sz);
  564 + omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
  565 + omap1610_cpu_suspend_sz);
621 566 }
622 567  
  568 + if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
  569 + printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
  570 + return -ENODEV;
  571 + }
  572 +
  573 + pm_idle = omap_pm_idle;
  574 +
  575 + setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
  576 +#if 0
  577 + /* --- BEGIN BOARD-DEPENDENT CODE --- */
  578 + /* Sleepx mask direction */
  579 + omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
  580 + /* Unmask sleepx signal */
  581 + omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
  582 + /* --- END BOARD-DEPENDENT CODE --- */
  583 +#endif
  584 +
  585 + /* Program new power ramp-up time
  586 + * (0 for most boards since we don't lower voltage when in deep sleep)
  587 + */
  588 + omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
  589 +
  590 + /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
  591 + omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
  592 +
  593 + /* Configure IDLECT3 */
  594 + if (cpu_is_omap16xx())
  595 + omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
  596 +
623 597 pm_set_ops(&omap_pm_ops);
624 598  
625 599 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
626 600 omap_pm_init_proc();
627 601 #endif
  602 +
  603 + /* configure LOW_PWR pin */
  604 + omap_cfg_reg(T20_1610_LOW_PWR);
628 605  
629 606 return 0;
630 607 }
arch/arm/plat-omap/sleep.S
... ... @@ -66,7 +66,7 @@
66 66 @ get ARM_IDLECT2 into r2
67 67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
68 68 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
69   - orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
  69 + orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
70 70 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
71 71  
72 72 @ request ARM idle
... ... @@ -76,7 +76,7 @@
76 76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
77 77  
78 78 mov r5, #IDLE_WAIT_CYCLES & 0xff
79   - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
  79 + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
80 80 l_1510: subs r5, r5, #1
81 81 bne l_1510
82 82 /*
... ... @@ -96,7 +96,7 @@
96 96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
97 97 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
98 98  
99   - ldmfd sp!, {r0 - r12, pc} @ restore regs and return
  99 + ldmfd sp!, {r0 - r12, pc} @ restore regs and return
100 100  
101 101 ENTRY(omap1510_idle_loop_suspend_sz)
102 102 .word . - omap1510_idle_loop_suspend
... ... @@ -115,8 +115,8 @@
115 115 @ turn off clock domains
116 116 @ get ARM_IDLECT2 into r2
117 117 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
118   - mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
119   - orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
  118 + mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
  119 + orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
120 120 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
121 121  
122 122 @ request ARM idle
... ... @@ -126,7 +126,7 @@
126 126 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
127 127  
128 128 mov r5, #IDLE_WAIT_CYCLES & 0xff
129   - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
  129 + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
130 130 l_1610: subs r5, r5, #1
131 131 bne l_1610
132 132 /*
... ... @@ -146,7 +146,7 @@
146 146 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
147 147 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
148 148  
149   - ldmfd sp!, {r0 - r12, pc} @ restore regs and return
  149 + ldmfd sp!, {r0 - r12, pc} @ restore regs and return
150 150  
151 151 ENTRY(omap1610_idle_loop_suspend_sz)
152 152 .word . - omap1610_idle_loop_suspend
... ... @@ -208,7 +208,7 @@
208 208  
209 209 @ turn off clock domains
210 210 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
211   - orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
  211 + orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
212 212 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
213 213  
214 214 @ request ARM idle
... ... @@ -217,7 +217,7 @@
217 217 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
218 218  
219 219 mov r5, #IDLE_WAIT_CYCLES & 0xff
220   - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
  220 + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
221 221 l_1510_2:
222 222 subs r5, r5, #1
223 223 bne l_1510_2
... ... @@ -237,7 +237,7 @@
237 237 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
238 238  
239 239 @ restore regs and return
240   - ldmfd sp!, {r0 - r12, pc}
  240 + ldmfd sp!, {r0 - r12, pc}
241 241  
242 242 ENTRY(omap1510_cpu_suspend_sz)
243 243 .word . - omap1510_cpu_suspend
244 244  
245 245  
246 246  
... ... @@ -249,21 +249,26 @@
249 249 @ save registers on stack
250 250 stmfd sp!, {r0 - r12, lr}
251 251  
  252 + @ Drain write cache
  253 + mov r4, #0
  254 + mcr p15, 0, r0, c7, c10, 4
  255 + nop
  256 +
252 257 @ load base address of Traffic Controller
253   - mov r4, #TCMIF_ASM_BASE & 0xff000000
254   - orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
255   - orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
  258 + mov r6, #TCMIF_ASM_BASE & 0xff000000
  259 + orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
  260 + orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
256 261  
257 262 @ prepare to put SDRAM into self-refresh manually
258   - ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
259   - orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
260   - orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
261   - str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
  263 + ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
  264 + orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
  265 + orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
  266 + str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
262 267  
263 268 @ prepare to put EMIFS to Sleep
264   - ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
265   - orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
266   - str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
  269 + ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
  270 + orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
  271 + str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
267 272  
268 273 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
269 274 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
270 275  
271 276  
272 277  
... ... @@ -271,26 +276,22 @@
271 276 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
272 277  
273 278 @ turn off clock domains
274   - mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
275   - orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
  279 + @ do not disable PERCK (0x04)
  280 + mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
  281 + orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
276 282 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
277 283  
278   - @ work around errata of OMAP1610/5912. Enable (!) peripheral
279   - @ clock to let the chip go into deep sleep
280   - ldrh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
281   - orr r5,r5, #EN_PERCK_BIT & 0xff
282   - strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
283   -
284 284 @ request ARM idle
285   - mov r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff
286   - orr r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00
  285 + mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
  286 + orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
287 287 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
288 288  
289   - mov r5, #IDLE_WAIT_CYCLES & 0xff
290   - orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
291   -l_1610_2:
292   - subs r5, r5, #1
293   - bne l_1610_2
  289 + @ disable instruction cache
  290 + mrc p15, 0, r9, c1, c0, 0
  291 + bic r2, r9, #0x1000
  292 + mcr p15, 0, r2, c1, c0, 0
  293 + nop
  294 +
294 295 /*
295 296 * Let's wait for the next wake up event to wake us up. r0 can't be
296 297 * used here because r0 holds ARM_IDLECT1
297 298  
298 299  
299 300  
... ... @@ -301,13 +302,21 @@
301 302 * omap1610_cpu_suspend()'s resume point.
302 303 *
303 304 * It will just start executing here, so we'll restore stuff from the
304   - * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
  305 + * stack.
305 306 */
  307 + @ re-enable Icache
  308 + mcr p15, 0, r9, c1, c0, 0
  309 +
  310 + @ reset the ARM_IDLECT1 and ARM_IDLECT2.
306 311 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
307 312 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
308 313  
  314 + @ Restore EMIFF controls
  315 + str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
  316 + str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
  317 +
309 318 @ restore regs and return
310   - ldmfd sp!, {r0 - r12, pc}
  319 + ldmfd sp!, {r0 - r12, pc}
311 320  
312 321 ENTRY(omap1610_cpu_suspend_sz)
313 322 .word . - omap1610_cpu_suspend
arch/arm/plat-omap/sram-fn.S
  1 +/*
  2 + * linux/arch/arm/plat-omap/sram.S
  3 + *
  4 + * Functions that need to be run in internal SRAM
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License version 2 as
  8 + * published by the Free Software Foundation.
  9 + */
  10 +
  11 +#include <linux/config.h>
  12 +#include <linux/linkage.h>
  13 +#include <asm/assembler.h>
  14 +#include <asm/arch/io.h>
  15 +#include <asm/arch/hardware.h>
  16 +
  17 + .text
  18 +
  19 +/*
  20 + * Reprograms ULPD and CKCTL.
  21 + */
  22 +ENTRY(sram_reprogram_clock)
  23 + stmfd sp!, {r0 - r12, lr} @ save registers on stack
  24 +
  25 + mov r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000
  26 + orr r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x00ff0000
  27 + orr r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x0000ff00
  28 +
  29 + mov r3, #IO_ADDRESS(ARM_CKCTL) & 0xff000000
  30 + orr r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x00ff0000
  31 + orr r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x0000ff00
  32 +
  33 + tst r0, #1 << 4 @ want lock mode?
  34 + beq newck @ nope
  35 + bic r0, r0, #1 << 4 @ else clear lock bit
  36 + strh r0, [r2] @ set dpll into bypass mode
  37 + orr r0, r0, #1 << 4 @ set lock bit again
  38 +
  39 +newck:
  40 + strh r1, [r3] @ write new ckctl value
  41 + strh r0, [r2] @ write new dpll value
  42 +
  43 + mov r4, #0x0700 @ let the clocks settle
  44 + orr r4, r4, #0x00ff
  45 +delay: sub r4, r4, #1
  46 + cmp r4, #0
  47 + bne delay
  48 +
  49 +lock: ldrh r4, [r2], #0 @ read back dpll value
  50 + tst r0, #1 << 4 @ want lock mode?
  51 + beq out @ nope
  52 + tst r4, #1 << 0 @ dpll rate locked?
  53 + beq lock @ try again
  54 +
  55 +out:
  56 + ldmfd sp!, {r0 - r12, pc} @ restore regs and return
  57 +ENTRY(sram_reprogram_clock_sz)
  58 + .word . - sram_reprogram_clock
arch/arm/plat-omap/sram.c
  1 +/*
  2 + * linux/arch/arm/plat-omap/sram.c
  3 + *
  4 + * OMAP SRAM detection and management
  5 + *
  6 + * Copyright (C) 2005 Nokia Corporation
  7 + * Written by Tony Lindgren <tony@atomide.com>
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 + */
  13 +
  14 +#include <linux/config.h>
  15 +#include <linux/module.h>
  16 +#include <linux/kernel.h>
  17 +#include <linux/init.h>
  18 +
  19 +#include <asm/mach/map.h>
  20 +#include <asm/io.h>
  21 +#include <asm/cacheflush.h>
  22 +
  23 +#include "sram.h"
  24 +
  25 +#define OMAP1_SRAM_BASE 0xd0000000
  26 +#define OMAP1_SRAM_START 0x20000000
  27 +#define SRAM_BOOTLOADER_SZ 0x80
  28 +
  29 +static unsigned long omap_sram_base;
  30 +static unsigned long omap_sram_size;
  31 +static unsigned long omap_sram_ceil;
  32 +
  33 +/*
  34 + * The amount of SRAM depends on the core type:
  35 + * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
  36 + * Note that we cannot try to test for SRAM here because writes
  37 + * to secure SRAM will hang the system. Also the SRAM is not
  38 + * yet mapped at this point.
  39 + */
  40 +void __init omap_detect_sram(void)
  41 +{
  42 + omap_sram_base = OMAP1_SRAM_BASE;
  43 +
  44 + if (cpu_is_omap730())
  45 + omap_sram_size = 0x32000;
  46 + else if (cpu_is_omap1510())
  47 + omap_sram_size = 0x80000;
  48 + else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
  49 + omap_sram_size = 0x4000;
  50 + else if (cpu_is_omap1611())
  51 + omap_sram_size = 0x3e800;
  52 + else {
  53 + printk(KERN_ERR "Could not detect SRAM size\n");
  54 + omap_sram_size = 0x4000;
  55 + }
  56 +
  57 + printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
  58 + omap_sram_ceil = omap_sram_base + omap_sram_size;
  59 +}
  60 +
  61 +static struct map_desc omap_sram_io_desc[] __initdata = {
  62 + { OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE }
  63 +};
  64 +
  65 +/*
  66 + * In order to use last 2kB of SRAM on 1611b, we must round the size
  67 + * up to multiple of PAGE_SIZE. We cannot use ioremap for SRAM, as
  68 + * clock init needs SRAM early.
  69 + */
  70 +void __init omap_map_sram(void)
  71 +{
  72 + if (omap_sram_size == 0)
  73 + return;
  74 +
  75 + omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
  76 + omap_sram_io_desc[0].length *= PAGE_SIZE;
  77 + iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
  78 +
  79 + /*
  80 + * Looks like we need to preserve some bootloader code at the
  81 + * beginning of SRAM for jumping to flash for reboot to work...
  82 + */
  83 + memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0,
  84 + omap_sram_size - SRAM_BOOTLOADER_SZ);
  85 +}
  86 +
  87 +static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
  88 +
  89 +void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
  90 +{
  91 + if (_omap_sram_reprogram_clock == NULL)
  92 + panic("Cannot use SRAM");
  93 +
  94 + return _omap_sram_reprogram_clock(dpllctl, ckctl);
  95 +}
  96 +
  97 +void * omap_sram_push(void * start, unsigned long size)
  98 +{
  99 + if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
  100 + printk(KERN_ERR "Not enough space in SRAM\n");
  101 + return NULL;
  102 + }
  103 + omap_sram_ceil -= size;
  104 + omap_sram_ceil &= ~0x3;
  105 + memcpy((void *)omap_sram_ceil, start, size);
  106 +
  107 + return (void *)omap_sram_ceil;
  108 +}
  109 +
  110 +void __init omap_sram_init(void)
  111 +{
  112 + omap_detect_sram();
  113 + omap_map_sram();
  114 + _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
  115 + sram_reprogram_clock_sz);
  116 +}
arch/arm/plat-omap/sram.h
  1 +/*
  2 + * linux/arch/arm/plat-omap/sram.h
  3 + *
  4 + * Interface for functions that need to be run in internal SRAM
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License version 2 as
  8 + * published by the Free Software Foundation.
  9 + */
  10 +
  11 +#ifndef __ARCH_ARM_OMAP_SRAM_H
  12 +#define __ARCH_ARM_OMAP_SRAM_H
  13 +
  14 +extern void * omap_sram_push(void * start, unsigned long size);
  15 +extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
  16 +
  17 +/* Do not use these */
  18 +extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
  19 +extern unsigned long sram_reprogram_clock_sz;
  20 +
  21 +#endif
arch/arm/plat-omap/usb.c
... ... @@ -41,6 +41,7 @@
41 41  
42 42 /* These routines should handle the standard chip-specific modes
43 43 * for usb0/1/2 ports, covering basic mux and transceiver setup.
  44 + * Call omap_usb_init() once, from INIT_MACHINE().
44 45 *
45 46 * Some board-*.c files will need to set up additional mux options,
46 47 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.