diff options
Diffstat (limited to 'recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch')
-rw-r--r-- | recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch deleted file mode 100644 index 59d5ec47..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
1 | From 948eeb1f03da5fca0f6734c10efbc35ad63a1d08 Mon Sep 17 00:00:00 2001 | ||
2 | From: David Vrabel <david.vrabel@csr.com> | ||
3 | Date: Fri, 2 Apr 2010 08:42:22 -0700 | ||
4 | Subject: [PATCH 13/32] Enable the use of SDIO card interrupts. | ||
5 | |||
6 | FCLK must be enabled while SDIO interrupts are enabled or the MMC | ||
7 | module won't wake-up (even though ENAWAKEUP in SYSCONFIG and IWE in | ||
8 | HTCL have been set). Enabling the MMC module to wake-up would require | ||
9 | configuring the MMC module (and the mmci_dat[1] GPIO when the CORE | ||
10 | power domain is OFF) as wake-up sources in the PRCM. | ||
11 | |||
12 | The writes to STAT and ISE when starting a command are unnecessary and | ||
13 | have been removed. | ||
14 | |||
15 | Signed-off-by: David Vrabel <david.vrabel@csr.com> | ||
16 | --- | ||
17 | drivers/mmc/host/omap_hsmmc.c | 118 +++++++++++++++++++++++++++++------------ | ||
18 | 1 files changed, 83 insertions(+), 35 deletions(-) | ||
19 | |||
20 | diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c | ||
21 | index 83f93ab..d57686c 100644 | ||
22 | --- a/drivers/mmc/host/omap_hsmmc.c | ||
23 | +++ b/drivers/mmc/host/omap_hsmmc.c | ||
24 | @@ -67,6 +67,7 @@ | ||
25 | #define SDVS_MASK 0x00000E00 | ||
26 | #define SDVSCLR 0xFFFFF1FF | ||
27 | #define SDVSDET 0x00000400 | ||
28 | +#define ENAWAKEUP (1 << 2) | ||
29 | #define AUTOIDLE 0x1 | ||
30 | #define SDBP (1 << 8) | ||
31 | #define DTO 0xe | ||
32 | @@ -77,10 +78,13 @@ | ||
33 | #define CLKD_SHIFT 6 | ||
34 | #define DTO_MASK 0x000F0000 | ||
35 | #define DTO_SHIFT 16 | ||
36 | +#define CIRQ_ENABLE (1 << 8) | ||
37 | #define INT_EN_MASK 0x307F0033 | ||
38 | #define BWR_ENABLE (1 << 4) | ||
39 | #define BRR_ENABLE (1 << 5) | ||
40 | #define DTO_ENABLE (1 << 20) | ||
41 | +#define CTPL (1 << 11) | ||
42 | +#define CLKEXTFREE (1 << 16) | ||
43 | #define INIT_STREAM (1 << 1) | ||
44 | #define DP_SELECT (1 << 21) | ||
45 | #define DDIR (1 << 4) | ||
46 | @@ -88,10 +92,12 @@ | ||
47 | #define MSBS (1 << 5) | ||
48 | #define BCE (1 << 1) | ||
49 | #define FOUR_BIT (1 << 1) | ||
50 | +#define IWE (1 << 24) | ||
51 | #define DW8 (1 << 5) | ||
52 | #define CC 0x1 | ||
53 | #define TC 0x02 | ||
54 | #define OD 0x1 | ||
55 | +#define CIRQ (1 << 8) | ||
56 | #define ERR (1 << 15) | ||
57 | #define CMD_TIMEOUT (1 << 16) | ||
58 | #define DATA_TIMEOUT (1 << 20) | ||
59 | @@ -186,6 +192,7 @@ struct omap_hsmmc_host { | ||
60 | int protect_card; | ||
61 | int reqs_blocked; | ||
62 | int use_reg; | ||
63 | + int sdio_int; | ||
64 | |||
65 | struct omap_mmc_platform_data *pdata; | ||
66 | }; | ||
67 | @@ -598,7 +605,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) | ||
68 | ; | ||
69 | |||
70 | OMAP_HSMMC_WRITE(host->base, SYSCONFIG, | ||
71 | - OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE); | ||
72 | + OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE | ENAWAKEUP); | ||
73 | |||
74 | if (host->id == OMAP_MMC1_DEVID) { | ||
75 | if (host->power_mode != MMC_POWER_OFF && | ||
76 | @@ -613,7 +620,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) | ||
77 | } | ||
78 | |||
79 | OMAP_HSMMC_WRITE(host->base, HCTL, | ||
80 | - OMAP_HSMMC_READ(host->base, HCTL) | hctl); | ||
81 | + OMAP_HSMMC_READ(host->base, HCTL) | hctl | IWE); | ||
82 | |||
83 | OMAP_HSMMC_WRITE(host->base, CAPA, | ||
84 | OMAP_HSMMC_READ(host->base, CAPA) | capa); | ||
85 | @@ -627,7 +634,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) | ||
86 | ; | ||
87 | |||
88 | OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); | ||
89 | - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); | ||
90 | + OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ); | ||
91 | OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); | ||
92 | |||
93 | /* Do not initialize card-specific things if the power is off */ | ||
94 | @@ -791,22 +798,19 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, | ||
95 | struct mmc_data *data) | ||
96 | { | ||
97 | int cmdreg = 0, resptype = 0, cmdtype = 0; | ||
98 | + int int_en_mask = INT_EN_MASK; | ||
99 | |||
100 | dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n", | ||
101 | mmc_hostname(host->mmc), cmd->opcode, cmd->arg); | ||
102 | host->cmd = cmd; | ||
103 | |||
104 | - /* | ||
105 | - * Clear status bits and enable interrupts | ||
106 | - */ | ||
107 | - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); | ||
108 | - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); | ||
109 | - | ||
110 | if (host->use_dma) | ||
111 | - OMAP_HSMMC_WRITE(host->base, IE, | ||
112 | - INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); | ||
113 | - else | ||
114 | - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); | ||
115 | + int_en_mask &= ~(BRR_ENABLE | BWR_ENABLE); | ||
116 | + | ||
117 | + if (host->sdio_int) | ||
118 | + int_en_mask |= CIRQ; | ||
119 | + | ||
120 | + OMAP_HSMMC_WRITE(host->base, IE, int_en_mask); | ||
121 | |||
122 | host->response_busy = 0; | ||
123 | if (cmd->flags & MMC_RSP_PRESENT) { | ||
124 | @@ -1019,23 +1023,26 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) | ||
125 | { | ||
126 | struct omap_hsmmc_host *host = dev_id; | ||
127 | struct mmc_data *data; | ||
128 | - int end_cmd = 0, end_trans = 0, status; | ||
129 | + u32 status; | ||
130 | + int end_cmd = 0, end_trans = 0; | ||
131 | + bool card_irq = false; | ||
132 | |||
133 | spin_lock(&host->irq_lock); | ||
134 | |||
135 | - if (host->mrq == NULL) { | ||
136 | - OMAP_HSMMC_WRITE(host->base, STAT, | ||
137 | - OMAP_HSMMC_READ(host->base, STAT)); | ||
138 | - /* Flush posted write */ | ||
139 | - OMAP_HSMMC_READ(host->base, STAT); | ||
140 | - spin_unlock(&host->irq_lock); | ||
141 | - return IRQ_HANDLED; | ||
142 | - } | ||
143 | - | ||
144 | - data = host->data; | ||
145 | status = OMAP_HSMMC_READ(host->base, STAT); | ||
146 | + OMAP_HSMMC_WRITE(host->base, STAT, status); | ||
147 | + OMAP_HSMMC_READ(host->base, STAT); /* Flush posted write. */ | ||
148 | + | ||
149 | dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); | ||
150 | |||
151 | + if (status & CIRQ) | ||
152 | + card_irq = true; | ||
153 | + | ||
154 | + if (host->mrq == NULL) | ||
155 | + goto out; | ||
156 | + | ||
157 | + data = host->data; | ||
158 | + | ||
159 | if (status & ERR) { | ||
160 | #ifdef CONFIG_MMC_DEBUG | ||
161 | omap_hsmmc_report_irq(host, status); | ||
162 | @@ -1085,17 +1092,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) | ||
163 | } | ||
164 | } | ||
165 | |||
166 | - OMAP_HSMMC_WRITE(host->base, STAT, status); | ||
167 | - /* Flush posted write */ | ||
168 | - OMAP_HSMMC_READ(host->base, STAT); | ||
169 | - | ||
170 | if (end_cmd || ((status & CC) && host->cmd)) | ||
171 | omap_hsmmc_cmd_done(host, host->cmd); | ||
172 | if ((end_trans || (status & TC)) && host->mrq) | ||
173 | omap_hsmmc_xfer_done(host, data); | ||
174 | - | ||
175 | +out: | ||
176 | spin_unlock(&host->irq_lock); | ||
177 | |||
178 | + if (card_irq) | ||
179 | + mmc_signal_sdio_irq(host->mmc); | ||
180 | + | ||
181 | return IRQ_HANDLED; | ||
182 | } | ||
183 | |||
184 | @@ -1643,6 +1649,47 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) | ||
185 | mmc_slot(host).init_card(card); | ||
186 | } | ||
187 | |||
188 | +static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | ||
189 | +{ | ||
190 | + struct omap_hsmmc_host *host = mmc_priv(mmc); | ||
191 | + u32 ie, con; | ||
192 | + unsigned long flags; | ||
193 | + | ||
194 | + spin_lock_irqsave(&host->irq_lock, flags); | ||
195 | + | ||
196 | + /* | ||
197 | + * When interrupts are enabled, CTPL must be set to enable | ||
198 | + * DAT1 input buffer (or the card interrupt is always | ||
199 | + * asserted) and FCLK must be enabled as wake-up does not | ||
200 | + * work. Take care to disable FCLK after all the register | ||
201 | + * accesses as they might not complete if FCLK is off. | ||
202 | + * | ||
203 | + * FIXME: if the MMC module (and the mmci_dat[1] GPIO when the | ||
204 | + * CORE power domain is OFF) are configured as a wake-up | ||
205 | + * sources in the PRCM, then FCLK could be switched off. This | ||
206 | + * might add too much latency. | ||
207 | + */ | ||
208 | + con = OMAP_HSMMC_READ(host->base, CON); | ||
209 | + ie = OMAP_HSMMC_READ(host->base, IE); | ||
210 | + if (enable) { | ||
211 | + clk_enable(host->fclk); | ||
212 | + ie |= CIRQ_ENABLE; | ||
213 | + con |= CTPL | CLKEXTFREE; | ||
214 | + host->sdio_int = 1; | ||
215 | + } else { | ||
216 | + ie &= ~CIRQ_ENABLE; | ||
217 | + con &= ~(CTPL | CLKEXTFREE); | ||
218 | + host->sdio_int = 0; | ||
219 | + } | ||
220 | + OMAP_HSMMC_WRITE(host->base, CON, con); | ||
221 | + OMAP_HSMMC_WRITE(host->base, IE, ie); | ||
222 | + OMAP_HSMMC_READ(host->base, IE); /* flush posted write */ | ||
223 | + if (!enable) | ||
224 | + clk_disable(host->fclk); | ||
225 | + | ||
226 | + spin_unlock_irqrestore(&host->irq_lock, flags); | ||
227 | +} | ||
228 | + | ||
229 | static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) | ||
230 | { | ||
231 | u32 hctl, capa, value; | ||
232 | @@ -1657,14 +1704,14 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) | ||
233 | } | ||
234 | |||
235 | value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK; | ||
236 | - OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl); | ||
237 | + OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl | IWE); | ||
238 | |||
239 | value = OMAP_HSMMC_READ(host->base, CAPA); | ||
240 | OMAP_HSMMC_WRITE(host->base, CAPA, value | capa); | ||
241 | |||
242 | /* Set the controller to AUTO IDLE mode */ | ||
243 | value = OMAP_HSMMC_READ(host->base, SYSCONFIG); | ||
244 | - OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE); | ||
245 | + OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE | ENAWAKEUP); | ||
246 | |||
247 | /* Set SD bus power bit */ | ||
248 | set_sd_bus_power(host); | ||
249 | @@ -1918,7 +1965,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = { | ||
250 | .get_cd = omap_hsmmc_get_cd, | ||
251 | .get_ro = omap_hsmmc_get_ro, | ||
252 | .init_card = omap_hsmmc_init_card, | ||
253 | - /* NYET -- enable_sdio_irq */ | ||
254 | + .enable_sdio_irq = omap_hsmmc_enable_sdio_irq, | ||
255 | }; | ||
256 | |||
257 | static const struct mmc_host_ops omap_hsmmc_ps_ops = { | ||
258 | @@ -1929,7 +1976,7 @@ static const struct mmc_host_ops omap_hsmmc_ps_ops = { | ||
259 | .get_cd = omap_hsmmc_get_cd, | ||
260 | .get_ro = omap_hsmmc_get_ro, | ||
261 | .init_card = omap_hsmmc_init_card, | ||
262 | - /* NYET -- enable_sdio_irq */ | ||
263 | + .enable_sdio_irq = omap_hsmmc_enable_sdio_irq, | ||
264 | }; | ||
265 | |||
266 | #ifdef CONFIG_DEBUG_FS | ||
267 | @@ -2145,7 +2192,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | ||
268 | mmc->max_seg_size = mmc->max_req_size; | ||
269 | |||
270 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | | ||
271 | - MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; | ||
272 | + MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | | ||
273 | + MMC_CAP_SDIO_IRQ; | ||
274 | |||
275 | mmc->caps |= mmc_slot(host).caps; | ||
276 | if (mmc->caps & MMC_CAP_8_BIT_DATA) | ||
277 | @@ -2224,7 +2272,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | ||
278 | pdata->resume = omap_hsmmc_resume_cdirq; | ||
279 | } | ||
280 | |||
281 | - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); | ||
282 | + OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ); | ||
283 | OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); | ||
284 | |||
285 | mmc_host_lazy_disable(host->mmc); | ||
286 | -- | ||
287 | 1.6.6.1 | ||
288 | |||