aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-01-28 08:21:38 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-01-28 08:21:38 -0500
commit0ff66f0c7a5f1f4f5a0d91341b6f71fd2a49f0fa (patch)
tree7c4d74a76bf4f49e87d769c236fdd2db77fb241d /arch/arm/mach-pxa
parentc00d4ffdbace1bdc9fdd888e4ba6d207ffa3b679 (diff)
parent4e4fc05a2b6e7bd2e0facd96e0c18dceb34d9349 (diff)
Merge branch 'pxa-plat' into devel
* pxa-plat: (53 commits) [ARM] 4762/1: Basic support for Toradex Colibri module [ARM] pxa: fix mci_init functions returning -1 [ARM] 4737/1: Refactor corgi_lcd to improve readability + bugfix [ARM] 4747/1: pcm027: support for pcm990 baseboard for phyCORE-PXA270 [ARM] 4746/1: pcm027: network support for phyCORE-PXA270 [ARM] 4745/1: pcm027: default configuration [ARM] 4744/1: pcm027: add support for phyCORE-PXA270 CPU module [NET] smc91x: Make smc91x use IRQ resource trigger flags [ARM] pxa: add default config for littleton [ARM] pxa: add basic support for Littleton (PXA3xx Form Factor Platform) [ARM] 4664/1: Add basic support for HTC Magician PDA phones [ARM] 4649/1: Base support for pxa-based Toshiba e-series PDAs. [ARM] pxa: skip registers saving/restoring if entering standby mode [ARM] pxa: fix PXA27x resume [ARM] pxa: Avoid fiddling with CKEN register on suspend [ARM] pxa: Add PXA3 standby code hooked into the IRQ wake scheme [ARM] pxa: Add zylonite MFP wakeup configurations [ARM] pxa: program MFPs for low power mode when suspending [ARM] pxa: make MFP configuration processor independent [ARM] pxa: remove un-used pxa3xx_mfp_set_xxx() functions ... Conflicts: arch/arm/mach-pxa/ssp.c Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig73
-rw-r--r--arch/arm/mach-pxa/Makefile15
-rw-r--r--arch/arm/mach-pxa/cm-x270.c7
-rw-r--r--arch/arm/mach-pxa/colibri.c134
-rw-r--r--arch/arm/mach-pxa/corgi.c189
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c299
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c1
-rw-r--r--arch/arm/mach-pxa/cpu-pxa.c294
-rw-r--r--arch/arm/mach-pxa/devices.c662
-rw-r--r--arch/arm/mach-pxa/devices.h12
-rw-r--r--arch/arm/mach-pxa/eseries.c101
-rw-r--r--arch/arm/mach-pxa/generic.c251
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/littleton.c325
-rw-r--r--arch/arm/mach-pxa/lpd270.c1
-rw-r--r--arch/arm/mach-pxa/lubbock.c30
-rw-r--r--arch/arm/mach-pxa/magician.c218
-rw-r--r--arch/arm/mach-pxa/mainstone.c79
-rw-r--r--arch/arm/mach-pxa/mfp.c261
-rw-r--r--arch/arm/mach-pxa/pcm027.c216
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c330
-rw-r--r--arch/arm/mach-pxa/pm.c33
-rw-r--r--arch/arm/mach-pxa/poodle.c6
-rw-r--r--arch/arm/mach-pxa/pxa25x.c22
-rw-r--r--arch/arm/mach-pxa/pxa27x.c59
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c241
-rw-r--r--arch/arm/mach-pxa/sharpsl.h19
-rw-r--r--arch/arm/mach-pxa/sleep.S9
-rw-r--r--arch/arm/mach-pxa/spitz.c112
-rw-r--r--arch/arm/mach-pxa/ssp.c384
-rw-r--r--arch/arm/mach-pxa/standby.S83
-rw-r--r--arch/arm/mach-pxa/time.c84
-rw-r--r--arch/arm/mach-pxa/tosa.c11
-rw-r--r--arch/arm/mach-pxa/trizeps4.c7
-rw-r--r--arch/arm/mach-pxa/zylonite.c96
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c65
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c45
37 files changed, 3753 insertions, 1023 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 656d49661a29..0908bea0f609 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -51,6 +51,50 @@ config PXA_SHARPSL
51 SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) 51 SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
52 handheld computer. 52 handheld computer.
53 53
54config ARCH_PXA_ESERIES
55 bool "PXA based Toshiba e-series PDAs"
56 select PXA25x
57
58config MACH_E330
59 bool "Toshiba e330"
60 default y
61 depends on ARCH_PXA_ESERIES
62 help
63 Say Y here if you intend to run this kernel on a Toshiba
64 e330 family PDA.
65
66config MACH_E740
67 bool "Toshiba e740"
68 default y
69 depends on ARCH_PXA_ESERIES
70 help
71 Say Y here if you intend to run this kernel on a Toshiba
72 e740 family PDA.
73
74config MACH_E750
75 bool "Toshiba e750"
76 default y
77 depends on ARCH_PXA_ESERIES
78 help
79 Say Y here if you intend to run this kernel on a Toshiba
80 e750 family PDA.
81
82config MACH_E400
83 bool "Toshiba e400"
84 default y
85 depends on ARCH_PXA_ESERIES
86 help
87 Say Y here if you intend to run this kernel on a Toshiba
88 e400 family PDA.
89
90config MACH_E800
91 bool "Toshiba e800"
92 default y
93 depends on ARCH_PXA_ESERIES
94 help
95 Say Y here if you intend to run this kernel on a Toshiba
96 e800 family PDA.
97
54config MACH_TRIZEPS4 98config MACH_TRIZEPS4
55 bool "Keith und Koep Trizeps4 DIMM-Module" 99 bool "Keith und Koep Trizeps4 DIMM-Module"
56 select PXA27x 100 select PXA27x
@@ -59,15 +103,44 @@ config MACH_EM_X270
59 bool "CompuLab EM-x270 platform" 103 bool "CompuLab EM-x270 platform"
60 select PXA27x 104 select PXA27x
61 105
106config MACH_COLIBRI
107 bool "Toradex Colibri PX27x"
108 select PXA27x
109
62config MACH_ZYLONITE 110config MACH_ZYLONITE
63 bool "PXA3xx Development Platform" 111 bool "PXA3xx Development Platform"
64 select PXA3xx 112 select PXA3xx
65 113
114config MACH_LITTLETON
115 bool "PXA3xx Form Factor Platform (aka Littleton)"
116 select PXA3xx
117 select PXA_SSP
118
66config MACH_ARMCORE 119config MACH_ARMCORE
67 bool "CompuLab CM-X270 modules" 120 bool "CompuLab CM-X270 modules"
68 select PXA27x 121 select PXA27x
69 select IWMMXT 122 select IWMMXT
70 123
124config MACH_MAGICIAN
125 bool "Enable HTC Magician Support"
126 depends on ARCH_PXA
127 select PXA27x
128 select IWMMXT
129
130config MACH_PCM027
131 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
132 select PXA27x
133 select IWMMXT
134
135endchoice
136
137choice
138 prompt "Used baseboard"
139 depends on MACH_PCM027
140
141config MACH_PCM990_BASEBOARD
142 bool "PHYTEC PCM-990 development board"
143
71endchoice 144endchoice
72 145
73if PXA_SHARPSL 146if PXA_SHARPSL
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 4263527e5123..b5c916c0747d 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support (must be linked before board specific support) 5# Common support (must be linked before board specific support)
6obj-y += clock.o generic.o irq.o dma.o time.o 6obj-y += clock.o devices.o generic.o irq.o dma.o time.o
7obj-$(CONFIG_PXA25x) += pxa25x.o 7obj-$(CONFIG_PXA25x) += pxa25x.o
8obj-$(CONFIG_PXA27x) += pxa27x.o 8obj-$(CONFIG_PXA27x) += pxa27x.o
9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o 9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
@@ -16,18 +16,24 @@ obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
16obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 16obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
17obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 17obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
18obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o 18obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
19obj-$(CONFIG_MACH_COLIBRI) += colibri.o
19obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o 20obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
20obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o 21obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
21obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o 22obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
22obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o 23obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
24obj-$(CONFIG_MACH_PCM027) += pcm027.o
25obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
23obj-$(CONFIG_MACH_TOSA) += tosa.o 26obj-$(CONFIG_MACH_TOSA) += tosa.o
24obj-$(CONFIG_MACH_EM_X270) += em-x270.o 27obj-$(CONFIG_MACH_EM_X270) += em-x270.o
28obj-$(CONFIG_MACH_MAGICIAN) += magician.o
29obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
25 30
26ifeq ($(CONFIG_MACH_ZYLONITE),y) 31ifeq ($(CONFIG_MACH_ZYLONITE),y)
27 obj-y += zylonite.o 32 obj-y += zylonite.o
28 obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o 33 obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
29 obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o 34 obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
30endif 35endif
36obj-$(CONFIG_MACH_LITTLETON) += littleton.o
31 37
32obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o 38obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o
33 39
@@ -41,13 +47,10 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o
41obj-$(CONFIG_LEDS) += $(led-y) 47obj-$(CONFIG_LEDS) += $(led-y)
42 48
43# Misc features 49# Misc features
44obj-$(CONFIG_PM) += pm.o sleep.o 50obj-$(CONFIG_PM) += pm.o sleep.o standby.o
51obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
45obj-$(CONFIG_PXA_SSP) += ssp.o 52obj-$(CONFIG_PXA_SSP) += ssp.o
46 53
47ifeq ($(CONFIG_PXA27x),y)
48obj-$(CONFIG_PM) += standby.o
49endif
50
51ifeq ($(CONFIG_PCI),y) 54ifeq ($(CONFIG_PCI),y)
52obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o 55obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
53endif 56endif
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index a16349272f54..28cfd71c032d 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -487,18 +487,15 @@ static int cmx270_mci_init(struct device *dev,
487 487
488 /* card detect IRQ on GPIO 83 */ 488 /* card detect IRQ on GPIO 83 */
489 pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); 489 pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
490 set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING);
491 490
492 err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, 491 err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
493 IRQF_DISABLED | IRQF_TRIGGER_FALLING, 492 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
494 "MMC card detect", data); 493 "MMC card detect", data);
495 if (err) { 494 if (err)
496 printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't" 495 printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
497 " request MMC card detect IRQ\n"); 496 " request MMC card detect IRQ\n");
498 return -1;
499 }
500 497
501 return 0; 498 return err;
502} 499}
503 500
504static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) 501static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c
new file mode 100644
index 000000000000..6db54e31c397
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri.c
@@ -0,0 +1,134 @@
1/*
2 * linux/arch/arm/mach-pxa/colibri.c
3 *
4 * Support for Toradex PXA27x based Colibri module
5 * Daniel Mack <daniel@caiaq.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/sysdev.h>
16#include <linux/interrupt.h>
17#include <linux/bitops.h>
18#include <linux/ioport.h>
19#include <linux/delay.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/partitions.h>
22#include <linux/mtd/physmap.h>
23#include <asm/mach-types.h>
24#include <asm/hardware.h>
25#include <asm/irq.h>
26#include <asm/sizes.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30#include <asm/mach/flash.h>
31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/colibri.h>
33
34#include "generic.h"
35#include "devices.h"
36
37/*
38 * Flash
39 */
40static struct mtd_partition colibri_partitions[] = {
41 {
42 .name = "Bootloader",
43 .offset = 0x00000000,
44 .size = 0x00040000,
45 .mask_flags = MTD_WRITEABLE /* force read-only */
46 }, {
47 .name = "Kernel",
48 .offset = 0x00040000,
49 .size = 0x00400000,
50 .mask_flags = 0
51 }, {
52 .name = "Rootfs",
53 .offset = 0x00440000,
54 .size = MTDPART_SIZ_FULL,
55 .mask_flags = 0
56 }
57};
58
59static struct physmap_flash_data colibri_flash_data[] = {
60 {
61 .width = 4, /* bankwidth in bytes */
62 .parts = colibri_partitions,
63 .nr_parts = ARRAY_SIZE(colibri_partitions)
64 }
65};
66
67static struct resource flash_resource = {
68 .start = PXA_CS0_PHYS,
69 .end = PXA_CS0_PHYS + SZ_32M - 1,
70 .flags = IORESOURCE_MEM,
71};
72
73static struct platform_device flash_device = {
74 .name = "physmap-flash",
75 .id = 0,
76 .dev = {
77 .platform_data = colibri_flash_data,
78 },
79 .resource = &flash_resource,
80 .num_resources = 1,
81};
82
83/*
84 * DM9000 Ethernet
85 */
86static struct resource dm9000_resources[] = {
87 [0] = {
88 .start = COLIBRI_ETH_PHYS,
89 .end = COLIBRI_ETH_PHYS + 3,
90 .flags = IORESOURCE_MEM,
91 },
92 [1] = {
93 .start = COLIBRI_ETH_PHYS + 4,
94 .end = COLIBRI_ETH_PHYS + 4 + 500,
95 .flags = IORESOURCE_MEM,
96 },
97 [2] = {
98 .start = COLIBRI_ETH_IRQ,
99 .end = COLIBRI_ETH_IRQ,
100 .flags = IORESOURCE_IRQ,
101 },
102};
103
104static struct platform_device dm9000_device = {
105 .name = "dm9000",
106 .id = -1,
107 .num_resources = ARRAY_SIZE(dm9000_resources),
108 .resource = dm9000_resources,
109};
110
111static struct platform_device *colibri_devices[] __initdata = {
112 &flash_device,
113 &dm9000_device,
114};
115
116static void __init colibri_init(void)
117{
118 /* DM9000 LAN */
119 pxa_gpio_mode(GPIO78_nCS_2_MD);
120 pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
121 set_irq_type(COLIBRI_ETH_IRQ, IRQT_FALLING);
122
123 platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
124}
125
126MACHINE_START(COLIBRI, "Toradex Colibri PXA27x")
127 .phys_io = 0x40000000,
128 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
129 .boot_params = COLIBRI_SDRAM_BASE + 0x100,
130 .init_machine = colibri_init,
131 .map_io = pxa_map_io,
132 .init_irq = pxa27x_init_irq,
133 .timer = &pxa_timer,
134MACHINE_END
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 2363cc64fe07..9292576b83b3 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -21,6 +21,7 @@
21#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/backlight.h> 23#include <linux/backlight.h>
24#include <video/w100fb.h>
24 25
25#include <asm/setup.h> 26#include <asm/setup.h>
26#include <asm/memory.h> 27#include <asm/memory.h>
@@ -141,6 +142,136 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
141 142
142 143
143/* 144/*
145 * LCD/Framebuffer
146 */
147static void w100_lcdtg_suspend(struct w100fb_par *par)
148{
149 corgi_lcdtg_suspend();
150}
151
152static void w100_lcdtg_init(struct w100fb_par *par)
153{
154 corgi_lcdtg_hw_init(par->xres);
155}
156
157
158static struct w100_tg_info corgi_lcdtg_info = {
159 .change = w100_lcdtg_init,
160 .suspend = w100_lcdtg_suspend,
161 .resume = w100_lcdtg_init,
162};
163
164static struct w100_mem_info corgi_fb_mem = {
165 .ext_cntl = 0x00040003,
166 .sdram_mode_reg = 0x00650021,
167 .ext_timing_cntl = 0x10002a4a,
168 .io_cntl = 0x7ff87012,
169 .size = 0x1fffff,
170};
171
172static struct w100_gen_regs corgi_fb_regs = {
173 .lcd_format = 0x00000003,
174 .lcdd_cntl1 = 0x01CC0000,
175 .lcdd_cntl2 = 0x0003FFFF,
176 .genlcd_cntl1 = 0x00FFFF0D,
177 .genlcd_cntl2 = 0x003F3003,
178 .genlcd_cntl3 = 0x000102aa,
179};
180
181static struct w100_gpio_regs corgi_fb_gpio = {
182 .init_data1 = 0x000000bf,
183 .init_data2 = 0x00000000,
184 .gpio_dir1 = 0x00000000,
185 .gpio_oe1 = 0x03c0feff,
186 .gpio_dir2 = 0x00000000,
187 .gpio_oe2 = 0x00000000,
188};
189
190static struct w100_mode corgi_fb_modes[] = {
191{
192 .xres = 480,
193 .yres = 640,
194 .left_margin = 0x56,
195 .right_margin = 0x55,
196 .upper_margin = 0x03,
197 .lower_margin = 0x00,
198 .crtc_ss = 0x82360056,
199 .crtc_ls = 0xA0280000,
200 .crtc_gs = 0x80280028,
201 .crtc_vpos_gs = 0x02830002,
202 .crtc_rev = 0x00400008,
203 .crtc_dclk = 0xA0000000,
204 .crtc_gclk = 0x8015010F,
205 .crtc_goe = 0x80100110,
206 .crtc_ps1_active = 0x41060010,
207 .pll_freq = 75,
208 .fast_pll_freq = 100,
209 .sysclk_src = CLK_SRC_PLL,
210 .sysclk_divider = 0,
211 .pixclk_src = CLK_SRC_PLL,
212 .pixclk_divider = 2,
213 .pixclk_divider_rotated = 6,
214},{
215 .xres = 240,
216 .yres = 320,
217 .left_margin = 0x27,
218 .right_margin = 0x2e,
219 .upper_margin = 0x01,
220 .lower_margin = 0x00,
221 .crtc_ss = 0x81170027,
222 .crtc_ls = 0xA0140000,
223 .crtc_gs = 0xC0140014,
224 .crtc_vpos_gs = 0x00010141,
225 .crtc_rev = 0x00400008,
226 .crtc_dclk = 0xA0000000,
227 .crtc_gclk = 0x8015010F,
228 .crtc_goe = 0x80100110,
229 .crtc_ps1_active = 0x41060010,
230 .pll_freq = 0,
231 .fast_pll_freq = 0,
232 .sysclk_src = CLK_SRC_XTAL,
233 .sysclk_divider = 0,
234 .pixclk_src = CLK_SRC_XTAL,
235 .pixclk_divider = 1,
236 .pixclk_divider_rotated = 1,
237},
238
239};
240
241static struct w100fb_mach_info corgi_fb_info = {
242 .tg = &corgi_lcdtg_info,
243 .init_mode = INIT_MODE_ROTATED,
244 .mem = &corgi_fb_mem,
245 .regs = &corgi_fb_regs,
246 .modelist = &corgi_fb_modes[0],
247 .num_modes = 2,
248 .gpio = &corgi_fb_gpio,
249 .xtal_freq = 12500000,
250 .xtal_dbl = 0,
251};
252
253static struct resource corgi_fb_resources[] = {
254 [0] = {
255 .start = 0x08000000,
256 .end = 0x08ffffff,
257 .flags = IORESOURCE_MEM,
258 },
259};
260
261static struct platform_device corgifb_device = {
262 .name = "w100fb",
263 .id = -1,
264 .num_resources = ARRAY_SIZE(corgi_fb_resources),
265 .resource = corgi_fb_resources,
266 .dev = {
267 .platform_data = &corgi_fb_info,
268 .parent = &corgissp_device.dev,
269 },
270
271};
272
273
274/*
144 * Corgi Backlight Device 275 * Corgi Backlight Device
145 */ 276 */
146static void corgi_bl_kick_battery(void) 277static void corgi_bl_kick_battery(void)
@@ -154,6 +285,21 @@ static void corgi_bl_kick_battery(void)
154 } 285 }
155} 286}
156 287
288static void corgi_bl_set_intensity(int intensity)
289{
290 if (intensity > 0x10)
291 intensity += 0x10;
292
293 /* Bits 0-4 are accessed via the SSP interface */
294 corgi_ssp_blduty_set(intensity & 0x1f);
295
296 /* Bit 5 is via SCOOP */
297 if (intensity & 0x0020)
298 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
299 else
300 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
301}
302
157static struct generic_bl_info corgi_bl_machinfo = { 303static struct generic_bl_info corgi_bl_machinfo = {
158 .name = "corgi-bl", 304 .name = "corgi-bl",
159 .max_intensity = 0x2f, 305 .max_intensity = 0x2f,
@@ -190,9 +336,40 @@ static struct platform_device corgiled_device = {
190 .id = -1, 336 .id = -1,
191}; 337};
192 338
339
193/* 340/*
194 * Corgi Touch Screen Device 341 * Corgi Touch Screen Device
195 */ 342 */
343static unsigned long (*get_hsync_invperiod)(struct device *dev);
344
345static void inline sharpsl_wait_sync(int gpio)
346{
347 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
348 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
349}
350
351static unsigned long corgi_get_hsync_invperiod(void)
352{
353 if (!get_hsync_invperiod)
354 get_hsync_invperiod = symbol_get(w100fb_get_hsynclen);
355 if (!get_hsync_invperiod)
356 return 0;
357
358 return get_hsync_invperiod(&corgifb_device.dev);
359}
360
361static void corgi_put_hsync(void)
362{
363 if (get_hsync_invperiod)
364 symbol_put(w100fb_get_hsynclen);
365 get_hsync_invperiod = NULL;
366}
367
368static void corgi_wait_hsync(void)
369{
370 sharpsl_wait_sync(CORGI_GPIO_HSYNC);
371}
372
196static struct resource corgits_resources[] = { 373static struct resource corgits_resources[] = {
197 [0] = { 374 [0] = {
198 .start = CORGI_IRQ_GPIO_TP_INT, 375 .start = CORGI_IRQ_GPIO_TP_INT,
@@ -202,9 +379,9 @@ static struct resource corgits_resources[] = {
202}; 379};
203 380
204static struct corgits_machinfo corgi_ts_machinfo = { 381static struct corgits_machinfo corgi_ts_machinfo = {
205 .get_hsync_len = corgi_get_hsync_len, 382 .get_hsync_invperiod = corgi_get_hsync_invperiod,
206 .put_hsync = corgi_put_hsync, 383 .put_hsync = corgi_put_hsync,
207 .wait_hsync = corgi_wait_hsync, 384 .wait_hsync = corgi_wait_hsync,
208}; 385};
209 386
210static struct platform_device corgits_device = { 387static struct platform_device corgits_device = {
@@ -242,12 +419,10 @@ static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, vo
242 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, 419 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
243 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 420 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
244 "MMC card detect", data); 421 "MMC card detect", data);
245 if (err) { 422 if (err)
246 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 423 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
247 return -1;
248 }
249 424
250 return 0; 425 return err;
251} 426}
252 427
253static void corgi_mci_setpower(struct device *dev, unsigned int vdd) 428static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 365b9435f748..9328df37afd1 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -173,7 +173,7 @@ static void lcdtg_set_phadadj(int mode)
173 173
174static int lcd_inited; 174static int lcd_inited;
175 175
176static void lcdtg_hw_init(int mode) 176void corgi_lcdtg_hw_init(int mode)
177{ 177{
178 if (!lcd_inited) { 178 if (!lcd_inited) {
179 int comadj; 179 int comadj;
@@ -254,7 +254,7 @@ static void lcdtg_hw_init(int mode)
254 } 254 }
255} 255}
256 256
257static void lcdtg_suspend(void) 257void corgi_lcdtg_suspend(void)
258{ 258{
259 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ 259 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
260 mdelay(34); 260 mdelay(34);
@@ -288,298 +288,3 @@ static void lcdtg_suspend(void)
288 lcd_inited = 0; 288 lcd_inited = 0;
289} 289}
290 290
291
292/*
293 * Corgi w100 Frame Buffer Device
294 */
295#ifdef CONFIG_PXA_SHARP_C7xx
296
297#include <video/w100fb.h>
298
299static void w100_lcdtg_suspend(struct w100fb_par *par)
300{
301 lcdtg_suspend();
302}
303
304static void w100_lcdtg_init(struct w100fb_par *par)
305{
306 lcdtg_hw_init(par->xres);
307}
308
309
310static struct w100_tg_info corgi_lcdtg_info = {
311 .change = w100_lcdtg_init,
312 .suspend = w100_lcdtg_suspend,
313 .resume = w100_lcdtg_init,
314};
315
316static struct w100_mem_info corgi_fb_mem = {
317 .ext_cntl = 0x00040003,
318 .sdram_mode_reg = 0x00650021,
319 .ext_timing_cntl = 0x10002a4a,
320 .io_cntl = 0x7ff87012,
321 .size = 0x1fffff,
322};
323
324static struct w100_gen_regs corgi_fb_regs = {
325 .lcd_format = 0x00000003,
326 .lcdd_cntl1 = 0x01CC0000,
327 .lcdd_cntl2 = 0x0003FFFF,
328 .genlcd_cntl1 = 0x00FFFF0D,
329 .genlcd_cntl2 = 0x003F3003,
330 .genlcd_cntl3 = 0x000102aa,
331};
332
333static struct w100_gpio_regs corgi_fb_gpio = {
334 .init_data1 = 0x000000bf,
335 .init_data2 = 0x00000000,
336 .gpio_dir1 = 0x00000000,
337 .gpio_oe1 = 0x03c0feff,
338 .gpio_dir2 = 0x00000000,
339 .gpio_oe2 = 0x00000000,
340};
341
342static struct w100_mode corgi_fb_modes[] = {
343{
344 .xres = 480,
345 .yres = 640,
346 .left_margin = 0x56,
347 .right_margin = 0x55,
348 .upper_margin = 0x03,
349 .lower_margin = 0x00,
350 .crtc_ss = 0x82360056,
351 .crtc_ls = 0xA0280000,
352 .crtc_gs = 0x80280028,
353 .crtc_vpos_gs = 0x02830002,
354 .crtc_rev = 0x00400008,
355 .crtc_dclk = 0xA0000000,
356 .crtc_gclk = 0x8015010F,
357 .crtc_goe = 0x80100110,
358 .crtc_ps1_active = 0x41060010,
359 .pll_freq = 75,
360 .fast_pll_freq = 100,
361 .sysclk_src = CLK_SRC_PLL,
362 .sysclk_divider = 0,
363 .pixclk_src = CLK_SRC_PLL,
364 .pixclk_divider = 2,
365 .pixclk_divider_rotated = 6,
366},{
367 .xres = 240,
368 .yres = 320,
369 .left_margin = 0x27,
370 .right_margin = 0x2e,
371 .upper_margin = 0x01,
372 .lower_margin = 0x00,
373 .crtc_ss = 0x81170027,
374 .crtc_ls = 0xA0140000,
375 .crtc_gs = 0xC0140014,
376 .crtc_vpos_gs = 0x00010141,
377 .crtc_rev = 0x00400008,
378 .crtc_dclk = 0xA0000000,
379 .crtc_gclk = 0x8015010F,
380 .crtc_goe = 0x80100110,
381 .crtc_ps1_active = 0x41060010,
382 .pll_freq = 0,
383 .fast_pll_freq = 0,
384 .sysclk_src = CLK_SRC_XTAL,
385 .sysclk_divider = 0,
386 .pixclk_src = CLK_SRC_XTAL,
387 .pixclk_divider = 1,
388 .pixclk_divider_rotated = 1,
389},
390
391};
392
393static struct w100fb_mach_info corgi_fb_info = {
394 .tg = &corgi_lcdtg_info,
395 .init_mode = INIT_MODE_ROTATED,
396 .mem = &corgi_fb_mem,
397 .regs = &corgi_fb_regs,
398 .modelist = &corgi_fb_modes[0],
399 .num_modes = 2,
400 .gpio = &corgi_fb_gpio,
401 .xtal_freq = 12500000,
402 .xtal_dbl = 0,
403};
404
405static struct resource corgi_fb_resources[] = {
406 [0] = {
407 .start = 0x08000000,
408 .end = 0x08ffffff,
409 .flags = IORESOURCE_MEM,
410 },
411};
412
413struct platform_device corgifb_device = {
414 .name = "w100fb",
415 .id = -1,
416 .num_resources = ARRAY_SIZE(corgi_fb_resources),
417 .resource = corgi_fb_resources,
418 .dev = {
419 .platform_data = &corgi_fb_info,
420 .parent = &corgissp_device.dev,
421 },
422
423};
424#endif
425
426
427/*
428 * Spitz PXA Frame Buffer Device
429 */
430#ifdef CONFIG_PXA_SHARP_Cxx00
431
432#include <asm/arch/pxafb.h>
433
434void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
435{
436 if (on)
437 lcdtg_hw_init(var->xres);
438 else
439 lcdtg_suspend();
440}
441
442#endif
443
444
445/*
446 * Corgi/Spitz Touchscreen to LCD interface
447 */
448static unsigned long (*get_hsync_time)(struct device *dev);
449
450static void inline sharpsl_wait_sync(int gpio)
451{
452 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
453 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
454}
455
456#ifdef CONFIG_PXA_SHARP_C7xx
457unsigned long corgi_get_hsync_len(void)
458{
459 if (!get_hsync_time)
460 get_hsync_time = symbol_get(w100fb_get_hsynclen);
461 if (!get_hsync_time)
462 return 0;
463
464 return get_hsync_time(&corgifb_device.dev);
465}
466
467void corgi_put_hsync(void)
468{
469 if (get_hsync_time)
470 symbol_put(w100fb_get_hsynclen);
471 get_hsync_time = NULL;
472}
473
474void corgi_wait_hsync(void)
475{
476 sharpsl_wait_sync(CORGI_GPIO_HSYNC);
477}
478#endif
479
480#ifdef CONFIG_PXA_SHARP_Cxx00
481static struct device *spitz_pxafb_dev;
482
483static int is_pxafb_device(struct device * dev, void * data)
484{
485 struct platform_device *pdev = container_of(dev, struct platform_device, dev);
486
487 return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
488}
489
490unsigned long spitz_get_hsync_len(void)
491{
492#ifdef CONFIG_FB_PXA
493 if (!spitz_pxafb_dev) {
494 spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
495 if (!spitz_pxafb_dev)
496 return 0;
497 }
498 if (!get_hsync_time)
499 get_hsync_time = symbol_get(pxafb_get_hsync_time);
500 if (!get_hsync_time)
501#endif
502 return 0;
503
504 return pxafb_get_hsync_time(spitz_pxafb_dev);
505}
506
507void spitz_put_hsync(void)
508{
509 put_device(spitz_pxafb_dev);
510 if (get_hsync_time)
511 symbol_put(pxafb_get_hsync_time);
512 spitz_pxafb_dev = NULL;
513 get_hsync_time = NULL;
514}
515
516void spitz_wait_hsync(void)
517{
518 sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
519}
520#endif
521
522/*
523 * Corgi/Spitz Backlight Power
524 */
525#ifdef CONFIG_PXA_SHARP_C7xx
526void corgi_bl_set_intensity(int intensity)
527{
528 if (intensity > 0x10)
529 intensity += 0x10;
530
531 /* Bits 0-4 are accessed via the SSP interface */
532 corgi_ssp_blduty_set(intensity & 0x1f);
533
534 /* Bit 5 is via SCOOP */
535 if (intensity & 0x0020)
536 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
537 else
538 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
539}
540#endif
541
542
543#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
544void spitz_bl_set_intensity(int intensity)
545{
546 if (intensity > 0x10)
547 intensity += 0x10;
548
549 /* Bits 0-4 are accessed via the SSP interface */
550 corgi_ssp_blduty_set(intensity & 0x1f);
551
552 /* Bit 5 is via SCOOP */
553 if (intensity & 0x0020)
554 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
555 else
556 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
557
558 if (intensity)
559 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
560 else
561 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
562}
563#endif
564
565#ifdef CONFIG_MACH_AKITA
566void akita_bl_set_intensity(int intensity)
567{
568 if (intensity > 0x10)
569 intensity += 0x10;
570
571 /* Bits 0-4 are accessed via the SSP interface */
572 corgi_ssp_blduty_set(intensity & 0x1f);
573
574 /* Bit 5 is via IO-Expander */
575 if (intensity & 0x0020)
576 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
577 else
578 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
579
580 if (intensity)
581 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
582 else
583 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
584}
585#endif
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 40dea3d5142b..efba65edcd51 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -21,6 +21,7 @@
21 21
22#include <asm/arch/ssp.h> 22#include <asm/arch/ssp.h>
23#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/regs-ssp.h>
24#include "sharpsl.h" 25#include "sharpsl.h"
25 26
26static DEFINE_SPINLOCK(corgi_ssp_lock); 27static DEFINE_SPINLOCK(corgi_ssp_lock);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
new file mode 100644
index 000000000000..cbc583beedc8
--- /dev/null
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -0,0 +1,294 @@
1/*
2 * linux/arch/arm/mach-pxa/cpu-pxa.c
3 *
4 * Copyright (C) 2002,2003 Intrinsyc Software
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * History:
21 * 31-Jul-2002 : Initial version [FB]
22 * 29-Jan-2003 : added PXA255 support [FB]
23 * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
24 *
25 * Note:
26 * This driver may change the memory bus clock rate, but will not do any
27 * platform specific access timing changes... for example if you have flash
28 * memory connected to CS0, you will need to register a platform specific
29 * notifier which will adjust the memory access strobes to maintain a
30 * minimum strobe width.
31 *
32 */
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/sched.h>
37#include <linux/init.h>
38#include <linux/cpufreq.h>
39
40#include <asm/hardware.h>
41#include <asm/arch/pxa-regs.h>
42#include <asm/arch/pxa2xx-regs.h>
43
44#ifdef DEBUG
45static unsigned int freq_debug;
46MODULE_PARM(freq_debug, "i");
47MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
48#else
49#define freq_debug 0
50#endif
51
52typedef struct {
53 unsigned int khz;
54 unsigned int membus;
55 unsigned int cccr;
56 unsigned int div2;
57} pxa_freqs_t;
58
59/* Define the refresh period in mSec for the SDRAM and the number of rows */
60#define SDRAM_TREF 64 /* standard 64ms SDRAM */
61#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
62#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
63
64#define CCLKCFG_TURBO 0x1
65#define CCLKCFG_FCS 0x2
66#define PXA25x_MIN_FREQ 99500
67#define PXA25x_MAX_FREQ 398100
68#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
69#define MDREFR_DRI_MASK 0xFFF
70
71
72/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
73static pxa_freqs_t pxa255_run_freqs[] =
74{
75 /* CPU MEMBUS CCCR DIV2*/
76 { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
77 {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
78 {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
79 {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
80 {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
81 {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
82 {0,}
83};
84#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
85
86static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
87
88/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
89static pxa_freqs_t pxa255_turbo_freqs[] =
90{
91 /* CPU MEMBUS CCCR DIV2*/
92 { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
93 {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
94 {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
95 {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
96 {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
97 {0,}
98};
99#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
100
101static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
102
103extern unsigned get_clk_frequency_khz(int info);
104
105/* find a valid frequency point */
106static int pxa_verify_policy(struct cpufreq_policy *policy)
107{
108 struct cpufreq_frequency_table *pxa_freqs_table;
109 int ret;
110
111 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
112 pxa_freqs_table = pxa255_run_freq_table;
113 } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
114 pxa_freqs_table = pxa255_turbo_freq_table;
115 } else {
116 printk("CPU PXA: Unknown policy found. "
117 "Using CPUFREQ_POLICY_PERFORMANCE\n");
118 pxa_freqs_table = pxa255_run_freq_table;
119 }
120
121 ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
122
123 if (freq_debug)
124 pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
125 policy->min, policy->max);
126
127 return ret;
128}
129
130static int pxa_set_target(struct cpufreq_policy *policy,
131 unsigned int target_freq,
132 unsigned int relation)
133{
134 struct cpufreq_frequency_table *pxa_freqs_table;
135 pxa_freqs_t *pxa_freq_settings;
136 struct cpufreq_freqs freqs;
137 int idx;
138 unsigned long flags;
139 unsigned int unused, preset_mdrefr, postset_mdrefr;
140 void *ramstart = phys_to_virt(0xa0000000);
141
142 /* Get the current policy */
143 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
144 pxa_freq_settings = pxa255_run_freqs;
145 pxa_freqs_table = pxa255_run_freq_table;
146 } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
147 pxa_freq_settings = pxa255_turbo_freqs;
148 pxa_freqs_table = pxa255_turbo_freq_table;
149 } else {
150 printk("CPU PXA: Unknown policy found. "
151 "Using CPUFREQ_POLICY_PERFORMANCE\n");
152 pxa_freq_settings = pxa255_run_freqs;
153 pxa_freqs_table = pxa255_run_freq_table;
154 }
155
156 /* Lookup the next frequency */
157 if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
158 target_freq, relation, &idx)) {
159 return -EINVAL;
160 }
161
162 freqs.old = policy->cur;
163 freqs.new = pxa_freq_settings[idx].khz;
164 freqs.cpu = policy->cpu;
165
166 if (freq_debug)
167 pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
168 freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
169 (pxa_freq_settings[idx].membus / 2000) :
170 (pxa_freq_settings[idx].membus / 1000));
171
172 /*
173 * Tell everyone what we're about to do...
174 * you should add a notify client with any platform specific
175 * Vcc changing capability
176 */
177 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
178
179 /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
180 * we need to preset the smaller DRI before the change. If we're speeding
181 * up we need to set the larger DRI value after the change.
182 */
183 preset_mdrefr = postset_mdrefr = MDREFR;
184 if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
185 preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
186 MDREFR_DRI(pxa_freq_settings[idx].membus);
187 }
188 postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
189 MDREFR_DRI(pxa_freq_settings[idx].membus);
190
191 /* If we're dividing the memory clock by two for the SDRAM clock, this
192 * must be set prior to the change. Clearing the divide must be done
193 * after the change.
194 */
195 if (pxa_freq_settings[idx].div2) {
196 preset_mdrefr |= MDREFR_DB2_MASK;
197 postset_mdrefr |= MDREFR_DB2_MASK;
198 } else {
199 postset_mdrefr &= ~MDREFR_DB2_MASK;
200 }
201
202 local_irq_save(flags);
203
204 /* Set new the CCCR */
205 CCCR = pxa_freq_settings[idx].cccr;
206
207 asm volatile(" \n\
208 ldr r4, [%1] /* load MDREFR */ \n\
209 b 2f \n\
210 .align 5 \n\
2111: \n\
212 str %4, [%1] /* preset the MDREFR */ \n\
213 mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\
214 str %5, [%1] /* postset the MDREFR */ \n\
215 \n\
216 b 3f \n\
2172: b 1b \n\
2183: nop \n\
219 "
220 : "=&r" (unused)
221 : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
222 "r" (preset_mdrefr), "r" (postset_mdrefr)
223 : "r4", "r5");
224 local_irq_restore(flags);
225
226 /*
227 * Tell everyone what we've just done...
228 * you should add a notify client with any platform specific
229 * SDRAM refresh timer adjustments
230 */
231 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
232
233 return 0;
234}
235
236static int pxa_cpufreq_init(struct cpufreq_policy *policy)
237{
238 int i;
239
240 /* set default policy and cpuinfo */
241 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
242 policy->policy = CPUFREQ_POLICY_PERFORMANCE;
243 policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
244 policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
245 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
246 policy->cur = get_clk_frequency_khz(0); /* current freq */
247 policy->min = policy->max = policy->cur;
248
249 /* Generate the run cpufreq_frequency_table struct */
250 for (i = 0; i < NUM_RUN_FREQS; i++) {
251 pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
252 pxa255_run_freq_table[i].index = i;
253 }
254
255 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
256 /* Generate the turbo cpufreq_frequency_table struct */
257 for (i = 0; i < NUM_TURBO_FREQS; i++) {
258 pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
259 pxa255_turbo_freq_table[i].index = i;
260 }
261 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
262
263 printk(KERN_INFO "PXA CPU frequency change support initialized\n");
264
265 return 0;
266}
267
268static struct cpufreq_driver pxa_cpufreq_driver = {
269 .verify = pxa_verify_policy,
270 .target = pxa_set_target,
271 .init = pxa_cpufreq_init,
272 .name = "PXA25x",
273};
274
275static int __init pxa_cpu_init(void)
276{
277 int ret = -ENODEV;
278 if (cpu_is_pxa25x())
279 ret = cpufreq_register_driver(&pxa_cpufreq_driver);
280 return ret;
281}
282
283static void __exit pxa_cpu_exit(void)
284{
285 if (cpu_is_pxa25x())
286 cpufreq_unregister_driver(&pxa_cpufreq_driver);
287}
288
289
290MODULE_AUTHOR ("Intrinsyc Software Inc.");
291MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
292MODULE_LICENSE("GPL");
293module_init(pxa_cpu_init);
294module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 000000000000..50ff453ad370
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,662 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/init.h>
4#include <linux/platform_device.h>
5#include <linux/dma-mapping.h>
6
7#include <asm/arch/gpio.h>
8#include <asm/arch/udc.h>
9#include <asm/arch/pxafb.h>
10#include <asm/arch/mmc.h>
11#include <asm/arch/irda.h>
12#include <asm/arch/i2c.h>
13
14#include "devices.h"
15
16void __init pxa_register_device(struct platform_device *dev, void *data)
17{
18 int ret;
19
20 dev->dev.platform_data = data;
21
22 ret = platform_device_register(dev);
23 if (ret)
24 dev_err(&dev->dev, "unable to register device: %d\n", ret);
25}
26
27static struct resource pxamci_resources[] = {
28 [0] = {
29 .start = 0x41100000,
30 .end = 0x41100fff,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_MMC,
35 .end = IRQ_MMC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = 21,
40 .end = 21,
41 .flags = IORESOURCE_DMA,
42 },
43 [3] = {
44 .start = 22,
45 .end = 22,
46 .flags = IORESOURCE_DMA,
47 },
48};
49
50static u64 pxamci_dmamask = 0xffffffffUL;
51
52struct platform_device pxa_device_mci = {
53 .name = "pxa2xx-mci",
54 .id = 0,
55 .dev = {
56 .dma_mask = &pxamci_dmamask,
57 .coherent_dma_mask = 0xffffffff,
58 },
59 .num_resources = ARRAY_SIZE(pxamci_resources),
60 .resource = pxamci_resources,
61};
62
63void __init pxa_set_mci_info(struct pxamci_platform_data *info)
64{
65 pxa_register_device(&pxa_device_mci, info);
66}
67
68
69static struct pxa2xx_udc_mach_info pxa_udc_info;
70
71void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
72{
73 memcpy(&pxa_udc_info, info, sizeof *info);
74}
75
76static struct resource pxa2xx_udc_resources[] = {
77 [0] = {
78 .start = 0x40600000,
79 .end = 0x4060ffff,
80 .flags = IORESOURCE_MEM,
81 },
82 [1] = {
83 .start = IRQ_USB,
84 .end = IRQ_USB,
85 .flags = IORESOURCE_IRQ,
86 },
87};
88
89static u64 udc_dma_mask = ~(u32)0;
90
91struct platform_device pxa_device_udc = {
92 .name = "pxa2xx-udc",
93 .id = -1,
94 .resource = pxa2xx_udc_resources,
95 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
96 .dev = {
97 .platform_data = &pxa_udc_info,
98 .dma_mask = &udc_dma_mask,
99 }
100};
101
102static struct resource pxafb_resources[] = {
103 [0] = {
104 .start = 0x44000000,
105 .end = 0x4400ffff,
106 .flags = IORESOURCE_MEM,
107 },
108 [1] = {
109 .start = IRQ_LCD,
110 .end = IRQ_LCD,
111 .flags = IORESOURCE_IRQ,
112 },
113};
114
115static u64 fb_dma_mask = ~(u64)0;
116
117struct platform_device pxa_device_fb = {
118 .name = "pxa2xx-fb",
119 .id = -1,
120 .dev = {
121 .dma_mask = &fb_dma_mask,
122 .coherent_dma_mask = 0xffffffff,
123 },
124 .num_resources = ARRAY_SIZE(pxafb_resources),
125 .resource = pxafb_resources,
126};
127
128void __init set_pxa_fb_info(struct pxafb_mach_info *info)
129{
130 pxa_register_device(&pxa_device_fb, info);
131}
132
133void __init set_pxa_fb_parent(struct device *parent_dev)
134{
135 pxa_device_fb.dev.parent = parent_dev;
136}
137
138static struct resource pxa_resource_ffuart[] = {
139 {
140 .start = __PREG(FFUART),
141 .end = __PREG(FFUART) + 35,
142 .flags = IORESOURCE_MEM,
143 }, {
144 .start = IRQ_FFUART,
145 .end = IRQ_FFUART,
146 .flags = IORESOURCE_IRQ,
147 }
148};
149
150struct platform_device pxa_device_ffuart= {
151 .name = "pxa2xx-uart",
152 .id = 0,
153 .resource = pxa_resource_ffuart,
154 .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
155};
156
157static struct resource pxa_resource_btuart[] = {
158 {
159 .start = __PREG(BTUART),
160 .end = __PREG(BTUART) + 35,
161 .flags = IORESOURCE_MEM,
162 }, {
163 .start = IRQ_BTUART,
164 .end = IRQ_BTUART,
165 .flags = IORESOURCE_IRQ,
166 }
167};
168
169struct platform_device pxa_device_btuart = {
170 .name = "pxa2xx-uart",
171 .id = 1,
172 .resource = pxa_resource_btuart,
173 .num_resources = ARRAY_SIZE(pxa_resource_btuart),
174};
175
176static struct resource pxa_resource_stuart[] = {
177 {
178 .start = __PREG(STUART),
179 .end = __PREG(STUART) + 35,
180 .flags = IORESOURCE_MEM,
181 }, {
182 .start = IRQ_STUART,
183 .end = IRQ_STUART,
184 .flags = IORESOURCE_IRQ,
185 }
186};
187
188struct platform_device pxa_device_stuart = {
189 .name = "pxa2xx-uart",
190 .id = 2,
191 .resource = pxa_resource_stuart,
192 .num_resources = ARRAY_SIZE(pxa_resource_stuart),
193};
194
195static struct resource pxa_resource_hwuart[] = {
196 {
197 .start = __PREG(HWUART),
198 .end = __PREG(HWUART) + 47,
199 .flags = IORESOURCE_MEM,
200 }, {
201 .start = IRQ_HWUART,
202 .end = IRQ_HWUART,
203 .flags = IORESOURCE_IRQ,
204 }
205};
206
207struct platform_device pxa_device_hwuart = {
208 .name = "pxa2xx-uart",
209 .id = 3,
210 .resource = pxa_resource_hwuart,
211 .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
212};
213
214static struct resource pxai2c_resources[] = {
215 {
216 .start = 0x40301680,
217 .end = 0x403016a3,
218 .flags = IORESOURCE_MEM,
219 }, {
220 .start = IRQ_I2C,
221 .end = IRQ_I2C,
222 .flags = IORESOURCE_IRQ,
223 },
224};
225
226struct platform_device pxa_device_i2c = {
227 .name = "pxa2xx-i2c",
228 .id = 0,
229 .resource = pxai2c_resources,
230 .num_resources = ARRAY_SIZE(pxai2c_resources),
231};
232
233void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
234{
235 pxa_register_device(&pxa_device_i2c, info);
236}
237
238static struct resource pxai2s_resources[] = {
239 {
240 .start = 0x40400000,
241 .end = 0x40400083,
242 .flags = IORESOURCE_MEM,
243 }, {
244 .start = IRQ_I2S,
245 .end = IRQ_I2S,
246 .flags = IORESOURCE_IRQ,
247 },
248};
249
250struct platform_device pxa_device_i2s = {
251 .name = "pxa2xx-i2s",
252 .id = -1,
253 .resource = pxai2s_resources,
254 .num_resources = ARRAY_SIZE(pxai2s_resources),
255};
256
257static u64 pxaficp_dmamask = ~(u32)0;
258
259struct platform_device pxa_device_ficp = {
260 .name = "pxa2xx-ir",
261 .id = -1,
262 .dev = {
263 .dma_mask = &pxaficp_dmamask,
264 .coherent_dma_mask = 0xffffffff,
265 },
266};
267
268void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
269{
270 pxa_register_device(&pxa_device_ficp, info);
271}
272
273struct platform_device pxa_device_rtc = {
274 .name = "sa1100-rtc",
275 .id = -1,
276};
277
278#ifdef CONFIG_PXA25x
279
280static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32);
281
282static struct resource pxa25x_resource_ssp[] = {
283 [0] = {
284 .start = 0x41000000,
285 .end = 0x4100001f,
286 .flags = IORESOURCE_MEM,
287 },
288 [1] = {
289 .start = IRQ_SSP,
290 .end = IRQ_SSP,
291 .flags = IORESOURCE_IRQ,
292 },
293 [2] = {
294 /* DRCMR for RX */
295 .start = 13,
296 .end = 13,
297 .flags = IORESOURCE_DMA,
298 },
299 [3] = {
300 /* DRCMR for TX */
301 .start = 14,
302 .end = 14,
303 .flags = IORESOURCE_DMA,
304 },
305};
306
307struct platform_device pxa25x_device_ssp = {
308 .name = "pxa25x-ssp",
309 .id = 0,
310 .dev = {
311 .dma_mask = &pxa25x_ssp_dma_mask,
312 .coherent_dma_mask = DMA_BIT_MASK(32),
313 },
314 .resource = pxa25x_resource_ssp,
315 .num_resources = ARRAY_SIZE(pxa25x_resource_ssp),
316};
317
318static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32);
319
320static struct resource pxa25x_resource_nssp[] = {
321 [0] = {
322 .start = 0x41400000,
323 .end = 0x4140002f,
324 .flags = IORESOURCE_MEM,
325 },
326 [1] = {
327 .start = IRQ_NSSP,
328 .end = IRQ_NSSP,
329 .flags = IORESOURCE_IRQ,
330 },
331 [2] = {
332 /* DRCMR for RX */
333 .start = 15,
334 .end = 15,
335 .flags = IORESOURCE_DMA,
336 },
337 [3] = {
338 /* DRCMR for TX */
339 .start = 16,
340 .end = 16,
341 .flags = IORESOURCE_DMA,
342 },
343};
344
345struct platform_device pxa25x_device_nssp = {
346 .name = "pxa25x-nssp",
347 .id = 1,
348 .dev = {
349 .dma_mask = &pxa25x_nssp_dma_mask,
350 .coherent_dma_mask = DMA_BIT_MASK(32),
351 },
352 .resource = pxa25x_resource_nssp,
353 .num_resources = ARRAY_SIZE(pxa25x_resource_nssp),
354};
355
356static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32);
357
358static struct resource pxa25x_resource_assp[] = {
359 [0] = {
360 .start = 0x41500000,
361 .end = 0x4150002f,
362 .flags = IORESOURCE_MEM,
363 },
364 [1] = {
365 .start = IRQ_ASSP,
366 .end = IRQ_ASSP,
367 .flags = IORESOURCE_IRQ,
368 },
369 [2] = {
370 /* DRCMR for RX */
371 .start = 23,
372 .end = 23,
373 .flags = IORESOURCE_DMA,
374 },
375 [3] = {
376 /* DRCMR for TX */
377 .start = 24,
378 .end = 24,
379 .flags = IORESOURCE_DMA,
380 },
381};
382
383struct platform_device pxa25x_device_assp = {
384 /* ASSP is basically equivalent to NSSP */
385 .name = "pxa25x-nssp",
386 .id = 2,
387 .dev = {
388 .dma_mask = &pxa25x_assp_dma_mask,
389 .coherent_dma_mask = DMA_BIT_MASK(32),
390 },
391 .resource = pxa25x_resource_assp,
392 .num_resources = ARRAY_SIZE(pxa25x_resource_assp),
393};
394#endif /* CONFIG_PXA25x */
395
396#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
397
398static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
399
400static struct resource pxa27x_resource_ohci[] = {
401 [0] = {
402 .start = 0x4C000000,
403 .end = 0x4C00ff6f,
404 .flags = IORESOURCE_MEM,
405 },
406 [1] = {
407 .start = IRQ_USBH1,
408 .end = IRQ_USBH1,
409 .flags = IORESOURCE_IRQ,
410 },
411};
412
413struct platform_device pxa27x_device_ohci = {
414 .name = "pxa27x-ohci",
415 .id = -1,
416 .dev = {
417 .dma_mask = &pxa27x_ohci_dma_mask,
418 .coherent_dma_mask = DMA_BIT_MASK(32),
419 },
420 .num_resources = ARRAY_SIZE(pxa27x_resource_ohci),
421 .resource = pxa27x_resource_ohci,
422};
423
424void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
425{
426 pxa_register_device(&pxa27x_device_ohci, info);
427}
428
429static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
430
431static struct resource pxa27x_resource_ssp1[] = {
432 [0] = {
433 .start = 0x41000000,
434 .end = 0x4100003f,
435 .flags = IORESOURCE_MEM,
436 },
437 [1] = {
438 .start = IRQ_SSP,
439 .end = IRQ_SSP,
440 .flags = IORESOURCE_IRQ,
441 },
442 [2] = {
443 /* DRCMR for RX */
444 .start = 13,
445 .end = 13,
446 .flags = IORESOURCE_DMA,
447 },
448 [3] = {
449 /* DRCMR for TX */
450 .start = 14,
451 .end = 14,
452 .flags = IORESOURCE_DMA,
453 },
454};
455
456struct platform_device pxa27x_device_ssp1 = {
457 .name = "pxa27x-ssp",
458 .id = 0,
459 .dev = {
460 .dma_mask = &pxa27x_ssp1_dma_mask,
461 .coherent_dma_mask = DMA_BIT_MASK(32),
462 },
463 .resource = pxa27x_resource_ssp1,
464 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1),
465};
466
467static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32);
468
469static struct resource pxa27x_resource_ssp2[] = {
470 [0] = {
471 .start = 0x41700000,
472 .end = 0x4170003f,
473 .flags = IORESOURCE_MEM,
474 },
475 [1] = {
476 .start = IRQ_SSP2,
477 .end = IRQ_SSP2,
478 .flags = IORESOURCE_IRQ,
479 },
480 [2] = {
481 /* DRCMR for RX */
482 .start = 15,
483 .end = 15,
484 .flags = IORESOURCE_DMA,
485 },
486 [3] = {
487 /* DRCMR for TX */
488 .start = 16,
489 .end = 16,
490 .flags = IORESOURCE_DMA,
491 },
492};
493
494struct platform_device pxa27x_device_ssp2 = {
495 .name = "pxa27x-ssp",
496 .id = 1,
497 .dev = {
498 .dma_mask = &pxa27x_ssp2_dma_mask,
499 .coherent_dma_mask = DMA_BIT_MASK(32),
500 },
501 .resource = pxa27x_resource_ssp2,
502 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2),
503};
504
505static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32);
506
507static struct resource pxa27x_resource_ssp3[] = {
508 [0] = {
509 .start = 0x41900000,
510 .end = 0x4190003f,
511 .flags = IORESOURCE_MEM,
512 },
513 [1] = {
514 .start = IRQ_SSP3,
515 .end = IRQ_SSP3,
516 .flags = IORESOURCE_IRQ,
517 },
518 [2] = {
519 /* DRCMR for RX */
520 .start = 66,
521 .end = 66,
522 .flags = IORESOURCE_DMA,
523 },
524 [3] = {
525 /* DRCMR for TX */
526 .start = 67,
527 .end = 67,
528 .flags = IORESOURCE_DMA,
529 },
530};
531
532struct platform_device pxa27x_device_ssp3 = {
533 .name = "pxa27x-ssp",
534 .id = 2,
535 .dev = {
536 .dma_mask = &pxa27x_ssp3_dma_mask,
537 .coherent_dma_mask = DMA_BIT_MASK(32),
538 },
539 .resource = pxa27x_resource_ssp3,
540 .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3),
541};
542#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
543
544#ifdef CONFIG_PXA3xx
545static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
546
547static struct resource pxa3xx_resource_ssp4[] = {
548 [0] = {
549 .start = 0x41a00000,
550 .end = 0x41a0003f,
551 .flags = IORESOURCE_MEM,
552 },
553 [1] = {
554 .start = IRQ_SSP4,
555 .end = IRQ_SSP4,
556 .flags = IORESOURCE_IRQ,
557 },
558 [2] = {
559 /* DRCMR for RX */
560 .start = 2,
561 .end = 2,
562 .flags = IORESOURCE_DMA,
563 },
564 [3] = {
565 /* DRCMR for TX */
566 .start = 3,
567 .end = 3,
568 .flags = IORESOURCE_DMA,
569 },
570};
571
572struct platform_device pxa3xx_device_ssp4 = {
573 /* PXA3xx SSP is basically equivalent to PXA27x */
574 .name = "pxa27x-ssp",
575 .id = 3,
576 .dev = {
577 .dma_mask = &pxa3xx_ssp4_dma_mask,
578 .coherent_dma_mask = DMA_BIT_MASK(32),
579 },
580 .resource = pxa3xx_resource_ssp4,
581 .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
582};
583
584static struct resource pxa3xx_resources_mci2[] = {
585 [0] = {
586 .start = 0x42000000,
587 .end = 0x42000fff,
588 .flags = IORESOURCE_MEM,
589 },
590 [1] = {
591 .start = IRQ_MMC2,
592 .end = IRQ_MMC2,
593 .flags = IORESOURCE_IRQ,
594 },
595 [2] = {
596 .start = 93,
597 .end = 93,
598 .flags = IORESOURCE_DMA,
599 },
600 [3] = {
601 .start = 94,
602 .end = 94,
603 .flags = IORESOURCE_DMA,
604 },
605};
606
607struct platform_device pxa3xx_device_mci2 = {
608 .name = "pxa2xx-mci",
609 .id = 1,
610 .dev = {
611 .dma_mask = &pxamci_dmamask,
612 .coherent_dma_mask = 0xffffffff,
613 },
614 .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2),
615 .resource = pxa3xx_resources_mci2,
616};
617
618void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info)
619{
620 pxa_register_device(&pxa3xx_device_mci2, info);
621}
622
623static struct resource pxa3xx_resources_mci3[] = {
624 [0] = {
625 .start = 0x42500000,
626 .end = 0x42500fff,
627 .flags = IORESOURCE_MEM,
628 },
629 [1] = {
630 .start = IRQ_MMC3,
631 .end = IRQ_MMC3,
632 .flags = IORESOURCE_IRQ,
633 },
634 [2] = {
635 .start = 100,
636 .end = 100,
637 .flags = IORESOURCE_DMA,
638 },
639 [3] = {
640 .start = 101,
641 .end = 101,
642 .flags = IORESOURCE_DMA,
643 },
644};
645
646struct platform_device pxa3xx_device_mci3 = {
647 .name = "pxa2xx-mci",
648 .id = 2,
649 .dev = {
650 .dma_mask = &pxamci_dmamask,
651 .coherent_dma_mask = 0xffffffff,
652 },
653 .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3),
654 .resource = pxa3xx_resources_mci3,
655};
656
657void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
658{
659 pxa_register_device(&pxa3xx_device_mci3, info);
660}
661
662#endif /* CONFIG_PXA3xx */
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 94c8d5cdd60a..96c7c8909068 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -1,4 +1,6 @@
1extern struct platform_device pxa_device_mci; 1extern struct platform_device pxa_device_mci;
2extern struct platform_device pxa3xx_device_mci2;
3extern struct platform_device pxa3xx_device_mci3;
2extern struct platform_device pxa_device_udc; 4extern struct platform_device pxa_device_udc;
3extern struct platform_device pxa_device_fb; 5extern struct platform_device pxa_device_fb;
4extern struct platform_device pxa_device_ffuart; 6extern struct platform_device pxa_device_ffuart;
@@ -12,3 +14,13 @@ extern struct platform_device pxa_device_rtc;
12 14
13extern struct platform_device pxa27x_device_i2c_power; 15extern struct platform_device pxa27x_device_i2c_power;
14extern struct platform_device pxa27x_device_ohci; 16extern struct platform_device pxa27x_device_ohci;
17
18extern struct platform_device pxa25x_device_ssp;
19extern struct platform_device pxa25x_device_nssp;
20extern struct platform_device pxa25x_device_assp;
21extern struct platform_device pxa27x_device_ssp1;
22extern struct platform_device pxa27x_device_ssp2;
23extern struct platform_device pxa27x_device_ssp3;
24extern struct platform_device pxa3xx_device_ssp4;
25
26void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
new file mode 100644
index 000000000000..ee0ae93c876a
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.c
@@ -0,0 +1,101 @@
1/*
2 * Hardware definitions for the Toshiba eseries PDAs
3 *
4 * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
5 *
6 * This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 */
12
13#include <linux/init.h>
14
15#include <asm/setup.h>
16#include <asm/mach/arch.h>
17#include <asm/arch/hardware.h>
18#include <asm/mach-types.h>
19
20#include <generic.h>
21
22/* Only e800 has 128MB RAM */
23static void __init eseries_fixup(struct machine_desc *desc,
24 struct tag *tags, char **cmdline, struct meminfo *mi)
25{
26 mi->nr_banks=1;
27 mi->bank[0].start = 0xa0000000;
28 mi->bank[0].node = 0;
29 if (machine_is_e800())
30 mi->bank[0].size = (128*1024*1024);
31 else
32 mi->bank[0].size = (64*1024*1024);
33}
34
35/* e-series machine definitions */
36
37#ifdef CONFIG_MACH_E330
38MACHINE_START(E330, "Toshiba e330")
39 /* Maintainer: Ian Molton (spyro@f2s.com) */
40 .phys_io = 0x40000000,
41 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
42 .boot_params = 0xa0000100,
43 .map_io = pxa_map_io,
44 .init_irq = pxa25x_init_irq,
45 .fixup = eseries_fixup,
46 .timer = &pxa_timer,
47MACHINE_END
48#endif
49
50#ifdef CONFIG_MACH_E740
51MACHINE_START(E740, "Toshiba e740")
52 /* Maintainer: Ian Molton (spyro@f2s.com) */
53 .phys_io = 0x40000000,
54 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
55 .boot_params = 0xa0000100,
56 .map_io = pxa_map_io,
57 .init_irq = pxa25x_init_irq,
58 .fixup = eseries_fixup,
59 .timer = &pxa_timer,
60MACHINE_END
61#endif
62
63#ifdef CONFIG_MACH_E750
64MACHINE_START(E750, "Toshiba e750")
65 /* Maintainer: Ian Molton (spyro@f2s.com) */
66 .phys_io = 0x40000000,
67 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
68 .boot_params = 0xa0000100,
69 .map_io = pxa_map_io,
70 .init_irq = pxa25x_init_irq,
71 .fixup = eseries_fixup,
72 .timer = &pxa_timer,
73MACHINE_END
74#endif
75
76#ifdef CONFIG_MACH_E400
77MACHINE_START(E400, "Toshiba e400")
78 /* Maintainer: Ian Molton (spyro@f2s.com) */
79 .phys_io = 0x40000000,
80 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
81 .boot_params = 0xa0000100,
82 .map_io = pxa_map_io,
83 .init_irq = pxa25x_init_irq,
84 .fixup = eseries_fixup,
85 .timer = &pxa_timer,
86MACHINE_END
87#endif
88
89#ifdef CONFIG_MACH_E800
90MACHINE_START(E800, "Toshiba e800")
91 /* Maintainer: Ian Molton (spyro@f2s.com) */
92 .phys_io = 0x40000000,
93 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
94 .boot_params = 0xa0000100,
95 .map_io = pxa_map_io,
96 .init_irq = pxa25x_init_irq,
97 .fixup = eseries_fixup,
98 .timer = &pxa_timer,
99MACHINE_END
100#endif
101
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 1c34946ee16e..698aeec52961 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -20,7 +20,6 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/ioport.h> 23#include <linux/ioport.h>
25#include <linux/pm.h> 24#include <linux/pm.h>
26#include <linux/string.h> 25#include <linux/string.h>
@@ -33,13 +32,7 @@
33 32
34#include <asm/arch/pxa-regs.h> 33#include <asm/arch/pxa-regs.h>
35#include <asm/arch/gpio.h> 34#include <asm/arch/gpio.h>
36#include <asm/arch/udc.h>
37#include <asm/arch/pxafb.h>
38#include <asm/arch/mmc.h>
39#include <asm/arch/irda.h>
40#include <asm/arch/i2c.h>
41 35
42#include "devices.h"
43#include "generic.h" 36#include "generic.h"
44 37
45/* 38/*
@@ -203,7 +196,7 @@ static struct map_desc standard_io_desc[] __initdata = {
203 }, { /* Mem Ctl */ 196 }, { /* Mem Ctl */
204 .virtual = 0xf6000000, 197 .virtual = 0xf6000000,
205 .pfn = __phys_to_pfn(0x48000000), 198 .pfn = __phys_to_pfn(0x48000000),
206 .length = 0x00100000, 199 .length = 0x00200000,
207 .type = MT_DEVICE 200 .type = MT_DEVICE
208 }, { /* USB host */ 201 }, { /* USB host */
209 .virtual = 0xf8000000, 202 .virtual = 0xf8000000,
@@ -233,245 +226,3 @@ void __init pxa_map_io(void)
233 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 226 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
234 get_clk_frequency_khz(1); 227 get_clk_frequency_khz(1);
235} 228}
236
237
238static struct resource pxamci_resources[] = {
239 [0] = {
240 .start = 0x41100000,
241 .end = 0x41100fff,
242 .flags = IORESOURCE_MEM,
243 },
244 [1] = {
245 .start = IRQ_MMC,
246 .end = IRQ_MMC,
247 .flags = IORESOURCE_IRQ,
248 },
249};
250
251static u64 pxamci_dmamask = 0xffffffffUL;
252
253struct platform_device pxa_device_mci = {
254 .name = "pxa2xx-mci",
255 .id = -1,
256 .dev = {
257 .dma_mask = &pxamci_dmamask,
258 .coherent_dma_mask = 0xffffffff,
259 },
260 .num_resources = ARRAY_SIZE(pxamci_resources),
261 .resource = pxamci_resources,
262};
263
264void __init pxa_set_mci_info(struct pxamci_platform_data *info)
265{
266 pxa_device_mci.dev.platform_data = info;
267}
268
269
270static struct pxa2xx_udc_mach_info pxa_udc_info;
271
272void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
273{
274 memcpy(&pxa_udc_info, info, sizeof *info);
275}
276
277static struct resource pxa2xx_udc_resources[] = {
278 [0] = {
279 .start = 0x40600000,
280 .end = 0x4060ffff,
281 .flags = IORESOURCE_MEM,
282 },
283 [1] = {
284 .start = IRQ_USB,
285 .end = IRQ_USB,
286 .flags = IORESOURCE_IRQ,
287 },
288};
289
290static u64 udc_dma_mask = ~(u32)0;
291
292struct platform_device pxa_device_udc = {
293 .name = "pxa2xx-udc",
294 .id = -1,
295 .resource = pxa2xx_udc_resources,
296 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
297 .dev = {
298 .platform_data = &pxa_udc_info,
299 .dma_mask = &udc_dma_mask,
300 }
301};
302
303static struct resource pxafb_resources[] = {
304 [0] = {
305 .start = 0x44000000,
306 .end = 0x4400ffff,
307 .flags = IORESOURCE_MEM,
308 },
309 [1] = {
310 .start = IRQ_LCD,
311 .end = IRQ_LCD,
312 .flags = IORESOURCE_IRQ,
313 },
314};
315
316static u64 fb_dma_mask = ~(u64)0;
317
318struct platform_device pxa_device_fb = {
319 .name = "pxa2xx-fb",
320 .id = -1,
321 .dev = {
322 .dma_mask = &fb_dma_mask,
323 .coherent_dma_mask = 0xffffffff,
324 },
325 .num_resources = ARRAY_SIZE(pxafb_resources),
326 .resource = pxafb_resources,
327};
328
329void __init set_pxa_fb_info(struct pxafb_mach_info *info)
330{
331 pxa_device_fb.dev.platform_data = info;
332}
333
334void __init set_pxa_fb_parent(struct device *parent_dev)
335{
336 pxa_device_fb.dev.parent = parent_dev;
337}
338
339static struct resource pxa_resource_ffuart[] = {
340 {
341 .start = __PREG(FFUART),
342 .end = __PREG(FFUART) + 35,
343 .flags = IORESOURCE_MEM,
344 }, {
345 .start = IRQ_FFUART,
346 .end = IRQ_FFUART,
347 .flags = IORESOURCE_IRQ,
348 }
349};
350
351struct platform_device pxa_device_ffuart= {
352 .name = "pxa2xx-uart",
353 .id = 0,
354 .resource = pxa_resource_ffuart,
355 .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
356};
357
358static struct resource pxa_resource_btuart[] = {
359 {
360 .start = __PREG(BTUART),
361 .end = __PREG(BTUART) + 35,
362 .flags = IORESOURCE_MEM,
363 }, {
364 .start = IRQ_BTUART,
365 .end = IRQ_BTUART,
366 .flags = IORESOURCE_IRQ,
367 }
368};
369
370struct platform_device pxa_device_btuart = {
371 .name = "pxa2xx-uart",
372 .id = 1,
373 .resource = pxa_resource_btuart,
374 .num_resources = ARRAY_SIZE(pxa_resource_btuart),
375};
376
377static struct resource pxa_resource_stuart[] = {
378 {
379 .start = __PREG(STUART),
380 .end = __PREG(STUART) + 35,
381 .flags = IORESOURCE_MEM,
382 }, {
383 .start = IRQ_STUART,
384 .end = IRQ_STUART,
385 .flags = IORESOURCE_IRQ,
386 }
387};
388
389struct platform_device pxa_device_stuart = {
390 .name = "pxa2xx-uart",
391 .id = 2,
392 .resource = pxa_resource_stuart,
393 .num_resources = ARRAY_SIZE(pxa_resource_stuart),
394};
395
396static struct resource pxa_resource_hwuart[] = {
397 {
398 .start = __PREG(HWUART),
399 .end = __PREG(HWUART) + 47,
400 .flags = IORESOURCE_MEM,
401 }, {
402 .start = IRQ_HWUART,
403 .end = IRQ_HWUART,
404 .flags = IORESOURCE_IRQ,
405 }
406};
407
408struct platform_device pxa_device_hwuart = {
409 .name = "pxa2xx-uart",
410 .id = 3,
411 .resource = pxa_resource_hwuart,
412 .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
413};
414
415static struct resource pxai2c_resources[] = {
416 {
417 .start = 0x40301680,
418 .end = 0x403016a3,
419 .flags = IORESOURCE_MEM,
420 }, {
421 .start = IRQ_I2C,
422 .end = IRQ_I2C,
423 .flags = IORESOURCE_IRQ,
424 },
425};
426
427struct platform_device pxa_device_i2c = {
428 .name = "pxa2xx-i2c",
429 .id = 0,
430 .resource = pxai2c_resources,
431 .num_resources = ARRAY_SIZE(pxai2c_resources),
432};
433
434void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
435{
436 pxa_device_i2c.dev.platform_data = info;
437}
438
439static struct resource pxai2s_resources[] = {
440 {
441 .start = 0x40400000,
442 .end = 0x40400083,
443 .flags = IORESOURCE_MEM,
444 }, {
445 .start = IRQ_I2S,
446 .end = IRQ_I2S,
447 .flags = IORESOURCE_IRQ,
448 },
449};
450
451struct platform_device pxa_device_i2s = {
452 .name = "pxa2xx-i2s",
453 .id = -1,
454 .resource = pxai2s_resources,
455 .num_resources = ARRAY_SIZE(pxai2s_resources),
456};
457
458static u64 pxaficp_dmamask = ~(u32)0;
459
460struct platform_device pxa_device_ficp = {
461 .name = "pxa2xx-ir",
462 .id = -1,
463 .dev = {
464 .dma_mask = &pxaficp_dmamask,
465 .coherent_dma_mask = 0xffffffff,
466 },
467};
468
469void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
470{
471 pxa_device_ficp.dev.platform_data = info;
472}
473
474struct platform_device pxa_device_rtc = {
475 .name = "sa1100-rtc",
476 .id = -1,
477};
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 465108da2851..0a9434432c55 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -54,7 +54,7 @@ static struct resource smc91x_resources[] = {
54 [1] = { 54 [1] = {
55 .start = IRQ_GPIO(4), 55 .start = IRQ_GPIO(4),
56 .end = IRQ_GPIO(4), 56 .end = IRQ_GPIO(4),
57 .flags = IORESOURCE_IRQ, 57 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
58 } 58 }
59}; 59};
60 60
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
new file mode 100644
index 000000000000..0a4b54c21314
--- /dev/null
+++ b/arch/arm/mach-pxa/littleton.c
@@ -0,0 +1,325 @@
1/*
2 * linux/arch/arm/mach-pxa/littleton.c
3 *
4 * Support for the Marvell Littleton Development Platform.
5 *
6 * Author: Jason Chagas (largely modified code)
7 * Created: Nov 20, 2006
8 * Copyright: (C) Copyright 2006 Marvell International Ltd.
9 *
10 * 2007-11-22 modified to align with latest kernel
11 * eric miao <eric.miao@marvell.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * publishhed by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/delay.h>
21#include <linux/platform_device.h>
22#include <linux/clk.h>
23
24#include <asm/types.h>
25#include <asm/setup.h>
26#include <asm/memory.h>
27#include <asm/mach-types.h>
28#include <asm/hardware.h>
29#include <asm/irq.h>
30
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33#include <asm/mach/irq.h>
34
35#include <asm/arch/pxa-regs.h>
36#include <asm/arch/mfp-pxa300.h>
37#include <asm/arch/gpio.h>
38#include <asm/arch/pxafb.h>
39#include <asm/arch/ssp.h>
40#include <asm/arch/littleton.h>
41
42#include "generic.h"
43
44#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
45
46/* Littleton MFP configurations */
47static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
48 /* LCD */
49 GPIO54_LCD_LDD_0,
50 GPIO55_LCD_LDD_1,
51 GPIO56_LCD_LDD_2,
52 GPIO57_LCD_LDD_3,
53 GPIO58_LCD_LDD_4,
54 GPIO59_LCD_LDD_5,
55 GPIO60_LCD_LDD_6,
56 GPIO61_LCD_LDD_7,
57 GPIO62_LCD_LDD_8,
58 GPIO63_LCD_LDD_9,
59 GPIO64_LCD_LDD_10,
60 GPIO65_LCD_LDD_11,
61 GPIO66_LCD_LDD_12,
62 GPIO67_LCD_LDD_13,
63 GPIO68_LCD_LDD_14,
64 GPIO69_LCD_LDD_15,
65 GPIO70_LCD_LDD_16,
66 GPIO71_LCD_LDD_17,
67 GPIO72_LCD_FCLK,
68 GPIO73_LCD_LCLK,
69 GPIO74_LCD_PCLK,
70 GPIO75_LCD_BIAS,
71
72 /* SSP2 */
73 GPIO25_SSP2_SCLK,
74 GPIO17_SSP2_FRM,
75 GPIO27_SSP2_TXD,
76
77 /* Debug Ethernet */
78 GPIO90_GPIO,
79};
80
81static struct resource smc91x_resources[] = {
82 [0] = {
83 .start = (LITTLETON_ETH_PHYS + 0x300),
84 .end = (LITTLETON_ETH_PHYS + 0xfffff),
85 .flags = IORESOURCE_MEM,
86 },
87 [1] = {
88 .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
89 .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
90 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
91 }
92};
93
94static struct platform_device smc91x_device = {
95 .name = "smc91x",
96 .id = 0,
97 .num_resources = ARRAY_SIZE(smc91x_resources),
98 .resource = smc91x_resources,
99};
100
101#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES)
102/* use bit 30, 31 as the indicator of command parameter number */
103#define CMD0(x) ((0x00000000) | ((x) << 9))
104#define CMD1(x, x1) ((0x40000000) | ((x) << 9) | 0x100 | (x1))
105#define CMD2(x, x1, x2) ((0x80000000) | ((x) << 18) | 0x20000 |\
106 ((x1) << 9) | 0x100 | (x2))
107
108static uint32_t lcd_panel_reset[] = {
109 CMD0(0x1), /* reset */
110 CMD0(0x0), /* nop */
111 CMD0(0x0), /* nop */
112 CMD0(0x0), /* nop */
113};
114
115static uint32_t lcd_panel_on[] = {
116 CMD0(0x29), /* Display ON */
117 CMD2(0xB8, 0xFF, 0xF9), /* Output Control */
118 CMD0(0x11), /* Sleep out */
119 CMD1(0xB0, 0x16), /* Wake */
120};
121
122static uint32_t lcd_panel_off[] = {
123 CMD0(0x28), /* Display OFF */
124 CMD2(0xB8, 0x80, 0x02), /* Output Control */
125 CMD0(0x10), /* Sleep in */
126 CMD1(0xB0, 0x00), /* Deep stand by in */
127};
128
129static uint32_t lcd_vga_pass_through[] = {
130 CMD1(0xB0, 0x16),
131 CMD1(0xBC, 0x80),
132 CMD1(0xE1, 0x00),
133 CMD1(0x36, 0x50),
134 CMD1(0x3B, 0x00),
135};
136
137static uint32_t lcd_qvga_pass_through[] = {
138 CMD1(0xB0, 0x16),
139 CMD1(0xBC, 0x81),
140 CMD1(0xE1, 0x00),
141 CMD1(0x36, 0x50),
142 CMD1(0x3B, 0x22),
143};
144
145static uint32_t lcd_vga_transfer[] = {
146 CMD1(0xcf, 0x02), /* Blanking period control (1) */
147 CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
148 CMD1(0xd1, 0x01), /* CKV timing control on/off */
149 CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */
150 CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */
151 CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */
152 CMD1(0xd5, 0x14), /* ASW timing control (2) */
153 CMD0(0x21), /* Invert for normally black display */
154 CMD0(0x29), /* Display on */
155};
156
157static uint32_t lcd_qvga_transfer[] = {
158 CMD1(0xd6, 0x02), /* Blanking period control (1) */
159 CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */
160 CMD1(0xd8, 0x01), /* CKV timing control on/off */
161 CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */
162 CMD2(0xde, 0x05, 0x0a), /* OEV timing control */
163 CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */
164 CMD1(0xe0, 0x0a), /* ASW timing control (2) */
165 CMD0(0x21), /* Invert for normally black display */
166 CMD0(0x29), /* Display on */
167};
168
169static uint32_t lcd_panel_config[] = {
170 CMD2(0xb8, 0xff, 0xf9), /* Output control */
171 CMD0(0x11), /* sleep out */
172 CMD1(0xba, 0x01), /* Display mode (1) */
173 CMD1(0xbb, 0x00), /* Display mode (2) */
174 CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */
175 CMD1(0xbf, 0x10), /* Drive system change control */
176 CMD1(0xb1, 0x56), /* Booster operation setup */
177 CMD1(0xb2, 0x33), /* Booster mode setup */
178 CMD1(0xb3, 0x11), /* Booster frequency setup */
179 CMD1(0xb4, 0x02), /* Op amp/system clock */
180 CMD1(0xb5, 0x35), /* VCS voltage */
181 CMD1(0xb6, 0x40), /* VCOM voltage */
182 CMD1(0xb7, 0x03), /* External display signal */
183 CMD1(0xbd, 0x00), /* ASW slew rate */
184 CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */
185 CMD1(0xc0, 0x11), /* Sleep out FR count (A) */
186 CMD1(0xc1, 0x11), /* Sleep out FR count (B) */
187 CMD1(0xc2, 0x11), /* Sleep out FR count (C) */
188 CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */
189 CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */
190 CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */
191 CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */
192 CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */
193 CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */
194 CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */
195 CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */
196 CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */
197};
198
199static void ssp_reconfig(struct ssp_dev *dev, int nparam)
200{
201 static int last_nparam = -1;
202
203 /* check if it is necessary to re-config SSP */
204 if (nparam == last_nparam)
205 return;
206
207 ssp_disable(dev);
208 ssp_config(dev, (nparam == 2) ? 0x0010058a : 0x00100581, 0x18, 0, 0);
209
210 last_nparam = nparam;
211}
212
213static void ssp_send_cmd(uint32_t *cmd, int num)
214{
215 static int ssp_initialized;
216 static struct ssp_dev ssp2;
217
218 int i;
219
220 if (!ssp_initialized) {
221 ssp_init(&ssp2, 2, SSP_NO_IRQ);
222 ssp_initialized = 1;
223 }
224
225 clk_enable(ssp2.ssp->clk);
226 for (i = 0; i < num; i++, cmd++) {
227 ssp_reconfig(&ssp2, (*cmd >> 30) & 0x3);
228 ssp_write_word(&ssp2, *cmd & 0x3fffffff);
229
230 /* FIXME: ssp_flush() is mandatory here to work */
231 ssp_flush(&ssp2);
232 }
233 clk_disable(ssp2.ssp->clk);
234}
235
236static void littleton_lcd_power(int on, struct fb_var_screeninfo *var)
237{
238 if (on) {
239 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_on));
240 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_reset));
241 if (var->xres > 240) {
242 /* VGA */
243 ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_pass_through));
244 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
245 ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_transfer));
246 } else {
247 /* QVGA */
248 ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_pass_through));
249 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
250 ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_transfer));
251 }
252 } else
253 ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_off));
254}
255
256static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = {
257 [0] = {
258 /* VGA */
259 .pixclock = 38250,
260 .xres = 480,
261 .yres = 640,
262 .bpp = 16,
263 .hsync_len = 8,
264 .left_margin = 8,
265 .right_margin = 24,
266 .vsync_len = 2,
267 .upper_margin = 2,
268 .lower_margin = 4,
269 .sync = 0,
270 },
271 [1] = {
272 /* QVGA */
273 .pixclock = 153000,
274 .xres = 240,
275 .yres = 320,
276 .bpp = 16,
277 .hsync_len = 8,
278 .left_margin = 8,
279 .right_margin = 88,
280 .vsync_len = 2,
281 .upper_margin = 2,
282 .lower_margin = 2,
283 .sync = 0,
284 },
285};
286
287static struct pxafb_mach_info littleton_lcd_info = {
288 .modes = tpo_tdo24mtea1_modes,
289 .num_modes = 2,
290 .lccr0 = LCCR0_Act,
291 .lccr3 = LCCR3_HSP | LCCR3_VSP,
292 .pxafb_lcd_power = littleton_lcd_power,
293};
294
295static void littleton_init_lcd(void)
296{
297 set_pxa_fb_info(&littleton_lcd_info);
298}
299#else
300static inline void littleton_init_lcd(void) {};
301#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */
302
303static void __init littleton_init(void)
304{
305 /* initialize MFP configurations */
306 pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg));
307
308 /*
309 * Note: we depend bootloader set the correct
310 * value to MSC register for SMC91x.
311 */
312 platform_device_register(&smc91x_device);
313
314 littleton_init_lcd();
315}
316
317MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
318 .phys_io = 0x40000000,
319 .boot_params = 0xa0000100,
320 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
321 .map_io = pxa_map_io,
322 .init_irq = pxa3xx_init_irq,
323 .timer = &pxa_timer,
324 .init_machine = littleton_init,
325MACHINE_END
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 78ebad063cba..afa62ffe3ad5 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -38,6 +38,7 @@
38#include <asm/mach/flash.h> 38#include <asm/mach/flash.h>
39 39
40#include <asm/arch/pxa-regs.h> 40#include <asm/arch/pxa-regs.h>
41#include <asm/arch/pxa2xx-regs.h>
41#include <asm/arch/lpd270.h> 42#include <asm/arch/lpd270.h>
42#include <asm/arch/audio.h> 43#include <asm/arch/audio.h>
43#include <asm/arch/pxafb.h> 44#include <asm/arch/pxafb.h>
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1d3112dc629e..e7ae4bb3e361 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -41,6 +41,7 @@
41#include <asm/hardware/sa1111.h> 41#include <asm/hardware/sa1111.h>
42 42
43#include <asm/arch/pxa-regs.h> 43#include <asm/arch/pxa-regs.h>
44#include <asm/arch/pxa2xx-regs.h>
44#include <asm/arch/lubbock.h> 45#include <asm/arch/lubbock.h>
45#include <asm/arch/udc.h> 46#include <asm/arch/udc.h>
46#include <asm/arch/irda.h> 47#include <asm/arch/irda.h>
@@ -136,9 +137,13 @@ static struct sys_device lubbock_irq_device = {
136 137
137static int __init lubbock_irq_device_init(void) 138static int __init lubbock_irq_device_init(void)
138{ 139{
139 int ret = sysdev_class_register(&lubbock_irq_sysclass); 140 int ret = -ENODEV;
140 if (ret == 0) 141
141 ret = sysdev_register(&lubbock_irq_device); 142 if (machine_is_lubbock()) {
143 ret = sysdev_class_register(&lubbock_irq_sysclass);
144 if (ret == 0)
145 ret = sysdev_register(&lubbock_irq_device);
146 }
142 return ret; 147 return ret;
143} 148}
144 149
@@ -191,7 +196,7 @@ static struct resource smc91x_resources[] = {
191 [1] = { 196 [1] = {
192 .start = LUBBOCK_ETH_IRQ, 197 .start = LUBBOCK_ETH_IRQ,
193 .end = LUBBOCK_ETH_IRQ, 198 .end = LUBBOCK_ETH_IRQ,
194 .flags = IORESOURCE_IRQ, 199 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
195 }, 200 },
196 [2] = { 201 [2] = {
197 .name = "smc91x-attrib", 202 .name = "smc91x-attrib",
@@ -206,30 +211,13 @@ static struct resource smc91x_resources[] = {
206 * (to J5) and poking board registers (as done below). Else it's only useful 211 * (to J5) and poking board registers (as done below). Else it's only useful
207 * for the temperature sensors. 212 * for the temperature sensors.
208 */ 213 */
209static struct resource pxa_ssp_resources[] = {
210 [0] = {
211 .start = __PREG(SSCR0_P(1)),
212 .end = __PREG(SSCR0_P(1)) + 0x14,
213 .flags = IORESOURCE_MEM,
214 },
215 [1] = {
216 .start = IRQ_SSP,
217 .end = IRQ_SSP,
218 .flags = IORESOURCE_IRQ,
219 },
220};
221
222static struct pxa2xx_spi_master pxa_ssp_master_info = { 214static struct pxa2xx_spi_master pxa_ssp_master_info = {
223 .ssp_type = PXA25x_SSP,
224 .clock_enable = CKEN_SSP,
225 .num_chipselect = 0, 215 .num_chipselect = 0,
226}; 216};
227 217
228static struct platform_device pxa_ssp = { 218static struct platform_device pxa_ssp = {
229 .name = "pxa2xx-spi", 219 .name = "pxa2xx-spi",
230 .id = 1, 220 .id = 1,
231 .resource = pxa_ssp_resources,
232 .num_resources = ARRAY_SIZE(pxa_ssp_resources),
233 .dev = { 221 .dev = {
234 .platform_data = &pxa_ssp_master_info, 222 .platform_data = &pxa_ssp_master_info,
235 }, 223 },
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
new file mode 100644
index 000000000000..d98ef7ada2f8
--- /dev/null
+++ b/arch/arm/mach-pxa/magician.c
@@ -0,0 +1,218 @@
1/*
2 * Support for HTC Magician PDA phones:
3 * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
4 * and T-Mobile MDA Compact.
5 *
6 * Copyright (c) 2006-2007 Philipp Zabel
7 *
8 * Based on hx4700.c, spitz.c and others.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/gpio_keys.h>
20#include <linux/input.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/map.h>
23#include <linux/mtd/physmap.h>
24
25#include <asm/gpio.h>
26#include <asm/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/arch/magician.h>
30#include <asm/arch/pxa-regs.h>
31#include <asm/arch/pxafb.h>
32#include <asm/arch/irda.h>
33#include <asm/arch/ohci.h>
34
35#include "generic.h"
36
37/*
38 * IRDA
39 */
40
41static void magician_irda_transceiver_mode(struct device *dev, int mode)
42{
43 gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
44}
45
46static struct pxaficp_platform_data magician_ficp_info = {
47 .transceiver_cap = IR_SIRMODE | IR_OFF,
48 .transceiver_mode = magician_irda_transceiver_mode,
49};
50
51/*
52 * GPIO Keys
53 */
54
55static struct gpio_keys_button magician_button_table[] = {
56 {KEY_POWER, GPIO0_MAGICIAN_KEY_POWER, 0, "Power button"},
57 {KEY_ESC, GPIO37_MAGICIAN_KEY_HANGUP, 0, "Hangup button"},
58 {KEY_F10, GPIO38_MAGICIAN_KEY_CONTACTS, 0, "Contacts button"},
59 {KEY_CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, 0, "Calendar button"},
60 {KEY_CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, 0, "Camera button"},
61 {KEY_UP, GPIO93_MAGICIAN_KEY_UP, 0, "Up button"},
62 {KEY_DOWN, GPIO94_MAGICIAN_KEY_DOWN, 0, "Down button"},
63 {KEY_LEFT, GPIO95_MAGICIAN_KEY_LEFT, 0, "Left button"},
64 {KEY_RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, 0, "Right button"},
65 {KEY_KPENTER, GPIO97_MAGICIAN_KEY_ENTER, 0, "Action button"},
66 {KEY_RECORD, GPIO98_MAGICIAN_KEY_RECORD, 0, "Record button"},
67 {KEY_VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, 0, "Volume up"},
68 {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
69 {KEY_PHONE, GPIO102_MAGICIAN_KEY_PHONE, 0, "Phone button"},
70 {KEY_PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, 0, "Headset button"},
71};
72
73static struct gpio_keys_platform_data gpio_keys_data = {
74 .buttons = magician_button_table,
75 .nbuttons = ARRAY_SIZE(magician_button_table),
76};
77
78static struct platform_device gpio_keys = {
79 .name = "gpio-keys",
80 .dev = {
81 .platform_data = &gpio_keys_data,
82 },
83 .id = -1,
84};
85
86/*
87 * LCD - Toppoly TD028STEB1
88 */
89
90static struct pxafb_mode_info toppoly_modes[] = {
91 {
92 .pixclock = 96153,
93 .bpp = 16,
94 .xres = 240,
95 .yres = 320,
96 .hsync_len = 11,
97 .vsync_len = 3,
98 .left_margin = 19,
99 .upper_margin = 2,
100 .right_margin = 10,
101 .lower_margin = 2,
102 .sync = 0,
103 },
104};
105
106static struct pxafb_mach_info toppoly_info = {
107 .modes = toppoly_modes,
108 .num_modes = 1,
109 .fixed_modes = 1,
110 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
111 .lccr3 = LCCR3_PixRsEdg,
112};
113
114/*
115 * Backlight
116 */
117
118static void magician_set_bl_intensity(int intensity)
119{
120 if (intensity) {
121 PWM_CTRL0 = 1;
122 PWM_PERVAL0 = 0xc8;
123 PWM_PWDUTY0 = intensity;
124 pxa_set_cken(CKEN_PWM0, 1);
125 } else {
126 pxa_set_cken(CKEN_PWM0, 0);
127 }
128}
129
130static struct generic_bl_info backlight_info = {
131 .default_intensity = 0x64,
132 .limit_mask = 0x0b,
133 .max_intensity = 0xc7,
134 .set_bl_intensity = magician_set_bl_intensity,
135};
136
137static struct platform_device backlight = {
138 .name = "corgi-bl",
139 .dev = {
140 .platform_data = &backlight_info,
141 },
142 .id = -1,
143};
144
145
146/*
147 * USB OHCI
148 */
149
150static int magician_ohci_init(struct device *dev)
151{
152 UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
153 ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
154
155 return 0;
156}
157
158static struct pxaohci_platform_data magician_ohci_info = {
159 .port_mode = PMM_PERPORT_MODE,
160 .init = magician_ohci_init,
161 .power_budget = 0,
162};
163
164
165/*
166 * StrataFlash
167 */
168
169#define PXA_CS_SIZE 0x04000000
170
171static struct resource strataflash_resource = {
172 .start = PXA_CS0_PHYS,
173 .end = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
174 .flags = IORESOURCE_MEM,
175};
176
177static struct physmap_flash_data strataflash_data = {
178 .width = 4,
179};
180
181static struct platform_device strataflash = {
182 .name = "physmap-flash",
183 .id = -1,
184 .num_resources = 1,
185 .resource = &strataflash_resource,
186 .dev = {
187 .platform_data = &strataflash_data,
188 },
189};
190
191/*
192 * Platform devices
193 */
194
195static struct platform_device *devices[] __initdata = {
196 &gpio_keys,
197 &backlight,
198 &strataflash,
199};
200
201static void __init magician_init(void)
202{
203 platform_add_devices(devices, ARRAY_SIZE(devices));
204 pxa_set_ohci_info(&magician_ohci_info);
205 pxa_set_ficp_info(&magician_ficp_info);
206 set_pxa_fb_info(&toppoly_info);
207}
208
209
210MACHINE_START(MAGICIAN, "HTC Magician")
211 .phys_io = 0x40000000,
212 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
213 .boot_params = 0xa0000100,
214 .map_io = pxa_map_io,
215 .init_irq = pxa27x_init_irq,
216 .init_machine = magician_init,
217 .timer = &pxa_timer,
218MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 41d8c6cea62b..345c3deeb02e 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -23,6 +23,7 @@
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26#include <linux/backlight.h>
26 27
27#include <asm/types.h> 28#include <asm/types.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
@@ -38,6 +39,7 @@
38#include <asm/mach/flash.h> 39#include <asm/mach/flash.h>
39 40
40#include <asm/arch/pxa-regs.h> 41#include <asm/arch/pxa-regs.h>
42#include <asm/arch/pxa2xx-regs.h>
41#include <asm/arch/mainstone.h> 43#include <asm/arch/mainstone.h>
42#include <asm/arch/audio.h> 44#include <asm/arch/audio.h>
43#include <asm/arch/pxafb.h> 45#include <asm/arch/pxafb.h>
@@ -130,9 +132,13 @@ static struct sys_device mainstone_irq_device = {
130 132
131static int __init mainstone_irq_device_init(void) 133static int __init mainstone_irq_device_init(void)
132{ 134{
133 int ret = sysdev_class_register(&mainstone_irq_sysclass); 135 int ret = -ENODEV;
134 if (ret == 0) 136
135 ret = sysdev_register(&mainstone_irq_device); 137 if (machine_is_mainstone()) {
138 ret = sysdev_class_register(&mainstone_irq_sysclass);
139 if (ret == 0)
140 ret = sysdev_register(&mainstone_irq_device);
141 }
136 return ret; 142 return ret;
137} 143}
138 144
@@ -150,7 +156,7 @@ static struct resource smc91x_resources[] = {
150 [1] = { 156 [1] = {
151 .start = MAINSTONE_IRQ(3), 157 .start = MAINSTONE_IRQ(3),
152 .end = MAINSTONE_IRQ(3), 158 .end = MAINSTONE_IRQ(3),
153 .flags = IORESOURCE_IRQ, 159 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
154 } 160 }
155}; 161};
156 162
@@ -263,21 +269,60 @@ static struct platform_device mst_flash_device[2] = {
263 }, 269 },
264}; 270};
265 271
266static void mainstone_backlight_power(int on) 272#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
273static int mainstone_backlight_update_status(struct backlight_device *bl)
267{ 274{
268 if (on) { 275 int brightness = bl->props.brightness;
276
277 if (bl->props.power != FB_BLANK_UNBLANK ||
278 bl->props.fb_blank != FB_BLANK_UNBLANK)
279 brightness = 0;
280
281 if (brightness != 0) {
269 pxa_gpio_mode(GPIO16_PWM0_MD); 282 pxa_gpio_mode(GPIO16_PWM0_MD);
270 pxa_set_cken(CKEN_PWM0, 1); 283 pxa_set_cken(CKEN_PWM0, 1);
271 PWM_CTRL0 = 0; 284 }
272 PWM_PWDUTY0 = 0x3ff; 285 PWM_CTRL0 = 0;
273 PWM_PERVAL0 = 0x3ff; 286 PWM_PWDUTY0 = brightness;
274 } else { 287 PWM_PERVAL0 = bl->props.max_brightness;
275 PWM_CTRL0 = 0; 288 if (brightness == 0)
276 PWM_PWDUTY0 = 0x0;
277 PWM_PERVAL0 = 0x3FF;
278 pxa_set_cken(CKEN_PWM0, 0); 289 pxa_set_cken(CKEN_PWM0, 0);
290 return 0; /* pointless return value */
291}
292
293static int mainstone_backlight_get_brightness(struct backlight_device *bl)
294{
295 return PWM_PWDUTY0;
296}
297
298static /*const*/ struct backlight_ops mainstone_backlight_ops = {
299 .update_status = mainstone_backlight_update_status,
300 .get_brightness = mainstone_backlight_get_brightness,
301};
302
303static void __init mainstone_backlight_register(void)
304{
305 struct backlight_device *bl;
306
307 bl = backlight_device_register("mainstone-bl", &pxa_device_fb.dev,
308 NULL, &mainstone_backlight_ops);
309 if (IS_ERR(bl)) {
310 printk(KERN_ERR "mainstone: unable to register backlight: %ld\n",
311 PTR_ERR(bl));
312 return;
279 } 313 }
314
315 /*
316 * broken design - register-then-setup interfaces are
317 * utterly broken by definition.
318 */
319 bl->props.max_brightness = 1023;
320 bl->props.brightness = 1023;
321 backlight_update_status(bl);
280} 322}
323#else
324#define mainstone_backlight_register() do { } while (0)
325#endif
281 326
282static struct pxafb_mode_info toshiba_ltm04c380k_mode = { 327static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
283 .pixclock = 50000, 328 .pixclock = 50000,
@@ -311,7 +356,6 @@ static struct pxafb_mach_info mainstone_pxafb_info = {
311 .num_modes = 1, 356 .num_modes = 1,
312 .lccr0 = LCCR0_Act, 357 .lccr0 = LCCR0_Act,
313 .lccr3 = LCCR3_PCP, 358 .lccr3 = LCCR3_PCP,
314 .pxafb_backlight_power = mainstone_backlight_power,
315}; 359};
316 360
317static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data) 361static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
@@ -335,12 +379,10 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in
335 379
336 err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED, 380 err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
337 "MMC card detect", data); 381 "MMC card detect", data);
338 if (err) { 382 if (err)
339 printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 383 printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
340 return -1;
341 }
342 384
343 return 0; 385 return err;
344} 386}
345 387
346static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) 388static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
@@ -473,6 +515,7 @@ static void __init mainstone_init(void)
473 mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; 515 mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
474 516
475 set_pxa_fb_info(&mainstone_pxafb_info); 517 set_pxa_fb_info(&mainstone_pxafb_info);
518 mainstone_backlight_register();
476 519
477 pxa_set_mci_info(&mainstone_mci_platform_data); 520 pxa_set_mci_info(&mainstone_mci_platform_data);
478 pxa_set_ficp_info(&mainstone_ficp_platform_data); 521 pxa_set_ficp_info(&mainstone_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index 436f96574964..ec1b2d8f61c4 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -17,9 +17,11 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/sysdev.h>
20 21
21#include <asm/hardware.h> 22#include <asm/hardware.h>
22#include <asm/arch/mfp.h> 23#include <asm/arch/mfp.h>
24#include <asm/arch/mfp-pxa3xx.h>
23 25
24/* mfp_spin_lock is used to ensure that MFP register configuration 26/* mfp_spin_lock is used to ensure that MFP register configuration
25 * (most likely a read-modify-write operation) is atomic, and that 27 * (most likely a read-modify-write operation) is atomic, and that
@@ -28,43 +30,110 @@
28static DEFINE_SPINLOCK(mfp_spin_lock); 30static DEFINE_SPINLOCK(mfp_spin_lock);
29 31
30static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE); 32static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
33
34struct pxa3xx_mfp_pin {
35 unsigned long config; /* -1 for not configured */
36 unsigned long mfpr_off; /* MFPRxx Register offset */
37 unsigned long mfpr_run; /* Run-Mode Register Value */
38 unsigned long mfpr_lpm; /* Low Power Mode Register Value */
39};
40
31static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX]; 41static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
32 42
43/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
44const static unsigned long mfpr_lpm[] = {
45 MFPR_LPM_INPUT,
46 MFPR_LPM_DRIVE_LOW,
47 MFPR_LPM_DRIVE_HIGH,
48 MFPR_LPM_PULL_LOW,
49 MFPR_LPM_PULL_HIGH,
50 MFPR_LPM_FLOAT,
51};
52
53/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
54const static unsigned long mfpr_pull[] = {
55 MFPR_PULL_NONE,
56 MFPR_PULL_LOW,
57 MFPR_PULL_HIGH,
58 MFPR_PULL_BOTH,
59};
60
61/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
62const static unsigned long mfpr_edge[] = {
63 MFPR_EDGE_NONE,
64 MFPR_EDGE_RISE,
65 MFPR_EDGE_FALL,
66 MFPR_EDGE_BOTH,
67};
68
33#define mfpr_readl(off) \ 69#define mfpr_readl(off) \
34 __raw_readl(mfpr_mmio_base + (off)) 70 __raw_readl(mfpr_mmio_base + (off))
35 71
36#define mfpr_writel(off, val) \ 72#define mfpr_writel(off, val) \
37 __raw_writel(val, mfpr_mmio_base + (off)) 73 __raw_writel(val, mfpr_mmio_base + (off))
38 74
75#define mfp_configured(p) ((p)->config != -1)
76
39/* 77/*
40 * perform a read-back of any MFPR register to make sure the 78 * perform a read-back of any MFPR register to make sure the
41 * previous writings are finished 79 * previous writings are finished
42 */ 80 */
43#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) 81#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
44 82
45static inline void __mfp_config(int pin, unsigned long val) 83static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
46{ 84{
47 unsigned long off = mfp_table[pin].mfpr_off; 85 if (mfp_configured(p))
86 mfpr_writel(p->mfpr_off, p->mfpr_run);
87}
48 88
49 mfp_table[pin].mfpr_val = val; 89static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
50 mfpr_writel(off, val); 90{
91 if (mfp_configured(p)) {
92 unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
93 if (mfpr_clr != p->mfpr_run)
94 mfpr_writel(p->mfpr_off, mfpr_clr);
95 if (p->mfpr_lpm != mfpr_clr)
96 mfpr_writel(p->mfpr_off, p->mfpr_lpm);
97 }
51} 98}
52 99
53void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num) 100void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
54{ 101{
55 int i, pin; 102 unsigned long flags;
56 unsigned long val, flags; 103 int i;
57 mfp_cfg_t *mfp_cfg = mfp_cfgs;
58 104
59 spin_lock_irqsave(&mfp_spin_lock, flags); 105 spin_lock_irqsave(&mfp_spin_lock, flags);
60 106
61 for (i = 0; i < num; i++, mfp_cfg++) { 107 for (i = 0; i < num; i++, mfp_cfgs++) {
62 pin = MFP_CFG_PIN(*mfp_cfg); 108 unsigned long tmp, c = *mfp_cfgs;
63 val = MFP_CFG_VAL(*mfp_cfg); 109 struct pxa3xx_mfp_pin *p;
110 int pin, af, drv, lpm, edge, pull;
64 111
112 pin = MFP_PIN(c);
65 BUG_ON(pin >= MFP_PIN_MAX); 113 BUG_ON(pin >= MFP_PIN_MAX);
66 114 p = &mfp_table[pin];
67 __mfp_config(pin, val); 115
116 af = MFP_AF(c);
117 drv = MFP_DS(c);
118 lpm = MFP_LPM_STATE(c);
119 edge = MFP_LPM_EDGE(c);
120 pull = MFP_PULL(c);
121
122 /* run-mode pull settings will conflict with MFPR bits of
123 * low power mode state, calculate mfpr_run and mfpr_lpm
124 * individually if pull != MFP_PULL_NONE
125 */
126 tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
127
128 if (likely(pull == MFP_PULL_NONE)) {
129 p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
130 p->mfpr_lpm = p->mfpr_run;
131 } else {
132 p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
133 p->mfpr_run = tmp | mfpr_pull[pull];
134 }
135
136 p->config = c; __mfp_config_run(p);
68 } 137 }
69 138
70 mfpr_sync(); 139 mfpr_sync();
@@ -96,140 +165,82 @@ void pxa3xx_mfp_write(int mfp, unsigned long val)
96 spin_unlock_irqrestore(&mfp_spin_lock, flags); 165 spin_unlock_irqrestore(&mfp_spin_lock, flags);
97} 166}
98 167
99void pxa3xx_mfp_set_afds(int mfp, int af, int ds) 168void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
100{
101 uint32_t mfpr_off, mfpr_val;
102 unsigned long flags;
103
104 BUG_ON(mfp >= MFP_PIN_MAX);
105
106 spin_lock_irqsave(&mfp_spin_lock, flags);
107 mfpr_off = mfp_table[mfp].mfpr_off;
108
109 mfpr_val = mfpr_readl(mfpr_off);
110 mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
111 mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
112 ((ds & 0x7) << MFPR_DRV_OFFSET));
113
114 mfpr_writel(mfpr_off, mfpr_val);
115 mfpr_sync();
116
117 spin_unlock_irqrestore(&mfp_spin_lock, flags);
118}
119
120void pxa3xx_mfp_set_rdh(int mfp, int rdh)
121{ 169{
122 uint32_t mfpr_off, mfpr_val; 170 struct pxa3xx_mfp_addr_map *p;
123 unsigned long flags; 171 unsigned long offset, flags;
124 172 int i;
125 BUG_ON(mfp >= MFP_PIN_MAX);
126 173
127 spin_lock_irqsave(&mfp_spin_lock, flags); 174 spin_lock_irqsave(&mfp_spin_lock, flags);
128 175
129 mfpr_off = mfp_table[mfp].mfpr_off; 176 for (p = map; p->start != MFP_PIN_INVALID; p++) {
130 177 offset = p->offset;
131 mfpr_val = mfpr_readl(mfpr_off); 178 i = p->start;
132 mfpr_val &= ~MFPR_RDH_MASK;
133
134 if (likely(rdh))
135 mfpr_val |= (1u << MFPR_SS_OFFSET);
136 179
137 mfpr_writel(mfpr_off, mfpr_val); 180 do {
138 mfpr_sync(); 181 mfp_table[i].mfpr_off = offset;
182 mfp_table[i].mfpr_run = 0;
183 mfp_table[i].mfpr_lpm = 0;
184 offset += 4; i++;
185 } while ((i <= p->end) && (p->end != -1));
186 }
139 187
140 spin_unlock_irqrestore(&mfp_spin_lock, flags); 188 spin_unlock_irqrestore(&mfp_spin_lock, flags);
141} 189}
142 190
143void pxa3xx_mfp_set_lpm(int mfp, int lpm) 191void __init pxa3xx_init_mfp(void)
144{ 192{
145 uint32_t mfpr_off, mfpr_val; 193 int i;
146 unsigned long flags;
147
148 BUG_ON(mfp >= MFP_PIN_MAX);
149
150 spin_lock_irqsave(&mfp_spin_lock, flags);
151
152 mfpr_off = mfp_table[mfp].mfpr_off;
153 mfpr_val = mfpr_readl(mfpr_off);
154 mfpr_val &= ~MFPR_LPM_MASK;
155
156 if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
157 if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
158 if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
159 if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
160 if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
161
162 mfpr_writel(mfpr_off, mfpr_val);
163 mfpr_sync();
164 194
165 spin_unlock_irqrestore(&mfp_spin_lock, flags); 195 for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
196 mfp_table[i].config = -1;
166} 197}
167 198
168void pxa3xx_mfp_set_pull(int mfp, int pull) 199#ifdef CONFIG_PM
200/*
201 * Configure the MFPs appropriately for suspend/resume.
202 * FIXME: this should probably depend on which system state we're
203 * entering - for instance, we might not want to place MFP pins in
204 * a pull-down mode if they're an active low chip select, and we're
205 * just entering standby.
206 */
207static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
169{ 208{
170 uint32_t mfpr_off, mfpr_val; 209 int pin;
171 unsigned long flags;
172
173 BUG_ON(mfp >= MFP_PIN_MAX);
174
175 spin_lock_irqsave(&mfp_spin_lock, flags);
176 210
177 mfpr_off = mfp_table[mfp].mfpr_off; 211 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
178 mfpr_val = mfpr_readl(mfpr_off); 212 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
179 mfpr_val &= ~MFPR_PULL_MASK; 213 __mfp_config_lpm(p);
180 mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET); 214 }
181 215 return 0;
182 mfpr_writel(mfpr_off, mfpr_val);
183 mfpr_sync();
184
185 spin_unlock_irqrestore(&mfp_spin_lock, flags);
186} 216}
187 217
188void pxa3xx_mfp_set_edge(int mfp, int edge) 218static int pxa3xx_mfp_resume(struct sys_device *d)
189{ 219{
190 uint32_t mfpr_off, mfpr_val; 220 int pin;
191 unsigned long flags;
192
193 BUG_ON(mfp >= MFP_PIN_MAX);
194
195 spin_lock_irqsave(&mfp_spin_lock, flags);
196
197 mfpr_off = mfp_table[mfp].mfpr_off;
198 mfpr_val = mfpr_readl(mfpr_off);
199
200 mfpr_val &= ~MFPR_EDGE_MASK;
201 mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
202 mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
203 221
204 mfpr_writel(mfpr_off, mfpr_val); 222 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
205 mfpr_sync(); 223 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
206 224 __mfp_config_run(p);
207 spin_unlock_irqrestore(&mfp_spin_lock, flags); 225 }
226 return 0;
208} 227}
209 228
210void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map) 229static struct sysdev_class mfp_sysclass = {
211{ 230 set_kset_name("mfp"),
212 struct pxa3xx_mfp_addr_map *p; 231 .suspend = pxa3xx_mfp_suspend,
213 unsigned long offset, flags; 232 .resume = pxa3xx_mfp_resume,
214 int i; 233};
215
216 spin_lock_irqsave(&mfp_spin_lock, flags);
217
218 for (p = map; p->start != MFP_PIN_INVALID; p++) {
219 offset = p->offset;
220 i = p->start;
221
222 do {
223 mfp_table[i].mfpr_off = offset;
224 mfp_table[i].mfpr_val = 0;
225 offset += 4; i++;
226 } while ((i <= p->end) && (p->end != -1));
227 }
228 234
229 spin_unlock_irqrestore(&mfp_spin_lock, flags); 235static struct sys_device mfp_device = {
230} 236 .id = 0,
237 .cls = &mfp_sysclass,
238};
231 239
232void __init pxa3xx_init_mfp(void) 240static int __init mfp_init_devicefs(void)
233{ 241{
234 memset(mfp_table, 0, sizeof(mfp_table)); 242 sysdev_class_register(&mfp_sysclass);
243 return sysdev_register(&mfp_device);
235} 244}
245device_initcall(mfp_init_devicefs);
246#endif
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
new file mode 100644
index 000000000000..540c3bba5f9a
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -0,0 +1,216 @@
1/*
2 * linux/arch/arm/mach-pxa/pcm027.c
3 * Support for the Phytec phyCORE-PXA270 CPU card (aka PCM-027).
4 *
5 * Refer
6 * http://www.phytec.com/products/sbc/ARM-XScale/phyCORE-XScale-PXA270.html
7 * for additional hardware info
8 *
9 * Author: Juergen Kilb
10 * Created: April 05, 2005
11 * Copyright: Phytec Messtechnik GmbH
12 * e-Mail: armlinux@phytec.de
13 *
14 * based on Intel Mainstone Board
15 *
16 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/mtd/physmap.h>
26#include <linux/spi/spi.h>
27#include <linux/leds.h>
28#include <asm/mach-types.h>
29#include <asm/mach/arch.h>
30#include <asm/arch/hardware.h>
31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/pxa2xx_spi.h>
33#include <asm/arch/pcm027.h>
34#include "generic.h"
35
36/*
37 * ABSTRACT:
38 *
39 * The PXA270 processor comes with a bunch of hardware on its silicon.
40 * Not all of this hardware can be used at the same time and not all
41 * is routed to module's connectors. Also it depends on the baseboard, what
42 * kind of hardware can be used in which way.
43 * -> So this file supports the main devices on the CPU card only!
44 * Refer pcm990-baseboard.c how to extend this features to get a full
45 * blown system with many common interfaces.
46 *
47 * The PCM-027 supports the following interfaces through its connectors and
48 * will be used in pcm990-baseboard.c:
49 *
50 * - LCD support
51 * - MMC support
52 * - IDE/CF card
53 * - FFUART
54 * - BTUART
55 * - IRUART
56 * - AC97
57 * - SSP
58 * - SSP3
59 *
60 * Claimed GPIOs:
61 * GPIO0 -> IRQ input from RTC
62 * GPIO2 -> SYS_ENA*)
63 * GPIO3 -> PWR_SCL
64 * GPIO4 -> PWR_SDA
65 * GPIO5 -> PowerCap0*)
66 * GPIO6 -> PowerCap1*)
67 * GPIO7 -> PowerCap2*)
68 * GPIO8 -> PowerCap3*)
69 * GPIO15 -> /CS1
70 * GPIO20 -> /CS2
71 * GPIO21 -> /CS3
72 * GPIO33 -> /CS5 network controller select
73 * GPIO52 -> IRQ from network controller
74 * GPIO78 -> /CS2
75 * GPIO80 -> /CS4
76 * GPIO90 -> LED0
77 * GPIO91 -> LED1
78 * GPIO114 -> IRQ from CAN controller
79 * GPIO117 -> SCL
80 * GPIO118 -> SDA
81 *
82 * *) CPU internal use only
83 */
84
85/*
86 * SMC91x network controller specific stuff
87 */
88static struct resource smc91x_resources[] = {
89 [0] = {
90 .start = PCM027_ETH_PHYS + 0x300,
91 .end = PCM027_ETH_PHYS + PCM027_ETH_SIZE,
92 .flags = IORESOURCE_MEM,
93 },
94 [1] = {
95 .start = PCM027_ETH_IRQ,
96 .end = PCM027_ETH_IRQ,
97 /* note: smc91x's driver doesn't use the trigger bits yet */
98 .flags = IORESOURCE_IRQ | PCM027_ETH_IRQ_EDGE,
99 }
100};
101
102static struct platform_device smc91x_device = {
103 .name = "smc91x",
104 .id = 0,
105 .num_resources = ARRAY_SIZE(smc91x_resources),
106 .resource = smc91x_resources,
107};
108
109static struct physmap_flash_data pcm027_flash_data = {
110 .width = 4,
111};
112
113static struct resource pcm027_flash_resource = {
114 .start = PCM027_FLASH_PHYS,
115 .end = PCM027_FLASH_PHYS + PCM027_FLASH_SIZE - 1 ,
116 .flags = IORESOURCE_MEM,
117};
118
119static struct platform_device pcm027_flash = {
120 .name = "physmap-flash",
121 .id = 0,
122 .dev = {
123 .platform_data = &pcm027_flash_data,
124 },
125 .resource = &pcm027_flash_resource,
126 .num_resources = 1,
127};
128
129#ifdef CONFIG_LEDS_GPIO
130
131static struct gpio_led pcm027_led[] = {
132 {
133 .name = "led0:red", /* FIXME */
134 .gpio = PCM027_LED_CPU
135 },
136 {
137 .name = "led1:green", /* FIXME */
138 .gpio = PCM027_LED_HEARD_BEAT
139 },
140};
141
142static struct gpio_led_platform_data pcm027_led_data = {
143 .num_leds = ARRAY_SIZE(pcm027_led),
144 .leds = pcm027_led
145};
146
147static struct platform_device pcm027_led_dev = {
148 .name = "leds-gpio",
149 .id = 0,
150 .dev = {
151 .platform_data = &pcm027_led_data,
152 },
153};
154
155#endif /* CONFIG_LEDS_GPIO */
156
157/*
158 * declare the available device resources on this board
159 */
160static struct platform_device *devices[] __initdata = {
161 &smc91x_device,
162 &pcm027_flash,
163#ifdef CONFIG_LEDS_GPIO
164 &pcm027_led_dev
165#endif
166};
167
168/*
169 * pcm027_init - breath some life into the board
170 */
171static void __init pcm027_init(void)
172{
173 /* system bus arbiter setting
174 * - Core_Park
175 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
176 */
177 ARB_CNTRL = ARB_CORE_PARK | 0x234;
178
179 platform_add_devices(devices, ARRAY_SIZE(devices));
180
181 /* LEDs (on demand only) */
182#ifdef CONFIG_LEDS_GPIO
183 pxa_gpio_mode(PCM027_LED_CPU | GPIO_OUT);
184 pxa_gpio_mode(PCM027_LED_HEARD_BEAT | GPIO_OUT);
185#endif /* CONFIG_LEDS_GPIO */
186
187 /* at last call the baseboard to initialize itself */
188#ifdef CONFIG_MACH_PCM990_BASEBOARD
189 pcm990_baseboard_init();
190#endif
191}
192
193static void __init pcm027_map_io(void)
194{
195 pxa_map_io();
196
197 /* initialize sleep mode regs (wake-up sources, etc) */
198 PGSR0 = 0x01308000;
199 PGSR1 = 0x00CF0002;
200 PGSR2 = 0x0E294000;
201 PGSR3 = 0x0000C000;
202 PWER = 0x40000000 | PWER_GPIO0 | PWER_GPIO1;
203 PRER = 0x00000000;
204 PFER = 0x00000003;
205}
206
207MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
208 /* Maintainer: Pengutronix */
209 .boot_params = 0xa0000100,
210 .phys_io = 0x40000000,
211 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
212 .map_io = pcm027_map_io,
213 .init_irq = pxa27x_init_irq,
214 .timer = &pxa_timer,
215 .init_machine = pcm027_init,
216MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
new file mode 100644
index 000000000000..3dda16a20049
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -0,0 +1,330 @@
1/*
2 * arch/arm/mach-pxa/pcm990-baseboard.c
3 * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
4 *
5 * Refer
6 * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
7 * for additional hardware info
8 *
9 * Author: Juergen Kilb
10 * Created: April 05, 2005
11 * Copyright: Phytec Messtechnik GmbH
12 * e-Mail: armlinux@phytec.de
13 *
14 * based on Intel Mainstone Board
15 *
16 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/ide.h>
26#include <asm/mach/map.h>
27#include <asm/arch/pxa-regs.h>
28#include <asm/arch/mmc.h>
29#include <asm/arch/ohci.h>
30#include <asm/arch/pcm990_baseboard.h>
31
32/*
33 * The PCM-990 development baseboard uses PCM-027's hardeware in the
34 * following way:
35 *
36 * - LCD support is in use
37 * - GPIO16 is output for back light on/off with PWM
38 * - GPIO58 ... GPIO73 are outputs for display data
39 * - GPIO74 is output output for LCDFCLK
40 * - GPIO75 is output for LCDLCLK
41 * - GPIO76 is output for LCDPCLK
42 * - GPIO77 is output for LCDBIAS
43 * - MMC support is in use
44 * - GPIO32 is output for MMCCLK
45 * - GPIO92 is MMDAT0
46 * - GPIO109 is MMDAT1
47 * - GPIO110 is MMCS0
48 * - GPIO111 is MMCS1
49 * - GPIO112 is MMCMD
50 * - IDE/CF card is in use
51 * - GPIO48 is output /POE
52 * - GPIO49 is output /PWE
53 * - GPIO50 is output /PIOR
54 * - GPIO51 is output /PIOW
55 * - GPIO54 is output /PCE2
56 * - GPIO55 is output /PREG
57 * - GPIO56 is input /PWAIT
58 * - GPIO57 is output /PIOS16
59 * - GPIO79 is output PSKTSEL
60 * - GPIO85 is output /PCE1
61 * - FFUART is in use
62 * - GPIO34 is input FFRXD
63 * - GPIO35 is input FFCTS
64 * - GPIO36 is input FFDCD
65 * - GPIO37 is input FFDSR
66 * - GPIO38 is input FFRI
67 * - GPIO39 is output FFTXD
68 * - GPIO40 is output FFDTR
69 * - GPIO41 is output FFRTS
70 * - BTUART is in use
71 * - GPIO42 is input BTRXD
72 * - GPIO43 is output BTTXD
73 * - GPIO44 is input BTCTS
74 * - GPIO45 is output BTRTS
75 * - IRUART is in use
76 * - GPIO46 is input STDRXD
77 * - GPIO47 is output STDTXD
78 * - AC97 is in use*)
79 * - GPIO28 is input AC97CLK
80 * - GPIO29 is input AC97DatIn
81 * - GPIO30 is output AC97DatO
82 * - GPIO31 is output AC97SYNC
83 * - GPIO113 is output AC97_RESET
84 * - SSP is in use
85 * - GPIO23 is output SSPSCLK
86 * - GPIO24 is output chip select to Max7301
87 * - GPIO25 is output SSPTXD
88 * - GPIO26 is input SSPRXD
89 * - GPIO27 is input for Max7301 IRQ
90 * - GPIO53 is input SSPSYSCLK
91 * - SSP3 is in use
92 * - GPIO81 is output SSPTXD3
93 * - GPIO82 is input SSPRXD3
94 * - GPIO83 is output SSPSFRM
95 * - GPIO84 is output SSPCLK3
96 *
97 * Otherwise claimed GPIOs:
98 * GPIO1 -> IRQ from user switch
99 * GPIO9 -> IRQ from power management
100 * GPIO10 -> IRQ from WML9712 AC97 controller
101 * GPIO11 -> IRQ from IDE controller
102 * GPIO12 -> IRQ from CF controller
103 * GPIO13 -> IRQ from CF controller
104 * GPIO14 -> GPIO free
105 * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
106 * GPIO19 -> GPIO free
107 * GPIO20 -> /SDCS2
108 * GPIO21 -> /CS3 PC card socket select
109 * GPIO33 -> /CS5 network controller select
110 * GPIO78 -> /CS2 (16 bit wide data path)
111 * GPIO80 -> /CS4 (16 bit wide data path)
112 * GPIO86 -> GPIO free
113 * GPIO87 -> GPIO free
114 * GPIO90 -> LED0 on CPU module
115 * GPIO91 -> LED1 on CPI module
116 * GPIO117 -> SCL
117 * GPIO118 -> SDA
118 */
119
120static unsigned long pcm990_irq_enabled;
121
122static void pcm990_mask_ack_irq(unsigned int irq)
123{
124 int pcm990_irq = (irq - PCM027_IRQ(0));
125 PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
126}
127
128static void pcm990_unmask_irq(unsigned int irq)
129{
130 int pcm990_irq = (irq - PCM027_IRQ(0));
131 /* the irq can be acknowledged only if deasserted, so it's done here */
132 PCM990_INTSETCLR |= 1 << pcm990_irq;
133 PCM990_INTMSKENA = (pcm990_irq_enabled |= (1 << pcm990_irq));
134}
135
136static struct irq_chip pcm990_irq_chip = {
137 .mask_ack = pcm990_mask_ack_irq,
138 .unmask = pcm990_unmask_irq,
139};
140
141static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
142{
143 unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
144
145 do {
146 GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
147 GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
148 if (likely(pending)) {
149 irq = PCM027_IRQ(0) + __ffs(pending);
150 desc = irq_desc + irq;
151 desc_handle_irq(irq, desc);
152 }
153 pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
154 } while (pending);
155}
156
157static void __init pcm990_init_irq(void)
158{
159 int irq;
160
161 /* setup extra PCM990 irqs */
162 for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
163 set_irq_chip(irq, &pcm990_irq_chip);
164 set_irq_handler(irq, handle_level_irq);
165 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
166 }
167
168 PCM990_INTMSKENA = 0x00; /* disable all Interrupts */
169 PCM990_INTSETCLR = 0xFF;
170
171 set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
172 set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
173}
174
175static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
176 void *data)
177{
178 int err;
179
180 /*
181 * enable GPIO for PXA27x MMC controller
182 */
183 pxa_gpio_mode(GPIO32_MMCCLK_MD);
184 pxa_gpio_mode(GPIO112_MMCCMD_MD);
185 pxa_gpio_mode(GPIO92_MMCDAT0_MD);
186 pxa_gpio_mode(GPIO109_MMCDAT1_MD);
187 pxa_gpio_mode(GPIO110_MMCDAT2_MD);
188 pxa_gpio_mode(GPIO111_MMCDAT3_MD);
189
190 err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
191 "MMC card detect", data);
192 if (err)
193 printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
194 "card detect IRQ\n");
195
196 return err;
197}
198
199static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
200{
201 struct pxamci_platform_data *p_d = dev->platform_data;
202
203 if ((1 << vdd) & p_d->ocr_mask)
204 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
205 PCM990_CTRL_MMC2PWR;
206 else
207 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
208 ~PCM990_CTRL_MMC2PWR;
209}
210
211static void pcm990_mci_exit(struct device *dev, void *data)
212{
213 free_irq(PCM027_MMCDET_IRQ, data);
214}
215
216#define MSECS_PER_JIFFY (1000/HZ)
217
218static struct pxamci_platform_data pcm990_mci_platform_data = {
219 .detect_delay = 250 / MSECS_PER_JIFFY,
220 .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
221 .init = pcm990_mci_init,
222 .setpower = pcm990_mci_setpower,
223 .exit = pcm990_mci_exit,
224};
225
226/*
227 * init OHCI hardware to work with
228 *
229 * Note: Only USB port 1 (host only) is connected
230 *
231 * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
232 * GPIO89 (USBHPEN#1): power-on out, on when low
233 */
234static int pcm990_ohci_init(struct device *dev)
235{
236 pxa_gpio_mode(PCM990_USB_OVERCURRENT);
237 pxa_gpio_mode(PCM990_USB_PWR_EN);
238 /*
239 * disable USB port 2 and 3
240 * power sense is active low
241 */
242 UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
243 UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
244 /*
245 * wait 10ms after Power on
246 * overcurrent per port
247 * power switch per port
248 */
249 UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */
250
251 return 0;
252}
253
254static struct pxaohci_platform_data pcm990_ohci_platform_data = {
255 .port_mode = PMM_PERPORT_MODE,
256 .init = pcm990_ohci_init,
257 .exit = NULL,
258};
259
260/*
261 * AC97 support
262 * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ
263 */
264static struct resource pxa27x_ac97_resources[] = {
265 [0] = {
266 .start = 0x40500000,
267 .end = 0x40500000 + 0xfff,
268 .flags = IORESOURCE_MEM,
269 },
270 [1] = {
271 .start = IRQ_AC97,
272 .end = IRQ_AC97,
273 .flags = IORESOURCE_IRQ,
274 },
275};
276
277static u64 pxa_ac97_dmamask = 0xffffffffUL;
278
279static struct platform_device pxa27x_device_ac97 = {
280 .name = "pxa2xx-ac97",
281 .id = -1,
282 .dev = {
283 .dma_mask = &pxa_ac97_dmamask,
284 .coherent_dma_mask = 0xffffffff,
285 },
286 .num_resources = ARRAY_SIZE(pxa27x_ac97_resources),
287 .resource = pxa27x_ac97_resources,
288};
289
290/*
291 * enable generic access to the base board control CPLDs U6 and U7
292 */
293static struct map_desc pcm990_io_desc[] __initdata = {
294 {
295 .virtual = PCM990_CTRL_BASE,
296 .pfn = __phys_to_pfn(PCM990_CTRL_PHYS),
297 .length = PCM990_CTRL_SIZE,
298 .type = MT_DEVICE /* CPLD */
299 }, {
300 .virtual = PCM990_CF_PLD_BASE,
301 .pfn = __phys_to_pfn(PCM990_CF_PLD_PHYS),
302 .length = PCM990_CF_PLD_SIZE,
303 .type = MT_DEVICE /* CPLD */
304 }
305};
306
307/*
308 * system init for baseboard usage. Will be called by pcm027 init.
309 *
310 * Add platform devices present on this baseboard and init
311 * them from CPU side as far as required to use them later on
312 */
313void __init pcm990_baseboard_init(void)
314{
315 /* register CPLD access */
316 iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
317
318 /* register CPLD's IRQ controller */
319 pcm990_init_irq();
320
321 platform_device_register(&pxa27x_device_ac97);
322
323 /* MMC */
324 pxa_set_mci_info(&pcm990_mci_platform_data);
325
326 /* USB host */
327 pxa_set_ohci_info(&pcm990_ohci_platform_data);
328
329 printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
330}
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index a941c71c7d06..039194cbe477 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -38,34 +38,37 @@ int pxa_pm_enter(suspend_state_t state)
38 iwmmxt_task_disable(NULL); 38 iwmmxt_task_disable(NULL);
39#endif 39#endif
40 40
41 pxa_cpu_pm_fns->save(sleep_save); 41 /* skip registers saving for standby */
42 if (state != PM_SUSPEND_STANDBY) {
43 pxa_cpu_pm_fns->save(sleep_save);
44 /* before sleeping, calculate and save a checksum */
45 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
46 sleep_save_checksum += sleep_save[i];
47 }
42 48
43 /* Clear sleep reset status */ 49 /* Clear sleep reset status */
44 RCSR = RCSR_SMR; 50 RCSR = RCSR_SMR;
45 51
46 /* before sleeping, calculate and save a checksum */
47 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
48 sleep_save_checksum += sleep_save[i];
49
50 /* *** go zzz *** */ 52 /* *** go zzz *** */
51 pxa_cpu_pm_fns->enter(state); 53 pxa_cpu_pm_fns->enter(state);
52 cpu_init(); 54 cpu_init();
53 55
54 /* after sleeping, validate the checksum */ 56 if (state != PM_SUSPEND_STANDBY) {
55 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) 57 /* after sleeping, validate the checksum */
56 checksum += sleep_save[i]; 58 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
59 checksum += sleep_save[i];
57 60
58 /* if invalid, display message and wait for a hardware reset */ 61 /* if invalid, display message and wait for a hardware reset */
59 if (checksum != sleep_save_checksum) { 62 if (checksum != sleep_save_checksum) {
60#ifdef CONFIG_ARCH_LUBBOCK 63#ifdef CONFIG_ARCH_LUBBOCK
61 LUB_HEXLED = 0xbadbadc5; 64 LUB_HEXLED = 0xbadbadc5;
62#endif 65#endif
63 while (1) 66 while (1)
64 pxa_cpu_pm_fns->enter(state); 67 pxa_cpu_pm_fns->enter(state);
68 }
69 pxa_cpu_pm_fns->restore(sleep_save);
65 } 70 }
66 71
67 pxa_cpu_pm_fns->restore(sleep_save);
68
69 pr_debug("*** made it back from resume\n"); 72 pr_debug("*** made it back from resume\n");
70 73
71 return 0; 74 return 0;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 655668d4d0e9..dd54496083cb 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -215,12 +215,10 @@ static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int,
215 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, 215 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
216 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 216 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
217 "MMC card detect", data); 217 "MMC card detect", data);
218 if (err) { 218 if (err)
219 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 219 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
220 return -1;
221 }
222 220
223 return 0; 221 return err;
224} 222}
225 223
226static void poodle_mci_setpower(struct device *dev, unsigned int vdd) 224static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 006a6e09589c..ddd05bf78e02 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -123,12 +123,15 @@ static struct clk pxa25x_clks[] = {
123 INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), 123 INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
124 INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), 124 INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
125 INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), 125 INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
126
127 INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev),
128 INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev),
129 INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
130
126 /* 131 /*
127 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), 132 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
128 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), 133 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
129 INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL),
130 INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), 134 INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
131 INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL),
132 */ 135 */
133 INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), 136 INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
134}; 137};
@@ -216,8 +219,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
216 219
217static void pxa25x_cpu_pm_enter(suspend_state_t state) 220static void pxa25x_cpu_pm_enter(suspend_state_t state)
218{ 221{
219 CKEN = 0;
220
221 switch (state) { 222 switch (state) {
222 case PM_SUSPEND_MEM: 223 case PM_SUSPEND_MEM:
223 /* set resume return address */ 224 /* set resume return address */
@@ -239,6 +240,8 @@ static void __init pxa25x_init_pm(void)
239{ 240{
240 pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; 241 pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
241} 242}
243#else
244static inline void pxa25x_init_pm(void) {}
242#endif 245#endif
243 246
244/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm 247/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
@@ -290,16 +293,15 @@ void __init pxa25x_init_irq(void)
290} 293}
291 294
292static struct platform_device *pxa25x_devices[] __initdata = { 295static struct platform_device *pxa25x_devices[] __initdata = {
293 &pxa_device_mci,
294 &pxa_device_udc, 296 &pxa_device_udc,
295 &pxa_device_fb,
296 &pxa_device_ffuart, 297 &pxa_device_ffuart,
297 &pxa_device_btuart, 298 &pxa_device_btuart,
298 &pxa_device_stuart, 299 &pxa_device_stuart,
299 &pxa_device_i2c,
300 &pxa_device_i2s, 300 &pxa_device_i2s,
301 &pxa_device_ficp,
302 &pxa_device_rtc, 301 &pxa_device_rtc,
302 &pxa25x_device_ssp,
303 &pxa25x_device_nssp,
304 &pxa25x_device_assp,
303}; 305};
304 306
305static int __init pxa25x_init(void) 307static int __init pxa25x_init(void)
@@ -315,9 +317,9 @@ static int __init pxa25x_init(void)
315 317
316 if ((ret = pxa_init_dma(16))) 318 if ((ret = pxa_init_dma(16)))
317 return ret; 319 return ret;
318#ifdef CONFIG_PM 320
319 pxa25x_init_pm(); 321 pxa25x_init_pm();
320#endif 322
321 ret = platform_add_devices(pxa25x_devices, 323 ret = platform_add_devices(pxa25x_devices,
322 ARRAY_SIZE(pxa25x_devices)); 324 ARRAY_SIZE(pxa25x_devices));
323 } 325 }
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 57efebdc4324..96cf274ec7cb 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,6 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/arch/irqs.h> 22#include <asm/arch/irqs.h>
23#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/pxa2xx-regs.h>
24#include <asm/arch/ohci.h> 25#include <asm/arch/ohci.h>
25#include <asm/arch/pm.h> 26#include <asm/arch/pm.h>
26#include <asm/arch/dma.h> 27#include <asm/arch/dma.h>
@@ -151,11 +152,12 @@ static struct clk pxa27x_clks[] = {
151 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), 152 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
152 INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL), 153 INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
153 154
155 INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
156 INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
157 INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
158
154 /* 159 /*
155 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), 160 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
156 INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL),
157 INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL),
158 INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL),
159 INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), 161 INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
160 INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), 162 INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
161 INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), 163 INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
@@ -264,12 +266,6 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
264{ 266{
265 extern void pxa_cpu_standby(void); 267 extern void pxa_cpu_standby(void);
266 268
267 if (state == PM_SUSPEND_STANDBY)
268 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
269 (1 << CKEN_LCD) | (1 << CKEN_PWM0);
270 else
271 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
272
273 /* ensure voltage-change sequencer not initiated, which hangs */ 269 /* ensure voltage-change sequencer not initiated, which hangs */
274 PCFR &= ~PCFR_FVC; 270 PCFR &= ~PCFR_FVC;
275 271
@@ -305,6 +301,8 @@ static void __init pxa27x_init_pm(void)
305{ 301{
306 pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; 302 pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
307} 303}
304#else
305static inline void pxa27x_init_pm(void) {}
308#endif 306#endif
309 307
310/* PXA27x: Various gpios can issue wakeup events. This logic only 308/* PXA27x: Various gpios can issue wakeup events. This logic only
@@ -374,37 +372,6 @@ void __init pxa27x_init_irq(void)
374 * device registration specific to PXA27x. 372 * device registration specific to PXA27x.
375 */ 373 */
376 374
377static u64 pxa27x_dmamask = 0xffffffffUL;
378
379static struct resource pxa27x_ohci_resources[] = {
380 [0] = {
381 .start = 0x4C000000,
382 .end = 0x4C00ff6f,
383 .flags = IORESOURCE_MEM,
384 },
385 [1] = {
386 .start = IRQ_USBH1,
387 .end = IRQ_USBH1,
388 .flags = IORESOURCE_IRQ,
389 },
390};
391
392struct platform_device pxa27x_device_ohci = {
393 .name = "pxa27x-ohci",
394 .id = -1,
395 .dev = {
396 .dma_mask = &pxa27x_dmamask,
397 .coherent_dma_mask = 0xffffffff,
398 },
399 .num_resources = ARRAY_SIZE(pxa27x_ohci_resources),
400 .resource = pxa27x_ohci_resources,
401};
402
403void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
404{
405 pxa27x_device_ohci.dev.platform_data = info;
406}
407
408static struct resource i2c_power_resources[] = { 375static struct resource i2c_power_resources[] = {
409 { 376 {
410 .start = 0x40f00180, 377 .start = 0x40f00180,
@@ -430,18 +397,16 @@ void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
430} 397}
431 398
432static struct platform_device *devices[] __initdata = { 399static struct platform_device *devices[] __initdata = {
433 &pxa_device_mci,
434 &pxa_device_udc, 400 &pxa_device_udc,
435 &pxa_device_fb,
436 &pxa_device_ffuart, 401 &pxa_device_ffuart,
437 &pxa_device_btuart, 402 &pxa_device_btuart,
438 &pxa_device_stuart, 403 &pxa_device_stuart,
439 &pxa_device_i2c,
440 &pxa_device_i2s, 404 &pxa_device_i2s,
441 &pxa_device_ficp,
442 &pxa_device_rtc, 405 &pxa_device_rtc,
443 &pxa27x_device_i2c_power, 406 &pxa27x_device_i2c_power,
444 &pxa27x_device_ohci, 407 &pxa27x_device_ssp1,
408 &pxa27x_device_ssp2,
409 &pxa27x_device_ssp3,
445}; 410};
446 411
447static int __init pxa27x_init(void) 412static int __init pxa27x_init(void)
@@ -452,9 +417,9 @@ static int __init pxa27x_init(void)
452 417
453 if ((ret = pxa_init_dma(32))) 418 if ((ret = pxa_init_dma(32)))
454 return ret; 419 return ret;
455#ifdef CONFIG_PM 420
456 pxa27x_init_pm(); 421 pxa27x_init_pm();
457#endif 422
458 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 423 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
459 } 424 }
460 return ret; 425 return ret;
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 37e93f9ba8fc..5cbf057a1b32 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/io.h>
22 23
23#include <asm/hardware.h> 24#include <asm/hardware.h>
24#include <asm/arch/pxa3xx-regs.h> 25#include <asm/arch/pxa3xx-regs.h>
@@ -189,8 +190,237 @@ static struct clk pxa3xx_clks[] = {
189 190
190 PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), 191 PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
191 PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), 192 PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
193 PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
194
195 PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
196 PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
197 PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
198 PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
199
200 PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
201 PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
202 PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
203};
204
205#ifdef CONFIG_PM
206#define SLEEP_SAVE_SIZE 4
207
208#define ISRAM_START 0x5c000000
209#define ISRAM_SIZE SZ_256K
210
211static void __iomem *sram;
212static unsigned long wakeup_src;
213
214static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
215{
216 pr_debug("PM: CKENA=%08x CKENB=%08x\n", CKENA, CKENB);
217
218 if (CKENA & (1 << CKEN_USBH)) {
219 printk(KERN_ERR "PM: USB host clock not stopped?\n");
220 CKENA &= ~(1 << CKEN_USBH);
221 }
222// CKENA |= 1 << (CKEN_ISC & 31);
223
224 /*
225 * Low power modes require the HSIO2 clock to be enabled.
226 */
227 CKENB |= 1 << (CKEN_HSIO2 & 31);
228}
229
230static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save)
231{
232 CKENB &= ~(1 << (CKEN_HSIO2 & 31));
233}
234
235/*
236 * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic
237 * memory controller has to be reinitialised, so we place some code
238 * in the SRAM to perform this function.
239 *
240 * We disable FIQs across the standby - otherwise, we might receive a
241 * FIQ while the SDRAM is unavailable.
242 */
243static void pxa3xx_cpu_standby(unsigned int pwrmode)
244{
245 extern const char pm_enter_standby_start[], pm_enter_standby_end[];
246 void (*fn)(unsigned int) = (void __force *)(sram + 0x8000);
247
248 memcpy_toio(sram + 0x8000, pm_enter_standby_start,
249 pm_enter_standby_end - pm_enter_standby_start);
250
251 AD2D0SR = ~0;
252 AD2D1SR = ~0;
253 AD2D0ER = wakeup_src;
254 AD2D1ER = 0;
255 ASCR = ASCR;
256 ARSR = ARSR;
257
258 local_fiq_disable();
259 fn(pwrmode);
260 local_fiq_enable();
261
262 AD2D0ER = 0;
263 AD2D1ER = 0;
264
265 printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR);
266}
267
268static void pxa3xx_cpu_pm_enter(suspend_state_t state)
269{
270 /*
271 * Don't sleep if no wakeup sources are defined
272 */
273 if (wakeup_src == 0)
274 return;
275
276 switch (state) {
277 case PM_SUSPEND_STANDBY:
278 pxa3xx_cpu_standby(PXA3xx_PM_S0D2C2);
279 break;
280
281 case PM_SUSPEND_MEM:
282 break;
283 }
284}
285
286static int pxa3xx_cpu_pm_valid(suspend_state_t state)
287{
288 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
289}
290
291static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
292 .save_size = SLEEP_SAVE_SIZE,
293 .save = pxa3xx_cpu_pm_save,
294 .restore = pxa3xx_cpu_pm_restore,
295 .valid = pxa3xx_cpu_pm_valid,
296 .enter = pxa3xx_cpu_pm_enter,
192}; 297};
193 298
299static void __init pxa3xx_init_pm(void)
300{
301 sram = ioremap(ISRAM_START, ISRAM_SIZE);
302 if (!sram) {
303 printk(KERN_ERR "Unable to map ISRAM: disabling standby/suspend\n");
304 return;
305 }
306
307 /*
308 * Since we copy wakeup code into the SRAM, we need to ensure
309 * that it is preserved over the low power modes. Note: bit 8
310 * is undocumented in the developer manual, but must be set.
311 */
312 AD1R |= ADXR_L2 | ADXR_R0;
313 AD2R |= ADXR_L2 | ADXR_R0;
314 AD3R |= ADXR_L2 | ADXR_R0;
315
316 /*
317 * Clear the resume enable registers.
318 */
319 AD1D0ER = 0;
320 AD2D0ER = 0;
321 AD2D1ER = 0;
322 AD3ER = 0;
323
324 pxa_cpu_pm_fns = &pxa3xx_cpu_pm_fns;
325}
326
327static int pxa3xx_set_wake(unsigned int irq, unsigned int on)
328{
329 unsigned long flags, mask = 0;
330
331 switch (irq) {
332 case IRQ_SSP3:
333 mask = ADXER_MFP_WSSP3;
334 break;
335 case IRQ_MSL:
336 mask = ADXER_WMSL0;
337 break;
338 case IRQ_USBH2:
339 case IRQ_USBH1:
340 mask = ADXER_WUSBH;
341 break;
342 case IRQ_KEYPAD:
343 mask = ADXER_WKP;
344 break;
345 case IRQ_AC97:
346 mask = ADXER_MFP_WAC97;
347 break;
348 case IRQ_USIM:
349 mask = ADXER_WUSIM0;
350 break;
351 case IRQ_SSP2:
352 mask = ADXER_MFP_WSSP2;
353 break;
354 case IRQ_I2C:
355 mask = ADXER_MFP_WI2C;
356 break;
357 case IRQ_STUART:
358 mask = ADXER_MFP_WUART3;
359 break;
360 case IRQ_BTUART:
361 mask = ADXER_MFP_WUART2;
362 break;
363 case IRQ_FFUART:
364 mask = ADXER_MFP_WUART1;
365 break;
366 case IRQ_MMC:
367 mask = ADXER_MFP_WMMC1;
368 break;
369 case IRQ_SSP:
370 mask = ADXER_MFP_WSSP1;
371 break;
372 case IRQ_RTCAlrm:
373 mask = ADXER_WRTC;
374 break;
375 case IRQ_SSP4:
376 mask = ADXER_MFP_WSSP4;
377 break;
378 case IRQ_TSI:
379 mask = ADXER_WTSI;
380 break;
381 case IRQ_USIM2:
382 mask = ADXER_WUSIM1;
383 break;
384 case IRQ_MMC2:
385 mask = ADXER_MFP_WMMC2;
386 break;
387 case IRQ_NAND:
388 mask = ADXER_MFP_WFLASH;
389 break;
390 case IRQ_USB2:
391 mask = ADXER_WUSB2;
392 break;
393 case IRQ_WAKEUP0:
394 mask = ADXER_WEXTWAKE0;
395 break;
396 case IRQ_WAKEUP1:
397 mask = ADXER_WEXTWAKE1;
398 break;
399 case IRQ_MMC3:
400 mask = ADXER_MFP_GEN12;
401 break;
402 }
403
404 local_irq_save(flags);
405 if (on)
406 wakeup_src |= mask;
407 else
408 wakeup_src &= ~mask;
409 local_irq_restore(flags);
410
411 return 0;
412}
413
414static void pxa3xx_init_irq_pm(void)
415{
416 pxa_init_irq_set_wake(pxa3xx_set_wake);
417}
418
419#else
420static inline void pxa3xx_init_pm(void) {}
421static inline void pxa3xx_init_irq_pm(void) {}
422#endif
423
194void __init pxa3xx_init_irq(void) 424void __init pxa3xx_init_irq(void)
195{ 425{
196 /* enable CP6 access */ 426 /* enable CP6 access */
@@ -202,6 +432,7 @@ void __init pxa3xx_init_irq(void)
202 pxa_init_irq_low(); 432 pxa_init_irq_low();
203 pxa_init_irq_high(); 433 pxa_init_irq_high();
204 pxa_init_irq_gpio(128); 434 pxa_init_irq_gpio(128);
435 pxa3xx_init_irq_pm();
205} 436}
206 437
207/* 438/*
@@ -209,16 +440,16 @@ void __init pxa3xx_init_irq(void)
209 */ 440 */
210 441
211static struct platform_device *devices[] __initdata = { 442static struct platform_device *devices[] __initdata = {
212 &pxa_device_mci,
213 &pxa_device_udc, 443 &pxa_device_udc,
214 &pxa_device_fb,
215 &pxa_device_ffuart, 444 &pxa_device_ffuart,
216 &pxa_device_btuart, 445 &pxa_device_btuart,
217 &pxa_device_stuart, 446 &pxa_device_stuart,
218 &pxa_device_i2c,
219 &pxa_device_i2s, 447 &pxa_device_i2s,
220 &pxa_device_ficp,
221 &pxa_device_rtc, 448 &pxa_device_rtc,
449 &pxa27x_device_ssp1,
450 &pxa27x_device_ssp2,
451 &pxa27x_device_ssp3,
452 &pxa3xx_device_ssp4,
222}; 453};
223 454
224static int __init pxa3xx_init(void) 455static int __init pxa3xx_init(void)
@@ -231,6 +462,8 @@ static int __init pxa3xx_init(void)
231 if ((ret = pxa_init_dma(32))) 462 if ((ret = pxa_init_dma(32)))
232 return ret; 463 return ret;
233 464
465 pxa3xx_init_pm();
466
234 return platform_add_devices(devices, ARRAY_SIZE(devices)); 467 return platform_add_devices(devices, ARRAY_SIZE(devices));
235 } 468 }
236 return 0; 469 return 0;
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index da4769caaf72..047909a76651 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -26,28 +26,15 @@ void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
26 26
27 27
28/* 28/*
29 * SharpSL Backlight 29 * SharpSL/Corgi LCD Driver
30 */ 30 */
31void corgi_bl_set_intensity(int intensity); 31void corgi_lcdtg_suspend(void);
32void spitz_bl_set_intensity(int intensity); 32void corgi_lcdtg_hw_init(int mode);
33void akita_bl_set_intensity(int intensity);
34
35
36/*
37 * SharpSL Touchscreen Driver
38 */
39unsigned long corgi_get_hsync_len(void);
40unsigned long spitz_get_hsync_len(void);
41void corgi_put_hsync(void);
42void spitz_put_hsync(void);
43void corgi_wait_hsync(void);
44void spitz_wait_hsync(void);
45 33
46 34
47/* 35/*
48 * SharpSL Battery/PM Driver 36 * SharpSL Battery/PM Driver
49 */ 37 */
50
51#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) 38#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
52 39
53/* MAX1111 Channel Definitions */ 40/* MAX1111 Channel Definitions */
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index d0447723b73a..14bb4a93ea52 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -16,6 +16,7 @@
16#include <asm/hardware.h> 16#include <asm/hardware.h>
17 17
18#include <asm/arch/pxa-regs.h> 18#include <asm/arch/pxa-regs.h>
19#include <asm/arch/pxa2xx-regs.h>
19 20
20#define MDREFR_KDIV 0x200a4000 // all banks 21#define MDREFR_KDIV 0x200a4000 // all banks
21#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0 22#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
@@ -49,6 +50,7 @@ pxa_cpu_save_sp:
49 str r0, [r1] 50 str r0, [r1]
50 ldr pc, [sp], #4 51 ldr pc, [sp], #4
51 52
53#ifdef CONFIG_PXA27x
52/* 54/*
53 * pxa27x_cpu_suspend() 55 * pxa27x_cpu_suspend()
54 * 56 *
@@ -104,9 +106,11 @@ ENTRY(pxa27x_cpu_suspend)
104 106
105 @ align execution to a cache line 107 @ align execution to a cache line
106 b pxa_cpu_do_suspend 108 b pxa_cpu_do_suspend
109#endif
107 110
111#ifdef CONFIG_PXA25x
108/* 112/*
109 * pxa27x_cpu_suspend() 113 * pxa25x_cpu_suspend()
110 * 114 *
111 * Forces CPU into sleep state. 115 * Forces CPU into sleep state.
112 * 116 *
@@ -169,6 +173,7 @@ ENTRY(pxa25x_cpu_suspend)
169 mcr p14, 0, r0, c6, c0, 0 173 mcr p14, 0, r0, c6, c0, 0
170 orr r0, r0, #2 @ initiate change bit 174 orr r0, r0, #2 @ initiate change bit
171 b pxa_cpu_do_suspend 175 b pxa_cpu_do_suspend
176#endif
172 177
173 .ltorg 178 .ltorg
174 .align 5 179 .align 5
@@ -208,7 +213,7 @@ pxa_cpu_do_suspend:
20820: b 20b @ loop waiting for sleep 21320: b 20b @ loop waiting for sleep
209 214
210/* 215/*
211 * cpu_pxa_resume() 216 * pxa_cpu_resume()
212 * 217 *
213 * entry point from bootloader into kernel during resume 218 * entry point from bootloader into kernel during resume
214 * 219 *
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 2d78199d24af..5078edeadf96 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -271,6 +271,55 @@ static struct platform_device spitzled_device = {
271/* 271/*
272 * Spitz Touch Screen Device 272 * Spitz Touch Screen Device
273 */ 273 */
274
275static unsigned long (*get_hsync_invperiod)(struct device *dev);
276
277static void inline sharpsl_wait_sync(int gpio)
278{
279 while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
280 while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
281}
282
283static struct device *spitz_pxafb_dev;
284
285static int is_pxafb_device(struct device * dev, void * data)
286{
287 struct platform_device *pdev = container_of(dev, struct platform_device, dev);
288
289 return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
290}
291
292static unsigned long spitz_get_hsync_invperiod(void)
293{
294#ifdef CONFIG_FB_PXA
295 if (!spitz_pxafb_dev) {
296 spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
297 if (!spitz_pxafb_dev)
298 return 0;
299 }
300 if (!get_hsync_invperiod)
301 get_hsync_invperiod = symbol_get(pxafb_get_hsync_time);
302 if (!get_hsync_invperiod)
303#endif
304 return 0;
305
306 return get_hsync_invperiod(spitz_pxafb_dev);
307}
308
309static void spitz_put_hsync(void)
310{
311 put_device(spitz_pxafb_dev);
312 if (get_hsync_invperiod)
313 symbol_put(pxafb_get_hsync_time);
314 spitz_pxafb_dev = NULL;
315 get_hsync_invperiod = NULL;
316}
317
318static void spitz_wait_hsync(void)
319{
320 sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
321}
322
274static struct resource spitzts_resources[] = { 323static struct resource spitzts_resources[] = {
275 [0] = { 324 [0] = {
276 .start = SPITZ_IRQ_GPIO_TP_INT, 325 .start = SPITZ_IRQ_GPIO_TP_INT,
@@ -280,9 +329,9 @@ static struct resource spitzts_resources[] = {
280}; 329};
281 330
282static struct corgits_machinfo spitz_ts_machinfo = { 331static struct corgits_machinfo spitz_ts_machinfo = {
283 .get_hsync_len = spitz_get_hsync_len, 332 .get_hsync_invperiod = spitz_get_hsync_invperiod,
284 .put_hsync = spitz_put_hsync, 333 .put_hsync = spitz_put_hsync,
285 .wait_hsync = spitz_wait_hsync, 334 .wait_hsync = spitz_wait_hsync,
286}; 335};
287 336
288static struct platform_device spitzts_device = { 337static struct platform_device spitzts_device = {
@@ -325,12 +374,10 @@ static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, vo
325 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, 374 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
326 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 375 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
327 "MMC card detect", data); 376 "MMC card detect", data);
328 if (err) { 377 if (err)
329 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 378 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
330 return -1;
331 }
332 379
333 return 0; 380 return err;
334} 381}
335 382
336static void spitz_mci_setpower(struct device *dev, unsigned int vdd) 383static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
@@ -423,6 +470,14 @@ static struct pxaficp_platform_data spitz_ficp_platform_data = {
423 * Spitz PXA Framebuffer 470 * Spitz PXA Framebuffer
424 */ 471 */
425 472
473static void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
474{
475 if (on)
476 corgi_lcdtg_hw_init(var->xres);
477 else
478 corgi_lcdtg_suspend();
479}
480
426static struct pxafb_mode_info spitz_pxafb_modes[] = { 481static struct pxafb_mode_info spitz_pxafb_modes[] = {
427{ 482{
428 .pixclock = 19231, 483 .pixclock = 19231,
@@ -520,6 +575,27 @@ static void __init common_init(void)
520 set_pxa_fb_info(&spitz_pxafb_info); 575 set_pxa_fb_info(&spitz_pxafb_info);
521} 576}
522 577
578#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
579static void spitz_bl_set_intensity(int intensity)
580{
581 if (intensity > 0x10)
582 intensity += 0x10;
583
584 /* Bits 0-4 are accessed via the SSP interface */
585 corgi_ssp_blduty_set(intensity & 0x1f);
586
587 /* Bit 5 is via SCOOP */
588 if (intensity & 0x0020)
589 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
590 else
591 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
592
593 if (intensity)
594 set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
595 else
596 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
597}
598
523static void __init spitz_init(void) 599static void __init spitz_init(void)
524{ 600{
525 platform_scoop_config = &spitz_pcmcia_config; 601 platform_scoop_config = &spitz_pcmcia_config;
@@ -530,6 +606,7 @@ static void __init spitz_init(void)
530 606
531 platform_device_register(&spitzscoop2_device); 607 platform_device_register(&spitzscoop2_device);
532} 608}
609#endif
533 610
534#ifdef CONFIG_MACH_AKITA 611#ifdef CONFIG_MACH_AKITA
535/* 612/*
@@ -542,6 +619,26 @@ struct platform_device akitaioexp_device = {
542 619
543EXPORT_SYMBOL_GPL(akitaioexp_device); 620EXPORT_SYMBOL_GPL(akitaioexp_device);
544 621
622static void akita_bl_set_intensity(int intensity)
623{
624 if (intensity > 0x10)
625 intensity += 0x10;
626
627 /* Bits 0-4 are accessed via the SSP interface */
628 corgi_ssp_blduty_set(intensity & 0x1f);
629
630 /* Bit 5 is via IO-Expander */
631 if (intensity & 0x0020)
632 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
633 else
634 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
635
636 if (intensity)
637 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
638 else
639 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
640}
641
545static void __init akita_init(void) 642static void __init akita_init(void)
546{ 643{
547 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode; 644 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
@@ -558,7 +655,6 @@ static void __init akita_init(void)
558} 655}
559#endif 656#endif
560 657
561
562static void __init fixup_spitz(struct machine_desc *desc, 658static void __init fixup_spitz(struct machine_desc *desc,
563 struct tag *tags, char **cmdline, struct meminfo *mi) 659 struct tag *tags, char **cmdline, struct meminfo *mi)
564{ 660{
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index b2eb38543d1c..00af7f2fed66 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -32,45 +32,27 @@
32#include <linux/ioport.h> 32#include <linux/ioport.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/clk.h>
36#include <linux/err.h>
37#include <linux/platform_device.h>
38
35#include <asm/io.h> 39#include <asm/io.h>
36#include <asm/irq.h> 40#include <asm/irq.h>
37#include <asm/hardware.h> 41#include <asm/hardware.h>
38#include <asm/arch/ssp.h> 42#include <asm/arch/ssp.h>
39#include <asm/arch/pxa-regs.h> 43#include <asm/arch/pxa-regs.h>
40 44#include <asm/arch/regs-ssp.h>
41#define PXA_SSP_PORTS 3
42 45
43#define TIMEOUT 100000 46#define TIMEOUT 100000
44 47
45struct ssp_info_ {
46 int irq;
47 u32 clock;
48};
49
50/*
51 * SSP port clock and IRQ settings
52 */
53static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
54#if defined (CONFIG_PXA27x)
55 {IRQ_SSP, CKEN_SSP1},
56 {IRQ_SSP2, CKEN_SSP2},
57 {IRQ_SSP3, CKEN_SSP3},
58#else
59 {IRQ_SSP, CKEN_SSP},
60 {IRQ_NSSP, CKEN_NSSP},
61 {IRQ_ASSP, CKEN_ASSP},
62#endif
63};
64
65static DEFINE_MUTEX(mutex);
66static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
67
68static irqreturn_t ssp_interrupt(int irq, void *dev_id) 48static irqreturn_t ssp_interrupt(int irq, void *dev_id)
69{ 49{
70 struct ssp_dev *dev = dev_id; 50 struct ssp_dev *dev = dev_id;
71 unsigned int status = SSSR_P(dev->port); 51 struct ssp_device *ssp = dev->ssp;
52 unsigned int status;
72 53
73 SSSR_P(dev->port) = status; /* clear status bits */ 54 status = __raw_readl(ssp->mmio_base + SSSR);
55 __raw_writel(status, ssp->mmio_base + SSSR);
74 56
75 if (status & SSSR_ROR) 57 if (status & SSSR_ROR)
76 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); 58 printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
@@ -99,15 +81,16 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id)
99 */ 81 */
100int ssp_write_word(struct ssp_dev *dev, u32 data) 82int ssp_write_word(struct ssp_dev *dev, u32 data)
101{ 83{
84 struct ssp_device *ssp = dev->ssp;
102 int timeout = TIMEOUT; 85 int timeout = TIMEOUT;
103 86
104 while (!(SSSR_P(dev->port) & SSSR_TNF)) { 87 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
105 if (!--timeout) 88 if (!--timeout)
106 return -ETIMEDOUT; 89 return -ETIMEDOUT;
107 cpu_relax(); 90 cpu_relax();
108 } 91 }
109 92
110 SSDR_P(dev->port) = data; 93 __raw_writel(data, ssp->mmio_base + SSDR);
111 94
112 return 0; 95 return 0;
113} 96}
@@ -129,15 +112,16 @@ int ssp_write_word(struct ssp_dev *dev, u32 data)
129 */ 112 */
130int ssp_read_word(struct ssp_dev *dev, u32 *data) 113int ssp_read_word(struct ssp_dev *dev, u32 *data)
131{ 114{
115 struct ssp_device *ssp = dev->ssp;
132 int timeout = TIMEOUT; 116 int timeout = TIMEOUT;
133 117
134 while (!(SSSR_P(dev->port) & SSSR_RNE)) { 118 while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
135 if (!--timeout) 119 if (!--timeout)
136 return -ETIMEDOUT; 120 return -ETIMEDOUT;
137 cpu_relax(); 121 cpu_relax();
138 } 122 }
139 123
140 *data = SSDR_P(dev->port); 124 *data = __raw_readl(ssp->mmio_base + SSDR);
141 return 0; 125 return 0;
142} 126}
143 127
@@ -151,17 +135,28 @@ int ssp_read_word(struct ssp_dev *dev, u32 *data)
151 */ 135 */
152int ssp_flush(struct ssp_dev *dev) 136int ssp_flush(struct ssp_dev *dev)
153{ 137{
138 struct ssp_device *ssp = dev->ssp;
154 int timeout = TIMEOUT * 2; 139 int timeout = TIMEOUT * 2;
155 140
141 /* ensure TX FIFO is empty instead of not full */
142 if (cpu_is_pxa3xx()) {
143 while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) {
144 if (!--timeout)
145 return -ETIMEDOUT;
146 cpu_relax();
147 }
148 timeout = TIMEOUT * 2;
149 }
150
156 do { 151 do {
157 while (SSSR_P(dev->port) & SSSR_RNE) { 152 while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
158 if (!--timeout) 153 if (!--timeout)
159 return -ETIMEDOUT; 154 return -ETIMEDOUT;
160 (void) SSDR_P(dev->port); 155 (void)__raw_readl(ssp->mmio_base + SSDR);
161 } 156 }
162 if (!--timeout) 157 if (!--timeout)
163 return -ETIMEDOUT; 158 return -ETIMEDOUT;
164 } while (SSSR_P(dev->port) & SSSR_BSY); 159 } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
165 160
166 return 0; 161 return 0;
167} 162}
@@ -173,7 +168,12 @@ int ssp_flush(struct ssp_dev *dev)
173 */ 168 */
174void ssp_enable(struct ssp_dev *dev) 169void ssp_enable(struct ssp_dev *dev)
175{ 170{
176 SSCR0_P(dev->port) |= SSCR0_SSE; 171 struct ssp_device *ssp = dev->ssp;
172 uint32_t sscr0;
173
174 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
175 sscr0 |= SSCR0_SSE;
176 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
177} 177}
178 178
179/** 179/**
@@ -183,7 +183,12 @@ void ssp_enable(struct ssp_dev *dev)
183 */ 183 */
184void ssp_disable(struct ssp_dev *dev) 184void ssp_disable(struct ssp_dev *dev)
185{ 185{
186 SSCR0_P(dev->port) &= ~SSCR0_SSE; 186 struct ssp_device *ssp = dev->ssp;
187 uint32_t sscr0;
188
189 sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
190 sscr0 &= ~SSCR0_SSE;
191 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
187} 192}
188 193
189/** 194/**
@@ -192,14 +197,16 @@ void ssp_disable(struct ssp_dev *dev)
192 * 197 *
193 * Save the configured SSP state for suspend. 198 * Save the configured SSP state for suspend.
194 */ 199 */
195void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp) 200void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
196{ 201{
197 ssp->cr0 = SSCR0_P(dev->port); 202 struct ssp_device *ssp = dev->ssp;
198 ssp->cr1 = SSCR1_P(dev->port); 203
199 ssp->to = SSTO_P(dev->port); 204 state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
200 ssp->psp = SSPSP_P(dev->port); 205 state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
206 state->to = __raw_readl(ssp->mmio_base + SSTO);
207 state->psp = __raw_readl(ssp->mmio_base + SSPSP);
201 208
202 SSCR0_P(dev->port) &= ~SSCR0_SSE; 209 ssp_disable(dev);
203} 210}
204 211
205/** 212/**
@@ -208,16 +215,18 @@ void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp)
208 * 215 *
209 * Restore the SSP configuration saved previously by ssp_save_state. 216 * Restore the SSP configuration saved previously by ssp_save_state.
210 */ 217 */
211void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp) 218void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
212{ 219{
213 SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE; 220 struct ssp_device *ssp = dev->ssp;
221 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
214 222
215 SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE; 223 __raw_writel(sssr, ssp->mmio_base + SSSR);
216 SSCR1_P(dev->port) = ssp->cr1;
217 SSTO_P(dev->port) = ssp->to;
218 SSPSP_P(dev->port) = ssp->psp;
219 224
220 SSCR0_P(dev->port) = ssp->cr0; 225 __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
226 __raw_writel(state->cr1, ssp->mmio_base + SSCR1);
227 __raw_writel(state->to, ssp->mmio_base + SSTO);
228 __raw_writel(state->psp, ssp->mmio_base + SSPSP);
229 __raw_writel(state->cr0, ssp->mmio_base + SSCR0);
221} 230}
222 231
223/** 232/**
@@ -231,15 +240,17 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
231 */ 240 */
232int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) 241int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
233{ 242{
243 struct ssp_device *ssp = dev->ssp;
244
234 dev->mode = mode; 245 dev->mode = mode;
235 dev->flags = flags; 246 dev->flags = flags;
236 dev->psp_flags = psp_flags; 247 dev->psp_flags = psp_flags;
237 dev->speed = speed; 248 dev->speed = speed;
238 249
239 /* set up port type, speed, port settings */ 250 /* set up port type, speed, port settings */
240 SSCR0_P(dev->port) = (dev->speed | dev->mode); 251 __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
241 SSCR1_P(dev->port) = dev->flags; 252 __raw_writel(dev->flags, ssp->mmio_base + SSCR1);
242 SSPSP_P(dev->port) = dev->psp_flags; 253 __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
243 254
244 return 0; 255 return 0;
245} 256}
@@ -256,44 +267,32 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
256 */ 267 */
257int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) 268int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
258{ 269{
270 struct ssp_device *ssp;
259 int ret; 271 int ret;
260 272
261 if (port > PXA_SSP_PORTS || port == 0) 273 ssp = ssp_request(port, "SSP");
274 if (ssp == NULL)
262 return -ENODEV; 275 return -ENODEV;
263 276
264 mutex_lock(&mutex); 277 dev->ssp = ssp;
265 if (use_count[port - 1]) {
266 mutex_unlock(&mutex);
267 return -EBUSY;
268 }
269 use_count[port - 1]++;
270
271 if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
272 use_count[port - 1]--;
273 mutex_unlock(&mutex);
274 return -EBUSY;
275 }
276 dev->port = port; 278 dev->port = port;
277 279
278 /* do we need to get irq */ 280 /* do we need to get irq */
279 if (!(init_flags & SSP_NO_IRQ)) { 281 if (!(init_flags & SSP_NO_IRQ)) {
280 ret = request_irq(ssp_info[port-1].irq, ssp_interrupt, 282 ret = request_irq(ssp->irq, ssp_interrupt,
281 0, "SSP", dev); 283 0, "SSP", dev);
282 if (ret) 284 if (ret)
283 goto out_region; 285 goto out_region;
284 dev->irq = ssp_info[port-1].irq; 286 dev->irq = ssp->irq;
285 } else 287 } else
286 dev->irq = 0; 288 dev->irq = 0;
287 289
288 /* turn on SSP port clock */ 290 /* turn on SSP port clock */
289 pxa_set_cken(ssp_info[port-1].clock, 1); 291 clk_enable(ssp->clk);
290 mutex_unlock(&mutex);
291 return 0; 292 return 0;
292 293
293out_region: 294out_region:
294 release_mem_region(__PREG(SSCR0_P(port)), 0x2c); 295 ssp_free(ssp);
295 use_count[port - 1]--;
296 mutex_unlock(&mutex);
297 return ret; 296 return ret;
298} 297}
299 298
@@ -304,23 +303,240 @@ out_region:
304 */ 303 */
305void ssp_exit(struct ssp_dev *dev) 304void ssp_exit(struct ssp_dev *dev)
306{ 305{
307 mutex_lock(&mutex); 306 struct ssp_device *ssp = dev->ssp;
308 SSCR0_P(dev->port) &= ~SSCR0_SSE; 307
308 ssp_disable(dev);
309 free_irq(dev->irq, dev);
310 clk_disable(ssp->clk);
311 ssp_free(ssp);
312}
313
314static DEFINE_MUTEX(ssp_lock);
315static LIST_HEAD(ssp_list);
316
317struct ssp_device *ssp_request(int port, const char *label)
318{
319 struct ssp_device *ssp = NULL;
320
321 mutex_lock(&ssp_lock);
322
323 list_for_each_entry(ssp, &ssp_list, node) {
324 if (ssp->port_id == port && ssp->use_count == 0) {
325 ssp->use_count++;
326 ssp->label = label;
327 break;
328 }
329 }
330
331 mutex_unlock(&ssp_lock);
332
333 if (ssp->port_id != port)
334 return NULL;
335
336 return ssp;
337}
338EXPORT_SYMBOL(ssp_request);
339
340void ssp_free(struct ssp_device *ssp)
341{
342 mutex_lock(&ssp_lock);
343 if (ssp->use_count) {
344 ssp->use_count--;
345 ssp->label = NULL;
346 } else
347 dev_err(&ssp->pdev->dev, "device already free\n");
348 mutex_unlock(&ssp_lock);
349}
350EXPORT_SYMBOL(ssp_free);
351
352static int __devinit ssp_probe(struct platform_device *pdev, int type)
353{
354 struct resource *res;
355 struct ssp_device *ssp;
356 int ret = 0;
357
358 ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
359 if (ssp == NULL) {
360 dev_err(&pdev->dev, "failed to allocate memory");
361 return -ENOMEM;
362 }
363
364 ssp->clk = clk_get(&pdev->dev, "SSPCLK");
365 if (IS_ERR(ssp->clk)) {
366 ret = PTR_ERR(ssp->clk);
367 goto err_free;
368 }
369
370 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
371 if (res == NULL) {
372 dev_err(&pdev->dev, "no memory resource defined\n");
373 ret = -ENODEV;
374 goto err_free_clk;
375 }
376
377 res = request_mem_region(res->start, res->end - res->start + 1,
378 pdev->name);
379 if (res == NULL) {
380 dev_err(&pdev->dev, "failed to request memory resource\n");
381 ret = -EBUSY;
382 goto err_free_clk;
383 }
384
385 ssp->phys_base = res->start;
386
387 ssp->mmio_base = ioremap(res->start, res->end - res->start + 1);
388 if (ssp->mmio_base == NULL) {
389 dev_err(&pdev->dev, "failed to ioremap() registers\n");
390 ret = -ENODEV;
391 goto err_free_mem;
392 }
393
394 ssp->irq = platform_get_irq(pdev, 0);
395 if (ssp->irq < 0) {
396 dev_err(&pdev->dev, "no IRQ resource defined\n");
397 ret = -ENODEV;
398 goto err_free_io;
399 }
400
401 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
402 if (res == NULL) {
403 dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
404 ret = -ENODEV;
405 goto err_free_io;
406 }
407 ssp->drcmr_rx = res->start;
408
409 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
410 if (res == NULL) {
411 dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
412 ret = -ENODEV;
413 goto err_free_io;
414 }
415 ssp->drcmr_tx = res->start;
416
417 /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
418 * starts from 0, do a translation here
419 */
420 ssp->port_id = pdev->id + 1;
421 ssp->use_count = 0;
422 ssp->type = type;
423
424 mutex_lock(&ssp_lock);
425 list_add(&ssp->node, &ssp_list);
426 mutex_unlock(&ssp_lock);
427
428 platform_set_drvdata(pdev, ssp);
429 return 0;
430
431err_free_io:
432 iounmap(ssp->mmio_base);
433err_free_mem:
434 release_mem_region(res->start, res->end - res->start + 1);
435err_free_clk:
436 clk_put(ssp->clk);
437err_free:
438 kfree(ssp);
439 return ret;
440}
441
442static int __devexit ssp_remove(struct platform_device *pdev)
443{
444 struct resource *res;
445 struct ssp_device *ssp;
446
447 ssp = platform_get_drvdata(pdev);
448 if (ssp == NULL)
449 return -ENODEV;
450
451 iounmap(ssp->mmio_base);
452
453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
454 release_mem_region(res->start, res->end - res->start + 1);
455
456 clk_put(ssp->clk);
309 457
310 if (dev->port > PXA_SSP_PORTS || dev->port == 0) { 458 mutex_lock(&ssp_lock);
311 printk(KERN_WARNING "SSP: tried to close invalid port\n"); 459 list_del(&ssp->node);
312 mutex_unlock(&mutex); 460 mutex_unlock(&ssp_lock);
313 return; 461
462 kfree(ssp);
463 return 0;
464}
465
466static int __devinit pxa25x_ssp_probe(struct platform_device *pdev)
467{
468 return ssp_probe(pdev, PXA25x_SSP);
469}
470
471static int __devinit pxa25x_nssp_probe(struct platform_device *pdev)
472{
473 return ssp_probe(pdev, PXA25x_NSSP);
474}
475
476static int __devinit pxa27x_ssp_probe(struct platform_device *pdev)
477{
478 return ssp_probe(pdev, PXA27x_SSP);
479}
480
481static struct platform_driver pxa25x_ssp_driver = {
482 .driver = {
483 .name = "pxa25x-ssp",
484 },
485 .probe = pxa25x_ssp_probe,
486 .remove = __devexit_p(ssp_remove),
487};
488
489static struct platform_driver pxa25x_nssp_driver = {
490 .driver = {
491 .name = "pxa25x-nssp",
492 },
493 .probe = pxa25x_nssp_probe,
494 .remove = __devexit_p(ssp_remove),
495};
496
497static struct platform_driver pxa27x_ssp_driver = {
498 .driver = {
499 .name = "pxa27x-ssp",
500 },
501 .probe = pxa27x_ssp_probe,
502 .remove = __devexit_p(ssp_remove),
503};
504
505static int __init pxa_ssp_init(void)
506{
507 int ret = 0;
508
509 ret = platform_driver_register(&pxa25x_ssp_driver);
510 if (ret) {
511 printk(KERN_ERR "failed to register pxa25x_ssp_driver");
512 return ret;
513 }
514
515 ret = platform_driver_register(&pxa25x_nssp_driver);
516 if (ret) {
517 printk(KERN_ERR "failed to register pxa25x_nssp_driver");
518 return ret;
519 }
520
521 ret = platform_driver_register(&pxa27x_ssp_driver);
522 if (ret) {
523 printk(KERN_ERR "failed to register pxa27x_ssp_driver");
524 return ret;
314 } 525 }
315 526
316 pxa_set_cken(ssp_info[dev->port-1].clock, 0); 527 return ret;
317 if (dev->irq) 528}
318 free_irq(dev->irq, dev); 529
319 release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); 530static void __exit pxa_ssp_exit(void)
320 use_count[dev->port - 1]--; 531{
321 mutex_unlock(&mutex); 532 platform_driver_unregister(&pxa25x_ssp_driver);
533 platform_driver_unregister(&pxa25x_nssp_driver);
534 platform_driver_unregister(&pxa27x_ssp_driver);
322} 535}
323 536
537arch_initcall(pxa_ssp_init);
538module_exit(pxa_ssp_exit);
539
324EXPORT_SYMBOL(ssp_write_word); 540EXPORT_SYMBOL(ssp_write_word);
325EXPORT_SYMBOL(ssp_read_word); 541EXPORT_SYMBOL(ssp_read_word);
326EXPORT_SYMBOL(ssp_flush); 542EXPORT_SYMBOL(ssp_flush);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index d774430d02c0..167412e6bec8 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -17,6 +17,7 @@
17 17
18 .text 18 .text
19 19
20#ifdef CONFIG_PXA27x
20ENTRY(pxa_cpu_standby) 21ENTRY(pxa_cpu_standby)
21 ldr r0, =PSSR 22 ldr r0, =PSSR
22 mov r1, #(PSSR_PH | PSSR_STS) 23 mov r1, #(PSSR_PH | PSSR_STS)
@@ -29,3 +30,85 @@ ENTRY(pxa_cpu_standby)
291: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby 301: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
30 str r1, [r0] @ make sure PSSR_PH/STS are clear 31 str r1, [r0] @ make sure PSSR_PH/STS are clear
31 mov pc, lr 32 mov pc, lr
33
34#endif
35
36#ifdef CONFIG_PXA3xx
37
38#define MDCNFG 0x0000
39#define MDCNFG_DMCEN (1 << 30)
40#define DDR_HCAL 0x0060
41#define DDR_HCAL_HCRNG 0x1f
42#define DDR_HCAL_HCPROG (1 << 28)
43#define DDR_HCAL_HCEN (1 << 31)
44#define DMCIER 0x0070
45#define DMCIER_EDLP (1 << 29)
46#define DMCISR 0x0078
47#define RCOMP 0x0100
48#define RCOMP_SWEVAL (1 << 31)
49
50ENTRY(pm_enter_standby_start)
51 mov r1, #0xf6000000 @ DMEMC_REG_BASE (MDCNFG)
52 add r1, r1, #0x00100000
53
54 /*
55 * Preload the TLB entry for accessing the dynamic memory
56 * controller registers. Note that page table lookups will
57 * fail until the dynamic memory controller has been
58 * reinitialised - and that includes MMU page table walks.
59 * This also means that only the dynamic memory controller
60 * can be reliably accessed in the code following standby.
61 */
62 ldr r2, [r1] @ Dummy read MDCNFG
63
64 mcr p14, 0, r0, c7, c0, 0
65 .rept 8
66 nop
67 .endr
68
69 ldr r0, [r1, #DDR_HCAL] @ Clear (and wait for) HCEN
70 bic r0, r0, #DDR_HCAL_HCEN
71 str r0, [r1, #DDR_HCAL]
721: ldr r0, [r1, #DDR_HCAL]
73 tst r0, #DDR_HCAL_HCEN
74 bne 1b
75
76 ldr r0, [r1, #RCOMP] @ Initiate RCOMP
77 orr r0, r0, #RCOMP_SWEVAL
78 str r0, [r1, #RCOMP]
79
80 mov r0, #~0 @ Clear interrupts
81 str r0, [r1, #DMCISR]
82
83 ldr r0, [r1, #DMCIER] @ set DMIER[EDLP]
84 orr r0, r0, #DMCIER_EDLP
85 str r0, [r1, #DMCIER]
86
87 ldr r0, [r1, #DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN
88 bic r0, r0, #DDR_HCAL_HCRNG
89 orr r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG
90 str r0, [r1, #DDR_HCAL]
91
921: ldr r0, [r1, #DMCISR]
93 tst r0, #DMCIER_EDLP
94 beq 1b
95
96 ldr r0, [r1, #MDCNFG] @ set MDCNFG[DMCEN]
97 orr r0, r0, #MDCNFG_DMCEN
98 str r0, [r1, #MDCNFG]
991: ldr r0, [r1, #MDCNFG]
100 tst r0, #MDCNFG_DMCEN
101 beq 1b
102
103 ldr r0, [r1, #DDR_HCAL] @ set DDR_HCAL[HCRNG]
104 orr r0, r0, #2 @ HCRNG
105 str r0, [r1, #DDR_HCAL]
106
107 ldr r0, [r1, #DMCIER] @ Clear the interrupt
108 bic r0, r0, #0x20000000
109 str r0, [r1, #DMCIER]
110
111 mov pc, lr
112ENTRY(pm_enter_standby_end)
113
114#endif
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fbfa1920353d..7b7c0179795b 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
59} 59}
60 60
61 61
62#define MIN_OSCR_DELTA 16
63
62static irqreturn_t 64static irqreturn_t
63pxa_ost0_interrupt(int irq, void *dev_id) 65pxa_ost0_interrupt(int irq, void *dev_id)
64{ 66{
65 int next_match;
66 struct clock_event_device *c = dev_id; 67 struct clock_event_device *c = dev_id;
67 68
68 if (c->mode == CLOCK_EVT_MODE_ONESHOT) { 69 /* Disarm the compare/match, signal the event. */
69 /* Disarm the compare/match, signal the event. */ 70 OIER &= ~OIER_E0;
70 OIER &= ~OIER_E0; 71 OSSR = OSSR_M0;
71 OSSR = OSSR_M0; 72 c->event_handler(c);
72 c->event_handler(c);
73 } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
74 /* Call the event handler as many times as necessary
75 * to recover missed events, if any (if we update
76 * OSMR0 and OSCR0 is still ahead of us, we've missed
77 * the event). As we're dealing with that, re-arm the
78 * compare/match for the next event.
79 *
80 * HACK ALERT:
81 *
82 * There's a latency between the instruction that
83 * writes to OSMR0 and the actual commit to the
84 * physical hardware, because the CPU doesn't (have
85 * to) run at bus speed, there's a write buffer
86 * between the CPU and the bus, etc. etc. So if the
87 * target OSCR0 is "very close", to the OSMR0 load
88 * value, the update to OSMR0 might not get to the
89 * hardware in time and we'll miss that interrupt.
90 *
91 * To be safe, if the new OSMR0 is "very close" to the
92 * target OSCR0 value, we call the event_handler as
93 * though the event actually happened. According to
94 * Nico's comment in the previous version of this
95 * code, experience has shown that 6 OSCR ticks is
96 * "very close" but he went with 8. We will use 16,
97 * based on the results of testing on PXA270.
98 *
99 * To be doubly sure, we also tell clkevt via
100 * clockevents_register_device() not to ask for
101 * anything that might put us "very close".
102 */
103#define MIN_OSCR_DELTA 16
104 do {
105 OSSR = OSSR_M0;
106 next_match = (OSMR0 += LATCH);
107 c->event_handler(c);
108 } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
109 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
110 }
111 73
112 return IRQ_HANDLED; 74 return IRQ_HANDLED;
113} 75}
@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
133 unsigned long irqflags; 95 unsigned long irqflags;
134 96
135 switch (mode) { 97 switch (mode) {
136 case CLOCK_EVT_MODE_PERIODIC:
137 raw_local_irq_save(irqflags);
138 OSSR = OSSR_M0;
139 OIER |= OIER_E0;
140 OSMR0 = OSCR + LATCH;
141 raw_local_irq_restore(irqflags);
142 break;
143
144 case CLOCK_EVT_MODE_ONESHOT: 98 case CLOCK_EVT_MODE_ONESHOT:
145 raw_local_irq_save(irqflags); 99 raw_local_irq_save(irqflags);
146 OIER &= ~OIER_E0; 100 OIER &= ~OIER_E0;
@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
158 break; 112 break;
159 113
160 case CLOCK_EVT_MODE_RESUME: 114 case CLOCK_EVT_MODE_RESUME:
115 case CLOCK_EVT_MODE_PERIODIC:
161 break; 116 break;
162 } 117 }
163} 118}
164 119
165static struct clock_event_device ckevt_pxa_osmr0 = { 120static struct clock_event_device ckevt_pxa_osmr0 = {
166 .name = "osmr0", 121 .name = "osmr0",
167 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 122 .features = CLOCK_EVT_FEAT_ONESHOT,
168 .shift = 32, 123 .shift = 32,
169 .rating = 200, 124 .rating = 200,
170 .cpumask = CPU_MASK_CPU0, 125 .cpumask = CPU_MASK_CPU0,
@@ -214,7 +169,7 @@ static void __init pxa_timer_init(void)
214 ckevt_pxa_osmr0.max_delta_ns = 169 ckevt_pxa_osmr0.max_delta_ns =
215 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); 170 clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
216 ckevt_pxa_osmr0.min_delta_ns = 171 ckevt_pxa_osmr0.min_delta_ns =
217 clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1; 172 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
218 173
219 cksrc_pxa_oscr0.mult = 174 cksrc_pxa_oscr0.mult =
220 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); 175 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
@@ -226,7 +181,7 @@ static void __init pxa_timer_init(void)
226} 181}
227 182
228#ifdef CONFIG_PM 183#ifdef CONFIG_PM
229static unsigned long osmr[4], oier; 184static unsigned long osmr[4], oier, oscr;
230 185
231static void pxa_timer_suspend(void) 186static void pxa_timer_suspend(void)
232{ 187{
@@ -235,23 +190,26 @@ static void pxa_timer_suspend(void)
235 osmr[2] = OSMR2; 190 osmr[2] = OSMR2;
236 osmr[3] = OSMR3; 191 osmr[3] = OSMR3;
237 oier = OIER; 192 oier = OIER;
193 oscr = OSCR;
238} 194}
239 195
240static void pxa_timer_resume(void) 196static void pxa_timer_resume(void)
241{ 197{
198 /*
199 * Ensure that we have at least MIN_OSCR_DELTA between match
200 * register 0 and the OSCR, to guarantee that we will receive
201 * the one-shot timer interrupt. We adjust OSMR0 in preference
202 * to OSCR to guarantee that OSCR is monotonically incrementing.
203 */
204 if (osmr[0] - oscr < MIN_OSCR_DELTA)
205 osmr[0] += MIN_OSCR_DELTA;
206
242 OSMR0 = osmr[0]; 207 OSMR0 = osmr[0];
243 OSMR1 = osmr[1]; 208 OSMR1 = osmr[1];
244 OSMR2 = osmr[2]; 209 OSMR2 = osmr[2];
245 OSMR3 = osmr[3]; 210 OSMR3 = osmr[3];
246 OIER = oier; 211 OIER = oier;
247 212 OSCR = oscr;
248 /*
249 * OSCR0 is the system timer, which has to increase
250 * monotonically until it rolls over in hardware. The value
251 * (OSMR0 - LATCH) is OSCR0 at the most recent system tick,
252 * which is a handy value to restore to OSCR0.
253 */
254 OSCR = OSMR0 - LATCH;
255} 213}
256#else 214#else
257#define pxa_timer_suspend NULL 215#define pxa_timer_suspend NULL
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 240fd042083d..1919756900f4 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -184,16 +184,13 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
184 184
185 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); 185 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
186 186
187 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED, 187 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
188 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
188 "MMC/SD card detect", data); 189 "MMC/SD card detect", data);
189 if (err) { 190 if (err)
190 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 191 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
191 return -1;
192 }
193
194 set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
195 192
196 return 0; 193 return err;
197} 194}
198 195
199static void tosa_mci_setpower(struct device *dev, unsigned int vdd) 196static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index e4ba43bdf85d..853fc9433750 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -296,11 +296,10 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, v
296 err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, 296 err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
297 IRQF_DISABLED | IRQF_TRIGGER_RISING, 297 IRQF_DISABLED | IRQF_TRIGGER_RISING,
298 "MMC card detect", data); 298 "MMC card detect", data);
299 if (err) { 299 if (err)
300 printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 300 printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
301 return -1; 301
302 } 302 return err;
303 return 0;
304} 303}
305 304
306static void trizeps4_mci_exit(struct device *dev, void *data) 305static void trizeps4_mci_exit(struct device *dev, void *data)
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 743a87b2faa1..7731d50dd86c 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -25,9 +25,13 @@
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26#include <asm/arch/pxafb.h> 26#include <asm/arch/pxafb.h>
27#include <asm/arch/zylonite.h> 27#include <asm/arch/zylonite.h>
28#include <asm/arch/mmc.h>
28 29
29#include "generic.h" 30#include "generic.h"
30 31
32#define MAX_SLOTS 3
33struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
34
31int gpio_backlight; 35int gpio_backlight;
32int gpio_eth_irq; 36int gpio_eth_irq;
33 37
@@ -43,7 +47,7 @@ static struct resource smc91x_resources[] = {
43 [1] = { 47 [1] = {
44 .start = -1, /* for run-time assignment */ 48 .start = -1, /* for run-time assignment */
45 .end = -1, 49 .end = -1,
46 .flags = IORESOURCE_IRQ, 50 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
47 } 51 }
48}; 52};
49 53
@@ -156,6 +160,95 @@ static void __init zylonite_init_lcd(void)
156static inline void zylonite_init_lcd(void) {} 160static inline void zylonite_init_lcd(void) {}
157#endif 161#endif
158 162
163#if defined(CONFIG_MMC)
164static int zylonite_mci_ro(struct device *dev)
165{
166 struct platform_device *pdev = to_platform_device(dev);
167
168 return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
169}
170
171static int zylonite_mci_init(struct device *dev,
172 irq_handler_t zylonite_detect_int,
173 void *data)
174{
175 struct platform_device *pdev = to_platform_device(dev);
176 int err, cd_irq, gpio_cd, gpio_wp;
177
178 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
179 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
180 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
181
182 /*
183 * setup GPIO for Zylonite MMC controller
184 */
185 err = gpio_request(gpio_cd, "mmc card detect");
186 if (err)
187 goto err_request_cd;
188 gpio_direction_input(gpio_cd);
189
190 err = gpio_request(gpio_wp, "mmc write protect");
191 if (err)
192 goto err_request_wp;
193 gpio_direction_input(gpio_wp);
194
195 err = request_irq(cd_irq, zylonite_detect_int,
196 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
197 "MMC card detect", data);
198 if (err) {
199 printk(KERN_ERR "%s: MMC/SD/SDIO: "
200 "can't request card detect IRQ\n", __func__);
201 goto err_request_irq;
202 }
203
204 return 0;
205
206err_request_irq:
207 gpio_free(gpio_wp);
208err_request_wp:
209 gpio_free(gpio_cd);
210err_request_cd:
211 return err;
212}
213
214static void zylonite_mci_exit(struct device *dev, void *data)
215{
216 struct platform_device *pdev = to_platform_device(dev);
217 int cd_irq, gpio_cd, gpio_wp;
218
219 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
220 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
221 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
222
223 free_irq(cd_irq, data);
224 gpio_free(gpio_cd);
225 gpio_free(gpio_wp);
226}
227
228static struct pxamci_platform_data zylonite_mci_platform_data = {
229 .detect_delay = 20,
230 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
231 .init = zylonite_mci_init,
232 .exit = zylonite_mci_exit,
233 .get_ro = zylonite_mci_ro,
234};
235
236static struct pxamci_platform_data zylonite_mci2_platform_data = {
237 .detect_delay = 20,
238 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
239};
240
241static void __init zylonite_init_mmc(void)
242{
243 pxa_set_mci_info(&zylonite_mci_platform_data);
244 pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
245 if (cpu_is_pxa310())
246 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
247}
248#else
249static inline void zylonite_init_mmc(void) {}
250#endif
251
159static void __init zylonite_init(void) 252static void __init zylonite_init(void)
160{ 253{
161 /* board-processor specific initialization */ 254 /* board-processor specific initialization */
@@ -171,6 +264,7 @@ static void __init zylonite_init(void)
171 platform_device_register(&smc91x_device); 264 platform_device_register(&smc91x_device);
172 265
173 zylonite_init_lcd(); 266 zylonite_init_lcd();
267 zylonite_init_mmc();
174} 268}
175 269
176MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") 270MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 1832bc316501..6ac04c09b0e9 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -53,13 +53,13 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
53 53
54 /* BTUART */ 54 /* BTUART */
55 GPIO111_UART2_RTS, 55 GPIO111_UART2_RTS,
56 GPIO112_UART2_RXD, 56 GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
57 GPIO113_UART2_TXD, 57 GPIO113_UART2_TXD,
58 GPIO114_UART2_CTS, 58 GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
59 59
60 /* STUART */ 60 /* STUART */
61 GPIO109_UART3_TXD, 61 GPIO109_UART3_TXD,
62 GPIO110_UART3_RXD, 62 GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
63 63
64 /* AC97 */ 64 /* AC97 */
65 GPIO23_AC97_nACRESET, 65 GPIO23_AC97_nACRESET,
@@ -70,16 +70,16 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
70 GPIO28_AC97_SYNC, 70 GPIO28_AC97_SYNC,
71 71
72 /* Keypad */ 72 /* Keypad */
73 GPIO107_KP_DKIN_0, 73 GPIO107_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
74 GPIO108_KP_DKIN_1, 74 GPIO108_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
75 GPIO115_KP_MKIN_0, 75 GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
76 GPIO116_KP_MKIN_1, 76 GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
77 GPIO117_KP_MKIN_2, 77 GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
78 GPIO118_KP_MKIN_3, 78 GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
79 GPIO119_KP_MKIN_4, 79 GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
80 GPIO120_KP_MKIN_5, 80 GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
81 GPIO2_2_KP_MKIN_6, 81 GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
82 GPIO3_2_KP_MKIN_7, 82 GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
83 GPIO121_KP_MKOUT_0, 83 GPIO121_KP_MKOUT_0,
84 GPIO122_KP_MKOUT_1, 84 GPIO122_KP_MKOUT_1,
85 GPIO123_KP_MKOUT_2, 85 GPIO123_KP_MKOUT_2,
@@ -88,16 +88,33 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
88 GPIO4_2_KP_MKOUT_5, 88 GPIO4_2_KP_MKOUT_5,
89 GPIO5_2_KP_MKOUT_6, 89 GPIO5_2_KP_MKOUT_6,
90 GPIO6_2_KP_MKOUT_7, 90 GPIO6_2_KP_MKOUT_7,
91
92 /* MMC1 */
93 GPIO3_MMC1_DAT0,
94 GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
95 GPIO5_MMC1_DAT2,
96 GPIO6_MMC1_DAT3,
97 GPIO7_MMC1_CLK,
98 GPIO8_MMC1_CMD, /* CMD0 for slot 0 */
99 GPIO15_GPIO, /* CMD1 default as GPIO for slot 0 */
100
101 /* MMC2 */
102 GPIO9_MMC2_DAT0,
103 GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
104 GPIO11_MMC2_DAT2,
105 GPIO12_MMC2_DAT3,
106 GPIO13_MMC2_CLK,
107 GPIO14_MMC2_CMD,
91}; 108};
92 109
93static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { 110static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
94 /* FFUART */ 111 /* FFUART */
95 GPIO30_UART1_RXD, 112 GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
96 GPIO31_UART1_TXD, 113 GPIO31_UART1_TXD,
97 GPIO32_UART1_CTS, 114 GPIO32_UART1_CTS,
98 GPIO37_UART1_RTS, 115 GPIO37_UART1_RTS,
99 GPIO33_UART1_DCD, 116 GPIO33_UART1_DCD,
100 GPIO34_UART1_DSR, 117 GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
101 GPIO35_UART1_RI, 118 GPIO35_UART1_RI,
102 GPIO36_UART1_DTR, 119 GPIO36_UART1_DTR,
103 120
@@ -108,7 +125,7 @@ static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
108 125
109static mfp_cfg_t pxa310_mfp_cfg[] __initdata = { 126static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
110 /* FFUART */ 127 /* FFUART */
111 GPIO99_UART1_RXD, 128 GPIO99_UART1_RXD | MFP_LPM_EDGE_FALL,
112 GPIO100_UART1_TXD, 129 GPIO100_UART1_TXD,
113 GPIO101_UART1_CTS, 130 GPIO101_UART1_CTS,
114 GPIO106_UART1_RTS, 131 GPIO106_UART1_RTS,
@@ -116,6 +133,14 @@ static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
116 /* Ethernet */ 133 /* Ethernet */
117 GPIO2_nCS3, 134 GPIO2_nCS3,
118 GPIO102_GPIO, 135 GPIO102_GPIO,
136
137 /* MMC3 */
138 GPIO7_2_MMC3_DAT0,
139 GPIO8_2_MMC3_DAT1 | MFP_LPM_EDGE_BOTH,
140 GPIO9_2_MMC3_DAT2,
141 GPIO10_2_MMC3_DAT3,
142 GPIO103_MMC3_CLK,
143 GPIO105_MMC3_CMD,
119}; 144};
120 145
121#define NUM_LCD_DETECT_PINS 7 146#define NUM_LCD_DETECT_PINS 7
@@ -174,6 +199,10 @@ void __init zylonite_pxa300_init(void)
174 199
175 /* GPIO pin assignment */ 200 /* GPIO pin assignment */
176 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); 201 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
202
203 /* MMC card detect & write protect for controller 0 */
204 zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0);
205 zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2);
177 } 206 }
178 207
179 if (cpu_is_pxa300()) { 208 if (cpu_is_pxa300()) {
@@ -184,5 +213,9 @@ void __init zylonite_pxa300_init(void)
184 if (cpu_is_pxa310()) { 213 if (cpu_is_pxa310()) {
185 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); 214 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
186 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); 215 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
216
217 /* MMC card detect & write protect for controller 2 */
218 zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30);
219 zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31);
187 } 220 }
188} 221}
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 94c715808b59..dfa79992b8ab 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -51,11 +51,11 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
51 GPIO17_2_LCD_BIAS, 51 GPIO17_2_LCD_BIAS,
52 52
53 /* FFUART */ 53 /* FFUART */
54 GPIO41_UART1_RXD, 54 GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL,
55 GPIO42_UART1_TXD, 55 GPIO42_UART1_TXD,
56 GPIO43_UART1_CTS, 56 GPIO43_UART1_CTS,
57 GPIO44_UART1_DCD, 57 GPIO44_UART1_DCD,
58 GPIO45_UART1_DSR, 58 GPIO45_UART1_DSR | MFP_LPM_EDGE_FALL,
59 GPIO46_UART1_RI, 59 GPIO46_UART1_RI,
60 GPIO47_UART1_DTR, 60 GPIO47_UART1_DTR,
61 GPIO48_UART1_RTS, 61 GPIO48_UART1_RTS,
@@ -73,16 +73,16 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
73 GPIO33_I2C_SDA, 73 GPIO33_I2C_SDA,
74 74
75 /* Keypad */ 75 /* Keypad */
76 GPIO105_KP_DKIN_0, 76 GPIO105_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
77 GPIO106_KP_DKIN_1, 77 GPIO106_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
78 GPIO113_KP_MKIN_0, 78 GPIO113_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
79 GPIO114_KP_MKIN_1, 79 GPIO114_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
80 GPIO115_KP_MKIN_2, 80 GPIO115_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
81 GPIO116_KP_MKIN_3, 81 GPIO116_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
82 GPIO117_KP_MKIN_4, 82 GPIO117_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
83 GPIO118_KP_MKIN_5, 83 GPIO118_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
84 GPIO119_KP_MKIN_6, 84 GPIO119_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
85 GPIO120_KP_MKIN_7, 85 GPIO120_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
86 GPIO121_KP_MKOUT_0, 86 GPIO121_KP_MKOUT_0,
87 GPIO122_KP_MKOUT_1, 87 GPIO122_KP_MKOUT_1,
88 GPIO123_KP_MKOUT_2, 88 GPIO123_KP_MKOUT_2,
@@ -95,6 +95,23 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
95 /* Ethernet */ 95 /* Ethernet */
96 GPIO4_nCS3, 96 GPIO4_nCS3,
97 GPIO90_GPIO, 97 GPIO90_GPIO,
98
99 /* MMC1 */
100 GPIO18_MMC1_DAT0,
101 GPIO19_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
102 GPIO20_MMC1_DAT2,
103 GPIO21_MMC1_DAT3,
104 GPIO22_MMC1_CLK,
105 GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
106 GPIO31_GPIO, /* CMD1 default as GPIO for slot 0 */
107
108 /* MMC2 */
109 GPIO24_MMC2_DAT0,
110 GPIO25_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
111 GPIO26_MMC2_DAT2,
112 GPIO27_MMC2_DAT3,
113 GPIO28_MMC2_CLK,
114 GPIO29_MMC2_CMD,
98}; 115};
99 116
100#define NUM_LCD_DETECT_PINS 7 117#define NUM_LCD_DETECT_PINS 7
@@ -169,5 +186,9 @@ void __init zylonite_pxa320_init(void)
169 /* GPIO pin assignment */ 186 /* GPIO pin assignment */
170 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); 187 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
171 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); 188 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
189
190 /* MMC card detect & write protect for controller 0 */
191 zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1);
192 zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5);
172 } 193 }
173} 194}