[coldfire]: switch to 2.6.38
[openwrt/svn-archive/archive.git] / target / linux / coldfire / patches / 028-Add-SD-MMC-SDIO-over-SPI-support-for-MCF54451-and-MC.patch
1 From d1b6aa1480c937e326bef99746299cd004a51f28 Mon Sep 17 00:00:00 2001
2 From: Alison Wang <b18965@freescale.com>
3 Date: Thu, 4 Aug 2011 09:59:46 +0800
4 Subject: [PATCH 28/52] Add SD/MMC/SDIO over SPI support for MCF54451 and MCF54418
5
6 Add SD/MMC/SDIO over SPI support for MCF54451 and MCF54418.
7
8 Signed-off-by: Alison Wang <b18965@freescale.com>
9 ---
10 drivers/mmc/core/sdio.c | 9 +++++-
11 drivers/mmc/host/Kconfig | 35 +++++++++++++++++++++
12 drivers/mmc/host/mmc_spi.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
13 3 files changed, 116 insertions(+), 1 deletions(-)
14
15 --- a/drivers/mmc/core/sdio.c
16 +++ b/drivers/mmc/core/sdio.c
17 @@ -566,8 +566,15 @@ static void mmc_sdio_detect(struct mmc_h
18 /*
19 * Just check if our card has been removed.
20 */
21 +#if defined(M54451_SD_HW_DETECT)
22 + {
23 + unsigned char x;
24 + err = mmc_io_rw_direct(host->card, 0, 0,
25 + SDIO_FBR_BASE(0) + SDIO_FBR_CIS + 0, 0, &x);
26 + }
27 +#else
28 err = mmc_select_card(host->card);
29 -
30 +#endif
31 mmc_release_host(host);
32
33 /*
34 --- a/drivers/mmc/host/Kconfig
35 +++ b/drivers/mmc/host/Kconfig
36 @@ -368,6 +368,41 @@ config MMC_SPI
37
38 If unsure, or if your system has no SPI master driver, say N.
39
40 +config M54451_SD_HW_DETECT
41 + tristate "use extern IRQ7 to detect SD/MMC card"
42 + depends on MMC_SPI && M54451
43 + default y
44 + help
45 + MMC/SD interface on 54551evb was over SPI. Enable this option will
46 + use irq7 to dectect the card inserting/removing.
47 +
48 +config M5441X_SD_HW_DETECT
49 + tristate "use extern IRQ to detect SD/MMC card"
50 + depends on MMC_SPI && M5441X
51 + help
52 + MMC/SD interface on 54418evb was over SPI. Enable this option will
53 + use irq7 or irq1 to dectect the card inserting/removing.
54 +
55 +choice
56 + prompt "MMC/SD card detect "
57 + depends on M5441X_SD_HW_DETECT
58 +
59 +config DETECT_USE_EXTERN_IRQ7
60 + tristate "based extern IRQ7"
61 + depends on M5441X_SD_HW_DETECT
62 + help
63 + MMC/SD cards using spi controller,
64 + we use the extern irq7 to detect card.
65 +
66 +config DETECT_USE_EXTERN_IRQ1
67 + tristate "based extern IRQ1"
68 + depends on M5441X_SD_HW_DETECT
69 + help
70 + MMC/SD cards using spi controller,
71 + we use the extern irq1 to detect card.
72 +
73 +endchoice
74 +
75 config MMC_S3C
76 tristate "Samsung S3C SD/MMC Card Interface support"
77 depends on ARCH_S3C2410
78 --- a/drivers/mmc/host/mmc_spi.c
79 +++ b/drivers/mmc/host/mmc_spi.c
80 @@ -9,6 +9,10 @@
81 * (C) Copyright 2007, ATRON electronic GmbH,
82 * Jan Nikitenko <jan.nikitenko@gmail.com>
83 *
84 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
85 + * Modified for M54451EVB/M54418TWR boards.
86 + * Shrek Wu <b16972@freescale.com>
87 + * Jingchang Lu <b22599@freescale.com>
88 *
89 * This program is free software; you can redistribute it and/or modify
90 * it under the terms of the GNU General Public License as published by
91 @@ -32,6 +36,14 @@
92 #include <linux/crc7.h>
93 #include <linux/crc-itu-t.h>
94 #include <linux/scatterlist.h>
95 +#if defined(CONFIG_M54451_SD_HW_DETECT)
96 +#include <asm/mcf5445x_eport.h>
97 +#include <asm/mcf5445x_intc.h>
98 +#include <asm/mcfsim.h>
99 +#elif defined(CONFIG_M5441X_SD_HW_DETECT)
100 +#include <asm/mcf5441x_eport.h>
101 +#include <asm/mcfsim.h>
102 +#endif
103
104 #include <linux/mmc/host.h>
105 #include <linux/mmc/mmc.h> /* for R1_SPI_* bit values */
106 @@ -268,6 +280,9 @@ static int mmc_spi_response_get(struct m
107 unsigned short rotator;
108 int i;
109 char tag[32];
110 +#if defined(CONFIG_M54451_SD_HW_DETECT) || defined(CONFIG_M5441X_SD_HW_DETECT)
111 + u8 oldcp_value = 0;
112 +#endif
113
114 snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s",
115 cmd->opcode, maptype(cmd));
116 @@ -278,6 +293,9 @@ static int mmc_spi_response_get(struct m
117 * first byte. After STOP_TRANSMISSION command it may include
118 * two data bits, but otherwise it's all ones.
119 */
120 +#if defined(CONFIG_M54451_SD_HW_DETECT) || defined(CONFIG_M5441X_SD_HW_DETECT)
121 + oldcp_value = *cp;
122 +#endif
123 cp += 8;
124 while (cp < end && *cp == 0xff)
125 cp++;
126 @@ -310,6 +328,15 @@ static int mmc_spi_response_get(struct m
127 }
128
129 checkstatus:
130 +#if defined(CONFIG_M54451_SD_HW_DETECT) || defined(CONFIG_M5441X_SD_HW_DETECT)
131 + if ((*cp == 0) && (oldcp_value == 0)) {
132 + dev_dbg(&host->spi->dev, "NO CARD in the SD SOCKET, "
133 + "new status %02x, old status %02x\n",
134 + *cp, oldcp_value);
135 + value = -EBADR;
136 + goto done;
137 + }
138 +#endif
139 bitshift = 0;
140 if (*cp & 0x80) {
141 /* Houston, we have an ugly card with a bit-shifted response */
142 @@ -1313,7 +1340,53 @@ mmc_spi_detect_irq(int irq, void *mmc)
143 struct mmc_spi_host *host = mmc_priv(mmc);
144 u16 delay_msec = max(host->pdata->detect_delay, (u16)100);
145
146 +#if defined(CONFIG_M54451_SD_HW_DETECT)
147 + dev_dbg(&host->spi->dev, "mmc_spi_detect_irq "
148 + "MCF_EPORT_EPPAR %x, MCF_EPORT_EPIER %x,"
149 + "MCF_INTC0_ICR7 %x, MCF_GPIO_PAR_IRQ %x,"
150 + "MCF_EPORT_EPDDR %x, MCF_EPORT_EPFR %x\n",
151 + MCF_EPORT_EPPAR, MCF_EPORT_EPIER,
152 + MCF_INTC0_ICR7, MCF_GPIO_PAR_IRQ,
153 + MCF_EPORT_EPDDR, MCF_EPORT_EPFR);
154 +
155 + MCF_EPORT_EPIER &= (~MCF_EPORT_EPIER_EPIE7);
156 +#elif defined(CONFIG_M5441X_SD_HW_DETECT)
157 +#if defined(CONFIG_DETECT_USE_EXTERN_IRQ1)
158 + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE1);
159 +#elif defined(CONFIG_DETECT_USE_EXTERN_IRQ7)
160 + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE7);
161 +#else
162 + MCF_EPORT_EPIER = MCF_EPORT_EPIER & (~MCF_EPORT_EPIER_EPIE7);
163 +#endif
164 +#endif
165 mmc_detect_change(mmc, msecs_to_jiffies(delay_msec));
166 +#if defined(CONFIG_M54451_SD_HW_DETECT)
167 + MCF_EPORT_EPPAR |= MCF_EPORT_EPPAR_EPPA7_BOTH;
168 + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
169 + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF7;
170 + dev_dbg(&host->spi->dev, "mmc_spi_detect_irq "
171 + "MCF_EPORT_EPPAR %x, MCF_EPORT_EPIER %x,"
172 + "MCF_INTC0_ICR7 %x, MCF_GPIO_PAR_IRQ %x,"
173 + "MCF_EPORT_EPDDR %x, MCF_EPORT_EPFR %x\n",
174 + MCF_EPORT_EPPAR, MCF_EPORT_EPIER,
175 + MCF_INTC0_ICR7, MCF_GPIO_PAR_IRQ,
176 + MCF_EPORT_EPDDR, MCF_EPORT_EPFR);
177 +
178 +#elif defined(CONFIG_M5441X_SD_HW_DETECT)
179 +#if defined(CONFIG_DETECT_USE_EXTERN_IRQ1)
180 + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA1_BOTH;
181 + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE1;
182 + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF1;
183 +#elif defined(CONFIG_DETECT_USE_EXTERN_IRQ7)
184 + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
185 + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
186 + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF7;
187 +#else
188 + MCF_EPORT_EPPAR = MCF_EPORT_EPPAR | MCF_EPORT_EPPAR_EPPA7_BOTH;
189 + MCF_EPORT_EPIER = MCF_EPORT_EPIER | MCF_EPORT_EPIER_EPIE7;
190 + MCF_EPORT_EPFR = MCF_EPORT_EPFR | MCF_EPORT_EPFR_EPF7;
191 +#endif
192 +#endif
193 return IRQ_HANDLED;
194 }
195