aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2008-12-10 20:37:16 -0500
committerTony Lindgren <tony@atomide.com>2008-12-10 20:37:16 -0500
commitd88746652b4d133284d1fdd05b5e999e8f44c998 (patch)
tree2a6cfd6fe175a18eb4b4f600e0a79444259c9a5d
parent652bcd8f72cc0cdf4499ce7d73990514e5e3e4b9 (diff)
omap mmc: Add better MMC low-level init
This will simplify the MMC low-level init, and make it more flexible to add support for a newer MMC controller in the following patches. The patch rearranges platform data and gets rid of slot vs controller confusion in the old data structures. Also fix device id numbering in the clock code. Some code snippets are based on an earlier patch by Russell King <linux@arm.linux.org.uk>. Cc: Pierre Ossman <drzeus-mmc@drzeus.cx> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap1/board-h2-mmc.c63
-rw-r--r--arch/arm/mach-omap1/board-h2.c15
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c50
-rw-r--r--arch/arm/mach-omap1/board-innovator.c50
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c74
-rw-r--r--arch/arm/mach-omap1/board-sx1-mmc.c31
-rw-r--r--arch/arm/mach-omap1/clock.h3
-rw-r--r--arch/arm/mach-omap1/devices.c90
-rw-r--r--arch/arm/mach-omap2/clock24xx.h9
-rw-r--r--arch/arm/mach-omap2/clock34xx.h10
-rw-r--r--arch/arm/mach-omap2/devices.c83
-rw-r--r--arch/arm/plat-omap/devices.c225
-rw-r--r--arch/arm/plat-omap/include/mach/board-h2.h6
-rw-r--r--arch/arm/plat-omap/include/mach/board.h22
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h74
-rw-r--r--drivers/mmc/host/omap.c7
16 files changed, 529 insertions, 283 deletions
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index 504ae881360f..409fa56d0a87 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -12,13 +12,74 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/platform_device.h>
16
17#include <linux/i2c/tps65010.h>
18
15#include <mach/mmc.h> 19#include <mach/mmc.h>
16#include <mach/gpio.h> 20#include <mach/gpio.h>
17 21
22#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
23
24static int mmc_set_power(struct device *dev, int slot, int power_on,
25 int vdd)
26{
27 if (power_on)
28 gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
29 else
30 gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
31
32 return 0;
33}
34
35static int mmc_late_init(struct device *dev)
36{
37 int ret;
38
39 ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
40 if (ret < 0)
41 return ret;
42
43 gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
44
45 return ret;
46}
47
48static void mmc_shutdown(struct device *dev)
49{
50 gpio_free(H2_TPS_GPIO_MMC_PWR_EN);
51}
52
53/*
54 * H2 could use the following functions tested:
55 * - mmc_get_cover_state that uses OMAP_MPUIO(1)
56 * - mmc_get_wp that uses OMAP_MPUIO(3)
57 */
58static struct omap_mmc_platform_data mmc1_data = {
59 .nr_slots = 1,
60 .init = mmc_late_init,
61 .shutdown = mmc_shutdown,
62 .dma_mask = 0xffffffff,
63 .slots[0] = {
64 .set_power = mmc_set_power,
65 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
66 MMC_VDD_32_33 | MMC_VDD_33_34,
67 .name = "mmcblk",
68 },
69};
70
71static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
72
18void __init h2_mmc_init(void) 73void __init h2_mmc_init(void)
19{ 74{
75 mmc_data[0] = &mmc1_data;
76 omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
20} 77}
21 78
22void h2_mmc_slot_cover_handler(void *arg, int state) 79#else
80
81void __init h2_mmc_init(void)
23{ 82{
24} 83}
84
85#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 125d8e21dcea..b240c5f861da 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -345,10 +345,25 @@ static void __init h2_init_smc91x(void)
345 } 345 }
346} 346}
347 347
348static int tps_setup(struct i2c_client *client, void *context)
349{
350 tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
351 TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
352
353 return 0;
354}
355
356static struct tps65010_board tps_board = {
357 .base = H2_TPS_GPIO_BASE,
358 .outmask = 0x0f,
359 .setup = tps_setup,
360};
361
348static struct i2c_board_info __initdata h2_i2c_board_info[] = { 362static struct i2c_board_info __initdata h2_i2c_board_info[] = {
349 { 363 {
350 I2C_BOARD_INFO("tps65010", 0x48), 364 I2C_BOARD_INFO("tps65010", 0x48),
351 .irq = OMAP_GPIO_IRQ(58), 365 .irq = OMAP_GPIO_IRQ(58),
366 .platform_data = &tps_board,
352 }, { 367 }, {
353 I2C_BOARD_INFO("isp1301_omap", 0x2d), 368 I2C_BOARD_INFO("isp1301_omap", 0x2d),
354 .irq = OMAP_GPIO_IRQ(2), 369 .irq = OMAP_GPIO_IRQ(2),
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index 0baba1c4d12d..fdfe793d56f2 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -12,13 +12,61 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/platform_device.h>
16
17#include <linux/i2c/tps65010.h>
18
15#include <mach/mmc.h> 19#include <mach/mmc.h>
16#include <mach/gpio.h> 20#include <mach/gpio.h>
17 21
22#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
23
24static int mmc_set_power(struct device *dev, int slot, int power_on,
25 int vdd)
26{
27 if (power_on)
28 gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
29 else
30 gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
31
32 return 0;
33}
34
35/*
36 * H3 could use the following functions tested:
37 * - mmc_get_cover_state that uses OMAP_MPUIO(1)
38 * - mmc_get_wp that maybe uses OMAP_MPUIO(3)
39 */
40static struct omap_mmc_platform_data mmc1_data = {
41 .nr_slots = 1,
42 .dma_mask = 0xffffffff,
43 .slots[0] = {
44 .set_power = mmc_set_power,
45 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
46 MMC_VDD_32_33 | MMC_VDD_33_34,
47 .name = "mmcblk",
48 },
49};
50
51static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
52
18void __init h3_mmc_init(void) 53void __init h3_mmc_init(void)
19{ 54{
55 int ret;
56
57 ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power");
58 if (ret < 0)
59 return;
60 gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
61
62 mmc_data[0] = &mmc1_data;
63 omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
20} 64}
21 65
22void h3_mmc_slot_cover_handler(void *arg, int state) 66#else
67
68void __init h3_mmc_init(void)
23{ 69{
24} 70}
71
72#endif
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index a21e365a7a87..8ffb06fc0f08 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -39,6 +39,7 @@
39#include <mach/common.h> 39#include <mach/common.h>
40#include <mach/mcbsp.h> 40#include <mach/mcbsp.h>
41#include <mach/omap-alsa.h> 41#include <mach/omap-alsa.h>
42#include <mach/mmc.h>
42 43
43static int innovator_keymap[] = { 44static int innovator_keymap[] = {
44 KEY(0, 0, KEY_F1), 45 KEY(0, 0, KEY_F1),
@@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = {
360}; 361};
361#endif 362#endif
362 363
363static struct omap_mmc_config innovator_mmc_config __initdata = { 364#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
364 .mmc [0] = { 365
365 .enabled = 1, 366static int mmc_set_power(struct device *dev, int slot, int power_on,
366 .wire4 = 1, 367 int vdd)
367 .wp_pin = OMAP_MPUIO(3), 368{
368 .power_pin = -1, /* FPGA F3 UIO42 */ 369 if (power_on)
369 .switch_pin = -1, /* FPGA F4 UIO43 */ 370 fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
371 OMAP1510_FPGA_POWER);
372 else
373 fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
374 OMAP1510_FPGA_POWER);
375
376 return 0;
377}
378
379/*
380 * Innovator could use the following functions tested:
381 * - mmc_get_wp that uses OMAP_MPUIO(3)
382 * - mmc_get_cover_state that uses FPGA F4 UIO43
383 */
384static struct omap_mmc_platform_data mmc1_data = {
385 .nr_slots = 1,
386 .slots[0] = {
387 .set_power = mmc_set_power,
388 .wire4 = 1,
389 .name = "mmcblk",
370 }, 390 },
371}; 391};
372 392
393static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
394
395void __init innovator_mmc_init(void)
396{
397 mmc_data[0] = &mmc1_data;
398 omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
399}
400
401#else
402static inline void innovator_mmc_init(void)
403{
404}
405#endif
406
373static struct omap_uart_config innovator_uart_config __initdata = { 407static struct omap_uart_config innovator_uart_config __initdata = {
374 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 408 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
375}; 409};
@@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
377static struct omap_board_config_kernel innovator_config[] = { 411static struct omap_board_config_kernel innovator_config[] = {
378 { OMAP_TAG_USB, NULL }, 412 { OMAP_TAG_USB, NULL },
379 { OMAP_TAG_LCD, NULL }, 413 { OMAP_TAG_LCD, NULL },
380 { OMAP_TAG_MMC, &innovator_mmc_config },
381 { OMAP_TAG_UART, &innovator_uart_config }, 414 { OMAP_TAG_UART, &innovator_uart_config },
382}; 415};
383 416
@@ -412,6 +445,7 @@ static void __init innovator_init(void)
412 omap_board_config_size = ARRAY_SIZE(innovator_config); 445 omap_board_config_size = ARRAY_SIZE(innovator_config);
413 omap_serial_init(); 446 omap_serial_init();
414 omap_register_i2c_bus(1, 100, NULL, 0); 447 omap_register_i2c_bus(1, 100, NULL, 0);
448 innovator_mmc_init();
415} 449}
416 450
417static void __init innovator_map_io(void) 451static void __init innovator_map_io(void)
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index b26782471e59..4970c402a594 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -35,6 +35,7 @@
35#include <mach/aic23.h> 35#include <mach/aic23.h>
36#include <mach/omapfb.h> 36#include <mach/omapfb.h>
37#include <mach/lcd_mipid.h> 37#include <mach/lcd_mipid.h>
38#include <mach/mmc.h>
38 39
39#define ADS7846_PENDOWN_GPIO 15 40#define ADS7846_PENDOWN_GPIO 15
40 41
@@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
173 .pins[0] = 6, 174 .pins[0] = 6,
174}; 175};
175 176
176static struct omap_mmc_config nokia770_mmc_config __initdata = { 177#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
177 .mmc[0] = { 178
178 .enabled = 0, 179#define NOKIA770_GPIO_MMC_POWER 41
179 .wire4 = 0, 180#define NOKIA770_GPIO_MMC_SWITCH 23
180 .wp_pin = -1, 181
181 .power_pin = -1, 182static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
182 .switch_pin = -1, 183 int vdd)
183 }, 184{
184 .mmc[1] = { 185 if (power_on)
185 .enabled = 0, 186 gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
186 .wire4 = 0, 187 else
187 .wp_pin = -1, 188 gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
188 .power_pin = -1, 189
189 .switch_pin = -1, 190 return 0;
191}
192
193static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
194{
195 return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
196}
197
198static struct omap_mmc_platform_data nokia770_mmc2_data = {
199 .nr_slots = 1,
200 .dma_mask = 0xffffffff,
201 .slots[0] = {
202 .set_power = nokia770_mmc_set_power,
203 .get_cover_state = nokia770_mmc_get_cover_state,
204 .name = "mmcblk",
190 }, 205 },
191}; 206};
192 207
208static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
209
210static void __init nokia770_mmc_init(void)
211{
212 int ret;
213
214 ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
215 if (ret < 0)
216 return;
217 gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
218
219 ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
220 if (ret < 0) {
221 gpio_free(NOKIA770_GPIO_MMC_POWER);
222 return;
223 }
224 gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
225
226 /* Only the second MMC controller is used */
227 nokia770_mmc_data[1] = &nokia770_mmc2_data;
228 omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
229}
230
231#else
232static inline void nokia770_mmc_init(void)
233{
234}
235#endif
236
193static struct omap_board_config_kernel nokia770_config[] __initdata = { 237static struct omap_board_config_kernel nokia770_config[] __initdata = {
194 { OMAP_TAG_USB, NULL }, 238 { OMAP_TAG_USB, NULL },
195 { OMAP_TAG_MMC, &nokia770_mmc_config },
196}; 239};
197 240
198#if defined(CONFIG_OMAP_DSP) 241#if defined(CONFIG_OMAP_DSP)
@@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void)
335 omap_dsp_init(); 378 omap_dsp_init();
336 ads7846_dev_init(); 379 ads7846_dev_init();
337 mipid_dev_init(); 380 mipid_dev_init();
381 nokia770_mmc_init();
338} 382}
339 383
340static void __init omap_nokia770_map_io(void) 384static void __init omap_nokia770_map_io(void)
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 0ece109aee41..66a4d7d5255d 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -12,30 +12,20 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/platform_device.h>
16
15#include <mach/hardware.h> 17#include <mach/hardware.h>
16#include <mach/mmc.h> 18#include <mach/mmc.h>
17#include <mach/gpio.h> 19#include <mach/gpio.h>
18 20
19#ifdef CONFIG_MMC_OMAP 21#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
20static int slot_cover_open;
21static struct device *mmc_device;
22 22
23static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, 23static int mmc_set_power(struct device *dev, int slot, int power_on,
24 int vdd) 24 int vdd)
25{ 25{
26 int err; 26 int err;
27 u8 dat = 0; 27 u8 dat = 0;
28 28
29#ifdef CONFIG_MMC_DEBUG
30 dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
31 power_on ? "on" : "off", vdd);
32#endif
33
34 if (slot != 0) {
35 dev_err(dev, "No such slot %d\n", slot + 1);
36 return -ENODEV;
37 }
38
39 err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); 29 err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
40 if (err < 0) 30 if (err < 0)
41 return err; 31 return err;
@@ -48,19 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
48 return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); 38 return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
49} 39}
50 40
51static struct omap_mmc_platform_data sx1_mmc_data = { 41/* Cover switch is at OMAP_MPUIO(3) */
42static struct omap_mmc_platform_data mmc1_data = {
52 .nr_slots = 1, 43 .nr_slots = 1,
53 .slots[0] = { 44 .slots[0] = {
54 .set_power = sx1_mmc_set_power, 45 .set_power = mmc_set_power,
55 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | 46 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
56 MMC_VDD_32_33 | MMC_VDD_33_34, 47 MMC_VDD_32_33 | MMC_VDD_33_34,
57 .name = "mmcblk", 48 .name = "mmcblk",
58 }, 49 },
59}; 50};
60 51
52static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC];
53
61void __init sx1_mmc_init(void) 54void __init sx1_mmc_init(void)
62{ 55{
63 omap_set_mmc_info(1, &sx1_mmc_data); 56 mmc_data[0] = &mmc1_data;
57 omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
64} 58}
65 59
66#else 60#else
@@ -69,7 +63,4 @@ void __init sx1_mmc_init(void)
69{ 63{
70} 64}
71 65
72void sx1_mmc_slot_cover_handler(void *arg, int state)
73{
74}
75#endif 66#endif
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 5635b511ab6f..c1dcdf18d8dd 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -705,7 +705,6 @@ static struct clk bclk_16xx = {
705 705
706static struct clk mmc1_ck = { 706static struct clk mmc1_ck = {
707 .name = "mmc_ck", 707 .name = "mmc_ck",
708 .id = 1,
709 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 708 /* Functional clock is direct from ULPD, interface clock is ARMPER */
710 .parent = &armper_ck.clk, 709 .parent = &armper_ck.clk,
711 .rate = 48000000, 710 .rate = 48000000,
@@ -720,7 +719,7 @@ static struct clk mmc1_ck = {
720 719
721static struct clk mmc2_ck = { 720static struct clk mmc2_ck = {
722 .name = "mmc_ck", 721 .name = "mmc_ck",
723 .id = 2, 722 .id = 1,
724 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 723 /* Functional clock is direct from ULPD, interface clock is ARMPER */
725 .parent = &armper_ck.clk, 724 .parent = &armper_ck.clk,
726 .rate = 48000000, 725 .rate = 48000000,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index e382b438c64e..024dab13d4b4 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
22#include <mach/board.h> 22#include <mach/board.h>
23#include <mach/mux.h> 23#include <mach/mux.h>
24#include <mach/gpio.h> 24#include <mach/gpio.h>
25#include <mach/mmc.h>
25 26
26/*-------------------------------------------------------------------------*/ 27/*-------------------------------------------------------------------------*/
27 28
@@ -99,6 +100,95 @@ static inline void omap_init_mbox(void)
99static inline void omap_init_mbox(void) { } 100static inline void omap_init_mbox(void) { }
100#endif 101#endif
101 102
103/*-------------------------------------------------------------------------*/
104
105#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
106
107static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
108 int controller_nr)
109{
110 if (controller_nr == 0) {
111 omap_cfg_reg(MMC_CMD);
112 omap_cfg_reg(MMC_CLK);
113 omap_cfg_reg(MMC_DAT0);
114 if (cpu_is_omap1710()) {
115 omap_cfg_reg(M15_1710_MMC_CLKI);
116 omap_cfg_reg(P19_1710_MMC_CMDDIR);
117 omap_cfg_reg(P20_1710_MMC_DATDIR0);
118 }
119 if (mmc_controller->slots[0].wire4) {
120 omap_cfg_reg(MMC_DAT1);
121 /* NOTE: DAT2 can be on W10 (here) or M15 */
122 if (!mmc_controller->slots[0].nomux)
123 omap_cfg_reg(MMC_DAT2);
124 omap_cfg_reg(MMC_DAT3);
125 }
126 }
127
128 /* Block 2 is on newer chips, and has many pinout options */
129 if (cpu_is_omap16xx() && controller_nr == 1) {
130 if (!mmc_controller->slots[1].nomux) {
131 omap_cfg_reg(Y8_1610_MMC2_CMD);
132 omap_cfg_reg(Y10_1610_MMC2_CLK);
133 omap_cfg_reg(R18_1610_MMC2_CLKIN);
134 omap_cfg_reg(W8_1610_MMC2_DAT0);
135 if (mmc_controller->slots[1].wire4) {
136 omap_cfg_reg(V8_1610_MMC2_DAT1);
137 omap_cfg_reg(W15_1610_MMC2_DAT2);
138 omap_cfg_reg(R10_1610_MMC2_DAT3);
139 }
140
141 /* These are needed for the level shifter */
142 omap_cfg_reg(V9_1610_MMC2_CMDDIR);
143 omap_cfg_reg(V5_1610_MMC2_DATDIR0);
144 omap_cfg_reg(W19_1610_MMC2_DATDIR1);
145 }
146
147 /* Feedback clock must be set on OMAP-1710 MMC2 */
148 if (cpu_is_omap1710())
149 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
150 MOD_CONF_CTRL_1);
151 }
152}
153
154void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
155 int nr_controllers)
156{
157 int i;
158
159 for (i = 0; i < nr_controllers; i++) {
160 unsigned long base, size;
161 unsigned int irq = 0;
162
163 if (!mmc_data[i])
164 continue;
165
166 omap1_mmc_mux(mmc_data[i], i);
167
168 switch (i) {
169 case 0:
170 base = OMAP1_MMC1_BASE;
171 irq = INT_MMC;
172 break;
173 case 1:
174 if (!cpu_is_omap16xx())
175 return;
176 base = OMAP1_MMC2_BASE;
177 irq = INT_1610_MMC2;
178 break;
179 default:
180 continue;
181 }
182 size = OMAP1_MMC_SIZE;
183
184 omap_mmc_add(i, base, size, irq, mmc_data[i]);
185 };
186}
187
188#endif
189
190/*-------------------------------------------------------------------------*/
191
102#if defined(CONFIG_OMAP_STI) 192#if defined(CONFIG_OMAP_STI)
103 193
104#define OMAP1_STI_BASE 0xfffea000 194#define OMAP1_STI_BASE 0xfffea000
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index 242a19d86ccd..ff6cd14d254d 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -2522,7 +2522,6 @@ static struct clk usbhs_ick = {
2522 2522
2523static struct clk mmchs1_ick = { 2523static struct clk mmchs1_ick = {
2524 .name = "mmchs_ick", 2524 .name = "mmchs_ick",
2525 .id = 1,
2526 .parent = &l4_ck, 2525 .parent = &l4_ck,
2527 .flags = CLOCK_IN_OMAP243X, 2526 .flags = CLOCK_IN_OMAP243X,
2528 .clkdm_name = "core_l4_clkdm", 2527 .clkdm_name = "core_l4_clkdm",
@@ -2533,7 +2532,6 @@ static struct clk mmchs1_ick = {
2533 2532
2534static struct clk mmchs1_fck = { 2533static struct clk mmchs1_fck = {
2535 .name = "mmchs_fck", 2534 .name = "mmchs_fck",
2536 .id = 1,
2537 .parent = &func_96m_ck, 2535 .parent = &func_96m_ck,
2538 .flags = CLOCK_IN_OMAP243X, 2536 .flags = CLOCK_IN_OMAP243X,
2539 .clkdm_name = "core_l3_clkdm", 2537 .clkdm_name = "core_l3_clkdm",
@@ -2544,7 +2542,7 @@ static struct clk mmchs1_fck = {
2544 2542
2545static struct clk mmchs2_ick = { 2543static struct clk mmchs2_ick = {
2546 .name = "mmchs_ick", 2544 .name = "mmchs_ick",
2547 .id = 2, 2545 .id = 1,
2548 .parent = &l4_ck, 2546 .parent = &l4_ck,
2549 .flags = CLOCK_IN_OMAP243X, 2547 .flags = CLOCK_IN_OMAP243X,
2550 .clkdm_name = "core_l4_clkdm", 2548 .clkdm_name = "core_l4_clkdm",
@@ -2555,7 +2553,7 @@ static struct clk mmchs2_ick = {
2555 2553
2556static struct clk mmchs2_fck = { 2554static struct clk mmchs2_fck = {
2557 .name = "mmchs_fck", 2555 .name = "mmchs_fck",
2558 .id = 2, 2556 .id = 1,
2559 .parent = &func_96m_ck, 2557 .parent = &func_96m_ck,
2560 .flags = CLOCK_IN_OMAP243X, 2558 .flags = CLOCK_IN_OMAP243X,
2561 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), 2559 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
@@ -2595,7 +2593,6 @@ static struct clk mdm_intc_ick = {
2595 2593
2596static struct clk mmchsdb1_fck = { 2594static struct clk mmchsdb1_fck = {
2597 .name = "mmchsdb_fck", 2595 .name = "mmchsdb_fck",
2598 .id = 1,
2599 .parent = &func_32k_ck, 2596 .parent = &func_32k_ck,
2600 .flags = CLOCK_IN_OMAP243X, 2597 .flags = CLOCK_IN_OMAP243X,
2601 .clkdm_name = "core_l4_clkdm", 2598 .clkdm_name = "core_l4_clkdm",
@@ -2606,7 +2603,7 @@ static struct clk mmchsdb1_fck = {
2606 2603
2607static struct clk mmchsdb2_fck = { 2604static struct clk mmchsdb2_fck = {
2608 .name = "mmchsdb_fck", 2605 .name = "mmchsdb_fck",
2609 .id = 2, 2606 .id = 1,
2610 .parent = &func_32k_ck, 2607 .parent = &func_32k_ck,
2611 .flags = CLOCK_IN_OMAP243X, 2608 .flags = CLOCK_IN_OMAP243X,
2612 .clkdm_name = "core_l4_clkdm", 2609 .clkdm_name = "core_l4_clkdm",
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 7217a0824ec4..a826094d89b5 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -1374,7 +1374,7 @@ static struct clk core_96m_fck = {
1374 1374
1375static struct clk mmchs3_fck = { 1375static struct clk mmchs3_fck = {
1376 .name = "mmchs_fck", 1376 .name = "mmchs_fck",
1377 .id = 3, 1377 .id = 2,
1378 .parent = &core_96m_fck, 1378 .parent = &core_96m_fck,
1379 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1379 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1380 .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, 1380 .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
@@ -1385,7 +1385,7 @@ static struct clk mmchs3_fck = {
1385 1385
1386static struct clk mmchs2_fck = { 1386static struct clk mmchs2_fck = {
1387 .name = "mmchs_fck", 1387 .name = "mmchs_fck",
1388 .id = 2, 1388 .id = 1,
1389 .parent = &core_96m_fck, 1389 .parent = &core_96m_fck,
1390 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1390 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1391 .enable_bit = OMAP3430_EN_MMC2_SHIFT, 1391 .enable_bit = OMAP3430_EN_MMC2_SHIFT,
@@ -1406,7 +1406,6 @@ static struct clk mspro_fck = {
1406 1406
1407static struct clk mmchs1_fck = { 1407static struct clk mmchs1_fck = {
1408 .name = "mmchs_fck", 1408 .name = "mmchs_fck",
1409 .id = 1,
1410 .parent = &core_96m_fck, 1409 .parent = &core_96m_fck,
1411 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1410 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1412 .enable_bit = OMAP3430_EN_MMC1_SHIFT, 1411 .enable_bit = OMAP3430_EN_MMC1_SHIFT,
@@ -1722,7 +1721,7 @@ static struct clk usbtll_ick = {
1722 1721
1723static struct clk mmchs3_ick = { 1722static struct clk mmchs3_ick = {
1724 .name = "mmchs_ick", 1723 .name = "mmchs_ick",
1725 .id = 3, 1724 .id = 2,
1726 .parent = &core_l4_ick, 1725 .parent = &core_l4_ick,
1727 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), 1726 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
1728 .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, 1727 .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
@@ -1774,7 +1773,7 @@ static struct clk des2_ick = {
1774 1773
1775static struct clk mmchs2_ick = { 1774static struct clk mmchs2_ick = {
1776 .name = "mmchs_ick", 1775 .name = "mmchs_ick",
1777 .id = 2, 1776 .id = 1,
1778 .parent = &core_l4_ick, 1777 .parent = &core_l4_ick,
1779 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), 1778 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
1780 .enable_bit = OMAP3430_EN_MMC2_SHIFT, 1779 .enable_bit = OMAP3430_EN_MMC2_SHIFT,
@@ -1785,7 +1784,6 @@ static struct clk mmchs2_ick = {
1785 1784
1786static struct clk mmchs1_ick = { 1785static struct clk mmchs1_ick = {
1787 .name = "mmchs_ick", 1786 .name = "mmchs_ick",
1788 .id = 1,
1789 .parent = &core_l4_ick, 1787 .parent = &core_l4_ick,
1790 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), 1788 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
1791 .enable_bit = OMAP3430_EN_MMC1_SHIFT, 1789 .enable_bit = OMAP3430_EN_MMC1_SHIFT,
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 90af2ac469aa..8ccdfcf2942c 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -24,6 +24,7 @@
24#include <mach/mux.h> 24#include <mach/mux.h>
25#include <mach/gpio.h> 25#include <mach/gpio.h>
26#include <mach/eac.h> 26#include <mach/eac.h>
27#include <mach/mmc.h>
27 28
28#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) 29#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
29#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) 30#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
@@ -295,6 +296,88 @@ static void omap_init_sha1_md5(void)
295static inline void omap_init_sha1_md5(void) { } 296static inline void omap_init_sha1_md5(void) { }
296#endif 297#endif
297 298
299/*-------------------------------------------------------------------------*/
300
301#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
302 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
303
304static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
305 int controller_nr)
306{
307 if (cpu_is_omap2420() && controller_nr == 0) {
308 omap_cfg_reg(H18_24XX_MMC_CMD);
309 omap_cfg_reg(H15_24XX_MMC_CLKI);
310 omap_cfg_reg(G19_24XX_MMC_CLKO);
311 omap_cfg_reg(F20_24XX_MMC_DAT0);
312 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
313 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
314 if (mmc_controller->slots[0].wire4) {
315 omap_cfg_reg(H14_24XX_MMC_DAT1);
316 omap_cfg_reg(E19_24XX_MMC_DAT2);
317 omap_cfg_reg(D19_24XX_MMC_DAT3);
318 omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
319 omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
320 omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
321 }
322
323 /*
324 * Use internal loop-back in MMC/SDIO Module Input Clock
325 * selection
326 */
327 if (mmc_controller->slots[0].internal_clock) {
328 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
329 v |= (1 << 24);
330 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
331 }
332 }
333}
334
335void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
336 int nr_controllers)
337{
338 int i;
339
340 for (i = 0; i < nr_controllers; i++) {
341 unsigned long base, size;
342 unsigned int irq = 0;
343
344 if (!mmc_data[i])
345 continue;
346
347 omap2_mmc_mux(mmc_data[i], i);
348
349 switch (i) {
350 case 0:
351 base = OMAP2_MMC1_BASE;
352 irq = INT_24XX_MMC_IRQ;
353 break;
354 case 1:
355 base = OMAP2_MMC2_BASE;
356 irq = INT_24XX_MMC2_IRQ;
357 break;
358 case 2:
359 if (!cpu_is_omap34xx())
360 return;
361 base = OMAP3_MMC3_BASE;
362 irq = INT_34XX_MMC3_IRQ;
363 break;
364 default:
365 continue;
366 }
367
368 if (cpu_is_omap2420())
369 size = OMAP2420_MMC_SIZE;
370 else
371 size = HSMMC_SIZE;
372
373 omap_mmc_add(i, base, size, irq, mmc_data[i]);
374 };
375}
376
377#endif
378
379/*-------------------------------------------------------------------------*/
380
298#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) 381#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
299#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) 382#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
300#define OMAP_HDQ_BASE 0x480B2000 383#define OMAP_HDQ_BASE 0x480B2000
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 0cb2b22388e9..ac15c23fd5da 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -192,202 +192,48 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
192 192
193/*-------------------------------------------------------------------------*/ 193/*-------------------------------------------------------------------------*/
194 194
195#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ 195#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
196 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) 196 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
197 197
198#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 198#define OMAP_MMC_NR_RES 2
199#define OMAP_MMC1_BASE 0x4809c000
200#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc)
201#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
202 199
203#define OMAP_MMC2_BASE 0x480b4000 200/*
204#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc) 201 * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
205#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ 202 */
206 203int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
207#else 204 unsigned int irq, struct omap_mmc_platform_data *data)
208
209#define OMAP_MMC1_BASE 0xfffb7800
210#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f)
211#define OMAP_MMC1_INT INT_MMC
212
213#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
214#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f)
215#define OMAP_MMC2_INT INT_1610_MMC2
216
217#endif
218
219static struct omap_mmc_platform_data mmc1_data;
220
221static u64 mmc1_dmamask = 0xffffffff;
222
223static struct resource mmc1_resources[] = {
224 {
225 .start = OMAP_MMC1_BASE,
226 .end = OMAP_MMC1_END,
227 .flags = IORESOURCE_MEM,
228 },
229 {
230 .start = OMAP_MMC1_INT,
231 .flags = IORESOURCE_IRQ,
232 },
233};
234
235static struct platform_device mmc_omap_device1 = {
236 .name = "mmci-omap",
237 .id = 1,
238 .dev = {
239 .dma_mask = &mmc1_dmamask,
240 .platform_data = &mmc1_data,
241 },
242 .num_resources = ARRAY_SIZE(mmc1_resources),
243 .resource = mmc1_resources,
244};
245
246#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
247 defined(CONFIG_ARCH_OMAP34XX)
248
249static struct omap_mmc_platform_data mmc2_data;
250
251static u64 mmc2_dmamask = 0xffffffff;
252
253static struct resource mmc2_resources[] = {
254 {
255 .start = OMAP_MMC2_BASE,
256 .end = OMAP_MMC2_END,
257 .flags = IORESOURCE_MEM,
258 },
259 {
260 .start = OMAP_MMC2_INT,
261 .flags = IORESOURCE_IRQ,
262 },
263};
264
265static struct platform_device mmc_omap_device2 = {
266 .name = "mmci-omap",
267 .id = 2,
268 .dev = {
269 .dma_mask = &mmc2_dmamask,
270 .platform_data = &mmc2_data,
271 },
272 .num_resources = ARRAY_SIZE(mmc2_resources),
273 .resource = mmc2_resources,
274};
275#endif
276
277static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
278{
279 if (cpu_is_omap2430() || cpu_is_omap34xx())
280 return;
281
282 if (mmc_conf->mmc[0].enabled) {
283 if (cpu_is_omap24xx()) {
284 omap_cfg_reg(H18_24XX_MMC_CMD);
285 omap_cfg_reg(H15_24XX_MMC_CLKI);
286 omap_cfg_reg(G19_24XX_MMC_CLKO);
287 omap_cfg_reg(F20_24XX_MMC_DAT0);
288 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
289 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
290 } else {
291 omap_cfg_reg(MMC_CMD);
292 omap_cfg_reg(MMC_CLK);
293 omap_cfg_reg(MMC_DAT0);
294 if (cpu_is_omap1710()) {
295 omap_cfg_reg(M15_1710_MMC_CLKI);
296 omap_cfg_reg(P19_1710_MMC_CMDDIR);
297 omap_cfg_reg(P20_1710_MMC_DATDIR0);
298 }
299 }
300 if (mmc_conf->mmc[0].wire4) {
301 if (cpu_is_omap24xx()) {
302 omap_cfg_reg(H14_24XX_MMC_DAT1);
303 omap_cfg_reg(E19_24XX_MMC_DAT2);
304 omap_cfg_reg(D19_24XX_MMC_DAT3);
305 omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
306 omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
307 omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
308 } else {
309 omap_cfg_reg(MMC_DAT1);
310 /* NOTE: DAT2 can be on W10 (here) or M15 */
311 if (!mmc_conf->mmc[0].nomux)
312 omap_cfg_reg(MMC_DAT2);
313 omap_cfg_reg(MMC_DAT3);
314 }
315 }
316 }
317
318#ifdef CONFIG_ARCH_OMAP16XX
319 /* block 2 is on newer chips, and has many pinout options */
320 if (mmc_conf->mmc[1].enabled) {
321 if (!mmc_conf->mmc[1].nomux) {
322 omap_cfg_reg(Y8_1610_MMC2_CMD);
323 omap_cfg_reg(Y10_1610_MMC2_CLK);
324 omap_cfg_reg(R18_1610_MMC2_CLKIN);
325 omap_cfg_reg(W8_1610_MMC2_DAT0);
326 if (mmc_conf->mmc[1].wire4) {
327 omap_cfg_reg(V8_1610_MMC2_DAT1);
328 omap_cfg_reg(W15_1610_MMC2_DAT2);
329 omap_cfg_reg(R10_1610_MMC2_DAT3);
330 }
331
332 /* These are needed for the level shifter */
333 omap_cfg_reg(V9_1610_MMC2_CMDDIR);
334 omap_cfg_reg(V5_1610_MMC2_DATDIR0);
335 omap_cfg_reg(W19_1610_MMC2_DATDIR1);
336 }
337
338 /* Feedback clock must be set on OMAP-1710 MMC2 */
339 if (cpu_is_omap1710())
340 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
341 MOD_CONF_CTRL_1);
342 }
343#endif
344}
345
346static void __init omap_init_mmc(void)
347{ 205{
348 const struct omap_mmc_config *mmc_conf; 206 struct platform_device *pdev;
349 207 struct resource res[OMAP_MMC_NR_RES];
350 /* NOTE: assumes MMC was never (wrongly) enabled */ 208 int ret;
351 mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); 209
352 if (!mmc_conf) 210 pdev = platform_device_alloc("mmci-omap", id);
353 return; 211 if (!pdev)
354 212 return -ENOMEM;
355 omap_init_mmc_conf(mmc_conf); 213
356 214 memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
357 if (mmc_conf->mmc[0].enabled) { 215 res[0].start = base;
358 mmc1_data.conf = mmc_conf->mmc[0]; 216 res[0].end = base + size - 1;
359 (void) platform_device_register(&mmc_omap_device1); 217 res[0].flags = IORESOURCE_MEM;
360 } 218 res[1].start = res[1].end = irq;
361 219 res[1].flags = IORESOURCE_IRQ;
362#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ 220
363 defined(CONFIG_ARCH_OMAP34XX) 221 ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
364 if (mmc_conf->mmc[1].enabled) { 222 if (ret == 0)
365 mmc2_data.conf = mmc_conf->mmc[1]; 223 ret = platform_device_add_data(pdev, data, sizeof(*data));
366 (void) platform_device_register(&mmc_omap_device2); 224 if (ret)
367 } 225 goto fail;
368#endif 226
369} 227 ret = platform_device_add(pdev);
228 if (ret)
229 goto fail;
230 return 0;
370 231
371void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) 232fail:
372{ 233 platform_device_put(pdev);
373 switch (host) { 234 return ret;
374 case 1:
375 mmc1_data = *info;
376 break;
377#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
378 defined(CONFIG_ARCH_OMAP34XX)
379 case 2:
380 mmc2_data = *info;
381 break;
382#endif
383 default:
384 BUG();
385 }
386} 235}
387 236
388#else
389static inline void omap_init_mmc(void) {}
390void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
391#endif 237#endif
392 238
393/*-------------------------------------------------------------------------*/ 239/*-------------------------------------------------------------------------*/
@@ -532,7 +378,6 @@ static int __init omap_init_devices(void)
532 */ 378 */
533 omap_init_dsp(); 379 omap_init_dsp();
534 omap_init_kp(); 380 omap_init_kp();
535 omap_init_mmc();
536 omap_init_uwire(); 381 omap_init_uwire();
537 omap_init_wdt(); 382 omap_init_wdt();
538 omap_init_rng(); 383 omap_init_rng();
diff --git a/arch/arm/plat-omap/include/mach/board-h2.h b/arch/arm/plat-omap/include/mach/board-h2.h
index 2a050e9be65f..15531c8dc0e6 100644
--- a/arch/arm/plat-omap/include/mach/board-h2.h
+++ b/arch/arm/plat-omap/include/mach/board-h2.h
@@ -29,13 +29,13 @@
29#ifndef __ASM_ARCH_OMAP_H2_H 29#ifndef __ASM_ARCH_OMAP_H2_H
30#define __ASM_ARCH_OMAP_H2_H 30#define __ASM_ARCH_OMAP_H2_H
31 31
32/* Placeholder for H2 specific defines */
33
34/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ 32/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
35#define OMAP1610_ETHR_START 0x04000300 33#define OMAP1610_ETHR_START 0x04000300
36 34
35#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
36# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3)
37
37extern void h2_mmc_init(void); 38extern void h2_mmc_init(void);
38extern void h2_mmc_slot_cover_handler(void *arg, int state);
39 39
40#endif /* __ASM_ARCH_OMAP_H2_H */ 40#endif /* __ASM_ARCH_OMAP_H2_H */
41 41
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index c23c12ccb353..9466772fc7c8 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -16,7 +16,6 @@
16 16
17/* Different peripheral ids */ 17/* Different peripheral ids */
18#define OMAP_TAG_CLOCK 0x4f01 18#define OMAP_TAG_CLOCK 0x4f01
19#define OMAP_TAG_MMC 0x4f02
20#define OMAP_TAG_SERIAL_CONSOLE 0x4f03 19#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
21#define OMAP_TAG_USB 0x4f04 20#define OMAP_TAG_USB 0x4f04
22#define OMAP_TAG_LCD 0x4f05 21#define OMAP_TAG_LCD 0x4f05
@@ -35,27 +34,6 @@ struct omap_clock_config {
35 u8 system_clock_type; 34 u8 system_clock_type;
36}; 35};
37 36
38struct omap_mmc_conf {
39 unsigned enabled:1;
40 /* nomux means "standard" muxing is wrong on this board, and that
41 * board-specific code handled it before common init logic.
42 */
43 unsigned nomux:1;
44 /* switch pin can be for card detect (default) or card cover */
45 unsigned cover:1;
46 /* 4 wire signaling is optional, and is only used for SD/SDIO */
47 unsigned wire4:1;
48 /* use the internal clock */
49 unsigned internal_clock:1;
50 s16 power_pin;
51 s16 switch_pin;
52 s16 wp_pin;
53};
54
55struct omap_mmc_config {
56 struct omap_mmc_conf mmc[2];
57};
58
59struct omap_serial_console_config { 37struct omap_serial_console_config {
60 u8 console_uart; 38 u8 console_uart;
61 u32 console_speed; 39 u32 console_speed;
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index fc15d13058fc..0c2ef3b8956a 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -17,12 +17,28 @@
17 17
18#include <mach/board.h> 18#include <mach/board.h>
19 19
20#define OMAP15XX_NR_MMC 1
21#define OMAP16XX_NR_MMC 2
22#define OMAP1_MMC_SIZE 0x080
23#define OMAP1_MMC1_BASE 0xfffb7800
24#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */
25
26#define OMAP24XX_NR_MMC 2
27#define OMAP34XX_NR_MMC 3
28#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE
29#define HSMMC_SIZE 0x200
30#define OMAP2_MMC1_BASE 0x4809c000
31#define OMAP2_MMC2_BASE 0x480b4000
32#define OMAP3_MMC3_BASE 0x480ad000
33#define HSMMC3 (1 << 2)
34#define HSMMC2 (1 << 1)
35#define HSMMC1 (1 << 0)
36
20#define OMAP_MMC_MAX_SLOTS 2 37#define OMAP_MMC_MAX_SLOTS 2
21 38
22struct omap_mmc_platform_data { 39struct omap_mmc_platform_data {
23 struct omap_mmc_conf conf;
24 40
25 /* number of slots on board */ 41 /* number of slots per controller */
26 unsigned nr_slots:2; 42 unsigned nr_slots:2;
27 43
28 /* set if your board has components or wiring that limits the 44 /* set if your board has components or wiring that limits the
@@ -41,7 +57,27 @@ struct omap_mmc_platform_data {
41 int (*suspend)(struct device *dev, int slot); 57 int (*suspend)(struct device *dev, int slot);
42 int (*resume)(struct device *dev, int slot); 58 int (*resume)(struct device *dev, int slot);
43 59
60 u64 dma_mask;
61
44 struct omap_mmc_slot_data { 62 struct omap_mmc_slot_data {
63
64 /*
65 * nomux means "standard" muxing is wrong on this board, and
66 * that board-specific code handled it before common init logic.
67 */
68 unsigned nomux:1;
69
70 /* switch pin can be for card detect (default) or card cover */
71 unsigned cover:1;
72
73 /* 4 wire signaling is optional, and is only used for SD/SDIO */
74 unsigned wire4:1;
75
76 /* use the internal clock */
77 unsigned internal_clock:1;
78 s16 power_pin;
79 s16 switch_pin;
80
45 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); 81 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
46 int (* set_power)(struct device *dev, int slot, int power_on, int vdd); 82 int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
47 int (* get_ro)(struct device *dev, int slot); 83 int (* get_ro)(struct device *dev, int slot);
@@ -49,8 +85,8 @@ struct omap_mmc_platform_data {
49 /* return MMC cover switch state, can be NULL if not supported. 85 /* return MMC cover switch state, can be NULL if not supported.
50 * 86 *
51 * possible return values: 87 * possible return values:
52 * 0 - open 88 * 0 - closed
53 * 1 - closed 89 * 1 - open
54 */ 90 */
55 int (* get_cover_state)(struct device *dev, int slot); 91 int (* get_cover_state)(struct device *dev, int slot);
56 92
@@ -66,9 +102,35 @@ struct omap_mmc_platform_data {
66 } slots[OMAP_MMC_MAX_SLOTS]; 102 } slots[OMAP_MMC_MAX_SLOTS];
67}; 103};
68 104
69extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
70
71/* called from board-specific card detection service routine */ 105/* called from board-specific card detection service routine */
72extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); 106extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
73 107
108#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
109 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
110void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
111 int nr_controllers);
112void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
113 int nr_controllers);
114void hsmmc_init(int controller_mask);
115int omap_mmc_add(int id, unsigned long base, unsigned long size,
116 unsigned int irq, struct omap_mmc_platform_data *data);
117#else
118static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
119 int nr_controllers)
120{
121}
122static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
123 int nr_controllers)
124{
125}
126static inline void hsmmc_init(int controller_mask)
127{
128}
129static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
130 unsigned int irq, struct omap_mmc_platform_data *data)
131{
132 return 0;
133}
134
135#endif
74#endif 136#endif
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 1b9fc3c6b875..c6544d2d072a 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1015,7 +1015,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data
1015 } 1015 }
1016 1016
1017 if (is_read) { 1017 if (is_read) {
1018 if (host->id == 1) { 1018 if (host->id == 0) {
1019 sync_dev = OMAP_DMA_MMC_RX; 1019 sync_dev = OMAP_DMA_MMC_RX;
1020 dma_dev_name = "MMC1 read"; 1020 dma_dev_name = "MMC1 read";
1021 } else { 1021 } else {
@@ -1023,7 +1023,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data
1023 dma_dev_name = "MMC2 read"; 1023 dma_dev_name = "MMC2 read";
1024 } 1024 }
1025 } else { 1025 } else {
1026 if (host->id == 1) { 1026 if (host->id == 0) {
1027 sync_dev = OMAP_DMA_MMC_TX; 1027 sync_dev = OMAP_DMA_MMC_TX;
1028 dma_dev_name = "MMC1 write"; 1028 dma_dev_name = "MMC1 write";
1029 } else { 1029 } else {
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
1317 host->slots[id] = slot; 1317 host->slots[id] = slot;
1318 1318
1319 mmc->caps = 0; 1319 mmc->caps = 0;
1320 if (host->pdata->conf.wire4) 1320 if (host->pdata->slots[id].wire4)
1321 mmc->caps |= MMC_CAP_4_BIT_DATA; 1321 mmc->caps |= MMC_CAP_4_BIT_DATA;
1322 1322
1323 mmc->ops = &mmc_omap_ops; 1323 mmc->ops = &mmc_omap_ops;
@@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1451 host->irq = irq; 1451 host->irq = irq;
1452 1452
1453 host->use_dma = 1; 1453 host->use_dma = 1;
1454 host->dev->dma_mask = &pdata->dma_mask;
1454 host->dma_ch = -1; 1455 host->dma_ch = -1;
1455 1456
1456 host->irq = irq; 1457 host->irq = irq;