[coldfire]: switch to 2.6.38
[openwrt.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