aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Brown <davidb@codeaurora.org>2010-12-20 16:11:10 -0500
committerDavid Brown <davidb@codeaurora.org>2010-12-20 16:11:10 -0500
commitba119204ff6ff722dcec387b305d9c2d23380726 (patch)
treeae608ce52cf4d47a4278bb9d5df9a8616bb7200c
parentcf7d7e5a1980d1116ee152d25dac382b112b9c17 (diff)
parent0c521ccbd0c9ad5623ff9b37b20b3ff9d4ad65a7 (diff)
Merge branches 'msm-core' and 'msm-mmc' into for-next
* msm-core: (28 commits) msm: initial framebuffer support msm: add handling for clocks tagged as CLK_MINMAX msm: trout: change name of pmdh_clk to mddi_clk msm: add CLK_MINMAX to pmdh_clk msm: trout: add gpio_to_irq msm: iommu: Use the correct memory allocation flag msm_serial: Remove redundant unlikely() msm: iommu: Miscellaneous code cleanup msm: iommu: Support cache-coherent memory access msm: iommu: Definitions for extended memory attributes msm: iommu: Kconfig dependency for the IOMMU API msm: iommu: Check if device is already attached msm: iommu: Kconfig item for cacheable page tables msm: iommu: Don't flush page tables if no devices attached msm: iommu: Mark functions with the right section names msm: iommu: Support for the 2nd GFX core's IOMMU msm: iommu: Revise GFX2D0 IOMMU contexts and M2V mappings msm: iommu: Revise GFX3D IOMMU contexts and M2V mappings msm: iommu: Use more consistent naming in platform data msm: iomap: Addresses and IRQs for 2nd GFX core IOMMU ... * msm-mmc: (33 commits) mmc: msm_sdcc: Check for only DATA_END interrupt to end a request mmc: msm_sdcc: Fix bug in PIO mode when data size is not word aligned mmc: msm_sdcc: Reset SDCC in case of data transfer errors mmc: msm_sdcc: Add prog done interrupt support mmc: msm_sdcc: Fix possible circular locking dependency warning msm: initial framebuffer support msm: add handling for clocks tagged as CLK_MINMAX msm: trout: change name of pmdh_clk to mddi_clk msm: add CLK_MINMAX to pmdh_clk msm: trout: add gpio_to_irq msm: iommu: Use the correct memory allocation flag msm_serial: Remove redundant unlikely() msm: iommu: Miscellaneous code cleanup msm: iommu: Support cache-coherent memory access msm: iommu: Definitions for extended memory attributes msm: iommu: Kconfig dependency for the IOMMU API msm: iommu: Check if device is already attached msm: iommu: Kconfig item for cacheable page tables msm: iommu: Don't flush page tables if no devices attached msm: iommu: Mark functions with the right section names ...
-rw-r--r--arch/arm/mach-msm/Kconfig8
-rw-r--r--arch/arm/mach-msm/Makefile5
-rw-r--r--arch/arm/mach-msm/board-trout-gpio.c8
-rw-r--r--arch/arm/mach-msm/board-trout-panel.c297
-rw-r--r--arch/arm/mach-msm/clock.c15
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c69
-rw-r--r--arch/arm/mach-msm/devices-msm8x60-iommu.c243
-rw-r--r--arch/arm/mach-msm/devices.h4
-rw-r--r--arch/arm/mach-msm/gpio-v2.c426
-rw-r--r--arch/arm/mach-msm/include/mach/iommu.h15
-rw-r--r--arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h22
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x60.h7
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x60.h3
-rw-r--r--arch/arm/mach-msm/io.c1
-rw-r--r--arch/arm/mach-msm/iommu.c146
-rw-r--r--arch/arm/mach-msm/iommu_dev.c4
-rw-r--r--arch/arm/mach-msm/sirc.c3
-rw-r--r--arch/arm/mach-msm/smd.c17
-rw-r--r--arch/arm/mach-msm/smd_debug.c2
-rw-r--r--drivers/mmc/host/msm_sdcc.c139
-rw-r--r--drivers/mmc/host/msm_sdcc.h8
-rw-r--r--drivers/serial/msm_serial.c2
22 files changed, 1247 insertions, 197 deletions
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index dbbcfeb919db..1a11f1ed216d 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -44,6 +44,7 @@ config ARCH_MSM8X60
44 select CPU_V7 44 select CPU_V7
45 select MSM_V2_TLMM 45 select MSM_V2_TLMM
46 select MSM_GPIOMUX 46 select MSM_GPIOMUX
47 select IOMMU_API
47 48
48endchoice 49endchoice
49 50
@@ -122,6 +123,10 @@ config MACH_MSM8X60_FFA
122 123
123endmenu 124endmenu
124 125
126config IOMMU_PGTABLES_L2
127 def_bool y
128 depends on ARCH_MSM8X60 && MMU && SMP && CPU_DCACHE_DISABLE=n
129
125config MSM_DEBUG_UART 130config MSM_DEBUG_UART
126 int 131 int
127 default 1 if MSM_DEBUG_UART1 132 default 1 if MSM_DEBUG_UART1
@@ -162,4 +167,7 @@ config MSM_GPIOMUX
162 167
163config MSM_V2_TLMM 168config MSM_V2_TLMM
164 bool 169 bool
170
171config IOMMU_API
172 bool
165endif 173endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b5a7b07a44f5..59646bbd6195 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
20obj-$(CONFIG_MSM_SMD) += last_radio_log.o 20obj-$(CONFIG_MSM_SMD) += last_radio_log.o
21 21
22obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o 22obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
23obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
23obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o 24obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
24obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o 25obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
25obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o 26obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
@@ -28,6 +29,8 @@ obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
28obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o 29obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
29obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o 30obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
30obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o 31obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
31ifndef CONFIG_MSM_V2_TLMM 32ifdef CONFIG_MSM_V2_TLMM
33obj-y += gpio-v2.o
34else
32obj-y += gpio.o 35obj-y += gpio.o
33endif 36endif
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c
index c50f3afc3134..f8c09ef6666f 100644
--- a/arch/arm/mach-msm/board-trout-gpio.c
+++ b/arch/arm/mach-msm/board-trout-gpio.c
@@ -72,6 +72,13 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip,
72 return 0; 72 return 0;
73} 73}
74 74
75static int trout_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
76{
77 struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
78
79 return TROUT_GPIO_TO_INT(offset + chip->base);
80}
81
75#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \ 82#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
76 { \ 83 { \
77 .chip = { \ 84 .chip = { \
@@ -80,6 +87,7 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip,
80 .direction_output = msm_gpiolib_direction_output, \ 87 .direction_output = msm_gpiolib_direction_output, \
81 .get = msm_gpiolib_get, \ 88 .get = msm_gpiolib_get, \
82 .set = msm_gpiolib_set, \ 89 .set = msm_gpiolib_set, \
90 .to_irq = trout_gpio_to_irq, \
83 .base = base_gpio, \ 91 .base = base_gpio, \
84 .ngpio = 8, \ 92 .ngpio = 8, \
85 }, \ 93 }, \
diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c
new file mode 100644
index 000000000000..729bb49a44ca
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-panel.c
@@ -0,0 +1,297 @@
1/* linux/arch/arm/mach-msm/board-trout-mddi.c
2** Author: Brian Swetland <swetland@google.com>
3*/
4
5#include <linux/kernel.h>
6#include <linux/init.h>
7#include <linux/platform_device.h>
8#include <linux/delay.h>
9#include <linux/leds.h>
10#include <linux/clk.h>
11#include <linux/err.h>
12
13#include <asm/io.h>
14#include <asm/gpio.h>
15#include <asm/mach-types.h>
16
17#include <mach/msm_fb.h>
18#include <mach/vreg.h>
19
20#include "board-trout.h"
21#include "proc_comm.h"
22#include "devices.h"
23
24#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255
25
26#define MDDI_CLIENT_CORE_BASE 0x108000
27#define LCD_CONTROL_BLOCK_BASE 0x110000
28#define SPI_BLOCK_BASE 0x120000
29#define I2C_BLOCK_BASE 0x130000
30#define PWM_BLOCK_BASE 0x140000
31#define GPIO_BLOCK_BASE 0x150000
32#define SYSTEM_BLOCK1_BASE 0x160000
33#define SYSTEM_BLOCK2_BASE 0x170000
34
35
36#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
37#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)
38#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
39
40#define V_VDDE2E_VDD2_GPIO 0
41#define MDDI_RST_N 82
42
43#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
44#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
45#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
46#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
47#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
48#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
49#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
50#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
51#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
52#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
53#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
54#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
55#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
56#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
57#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
58#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
59#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
60#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
61#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
62#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
63#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
64#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
65
66#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
67#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
68#define START (LCD_CONTROL_BLOCK_BASE|0x08)
69#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
70#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
71#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
72#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
73#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
74#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
75#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
76#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
77#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
78#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
79#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
80#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
81#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
82#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
83#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
84#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
85#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
86#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
87#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
88#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
89#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
90#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
91#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
92#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
93#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
94#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
95#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
96#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
97#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
98#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
99#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
100#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
101
102#define SSICTL (SPI_BLOCK_BASE|0x00)
103#define SSITIME (SPI_BLOCK_BASE|0x04)
104#define SSITX (SPI_BLOCK_BASE|0x08)
105#define SSIRX (SPI_BLOCK_BASE|0x0C)
106#define SSIINTC (SPI_BLOCK_BASE|0x10)
107#define SSIINTS (SPI_BLOCK_BASE|0x14)
108#define SSIDBG1 (SPI_BLOCK_BASE|0x18)
109#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
110#define SSIID (SPI_BLOCK_BASE|0x20)
111
112#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
113#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
114#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
115#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
116#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
117
118#define GPIODATA (GPIO_BLOCK_BASE|0x00)
119#define GPIODIR (GPIO_BLOCK_BASE|0x04)
120#define GPIOIS (GPIO_BLOCK_BASE|0x08)
121#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
122#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
123#define GPIOIE (GPIO_BLOCK_BASE|0x14)
124#define GPIORIS (GPIO_BLOCK_BASE|0x18)
125#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
126#define GPIOIC (GPIO_BLOCK_BASE|0x20)
127#define GPIOOMS (GPIO_BLOCK_BASE|0x24)
128#define GPIOPC (GPIO_BLOCK_BASE|0x28)
129#define GPIOID (GPIO_BLOCK_BASE|0x30)
130
131#define SPI_WRITE(reg, val) \
132 { SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
133 { 0, 5 },
134
135#define SPI_WRITE1(reg) \
136 { SSITX, (reg) & 0xff }, \
137 { 0, 5 },
138
139struct mddi_table {
140 uint32_t reg;
141 uint32_t value;
142};
143static struct mddi_table mddi_toshiba_init_table[] = {
144 { DPSET0, 0x09e90046 },
145 { DPSET1, 0x00000118 },
146 { DPSUS, 0x00000000 },
147 { DPRUN, 0x00000001 },
148 { 1, 14 }, /* msleep 14 */
149 { SYSCKENA, 0x00000001 },
150 { CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */
151
152 { GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
153 { GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */
154 { GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */
155 { GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */
156 { WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */
157
158 { GPIOIBE, 0x000003FF },
159 { GPIOIS, 0x00000000 },
160 { GPIOIC, 0x000003FF },
161 { GPIOIE, 0x00000000 },
162
163 { GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
164 { 1, 1 }, /* msleep 1 */
165 { GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
166 { DRAMPWR, 0x00000001 }, /* eDRAM power */
167};
168
169#define GPIOSEL_VWAKEINT (1U << 0)
170#define INTMASK_VWAKEOUT (1U << 0)
171
172
173static struct clk *gp_clk;
174static int trout_new_backlight = 1;
175static struct vreg *vreg_mddi_1v5;
176static struct vreg *vreg_lcm_2v85;
177
178static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,
179 struct mddi_table *table, size_t count)
180{
181 int i;
182 for (i = 0; i < count; i++) {
183 uint32_t reg = table[i].reg;
184 uint32_t value = table[i].value;
185
186 if (reg == 0)
187 udelay(value);
188 else if (reg == 1)
189 msleep(value);
190 else
191 client_data->remote_write(client_data, value, reg);
192 }
193}
194
195static int trout_mddi_toshiba_client_init(
196 struct msm_mddi_bridge_platform_data *bridge_data,
197 struct msm_mddi_client_data *client_data)
198{
199 int panel_id;
200
201 client_data->auto_hibernate(client_data, 0);
202 trout_process_mddi_table(client_data, mddi_toshiba_init_table,
203 ARRAY_SIZE(mddi_toshiba_init_table));
204 client_data->auto_hibernate(client_data, 1);
205 panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
206 if (panel_id > 1) {
207 printk(KERN_WARNING "unknown panel id at mddi_enable\n");
208 return -1;
209 }
210 return 0;
211}
212
213static int trout_mddi_toshiba_client_uninit(
214 struct msm_mddi_bridge_platform_data *bridge_data,
215 struct msm_mddi_client_data *client_data)
216{
217 return 0;
218}
219
220static struct resource resources_msm_fb[] = {
221 {
222 .start = MSM_FB_BASE,
223 .end = MSM_FB_BASE + MSM_FB_SIZE,
224 .flags = IORESOURCE_MEM,
225 },
226};
227
228struct msm_mddi_bridge_platform_data toshiba_client_data = {
229 .init = trout_mddi_toshiba_client_init,
230 .uninit = trout_mddi_toshiba_client_uninit,
231 .fb_data = {
232 .xres = 320,
233 .yres = 480,
234 .width = 45,
235 .height = 67,
236 .output_format = 0,
237 },
238};
239
240static struct msm_mddi_platform_data mddi_pdata = {
241 .clk_rate = 122880000,
242 .fb_resource = resources_msm_fb,
243 .num_clients = 1,
244 .client_platform_data = {
245 {
246 .product_id = (0xd263 << 16 | 0),
247 .name = "mddi_c_d263_0000",
248 .id = 0,
249 .client_data = &toshiba_client_data,
250 .clk_rate = 0,
251 },
252 },
253};
254
255int __init trout_init_panel(void)
256{
257 int rc;
258
259 if (!machine_is_trout())
260 return 0;
261 vreg_mddi_1v5 = vreg_get(0, "gp2");
262 if (IS_ERR(vreg_mddi_1v5))
263 return PTR_ERR(vreg_mddi_1v5);
264 vreg_lcm_2v85 = vreg_get(0, "gp4");
265 if (IS_ERR(vreg_lcm_2v85))
266 return PTR_ERR(vreg_lcm_2v85);
267
268 trout_new_backlight = system_rev >= 5;
269 if (trout_new_backlight) {
270 uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,
271 GPIO_NO_PULL, GPIO_8MA);
272 msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
273 } else {
274 uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
275 GPIO_NO_PULL, GPIO_8MA);
276 msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
277
278 gp_clk = clk_get(NULL, "gp_clk");
279 if (IS_ERR(gp_clk)) {
280 printk(KERN_ERR "trout_init_panel: could not get gp"
281 "clock\n");
282 gp_clk = NULL;
283 }
284 rc = clk_set_rate(gp_clk, 19200000);
285 if (rc)
286 printk(KERN_ERR "trout_init_panel: set clock rate "
287 "failed\n");
288 }
289
290 rc = platform_device_register(&msm_device_mdp);
291 if (rc)
292 return rc;
293 msm_device_mddi0.dev.platform_data = &mddi_pdata;
294 return platform_device_register(&msm_device_mddi0);
295}
296
297device_initcall(trout_init_panel);
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c57210f4f06a..2069bfaa3a26 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -120,6 +120,21 @@ EXPORT_SYMBOL(clk_get_rate);
120 120
121int clk_set_rate(struct clk *clk, unsigned long rate) 121int clk_set_rate(struct clk *clk, unsigned long rate)
122{ 122{
123 int ret;
124 if (clk->flags & CLKFLAG_MAX) {
125 ret = clk->ops->set_max_rate(clk->id, rate);
126 if (ret)
127 return ret;
128 }
129 if (clk->flags & CLKFLAG_MIN) {
130 ret = clk->ops->set_min_rate(clk->id, rate);
131 if (ret)
132 return ret;
133 }
134
135 if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN)
136 return ret;
137
123 return clk->ops->set_rate(clk->id, rate); 138 return clk->ops->set_rate(clk->id, rate);
124} 139}
125EXPORT_SYMBOL(clk_set_rate); 140EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
index 4e8c0bcdc92d..fb548a8a21db 100644
--- a/arch/arm/mach-msm/devices-msm7x00.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -347,6 +347,73 @@ int __init msm_add_sdcc(unsigned int controller,
347 return platform_device_register(pdev); 347 return platform_device_register(pdev);
348} 348}
349 349
350static struct resource resources_mddi0[] = {
351 {
352 .start = MSM_PMDH_PHYS,
353 .end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1,
354 .flags = IORESOURCE_MEM,
355 },
356 {
357 .start = INT_MDDI_PRI,
358 .end = INT_MDDI_PRI,
359 .flags = IORESOURCE_IRQ,
360 },
361};
362
363static struct resource resources_mddi1[] = {
364 {
365 .start = MSM_EMDH_PHYS,
366 .end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1,
367 .flags = IORESOURCE_MEM,
368 },
369 {
370 .start = INT_MDDI_EXT,
371 .end = INT_MDDI_EXT,
372 .flags = IORESOURCE_IRQ,
373 },
374};
375
376struct platform_device msm_device_mddi0 = {
377 .name = "msm_mddi",
378 .id = 0,
379 .num_resources = ARRAY_SIZE(resources_mddi0),
380 .resource = resources_mddi0,
381 .dev = {
382 .coherent_dma_mask = 0xffffffff,
383 },
384};
385
386struct platform_device msm_device_mddi1 = {
387 .name = "msm_mddi",
388 .id = 1,
389 .num_resources = ARRAY_SIZE(resources_mddi1),
390 .resource = resources_mddi1,
391 .dev = {
392 .coherent_dma_mask = 0xffffffff,
393 },
394};
395
396static struct resource resources_mdp[] = {
397 {
398 .start = MSM_MDP_PHYS,
399 .end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1,
400 .name = "mdp",
401 .flags = IORESOURCE_MEM
402 },
403 {
404 .start = INT_MDP,
405 .end = INT_MDP,
406 .flags = IORESOURCE_IRQ,
407 },
408};
409
410struct platform_device msm_device_mdp = {
411 .name = "msm_mdp",
412 .id = 0,
413 .num_resources = ARRAY_SIZE(resources_mdp),
414 .resource = resources_mdp,
415};
416
350struct clk msm_clocks_7x01a[] = { 417struct clk msm_clocks_7x01a[] = {
351 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), 418 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
352 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), 419 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
@@ -364,7 +431,7 @@ struct clk msm_clocks_7x01a[] = {
364 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), 431 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
365 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), 432 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
366 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), 433 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
367 CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ), 434 CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
368 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), 435 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
369 CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), 436 CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
370 CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), 437 CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF),
diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c
index 89b9d4437e92..f9e7bd34ec59 100644
--- a/arch/arm/mach-msm/devices-msm8x60-iommu.c
+++ b/arch/arm/mach-msm/devices-msm8x60-iommu.c
@@ -254,60 +254,86 @@ static struct resource msm_iommu_gfx2d0_resources[] = {
254 }, 254 },
255}; 255};
256 256
257static struct resource msm_iommu_gfx2d1_resources[] = {
258 {
259 .start = MSM_IOMMU_GFX2D1_PHYS,
260 .end = MSM_IOMMU_GFX2D1_PHYS + MSM_IOMMU_GFX2D1_SIZE - 1,
261 .name = "physbase",
262 .flags = IORESOURCE_MEM,
263 },
264 {
265 .name = "nonsecure_irq",
266 .start = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
267 .end = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
268 .flags = IORESOURCE_IRQ,
269 },
270 {
271 .name = "secure_irq",
272 .start = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
273 .end = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
274 .flags = IORESOURCE_IRQ,
275 },
276};
277
257static struct platform_device msm_root_iommu_dev = { 278static struct platform_device msm_root_iommu_dev = {
258 .name = "msm_iommu", 279 .name = "msm_iommu",
259 .id = -1, 280 .id = -1,
260}; 281};
261 282
262static struct msm_iommu_dev jpegd_smmu = { 283static struct msm_iommu_dev jpegd_iommu = {
263 .name = "jpegd", 284 .name = "jpegd",
264 .clk_rate = -1 285 .clk_rate = -1
265}; 286};
266 287
267static struct msm_iommu_dev vpe_smmu = { 288static struct msm_iommu_dev vpe_iommu = {
268 .name = "vpe" 289 .name = "vpe"
269}; 290};
270 291
271static struct msm_iommu_dev mdp0_smmu = { 292static struct msm_iommu_dev mdp0_iommu = {
272 .name = "mdp0" 293 .name = "mdp0"
273}; 294};
274 295
275static struct msm_iommu_dev mdp1_smmu = { 296static struct msm_iommu_dev mdp1_iommu = {
276 .name = "mdp1" 297 .name = "mdp1"
277}; 298};
278 299
279static struct msm_iommu_dev rot_smmu = { 300static struct msm_iommu_dev rot_iommu = {
280 .name = "rot" 301 .name = "rot"
281}; 302};
282 303
283static struct msm_iommu_dev ijpeg_smmu = { 304static struct msm_iommu_dev ijpeg_iommu = {
284 .name = "ijpeg" 305 .name = "ijpeg"
285}; 306};
286 307
287static struct msm_iommu_dev vfe_smmu = { 308static struct msm_iommu_dev vfe_iommu = {
288 .name = "vfe", 309 .name = "vfe",
289 .clk_rate = -1 310 .clk_rate = -1
290}; 311};
291 312
292static struct msm_iommu_dev vcodec_a_smmu = { 313static struct msm_iommu_dev vcodec_a_iommu = {
293 .name = "vcodec_a" 314 .name = "vcodec_a"
294}; 315};
295 316
296static struct msm_iommu_dev vcodec_b_smmu = { 317static struct msm_iommu_dev vcodec_b_iommu = {
297 .name = "vcodec_b" 318 .name = "vcodec_b"
298}; 319};
299 320
300static struct msm_iommu_dev gfx3d_smmu = { 321static struct msm_iommu_dev gfx3d_iommu = {
301 .name = "gfx3d", 322 .name = "gfx3d",
302 .clk_rate = 27000000 323 .clk_rate = 27000000
303}; 324};
304 325
305static struct msm_iommu_dev gfx2d0_smmu = { 326static struct msm_iommu_dev gfx2d0_iommu = {
306 .name = "gfx2d0", 327 .name = "gfx2d0",
307 .clk_rate = 27000000 328 .clk_rate = 27000000
308}; 329};
309 330
310static struct platform_device msm_device_smmu_jpegd = { 331static struct msm_iommu_dev gfx2d1_iommu = {
332 .name = "gfx2d1",
333 .clk_rate = 27000000
334};
335
336static struct platform_device msm_device_iommu_jpegd = {
311 .name = "msm_iommu", 337 .name = "msm_iommu",
312 .id = 0, 338 .id = 0,
313 .dev = { 339 .dev = {
@@ -317,7 +343,7 @@ static struct platform_device msm_device_smmu_jpegd = {
317 .resource = msm_iommu_jpegd_resources, 343 .resource = msm_iommu_jpegd_resources,
318}; 344};
319 345
320static struct platform_device msm_device_smmu_vpe = { 346static struct platform_device msm_device_iommu_vpe = {
321 .name = "msm_iommu", 347 .name = "msm_iommu",
322 .id = 1, 348 .id = 1,
323 .dev = { 349 .dev = {
@@ -327,7 +353,7 @@ static struct platform_device msm_device_smmu_vpe = {
327 .resource = msm_iommu_vpe_resources, 353 .resource = msm_iommu_vpe_resources,
328}; 354};
329 355
330static struct platform_device msm_device_smmu_mdp0 = { 356static struct platform_device msm_device_iommu_mdp0 = {
331 .name = "msm_iommu", 357 .name = "msm_iommu",
332 .id = 2, 358 .id = 2,
333 .dev = { 359 .dev = {
@@ -337,7 +363,7 @@ static struct platform_device msm_device_smmu_mdp0 = {
337 .resource = msm_iommu_mdp0_resources, 363 .resource = msm_iommu_mdp0_resources,
338}; 364};
339 365
340static struct platform_device msm_device_smmu_mdp1 = { 366static struct platform_device msm_device_iommu_mdp1 = {
341 .name = "msm_iommu", 367 .name = "msm_iommu",
342 .id = 3, 368 .id = 3,
343 .dev = { 369 .dev = {
@@ -347,7 +373,7 @@ static struct platform_device msm_device_smmu_mdp1 = {
347 .resource = msm_iommu_mdp1_resources, 373 .resource = msm_iommu_mdp1_resources,
348}; 374};
349 375
350static struct platform_device msm_device_smmu_rot = { 376static struct platform_device msm_device_iommu_rot = {
351 .name = "msm_iommu", 377 .name = "msm_iommu",
352 .id = 4, 378 .id = 4,
353 .dev = { 379 .dev = {
@@ -357,7 +383,7 @@ static struct platform_device msm_device_smmu_rot = {
357 .resource = msm_iommu_rot_resources, 383 .resource = msm_iommu_rot_resources,
358}; 384};
359 385
360static struct platform_device msm_device_smmu_ijpeg = { 386static struct platform_device msm_device_iommu_ijpeg = {
361 .name = "msm_iommu", 387 .name = "msm_iommu",
362 .id = 5, 388 .id = 5,
363 .dev = { 389 .dev = {
@@ -367,7 +393,7 @@ static struct platform_device msm_device_smmu_ijpeg = {
367 .resource = msm_iommu_ijpeg_resources, 393 .resource = msm_iommu_ijpeg_resources,
368}; 394};
369 395
370static struct platform_device msm_device_smmu_vfe = { 396static struct platform_device msm_device_iommu_vfe = {
371 .name = "msm_iommu", 397 .name = "msm_iommu",
372 .id = 6, 398 .id = 6,
373 .dev = { 399 .dev = {
@@ -377,7 +403,7 @@ static struct platform_device msm_device_smmu_vfe = {
377 .resource = msm_iommu_vfe_resources, 403 .resource = msm_iommu_vfe_resources,
378}; 404};
379 405
380static struct platform_device msm_device_smmu_vcodec_a = { 406static struct platform_device msm_device_iommu_vcodec_a = {
381 .name = "msm_iommu", 407 .name = "msm_iommu",
382 .id = 7, 408 .id = 7,
383 .dev = { 409 .dev = {
@@ -387,7 +413,7 @@ static struct platform_device msm_device_smmu_vcodec_a = {
387 .resource = msm_iommu_vcodec_a_resources, 413 .resource = msm_iommu_vcodec_a_resources,
388}; 414};
389 415
390static struct platform_device msm_device_smmu_vcodec_b = { 416static struct platform_device msm_device_iommu_vcodec_b = {
391 .name = "msm_iommu", 417 .name = "msm_iommu",
392 .id = 8, 418 .id = 8,
393 .dev = { 419 .dev = {
@@ -397,7 +423,7 @@ static struct platform_device msm_device_smmu_vcodec_b = {
397 .resource = msm_iommu_vcodec_b_resources, 423 .resource = msm_iommu_vcodec_b_resources,
398}; 424};
399 425
400static struct platform_device msm_device_smmu_gfx3d = { 426static struct platform_device msm_device_iommu_gfx3d = {
401 .name = "msm_iommu", 427 .name = "msm_iommu",
402 .id = 9, 428 .id = 9,
403 .dev = { 429 .dev = {
@@ -407,7 +433,7 @@ static struct platform_device msm_device_smmu_gfx3d = {
407 .resource = msm_iommu_gfx3d_resources, 433 .resource = msm_iommu_gfx3d_resources,
408}; 434};
409 435
410static struct platform_device msm_device_smmu_gfx2d0 = { 436static struct platform_device msm_device_iommu_gfx2d0 = {
411 .name = "msm_iommu", 437 .name = "msm_iommu",
412 .id = 10, 438 .id = 10,
413 .dev = { 439 .dev = {
@@ -417,6 +443,16 @@ static struct platform_device msm_device_smmu_gfx2d0 = {
417 .resource = msm_iommu_gfx2d0_resources, 443 .resource = msm_iommu_gfx2d0_resources,
418}; 444};
419 445
446struct platform_device msm_device_iommu_gfx2d1 = {
447 .name = "msm_iommu",
448 .id = 11,
449 .dev = {
450 .parent = &msm_root_iommu_dev.dev,
451 },
452 .num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources),
453 .resource = msm_iommu_gfx2d1_resources,
454};
455
420static struct msm_iommu_ctx_dev jpegd_src_ctx = { 456static struct msm_iommu_ctx_dev jpegd_src_ctx = {
421 .name = "jpegd_src", 457 .name = "jpegd_src",
422 .num = 0, 458 .num = 0,
@@ -519,41 +555,36 @@ static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
519 .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} 555 .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
520}; 556};
521 557
522static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = { 558static struct msm_iommu_ctx_dev gfx3d_user_ctx = {
523 .name = "gfx3d_rbpa", 559 .name = "gfx3d_user",
524 .num = 0, 560 .num = 0,
525 .mids = {-1} 561 .mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
526}; 562};
527 563
528static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = { 564static struct msm_iommu_ctx_dev gfx3d_priv_ctx = {
529 .name = "gfx3d_cpvgttc", 565 .name = "gfx3d_priv",
530 .num = 1, 566 .num = 1,
531 .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1} 567 .mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
532}; 568 31, -1}
533
534static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = {
535 .name = "gfx3d_smmu",
536 .num = 2,
537 .mids = {8, 9, 10, 11, 12, -1}
538}; 569};
539 570
540static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = { 571static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
541 .name = "gfx2d0_pixv1_smmu", 572 .name = "gfx2d0_2d0",
542 .num = 0, 573 .num = 0,
543 .mids = {0, 3, 4, -1} 574 .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
544}; 575};
545 576
546static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = { 577static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = {
547 .name = "gfx2d0_texv3_smmu", 578 .name = "gfx2d1_2d1",
548 .num = 1, 579 .num = 0,
549 .mids = {1, 6, 7, -1} 580 .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
550}; 581};
551 582
552static struct platform_device msm_device_jpegd_src_ctx = { 583static struct platform_device msm_device_jpegd_src_ctx = {
553 .name = "msm_iommu_ctx", 584 .name = "msm_iommu_ctx",
554 .id = 0, 585 .id = 0,
555 .dev = { 586 .dev = {
556 .parent = &msm_device_smmu_jpegd.dev, 587 .parent = &msm_device_iommu_jpegd.dev,
557 }, 588 },
558}; 589};
559 590
@@ -561,7 +592,7 @@ static struct platform_device msm_device_jpegd_dst_ctx = {
561 .name = "msm_iommu_ctx", 592 .name = "msm_iommu_ctx",
562 .id = 1, 593 .id = 1,
563 .dev = { 594 .dev = {
564 .parent = &msm_device_smmu_jpegd.dev, 595 .parent = &msm_device_iommu_jpegd.dev,
565 }, 596 },
566}; 597};
567 598
@@ -569,7 +600,7 @@ static struct platform_device msm_device_vpe_src_ctx = {
569 .name = "msm_iommu_ctx", 600 .name = "msm_iommu_ctx",
570 .id = 2, 601 .id = 2,
571 .dev = { 602 .dev = {
572 .parent = &msm_device_smmu_vpe.dev, 603 .parent = &msm_device_iommu_vpe.dev,
573 }, 604 },
574}; 605};
575 606
@@ -577,7 +608,7 @@ static struct platform_device msm_device_vpe_dst_ctx = {
577 .name = "msm_iommu_ctx", 608 .name = "msm_iommu_ctx",
578 .id = 3, 609 .id = 3,
579 .dev = { 610 .dev = {
580 .parent = &msm_device_smmu_vpe.dev, 611 .parent = &msm_device_iommu_vpe.dev,
581 }, 612 },
582}; 613};
583 614
@@ -585,7 +616,7 @@ static struct platform_device msm_device_mdp_vg1_ctx = {
585 .name = "msm_iommu_ctx", 616 .name = "msm_iommu_ctx",
586 .id = 4, 617 .id = 4,
587 .dev = { 618 .dev = {
588 .parent = &msm_device_smmu_mdp0.dev, 619 .parent = &msm_device_iommu_mdp0.dev,
589 }, 620 },
590}; 621};
591 622
@@ -593,7 +624,7 @@ static struct platform_device msm_device_mdp_rgb1_ctx = {
593 .name = "msm_iommu_ctx", 624 .name = "msm_iommu_ctx",
594 .id = 5, 625 .id = 5,
595 .dev = { 626 .dev = {
596 .parent = &msm_device_smmu_mdp0.dev, 627 .parent = &msm_device_iommu_mdp0.dev,
597 }, 628 },
598}; 629};
599 630
@@ -601,7 +632,7 @@ static struct platform_device msm_device_mdp_vg2_ctx = {
601 .name = "msm_iommu_ctx", 632 .name = "msm_iommu_ctx",
602 .id = 6, 633 .id = 6,
603 .dev = { 634 .dev = {
604 .parent = &msm_device_smmu_mdp1.dev, 635 .parent = &msm_device_iommu_mdp1.dev,
605 }, 636 },
606}; 637};
607 638
@@ -609,7 +640,7 @@ static struct platform_device msm_device_mdp_rgb2_ctx = {
609 .name = "msm_iommu_ctx", 640 .name = "msm_iommu_ctx",
610 .id = 7, 641 .id = 7,
611 .dev = { 642 .dev = {
612 .parent = &msm_device_smmu_mdp1.dev, 643 .parent = &msm_device_iommu_mdp1.dev,
613 }, 644 },
614}; 645};
615 646
@@ -617,7 +648,7 @@ static struct platform_device msm_device_rot_src_ctx = {
617 .name = "msm_iommu_ctx", 648 .name = "msm_iommu_ctx",
618 .id = 8, 649 .id = 8,
619 .dev = { 650 .dev = {
620 .parent = &msm_device_smmu_rot.dev, 651 .parent = &msm_device_iommu_rot.dev,
621 }, 652 },
622}; 653};
623 654
@@ -625,7 +656,7 @@ static struct platform_device msm_device_rot_dst_ctx = {
625 .name = "msm_iommu_ctx", 656 .name = "msm_iommu_ctx",
626 .id = 9, 657 .id = 9,
627 .dev = { 658 .dev = {
628 .parent = &msm_device_smmu_rot.dev, 659 .parent = &msm_device_iommu_rot.dev,
629 }, 660 },
630}; 661};
631 662
@@ -633,7 +664,7 @@ static struct platform_device msm_device_ijpeg_src_ctx = {
633 .name = "msm_iommu_ctx", 664 .name = "msm_iommu_ctx",
634 .id = 10, 665 .id = 10,
635 .dev = { 666 .dev = {
636 .parent = &msm_device_smmu_ijpeg.dev, 667 .parent = &msm_device_iommu_ijpeg.dev,
637 }, 668 },
638}; 669};
639 670
@@ -641,7 +672,7 @@ static struct platform_device msm_device_ijpeg_dst_ctx = {
641 .name = "msm_iommu_ctx", 672 .name = "msm_iommu_ctx",
642 .id = 11, 673 .id = 11,
643 .dev = { 674 .dev = {
644 .parent = &msm_device_smmu_ijpeg.dev, 675 .parent = &msm_device_iommu_ijpeg.dev,
645 }, 676 },
646}; 677};
647 678
@@ -649,7 +680,7 @@ static struct platform_device msm_device_vfe_imgwr_ctx = {
649 .name = "msm_iommu_ctx", 680 .name = "msm_iommu_ctx",
650 .id = 12, 681 .id = 12,
651 .dev = { 682 .dev = {
652 .parent = &msm_device_smmu_vfe.dev, 683 .parent = &msm_device_iommu_vfe.dev,
653 }, 684 },
654}; 685};
655 686
@@ -657,7 +688,7 @@ static struct platform_device msm_device_vfe_misc_ctx = {
657 .name = "msm_iommu_ctx", 688 .name = "msm_iommu_ctx",
658 .id = 13, 689 .id = 13,
659 .dev = { 690 .dev = {
660 .parent = &msm_device_smmu_vfe.dev, 691 .parent = &msm_device_iommu_vfe.dev,
661 }, 692 },
662}; 693};
663 694
@@ -665,7 +696,7 @@ static struct platform_device msm_device_vcodec_a_stream_ctx = {
665 .name = "msm_iommu_ctx", 696 .name = "msm_iommu_ctx",
666 .id = 14, 697 .id = 14,
667 .dev = { 698 .dev = {
668 .parent = &msm_device_smmu_vcodec_a.dev, 699 .parent = &msm_device_iommu_vcodec_a.dev,
669 }, 700 },
670}; 701};
671 702
@@ -673,7 +704,7 @@ static struct platform_device msm_device_vcodec_a_mm1_ctx = {
673 .name = "msm_iommu_ctx", 704 .name = "msm_iommu_ctx",
674 .id = 15, 705 .id = 15,
675 .dev = { 706 .dev = {
676 .parent = &msm_device_smmu_vcodec_a.dev, 707 .parent = &msm_device_iommu_vcodec_a.dev,
677 }, 708 },
678}; 709};
679 710
@@ -681,76 +712,70 @@ static struct platform_device msm_device_vcodec_b_mm2_ctx = {
681 .name = "msm_iommu_ctx", 712 .name = "msm_iommu_ctx",
682 .id = 16, 713 .id = 16,
683 .dev = { 714 .dev = {
684 .parent = &msm_device_smmu_vcodec_b.dev, 715 .parent = &msm_device_iommu_vcodec_b.dev,
685 }, 716 },
686}; 717};
687 718
688static struct platform_device msm_device_gfx3d_rbpa_ctx = { 719static struct platform_device msm_device_gfx3d_user_ctx = {
689 .name = "msm_iommu_ctx", 720 .name = "msm_iommu_ctx",
690 .id = 17, 721 .id = 17,
691 .dev = { 722 .dev = {
692 .parent = &msm_device_smmu_gfx3d.dev, 723 .parent = &msm_device_iommu_gfx3d.dev,
693 }, 724 },
694}; 725};
695 726
696static struct platform_device msm_device_gfx3d_cpvgttc_ctx = { 727static struct platform_device msm_device_gfx3d_priv_ctx = {
697 .name = "msm_iommu_ctx", 728 .name = "msm_iommu_ctx",
698 .id = 18, 729 .id = 18,
699 .dev = { 730 .dev = {
700 .parent = &msm_device_smmu_gfx3d.dev, 731 .parent = &msm_device_iommu_gfx3d.dev,
701 }, 732 },
702}; 733};
703 734
704static struct platform_device msm_device_gfx3d_smmu_ctx = { 735static struct platform_device msm_device_gfx2d0_2d0_ctx = {
705 .name = "msm_iommu_ctx", 736 .name = "msm_iommu_ctx",
706 .id = 19, 737 .id = 19,
707 .dev = { 738 .dev = {
708 .parent = &msm_device_smmu_gfx3d.dev, 739 .parent = &msm_device_iommu_gfx2d0.dev,
709 }, 740 },
710}; 741};
711 742
712static struct platform_device msm_device_gfx2d0_pixv1_ctx = { 743static struct platform_device msm_device_gfx2d1_2d1_ctx = {
713 .name = "msm_iommu_ctx", 744 .name = "msm_iommu_ctx",
714 .id = 20, 745 .id = 20,
715 .dev = { 746 .dev = {
716 .parent = &msm_device_smmu_gfx2d0.dev, 747 .parent = &msm_device_iommu_gfx2d1.dev,
717 },
718};
719
720static struct platform_device msm_device_gfx2d0_texv3_ctx = {
721 .name = "msm_iommu_ctx",
722 .id = 21,
723 .dev = {
724 .parent = &msm_device_smmu_gfx2d0.dev,
725 }, 748 },
726}; 749};
727 750
728static struct platform_device *msm_iommu_devs[] = { 751static struct platform_device *msm_iommu_devs[] = {
729 &msm_device_smmu_jpegd, 752 &msm_device_iommu_jpegd,
730 &msm_device_smmu_vpe, 753 &msm_device_iommu_vpe,
731 &msm_device_smmu_mdp0, 754 &msm_device_iommu_mdp0,
732 &msm_device_smmu_mdp1, 755 &msm_device_iommu_mdp1,
733 &msm_device_smmu_rot, 756 &msm_device_iommu_rot,
734 &msm_device_smmu_ijpeg, 757 &msm_device_iommu_ijpeg,
735 &msm_device_smmu_vfe, 758 &msm_device_iommu_vfe,
736 &msm_device_smmu_vcodec_a, 759 &msm_device_iommu_vcodec_a,
737 &msm_device_smmu_vcodec_b, 760 &msm_device_iommu_vcodec_b,
738 &msm_device_smmu_gfx3d, 761 &msm_device_iommu_gfx3d,
739 &msm_device_smmu_gfx2d0, 762 &msm_device_iommu_gfx2d0,
763 &msm_device_iommu_gfx2d1,
740}; 764};
741 765
742static struct msm_iommu_dev *msm_iommu_data[] = { 766static struct msm_iommu_dev *msm_iommu_data[] = {
743 &jpegd_smmu, 767 &jpegd_iommu,
744 &vpe_smmu, 768 &vpe_iommu,
745 &mdp0_smmu, 769 &mdp0_iommu,
746 &mdp1_smmu, 770 &mdp1_iommu,
747 &rot_smmu, 771 &rot_iommu,
748 &ijpeg_smmu, 772 &ijpeg_iommu,
749 &vfe_smmu, 773 &vfe_iommu,
750 &vcodec_a_smmu, 774 &vcodec_a_iommu,
751 &vcodec_b_smmu, 775 &vcodec_b_iommu,
752 &gfx3d_smmu, 776 &gfx3d_iommu,
753 &gfx2d0_smmu, 777 &gfx2d0_iommu,
778 &gfx2d1_iommu,
754}; 779};
755 780
756static struct platform_device *msm_iommu_ctx_devs[] = { 781static struct platform_device *msm_iommu_ctx_devs[] = {
@@ -771,11 +796,10 @@ static struct platform_device *msm_iommu_ctx_devs[] = {
771 &msm_device_vcodec_a_stream_ctx, 796 &msm_device_vcodec_a_stream_ctx,
772 &msm_device_vcodec_a_mm1_ctx, 797 &msm_device_vcodec_a_mm1_ctx,
773 &msm_device_vcodec_b_mm2_ctx, 798 &msm_device_vcodec_b_mm2_ctx,
774 &msm_device_gfx3d_rbpa_ctx, 799 &msm_device_gfx3d_user_ctx,
775 &msm_device_gfx3d_cpvgttc_ctx, 800 &msm_device_gfx3d_priv_ctx,
776 &msm_device_gfx3d_smmu_ctx, 801 &msm_device_gfx2d0_2d0_ctx,
777 &msm_device_gfx2d0_pixv1_ctx, 802 &msm_device_gfx2d1_2d1_ctx,
778 &msm_device_gfx2d0_texv3_ctx,
779}; 803};
780 804
781static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = { 805static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
@@ -796,14 +820,13 @@ static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
796 &vcodec_a_stream_ctx, 820 &vcodec_a_stream_ctx,
797 &vcodec_a_mm1_ctx, 821 &vcodec_a_mm1_ctx,
798 &vcodec_b_mm2_ctx, 822 &vcodec_b_mm2_ctx,
799 &gfx3d_rbpa_ctx, 823 &gfx3d_user_ctx,
800 &gfx3d_cpvgttc_ctx, 824 &gfx3d_priv_ctx,
801 &gfx3d_smmu_ctx, 825 &gfx2d0_2d0_ctx,
802 &gfx2d0_pixv1_ctx, 826 &gfx2d1_2d1_ctx,
803 &gfx2d0_texv3_ctx,
804}; 827};
805 828
806static int msm8x60_iommu_init(void) 829static int __init msm8x60_iommu_init(void)
807{ 830{
808 int ret, i; 831 int ret, i;
809 832
@@ -826,7 +849,7 @@ static int msm8x60_iommu_init(void)
826 ret = platform_device_register(msm_iommu_devs[i]); 849 ret = platform_device_register(msm_iommu_devs[i]);
827 850
828 if (ret != 0) { 851 if (ret != 0) {
829 pr_err("platform_device_register smmu failed, " 852 pr_err("platform_device_register iommu failed, "
830 "i = %d\n", i); 853 "i = %d\n", i);
831 goto failure_unwind; 854 goto failure_unwind;
832 } 855 }
@@ -837,7 +860,7 @@ static int msm8x60_iommu_init(void)
837 msm_iommu_ctx_data[i], 860 msm_iommu_ctx_data[i],
838 sizeof(*msm_iommu_ctx_devs[i])); 861 sizeof(*msm_iommu_ctx_devs[i]));
839 if (ret != 0) { 862 if (ret != 0) {
840 pr_err("platform_device_add_data smmu failed, " 863 pr_err("platform_device_add_data iommu failed, "
841 "i = %d\n", i); 864 "i = %d\n", i);
842 goto failure_unwind2; 865 goto failure_unwind2;
843 } 866 }
@@ -863,7 +886,7 @@ failure:
863 return ret; 886 return ret;
864} 887}
865 888
866static void msm8x60_iommu_exit(void) 889static void __exit msm8x60_iommu_exit(void)
867{ 890{
868 int i; 891 int i;
869 892
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 568443e76423..68b8075f8ca4 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -35,6 +35,10 @@ extern struct platform_device msm_device_smd;
35 35
36extern struct platform_device msm_device_nand; 36extern struct platform_device msm_device_nand;
37 37
38extern struct platform_device msm_device_mddi0;
39extern struct platform_device msm_device_mddi1;
40extern struct platform_device msm_device_mdp;
41
38extern struct clk msm_clocks_7x01a[]; 42extern struct clk msm_clocks_7x01a[];
39extern unsigned msm_num_clocks_7x01a; 43extern unsigned msm_num_clocks_7x01a;
40 44
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c
new file mode 100644
index 000000000000..0de19ec74e34
--- /dev/null
+++ b/arch/arm/mach-msm/gpio-v2.c
@@ -0,0 +1,426 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 */
18#define pr_fmt(fmt) "%s: " fmt, __func__
19
20#include <linux/bitmap.h>
21#include <linux/bitops.h>
22#include <linux/gpio.h>
23#include <linux/init.h>
24#include <linux/interrupt.h>
25#include <linux/io.h>
26#include <linux/irq.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/spinlock.h>
30#include <mach/msm_iomap.h>
31#include "gpiomux.h"
32
33/* Bits of interest in the GPIO_IN_OUT register.
34 */
35enum {
36 GPIO_IN = 0,
37 GPIO_OUT = 1
38};
39
40/* Bits of interest in the GPIO_INTR_STATUS register.
41 */
42enum {
43 INTR_STATUS = 0,
44};
45
46/* Bits of interest in the GPIO_CFG register.
47 */
48enum {
49 GPIO_OE = 9,
50};
51
52/* Bits of interest in the GPIO_INTR_CFG register.
53 * When a GPIO triggers, two separate decisions are made, controlled
54 * by two separate flags.
55 *
56 * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
57 * register for that GPIO will be updated to reflect the triggering of that
58 * gpio. If this bit is 0, this register will not be updated.
59 * - Second, INTR_ENABLE controls whether an interrupt is triggered.
60 *
61 * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
62 * can be triggered but the status register will not reflect it.
63 */
64enum {
65 INTR_ENABLE = 0,
66 INTR_POL_CTL = 1,
67 INTR_DECT_CTL = 2,
68 INTR_RAW_STATUS_EN = 3,
69};
70
71/* Codes of interest in GPIO_INTR_CFG_SU.
72 */
73enum {
74 TARGET_PROC_SCORPION = 4,
75 TARGET_PROC_NONE = 7,
76};
77
78
79#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
80#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
81#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
82#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
83#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
84
85/**
86 * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
87 *
88 * @enabled_irqs: a bitmap used to optimize the summary-irq handler. By
89 * keeping track of which gpios are unmasked as irq sources, we avoid
90 * having to do readl calls on hundreds of iomapped registers each time
91 * the summary interrupt fires in order to locate the active interrupts.
92 *
93 * @wake_irqs: a bitmap for tracking which interrupt lines are enabled
94 * as wakeup sources. When the device is suspended, interrupts which are
95 * not wakeup sources are disabled.
96 *
97 * @dual_edge_irqs: a bitmap used to track which irqs are configured
98 * as dual-edge, as this is not supported by the hardware and requires
99 * some special handling in the driver.
100 */
101struct msm_gpio_dev {
102 struct gpio_chip gpio_chip;
103 DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
104 DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
105 DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
106};
107
108static DEFINE_SPINLOCK(tlmm_lock);
109
110static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
111{
112 return container_of(chip, struct msm_gpio_dev, gpio_chip);
113}
114
115static inline void set_gpio_bits(unsigned n, void __iomem *reg)
116{
117 writel(readl(reg) | n, reg);
118}
119
120static inline void clear_gpio_bits(unsigned n, void __iomem *reg)
121{
122 writel(readl(reg) & ~n, reg);
123}
124
125static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
126{
127 return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN);
128}
129
130static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
131{
132 writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset));
133}
134
135static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
136{
137 unsigned long irq_flags;
138
139 spin_lock_irqsave(&tlmm_lock, irq_flags);
140 clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
141 spin_unlock_irqrestore(&tlmm_lock, irq_flags);
142 return 0;
143}
144
145static int msm_gpio_direction_output(struct gpio_chip *chip,
146 unsigned offset,
147 int val)
148{
149 unsigned long irq_flags;
150
151 spin_lock_irqsave(&tlmm_lock, irq_flags);
152 msm_gpio_set(chip, offset, val);
153 set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
154 spin_unlock_irqrestore(&tlmm_lock, irq_flags);
155 return 0;
156}
157
158static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
159{
160 return msm_gpiomux_get(chip->base + offset);
161}
162
163static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
164{
165 msm_gpiomux_put(chip->base + offset);
166}
167
168static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
169{
170 return MSM_GPIO_TO_INT(chip->base + offset);
171}
172
173static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
174{
175 return irq - MSM_GPIO_TO_INT(chip->base);
176}
177
178static struct msm_gpio_dev msm_gpio = {
179 .gpio_chip = {
180 .base = 0,
181 .ngpio = NR_GPIO_IRQS,
182 .direction_input = msm_gpio_direction_input,
183 .direction_output = msm_gpio_direction_output,
184 .get = msm_gpio_get,
185 .set = msm_gpio_set,
186 .to_irq = msm_gpio_to_irq,
187 .request = msm_gpio_request,
188 .free = msm_gpio_free,
189 },
190};
191
192/* For dual-edge interrupts in software, since the hardware has no
193 * such support:
194 *
195 * At appropriate moments, this function may be called to flip the polarity
196 * settings of both-edge irq lines to try and catch the next edge.
197 *
198 * The attempt is considered successful if:
199 * - the status bit goes high, indicating that an edge was caught, or
200 * - the input value of the gpio doesn't change during the attempt.
201 * If the value changes twice during the process, that would cause the first
202 * test to fail but would force the second, as two opposite
203 * transitions would cause a detection no matter the polarity setting.
204 *
205 * The do-loop tries to sledge-hammer closed the timing hole between
206 * the initial value-read and the polarity-write - if the line value changes
207 * during that window, an interrupt is lost, the new polarity setting is
208 * incorrect, and the first success test will fail, causing a retry.
209 *
210 * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c.
211 */
212static void msm_gpio_update_dual_edge_pos(unsigned gpio)
213{
214 int loop_limit = 100;
215 unsigned val, val2, intstat;
216
217 do {
218 val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
219 if (val)
220 clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
221 else
222 set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
223 val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
224 intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS);
225 if (intstat || val == val2)
226 return;
227 } while (loop_limit-- > 0);
228 pr_err("dual-edge irq failed to stabilize, "
229 "interrupts dropped. %#08x != %#08x\n",
230 val, val2);
231}
232
233static void msm_gpio_irq_ack(unsigned int irq)
234{
235 int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
236
237 writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
238 if (test_bit(gpio, msm_gpio.dual_edge_irqs))
239 msm_gpio_update_dual_edge_pos(gpio);
240}
241
242static void msm_gpio_irq_mask(unsigned int irq)
243{
244 int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
245 unsigned long irq_flags;
246
247 spin_lock_irqsave(&tlmm_lock, irq_flags);
248 writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
249 clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
250 __clear_bit(gpio, msm_gpio.enabled_irqs);
251 spin_unlock_irqrestore(&tlmm_lock, irq_flags);
252}
253
254static void msm_gpio_irq_unmask(unsigned int irq)
255{
256 int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
257 unsigned long irq_flags;
258
259 spin_lock_irqsave(&tlmm_lock, irq_flags);
260 __set_bit(gpio, msm_gpio.enabled_irqs);
261 set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
262 writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
263 spin_unlock_irqrestore(&tlmm_lock, irq_flags);
264}
265
266static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
267{
268 int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
269 unsigned long irq_flags;
270 uint32_t bits;
271
272 spin_lock_irqsave(&tlmm_lock, irq_flags);
273
274 bits = readl(GPIO_INTR_CFG(gpio));
275
276 if (flow_type & IRQ_TYPE_EDGE_BOTH) {
277 bits |= BIT(INTR_DECT_CTL);
278 irq_desc[irq].handle_irq = handle_edge_irq;
279 if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
280 __set_bit(gpio, msm_gpio.dual_edge_irqs);
281 else
282 __clear_bit(gpio, msm_gpio.dual_edge_irqs);
283 } else {
284 bits &= ~BIT(INTR_DECT_CTL);
285 irq_desc[irq].handle_irq = handle_level_irq;
286 __clear_bit(gpio, msm_gpio.dual_edge_irqs);
287 }
288
289 if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
290 bits |= BIT(INTR_POL_CTL);
291 else
292 bits &= ~BIT(INTR_POL_CTL);
293
294 writel(bits, GPIO_INTR_CFG(gpio));
295
296 if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
297 msm_gpio_update_dual_edge_pos(gpio);
298
299 spin_unlock_irqrestore(&tlmm_lock, irq_flags);
300
301 return 0;
302}
303
304/*
305 * When the summary IRQ is raised, any number of GPIO lines may be high.
306 * It is the job of the summary handler to find all those GPIO lines
307 * which have been set as summary IRQ lines and which are triggered,
308 * and to call their interrupt handlers.
309 */
310static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
311{
312 unsigned long i;
313
314 for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
315 i < NR_GPIO_IRQS;
316 i = find_next_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS, i + 1)) {
317 if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
318 generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
319 i));
320 }
321 desc->chip->ack(irq);
322}
323
324static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
325{
326 int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
327
328 if (on) {
329 if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
330 set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
331 set_bit(gpio, msm_gpio.wake_irqs);
332 } else {
333 clear_bit(gpio, msm_gpio.wake_irqs);
334 if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
335 set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
336 }
337
338 return 0;
339}
340
341static struct irq_chip msm_gpio_irq_chip = {
342 .name = "msmgpio",
343 .mask = msm_gpio_irq_mask,
344 .unmask = msm_gpio_irq_unmask,
345 .ack = msm_gpio_irq_ack,
346 .set_type = msm_gpio_irq_set_type,
347 .set_wake = msm_gpio_irq_set_wake,
348};
349
350static int __devinit msm_gpio_probe(struct platform_device *dev)
351{
352 int i, irq, ret;
353
354 bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
355 bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
356 bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
357 msm_gpio.gpio_chip.label = dev->name;
358 ret = gpiochip_add(&msm_gpio.gpio_chip);
359 if (ret < 0)
360 return ret;
361
362 for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
363 irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
364 set_irq_chip(irq, &msm_gpio_irq_chip);
365 set_irq_handler(irq, handle_level_irq);
366 set_irq_flags(irq, IRQF_VALID);
367 }
368
369 set_irq_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
370 msm_summary_irq_handler);
371 return 0;
372}
373
374static int __devexit msm_gpio_remove(struct platform_device *dev)
375{
376 int ret = gpiochip_remove(&msm_gpio.gpio_chip);
377
378 if (ret < 0)
379 return ret;
380
381 set_irq_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
382
383 return 0;
384}
385
386static struct platform_driver msm_gpio_driver = {
387 .probe = msm_gpio_probe,
388 .remove = __devexit_p(msm_gpio_remove),
389 .driver = {
390 .name = "msmgpio",
391 .owner = THIS_MODULE,
392 },
393};
394
395static struct platform_device msm_device_gpio = {
396 .name = "msmgpio",
397 .id = -1,
398};
399
400static int __init msm_gpio_init(void)
401{
402 int rc;
403
404 rc = platform_driver_register(&msm_gpio_driver);
405 if (!rc) {
406 rc = platform_device_register(&msm_device_gpio);
407 if (rc)
408 platform_driver_unregister(&msm_gpio_driver);
409 }
410
411 return rc;
412}
413
414static void __exit msm_gpio_exit(void)
415{
416 platform_device_unregister(&msm_device_gpio);
417 platform_driver_unregister(&msm_gpio_driver);
418}
419
420postcore_initcall(msm_gpio_init);
421module_exit(msm_gpio_exit);
422
423MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
424MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
425MODULE_LICENSE("GPL v2");
426MODULE_ALIAS("platform:msmgpio");
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 218ef5732a24..296c0f10f230 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -20,13 +20,26 @@
20 20
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22 22
23/* Sharability attributes of MSM IOMMU mappings */
24#define MSM_IOMMU_ATTR_NON_SH 0x0
25#define MSM_IOMMU_ATTR_SH 0x4
26
27/* Cacheability attributes of MSM IOMMU mappings */
28#define MSM_IOMMU_ATTR_NONCACHED 0x0
29#define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1
30#define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2
31#define MSM_IOMMU_ATTR_CACHED_WT 0x3
32
33/* Mask for the cache policy attribute */
34#define MSM_IOMMU_CP_MASK 0x03
35
23/* Maximum number of Machine IDs that we are allowing to be mapped to the same 36/* Maximum number of Machine IDs that we are allowing to be mapped to the same
24 * context bank. The number of MIDs mapped to the same CB does not affect 37 * context bank. The number of MIDs mapped to the same CB does not affect
25 * performance, but there is a practical limit on how many distinct MIDs may 38 * performance, but there is a practical limit on how many distinct MIDs may
26 * be present. These mappings are typically determined at design time and are 39 * be present. These mappings are typically determined at design time and are
27 * not expected to change at run time. 40 * not expected to change at run time.
28 */ 41 */
29#define MAX_NUM_MIDS 16 42#define MAX_NUM_MIDS 32
30 43
31/** 44/**
32 * struct msm_iommu_dev - a single IOMMU hardware instance 45 * struct msm_iommu_dev - a single IOMMU hardware instance
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index f9386d3a2f77..c2c3da9444f4 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -54,6 +54,7 @@ do { \
54 54
55#define NUM_FL_PTE 4096 55#define NUM_FL_PTE 4096
56#define NUM_SL_PTE 256 56#define NUM_SL_PTE 256
57#define NUM_TEX_CLASS 8
57 58
58/* First-level page table bits */ 59/* First-level page table bits */
59#define FL_BASE_MASK 0xFFFFFC00 60#define FL_BASE_MASK 0xFFFFFC00
@@ -63,6 +64,9 @@ do { \
63#define FL_AP_WRITE (1 << 10) 64#define FL_AP_WRITE (1 << 10)
64#define FL_AP_READ (1 << 11) 65#define FL_AP_READ (1 << 11)
65#define FL_SHARED (1 << 16) 66#define FL_SHARED (1 << 16)
67#define FL_BUFFERABLE (1 << 2)
68#define FL_CACHEABLE (1 << 3)
69#define FL_TEX0 (1 << 12)
66#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20) 70#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20)
67 71
68/* Second-level page table bits */ 72/* Second-level page table bits */
@@ -73,8 +77,20 @@ do { \
73#define SL_AP0 (1 << 4) 77#define SL_AP0 (1 << 4)
74#define SL_AP1 (2 << 4) 78#define SL_AP1 (2 << 4)
75#define SL_SHARED (1 << 10) 79#define SL_SHARED (1 << 10)
80#define SL_BUFFERABLE (1 << 2)
81#define SL_CACHEABLE (1 << 3)
82#define SL_TEX0 (1 << 6)
76#define SL_OFFSET(va) (((va) & 0xFF000) >> 12) 83#define SL_OFFSET(va) (((va) & 0xFF000) >> 12)
77 84
85/* Memory type and cache policy attributes */
86#define MT_SO 0
87#define MT_DEV 1
88#define MT_NORMAL 2
89#define CP_NONCACHED 0
90#define CP_WB_WA 1
91#define CP_WT 2
92#define CP_WB_NWA 3
93
78/* Global register setters / getters */ 94/* Global register setters / getters */
79#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v)) 95#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
80#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v)) 96#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
@@ -706,7 +722,9 @@ do { \
706#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5) 722#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
707#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6) 723#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
708#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7) 724#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
709 725#define NMRR_ICP(nmrr, n) (((nmrr) & (3 << ((n) * 2))) >> ((n) * 2))
726#define NMRR_OCP(nmrr, n) (((nmrr) & (3 << ((n) * 2 + 16))) >> \
727 ((n) * 2 + 16))
710 728
711/* PAR */ 729/* PAR */
712#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT) 730#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT)
@@ -750,6 +768,8 @@ do { \
750#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5) 768#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
751#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6) 769#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
752#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7) 770#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
771#define PRRR_NOS(prrr, n) ((prrr) & (1 << ((n) + 24)) ? 1 : 0)
772#define PRRR_MT(prrr, n) ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2)))
753 773
754 774
755/* RESUME */ 775/* RESUME */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
index 36074cfc9ad2..f65841c74c0b 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x60.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -237,7 +237,12 @@
237#define GSBI11_QUP_IRQ (GIC_SPI_START + 194) 237#define GSBI11_QUP_IRQ (GIC_SPI_START + 194)
238#define INT_UART12DM_IRQ (GIC_SPI_START + 195) 238#define INT_UART12DM_IRQ (GIC_SPI_START + 195)
239#define GSBI12_QUP_IRQ (GIC_SPI_START + 196) 239#define GSBI12_QUP_IRQ (GIC_SPI_START + 196)
240/*SPI 197 to 216 arent used in 8x60*/ 240
241/*SPI 197 to 209 arent used in 8x60*/
242#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210)
243#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211)
244
245/*SPI 212 to 216 arent used in 8x60*/
241#define SMPSS_SPARE_1 (GIC_SPI_START + 217) 246#define SMPSS_SPARE_1 (GIC_SPI_START + 217)
242#define SMPSS_SPARE_2 (GIC_SPI_START + 218) 247#define SMPSS_SPARE_2 (GIC_SPI_START + 218)
243#define SMPSS_SPARE_3 (GIC_SPI_START + 219) 248#define SMPSS_SPARE_3 (GIC_SPI_START + 219)
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 45bab50e3ee6..7c43a9bff1a9 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -98,4 +98,7 @@
98#define MSM_IOMMU_GFX2D0_PHYS 0x07D00000 98#define MSM_IOMMU_GFX2D0_PHYS 0x07D00000
99#define MSM_IOMMU_GFX2D0_SIZE SZ_1M 99#define MSM_IOMMU_GFX2D0_SIZE SZ_1M
100 100
101#define MSM_IOMMU_GFX2D1_PHYS 0x07E00000
102#define MSM_IOMMU_GFX2D1_SIZE SZ_1M
103
101#endif 104#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index d36b61074146..f912d7bf1889 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -163,3 +163,4 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
163 return __arm_ioremap_caller(phys_addr, size, mtype, 163 return __arm_ioremap_caller(phys_addr, size, mtype,
164 __builtin_return_address(0)); 164 __builtin_return_address(0));
165} 165}
166EXPORT_SYMBOL(__msm_ioremap);
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index f71747db3bee..e2d58e4cb0d7 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -33,6 +33,16 @@
33#include <mach/iommu_hw-8xxx.h> 33#include <mach/iommu_hw-8xxx.h>
34#include <mach/iommu.h> 34#include <mach/iommu.h>
35 35
36#define MRC(reg, processor, op1, crn, crm, op2) \
37__asm__ __volatile__ ( \
38" mrc " #processor "," #op1 ", %0," #crn "," #crm "," #op2 "\n" \
39: "=r" (reg))
40
41#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
42#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
43
44static int msm_iommu_tex_class[4];
45
36DEFINE_SPINLOCK(msm_iommu_lock); 46DEFINE_SPINLOCK(msm_iommu_lock);
37 47
38struct msm_priv { 48struct msm_priv {
@@ -40,23 +50,26 @@ struct msm_priv {
40 struct list_head list_attached; 50 struct list_head list_attached;
41}; 51};
42 52
43static void __flush_iotlb(struct iommu_domain *domain) 53static int __flush_iotlb(struct iommu_domain *domain)
44{ 54{
45 struct msm_priv *priv = domain->priv; 55 struct msm_priv *priv = domain->priv;
46 struct msm_iommu_drvdata *iommu_drvdata; 56 struct msm_iommu_drvdata *iommu_drvdata;
47 struct msm_iommu_ctx_drvdata *ctx_drvdata; 57 struct msm_iommu_ctx_drvdata *ctx_drvdata;
48 58 int ret = 0;
49#ifndef CONFIG_IOMMU_PGTABLES_L2 59#ifndef CONFIG_IOMMU_PGTABLES_L2
50 unsigned long *fl_table = priv->pgtable; 60 unsigned long *fl_table = priv->pgtable;
51 int i; 61 int i;
52 62
53 dmac_flush_range(fl_table, fl_table + SZ_16K); 63 if (!list_empty(&priv->list_attached)) {
64 dmac_flush_range(fl_table, fl_table + SZ_16K);
54 65
55 for (i = 0; i < NUM_FL_PTE; i++) 66 for (i = 0; i < NUM_FL_PTE; i++)
56 if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) { 67 if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
57 void *sl_table = __va(fl_table[i] & FL_BASE_MASK); 68 void *sl_table = __va(fl_table[i] &
58 dmac_flush_range(sl_table, sl_table + SZ_4K); 69 FL_BASE_MASK);
59 } 70 dmac_flush_range(sl_table, sl_table + SZ_4K);
71 }
72 }
60#endif 73#endif
61 74
62 list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) { 75 list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
@@ -66,6 +79,8 @@ static void __flush_iotlb(struct iommu_domain *domain)
66 iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent); 79 iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
67 SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0); 80 SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
68 } 81 }
82
83 return ret;
69} 84}
70 85
71static void __reset_context(void __iomem *base, int ctx) 86static void __reset_context(void __iomem *base, int ctx)
@@ -95,6 +110,7 @@ static void __reset_context(void __iomem *base, int ctx)
95 110
96static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable) 111static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
97{ 112{
113 unsigned int prrr, nmrr;
98 __reset_context(base, ctx); 114 __reset_context(base, ctx);
99 115
100 /* Set up HTW mode */ 116 /* Set up HTW mode */
@@ -127,11 +143,11 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
127 /* Turn on TEX Remap */ 143 /* Turn on TEX Remap */
128 SET_TRE(base, ctx, 1); 144 SET_TRE(base, ctx, 1);
129 145
130 /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume 146 /* Set TEX remap attributes */
131 * TEX class 0 for everything until attributes are properly worked out 147 RCP15_PRRR(prrr);
132 */ 148 RCP15_NMRR(nmrr);
133 SET_PRRR(base, ctx, 0); 149 SET_PRRR(base, ctx, prrr);
134 SET_NMRR(base, ctx, 0); 150 SET_NMRR(base, ctx, nmrr);
135 151
136 /* Turn on BFB prefetch */ 152 /* Turn on BFB prefetch */
137 SET_BFBDFE(base, ctx, 1); 153 SET_BFBDFE(base, ctx, 1);
@@ -238,6 +254,11 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
238 goto fail; 254 goto fail;
239 } 255 }
240 256
257 if (!list_empty(&ctx_drvdata->attached_elm)) {
258 ret = -EBUSY;
259 goto fail;
260 }
261
241 list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm) 262 list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
242 if (tmp_drvdata == ctx_drvdata) { 263 if (tmp_drvdata == ctx_drvdata) {
243 ret = -EBUSY; 264 ret = -EBUSY;
@@ -248,7 +269,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
248 __pa(priv->pgtable)); 269 __pa(priv->pgtable));
249 270
250 list_add(&(ctx_drvdata->attached_elm), &priv->list_attached); 271 list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
251 __flush_iotlb(domain); 272 ret = __flush_iotlb(domain);
252 273
253fail: 274fail:
254 spin_unlock_irqrestore(&msm_iommu_lock, flags); 275 spin_unlock_irqrestore(&msm_iommu_lock, flags);
@@ -263,6 +284,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
263 struct msm_iommu_drvdata *iommu_drvdata; 284 struct msm_iommu_drvdata *iommu_drvdata;
264 struct msm_iommu_ctx_drvdata *ctx_drvdata; 285 struct msm_iommu_ctx_drvdata *ctx_drvdata;
265 unsigned long flags; 286 unsigned long flags;
287 int ret;
266 288
267 spin_lock_irqsave(&msm_iommu_lock, flags); 289 spin_lock_irqsave(&msm_iommu_lock, flags);
268 priv = domain->priv; 290 priv = domain->priv;
@@ -277,7 +299,10 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
277 if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) 299 if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
278 goto fail; 300 goto fail;
279 301
280 __flush_iotlb(domain); 302 ret = __flush_iotlb(domain);
303 if (ret)
304 goto fail;
305
281 __reset_context(iommu_drvdata->base, ctx_dev->num); 306 __reset_context(iommu_drvdata->base, ctx_dev->num);
282 list_del_init(&ctx_drvdata->attached_elm); 307 list_del_init(&ctx_drvdata->attached_elm);
283 308
@@ -296,12 +321,21 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
296 unsigned long *sl_table; 321 unsigned long *sl_table;
297 unsigned long *sl_pte; 322 unsigned long *sl_pte;
298 unsigned long sl_offset; 323 unsigned long sl_offset;
324 unsigned int pgprot;
299 size_t len = 0x1000UL << order; 325 size_t len = 0x1000UL << order;
300 int ret = 0; 326 int ret = 0, tex, sh;
301 327
302 spin_lock_irqsave(&msm_iommu_lock, flags); 328 spin_lock_irqsave(&msm_iommu_lock, flags);
303 priv = domain->priv;
304 329
330 sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
331 tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
332
333 if (tex < 0 || tex > NUM_TEX_CLASS - 1) {
334 ret = -EINVAL;
335 goto fail;
336 }
337
338 priv = domain->priv;
305 if (!priv) { 339 if (!priv) {
306 ret = -EINVAL; 340 ret = -EINVAL;
307 goto fail; 341 goto fail;
@@ -322,6 +356,18 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
322 goto fail; 356 goto fail;
323 } 357 }
324 358
359 if (len == SZ_16M || len == SZ_1M) {
360 pgprot = sh ? FL_SHARED : 0;
361 pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
362 pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
363 pgprot |= tex & 0x04 ? FL_TEX0 : 0;
364 } else {
365 pgprot = sh ? SL_SHARED : 0;
366 pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
367 pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
368 pgprot |= tex & 0x04 ? SL_TEX0 : 0;
369 }
370
325 fl_offset = FL_OFFSET(va); /* Upper 12 bits */ 371 fl_offset = FL_OFFSET(va); /* Upper 12 bits */
326 fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */ 372 fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
327 373
@@ -330,17 +376,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
330 for (i = 0; i < 16; i++) 376 for (i = 0; i < 16; i++)
331 *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION | 377 *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
332 FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT | 378 FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
333 FL_SHARED; 379 FL_SHARED | pgprot;
334 } 380 }
335 381
336 if (len == SZ_1M) 382 if (len == SZ_1M)
337 *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | 383 *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
338 FL_TYPE_SECT | FL_SHARED; 384 FL_TYPE_SECT | FL_SHARED | pgprot;
339 385
340 /* Need a 2nd level table */ 386 /* Need a 2nd level table */
341 if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) { 387 if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) {
342 unsigned long *sl; 388 unsigned long *sl;
343 sl = (unsigned long *) __get_free_pages(GFP_KERNEL, 389 sl = (unsigned long *) __get_free_pages(GFP_ATOMIC,
344 get_order(SZ_4K)); 390 get_order(SZ_4K));
345 391
346 if (!sl) { 392 if (!sl) {
@@ -360,17 +406,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
360 406
361 if (len == SZ_4K) 407 if (len == SZ_4K)
362 *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | 408 *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
363 SL_SHARED | SL_TYPE_SMALL; 409 SL_SHARED | SL_TYPE_SMALL | pgprot;
364 410
365 if (len == SZ_64K) { 411 if (len == SZ_64K) {
366 int i; 412 int i;
367 413
368 for (i = 0; i < 16; i++) 414 for (i = 0; i < 16; i++)
369 *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 | 415 *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
370 SL_AP1 | SL_SHARED | SL_TYPE_LARGE; 416 SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
371 } 417 }
372 418
373 __flush_iotlb(domain); 419 ret = __flush_iotlb(domain);
374fail: 420fail:
375 spin_unlock_irqrestore(&msm_iommu_lock, flags); 421 spin_unlock_irqrestore(&msm_iommu_lock, flags);
376 return ret; 422 return ret;
@@ -455,7 +501,7 @@ static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
455 } 501 }
456 } 502 }
457 503
458 __flush_iotlb(domain); 504 ret = __flush_iotlb(domain);
459fail: 505fail:
460 spin_unlock_irqrestore(&msm_iommu_lock, flags); 506 spin_unlock_irqrestore(&msm_iommu_lock, flags);
461 return ret; 507 return ret;
@@ -490,9 +536,6 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
490 SET_CTX_TLBIALL(base, ctx, 0); 536 SET_CTX_TLBIALL(base, ctx, 0);
491 SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT); 537 SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT);
492 538
493 if (GET_FAULT(base, ctx))
494 goto fail;
495
496 par = GET_PAR(base, ctx); 539 par = GET_PAR(base, ctx);
497 540
498 /* We are dealing with a supersection */ 541 /* We are dealing with a supersection */
@@ -501,6 +544,9 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
501 else /* Upper 20 bits from PAR, lower 12 from VA */ 544 else /* Upper 20 bits from PAR, lower 12 from VA */
502 ret = (par & 0xFFFFF000) | (va & 0x00000FFF); 545 ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
503 546
547 if (GET_FAULT(base, ctx))
548 ret = 0;
549
504fail: 550fail:
505 spin_unlock_irqrestore(&msm_iommu_lock, flags); 551 spin_unlock_irqrestore(&msm_iommu_lock, flags);
506 return ret; 552 return ret;
@@ -543,8 +589,8 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
543{ 589{
544 struct msm_iommu_drvdata *drvdata = dev_id; 590 struct msm_iommu_drvdata *drvdata = dev_id;
545 void __iomem *base; 591 void __iomem *base;
546 unsigned int fsr = 0; 592 unsigned int fsr;
547 int ncb = 0, i = 0; 593 int ncb, i;
548 594
549 spin_lock(&msm_iommu_lock); 595 spin_lock(&msm_iommu_lock);
550 596
@@ -555,7 +601,6 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
555 601
556 base = drvdata->base; 602 base = drvdata->base;
557 603
558 pr_err("===== WOAH! =====\n");
559 pr_err("Unexpected IOMMU page fault!\n"); 604 pr_err("Unexpected IOMMU page fault!\n");
560 pr_err("base = %08x\n", (unsigned int) base); 605 pr_err("base = %08x\n", (unsigned int) base);
561 606
@@ -585,8 +630,47 @@ static struct iommu_ops msm_iommu_ops = {
585 .domain_has_cap = msm_iommu_domain_has_cap 630 .domain_has_cap = msm_iommu_domain_has_cap
586}; 631};
587 632
588static int msm_iommu_init(void) 633static int __init get_tex_class(int icp, int ocp, int mt, int nos)
634{
635 int i = 0;
636 unsigned int prrr = 0;
637 unsigned int nmrr = 0;
638 int c_icp, c_ocp, c_mt, c_nos;
639
640 RCP15_PRRR(prrr);
641 RCP15_NMRR(nmrr);
642
643 for (i = 0; i < NUM_TEX_CLASS; i++) {
644 c_nos = PRRR_NOS(prrr, i);
645 c_mt = PRRR_MT(prrr, i);
646 c_icp = NMRR_ICP(nmrr, i);
647 c_ocp = NMRR_OCP(nmrr, i);
648
649 if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
650 return i;
651 }
652
653 return -ENODEV;
654}
655
656static void __init setup_iommu_tex_classes(void)
657{
658 msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
659 get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
660
661 msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
662 get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
663
664 msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
665 get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
666
667 msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
668 get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
669}
670
671static int __init msm_iommu_init(void)
589{ 672{
673 setup_iommu_tex_classes();
590 register_iommu(&msm_iommu_ops); 674 register_iommu(&msm_iommu_ops);
591 return 0; 675 return 0;
592} 676}
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 9019cee2907b..b83c73b41fd1 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -346,7 +346,7 @@ static struct platform_driver msm_iommu_ctx_driver = {
346 .remove = msm_iommu_ctx_remove, 346 .remove = msm_iommu_ctx_remove,
347}; 347};
348 348
349static int msm_iommu_driver_init(void) 349static int __init msm_iommu_driver_init(void)
350{ 350{
351 int ret; 351 int ret;
352 ret = platform_driver_register(&msm_iommu_driver); 352 ret = platform_driver_register(&msm_iommu_driver);
@@ -365,7 +365,7 @@ error:
365 return ret; 365 return ret;
366} 366}
367 367
368static void msm_iommu_driver_exit(void) 368static void __exit msm_iommu_driver_exit(void)
369{ 369{
370 platform_driver_unregister(&msm_iommu_ctx_driver); 370 platform_driver_unregister(&msm_iommu_ctx_driver);
371 platform_driver_unregister(&msm_iommu_driver); 371 platform_driver_unregister(&msm_iommu_driver);
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
index b0794524ba6e..152eefda3ce6 100644
--- a/arch/arm/mach-msm/sirc.c
+++ b/arch/arm/mach-msm/sirc.c
@@ -40,9 +40,6 @@ static struct sirc_cascade_regs sirc_reg_table[] = {
40 } 40 }
41}; 41};
42 42
43static unsigned int save_type;
44static unsigned int save_polarity;
45
46/* Mask off the given interrupt. Keep the int_enable mask in sync with 43/* Mask off the given interrupt. Keep the int_enable mask in sync with
47 the enable reg, so it can be restored after power collapse. */ 44 the enable reg, so it can be restored after power collapse. */
48static void sirc_irq_mask(unsigned int irq) 45static void sirc_irq_mask(unsigned int irq)
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index f07dc7c738f0..657be73297db 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -14,6 +14,8 @@
14 * 14 *
15 */ 15 */
16 16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
17#include <linux/platform_device.h> 19#include <linux/platform_device.h>
18#include <linux/module.h> 20#include <linux/module.h>
19#include <linux/fs.h> 21#include <linux/fs.h>
@@ -89,7 +91,7 @@ static void smd_diag(void)
89 x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); 91 x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
90 if (x != 0) { 92 if (x != 0) {
91 x[SZ_DIAG_ERR_MSG - 1] = 0; 93 x[SZ_DIAG_ERR_MSG - 1] = 0;
92 pr_info("smem: DIAG '%s'\n", x); 94 pr_debug("DIAG '%s'\n", x);
93 } 95 }
94} 96}
95 97
@@ -312,7 +314,7 @@ static void smd_state_change(struct smd_channel *ch,
312{ 314{
313 ch->last_state = next; 315 ch->last_state = next;
314 316
315 pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next); 317 pr_debug("ch %d %d -> %d\n", ch->n, last, next);
316 318
317 switch (next) { 319 switch (next) {
318 case SMD_SS_OPENING: 320 case SMD_SS_OPENING:
@@ -601,7 +603,7 @@ static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
601 ch->pdev.name = ch->name; 603 ch->pdev.name = ch->name;
602 ch->pdev.id = -1; 604 ch->pdev.id = -1;
603 605
604 pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n", 606 pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
605 ch->n, ch->fifo_size, ch->name); 607 ch->n, ch->fifo_size, ch->name);
606 608
607 mutex_lock(&smd_creation_mutex); 609 mutex_lock(&smd_creation_mutex);
@@ -621,7 +623,7 @@ static void smd_channel_probe_worker(struct work_struct *work)
621 623
622 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); 624 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
623 if (!shared) { 625 if (!shared) {
624 pr_err("smd: cannot find allocation table\n"); 626 pr_err("cannot find allocation table\n");
625 return; 627 return;
626 } 628 }
627 for (n = 0; n < 64; n++) { 629 for (n = 0; n < 64; n++) {
@@ -725,8 +727,6 @@ int smd_close(smd_channel_t *ch)
725{ 727{
726 unsigned long flags; 728 unsigned long flags;
727 729
728 pr_info("smd_close(%p)\n", ch);
729
730 if (ch == 0) 730 if (ch == 0)
731 return -1; 731 return -1;
732 732
@@ -939,7 +939,6 @@ int smsm_set_sleep_duration(uint32_t delay)
939int smd_core_init(void) 939int smd_core_init(void)
940{ 940{
941 int r; 941 int r;
942 pr_info("smd_core_init()\n");
943 942
944 /* wait for essential items to be initialized */ 943 /* wait for essential items to be initialized */
945 for (;;) { 944 for (;;) {
@@ -992,15 +991,11 @@ int smd_core_init(void)
992 smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0); 991 smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
993#endif 992#endif
994 993
995 pr_info("smd_core_init() done\n");
996
997 return 0; 994 return 0;
998} 995}
999 996
1000static int __devinit msm_smd_probe(struct platform_device *pdev) 997static int __devinit msm_smd_probe(struct platform_device *pdev)
1001{ 998{
1002 pr_info("smd_init()\n");
1003
1004 /* 999 /*
1005 * If we haven't waited for the ARM9 to boot up till now, 1000 * If we haven't waited for the ARM9 to boot up till now,
1006 * then we need to wait here. Otherwise this should just 1001 * then we need to wait here. Otherwise this should just
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index f91c3b7bc655..8736afff82f3 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -270,8 +270,10 @@ void smsm_print_sleep_info(void)
270{ 270{
271 unsigned long flags; 271 unsigned long flags;
272 uint32_t *ptr; 272 uint32_t *ptr;
273#ifndef CONFIG_ARCH_MSM_SCORPION
273 struct tramp_gpio_smem *gpio; 274 struct tramp_gpio_smem *gpio;
274 struct smsm_interrupt_info *int_info; 275 struct smsm_interrupt_info *int_info;
276#endif
275 277
276 278
277 spin_lock_irqsave(&smem_lock, flags); 279 spin_lock_irqsave(&smem_lock, flags);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 1290d14c5839..5decfd0bd61d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -44,6 +44,7 @@
44#include <mach/mmc.h> 44#include <mach/mmc.h>
45#include <mach/msm_iomap.h> 45#include <mach/msm_iomap.h>
46#include <mach/dma.h> 46#include <mach/dma.h>
47#include <mach/clk.h>
47 48
48#include "msm_sdcc.h" 49#include "msm_sdcc.h"
49 50
@@ -126,6 +127,40 @@ static void
126msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, 127msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
127 u32 c); 128 u32 c);
128 129
130static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
131{
132 u32 mci_clk = 0;
133 u32 mci_mask0 = 0;
134 int ret = 0;
135
136 /* Save the controller state */
137 mci_clk = readl(host->base + MMCICLOCK);
138 mci_mask0 = readl(host->base + MMCIMASK0);
139
140 /* Reset the controller */
141 ret = clk_reset(host->clk, CLK_RESET_ASSERT);
142 if (ret)
143 pr_err("%s: Clock assert failed at %u Hz with err %d\n",
144 mmc_hostname(host->mmc), host->clk_rate, ret);
145
146 ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
147 if (ret)
148 pr_err("%s: Clock deassert failed at %u Hz with err %d\n",
149 mmc_hostname(host->mmc), host->clk_rate, ret);
150
151 pr_info("%s: Controller has been re-initialiazed\n",
152 mmc_hostname(host->mmc));
153
154 /* Restore the contoller state */
155 writel(host->pwr, host->base + MMCIPOWER);
156 writel(mci_clk, host->base + MMCICLOCK);
157 writel(mci_mask0, host->base + MMCIMASK0);
158 ret = clk_set_rate(host->clk, host->clk_rate);
159 if (ret)
160 pr_err("%s: Failed to set clk rate %u Hz (%d)\n",
161 mmc_hostname(host->mmc), host->clk_rate, ret);
162}
163
129static void 164static void
130msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) 165msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
131{ 166{
@@ -155,7 +190,7 @@ static void
155msmsdcc_stop_data(struct msmsdcc_host *host) 190msmsdcc_stop_data(struct msmsdcc_host *host)
156{ 191{
157 host->curr.data = NULL; 192 host->curr.data = NULL;
158 host->curr.got_dataend = host->curr.got_datablkend = 0; 193 host->curr.got_dataend = 0;
159} 194}
160 195
161uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) 196uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
@@ -189,42 +224,42 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
189} 224}
190 225
191static void 226static void
192msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, 227msmsdcc_dma_complete_tlet(unsigned long data)
193 unsigned int result,
194 struct msm_dmov_errdata *err)
195{ 228{
196 struct msmsdcc_dma_data *dma_data = 229 struct msmsdcc_host *host = (struct msmsdcc_host *)data;
197 container_of(cmd, struct msmsdcc_dma_data, hdr);
198 struct msmsdcc_host *host = dma_data->host;
199 unsigned long flags; 230 unsigned long flags;
200 struct mmc_request *mrq; 231 struct mmc_request *mrq;
232 struct msm_dmov_errdata err;
201 233
202 spin_lock_irqsave(&host->lock, flags); 234 spin_lock_irqsave(&host->lock, flags);
203 host->dma.active = 0; 235 host->dma.active = 0;
204 236
237 err = host->dma.err;
205 mrq = host->curr.mrq; 238 mrq = host->curr.mrq;
206 BUG_ON(!mrq); 239 BUG_ON(!mrq);
207 WARN_ON(!mrq->data); 240 WARN_ON(!mrq->data);
208 241
209 if (!(result & DMOV_RSLT_VALID)) { 242 if (!(host->dma.result & DMOV_RSLT_VALID)) {
210 pr_err("msmsdcc: Invalid DataMover result\n"); 243 pr_err("msmsdcc: Invalid DataMover result\n");
211 goto out; 244 goto out;
212 } 245 }
213 246
214 if (result & DMOV_RSLT_DONE) { 247 if (host->dma.result & DMOV_RSLT_DONE) {
215 host->curr.data_xfered = host->curr.xfer_size; 248 host->curr.data_xfered = host->curr.xfer_size;
216 } else { 249 } else {
217 /* Error or flush */ 250 /* Error or flush */
218 if (result & DMOV_RSLT_ERROR) 251 if (host->dma.result & DMOV_RSLT_ERROR)
219 pr_err("%s: DMA error (0x%.8x)\n", 252 pr_err("%s: DMA error (0x%.8x)\n",
220 mmc_hostname(host->mmc), result); 253 mmc_hostname(host->mmc), host->dma.result);
221 if (result & DMOV_RSLT_FLUSH) 254 if (host->dma.result & DMOV_RSLT_FLUSH)
222 pr_err("%s: DMA channel flushed (0x%.8x)\n", 255 pr_err("%s: DMA channel flushed (0x%.8x)\n",
223 mmc_hostname(host->mmc), result); 256 mmc_hostname(host->mmc), host->dma.result);
224 if (err) 257
225 pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", 258 pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n",
226 err->flush[0], err->flush[1], err->flush[2], 259 err.flush[0], err.flush[1], err.flush[2],
227 err->flush[3], err->flush[4], err->flush[5]); 260 err.flush[3], err.flush[4], err.flush[5]);
261
262 msmsdcc_reset_and_restore(host);
228 if (!mrq->data->error) 263 if (!mrq->data->error)
229 mrq->data->error = -EIO; 264 mrq->data->error = -EIO;
230 } 265 }
@@ -242,8 +277,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
242 host->dma.sg = NULL; 277 host->dma.sg = NULL;
243 host->dma.busy = 0; 278 host->dma.busy = 0;
244 279
245 if ((host->curr.got_dataend && host->curr.got_datablkend) 280 if (host->curr.got_dataend || mrq->data->error) {
246 || mrq->data->error) {
247 281
248 /* 282 /*
249 * If we've already gotten our DATAEND / DATABLKEND 283 * If we've already gotten our DATAEND / DATABLKEND
@@ -273,6 +307,22 @@ out:
273 return; 307 return;
274} 308}
275 309
310static void
311msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
312 unsigned int result,
313 struct msm_dmov_errdata *err)
314{
315 struct msmsdcc_dma_data *dma_data =
316 container_of(cmd, struct msmsdcc_dma_data, hdr);
317 struct msmsdcc_host *host = dma_data->host;
318
319 dma_data->result = result;
320 if (err)
321 memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata));
322
323 tasklet_schedule(&host->dma_tlet);
324}
325
276static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) 326static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data)
277{ 327{
278 if (host->dma.channel == -1) 328 if (host->dma.channel == -1)
@@ -424,6 +474,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
424 (cmd->opcode == 53)) 474 (cmd->opcode == 53))
425 *c |= MCI_CSPM_DATCMD; 475 *c |= MCI_CSPM_DATCMD;
426 476
477 if (host->prog_scan && (cmd->opcode == 12)) {
478 *c |= MCI_CPSM_PROGENA;
479 host->prog_enable = true;
480 }
481
427 if (cmd == cmd->mrq->stop) 482 if (cmd == cmd->mrq->stop)
428 *c |= MCI_CSPM_MCIABORT; 483 *c |= MCI_CSPM_MCIABORT;
429 484
@@ -450,7 +505,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
450 host->curr.xfer_remain = host->curr.xfer_size; 505 host->curr.xfer_remain = host->curr.xfer_size;
451 host->curr.data_xfered = 0; 506 host->curr.data_xfered = 0;
452 host->curr.got_dataend = 0; 507 host->curr.got_dataend = 0;
453 host->curr.got_datablkend = 0;
454 508
455 memset(&host->pio, 0, sizeof(host->pio)); 509 memset(&host->pio, 0, sizeof(host->pio));
456 510
@@ -494,6 +548,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
494 host->cmd_c = c; 548 host->cmd_c = c;
495 } 549 }
496 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); 550 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
551 if (data->flags & MMC_DATA_WRITE)
552 host->prog_scan = true;
497 } else { 553 } else {
498 msmsdcc_writel(host, timeout, MMCIDATATIMER); 554 msmsdcc_writel(host, timeout, MMCIDATATIMER);
499 555
@@ -555,6 +611,9 @@ msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain)
555 uint32_t *ptr = (uint32_t *) buffer; 611 uint32_t *ptr = (uint32_t *) buffer;
556 int count = 0; 612 int count = 0;
557 613
614 if (remain % 4)
615 remain = ((remain >> 2) + 1) << 2;
616
558 while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) { 617 while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) {
559 *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE)); 618 *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE));
560 ptr++; 619 ptr++;
@@ -575,13 +634,14 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer,
575 char *ptr = buffer; 634 char *ptr = buffer;
576 635
577 do { 636 do {
578 unsigned int count, maxcnt; 637 unsigned int count, maxcnt, sz;
579 638
580 maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : 639 maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE :
581 MCI_FIFOHALFSIZE; 640 MCI_FIFOHALFSIZE;
582 count = min(remain, maxcnt); 641 count = min(remain, maxcnt);
583 642
584 writesl(base + MMCIFIFO, ptr, count >> 2); 643 sz = count % 4 ? (count >> 2) + 1 : (count >> 2);
644 writesl(base + MMCIFIFO, ptr, sz);
585 ptr += count; 645 ptr += count;
586 remain -= count; 646 remain -= count;
587 647
@@ -702,10 +762,26 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
702 msm_dmov_stop_cmd(host->dma.channel, 762 msm_dmov_stop_cmd(host->dma.channel,
703 &host->dma.hdr, 0); 763 &host->dma.hdr, 0);
704 else if (host->curr.data) { /* Non DMA */ 764 else if (host->curr.data) { /* Non DMA */
765 msmsdcc_reset_and_restore(host);
705 msmsdcc_stop_data(host); 766 msmsdcc_stop_data(host);
706 msmsdcc_request_end(host, cmd->mrq); 767 msmsdcc_request_end(host, cmd->mrq);
707 } else /* host->data == NULL */ 768 } else { /* host->data == NULL */
708 msmsdcc_request_end(host, cmd->mrq); 769 if (!cmd->error && host->prog_enable) {
770 if (status & MCI_PROGDONE) {
771 host->prog_scan = false;
772 host->prog_enable = false;
773 msmsdcc_request_end(host, cmd->mrq);
774 } else {
775 host->curr.cmd = cmd;
776 }
777 } else {
778 if (host->prog_enable) {
779 host->prog_scan = false;
780 host->prog_enable = false;
781 }
782 msmsdcc_request_end(host, cmd->mrq);
783 }
784 }
709 } else if (cmd->data) 785 } else if (cmd->data)
710 if (!(cmd->data->flags & MMC_DATA_READ)) 786 if (!(cmd->data->flags & MMC_DATA_READ))
711 msmsdcc_start_data(host, cmd->data, 787 msmsdcc_start_data(host, cmd->data,
@@ -719,7 +795,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
719 struct mmc_data *data = host->curr.data; 795 struct mmc_data *data = host->curr.data;
720 796
721 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | 797 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
722 MCI_CMDTIMEOUT) && host->curr.cmd) { 798 MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
723 msmsdcc_do_cmdirq(host, status); 799 msmsdcc_do_cmdirq(host, status);
724 } 800 }
725 801
@@ -735,6 +811,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
735 msm_dmov_stop_cmd(host->dma.channel, 811 msm_dmov_stop_cmd(host->dma.channel,
736 &host->dma.hdr, 0); 812 &host->dma.hdr, 0);
737 else { 813 else {
814 msmsdcc_reset_and_restore(host);
738 if (host->curr.data) 815 if (host->curr.data)
739 msmsdcc_stop_data(host); 816 msmsdcc_stop_data(host);
740 if (!data->stop) 817 if (!data->stop)
@@ -748,14 +825,10 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
748 if (!host->curr.got_dataend && (status & MCI_DATAEND)) 825 if (!host->curr.got_dataend && (status & MCI_DATAEND))
749 host->curr.got_dataend = 1; 826 host->curr.got_dataend = 1;
750 827
751 if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND))
752 host->curr.got_datablkend = 1;
753
754 /* 828 /*
755 * If DMA is still in progress, we complete via the completion handler 829 * If DMA is still in progress, we complete via the completion handler
756 */ 830 */
757 if (host->curr.got_dataend && host->curr.got_datablkend && 831 if (host->curr.got_dataend && !host->dma.busy) {
758 !host->dma.busy) {
759 /* 832 /*
760 * There appears to be an issue in the controller where 833 * There appears to be an issue in the controller where
761 * if you request a small block transfer (< fifo size), 834 * if you request a small block transfer (< fifo size),
@@ -792,8 +865,7 @@ msmsdcc_irq(int irq, void *dev_id)
792 865
793 do { 866 do {
794 status = msmsdcc_readl(host, MMCISTATUS); 867 status = msmsdcc_readl(host, MMCISTATUS);
795 status &= (msmsdcc_readl(host, MMCIMASK0) | 868 status &= msmsdcc_readl(host, MMCIMASK0);
796 MCI_DATABLOCKENDMASK);
797 msmsdcc_writel(host, status, MMCICLEAR); 869 msmsdcc_writel(host, status, MMCICLEAR);
798 870
799 if (status & MCI_SDIOINTR) 871 if (status & MCI_SDIOINTR)
@@ -1118,6 +1190,9 @@ msmsdcc_probe(struct platform_device *pdev)
1118 host->dmares = dmares; 1190 host->dmares = dmares;
1119 spin_lock_init(&host->lock); 1191 spin_lock_init(&host->lock);
1120 1192
1193 tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet,
1194 (unsigned long)host);
1195
1121 /* 1196 /*
1122 * Setup DMA 1197 * Setup DMA
1123 */ 1198 */
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ff2b0f74f6f4..939557af266d 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -138,7 +138,7 @@
138#define MCI_IRQENABLE \ 138#define MCI_IRQENABLE \
139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ 139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ 140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK) 141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
142 142
143/* 143/*
144 * The size of the FIFO in bytes. 144 * The size of the FIFO in bytes.
@@ -172,6 +172,8 @@ struct msmsdcc_dma_data {
172 struct msmsdcc_host *host; 172 struct msmsdcc_host *host;
173 int busy; /* Set if DM is busy */ 173 int busy; /* Set if DM is busy */
174 int active; 174 int active;
175 unsigned int result;
176 struct msm_dmov_errdata err;
175}; 177};
176 178
177struct msmsdcc_pio_data { 179struct msmsdcc_pio_data {
@@ -188,7 +190,6 @@ struct msmsdcc_curr_req {
188 unsigned int xfer_remain; /* Bytes remaining to send */ 190 unsigned int xfer_remain; /* Bytes remaining to send */
189 unsigned int data_xfered; /* Bytes acked by BLKEND irq */ 191 unsigned int data_xfered; /* Bytes acked by BLKEND irq */
190 int got_dataend; 192 int got_dataend;
191 int got_datablkend;
192 int user_pages; 193 int user_pages;
193}; 194};
194 195
@@ -235,6 +236,7 @@ struct msmsdcc_host {
235 int cmdpoll; 236 int cmdpoll;
236 struct msmsdcc_stats stats; 237 struct msmsdcc_stats stats;
237 238
239 struct tasklet_struct dma_tlet;
238 /* Command parameters */ 240 /* Command parameters */
239 unsigned int cmd_timeout; 241 unsigned int cmd_timeout;
240 unsigned int cmd_pio_irqmask; 242 unsigned int cmd_pio_irqmask;
@@ -242,6 +244,8 @@ struct msmsdcc_host {
242 struct mmc_command *cmd_cmd; 244 struct mmc_command *cmd_cmd;
243 u32 cmd_c; 245 u32 cmd_c;
244 246
247 bool prog_scan;
248 bool prog_enable;
245}; 249};
246 250
247#endif 251#endif
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c
index f8c816e7725d..8e43a7b69e64 100644
--- a/drivers/serial/msm_serial.c
+++ b/drivers/serial/msm_serial.c
@@ -686,7 +686,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
686 msm_port = UART_TO_MSM(port); 686 msm_port = UART_TO_MSM(port);
687 687
688 msm_port->clk = clk_get(&pdev->dev, "uart_clk"); 688 msm_port->clk = clk_get(&pdev->dev, "uart_clk");
689 if (unlikely(IS_ERR(msm_port->clk))) 689 if (IS_ERR(msm_port->clk))
690 return PTR_ERR(msm_port->clk); 690 return PTR_ERR(msm_port->clk);
691 port->uartclk = clk_get_rate(msm_port->clk); 691 port->uartclk = clk_get_rate(msm_port->clk);
692 printk(KERN_INFO "uartclk = %d\n", port->uartclk); 692 printk(KERN_INFO "uartclk = %d\n", port->uartclk);