sdhci.c revision 5f619704d18b93869d045abc49e09cdba109b04b
1d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*
270f10482c668301c483acded13bf68780ad352b9Pierre Ossman *  linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver
3d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *
4b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
5d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *
6d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * This program is free software; you can redistribute it and/or modify
7643f720cea989d2913fc0120a2384fecc1be1f9aPierre Ossman * it under the terms of the GNU General Public License as published by
8643f720cea989d2913fc0120a2384fecc1be1f9aPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at
9643f720cea989d2913fc0120a2384fecc1be1f9aPierre Ossman * your option) any later version.
1084c46a53fc4ea4ff36df783a20187b2f65dd21ccPierre Ossman *
1184c46a53fc4ea4ff36df783a20187b2f65dd21ccPierre Ossman * Thanks to the following companies for their support:
1284c46a53fc4ea4ff36df783a20187b2f65dd21ccPierre Ossman *
1384c46a53fc4ea4ff36df783a20187b2f65dd21ccPierre Ossman *     - JMicron (hardware and technical support)
14d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman */
15d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#include <linux/delay.h>
17d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#include <linux/highmem.h>
18b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman#include <linux/io.h>
19d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#include <linux/dma-mapping.h>
205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
21117636092a87a28a013a4acb5de5492645ed620fRalf Baechle#include <linux/scatterlist.h>
229bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski#include <linux/regulator/consumer.h>
23d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
242f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#include <linux/leds.h>
252f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
26d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#include <linux/mmc/host.h>
27d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
28d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#include "sdhci.h"
29d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
30d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#define DRIVER_NAME "sdhci"
31d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
32d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#define DBG(f, x...) \
33c65631781eb0f2e81865017c1484e9aef76e1b61Russell King	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
34d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
35f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
36f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman	defined(CONFIG_MMC_SDHCI_MODULE))
37f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#define SDHCI_USE_LEDS_CLASS
38f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#endif
39f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman
40df673b227ce08a7706b30fd2bf6512393d9c3c29Pierre Ossmanstatic unsigned int debug_quirks = 0;
416743527441430586aa82a0dee1b2700a2a974ebcPierre Ossman
42d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
43d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_finish_data(struct sdhci_host *);
44d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
45d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
46d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_finish_command(struct sdhci_host *);
47d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
48d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_dumpregs(struct sdhci_host *host)
49d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
50412ab659b2bdad6afac8f84daf2a8a393145dcaePhilip Rakity	printk(KERN_DEBUG DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
51412ab659b2bdad6afac8f84daf2a8a393145dcaePhilip Rakity		mmc_hostname(host->mmc));
52d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
53d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
544e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_DMA_ADDRESS),
554e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_HOST_VERSION));
56d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
574e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_BLOCK_SIZE),
584e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_BLOCK_COUNT));
59d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
604e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_ARGUMENT),
614e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_TRANSFER_MODE));
62d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
634e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_PRESENT_STATE),
644e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readb(host, SDHCI_HOST_CONTROL));
65d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
664e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readb(host, SDHCI_POWER_CONTROL),
674e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
68d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
694e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
704e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
71d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
724e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
734e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_INT_STATUS));
74d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
754e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_INT_ENABLE),
764e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
77d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
784e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_ACMD12_ERR),
794e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
80d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
814e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_CAPABILITIES),
824e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_readl(host, SDHCI_MAX_CURRENT));
83d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
84be3f4ae0c0c56aab903aceaceed4b9d8418e180eBen Dooks	if (host->flags & SDHCI_USE_ADMA)
85be3f4ae0c0c56aab903aceaceed4b9d8418e180eBen Dooks		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
86be3f4ae0c0c56aab903aceaceed4b9d8418e180eBen Dooks		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
87be3f4ae0c0c56aab903aceaceed4b9d8418e180eBen Dooks		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
88be3f4ae0c0c56aab903aceaceed4b9d8418e180eBen Dooks
89d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
90d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
91d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
92d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
93d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
94d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Low level functions                                                       *
95d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
96d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
97d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
987260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
997260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1007260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	u32 ier;
1017260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1027260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
1037260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	ier &= ~clear;
1047260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	ier |= set;
1057260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
1067260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
1077260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1087260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1097260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
1107260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1117260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_clear_set_irqs(host, 0, irqs);
1127260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1137260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1147260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
1157260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1167260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_clear_set_irqs(host, irqs, 0);
1177260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1187260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1197260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
1207260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1217260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
1227260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
12368d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
12468d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov		return;
12568d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov
1267260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	if (enable)
1277260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		sdhci_unmask_irqs(host, irqs);
1287260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	else
1297260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		sdhci_mask_irqs(host, irqs);
1307260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1317260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1327260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_enable_card_detection(struct sdhci_host *host)
1337260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1347260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_set_card_detection(host, true);
1357260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1367260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1377260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_disable_card_detection(struct sdhci_host *host)
1387260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
1397260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_set_card_detection(host, false);
1407260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
1417260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
142d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_reset(struct sdhci_host *host, u8 mask)
143d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
144e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman	unsigned long timeout;
145063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov	u32 uninitialized_var(ier);
146e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman
147b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
1484e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
1498a4da1430f7f2a16df3be9c7b5d55ba4e75b708cPierre Ossman			SDHCI_CARD_PRESENT))
1508a4da1430f7f2a16df3be9c7b5d55ba4e75b708cPierre Ossman			return;
1518a4da1430f7f2a16df3be9c7b5d55ba4e75b708cPierre Ossman	}
1528a4da1430f7f2a16df3be9c7b5d55ba4e75b708cPierre Ossman
153063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
154063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
155063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov
1564e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
157d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
158e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman	if (mask & SDHCI_RESET_ALL)
159d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		host->clock = 0;
160d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
161e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman	/* Wait max 100 ms */
162e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman	timeout = 100;
163e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman
164e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman	/* hw clears the bit when it's done */
1654e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
166e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman		if (timeout == 0) {
167acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
168e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman				mmc_hostname(host->mmc), (int)mask);
169e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman			sdhci_dumpregs(host);
170e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman			return;
171e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman		}
172e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman		timeout--;
173e16514d8d86ecbde18a2a7495cf028861b34c157Pierre Ossman		mdelay(1);
174d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
175063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov
176063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
177063a9dbbce5559770b7e2e2f51bd29adf3ab9b1eAnton Vorontsov		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
178d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
179d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1802f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitrestatic void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
1812f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre
1822f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitrestatic void sdhci_init(struct sdhci_host *host, int soft)
183d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1842f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	if (soft)
1852f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
1862f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	else
1872f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre		sdhci_reset(host, SDHCI_RESET_ALL);
188d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1897260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
1907260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
1913192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
1923192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
1936aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
1942f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre
1952f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	if (soft) {
1962f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre		/* force clock reconfiguration */
1972f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre		host->clock = 0;
1982f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre		sdhci_set_ios(host->mmc, &host->mmc->ios);
1992f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	}
2007260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov}
201d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2027260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsovstatic void sdhci_reinit(struct sdhci_host *host)
2037260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov{
2042f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	sdhci_init(host, 0);
2057260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_enable_card_detection(host);
206d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
207d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
208d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_activate_led(struct sdhci_host *host)
209d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
210d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	u8 ctrl;
211d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2124e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
213d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	ctrl |= SDHCI_CTRL_LED;
2144e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
215d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
216d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
217d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_deactivate_led(struct sdhci_host *host)
218d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
219d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	u8 ctrl;
220d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2214e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
222d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	ctrl &= ~SDHCI_CTRL_LED;
2234e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
224d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
225d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
226f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifdef SDHCI_USE_LEDS_CLASS
2272f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossmanstatic void sdhci_led_control(struct led_classdev *led,
2282f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	enum led_brightness brightness)
2292f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman{
2302f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
2312f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	unsigned long flags;
2322f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
2332f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
2342f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
2352f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	if (brightness == LED_OFF)
2362f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman		sdhci_deactivate_led(host);
2372f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	else
2382f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman		sdhci_activate_led(host);
2392f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
2402f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
2412f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman}
2422f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
2432f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
244d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
245d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
246d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Core functions                                                            *
247d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
248d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
249d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
250a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossmanstatic void sdhci_read_block_pio(struct sdhci_host *host)
251d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
2527659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	unsigned long flags;
2537659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	size_t blksize, len, chunk;
2547244b85bd17313d7d300ee93ec7bfbca1f4ccf3dSteven Noonan	u32 uninitialized_var(scratch);
2557659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	u8 *buf;
256d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
257a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	DBG("PIO reading\n");
258d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
259a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	blksize = host->data->blksz;
2607659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	chunk = 0;
261d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2627659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	local_irq_save(flags);
263d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
264a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	while (blksize) {
2657659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		if (!sg_miter_next(&host->sg_miter))
2667659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			BUG();
267d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2687659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		len = min(host->sg_miter.length, blksize);
269d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2707659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		blksize -= len;
2717659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		host->sg_miter.consumed = len;
27214d836e7499c53a1f6a65086c3d11600e871a971Alex Dubov
2737659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		buf = host->sg_miter.addr;
274d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2757659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		while (len) {
2767659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			if (chunk == 0) {
2774e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				scratch = sdhci_readl(host, SDHCI_BUFFER);
2787659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman				chunk = 4;
279a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman			}
2807659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
2817659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			*buf = scratch & 0xFF;
2827659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
2837659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			buf++;
2847659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			scratch >>= 8;
2857659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			chunk--;
2867659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			len--;
287d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
288a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	}
2897659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
2907659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	sg_miter_stop(&host->sg_miter);
2917659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
2927659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	local_irq_restore(flags);
293a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman}
294d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
295a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossmanstatic void sdhci_write_block_pio(struct sdhci_host *host)
296a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman{
2977659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	unsigned long flags;
2987659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	size_t blksize, len, chunk;
2997659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	u32 scratch;
3007659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	u8 *buf;
301d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
302a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	DBG("PIO writing\n");
303a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
304a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	blksize = host->data->blksz;
3057659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	chunk = 0;
3067659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	scratch = 0;
307d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
3087659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	local_irq_save(flags);
309d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
310a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	while (blksize) {
3117659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		if (!sg_miter_next(&host->sg_miter))
3127659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			BUG();
313a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
3147659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		len = min(host->sg_miter.length, blksize);
3157659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3167659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		blksize -= len;
3177659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		host->sg_miter.consumed = len;
3187659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3197659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		buf = host->sg_miter.addr;
320d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
3217659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		while (len) {
3227659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			scratch |= (u32)*buf << (chunk * 8);
3237659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3247659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			buf++;
3257659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			chunk++;
3267659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			len--;
3277659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3287659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
3294e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				sdhci_writel(host, scratch, SDHCI_BUFFER);
3307659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman				chunk = 0;
3317659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman				scratch = 0;
332d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			}
333d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
334d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
3357659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3367659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	sg_miter_stop(&host->sg_miter);
3377659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman
3387659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	local_irq_restore(flags);
339a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman}
340a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
341a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossmanstatic void sdhci_transfer_pio(struct sdhci_host *host)
342a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman{
343a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	u32 mask;
344a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
345a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	BUG_ON(!host->data);
346a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
3477659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	if (host->blocks == 0)
348a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		return;
349a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
350a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	if (host->data->flags & MMC_DATA_READ)
351a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		mask = SDHCI_DATA_AVAILABLE;
352a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	else
353a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		mask = SDHCI_SPACE_AVAILABLE;
354a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman
3554a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	/*
3564a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	 * Some controllers (JMicron JMB38x) mess up the buffer bits
3574a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	 * for transfers < 4 bytes. As long as it is just one block,
3584a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	 * we can ignore the bits.
3594a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	 */
3604a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
3614a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman		(host->data->blocks == 1))
3624a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman		mask = ~0;
3634a3cba32cb514168bb2516c045b178e6660421d1Pierre Ossman
3644e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
3653e3bf20756aeee57a40fd37b923263c9a51b8c68Anton Vorontsov		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
3663e3bf20756aeee57a40fd37b923263c9a51b8c68Anton Vorontsov			udelay(100);
3673e3bf20756aeee57a40fd37b923263c9a51b8c68Anton Vorontsov
368a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		if (host->data->flags & MMC_DATA_READ)
369a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman			sdhci_read_block_pio(host);
370a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		else
371a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman			sdhci_write_block_pio(host);
372d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
3737659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		host->blocks--;
3747659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		if (host->blocks == 0)
375a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman			break;
376a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	}
377d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
378a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman	DBG("PIO transfer complete.\n");
379d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
380d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
3812134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossmanstatic char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
3822134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman{
3832134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	local_irq_save(*flags);
3842134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
3852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman}
3862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
3872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossmanstatic void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
3882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman{
3892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
3902134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	local_irq_restore(*flags);
3912134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman}
3922134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
393118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooksstatic void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd)
394118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks{
3959e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	__le32 *dataddr = (__le32 __force *)(desc + 4);
3969e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	__le16 *cmdlen = (__le16 __force *)desc;
397118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks
3989e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	/* SDHCI specification says ADMA descriptors should be 4 byte
3999e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	 * aligned, so using 16 or 32bit operations should be safe. */
400118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks
4019e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	cmdlen[0] = cpu_to_le16(cmd);
4029e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	cmdlen[1] = cpu_to_le16(len);
4039e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks
4049e506f35b1dc327c448d4791bc098f07b9b2efe9Ben Dooks	dataddr[0] = cpu_to_le32(addr);
405118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks}
406118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks
4078f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossmanstatic int sdhci_adma_table_pre(struct sdhci_host *host,
4082134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	struct mmc_data *data)
4092134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman{
4102134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	int direction;
4112134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4122134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	u8 *desc;
4132134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	u8 *align;
4142134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	dma_addr_t addr;
4152134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	dma_addr_t align_addr;
4162134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	int len, offset;
4172134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4182134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	struct scatterlist *sg;
4192134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	int i;
4202134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	char *buffer;
4212134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	unsigned long flags;
4222134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4232134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	/*
4242134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * The spec does not specify endianness of descriptor table.
4252134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * We currently guess that it is LE.
4262134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 */
4272134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4282134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (data->flags & MMC_DATA_READ)
4292134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		direction = DMA_FROM_DEVICE;
4302134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	else
4312134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		direction = DMA_TO_DEVICE;
4322134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4332134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	/*
4342134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * The ADMA descriptor table is mapped further down as we
4352134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * need to fill it with data first.
4362134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 */
4372134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4382134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->align_addr = dma_map_single(mmc_dev(host->mmc),
4392134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->align_buffer, 128 * 4, direction);
4408d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
4418f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		goto fail;
4422134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	BUG_ON(host->align_addr & 0x3);
4432134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4442134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->sg_count = dma_map_sg(mmc_dev(host->mmc),
4452134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		data->sg, data->sg_len, direction);
4468f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	if (host->sg_count == 0)
4478f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		goto unmap_align;
4482134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4492134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	desc = host->adma_desc;
4502134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	align = host->align_buffer;
4512134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4522134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	align_addr = host->align_addr;
4532134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4542134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	for_each_sg(data->sg, sg, host->sg_count, i) {
4552134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		addr = sg_dma_address(sg);
4562134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		len = sg_dma_len(sg);
4572134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4582134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		/*
4592134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * The SDHCI specification states that ADMA
4602134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * addresses must be 32-bit aligned. If they
4612134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * aren't, then we use a bounce buffer for
4622134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * the (up to three) bytes that screw up the
4632134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * alignment.
4642134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 */
4652134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		offset = (4 - (addr & 0x3)) & 0x3;
4662134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (offset) {
4672134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (data->flags & MMC_DATA_WRITE) {
4682134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				buffer = sdhci_kmap_atomic(sg, &flags);
4696cefd05f35177ad5d22d44519c680cf43f2ac86dPierre Ossman				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
4702134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				memcpy(align, buffer, offset);
4712134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				sdhci_kunmap_atomic(buffer, &flags);
4722134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			}
4732134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
474118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks			/* tran, valid */
475118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks			sdhci_set_adma_desc(desc, align_addr, offset, 0x21);
4762134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4772134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			BUG_ON(offset > 65536);
4782134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4792134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			align += 4;
4802134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			align_addr += 4;
4812134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4822134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			desc += 8;
4832134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4842134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			addr += offset;
4852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			len -= offset;
4862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
4872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		BUG_ON(len > 65536);
4892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
490118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks		/* tran, valid */
491118cd17d4137f34c747c32765c1cb4d3910c04d4Ben Dooks		sdhci_set_adma_desc(desc, addr, len, 0x21);
4922134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		desc += 8;
4932134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
4942134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		/*
4952134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * If this triggers then we have a calculation bug
4962134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * somewhere. :/
4972134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 */
4982134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
4992134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
5002134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
50170764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham	if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
50270764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		/*
50370764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		* Mark the last descriptor as the terminating descriptor
50470764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		*/
50570764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		if (desc != host->adma_desc) {
50670764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham			desc -= 8;
50770764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham			desc[0] |= 0x2; /* end */
50870764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		}
50970764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham	} else {
51070764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		/*
51170764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		* Add a terminating entry.
51270764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		*/
5132134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
51470764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		/* nop, end, valid */
51570764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham		sdhci_set_adma_desc(desc, 0, 0, 0x3);
51670764a905785ebacc8d44fed7a12fba3db267ae6Thomas Abraham	}
5172134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5182134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	/*
5192134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * Resync align buffer as we might have changed it.
5202134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 */
5212134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (data->flags & MMC_DATA_WRITE) {
5222134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		dma_sync_single_for_device(mmc_dev(host->mmc),
5232134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			host->align_addr, 128 * 4, direction);
5242134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
5252134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5262134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
5272134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
528980167b7fb20fb181766218b4771fc7420a7bbb4Pierre Ossman	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
5298f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		goto unmap_entries;
5302134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	BUG_ON(host->adma_addr & 0x3);
5318f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman
5328f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	return 0;
5338f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman
5348f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossmanunmap_entries:
5358f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5368f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		data->sg_len, direction);
5378f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossmanunmap_align:
5388f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5398f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		128 * 4, direction);
5408f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossmanfail:
5418f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	return -EINVAL;
5422134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman}
5432134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5442134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossmanstatic void sdhci_adma_table_post(struct sdhci_host *host,
5452134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	struct mmc_data *data)
5462134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman{
5472134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	int direction;
5482134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5492134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	struct scatterlist *sg;
5502134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	int i, size;
5512134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	u8 *align;
5522134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	char *buffer;
5532134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	unsigned long flags;
5542134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5552134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (data->flags & MMC_DATA_READ)
5562134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		direction = DMA_FROM_DEVICE;
5572134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	else
5582134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		direction = DMA_TO_DEVICE;
5592134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5602134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
5612134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
5622134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5632134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5642134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		128 * 4, direction);
5652134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5662134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (data->flags & MMC_DATA_READ) {
5672134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
5682134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			data->sg_len, direction);
5692134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5702134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		align = host->align_buffer;
5712134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5722134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		for_each_sg(data->sg, sg, host->sg_count, i) {
5732134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (sg_dma_address(sg) & 0x3) {
5742134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				size = 4 - (sg_dma_address(sg) & 0x3);
5752134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5762134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				buffer = sdhci_kmap_atomic(sg, &flags);
5776cefd05f35177ad5d22d44519c680cf43f2ac86dPierre Ossman				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
5782134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				memcpy(buffer, align, size);
5792134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				sdhci_kunmap_atomic(buffer, &flags);
5802134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5812134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				align += 4;
5822134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			}
5832134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
5842134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
5852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
5862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		data->sg_len, direction);
5882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman}
5892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
590ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossmanstatic u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
591d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
5921c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	u8 count;
5931c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	unsigned target_timeout, current_timeout;
594d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
595ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	/*
596ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	 * If the host controller provides us with an incorrect timeout
597ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	 * value, just skip the check and use 0xE.  The hardware may take
598ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	 * longer to time out, but that's much better than having a too-short
599ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	 * timeout value.
600ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	 */
60111a2f1b78a43d0c2bd026d79b952742c7588f529Pierre Ossman	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
602ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman		return 0xE;
603e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman
6041c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	/* timeout in us */
6051c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	target_timeout = data->timeout_ns / 1000 +
6061c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		data->timeout_clks / host->clock;
607d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
60881b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
60981b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov		host->timeout_clk = host->clock / 1000;
61081b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov
6111c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	/*
6121c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * Figure out needed cycles.
6131c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * We do this in steps in order to fit inside a 32 bit int.
6141c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * The first step is the minimum timeout, which will have a
6151c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * minimum resolution of 6 bits:
6161c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * (1) 2^13*1000 > 2^22,
6171c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 * (2) host->timeout_clk < 2^16
6181c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 *     =>
6191c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 *     (1) / (2) > 2^6
6201c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	 */
6211c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	count = 0;
6221c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
6231c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	while (current_timeout < target_timeout) {
6241c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		count++;
6251c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		current_timeout <<= 1;
6261c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		if (count >= 0xF)
6271c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman			break;
6281c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	}
6291c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman
6301c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	if (count >= 0xF) {
6311c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		printk(KERN_WARNING "%s: Too large timeout requested!\n",
6321c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman			mmc_hostname(host->mmc));
6331c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		count = 0xE;
6341c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	}
6351c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman
636ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	return count;
637ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman}
638ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
6396aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsovstatic void sdhci_set_transfer_irqs(struct sdhci_host *host)
6406aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov{
6416aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
6426aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
6436aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov
6446aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov	if (host->flags & SDHCI_REQ_USE_DMA)
6456aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
6466aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov	else
6476aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
6486aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov}
6496aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov
650ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossmanstatic void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
651ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman{
652ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	u8 count;
6532134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	u8 ctrl;
6548f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	int ret;
655ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
656ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	WARN_ON(host->data);
657ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
658ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	if (data == NULL)
659ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman		return;
660ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
661ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	/* Sanity checks */
662ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	BUG_ON(data->blksz * data->blocks > 524288);
663ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	BUG_ON(data->blksz > host->mmc->max_blk_size);
664ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	BUG_ON(data->blocks > 65535);
665ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
666ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	host->data = data;
667ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	host->data_early = 0;
668ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman
669ee53ab5d73998e502801c024a08de2c39a92c52aPierre Ossman	count = sdhci_calc_timeout(host, data);
6704e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
671d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
672a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
673c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman		host->flags |= SDHCI_REQ_USE_DMA;
674c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman
6752134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	/*
6762134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * FIXME: This doesn't account for merging when mapping the
6772134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * scatterlist.
6782134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 */
6792134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->flags & SDHCI_REQ_USE_DMA) {
6802134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		int broken, i;
6812134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		struct scatterlist *sg;
6822134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
6832134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		broken = 0;
6842134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (host->flags & SDHCI_USE_ADMA) {
6852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
6862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				broken = 1;
6872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		} else {
6882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
6892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				broken = 1;
6902134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
6912134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
6922134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (unlikely(broken)) {
6932134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			for_each_sg(data->sg, sg, data->sg_len, i) {
6942134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				if (sg->length & 0x3) {
6952134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					DBG("Reverting to PIO because of "
6962134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman						"transfer size (%d)\n",
6972134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman						sg->length);
6982134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					host->flags &= ~SDHCI_REQ_USE_DMA;
6992134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					break;
7002134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				}
7012134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			}
7022134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
703c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	}
704c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman
705c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	/*
706c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	 * The assumption here being that alignment is the same after
707c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	 * translation to device address space.
708c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	 */
7092134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->flags & SDHCI_REQ_USE_DMA) {
7102134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		int broken, i;
7112134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		struct scatterlist *sg;
7122134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
7132134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		broken = 0;
7142134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (host->flags & SDHCI_USE_ADMA) {
7152134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			/*
7162134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			 * As we use 3 byte chunks to work around
7172134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			 * alignment problems, we need to check this
7182134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			 * quirk.
7192134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			 */
7202134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
7212134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				broken = 1;
7222134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		} else {
7232134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
7242134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				broken = 1;
7252134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
7262134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
7272134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (unlikely(broken)) {
7282134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			for_each_sg(data->sg, sg, data->sg_len, i) {
7292134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				if (sg->offset & 0x3) {
7302134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					DBG("Reverting to PIO because of "
7312134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman						"bad alignment\n");
7322134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					host->flags &= ~SDHCI_REQ_USE_DMA;
7332134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					break;
7342134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				}
7352134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			}
7362134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
7372134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
7382134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
7398f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	if (host->flags & SDHCI_REQ_USE_DMA) {
7408f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		if (host->flags & SDHCI_USE_ADMA) {
7418f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			ret = sdhci_adma_table_pre(host, data);
7428f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			if (ret) {
7438f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				/*
7448f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 * This only happens when someone fed
7458f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 * us an invalid request.
7468f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 */
7478f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				WARN_ON(1);
748ebd6d357848edb8709dd9bed4b93834d1b4d7044Pierre Ossman				host->flags &= ~SDHCI_REQ_USE_DMA;
7498f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			} else {
7504e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				sdhci_writel(host, host->adma_addr,
7514e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov					SDHCI_ADMA_ADDRESS);
7528f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			}
7538f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		} else {
754c8b3e02eb250ceb661437e9b198757eff0eb6fd2Tomas Winkler			int sg_cnt;
7558f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman
756c8b3e02eb250ceb661437e9b198757eff0eb6fd2Tomas Winkler			sg_cnt = dma_map_sg(mmc_dev(host->mmc),
7578f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman					data->sg, data->sg_len,
7588f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman					(data->flags & MMC_DATA_READ) ?
7598f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman						DMA_FROM_DEVICE :
7608f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman						DMA_TO_DEVICE);
761c8b3e02eb250ceb661437e9b198757eff0eb6fd2Tomas Winkler			if (sg_cnt == 0) {
7628f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				/*
7638f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 * This only happens when someone fed
7648f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 * us an invalid request.
7658f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				 */
7668f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman				WARN_ON(1);
767ebd6d357848edb8709dd9bed4b93834d1b4d7044Pierre Ossman				host->flags &= ~SDHCI_REQ_USE_DMA;
7688f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			} else {
769719a61b452ff74cf81a96e4212748d9d63bcc924Pierre Ossman				WARN_ON(sg_cnt != 1);
7704e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				sdhci_writel(host, sg_dma_address(data->sg),
7714e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov					SDHCI_DMA_ADDRESS);
7728f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman			}
7738f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman		}
7748f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	}
7758f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman
7762134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	/*
7772134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * Always adjust the DMA selection as some controllers
7782134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * (e.g. JMicron) can't do PIO properly when the selection
7792134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * is ADMA.
7802134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 */
7812134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->version >= SDHCI_SPEC_200) {
7824e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
7832134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		ctrl &= ~SDHCI_CTRL_DMA_MASK;
7842134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if ((host->flags & SDHCI_REQ_USE_DMA) &&
7852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			(host->flags & SDHCI_USE_ADMA))
7862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			ctrl |= SDHCI_CTRL_ADMA32;
7872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		else
7882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			ctrl |= SDHCI_CTRL_SDMA;
7894e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
790c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	}
791c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman
7928f1934ce784bd8f2eaf06f190526500f7f3f9c74Pierre Ossman	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
793da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior		int flags;
794da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior
795da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior		flags = SG_MITER_ATOMIC;
796da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior		if (host->data->flags & MMC_DATA_READ)
797da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior			flags |= SG_MITER_TO_SG;
798da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior		else
799da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior			flags |= SG_MITER_FROM_SG;
800da60a91d012bcb10bc5bcd86d585c4281742832cSebastian Andrzej Siewior		sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
8017659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		host->blocks = data->blocks;
802d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
803c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
8046aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov	sdhci_set_transfer_irqs(host);
8056aa943ab8994fe6e4ccba22c5bc8150a84268bddAnton Vorontsov
806bab7696184bbf0ea48d56902bd1f9ac983079ad2Pierre Ossman	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
8074e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
8084e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
809c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman}
810c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
811c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossmanstatic void sdhci_set_transfer_mode(struct sdhci_host *host,
812c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	struct mmc_data *data)
813c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman{
814c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	u16 mode;
815c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
816c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	if (data == NULL)
817c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman		return;
818c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
819e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman	WARN_ON(!host->data);
820e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman
821c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	mode = SDHCI_TRNS_BLK_CNT_EN;
822c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang	if (data->blocks > 1) {
823c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
824c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
825c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang		else
826c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang			mode |= SDHCI_TRNS_MULTI;
827c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang	}
828c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	if (data->flags & MMC_DATA_READ)
829c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman		mode |= SDHCI_TRNS_READ;
830c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	if (host->flags & SDHCI_REQ_USE_DMA)
831c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman		mode |= SDHCI_TRNS_DMA;
832c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
8334e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
834d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
835d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
836d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_finish_data(struct sdhci_host *host)
837d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
838d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct mmc_data *data;
839d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
840d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	BUG_ON(!host->data);
841d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
842d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	data = host->data;
843d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->data = NULL;
844d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
845c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990Pierre Ossman	if (host->flags & SDHCI_REQ_USE_DMA) {
8462134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (host->flags & SDHCI_USE_ADMA)
8472134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			sdhci_adma_table_post(host, data);
8482134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		else {
8492134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
8502134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				data->sg_len, (data->flags & MMC_DATA_READ) ?
8512134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman					DMA_FROM_DEVICE : DMA_TO_DEVICE);
8522134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
853d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
854d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
855d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
856c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	 * The specification states that the block count register must
857c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	 * be updated, but it does not specify at what point in the
858c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	 * data flow. That makes the register entirely useless to read
859c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	 * back so we have to assume that nothing made it to the card
860c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	 * in the event of an error.
861d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
862c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman	if (data->error)
863c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman		data->bytes_xfered = 0;
864d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else
865c9b74c5b8fb807187f6b1db09012828fcd2d7e73Pierre Ossman		data->bytes_xfered = data->blksz * data->blocks;
866d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
867d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (data->stop) {
868d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		/*
869d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		 * The controller needs a reset of internal state machines
870d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		 * upon error conditions.
871d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		 */
87217b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		if (data->error) {
873d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_reset(host, SDHCI_RESET_CMD);
874d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_reset(host, SDHCI_RESET_DATA);
875d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
876d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
877d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_send_command(host, data->stop);
878d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	} else
879d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->finish_tasklet);
880d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
881d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
882d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
883d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
884d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	int flags;
885fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	u32 mask;
8867cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman	unsigned long timeout;
887d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
888d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	WARN_ON(host->cmd);
889d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
890d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/* Wait max 10 ms */
8917cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman	timeout = 10;
892fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman
893fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	mask = SDHCI_CMD_INHIBIT;
894fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
895fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman		mask |= SDHCI_DATA_INHIBIT;
896fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman
897fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	/* We shouldn't wait for data inihibit for stop commands, even
898fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	   though they might use busy signaling */
899fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman	if (host->mrq->data && (cmd == host->mrq->data->stop))
900fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman		mask &= ~SDHCI_DATA_INHIBIT;
901fd2208d7c72ef5995b730f1e23b082261499e334Pierre Ossman
9024e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
9037cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		if (timeout == 0) {
904d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			printk(KERN_ERR "%s: Controller never released "
905acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman				"inhibit bit(s).\n", mmc_hostname(host->mmc));
906d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_dumpregs(host);
90717b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman			cmd->error = -EIO;
908d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			tasklet_schedule(&host->finish_tasklet);
909d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			return;
910d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
9117cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		timeout--;
9127cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		mdelay(1);
9137cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman	}
914d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
915d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mod_timer(&host->timer, jiffies + 10 * HZ);
916d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
917d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->cmd = cmd;
918d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
919d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	sdhci_prepare_data(host, cmd->data);
920d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
9214e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
922d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
923c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman	sdhci_set_transfer_mode(host, cmd->data);
924c7fa9963ee6317b54e85b260791d603ea2feb8e3Pierre Ossman
925d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
926acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman		printk(KERN_ERR "%s: Unsupported response type!\n",
927d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			mmc_hostname(host->mmc));
92817b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		cmd->error = -EINVAL;
929d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->finish_tasklet);
930d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		return;
931d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
932d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
933d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (!(cmd->flags & MMC_RSP_PRESENT))
934d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags = SDHCI_CMD_RESP_NONE;
935d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else if (cmd->flags & MMC_RSP_136)
936d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags = SDHCI_CMD_RESP_LONG;
937d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else if (cmd->flags & MMC_RSP_BUSY)
938d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags = SDHCI_CMD_RESP_SHORT_BUSY;
939d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else
940d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags = SDHCI_CMD_RESP_SHORT;
941d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
942d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (cmd->flags & MMC_RSP_CRC)
943d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags |= SDHCI_CMD_CRC;
944d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (cmd->flags & MMC_RSP_OPCODE)
945d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags |= SDHCI_CMD_INDEX;
946d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (cmd->data)
947d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		flags |= SDHCI_CMD_DATA;
948d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
9494e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
950d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
951d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
952d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_finish_command(struct sdhci_host *host)
953d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
954d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	int i;
955d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
956d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	BUG_ON(host->cmd == NULL);
957d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
958d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (host->cmd->flags & MMC_RSP_PRESENT) {
959d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		if (host->cmd->flags & MMC_RSP_136) {
960d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			/* CRC is stripped so we need to do some shifting. */
961d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			for (i = 0;i < 4;i++) {
9624e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				host->cmd->resp[i] = sdhci_readl(host,
963d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman					SDHCI_RESPONSE + (3-i)*4) << 8;
964d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman				if (i != 3)
965d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman					host->cmd->resp[i] |=
9664e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov						sdhci_readb(host,
967d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman						SDHCI_RESPONSE + (3-i)*4-1);
968d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			}
969d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		} else {
9704e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov			host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
971d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
972d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
973d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
97417b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	host->cmd->error = 0;
975d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
976e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman	if (host->data && host->data_early)
977e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman		sdhci_finish_data(host);
978e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman
979e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman	if (!host->cmd->data)
980d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->finish_tasklet);
981d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
982d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->cmd = NULL;
983d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
984d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
985d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
986d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
987d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	int div;
988d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	u16 clk;
9897cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman	unsigned long timeout;
990d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
991d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (clock == host->clock)
992d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		return;
993d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
9948114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov	if (host->ops->set_clock) {
9958114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov		host->ops->set_clock(host, clock);
9968114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
9978114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov			return;
9988114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov	}
9998114634ccb54d67a8c01e5825d95bff4e7f7b357Anton Vorontsov
10004e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
1001d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1002d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (clock == 0)
1003d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		goto out;
1004d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
100585105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao	if (host->version >= SDHCI_SPEC_300) {
100685105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		/* Version 3.00 divisors must be a multiple of 2. */
100785105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		if (host->max_clk <= clock)
100885105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao			div = 1;
100985105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		else {
10100397526d6ae2518b6c53efd1ff1e81b7d24c91daZhangfei Gao			for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
101185105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao				if ((host->max_clk / div) <= clock)
101285105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao					break;
101385105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao			}
101485105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		}
101585105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao	} else {
101685105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		/* Version 2.00 divisors must be a power of 2. */
10170397526d6ae2518b6c53efd1ff1e81b7d24c91daZhangfei Gao		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
101885105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao			if ((host->max_clk / div) <= clock)
101985105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao				break;
102085105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		}
1021d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1022d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	div >>= 1;
1023d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
102485105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao	clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
102585105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
102685105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao		<< SDHCI_DIVIDER_HI_SHIFT;
1027d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	clk |= SDHCI_CLOCK_INT_EN;
10284e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1029d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
103027f6cb160b71b342b7a47d28a4b6c422ea74ccd1Chris Ball	/* Wait max 20 ms */
103127f6cb160b71b342b7a47d28a4b6c422ea74ccd1Chris Ball	timeout = 20;
10324e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
10337cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		& SDHCI_CLOCK_INT_STABLE)) {
10347cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		if (timeout == 0) {
1035acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman			printk(KERN_ERR "%s: Internal clock never "
1036acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman				"stabilised.\n", mmc_hostname(host->mmc));
1037d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_dumpregs(host);
1038d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			return;
1039d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
10407cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		timeout--;
10417cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman		mdelay(1);
10427cb2c76fa2251474e42d55b75163c9d7ed11741ePierre Ossman	}
1043d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1044d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	clk |= SDHCI_CLOCK_CARD_EN;
10454e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
1046d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1047d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanout:
1048d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->clock = clock;
1049d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1050d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1051146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossmanstatic void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1052146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman{
10538364248a829d50495a796e7561aaf9a6976f846cGiuseppe Cavallaro	u8 pwr = 0;
1054146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
10558364248a829d50495a796e7561aaf9a6976f846cGiuseppe Cavallaro	if (power != (unsigned short)-1) {
1056ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		switch (1 << power) {
1057ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		case MMC_VDD_165_195:
1058ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			pwr = SDHCI_POWER_180;
1059ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			break;
1060ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		case MMC_VDD_29_30:
1061ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		case MMC_VDD_30_31:
1062ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			pwr = SDHCI_POWER_300;
1063ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			break;
1064ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		case MMC_VDD_32_33:
1065ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		case MMC_VDD_33_34:
1066ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			pwr = SDHCI_POWER_330;
1067ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			break;
1068ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		default:
1069ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman			BUG();
1070ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		}
1071ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	}
1072ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman
1073ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	if (host->pwr == pwr)
1074146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		return;
1075146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1076ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	host->pwr = pwr;
1077ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman
1078ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	if (pwr == 0) {
10794e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1080ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		return;
10819e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt	}
10829e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt
10839e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt	/*
10849e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt	 * Spec says that we should clear the power reg before setting
10859e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt	 * a new value. Some controllers don't seem to like this though.
10869e9dc5f29f2eb65153a15c4fdb12b4382e3a75b2Darren Salt	 */
1087b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
10884e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1089146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1090e08c1694d9e2138204f2b79b73f0f159074ce2f5Andres Salomon	/*
1091c71f65129a1fb67bc6b9b8d03b493675b5c9302bAndres Salomon	 * At least the Marvell CaFe chip gets confused if we set the voltage
1092e08c1694d9e2138204f2b79b73f0f159074ce2f5Andres Salomon	 * and set turn on power at the same time, so set the voltage first.
1093e08c1694d9e2138204f2b79b73f0f159074ce2f5Andres Salomon	 */
109411a2f1b78a43d0c2bd026d79b952742c7588f529Pierre Ossman	if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
1095ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1096e08c1694d9e2138204f2b79b73f0f159074ce2f5Andres Salomon
1097ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	pwr |= SDHCI_POWER_ON;
1098146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1099ae628903ab6cc9a04fdf8d4ff3f0c5b2ffa6f939Pierre Ossman	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1100557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte
1101557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte	/*
1102557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte	 * Some controllers need an extra 10ms delay of 10ms before they
1103557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte	 * can apply clock after applying power
1104557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte	 */
110511a2f1b78a43d0c2bd026d79b952742c7588f529Pierre Ossman	if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
1106557b06971b1f05cbadec2f376a305ee1954e9b0dHarald Welte		mdelay(10);
1107146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman}
1108146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1109d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
1110d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1111d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * MMC callbacks                                                             *
1112d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1113d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
1114d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1115d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1116d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1117d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
111868d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	bool present;
1119d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
1120d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1121d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = mmc_priv(mmc);
1122d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1123d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1124d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1125d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	WARN_ON(host->mrq != NULL);
1126d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1127f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifndef SDHCI_USE_LEDS_CLASS
1128d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	sdhci_activate_led(host);
11292f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
1130c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
1131c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang		if (mrq->stop) {
1132c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang			mrq->data->stop = NULL;
1133c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang			mrq->stop = NULL;
1134c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang		}
1135c4512f79dcb236c8dc2afae176a0dc520096f0bcJerry Huang	}
1136d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1137d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->mrq = mrq;
1138d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
113968d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	/* If polling, assume that the card is always present. */
114068d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
114168d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov		present = true;
114268d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	else
114368d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
114468d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov				SDHCI_CARD_PRESENT;
114568d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov
114668d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
114717b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		host->mrq->cmd->error = -ENOMEDIUM;
1148d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->finish_tasklet);
1149d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	} else
1150d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_send_command(host, mrq->cmd);
1151d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
11525f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
1153d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1154d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1155d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1156d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1157d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1158d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1159d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
1160d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	u8 ctrl;
1161d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1162d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = mmc_priv(mmc);
1163d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1164d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1165d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
11661e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (host->flags & SDHCI_DEVICE_DEAD)
11671e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		goto out;
11681e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
1169d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1170d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * Reset the chip on each power off.
1171d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * Should clear out any weird states.
1172d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
1173d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (ios->power_mode == MMC_POWER_OFF) {
11744e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
11757260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		sdhci_reinit(host);
1176d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1177d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1178d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	sdhci_set_clock(host, ios->clock);
1179d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1180d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (ios->power_mode == MMC_POWER_OFF)
1181146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		sdhci_set_power(host, -1);
1182d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else
1183146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		sdhci_set_power(host, ios->vdd);
1184d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1185643a81ff3c5a89ae5c0768f89b29d3e1d08be5c3Philip Rakity	if (host->ops->platform_send_init_74_clocks)
1186643a81ff3c5a89ae5c0768f89b29d3e1d08be5c3Philip Rakity		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
1187643a81ff3c5a89ae5c0768f89b29d3e1d08be5c3Philip Rakity
11884e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
1189cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman
1190ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7Kyungmin Park	if (ios->bus_width == MMC_BUS_WIDTH_8)
1191ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7Kyungmin Park		ctrl |= SDHCI_CTRL_8BITBUS;
1192ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7Kyungmin Park	else
1193ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7Kyungmin Park		ctrl &= ~SDHCI_CTRL_8BITBUS;
1194ae6d6c92212e94b12ab9365c23fb73acc2c3c2e7Kyungmin Park
1195d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (ios->bus_width == MMC_BUS_WIDTH_4)
1196d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		ctrl |= SDHCI_CTRL_4BITBUS;
1197d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else
1198d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		ctrl &= ~SDHCI_CTRL_4BITBUS;
1199cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman
12003ab9c8dad6444007700b5949ec80cfdc823d31b4Philip Rakity	if ((ios->timing == MMC_TIMING_SD_HS ||
12013ab9c8dad6444007700b5949ec80cfdc823d31b4Philip Rakity	     ios->timing == MMC_TIMING_MMC_HS)
12023ab9c8dad6444007700b5949ec80cfdc823d31b4Philip Rakity	    && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
1203cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman		ctrl |= SDHCI_CTRL_HISPD;
1204cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman	else
1205cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman		ctrl &= ~SDHCI_CTRL_HISPD;
1206cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman
12074e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1208d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1209b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo	/*
1210b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo	 * Some (ENE) controllers go apeshit on some ios operation,
1211b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo	 * signalling timeout and CRC errors even on CMD0. Resetting
1212b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo	 * it on each ios seems to solve the problem.
1213b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo	 */
1214b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
1215b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
1216b8352260d28b30cb2bb2df99814fb9c360e38901Leandro Dorileo
12171e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossmanout:
12185f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
1219d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1220d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1221d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1222d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic int sdhci_get_ro(struct mmc_host *mmc)
1223d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1224d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1225d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
12262dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang	int is_readonly;
1227d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1228d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = mmc_priv(mmc);
1229d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1230d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1231d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
12321e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (host->flags & SDHCI_DEVICE_DEAD)
12332dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang		is_readonly = 0;
12342dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang	else if (host->ops->get_ro)
12352dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang		is_readonly = host->ops->get_ro(host);
12361e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	else
12372dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang		is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
12382dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang				& SDHCI_WRITE_PROTECT);
1239d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1240d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1241d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
12422dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang	/* This quirk needs to be replaced by a callback-function later */
12432dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang	return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
12442dfb579c7da171f6153cd58e8fbf7dcfe684778dWolfram Sang		!is_readonly : is_readonly;
1245d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1246d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1247f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossmanstatic void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1248f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman{
1249f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	struct sdhci_host *host;
1250f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	unsigned long flags;
1251f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1252f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	host = mmc_priv(mmc);
1253f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1254f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1255f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
12561e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (host->flags & SDHCI_DEVICE_DEAD)
12571e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		goto out;
12581e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
1259f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	if (enable)
12607260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
12617260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	else
12627260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
12631e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossmanout:
1264f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	mmiowb();
1265f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1266f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1267f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman}
1268f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1269ab7aefd0b38297e6d2d71f43e8f81f9f4a36cdaeDavid Brownellstatic const struct mmc_host_ops sdhci_ops = {
1270d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	.request	= sdhci_request,
1271d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	.set_ios	= sdhci_set_ios,
1272d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	.get_ro		= sdhci_get_ro,
1273f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	.enable_sdio_irq = sdhci_enable_sdio_irq,
1274d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman};
1275d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1276d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
1277d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1278d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Tasklets                                                                  *
1279d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1280d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
1281d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1282d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_tasklet_card(unsigned long param)
1283d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1284d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1285d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
1286d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1287d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = (struct sdhci_host*)param;
1288d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1289d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1290d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
12914e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
1292d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		if (host->mrq) {
1293d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			printk(KERN_ERR "%s: Card removed during transfer!\n",
1294d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman				mmc_hostname(host->mmc));
1295d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			printk(KERN_ERR "%s: Resetting controller.\n",
1296d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman				mmc_hostname(host->mmc));
1297d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1298d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_reset(host, SDHCI_RESET_CMD);
1299d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_reset(host, SDHCI_RESET_DATA);
1300d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
130117b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman			host->mrq->cmd->error = -ENOMEDIUM;
1302d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			tasklet_schedule(&host->finish_tasklet);
1303d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
1304d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1305d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1306d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1307d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
130804cf585d2902404ed06861c6dc27897100340dbaPierre Ossman	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
1309d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1310d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1311d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_tasklet_finish(unsigned long param)
1312d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1313d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1314d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
1315d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct mmc_request *mrq;
1316d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1317d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = (struct sdhci_host*)param;
1318d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1319d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1320d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1321d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	del_timer(&host->timer);
1322d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1323d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mrq = host->mrq;
1324d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1325d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1326d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * The controller needs a reset of internal state machines
1327d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * upon error conditions.
1328d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
13291e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
13301e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		(mrq->cmd->error ||
13311e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		 (mrq->data && (mrq->data->error ||
13321e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		  (mrq->data->stop && mrq->data->stop->error))) ||
13331e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
1334645289dca5021224279e67b4655796cafdfdad00Pierre Ossman
1335645289dca5021224279e67b4655796cafdfdad00Pierre Ossman		/* Some controllers need this kick or reset won't work here */
1336b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
1337645289dca5021224279e67b4655796cafdfdad00Pierre Ossman			unsigned int clock;
1338645289dca5021224279e67b4655796cafdfdad00Pierre Ossman
1339645289dca5021224279e67b4655796cafdfdad00Pierre Ossman			/* This is to force an update */
1340645289dca5021224279e67b4655796cafdfdad00Pierre Ossman			clock = host->clock;
1341645289dca5021224279e67b4655796cafdfdad00Pierre Ossman			host->clock = 0;
1342645289dca5021224279e67b4655796cafdfdad00Pierre Ossman			sdhci_set_clock(host, clock);
1343645289dca5021224279e67b4655796cafdfdad00Pierre Ossman		}
1344645289dca5021224279e67b4655796cafdfdad00Pierre Ossman
1345645289dca5021224279e67b4655796cafdfdad00Pierre Ossman		/* Spec says we should do both at the same time, but Ricoh
1346645289dca5021224279e67b4655796cafdfdad00Pierre Ossman		   controllers do not like that. */
1347d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_reset(host, SDHCI_RESET_CMD);
1348d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_reset(host, SDHCI_RESET_DATA);
1349d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1350d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1351d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->mrq = NULL;
1352d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->cmd = NULL;
1353d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->data = NULL;
1354d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1355f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifndef SDHCI_USE_LEDS_CLASS
1356d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	sdhci_deactivate_led(host);
13572f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
1358d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
13595f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
1360d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1361d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1362d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mmc_request_done(host->mmc, mrq);
1363d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1364d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1365d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_timeout_timer(unsigned long data)
1366d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1367d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1368d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	unsigned long flags;
1369d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1370d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = (struct sdhci_host*)data;
1371d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1372d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_irqsave(&host->lock, flags);
1373d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1374d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (host->mrq) {
1375acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman		printk(KERN_ERR "%s: Timeout waiting for hardware "
1376acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman			"interrupt.\n", mmc_hostname(host->mmc));
1377d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_dumpregs(host);
1378d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1379d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		if (host->data) {
138017b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman			host->data->error = -ETIMEDOUT;
1381d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_finish_data(host);
1382d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		} else {
1383d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			if (host->cmd)
138417b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman				host->cmd->error = -ETIMEDOUT;
1385d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			else
138617b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman				host->mrq->cmd->error = -ETIMEDOUT;
1387d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1388d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			tasklet_schedule(&host->finish_tasklet);
1389d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
1390d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1391d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
13925f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
1393d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock_irqrestore(&host->lock, flags);
1394d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1395d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1396d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
1397d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1398d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Interrupt handling                                                        *
1399d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1400d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
1401d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1402d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
1403d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1404d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	BUG_ON(intmask == 0);
1405d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1406d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (!host->cmd) {
1407b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
1408b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman			"though no command operation was in progress.\n",
1409b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman			mmc_hostname(host->mmc), (unsigned)intmask);
1410d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_dumpregs(host);
1411d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		return;
1412d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1413d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
141443b58b36b7e6554b8a96be6b9f63542c583c06e5Pierre Ossman	if (intmask & SDHCI_INT_TIMEOUT)
141517b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		host->cmd->error = -ETIMEDOUT;
141617b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
141717b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman			SDHCI_INT_INDEX))
141817b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		host->cmd->error = -EILSEQ;
141943b58b36b7e6554b8a96be6b9f63542c583c06e5Pierre Ossman
1420e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	if (host->cmd->error) {
1421d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->finish_tasklet);
1422e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		return;
1423e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	}
1424e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman
1425e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	/*
1426e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * The host can send and interrupt when the busy state has
1427e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * ended, allowing us to wait without wasting CPU cycles.
1428e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * Unfortunately this is overloaded on the "data complete"
1429e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * interrupt, so we need to take some care when handling
1430e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * it.
1431e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 *
1432e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 * Note: The 1.0 specification is a bit ambiguous about this
1433e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 *       feature so there might be some problems with older
1434e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 *       controllers.
1435e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	 */
1436e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	if (host->cmd->flags & MMC_RSP_BUSY) {
1437e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		if (host->cmd->data)
1438e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman			DBG("Cannot wait for busy signal when also "
1439e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman				"doing a data transfer");
1440f945405cdecd9e0ae3e58ff84cabd19b4522965eBen Dooks		else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
1441e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman			return;
1442f945405cdecd9e0ae3e58ff84cabd19b4522965eBen Dooks
1443f945405cdecd9e0ae3e58ff84cabd19b4522965eBen Dooks		/* The controller does not support the end-of-busy IRQ,
1444f945405cdecd9e0ae3e58ff84cabd19b4522965eBen Dooks		 * fall through and take the SDHCI_INT_RESPONSE */
1445e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	}
1446e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman
1447e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman	if (intmask & SDHCI_INT_RESPONSE)
144843b58b36b7e6554b8a96be6b9f63542c583c06e5Pierre Ossman		sdhci_finish_command(host);
1449d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1450d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
14510957c3339efa333b7895157eb18b9b578394f80cGeorge G. Davis#ifdef CONFIG_MMC_DEBUG
14526882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooksstatic void sdhci_show_adma_error(struct sdhci_host *host)
14536882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks{
14546882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	const char *name = mmc_hostname(host->mmc);
14556882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	u8 *desc = host->adma_desc;
14566882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	__le32 *dma;
14576882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	__le16 *len;
14586882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	u8 attr;
14596882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
14606882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	sdhci_dumpregs(host);
14616882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
14626882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	while (true) {
14636882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		dma = (__le32 *)(desc + 4);
14646882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		len = (__le16 *)(desc + 2);
14656882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		attr = *desc;
14666882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
14676882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
14686882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		    name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr);
14696882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
14706882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		desc += 8;
14716882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
14726882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		if (attr & 2)
14736882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks			break;
14746882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	}
14756882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks}
14766882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks#else
14776882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooksstatic void sdhci_show_adma_error(struct sdhci_host *host) { }
14786882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks#endif
14796882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks
1480d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
1481d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1482d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	BUG_ON(intmask == 0);
1483d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1484d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (!host->data) {
1485d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		/*
1486e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		 * The "data complete" interrupt is also used to
1487e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		 * indicate that a busy state has ended. See comment
1488e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		 * above in sdhci_cmd_irq().
1489d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		 */
1490e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
1491e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman			if (intmask & SDHCI_INT_DATA_END) {
1492e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman				sdhci_finish_command(host);
1493e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman				return;
1494e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman			}
1495e809517f6fa5803a5a1cd56026f0e2190fc13d5cPierre Ossman		}
1496d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1497b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
1498b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman			"though no data operation was in progress.\n",
1499b67ac3f339c76dfea3cc75fc0285b6d13edc35faPierre Ossman			mmc_hostname(host->mmc), (unsigned)intmask);
1500d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_dumpregs(host);
1501d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1502d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		return;
1503d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1504d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1505d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (intmask & SDHCI_INT_DATA_TIMEOUT)
150617b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		host->data->error = -ETIMEDOUT;
150717b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
150817b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman		host->data->error = -EILSEQ;
15096882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	else if (intmask & SDHCI_INT_ADMA_ERROR) {
15106882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc));
15116882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks		sdhci_show_adma_error(host);
15122134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->data->error = -EIO;
15136882a8c071d609f4c088bee41e79572c7cfc1790Ben Dooks	}
1514d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
151517b0429dde9ab60f9cee8e07ab28c7dc6cfe6efdPierre Ossman	if (host->data->error)
1516d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_finish_data(host);
1517d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	else {
1518a406f5a3b68ee1db2306a2ba1c9b00dbd3505d05Pierre Ossman		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
1519d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			sdhci_transfer_pio(host);
1520d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15216ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		/*
15226ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		 * We currently don't do anything fancy with DMA
15236ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		 * boundaries, but as we can't disable the feature
15246ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		 * we need to at least restart the transfer.
15256ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		 */
15266ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman		if (intmask & SDHCI_INT_DMA_END)
15274e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
15284e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov				SDHCI_DMA_ADDRESS);
15296ba736a10e4ae63b38ccfee9f22b3263a6e5d050Pierre Ossman
1530e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman		if (intmask & SDHCI_INT_DATA_END) {
1531e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman			if (host->cmd) {
1532e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				/*
1533e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				 * Data managed to finish before the
1534e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				 * command completed. Make sure we do
1535e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				 * things in the proper order.
1536e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				 */
1537e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				host->data_early = 1;
1538e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman			} else {
1539e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman				sdhci_finish_data(host);
1540e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman			}
1541e538fbe83e374a3521128c1f4642aca037661c9dPierre Ossman		}
1542d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1543d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1544d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15457d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t sdhci_irq(int irq, void *dev_id)
1546d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1547d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	irqreturn_t result;
1548d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host* host = dev_id;
1549d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	u32 intmask;
1550f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	int cardint = 0;
1551d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1552d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock(&host->lock);
1553d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15544e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
1555d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
155662df67a523acd7a22d936bf946b1889dbd60ca98Mark Lord	if (!intmask || intmask == 0xffffffff) {
1557d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		result = IRQ_NONE;
1558d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		goto out;
1559d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1560d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1561b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman	DBG("*** %s got interrupt: 0x%08x\n",
1562b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman		mmc_hostname(host->mmc), intmask);
1563d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15643192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
15654e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
15664e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
1567d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		tasklet_schedule(&host->card_tasklet);
15683192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	}
1569d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15703192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
1571d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15723192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	if (intmask & SDHCI_INT_CMD_MASK) {
15734e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
15744e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov			SDHCI_INT_STATUS);
15753192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
1576d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1577d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1578d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (intmask & SDHCI_INT_DATA_MASK) {
15794e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
15804e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov			SDHCI_INT_STATUS);
15813192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
1582d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1583d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1584d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
1585d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1586964f9ce2ff42dc47cf40fbd2f5c81cd60689e384Pierre Ossman	intmask &= ~SDHCI_INT_ERROR;
1587964f9ce2ff42dc47cf40fbd2f5c81cd60689e384Pierre Ossman
1588d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (intmask & SDHCI_INT_BUS_POWER) {
15893192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman		printk(KERN_ERR "%s: Card is consuming too much power!\n",
1590d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman			mmc_hostname(host->mmc));
15914e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
1592d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1593d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
15949d26a5d3f2b9c4fe4b2ba491683c6989ecd6ae04Rolf Eike Beer	intmask &= ~SDHCI_INT_BUS_POWER;
15953192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman
1596f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	if (intmask & SDHCI_INT_CARD_INT)
1597f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman		cardint = 1;
1598f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1599f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	intmask &= ~SDHCI_INT_CARD_INT;
1600f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
16013192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	if (intmask) {
1602acf1da4522add3771f4851c09c7fe6bcf1dd6636Pierre Ossman		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
16033192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman			mmc_hostname(host->mmc), intmask);
1604d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_dumpregs(host);
1605d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16064e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
16073192a28f7d34ea8f1d0fef8ca5bc0314b5b5bb19Pierre Ossman	}
1608d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1609d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	result = IRQ_HANDLED;
1610d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16115f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
1612d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanout:
1613d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_unlock(&host->lock);
1614d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1615f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	/*
1616f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	 * We have to delay this as it calls back into the driver.
1617f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	 */
1618f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman	if (cardint)
1619f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman		mmc_signal_sdio_irq(host->mmc);
1620f75979b77fb20b01522d8fab96dfc76cc9f42420Pierre Ossman
1621d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	return result;
1622d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1623d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1624d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
1625d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1626d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Suspend/resume                                                            *
1627d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1628d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
1629d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1630d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#ifdef CONFIG_PM
1631d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1632b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossmanint sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
1633d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1634b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	int ret;
1635a715dfc7b9ef15ed5b398b185bd84cc015ff37f6Pierre Ossman
16367260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_disable_card_detection(host);
16377260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
16381a13f8fa76c880be41d6b1e6a2b44404bcbfdf9eMatt Fleming	ret = mmc_suspend_host(host->mmc);
1639b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (ret)
1640b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		return ret;
1641a715dfc7b9ef15ed5b398b185bd84cc015ff37f6Pierre Ossman
1642b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	free_irq(host->irq, host);
1643d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16449bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	if (host->vmmc)
16459bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		ret = regulator_disable(host->vmmc);
16469bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski
16479bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	return ret;
1648d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1649d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1650b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_suspend_host);
1651d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1652b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossmanint sdhci_resume_host(struct sdhci_host *host)
1653b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman{
1654b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	int ret;
1655d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16569bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	if (host->vmmc) {
16579bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		int ret = regulator_enable(host->vmmc);
16589bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		if (ret)
16599bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski			return ret;
16609bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	}
16619bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski
16629bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski
1663a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1664b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		if (host->ops->enable_dma)
1665b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman			host->ops->enable_dma(host);
1666b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	}
1667d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1668b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1669b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman			  mmc_hostname(host->mmc), host);
1670df1c4b7bf7f3b3a48d78c6e5c2fc5b9a1c01b821Pierre Ossman	if (ret)
1671df1c4b7bf7f3b3a48d78c6e5c2fc5b9a1c01b821Pierre Ossman		return ret;
1672d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16732f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
1674b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	mmiowb();
1675b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman
1676b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	ret = mmc_resume_host(host->mmc);
16777260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_enable_card_detection(host);
16787260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
16792f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	return ret;
1680d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
1681d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1682b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_resume_host);
1683d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
16845f619704d18b93869d045abc49e09cdba109b04bDaniel Drakevoid sdhci_enable_irq_wakeups(struct sdhci_host *host)
16855f619704d18b93869d045abc49e09cdba109b04bDaniel Drake{
16865f619704d18b93869d045abc49e09cdba109b04bDaniel Drake	u8 val;
16875f619704d18b93869d045abc49e09cdba109b04bDaniel Drake	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
16885f619704d18b93869d045abc49e09cdba109b04bDaniel Drake	val |= SDHCI_WAKE_ON_INT;
16895f619704d18b93869d045abc49e09cdba109b04bDaniel Drake	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
16905f619704d18b93869d045abc49e09cdba109b04bDaniel Drake}
16915f619704d18b93869d045abc49e09cdba109b04bDaniel Drake
16925f619704d18b93869d045abc49e09cdba109b04bDaniel DrakeEXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
16935f619704d18b93869d045abc49e09cdba109b04bDaniel Drake
1694d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#endif /* CONFIG_PM */
1695d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1696d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
1697d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1698b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman * Device allocation/registration                                            *
1699d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
1700d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
1701d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1702b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossmanstruct sdhci_host *sdhci_alloc_host(struct device *dev,
1703b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	size_t priv_size)
1704d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
1705d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct mmc_host *mmc;
1706d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	struct sdhci_host *host;
1707d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1708b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	WARN_ON(dev == NULL);
1709d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1710b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
1711d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (!mmc)
1712b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		return ERR_PTR(-ENOMEM);
1713d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1714d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host = mmc_priv(mmc);
1715d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	host->mmc = mmc;
1716d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1717b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	return host;
1718b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman}
17198a4da1430f7f2a16df3be9c7b5d55ba4e75b708cPierre Ossman
1720b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_alloc_host);
1721d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1722b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossmanint sdhci_add_host(struct sdhci_host *host)
1723b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman{
1724b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	struct mmc_host *mmc;
1725b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	unsigned int caps;
1726b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	int ret;
1727d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1728b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	WARN_ON(host == NULL);
1729b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (host == NULL)
1730b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		return -EINVAL;
1731d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1732b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	mmc = host->mmc;
1733d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1734b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (debug_quirks)
1735b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		host->quirks = debug_quirks;
1736d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1737d96649ed5ace812ffc8d86252d7c663326ca47f8Pierre Ossman	sdhci_reset(host, SDHCI_RESET_ALL);
1738d96649ed5ace812ffc8d86252d7c663326ca47f8Pierre Ossman
17394e4141a526dd7f5ac3ce1458ae79ea6e5a515b06Anton Vorontsov	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
17402134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->version = (host->version & SDHCI_SPEC_VER_MASK)
17412134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				>> SDHCI_SPEC_VER_SHIFT;
174285105c53b0ce70a277160379f9d89309cefc0bfdZhangfei Gao	if (host->version > SDHCI_SPEC_300) {
17434a9655051fb1efa568e53baf5dfb21e33bad6bf6Pierre Ossman		printk(KERN_ERR "%s: Unknown controller version (%d). "
1744b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman			"You may experience problems.\n", mmc_hostname(mmc),
17452134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			host->version);
17464a9655051fb1efa568e53baf5dfb21e33bad6bf6Pierre Ossman	}
17474a9655051fb1efa568e53baf5dfb21e33bad6bf6Pierre Ossman
1748ccc92c23240cdf952ef7cc39ba563910dcbc9cbeMaxim Levitsky	caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
1749ccc92c23240cdf952ef7cc39ba563910dcbc9cbeMaxim Levitsky		sdhci_readl(host, SDHCI_CAPABILITIES);
1750d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1751b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
1752a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		host->flags |= SDHCI_USE_SDMA;
1753a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	else if (!(caps & SDHCI_CAN_DO_SDMA))
1754a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		DBG("Controller doesn't have SDMA capability\n");
17556743527441430586aa82a0dee1b2700a2a974ebcPierre Ossman	else
1756a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		host->flags |= SDHCI_USE_SDMA;
1757d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1758b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
1759a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		(host->flags & SDHCI_USE_SDMA)) {
1760cee687ce4ab1197e20d4dacc09df01531362fdbdRolf Eike Beer		DBG("Disabling DMA as it is marked broken\n");
1761a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		host->flags &= ~SDHCI_USE_SDMA;
17627c168e3db7d900008ee304574057e0dc1a8505afFeng Tang	}
17637c168e3db7d900008ee304574057e0dc1a8505afFeng Tang
1764a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
1765a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		host->flags |= SDHCI_USE_ADMA;
17662134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
17672134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
17682134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		(host->flags & SDHCI_USE_ADMA)) {
17692134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		DBG("Disabling ADMA as it is marked broken\n");
17702134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->flags &= ~SDHCI_USE_ADMA;
17712134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
17722134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
1773a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1774b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		if (host->ops->enable_dma) {
1775b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman			if (host->ops->enable_dma(host)) {
1776b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman				printk(KERN_WARNING "%s: No suitable DMA "
1777b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman					"available. Falling back to PIO.\n",
1778b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman					mmc_hostname(mmc));
1779a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors				host->flags &=
1780a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors					~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
1781b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman			}
1782d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		}
1783d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	}
1784d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
17852134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->flags & SDHCI_USE_ADMA) {
17862134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		/*
17872134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * We need to allocate descriptors for all sg entries
17882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * (128) and potentially one alignment transfer for
17892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 * each of those entries.
17902134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		 */
17912134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
17922134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
17932134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		if (!host->adma_desc || !host->align_buffer) {
17942134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			kfree(host->adma_desc);
17952134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			kfree(host->align_buffer);
17962134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			printk(KERN_WARNING "%s: Unable to allocate ADMA "
17972134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				"buffers. Falling back to standard DMA.\n",
17982134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman				mmc_hostname(mmc));
17992134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman			host->flags &= ~SDHCI_USE_ADMA;
18002134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		}
18012134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	}
18022134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
18037659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	/*
18047659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	 * If we use DMA, then it's up to the caller to set the DMA
18057659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	 * mask, but PIO does not need the hw shim so we set a new
18067659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	 * mask here in that case.
18077659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	 */
1808a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
18097659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		host->dma_mask = DMA_BIT_MASK(64);
18107659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman		mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
18117659150c60839a2bd31f74e866374abb9be17e43Pierre Ossman	}
1812d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1813c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao	if (host->version >= SDHCI_SPEC_300)
1814c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao		host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK)
1815c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao			>> SDHCI_CLOCK_BASE_SHIFT;
1816c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao	else
1817c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao		host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK)
1818c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao			>> SDHCI_CLOCK_BASE_SHIFT;
1819c4687d5f601be3f928b815b46964f7426c31aec7Zhangfei Gao
18204240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks	host->max_clk *= 1000000;
1821f27f47ef5b67106ff1cdeebf061387a7b30c12bcAnton Vorontsov	if (host->max_clk == 0 || host->quirks &
1822f27f47ef5b67106ff1cdeebf061387a7b30c12bcAnton Vorontsov			SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
18234240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks		if (!host->ops->get_max_clock) {
18244240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			printk(KERN_ERR
18254240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			       "%s: Hardware doesn't specify base clock "
18264240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			       "frequency.\n", mmc_hostname(mmc));
18274240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			return -ENODEV;
18284240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks		}
18294240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks		host->max_clk = host->ops->get_max_clock(host);
18308ef1a14379e105c1419d21e96ffac53202bc0501Pierre Ossman	}
1831d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
18321c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	host->timeout_clk =
18331c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
18341c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	if (host->timeout_clk == 0) {
183581b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov		if (host->ops->get_timeout_clock) {
183681b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov			host->timeout_clk = host->ops->get_timeout_clock(host);
183781b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov		} else if (!(host->quirks &
183881b39802468fe4bf5c6b038837319b608acfdd3eAnton Vorontsov				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
18394240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			printk(KERN_ERR
18404240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			       "%s: Hardware doesn't specify timeout clock "
18414240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			       "frequency.\n", mmc_hostname(mmc));
18424240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks			return -ENODEV;
18434240ff0a02cb52f7d10dc1df6d82ba9c27dba07bBen Dooks		}
18441c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	}
18451c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
18461c8cde92fa5c57daa9ff58d970ca6374f8d484a2Pierre Ossman		host->timeout_clk *= 1000;
1847d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1848d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1849d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * Set host parameters.
1850d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
1851d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mmc->ops = &sdhci_ops;
1852ce5f036bbbfc6c21d7b55b8fdaa2e2bd56392d94Marek Szyprowski	if (host->ops->get_min_clock)
1853a9e58f25734e153b8c6516d904e2398fb8b0b23dAnton Vorontsov		mmc->f_min = host->ops->get_min_clock(host);
18540397526d6ae2518b6c53efd1ff1e81b7d24c91daZhangfei Gao	else if (host->version >= SDHCI_SPEC_300)
18550397526d6ae2518b6c53efd1ff1e81b7d24c91daZhangfei Gao		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
1856a9e58f25734e153b8c6516d904e2398fb8b0b23dAnton Vorontsov	else
18570397526d6ae2518b6c53efd1ff1e81b7d24c91daZhangfei Gao		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
1858d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mmc->f_max = host->max_clk;
1859c1f5977c6a136acbf525c634c8511e19d0c1f195Kyungmin Park	mmc->caps |= MMC_CAP_SDIO_IRQ;
18605fe23c7f51def59f66bc6aeee988ef1a467a2c8cAnton Vorontsov
18615fe23c7f51def59f66bc6aeee988ef1a467a2c8cAnton Vorontsov	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
1862b08caed8659ab27199db51c63a35c5ee067fc7efGiuseppe Cavallaro		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
1863d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
186486a6a8749d5b8fd5c2b544fe9fd11101e3d0550fPierre Ossman	if (caps & SDHCI_CAN_DO_HISPD)
1865a29e7e18bddde778deb2cb101dbceca56b15e05eZhangfei Gao		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
1866cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman
1867176d1ed426a2a73a87c62a8aa05f6d002353cd50Jaehoon Chung	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
1868176d1ed426a2a73a87c62a8aa05f6d002353cd50Jaehoon Chung	    mmc_card_is_removable(mmc))
186968d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov		mmc->caps |= MMC_CAP_NEEDS_POLL;
187068d1fb7e229c6f95be4fbbe3eb46b24e41184924Anton Vorontsov
1871146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman	mmc->ocr_avail = 0;
1872146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman	if (caps & SDHCI_CAN_VDD_330)
1873146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
1874c70840e819acdbab96b8cdf71d27cb68c6567efaPierre Ossman	if (caps & SDHCI_CAN_VDD_300)
1875146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
1876c70840e819acdbab96b8cdf71d27cb68c6567efaPierre Ossman	if (caps & SDHCI_CAN_VDD_180)
187755556da01284af8c2174b786b3eca8e11301b656Philip Langdale		mmc->ocr_avail |= MMC_VDD_165_195;
1878146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1879146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman	if (mmc->ocr_avail == 0) {
1880146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman		printk(KERN_ERR "%s: Hardware doesn't report any "
1881b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman			"support voltages.\n", mmc_hostname(mmc));
1882b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman		return -ENODEV;
1883146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman	}
1884146ad66eac836c0b976c98f428d73e1f6a75270dPierre Ossman
1885d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	spin_lock_init(&host->lock);
1886d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1887d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
18882134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * Maximum number of segments. Depends on if the hardware
18892134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * can do scatter/gather or not.
1890d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
18912134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->flags & SDHCI_USE_ADMA)
1892a36274e0184193e393fb82957925c3981a6b0477Martin K. Petersen		mmc->max_segs = 128;
1893a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	else if (host->flags & SDHCI_USE_SDMA)
1894a36274e0184193e393fb82957925c3981a6b0477Martin K. Petersen		mmc->max_segs = 1;
18952134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	else /* PIO */
1896a36274e0184193e393fb82957925c3981a6b0477Martin K. Petersen		mmc->max_segs = 128;
1897d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1898d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1899bab7696184bbf0ea48d56902bd1f9ac983079ad2Pierre Ossman	 * Maximum number of sectors in one transfer. Limited by DMA boundary
190055db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman	 * size (512KiB).
1901d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
190255db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman	mmc->max_req_size = 524288;
1903d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1904d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1905d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * Maximum segment size. Could be one segment with the maximum number
19062134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * of bytes. When doing hardware scatter/gather, each entry cannot
19072134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	 * be larger than 64 KiB though.
1908d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
19092134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	if (host->flags & SDHCI_USE_ADMA)
19102134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		mmc->max_seg_size = 65536;
19112134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	else
19122134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman		mmc->max_seg_size = mmc->max_req_size;
1913d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1914d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	/*
1915fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman	 * Maximum block size. This varies from controller to controller and
1916fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman	 * is specified in the capabilities register.
1917fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman	 */
19180633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
19190633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov		mmc->max_blk_size = 2;
19200633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov	} else {
19210633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
19220633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov				SDHCI_MAX_BLOCK_SHIFT;
19230633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov		if (mmc->max_blk_size >= 3) {
19240633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov			printk(KERN_WARNING "%s: Invalid maximum block size, "
19250633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov				"assuming 512 bytes\n", mmc_hostname(mmc));
19260633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov			mmc->max_blk_size = 0;
19270633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov		}
19280633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov	}
19290633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov
19300633f654241483edc8a235ab87264ff6bbcd08d5Anton Vorontsov	mmc->max_blk_size = 512 << mmc->max_blk_size;
1931fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman
1932fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman	/*
193355db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman	 * Maximum block count.
193455db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman	 */
19351388eefd5a5e6aaa3cb04070bfc2b944c1d24b82Ben Dooks	mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
193655db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman
193755db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman	/*
1938d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 * Init tasklets.
1939d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	 */
1940d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_init(&host->card_tasklet,
1941d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_tasklet_card, (unsigned long)host);
1942d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_init(&host->finish_tasklet,
1943d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman		sdhci_tasklet_finish, (unsigned long)host);
1944d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1945e4cad1b5a4851c90c1bcf460062074a2fa10815bAl Viro	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
1946d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1947dace145374b8e39aeb920304c358ab5e220341abThomas Gleixner	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1948b69c9058907642f8e1b32076906755c6623ea060Pierre Ossman		mmc_hostname(mmc), host);
1949d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	if (ret)
19508ef1a14379e105c1419d21e96ffac53202bc0501Pierre Ossman		goto untasklet;
1951d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
19529bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
19539bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	if (IS_ERR(host->vmmc)) {
19549bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc));
19559bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		host->vmmc = NULL;
19569bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	} else {
19579bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		regulator_enable(host->vmmc);
19589bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	}
19599bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski
19602f4cbb3d834922ffa0309b6a08fa42dac87ef9d2Nicolas Pitre	sdhci_init(host, 0);
1961d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1962d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#ifdef CONFIG_MMC_DEBUG
1963d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	sdhci_dumpregs(host);
1964d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman#endif
1965d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1966f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifdef SDHCI_USE_LEDS_CLASS
19675dbace0c9ba110c1a3810a89fa6bf12b7574b5a3Helmut Schaa	snprintf(host->led_name, sizeof(host->led_name),
19685dbace0c9ba110c1a3810a89fa6bf12b7574b5a3Helmut Schaa		"%s::", mmc_hostname(mmc));
19695dbace0c9ba110c1a3810a89fa6bf12b7574b5a3Helmut Schaa	host->led.name = host->led_name;
19702f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	host->led.brightness = LED_OFF;
19712f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	host->led.default_trigger = mmc_hostname(mmc);
19722f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	host->led.brightness_set = sdhci_led_control;
19732f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
1974b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	ret = led_classdev_register(mmc_dev(mmc), &host->led);
19752f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	if (ret)
19762f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman		goto reset;
19772f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
19782f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
19795f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman	mmiowb();
19805f25a66f6bbac563c94af94f03491b3ae43c40afPierre Ossman
1981d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	mmc_add_host(mmc);
1982d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1983a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
1984d1b268630875a7713b5d468a0c03403c5b721c8eKay Sievers		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
1985a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		(host->flags & SDHCI_USE_ADMA) ? "ADMA" :
1986a13abc7b0814da7733c531453a207729b542ecf8Richard Röjfors		(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
1987d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
19887260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_enable_card_detection(host);
19897260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
1990d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	return 0;
1991d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
1992f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifdef SDHCI_USE_LEDS_CLASS
19932f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossmanreset:
19942f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	sdhci_reset(host, SDHCI_RESET_ALL);
19952f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	free_irq(host->irq, host);
19962f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
19978ef1a14379e105c1419d21e96ffac53202bc0501Pierre Ossmanuntasklet:
1998d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_kill(&host->card_tasklet);
1999d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_kill(&host->finish_tasklet);
2000d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2001d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	return ret;
2002d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
2003d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2004b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_add_host);
2005d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
20061e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossmanvoid sdhci_remove_host(struct sdhci_host *host, int dead)
2007b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman{
20081e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	unsigned long flags;
20091e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20101e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (dead) {
20111e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		spin_lock_irqsave(&host->lock, flags);
20121e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20131e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		host->flags |= SDHCI_DEVICE_DEAD;
20141e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20151e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		if (host->mrq) {
20161e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman			printk(KERN_ERR "%s: Controller removed during "
20171e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman				" transfer!\n", mmc_hostname(host->mmc));
20181e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20191e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman			host->mrq->cmd->error = -ENOMEDIUM;
20201e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman			tasklet_schedule(&host->finish_tasklet);
20211e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		}
20221e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20231e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		spin_unlock_irqrestore(&host->lock, flags);
20241e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	}
20251e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman
20267260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov	sdhci_disable_card_detection(host);
20277260cf5e12393536ce61d184c3fc750fb2ba635aAnton Vorontsov
2028b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	mmc_remove_host(host->mmc);
2029d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2030f9134319c81c6c56e0ddf38e7adac2492b243d9bPierre Ossman#ifdef SDHCI_USE_LEDS_CLASS
20312f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman	led_classdev_unregister(&host->led);
20322f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman#endif
20332f730fec83be76f1b3b8f0066b3447f55c50d7a0Pierre Ossman
20341e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman	if (!dead)
20351e72859e3ae16346d4007024b20d2d4ef387dcc3Pierre Ossman		sdhci_reset(host, SDHCI_RESET_ALL);
2036d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2037d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	free_irq(host->irq, host);
2038d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2039d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	del_timer_sync(&host->timer);
2040d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2041d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_kill(&host->card_tasklet);
2042d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	tasklet_kill(&host->finish_tasklet);
20432134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
20449bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	if (host->vmmc) {
20459bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		regulator_disable(host->vmmc);
20469bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski		regulator_put(host->vmmc);
20479bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski	}
20489bea3c850dbff2296892298614388bdc71ad2170Marek Szyprowski
20492134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	kfree(host->adma_desc);
20502134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	kfree(host->align_buffer);
20512134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman
20522134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->adma_desc = NULL;
20532134a922c6e75c779983cad5d8aae832275f5a0dPierre Ossman	host->align_buffer = NULL;
2054d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
2055d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2056b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_remove_host);
2057d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2058b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossmanvoid sdhci_free_host(struct sdhci_host *host)
2059d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
2060b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	mmc_free_host(host->mmc);
2061d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
2062d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2063b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanEXPORT_SYMBOL_GPL(sdhci_free_host);
2064d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2065d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman/*****************************************************************************\
2066d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
2067d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman * Driver init/exit                                                          *
2068d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman *                                                                           *
2069d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman\*****************************************************************************/
2070d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2071d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic int __init sdhci_drv_init(void)
2072d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
2073d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_INFO DRIVER_NAME
207452fbf9c976b36654e08e94c3107ddbaac7e2da33Pierre Ossman		": Secure Digital Host Controller Interface driver\n");
2075d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
2076d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2077b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre Ossman	return 0;
2078d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
2079d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2080d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanstatic void __exit sdhci_drv_exit(void)
2081d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman{
2082d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman}
2083d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2084d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanmodule_init(sdhci_drv_init);
2085d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossmanmodule_exit(sdhci_drv_exit);
2086d129bceb1d44ed3c23b99164849193703372bab4Pierre Ossman
2087df673b227ce08a7706b30fd2bf6512393d9c3c29Pierre Ossmanmodule_param(debug_quirks, uint, 0444);
20886743527441430586aa82a0dee1b2700a2a974ebcPierre Ossman
208932710e8fd537adeb53f98dec92e4a77caac512f5Pierre OssmanMODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
2090b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3Pierre OssmanMODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
2091d129bceb1d44ed3c23b99164849193703372bab4Pierre OssmanMODULE_LICENSE("GPL");
20926743527441430586aa82a0dee1b2700a2a974ebcPierre Ossman
2093df673b227ce08a7706b30fd2bf6512393d9c3c29Pierre OssmanMODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
2094