aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2005-09-07 12:20:26 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-09-07 12:20:26 -0400
commit92105bb70634abacc08bbe12bf6f888fbd7dad38 (patch)
tree194e3032671ee3a90644c68cda8ddf471cb09d0e /arch
parent7efb833d645d10258e32664404354d26cf6070e3 (diff)
[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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-omap/Kconfig16
-rw-r--r--arch/arm/plat-omap/Makefile4
-rw-r--r--arch/arm/plat-omap/clock.c39
-rw-r--r--arch/arm/plat-omap/common.c7
-rw-r--r--arch/arm/plat-omap/dma.c25
-rw-r--r--arch/arm/plat-omap/dmtimer.c260
-rw-r--r--arch/arm/plat-omap/gpio.c524
-rw-r--r--arch/arm/plat-omap/mcbsp.c9
-rw-r--r--arch/arm/plat-omap/mux.c3
-rw-r--r--arch/arm/plat-omap/ocpi.c1
-rw-r--r--arch/arm/plat-omap/pm.c255
-rw-r--r--arch/arm/plat-omap/sleep.S83
-rw-r--r--arch/arm/plat-omap/sram-fn.S58
-rw-r--r--arch/arm/plat-omap/sram.c116
-rw-r--r--arch/arm/plat-omap/sram.h21
-rw-r--r--arch/arm/plat-omap/usb.c1
16 files changed, 1115 insertions, 307 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 345365852f8..9693e9b4ffd 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -91,6 +91,13 @@ config OMAP_32K_TIMER_HZ
91 Kernel internal timer frequency should be a divisor of 32768, 91 Kernel internal timer frequency should be a divisor of 32768,
92 such as 64 or 128. 92 such as 64 or 128.
93 93
94config 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
94choice 101choice
95 prompt "Low-level debug console UART" 102 prompt "Low-level debug console UART"
96 depends on ARCH_OMAP 103 depends on ARCH_OMAP
@@ -107,6 +114,15 @@ config OMAP_LL_DEBUG_UART3
107 114
108endchoice 115endchoice
109 116
117config 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.
125
110endmenu 126endmenu
111 127
112endif 128endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 531e11af54d..7e144f9cad1 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o 6obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
@@ -15,3 +15,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
15obj-$(CONFIG_PM) += pm.o sleep.o 15obj-$(CONFIG_PM) += pm.o sleep.o
16 16
17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o 17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
18obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
19
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 59d91b3262b..52a58b2da28 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
21#include <asm/arch/usb.h> 21#include <asm/arch/usb.h>
22 22
23#include "clock.h" 23#include "clock.h"
24#include "sram.h"
24 25
25static LIST_HEAD(clocks); 26static LIST_HEAD(clocks);
26static DECLARE_MUTEX(clocks_sem); 27static DECLARE_MUTEX(clocks_sem);
@@ -141,7 +142,7 @@ static struct clk arm_ck = {
141static struct clk armper_ck = { 142static struct clk armper_ck = {
142 .name = "armper_ck", 143 .name = "armper_ck",
143 .parent = &ck_dpll1, 144 .parent = &ck_dpll1,
144 .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 145 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
145 RATE_CKCTL, 146 RATE_CKCTL,
146 .enable_reg = ARM_IDLECT2, 147 .enable_reg = ARM_IDLECT2,
147 .enable_bit = EN_PERCK, 148 .enable_bit = EN_PERCK,
@@ -385,7 +386,8 @@ static struct clk uart2_ck = {
385 .name = "uart2_ck", 386 .name = "uart2_ck",
386 /* Direct from ULPD, no parent */ 387 /* Direct from ULPD, no parent */
387 .rate = 12000000, 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 .enable_reg = MOD_CONF_CTRL_0, 391 .enable_reg = MOD_CONF_CTRL_0,
390 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ 392 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
391 .set_rate = &set_uart_rate, 393 .set_rate = &set_uart_rate,
@@ -443,6 +445,15 @@ static struct clk usb_hhc_ck16xx = {
443 .enable_bit = 8 /* UHOST_EN */, 445 .enable_bit = 8 /* UHOST_EN */,
444}; 446};
445 447
448static 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
446static struct clk mclk_1510 = { 457static struct clk mclk_1510 = {
447 .name = "mclk", 458 .name = "mclk",
448 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 459 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
@@ -552,6 +563,7 @@ static struct clk * onchip_clks[] = {
552 &uart3_16xx, 563 &uart3_16xx,
553 &usb_clko, 564 &usb_clko,
554 &usb_hhc_ck1510, &usb_hhc_ck16xx, 565 &usb_hhc_ck1510, &usb_hhc_ck16xx,
566 &usb_dc_ck,
555 &mclk_1510, &mclk_16xx, 567 &mclk_1510, &mclk_16xx,
556 &bclk_1510, &bclk_16xx, 568 &bclk_1510, &bclk_16xx,
557 &mmc1_ck, 569 &mmc1_ck,
@@ -946,14 +958,13 @@ static int select_table_rate(struct clk * clk, unsigned long rate)
946 if (!ptr->rate) 958 if (!ptr->rate)
947 return -EINVAL; 959 return -EINVAL;
948 960
949 if (!ptr->rate) 961 /*
950 return -EINVAL; 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)) { 967 ck_dpll1.rate = ptr->pll_rate;
953 omap_writew(ptr->dpllctl_val, DPLL_CTL);
954 ck_dpll1.rate = ptr->pll_rate;
955 }
956 omap_writew(ptr->ckctl_val, ARM_CKCTL);
957 propagate_rate(&ck_dpll1); 968 propagate_rate(&ck_dpll1);
958 return 0; 969 return 0;
959} 970}
@@ -1224,9 +1235,11 @@ int __init clk_init(void)
1224#endif 1235#endif
1225 /* Cache rates for clocks connected to ck_ref (not dpll1) */ 1236 /* Cache rates for clocks connected to ck_ref (not dpll1) */
1226 propagate_rate(&ck_ref); 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 ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, 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#ifdef CONFIG_MACH_OMAP_PERSEUS2 1244#ifdef CONFIG_MACH_OMAP_PERSEUS2
1232 /* Select slicer output as OMAP input clock */ 1245 /* Select slicer output as OMAP input clock */
@@ -1271,7 +1284,9 @@ static int __init omap_late_clk_reset(void)
1271 struct clk *p; 1284 struct clk *p;
1272 __u32 regval32; 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 omap_writew(0, SOFT_REQ_REG2); 1290 omap_writew(0, SOFT_REQ_REG2);
1276 1291
1277 list_for_each_entry(p, &clocks, node) { 1292 list_for_each_entry(p, &clocks, node) {
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index ea967a8f6ce..6cb20aea7f5 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -26,6 +26,7 @@
26#include <asm/hardware/clock.h> 26#include <asm/hardware/clock.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/mach-types.h> 28#include <asm/mach-types.h>
29#include <asm/setup.h>
29 30
30#include <asm/arch/board.h> 31#include <asm/arch/board.h>
31#include <asm/arch/mux.h> 32#include <asm/arch/mux.h>
@@ -35,11 +36,11 @@
35 36
36#define NO_LENGTH_CHECK 0xffffffff 37#define NO_LENGTH_CHECK 0xffffffff
37 38
38extern int omap_bootloader_tag_len; 39unsigned char omap_bootloader_tag[512];
39extern u8 omap_bootloader_tag[]; 40int omap_bootloader_tag_len;
40 41
41struct omap_board_config_kernel *omap_board_config; 42struct omap_board_config_kernel *omap_board_config;
42int omap_board_config_size = 0; 43int omap_board_config_size;
43 44
44static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) 45static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
45{ 46{
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c0a5c2fa42b..da7b6514565 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -425,7 +425,7 @@ static int dma_handle_ch(int ch)
425 dma_chan[ch + 6].saved_csr = csr >> 7; 425 dma_chan[ch + 6].saved_csr = csr >> 7;
426 csr &= 0x7f; 426 csr &= 0x7f;
427 } 427 }
428 if (!csr) 428 if ((csr & 0x3f) == 0)
429 return 0; 429 return 0;
430 if (unlikely(dma_chan[ch].dev_id == -1)) { 430 if (unlikely(dma_chan[ch].dev_id == -1)) {
431 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n", 431 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
@@ -890,11 +890,11 @@ void omap_enable_lcd_dma(void)
890 w |= 1 << 8; 890 w |= 1 << 8;
891 omap_writew(w, OMAP1610_DMA_LCD_CTRL); 891 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
892 892
893 lcd_dma.active = 1;
894
893 w = omap_readw(OMAP1610_DMA_LCD_CCR); 895 w = omap_readw(OMAP1610_DMA_LCD_CCR);
894 w |= 1 << 7; 896 w |= 1 << 7;
895 omap_writew(w, OMAP1610_DMA_LCD_CCR); 897 omap_writew(w, OMAP1610_DMA_LCD_CCR);
896
897 lcd_dma.active = 1;
898} 898}
899 899
900void omap_setup_lcd_dma(void) 900void omap_setup_lcd_dma(void)
@@ -965,8 +965,8 @@ void omap_clear_dma(int lch)
965 */ 965 */
966dma_addr_t omap_get_dma_src_pos(int lch) 966dma_addr_t omap_get_dma_src_pos(int lch)
967{ 967{
968 return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) | 968 return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) |
969 (OMAP_DMA_CSSA_U(lch) << 16)); 969 (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16));
970} 970}
971 971
972/* 972/*
@@ -979,8 +979,18 @@ dma_addr_t omap_get_dma_src_pos(int lch)
979 */ 979 */
980dma_addr_t omap_get_dma_dst_pos(int lch) 980dma_addr_t omap_get_dma_dst_pos(int lch)
981{ 981{
982 return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) | 982 return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) |
983 (OMAP_DMA_CDSA_U(lch) << 16)); 983 (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16));
984}
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 */
991int omap_get_dma_src_addr_counter(int lch)
992{
993 return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch));
984} 994}
985 995
986int omap_dma_running(void) 996int omap_dma_running(void)
@@ -1076,6 +1086,7 @@ arch_initcall(omap_init_dma);
1076 1086
1077EXPORT_SYMBOL(omap_get_dma_src_pos); 1087EXPORT_SYMBOL(omap_get_dma_src_pos);
1078EXPORT_SYMBOL(omap_get_dma_dst_pos); 1088EXPORT_SYMBOL(omap_get_dma_dst_pos);
1089EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
1079EXPORT_SYMBOL(omap_clear_dma); 1090EXPORT_SYMBOL(omap_clear_dma);
1080EXPORT_SYMBOL(omap_set_dma_priority); 1091EXPORT_SYMBOL(omap_set_dma_priority);
1081EXPORT_SYMBOL(omap_request_dma); 1092EXPORT_SYMBOL(omap_request_dma);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
new file mode 100644
index 00000000000..a1468d7326e
--- /dev/null
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -0,0 +1,260 @@
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
54static struct dmtimer_info_struct {
55 struct list_head unused_timers;
56 struct list_head reserved_timers;
57} dm_timer_info;
58
59static 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
72static spinlock_t dm_timer_lock;
73
74
75inline 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
82u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
83{
84 return omap_readl(timer->base + reg);
85}
86
87int 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
100void 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
111static 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
122struct 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
140void 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
151void 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
157unsigned 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
162void 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
167void 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
175void omap_dm_timer_trigger(struct omap_dm_timer *timer)
176{
177 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1);
178}
179
180void 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
189void 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
198void 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
207unsigned 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
212void 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
217void 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
222void 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
227void 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
237static 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
253static int __init omap_dm_timer_init(void)
254{
255 if (cpu_is_omap16xx())
256 __dm_timer_init();
257 return 0;
258}
259
260arch_initcall(omap_dm_timer_init);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index aa481ea3d70..55059a24ad4 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Support functions for OMAP GPIO 4 * Support functions for OMAP GPIO
5 * 5 *
6 * Copyright (C) 2003 Nokia Corporation 6 * Copyright (C) 2003-2005 Nokia Corporation
7 * Written by Juha Yrjölä <juha.yrjola@nokia.com> 7 * Written by Juha Yrjölä <juha.yrjola@nokia.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,11 @@
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/ptrace.h> 19#include <linux/ptrace.h>
20#include <linux/sysdev.h>
21#include <linux/err.h>
20 22
21#include <asm/hardware.h> 23#include <asm/hardware.h>
24#include <asm/hardware/clock.h>
22#include <asm/irq.h> 25#include <asm/irq.h>
23#include <asm/arch/irqs.h> 26#include <asm/arch/irqs.h>
24#include <asm/arch/gpio.h> 27#include <asm/arch/gpio.h>
@@ -29,7 +32,7 @@
29/* 32/*
30 * OMAP1510 GPIO registers 33 * OMAP1510 GPIO registers
31 */ 34 */
32#define OMAP1510_GPIO_BASE 0xfffce000 35#define OMAP1510_GPIO_BASE (void __iomem *)0xfffce000
33#define OMAP1510_GPIO_DATA_INPUT 0x00 36#define OMAP1510_GPIO_DATA_INPUT 0x00
34#define OMAP1510_GPIO_DATA_OUTPUT 0x04 37#define OMAP1510_GPIO_DATA_OUTPUT 0x04
35#define OMAP1510_GPIO_DIR_CONTROL 0x08 38#define OMAP1510_GPIO_DIR_CONTROL 0x08
@@ -43,34 +46,37 @@
43/* 46/*
44 * OMAP1610 specific GPIO registers 47 * OMAP1610 specific GPIO registers
45 */ 48 */
46#define OMAP1610_GPIO1_BASE 0xfffbe400 49#define OMAP1610_GPIO1_BASE (void __iomem *)0xfffbe400
47#define OMAP1610_GPIO2_BASE 0xfffbec00 50#define OMAP1610_GPIO2_BASE (void __iomem *)0xfffbec00
48#define OMAP1610_GPIO3_BASE 0xfffbb400 51#define OMAP1610_GPIO3_BASE (void __iomem *)0xfffbb400
49#define OMAP1610_GPIO4_BASE 0xfffbbc00 52#define OMAP1610_GPIO4_BASE (void __iomem *)0xfffbbc00
50#define OMAP1610_GPIO_REVISION 0x0000 53#define OMAP1610_GPIO_REVISION 0x0000
51#define OMAP1610_GPIO_SYSCONFIG 0x0010 54#define OMAP1610_GPIO_SYSCONFIG 0x0010
52#define OMAP1610_GPIO_SYSSTATUS 0x0014 55#define OMAP1610_GPIO_SYSSTATUS 0x0014
53#define OMAP1610_GPIO_IRQSTATUS1 0x0018 56#define OMAP1610_GPIO_IRQSTATUS1 0x0018
54#define OMAP1610_GPIO_IRQENABLE1 0x001c 57#define OMAP1610_GPIO_IRQENABLE1 0x001c
58#define OMAP1610_GPIO_WAKEUPENABLE 0x0028
55#define OMAP1610_GPIO_DATAIN 0x002c 59#define OMAP1610_GPIO_DATAIN 0x002c
56#define OMAP1610_GPIO_DATAOUT 0x0030 60#define OMAP1610_GPIO_DATAOUT 0x0030
57#define OMAP1610_GPIO_DIRECTION 0x0034 61#define OMAP1610_GPIO_DIRECTION 0x0034
58#define OMAP1610_GPIO_EDGE_CTRL1 0x0038 62#define OMAP1610_GPIO_EDGE_CTRL1 0x0038
59#define OMAP1610_GPIO_EDGE_CTRL2 0x003c 63#define OMAP1610_GPIO_EDGE_CTRL2 0x003c
60#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c 64#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
65#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8
61#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 66#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
62#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc 67#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
68#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8
63#define OMAP1610_GPIO_SET_DATAOUT 0x00f0 69#define OMAP1610_GPIO_SET_DATAOUT 0x00f0
64 70
65/* 71/*
66 * OMAP730 specific GPIO registers 72 * OMAP730 specific GPIO registers
67 */ 73 */
68#define OMAP730_GPIO1_BASE 0xfffbc000 74#define OMAP730_GPIO1_BASE (void __iomem *)0xfffbc000
69#define OMAP730_GPIO2_BASE 0xfffbc800 75#define OMAP730_GPIO2_BASE (void __iomem *)0xfffbc800
70#define OMAP730_GPIO3_BASE 0xfffbd000 76#define OMAP730_GPIO3_BASE (void __iomem *)0xfffbd000
71#define OMAP730_GPIO4_BASE 0xfffbd800 77#define OMAP730_GPIO4_BASE (void __iomem *)0xfffbd800
72#define OMAP730_GPIO5_BASE 0xfffbe000 78#define OMAP730_GPIO5_BASE (void __iomem *)0xfffbe000
73#define OMAP730_GPIO6_BASE 0xfffbe800 79#define OMAP730_GPIO6_BASE (void __iomem *)0xfffbe800
74#define OMAP730_GPIO_DATA_INPUT 0x00 80#define OMAP730_GPIO_DATA_INPUT 0x00
75#define OMAP730_GPIO_DATA_OUTPUT 0x04 81#define OMAP730_GPIO_DATA_OUTPUT 0x04
76#define OMAP730_GPIO_DIR_CONTROL 0x08 82#define OMAP730_GPIO_DIR_CONTROL 0x08
@@ -78,14 +84,43 @@
78#define OMAP730_GPIO_INT_MASK 0x10 84#define OMAP730_GPIO_INT_MASK 0x10
79#define OMAP730_GPIO_INT_STATUS 0x14 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#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) 114#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
82 115
83struct gpio_bank { 116struct gpio_bank {
84 u32 base; 117 void __iomem *base;
85 u16 irq; 118 u16 irq;
86 u16 virtual_irq_start; 119 u16 virtual_irq_start;
87 u8 method; 120 int method;
88 u32 reserved_map; 121 u32 reserved_map;
122 u32 suspend_wakeup;
123 u32 saved_wakeup;
89 spinlock_t lock; 124 spinlock_t lock;
90}; 125};
91 126
@@ -93,8 +128,9 @@ struct gpio_bank {
93#define METHOD_GPIO_1510 1 128#define METHOD_GPIO_1510 1
94#define METHOD_GPIO_1610 2 129#define METHOD_GPIO_1610 2
95#define METHOD_GPIO_730 3 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
98static struct gpio_bank gpio_bank_1610[5] = { 134static struct gpio_bank gpio_bank_1610[5] = {
99 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO}, 135 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
100 { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 }, 136 { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
@@ -123,6 +159,15 @@ static struct gpio_bank gpio_bank_730[7] = {
123}; 159};
124#endif 160#endif
125 161
162#ifdef CONFIG_ARCH_OMAP24XX
163static 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
126static struct gpio_bank *gpio_bank; 171static struct gpio_bank *gpio_bank;
127static int gpio_bank_count; 172static int gpio_bank_count;
128 173
@@ -149,14 +194,23 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
149 return &gpio_bank[1 + (gpio >> 5)]; 194 return &gpio_bank[1 + (gpio >> 5)];
150 } 195 }
151#endif 196#endif
197#ifdef CONFIG_ARCH_OMAP24XX
198 if (cpu_is_omap24xx())
199 return &gpio_bank[gpio >> 5];
200#endif
152} 201}
153 202
154static inline int get_gpio_index(int gpio) 203static inline int get_gpio_index(int gpio)
155{ 204{
205#ifdef CONFIG_ARCH_OMAP730
156 if (cpu_is_omap730()) 206 if (cpu_is_omap730())
157 return gpio & 0x1f; 207 return gpio & 0x1f;
158 else 208#endif
159 return gpio & 0x0f; 209#ifdef CONFIG_ARCH_OMAP24XX
210 if (cpu_is_omap24xx())
211 return gpio & 0x1f;
212#endif
213 return gpio & 0x0f;
160} 214}
161 215
162static inline int gpio_valid(int gpio) 216static inline int gpio_valid(int gpio)
@@ -180,6 +234,10 @@ static inline int gpio_valid(int gpio)
180 if (cpu_is_omap730() && gpio < 192) 234 if (cpu_is_omap730() && gpio < 192)
181 return 0; 235 return 0;
182#endif 236#endif
237#ifdef CONFIG_ARCH_OMAP24XX
238 if (cpu_is_omap24xx() && gpio < 128)
239 return 0;
240#endif
183 return -1; 241 return -1;
184} 242}
185 243
@@ -195,7 +253,7 @@ static int check_gpio(int gpio)
195 253
196static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) 254static 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 u32 l; 257 u32 l;
200 258
201 switch (bank->method) { 259 switch (bank->method) {
@@ -211,6 +269,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
211 case METHOD_GPIO_730: 269 case METHOD_GPIO_730:
212 reg += OMAP730_GPIO_DIR_CONTROL; 270 reg += OMAP730_GPIO_DIR_CONTROL;
213 break; 271 break;
272 case METHOD_GPIO_24XX:
273 reg += OMAP24XX_GPIO_OE;
274 break;
214 } 275 }
215 l = __raw_readl(reg); 276 l = __raw_readl(reg);
216 if (is_input) 277 if (is_input)
@@ -234,7 +295,7 @@ void omap_set_gpio_direction(int gpio, int is_input)
234 295
235static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) 296static 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 u32 l = 0; 299 u32 l = 0;
239 300
240 switch (bank->method) { 301 switch (bank->method) {
@@ -269,6 +330,13 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
269 else 330 else
270 l &= ~(1 << gpio); 331 l &= ~(1 << gpio);
271 break; 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 default: 340 default:
273 BUG(); 341 BUG();
274 return; 342 return;
@@ -291,7 +359,7 @@ void omap_set_gpio_dataout(int gpio, int enable)
291int omap_get_gpio_datain(int gpio) 359int omap_get_gpio_datain(int gpio)
292{ 360{
293 struct gpio_bank *bank; 361 struct gpio_bank *bank;
294 u32 reg; 362 void __iomem *reg;
295 363
296 if (check_gpio(gpio) < 0) 364 if (check_gpio(gpio) < 0)
297 return -1; 365 return -1;
@@ -310,109 +378,132 @@ int omap_get_gpio_datain(int gpio)
310 case METHOD_GPIO_730: 378 case METHOD_GPIO_730:
311 reg += OMAP730_GPIO_DATA_INPUT; 379 reg += OMAP730_GPIO_DATA_INPUT;
312 break; 380 break;
381 case METHOD_GPIO_24XX:
382 reg += OMAP24XX_GPIO_DATAIN;
383 break;
313 default: 384 default:
314 BUG(); 385 BUG();
315 return -1; 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
320static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) 392#define MOD_REG_BIT(reg, bit_mask, set) \
393do { \
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
400static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger)
321{ 401{
322 u32 reg = bank->base; 402 u32 gpio_bit = 1 << gpio;
323 u32 l; 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
416static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
417{
418 void __iomem *reg = bank->base;
419 u32 l = 0;
324 420
325 switch (bank->method) { 421 switch (bank->method) {
326 case METHOD_MPUIO: 422 case METHOD_MPUIO:
327 reg += OMAP_MPUIO_GPIO_INT_EDGE; 423 reg += OMAP_MPUIO_GPIO_INT_EDGE;
328 l = __raw_readl(reg); 424 l = __raw_readl(reg);
329 if (edge == OMAP_GPIO_RISING_EDGE) 425 if (trigger == IRQT_RISING)
330 l |= 1 << gpio; 426 l |= 1 << gpio;
331 else 427 else if (trigger == IRQT_FALLING)
332 l &= ~(1 << gpio); 428 l &= ~(1 << gpio);
333 __raw_writel(l, reg); 429 else
430 goto bad;
334 break; 431 break;
335 case METHOD_GPIO_1510: 432 case METHOD_GPIO_1510:
336 reg += OMAP1510_GPIO_INT_CONTROL; 433 reg += OMAP1510_GPIO_INT_CONTROL;
337 l = __raw_readl(reg); 434 l = __raw_readl(reg);
338 if (edge == OMAP_GPIO_RISING_EDGE) 435 if (trigger == IRQT_RISING)
339 l |= 1 << gpio; 436 l |= 1 << gpio;
340 else 437 else if (trigger == IRQT_FALLING)
341 l &= ~(1 << gpio); 438 l &= ~(1 << gpio);
342 __raw_writel(l, reg); 439 else
440 goto bad;
343 break; 441 break;
344 case METHOD_GPIO_1610: 442 case METHOD_GPIO_1610:
345 edge &= 0x03;
346 if (gpio & 0x08) 443 if (gpio & 0x08)
347 reg += OMAP1610_GPIO_EDGE_CTRL2; 444 reg += OMAP1610_GPIO_EDGE_CTRL2;
348 else 445 else
349 reg += OMAP1610_GPIO_EDGE_CTRL1; 446 reg += OMAP1610_GPIO_EDGE_CTRL1;
350 gpio &= 0x07; 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 l = __raw_readl(reg); 453 l = __raw_readl(reg);
352 l &= ~(3 << (gpio << 1)); 454 l &= ~(3 << (gpio << 1));
353 l |= edge << (gpio << 1); 455 l |= trigger << (gpio << 1);
354 __raw_writel(l, reg);
355 break; 456 break;
356 case METHOD_GPIO_730: 457 case METHOD_GPIO_730:
357 reg += OMAP730_GPIO_INT_CONTROL; 458 reg += OMAP730_GPIO_INT_CONTROL;
358 l = __raw_readl(reg); 459 l = __raw_readl(reg);
359 if (edge == OMAP_GPIO_RISING_EDGE) 460 if (trigger == IRQT_RISING)
360 l |= 1 << gpio; 461 l |= 1 << gpio;
361 else 462 else if (trigger == IRQT_FALLING)
362 l &= ~(1 << gpio); 463 l &= ~(1 << gpio);
363 __raw_writel(l, reg); 464 else
465 goto bad;
466 break;
467 case METHOD_GPIO_24XX:
468 set_24xx_gpio_triggering(reg, gpio, trigger);
364 break; 469 break;
365 default: 470 default:
366 BUG(); 471 BUG();
367 return; 472 goto bad;
368 } 473 }
474 __raw_writel(l, reg);
475 return 0;
476bad:
477 return -EINVAL;
369} 478}
370 479
371void omap_set_gpio_edge_ctrl(int gpio, int edge) 480static int gpio_irq_type(unsigned irq, unsigned type)
372{ 481{
373 struct gpio_bank *bank; 482 struct gpio_bank *bank;
483 unsigned gpio;
484 int retval;
485
486 if (irq > IH_MPUIO_BASE)
487 gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
488 else
489 gpio = irq - IH_GPIO_BASE;
374 490
375 if (check_gpio(gpio) < 0) 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 bank = get_gpio_bank(gpio); 497 bank = get_gpio_bank(gpio);
378 spin_lock(&bank->lock); 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 spin_unlock(&bank->lock); 500 spin_unlock(&bank->lock);
381} 501 return retval;
382
383
384static 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} 502}
412 503
413static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) 504static 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 switch (bank->method) { 508 switch (bank->method) {
418 case METHOD_MPUIO: 509 case METHOD_MPUIO:
@@ -428,6 +519,9 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
428 case METHOD_GPIO_730: 519 case METHOD_GPIO_730:
429 reg += OMAP730_GPIO_INT_STATUS; 520 reg += OMAP730_GPIO_INT_STATUS;
430 break; 521 break;
522 case METHOD_GPIO_24XX:
523 reg += OMAP24XX_GPIO_IRQSTATUS1;
524 break;
431 default: 525 default:
432 BUG(); 526 BUG();
433 return; 527 return;
@@ -442,7 +536,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
442 536
443static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) 537static 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 u32 l; 540 u32 l;
447 541
448 switch (bank->method) { 542 switch (bank->method) {
@@ -477,6 +571,13 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
477 else 571 else
478 l |= gpio_mask; 572 l |= gpio_mask;
479 break; 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 default: 581 default:
481 BUG(); 582 BUG();
482 return; 583 return;
@@ -489,6 +590,50 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
489 _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable); 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 */
601static 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 */
621static 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
492int omap_request_gpio(int gpio) 637int omap_request_gpio(int gpio)
493{ 638{
494 struct gpio_bank *bank; 639 struct gpio_bank *bank;
@@ -505,15 +650,33 @@ int omap_request_gpio(int gpio)
505 return -1; 650 return -1;
506 } 651 }
507 bank->reserved_map |= (1 << get_gpio_index(gpio)); 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#ifdef CONFIG_ARCH_OMAP1510 657#ifdef CONFIG_ARCH_OMAP1510
509 if (bank->method == METHOD_GPIO_1510) { 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 reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; 662 reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
514 __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); 663 __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
515 } 664 }
516#endif 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 spin_unlock(&bank->lock); 680 spin_unlock(&bank->lock);
518 681
519 return 0; 682 return 0;
@@ -533,6 +696,20 @@ void omap_free_gpio(int gpio)
533 spin_unlock(&bank->lock); 696 spin_unlock(&bank->lock);
534 return; 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 bank->reserved_map &= ~(1 << get_gpio_index(gpio)); 713 bank->reserved_map &= ~(1 << get_gpio_index(gpio));
537 _set_gpio_direction(bank, get_gpio_index(gpio), 1); 714 _set_gpio_direction(bank, get_gpio_index(gpio), 1);
538 _set_gpio_irqenable(bank, gpio, 0); 715 _set_gpio_irqenable(bank, gpio, 0);
@@ -552,7 +729,7 @@ void omap_free_gpio(int gpio)
552static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, 729static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
553 struct pt_regs *regs) 730 struct pt_regs *regs)
554{ 731{
555 u32 isr_reg = 0; 732 void __iomem *isr_reg = NULL;
556 u32 isr; 733 u32 isr;
557 unsigned int gpio_irq; 734 unsigned int gpio_irq;
558 struct gpio_bank *bank; 735 struct gpio_bank *bank;
@@ -574,24 +751,30 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
574 if (bank->method == METHOD_GPIO_730) 751 if (bank->method == METHOD_GPIO_730)
575 isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; 752 isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
576#endif 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); 759 while(1) {
579 _enable_gpio_irqbank(bank, isr, 0); 760 isr = __raw_readl(isr_reg);
580 _clear_gpio_irqbank(bank, isr); 761 _enable_gpio_irqbank(bank, isr, 0);
581 _enable_gpio_irqbank(bank, isr, 1); 762 _clear_gpio_irqbank(bank, isr);
582 desc->chip->unmask(irq); 763 _enable_gpio_irqbank(bank, isr, 1);
583 764 desc->chip->unmask(irq);
584 if (unlikely(!isr)) 765
585 return; 766 if (!isr)
586 767 break;
587 gpio_irq = bank->virtual_irq_start; 768
588 for (; isr != 0; isr >>= 1, gpio_irq++) { 769 gpio_irq = bank->virtual_irq_start;
589 struct irqdesc *d; 770 for (; isr != 0; isr >>= 1, gpio_irq++) {
590 if (!(isr & 1)) 771 struct irqdesc *d;
591 continue; 772 if (!(isr & 1))
592 d = irq_desc + gpio_irq; 773 continue;
593 desc_handle_irq(gpio_irq, d, regs); 774 d = irq_desc + gpio_irq;
594 } 775 desc_handle_irq(gpio_irq, d, regs);
776 }
777 }
595} 778}
596 779
597static void gpio_ack_irq(unsigned int irq) 780static void gpio_ack_irq(unsigned int irq)
@@ -613,14 +796,10 @@ static void gpio_mask_irq(unsigned int irq)
613static void gpio_unmask_irq(unsigned int irq) 796static void gpio_unmask_irq(unsigned int irq)
614{ 797{
615 unsigned int gpio = irq - IH_GPIO_BASE; 798 unsigned int gpio = irq - IH_GPIO_BASE;
799 unsigned int gpio_idx = get_gpio_index(gpio);
616 struct gpio_bank *bank = get_gpio_bank(gpio); 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) { 802 _set_gpio_irqenable(bank, gpio_idx, 1);
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);
624} 803}
625 804
626static void mpuio_ack_irq(unsigned int irq) 805static void mpuio_ack_irq(unsigned int irq)
@@ -645,9 +824,11 @@ static void mpuio_unmask_irq(unsigned int irq)
645} 824}
646 825
647static struct irqchip gpio_irq_chip = { 826static struct irqchip gpio_irq_chip = {
648 .ack = gpio_ack_irq, 827 .ack = gpio_ack_irq,
649 .mask = gpio_mask_irq, 828 .mask = gpio_mask_irq,
650 .unmask = gpio_unmask_irq, 829 .unmask = gpio_unmask_irq,
830 .set_type = gpio_irq_type,
831 .set_wake = gpio_wake_enable,
651}; 832};
652 833
653static struct irqchip mpuio_irq_chip = { 834static struct irqchip mpuio_irq_chip = {
@@ -657,6 +838,7 @@ static struct irqchip mpuio_irq_chip = {
657}; 838};
658 839
659static int initialized = 0; 840static int initialized = 0;
841static struct clk * gpio_ck = NULL;
660 842
661static int __init _omap_gpio_init(void) 843static int __init _omap_gpio_init(void)
662{ 844{
@@ -665,6 +847,14 @@ static int __init _omap_gpio_init(void)
665 847
666 initialized = 1; 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#ifdef CONFIG_ARCH_OMAP1510 858#ifdef CONFIG_ARCH_OMAP1510
669 if (cpu_is_omap1510()) { 859 if (cpu_is_omap1510()) {
670 printk(KERN_INFO "OMAP1510 GPIO hardware\n"); 860 printk(KERN_INFO "OMAP1510 GPIO hardware\n");
@@ -674,7 +864,7 @@ static int __init _omap_gpio_init(void)
674#endif 864#endif
675#if defined(CONFIG_ARCH_OMAP16XX) 865#if defined(CONFIG_ARCH_OMAP16XX)
676 if (cpu_is_omap16xx()) { 866 if (cpu_is_omap16xx()) {
677 int rev; 867 u32 rev;
678 868
679 gpio_bank_count = 5; 869 gpio_bank_count = 5;
680 gpio_bank = gpio_bank_1610; 870 gpio_bank = gpio_bank_1610;
@@ -690,6 +880,17 @@ static int __init _omap_gpio_init(void)
690 gpio_bank = gpio_bank_730; 880 gpio_bank = gpio_bank_730;
691 } 881 }
692#endif 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 for (i = 0; i < gpio_bank_count; i++) { 894 for (i = 0; i < gpio_bank_count; i++) {
694 int j, gpio_count = 16; 895 int j, gpio_count = 16;
695 896
@@ -710,6 +911,7 @@ static int __init _omap_gpio_init(void)
710 if (bank->method == METHOD_GPIO_1610) { 911 if (bank->method == METHOD_GPIO_1610) {
711 __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); 912 __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
712 __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); 913 __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
914 __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
713 } 915 }
714#endif 916#endif
715#ifdef CONFIG_ARCH_OMAP730 917#ifdef CONFIG_ARCH_OMAP730
@@ -720,6 +922,14 @@ static int __init _omap_gpio_init(void)
720 gpio_count = 32; /* 730 has 32-bit GPIOs */ 922 gpio_count = 32; /* 730 has 32-bit GPIOs */
721 } 923 }
722#endif 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 for (j = bank->virtual_irq_start; 933 for (j = bank->virtual_irq_start;
724 j < bank->virtual_irq_start + gpio_count; j++) { 934 j < bank->virtual_irq_start + gpio_count; j++) {
725 if (bank->method == METHOD_MPUIO) 935 if (bank->method == METHOD_MPUIO)
@@ -735,12 +945,97 @@ static int __init _omap_gpio_init(void)
735 945
736 /* Enable system clock for GPIO module. 946 /* Enable system clock for GPIO module.
737 * The CAM_CLK_CTRL *is* really the right place. */ 947 * The CAM_CLK_CTRL *is* really the right place. */
738 if (cpu_is_omap1610() || cpu_is_omap1710()) 948 if (cpu_is_omap16xx())
739 omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); 949 omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
740 950
741 return 0; 951 return 0;
742} 952}
743 953
954#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
955static 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
993static 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
1027static struct sysdev_class omap_gpio_sysclass = {
1028 set_kset_name("gpio"),
1029 .suspend = omap_gpio_suspend,
1030 .resume = omap_gpio_resume,
1031};
1032
1033static struct sys_device omap_gpio_device = {
1034 .id = 0,
1035 .cls = &omap_gpio_sysclass,
1036};
1037#endif
1038
744/* 1039/*
745 * This may get called early from board specific init 1040 * This may get called early from board specific init
746 */ 1041 */
@@ -752,11 +1047,30 @@ int omap_gpio_init(void)
752 return 0; 1047 return 0;
753} 1048}
754 1049
1050static 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
755EXPORT_SYMBOL(omap_request_gpio); 1070EXPORT_SYMBOL(omap_request_gpio);
756EXPORT_SYMBOL(omap_free_gpio); 1071EXPORT_SYMBOL(omap_free_gpio);
757EXPORT_SYMBOL(omap_set_gpio_direction); 1072EXPORT_SYMBOL(omap_set_gpio_direction);
758EXPORT_SYMBOL(omap_set_gpio_dataout); 1073EXPORT_SYMBOL(omap_set_gpio_dataout);
759EXPORT_SYMBOL(omap_get_gpio_datain); 1074EXPORT_SYMBOL(omap_get_gpio_datain);
760EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
761 1075
762arch_initcall(omap_gpio_init); 1076arch_initcall(omap_gpio_sysinit);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 43567d5eddd..9c9b7df3faf 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,6 +27,7 @@
27#include <asm/arch/dma.h> 27#include <asm/arch/dma.h>
28#include <asm/arch/mux.h> 28#include <asm/arch/mux.h>
29#include <asm/arch/irqs.h> 29#include <asm/arch/irqs.h>
30#include <asm/arch/dsp_common.h>
30#include <asm/arch/mcbsp.h> 31#include <asm/arch/mcbsp.h>
31 32
32#include <asm/hardware/clock.h> 33#include <asm/hardware/clock.h>
@@ -187,9 +188,6 @@ static int omap_mcbsp_check(unsigned int id)
187 return -1; 188 return -1;
188} 189}
189 190
190#define EN_XORPCK 1
191#define DSP_RSTCT2 0xe1008014
192
193static void omap_mcbsp_dsp_request(void) 191static void omap_mcbsp_dsp_request(void)
194{ 192{
195 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 193 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
@@ -198,6 +196,11 @@ static void omap_mcbsp_dsp_request(void)
198 196
199 /* enable 12MHz clock to mcbsp 1 & 3 */ 197 /* enable 12MHz clock to mcbsp 1 & 3 */
200 clk_use(mcbsp_dspxor_ck); 198 clk_use(mcbsp_dspxor_ck);
199
200 /*
201 * DSP external peripheral reset
202 * FIXME: This should be moved to dsp code
203 */
201 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, 204 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
202 DSP_RSTCT2); 205 DSP_RSTCT2);
203 } 206 }
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index ea7b955b9c8..64482040f89 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -48,6 +48,9 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
48 pull_orig = 0, pull = 0; 48 pull_orig = 0, pull = 0;
49 unsigned int mask, warn = 0; 49 unsigned int mask, warn = 0;
50 50
51 if (cpu_is_omap7xx())
52 return 0;
53
51 if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { 54 if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
52 printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); 55 printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
53 return -EINVAL; 56 return -EINVAL;
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 2ede2ee8cae..1fb16f9edfd 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
28#include <linux/types.h> 29#include <linux/types.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
30#include <linux/kernel.h> 31#include <linux/kernel.h>
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index e6536b16c38..e15c6c1ddec 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -39,24 +39,32 @@
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/pm.h> 41#include <linux/pm.h>
42#include <linux/interrupt.h>
42 43
43#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/irq.h>
44#include <asm/mach/time.h> 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#include <asm/arch/pm.h> 52#include <asm/arch/pm.h>
49#include <asm/arch/mux.h> 53#include <asm/arch/mux.h>
50#include <asm/arch/tc.h>
51#include <asm/arch/tps65010.h> 54#include <asm/arch/tps65010.h>
55#include <asm/arch/dsp_common.h>
52 56
53#include "clock.h" 57#include "clock.h"
58#include "sram.h"
54 59
55static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; 60static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
56static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; 61static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
57static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; 62static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
58static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; 63static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
59 64
65static void (*omap_sram_idle)(void) = NULL;
66static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
67
60/* 68/*
61 * Let's power down on idle, but only if we are really 69 * Let's power down on idle, but only if we are really
62 * idle, because once we start down the path of 70 * idle, because once we start down the path of
@@ -65,7 +73,6 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
65 */ 73 */
66void omap_pm_idle(void) 74void omap_pm_idle(void)
67{ 75{
68 int (*func_ptr)(void) = 0;
69 unsigned int mask32 = 0; 76 unsigned int mask32 = 0;
70 77
71 /* 78 /*
@@ -84,6 +91,13 @@ void omap_pm_idle(void)
84 mask32 = omap_readl(ARM_SYSST); 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 * Since an interrupt may set up a timer, we don't want to 101 * Since an interrupt may set up a timer, we don't want to
88 * reprogram the hardware timer with interrupts enabled. 102 * reprogram the hardware timer with interrupts enabled.
89 * Re-enable interrupts only after returning from idle. 103 * Re-enable interrupts only after returning from idle.
@@ -92,18 +106,9 @@ void omap_pm_idle(void)
92 106
93 if ((mask32 & DSP_IDLE) == 0) { 107 if ((mask32 & DSP_IDLE) == 0) {
94 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); 108 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
95 } else { 109 } else
96 110 omap_sram_idle();
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 111
105 func_ptr();
106 }
107 local_fiq_enable(); 112 local_fiq_enable();
108 local_irq_enable(); 113 local_irq_enable();
109} 114}
@@ -115,58 +120,55 @@ void omap_pm_idle(void)
115 */ 120 */
116static void omap_pm_wakeup_setup(void) 121static void omap_pm_wakeup_setup(void)
117{ 122{
118 /* 123 u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
119 * Enable ARM XOR clock and release peripheral from reset by 124 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
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
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 125
128 /* 126 /*
129 * Turn off all interrupts except L1-2nd level cascade, 127 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
130 * and the L2 wakeup interrupts: keypad and UART2. 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()) { 139 if (cpu_is_omap1510())
136 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR); 140 omap_writel(~level2_wake, OMAP_IH2_MIR);
137 }
138 141
142 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
139 if (cpu_is_omap16xx()) { 143 if (cpu_is_omap16xx()) {
140 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR); 144 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
141 145 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
142 omap_writel(~0x0, OMAP_IH2_1_MIR);
143 omap_writel(~0x0, OMAP_IH2_2_MIR); 146 omap_writel(~0x0, OMAP_IH2_2_MIR);
144 omap_writel(~0x0, OMAP_IH2_3_MIR); 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 omap_writel(1, OMAP_IH1_CONTROL); 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
154void omap_pm_suspend(void) 155void omap_pm_suspend(void)
155{ 156{
156 unsigned int mask32 = 0;
157 unsigned long arg0 = 0, arg1 = 0; 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);
160
161 omap_serial_wake_trigger(1);
162 162
163 if (machine_is_omap_osk()) { 163 if (machine_is_omap_osk()) {
164 /* Stop LED1 (D9) blink */ 164 /* Stop LED1 (D9) blink */
165 tps65010_set_led(LED1, OFF); 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 local_irq_disable(); 174 local_irq_disable();
@@ -207,6 +209,8 @@ void omap_pm_suspend(void)
207 ARM_SAVE(ARM_CKCTL); 209 ARM_SAVE(ARM_CKCTL);
208 ARM_SAVE(ARM_IDLECT1); 210 ARM_SAVE(ARM_IDLECT1);
209 ARM_SAVE(ARM_IDLECT2); 211 ARM_SAVE(ARM_IDLECT2);
212 if (!(cpu_is_omap1510()))
213 ARM_SAVE(ARM_IDLECT3);
210 ARM_SAVE(ARM_EWUPCT); 214 ARM_SAVE(ARM_EWUPCT);
211 ARM_SAVE(ARM_RSTCT1); 215 ARM_SAVE(ARM_RSTCT1);
212 ARM_SAVE(ARM_RSTCT2); 216 ARM_SAVE(ARM_RSTCT2);
@@ -214,42 +218,12 @@ void omap_pm_suspend(void)
214 ULPD_SAVE(ULPD_CLOCK_CTRL); 218 ULPD_SAVE(ULPD_CLOCK_CTRL);
215 ULPD_SAVE(ULPD_STATUS_REQ); 219 ULPD_SAVE(ULPD_STATUS_REQ);
216 220
217 /* 221 /* (Step 3 removed - we now allow deep sleep by default) */
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 }
231
232 /* configure LOW_PWR pin */
233 omap_cfg_reg(T20_1610_LOW_PWR);
234 222
235 /* 223 /*
236 * Step 4: OMAP DSP Shutdown 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
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 227
254 /* 228 /*
255 * Step 5: Wakeup Event Setup 229 * Step 5: Wakeup Event Setup
@@ -258,24 +232,9 @@ void omap_pm_suspend(void)
258 omap_pm_wakeup_setup(); 232 omap_pm_wakeup_setup();
259 233
260 /* 234 /*
261 * Step 6a: ARM and Traffic controller shutdown 235 * Step 6: ARM and Traffic controller shutdown
262 *
263 * Step 6 starts here with clock and watchdog disable
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 /* disable ARM watchdog */ 238 /* disable ARM watchdog */
280 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); 239 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
281 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); 240 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
@@ -295,47 +254,24 @@ void omap_pm_suspend(void)
295 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; 254 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
296 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; 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 * Step 6c: ARM and Traffic controller shutdown 258 * Step 6c: ARM and Traffic controller shutdown
308 * 259 *
309 * Jump to assembly code. The processor will stay there 260 * Jump to assembly code. The processor will stay there
310 * until wake up. 261 * until wake up.
311 */ 262 */
312 263 omap_sram_suspend(arg0, arg1);
313 func_ptr(arg0, arg1);
314 264
315 /* 265 /*
316 * If we are here, processor is woken up! 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 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did 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 ARM_RESTORE(ARM_CKCTL); 275 ARM_RESTORE(ARM_CKCTL);
340 ARM_RESTORE(ARM_EWUPCT); 276 ARM_RESTORE(ARM_EWUPCT);
341 ARM_RESTORE(ARM_RSTCT1); 277 ARM_RESTORE(ARM_RSTCT1);
@@ -366,6 +302,8 @@ void omap_pm_suspend(void)
366 MPUI1610_RESTORE(OMAP_IH2_3_MIR); 302 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
367 } 303 }
368 304
305 omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
306
369 /* 307 /*
370 * Reenable interrupts 308 * Reenable interrupts
371 */ 309 */
@@ -373,6 +311,8 @@ void omap_pm_suspend(void)
373 local_irq_enable(); 311 local_irq_enable();
374 local_fiq_enable(); 312 local_fiq_enable();
375 313
314 omap_serial_wake_trigger(0);
315
376 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); 316 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
377 317
378 if (machine_is_omap_osk()) { 318 if (machine_is_omap_osk()) {
@@ -401,6 +341,8 @@ static int omap_pm_read_proc(
401 ARM_SAVE(ARM_CKCTL); 341 ARM_SAVE(ARM_CKCTL);
402 ARM_SAVE(ARM_IDLECT1); 342 ARM_SAVE(ARM_IDLECT1);
403 ARM_SAVE(ARM_IDLECT2); 343 ARM_SAVE(ARM_IDLECT2);
344 if (!(cpu_is_omap1510()))
345 ARM_SAVE(ARM_IDLECT3);
404 ARM_SAVE(ARM_EWUPCT); 346 ARM_SAVE(ARM_EWUPCT);
405 ARM_SAVE(ARM_RSTCT1); 347 ARM_SAVE(ARM_RSTCT1);
406 ARM_SAVE(ARM_RSTCT2); 348 ARM_SAVE(ARM_RSTCT2);
@@ -436,6 +378,7 @@ static int omap_pm_read_proc(
436 "ARM_CKCTL_REG: 0x%-8x \n" 378 "ARM_CKCTL_REG: 0x%-8x \n"
437 "ARM_IDLECT1_REG: 0x%-8x \n" 379 "ARM_IDLECT1_REG: 0x%-8x \n"
438 "ARM_IDLECT2_REG: 0x%-8x \n" 380 "ARM_IDLECT2_REG: 0x%-8x \n"
381 "ARM_IDLECT3_REG: 0x%-8x \n"
439 "ARM_EWUPCT_REG: 0x%-8x \n" 382 "ARM_EWUPCT_REG: 0x%-8x \n"
440 "ARM_RSTCT1_REG: 0x%-8x \n" 383 "ARM_RSTCT1_REG: 0x%-8x \n"
441 "ARM_RSTCT2_REG: 0x%-8x \n" 384 "ARM_RSTCT2_REG: 0x%-8x \n"
@@ -449,6 +392,7 @@ static int omap_pm_read_proc(
449 ARM_SHOW(ARM_CKCTL), 392 ARM_SHOW(ARM_CKCTL),
450 ARM_SHOW(ARM_IDLECT1), 393 ARM_SHOW(ARM_IDLECT1),
451 ARM_SHOW(ARM_IDLECT2), 394 ARM_SHOW(ARM_IDLECT2),
395 ARM_SHOW(ARM_IDLECT3),
452 ARM_SHOW(ARM_EWUPCT), 396 ARM_SHOW(ARM_EWUPCT),
453 ARM_SHOW(ARM_RSTCT1), 397 ARM_SHOW(ARM_RSTCT1),
454 ARM_SHOW(ARM_RSTCT2), 398 ARM_SHOW(ARM_RSTCT2),
@@ -507,7 +451,7 @@ static void omap_pm_init_proc(void)
507 451
508 entry = create_proc_read_entry("driver/omap_pm", 452 entry = create_proc_read_entry("driver/omap_pm",
509 S_IWUSR | S_IRUGO, NULL, 453 S_IWUSR | S_IRUGO, NULL,
510 omap_pm_read_proc, 0); 454 omap_pm_read_proc, NULL);
511} 455}
512 456
513#endif /* DEBUG && CONFIG_PROC_FS */ 457#endif /* DEBUG && CONFIG_PROC_FS */
@@ -580,7 +524,21 @@ static int omap_pm_finish(suspend_state_t state)
580} 524}
581 525
582 526
583struct pm_ops omap_pm_ops ={ 527static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
528 struct pt_regs * regs)
529{
530 return IRQ_HANDLED;
531}
532
533static struct irqaction omap_wakeup_irq = {
534 .name = "peripheral wakeup",
535 .flags = SA_INTERRUPT,
536 .handler = omap_wakeup_interrupt
537};
538
539
540
541static struct pm_ops omap_pm_ops ={
584 .pm_disk_mode = 0, 542 .pm_disk_mode = 0,
585 .prepare = omap_pm_prepare, 543 .prepare = omap_pm_prepare,
586 .enter = omap_pm_enter, 544 .enter = omap_pm_enter,
@@ -590,42 +548,61 @@ struct pm_ops omap_pm_ops ={
590static int __init omap_pm_init(void) 548static int __init omap_pm_init(void)
591{ 549{
592 printk("Power Management for TI OMAP.\n"); 550 printk("Power Management for TI OMAP.\n");
593 pm_idle = omap_pm_idle;
594 /* 551 /*
595 * We copy the assembler sleep/wakeup routines to SRAM. 552 * We copy the assembler sleep/wakeup routines to SRAM.
596 * These routines need to be in SRAM as that's the only 553 * These routines need to be in SRAM as that's the only
597 * memory the MPU can see when it wakes up. 554 * memory the MPU can see when it wakes up.
598 */ 555 */
599
600#ifdef CONFIG_ARCH_OMAP1510
601 if (cpu_is_omap1510()) { 556 if (cpu_is_omap1510()) {
602 memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND, 557 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
603 omap1510_idle_loop_suspend, 558 omap1510_idle_loop_suspend_sz);
604 omap1510_idle_loop_suspend_sz); 559 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
605 memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend, 560 omap1510_cpu_suspend_sz);
606 omap1510_cpu_suspend_sz); 561 } else if (cpu_is_omap16xx()) {
607 } else 562 omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
608#endif 563 omap1610_idle_loop_suspend_sz);
609 if (cpu_is_omap1610() || cpu_is_omap1710()) { 564 omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
610 memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND, 565 omap1610_cpu_suspend_sz);
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);
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 pm_set_ops(&omap_pm_ops); 597 pm_set_ops(&omap_pm_ops);
624 598
625#if defined(DEBUG) && defined(CONFIG_PROC_FS) 599#if defined(DEBUG) && defined(CONFIG_PROC_FS)
626 omap_pm_init_proc(); 600 omap_pm_init_proc();
627#endif 601#endif
628 602
603 /* configure LOW_PWR pin */
604 omap_cfg_reg(T20_1610_LOW_PWR);
605
629 return 0; 606 return 0;
630} 607}
631__initcall(omap_pm_init); 608__initcall(omap_pm_init);
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
index 279490ce772..9f745836f6a 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/plat-omap/sleep.S
@@ -66,7 +66,7 @@ ENTRY(omap1510_idle_loop_suspend)
66 @ get ARM_IDLECT2 into r2 66 @ get ARM_IDLECT2 into r2
67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
68 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff 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 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 70 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
71 71
72 @ request ARM idle 72 @ request ARM idle
@@ -76,7 +76,7 @@ ENTRY(omap1510_idle_loop_suspend)
76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
77 77
78 mov r5, #IDLE_WAIT_CYCLES & 0xff 78 mov r5, #IDLE_WAIT_CYCLES & 0xff
79 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 79 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
80l_1510: subs r5, r5, #1 80l_1510: subs r5, r5, #1
81 bne l_1510 81 bne l_1510
82/* 82/*
@@ -96,7 +96,7 @@ l_1510: subs r5, r5, #1
96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
97 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 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
101ENTRY(omap1510_idle_loop_suspend_sz) 101ENTRY(omap1510_idle_loop_suspend_sz)
102 .word . - omap1510_idle_loop_suspend 102 .word . - omap1510_idle_loop_suspend
@@ -115,8 +115,8 @@ ENTRY(omap1610_idle_loop_suspend)
115 @ turn off clock domains 115 @ turn off clock domains
116 @ get ARM_IDLECT2 into r2 116 @ get ARM_IDLECT2 into r2
117 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 117 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
118 mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff 118 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
119 orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 119 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
120 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 120 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
121 121
122 @ request ARM idle 122 @ request ARM idle
@@ -126,7 +126,7 @@ ENTRY(omap1610_idle_loop_suspend)
126 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 126 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
127 127
128 mov r5, #IDLE_WAIT_CYCLES & 0xff 128 mov r5, #IDLE_WAIT_CYCLES & 0xff
129 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 129 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
130l_1610: subs r5, r5, #1 130l_1610: subs r5, r5, #1
131 bne l_1610 131 bne l_1610
132/* 132/*
@@ -146,7 +146,7 @@ l_1610: subs r5, r5, #1
146 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 146 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
147 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 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
151ENTRY(omap1610_idle_loop_suspend_sz) 151ENTRY(omap1610_idle_loop_suspend_sz)
152 .word . - omap1610_idle_loop_suspend 152 .word . - omap1610_idle_loop_suspend
@@ -208,7 +208,7 @@ ENTRY(omap1510_cpu_suspend)
208 208
209 @ turn off clock domains 209 @ turn off clock domains
210 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff 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 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 212 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
213 213
214 @ request ARM idle 214 @ request ARM idle
@@ -217,7 +217,7 @@ ENTRY(omap1510_cpu_suspend)
217 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 217 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
218 218
219 mov r5, #IDLE_WAIT_CYCLES & 0xff 219 mov r5, #IDLE_WAIT_CYCLES & 0xff
220 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 220 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
221l_1510_2: 221l_1510_2:
222 subs r5, r5, #1 222 subs r5, r5, #1
223 bne l_1510_2 223 bne l_1510_2
@@ -237,7 +237,7 @@ l_1510_2:
237 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 237 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
238 238
239 @ restore regs and return 239 @ restore regs and return
240 ldmfd sp!, {r0 - r12, pc} 240 ldmfd sp!, {r0 - r12, pc}
241 241
242ENTRY(omap1510_cpu_suspend_sz) 242ENTRY(omap1510_cpu_suspend_sz)
243 .word . - omap1510_cpu_suspend 243 .word . - omap1510_cpu_suspend
@@ -249,21 +249,26 @@ ENTRY(omap1610_cpu_suspend)
249 @ save registers on stack 249 @ save registers on stack
250 stmfd sp!, {r0 - r12, lr} 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 @ load base address of Traffic Controller 257 @ load base address of Traffic Controller
253 mov r4, #TCMIF_ASM_BASE & 0xff000000 258 mov r6, #TCMIF_ASM_BASE & 0xff000000
254 orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 259 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
255 orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 260 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
256 261
257 @ prepare to put SDRAM into self-refresh manually 262 @ prepare to put SDRAM into self-refresh manually
258 ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 263 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
259 orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 264 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
260 orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff 265 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
261 str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 266 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
262 267
263 @ prepare to put EMIFS to Sleep 268 @ prepare to put EMIFS to Sleep
264 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 269 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
265 orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff 270 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
266 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 271 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
267 272
268 @ load base address of ARM_IDLECT1 and ARM_IDLECT2 273 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
269 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 274 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
@@ -271,26 +276,22 @@ ENTRY(omap1610_cpu_suspend)
271 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 276 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
272 277
273 @ turn off clock domains 278 @ turn off clock domains
274 mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff 279 @ do not disable PERCK (0x04)
275 orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 280 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
276 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 281 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
277
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] 282 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
283 283
284 @ request ARM idle 284 @ request ARM idle
285 mov r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff 285 mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
286 orr r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00 286 orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
287 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 287 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
288 288
289 mov r5, #IDLE_WAIT_CYCLES & 0xff 289 @ disable instruction cache
290 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 290 mrc p15, 0, r9, c1, c0, 0
291l_1610_2: 291 bic r2, r9, #0x1000
292 subs r5, r5, #1 292 mcr p15, 0, r2, c1, c0, 0
293 bne l_1610_2 293 nop
294
294/* 295/*
295 * Let's wait for the next wake up event to wake us up. r0 can't be 296 * Let's wait for the next wake up event to wake us up. r0 can't be
296 * used here because r0 holds ARM_IDLECT1 297 * used here because r0 holds ARM_IDLECT1
@@ -301,13 +302,21 @@ l_1610_2:
301 * omap1610_cpu_suspend()'s resume point. 302 * omap1610_cpu_suspend()'s resume point.
302 * 303 *
303 * It will just start executing here, so we'll restore stuff from the 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 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 311 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
307 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 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 @ restore regs and return 318 @ restore regs and return
310 ldmfd sp!, {r0 - r12, pc} 319 ldmfd sp!, {r0 - r12, pc}
311 320
312ENTRY(omap1610_cpu_suspend_sz) 321ENTRY(omap1610_cpu_suspend_sz)
313 .word . - omap1610_cpu_suspend 322 .word . - omap1610_cpu_suspend
diff --git a/arch/arm/plat-omap/sram-fn.S b/arch/arm/plat-omap/sram-fn.S
new file mode 100644
index 00000000000..4bea36964a0
--- /dev/null
+++ b/arch/arm/plat-omap/sram-fn.S
@@ -0,0 +1,58 @@
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 */
22ENTRY(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
39newck:
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
45delay: sub r4, r4, #1
46 cmp r4, #0
47 bne delay
48
49lock: 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
55out:
56 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
57ENTRY(sram_reprogram_clock_sz)
58 .word . - sram_reprogram_clock
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
new file mode 100644
index 00000000000..7719a4062e3
--- /dev/null
+++ b/arch/arm/plat-omap/sram.c
@@ -0,0 +1,116 @@
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
29static unsigned long omap_sram_base;
30static unsigned long omap_sram_size;
31static 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 */
40void __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
61static 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 */
70void __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
87static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
88
89void 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
97void * 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
110void __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}
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
new file mode 100644
index 00000000000..71984efa6ae
--- /dev/null
+++ b/arch/arm/plat-omap/sram.h
@@ -0,0 +1,21 @@
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
14extern void * omap_sram_push(void * start, unsigned long size);
15extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
16
17/* Do not use these */
18extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
19extern unsigned long sram_reprogram_clock_sz;
20
21#endif
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 25bc4a8dd76..98f1c76f866 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -41,6 +41,7 @@
41 41
42/* These routines should handle the standard chip-specific modes 42/* These routines should handle the standard chip-specific modes
43 * for usb0/1/2 ports, covering basic mux and transceiver setup. 43 * for usb0/1/2 ports, covering basic mux and transceiver setup.
44 * Call omap_usb_init() once, from INIT_MACHINE().
44 * 45 *
45 * Some board-*.c files will need to set up additional mux options, 46 * Some board-*.c files will need to set up additional mux options,
46 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. 47 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.