* [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
@ 2008-08-13 6:13 Madhusudhan Chikkature
2008-09-10 23:56 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Madhusudhan Chikkature @ 2008-08-13 6:13 UTC (permalink / raw)
To: tony; +Cc: linux-omap
From: Madhusudhan Chikkature<madhu.cr@ti.com>
ARM: OMAP3: Enable 4-bit support for HSMMC.
This patch provides the fix to enable 4-bit support for HSMMC.
Signed-off-by: Madhusudhan Chikkature<madhu.cr@ti.com>
Signed-off-by: purushotam<purushotam@ti.com>
---
arch/arm/plat-omap/devices.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
Index: linux-omap-2.6/arch/arm/plat-omap/devices.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/plat-omap/devices.c 2008-08-07
15:56:52.000000000 +0530
+++ linux-omap-2.6/arch/arm/plat-omap/devices.c 2008-08-11 10:57:37.000000000
+0530
@@ -289,13 +289,17 @@ static void __init omap_init_mmc(void)
mmc = &mmc_conf->mmc[0];
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc1_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device1);
+ }
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
mmc = &mmc_conf->mmc[1];
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc2_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device2);
+ }
#endif
return;
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-08-13 6:13 [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Madhusudhan Chikkature
@ 2008-09-10 23:56 ` Tony Lindgren
2008-09-11 8:48 ` Russell King - ARM Linux
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2008-09-10 23:56 UTC (permalink / raw)
To: Madhusudhan Chikkature; +Cc: linux-omap
* Madhusudhan Chikkature <madhu.cr@ti.com> [080812 23:13]:
> From: Madhusudhan Chikkature<madhu.cr@ti.com>
>
> ARM: OMAP3: Enable 4-bit support for HSMMC.
>
> This patch provides the fix to enable 4-bit support for HSMMC.
Pushing today.
Tony
> Signed-off-by: Madhusudhan Chikkature<madhu.cr@ti.com>
> Signed-off-by: purushotam<purushotam@ti.com>
> ---
> arch/arm/plat-omap/devices.c | 8 ++++++--
> 1 files changed, 6 insertions(+), 2 deletions(-)
>
> Index: linux-omap-2.6/arch/arm/plat-omap/devices.c
> ===================================================================
> --- linux-omap-2.6.orig/arch/arm/plat-omap/devices.c 2008-08-07
> 15:56:52.000000000 +0530
> +++ linux-omap-2.6/arch/arm/plat-omap/devices.c 2008-08-11 10:57:37.000000000
> +0530
> @@ -289,13 +289,17 @@ static void __init omap_init_mmc(void)
> mmc = &mmc_conf->mmc[0];
>
> if (cpu_is_omap2430() || cpu_is_omap34xx()) {
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc1_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device1);
> + }
>
> #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
> mmc = &mmc_conf->mmc[1];
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc2_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device2);
> + }
> #endif
>
> return;
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-10 23:56 ` Tony Lindgren
@ 2008-09-11 8:48 ` Russell King - ARM Linux
2008-09-11 9:13 ` Russell King - ARM Linux
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
0 siblings, 2 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2008-09-11 8:48 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Madhusudhan Chikkature, linux-omap
On Wed, Sep 10, 2008 at 04:56:46PM -0700, Tony Lindgren wrote:
> * Madhusudhan Chikkature <madhu.cr@ti.com> [080812 23:13]:
> > From: Madhusudhan Chikkature<madhu.cr@ti.com>
> >
> > ARM: OMAP3: Enable 4-bit support for HSMMC.
> >
> > This patch provides the fix to enable 4-bit support for HSMMC.
>
> Pushing today.
So, given my update for this, shouldn't this be something sent almost
immediately to me so stuff for mainline isn't falling behind.
Otherwise we're wasting our time trying to get mainline up to date.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 8:48 ` Russell King - ARM Linux
@ 2008-09-11 9:13 ` Russell King - ARM Linux
2008-09-11 17:33 ` Tony Lindgren
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
1 sibling, 1 reply; 20+ messages in thread
From: Russell King - ARM Linux @ 2008-09-11 9:13 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Madhusudhan Chikkature, linux-omap
On Thu, Sep 11, 2008 at 09:48:28AM +0100, Russell King - ARM Linux wrote:
> On Wed, Sep 10, 2008 at 04:56:46PM -0700, Tony Lindgren wrote:
> > * Madhusudhan Chikkature <madhu.cr@ti.com> [080812 23:13]:
> > > From: Madhusudhan Chikkature<madhu.cr@ti.com>
> > >
> > > ARM: OMAP3: Enable 4-bit support for HSMMC.
> > >
> > > This patch provides the fix to enable 4-bit support for HSMMC.
> >
> > Pushing today.
>
> So, given my update for this, shouldn't this be something sent almost
> immediately to me so stuff for mainline isn't falling behind.
>
> Otherwise we're wasting our time trying to get mainline up to date.
New version of the MMC updates for mainline pushed out - with additional
cleanups in place (and since it's a different patch, I've dropped Tony's
ack from it.)
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 8:48 ` Russell King - ARM Linux
2008-09-11 9:13 ` Russell King - ARM Linux
@ 2008-09-11 11:23 ` Jarkko Lavinen
2008-09-11 11:35 ` Felipe Balbi
` (2 more replies)
1 sibling, 3 replies; 20+ messages in thread
From: Jarkko Lavinen @ 2008-09-11 11:23 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Tony Lindgren, Madhusudhan Chikkature, linux-omap
On Thu, Sep 11, 2008 at 09:48:28AM +0100, ext Russell King - ARM Linux wrote:
> So, given my update for this, shouldn't this be something sent almost
> immediately to me so stuff for mainline isn't falling behind.
Hi Russell and all
Here is a hopefully self-explaining patch, which enables 8-bit
support similar to the 4-bit support in Omap HSMMC when then mmc
confifuration from platform data tells it is available.
I have tested it on a testboard with 2.6.26 beased kernel and
write speed increased some 30..40%.
Cheers,
Jarkko
---
>From f739457703988da18a5509bd297c4f6ebed83291 Mon Sep 17 00:00:00 2001
From: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Date: Thu, 11 Sep 2008 14:15:31 +0300
Subject: [PATCH] HSMMC: Enable 8-bit transfer when available.
Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
---
arch/arm/plat-omap/devices.c | 8 ++++++--
arch/arm/plat-omap/include/mach/board.h | 4 +++-
drivers/mmc/core/mmc.c | 17 +++++++++++++----
drivers/mmc/host/omap_hsmmc.c | 10 ++++++++++
include/linux/mmc/host.h | 12 +++++++-----
5 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 3bd1da2..aa1299f 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -289,13 +289,17 @@ static void __init omap_init_mmc(void)
mmc = &mmc_conf->mmc[0];
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc1_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device1);
+ }
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
mmc = &mmc_conf->mmc[1];
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc2_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device2);
+ }
#endif
return;
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index a1a66ac..cd287dd 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -46,8 +46,10 @@ struct omap_mmc_conf {
unsigned nomux:1;
/* switch pin can be for card detect (default) or card cover */
unsigned cover:1;
- /* 4 wire signaling is optional, and is only used for SD/SDIO */
+ /* 4 and 8 wire signaling are optional */
unsigned wire4:1;
+ unsigned wire8:1;
+
/* use the internal clock */
unsigned internal_clock:1;
s16 power_pin;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index fdd7c76..8c55df3 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -434,13 +434,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* Activate wide bus (if supported).
*/
if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
- (host->caps & MMC_CAP_4_BIT_DATA)) {
+ (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
+ unsigned ext_csd_bit, driver_width;
+
+ if (host->caps & MMC_CAP_8_BIT_DATA) {
+ ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
+ driver_width = MMC_BUS_WIDTH_8;
+ } else {
+ ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
+ driver_width = MMC_BUS_WIDTH_4;
+ }
+
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
+ EXT_CSD_BUS_WIDTH, ext_csd_bit);
if (err)
goto free_card;
- mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+ mmc_set_bus_width(card->host, driver_width);
}
if (!oldcard)
@@ -624,4 +634,3 @@ err:
return err;
}
-
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index af34871..92ad67e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -72,6 +72,7 @@
#define MSBS 1<<5
#define BCE 1<<1
#define FOUR_BIT 1 << 1
+#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
#define OD 0x1
@@ -631,6 +632,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
u16 dsor = 0;
unsigned long regval;
unsigned long timeout;
+ u32 con;
switch (ios->power_mode) {
case MMC_POWER_OFF:
@@ -641,12 +643,18 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
break;
}
+ con = OMAP_HSMMC_READ(host->base, CON);
switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_8:
+ OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+ break;
case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
break;
case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
break;
@@ -814,6 +822,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
if (pdata->conf.wire4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
+ if (pdata->conf.wire8)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
/* Only MMC1 supports 3.0V */
if (host->id == OMAP_MMC1_DEVID) {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9c288c9..ddd8b97 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -41,6 +41,7 @@ struct mmc_ios {
#define MMC_BUS_WIDTH_1 0
#define MMC_BUS_WIDTH_4 2
+#define MMC_BUS_WIDTH_8 3
unsigned char timing; /* timing specification used */
@@ -111,11 +112,12 @@ struct mmc_host {
unsigned long caps; /* Host capabilities */
#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
-#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
-#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
-#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
-#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
-#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
+#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can the host do 8 bit transfers */
+#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
+#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
+#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
+#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */
+#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
@ 2008-09-11 11:35 ` Felipe Balbi
2008-09-20 10:02 ` Pierre Ossman
2008-09-11 19:53 ` Tony Lindgren
2008-09-12 12:32 ` Madhusudhan Chikkature
2 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2008-09-11 11:35 UTC (permalink / raw)
To: ext Jarkko Lavinen
Cc: Russell King - ARM Linux, Tony Lindgren, Madhusudhan Chikkature,
linux-omap, Pierre Ossman
On Thu, Sep 11, 2008 at 02:23:15PM +0300, ext Jarkko Lavinen wrote:
> On Thu, Sep 11, 2008 at 09:48:28AM +0100, ext Russell King - ARM Linux wrote:
> > So, given my update for this, shouldn't this be something sent almost
> > immediately to me so stuff for mainline isn't falling behind.
>
> Hi Russell and all
>
> Here is a hopefully self-explaining patch, which enables 8-bit
> support similar to the 4-bit support in Omap HSMMC when then mmc
> confifuration from platform data tells it is available.
>
> I have tested it on a testboard with 2.6.26 beased kernel and
> write speed increased some 30..40%.
Maybe Pierre should be watching this patch as well. I'm putting him in
the loop.
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index fdd7c76..8c55df3 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -434,13 +434,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> * Activate wide bus (if supported).
> */
> if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
> - (host->caps & MMC_CAP_4_BIT_DATA)) {
> + (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
> + unsigned ext_csd_bit, driver_width;
> +
> + if (host->caps & MMC_CAP_8_BIT_DATA) {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
> + driver_width = MMC_BUS_WIDTH_8;
> + } else {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
> + driver_width = MMC_BUS_WIDTH_4;
> + }
maybe you could:
[...]
unsigned ext_csd_bit, driver_width;
[...]
if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
(host->caps & MMC_CAP_4_BIT_DATA)) {
ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
driver_width = MMC_BUS_WIDTH_8;
}
if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
(host->caps & MMC_CAP_8_BIT_DATA)) {
ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
driver_width = MMC_BUS_WIDTH_4;
}
> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index af34871..92ad67e 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -72,6 +72,7 @@
> #define MSBS 1<<5
> #define BCE 1<<1
> #define FOUR_BIT 1 << 1
someone needs to clean up those #defines...
> @@ -111,11 +112,12 @@ struct mmc_host {
> unsigned long caps; /* Host capabilities */
>
> #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
> -#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
> -#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
> -#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
> -#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
> -#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
> +#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can the host do 8 bit transfers */
> +#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
> +#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
> +#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
> +#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */
> +#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */
This would require changes to all other mmc host drivers, right ?
How about:
+#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */
--
balbi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 9:13 ` Russell King - ARM Linux
@ 2008-09-11 17:33 ` Tony Lindgren
2008-09-11 18:13 ` Russell King - ARM Linux
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2008-09-11 17:33 UTC (permalink / raw)
To: Russell King - ARM Linux; +Cc: Madhusudhan Chikkature, linux-omap
* Russell King - ARM Linux <linux@arm.linux.org.uk> [080911 02:13]:
> On Thu, Sep 11, 2008 at 09:48:28AM +0100, Russell King - ARM Linux wrote:
> > On Wed, Sep 10, 2008 at 04:56:46PM -0700, Tony Lindgren wrote:
> > > * Madhusudhan Chikkature <madhu.cr@ti.com> [080812 23:13]:
> > > > From: Madhusudhan Chikkature<madhu.cr@ti.com>
> > > >
> > > > ARM: OMAP3: Enable 4-bit support for HSMMC.
> > > >
> > > > This patch provides the fix to enable 4-bit support for HSMMC.
> > >
> > > Pushing today.
> >
> > So, given my update for this, shouldn't this be something sent almost
> > immediately to me so stuff for mainline isn't falling behind.
> >
> > Otherwise we're wasting our time trying to get mainline up to date.
Totally.
> New version of the MMC updates for mainline pushed out - with additional
> cleanups in place (and since it's a different patch, I've dropped Tony's
> ack from it.)
While we're at it, let's clean up the mmc mess further and split the
resources to mach-omap1/devices.c and mach-omap2/devices.c. That way
we get rid of the ifdef else between omap1 and omap2.
I'll post some patches for that.
Tony
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 17:33 ` Tony Lindgren
@ 2008-09-11 18:13 ` Russell King - ARM Linux
2008-09-11 21:18 ` Steve Sakoman
2008-09-12 0:48 ` [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data) Tony Lindgren
0 siblings, 2 replies; 20+ messages in thread
From: Russell King - ARM Linux @ 2008-09-11 18:13 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Madhusudhan Chikkature, linux-omap
On Thu, Sep 11, 2008 at 10:33:33AM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [080911 02:13]:
> > New version of the MMC updates for mainline pushed out - with additional
> > cleanups in place (and since it's a different patch, I've dropped Tony's
> > ack from it.)
>
> While we're at it, let's clean up the mmc mess further and split the
> resources to mach-omap1/devices.c and mach-omap2/devices.c. That way
> we get rid of the ifdef else between omap1 and omap2.
Great, it would be nice to get something in OMAP to the point where we
can say it's finished, and doesn't have to be regularly tinkered with
anymore.
Is there anything else that the MMC stuff is missing at present?
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
2008-09-11 11:35 ` Felipe Balbi
@ 2008-09-11 19:53 ` Tony Lindgren
2008-09-12 12:32 ` Madhusudhan Chikkature
2 siblings, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2008-09-11 19:53 UTC (permalink / raw)
To: Jarkko Lavinen
Cc: Russell King - ARM Linux, Madhusudhan Chikkature, linux-omap
* Jarkko Lavinen <jarkko.lavinen@nokia.com> [080911 04:23]:
> On Thu, Sep 11, 2008 at 09:48:28AM +0100, ext Russell King - ARM Linux wrote:
> > So, given my update for this, shouldn't this be something sent almost
> > immediately to me so stuff for mainline isn't falling behind.
>
> Hi Russell and all
>
> Here is a hopefully self-explaining patch, which enables 8-bit
> support similar to the 4-bit support in Omap HSMMC when then mmc
> confifuration from platform data tells it is available.
>
> I have tested it on a testboard with 2.6.26 beased kernel and
> write speed increased some 30..40%.
>
> Cheers,
> Jarkko
>
> ---
>
> From f739457703988da18a5509bd297c4f6ebed83291 Mon Sep 17 00:00:00 2001
> From: Jarkko Lavinen <jarkko.lavinen@nokia.com>
> Date: Thu, 11 Sep 2008 14:15:31 +0300
> Subject: [PATCH] HSMMC: Enable 8-bit transfer when available.
>
> Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
> ---
> arch/arm/plat-omap/devices.c | 8 ++++++--
> arch/arm/plat-omap/include/mach/board.h | 4 +++-
> drivers/mmc/core/mmc.c | 17 +++++++++++++----
> drivers/mmc/host/omap_hsmmc.c | 10 ++++++++++
> include/linux/mmc/host.h | 12 +++++++-----
> 5 files changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
> index 3bd1da2..aa1299f 100644
> --- a/arch/arm/plat-omap/devices.c
> +++ b/arch/arm/plat-omap/devices.c
> @@ -289,13 +289,17 @@ static void __init omap_init_mmc(void)
> mmc = &mmc_conf->mmc[0];
>
> if (cpu_is_omap2430() || cpu_is_omap34xx()) {
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc1_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device1);
> + }
>
> #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
> mmc = &mmc_conf->mmc[1];
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc2_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device2);
> + }
> #endif
>
> return;
I'm about to get rid of the old mmc_conf and use only
omap_mmc_platform_data. So this will need to be modified a bit
as soon as I'm done.
Regards,
Tony
> diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
> index a1a66ac..cd287dd 100644
> --- a/arch/arm/plat-omap/include/mach/board.h
> +++ b/arch/arm/plat-omap/include/mach/board.h
> @@ -46,8 +46,10 @@ struct omap_mmc_conf {
> unsigned nomux:1;
> /* switch pin can be for card detect (default) or card cover */
> unsigned cover:1;
> - /* 4 wire signaling is optional, and is only used for SD/SDIO */
> + /* 4 and 8 wire signaling are optional */
> unsigned wire4:1;
> + unsigned wire8:1;
> +
> /* use the internal clock */
> unsigned internal_clock:1;
> s16 power_pin;
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index fdd7c76..8c55df3 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -434,13 +434,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> * Activate wide bus (if supported).
> */
> if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
> - (host->caps & MMC_CAP_4_BIT_DATA)) {
> + (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
> + unsigned ext_csd_bit, driver_width;
> +
> + if (host->caps & MMC_CAP_8_BIT_DATA) {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
> + driver_width = MMC_BUS_WIDTH_8;
> + } else {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
> + driver_width = MMC_BUS_WIDTH_4;
> + }
> +
> err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
> + EXT_CSD_BUS_WIDTH, ext_csd_bit);
> if (err)
> goto free_card;
>
> - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
> + mmc_set_bus_width(card->host, driver_width);
> }
>
> if (!oldcard)
> @@ -624,4 +634,3 @@ err:
>
> return err;
> }
> -
> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index af34871..92ad67e 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -72,6 +72,7 @@
> #define MSBS 1<<5
> #define BCE 1<<1
> #define FOUR_BIT 1 << 1
> +#define DW8 (1 << 5)
> #define CC 0x1
> #define TC 0x02
> #define OD 0x1
> @@ -631,6 +632,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> u16 dsor = 0;
> unsigned long regval;
> unsigned long timeout;
> + u32 con;
>
> switch (ios->power_mode) {
> case MMC_POWER_OFF:
> @@ -641,12 +643,18 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> break;
> }
>
> + con = OMAP_HSMMC_READ(host->base, CON);
> switch (mmc->ios.bus_width) {
> + case MMC_BUS_WIDTH_8:
> + OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
> + break;
> case MMC_BUS_WIDTH_4:
> + OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
> OMAP_HSMMC_WRITE(host->base, HCTL,
> OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
> break;
> case MMC_BUS_WIDTH_1:
> + OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
> OMAP_HSMMC_WRITE(host->base, HCTL,
> OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
> break;
> @@ -814,6 +822,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
>
> if (pdata->conf.wire4)
> mmc->caps |= MMC_CAP_4_BIT_DATA;
> + if (pdata->conf.wire8)
> + mmc->caps |= MMC_CAP_8_BIT_DATA;
>
> /* Only MMC1 supports 3.0V */
> if (host->id == OMAP_MMC1_DEVID) {
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 9c288c9..ddd8b97 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -41,6 +41,7 @@ struct mmc_ios {
>
> #define MMC_BUS_WIDTH_1 0
> #define MMC_BUS_WIDTH_4 2
> +#define MMC_BUS_WIDTH_8 3
>
> unsigned char timing; /* timing specification used */
>
> @@ -111,11 +112,12 @@ struct mmc_host {
> unsigned long caps; /* Host capabilities */
>
> #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
> -#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
> -#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
> -#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
> -#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
> -#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
> +#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can the host do 8 bit transfers */
> +#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
> +#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
> +#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
> +#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */
> +#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */
>
> /* host specific block data */
> unsigned int max_seg_size; /* see blk_queue_max_segment_size */
> --
> 1.5.6.5
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 18:13 ` Russell King - ARM Linux
@ 2008-09-11 21:18 ` Steve Sakoman
2008-09-12 8:04 ` Felipe Balbi
2008-09-12 0:48 ` [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data) Tony Lindgren
1 sibling, 1 reply; 20+ messages in thread
From: Steve Sakoman @ 2008-09-11 21:18 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Tony Lindgren, Madhusudhan Chikkature, linux-omap
On Thu, Sep 11, 2008 at 11:13 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Is there anything else that the MMC stuff is missing at present?
Not an answer to your question, but perhaps an expansion of it (or
maybe even a demonstration of my ignorance, not sure which) :-)
Has anyone successfully used the omap mmc infrastructure to support an
SDIO device (say for example the libertas_sdio driver)?
Steve
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-11 18:13 ` Russell King - ARM Linux
2008-09-11 21:18 ` Steve Sakoman
@ 2008-09-12 0:48 ` Tony Lindgren
2008-09-13 9:59 ` Russell King - ARM Linux
1 sibling, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2008-09-12 0:48 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
[-- Attachment #1: Type: text/plain, Size: 1012 bytes --]
* Russell King - ARM Linux <linux@arm.linux.org.uk> [080911 11:13]:
> On Thu, Sep 11, 2008 at 10:33:33AM -0700, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [080911 02:13]:
> > > New version of the MMC updates for mainline pushed out - with additional
> > > cleanups in place (and since it's a different patch, I've dropped Tony's
> > > ack from it.)
> >
> > While we're at it, let's clean up the mmc mess further and split the
> > resources to mach-omap1/devices.c and mach-omap2/devices.c. That way
> > we get rid of the ifdef else between omap1 and omap2.
>
> Great, it would be nice to get something in OMAP to the point where we
> can say it's finished, and doesn't have to be regularly tinkered with
> anymore.
OK, I've pushed a patch to l-o tree. Here's a patch for you against your
devel branch.
> Is there anything else that the MMC stuff is missing at present?
Well the omap_hsmmc.c driver is not quite ready yet. That should not
affect the device init code.
Tony
[-- Attachment #2: omap-mmc-init.patch --]
[-- Type: text/x-diff, Size: 34159 bytes --]
From: Tony Lindgren <tony@atomide.com>
Date: Thu, 11 Sep 2008 17:42:37 -0700
Subject: [PATCH] ARM: OMAP: Clean-up MMC device init
Clean-up MMC device init:
- Initialize devices in mach-omap1/devices.c and mach-omap2/devices.c
instead of plat-omap/devices.c
- Remove old struct omap_mmc_config, use struct omap_mmc_platform_data instead
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index ab9ee58..37031e0 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -14,6 +14,7 @@
#include <mach/mmc.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
#ifdef CONFIG_MMC_OMAP
static int slot_cover_open;
@@ -83,6 +84,8 @@ static struct omap_mmc_platform_data h2_mmc_data = {
.init = h2_mmc_late_init,
.cleanup = h2_mmc_cleanup,
.slots[0] = {
+ .enabled = 1,
+ .wire4 = 1,
.set_power = h2_mmc_set_power,
.set_bus_mode = h2_mmc_set_bus_mode,
.get_ro = NULL,
@@ -95,7 +98,7 @@ static struct omap_mmc_platform_data h2_mmc_data = {
void __init h2_mmc_init(void)
{
- omap_set_mmc_info(1, &h2_mmc_data);
+ omap1_init_mmc(&h2_mmc_data);
}
#else
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 3b65914..3b59354 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -381,15 +381,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h2_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h2_mmc_data;
-
static struct omap_uart_config h2_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -400,7 +391,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
static struct omap_board_config_kernel h2_config[] __initdata = {
{ OMAP_TAG_USB, &h2_usb_config },
- { OMAP_TAG_MMC, &h2_mmc_config },
{ OMAP_TAG_UART, &h2_uart_config },
{ OMAP_TAG_LCD, &h2_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index 3608581..44e9d53 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -14,6 +14,7 @@
#include <mach/mmc.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
#ifdef CONFIG_MMC_OMAP
static int slot_cover_open;
@@ -87,6 +88,8 @@ static struct omap_mmc_platform_data h3_mmc_data = {
.init = h3_mmc_late_init,
.cleanup = h3_mmc_cleanup,
.slots[0] = {
+ .enabled = 1,
+ .wire4 = 1,
.set_power = h3_mmc_set_power,
.set_bus_mode = h3_mmc_set_bus_mode,
.get_ro = NULL,
@@ -99,7 +102,7 @@ static struct omap_mmc_platform_data h3_mmc_data = {
void __init h3_mmc_init(void)
{
- omap_set_mmc_info(1, &h3_mmc_data);
+ omap1_init_mmc(&h3_mmc_data);
}
#else
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2ced6d9..ff9bbe2 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h3_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h3_mmc_data;
-
static struct omap_uart_config h3_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
static struct omap_board_config_kernel h3_config[] __initdata = {
{ OMAP_TAG_USB, &h3_usb_config },
- { OMAP_TAG_MMC, &h3_mmc_config },
{ OMAP_TAG_UART, &h3_uart_config },
{ OMAP_TAG_LCD, &h3_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index cbc11be..9ed0fef 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -39,6 +39,7 @@
#include <mach/common.h>
#include <mach/mcbsp.h>
#include <mach/omap-alsa.h>
+#include <mach/mmc.h>
static int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
@@ -360,13 +361,15 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = {
};
#endif
-static struct omap_mmc_config innovator_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = OMAP_MPUIO(3),
- .power_pin = -1, /* FPGA F3 UIO42 */
- .switch_pin = -1, /* FPGA F4 UIO43 */
+static struct omap_mmc_platform_data innovator_mmc_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .enabled = 1,
+ .wire4 = 1,
+ .wp_pin = OMAP_MPUIO(3),
+ .power_pin = -1, /* FPGA F3 UIO42 */
+ .switch_pin = -1, /* FPGA F4 UIO43 */
+ .name = "mmcblk",
},
};
@@ -377,7 +380,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
{ OMAP_TAG_LCD, NULL },
- { OMAP_TAG_MMC, &innovator_mmc_config },
{ OMAP_TAG_UART, &innovator_uart_config },
};
@@ -412,6 +414,7 @@ static void __init innovator_init(void)
omap_board_config_size = ARRAY_SIZE(innovator_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
+ omap1_init_mmc(&innovator_mmc_data);
}
static 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 38d9783..a8d2fef 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -35,6 +35,7 @@
#include <mach/aic23.h>
#include <mach/omapfb.h>
#include <mach/lcd_mipid.h>
+#include <mach/mmc.h>
#define ADS7846_PENDOWN_GPIO 15
@@ -173,26 +174,29 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
.pins[0] = 6,
};
-static struct omap_mmc_config nokia770_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
+static struct omap_mmc_platform_data nokia770_mmc_data = {
+ .nr_slots = 2,
+ .slots[0] = {
+ .enabled = 0,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ .name = "mmcblk",
},
- .mmc[1] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
+ .slots[1] = {
+ .enabled = 0,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ .name = "mmcblk",
},
+
};
static struct omap_board_config_kernel nokia770_config[] __initdata = {
{ OMAP_TAG_USB, NULL },
- { OMAP_TAG_MMC, &nokia770_mmc_config },
};
#if defined(CONFIG_OMAP_DSP)
@@ -335,6 +339,7 @@ static void __init omap_nokia770_init(void)
omap_dsp_init();
ads7846_dev_init();
mipid_dev_init();
+ omap1_init_mmc(&nokia770_mmc_data);
}
static void __init omap_nokia770_map_io(void)
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index b580436..52fd4e3 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -44,6 +44,7 @@
#include <mach/common.h>
#include <mach/mcbsp.h>
#include <mach/omap-alsa.h>
+#include <mach/mmc.h>
static void __init omap_palmte_init_irq(void)
{
@@ -195,12 +196,14 @@ static struct omap_usb_config palmte_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmte_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wp_pin = PALMTE_MMC_WP_GPIO,
- .power_pin = PALMTE_MMC_POWER_GPIO,
- .switch_pin = PALMTE_MMC_SWITCH_GPIO,
+static struct omap_mmc_platform_data palmzte_mmc_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .enabled = 1,
+ .wp_pin = PALMTE_MMC_WP_GPIO,
+ .power_pin = PALMTE_MMC_POWER_GPIO,
+ .switch_pin = PALMTE_MMC_SWITCH_GPIO,
+ .name = "mmcblk",
},
};
@@ -316,7 +319,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
static struct omap_board_config_kernel palmte_config[] __initdata = {
{ OMAP_TAG_USB, &palmte_usb_config },
- { OMAP_TAG_MMC, &palmte_mmc_config },
{ OMAP_TAG_LCD, &palmte_lcd_config },
{ OMAP_TAG_UART, &palmte_uart_config },
};
@@ -372,6 +374,7 @@ static void __init omap_palmte_init(void)
palmte_misc_gpio_setup();
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
+ omap1_init_mmc(&palmte_mmc_data);
}
static void __init omap_palmte_map_io(void)
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index e719294..5c75b9a 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -43,6 +43,7 @@
#include <mach/keypad.h>
#include <mach/common.h>
#include <mach/omap-alsa.h>
+#include <mach/mmc.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
@@ -267,13 +268,15 @@ static struct omap_usb_config palmz71_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmz71_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 0,
- .wp_pin = PALMZ71_MMC_WP_GPIO,
- .power_pin = -1,
- .switch_pin = PALMZ71_MMC_IN_GPIO,
+static struct omap_mmc_platform_data palmz71_mmc_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .enabled = 1,
+ .wire4 = 0,
+ .wp_pin = PALMZ71_MMC_WP_GPIO,
+ .power_pin = -1,
+ .switch_pin = PALMZ71_MMC_IN_GPIO,
+ .name = "mmcblk",
},
};
@@ -287,7 +290,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {
static struct omap_board_config_kernel palmz71_config[] __initdata = {
{OMAP_TAG_USB, &palmz71_usb_config},
- {OMAP_TAG_MMC, &palmz71_mmc_config},
{OMAP_TAG_LCD, &palmz71_lcd_config},
{OMAP_TAG_UART, &palmz71_uart_config},
};
@@ -365,6 +367,7 @@ omap_palmz71_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
palmz71_gpio_setup(0);
+ omap1_init_mmc(&palmz71_mmc_data);
}
static void __init
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 0be4eba..524d22d 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -12,6 +12,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/gpio.h>
@@ -97,6 +99,8 @@ static struct omap_mmc_platform_data sx1_mmc_data = {
.init = sx1_mmc_late_init,
.cleanup = sx1_mmc_cleanup,
.slots[0] = {
+ .enabled = 1,
+ .wire4 = 0,
.set_power = sx1_mmc_set_power,
.set_bus_mode = sx1_mmc_set_bus_mode,
.get_ro = NULL,
@@ -109,7 +113,7 @@ static struct omap_mmc_platform_data sx1_mmc_data = {
void __init sx1_mmc_init(void)
{
- omap_set_mmc_info(1, &sx1_mmc_data);
+ omap1_init_mmc(&sx1_mmc_data);
}
#else
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 130bcc6..f915839 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
.pins[2] = 0,
};
-/*----------- MMC -------------------------*/
-
-static struct omap_mmc_config sx1_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 0,
- },
-};
-
/*----------- LCD -------------------------*/
static struct platform_device sx1_lcd_device = {
@@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {
static struct omap_board_config_kernel sx1_config[] __initdata = {
{ OMAP_TAG_USB, &sx1_usb_config },
- { OMAP_TAG_MMC, &sx1_mmc_config },
{ OMAP_TAG_LCD, &sx1_lcd_config },
{ OMAP_TAG_UART, &sx1_uart_config },
};
@@ -443,7 +433,6 @@ static void __init omap_sx1_init(void)
omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */
omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */
omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */
-
}
/*----------------------------------------*/
static void __init omap_sx1_init_irq(void)
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 213b487..f5d8ba6 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -33,6 +33,7 @@
#include <mach/mux.h>
#include <mach/tc.h>
#include <mach/usb.h>
+#include <mach/mmc.h>
static struct plat_serial8250_port voiceblue_ports[] = {
{
@@ -139,11 +140,13 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
.pins[2] = 6,
};
-static struct omap_mmc_config voiceblue_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .power_pin = 2,
- .switch_pin = -1,
+static struct omap_mmc_platform_data voiceblue_mmc_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .enabled = 1,
+ .power_pin = 2,
+ .switch_pin = -1,
+ .name = "mmcblk",
},
};
@@ -153,7 +156,6 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
static struct omap_board_config_kernel voiceblue_config[] = {
{ OMAP_TAG_USB, &voiceblue_usb_config },
- { OMAP_TAG_MMC, &voiceblue_mmc_config },
{ OMAP_TAG_UART, &voiceblue_uart_config },
};
@@ -201,6 +203,8 @@ static void __init voiceblue_init(void)
* (it is connected through invertor) */
omap_writeb(0x00, OMAP_LPG1_LCR);
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
+
+ omap1_init_mmc(&voiceblue_mmc_data);
}
static void __init voiceblue_map_io(void)
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 99982d3..d9a1002 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
/*-------------------------------------------------------------------------*/
@@ -99,6 +100,136 @@ static inline void omap_init_mbox(void)
static inline void omap_init_mbox(void) { }
#endif
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define OMAP1_MMC1_BASE 0xfffb7800
+#define OMAP1_MMC1_END (OMAP1_MMC1_BASE + 0x7f)
+#define OMAP1_MMC1_INT INT_MMC
+
+#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+#define OMAP1_MMC2_END (OMAP1_MMC2_BASE + 0x7f)
+#define OMAP1_MMC2_INT INT_1610_MMC2
+
+static u64 omap1_mmc1_dmamask = 0xffffffff;
+
+static struct resource omap1_mmc1_resources[] = {
+ {
+ .start = OMAP1_MMC1_BASE,
+ .end = OMAP1_MMC1_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP1_MMC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap1_mmc1_device = {
+ .name = "mmci-omap",
+ .id = 1,
+ .dev = {
+ .dma_mask = &omap1_mmc1_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(omap1_mmc1_resources),
+ .resource = omap1_mmc1_resources,
+};
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+
+static u64 omap1_mmc2_dmamask = 0xffffffff;
+
+static struct resource omap1_mmc2_resources[] = {
+ {
+ .start = OMAP1_MMC2_BASE,
+ .end = OMAP1_MMC2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP1_MMC2_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap1_mmc2_device = {
+ .name = "mmci-omap",
+ .id = 2,
+ .dev = {
+ .dma_mask = &omap1_mmc2_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(omap1_mmc2_resources),
+ .resource = omap1_mmc2_resources,
+};
+#define OMAP1_MMC2_DEVICE &omap1_mmc2_device
+#else
+#define OMAP1_MMC2_DEVICE &omap1_mmc1_device /* Dummy */
+#endif
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *info)
+{
+ if (info->slots[0].enabled) {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (info->slots[0].wire4) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!info->slots[0].nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ }
+
+ /* Block 2 is on newer chips, and has many pinout options */
+ if (cpu_is_omap16xx() && info->slots[1].enabled) {
+ if (!info->slots[1].nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (info->slots[1].wire4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ }
+}
+
+void omap1_init_mmc(struct omap_mmc_platform_data *info)
+{
+ if (!info)
+ return;
+
+ omap1_mmc_mux(info);
+ platform_set_drvdata(&omap1_mmc1_device, info);
+
+ if (cpu_is_omap16xx())
+ platform_set_drvdata(OMAP1_MMC2_DEVICE, info);
+
+ omap_init_mmc(info, &omap1_mmc1_device, OMAP1_MMC2_DEVICE);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
#if defined(CONFIG_OMAP_STI)
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 989ad15..eec2fea 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = {
.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
};
-static struct omap_mmc_config apollon_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_usb_config apollon_usb_config __initdata = {
.register_dev = 1,
.hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
@@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
static struct omap_board_config_kernel apollon_config[] = {
{ OMAP_TAG_UART, &apollon_uart_config },
- { OMAP_TAG_MMC, &apollon_mmc_config },
{ OMAP_TAG_USB, &apollon_usb_config },
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 9ba0978..3b34c20 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config generic_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_UART, &generic_uart_config },
- { OMAP_TAG_MMC, &generic_mmc_config },
};
static void __init omap_generic_init(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index d4e3b6f..9f01681 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -371,23 +371,12 @@ static struct omap_uart_config h4_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config h4_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_lcd_config h4_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_UART, &h4_uart_config },
- { OMAP_TAG_MMC, &h4_mmc_config },
{ OMAP_TAG_LCD, &h4_lcd_config },
};
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2ee954a..79a026e 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,10 +19,12 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
+#include <mach/control.h>
#include <mach/tc.h>
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
@@ -203,6 +205,113 @@ static inline void omap_init_mcspi(void) {}
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+#define OMAP2_MMC1_BASE 0x4809c000
+#define OMAP2_MMC1_END (OMAP2_MMC1_BASE + 0x1fc)
+#define OMAP2_MMC1_INT INT_24XX_MMC_IRQ
+
+#define OMAP2_MMC2_BASE 0x480b4000
+#define OMAP2_MMC2_END (OMAP2_MMC2_BASE + 0x1fc)
+#define OMAP2_MMC2_INT INT_24XX_MMC2_IRQ
+
+static u64 omap2_mmc1_dmamask = 0xffffffff;
+
+static struct resource omap2_mmc1_resources[] = {
+ {
+ .start = OMAP2_MMC1_BASE,
+ .end = OMAP2_MMC1_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP2_MMC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap2_mmc1_device = {
+ .name = "mmci-omap",
+ .id = 1,
+ .dev = {
+ .dma_mask = &omap2_mmc1_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(omap2_mmc1_resources),
+ .resource = omap2_mmc1_resources,
+};
+
+static u64 omap2_mmc2_dmamask = 0xffffffff;
+
+static struct resource omap2_mmc2_resources[] = {
+ {
+ .start = OMAP2_MMC2_BASE,
+ .end = OMAP2_MMC2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP2_MMC2_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap2_mmc2_device = {
+ .name = "mmci-omap",
+ .id = 2,
+ .dev = {
+ .dma_mask = &omap2_mmc2_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(omap2_mmc2_resources),
+ .resource = omap2_mmc2_resources,
+};
+
+static inline void omap2_mmc_mux(struct omap_mmc_platform_data *info)
+{
+ if (!cpu_is_omap2420())
+ return;
+
+ if (info->slots[0].enabled) {
+ omap_cfg_reg(H18_24XX_MMC_CMD);
+ omap_cfg_reg(H15_24XX_MMC_CLKI);
+ omap_cfg_reg(G19_24XX_MMC_CLKO);
+ omap_cfg_reg(F20_24XX_MMC_DAT0);
+ omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
+ omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+ if (info->slots[0].wire4) {
+ omap_cfg_reg(H14_24XX_MMC_DAT1);
+ omap_cfg_reg(E19_24XX_MMC_DAT2);
+ omap_cfg_reg(D19_24XX_MMC_DAT3);
+ omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
+ omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
+ omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+ }
+
+ /*
+ * Use internal loop-back in MMC/SDIO Module Input Clock
+ * selection
+ */
+ if (info->slots[0].internal_clock) {
+ u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+ }
+ }
+}
+
+void omap2_init_mmc(struct omap_mmc_platform_data *info)
+{
+ if (!info)
+ return;
+
+ omap2_mmc_mux(info);
+ omap2_mmc1_device.dev.platform_data = info;
+ omap2_mmc2_device.dev.platform_data = info;
+ omap_init_mmc(info, &omap2_mmc1_device, &omap2_mmc2_device);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
static int __init omap2_init_devices(void)
{
/* please keep these calls, and their implementations above,
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index b38410f..db63c24 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -198,212 +198,22 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP_MMC1_BASE 0x4809c000
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc)
-#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
-
-#define OMAP_MMC2_BASE 0x480b4000
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc)
-#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ
-
-#else
-
-#define OMAP_MMC1_BASE 0xfffb7800
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f)
-#define OMAP_MMC1_INT INT_MMC
-
-#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f)
-#define OMAP_MMC2_INT INT_1610_MMC2
-
-#endif
-
-static struct omap_mmc_platform_data mmc1_data;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
- {
- .start = OMAP_MMC1_BASE,
- .end = OMAP_MMC1_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC1_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device1 = {
- .name = "mmci-omap",
- .id = 1,
- .dev = {
- .dma_mask = &mmc1_dmamask,
- .platform_data = &mmc1_data,
- },
- .num_resources = ARRAY_SIZE(mmc1_resources),
- .resource = mmc1_resources,
-};
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
-
-static struct omap_mmc_platform_data mmc2_data;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
- {
- .start = OMAP_MMC2_BASE,
- .end = OMAP_MMC2_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC2_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device2 = {
- .name = "mmci-omap",
- .id = 2,
- .dev = {
- .dma_mask = &mmc2_dmamask,
- .platform_data = &mmc2_data,
- },
- .num_resources = ARRAY_SIZE(mmc2_resources),
- .resource = mmc2_resources,
-};
-#endif
-
-static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
-{
- if (cpu_is_omap2430() || cpu_is_omap34xx())
- return;
-
- if (mmc_conf->mmc[0].enabled) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H18_24XX_MMC_CMD);
- omap_cfg_reg(H15_24XX_MMC_CLKI);
- omap_cfg_reg(G19_24XX_MMC_CLKO);
- omap_cfg_reg(F20_24XX_MMC_DAT0);
- omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
- omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
- } else {
- omap_cfg_reg(MMC_CMD);
- omap_cfg_reg(MMC_CLK);
- omap_cfg_reg(MMC_DAT0);
- if (cpu_is_omap1710()) {
- omap_cfg_reg(M15_1710_MMC_CLKI);
- omap_cfg_reg(P19_1710_MMC_CMDDIR);
- omap_cfg_reg(P20_1710_MMC_DATDIR0);
- }
- }
- if (mmc_conf->mmc[0].wire4) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H14_24XX_MMC_DAT1);
- omap_cfg_reg(E19_24XX_MMC_DAT2);
- omap_cfg_reg(D19_24XX_MMC_DAT3);
- omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
- omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
- omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
- } else {
- omap_cfg_reg(MMC_DAT1);
- /* NOTE: DAT2 can be on W10 (here) or M15 */
- if (!mmc_conf->mmc[0].nomux)
- omap_cfg_reg(MMC_DAT2);
- omap_cfg_reg(MMC_DAT3);
- }
- }
-#if defined(CONFIG_ARCH_OMAP2420)
- if (mmc_conf->mmc[0].internal_clock) {
- /*
- * Use internal loop-back in MMC/SDIO
- * Module Input Clock selection
- */
- if (cpu_is_omap24xx()) {
- u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- v |= (1 << 24); /* not used in 243x */
- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
- }
- }
-#endif
- }
-
-#ifdef CONFIG_ARCH_OMAP16XX
- /* block 2 is on newer chips, and has many pinout options */
- if (mmc_conf->mmc[1].enabled) {
- if (!mmc_conf->mmc[1].nomux) {
- omap_cfg_reg(Y8_1610_MMC2_CMD);
- omap_cfg_reg(Y10_1610_MMC2_CLK);
- omap_cfg_reg(R18_1610_MMC2_CLKIN);
- omap_cfg_reg(W8_1610_MMC2_DAT0);
- if (mmc_conf->mmc[1].wire4) {
- omap_cfg_reg(V8_1610_MMC2_DAT1);
- omap_cfg_reg(W15_1610_MMC2_DAT2);
- omap_cfg_reg(R10_1610_MMC2_DAT3);
- }
-
- /* These are needed for the level shifter */
- omap_cfg_reg(V9_1610_MMC2_CMDDIR);
- omap_cfg_reg(V5_1610_MMC2_DATDIR0);
- omap_cfg_reg(W19_1610_MMC2_DATDIR1);
- }
-
- /* Feedback clock must be set on OMAP-1710 MMC2 */
- if (cpu_is_omap1710())
- omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
- MOD_CONF_CTRL_1);
- }
-#endif
-}
-
-static void __init omap_init_mmc(void)
+/*
+ * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
+ */
+void omap_init_mmc(struct omap_mmc_platform_data *info,
+ struct platform_device *pdev1, struct platform_device *pdev2)
{
- const struct omap_mmc_config *mmc_conf;
-
- /* NOTE: assumes MMC was never (wrongly) enabled */
- mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
- if (!mmc_conf)
+ if (!info)
return;
- omap_init_mmc_conf(mmc_conf);
-
- if (mmc_conf->mmc[0].enabled) {
- mmc1_data.conf = mmc_conf->mmc[0];
- (void) platform_device_register(&mmc_omap_device1);
- }
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- if (mmc_conf->mmc[1].enabled) {
- mmc2_data.conf = mmc_conf->mmc[1];
- (void) platform_device_register(&mmc_omap_device2);
- }
-#endif
-}
+ if (info->slots[0].enabled && pdev1)
+ (void) platform_device_register(pdev1);
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
-{
- switch (host) {
- case 1:
- mmc1_data = *info;
- break;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- case 2:
- mmc2_data = *info;
- break;
-#endif
- default:
- BUG();
- }
+ if (info->slots[1].enabled && pdev2)
+ (void) platform_device_register(pdev2);
}
-#else
-static inline void omap_init_mmc(void) {}
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
#endif
/*-------------------------------------------------------------------------*/
@@ -547,7 +357,6 @@ static int __init omap_init_devices(void)
*/
omap_init_dsp();
omap_init_kp();
- omap_init_mmc();
omap_init_uwire();
omap_init_wdt();
omap_init_rng();
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 5444564..9466772 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -16,7 +16,6 @@
/* Different peripheral ids */
#define OMAP_TAG_CLOCK 0x4f01
-#define OMAP_TAG_MMC 0x4f02
#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
#define OMAP_TAG_USB 0x4f04
#define OMAP_TAG_LCD 0x4f05
@@ -35,25 +34,6 @@ struct omap_clock_config {
u8 system_clock_type;
};
-struct omap_mmc_conf {
- unsigned enabled:1;
- /* nomux means "standard" muxing is wrong on this board, and that
- * board-specific code handled it before common init logic.
- */
- unsigned nomux:1;
- /* switch pin can be for card detect (default) or card cover */
- unsigned cover:1;
- /* 4 wire signaling is optional, and is only used for SD/SDIO */
- unsigned wire4:1;
- s16 power_pin;
- s16 switch_pin;
- s16 wp_pin;
-};
-
-struct omap_mmc_config {
- struct omap_mmc_conf mmc[2];
-};
-
struct omap_serial_console_config {
u8 console_uart;
u32 console_speed;
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index 62aa7df..57414c4 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -279,6 +279,7 @@
#define INT_24XX_USB_IRQ_HSOF 79
#define INT_24XX_USB_IRQ_OTG 80
#define INT_24XX_MMC_IRQ 83
+#define INT_24XX_MMC2_IRQ 86
#define INT_34XX_BENCH_MPU_EMUL 3
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index fc15d13..af391e6 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -20,7 +20,6 @@
#define OMAP_MMC_MAX_SLOTS 2
struct omap_mmc_platform_data {
- struct omap_mmc_conf conf;
/* number of slots on board */
unsigned nr_slots:2;
@@ -42,6 +41,27 @@ struct omap_mmc_platform_data {
int (*resume)(struct device *dev, int slot);
struct omap_mmc_slot_data {
+
+ unsigned enabled:1;
+
+ /*
+ * nomux means "standard" muxing is wrong on this board, and
+ * that board-specific code handled it before common init logic.
+ */
+ unsigned nomux:1;
+
+ /* switch pin can be for card detect (default) or card cover */
+ unsigned cover:1;
+
+ /* 4 wire signaling is optional, and is only used for SD/SDIO */
+ unsigned wire4:1;
+
+ /* use the internal clock */
+ unsigned internal_clock:1;
+ s16 power_pin;
+ s16 switch_pin;
+ s16 wp_pin;
+
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
int (* get_ro)(struct device *dev, int slot);
@@ -66,9 +86,30 @@ struct omap_mmc_platform_data {
} slots[OMAP_MMC_MAX_SLOTS];
};
-extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
-
/* called from board-specific card detection service routine */
extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data *info);
+void omap2_init_mmc(struct omap_mmc_platform_data *info);
+void omap_init_mmc(struct omap_mmc_platform_data *info,
+ struct platform_device *pdev1, struct platform_device *pdev2);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data *info)
+{
+}
+static inline void omap2_init_mmc(struct omap_mmc_platform_data *info)
+{
+}
+static inline void omap_init_mmc(struct omap_mmc_platform_data *info,
+ struct platform_device *pdev1, struct platform_device *pdev2)
+{
+}
+#endif
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void __init hsmmc_init(void);
+#endif
+
#endif
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 1b9fc3c..6088294 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
host->slots[id] = slot;
mmc->caps = 0;
- if (host->pdata->conf.wire4)
+ if (host->pdata->slots[id].wire4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_omap_ops;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 21:18 ` Steve Sakoman
@ 2008-09-12 8:04 ` Felipe Balbi
0 siblings, 0 replies; 20+ messages in thread
From: Felipe Balbi @ 2008-09-12 8:04 UTC (permalink / raw)
To: ext Steve Sakoman
Cc: Russell King - ARM Linux, Tony Lindgren, Madhusudhan Chikkature,
linux-omap
On Thu, Sep 11, 2008 at 02:18:38PM -0700, ext Steve Sakoman wrote:
> On Thu, Sep 11, 2008 at 11:13 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>
> > Is there anything else that the MMC stuff is missing at present?
>
> Not an answer to your question, but perhaps an expansion of it (or
> maybe even a demonstration of my ignorance, not sure which) :-)
>
> Has anyone successfully used the omap mmc infrastructure to support an
> SDIO device (say for example the libertas_sdio driver)?
I used a sdio gps with my n800. Had to break the slot cover though :-p
--
balbi
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
2008-09-11 11:35 ` Felipe Balbi
2008-09-11 19:53 ` Tony Lindgren
@ 2008-09-12 12:32 ` Madhusudhan Chikkature
2 siblings, 0 replies; 20+ messages in thread
From: Madhusudhan Chikkature @ 2008-09-12 12:32 UTC (permalink / raw)
To: Jarkko Lavinen, Russell King - ARM Linux; +Cc: Tony Lindgren, linux-omap
Hi Jarko,
My comments inlined.
Regards,
Madhu
----- Original Message -----
From: "Jarkko Lavinen" <jarkko.lavinen@nokia.com>
To: "Russell King - ARM Linux" <linux@arm.linux.org.uk>
Cc: "Tony Lindgren" <tony@atomide.com>; "Madhusudhan Chikkature" <madhu.cr@ti.com>; <linux-omap@vger.kernel.org>
Sent: Thursday, September 11, 2008 4:53 PM
Subject: Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
> On Thu, Sep 11, 2008 at 09:48:28AM +0100, ext Russell King - ARM Linux wrote:
>> So, given my update for this, shouldn't this be something sent almost
>> immediately to me so stuff for mainline isn't falling behind.
>
> Hi Russell and all
>
> Here is a hopefully self-explaining patch, which enables 8-bit
> support similar to the 4-bit support in Omap HSMMC when then mmc
> confifuration from platform data tells it is available.
>
> I have tested it on a testboard with 2.6.26 beased kernel and
> write speed increased some 30..40%.
>
> Cheers,
> Jarkko
>
> ---
>
> From f739457703988da18a5509bd297c4f6ebed83291 Mon Sep 17 00:00:00 2001
> From: Jarkko Lavinen <jarkko.lavinen@nokia.com>
> Date: Thu, 11 Sep 2008 14:15:31 +0300
> Subject: [PATCH] HSMMC: Enable 8-bit transfer when available.
>
> Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
> ---
> arch/arm/plat-omap/devices.c | 8 ++++++--
> arch/arm/plat-omap/include/mach/board.h | 4 +++-
> drivers/mmc/core/mmc.c | 17 +++++++++++++----
> drivers/mmc/host/omap_hsmmc.c | 10 ++++++++++
> include/linux/mmc/host.h | 12 +++++++-----
> 5 files changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
> index 3bd1da2..aa1299f 100644
> --- a/arch/arm/plat-omap/devices.c
> +++ b/arch/arm/plat-omap/devices.c
> @@ -289,13 +289,17 @@ static void __init omap_init_mmc(void)
> mmc = &mmc_conf->mmc[0];
>
> if (cpu_is_omap2430() || cpu_is_omap34xx()) {
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc1_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device1);
> + }
>
> #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
> mmc = &mmc_conf->mmc[1];
> - if (mmc->enabled)
> + if (mmc->enabled) {
> + mmc2_data.conf = *mmc;
> (void) platform_device_register(&mmc_omap_device2);
> + }
> #endif
>
The above changes are already pushed by Tony.
> return;
> diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
> index a1a66ac..cd287dd 100644
> --- a/arch/arm/plat-omap/include/mach/board.h
> +++ b/arch/arm/plat-omap/include/mach/board.h
> @@ -46,8 +46,10 @@ struct omap_mmc_conf {
> unsigned nomux:1;
> /* switch pin can be for card detect (default) or card cover */
> unsigned cover:1;
> - /* 4 wire signaling is optional, and is only used for SD/SDIO */
> + /* 4 and 8 wire signaling are optional */
> unsigned wire4:1;
> + unsigned wire8:1;
> +
> /* use the internal clock */
> unsigned internal_clock:1;
> s16 power_pin;
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index fdd7c76..8c55df3 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -434,13 +434,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> * Activate wide bus (if supported).
> */
> if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
> - (host->caps & MMC_CAP_4_BIT_DATA)) {
> + (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
> + unsigned ext_csd_bit, driver_width;
> +
> + if (host->caps & MMC_CAP_8_BIT_DATA) {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
> + driver_width = MMC_BUS_WIDTH_8;
> + } else {
> + ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
> + driver_width = MMC_BUS_WIDTH_4;
> + }
> +
> err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
> + EXT_CSD_BUS_WIDTH, ext_csd_bit);
> if (err)
> goto free_card;
>
> - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
> + mmc_set_bus_width(card->host, driver_width);
> }
>
> if (!oldcard)
> @@ -624,4 +634,3 @@ err:
>
> return err;
> }
> -
> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index af34871..92ad67e 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -72,6 +72,7 @@
> #define MSBS 1<<5
> #define BCE 1<<1
> #define FOUR_BIT 1 << 1
> +#define DW8 (1 << 5)
> #define CC 0x1
> #define TC 0x02
> #define OD 0x1
> @@ -631,6 +632,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> u16 dsor = 0;
> unsigned long regval;
> unsigned long timeout;
> + u32 con;
>
> switch (ios->power_mode) {
> case MMC_POWER_OFF:
> @@ -641,12 +643,18 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> break;
> }
>
> + con = OMAP_HSMMC_READ(host->base, CON);
> switch (mmc->ios.bus_width) {
> + case MMC_BUS_WIDTH_8:
> + OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
> + break;
> case MMC_BUS_WIDTH_4:
> + OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
> OMAP_HSMMC_WRITE(host->base, HCTL,
> OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
> break;
> case MMC_BUS_WIDTH_1:
> + OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
> OMAP_HSMMC_WRITE(host->base, HCTL,
> OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
> break;
> @@ -814,6 +822,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
>
> if (pdata->conf.wire4)
> mmc->caps |= MMC_CAP_4_BIT_DATA;
> + if (pdata->conf.wire8)
> + mmc->caps |= MMC_CAP_8_BIT_DATA;
Have you tested an SD card after this change? Does the SD card switch to 4-bit mode?
My guess is that it might fail due to the below check in the SD core.
/*
* Switch to wider bus (if supported).
*/
if ((host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
>
> /* Only MMC1 supports 3.0V */
> if (host->id == OMAP_MMC1_DEVID) {
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 9c288c9..ddd8b97 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -41,6 +41,7 @@ struct mmc_ios {
>
> #define MMC_BUS_WIDTH_1 0
> #define MMC_BUS_WIDTH_4 2
> +#define MMC_BUS_WIDTH_8 3
>
> unsigned char timing; /* timing specification used */
>
> @@ -111,11 +112,12 @@ struct mmc_host {
> unsigned long caps; /* Host capabilities */
>
> #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
> -#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
> -#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
> -#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
> -#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
> -#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
> +#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can the host do 8 bit transfers */
> +#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
> +#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
> +#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
> +#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */
> +#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */
>
> /* host specific block data */
> unsigned int max_seg_size; /* see blk_queue_max_segment_size */
> --
> 1.5.6.5
>
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-12 0:48 ` [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data) Tony Lindgren
@ 2008-09-13 9:59 ` Russell King - ARM Linux
2008-09-13 17:11 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Russell King - ARM Linux @ 2008-09-13 9:59 UTC (permalink / raw)
To: Tony Lindgren
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
On Thu, Sep 11, 2008 at 05:48:49PM -0700, Tony Lindgren wrote:
> +static inline void omap1_mmc_mux(struct omap_mmc_platform_data *info)
> +{
> + if (info->slots[0].enabled) {
> + omap_cfg_reg(MMC_CMD);
> + omap_cfg_reg(MMC_CLK);
> + omap_cfg_reg(MMC_DAT0);
> + if (cpu_is_omap1710()) {
> + omap_cfg_reg(M15_1710_MMC_CLKI);
> + omap_cfg_reg(P19_1710_MMC_CMDDIR);
> + omap_cfg_reg(P20_1710_MMC_DATDIR0);
> + }
> + if (info->slots[0].wire4) {
> + omap_cfg_reg(MMC_DAT1);
> + /* NOTE: DAT2 can be on W10 (here) or M15 */
> + if (!info->slots[0].nomux)
> + omap_cfg_reg(MMC_DAT2);
> + omap_cfg_reg(MMC_DAT3);
> + }
> + }
> +
> + /* Block 2 is on newer chips, and has many pinout options */
> + if (cpu_is_omap16xx() && info->slots[1].enabled) {
> + if (!info->slots[1].nomux) {
> + omap_cfg_reg(Y8_1610_MMC2_CMD);
> + omap_cfg_reg(Y10_1610_MMC2_CLK);
> + omap_cfg_reg(R18_1610_MMC2_CLKIN);
> + omap_cfg_reg(W8_1610_MMC2_DAT0);
> + if (info->slots[1].wire4) {
> + omap_cfg_reg(V8_1610_MMC2_DAT1);
> + omap_cfg_reg(W15_1610_MMC2_DAT2);
> + omap_cfg_reg(R10_1610_MMC2_DAT3);
> + }
> +
> + /* These are needed for the level shifter */
> + omap_cfg_reg(V9_1610_MMC2_CMDDIR);
> + omap_cfg_reg(V5_1610_MMC2_DATDIR0);
> + omap_cfg_reg(W19_1610_MMC2_DATDIR1);
> + }
> +
> + /* Feedback clock must be set on OMAP-1710 MMC2 */
> + if (cpu_is_omap1710())
> + omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
> + MOD_CONF_CTRL_1);
> + }
> +}
> +
> +void omap1_init_mmc(struct omap_mmc_platform_data *info)
> +{
> + if (!info)
> + return;
> +
> + omap1_mmc_mux(info);
> + platform_set_drvdata(&omap1_mmc1_device, info);
> +
> + if (cpu_is_omap16xx())
> + platform_set_drvdata(OMAP1_MMC2_DEVICE, info);
> +
> + omap_init_mmc(info, &omap1_mmc1_device, OMAP1_MMC2_DEVICE);
> +}
> +
> +#endif
> +
> +/*-------------------------------------------------------------------------*/
> +
> #if defined(CONFIG_OMAP_STI)
>
> #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
> @@ -203,6 +205,113 @@ static inline void omap_init_mcspi(void) {}
>
> /*-------------------------------------------------------------------------*/
>
> +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
> + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
> +
> +#define OMAP2_MMC1_BASE 0x4809c000
> +#define OMAP2_MMC1_END (OMAP2_MMC1_BASE + 0x1fc)
> +#define OMAP2_MMC1_INT INT_24XX_MMC_IRQ
> +
> +#define OMAP2_MMC2_BASE 0x480b4000
> +#define OMAP2_MMC2_END (OMAP2_MMC2_BASE + 0x1fc)
> +#define OMAP2_MMC2_INT INT_24XX_MMC2_IRQ
> +
> +static u64 omap2_mmc1_dmamask = 0xffffffff;
> +
> +static struct resource omap2_mmc1_resources[] = {
> + {
> + .start = OMAP2_MMC1_BASE,
> + .end = OMAP2_MMC1_END,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = OMAP2_MMC1_INT,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct platform_device omap2_mmc1_device = {
> + .name = "mmci-omap",
> + .id = 1,
> + .dev = {
> + .dma_mask = &omap2_mmc1_dmamask,
> + },
> + .num_resources = ARRAY_SIZE(omap2_mmc1_resources),
> + .resource = omap2_mmc1_resources,
> +};
> +
> +static u64 omap2_mmc2_dmamask = 0xffffffff;
> +
> +static struct resource omap2_mmc2_resources[] = {
> + {
> + .start = OMAP2_MMC2_BASE,
> + .end = OMAP2_MMC2_END,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = OMAP2_MMC2_INT,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct platform_device omap2_mmc2_device = {
> + .name = "mmci-omap",
> + .id = 2,
> + .dev = {
> + .dma_mask = &omap2_mmc2_dmamask,
> + },
> + .num_resources = ARRAY_SIZE(omap2_mmc2_resources),
> + .resource = omap2_mmc2_resources,
> +};
> +
> +static inline void omap2_mmc_mux(struct omap_mmc_platform_data *info)
> +{
> + if (!cpu_is_omap2420())
> + return;
> +
> + if (info->slots[0].enabled) {
> + omap_cfg_reg(H18_24XX_MMC_CMD);
> + omap_cfg_reg(H15_24XX_MMC_CLKI);
> + omap_cfg_reg(G19_24XX_MMC_CLKO);
> + omap_cfg_reg(F20_24XX_MMC_DAT0);
> + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
> + omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
> + if (info->slots[0].wire4) {
> + omap_cfg_reg(H14_24XX_MMC_DAT1);
> + omap_cfg_reg(E19_24XX_MMC_DAT2);
> + omap_cfg_reg(D19_24XX_MMC_DAT3);
> + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
> + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
> + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
> + }
> +
> + /*
> + * Use internal loop-back in MMC/SDIO Module Input Clock
> + * selection
> + */
> + if (info->slots[0].internal_clock) {
> + u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
> + v |= (1 << 24);
> + omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
> + }
> + }
> +}
> +
> +void omap2_init_mmc(struct omap_mmc_platform_data *info)
> +{
> + if (!info)
> + return;
> +
> + omap2_mmc_mux(info);
> + omap2_mmc1_device.dev.platform_data = info;
> + omap2_mmc2_device.dev.platform_data = info;
> + omap_init_mmc(info, &omap2_mmc1_device, &omap2_mmc2_device);
> +}
> +
> +#endif
> +
> +/*-------------------------------------------------------------------------*/
> +
> static int __init omap2_init_devices(void)
> {
> /* please keep these calls, and their implementations above,
Hmm.
How about, in arch/arm/plat-omap/devices.c:
static int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data)
{
struct platform_device *dev;
struct resource res[2];
int ret;
dev = platform_device_alloc("mmci-omap", id);
if (!dev)
return -ENOMEM;
res[0].start = base;
res[0].end = base + size - 1;
res[0].flags = IORESOURCE_MEM;
res[1].start = res[1].end = irq;
res[1].flags = IORESOURCE_IRQ;
ret = platform_device_add_resources(dev, res, ARRAY_SIZE(res));
if (ret == 0)
ret = platform_device_add_data(dev, data, sizeof(*data));
if (ret)
goto fail;
ret = platform_device_add(dev);
if (ret)
goto fail;
return 0;
fail:
platform_device_put(dev);
return ret;
}
Now, for OMAP1 all you need, apart from the MUX function, is:
void omap1_init_mmc(struct omap_mmc_platform_data *info)
{
omap1_mmc_mux(info);
if (info->slots[0].enabled)
omap_mmc_add(0, OMAP1_MMC1_BASE, 0x7f, OMAP1_MMC1_INT, info);
if (cpu_is_omap16xx() && info->slots[1].enabled)
omap_mmc_add(1, OMAP1_MMC2_BASE, 0x7f, OMAP1_MMC2_INT, info);
}
And OMAP2 looks like this:
void omap2_init_mmc(struct omap_mmc_platform_data *info)
{
omap2_mmc_mux(info);
if (info->slots[0].enabled)
omap_mmc_add(0, OMAP2_MMC1_BASE, 0x1fc, OMAP2_MMC1_INT, info);
if (info->slots[1].enabled)
omap_mmc_add(1, OMAP2_MMC2_BASE, 0x1fc, OMAP2_MMC2_INT, info);
}
Maybe these functions should also be taking note of info->nr_slots?
Though I don't particularly like the way 'info' is shared between both
controllers. It's more usual to pass a data structure to drivers
describing just the data for _this_ instance of the device.
Now, when you come across a device with three controllers, you're not
modifying arch/arm/plat-omap/devices.c to add that third controller -
you're just creating the omapN_init_mmc() function with another
omap_mmc_add() line.
As an added bonus, notice the lack of nasty #ifdef's scattered in there
as well.
Oh, and I see little reason for checking for NULL data in these functions -
they clearly don't take NULL data, and if someone passes NULL data, they
deserve to oops - and hopefully they'll fix their code.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-13 9:59 ` Russell King - ARM Linux
@ 2008-09-13 17:11 ` Tony Lindgren
2008-09-16 23:13 ` Tony Lindgren
0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2008-09-13 17:11 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
* Russell King - ARM Linux <linux@arm.linux.org.uk> [080913 03:00]:
> On Thu, Sep 11, 2008 at 05:48:49PM -0700, Tony Lindgren wrote:
> > +static inline void omap1_mmc_mux(struct omap_mmc_platform_data *info)
> > +{
> > + if (info->slots[0].enabled) {
> > + omap_cfg_reg(MMC_CMD);
> > + omap_cfg_reg(MMC_CLK);
> > + omap_cfg_reg(MMC_DAT0);
> > + if (cpu_is_omap1710()) {
> > + omap_cfg_reg(M15_1710_MMC_CLKI);
> > + omap_cfg_reg(P19_1710_MMC_CMDDIR);
> > + omap_cfg_reg(P20_1710_MMC_DATDIR0);
> > + }
> > + if (info->slots[0].wire4) {
> > + omap_cfg_reg(MMC_DAT1);
> > + /* NOTE: DAT2 can be on W10 (here) or M15 */
> > + if (!info->slots[0].nomux)
> > + omap_cfg_reg(MMC_DAT2);
> > + omap_cfg_reg(MMC_DAT3);
> > + }
> > + }
> > +
> > + /* Block 2 is on newer chips, and has many pinout options */
> > + if (cpu_is_omap16xx() && info->slots[1].enabled) {
> > + if (!info->slots[1].nomux) {
> > + omap_cfg_reg(Y8_1610_MMC2_CMD);
> > + omap_cfg_reg(Y10_1610_MMC2_CLK);
> > + omap_cfg_reg(R18_1610_MMC2_CLKIN);
> > + omap_cfg_reg(W8_1610_MMC2_DAT0);
> > + if (info->slots[1].wire4) {
> > + omap_cfg_reg(V8_1610_MMC2_DAT1);
> > + omap_cfg_reg(W15_1610_MMC2_DAT2);
> > + omap_cfg_reg(R10_1610_MMC2_DAT3);
> > + }
> > +
> > + /* These are needed for the level shifter */
> > + omap_cfg_reg(V9_1610_MMC2_CMDDIR);
> > + omap_cfg_reg(V5_1610_MMC2_DATDIR0);
> > + omap_cfg_reg(W19_1610_MMC2_DATDIR1);
> > + }
> > +
> > + /* Feedback clock must be set on OMAP-1710 MMC2 */
> > + if (cpu_is_omap1710())
> > + omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
> > + MOD_CONF_CTRL_1);
> > + }
> > +}
> > +
> > +void omap1_init_mmc(struct omap_mmc_platform_data *info)
> > +{
> > + if (!info)
> > + return;
> > +
> > + omap1_mmc_mux(info);
> > + platform_set_drvdata(&omap1_mmc1_device, info);
> > +
> > + if (cpu_is_omap16xx())
> > + platform_set_drvdata(OMAP1_MMC2_DEVICE, info);
> > +
> > + omap_init_mmc(info, &omap1_mmc1_device, OMAP1_MMC2_DEVICE);
> > +}
> > +
> > +#endif
> > +
> > +/*-------------------------------------------------------------------------*/
> > +
> > #if defined(CONFIG_OMAP_STI)
> >
> > #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
>
>
> > @@ -203,6 +205,113 @@ static inline void omap_init_mcspi(void) {}
> >
> > /*-------------------------------------------------------------------------*/
> >
> > +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
> > + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
> > +
> > +#define OMAP2_MMC1_BASE 0x4809c000
> > +#define OMAP2_MMC1_END (OMAP2_MMC1_BASE + 0x1fc)
> > +#define OMAP2_MMC1_INT INT_24XX_MMC_IRQ
> > +
> > +#define OMAP2_MMC2_BASE 0x480b4000
> > +#define OMAP2_MMC2_END (OMAP2_MMC2_BASE + 0x1fc)
> > +#define OMAP2_MMC2_INT INT_24XX_MMC2_IRQ
> > +
> > +static u64 omap2_mmc1_dmamask = 0xffffffff;
> > +
> > +static struct resource omap2_mmc1_resources[] = {
> > + {
> > + .start = OMAP2_MMC1_BASE,
> > + .end = OMAP2_MMC1_END,
> > + .flags = IORESOURCE_MEM,
> > + },
> > + {
> > + .start = OMAP2_MMC1_INT,
> > + .flags = IORESOURCE_IRQ,
> > + },
> > +};
> > +
> > +static struct platform_device omap2_mmc1_device = {
> > + .name = "mmci-omap",
> > + .id = 1,
> > + .dev = {
> > + .dma_mask = &omap2_mmc1_dmamask,
> > + },
> > + .num_resources = ARRAY_SIZE(omap2_mmc1_resources),
> > + .resource = omap2_mmc1_resources,
> > +};
> > +
> > +static u64 omap2_mmc2_dmamask = 0xffffffff;
> > +
> > +static struct resource omap2_mmc2_resources[] = {
> > + {
> > + .start = OMAP2_MMC2_BASE,
> > + .end = OMAP2_MMC2_END,
> > + .flags = IORESOURCE_MEM,
> > + },
> > + {
> > + .start = OMAP2_MMC2_INT,
> > + .flags = IORESOURCE_IRQ,
> > + },
> > +};
> > +
> > +static struct platform_device omap2_mmc2_device = {
> > + .name = "mmci-omap",
> > + .id = 2,
> > + .dev = {
> > + .dma_mask = &omap2_mmc2_dmamask,
> > + },
> > + .num_resources = ARRAY_SIZE(omap2_mmc2_resources),
> > + .resource = omap2_mmc2_resources,
> > +};
> > +
> > +static inline void omap2_mmc_mux(struct omap_mmc_platform_data *info)
> > +{
> > + if (!cpu_is_omap2420())
> > + return;
> > +
> > + if (info->slots[0].enabled) {
> > + omap_cfg_reg(H18_24XX_MMC_CMD);
> > + omap_cfg_reg(H15_24XX_MMC_CLKI);
> > + omap_cfg_reg(G19_24XX_MMC_CLKO);
> > + omap_cfg_reg(F20_24XX_MMC_DAT0);
> > + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
> > + omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
> > + if (info->slots[0].wire4) {
> > + omap_cfg_reg(H14_24XX_MMC_DAT1);
> > + omap_cfg_reg(E19_24XX_MMC_DAT2);
> > + omap_cfg_reg(D19_24XX_MMC_DAT3);
> > + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
> > + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
> > + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
> > + }
> > +
> > + /*
> > + * Use internal loop-back in MMC/SDIO Module Input Clock
> > + * selection
> > + */
> > + if (info->slots[0].internal_clock) {
> > + u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
> > + v |= (1 << 24);
> > + omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
> > + }
> > + }
> > +}
> > +
> > +void omap2_init_mmc(struct omap_mmc_platform_data *info)
> > +{
> > + if (!info)
> > + return;
> > +
> > + omap2_mmc_mux(info);
> > + omap2_mmc1_device.dev.platform_data = info;
> > + omap2_mmc2_device.dev.platform_data = info;
> > + omap_init_mmc(info, &omap2_mmc1_device, &omap2_mmc2_device);
> > +}
> > +
> > +#endif
> > +
> > +/*-------------------------------------------------------------------------*/
> > +
> > static int __init omap2_init_devices(void)
> > {
> > /* please keep these calls, and their implementations above,
>
> Hmm.
>
> How about, in arch/arm/plat-omap/devices.c:
>
> static int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
> unsigned int irq, struct omap_mmc_platform_data *data)
> {
> struct platform_device *dev;
> struct resource res[2];
> int ret;
>
> dev = platform_device_alloc("mmci-omap", id);
> if (!dev)
> return -ENOMEM;
>
> res[0].start = base;
> res[0].end = base + size - 1;
> res[0].flags = IORESOURCE_MEM;
> res[1].start = res[1].end = irq;
> res[1].flags = IORESOURCE_IRQ;
>
> ret = platform_device_add_resources(dev, res, ARRAY_SIZE(res));
> if (ret == 0)
> ret = platform_device_add_data(dev, data, sizeof(*data));
> if (ret)
> goto fail;
>
> ret = platform_device_add(dev);
> if (ret)
> goto fail;
> return 0;
>
> fail:
> platform_device_put(dev);
> return ret;
> }
>
> Now, for OMAP1 all you need, apart from the MUX function, is:
>
> void omap1_init_mmc(struct omap_mmc_platform_data *info)
> {
> omap1_mmc_mux(info);
>
> if (info->slots[0].enabled)
> omap_mmc_add(0, OMAP1_MMC1_BASE, 0x7f, OMAP1_MMC1_INT, info);
>
> if (cpu_is_omap16xx() && info->slots[1].enabled)
> omap_mmc_add(1, OMAP1_MMC2_BASE, 0x7f, OMAP1_MMC2_INT, info);
> }
>
> And OMAP2 looks like this:
>
> void omap2_init_mmc(struct omap_mmc_platform_data *info)
> {
> omap2_mmc_mux(info);
>
> if (info->slots[0].enabled)
> omap_mmc_add(0, OMAP2_MMC1_BASE, 0x1fc, OMAP2_MMC1_INT, info);
>
> if (info->slots[1].enabled)
> omap_mmc_add(1, OMAP2_MMC2_BASE, 0x1fc, OMAP2_MMC2_INT, info);
> }
Sure, dynamic allocation is better.
> Maybe these functions should also be taking note of info->nr_slots?
> Though I don't particularly like the way 'info' is shared between both
> controllers. It's more usual to pass a data structure to drivers
> describing just the data for _this_ instance of the device.
Let's see if that can be sorted out too. Some implementations multiplex
the slot over I2C.
> Now, when you come across a device with three controllers, you're not
> modifying arch/arm/plat-omap/devices.c to add that third controller -
> you're just creating the omapN_init_mmc() function with another
> omap_mmc_add() line.
>
> As an added bonus, notice the lack of nasty #ifdef's scattered in there
> as well.
Yeah that's good.
> Oh, and I see little reason for checking for NULL data in these functions -
> they clearly don't take NULL data, and if someone passes NULL data, they
> deserve to oops - and hopefully they'll fix their code.
OK
Tony
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-13 17:11 ` Tony Lindgren
@ 2008-09-16 23:13 ` Tony Lindgren
2008-09-17 1:52 ` Tony Lindgren
2008-09-17 7:57 ` Russell King - ARM Linux
0 siblings, 2 replies; 20+ messages in thread
From: Tony Lindgren @ 2008-09-16 23:13 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
[-- Attachment #1: Type: text/plain, Size: 1579 bytes --]
* Tony Lindgren <tony@atomide.com> [080913 10:12]:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [080913 03:00]:
> > On Thu, Sep 11, 2008 at 05:48:49PM -0700, Tony Lindgren wrote:
<snip>
> > Maybe these functions should also be taking note of info->nr_slots?
> > Though I don't particularly like the way 'info' is shared between both
> > controllers. It's more usual to pass a data structure to drivers
> > describing just the data for _this_ instance of the device.
>
> Let's see if that can be sorted out too. Some implementations multiplex
> the slot over I2C.
>
> > Now, when you come across a device with three controllers, you're not
> > modifying arch/arm/plat-omap/devices.c to add that third controller -
> > you're just creating the omapN_init_mmc() function with another
> > omap_mmc_add() line.
> >
> > As an added bonus, notice the lack of nasty #ifdef's scattered in there
> > as well.
>
> Yeah that's good.
>
> > Oh, and I see little reason for checking for NULL data in these functions -
> > they clearly don't take NULL data, and if someone passes NULL data, they
> > deserve to oops - and hopefully they'll fix their code.
>
> OK
Here's the patch updated. If necessary, the patch could be broken into
several parts.
Turns out that the omap1 MMC support has been pretty badly broken for
a while now. I ended up removing all the obviously broken MMC
configurations, and only try to revive the ones that seem like
they should work. I also removed the cover switch handling that needs
to be reimplemented using gpio chip instead.
Regards,
Tony
[-- Attachment #2: omap-mmc-init-v2.patch --]
[-- Type: text/x-diff, Size: 43962 bytes --]
>From 5a8f6008f2e72aa6817e6acba3cef03981022ccf Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Tue, 16 Sep 2008 16:09:29 -0700
Subject: [PATCH] ARM: OMAP: Clean-up MMC device init
Clean-up MMC device init:
- Initialize devices in mach-omap1/devices.c and mach-omap2/devices.c
instead of plat-omap/devices.c
- Allocate MMC devices dynamically as suggested by Russell King
- Remove old struct omap_mmc_config, use struct omap_mmc_platform_data instead
- Fix omap1 mmc clock instance number
- Remove obviously broken MMC configurations. Those can be patched back
in later on when they work
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index ab9ee58..e6ab560 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -12,90 +12,55 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int h2_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int h2_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
+ if (power_on)
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
+ else
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
return 0;
}
-static int h2_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h2_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void h2_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data h2_mmc_data = {
+/*
+ * H2 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = h2_mmc_late_init,
- .cleanup = h2_mmc_cleanup,
+ .dma_mask = 0xffffffff,
.slots[0] = {
- .set_power = h2_mmc_set_power,
- .set_bus_mode = h2_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = h2_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
void __init h2_mmc_init(void)
{
- omap_set_mmc_info(1, &h2_mmc_data);
+ int ret;
+
+ ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
+
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
}
#else
@@ -104,7 +69,4 @@ void __init h2_mmc_init(void)
{
}
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 3b65914..9e106eb 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -348,10 +348,25 @@ static void __init h2_init_smc91x(void)
}
}
+static int h2_tps_setup(struct i2c_client *client, void *context)
+{
+ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
+ TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
+
+ return 0;
+}
+
+static struct tps65010_board tps_board = {
+ .base = H2_TPS_GPIO_BASE,
+ .outmask = 0x0f,
+ .setup = h2_tps_setup,
+};
+
static struct i2c_board_info __initdata h2_i2c_board_info[] = {
{
I2C_BOARD_INFO("tps65010", 0x48),
.irq = OMAP_GPIO_IRQ(58),
+ .platform_data = &tps_board,
}, {
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(2),
@@ -381,15 +396,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h2_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h2_mmc_data;
-
static struct omap_uart_config h2_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -400,7 +406,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
static struct omap_board_config_kernel h2_config[] __initdata = {
{ OMAP_TAG_USB, &h2_usb_config },
- { OMAP_TAG_MMC, &h2_mmc_config },
{ OMAP_TAG_UART, &h2_uart_config },
{ OMAP_TAG_LCD, &h2_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index 3608581..fdfe793 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -12,94 +12,55 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int h3_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
+ if (power_on)
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
+ else
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
return 0;
}
-static int h3_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
- int ret = 0;
-
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- /* Treated on upper level */
-
- return bus_mode;
-}
-
-static int h3_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h3_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void h3_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data h3_mmc_data = {
+/*
+ * H3 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that maybe uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = h3_mmc_late_init,
- .cleanup = h3_mmc_cleanup,
+ .dma_mask = 0xffffffff,
.slots[0] = {
- .set_power = h3_mmc_set_power,
- .set_bus_mode = h3_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = h3_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
void __init h3_mmc_init(void)
{
- omap_set_mmc_info(1, &h3_mmc_data);
+ int ret;
+
+ ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
+
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
}
#else
@@ -108,7 +69,4 @@ void __init h3_mmc_init(void)
{
}
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2ced6d9..ff9bbe2 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h3_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h3_mmc_data;
-
static struct omap_uart_config h3_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
static struct omap_board_config_kernel h3_config[] __initdata = {
{ OMAP_TAG_USB, &h3_usb_config },
- { OMAP_TAG_MMC, &h3_mmc_config },
{ OMAP_TAG_UART, &h3_uart_config },
{ OMAP_TAG_LCD, &h3_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index cbc11be..8b62bde 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -39,6 +39,7 @@
#include <mach/common.h>
#include <mach/mcbsp.h>
#include <mach/omap-alsa.h>
+#include <mach/mmc.h>
static int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
@@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = {
};
#endif
-static struct omap_mmc_config innovator_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = OMAP_MPUIO(3),
- .power_pin = -1, /* FPGA F3 UIO42 */
- .switch_pin = -1, /* FPGA F4 UIO43 */
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (power_on)
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
+ OMAP1510_FPGA_POWER);
+ else
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
+ OMAP1510_FPGA_POWER);
+
+ return 0;
+}
+
+/*
+ * Innovator could use the following functions tested:
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ * - mmc_get_cover_state that uses FPGA F4 UIO43
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .wire4 = 1,
+ .name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+void __init innovator_mmc_init(void)
+{
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
+}
+
+#else
+static void inline innovator_mmc_init(void)
+{
+}
+#endif
+
static struct omap_uart_config innovator_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
{ OMAP_TAG_LCD, NULL },
- { OMAP_TAG_MMC, &innovator_mmc_config },
{ OMAP_TAG_UART, &innovator_uart_config },
};
@@ -412,6 +445,7 @@ static void __init innovator_init(void)
omap_board_config_size = ARRAY_SIZE(innovator_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
+ innovator_mmc_init();
}
static 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 38d9783..c008ed8 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -35,6 +35,7 @@
#include <mach/aic23.h>
#include <mach/omapfb.h>
#include <mach/lcd_mipid.h>
+#include <mach/mmc.h>
#define ADS7846_PENDOWN_GPIO 15
@@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
.pins[0] = 6,
};
-static struct omap_mmc_config nokia770_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
- .mmc[1] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
+if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define NOKIA770_GPIO_MMC_POWER 41
+#define NOKIA770_GPIO_MMC_SWITCH 23
+
+static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (power_on)
+ gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
+ else
+ gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
+
+ return 0;
+}
+
+static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
+{
+ return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
+}
+
+static struct omap_mmc_platform_data nokia770_mmc2_data = {
+ .nr_slots = 1,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .set_power = nokia770_mmc_set_power,
+ .get_cover_state = nokia770_mmc_get_cover_state,
+ .name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
+
+static void __init nokia770_mmc_init(void)
+{
+ int ret;
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
+ if (ret < 0) {
+ gpio_free(NOKIA770_GPIO_MMC_POWER);
+ return;
+ }
+ gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
+
+ /* Only the second MMC controller is used */
+ nokia770_mmc_data[1] = &nokia770_mmc2_data;
+ omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+static inline void nokia770_mmc_init(void)
+{
+}
+#endif
+
static struct omap_board_config_kernel nokia770_config[] __initdata = {
{ OMAP_TAG_USB, NULL },
- { OMAP_TAG_MMC, &nokia770_mmc_config },
};
#if defined(CONFIG_OMAP_DSP)
@@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void)
omap_dsp_init();
ads7846_dev_init();
mipid_dev_init();
+ nokia770_mmc_init();
}
static void __init omap_nokia770_map_io(void)
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index b580436..86e927b 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -195,15 +195,6 @@ static struct omap_usb_config palmte_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmte_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wp_pin = PALMTE_MMC_WP_GPIO,
- .power_pin = PALMTE_MMC_POWER_GPIO,
- .switch_pin = PALMTE_MMC_SWITCH_GPIO,
- },
-};
-
static struct omap_lcd_config palmte_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -316,7 +307,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
static struct omap_board_config_kernel palmte_config[] __initdata = {
{ OMAP_TAG_USB, &palmte_usb_config },
- { OMAP_TAG_MMC, &palmte_mmc_config },
{ OMAP_TAG_LCD, &palmte_lcd_config },
{ OMAP_TAG_UART, &palmte_uart_config },
};
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index e719294..e8116c5 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -267,16 +267,6 @@ static struct omap_usb_config palmz71_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmz71_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 0,
- .wp_pin = PALMZ71_MMC_WP_GPIO,
- .power_pin = -1,
- .switch_pin = PALMZ71_MMC_IN_GPIO,
- },
-};
-
static struct omap_lcd_config palmz71_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -287,7 +277,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {
static struct omap_board_config_kernel palmz71_config[] __initdata = {
{OMAP_TAG_USB, &palmz71_usb_config},
- {OMAP_TAG_MMC, &palmz71_mmc_config},
{OMAP_TAG_LCD, &palmz71_lcd_config},
{OMAP_TAG_UART, &palmz71_uart_config},
};
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 0be4eba..66a4d7d 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -12,30 +12,20 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
int err;
u8 dat = 0;
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
-
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
if (err < 0)
return err;
@@ -48,68 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
}
-static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int sx1_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int sx1_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void sx1_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data sx1_mmc_data = {
+/* Cover switch is at OMAP_MPUIO(3) */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = sx1_mmc_late_init,
- .cleanup = sx1_mmc_cleanup,
.slots[0] = {
- .set_power = sx1_mmc_set_power,
- .set_bus_mode = sx1_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = sx1_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC];
+
void __init sx1_mmc_init(void)
{
- omap_set_mmc_info(1, &sx1_mmc_data);
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
}
#else
@@ -118,7 +63,4 @@ void __init sx1_mmc_init(void)
{
}
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 130bcc6..f915839 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
.pins[2] = 0,
};
-/*----------- MMC -------------------------*/
-
-static struct omap_mmc_config sx1_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 0,
- },
-};
-
/*----------- LCD -------------------------*/
static struct platform_device sx1_lcd_device = {
@@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {
static struct omap_board_config_kernel sx1_config[] __initdata = {
{ OMAP_TAG_USB, &sx1_usb_config },
- { OMAP_TAG_MMC, &sx1_mmc_config },
{ OMAP_TAG_LCD, &sx1_lcd_config },
{ OMAP_TAG_UART, &sx1_uart_config },
};
@@ -443,7 +433,6 @@ static void __init omap_sx1_init(void)
omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */
omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */
omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */
-
}
/*----------------------------------------*/
static void __init omap_sx1_init_irq(void)
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 213b487..2b1631b 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -139,21 +139,12 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
.pins[2] = 6,
};
-static struct omap_mmc_config voiceblue_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .power_pin = 2,
- .switch_pin = -1,
- },
-};
-
static struct omap_uart_config voiceblue_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
static struct omap_board_config_kernel voiceblue_config[] = {
{ OMAP_TAG_USB, &voiceblue_usb_config },
- { OMAP_TAG_MMC, &voiceblue_mmc_config },
{ OMAP_TAG_UART, &voiceblue_uart_config },
};
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 5635b51..c1dcdf1 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -705,7 +705,6 @@ static struct clk bclk_16xx = {
static struct clk mmc1_ck = {
.name = "mmc_ck",
- .id = 1,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
@@ -720,7 +719,7 @@ static struct clk mmc1_ck = {
static struct clk mmc2_ck = {
.name = "mmc_ck",
- .id = 2,
+ .id = 1,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 99982d3..84e26e6 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
/*-------------------------------------------------------------------------*/
@@ -99,6 +100,95 @@ static inline void omap_init_mbox(void)
static inline void omap_init_mbox(void) { }
#endif
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (controller_nr == 0) {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (mmc_controller->slots[0].wire4) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc_controller->slots[0].nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ }
+
+ /* Block 2 is on newer chips, and has many pinout options */
+ if (cpu_is_omap16xx() && controller_nr == 1) {
+ if (!mmc_controller->slots[1].nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (mmc_controller->slots[1].wire4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ }
+}
+
+void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap1_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP1_MMC1_BASE;
+ irq = INT_MMC;
+ break;
+ case 1:
+ if (!cpu_is_omap16xx())
+ return;
+ base = OMAP1_MMC2_BASE;
+ irq = INT_1610_MMC2;
+ break;
+ default:
+ continue;
+ }
+ size = OMAP1_MMC_SIZE;
+
+ omap_mmc_add(i, base, size, irq, mmc_data[i]);
+ };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
#if defined(CONFIG_OMAP_STI)
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 989ad15..eec2fea 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = {
.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
};
-static struct omap_mmc_config apollon_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_usb_config apollon_usb_config __initdata = {
.register_dev = 1,
.hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
@@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
static struct omap_board_config_kernel apollon_config[] = {
{ OMAP_TAG_UART, &apollon_uart_config },
- { OMAP_TAG_MMC, &apollon_mmc_config },
{ OMAP_TAG_USB, &apollon_usb_config },
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 9ba0978..3b34c20 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config generic_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_UART, &generic_uart_config },
- { OMAP_TAG_MMC, &generic_mmc_config },
};
static void __init omap_generic_init(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index d4e3b6f..9f01681 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -371,23 +371,12 @@ static struct omap_uart_config h4_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config h4_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_lcd_config h4_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_UART, &h4_uart_config },
- { OMAP_TAG_MMC, &h4_mmc_config },
{ OMAP_TAG_LCD, &h4_lcd_config },
};
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2ee954a..aa6a7b9 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,10 +19,12 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
+#include <mach/control.h>
#include <mach/tc.h>
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
@@ -203,6 +205,86 @@ static inline void omap_init_mcspi(void) {}
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (cpu_is_omap2420() && controller_nr == 0) {
+ omap_cfg_reg(H18_24XX_MMC_CMD);
+ omap_cfg_reg(H15_24XX_MMC_CLKI);
+ omap_cfg_reg(G19_24XX_MMC_CLKO);
+ omap_cfg_reg(F20_24XX_MMC_DAT0);
+ omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
+ omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+ if (mmc_controller->slots[0].wire4) {
+ omap_cfg_reg(H14_24XX_MMC_DAT1);
+ omap_cfg_reg(E19_24XX_MMC_DAT2);
+ omap_cfg_reg(D19_24XX_MMC_DAT3);
+ omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
+ omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
+ omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+ }
+
+ /*
+ * Use internal loop-back in MMC/SDIO Module Input Clock
+ * selection
+ */
+ if (mmc_controller->slots[0].internal_clock) {
+ u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+ }
+ }
+}
+
+void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap2_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP2_MMC1_BASE;
+ irq = INT_24XX_MMC_IRQ;
+ break;
+ case 1:
+ base = OMAP2_MMC2_BASE;
+ irq = INT_24XX_MMC2_IRQ;
+ break;
+ case 2:
+ if (!cpu_is_omap34xx())
+ return;
+ base = OMAP3_MMC3_BASE;
+ irq = INT_34XX_MMC3_IRQ;
+ break;
+ default:
+ continue;
+ }
+
+ if (cpu_is_omap2420())
+ size = OMAP2420_MMC_SIZE;
+ else
+ size = HSMMC_SIZE;
+
+ omap_mmc_add(i, base, size, irq, mmc_data[i]);
+ };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
static int __init omap2_init_devices(void)
{
/* please keep these calls, and their implementations above,
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index b38410f..5647434 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -198,212 +198,45 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP_MMC1_BASE 0x4809c000
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc)
-#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
+#define OMAP_MMC_NR_RES 2
-#define OMAP_MMC2_BASE 0x480b4000
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc)
-#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ
-
-#else
-
-#define OMAP_MMC1_BASE 0xfffb7800
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f)
-#define OMAP_MMC1_INT INT_MMC
-
-#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f)
-#define OMAP_MMC2_INT INT_1610_MMC2
-
-#endif
-
-static struct omap_mmc_platform_data mmc1_data;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
- {
- .start = OMAP_MMC1_BASE,
- .end = OMAP_MMC1_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC1_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device1 = {
- .name = "mmci-omap",
- .id = 1,
- .dev = {
- .dma_mask = &mmc1_dmamask,
- .platform_data = &mmc1_data,
- },
- .num_resources = ARRAY_SIZE(mmc1_resources),
- .resource = mmc1_resources,
-};
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
-
-static struct omap_mmc_platform_data mmc2_data;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
- {
- .start = OMAP_MMC2_BASE,
- .end = OMAP_MMC2_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC2_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device2 = {
- .name = "mmci-omap",
- .id = 2,
- .dev = {
- .dma_mask = &mmc2_dmamask,
- .platform_data = &mmc2_data,
- },
- .num_resources = ARRAY_SIZE(mmc2_resources),
- .resource = mmc2_resources,
-};
-#endif
-
-static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
-{
- if (cpu_is_omap2430() || cpu_is_omap34xx())
- return;
-
- if (mmc_conf->mmc[0].enabled) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H18_24XX_MMC_CMD);
- omap_cfg_reg(H15_24XX_MMC_CLKI);
- omap_cfg_reg(G19_24XX_MMC_CLKO);
- omap_cfg_reg(F20_24XX_MMC_DAT0);
- omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
- omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
- } else {
- omap_cfg_reg(MMC_CMD);
- omap_cfg_reg(MMC_CLK);
- omap_cfg_reg(MMC_DAT0);
- if (cpu_is_omap1710()) {
- omap_cfg_reg(M15_1710_MMC_CLKI);
- omap_cfg_reg(P19_1710_MMC_CMDDIR);
- omap_cfg_reg(P20_1710_MMC_DATDIR0);
- }
- }
- if (mmc_conf->mmc[0].wire4) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H14_24XX_MMC_DAT1);
- omap_cfg_reg(E19_24XX_MMC_DAT2);
- omap_cfg_reg(D19_24XX_MMC_DAT3);
- omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
- omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
- omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
- } else {
- omap_cfg_reg(MMC_DAT1);
- /* NOTE: DAT2 can be on W10 (here) or M15 */
- if (!mmc_conf->mmc[0].nomux)
- omap_cfg_reg(MMC_DAT2);
- omap_cfg_reg(MMC_DAT3);
- }
- }
-#if defined(CONFIG_ARCH_OMAP2420)
- if (mmc_conf->mmc[0].internal_clock) {
- /*
- * Use internal loop-back in MMC/SDIO
- * Module Input Clock selection
- */
- if (cpu_is_omap24xx()) {
- u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- v |= (1 << 24); /* not used in 243x */
- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
- }
- }
-#endif
- }
-
-#ifdef CONFIG_ARCH_OMAP16XX
- /* block 2 is on newer chips, and has many pinout options */
- if (mmc_conf->mmc[1].enabled) {
- if (!mmc_conf->mmc[1].nomux) {
- omap_cfg_reg(Y8_1610_MMC2_CMD);
- omap_cfg_reg(Y10_1610_MMC2_CLK);
- omap_cfg_reg(R18_1610_MMC2_CLKIN);
- omap_cfg_reg(W8_1610_MMC2_DAT0);
- if (mmc_conf->mmc[1].wire4) {
- omap_cfg_reg(V8_1610_MMC2_DAT1);
- omap_cfg_reg(W15_1610_MMC2_DAT2);
- omap_cfg_reg(R10_1610_MMC2_DAT3);
- }
-
- /* These are needed for the level shifter */
- omap_cfg_reg(V9_1610_MMC2_CMDDIR);
- omap_cfg_reg(V5_1610_MMC2_DATDIR0);
- omap_cfg_reg(W19_1610_MMC2_DATDIR1);
- }
-
- /* Feedback clock must be set on OMAP-1710 MMC2 */
- if (cpu_is_omap1710())
- omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
- MOD_CONF_CTRL_1);
- }
-#endif
-}
-
-static void __init omap_init_mmc(void)
+/*
+ * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
+ */
+int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data)
{
- const struct omap_mmc_config *mmc_conf;
-
- /* NOTE: assumes MMC was never (wrongly) enabled */
- mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
- if (!mmc_conf)
- return;
-
- omap_init_mmc_conf(mmc_conf);
-
- if (mmc_conf->mmc[0].enabled) {
- mmc1_data.conf = mmc_conf->mmc[0];
- (void) platform_device_register(&mmc_omap_device1);
- }
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- if (mmc_conf->mmc[1].enabled) {
- mmc2_data.conf = mmc_conf->mmc[1];
- (void) platform_device_register(&mmc_omap_device2);
- }
-#endif
-}
+ struct platform_device *pdev;
+ struct resource res[OMAP_MMC_NR_RES];
+ int ret;
+
+ pdev = platform_device_alloc("mmci-omap", id);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, NULL, OMAP_MMC_NR_RES * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret == 0)
+ ret = platform_device_add_data(pdev, data, sizeof(*data));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+ return 0;
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
-{
- switch (host) {
- case 1:
- mmc1_data = *info;
- break;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- case 2:
- mmc2_data = *info;
- break;
-#endif
- default:
- BUG();
- }
+fail:
+ platform_device_put(pdev);
+ return ret;
}
-#else
-static inline void omap_init_mmc(void) {}
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
#endif
/*-------------------------------------------------------------------------*/
@@ -547,7 +380,6 @@ static int __init omap_init_devices(void)
*/
omap_init_dsp();
omap_init_kp();
- omap_init_mmc();
omap_init_uwire();
omap_init_wdt();
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 2a050e9..15531c8 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 @@
#ifndef __ASM_ARCH_OMAP_H2_H
#define __ASM_ARCH_OMAP_H2_H
-/* Placeholder for H2 specific defines */
-
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define OMAP1610_ETHR_START 0x04000300
+#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3)
+
extern void h2_mmc_init(void);
-extern void h2_mmc_slot_cover_handler(void *arg, int state);
#endif /* __ASM_ARCH_OMAP_H2_H */
diff --git a/arch/arm/plat-omap/include/mach/board-h3.h b/arch/arm/plat-omap/include/mach/board-h3.h
index 14909dc..1888326 100644
--- a/arch/arm/plat-omap/include/mach/board-h3.h
+++ b/arch/arm/plat-omap/include/mach/board-h3.h
@@ -30,7 +30,9 @@
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
#define OMAP1710_ETHR_START 0x04000300
+#define H3_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H3_TPS_GPIO_MMC_PWR_EN (H3_TPS_GPIO_BASE + 4)
+
extern void h3_mmc_init(void);
-extern void h3_mmc_slot_cover_handler(void *arg, int state);
#endif /* __ASM_ARCH_OMAP_H3_H */
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 5444564..9466772 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -16,7 +16,6 @@
/* Different peripheral ids */
#define OMAP_TAG_CLOCK 0x4f01
-#define OMAP_TAG_MMC 0x4f02
#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
#define OMAP_TAG_USB 0x4f04
#define OMAP_TAG_LCD 0x4f05
@@ -35,25 +34,6 @@ struct omap_clock_config {
u8 system_clock_type;
};
-struct omap_mmc_conf {
- unsigned enabled:1;
- /* nomux means "standard" muxing is wrong on this board, and that
- * board-specific code handled it before common init logic.
- */
- unsigned nomux:1;
- /* switch pin can be for card detect (default) or card cover */
- unsigned cover:1;
- /* 4 wire signaling is optional, and is only used for SD/SDIO */
- unsigned wire4:1;
- s16 power_pin;
- s16 switch_pin;
- s16 wp_pin;
-};
-
-struct omap_mmc_config {
- struct omap_mmc_conf mmc[2];
-};
-
struct omap_serial_console_config {
u8 console_uart;
u32 console_speed;
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index 62aa7df..57414c4 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -279,6 +279,7 @@
#define INT_24XX_USB_IRQ_HSOF 79
#define INT_24XX_USB_IRQ_OTG 80
#define INT_24XX_MMC_IRQ 83
+#define INT_24XX_MMC2_IRQ 86
#define INT_34XX_BENCH_MPU_EMUL 3
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index fc15d13..d1c80c3 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -17,12 +17,25 @@
#include <mach/board.h>
+#define OMAP15XX_NR_MMC 1
+#define OMAP16XX_NR_MMC 2
+#define OMAP1_MMC_SIZE 0x080
+#define OMAP1_MMC1_BASE 0xfffb7800
+#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+
+#define OMAP24XX_NR_MMC 2
+#define OMAP34XX_NR_MMC 3
+#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE
+#define HSMMC_SIZE 0x200
+#define OMAP2_MMC1_BASE 0x4809c000
+#define OMAP2_MMC2_BASE 0x480b4000
+#define OMAP3_MMC3_BASE 0x480ad000
+
#define OMAP_MMC_MAX_SLOTS 2
struct omap_mmc_platform_data {
- struct omap_mmc_conf conf;
- /* number of slots on board */
+ /* number of slots per controller */
unsigned nr_slots:2;
/* set if your board has components or wiring that limits the
@@ -41,7 +54,27 @@ struct omap_mmc_platform_data {
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
+ u64 dma_mask;
+
struct omap_mmc_slot_data {
+
+ /*
+ * nomux means "standard" muxing is wrong on this board, and
+ * that board-specific code handled it before common init logic.
+ */
+ unsigned nomux:1;
+
+ /* switch pin can be for card detect (default) or card cover */
+ unsigned cover:1;
+
+ /* 4 wire signaling is optional, and is only used for SD/SDIO */
+ unsigned wire4:1;
+
+ /* use the internal clock */
+ unsigned internal_clock:1;
+ s16 power_pin;
+ s16 switch_pin;
+
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
int (* get_ro)(struct device *dev, int slot);
@@ -49,8 +82,8 @@ struct omap_mmc_platform_data {
/* return MMC cover switch state, can be NULL if not supported.
*
* possible return values:
- * 0 - open
- * 1 - closed
+ * 0 - closed
+ * 1 - open
*/
int (* get_cover_state)(struct device *dev, int slot);
@@ -66,9 +99,35 @@ struct omap_mmc_platform_data {
} slots[OMAP_MMC_MAX_SLOTS];
};
-extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
-
/* called from board-specific card detection service routine */
extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+int omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void __init hsmmc_init(void);
+#endif
+
#endif
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 1b9fc3c..086e6de 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
host->slots[id] = slot;
mmc->caps = 0;
- if (host->pdata->conf.wire4)
+ if (host->pdata->slots[id].wire4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_omap_ops;
@@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->irq = irq;
host->use_dma = 1;
+ host->dev->dma_mask = &pdata->dma_mask;
host->dma_ch = -1;
host->irq = irq;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-16 23:13 ` Tony Lindgren
@ 2008-09-17 1:52 ` Tony Lindgren
2008-09-17 7:57 ` Russell King - ARM Linux
1 sibling, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2008-09-17 1:52 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
[-- Attachment #1: Type: text/plain, Size: 1779 bytes --]
* Tony Lindgren <tony@atomide.com> [080916 16:14]:
> * Tony Lindgren <tony@atomide.com> [080913 10:12]:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [080913 03:00]:
> > > On Thu, Sep 11, 2008 at 05:48:49PM -0700, Tony Lindgren wrote:
>
> <snip>
>
> > > Maybe these functions should also be taking note of info->nr_slots?
> > > Though I don't particularly like the way 'info' is shared between both
> > > controllers. It's more usual to pass a data structure to drivers
> > > describing just the data for _this_ instance of the device.
> >
> > Let's see if that can be sorted out too. Some implementations multiplex
> > the slot over I2C.
> >
> > > Now, when you come across a device with three controllers, you're not
> > > modifying arch/arm/plat-omap/devices.c to add that third controller -
> > > you're just creating the omapN_init_mmc() function with another
> > > omap_mmc_add() line.
> > >
> > > As an added bonus, notice the lack of nasty #ifdef's scattered in there
> > > as well.
> >
> > Yeah that's good.
> >
> > > Oh, and I see little reason for checking for NULL data in these functions -
> > > they clearly don't take NULL data, and if someone passes NULL data, they
> > > deserve to oops - and hopefully they'll fix their code.
> >
> > OK
>
> Here's the patch updated. If necessary, the patch could be broken into
> several parts.
>
> Turns out that the omap1 MMC support has been pretty badly broken for
> a while now. I ended up removing all the obviously broken MMC
> configurations, and only try to revive the ones that seem like
> they should work. I also removed the cover switch handling that needs
> to be reimplemented using gpio chip instead.
Here's the patch with few compile and whitespace warnings fixed.
> Regards,
>
> Tony
[-- Attachment #2: omap-mmc-init-v3.patch --]
[-- Type: text/x-diff, Size: 43957 bytes --]
>From abd024013c6e66805b31877492172e1b2ac07b75 Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Tue, 16 Sep 2008 18:51:25 -0700
Subject: [PATCH] ARM: OMAP: Clean-up MMC device init
Clean-up MMC device init:
- Initialize devices in mach-omap1/devices.c and mach-omap2/devices.c
instead of plat-omap/devices.c
- Allocate MMC devices dynamically as suggested by Russell King
- Remove old struct omap_mmc_config, use struct omap_mmc_platform_data instead
- Fix omap1 mmc clock instance number
- Remove obviously broken MMC configurations. Those can be patched back
in later on when they work
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index ab9ee58..e6ab560 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -12,90 +12,55 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int h2_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int h2_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
+ if (power_on)
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
+ else
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
return 0;
}
-static int h2_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h2_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void h2_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data h2_mmc_data = {
+/*
+ * H2 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = h2_mmc_late_init,
- .cleanup = h2_mmc_cleanup,
+ .dma_mask = 0xffffffff,
.slots[0] = {
- .set_power = h2_mmc_set_power,
- .set_bus_mode = h2_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = h2_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
void __init h2_mmc_init(void)
{
- omap_set_mmc_info(1, &h2_mmc_data);
+ int ret;
+
+ ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
+
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
}
#else
@@ -104,7 +69,4 @@ void __init h2_mmc_init(void)
{
}
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 3b65914..9e106eb 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -348,10 +348,25 @@ static void __init h2_init_smc91x(void)
}
}
+static int h2_tps_setup(struct i2c_client *client, void *context)
+{
+ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
+ TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
+
+ return 0;
+}
+
+static struct tps65010_board tps_board = {
+ .base = H2_TPS_GPIO_BASE,
+ .outmask = 0x0f,
+ .setup = h2_tps_setup,
+};
+
static struct i2c_board_info __initdata h2_i2c_board_info[] = {
{
I2C_BOARD_INFO("tps65010", 0x48),
.irq = OMAP_GPIO_IRQ(58),
+ .platform_data = &tps_board,
}, {
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(2),
@@ -381,15 +396,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h2_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h2_mmc_data;
-
static struct omap_uart_config h2_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -400,7 +406,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
static struct omap_board_config_kernel h2_config[] __initdata = {
{ OMAP_TAG_USB, &h2_usb_config },
- { OMAP_TAG_MMC, &h2_mmc_config },
{ OMAP_TAG_UART, &h2_uart_config },
{ OMAP_TAG_LCD, &h2_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index 3608581..fdfe793 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -12,94 +12,55 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int h3_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
+ if (power_on)
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
+ else
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
return 0;
}
-static int h3_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
- int ret = 0;
-
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- /* Treated on upper level */
-
- return bus_mode;
-}
-
-static int h3_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h3_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void h3_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data h3_mmc_data = {
+/*
+ * H3 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that maybe uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = h3_mmc_late_init,
- .cleanup = h3_mmc_cleanup,
+ .dma_mask = 0xffffffff,
.slots[0] = {
- .set_power = h3_mmc_set_power,
- .set_bus_mode = h3_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = h3_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
void __init h3_mmc_init(void)
{
- omap_set_mmc_info(1, &h3_mmc_data);
+ int ret;
+
+ ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
+
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
}
#else
@@ -108,7 +69,4 @@ void __init h3_mmc_init(void)
{
}
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2ced6d9..ff9bbe2 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = {
.pins[1] = 3,
};
-static struct omap_mmc_config h3_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 1,
- },
-};
-
-extern struct omap_mmc_platform_data h3_mmc_data;
-
static struct omap_uart_config h3_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
static struct omap_board_config_kernel h3_config[] __initdata = {
{ OMAP_TAG_USB, &h3_usb_config },
- { OMAP_TAG_MMC, &h3_mmc_config },
{ OMAP_TAG_UART, &h3_uart_config },
{ OMAP_TAG_LCD, &h3_lcd_config },
};
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index cbc11be..7a97f6b 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -39,6 +39,7 @@
#include <mach/common.h>
#include <mach/mcbsp.h>
#include <mach/omap-alsa.h>
+#include <mach/mmc.h>
static int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
@@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = {
};
#endif
-static struct omap_mmc_config innovator_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = OMAP_MPUIO(3),
- .power_pin = -1, /* FPGA F3 UIO42 */
- .switch_pin = -1, /* FPGA F4 UIO43 */
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (power_on)
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
+ OMAP1510_FPGA_POWER);
+ else
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
+ OMAP1510_FPGA_POWER);
+
+ return 0;
+}
+
+/*
+ * Innovator could use the following functions tested:
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ * - mmc_get_cover_state that uses FPGA F4 UIO43
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .wire4 = 1,
+ .name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+void __init innovator_mmc_init(void)
+{
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
+}
+
+#else
+static inline void innovator_mmc_init(void)
+{
+}
+#endif
+
static struct omap_uart_config innovator_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
@@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
{ OMAP_TAG_LCD, NULL },
- { OMAP_TAG_MMC, &innovator_mmc_config },
{ OMAP_TAG_UART, &innovator_uart_config },
};
@@ -412,6 +445,7 @@ static void __init innovator_init(void)
omap_board_config_size = ARRAY_SIZE(innovator_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
+ innovator_mmc_init();
}
static 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 38d9783..c008ed8 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -35,6 +35,7 @@
#include <mach/aic23.h>
#include <mach/omapfb.h>
#include <mach/lcd_mipid.h>
+#include <mach/mmc.h>
#define ADS7846_PENDOWN_GPIO 15
@@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
.pins[0] = 6,
};
-static struct omap_mmc_config nokia770_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
- .mmc[1] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
+if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define NOKIA770_GPIO_MMC_POWER 41
+#define NOKIA770_GPIO_MMC_SWITCH 23
+
+static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (power_on)
+ gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
+ else
+ gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
+
+ return 0;
+}
+
+static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
+{
+ return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
+}
+
+static struct omap_mmc_platform_data nokia770_mmc2_data = {
+ .nr_slots = 1,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .set_power = nokia770_mmc_set_power,
+ .get_cover_state = nokia770_mmc_get_cover_state,
+ .name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
+
+static void __init nokia770_mmc_init(void)
+{
+ int ret;
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
+ if (ret < 0) {
+ gpio_free(NOKIA770_GPIO_MMC_POWER);
+ return;
+ }
+ gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
+
+ /* Only the second MMC controller is used */
+ nokia770_mmc_data[1] = &nokia770_mmc2_data;
+ omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+static inline void nokia770_mmc_init(void)
+{
+}
+#endif
+
static struct omap_board_config_kernel nokia770_config[] __initdata = {
{ OMAP_TAG_USB, NULL },
- { OMAP_TAG_MMC, &nokia770_mmc_config },
};
#if defined(CONFIG_OMAP_DSP)
@@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void)
omap_dsp_init();
ads7846_dev_init();
mipid_dev_init();
+ nokia770_mmc_init();
}
static void __init omap_nokia770_map_io(void)
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index b580436..86e927b 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -195,15 +195,6 @@ static struct omap_usb_config palmte_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmte_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wp_pin = PALMTE_MMC_WP_GPIO,
- .power_pin = PALMTE_MMC_POWER_GPIO,
- .switch_pin = PALMTE_MMC_SWITCH_GPIO,
- },
-};
-
static struct omap_lcd_config palmte_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -316,7 +307,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
static struct omap_board_config_kernel palmte_config[] __initdata = {
{ OMAP_TAG_USB, &palmte_usb_config },
- { OMAP_TAG_MMC, &palmte_mmc_config },
{ OMAP_TAG_LCD, &palmte_lcd_config },
{ OMAP_TAG_UART, &palmte_uart_config },
};
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index e719294..e8116c5 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -267,16 +267,6 @@ static struct omap_usb_config palmz71_usb_config __initdata = {
.pins[0] = 2,
};
-static struct omap_mmc_config palmz71_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .wire4 = 0,
- .wp_pin = PALMZ71_MMC_WP_GPIO,
- .power_pin = -1,
- .switch_pin = PALMZ71_MMC_IN_GPIO,
- },
-};
-
static struct omap_lcd_config palmz71_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -287,7 +277,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {
static struct omap_board_config_kernel palmz71_config[] __initdata = {
{OMAP_TAG_USB, &palmz71_usb_config},
- {OMAP_TAG_MMC, &palmz71_mmc_config},
{OMAP_TAG_LCD, &palmz71_lcd_config},
{OMAP_TAG_UART, &palmz71_uart_config},
};
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 0be4eba..66a4d7d 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -12,30 +12,20 @@
* published by the Free Software Foundation.
*/
+#include <linux/platform_device.h>
+
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/gpio.h>
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
int err;
u8 dat = 0;
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
- power_on ? "on" : "off", vdd);
-#endif
-
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
if (err < 0)
return err;
@@ -48,68 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
}
-static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-#ifdef CONFIG_MMC_DEBUG
- dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
- bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
- if (slot != 0) {
- dev_err(dev, "No such slot %d\n", slot + 1);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int sx1_mmc_get_cover_state(struct device *dev, int slot)
-{
- BUG_ON(slot != 0);
-
- return slot_cover_open;
-}
-
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
- if (mmc_device == NULL)
- return;
-
- slot_cover_open = state;
- omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int sx1_mmc_late_init(struct device *dev)
-{
- int ret = 0;
-
- mmc_device = dev;
-
- return ret;
-}
-
-static void sx1_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data sx1_mmc_data = {
+/* Cover switch is at OMAP_MPUIO(3) */
+static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .switch_slot = NULL,
- .init = sx1_mmc_late_init,
- .cleanup = sx1_mmc_cleanup,
.slots[0] = {
- .set_power = sx1_mmc_set_power,
- .set_bus_mode = sx1_mmc_set_bus_mode,
- .get_ro = NULL,
- .get_cover_state = sx1_mmc_get_cover_state,
+ .set_power = mmc_set_power,
.ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
MMC_VDD_32_33 | MMC_VDD_33_34,
.name = "mmcblk",
},
};
+static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC];
+
void __init sx1_mmc_init(void)
{
- omap_set_mmc_info(1, &sx1_mmc_data);
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
}
#else
@@ -118,7 +63,4 @@ void __init sx1_mmc_init(void)
{
}
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
-}
#endif
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 130bcc6..f915839 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
.pins[2] = 0,
};
-/*----------- MMC -------------------------*/
-
-static struct omap_mmc_config sx1_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 0,
- },
-};
-
/*----------- LCD -------------------------*/
static struct platform_device sx1_lcd_device = {
@@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {
static struct omap_board_config_kernel sx1_config[] __initdata = {
{ OMAP_TAG_USB, &sx1_usb_config },
- { OMAP_TAG_MMC, &sx1_mmc_config },
{ OMAP_TAG_LCD, &sx1_lcd_config },
{ OMAP_TAG_UART, &sx1_uart_config },
};
@@ -443,7 +433,6 @@ static void __init omap_sx1_init(void)
omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */
omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */
omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */
-
}
/*----------------------------------------*/
static void __init omap_sx1_init_irq(void)
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 213b487..2b1631b 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -139,21 +139,12 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
.pins[2] = 6,
};
-static struct omap_mmc_config voiceblue_mmc_config __initdata = {
- .mmc[0] = {
- .enabled = 1,
- .power_pin = 2,
- .switch_pin = -1,
- },
-};
-
static struct omap_uart_config voiceblue_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
static struct omap_board_config_kernel voiceblue_config[] = {
{ OMAP_TAG_USB, &voiceblue_usb_config },
- { OMAP_TAG_MMC, &voiceblue_mmc_config },
{ OMAP_TAG_UART, &voiceblue_uart_config },
};
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 5635b51..c1dcdf1 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -705,7 +705,6 @@ static struct clk bclk_16xx = {
static struct clk mmc1_ck = {
.name = "mmc_ck",
- .id = 1,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
@@ -720,7 +719,7 @@ static struct clk mmc1_ck = {
static struct clk mmc2_ck = {
.name = "mmc_ck",
- .id = 2,
+ .id = 1,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 99982d3..4801513 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
/*-------------------------------------------------------------------------*/
@@ -99,6 +100,95 @@ static inline void omap_init_mbox(void)
static inline void omap_init_mbox(void) { }
#endif
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (controller_nr == 0) {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (mmc_controller->slots[0].wire4) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc_controller->slots[0].nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ }
+
+ /* Block 2 is on newer chips, and has many pinout options */
+ if (cpu_is_omap16xx() && controller_nr == 1) {
+ if (!mmc_controller->slots[1].nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (mmc_controller->slots[1].wire4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ }
+}
+
+void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap1_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP1_MMC1_BASE;
+ irq = INT_MMC;
+ break;
+ case 1:
+ if (!cpu_is_omap16xx())
+ return;
+ base = OMAP1_MMC2_BASE;
+ irq = INT_1610_MMC2;
+ break;
+ default:
+ continue;
+ }
+ size = OMAP1_MMC_SIZE;
+
+ omap_mmc_add(i, base, size, irq, mmc_data[i]);
+ };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
#if defined(CONFIG_OMAP_STI)
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 989ad15..eec2fea 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = {
.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
};
-static struct omap_mmc_config apollon_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_usb_config apollon_usb_config __initdata = {
.register_dev = 1,
.hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
@@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
static struct omap_board_config_kernel apollon_config[] = {
{ OMAP_TAG_UART, &apollon_uart_config },
- { OMAP_TAG_MMC, &apollon_mmc_config },
{ OMAP_TAG_USB, &apollon_usb_config },
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 9ba0978..3b34c20 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config generic_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 0,
- .wire4 = 0,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_UART, &generic_uart_config },
- { OMAP_TAG_MMC, &generic_mmc_config },
};
static void __init omap_generic_init(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index d4e3b6f..9f01681 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -371,23 +371,12 @@ static struct omap_uart_config h4_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
};
-static struct omap_mmc_config h4_mmc_config __initdata = {
- .mmc [0] = {
- .enabled = 1,
- .wire4 = 1,
- .wp_pin = -1,
- .power_pin = -1,
- .switch_pin = -1,
- },
-};
-
static struct omap_lcd_config h4_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_UART, &h4_uart_config },
- { OMAP_TAG_MMC, &h4_mmc_config },
{ OMAP_TAG_LCD, &h4_lcd_config },
};
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2ee954a..3bbb76b 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,10 +19,12 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
+#include <mach/control.h>
#include <mach/tc.h>
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
+#include <mach/mmc.h>
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
@@ -203,6 +205,86 @@ static inline void omap_init_mcspi(void) {}
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (cpu_is_omap2420() && controller_nr == 0) {
+ omap_cfg_reg(H18_24XX_MMC_CMD);
+ omap_cfg_reg(H15_24XX_MMC_CLKI);
+ omap_cfg_reg(G19_24XX_MMC_CLKO);
+ omap_cfg_reg(F20_24XX_MMC_DAT0);
+ omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
+ omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+ if (mmc_controller->slots[0].wire4) {
+ omap_cfg_reg(H14_24XX_MMC_DAT1);
+ omap_cfg_reg(E19_24XX_MMC_DAT2);
+ omap_cfg_reg(D19_24XX_MMC_DAT3);
+ omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
+ omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
+ omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+ }
+
+ /*
+ * Use internal loop-back in MMC/SDIO Module Input Clock
+ * selection
+ */
+ if (mmc_controller->slots[0].internal_clock) {
+ u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+ }
+ }
+}
+
+void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap2_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP2_MMC1_BASE;
+ irq = INT_24XX_MMC_IRQ;
+ break;
+ case 1:
+ base = OMAP2_MMC2_BASE;
+ irq = INT_24XX_MMC2_IRQ;
+ break;
+ case 2:
+ if (!cpu_is_omap34xx())
+ return;
+ base = OMAP3_MMC3_BASE;
+ irq = INT_34XX_MMC3_IRQ;
+ break;
+ default:
+ continue;
+ }
+
+ if (cpu_is_omap2420())
+ size = OMAP2420_MMC_SIZE;
+ else
+ size = HSMMC_SIZE;
+
+ omap_mmc_add(i, base, size, irq, mmc_data[i]);
+ };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
static int __init omap2_init_devices(void)
{
/* please keep these calls, and their implementations above,
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index b38410f..85f2b2b 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -198,212 +198,45 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP_MMC1_BASE 0x4809c000
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc)
-#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
+#define OMAP_MMC_NR_RES 2
-#define OMAP_MMC2_BASE 0x480b4000
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc)
-#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ
-
-#else
-
-#define OMAP_MMC1_BASE 0xfffb7800
-#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f)
-#define OMAP_MMC1_INT INT_MMC
-
-#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
-#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f)
-#define OMAP_MMC2_INT INT_1610_MMC2
-
-#endif
-
-static struct omap_mmc_platform_data mmc1_data;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
- {
- .start = OMAP_MMC1_BASE,
- .end = OMAP_MMC1_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC1_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device1 = {
- .name = "mmci-omap",
- .id = 1,
- .dev = {
- .dma_mask = &mmc1_dmamask,
- .platform_data = &mmc1_data,
- },
- .num_resources = ARRAY_SIZE(mmc1_resources),
- .resource = mmc1_resources,
-};
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
-
-static struct omap_mmc_platform_data mmc2_data;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
- {
- .start = OMAP_MMC2_BASE,
- .end = OMAP_MMC2_END,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP_MMC2_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device2 = {
- .name = "mmci-omap",
- .id = 2,
- .dev = {
- .dma_mask = &mmc2_dmamask,
- .platform_data = &mmc2_data,
- },
- .num_resources = ARRAY_SIZE(mmc2_resources),
- .resource = mmc2_resources,
-};
-#endif
-
-static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
-{
- if (cpu_is_omap2430() || cpu_is_omap34xx())
- return;
-
- if (mmc_conf->mmc[0].enabled) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H18_24XX_MMC_CMD);
- omap_cfg_reg(H15_24XX_MMC_CLKI);
- omap_cfg_reg(G19_24XX_MMC_CLKO);
- omap_cfg_reg(F20_24XX_MMC_DAT0);
- omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
- omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
- } else {
- omap_cfg_reg(MMC_CMD);
- omap_cfg_reg(MMC_CLK);
- omap_cfg_reg(MMC_DAT0);
- if (cpu_is_omap1710()) {
- omap_cfg_reg(M15_1710_MMC_CLKI);
- omap_cfg_reg(P19_1710_MMC_CMDDIR);
- omap_cfg_reg(P20_1710_MMC_DATDIR0);
- }
- }
- if (mmc_conf->mmc[0].wire4) {
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(H14_24XX_MMC_DAT1);
- omap_cfg_reg(E19_24XX_MMC_DAT2);
- omap_cfg_reg(D19_24XX_MMC_DAT3);
- omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
- omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
- omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
- } else {
- omap_cfg_reg(MMC_DAT1);
- /* NOTE: DAT2 can be on W10 (here) or M15 */
- if (!mmc_conf->mmc[0].nomux)
- omap_cfg_reg(MMC_DAT2);
- omap_cfg_reg(MMC_DAT3);
- }
- }
-#if defined(CONFIG_ARCH_OMAP2420)
- if (mmc_conf->mmc[0].internal_clock) {
- /*
- * Use internal loop-back in MMC/SDIO
- * Module Input Clock selection
- */
- if (cpu_is_omap24xx()) {
- u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- v |= (1 << 24); /* not used in 243x */
- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
- }
- }
-#endif
- }
-
-#ifdef CONFIG_ARCH_OMAP16XX
- /* block 2 is on newer chips, and has many pinout options */
- if (mmc_conf->mmc[1].enabled) {
- if (!mmc_conf->mmc[1].nomux) {
- omap_cfg_reg(Y8_1610_MMC2_CMD);
- omap_cfg_reg(Y10_1610_MMC2_CLK);
- omap_cfg_reg(R18_1610_MMC2_CLKIN);
- omap_cfg_reg(W8_1610_MMC2_DAT0);
- if (mmc_conf->mmc[1].wire4) {
- omap_cfg_reg(V8_1610_MMC2_DAT1);
- omap_cfg_reg(W15_1610_MMC2_DAT2);
- omap_cfg_reg(R10_1610_MMC2_DAT3);
- }
-
- /* These are needed for the level shifter */
- omap_cfg_reg(V9_1610_MMC2_CMDDIR);
- omap_cfg_reg(V5_1610_MMC2_DATDIR0);
- omap_cfg_reg(W19_1610_MMC2_DATDIR1);
- }
-
- /* Feedback clock must be set on OMAP-1710 MMC2 */
- if (cpu_is_omap1710())
- omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
- MOD_CONF_CTRL_1);
- }
-#endif
-}
-
-static void __init omap_init_mmc(void)
+/*
+ * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
+ */
+int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data)
{
- const struct omap_mmc_config *mmc_conf;
-
- /* NOTE: assumes MMC was never (wrongly) enabled */
- mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
- if (!mmc_conf)
- return;
-
- omap_init_mmc_conf(mmc_conf);
-
- if (mmc_conf->mmc[0].enabled) {
- mmc1_data.conf = mmc_conf->mmc[0];
- (void) platform_device_register(&mmc_omap_device1);
- }
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- if (mmc_conf->mmc[1].enabled) {
- mmc2_data.conf = mmc_conf->mmc[1];
- (void) platform_device_register(&mmc_omap_device2);
- }
-#endif
-}
+ struct platform_device *pdev;
+ struct resource res[OMAP_MMC_NR_RES];
+ int ret;
+
+ pdev = platform_device_alloc("mmci-omap", id);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret == 0)
+ ret = platform_device_add_data(pdev, data, sizeof(*data));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+ return 0;
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
-{
- switch (host) {
- case 1:
- mmc1_data = *info;
- break;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
- defined(CONFIG_ARCH_OMAP34XX)
- case 2:
- mmc2_data = *info;
- break;
-#endif
- default:
- BUG();
- }
+fail:
+ platform_device_put(pdev);
+ return ret;
}
-#else
-static inline void omap_init_mmc(void) {}
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
#endif
/*-------------------------------------------------------------------------*/
@@ -547,7 +380,6 @@ static int __init omap_init_devices(void)
*/
omap_init_dsp();
omap_init_kp();
- omap_init_mmc();
omap_init_uwire();
omap_init_wdt();
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 2a050e9..15531c8 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 @@
#ifndef __ASM_ARCH_OMAP_H2_H
#define __ASM_ARCH_OMAP_H2_H
-/* Placeholder for H2 specific defines */
-
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define OMAP1610_ETHR_START 0x04000300
+#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3)
+
extern void h2_mmc_init(void);
-extern void h2_mmc_slot_cover_handler(void *arg, int state);
#endif /* __ASM_ARCH_OMAP_H2_H */
diff --git a/arch/arm/plat-omap/include/mach/board-h3.h b/arch/arm/plat-omap/include/mach/board-h3.h
index 14909dc..1888326 100644
--- a/arch/arm/plat-omap/include/mach/board-h3.h
+++ b/arch/arm/plat-omap/include/mach/board-h3.h
@@ -30,7 +30,9 @@
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
#define OMAP1710_ETHR_START 0x04000300
+#define H3_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H3_TPS_GPIO_MMC_PWR_EN (H3_TPS_GPIO_BASE + 4)
+
extern void h3_mmc_init(void);
-extern void h3_mmc_slot_cover_handler(void *arg, int state);
#endif /* __ASM_ARCH_OMAP_H3_H */
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 5444564..9466772 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -16,7 +16,6 @@
/* Different peripheral ids */
#define OMAP_TAG_CLOCK 0x4f01
-#define OMAP_TAG_MMC 0x4f02
#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
#define OMAP_TAG_USB 0x4f04
#define OMAP_TAG_LCD 0x4f05
@@ -35,25 +34,6 @@ struct omap_clock_config {
u8 system_clock_type;
};
-struct omap_mmc_conf {
- unsigned enabled:1;
- /* nomux means "standard" muxing is wrong on this board, and that
- * board-specific code handled it before common init logic.
- */
- unsigned nomux:1;
- /* switch pin can be for card detect (default) or card cover */
- unsigned cover:1;
- /* 4 wire signaling is optional, and is only used for SD/SDIO */
- unsigned wire4:1;
- s16 power_pin;
- s16 switch_pin;
- s16 wp_pin;
-};
-
-struct omap_mmc_config {
- struct omap_mmc_conf mmc[2];
-};
-
struct omap_serial_console_config {
u8 console_uart;
u32 console_speed;
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index 62aa7df..57414c4 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -279,6 +279,7 @@
#define INT_24XX_USB_IRQ_HSOF 79
#define INT_24XX_USB_IRQ_OTG 80
#define INT_24XX_MMC_IRQ 83
+#define INT_24XX_MMC2_IRQ 86
#define INT_34XX_BENCH_MPU_EMUL 3
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index fc15d13..d1c80c3 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -17,12 +17,25 @@
#include <mach/board.h>
+#define OMAP15XX_NR_MMC 1
+#define OMAP16XX_NR_MMC 2
+#define OMAP1_MMC_SIZE 0x080
+#define OMAP1_MMC1_BASE 0xfffb7800
+#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+
+#define OMAP24XX_NR_MMC 2
+#define OMAP34XX_NR_MMC 3
+#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE
+#define HSMMC_SIZE 0x200
+#define OMAP2_MMC1_BASE 0x4809c000
+#define OMAP2_MMC2_BASE 0x480b4000
+#define OMAP3_MMC3_BASE 0x480ad000
+
#define OMAP_MMC_MAX_SLOTS 2
struct omap_mmc_platform_data {
- struct omap_mmc_conf conf;
- /* number of slots on board */
+ /* number of slots per controller */
unsigned nr_slots:2;
/* set if your board has components or wiring that limits the
@@ -41,7 +54,27 @@ struct omap_mmc_platform_data {
int (*suspend)(struct device *dev, int slot);
int (*resume)(struct device *dev, int slot);
+ u64 dma_mask;
+
struct omap_mmc_slot_data {
+
+ /*
+ * nomux means "standard" muxing is wrong on this board, and
+ * that board-specific code handled it before common init logic.
+ */
+ unsigned nomux:1;
+
+ /* switch pin can be for card detect (default) or card cover */
+ unsigned cover:1;
+
+ /* 4 wire signaling is optional, and is only used for SD/SDIO */
+ unsigned wire4:1;
+
+ /* use the internal clock */
+ unsigned internal_clock:1;
+ s16 power_pin;
+ s16 switch_pin;
+
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
int (* get_ro)(struct device *dev, int slot);
@@ -49,8 +82,8 @@ struct omap_mmc_platform_data {
/* return MMC cover switch state, can be NULL if not supported.
*
* possible return values:
- * 0 - open
- * 1 - closed
+ * 0 - closed
+ * 1 - open
*/
int (* get_cover_state)(struct device *dev, int slot);
@@ -66,9 +99,35 @@ struct omap_mmc_platform_data {
} slots[OMAP_MMC_MAX_SLOTS];
};
-extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
-
/* called from board-specific card detection service routine */
extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+int omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
+ unsigned int irq, struct omap_mmc_platform_data *data)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void __init hsmmc_init(void);
+#endif
+
#endif
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 1b9fc3c..086e6de 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
host->slots[id] = slot;
mmc->caps = 0;
- if (host->pdata->conf.wire4)
+ if (host->pdata->slots[id].wire4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_omap_ops;
@@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->irq = irq;
host->use_dma = 1;
+ host->dev->dma_mask = &pdata->dma_mask;
host->dma_ch = -1;
host->irq = irq;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-16 23:13 ` Tony Lindgren
2008-09-17 1:52 ` Tony Lindgren
@ 2008-09-17 7:57 ` Russell King - ARM Linux
2008-09-24 9:02 ` Tony Lindgren
1 sibling, 1 reply; 20+ messages in thread
From: Russell King - ARM Linux @ 2008-09-17 7:57 UTC (permalink / raw)
To: Tony Lindgren
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
On Tue, Sep 16, 2008 at 04:13:57PM -0700, Tony Lindgren wrote:
> > OK
>
> Here's the patch updated. If necessary, the patch could be broken into
> several parts.
I've already got a patch doing what I've outlined (and some other stuff)
I just haven't had time to finish it off to email out yet.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data
2008-09-11 11:35 ` Felipe Balbi
@ 2008-09-20 10:02 ` Pierre Ossman
0 siblings, 0 replies; 20+ messages in thread
From: Pierre Ossman @ 2008-09-20 10:02 UTC (permalink / raw)
To: felipe.balbi
Cc: ext Jarkko Lavinen, Russell King - ARM Linux, Tony Lindgren,
Madhusudhan Chikkature, linux-omap
[-- Attachment #1: Type: text/plain, Size: 1897 bytes --]
On Thu, 11 Sep 2008 14:35:04 +0300
Felipe Balbi <felipe.balbi@nokia.com> wrote:
>
> Maybe Pierre should be watching this patch as well. I'm putting him in
> the loop.
>
Thanks ;)
When/if you want to submit this, put the core stuff in a separate patch.
> > @@ -111,11 +112,12 @@ struct mmc_host {
> > unsigned long caps; /* Host capabilities */
> >
> > #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
> > -#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
> > -#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
> > -#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
> > -#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
> > -#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
> > +#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can the host do 8 bit transfers */
> > +#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
> > +#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
> > +#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
> > +#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */
> > +#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */
>
> This would require changes to all other mmc host drivers, right ?
> How about:
>
> +#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */
>
This is not an exposed ABI so this kind of fiddling it not a problem.
Rgds
--
-- Pierre Ossman
Linux kernel, MMC maintainer http://www.kernel.org
rdesktop, core developer http://www.rdesktop.org
WARNING: This correspondence is being monitored by the
Swedish government. Make sure your server uses encryption
for SMTP traffic and consider using PGP for end-to-end
encryption.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data)
2008-09-17 7:57 ` Russell King - ARM Linux
@ 2008-09-24 9:02 ` Tony Lindgren
0 siblings, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2008-09-24 9:02 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Madhusudhan Chikkature, linux-omap, Pierre Ossman,
Jarkko Lavinen (NMP/Helsinki), Carlos Aguiar
* Russell King - ARM Linux <linux@arm.linux.org.uk> [080917 10:58]:
> On Tue, Sep 16, 2008 at 04:13:57PM -0700, Tony Lindgren wrote:
> > > OK
> >
> > Here's the patch updated. If necessary, the patch could be broken into
> > several parts.
>
> I've already got a patch doing what I've outlined (and some other stuff)
> I just haven't had time to finish it off to email out yet.
I guess I'll push my MMC init fixes to l-o tree and start working a
set of patches for you. If you have your MMC init patch somewhere,
let me know and I'll merge them with my patch. Sounds like they pretty
much do the same, so merging should be trivial.
Tony
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2008-09-24 9:02 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-13 6:13 [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Madhusudhan Chikkature
2008-09-10 23:56 ` Tony Lindgren
2008-09-11 8:48 ` Russell King - ARM Linux
2008-09-11 9:13 ` Russell King - ARM Linux
2008-09-11 17:33 ` Tony Lindgren
2008-09-11 18:13 ` Russell King - ARM Linux
2008-09-11 21:18 ` Steve Sakoman
2008-09-12 8:04 ` Felipe Balbi
2008-09-12 0:48 ` [PATCH] ARM: OMAP: Clean-up MMC device init (Was: [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data) Tony Lindgren
2008-09-13 9:59 ` Russell King - ARM Linux
2008-09-13 17:11 ` Tony Lindgren
2008-09-16 23:13 ` Tony Lindgren
2008-09-17 1:52 ` Tony Lindgren
2008-09-17 7:57 ` Russell King - ARM Linux
2008-09-24 9:02 ` Tony Lindgren
2008-09-11 11:23 ` [PATCH]Enable 4-bit in HSMMC1 and HSMMC2 platform data Jarkko Lavinen
2008-09-11 11:35 ` Felipe Balbi
2008-09-20 10:02 ` Pierre Ossman
2008-09-11 19:53 ` Tony Lindgren
2008-09-12 12:32 ` Madhusudhan Chikkature
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox