xref: /openbmc/linux/drivers/mmc/host/sdhci.c (revision 2dfb579c)
11c6a0718SPierre Ossman /*
270f10482SPierre Ossman  *  linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver
31c6a0718SPierre Ossman  *
4b69c9058SPierre Ossman  *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
51c6a0718SPierre Ossman  *
61c6a0718SPierre Ossman  * This program is free software; you can redistribute it and/or modify
71c6a0718SPierre Ossman  * it under the terms of the GNU General Public License as published by
81c6a0718SPierre Ossman  * the Free Software Foundation; either version 2 of the License, or (at
91c6a0718SPierre Ossman  * your option) any later version.
1084c46a53SPierre Ossman  *
1184c46a53SPierre Ossman  * Thanks to the following companies for their support:
1284c46a53SPierre Ossman  *
1384c46a53SPierre Ossman  *     - JMicron (hardware and technical support)
141c6a0718SPierre Ossman  */
151c6a0718SPierre Ossman 
161c6a0718SPierre Ossman #include <linux/delay.h>
171c6a0718SPierre Ossman #include <linux/highmem.h>
18b8c86fc5SPierre Ossman #include <linux/io.h>
191c6a0718SPierre Ossman #include <linux/dma-mapping.h>
205a0e3ad6STejun Heo #include <linux/slab.h>
2111763609SRalf Baechle #include <linux/scatterlist.h>
229bea3c85SMarek Szyprowski #include <linux/regulator/consumer.h>
231c6a0718SPierre Ossman 
242f730fecSPierre Ossman #include <linux/leds.h>
252f730fecSPierre Ossman 
261c6a0718SPierre Ossman #include <linux/mmc/host.h>
271c6a0718SPierre Ossman 
281c6a0718SPierre Ossman #include "sdhci.h"
291c6a0718SPierre Ossman 
301c6a0718SPierre Ossman #define DRIVER_NAME "sdhci"
311c6a0718SPierre Ossman 
321c6a0718SPierre Ossman #define DBG(f, x...) \
331c6a0718SPierre Ossman 	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
341c6a0718SPierre Ossman 
35f9134319SPierre Ossman #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
36f9134319SPierre Ossman 	defined(CONFIG_MMC_SDHCI_MODULE))
37f9134319SPierre Ossman #define SDHCI_USE_LEDS_CLASS
38f9134319SPierre Ossman #endif
39f9134319SPierre Ossman 
401c6a0718SPierre Ossman static unsigned int debug_quirks = 0;
411c6a0718SPierre Ossman 
421c6a0718SPierre Ossman static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
431c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *);
441c6a0718SPierre Ossman 
451c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
461c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *);
471c6a0718SPierre Ossman 
481c6a0718SPierre Ossman static void sdhci_dumpregs(struct sdhci_host *host)
491c6a0718SPierre Ossman {
50412ab659SPhilip Rakity 	printk(KERN_DEBUG DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
51412ab659SPhilip Rakity 		mmc_hostname(host->mmc));
521c6a0718SPierre Ossman 
531c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
544e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_DMA_ADDRESS),
554e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_HOST_VERSION));
561c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
574e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_BLOCK_SIZE),
584e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_BLOCK_COUNT));
591c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
604e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_ARGUMENT),
614e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
621c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
634e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_PRESENT_STATE),
644e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_HOST_CONTROL));
651c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
664e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_POWER_CONTROL),
674e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
681c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
694e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
704e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
711c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
724e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
734e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_INT_STATUS));
741c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
754e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_INT_ENABLE),
764e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
771c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
784e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_ACMD12_ERR),
794e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
801c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
814e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_CAPABILITIES),
824e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_MAX_CURRENT));
831c6a0718SPierre Ossman 
84be3f4ae0SBen Dooks 	if (host->flags & SDHCI_USE_ADMA)
85be3f4ae0SBen Dooks 		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
86be3f4ae0SBen Dooks 		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
87be3f4ae0SBen Dooks 		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
88be3f4ae0SBen Dooks 
891c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
901c6a0718SPierre Ossman }
911c6a0718SPierre Ossman 
921c6a0718SPierre Ossman /*****************************************************************************\
931c6a0718SPierre Ossman  *                                                                           *
941c6a0718SPierre Ossman  * Low level functions                                                       *
951c6a0718SPierre Ossman  *                                                                           *
961c6a0718SPierre Ossman \*****************************************************************************/
971c6a0718SPierre Ossman 
987260cf5eSAnton Vorontsov static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
997260cf5eSAnton Vorontsov {
1007260cf5eSAnton Vorontsov 	u32 ier;
1017260cf5eSAnton Vorontsov 
1027260cf5eSAnton Vorontsov 	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
1037260cf5eSAnton Vorontsov 	ier &= ~clear;
1047260cf5eSAnton Vorontsov 	ier |= set;
1057260cf5eSAnton Vorontsov 	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
1067260cf5eSAnton Vorontsov 	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
1077260cf5eSAnton Vorontsov }
1087260cf5eSAnton Vorontsov 
1097260cf5eSAnton Vorontsov static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
1107260cf5eSAnton Vorontsov {
1117260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, 0, irqs);
1127260cf5eSAnton Vorontsov }
1137260cf5eSAnton Vorontsov 
1147260cf5eSAnton Vorontsov static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
1157260cf5eSAnton Vorontsov {
1167260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, irqs, 0);
1177260cf5eSAnton Vorontsov }
1187260cf5eSAnton Vorontsov 
1197260cf5eSAnton Vorontsov static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
1207260cf5eSAnton Vorontsov {
1217260cf5eSAnton Vorontsov 	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
1227260cf5eSAnton Vorontsov 
12368d1fb7eSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
12468d1fb7eSAnton Vorontsov 		return;
12568d1fb7eSAnton Vorontsov 
1267260cf5eSAnton Vorontsov 	if (enable)
1277260cf5eSAnton Vorontsov 		sdhci_unmask_irqs(host, irqs);
1287260cf5eSAnton Vorontsov 	else
1297260cf5eSAnton Vorontsov 		sdhci_mask_irqs(host, irqs);
1307260cf5eSAnton Vorontsov }
1317260cf5eSAnton Vorontsov 
1327260cf5eSAnton Vorontsov static void sdhci_enable_card_detection(struct sdhci_host *host)
1337260cf5eSAnton Vorontsov {
1347260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, true);
1357260cf5eSAnton Vorontsov }
1367260cf5eSAnton Vorontsov 
1377260cf5eSAnton Vorontsov static void sdhci_disable_card_detection(struct sdhci_host *host)
1387260cf5eSAnton Vorontsov {
1397260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, false);
1407260cf5eSAnton Vorontsov }
1417260cf5eSAnton Vorontsov 
1421c6a0718SPierre Ossman static void sdhci_reset(struct sdhci_host *host, u8 mask)
1431c6a0718SPierre Ossman {
1441c6a0718SPierre Ossman 	unsigned long timeout;
145063a9dbbSAnton Vorontsov 	u32 uninitialized_var(ier);
1461c6a0718SPierre Ossman 
147b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
1484e4141a5SAnton Vorontsov 		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
1491c6a0718SPierre Ossman 			SDHCI_CARD_PRESENT))
1501c6a0718SPierre Ossman 			return;
1511c6a0718SPierre Ossman 	}
1521c6a0718SPierre Ossman 
153063a9dbbSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
154063a9dbbSAnton Vorontsov 		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
155063a9dbbSAnton Vorontsov 
1564e4141a5SAnton Vorontsov 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
1571c6a0718SPierre Ossman 
1581c6a0718SPierre Ossman 	if (mask & SDHCI_RESET_ALL)
1591c6a0718SPierre Ossman 		host->clock = 0;
1601c6a0718SPierre Ossman 
1611c6a0718SPierre Ossman 	/* Wait max 100 ms */
1621c6a0718SPierre Ossman 	timeout = 100;
1631c6a0718SPierre Ossman 
1641c6a0718SPierre Ossman 	/* hw clears the bit when it's done */
1654e4141a5SAnton Vorontsov 	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
1661c6a0718SPierre Ossman 		if (timeout == 0) {
1671c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
1681c6a0718SPierre Ossman 				mmc_hostname(host->mmc), (int)mask);
1691c6a0718SPierre Ossman 			sdhci_dumpregs(host);
1701c6a0718SPierre Ossman 			return;
1711c6a0718SPierre Ossman 		}
1721c6a0718SPierre Ossman 		timeout--;
1731c6a0718SPierre Ossman 		mdelay(1);
1741c6a0718SPierre Ossman 	}
175063a9dbbSAnton Vorontsov 
176063a9dbbSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
177063a9dbbSAnton Vorontsov 		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
1781c6a0718SPierre Ossman }
1791c6a0718SPierre Ossman 
1802f4cbb3dSNicolas Pitre static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
1812f4cbb3dSNicolas Pitre 
1822f4cbb3dSNicolas Pitre static void sdhci_init(struct sdhci_host *host, int soft)
1831c6a0718SPierre Ossman {
1842f4cbb3dSNicolas Pitre 	if (soft)
1852f4cbb3dSNicolas Pitre 		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
1862f4cbb3dSNicolas Pitre 	else
1871c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_ALL);
1881c6a0718SPierre Ossman 
1897260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
1907260cf5eSAnton Vorontsov 		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
1911c6a0718SPierre Ossman 		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
1921c6a0718SPierre Ossman 		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
1936aa943abSAnton Vorontsov 		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
1942f4cbb3dSNicolas Pitre 
1952f4cbb3dSNicolas Pitre 	if (soft) {
1962f4cbb3dSNicolas Pitre 		/* force clock reconfiguration */
1972f4cbb3dSNicolas Pitre 		host->clock = 0;
1982f4cbb3dSNicolas Pitre 		sdhci_set_ios(host->mmc, &host->mmc->ios);
1992f4cbb3dSNicolas Pitre 	}
2007260cf5eSAnton Vorontsov }
2011c6a0718SPierre Ossman 
2027260cf5eSAnton Vorontsov static void sdhci_reinit(struct sdhci_host *host)
2037260cf5eSAnton Vorontsov {
2042f4cbb3dSNicolas Pitre 	sdhci_init(host, 0);
2057260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
2061c6a0718SPierre Ossman }
2071c6a0718SPierre Ossman 
2081c6a0718SPierre Ossman static void sdhci_activate_led(struct sdhci_host *host)
2091c6a0718SPierre Ossman {
2101c6a0718SPierre Ossman 	u8 ctrl;
2111c6a0718SPierre Ossman 
2124e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
2131c6a0718SPierre Ossman 	ctrl |= SDHCI_CTRL_LED;
2144e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2151c6a0718SPierre Ossman }
2161c6a0718SPierre Ossman 
2171c6a0718SPierre Ossman static void sdhci_deactivate_led(struct sdhci_host *host)
2181c6a0718SPierre Ossman {
2191c6a0718SPierre Ossman 	u8 ctrl;
2201c6a0718SPierre Ossman 
2214e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
2221c6a0718SPierre Ossman 	ctrl &= ~SDHCI_CTRL_LED;
2234e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2241c6a0718SPierre Ossman }
2251c6a0718SPierre Ossman 
226f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
2272f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led,
2282f730fecSPierre Ossman 	enum led_brightness brightness)
2292f730fecSPierre Ossman {
2302f730fecSPierre Ossman 	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
2312f730fecSPierre Ossman 	unsigned long flags;
2322f730fecSPierre Ossman 
2332f730fecSPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
2342f730fecSPierre Ossman 
2352f730fecSPierre Ossman 	if (brightness == LED_OFF)
2362f730fecSPierre Ossman 		sdhci_deactivate_led(host);
2372f730fecSPierre Ossman 	else
2382f730fecSPierre Ossman 		sdhci_activate_led(host);
2392f730fecSPierre Ossman 
2402f730fecSPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
2412f730fecSPierre Ossman }
2422f730fecSPierre Ossman #endif
2432f730fecSPierre Ossman 
2441c6a0718SPierre Ossman /*****************************************************************************\
2451c6a0718SPierre Ossman  *                                                                           *
2461c6a0718SPierre Ossman  * Core functions                                                            *
2471c6a0718SPierre Ossman  *                                                                           *
2481c6a0718SPierre Ossman \*****************************************************************************/
2491c6a0718SPierre Ossman 
2501c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host)
2511c6a0718SPierre Ossman {
2527659150cSPierre Ossman 	unsigned long flags;
2537659150cSPierre Ossman 	size_t blksize, len, chunk;
2547244b85bSSteven Noonan 	u32 uninitialized_var(scratch);
2557659150cSPierre Ossman 	u8 *buf;
2561c6a0718SPierre Ossman 
2571c6a0718SPierre Ossman 	DBG("PIO reading\n");
2581c6a0718SPierre Ossman 
2591c6a0718SPierre Ossman 	blksize = host->data->blksz;
2607659150cSPierre Ossman 	chunk = 0;
2611c6a0718SPierre Ossman 
2627659150cSPierre Ossman 	local_irq_save(flags);
2631c6a0718SPierre Ossman 
2641c6a0718SPierre Ossman 	while (blksize) {
2657659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
2667659150cSPierre Ossman 			BUG();
2677659150cSPierre Ossman 
2687659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
2697659150cSPierre Ossman 
2707659150cSPierre Ossman 		blksize -= len;
2717659150cSPierre Ossman 		host->sg_miter.consumed = len;
2727659150cSPierre Ossman 
2737659150cSPierre Ossman 		buf = host->sg_miter.addr;
2747659150cSPierre Ossman 
2757659150cSPierre Ossman 		while (len) {
2767659150cSPierre Ossman 			if (chunk == 0) {
2774e4141a5SAnton Vorontsov 				scratch = sdhci_readl(host, SDHCI_BUFFER);
2787659150cSPierre Ossman 				chunk = 4;
2791c6a0718SPierre Ossman 			}
2801c6a0718SPierre Ossman 
2817659150cSPierre Ossman 			*buf = scratch & 0xFF;
2821c6a0718SPierre Ossman 
2837659150cSPierre Ossman 			buf++;
2847659150cSPierre Ossman 			scratch >>= 8;
2857659150cSPierre Ossman 			chunk--;
2867659150cSPierre Ossman 			len--;
2877659150cSPierre Ossman 		}
2881c6a0718SPierre Ossman 	}
2891c6a0718SPierre Ossman 
2907659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
2917659150cSPierre Ossman 
2927659150cSPierre Ossman 	local_irq_restore(flags);
2931c6a0718SPierre Ossman }
2941c6a0718SPierre Ossman 
2951c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host)
2961c6a0718SPierre Ossman {
2977659150cSPierre Ossman 	unsigned long flags;
2987659150cSPierre Ossman 	size_t blksize, len, chunk;
2997659150cSPierre Ossman 	u32 scratch;
3007659150cSPierre Ossman 	u8 *buf;
3011c6a0718SPierre Ossman 
3021c6a0718SPierre Ossman 	DBG("PIO writing\n");
3031c6a0718SPierre Ossman 
3041c6a0718SPierre Ossman 	blksize = host->data->blksz;
3057659150cSPierre Ossman 	chunk = 0;
3067659150cSPierre Ossman 	scratch = 0;
3071c6a0718SPierre Ossman 
3087659150cSPierre Ossman 	local_irq_save(flags);
3091c6a0718SPierre Ossman 
3101c6a0718SPierre Ossman 	while (blksize) {
3117659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
3127659150cSPierre Ossman 			BUG();
3131c6a0718SPierre Ossman 
3147659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
3151c6a0718SPierre Ossman 
3167659150cSPierre Ossman 		blksize -= len;
3177659150cSPierre Ossman 		host->sg_miter.consumed = len;
3187659150cSPierre Ossman 
3197659150cSPierre Ossman 		buf = host->sg_miter.addr;
3207659150cSPierre Ossman 
3217659150cSPierre Ossman 		while (len) {
3227659150cSPierre Ossman 			scratch |= (u32)*buf << (chunk * 8);
3237659150cSPierre Ossman 
3247659150cSPierre Ossman 			buf++;
3257659150cSPierre Ossman 			chunk++;
3267659150cSPierre Ossman 			len--;
3277659150cSPierre Ossman 
3287659150cSPierre Ossman 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
3294e4141a5SAnton Vorontsov 				sdhci_writel(host, scratch, SDHCI_BUFFER);
3307659150cSPierre Ossman 				chunk = 0;
3317659150cSPierre Ossman 				scratch = 0;
3327659150cSPierre Ossman 			}
3337659150cSPierre Ossman 		}
3341c6a0718SPierre Ossman 	}
3351c6a0718SPierre Ossman 
3367659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
3371c6a0718SPierre Ossman 
3387659150cSPierre Ossman 	local_irq_restore(flags);
3391c6a0718SPierre Ossman }
3401c6a0718SPierre Ossman 
3411c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host)
3421c6a0718SPierre Ossman {
3431c6a0718SPierre Ossman 	u32 mask;
3441c6a0718SPierre Ossman 
3451c6a0718SPierre Ossman 	BUG_ON(!host->data);
3461c6a0718SPierre Ossman 
3477659150cSPierre Ossman 	if (host->blocks == 0)
3481c6a0718SPierre Ossman 		return;
3491c6a0718SPierre Ossman 
3501c6a0718SPierre Ossman 	if (host->data->flags & MMC_DATA_READ)
3511c6a0718SPierre Ossman 		mask = SDHCI_DATA_AVAILABLE;
3521c6a0718SPierre Ossman 	else
3531c6a0718SPierre Ossman 		mask = SDHCI_SPACE_AVAILABLE;
3541c6a0718SPierre Ossman 
3554a3cba32SPierre Ossman 	/*
3564a3cba32SPierre Ossman 	 * Some controllers (JMicron JMB38x) mess up the buffer bits
3574a3cba32SPierre Ossman 	 * for transfers < 4 bytes. As long as it is just one block,
3584a3cba32SPierre Ossman 	 * we can ignore the bits.
3594a3cba32SPierre Ossman 	 */
3604a3cba32SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
3614a3cba32SPierre Ossman 		(host->data->blocks == 1))
3624a3cba32SPierre Ossman 		mask = ~0;
3634a3cba32SPierre Ossman 
3644e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
3653e3bf207SAnton Vorontsov 		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
3663e3bf207SAnton Vorontsov 			udelay(100);
3673e3bf207SAnton Vorontsov 
3681c6a0718SPierre Ossman 		if (host->data->flags & MMC_DATA_READ)
3691c6a0718SPierre Ossman 			sdhci_read_block_pio(host);
3701c6a0718SPierre Ossman 		else
3711c6a0718SPierre Ossman 			sdhci_write_block_pio(host);
3721c6a0718SPierre Ossman 
3737659150cSPierre Ossman 		host->blocks--;
3747659150cSPierre Ossman 		if (host->blocks == 0)
3751c6a0718SPierre Ossman 			break;
3761c6a0718SPierre Ossman 	}
3771c6a0718SPierre Ossman 
3781c6a0718SPierre Ossman 	DBG("PIO transfer complete.\n");
3791c6a0718SPierre Ossman }
3801c6a0718SPierre Ossman 
3812134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
3822134a922SPierre Ossman {
3832134a922SPierre Ossman 	local_irq_save(*flags);
3842134a922SPierre Ossman 	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
3852134a922SPierre Ossman }
3862134a922SPierre Ossman 
3872134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
3882134a922SPierre Ossman {
3892134a922SPierre Ossman 	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
3902134a922SPierre Ossman 	local_irq_restore(*flags);
3912134a922SPierre Ossman }
3922134a922SPierre Ossman 
393118cd17dSBen Dooks static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd)
394118cd17dSBen Dooks {
3959e506f35SBen Dooks 	__le32 *dataddr = (__le32 __force *)(desc + 4);
3969e506f35SBen Dooks 	__le16 *cmdlen = (__le16 __force *)desc;
397118cd17dSBen Dooks 
3989e506f35SBen Dooks 	/* SDHCI specification says ADMA descriptors should be 4 byte
3999e506f35SBen Dooks 	 * aligned, so using 16 or 32bit operations should be safe. */
400118cd17dSBen Dooks 
4019e506f35SBen Dooks 	cmdlen[0] = cpu_to_le16(cmd);
4029e506f35SBen Dooks 	cmdlen[1] = cpu_to_le16(len);
4039e506f35SBen Dooks 
4049e506f35SBen Dooks 	dataddr[0] = cpu_to_le32(addr);
405118cd17dSBen Dooks }
406118cd17dSBen Dooks 
4078f1934ceSPierre Ossman static int sdhci_adma_table_pre(struct sdhci_host *host,
4082134a922SPierre Ossman 	struct mmc_data *data)
4092134a922SPierre Ossman {
4102134a922SPierre Ossman 	int direction;
4112134a922SPierre Ossman 
4122134a922SPierre Ossman 	u8 *desc;
4132134a922SPierre Ossman 	u8 *align;
4142134a922SPierre Ossman 	dma_addr_t addr;
4152134a922SPierre Ossman 	dma_addr_t align_addr;
4162134a922SPierre Ossman 	int len, offset;
4172134a922SPierre Ossman 
4182134a922SPierre Ossman 	struct scatterlist *sg;
4192134a922SPierre Ossman 	int i;
4202134a922SPierre Ossman 	char *buffer;
4212134a922SPierre Ossman 	unsigned long flags;
4222134a922SPierre Ossman 
4232134a922SPierre Ossman 	/*
4242134a922SPierre Ossman 	 * The spec does not specify endianness of descriptor table.
4252134a922SPierre Ossman 	 * We currently guess that it is LE.
4262134a922SPierre Ossman 	 */
4272134a922SPierre Ossman 
4282134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
4292134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
4302134a922SPierre Ossman 	else
4312134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
4322134a922SPierre Ossman 
4332134a922SPierre Ossman 	/*
4342134a922SPierre Ossman 	 * The ADMA descriptor table is mapped further down as we
4352134a922SPierre Ossman 	 * need to fill it with data first.
4362134a922SPierre Ossman 	 */
4372134a922SPierre Ossman 
4382134a922SPierre Ossman 	host->align_addr = dma_map_single(mmc_dev(host->mmc),
4392134a922SPierre Ossman 		host->align_buffer, 128 * 4, direction);
4408d8bb39bSFUJITA Tomonori 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
4418f1934ceSPierre Ossman 		goto fail;
4422134a922SPierre Ossman 	BUG_ON(host->align_addr & 0x3);
4432134a922SPierre Ossman 
4442134a922SPierre Ossman 	host->sg_count = dma_map_sg(mmc_dev(host->mmc),
4452134a922SPierre Ossman 		data->sg, data->sg_len, direction);
4468f1934ceSPierre Ossman 	if (host->sg_count == 0)
4478f1934ceSPierre Ossman 		goto unmap_align;
4482134a922SPierre Ossman 
4492134a922SPierre Ossman 	desc = host->adma_desc;
4502134a922SPierre Ossman 	align = host->align_buffer;
4512134a922SPierre Ossman 
4522134a922SPierre Ossman 	align_addr = host->align_addr;
4532134a922SPierre Ossman 
4542134a922SPierre Ossman 	for_each_sg(data->sg, sg, host->sg_count, i) {
4552134a922SPierre Ossman 		addr = sg_dma_address(sg);
4562134a922SPierre Ossman 		len = sg_dma_len(sg);
4572134a922SPierre Ossman 
4582134a922SPierre Ossman 		/*
4592134a922SPierre Ossman 		 * The SDHCI specification states that ADMA
4602134a922SPierre Ossman 		 * addresses must be 32-bit aligned. If they
4612134a922SPierre Ossman 		 * aren't, then we use a bounce buffer for
4622134a922SPierre Ossman 		 * the (up to three) bytes that screw up the
4632134a922SPierre Ossman 		 * alignment.
4642134a922SPierre Ossman 		 */
4652134a922SPierre Ossman 		offset = (4 - (addr & 0x3)) & 0x3;
4662134a922SPierre Ossman 		if (offset) {
4672134a922SPierre Ossman 			if (data->flags & MMC_DATA_WRITE) {
4682134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
4696cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
4702134a922SPierre Ossman 				memcpy(align, buffer, offset);
4712134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
4722134a922SPierre Ossman 			}
4732134a922SPierre Ossman 
474118cd17dSBen Dooks 			/* tran, valid */
475118cd17dSBen Dooks 			sdhci_set_adma_desc(desc, align_addr, offset, 0x21);
4762134a922SPierre Ossman 
4772134a922SPierre Ossman 			BUG_ON(offset > 65536);
4782134a922SPierre Ossman 
4792134a922SPierre Ossman 			align += 4;
4802134a922SPierre Ossman 			align_addr += 4;
4812134a922SPierre Ossman 
4822134a922SPierre Ossman 			desc += 8;
4832134a922SPierre Ossman 
4842134a922SPierre Ossman 			addr += offset;
4852134a922SPierre Ossman 			len -= offset;
4862134a922SPierre Ossman 		}
4872134a922SPierre Ossman 
4882134a922SPierre Ossman 		BUG_ON(len > 65536);
4892134a922SPierre Ossman 
490118cd17dSBen Dooks 		/* tran, valid */
491118cd17dSBen Dooks 		sdhci_set_adma_desc(desc, addr, len, 0x21);
4922134a922SPierre Ossman 		desc += 8;
4932134a922SPierre Ossman 
4942134a922SPierre Ossman 		/*
4952134a922SPierre Ossman 		 * If this triggers then we have a calculation bug
4962134a922SPierre Ossman 		 * somewhere. :/
4972134a922SPierre Ossman 		 */
4982134a922SPierre Ossman 		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
4992134a922SPierre Ossman 	}
5002134a922SPierre Ossman 
50170764a90SThomas Abraham 	if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
50270764a90SThomas Abraham 		/*
50370764a90SThomas Abraham 		* Mark the last descriptor as the terminating descriptor
50470764a90SThomas Abraham 		*/
50570764a90SThomas Abraham 		if (desc != host->adma_desc) {
50670764a90SThomas Abraham 			desc -= 8;
50770764a90SThomas Abraham 			desc[0] |= 0x2; /* end */
50870764a90SThomas Abraham 		}
50970764a90SThomas Abraham 	} else {
5102134a922SPierre Ossman 		/*
5112134a922SPierre Ossman 		* Add a terminating entry.
5122134a922SPierre Ossman 		*/
5132134a922SPierre Ossman 
514118cd17dSBen Dooks 		/* nop, end, valid */
515118cd17dSBen Dooks 		sdhci_set_adma_desc(desc, 0, 0, 0x3);
51670764a90SThomas Abraham 	}
5172134a922SPierre Ossman 
5182134a922SPierre Ossman 	/*
5192134a922SPierre Ossman 	 * Resync align buffer as we might have changed it.
5202134a922SPierre Ossman 	 */
5212134a922SPierre Ossman 	if (data->flags & MMC_DATA_WRITE) {
5222134a922SPierre Ossman 		dma_sync_single_for_device(mmc_dev(host->mmc),
5232134a922SPierre Ossman 			host->align_addr, 128 * 4, direction);
5242134a922SPierre Ossman 	}
5252134a922SPierre Ossman 
5262134a922SPierre Ossman 	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
5272134a922SPierre Ossman 		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
528980167b7SPierre Ossman 	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
5298f1934ceSPierre Ossman 		goto unmap_entries;
5302134a922SPierre Ossman 	BUG_ON(host->adma_addr & 0x3);
5318f1934ceSPierre Ossman 
5328f1934ceSPierre Ossman 	return 0;
5338f1934ceSPierre Ossman 
5348f1934ceSPierre Ossman unmap_entries:
5358f1934ceSPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5368f1934ceSPierre Ossman 		data->sg_len, direction);
5378f1934ceSPierre Ossman unmap_align:
5388f1934ceSPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5398f1934ceSPierre Ossman 		128 * 4, direction);
5408f1934ceSPierre Ossman fail:
5418f1934ceSPierre Ossman 	return -EINVAL;
5422134a922SPierre Ossman }
5432134a922SPierre Ossman 
5442134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host,
5452134a922SPierre Ossman 	struct mmc_data *data)
5462134a922SPierre Ossman {
5472134a922SPierre Ossman 	int direction;
5482134a922SPierre Ossman 
5492134a922SPierre Ossman 	struct scatterlist *sg;
5502134a922SPierre Ossman 	int i, size;
5512134a922SPierre Ossman 	u8 *align;
5522134a922SPierre Ossman 	char *buffer;
5532134a922SPierre Ossman 	unsigned long flags;
5542134a922SPierre Ossman 
5552134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
5562134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
5572134a922SPierre Ossman 	else
5582134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
5592134a922SPierre Ossman 
5602134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
5612134a922SPierre Ossman 		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
5622134a922SPierre Ossman 
5632134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5642134a922SPierre Ossman 		128 * 4, direction);
5652134a922SPierre Ossman 
5662134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ) {
5672134a922SPierre Ossman 		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
5682134a922SPierre Ossman 			data->sg_len, direction);
5692134a922SPierre Ossman 
5702134a922SPierre Ossman 		align = host->align_buffer;
5712134a922SPierre Ossman 
5722134a922SPierre Ossman 		for_each_sg(data->sg, sg, host->sg_count, i) {
5732134a922SPierre Ossman 			if (sg_dma_address(sg) & 0x3) {
5742134a922SPierre Ossman 				size = 4 - (sg_dma_address(sg) & 0x3);
5752134a922SPierre Ossman 
5762134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
5776cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
5782134a922SPierre Ossman 				memcpy(buffer, align, size);
5792134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
5802134a922SPierre Ossman 
5812134a922SPierre Ossman 				align += 4;
5822134a922SPierre Ossman 			}
5832134a922SPierre Ossman 		}
5842134a922SPierre Ossman 	}
5852134a922SPierre Ossman 
5862134a922SPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5872134a922SPierre Ossman 		data->sg_len, direction);
5882134a922SPierre Ossman }
5892134a922SPierre Ossman 
590ee53ab5dSPierre Ossman static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
5911c6a0718SPierre Ossman {
5921c6a0718SPierre Ossman 	u8 count;
5931c6a0718SPierre Ossman 	unsigned target_timeout, current_timeout;
5941c6a0718SPierre Ossman 
595ee53ab5dSPierre Ossman 	/*
596ee53ab5dSPierre Ossman 	 * If the host controller provides us with an incorrect timeout
597ee53ab5dSPierre Ossman 	 * value, just skip the check and use 0xE.  The hardware may take
598ee53ab5dSPierre Ossman 	 * longer to time out, but that's much better than having a too-short
599ee53ab5dSPierre Ossman 	 * timeout value.
600ee53ab5dSPierre Ossman 	 */
60111a2f1b7SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
602ee53ab5dSPierre Ossman 		return 0xE;
603e538fbe8SPierre Ossman 
6041c6a0718SPierre Ossman 	/* timeout in us */
6051c6a0718SPierre Ossman 	target_timeout = data->timeout_ns / 1000 +
6061c6a0718SPierre Ossman 		data->timeout_clks / host->clock;
6071c6a0718SPierre Ossman 
60881b39802SAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
60981b39802SAnton Vorontsov 		host->timeout_clk = host->clock / 1000;
61081b39802SAnton Vorontsov 
6111c6a0718SPierre Ossman 	/*
6121c6a0718SPierre Ossman 	 * Figure out needed cycles.
6131c6a0718SPierre Ossman 	 * We do this in steps in order to fit inside a 32 bit int.
6141c6a0718SPierre Ossman 	 * The first step is the minimum timeout, which will have a
6151c6a0718SPierre Ossman 	 * minimum resolution of 6 bits:
6161c6a0718SPierre Ossman 	 * (1) 2^13*1000 > 2^22,
6171c6a0718SPierre Ossman 	 * (2) host->timeout_clk < 2^16
6181c6a0718SPierre Ossman 	 *     =>
6191c6a0718SPierre Ossman 	 *     (1) / (2) > 2^6
6201c6a0718SPierre Ossman 	 */
6211c6a0718SPierre Ossman 	count = 0;
6221c6a0718SPierre Ossman 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
6231c6a0718SPierre Ossman 	while (current_timeout < target_timeout) {
6241c6a0718SPierre Ossman 		count++;
6251c6a0718SPierre Ossman 		current_timeout <<= 1;
6261c6a0718SPierre Ossman 		if (count >= 0xF)
6271c6a0718SPierre Ossman 			break;
6281c6a0718SPierre Ossman 	}
6291c6a0718SPierre Ossman 
6301c6a0718SPierre Ossman 	if (count >= 0xF) {
6311c6a0718SPierre Ossman 		printk(KERN_WARNING "%s: Too large timeout requested!\n",
6321c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
6331c6a0718SPierre Ossman 		count = 0xE;
6341c6a0718SPierre Ossman 	}
6351c6a0718SPierre Ossman 
636ee53ab5dSPierre Ossman 	return count;
637ee53ab5dSPierre Ossman }
638ee53ab5dSPierre Ossman 
6396aa943abSAnton Vorontsov static void sdhci_set_transfer_irqs(struct sdhci_host *host)
6406aa943abSAnton Vorontsov {
6416aa943abSAnton Vorontsov 	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
6426aa943abSAnton Vorontsov 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
6436aa943abSAnton Vorontsov 
6446aa943abSAnton Vorontsov 	if (host->flags & SDHCI_REQ_USE_DMA)
6456aa943abSAnton Vorontsov 		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
6466aa943abSAnton Vorontsov 	else
6476aa943abSAnton Vorontsov 		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
6486aa943abSAnton Vorontsov }
6496aa943abSAnton Vorontsov 
650ee53ab5dSPierre Ossman static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
651ee53ab5dSPierre Ossman {
652ee53ab5dSPierre Ossman 	u8 count;
6532134a922SPierre Ossman 	u8 ctrl;
6548f1934ceSPierre Ossman 	int ret;
655ee53ab5dSPierre Ossman 
656ee53ab5dSPierre Ossman 	WARN_ON(host->data);
657ee53ab5dSPierre Ossman 
658ee53ab5dSPierre Ossman 	if (data == NULL)
659ee53ab5dSPierre Ossman 		return;
660ee53ab5dSPierre Ossman 
661ee53ab5dSPierre Ossman 	/* Sanity checks */
662ee53ab5dSPierre Ossman 	BUG_ON(data->blksz * data->blocks > 524288);
663ee53ab5dSPierre Ossman 	BUG_ON(data->blksz > host->mmc->max_blk_size);
664ee53ab5dSPierre Ossman 	BUG_ON(data->blocks > 65535);
665ee53ab5dSPierre Ossman 
666ee53ab5dSPierre Ossman 	host->data = data;
667ee53ab5dSPierre Ossman 	host->data_early = 0;
668ee53ab5dSPierre Ossman 
669ee53ab5dSPierre Ossman 	count = sdhci_calc_timeout(host, data);
6704e4141a5SAnton Vorontsov 	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
6711c6a0718SPierre Ossman 
672a13abc7bSRichard Röjfors 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
673c9fddbc4SPierre Ossman 		host->flags |= SDHCI_REQ_USE_DMA;
674c9fddbc4SPierre Ossman 
6752134a922SPierre Ossman 	/*
6762134a922SPierre Ossman 	 * FIXME: This doesn't account for merging when mapping the
6772134a922SPierre Ossman 	 * scatterlist.
6782134a922SPierre Ossman 	 */
6792134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
6802134a922SPierre Ossman 		int broken, i;
6812134a922SPierre Ossman 		struct scatterlist *sg;
6822134a922SPierre Ossman 
6832134a922SPierre Ossman 		broken = 0;
6842134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
6852134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
6862134a922SPierre Ossman 				broken = 1;
6872134a922SPierre Ossman 		} else {
6882134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
6892134a922SPierre Ossman 				broken = 1;
6902134a922SPierre Ossman 		}
6912134a922SPierre Ossman 
6922134a922SPierre Ossman 		if (unlikely(broken)) {
6932134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
6942134a922SPierre Ossman 				if (sg->length & 0x3) {
6952134a922SPierre Ossman 					DBG("Reverting to PIO because of "
6962134a922SPierre Ossman 						"transfer size (%d)\n",
6972134a922SPierre Ossman 						sg->length);
698c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
6992134a922SPierre Ossman 					break;
7002134a922SPierre Ossman 				}
7012134a922SPierre Ossman 			}
7022134a922SPierre Ossman 		}
703c9fddbc4SPierre Ossman 	}
704c9fddbc4SPierre Ossman 
705c9fddbc4SPierre Ossman 	/*
706c9fddbc4SPierre Ossman 	 * The assumption here being that alignment is the same after
707c9fddbc4SPierre Ossman 	 * translation to device address space.
708c9fddbc4SPierre Ossman 	 */
7092134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
7102134a922SPierre Ossman 		int broken, i;
7112134a922SPierre Ossman 		struct scatterlist *sg;
7122134a922SPierre Ossman 
7132134a922SPierre Ossman 		broken = 0;
7142134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
7152134a922SPierre Ossman 			/*
7162134a922SPierre Ossman 			 * As we use 3 byte chunks to work around
7172134a922SPierre Ossman 			 * alignment problems, we need to check this
7182134a922SPierre Ossman 			 * quirk.
7192134a922SPierre Ossman 			 */
7202134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
7212134a922SPierre Ossman 				broken = 1;
7222134a922SPierre Ossman 		} else {
7232134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
7242134a922SPierre Ossman 				broken = 1;
7252134a922SPierre Ossman 		}
7262134a922SPierre Ossman 
7272134a922SPierre Ossman 		if (unlikely(broken)) {
7282134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
7292134a922SPierre Ossman 				if (sg->offset & 0x3) {
7302134a922SPierre Ossman 					DBG("Reverting to PIO because of "
7312134a922SPierre Ossman 						"bad alignment\n");
732c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
7332134a922SPierre Ossman 					break;
7342134a922SPierre Ossman 				}
7352134a922SPierre Ossman 			}
7362134a922SPierre Ossman 		}
7372134a922SPierre Ossman 	}
7382134a922SPierre Ossman 
7398f1934ceSPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
7408f1934ceSPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
7418f1934ceSPierre Ossman 			ret = sdhci_adma_table_pre(host, data);
7428f1934ceSPierre Ossman 			if (ret) {
7438f1934ceSPierre Ossman 				/*
7448f1934ceSPierre Ossman 				 * This only happens when someone fed
7458f1934ceSPierre Ossman 				 * us an invalid request.
7468f1934ceSPierre Ossman 				 */
7478f1934ceSPierre Ossman 				WARN_ON(1);
748ebd6d357SPierre Ossman 				host->flags &= ~SDHCI_REQ_USE_DMA;
7498f1934ceSPierre Ossman 			} else {
7504e4141a5SAnton Vorontsov 				sdhci_writel(host, host->adma_addr,
7514e4141a5SAnton Vorontsov 					SDHCI_ADMA_ADDRESS);
7528f1934ceSPierre Ossman 			}
7538f1934ceSPierre Ossman 		} else {
754c8b3e02eSTomas Winkler 			int sg_cnt;
7558f1934ceSPierre Ossman 
756c8b3e02eSTomas Winkler 			sg_cnt = dma_map_sg(mmc_dev(host->mmc),
7578f1934ceSPierre Ossman 					data->sg, data->sg_len,
7588f1934ceSPierre Ossman 					(data->flags & MMC_DATA_READ) ?
7598f1934ceSPierre Ossman 						DMA_FROM_DEVICE :
7608f1934ceSPierre Ossman 						DMA_TO_DEVICE);
761c8b3e02eSTomas Winkler 			if (sg_cnt == 0) {
7628f1934ceSPierre Ossman 				/*
7638f1934ceSPierre Ossman 				 * This only happens when someone fed
7648f1934ceSPierre Ossman 				 * us an invalid request.
7658f1934ceSPierre Ossman 				 */
7668f1934ceSPierre Ossman 				WARN_ON(1);
767ebd6d357SPierre Ossman 				host->flags &= ~SDHCI_REQ_USE_DMA;
7688f1934ceSPierre Ossman 			} else {
769719a61b4SPierre Ossman 				WARN_ON(sg_cnt != 1);
7704e4141a5SAnton Vorontsov 				sdhci_writel(host, sg_dma_address(data->sg),
7714e4141a5SAnton Vorontsov 					SDHCI_DMA_ADDRESS);
7728f1934ceSPierre Ossman 			}
7738f1934ceSPierre Ossman 		}
7748f1934ceSPierre Ossman 	}
7758f1934ceSPierre Ossman 
7762134a922SPierre Ossman 	/*
7772134a922SPierre Ossman 	 * Always adjust the DMA selection as some controllers
7782134a922SPierre Ossman 	 * (e.g. JMicron) can't do PIO properly when the selection
7792134a922SPierre Ossman 	 * is ADMA.
7802134a922SPierre Ossman 	 */
7812134a922SPierre Ossman 	if (host->version >= SDHCI_SPEC_200) {
7824e4141a5SAnton Vorontsov 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
7832134a922SPierre Ossman 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
7842134a922SPierre Ossman 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
7852134a922SPierre Ossman 			(host->flags & SDHCI_USE_ADMA))
7862134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_ADMA32;
7872134a922SPierre Ossman 		else
7882134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_SDMA;
7894e4141a5SAnton Vorontsov 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
790c9fddbc4SPierre Ossman 	}
791c9fddbc4SPierre Ossman 
7928f1934ceSPierre Ossman 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
793da60a91dSSebastian Andrzej Siewior 		int flags;
794da60a91dSSebastian Andrzej Siewior 
795da60a91dSSebastian Andrzej Siewior 		flags = SG_MITER_ATOMIC;
796da60a91dSSebastian Andrzej Siewior 		if (host->data->flags & MMC_DATA_READ)
797da60a91dSSebastian Andrzej Siewior 			flags |= SG_MITER_TO_SG;
798da60a91dSSebastian Andrzej Siewior 		else
799da60a91dSSebastian Andrzej Siewior 			flags |= SG_MITER_FROM_SG;
800da60a91dSSebastian Andrzej Siewior 		sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
8017659150cSPierre Ossman 		host->blocks = data->blocks;
8021c6a0718SPierre Ossman 	}
8031c6a0718SPierre Ossman 
8046aa943abSAnton Vorontsov 	sdhci_set_transfer_irqs(host);
8056aa943abSAnton Vorontsov 
8061c6a0718SPierre Ossman 	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
8074e4141a5SAnton Vorontsov 	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
8084e4141a5SAnton Vorontsov 	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
8091c6a0718SPierre Ossman }
8101c6a0718SPierre Ossman 
8111c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host,
8121c6a0718SPierre Ossman 	struct mmc_data *data)
8131c6a0718SPierre Ossman {
8141c6a0718SPierre Ossman 	u16 mode;
8151c6a0718SPierre Ossman 
8161c6a0718SPierre Ossman 	if (data == NULL)
8171c6a0718SPierre Ossman 		return;
8181c6a0718SPierre Ossman 
819e538fbe8SPierre Ossman 	WARN_ON(!host->data);
820e538fbe8SPierre Ossman 
8211c6a0718SPierre Ossman 	mode = SDHCI_TRNS_BLK_CNT_EN;
822c4512f79SJerry Huang 	if (data->blocks > 1) {
823c4512f79SJerry Huang 		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
824c4512f79SJerry Huang 			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
825c4512f79SJerry Huang 		else
8261c6a0718SPierre Ossman 			mode |= SDHCI_TRNS_MULTI;
827c4512f79SJerry Huang 	}
8281c6a0718SPierre Ossman 	if (data->flags & MMC_DATA_READ)
8291c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_READ;
830c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA)
8311c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_DMA;
8321c6a0718SPierre Ossman 
8334e4141a5SAnton Vorontsov 	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
8341c6a0718SPierre Ossman }
8351c6a0718SPierre Ossman 
8361c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host)
8371c6a0718SPierre Ossman {
8381c6a0718SPierre Ossman 	struct mmc_data *data;
8391c6a0718SPierre Ossman 
8401c6a0718SPierre Ossman 	BUG_ON(!host->data);
8411c6a0718SPierre Ossman 
8421c6a0718SPierre Ossman 	data = host->data;
8431c6a0718SPierre Ossman 	host->data = NULL;
8441c6a0718SPierre Ossman 
845c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
8462134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA)
8472134a922SPierre Ossman 			sdhci_adma_table_post(host, data);
8482134a922SPierre Ossman 		else {
8492134a922SPierre Ossman 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
8502134a922SPierre Ossman 				data->sg_len, (data->flags & MMC_DATA_READ) ?
851b8c86fc5SPierre Ossman 					DMA_FROM_DEVICE : DMA_TO_DEVICE);
8521c6a0718SPierre Ossman 		}
8532134a922SPierre Ossman 	}
8541c6a0718SPierre Ossman 
8551c6a0718SPierre Ossman 	/*
856c9b74c5bSPierre Ossman 	 * The specification states that the block count register must
857c9b74c5bSPierre Ossman 	 * be updated, but it does not specify at what point in the
858c9b74c5bSPierre Ossman 	 * data flow. That makes the register entirely useless to read
859c9b74c5bSPierre Ossman 	 * back so we have to assume that nothing made it to the card
860c9b74c5bSPierre Ossman 	 * in the event of an error.
8611c6a0718SPierre Ossman 	 */
862c9b74c5bSPierre Ossman 	if (data->error)
863c9b74c5bSPierre Ossman 		data->bytes_xfered = 0;
8641c6a0718SPierre Ossman 	else
865c9b74c5bSPierre Ossman 		data->bytes_xfered = data->blksz * data->blocks;
8661c6a0718SPierre Ossman 
8671c6a0718SPierre Ossman 	if (data->stop) {
8681c6a0718SPierre Ossman 		/*
8691c6a0718SPierre Ossman 		 * The controller needs a reset of internal state machines
8701c6a0718SPierre Ossman 		 * upon error conditions.
8711c6a0718SPierre Ossman 		 */
87217b0429dSPierre Ossman 		if (data->error) {
8731c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
8741c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
8751c6a0718SPierre Ossman 		}
8761c6a0718SPierre Ossman 
8771c6a0718SPierre Ossman 		sdhci_send_command(host, data->stop);
8781c6a0718SPierre Ossman 	} else
8791c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
8801c6a0718SPierre Ossman }
8811c6a0718SPierre Ossman 
8821c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
8831c6a0718SPierre Ossman {
8841c6a0718SPierre Ossman 	int flags;
8851c6a0718SPierre Ossman 	u32 mask;
8861c6a0718SPierre Ossman 	unsigned long timeout;
8871c6a0718SPierre Ossman 
8881c6a0718SPierre Ossman 	WARN_ON(host->cmd);
8891c6a0718SPierre Ossman 
8901c6a0718SPierre Ossman 	/* Wait max 10 ms */
8911c6a0718SPierre Ossman 	timeout = 10;
8921c6a0718SPierre Ossman 
8931c6a0718SPierre Ossman 	mask = SDHCI_CMD_INHIBIT;
8941c6a0718SPierre Ossman 	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
8951c6a0718SPierre Ossman 		mask |= SDHCI_DATA_INHIBIT;
8961c6a0718SPierre Ossman 
8971c6a0718SPierre Ossman 	/* We shouldn't wait for data inihibit for stop commands, even
8981c6a0718SPierre Ossman 	   though they might use busy signaling */
8991c6a0718SPierre Ossman 	if (host->mrq->data && (cmd == host->mrq->data->stop))
9001c6a0718SPierre Ossman 		mask &= ~SDHCI_DATA_INHIBIT;
9011c6a0718SPierre Ossman 
9024e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
9031c6a0718SPierre Ossman 		if (timeout == 0) {
9041c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Controller never released "
9051c6a0718SPierre Ossman 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
9061c6a0718SPierre Ossman 			sdhci_dumpregs(host);
90717b0429dSPierre Ossman 			cmd->error = -EIO;
9081c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
9091c6a0718SPierre Ossman 			return;
9101c6a0718SPierre Ossman 		}
9111c6a0718SPierre Ossman 		timeout--;
9121c6a0718SPierre Ossman 		mdelay(1);
9131c6a0718SPierre Ossman 	}
9141c6a0718SPierre Ossman 
9151c6a0718SPierre Ossman 	mod_timer(&host->timer, jiffies + 10 * HZ);
9161c6a0718SPierre Ossman 
9171c6a0718SPierre Ossman 	host->cmd = cmd;
9181c6a0718SPierre Ossman 
9191c6a0718SPierre Ossman 	sdhci_prepare_data(host, cmd->data);
9201c6a0718SPierre Ossman 
9214e4141a5SAnton Vorontsov 	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
9221c6a0718SPierre Ossman 
9231c6a0718SPierre Ossman 	sdhci_set_transfer_mode(host, cmd->data);
9241c6a0718SPierre Ossman 
9251c6a0718SPierre Ossman 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
9261c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unsupported response type!\n",
9271c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
92817b0429dSPierre Ossman 		cmd->error = -EINVAL;
9291c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
9301c6a0718SPierre Ossman 		return;
9311c6a0718SPierre Ossman 	}
9321c6a0718SPierre Ossman 
9331c6a0718SPierre Ossman 	if (!(cmd->flags & MMC_RSP_PRESENT))
9341c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_NONE;
9351c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_136)
9361c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_LONG;
9371c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_BUSY)
9381c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT_BUSY;
9391c6a0718SPierre Ossman 	else
9401c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT;
9411c6a0718SPierre Ossman 
9421c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_CRC)
9431c6a0718SPierre Ossman 		flags |= SDHCI_CMD_CRC;
9441c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_OPCODE)
9451c6a0718SPierre Ossman 		flags |= SDHCI_CMD_INDEX;
9461c6a0718SPierre Ossman 	if (cmd->data)
9471c6a0718SPierre Ossman 		flags |= SDHCI_CMD_DATA;
9481c6a0718SPierre Ossman 
9494e4141a5SAnton Vorontsov 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
9501c6a0718SPierre Ossman }
9511c6a0718SPierre Ossman 
9521c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host)
9531c6a0718SPierre Ossman {
9541c6a0718SPierre Ossman 	int i;
9551c6a0718SPierre Ossman 
9561c6a0718SPierre Ossman 	BUG_ON(host->cmd == NULL);
9571c6a0718SPierre Ossman 
9581c6a0718SPierre Ossman 	if (host->cmd->flags & MMC_RSP_PRESENT) {
9591c6a0718SPierre Ossman 		if (host->cmd->flags & MMC_RSP_136) {
9601c6a0718SPierre Ossman 			/* CRC is stripped so we need to do some shifting. */
9611c6a0718SPierre Ossman 			for (i = 0;i < 4;i++) {
9624e4141a5SAnton Vorontsov 				host->cmd->resp[i] = sdhci_readl(host,
9631c6a0718SPierre Ossman 					SDHCI_RESPONSE + (3-i)*4) << 8;
9641c6a0718SPierre Ossman 				if (i != 3)
9651c6a0718SPierre Ossman 					host->cmd->resp[i] |=
9664e4141a5SAnton Vorontsov 						sdhci_readb(host,
9671c6a0718SPierre Ossman 						SDHCI_RESPONSE + (3-i)*4-1);
9681c6a0718SPierre Ossman 			}
9691c6a0718SPierre Ossman 		} else {
9704e4141a5SAnton Vorontsov 			host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
9711c6a0718SPierre Ossman 		}
9721c6a0718SPierre Ossman 	}
9731c6a0718SPierre Ossman 
97417b0429dSPierre Ossman 	host->cmd->error = 0;
9751c6a0718SPierre Ossman 
976e538fbe8SPierre Ossman 	if (host->data && host->data_early)
977e538fbe8SPierre Ossman 		sdhci_finish_data(host);
978e538fbe8SPierre Ossman 
979e538fbe8SPierre Ossman 	if (!host->cmd->data)
9801c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
9811c6a0718SPierre Ossman 
9821c6a0718SPierre Ossman 	host->cmd = NULL;
9831c6a0718SPierre Ossman }
9841c6a0718SPierre Ossman 
9851c6a0718SPierre Ossman static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
9861c6a0718SPierre Ossman {
9871c6a0718SPierre Ossman 	int div;
9881c6a0718SPierre Ossman 	u16 clk;
9891c6a0718SPierre Ossman 	unsigned long timeout;
9901c6a0718SPierre Ossman 
9911c6a0718SPierre Ossman 	if (clock == host->clock)
9921c6a0718SPierre Ossman 		return;
9931c6a0718SPierre Ossman 
9948114634cSAnton Vorontsov 	if (host->ops->set_clock) {
9958114634cSAnton Vorontsov 		host->ops->set_clock(host, clock);
9968114634cSAnton Vorontsov 		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
9978114634cSAnton Vorontsov 			return;
9988114634cSAnton Vorontsov 	}
9998114634cSAnton Vorontsov 
10004e4141a5SAnton Vorontsov 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
10011c6a0718SPierre Ossman 
10021c6a0718SPierre Ossman 	if (clock == 0)
10031c6a0718SPierre Ossman 		goto out;
10041c6a0718SPierre Ossman 
100585105c53SZhangfei Gao 	if (host->version >= SDHCI_SPEC_300) {
100685105c53SZhangfei Gao 		/* Version 3.00 divisors must be a multiple of 2. */
100785105c53SZhangfei Gao 		if (host->max_clk <= clock)
100885105c53SZhangfei Gao 			div = 1;
100985105c53SZhangfei Gao 		else {
10100397526dSZhangfei Gao 			for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
101185105c53SZhangfei Gao 				if ((host->max_clk / div) <= clock)
101285105c53SZhangfei Gao 					break;
101385105c53SZhangfei Gao 			}
101485105c53SZhangfei Gao 		}
101585105c53SZhangfei Gao 	} else {
101685105c53SZhangfei Gao 		/* Version 2.00 divisors must be a power of 2. */
10170397526dSZhangfei Gao 		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
10181c6a0718SPierre Ossman 			if ((host->max_clk / div) <= clock)
10191c6a0718SPierre Ossman 				break;
10201c6a0718SPierre Ossman 		}
102185105c53SZhangfei Gao 	}
10221c6a0718SPierre Ossman 	div >>= 1;
10231c6a0718SPierre Ossman 
102485105c53SZhangfei Gao 	clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
102585105c53SZhangfei Gao 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
102685105c53SZhangfei Gao 		<< SDHCI_DIVIDER_HI_SHIFT;
10271c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_INT_EN;
10284e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
10291c6a0718SPierre Ossman 
103027f6cb16SChris Ball 	/* Wait max 20 ms */
103127f6cb16SChris Ball 	timeout = 20;
10324e4141a5SAnton Vorontsov 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
10331c6a0718SPierre Ossman 		& SDHCI_CLOCK_INT_STABLE)) {
10341c6a0718SPierre Ossman 		if (timeout == 0) {
10351c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Internal clock never "
10361c6a0718SPierre Ossman 				"stabilised.\n", mmc_hostname(host->mmc));
10371c6a0718SPierre Ossman 			sdhci_dumpregs(host);
10381c6a0718SPierre Ossman 			return;
10391c6a0718SPierre Ossman 		}
10401c6a0718SPierre Ossman 		timeout--;
10411c6a0718SPierre Ossman 		mdelay(1);
10421c6a0718SPierre Ossman 	}
10431c6a0718SPierre Ossman 
10441c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_CARD_EN;
10454e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
10461c6a0718SPierre Ossman 
10471c6a0718SPierre Ossman out:
10481c6a0718SPierre Ossman 	host->clock = clock;
10491c6a0718SPierre Ossman }
10501c6a0718SPierre Ossman 
10511c6a0718SPierre Ossman static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
10521c6a0718SPierre Ossman {
10538364248aSGiuseppe Cavallaro 	u8 pwr = 0;
10541c6a0718SPierre Ossman 
10558364248aSGiuseppe Cavallaro 	if (power != (unsigned short)-1) {
1056ae628903SPierre Ossman 		switch (1 << power) {
1057ae628903SPierre Ossman 		case MMC_VDD_165_195:
1058ae628903SPierre Ossman 			pwr = SDHCI_POWER_180;
1059ae628903SPierre Ossman 			break;
1060ae628903SPierre Ossman 		case MMC_VDD_29_30:
1061ae628903SPierre Ossman 		case MMC_VDD_30_31:
1062ae628903SPierre Ossman 			pwr = SDHCI_POWER_300;
1063ae628903SPierre Ossman 			break;
1064ae628903SPierre Ossman 		case MMC_VDD_32_33:
1065ae628903SPierre Ossman 		case MMC_VDD_33_34:
1066ae628903SPierre Ossman 			pwr = SDHCI_POWER_330;
1067ae628903SPierre Ossman 			break;
1068ae628903SPierre Ossman 		default:
1069ae628903SPierre Ossman 			BUG();
1070ae628903SPierre Ossman 		}
1071ae628903SPierre Ossman 	}
1072ae628903SPierre Ossman 
1073ae628903SPierre Ossman 	if (host->pwr == pwr)
10741c6a0718SPierre Ossman 		return;
10751c6a0718SPierre Ossman 
1076ae628903SPierre Ossman 	host->pwr = pwr;
1077ae628903SPierre Ossman 
1078ae628903SPierre Ossman 	if (pwr == 0) {
10794e4141a5SAnton Vorontsov 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1080ae628903SPierre Ossman 		return;
10811c6a0718SPierre Ossman 	}
10821c6a0718SPierre Ossman 
10831c6a0718SPierre Ossman 	/*
10841c6a0718SPierre Ossman 	 * Spec says that we should clear the power reg before setting
10851c6a0718SPierre Ossman 	 * a new value. Some controllers don't seem to like this though.
10861c6a0718SPierre Ossman 	 */
1087b8c86fc5SPierre Ossman 	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
10884e4141a5SAnton Vorontsov 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
10891c6a0718SPierre Ossman 
1090e08c1694SAndres Salomon 	/*
1091c71f6512SAndres Salomon 	 * At least the Marvell CaFe chip gets confused if we set the voltage
1092e08c1694SAndres Salomon 	 * and set turn on power at the same time, so set the voltage first.
1093e08c1694SAndres Salomon 	 */
109411a2f1b7SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
10954e4141a5SAnton Vorontsov 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
10961c6a0718SPierre Ossman 
1097ae628903SPierre Ossman 	pwr |= SDHCI_POWER_ON;
1098ae628903SPierre Ossman 
1099ae628903SPierre Ossman 	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1100557b0697SHarald Welte 
1101557b0697SHarald Welte 	/*
1102557b0697SHarald Welte 	 * Some controllers need an extra 10ms delay of 10ms before they
1103557b0697SHarald Welte 	 * can apply clock after applying power
1104557b0697SHarald Welte 	 */
110511a2f1b7SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
1106557b0697SHarald Welte 		mdelay(10);
11071c6a0718SPierre Ossman }
11081c6a0718SPierre Ossman 
11091c6a0718SPierre Ossman /*****************************************************************************\
11101c6a0718SPierre Ossman  *                                                                           *
11111c6a0718SPierre Ossman  * MMC callbacks                                                             *
11121c6a0718SPierre Ossman  *                                                                           *
11131c6a0718SPierre Ossman \*****************************************************************************/
11141c6a0718SPierre Ossman 
11151c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
11161c6a0718SPierre Ossman {
11171c6a0718SPierre Ossman 	struct sdhci_host *host;
111868d1fb7eSAnton Vorontsov 	bool present;
11191c6a0718SPierre Ossman 	unsigned long flags;
11201c6a0718SPierre Ossman 
11211c6a0718SPierre Ossman 	host = mmc_priv(mmc);
11221c6a0718SPierre Ossman 
11231c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11241c6a0718SPierre Ossman 
11251c6a0718SPierre Ossman 	WARN_ON(host->mrq != NULL);
11261c6a0718SPierre Ossman 
1127f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS
11281c6a0718SPierre Ossman 	sdhci_activate_led(host);
11292f730fecSPierre Ossman #endif
1130c4512f79SJerry Huang 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
1131c4512f79SJerry Huang 		if (mrq->stop) {
1132c4512f79SJerry Huang 			mrq->data->stop = NULL;
1133c4512f79SJerry Huang 			mrq->stop = NULL;
1134c4512f79SJerry Huang 		}
1135c4512f79SJerry Huang 	}
11361c6a0718SPierre Ossman 
11371c6a0718SPierre Ossman 	host->mrq = mrq;
11381c6a0718SPierre Ossman 
113968d1fb7eSAnton Vorontsov 	/* If polling, assume that the card is always present. */
114068d1fb7eSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
114168d1fb7eSAnton Vorontsov 		present = true;
114268d1fb7eSAnton Vorontsov 	else
114368d1fb7eSAnton Vorontsov 		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
114468d1fb7eSAnton Vorontsov 				SDHCI_CARD_PRESENT;
114568d1fb7eSAnton Vorontsov 
114668d1fb7eSAnton Vorontsov 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
114717b0429dSPierre Ossman 		host->mrq->cmd->error = -ENOMEDIUM;
11481c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
11491c6a0718SPierre Ossman 	} else
11501c6a0718SPierre Ossman 		sdhci_send_command(host, mrq->cmd);
11511c6a0718SPierre Ossman 
11521c6a0718SPierre Ossman 	mmiowb();
11531c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
11541c6a0718SPierre Ossman }
11551c6a0718SPierre Ossman 
11561c6a0718SPierre Ossman static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11571c6a0718SPierre Ossman {
11581c6a0718SPierre Ossman 	struct sdhci_host *host;
11591c6a0718SPierre Ossman 	unsigned long flags;
11601c6a0718SPierre Ossman 	u8 ctrl;
11611c6a0718SPierre Ossman 
11621c6a0718SPierre Ossman 	host = mmc_priv(mmc);
11631c6a0718SPierre Ossman 
11641c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11651c6a0718SPierre Ossman 
11661e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
11671e72859eSPierre Ossman 		goto out;
11681e72859eSPierre Ossman 
11691c6a0718SPierre Ossman 	/*
11701c6a0718SPierre Ossman 	 * Reset the chip on each power off.
11711c6a0718SPierre Ossman 	 * Should clear out any weird states.
11721c6a0718SPierre Ossman 	 */
11731c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF) {
11744e4141a5SAnton Vorontsov 		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
11757260cf5eSAnton Vorontsov 		sdhci_reinit(host);
11761c6a0718SPierre Ossman 	}
11771c6a0718SPierre Ossman 
11781c6a0718SPierre Ossman 	sdhci_set_clock(host, ios->clock);
11791c6a0718SPierre Ossman 
11801c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF)
11811c6a0718SPierre Ossman 		sdhci_set_power(host, -1);
11821c6a0718SPierre Ossman 	else
11831c6a0718SPierre Ossman 		sdhci_set_power(host, ios->vdd);
11841c6a0718SPierre Ossman 
1185643a81ffSPhilip Rakity 	if (host->ops->platform_send_init_74_clocks)
1186643a81ffSPhilip Rakity 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
1187643a81ffSPhilip Rakity 
11884e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
11891c6a0718SPierre Ossman 
1190ae6d6c92SKyungmin Park 	if (ios->bus_width == MMC_BUS_WIDTH_8)
1191ae6d6c92SKyungmin Park 		ctrl |= SDHCI_CTRL_8BITBUS;
1192ae6d6c92SKyungmin Park 	else
1193ae6d6c92SKyungmin Park 		ctrl &= ~SDHCI_CTRL_8BITBUS;
1194ae6d6c92SKyungmin Park 
11951c6a0718SPierre Ossman 	if (ios->bus_width == MMC_BUS_WIDTH_4)
11961c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_4BITBUS;
11971c6a0718SPierre Ossman 	else
11981c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_4BITBUS;
11991c6a0718SPierre Ossman 
12003ab9c8daSPhilip Rakity 	if ((ios->timing == MMC_TIMING_SD_HS ||
12013ab9c8daSPhilip Rakity 	     ios->timing == MMC_TIMING_MMC_HS)
12023ab9c8daSPhilip Rakity 	    && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
12031c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_HISPD;
12041c6a0718SPierre Ossman 	else
12051c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_HISPD;
12061c6a0718SPierre Ossman 
12074e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
12081c6a0718SPierre Ossman 
1209b8352260SLeandro Dorileo 	/*
1210b8352260SLeandro Dorileo 	 * Some (ENE) controllers go apeshit on some ios operation,
1211b8352260SLeandro Dorileo 	 * signalling timeout and CRC errors even on CMD0. Resetting
1212b8352260SLeandro Dorileo 	 * it on each ios seems to solve the problem.
1213b8352260SLeandro Dorileo 	 */
1214b8c86fc5SPierre Ossman 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
1215b8352260SLeandro Dorileo 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
1216b8352260SLeandro Dorileo 
12171e72859eSPierre Ossman out:
12181c6a0718SPierre Ossman 	mmiowb();
12191c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12201c6a0718SPierre Ossman }
12211c6a0718SPierre Ossman 
12221c6a0718SPierre Ossman static int sdhci_get_ro(struct mmc_host *mmc)
12231c6a0718SPierre Ossman {
12241c6a0718SPierre Ossman 	struct sdhci_host *host;
12251c6a0718SPierre Ossman 	unsigned long flags;
1226*2dfb579cSWolfram Sang 	int is_readonly;
12271c6a0718SPierre Ossman 
12281c6a0718SPierre Ossman 	host = mmc_priv(mmc);
12291c6a0718SPierre Ossman 
12301c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
12311c6a0718SPierre Ossman 
12321e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
1233*2dfb579cSWolfram Sang 		is_readonly = 0;
1234*2dfb579cSWolfram Sang 	else if (host->ops->get_ro)
1235*2dfb579cSWolfram Sang 		is_readonly = host->ops->get_ro(host);
12361e72859eSPierre Ossman 	else
1237*2dfb579cSWolfram Sang 		is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
1238*2dfb579cSWolfram Sang 				& SDHCI_WRITE_PROTECT);
12391c6a0718SPierre Ossman 
12401c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12411c6a0718SPierre Ossman 
1242*2dfb579cSWolfram Sang 	/* This quirk needs to be replaced by a callback-function later */
1243*2dfb579cSWolfram Sang 	return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
1244*2dfb579cSWolfram Sang 		!is_readonly : is_readonly;
12451c6a0718SPierre Ossman }
12461c6a0718SPierre Ossman 
1247f75979b7SPierre Ossman static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1248f75979b7SPierre Ossman {
1249f75979b7SPierre Ossman 	struct sdhci_host *host;
1250f75979b7SPierre Ossman 	unsigned long flags;
1251f75979b7SPierre Ossman 
1252f75979b7SPierre Ossman 	host = mmc_priv(mmc);
1253f75979b7SPierre Ossman 
1254f75979b7SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
1255f75979b7SPierre Ossman 
12561e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
12571e72859eSPierre Ossman 		goto out;
12581e72859eSPierre Ossman 
1259f75979b7SPierre Ossman 	if (enable)
12607260cf5eSAnton Vorontsov 		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
12617260cf5eSAnton Vorontsov 	else
12627260cf5eSAnton Vorontsov 		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
12631e72859eSPierre Ossman out:
1264f75979b7SPierre Ossman 	mmiowb();
1265f75979b7SPierre Ossman 
1266f75979b7SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
1267f75979b7SPierre Ossman }
1268f75979b7SPierre Ossman 
12691c6a0718SPierre Ossman static const struct mmc_host_ops sdhci_ops = {
12701c6a0718SPierre Ossman 	.request	= sdhci_request,
12711c6a0718SPierre Ossman 	.set_ios	= sdhci_set_ios,
12721c6a0718SPierre Ossman 	.get_ro		= sdhci_get_ro,
1273f75979b7SPierre Ossman 	.enable_sdio_irq = sdhci_enable_sdio_irq,
12741c6a0718SPierre Ossman };
12751c6a0718SPierre Ossman 
12761c6a0718SPierre Ossman /*****************************************************************************\
12771c6a0718SPierre Ossman  *                                                                           *
12781c6a0718SPierre Ossman  * Tasklets                                                                  *
12791c6a0718SPierre Ossman  *                                                                           *
12801c6a0718SPierre Ossman \*****************************************************************************/
12811c6a0718SPierre Ossman 
12821c6a0718SPierre Ossman static void sdhci_tasklet_card(unsigned long param)
12831c6a0718SPierre Ossman {
12841c6a0718SPierre Ossman 	struct sdhci_host *host;
12851c6a0718SPierre Ossman 	unsigned long flags;
12861c6a0718SPierre Ossman 
12871c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
12881c6a0718SPierre Ossman 
12891c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
12901c6a0718SPierre Ossman 
12914e4141a5SAnton Vorontsov 	if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
12921c6a0718SPierre Ossman 		if (host->mrq) {
12931c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Card removed during transfer!\n",
12941c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
12951c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Resetting controller.\n",
12961c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
12971c6a0718SPierre Ossman 
12981c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
12991c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
13001c6a0718SPierre Ossman 
130117b0429dSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
13021c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
13031c6a0718SPierre Ossman 		}
13041c6a0718SPierre Ossman 	}
13051c6a0718SPierre Ossman 
13061c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
13071c6a0718SPierre Ossman 
130804cf585dSPierre Ossman 	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
13091c6a0718SPierre Ossman }
13101c6a0718SPierre Ossman 
13111c6a0718SPierre Ossman static void sdhci_tasklet_finish(unsigned long param)
13121c6a0718SPierre Ossman {
13131c6a0718SPierre Ossman 	struct sdhci_host *host;
13141c6a0718SPierre Ossman 	unsigned long flags;
13151c6a0718SPierre Ossman 	struct mmc_request *mrq;
13161c6a0718SPierre Ossman 
13171c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
13181c6a0718SPierre Ossman 
13191c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
13201c6a0718SPierre Ossman 
13211c6a0718SPierre Ossman 	del_timer(&host->timer);
13221c6a0718SPierre Ossman 
13231c6a0718SPierre Ossman 	mrq = host->mrq;
13241c6a0718SPierre Ossman 
13251c6a0718SPierre Ossman 	/*
13261c6a0718SPierre Ossman 	 * The controller needs a reset of internal state machines
13271c6a0718SPierre Ossman 	 * upon error conditions.
13281c6a0718SPierre Ossman 	 */
13291e72859eSPierre Ossman 	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
13301e72859eSPierre Ossman 		(mrq->cmd->error ||
133117b0429dSPierre Ossman 		 (mrq->data && (mrq->data->error ||
133284c46a53SPierre Ossman 		  (mrq->data->stop && mrq->data->stop->error))) ||
13331e72859eSPierre Ossman 		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
13341c6a0718SPierre Ossman 
13351c6a0718SPierre Ossman 		/* Some controllers need this kick or reset won't work here */
1336b8c86fc5SPierre Ossman 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
13371c6a0718SPierre Ossman 			unsigned int clock;
13381c6a0718SPierre Ossman 
13391c6a0718SPierre Ossman 			/* This is to force an update */
13401c6a0718SPierre Ossman 			clock = host->clock;
13411c6a0718SPierre Ossman 			host->clock = 0;
13421c6a0718SPierre Ossman 			sdhci_set_clock(host, clock);
13431c6a0718SPierre Ossman 		}
13441c6a0718SPierre Ossman 
13451c6a0718SPierre Ossman 		/* Spec says we should do both at the same time, but Ricoh
13461c6a0718SPierre Ossman 		   controllers do not like that. */
13471c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_CMD);
13481c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_DATA);
13491c6a0718SPierre Ossman 	}
13501c6a0718SPierre Ossman 
13511c6a0718SPierre Ossman 	host->mrq = NULL;
13521c6a0718SPierre Ossman 	host->cmd = NULL;
13531c6a0718SPierre Ossman 	host->data = NULL;
13541c6a0718SPierre Ossman 
1355f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS
13561c6a0718SPierre Ossman 	sdhci_deactivate_led(host);
13572f730fecSPierre Ossman #endif
13581c6a0718SPierre Ossman 
13591c6a0718SPierre Ossman 	mmiowb();
13601c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
13611c6a0718SPierre Ossman 
13621c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
13631c6a0718SPierre Ossman }
13641c6a0718SPierre Ossman 
13651c6a0718SPierre Ossman static void sdhci_timeout_timer(unsigned long data)
13661c6a0718SPierre Ossman {
13671c6a0718SPierre Ossman 	struct sdhci_host *host;
13681c6a0718SPierre Ossman 	unsigned long flags;
13691c6a0718SPierre Ossman 
13701c6a0718SPierre Ossman 	host = (struct sdhci_host*)data;
13711c6a0718SPierre Ossman 
13721c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
13731c6a0718SPierre Ossman 
13741c6a0718SPierre Ossman 	if (host->mrq) {
13751c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Timeout waiting for hardware "
13761c6a0718SPierre Ossman 			"interrupt.\n", mmc_hostname(host->mmc));
13771c6a0718SPierre Ossman 		sdhci_dumpregs(host);
13781c6a0718SPierre Ossman 
13791c6a0718SPierre Ossman 		if (host->data) {
138017b0429dSPierre Ossman 			host->data->error = -ETIMEDOUT;
13811c6a0718SPierre Ossman 			sdhci_finish_data(host);
13821c6a0718SPierre Ossman 		} else {
13831c6a0718SPierre Ossman 			if (host->cmd)
138417b0429dSPierre Ossman 				host->cmd->error = -ETIMEDOUT;
13851c6a0718SPierre Ossman 			else
138617b0429dSPierre Ossman 				host->mrq->cmd->error = -ETIMEDOUT;
13871c6a0718SPierre Ossman 
13881c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
13891c6a0718SPierre Ossman 		}
13901c6a0718SPierre Ossman 	}
13911c6a0718SPierre Ossman 
13921c6a0718SPierre Ossman 	mmiowb();
13931c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
13941c6a0718SPierre Ossman }
13951c6a0718SPierre Ossman 
13961c6a0718SPierre Ossman /*****************************************************************************\
13971c6a0718SPierre Ossman  *                                                                           *
13981c6a0718SPierre Ossman  * Interrupt handling                                                        *
13991c6a0718SPierre Ossman  *                                                                           *
14001c6a0718SPierre Ossman \*****************************************************************************/
14011c6a0718SPierre Ossman 
14021c6a0718SPierre Ossman static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
14031c6a0718SPierre Ossman {
14041c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
14051c6a0718SPierre Ossman 
14061c6a0718SPierre Ossman 	if (!host->cmd) {
1407b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
1408b67ac3f3SPierre Ossman 			"though no command operation was in progress.\n",
1409b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
14101c6a0718SPierre Ossman 		sdhci_dumpregs(host);
14111c6a0718SPierre Ossman 		return;
14121c6a0718SPierre Ossman 	}
14131c6a0718SPierre Ossman 
14141c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_TIMEOUT)
141517b0429dSPierre Ossman 		host->cmd->error = -ETIMEDOUT;
141617b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
141717b0429dSPierre Ossman 			SDHCI_INT_INDEX))
141817b0429dSPierre Ossman 		host->cmd->error = -EILSEQ;
14191c6a0718SPierre Ossman 
1420e809517fSPierre Ossman 	if (host->cmd->error) {
14211c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
1422e809517fSPierre Ossman 		return;
1423e809517fSPierre Ossman 	}
1424e809517fSPierre Ossman 
1425e809517fSPierre Ossman 	/*
1426e809517fSPierre Ossman 	 * The host can send and interrupt when the busy state has
1427e809517fSPierre Ossman 	 * ended, allowing us to wait without wasting CPU cycles.
1428e809517fSPierre Ossman 	 * Unfortunately this is overloaded on the "data complete"
1429e809517fSPierre Ossman 	 * interrupt, so we need to take some care when handling
1430e809517fSPierre Ossman 	 * it.
1431e809517fSPierre Ossman 	 *
1432e809517fSPierre Ossman 	 * Note: The 1.0 specification is a bit ambiguous about this
1433e809517fSPierre Ossman 	 *       feature so there might be some problems with older
1434e809517fSPierre Ossman 	 *       controllers.
1435e809517fSPierre Ossman 	 */
1436e809517fSPierre Ossman 	if (host->cmd->flags & MMC_RSP_BUSY) {
1437e809517fSPierre Ossman 		if (host->cmd->data)
1438e809517fSPierre Ossman 			DBG("Cannot wait for busy signal when also "
1439e809517fSPierre Ossman 				"doing a data transfer");
1440f945405cSBen Dooks 		else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
1441e809517fSPierre Ossman 			return;
1442f945405cSBen Dooks 
1443f945405cSBen Dooks 		/* The controller does not support the end-of-busy IRQ,
1444f945405cSBen Dooks 		 * fall through and take the SDHCI_INT_RESPONSE */
1445e809517fSPierre Ossman 	}
1446e809517fSPierre Ossman 
1447e809517fSPierre Ossman 	if (intmask & SDHCI_INT_RESPONSE)
144843b58b36SPierre Ossman 		sdhci_finish_command(host);
14491c6a0718SPierre Ossman }
14501c6a0718SPierre Ossman 
14510957c333SGeorge G. Davis #ifdef CONFIG_MMC_DEBUG
14526882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host)
14536882a8c0SBen Dooks {
14546882a8c0SBen Dooks 	const char *name = mmc_hostname(host->mmc);
14556882a8c0SBen Dooks 	u8 *desc = host->adma_desc;
14566882a8c0SBen Dooks 	__le32 *dma;
14576882a8c0SBen Dooks 	__le16 *len;
14586882a8c0SBen Dooks 	u8 attr;
14596882a8c0SBen Dooks 
14606882a8c0SBen Dooks 	sdhci_dumpregs(host);
14616882a8c0SBen Dooks 
14626882a8c0SBen Dooks 	while (true) {
14636882a8c0SBen Dooks 		dma = (__le32 *)(desc + 4);
14646882a8c0SBen Dooks 		len = (__le16 *)(desc + 2);
14656882a8c0SBen Dooks 		attr = *desc;
14666882a8c0SBen Dooks 
14676882a8c0SBen Dooks 		DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
14686882a8c0SBen Dooks 		    name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr);
14696882a8c0SBen Dooks 
14706882a8c0SBen Dooks 		desc += 8;
14716882a8c0SBen Dooks 
14726882a8c0SBen Dooks 		if (attr & 2)
14736882a8c0SBen Dooks 			break;
14746882a8c0SBen Dooks 	}
14756882a8c0SBen Dooks }
14766882a8c0SBen Dooks #else
14776882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host) { }
14786882a8c0SBen Dooks #endif
14796882a8c0SBen Dooks 
14801c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
14811c6a0718SPierre Ossman {
14821c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
14831c6a0718SPierre Ossman 
14841c6a0718SPierre Ossman 	if (!host->data) {
14851c6a0718SPierre Ossman 		/*
1486e809517fSPierre Ossman 		 * The "data complete" interrupt is also used to
1487e809517fSPierre Ossman 		 * indicate that a busy state has ended. See comment
1488e809517fSPierre Ossman 		 * above in sdhci_cmd_irq().
14891c6a0718SPierre Ossman 		 */
1490e809517fSPierre Ossman 		if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
1491e809517fSPierre Ossman 			if (intmask & SDHCI_INT_DATA_END) {
1492e809517fSPierre Ossman 				sdhci_finish_command(host);
14931c6a0718SPierre Ossman 				return;
1494e809517fSPierre Ossman 			}
1495e809517fSPierre Ossman 		}
14961c6a0718SPierre Ossman 
1497b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
1498b67ac3f3SPierre Ossman 			"though no data operation was in progress.\n",
1499b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
15001c6a0718SPierre Ossman 		sdhci_dumpregs(host);
15011c6a0718SPierre Ossman 
15021c6a0718SPierre Ossman 		return;
15031c6a0718SPierre Ossman 	}
15041c6a0718SPierre Ossman 
15051c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
150617b0429dSPierre Ossman 		host->data->error = -ETIMEDOUT;
150717b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
150817b0429dSPierre Ossman 		host->data->error = -EILSEQ;
15096882a8c0SBen Dooks 	else if (intmask & SDHCI_INT_ADMA_ERROR) {
15106882a8c0SBen Dooks 		printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc));
15116882a8c0SBen Dooks 		sdhci_show_adma_error(host);
15122134a922SPierre Ossman 		host->data->error = -EIO;
15136882a8c0SBen Dooks 	}
15141c6a0718SPierre Ossman 
151517b0429dSPierre Ossman 	if (host->data->error)
15161c6a0718SPierre Ossman 		sdhci_finish_data(host);
15171c6a0718SPierre Ossman 	else {
15181c6a0718SPierre Ossman 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
15191c6a0718SPierre Ossman 			sdhci_transfer_pio(host);
15201c6a0718SPierre Ossman 
15216ba736a1SPierre Ossman 		/*
15226ba736a1SPierre Ossman 		 * We currently don't do anything fancy with DMA
15236ba736a1SPierre Ossman 		 * boundaries, but as we can't disable the feature
15246ba736a1SPierre Ossman 		 * we need to at least restart the transfer.
15256ba736a1SPierre Ossman 		 */
15266ba736a1SPierre Ossman 		if (intmask & SDHCI_INT_DMA_END)
15274e4141a5SAnton Vorontsov 			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
15284e4141a5SAnton Vorontsov 				SDHCI_DMA_ADDRESS);
15296ba736a1SPierre Ossman 
1530e538fbe8SPierre Ossman 		if (intmask & SDHCI_INT_DATA_END) {
1531e538fbe8SPierre Ossman 			if (host->cmd) {
1532e538fbe8SPierre Ossman 				/*
1533e538fbe8SPierre Ossman 				 * Data managed to finish before the
1534e538fbe8SPierre Ossman 				 * command completed. Make sure we do
1535e538fbe8SPierre Ossman 				 * things in the proper order.
1536e538fbe8SPierre Ossman 				 */
1537e538fbe8SPierre Ossman 				host->data_early = 1;
1538e538fbe8SPierre Ossman 			} else {
15391c6a0718SPierre Ossman 				sdhci_finish_data(host);
15401c6a0718SPierre Ossman 			}
15411c6a0718SPierre Ossman 		}
1542e538fbe8SPierre Ossman 	}
1543e538fbe8SPierre Ossman }
15441c6a0718SPierre Ossman 
15451c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id)
15461c6a0718SPierre Ossman {
15471c6a0718SPierre Ossman 	irqreturn_t result;
15481c6a0718SPierre Ossman 	struct sdhci_host* host = dev_id;
15491c6a0718SPierre Ossman 	u32 intmask;
1550f75979b7SPierre Ossman 	int cardint = 0;
15511c6a0718SPierre Ossman 
15521c6a0718SPierre Ossman 	spin_lock(&host->lock);
15531c6a0718SPierre Ossman 
15544e4141a5SAnton Vorontsov 	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
15551c6a0718SPierre Ossman 
15561c6a0718SPierre Ossman 	if (!intmask || intmask == 0xffffffff) {
15571c6a0718SPierre Ossman 		result = IRQ_NONE;
15581c6a0718SPierre Ossman 		goto out;
15591c6a0718SPierre Ossman 	}
15601c6a0718SPierre Ossman 
1561b69c9058SPierre Ossman 	DBG("*** %s got interrupt: 0x%08x\n",
1562b69c9058SPierre Ossman 		mmc_hostname(host->mmc), intmask);
15631c6a0718SPierre Ossman 
15641c6a0718SPierre Ossman 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
15654e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
15664e4141a5SAnton Vorontsov 			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
15671c6a0718SPierre Ossman 		tasklet_schedule(&host->card_tasklet);
15681c6a0718SPierre Ossman 	}
15691c6a0718SPierre Ossman 
15701c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
15711c6a0718SPierre Ossman 
15721c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_CMD_MASK) {
15734e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
15744e4141a5SAnton Vorontsov 			SDHCI_INT_STATUS);
15751c6a0718SPierre Ossman 		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
15761c6a0718SPierre Ossman 	}
15771c6a0718SPierre Ossman 
15781c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_MASK) {
15794e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
15804e4141a5SAnton Vorontsov 			SDHCI_INT_STATUS);
15811c6a0718SPierre Ossman 		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
15821c6a0718SPierre Ossman 	}
15831c6a0718SPierre Ossman 
15841c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
15851c6a0718SPierre Ossman 
1586964f9ce2SPierre Ossman 	intmask &= ~SDHCI_INT_ERROR;
1587964f9ce2SPierre Ossman 
15881c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_BUS_POWER) {
15891c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Card is consuming too much power!\n",
15901c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
15914e4141a5SAnton Vorontsov 		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
15921c6a0718SPierre Ossman 	}
15931c6a0718SPierre Ossman 
15949d26a5d3SRolf Eike Beer 	intmask &= ~SDHCI_INT_BUS_POWER;
15951c6a0718SPierre Ossman 
1596f75979b7SPierre Ossman 	if (intmask & SDHCI_INT_CARD_INT)
1597f75979b7SPierre Ossman 		cardint = 1;
1598f75979b7SPierre Ossman 
1599f75979b7SPierre Ossman 	intmask &= ~SDHCI_INT_CARD_INT;
1600f75979b7SPierre Ossman 
16011c6a0718SPierre Ossman 	if (intmask) {
16021c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
16031c6a0718SPierre Ossman 			mmc_hostname(host->mmc), intmask);
16041c6a0718SPierre Ossman 		sdhci_dumpregs(host);
16051c6a0718SPierre Ossman 
16064e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
16071c6a0718SPierre Ossman 	}
16081c6a0718SPierre Ossman 
16091c6a0718SPierre Ossman 	result = IRQ_HANDLED;
16101c6a0718SPierre Ossman 
16111c6a0718SPierre Ossman 	mmiowb();
16121c6a0718SPierre Ossman out:
16131c6a0718SPierre Ossman 	spin_unlock(&host->lock);
16141c6a0718SPierre Ossman 
1615f75979b7SPierre Ossman 	/*
1616f75979b7SPierre Ossman 	 * We have to delay this as it calls back into the driver.
1617f75979b7SPierre Ossman 	 */
1618f75979b7SPierre Ossman 	if (cardint)
1619f75979b7SPierre Ossman 		mmc_signal_sdio_irq(host->mmc);
1620f75979b7SPierre Ossman 
16211c6a0718SPierre Ossman 	return result;
16221c6a0718SPierre Ossman }
16231c6a0718SPierre Ossman 
16241c6a0718SPierre Ossman /*****************************************************************************\
16251c6a0718SPierre Ossman  *                                                                           *
16261c6a0718SPierre Ossman  * Suspend/resume                                                            *
16271c6a0718SPierre Ossman  *                                                                           *
16281c6a0718SPierre Ossman \*****************************************************************************/
16291c6a0718SPierre Ossman 
16301c6a0718SPierre Ossman #ifdef CONFIG_PM
16311c6a0718SPierre Ossman 
1632b8c86fc5SPierre Ossman int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
16331c6a0718SPierre Ossman {
1634b8c86fc5SPierre Ossman 	int ret;
16351c6a0718SPierre Ossman 
16367260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
16377260cf5eSAnton Vorontsov 
16381a13f8faSMatt Fleming 	ret = mmc_suspend_host(host->mmc);
16391c6a0718SPierre Ossman 	if (ret)
16401c6a0718SPierre Ossman 		return ret;
16411c6a0718SPierre Ossman 
1642b8c86fc5SPierre Ossman 	free_irq(host->irq, host);
1643b8c86fc5SPierre Ossman 
16449bea3c85SMarek Szyprowski 	if (host->vmmc)
16459bea3c85SMarek Szyprowski 		ret = regulator_disable(host->vmmc);
16469bea3c85SMarek Szyprowski 
16479bea3c85SMarek Szyprowski 	return ret;
1648b8c86fc5SPierre Ossman }
1649b8c86fc5SPierre Ossman 
1650b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host);
1651b8c86fc5SPierre Ossman 
1652b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host)
1653b8c86fc5SPierre Ossman {
1654b8c86fc5SPierre Ossman 	int ret;
1655b8c86fc5SPierre Ossman 
16569bea3c85SMarek Szyprowski 	if (host->vmmc) {
16579bea3c85SMarek Szyprowski 		int ret = regulator_enable(host->vmmc);
16589bea3c85SMarek Szyprowski 		if (ret)
16599bea3c85SMarek Szyprowski 			return ret;
16609bea3c85SMarek Szyprowski 	}
16619bea3c85SMarek Szyprowski 
16629bea3c85SMarek Szyprowski 
1663a13abc7bSRichard Röjfors 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1664b8c86fc5SPierre Ossman 		if (host->ops->enable_dma)
1665b8c86fc5SPierre Ossman 			host->ops->enable_dma(host);
1666b8c86fc5SPierre Ossman 	}
1667b8c86fc5SPierre Ossman 
1668b8c86fc5SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1669b8c86fc5SPierre Ossman 			  mmc_hostname(host->mmc), host);
16701c6a0718SPierre Ossman 	if (ret)
16711c6a0718SPierre Ossman 		return ret;
1672b8c86fc5SPierre Ossman 
16732f4cbb3dSNicolas Pitre 	sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
16741c6a0718SPierre Ossman 	mmiowb();
1675b8c86fc5SPierre Ossman 
1676b8c86fc5SPierre Ossman 	ret = mmc_resume_host(host->mmc);
16777260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
16787260cf5eSAnton Vorontsov 
16792f4cbb3dSNicolas Pitre 	return ret;
16801c6a0718SPierre Ossman }
16811c6a0718SPierre Ossman 
1682b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host);
16831c6a0718SPierre Ossman 
16841c6a0718SPierre Ossman #endif /* CONFIG_PM */
16851c6a0718SPierre Ossman 
16861c6a0718SPierre Ossman /*****************************************************************************\
16871c6a0718SPierre Ossman  *                                                                           *
1688b8c86fc5SPierre Ossman  * Device allocation/registration                                            *
16891c6a0718SPierre Ossman  *                                                                           *
16901c6a0718SPierre Ossman \*****************************************************************************/
16911c6a0718SPierre Ossman 
1692b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev,
1693b8c86fc5SPierre Ossman 	size_t priv_size)
16941c6a0718SPierre Ossman {
16951c6a0718SPierre Ossman 	struct mmc_host *mmc;
16961c6a0718SPierre Ossman 	struct sdhci_host *host;
16971c6a0718SPierre Ossman 
1698b8c86fc5SPierre Ossman 	WARN_ON(dev == NULL);
16991c6a0718SPierre Ossman 
1700b8c86fc5SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
17011c6a0718SPierre Ossman 	if (!mmc)
1702b8c86fc5SPierre Ossman 		return ERR_PTR(-ENOMEM);
17031c6a0718SPierre Ossman 
17041c6a0718SPierre Ossman 	host = mmc_priv(mmc);
17051c6a0718SPierre Ossman 	host->mmc = mmc;
17061c6a0718SPierre Ossman 
1707b8c86fc5SPierre Ossman 	return host;
17081c6a0718SPierre Ossman }
17091c6a0718SPierre Ossman 
1710b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host);
1711b8c86fc5SPierre Ossman 
1712b8c86fc5SPierre Ossman int sdhci_add_host(struct sdhci_host *host)
1713b8c86fc5SPierre Ossman {
1714b8c86fc5SPierre Ossman 	struct mmc_host *mmc;
1715b8c86fc5SPierre Ossman 	unsigned int caps;
1716b8c86fc5SPierre Ossman 	int ret;
1717b8c86fc5SPierre Ossman 
1718b8c86fc5SPierre Ossman 	WARN_ON(host == NULL);
1719b8c86fc5SPierre Ossman 	if (host == NULL)
1720b8c86fc5SPierre Ossman 		return -EINVAL;
1721b8c86fc5SPierre Ossman 
1722b8c86fc5SPierre Ossman 	mmc = host->mmc;
1723b8c86fc5SPierre Ossman 
1724b8c86fc5SPierre Ossman 	if (debug_quirks)
1725b8c86fc5SPierre Ossman 		host->quirks = debug_quirks;
1726b8c86fc5SPierre Ossman 
17271c6a0718SPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
17281c6a0718SPierre Ossman 
17294e4141a5SAnton Vorontsov 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
17302134a922SPierre Ossman 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
17312134a922SPierre Ossman 				>> SDHCI_SPEC_VER_SHIFT;
173285105c53SZhangfei Gao 	if (host->version > SDHCI_SPEC_300) {
17331c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unknown controller version (%d). "
1734b69c9058SPierre Ossman 			"You may experience problems.\n", mmc_hostname(mmc),
17352134a922SPierre Ossman 			host->version);
17361c6a0718SPierre Ossman 	}
17371c6a0718SPierre Ossman 
1738ccc92c23SMaxim Levitsky 	caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
1739ccc92c23SMaxim Levitsky 		sdhci_readl(host, SDHCI_CAPABILITIES);
17401c6a0718SPierre Ossman 
1741b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
1742a13abc7bSRichard Röjfors 		host->flags |= SDHCI_USE_SDMA;
1743a13abc7bSRichard Röjfors 	else if (!(caps & SDHCI_CAN_DO_SDMA))
1744a13abc7bSRichard Röjfors 		DBG("Controller doesn't have SDMA capability\n");
17451c6a0718SPierre Ossman 	else
1746a13abc7bSRichard Röjfors 		host->flags |= SDHCI_USE_SDMA;
17471c6a0718SPierre Ossman 
1748b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
1749a13abc7bSRichard Röjfors 		(host->flags & SDHCI_USE_SDMA)) {
1750cee687ceSRolf Eike Beer 		DBG("Disabling DMA as it is marked broken\n");
1751a13abc7bSRichard Röjfors 		host->flags &= ~SDHCI_USE_SDMA;
17527c168e3dSFeng Tang 	}
17537c168e3dSFeng Tang 
1754a13abc7bSRichard Röjfors 	if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
17552134a922SPierre Ossman 		host->flags |= SDHCI_USE_ADMA;
17562134a922SPierre Ossman 
17572134a922SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
17582134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)) {
17592134a922SPierre Ossman 		DBG("Disabling ADMA as it is marked broken\n");
17602134a922SPierre Ossman 		host->flags &= ~SDHCI_USE_ADMA;
17612134a922SPierre Ossman 	}
17622134a922SPierre Ossman 
1763a13abc7bSRichard Röjfors 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1764b8c86fc5SPierre Ossman 		if (host->ops->enable_dma) {
1765b8c86fc5SPierre Ossman 			if (host->ops->enable_dma(host)) {
1766b8c86fc5SPierre Ossman 				printk(KERN_WARNING "%s: No suitable DMA "
1767b8c86fc5SPierre Ossman 					"available. Falling back to PIO.\n",
1768b8c86fc5SPierre Ossman 					mmc_hostname(mmc));
1769a13abc7bSRichard Röjfors 				host->flags &=
1770a13abc7bSRichard Röjfors 					~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
17711c6a0718SPierre Ossman 			}
17721c6a0718SPierre Ossman 		}
1773b8c86fc5SPierre Ossman 	}
17741c6a0718SPierre Ossman 
17752134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA) {
17762134a922SPierre Ossman 		/*
17772134a922SPierre Ossman 		 * We need to allocate descriptors for all sg entries
17782134a922SPierre Ossman 		 * (128) and potentially one alignment transfer for
17792134a922SPierre Ossman 		 * each of those entries.
17802134a922SPierre Ossman 		 */
17812134a922SPierre Ossman 		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
17822134a922SPierre Ossman 		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
17832134a922SPierre Ossman 		if (!host->adma_desc || !host->align_buffer) {
17842134a922SPierre Ossman 			kfree(host->adma_desc);
17852134a922SPierre Ossman 			kfree(host->align_buffer);
17862134a922SPierre Ossman 			printk(KERN_WARNING "%s: Unable to allocate ADMA "
17872134a922SPierre Ossman 				"buffers. Falling back to standard DMA.\n",
17882134a922SPierre Ossman 				mmc_hostname(mmc));
17892134a922SPierre Ossman 			host->flags &= ~SDHCI_USE_ADMA;
17902134a922SPierre Ossman 		}
17912134a922SPierre Ossman 	}
17922134a922SPierre Ossman 
17937659150cSPierre Ossman 	/*
17947659150cSPierre Ossman 	 * If we use DMA, then it's up to the caller to set the DMA
17957659150cSPierre Ossman 	 * mask, but PIO does not need the hw shim so we set a new
17967659150cSPierre Ossman 	 * mask here in that case.
17977659150cSPierre Ossman 	 */
1798a13abc7bSRichard Röjfors 	if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
17997659150cSPierre Ossman 		host->dma_mask = DMA_BIT_MASK(64);
18007659150cSPierre Ossman 		mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
18017659150cSPierre Ossman 	}
18021c6a0718SPierre Ossman 
1803c4687d5fSZhangfei Gao 	if (host->version >= SDHCI_SPEC_300)
1804c4687d5fSZhangfei Gao 		host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK)
1805c4687d5fSZhangfei Gao 			>> SDHCI_CLOCK_BASE_SHIFT;
1806c4687d5fSZhangfei Gao 	else
1807c4687d5fSZhangfei Gao 		host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK)
1808c4687d5fSZhangfei Gao 			>> SDHCI_CLOCK_BASE_SHIFT;
1809c4687d5fSZhangfei Gao 
18104240ff0aSBen Dooks 	host->max_clk *= 1000000;
1811f27f47efSAnton Vorontsov 	if (host->max_clk == 0 || host->quirks &
1812f27f47efSAnton Vorontsov 			SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
18134240ff0aSBen Dooks 		if (!host->ops->get_max_clock) {
18144240ff0aSBen Dooks 			printk(KERN_ERR
18154240ff0aSBen Dooks 			       "%s: Hardware doesn't specify base clock "
1816b69c9058SPierre Ossman 			       "frequency.\n", mmc_hostname(mmc));
1817b8c86fc5SPierre Ossman 			return -ENODEV;
18181c6a0718SPierre Ossman 		}
18194240ff0aSBen Dooks 		host->max_clk = host->ops->get_max_clock(host);
18204240ff0aSBen Dooks 	}
18211c6a0718SPierre Ossman 
18221c6a0718SPierre Ossman 	host->timeout_clk =
18231c6a0718SPierre Ossman 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
18241c6a0718SPierre Ossman 	if (host->timeout_clk == 0) {
182581b39802SAnton Vorontsov 		if (host->ops->get_timeout_clock) {
182681b39802SAnton Vorontsov 			host->timeout_clk = host->ops->get_timeout_clock(host);
182781b39802SAnton Vorontsov 		} else if (!(host->quirks &
182881b39802SAnton Vorontsov 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
18294240ff0aSBen Dooks 			printk(KERN_ERR
18304240ff0aSBen Dooks 			       "%s: Hardware doesn't specify timeout clock "
1831b69c9058SPierre Ossman 			       "frequency.\n", mmc_hostname(mmc));
1832b8c86fc5SPierre Ossman 			return -ENODEV;
18331c6a0718SPierre Ossman 		}
18344240ff0aSBen Dooks 	}
18351c6a0718SPierre Ossman 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
18361c6a0718SPierre Ossman 		host->timeout_clk *= 1000;
18371c6a0718SPierre Ossman 
18381c6a0718SPierre Ossman 	/*
18391c6a0718SPierre Ossman 	 * Set host parameters.
18401c6a0718SPierre Ossman 	 */
18411c6a0718SPierre Ossman 	mmc->ops = &sdhci_ops;
1842ce5f036bSMarek Szyprowski 	if (host->ops->get_min_clock)
1843a9e58f25SAnton Vorontsov 		mmc->f_min = host->ops->get_min_clock(host);
18440397526dSZhangfei Gao 	else if (host->version >= SDHCI_SPEC_300)
18450397526dSZhangfei Gao 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
1846a9e58f25SAnton Vorontsov 	else
18470397526dSZhangfei Gao 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
18481c6a0718SPierre Ossman 	mmc->f_max = host->max_clk;
1849c1f5977cSKyungmin Park 	mmc->caps |= MMC_CAP_SDIO_IRQ;
18505fe23c7fSAnton Vorontsov 
18515fe23c7fSAnton Vorontsov 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
1852b08caed8SGiuseppe Cavallaro 		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
18531c6a0718SPierre Ossman 
185486a6a874SPierre Ossman 	if (caps & SDHCI_CAN_DO_HISPD)
1855a29e7e18SZhangfei Gao 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
18561c6a0718SPierre Ossman 
1857176d1ed4SJaehoon Chung 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
1858176d1ed4SJaehoon Chung 	    mmc_card_is_removable(mmc))
185968d1fb7eSAnton Vorontsov 		mmc->caps |= MMC_CAP_NEEDS_POLL;
186068d1fb7eSAnton Vorontsov 
18611c6a0718SPierre Ossman 	mmc->ocr_avail = 0;
18621c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_330)
18631c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
18641c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_300)
18651c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
18661c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_180)
186755556da0SPhilip Langdale 		mmc->ocr_avail |= MMC_VDD_165_195;
18681c6a0718SPierre Ossman 
18691c6a0718SPierre Ossman 	if (mmc->ocr_avail == 0) {
18701c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Hardware doesn't report any "
1871b69c9058SPierre Ossman 			"support voltages.\n", mmc_hostname(mmc));
1872b8c86fc5SPierre Ossman 		return -ENODEV;
18731c6a0718SPierre Ossman 	}
18741c6a0718SPierre Ossman 
18751c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
18761c6a0718SPierre Ossman 
18771c6a0718SPierre Ossman 	/*
18782134a922SPierre Ossman 	 * Maximum number of segments. Depends on if the hardware
18792134a922SPierre Ossman 	 * can do scatter/gather or not.
18801c6a0718SPierre Ossman 	 */
18812134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
1882a36274e0SMartin K. Petersen 		mmc->max_segs = 128;
1883a13abc7bSRichard Röjfors 	else if (host->flags & SDHCI_USE_SDMA)
1884a36274e0SMartin K. Petersen 		mmc->max_segs = 1;
18852134a922SPierre Ossman 	else /* PIO */
1886a36274e0SMartin K. Petersen 		mmc->max_segs = 128;
18871c6a0718SPierre Ossman 
18881c6a0718SPierre Ossman 	/*
18891c6a0718SPierre Ossman 	 * Maximum number of sectors in one transfer. Limited by DMA boundary
18901c6a0718SPierre Ossman 	 * size (512KiB).
18911c6a0718SPierre Ossman 	 */
18921c6a0718SPierre Ossman 	mmc->max_req_size = 524288;
18931c6a0718SPierre Ossman 
18941c6a0718SPierre Ossman 	/*
18951c6a0718SPierre Ossman 	 * Maximum segment size. Could be one segment with the maximum number
18962134a922SPierre Ossman 	 * of bytes. When doing hardware scatter/gather, each entry cannot
18972134a922SPierre Ossman 	 * be larger than 64 KiB though.
18981c6a0718SPierre Ossman 	 */
18992134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
19002134a922SPierre Ossman 		mmc->max_seg_size = 65536;
19012134a922SPierre Ossman 	else
19021c6a0718SPierre Ossman 		mmc->max_seg_size = mmc->max_req_size;
19031c6a0718SPierre Ossman 
19041c6a0718SPierre Ossman 	/*
19051c6a0718SPierre Ossman 	 * Maximum block size. This varies from controller to controller and
19061c6a0718SPierre Ossman 	 * is specified in the capabilities register.
19071c6a0718SPierre Ossman 	 */
19080633f654SAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
19090633f654SAnton Vorontsov 		mmc->max_blk_size = 2;
19100633f654SAnton Vorontsov 	} else {
19110633f654SAnton Vorontsov 		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
19120633f654SAnton Vorontsov 				SDHCI_MAX_BLOCK_SHIFT;
19131c6a0718SPierre Ossman 		if (mmc->max_blk_size >= 3) {
1914b69c9058SPierre Ossman 			printk(KERN_WARNING "%s: Invalid maximum block size, "
1915b69c9058SPierre Ossman 				"assuming 512 bytes\n", mmc_hostname(mmc));
19160633f654SAnton Vorontsov 			mmc->max_blk_size = 0;
19170633f654SAnton Vorontsov 		}
19180633f654SAnton Vorontsov 	}
19190633f654SAnton Vorontsov 
19201c6a0718SPierre Ossman 	mmc->max_blk_size = 512 << mmc->max_blk_size;
19211c6a0718SPierre Ossman 
19221c6a0718SPierre Ossman 	/*
19231c6a0718SPierre Ossman 	 * Maximum block count.
19241c6a0718SPierre Ossman 	 */
19251388eefdSBen Dooks 	mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
19261c6a0718SPierre Ossman 
19271c6a0718SPierre Ossman 	/*
19281c6a0718SPierre Ossman 	 * Init tasklets.
19291c6a0718SPierre Ossman 	 */
19301c6a0718SPierre Ossman 	tasklet_init(&host->card_tasklet,
19311c6a0718SPierre Ossman 		sdhci_tasklet_card, (unsigned long)host);
19321c6a0718SPierre Ossman 	tasklet_init(&host->finish_tasklet,
19331c6a0718SPierre Ossman 		sdhci_tasklet_finish, (unsigned long)host);
19341c6a0718SPierre Ossman 
19351c6a0718SPierre Ossman 	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
19361c6a0718SPierre Ossman 
19371c6a0718SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1938b69c9058SPierre Ossman 		mmc_hostname(mmc), host);
19391c6a0718SPierre Ossman 	if (ret)
19401c6a0718SPierre Ossman 		goto untasklet;
19411c6a0718SPierre Ossman 
19429bea3c85SMarek Szyprowski 	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
19439bea3c85SMarek Szyprowski 	if (IS_ERR(host->vmmc)) {
19449bea3c85SMarek Szyprowski 		printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc));
19459bea3c85SMarek Szyprowski 		host->vmmc = NULL;
19469bea3c85SMarek Szyprowski 	} else {
19479bea3c85SMarek Szyprowski 		regulator_enable(host->vmmc);
19489bea3c85SMarek Szyprowski 	}
19499bea3c85SMarek Szyprowski 
19502f4cbb3dSNicolas Pitre 	sdhci_init(host, 0);
19511c6a0718SPierre Ossman 
19521c6a0718SPierre Ossman #ifdef CONFIG_MMC_DEBUG
19531c6a0718SPierre Ossman 	sdhci_dumpregs(host);
19541c6a0718SPierre Ossman #endif
19551c6a0718SPierre Ossman 
1956f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
19575dbace0cSHelmut Schaa 	snprintf(host->led_name, sizeof(host->led_name),
19585dbace0cSHelmut Schaa 		"%s::", mmc_hostname(mmc));
19595dbace0cSHelmut Schaa 	host->led.name = host->led_name;
19602f730fecSPierre Ossman 	host->led.brightness = LED_OFF;
19612f730fecSPierre Ossman 	host->led.default_trigger = mmc_hostname(mmc);
19622f730fecSPierre Ossman 	host->led.brightness_set = sdhci_led_control;
19632f730fecSPierre Ossman 
1964b8c86fc5SPierre Ossman 	ret = led_classdev_register(mmc_dev(mmc), &host->led);
19652f730fecSPierre Ossman 	if (ret)
19662f730fecSPierre Ossman 		goto reset;
19672f730fecSPierre Ossman #endif
19682f730fecSPierre Ossman 
19691c6a0718SPierre Ossman 	mmiowb();
19701c6a0718SPierre Ossman 
19711c6a0718SPierre Ossman 	mmc_add_host(mmc);
19721c6a0718SPierre Ossman 
1973a13abc7bSRichard Röjfors 	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
1974d1b26863SKay Sievers 		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
1975a13abc7bSRichard Röjfors 		(host->flags & SDHCI_USE_ADMA) ? "ADMA" :
1976a13abc7bSRichard Röjfors 		(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
19771c6a0718SPierre Ossman 
19787260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
19797260cf5eSAnton Vorontsov 
19801c6a0718SPierre Ossman 	return 0;
19811c6a0718SPierre Ossman 
1982f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
19832f730fecSPierre Ossman reset:
19842f730fecSPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
19852f730fecSPierre Ossman 	free_irq(host->irq, host);
19862f730fecSPierre Ossman #endif
19871c6a0718SPierre Ossman untasklet:
19881c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
19891c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
19901c6a0718SPierre Ossman 
19911c6a0718SPierre Ossman 	return ret;
19921c6a0718SPierre Ossman }
19931c6a0718SPierre Ossman 
1994b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host);
1995b8c86fc5SPierre Ossman 
19961e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead)
19971c6a0718SPierre Ossman {
19981e72859eSPierre Ossman 	unsigned long flags;
19991e72859eSPierre Ossman 
20001e72859eSPierre Ossman 	if (dead) {
20011e72859eSPierre Ossman 		spin_lock_irqsave(&host->lock, flags);
20021e72859eSPierre Ossman 
20031e72859eSPierre Ossman 		host->flags |= SDHCI_DEVICE_DEAD;
20041e72859eSPierre Ossman 
20051e72859eSPierre Ossman 		if (host->mrq) {
20061e72859eSPierre Ossman 			printk(KERN_ERR "%s: Controller removed during "
20071e72859eSPierre Ossman 				" transfer!\n", mmc_hostname(host->mmc));
20081e72859eSPierre Ossman 
20091e72859eSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
20101e72859eSPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
20111e72859eSPierre Ossman 		}
20121e72859eSPierre Ossman 
20131e72859eSPierre Ossman 		spin_unlock_irqrestore(&host->lock, flags);
20141e72859eSPierre Ossman 	}
20151e72859eSPierre Ossman 
20167260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
20177260cf5eSAnton Vorontsov 
2018b8c86fc5SPierre Ossman 	mmc_remove_host(host->mmc);
20191c6a0718SPierre Ossman 
2020f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
20212f730fecSPierre Ossman 	led_classdev_unregister(&host->led);
20222f730fecSPierre Ossman #endif
20232f730fecSPierre Ossman 
20241e72859eSPierre Ossman 	if (!dead)
20251c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_ALL);
20261c6a0718SPierre Ossman 
20271c6a0718SPierre Ossman 	free_irq(host->irq, host);
20281c6a0718SPierre Ossman 
20291c6a0718SPierre Ossman 	del_timer_sync(&host->timer);
20301c6a0718SPierre Ossman 
20311c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
20321c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
20332134a922SPierre Ossman 
20349bea3c85SMarek Szyprowski 	if (host->vmmc) {
20359bea3c85SMarek Szyprowski 		regulator_disable(host->vmmc);
20369bea3c85SMarek Szyprowski 		regulator_put(host->vmmc);
20379bea3c85SMarek Szyprowski 	}
20389bea3c85SMarek Szyprowski 
20392134a922SPierre Ossman 	kfree(host->adma_desc);
20402134a922SPierre Ossman 	kfree(host->align_buffer);
20412134a922SPierre Ossman 
20422134a922SPierre Ossman 	host->adma_desc = NULL;
20432134a922SPierre Ossman 	host->align_buffer = NULL;
20441c6a0718SPierre Ossman }
20451c6a0718SPierre Ossman 
2046b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host);
2047b8c86fc5SPierre Ossman 
2048b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host)
20491c6a0718SPierre Ossman {
2050b8c86fc5SPierre Ossman 	mmc_free_host(host->mmc);
20511c6a0718SPierre Ossman }
20521c6a0718SPierre Ossman 
2053b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host);
20541c6a0718SPierre Ossman 
20551c6a0718SPierre Ossman /*****************************************************************************\
20561c6a0718SPierre Ossman  *                                                                           *
20571c6a0718SPierre Ossman  * Driver init/exit                                                          *
20581c6a0718SPierre Ossman  *                                                                           *
20591c6a0718SPierre Ossman \*****************************************************************************/
20601c6a0718SPierre Ossman 
20611c6a0718SPierre Ossman static int __init sdhci_drv_init(void)
20621c6a0718SPierre Ossman {
20631c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME
20641c6a0718SPierre Ossman 		": Secure Digital Host Controller Interface driver\n");
20651c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
20661c6a0718SPierre Ossman 
2067b8c86fc5SPierre Ossman 	return 0;
20681c6a0718SPierre Ossman }
20691c6a0718SPierre Ossman 
20701c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void)
20711c6a0718SPierre Ossman {
20721c6a0718SPierre Ossman }
20731c6a0718SPierre Ossman 
20741c6a0718SPierre Ossman module_init(sdhci_drv_init);
20751c6a0718SPierre Ossman module_exit(sdhci_drv_exit);
20761c6a0718SPierre Ossman 
20771c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444);
20781c6a0718SPierre Ossman 
207932710e8fSPierre Ossman MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
2080b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
20811c6a0718SPierre Ossman MODULE_LICENSE("GPL");
20821c6a0718SPierre Ossman 
20831c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
2084