xref: /openbmc/linux/drivers/mmc/host/sdhci.c (revision 5fe23c7f)
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>
2011763609SRalf Baechle #include <linux/scatterlist.h>
211c6a0718SPierre Ossman 
222f730fecSPierre Ossman #include <linux/leds.h>
232f730fecSPierre Ossman 
241c6a0718SPierre Ossman #include <linux/mmc/host.h>
251c6a0718SPierre Ossman 
261c6a0718SPierre Ossman #include "sdhci.h"
271c6a0718SPierre Ossman 
281c6a0718SPierre Ossman #define DRIVER_NAME "sdhci"
291c6a0718SPierre Ossman 
301c6a0718SPierre Ossman #define DBG(f, x...) \
311c6a0718SPierre Ossman 	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
321c6a0718SPierre Ossman 
33f9134319SPierre Ossman #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
34f9134319SPierre Ossman 	defined(CONFIG_MMC_SDHCI_MODULE))
35f9134319SPierre Ossman #define SDHCI_USE_LEDS_CLASS
36f9134319SPierre Ossman #endif
37f9134319SPierre Ossman 
381c6a0718SPierre Ossman static unsigned int debug_quirks = 0;
391c6a0718SPierre Ossman 
401c6a0718SPierre Ossman static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
411c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *);
421c6a0718SPierre Ossman 
431c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
441c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *);
451c6a0718SPierre Ossman 
461c6a0718SPierre Ossman static void sdhci_dumpregs(struct sdhci_host *host)
471c6a0718SPierre Ossman {
481c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
491c6a0718SPierre Ossman 
501c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
514e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_DMA_ADDRESS),
524e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_HOST_VERSION));
531c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
544e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_BLOCK_SIZE),
554e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_BLOCK_COUNT));
561c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
574e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_ARGUMENT),
584e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
591c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
604e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_PRESENT_STATE),
614e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_HOST_CONTROL));
621c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
634e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_POWER_CONTROL),
644e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
651c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
664e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
674e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
681c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
694e4141a5SAnton Vorontsov 		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
704e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_INT_STATUS));
711c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
724e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_INT_ENABLE),
734e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
741c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
754e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_ACMD12_ERR),
764e4141a5SAnton Vorontsov 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
771c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
784e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_CAPABILITIES),
794e4141a5SAnton Vorontsov 		sdhci_readl(host, SDHCI_MAX_CURRENT));
801c6a0718SPierre Ossman 
81be3f4ae0SBen Dooks 	if (host->flags & SDHCI_USE_ADMA)
82be3f4ae0SBen Dooks 		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
83be3f4ae0SBen Dooks 		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
84be3f4ae0SBen Dooks 		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
85be3f4ae0SBen Dooks 
861c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
871c6a0718SPierre Ossman }
881c6a0718SPierre Ossman 
891c6a0718SPierre Ossman /*****************************************************************************\
901c6a0718SPierre Ossman  *                                                                           *
911c6a0718SPierre Ossman  * Low level functions                                                       *
921c6a0718SPierre Ossman  *                                                                           *
931c6a0718SPierre Ossman \*****************************************************************************/
941c6a0718SPierre Ossman 
957260cf5eSAnton Vorontsov static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
967260cf5eSAnton Vorontsov {
977260cf5eSAnton Vorontsov 	u32 ier;
987260cf5eSAnton Vorontsov 
997260cf5eSAnton Vorontsov 	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
1007260cf5eSAnton Vorontsov 	ier &= ~clear;
1017260cf5eSAnton Vorontsov 	ier |= set;
1027260cf5eSAnton Vorontsov 	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
1037260cf5eSAnton Vorontsov 	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
1047260cf5eSAnton Vorontsov }
1057260cf5eSAnton Vorontsov 
1067260cf5eSAnton Vorontsov static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
1077260cf5eSAnton Vorontsov {
1087260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, 0, irqs);
1097260cf5eSAnton Vorontsov }
1107260cf5eSAnton Vorontsov 
1117260cf5eSAnton Vorontsov static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
1127260cf5eSAnton Vorontsov {
1137260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, irqs, 0);
1147260cf5eSAnton Vorontsov }
1157260cf5eSAnton Vorontsov 
1167260cf5eSAnton Vorontsov static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
1177260cf5eSAnton Vorontsov {
1187260cf5eSAnton Vorontsov 	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
1197260cf5eSAnton Vorontsov 
12068d1fb7eSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
12168d1fb7eSAnton Vorontsov 		return;
12268d1fb7eSAnton Vorontsov 
1237260cf5eSAnton Vorontsov 	if (enable)
1247260cf5eSAnton Vorontsov 		sdhci_unmask_irqs(host, irqs);
1257260cf5eSAnton Vorontsov 	else
1267260cf5eSAnton Vorontsov 		sdhci_mask_irqs(host, irqs);
1277260cf5eSAnton Vorontsov }
1287260cf5eSAnton Vorontsov 
1297260cf5eSAnton Vorontsov static void sdhci_enable_card_detection(struct sdhci_host *host)
1307260cf5eSAnton Vorontsov {
1317260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, true);
1327260cf5eSAnton Vorontsov }
1337260cf5eSAnton Vorontsov 
1347260cf5eSAnton Vorontsov static void sdhci_disable_card_detection(struct sdhci_host *host)
1357260cf5eSAnton Vorontsov {
1367260cf5eSAnton Vorontsov 	sdhci_set_card_detection(host, false);
1377260cf5eSAnton Vorontsov }
1387260cf5eSAnton Vorontsov 
1391c6a0718SPierre Ossman static void sdhci_reset(struct sdhci_host *host, u8 mask)
1401c6a0718SPierre Ossman {
1411c6a0718SPierre Ossman 	unsigned long timeout;
142063a9dbbSAnton Vorontsov 	u32 uninitialized_var(ier);
1431c6a0718SPierre Ossman 
144b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
1454e4141a5SAnton Vorontsov 		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
1461c6a0718SPierre Ossman 			SDHCI_CARD_PRESENT))
1471c6a0718SPierre Ossman 			return;
1481c6a0718SPierre Ossman 	}
1491c6a0718SPierre Ossman 
150063a9dbbSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
151063a9dbbSAnton Vorontsov 		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
152063a9dbbSAnton Vorontsov 
1534e4141a5SAnton Vorontsov 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
1541c6a0718SPierre Ossman 
1551c6a0718SPierre Ossman 	if (mask & SDHCI_RESET_ALL)
1561c6a0718SPierre Ossman 		host->clock = 0;
1571c6a0718SPierre Ossman 
1581c6a0718SPierre Ossman 	/* Wait max 100 ms */
1591c6a0718SPierre Ossman 	timeout = 100;
1601c6a0718SPierre Ossman 
1611c6a0718SPierre Ossman 	/* hw clears the bit when it's done */
1624e4141a5SAnton Vorontsov 	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
1631c6a0718SPierre Ossman 		if (timeout == 0) {
1641c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
1651c6a0718SPierre Ossman 				mmc_hostname(host->mmc), (int)mask);
1661c6a0718SPierre Ossman 			sdhci_dumpregs(host);
1671c6a0718SPierre Ossman 			return;
1681c6a0718SPierre Ossman 		}
1691c6a0718SPierre Ossman 		timeout--;
1701c6a0718SPierre Ossman 		mdelay(1);
1711c6a0718SPierre Ossman 	}
172063a9dbbSAnton Vorontsov 
173063a9dbbSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
174063a9dbbSAnton Vorontsov 		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
1751c6a0718SPierre Ossman }
1761c6a0718SPierre Ossman 
1771c6a0718SPierre Ossman static void sdhci_init(struct sdhci_host *host)
1781c6a0718SPierre Ossman {
1791c6a0718SPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
1801c6a0718SPierre Ossman 
1817260cf5eSAnton Vorontsov 	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
1827260cf5eSAnton Vorontsov 		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
1831c6a0718SPierre Ossman 		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
1841c6a0718SPierre Ossman 		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
1856aa943abSAnton Vorontsov 		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
1867260cf5eSAnton Vorontsov }
1871c6a0718SPierre Ossman 
1887260cf5eSAnton Vorontsov static void sdhci_reinit(struct sdhci_host *host)
1897260cf5eSAnton Vorontsov {
1907260cf5eSAnton Vorontsov 	sdhci_init(host);
1917260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
1921c6a0718SPierre Ossman }
1931c6a0718SPierre Ossman 
1941c6a0718SPierre Ossman static void sdhci_activate_led(struct sdhci_host *host)
1951c6a0718SPierre Ossman {
1961c6a0718SPierre Ossman 	u8 ctrl;
1971c6a0718SPierre Ossman 
1984e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
1991c6a0718SPierre Ossman 	ctrl |= SDHCI_CTRL_LED;
2004e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2011c6a0718SPierre Ossman }
2021c6a0718SPierre Ossman 
2031c6a0718SPierre Ossman static void sdhci_deactivate_led(struct sdhci_host *host)
2041c6a0718SPierre Ossman {
2051c6a0718SPierre Ossman 	u8 ctrl;
2061c6a0718SPierre Ossman 
2074e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
2081c6a0718SPierre Ossman 	ctrl &= ~SDHCI_CTRL_LED;
2094e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
2101c6a0718SPierre Ossman }
2111c6a0718SPierre Ossman 
212f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
2132f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led,
2142f730fecSPierre Ossman 	enum led_brightness brightness)
2152f730fecSPierre Ossman {
2162f730fecSPierre Ossman 	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
2172f730fecSPierre Ossman 	unsigned long flags;
2182f730fecSPierre Ossman 
2192f730fecSPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
2202f730fecSPierre Ossman 
2212f730fecSPierre Ossman 	if (brightness == LED_OFF)
2222f730fecSPierre Ossman 		sdhci_deactivate_led(host);
2232f730fecSPierre Ossman 	else
2242f730fecSPierre Ossman 		sdhci_activate_led(host);
2252f730fecSPierre Ossman 
2262f730fecSPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
2272f730fecSPierre Ossman }
2282f730fecSPierre Ossman #endif
2292f730fecSPierre Ossman 
2301c6a0718SPierre Ossman /*****************************************************************************\
2311c6a0718SPierre Ossman  *                                                                           *
2321c6a0718SPierre Ossman  * Core functions                                                            *
2331c6a0718SPierre Ossman  *                                                                           *
2341c6a0718SPierre Ossman \*****************************************************************************/
2351c6a0718SPierre Ossman 
2361c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host)
2371c6a0718SPierre Ossman {
2387659150cSPierre Ossman 	unsigned long flags;
2397659150cSPierre Ossman 	size_t blksize, len, chunk;
2407244b85bSSteven Noonan 	u32 uninitialized_var(scratch);
2417659150cSPierre Ossman 	u8 *buf;
2421c6a0718SPierre Ossman 
2431c6a0718SPierre Ossman 	DBG("PIO reading\n");
2441c6a0718SPierre Ossman 
2451c6a0718SPierre Ossman 	blksize = host->data->blksz;
2467659150cSPierre Ossman 	chunk = 0;
2471c6a0718SPierre Ossman 
2487659150cSPierre Ossman 	local_irq_save(flags);
2491c6a0718SPierre Ossman 
2501c6a0718SPierre Ossman 	while (blksize) {
2517659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
2527659150cSPierre Ossman 			BUG();
2537659150cSPierre Ossman 
2547659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
2557659150cSPierre Ossman 
2567659150cSPierre Ossman 		blksize -= len;
2577659150cSPierre Ossman 		host->sg_miter.consumed = len;
2587659150cSPierre Ossman 
2597659150cSPierre Ossman 		buf = host->sg_miter.addr;
2607659150cSPierre Ossman 
2617659150cSPierre Ossman 		while (len) {
2627659150cSPierre Ossman 			if (chunk == 0) {
2634e4141a5SAnton Vorontsov 				scratch = sdhci_readl(host, SDHCI_BUFFER);
2647659150cSPierre Ossman 				chunk = 4;
2651c6a0718SPierre Ossman 			}
2661c6a0718SPierre Ossman 
2677659150cSPierre Ossman 			*buf = scratch & 0xFF;
2681c6a0718SPierre Ossman 
2697659150cSPierre Ossman 			buf++;
2707659150cSPierre Ossman 			scratch >>= 8;
2717659150cSPierre Ossman 			chunk--;
2727659150cSPierre Ossman 			len--;
2737659150cSPierre Ossman 		}
2741c6a0718SPierre Ossman 	}
2751c6a0718SPierre Ossman 
2767659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
2777659150cSPierre Ossman 
2787659150cSPierre Ossman 	local_irq_restore(flags);
2791c6a0718SPierre Ossman }
2801c6a0718SPierre Ossman 
2811c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host)
2821c6a0718SPierre Ossman {
2837659150cSPierre Ossman 	unsigned long flags;
2847659150cSPierre Ossman 	size_t blksize, len, chunk;
2857659150cSPierre Ossman 	u32 scratch;
2867659150cSPierre Ossman 	u8 *buf;
2871c6a0718SPierre Ossman 
2881c6a0718SPierre Ossman 	DBG("PIO writing\n");
2891c6a0718SPierre Ossman 
2901c6a0718SPierre Ossman 	blksize = host->data->blksz;
2917659150cSPierre Ossman 	chunk = 0;
2927659150cSPierre Ossman 	scratch = 0;
2931c6a0718SPierre Ossman 
2947659150cSPierre Ossman 	local_irq_save(flags);
2951c6a0718SPierre Ossman 
2961c6a0718SPierre Ossman 	while (blksize) {
2977659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
2987659150cSPierre Ossman 			BUG();
2991c6a0718SPierre Ossman 
3007659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
3011c6a0718SPierre Ossman 
3027659150cSPierre Ossman 		blksize -= len;
3037659150cSPierre Ossman 		host->sg_miter.consumed = len;
3047659150cSPierre Ossman 
3057659150cSPierre Ossman 		buf = host->sg_miter.addr;
3067659150cSPierre Ossman 
3077659150cSPierre Ossman 		while (len) {
3087659150cSPierre Ossman 			scratch |= (u32)*buf << (chunk * 8);
3097659150cSPierre Ossman 
3107659150cSPierre Ossman 			buf++;
3117659150cSPierre Ossman 			chunk++;
3127659150cSPierre Ossman 			len--;
3137659150cSPierre Ossman 
3147659150cSPierre Ossman 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
3154e4141a5SAnton Vorontsov 				sdhci_writel(host, scratch, SDHCI_BUFFER);
3167659150cSPierre Ossman 				chunk = 0;
3177659150cSPierre Ossman 				scratch = 0;
3187659150cSPierre Ossman 			}
3197659150cSPierre Ossman 		}
3201c6a0718SPierre Ossman 	}
3211c6a0718SPierre Ossman 
3227659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
3231c6a0718SPierre Ossman 
3247659150cSPierre Ossman 	local_irq_restore(flags);
3251c6a0718SPierre Ossman }
3261c6a0718SPierre Ossman 
3271c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host)
3281c6a0718SPierre Ossman {
3291c6a0718SPierre Ossman 	u32 mask;
3301c6a0718SPierre Ossman 
3311c6a0718SPierre Ossman 	BUG_ON(!host->data);
3321c6a0718SPierre Ossman 
3337659150cSPierre Ossman 	if (host->blocks == 0)
3341c6a0718SPierre Ossman 		return;
3351c6a0718SPierre Ossman 
3361c6a0718SPierre Ossman 	if (host->data->flags & MMC_DATA_READ)
3371c6a0718SPierre Ossman 		mask = SDHCI_DATA_AVAILABLE;
3381c6a0718SPierre Ossman 	else
3391c6a0718SPierre Ossman 		mask = SDHCI_SPACE_AVAILABLE;
3401c6a0718SPierre Ossman 
3414a3cba32SPierre Ossman 	/*
3424a3cba32SPierre Ossman 	 * Some controllers (JMicron JMB38x) mess up the buffer bits
3434a3cba32SPierre Ossman 	 * for transfers < 4 bytes. As long as it is just one block,
3444a3cba32SPierre Ossman 	 * we can ignore the bits.
3454a3cba32SPierre Ossman 	 */
3464a3cba32SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
3474a3cba32SPierre Ossman 		(host->data->blocks == 1))
3484a3cba32SPierre Ossman 		mask = ~0;
3494a3cba32SPierre Ossman 
3504e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
3513e3bf207SAnton Vorontsov 		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
3523e3bf207SAnton Vorontsov 			udelay(100);
3533e3bf207SAnton Vorontsov 
3541c6a0718SPierre Ossman 		if (host->data->flags & MMC_DATA_READ)
3551c6a0718SPierre Ossman 			sdhci_read_block_pio(host);
3561c6a0718SPierre Ossman 		else
3571c6a0718SPierre Ossman 			sdhci_write_block_pio(host);
3581c6a0718SPierre Ossman 
3597659150cSPierre Ossman 		host->blocks--;
3607659150cSPierre Ossman 		if (host->blocks == 0)
3611c6a0718SPierre Ossman 			break;
3621c6a0718SPierre Ossman 	}
3631c6a0718SPierre Ossman 
3641c6a0718SPierre Ossman 	DBG("PIO transfer complete.\n");
3651c6a0718SPierre Ossman }
3661c6a0718SPierre Ossman 
3672134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
3682134a922SPierre Ossman {
3692134a922SPierre Ossman 	local_irq_save(*flags);
3702134a922SPierre Ossman 	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
3712134a922SPierre Ossman }
3722134a922SPierre Ossman 
3732134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
3742134a922SPierre Ossman {
3752134a922SPierre Ossman 	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
3762134a922SPierre Ossman 	local_irq_restore(*flags);
3772134a922SPierre Ossman }
3782134a922SPierre Ossman 
3798f1934ceSPierre Ossman static int sdhci_adma_table_pre(struct sdhci_host *host,
3802134a922SPierre Ossman 	struct mmc_data *data)
3812134a922SPierre Ossman {
3822134a922SPierre Ossman 	int direction;
3832134a922SPierre Ossman 
3842134a922SPierre Ossman 	u8 *desc;
3852134a922SPierre Ossman 	u8 *align;
3862134a922SPierre Ossman 	dma_addr_t addr;
3872134a922SPierre Ossman 	dma_addr_t align_addr;
3882134a922SPierre Ossman 	int len, offset;
3892134a922SPierre Ossman 
3902134a922SPierre Ossman 	struct scatterlist *sg;
3912134a922SPierre Ossman 	int i;
3922134a922SPierre Ossman 	char *buffer;
3932134a922SPierre Ossman 	unsigned long flags;
3942134a922SPierre Ossman 
3952134a922SPierre Ossman 	/*
3962134a922SPierre Ossman 	 * The spec does not specify endianness of descriptor table.
3972134a922SPierre Ossman 	 * We currently guess that it is LE.
3982134a922SPierre Ossman 	 */
3992134a922SPierre Ossman 
4002134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
4012134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
4022134a922SPierre Ossman 	else
4032134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
4042134a922SPierre Ossman 
4052134a922SPierre Ossman 	/*
4062134a922SPierre Ossman 	 * The ADMA descriptor table is mapped further down as we
4072134a922SPierre Ossman 	 * need to fill it with data first.
4082134a922SPierre Ossman 	 */
4092134a922SPierre Ossman 
4102134a922SPierre Ossman 	host->align_addr = dma_map_single(mmc_dev(host->mmc),
4112134a922SPierre Ossman 		host->align_buffer, 128 * 4, direction);
4128d8bb39bSFUJITA Tomonori 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
4138f1934ceSPierre Ossman 		goto fail;
4142134a922SPierre Ossman 	BUG_ON(host->align_addr & 0x3);
4152134a922SPierre Ossman 
4162134a922SPierre Ossman 	host->sg_count = dma_map_sg(mmc_dev(host->mmc),
4172134a922SPierre Ossman 		data->sg, data->sg_len, direction);
4188f1934ceSPierre Ossman 	if (host->sg_count == 0)
4198f1934ceSPierre Ossman 		goto unmap_align;
4202134a922SPierre Ossman 
4212134a922SPierre Ossman 	desc = host->adma_desc;
4222134a922SPierre Ossman 	align = host->align_buffer;
4232134a922SPierre Ossman 
4242134a922SPierre Ossman 	align_addr = host->align_addr;
4252134a922SPierre Ossman 
4262134a922SPierre Ossman 	for_each_sg(data->sg, sg, host->sg_count, i) {
4272134a922SPierre Ossman 		addr = sg_dma_address(sg);
4282134a922SPierre Ossman 		len = sg_dma_len(sg);
4292134a922SPierre Ossman 
4302134a922SPierre Ossman 		/*
4312134a922SPierre Ossman 		 * The SDHCI specification states that ADMA
4322134a922SPierre Ossman 		 * addresses must be 32-bit aligned. If they
4332134a922SPierre Ossman 		 * aren't, then we use a bounce buffer for
4342134a922SPierre Ossman 		 * the (up to three) bytes that screw up the
4352134a922SPierre Ossman 		 * alignment.
4362134a922SPierre Ossman 		 */
4372134a922SPierre Ossman 		offset = (4 - (addr & 0x3)) & 0x3;
4382134a922SPierre Ossman 		if (offset) {
4392134a922SPierre Ossman 			if (data->flags & MMC_DATA_WRITE) {
4402134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
4416cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
4422134a922SPierre Ossman 				memcpy(align, buffer, offset);
4432134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
4442134a922SPierre Ossman 			}
4452134a922SPierre Ossman 
4462134a922SPierre Ossman 			desc[7] = (align_addr >> 24) & 0xff;
4472134a922SPierre Ossman 			desc[6] = (align_addr >> 16) & 0xff;
4482134a922SPierre Ossman 			desc[5] = (align_addr >> 8) & 0xff;
4492134a922SPierre Ossman 			desc[4] = (align_addr >> 0) & 0xff;
4502134a922SPierre Ossman 
4512134a922SPierre Ossman 			BUG_ON(offset > 65536);
4522134a922SPierre Ossman 
4532134a922SPierre Ossman 			desc[3] = (offset >> 8) & 0xff;
4542134a922SPierre Ossman 			desc[2] = (offset >> 0) & 0xff;
4552134a922SPierre Ossman 
4562134a922SPierre Ossman 			desc[1] = 0x00;
4572134a922SPierre Ossman 			desc[0] = 0x21; /* tran, valid */
4582134a922SPierre Ossman 
4592134a922SPierre Ossman 			align += 4;
4602134a922SPierre Ossman 			align_addr += 4;
4612134a922SPierre Ossman 
4622134a922SPierre Ossman 			desc += 8;
4632134a922SPierre Ossman 
4642134a922SPierre Ossman 			addr += offset;
4652134a922SPierre Ossman 			len -= offset;
4662134a922SPierre Ossman 		}
4672134a922SPierre Ossman 
4682134a922SPierre Ossman 		desc[7] = (addr >> 24) & 0xff;
4692134a922SPierre Ossman 		desc[6] = (addr >> 16) & 0xff;
4702134a922SPierre Ossman 		desc[5] = (addr >> 8) & 0xff;
4712134a922SPierre Ossman 		desc[4] = (addr >> 0) & 0xff;
4722134a922SPierre Ossman 
4732134a922SPierre Ossman 		BUG_ON(len > 65536);
4742134a922SPierre Ossman 
4752134a922SPierre Ossman 		desc[3] = (len >> 8) & 0xff;
4762134a922SPierre Ossman 		desc[2] = (len >> 0) & 0xff;
4772134a922SPierre Ossman 
4782134a922SPierre Ossman 		desc[1] = 0x00;
4792134a922SPierre Ossman 		desc[0] = 0x21; /* tran, valid */
4802134a922SPierre Ossman 
4812134a922SPierre Ossman 		desc += 8;
4822134a922SPierre Ossman 
4832134a922SPierre Ossman 		/*
4842134a922SPierre Ossman 		 * If this triggers then we have a calculation bug
4852134a922SPierre Ossman 		 * somewhere. :/
4862134a922SPierre Ossman 		 */
4872134a922SPierre Ossman 		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
4882134a922SPierre Ossman 	}
4892134a922SPierre Ossman 
4902134a922SPierre Ossman 	/*
4912134a922SPierre Ossman 	 * Add a terminating entry.
4922134a922SPierre Ossman 	 */
4932134a922SPierre Ossman 	desc[7] = 0;
4942134a922SPierre Ossman 	desc[6] = 0;
4952134a922SPierre Ossman 	desc[5] = 0;
4962134a922SPierre Ossman 	desc[4] = 0;
4972134a922SPierre Ossman 
4982134a922SPierre Ossman 	desc[3] = 0;
4992134a922SPierre Ossman 	desc[2] = 0;
5002134a922SPierre Ossman 
5012134a922SPierre Ossman 	desc[1] = 0x00;
5022134a922SPierre Ossman 	desc[0] = 0x03; /* nop, end, valid */
5032134a922SPierre Ossman 
5042134a922SPierre Ossman 	/*
5052134a922SPierre Ossman 	 * Resync align buffer as we might have changed it.
5062134a922SPierre Ossman 	 */
5072134a922SPierre Ossman 	if (data->flags & MMC_DATA_WRITE) {
5082134a922SPierre Ossman 		dma_sync_single_for_device(mmc_dev(host->mmc),
5092134a922SPierre Ossman 			host->align_addr, 128 * 4, direction);
5102134a922SPierre Ossman 	}
5112134a922SPierre Ossman 
5122134a922SPierre Ossman 	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
5132134a922SPierre Ossman 		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
514980167b7SPierre Ossman 	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
5158f1934ceSPierre Ossman 		goto unmap_entries;
5162134a922SPierre Ossman 	BUG_ON(host->adma_addr & 0x3);
5178f1934ceSPierre Ossman 
5188f1934ceSPierre Ossman 	return 0;
5198f1934ceSPierre Ossman 
5208f1934ceSPierre Ossman unmap_entries:
5218f1934ceSPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5228f1934ceSPierre Ossman 		data->sg_len, direction);
5238f1934ceSPierre Ossman unmap_align:
5248f1934ceSPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5258f1934ceSPierre Ossman 		128 * 4, direction);
5268f1934ceSPierre Ossman fail:
5278f1934ceSPierre Ossman 	return -EINVAL;
5282134a922SPierre Ossman }
5292134a922SPierre Ossman 
5302134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host,
5312134a922SPierre Ossman 	struct mmc_data *data)
5322134a922SPierre Ossman {
5332134a922SPierre Ossman 	int direction;
5342134a922SPierre Ossman 
5352134a922SPierre Ossman 	struct scatterlist *sg;
5362134a922SPierre Ossman 	int i, size;
5372134a922SPierre Ossman 	u8 *align;
5382134a922SPierre Ossman 	char *buffer;
5392134a922SPierre Ossman 	unsigned long flags;
5402134a922SPierre Ossman 
5412134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
5422134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
5432134a922SPierre Ossman 	else
5442134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
5452134a922SPierre Ossman 
5462134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
5472134a922SPierre Ossman 		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
5482134a922SPierre Ossman 
5492134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
5502134a922SPierre Ossman 		128 * 4, direction);
5512134a922SPierre Ossman 
5522134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ) {
5532134a922SPierre Ossman 		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
5542134a922SPierre Ossman 			data->sg_len, direction);
5552134a922SPierre Ossman 
5562134a922SPierre Ossman 		align = host->align_buffer;
5572134a922SPierre Ossman 
5582134a922SPierre Ossman 		for_each_sg(data->sg, sg, host->sg_count, i) {
5592134a922SPierre Ossman 			if (sg_dma_address(sg) & 0x3) {
5602134a922SPierre Ossman 				size = 4 - (sg_dma_address(sg) & 0x3);
5612134a922SPierre Ossman 
5622134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
5636cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
5642134a922SPierre Ossman 				memcpy(buffer, align, size);
5652134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
5662134a922SPierre Ossman 
5672134a922SPierre Ossman 				align += 4;
5682134a922SPierre Ossman 			}
5692134a922SPierre Ossman 		}
5702134a922SPierre Ossman 	}
5712134a922SPierre Ossman 
5722134a922SPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5732134a922SPierre Ossman 		data->sg_len, direction);
5742134a922SPierre Ossman }
5752134a922SPierre Ossman 
576ee53ab5dSPierre Ossman static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
5771c6a0718SPierre Ossman {
5781c6a0718SPierre Ossman 	u8 count;
5791c6a0718SPierre Ossman 	unsigned target_timeout, current_timeout;
5801c6a0718SPierre Ossman 
581ee53ab5dSPierre Ossman 	/*
582ee53ab5dSPierre Ossman 	 * If the host controller provides us with an incorrect timeout
583ee53ab5dSPierre Ossman 	 * value, just skip the check and use 0xE.  The hardware may take
584ee53ab5dSPierre Ossman 	 * longer to time out, but that's much better than having a too-short
585ee53ab5dSPierre Ossman 	 * timeout value.
586ee53ab5dSPierre Ossman 	 */
587ee53ab5dSPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL))
588ee53ab5dSPierre Ossman 		return 0xE;
589e538fbe8SPierre Ossman 
5901c6a0718SPierre Ossman 	/* timeout in us */
5911c6a0718SPierre Ossman 	target_timeout = data->timeout_ns / 1000 +
5921c6a0718SPierre Ossman 		data->timeout_clks / host->clock;
5931c6a0718SPierre Ossman 
5941c6a0718SPierre Ossman 	/*
5951c6a0718SPierre Ossman 	 * Figure out needed cycles.
5961c6a0718SPierre Ossman 	 * We do this in steps in order to fit inside a 32 bit int.
5971c6a0718SPierre Ossman 	 * The first step is the minimum timeout, which will have a
5981c6a0718SPierre Ossman 	 * minimum resolution of 6 bits:
5991c6a0718SPierre Ossman 	 * (1) 2^13*1000 > 2^22,
6001c6a0718SPierre Ossman 	 * (2) host->timeout_clk < 2^16
6011c6a0718SPierre Ossman 	 *     =>
6021c6a0718SPierre Ossman 	 *     (1) / (2) > 2^6
6031c6a0718SPierre Ossman 	 */
6041c6a0718SPierre Ossman 	count = 0;
6051c6a0718SPierre Ossman 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
6061c6a0718SPierre Ossman 	while (current_timeout < target_timeout) {
6071c6a0718SPierre Ossman 		count++;
6081c6a0718SPierre Ossman 		current_timeout <<= 1;
6091c6a0718SPierre Ossman 		if (count >= 0xF)
6101c6a0718SPierre Ossman 			break;
6111c6a0718SPierre Ossman 	}
6121c6a0718SPierre Ossman 
6131c6a0718SPierre Ossman 	if (count >= 0xF) {
6141c6a0718SPierre Ossman 		printk(KERN_WARNING "%s: Too large timeout requested!\n",
6151c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
6161c6a0718SPierre Ossman 		count = 0xE;
6171c6a0718SPierre Ossman 	}
6181c6a0718SPierre Ossman 
619ee53ab5dSPierre Ossman 	return count;
620ee53ab5dSPierre Ossman }
621ee53ab5dSPierre Ossman 
6226aa943abSAnton Vorontsov static void sdhci_set_transfer_irqs(struct sdhci_host *host)
6236aa943abSAnton Vorontsov {
6246aa943abSAnton Vorontsov 	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
6256aa943abSAnton Vorontsov 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
6266aa943abSAnton Vorontsov 
6276aa943abSAnton Vorontsov 	if (host->flags & SDHCI_REQ_USE_DMA)
6286aa943abSAnton Vorontsov 		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
6296aa943abSAnton Vorontsov 	else
6306aa943abSAnton Vorontsov 		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
6316aa943abSAnton Vorontsov }
6326aa943abSAnton Vorontsov 
633ee53ab5dSPierre Ossman static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
634ee53ab5dSPierre Ossman {
635ee53ab5dSPierre Ossman 	u8 count;
6362134a922SPierre Ossman 	u8 ctrl;
6378f1934ceSPierre Ossman 	int ret;
638ee53ab5dSPierre Ossman 
639ee53ab5dSPierre Ossman 	WARN_ON(host->data);
640ee53ab5dSPierre Ossman 
641ee53ab5dSPierre Ossman 	if (data == NULL)
642ee53ab5dSPierre Ossman 		return;
643ee53ab5dSPierre Ossman 
644ee53ab5dSPierre Ossman 	/* Sanity checks */
645ee53ab5dSPierre Ossman 	BUG_ON(data->blksz * data->blocks > 524288);
646ee53ab5dSPierre Ossman 	BUG_ON(data->blksz > host->mmc->max_blk_size);
647ee53ab5dSPierre Ossman 	BUG_ON(data->blocks > 65535);
648ee53ab5dSPierre Ossman 
649ee53ab5dSPierre Ossman 	host->data = data;
650ee53ab5dSPierre Ossman 	host->data_early = 0;
651ee53ab5dSPierre Ossman 
652ee53ab5dSPierre Ossman 	count = sdhci_calc_timeout(host, data);
6534e4141a5SAnton Vorontsov 	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
6541c6a0718SPierre Ossman 
655c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_USE_DMA)
656c9fddbc4SPierre Ossman 		host->flags |= SDHCI_REQ_USE_DMA;
657c9fddbc4SPierre Ossman 
6582134a922SPierre Ossman 	/*
6592134a922SPierre Ossman 	 * FIXME: This doesn't account for merging when mapping the
6602134a922SPierre Ossman 	 * scatterlist.
6612134a922SPierre Ossman 	 */
6622134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
6632134a922SPierre Ossman 		int broken, i;
6642134a922SPierre Ossman 		struct scatterlist *sg;
6652134a922SPierre Ossman 
6662134a922SPierre Ossman 		broken = 0;
6672134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
6682134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
6692134a922SPierre Ossman 				broken = 1;
6702134a922SPierre Ossman 		} else {
6712134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
6722134a922SPierre Ossman 				broken = 1;
6732134a922SPierre Ossman 		}
6742134a922SPierre Ossman 
6752134a922SPierre Ossman 		if (unlikely(broken)) {
6762134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
6772134a922SPierre Ossman 				if (sg->length & 0x3) {
6782134a922SPierre Ossman 					DBG("Reverting to PIO because of "
6792134a922SPierre Ossman 						"transfer size (%d)\n",
6802134a922SPierre Ossman 						sg->length);
681c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
6822134a922SPierre Ossman 					break;
6832134a922SPierre Ossman 				}
6842134a922SPierre Ossman 			}
6852134a922SPierre Ossman 		}
686c9fddbc4SPierre Ossman 	}
687c9fddbc4SPierre Ossman 
688c9fddbc4SPierre Ossman 	/*
689c9fddbc4SPierre Ossman 	 * The assumption here being that alignment is the same after
690c9fddbc4SPierre Ossman 	 * translation to device address space.
691c9fddbc4SPierre Ossman 	 */
6922134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
6932134a922SPierre Ossman 		int broken, i;
6942134a922SPierre Ossman 		struct scatterlist *sg;
6952134a922SPierre Ossman 
6962134a922SPierre Ossman 		broken = 0;
6972134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
6982134a922SPierre Ossman 			/*
6992134a922SPierre Ossman 			 * As we use 3 byte chunks to work around
7002134a922SPierre Ossman 			 * alignment problems, we need to check this
7012134a922SPierre Ossman 			 * quirk.
7022134a922SPierre Ossman 			 */
7032134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
7042134a922SPierre Ossman 				broken = 1;
7052134a922SPierre Ossman 		} else {
7062134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
7072134a922SPierre Ossman 				broken = 1;
7082134a922SPierre Ossman 		}
7092134a922SPierre Ossman 
7102134a922SPierre Ossman 		if (unlikely(broken)) {
7112134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
7122134a922SPierre Ossman 				if (sg->offset & 0x3) {
7132134a922SPierre Ossman 					DBG("Reverting to PIO because of "
7142134a922SPierre Ossman 						"bad alignment\n");
715c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
7162134a922SPierre Ossman 					break;
7172134a922SPierre Ossman 				}
7182134a922SPierre Ossman 			}
7192134a922SPierre Ossman 		}
7202134a922SPierre Ossman 	}
7212134a922SPierre Ossman 
7228f1934ceSPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
7238f1934ceSPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
7248f1934ceSPierre Ossman 			ret = sdhci_adma_table_pre(host, data);
7258f1934ceSPierre Ossman 			if (ret) {
7268f1934ceSPierre Ossman 				/*
7278f1934ceSPierre Ossman 				 * This only happens when someone fed
7288f1934ceSPierre Ossman 				 * us an invalid request.
7298f1934ceSPierre Ossman 				 */
7308f1934ceSPierre Ossman 				WARN_ON(1);
731ebd6d357SPierre Ossman 				host->flags &= ~SDHCI_REQ_USE_DMA;
7328f1934ceSPierre Ossman 			} else {
7334e4141a5SAnton Vorontsov 				sdhci_writel(host, host->adma_addr,
7344e4141a5SAnton Vorontsov 					SDHCI_ADMA_ADDRESS);
7358f1934ceSPierre Ossman 			}
7368f1934ceSPierre Ossman 		} else {
737c8b3e02eSTomas Winkler 			int sg_cnt;
7388f1934ceSPierre Ossman 
739c8b3e02eSTomas Winkler 			sg_cnt = dma_map_sg(mmc_dev(host->mmc),
7408f1934ceSPierre Ossman 					data->sg, data->sg_len,
7418f1934ceSPierre Ossman 					(data->flags & MMC_DATA_READ) ?
7428f1934ceSPierre Ossman 						DMA_FROM_DEVICE :
7438f1934ceSPierre Ossman 						DMA_TO_DEVICE);
744c8b3e02eSTomas Winkler 			if (sg_cnt == 0) {
7458f1934ceSPierre Ossman 				/*
7468f1934ceSPierre Ossman 				 * This only happens when someone fed
7478f1934ceSPierre Ossman 				 * us an invalid request.
7488f1934ceSPierre Ossman 				 */
7498f1934ceSPierre Ossman 				WARN_ON(1);
750ebd6d357SPierre Ossman 				host->flags &= ~SDHCI_REQ_USE_DMA;
7518f1934ceSPierre Ossman 			} else {
752719a61b4SPierre Ossman 				WARN_ON(sg_cnt != 1);
7534e4141a5SAnton Vorontsov 				sdhci_writel(host, sg_dma_address(data->sg),
7544e4141a5SAnton Vorontsov 					SDHCI_DMA_ADDRESS);
7558f1934ceSPierre Ossman 			}
7568f1934ceSPierre Ossman 		}
7578f1934ceSPierre Ossman 	}
7588f1934ceSPierre Ossman 
7592134a922SPierre Ossman 	/*
7602134a922SPierre Ossman 	 * Always adjust the DMA selection as some controllers
7612134a922SPierre Ossman 	 * (e.g. JMicron) can't do PIO properly when the selection
7622134a922SPierre Ossman 	 * is ADMA.
7632134a922SPierre Ossman 	 */
7642134a922SPierre Ossman 	if (host->version >= SDHCI_SPEC_200) {
7654e4141a5SAnton Vorontsov 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
7662134a922SPierre Ossman 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
7672134a922SPierre Ossman 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
7682134a922SPierre Ossman 			(host->flags & SDHCI_USE_ADMA))
7692134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_ADMA32;
7702134a922SPierre Ossman 		else
7712134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_SDMA;
7724e4141a5SAnton Vorontsov 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
773c9fddbc4SPierre Ossman 	}
774c9fddbc4SPierre Ossman 
7758f1934ceSPierre Ossman 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
7767659150cSPierre Ossman 		sg_miter_start(&host->sg_miter,
7777659150cSPierre Ossman 			data->sg, data->sg_len, SG_MITER_ATOMIC);
7787659150cSPierre Ossman 		host->blocks = data->blocks;
7791c6a0718SPierre Ossman 	}
7801c6a0718SPierre Ossman 
7816aa943abSAnton Vorontsov 	sdhci_set_transfer_irqs(host);
7826aa943abSAnton Vorontsov 
7831c6a0718SPierre Ossman 	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
7844e4141a5SAnton Vorontsov 	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
7854e4141a5SAnton Vorontsov 	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
7861c6a0718SPierre Ossman }
7871c6a0718SPierre Ossman 
7881c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host,
7891c6a0718SPierre Ossman 	struct mmc_data *data)
7901c6a0718SPierre Ossman {
7911c6a0718SPierre Ossman 	u16 mode;
7921c6a0718SPierre Ossman 
7931c6a0718SPierre Ossman 	if (data == NULL)
7941c6a0718SPierre Ossman 		return;
7951c6a0718SPierre Ossman 
796e538fbe8SPierre Ossman 	WARN_ON(!host->data);
797e538fbe8SPierre Ossman 
7981c6a0718SPierre Ossman 	mode = SDHCI_TRNS_BLK_CNT_EN;
7991c6a0718SPierre Ossman 	if (data->blocks > 1)
8001c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_MULTI;
8011c6a0718SPierre Ossman 	if (data->flags & MMC_DATA_READ)
8021c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_READ;
803c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA)
8041c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_DMA;
8051c6a0718SPierre Ossman 
8064e4141a5SAnton Vorontsov 	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
8071c6a0718SPierre Ossman }
8081c6a0718SPierre Ossman 
8091c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host)
8101c6a0718SPierre Ossman {
8111c6a0718SPierre Ossman 	struct mmc_data *data;
8121c6a0718SPierre Ossman 
8131c6a0718SPierre Ossman 	BUG_ON(!host->data);
8141c6a0718SPierre Ossman 
8151c6a0718SPierre Ossman 	data = host->data;
8161c6a0718SPierre Ossman 	host->data = NULL;
8171c6a0718SPierre Ossman 
818c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
8192134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA)
8202134a922SPierre Ossman 			sdhci_adma_table_post(host, data);
8212134a922SPierre Ossman 		else {
8222134a922SPierre Ossman 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
8232134a922SPierre Ossman 				data->sg_len, (data->flags & MMC_DATA_READ) ?
824b8c86fc5SPierre Ossman 					DMA_FROM_DEVICE : DMA_TO_DEVICE);
8251c6a0718SPierre Ossman 		}
8262134a922SPierre Ossman 	}
8271c6a0718SPierre Ossman 
8281c6a0718SPierre Ossman 	/*
829c9b74c5bSPierre Ossman 	 * The specification states that the block count register must
830c9b74c5bSPierre Ossman 	 * be updated, but it does not specify at what point in the
831c9b74c5bSPierre Ossman 	 * data flow. That makes the register entirely useless to read
832c9b74c5bSPierre Ossman 	 * back so we have to assume that nothing made it to the card
833c9b74c5bSPierre Ossman 	 * in the event of an error.
8341c6a0718SPierre Ossman 	 */
835c9b74c5bSPierre Ossman 	if (data->error)
836c9b74c5bSPierre Ossman 		data->bytes_xfered = 0;
8371c6a0718SPierre Ossman 	else
838c9b74c5bSPierre Ossman 		data->bytes_xfered = data->blksz * data->blocks;
8391c6a0718SPierre Ossman 
8401c6a0718SPierre Ossman 	if (data->stop) {
8411c6a0718SPierre Ossman 		/*
8421c6a0718SPierre Ossman 		 * The controller needs a reset of internal state machines
8431c6a0718SPierre Ossman 		 * upon error conditions.
8441c6a0718SPierre Ossman 		 */
84517b0429dSPierre Ossman 		if (data->error) {
8461c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
8471c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
8481c6a0718SPierre Ossman 		}
8491c6a0718SPierre Ossman 
8501c6a0718SPierre Ossman 		sdhci_send_command(host, data->stop);
8511c6a0718SPierre Ossman 	} else
8521c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
8531c6a0718SPierre Ossman }
8541c6a0718SPierre Ossman 
8551c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
8561c6a0718SPierre Ossman {
8571c6a0718SPierre Ossman 	int flags;
8581c6a0718SPierre Ossman 	u32 mask;
8591c6a0718SPierre Ossman 	unsigned long timeout;
8601c6a0718SPierre Ossman 
8611c6a0718SPierre Ossman 	WARN_ON(host->cmd);
8621c6a0718SPierre Ossman 
8631c6a0718SPierre Ossman 	/* Wait max 10 ms */
8641c6a0718SPierre Ossman 	timeout = 10;
8651c6a0718SPierre Ossman 
8661c6a0718SPierre Ossman 	mask = SDHCI_CMD_INHIBIT;
8671c6a0718SPierre Ossman 	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
8681c6a0718SPierre Ossman 		mask |= SDHCI_DATA_INHIBIT;
8691c6a0718SPierre Ossman 
8701c6a0718SPierre Ossman 	/* We shouldn't wait for data inihibit for stop commands, even
8711c6a0718SPierre Ossman 	   though they might use busy signaling */
8721c6a0718SPierre Ossman 	if (host->mrq->data && (cmd == host->mrq->data->stop))
8731c6a0718SPierre Ossman 		mask &= ~SDHCI_DATA_INHIBIT;
8741c6a0718SPierre Ossman 
8754e4141a5SAnton Vorontsov 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
8761c6a0718SPierre Ossman 		if (timeout == 0) {
8771c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Controller never released "
8781c6a0718SPierre Ossman 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
8791c6a0718SPierre Ossman 			sdhci_dumpregs(host);
88017b0429dSPierre Ossman 			cmd->error = -EIO;
8811c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
8821c6a0718SPierre Ossman 			return;
8831c6a0718SPierre Ossman 		}
8841c6a0718SPierre Ossman 		timeout--;
8851c6a0718SPierre Ossman 		mdelay(1);
8861c6a0718SPierre Ossman 	}
8871c6a0718SPierre Ossman 
8881c6a0718SPierre Ossman 	mod_timer(&host->timer, jiffies + 10 * HZ);
8891c6a0718SPierre Ossman 
8901c6a0718SPierre Ossman 	host->cmd = cmd;
8911c6a0718SPierre Ossman 
8921c6a0718SPierre Ossman 	sdhci_prepare_data(host, cmd->data);
8931c6a0718SPierre Ossman 
8944e4141a5SAnton Vorontsov 	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
8951c6a0718SPierre Ossman 
8961c6a0718SPierre Ossman 	sdhci_set_transfer_mode(host, cmd->data);
8971c6a0718SPierre Ossman 
8981c6a0718SPierre Ossman 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
8991c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unsupported response type!\n",
9001c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
90117b0429dSPierre Ossman 		cmd->error = -EINVAL;
9021c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
9031c6a0718SPierre Ossman 		return;
9041c6a0718SPierre Ossman 	}
9051c6a0718SPierre Ossman 
9061c6a0718SPierre Ossman 	if (!(cmd->flags & MMC_RSP_PRESENT))
9071c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_NONE;
9081c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_136)
9091c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_LONG;
9101c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_BUSY)
9111c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT_BUSY;
9121c6a0718SPierre Ossman 	else
9131c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT;
9141c6a0718SPierre Ossman 
9151c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_CRC)
9161c6a0718SPierre Ossman 		flags |= SDHCI_CMD_CRC;
9171c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_OPCODE)
9181c6a0718SPierre Ossman 		flags |= SDHCI_CMD_INDEX;
9191c6a0718SPierre Ossman 	if (cmd->data)
9201c6a0718SPierre Ossman 		flags |= SDHCI_CMD_DATA;
9211c6a0718SPierre Ossman 
9224e4141a5SAnton Vorontsov 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
9231c6a0718SPierre Ossman }
9241c6a0718SPierre Ossman 
9251c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host)
9261c6a0718SPierre Ossman {
9271c6a0718SPierre Ossman 	int i;
9281c6a0718SPierre Ossman 
9291c6a0718SPierre Ossman 	BUG_ON(host->cmd == NULL);
9301c6a0718SPierre Ossman 
9311c6a0718SPierre Ossman 	if (host->cmd->flags & MMC_RSP_PRESENT) {
9321c6a0718SPierre Ossman 		if (host->cmd->flags & MMC_RSP_136) {
9331c6a0718SPierre Ossman 			/* CRC is stripped so we need to do some shifting. */
9341c6a0718SPierre Ossman 			for (i = 0;i < 4;i++) {
9354e4141a5SAnton Vorontsov 				host->cmd->resp[i] = sdhci_readl(host,
9361c6a0718SPierre Ossman 					SDHCI_RESPONSE + (3-i)*4) << 8;
9371c6a0718SPierre Ossman 				if (i != 3)
9381c6a0718SPierre Ossman 					host->cmd->resp[i] |=
9394e4141a5SAnton Vorontsov 						sdhci_readb(host,
9401c6a0718SPierre Ossman 						SDHCI_RESPONSE + (3-i)*4-1);
9411c6a0718SPierre Ossman 			}
9421c6a0718SPierre Ossman 		} else {
9434e4141a5SAnton Vorontsov 			host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
9441c6a0718SPierre Ossman 		}
9451c6a0718SPierre Ossman 	}
9461c6a0718SPierre Ossman 
94717b0429dSPierre Ossman 	host->cmd->error = 0;
9481c6a0718SPierre Ossman 
949e538fbe8SPierre Ossman 	if (host->data && host->data_early)
950e538fbe8SPierre Ossman 		sdhci_finish_data(host);
951e538fbe8SPierre Ossman 
952e538fbe8SPierre Ossman 	if (!host->cmd->data)
9531c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
9541c6a0718SPierre Ossman 
9551c6a0718SPierre Ossman 	host->cmd = NULL;
9561c6a0718SPierre Ossman }
9571c6a0718SPierre Ossman 
9581c6a0718SPierre Ossman static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
9591c6a0718SPierre Ossman {
9601c6a0718SPierre Ossman 	int div;
9611c6a0718SPierre Ossman 	u16 clk;
9621c6a0718SPierre Ossman 	unsigned long timeout;
9631c6a0718SPierre Ossman 
9641c6a0718SPierre Ossman 	if (clock == host->clock)
9651c6a0718SPierre Ossman 		return;
9661c6a0718SPierre Ossman 
9678114634cSAnton Vorontsov 	if (host->ops->set_clock) {
9688114634cSAnton Vorontsov 		host->ops->set_clock(host, clock);
9698114634cSAnton Vorontsov 		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
9708114634cSAnton Vorontsov 			return;
9718114634cSAnton Vorontsov 	}
9728114634cSAnton Vorontsov 
9734e4141a5SAnton Vorontsov 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
9741c6a0718SPierre Ossman 
9751c6a0718SPierre Ossman 	if (clock == 0)
9761c6a0718SPierre Ossman 		goto out;
9771c6a0718SPierre Ossman 
9781c6a0718SPierre Ossman 	for (div = 1;div < 256;div *= 2) {
9791c6a0718SPierre Ossman 		if ((host->max_clk / div) <= clock)
9801c6a0718SPierre Ossman 			break;
9811c6a0718SPierre Ossman 	}
9821c6a0718SPierre Ossman 	div >>= 1;
9831c6a0718SPierre Ossman 
9841c6a0718SPierre Ossman 	clk = div << SDHCI_DIVIDER_SHIFT;
9851c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_INT_EN;
9864e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
9871c6a0718SPierre Ossman 
9881c6a0718SPierre Ossman 	/* Wait max 10 ms */
9891c6a0718SPierre Ossman 	timeout = 10;
9904e4141a5SAnton Vorontsov 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
9911c6a0718SPierre Ossman 		& SDHCI_CLOCK_INT_STABLE)) {
9921c6a0718SPierre Ossman 		if (timeout == 0) {
9931c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Internal clock never "
9941c6a0718SPierre Ossman 				"stabilised.\n", mmc_hostname(host->mmc));
9951c6a0718SPierre Ossman 			sdhci_dumpregs(host);
9961c6a0718SPierre Ossman 			return;
9971c6a0718SPierre Ossman 		}
9981c6a0718SPierre Ossman 		timeout--;
9991c6a0718SPierre Ossman 		mdelay(1);
10001c6a0718SPierre Ossman 	}
10011c6a0718SPierre Ossman 
10021c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_CARD_EN;
10034e4141a5SAnton Vorontsov 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
10041c6a0718SPierre Ossman 
10051c6a0718SPierre Ossman out:
10061c6a0718SPierre Ossman 	host->clock = clock;
10071c6a0718SPierre Ossman }
10081c6a0718SPierre Ossman 
10091c6a0718SPierre Ossman static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
10101c6a0718SPierre Ossman {
10111c6a0718SPierre Ossman 	u8 pwr;
10121c6a0718SPierre Ossman 
1013ae628903SPierre Ossman 	if (power == (unsigned short)-1)
1014ae628903SPierre Ossman 		pwr = 0;
1015ae628903SPierre Ossman 	else {
1016ae628903SPierre Ossman 		switch (1 << power) {
1017ae628903SPierre Ossman 		case MMC_VDD_165_195:
1018ae628903SPierre Ossman 			pwr = SDHCI_POWER_180;
1019ae628903SPierre Ossman 			break;
1020ae628903SPierre Ossman 		case MMC_VDD_29_30:
1021ae628903SPierre Ossman 		case MMC_VDD_30_31:
1022ae628903SPierre Ossman 			pwr = SDHCI_POWER_300;
1023ae628903SPierre Ossman 			break;
1024ae628903SPierre Ossman 		case MMC_VDD_32_33:
1025ae628903SPierre Ossman 		case MMC_VDD_33_34:
1026ae628903SPierre Ossman 			pwr = SDHCI_POWER_330;
1027ae628903SPierre Ossman 			break;
1028ae628903SPierre Ossman 		default:
1029ae628903SPierre Ossman 			BUG();
1030ae628903SPierre Ossman 		}
1031ae628903SPierre Ossman 	}
1032ae628903SPierre Ossman 
1033ae628903SPierre Ossman 	if (host->pwr == pwr)
10341c6a0718SPierre Ossman 		return;
10351c6a0718SPierre Ossman 
1036ae628903SPierre Ossman 	host->pwr = pwr;
1037ae628903SPierre Ossman 
1038ae628903SPierre Ossman 	if (pwr == 0) {
10394e4141a5SAnton Vorontsov 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1040ae628903SPierre Ossman 		return;
10411c6a0718SPierre Ossman 	}
10421c6a0718SPierre Ossman 
10431c6a0718SPierre Ossman 	/*
10441c6a0718SPierre Ossman 	 * Spec says that we should clear the power reg before setting
10451c6a0718SPierre Ossman 	 * a new value. Some controllers don't seem to like this though.
10461c6a0718SPierre Ossman 	 */
1047b8c86fc5SPierre Ossman 	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
10484e4141a5SAnton Vorontsov 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
10491c6a0718SPierre Ossman 
1050e08c1694SAndres Salomon 	/*
1051c71f6512SAndres Salomon 	 * At least the Marvell CaFe chip gets confused if we set the voltage
1052e08c1694SAndres Salomon 	 * and set turn on power at the same time, so set the voltage first.
1053e08c1694SAndres Salomon 	 */
1054b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
10554e4141a5SAnton Vorontsov 		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
10561c6a0718SPierre Ossman 
1057ae628903SPierre Ossman 	pwr |= SDHCI_POWER_ON;
1058ae628903SPierre Ossman 
1059ae628903SPierre Ossman 	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
10601c6a0718SPierre Ossman }
10611c6a0718SPierre Ossman 
10621c6a0718SPierre Ossman /*****************************************************************************\
10631c6a0718SPierre Ossman  *                                                                           *
10641c6a0718SPierre Ossman  * MMC callbacks                                                             *
10651c6a0718SPierre Ossman  *                                                                           *
10661c6a0718SPierre Ossman \*****************************************************************************/
10671c6a0718SPierre Ossman 
10681c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
10691c6a0718SPierre Ossman {
10701c6a0718SPierre Ossman 	struct sdhci_host *host;
107168d1fb7eSAnton Vorontsov 	bool present;
10721c6a0718SPierre Ossman 	unsigned long flags;
10731c6a0718SPierre Ossman 
10741c6a0718SPierre Ossman 	host = mmc_priv(mmc);
10751c6a0718SPierre Ossman 
10761c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
10771c6a0718SPierre Ossman 
10781c6a0718SPierre Ossman 	WARN_ON(host->mrq != NULL);
10791c6a0718SPierre Ossman 
1080f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS
10811c6a0718SPierre Ossman 	sdhci_activate_led(host);
10822f730fecSPierre Ossman #endif
10831c6a0718SPierre Ossman 
10841c6a0718SPierre Ossman 	host->mrq = mrq;
10851c6a0718SPierre Ossman 
108668d1fb7eSAnton Vorontsov 	/* If polling, assume that the card is always present. */
108768d1fb7eSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
108868d1fb7eSAnton Vorontsov 		present = true;
108968d1fb7eSAnton Vorontsov 	else
109068d1fb7eSAnton Vorontsov 		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
109168d1fb7eSAnton Vorontsov 				SDHCI_CARD_PRESENT;
109268d1fb7eSAnton Vorontsov 
109368d1fb7eSAnton Vorontsov 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
109417b0429dSPierre Ossman 		host->mrq->cmd->error = -ENOMEDIUM;
10951c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
10961c6a0718SPierre Ossman 	} else
10971c6a0718SPierre Ossman 		sdhci_send_command(host, mrq->cmd);
10981c6a0718SPierre Ossman 
10991c6a0718SPierre Ossman 	mmiowb();
11001c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
11011c6a0718SPierre Ossman }
11021c6a0718SPierre Ossman 
11031c6a0718SPierre Ossman static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11041c6a0718SPierre Ossman {
11051c6a0718SPierre Ossman 	struct sdhci_host *host;
11061c6a0718SPierre Ossman 	unsigned long flags;
11071c6a0718SPierre Ossman 	u8 ctrl;
11081c6a0718SPierre Ossman 
11091c6a0718SPierre Ossman 	host = mmc_priv(mmc);
11101c6a0718SPierre Ossman 
11111c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11121c6a0718SPierre Ossman 
11131e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
11141e72859eSPierre Ossman 		goto out;
11151e72859eSPierre Ossman 
11161c6a0718SPierre Ossman 	/*
11171c6a0718SPierre Ossman 	 * Reset the chip on each power off.
11181c6a0718SPierre Ossman 	 * Should clear out any weird states.
11191c6a0718SPierre Ossman 	 */
11201c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF) {
11214e4141a5SAnton Vorontsov 		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
11227260cf5eSAnton Vorontsov 		sdhci_reinit(host);
11231c6a0718SPierre Ossman 	}
11241c6a0718SPierre Ossman 
11251c6a0718SPierre Ossman 	sdhci_set_clock(host, ios->clock);
11261c6a0718SPierre Ossman 
11271c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF)
11281c6a0718SPierre Ossman 		sdhci_set_power(host, -1);
11291c6a0718SPierre Ossman 	else
11301c6a0718SPierre Ossman 		sdhci_set_power(host, ios->vdd);
11311c6a0718SPierre Ossman 
11324e4141a5SAnton Vorontsov 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
11331c6a0718SPierre Ossman 
11341c6a0718SPierre Ossman 	if (ios->bus_width == MMC_BUS_WIDTH_4)
11351c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_4BITBUS;
11361c6a0718SPierre Ossman 	else
11371c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_4BITBUS;
11381c6a0718SPierre Ossman 
11391c6a0718SPierre Ossman 	if (ios->timing == MMC_TIMING_SD_HS)
11401c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_HISPD;
11411c6a0718SPierre Ossman 	else
11421c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_HISPD;
11431c6a0718SPierre Ossman 
11444e4141a5SAnton Vorontsov 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
11451c6a0718SPierre Ossman 
1146b8352260SLeandro Dorileo 	/*
1147b8352260SLeandro Dorileo 	 * Some (ENE) controllers go apeshit on some ios operation,
1148b8352260SLeandro Dorileo 	 * signalling timeout and CRC errors even on CMD0. Resetting
1149b8352260SLeandro Dorileo 	 * it on each ios seems to solve the problem.
1150b8352260SLeandro Dorileo 	 */
1151b8c86fc5SPierre Ossman 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
1152b8352260SLeandro Dorileo 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
1153b8352260SLeandro Dorileo 
11541e72859eSPierre Ossman out:
11551c6a0718SPierre Ossman 	mmiowb();
11561c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
11571c6a0718SPierre Ossman }
11581c6a0718SPierre Ossman 
11591c6a0718SPierre Ossman static int sdhci_get_ro(struct mmc_host *mmc)
11601c6a0718SPierre Ossman {
11611c6a0718SPierre Ossman 	struct sdhci_host *host;
11621c6a0718SPierre Ossman 	unsigned long flags;
11631c6a0718SPierre Ossman 	int present;
11641c6a0718SPierre Ossman 
11651c6a0718SPierre Ossman 	host = mmc_priv(mmc);
11661c6a0718SPierre Ossman 
11671c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11681c6a0718SPierre Ossman 
11691e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
11701e72859eSPierre Ossman 		present = 0;
11711e72859eSPierre Ossman 	else
11724e4141a5SAnton Vorontsov 		present = sdhci_readl(host, SDHCI_PRESENT_STATE);
11731c6a0718SPierre Ossman 
11741c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
11751c6a0718SPierre Ossman 
1176c5075a10SAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
1177c5075a10SAnton Vorontsov 		return !!(present & SDHCI_WRITE_PROTECT);
11781c6a0718SPierre Ossman 	return !(present & SDHCI_WRITE_PROTECT);
11791c6a0718SPierre Ossman }
11801c6a0718SPierre Ossman 
1181f75979b7SPierre Ossman static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1182f75979b7SPierre Ossman {
1183f75979b7SPierre Ossman 	struct sdhci_host *host;
1184f75979b7SPierre Ossman 	unsigned long flags;
1185f75979b7SPierre Ossman 
1186f75979b7SPierre Ossman 	host = mmc_priv(mmc);
1187f75979b7SPierre Ossman 
1188f75979b7SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
1189f75979b7SPierre Ossman 
11901e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
11911e72859eSPierre Ossman 		goto out;
11921e72859eSPierre Ossman 
1193f75979b7SPierre Ossman 	if (enable)
11947260cf5eSAnton Vorontsov 		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
11957260cf5eSAnton Vorontsov 	else
11967260cf5eSAnton Vorontsov 		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
11971e72859eSPierre Ossman out:
1198f75979b7SPierre Ossman 	mmiowb();
1199f75979b7SPierre Ossman 
1200f75979b7SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
1201f75979b7SPierre Ossman }
1202f75979b7SPierre Ossman 
12031c6a0718SPierre Ossman static const struct mmc_host_ops sdhci_ops = {
12041c6a0718SPierre Ossman 	.request	= sdhci_request,
12051c6a0718SPierre Ossman 	.set_ios	= sdhci_set_ios,
12061c6a0718SPierre Ossman 	.get_ro		= sdhci_get_ro,
1207f75979b7SPierre Ossman 	.enable_sdio_irq = sdhci_enable_sdio_irq,
12081c6a0718SPierre Ossman };
12091c6a0718SPierre Ossman 
12101c6a0718SPierre Ossman /*****************************************************************************\
12111c6a0718SPierre Ossman  *                                                                           *
12121c6a0718SPierre Ossman  * Tasklets                                                                  *
12131c6a0718SPierre Ossman  *                                                                           *
12141c6a0718SPierre Ossman \*****************************************************************************/
12151c6a0718SPierre Ossman 
12161c6a0718SPierre Ossman static void sdhci_tasklet_card(unsigned long param)
12171c6a0718SPierre Ossman {
12181c6a0718SPierre Ossman 	struct sdhci_host *host;
12191c6a0718SPierre Ossman 	unsigned long flags;
12201c6a0718SPierre Ossman 
12211c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
12221c6a0718SPierre Ossman 
12231c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
12241c6a0718SPierre Ossman 
12254e4141a5SAnton Vorontsov 	if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
12261c6a0718SPierre Ossman 		if (host->mrq) {
12271c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Card removed during transfer!\n",
12281c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
12291c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Resetting controller.\n",
12301c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
12311c6a0718SPierre Ossman 
12321c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
12331c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
12341c6a0718SPierre Ossman 
123517b0429dSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
12361c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
12371c6a0718SPierre Ossman 		}
12381c6a0718SPierre Ossman 	}
12391c6a0718SPierre Ossman 
12401c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12411c6a0718SPierre Ossman 
124204cf585dSPierre Ossman 	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
12431c6a0718SPierre Ossman }
12441c6a0718SPierre Ossman 
12451c6a0718SPierre Ossman static void sdhci_tasklet_finish(unsigned long param)
12461c6a0718SPierre Ossman {
12471c6a0718SPierre Ossman 	struct sdhci_host *host;
12481c6a0718SPierre Ossman 	unsigned long flags;
12491c6a0718SPierre Ossman 	struct mmc_request *mrq;
12501c6a0718SPierre Ossman 
12511c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
12521c6a0718SPierre Ossman 
12531c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
12541c6a0718SPierre Ossman 
12551c6a0718SPierre Ossman 	del_timer(&host->timer);
12561c6a0718SPierre Ossman 
12571c6a0718SPierre Ossman 	mrq = host->mrq;
12581c6a0718SPierre Ossman 
12591c6a0718SPierre Ossman 	/*
12601c6a0718SPierre Ossman 	 * The controller needs a reset of internal state machines
12611c6a0718SPierre Ossman 	 * upon error conditions.
12621c6a0718SPierre Ossman 	 */
12631e72859eSPierre Ossman 	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
12641e72859eSPierre Ossman 		(mrq->cmd->error ||
126517b0429dSPierre Ossman 		 (mrq->data && (mrq->data->error ||
126684c46a53SPierre Ossman 		  (mrq->data->stop && mrq->data->stop->error))) ||
12671e72859eSPierre Ossman 		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
12681c6a0718SPierre Ossman 
12691c6a0718SPierre Ossman 		/* Some controllers need this kick or reset won't work here */
1270b8c86fc5SPierre Ossman 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
12711c6a0718SPierre Ossman 			unsigned int clock;
12721c6a0718SPierre Ossman 
12731c6a0718SPierre Ossman 			/* This is to force an update */
12741c6a0718SPierre Ossman 			clock = host->clock;
12751c6a0718SPierre Ossman 			host->clock = 0;
12761c6a0718SPierre Ossman 			sdhci_set_clock(host, clock);
12771c6a0718SPierre Ossman 		}
12781c6a0718SPierre Ossman 
12791c6a0718SPierre Ossman 		/* Spec says we should do both at the same time, but Ricoh
12801c6a0718SPierre Ossman 		   controllers do not like that. */
12811c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_CMD);
12821c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_DATA);
12831c6a0718SPierre Ossman 	}
12841c6a0718SPierre Ossman 
12851c6a0718SPierre Ossman 	host->mrq = NULL;
12861c6a0718SPierre Ossman 	host->cmd = NULL;
12871c6a0718SPierre Ossman 	host->data = NULL;
12881c6a0718SPierre Ossman 
1289f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS
12901c6a0718SPierre Ossman 	sdhci_deactivate_led(host);
12912f730fecSPierre Ossman #endif
12921c6a0718SPierre Ossman 
12931c6a0718SPierre Ossman 	mmiowb();
12941c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12951c6a0718SPierre Ossman 
12961c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
12971c6a0718SPierre Ossman }
12981c6a0718SPierre Ossman 
12991c6a0718SPierre Ossman static void sdhci_timeout_timer(unsigned long data)
13001c6a0718SPierre Ossman {
13011c6a0718SPierre Ossman 	struct sdhci_host *host;
13021c6a0718SPierre Ossman 	unsigned long flags;
13031c6a0718SPierre Ossman 
13041c6a0718SPierre Ossman 	host = (struct sdhci_host*)data;
13051c6a0718SPierre Ossman 
13061c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
13071c6a0718SPierre Ossman 
13081c6a0718SPierre Ossman 	if (host->mrq) {
13091c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Timeout waiting for hardware "
13101c6a0718SPierre Ossman 			"interrupt.\n", mmc_hostname(host->mmc));
13111c6a0718SPierre Ossman 		sdhci_dumpregs(host);
13121c6a0718SPierre Ossman 
13131c6a0718SPierre Ossman 		if (host->data) {
131417b0429dSPierre Ossman 			host->data->error = -ETIMEDOUT;
13151c6a0718SPierre Ossman 			sdhci_finish_data(host);
13161c6a0718SPierre Ossman 		} else {
13171c6a0718SPierre Ossman 			if (host->cmd)
131817b0429dSPierre Ossman 				host->cmd->error = -ETIMEDOUT;
13191c6a0718SPierre Ossman 			else
132017b0429dSPierre Ossman 				host->mrq->cmd->error = -ETIMEDOUT;
13211c6a0718SPierre Ossman 
13221c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
13231c6a0718SPierre Ossman 		}
13241c6a0718SPierre Ossman 	}
13251c6a0718SPierre Ossman 
13261c6a0718SPierre Ossman 	mmiowb();
13271c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
13281c6a0718SPierre Ossman }
13291c6a0718SPierre Ossman 
13301c6a0718SPierre Ossman /*****************************************************************************\
13311c6a0718SPierre Ossman  *                                                                           *
13321c6a0718SPierre Ossman  * Interrupt handling                                                        *
13331c6a0718SPierre Ossman  *                                                                           *
13341c6a0718SPierre Ossman \*****************************************************************************/
13351c6a0718SPierre Ossman 
13361c6a0718SPierre Ossman static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
13371c6a0718SPierre Ossman {
13381c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
13391c6a0718SPierre Ossman 
13401c6a0718SPierre Ossman 	if (!host->cmd) {
1341b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
1342b67ac3f3SPierre Ossman 			"though no command operation was in progress.\n",
1343b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
13441c6a0718SPierre Ossman 		sdhci_dumpregs(host);
13451c6a0718SPierre Ossman 		return;
13461c6a0718SPierre Ossman 	}
13471c6a0718SPierre Ossman 
13481c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_TIMEOUT)
134917b0429dSPierre Ossman 		host->cmd->error = -ETIMEDOUT;
135017b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
135117b0429dSPierre Ossman 			SDHCI_INT_INDEX))
135217b0429dSPierre Ossman 		host->cmd->error = -EILSEQ;
13531c6a0718SPierre Ossman 
1354e809517fSPierre Ossman 	if (host->cmd->error) {
13551c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
1356e809517fSPierre Ossman 		return;
1357e809517fSPierre Ossman 	}
1358e809517fSPierre Ossman 
1359e809517fSPierre Ossman 	/*
1360e809517fSPierre Ossman 	 * The host can send and interrupt when the busy state has
1361e809517fSPierre Ossman 	 * ended, allowing us to wait without wasting CPU cycles.
1362e809517fSPierre Ossman 	 * Unfortunately this is overloaded on the "data complete"
1363e809517fSPierre Ossman 	 * interrupt, so we need to take some care when handling
1364e809517fSPierre Ossman 	 * it.
1365e809517fSPierre Ossman 	 *
1366e809517fSPierre Ossman 	 * Note: The 1.0 specification is a bit ambiguous about this
1367e809517fSPierre Ossman 	 *       feature so there might be some problems with older
1368e809517fSPierre Ossman 	 *       controllers.
1369e809517fSPierre Ossman 	 */
1370e809517fSPierre Ossman 	if (host->cmd->flags & MMC_RSP_BUSY) {
1371e809517fSPierre Ossman 		if (host->cmd->data)
1372e809517fSPierre Ossman 			DBG("Cannot wait for busy signal when also "
1373e809517fSPierre Ossman 				"doing a data transfer");
1374f945405cSBen Dooks 		else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
1375e809517fSPierre Ossman 			return;
1376f945405cSBen Dooks 
1377f945405cSBen Dooks 		/* The controller does not support the end-of-busy IRQ,
1378f945405cSBen Dooks 		 * fall through and take the SDHCI_INT_RESPONSE */
1379e809517fSPierre Ossman 	}
1380e809517fSPierre Ossman 
1381e809517fSPierre Ossman 	if (intmask & SDHCI_INT_RESPONSE)
138243b58b36SPierre Ossman 		sdhci_finish_command(host);
13831c6a0718SPierre Ossman }
13841c6a0718SPierre Ossman 
13856882a8c0SBen Dooks #ifdef DEBUG
13866882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host)
13876882a8c0SBen Dooks {
13886882a8c0SBen Dooks 	const char *name = mmc_hostname(host->mmc);
13896882a8c0SBen Dooks 	u8 *desc = host->adma_desc;
13906882a8c0SBen Dooks 	__le32 *dma;
13916882a8c0SBen Dooks 	__le16 *len;
13926882a8c0SBen Dooks 	u8 attr;
13936882a8c0SBen Dooks 
13946882a8c0SBen Dooks 	sdhci_dumpregs(host);
13956882a8c0SBen Dooks 
13966882a8c0SBen Dooks 	while (true) {
13976882a8c0SBen Dooks 		dma = (__le32 *)(desc + 4);
13986882a8c0SBen Dooks 		len = (__le16 *)(desc + 2);
13996882a8c0SBen Dooks 		attr = *desc;
14006882a8c0SBen Dooks 
14016882a8c0SBen Dooks 		DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
14026882a8c0SBen Dooks 		    name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr);
14036882a8c0SBen Dooks 
14046882a8c0SBen Dooks 		desc += 8;
14056882a8c0SBen Dooks 
14066882a8c0SBen Dooks 		if (attr & 2)
14076882a8c0SBen Dooks 			break;
14086882a8c0SBen Dooks 	}
14096882a8c0SBen Dooks }
14106882a8c0SBen Dooks #else
14116882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host) { }
14126882a8c0SBen Dooks #endif
14136882a8c0SBen Dooks 
14141c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
14151c6a0718SPierre Ossman {
14161c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
14171c6a0718SPierre Ossman 
14181c6a0718SPierre Ossman 	if (!host->data) {
14191c6a0718SPierre Ossman 		/*
1420e809517fSPierre Ossman 		 * The "data complete" interrupt is also used to
1421e809517fSPierre Ossman 		 * indicate that a busy state has ended. See comment
1422e809517fSPierre Ossman 		 * above in sdhci_cmd_irq().
14231c6a0718SPierre Ossman 		 */
1424e809517fSPierre Ossman 		if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
1425e809517fSPierre Ossman 			if (intmask & SDHCI_INT_DATA_END) {
1426e809517fSPierre Ossman 				sdhci_finish_command(host);
14271c6a0718SPierre Ossman 				return;
1428e809517fSPierre Ossman 			}
1429e809517fSPierre Ossman 		}
14301c6a0718SPierre Ossman 
1431b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
1432b67ac3f3SPierre Ossman 			"though no data operation was in progress.\n",
1433b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
14341c6a0718SPierre Ossman 		sdhci_dumpregs(host);
14351c6a0718SPierre Ossman 
14361c6a0718SPierre Ossman 		return;
14371c6a0718SPierre Ossman 	}
14381c6a0718SPierre Ossman 
14391c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
144017b0429dSPierre Ossman 		host->data->error = -ETIMEDOUT;
144117b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
144217b0429dSPierre Ossman 		host->data->error = -EILSEQ;
14436882a8c0SBen Dooks 	else if (intmask & SDHCI_INT_ADMA_ERROR) {
14446882a8c0SBen Dooks 		printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc));
14456882a8c0SBen Dooks 		sdhci_show_adma_error(host);
14462134a922SPierre Ossman 		host->data->error = -EIO;
14476882a8c0SBen Dooks 	}
14481c6a0718SPierre Ossman 
144917b0429dSPierre Ossman 	if (host->data->error)
14501c6a0718SPierre Ossman 		sdhci_finish_data(host);
14511c6a0718SPierre Ossman 	else {
14521c6a0718SPierre Ossman 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
14531c6a0718SPierre Ossman 			sdhci_transfer_pio(host);
14541c6a0718SPierre Ossman 
14556ba736a1SPierre Ossman 		/*
14566ba736a1SPierre Ossman 		 * We currently don't do anything fancy with DMA
14576ba736a1SPierre Ossman 		 * boundaries, but as we can't disable the feature
14586ba736a1SPierre Ossman 		 * we need to at least restart the transfer.
14596ba736a1SPierre Ossman 		 */
14606ba736a1SPierre Ossman 		if (intmask & SDHCI_INT_DMA_END)
14614e4141a5SAnton Vorontsov 			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
14624e4141a5SAnton Vorontsov 				SDHCI_DMA_ADDRESS);
14636ba736a1SPierre Ossman 
1464e538fbe8SPierre Ossman 		if (intmask & SDHCI_INT_DATA_END) {
1465e538fbe8SPierre Ossman 			if (host->cmd) {
1466e538fbe8SPierre Ossman 				/*
1467e538fbe8SPierre Ossman 				 * Data managed to finish before the
1468e538fbe8SPierre Ossman 				 * command completed. Make sure we do
1469e538fbe8SPierre Ossman 				 * things in the proper order.
1470e538fbe8SPierre Ossman 				 */
1471e538fbe8SPierre Ossman 				host->data_early = 1;
1472e538fbe8SPierre Ossman 			} else {
14731c6a0718SPierre Ossman 				sdhci_finish_data(host);
14741c6a0718SPierre Ossman 			}
14751c6a0718SPierre Ossman 		}
1476e538fbe8SPierre Ossman 	}
1477e538fbe8SPierre Ossman }
14781c6a0718SPierre Ossman 
14791c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id)
14801c6a0718SPierre Ossman {
14811c6a0718SPierre Ossman 	irqreturn_t result;
14821c6a0718SPierre Ossman 	struct sdhci_host* host = dev_id;
14831c6a0718SPierre Ossman 	u32 intmask;
1484f75979b7SPierre Ossman 	int cardint = 0;
14851c6a0718SPierre Ossman 
14861c6a0718SPierre Ossman 	spin_lock(&host->lock);
14871c6a0718SPierre Ossman 
14884e4141a5SAnton Vorontsov 	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
14891c6a0718SPierre Ossman 
14901c6a0718SPierre Ossman 	if (!intmask || intmask == 0xffffffff) {
14911c6a0718SPierre Ossman 		result = IRQ_NONE;
14921c6a0718SPierre Ossman 		goto out;
14931c6a0718SPierre Ossman 	}
14941c6a0718SPierre Ossman 
1495b69c9058SPierre Ossman 	DBG("*** %s got interrupt: 0x%08x\n",
1496b69c9058SPierre Ossman 		mmc_hostname(host->mmc), intmask);
14971c6a0718SPierre Ossman 
14981c6a0718SPierre Ossman 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
14994e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
15004e4141a5SAnton Vorontsov 			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
15011c6a0718SPierre Ossman 		tasklet_schedule(&host->card_tasklet);
15021c6a0718SPierre Ossman 	}
15031c6a0718SPierre Ossman 
15041c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
15051c6a0718SPierre Ossman 
15061c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_CMD_MASK) {
15074e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
15084e4141a5SAnton Vorontsov 			SDHCI_INT_STATUS);
15091c6a0718SPierre Ossman 		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
15101c6a0718SPierre Ossman 	}
15111c6a0718SPierre Ossman 
15121c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_MASK) {
15134e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
15144e4141a5SAnton Vorontsov 			SDHCI_INT_STATUS);
15151c6a0718SPierre Ossman 		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
15161c6a0718SPierre Ossman 	}
15171c6a0718SPierre Ossman 
15181c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
15191c6a0718SPierre Ossman 
1520964f9ce2SPierre Ossman 	intmask &= ~SDHCI_INT_ERROR;
1521964f9ce2SPierre Ossman 
15221c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_BUS_POWER) {
15231c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Card is consuming too much power!\n",
15241c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
15254e4141a5SAnton Vorontsov 		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
15261c6a0718SPierre Ossman 	}
15271c6a0718SPierre Ossman 
15289d26a5d3SRolf Eike Beer 	intmask &= ~SDHCI_INT_BUS_POWER;
15291c6a0718SPierre Ossman 
1530f75979b7SPierre Ossman 	if (intmask & SDHCI_INT_CARD_INT)
1531f75979b7SPierre Ossman 		cardint = 1;
1532f75979b7SPierre Ossman 
1533f75979b7SPierre Ossman 	intmask &= ~SDHCI_INT_CARD_INT;
1534f75979b7SPierre Ossman 
15351c6a0718SPierre Ossman 	if (intmask) {
15361c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
15371c6a0718SPierre Ossman 			mmc_hostname(host->mmc), intmask);
15381c6a0718SPierre Ossman 		sdhci_dumpregs(host);
15391c6a0718SPierre Ossman 
15404e4141a5SAnton Vorontsov 		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
15411c6a0718SPierre Ossman 	}
15421c6a0718SPierre Ossman 
15431c6a0718SPierre Ossman 	result = IRQ_HANDLED;
15441c6a0718SPierre Ossman 
15451c6a0718SPierre Ossman 	mmiowb();
15461c6a0718SPierre Ossman out:
15471c6a0718SPierre Ossman 	spin_unlock(&host->lock);
15481c6a0718SPierre Ossman 
1549f75979b7SPierre Ossman 	/*
1550f75979b7SPierre Ossman 	 * We have to delay this as it calls back into the driver.
1551f75979b7SPierre Ossman 	 */
1552f75979b7SPierre Ossman 	if (cardint)
1553f75979b7SPierre Ossman 		mmc_signal_sdio_irq(host->mmc);
1554f75979b7SPierre Ossman 
15551c6a0718SPierre Ossman 	return result;
15561c6a0718SPierre Ossman }
15571c6a0718SPierre Ossman 
15581c6a0718SPierre Ossman /*****************************************************************************\
15591c6a0718SPierre Ossman  *                                                                           *
15601c6a0718SPierre Ossman  * Suspend/resume                                                            *
15611c6a0718SPierre Ossman  *                                                                           *
15621c6a0718SPierre Ossman \*****************************************************************************/
15631c6a0718SPierre Ossman 
15641c6a0718SPierre Ossman #ifdef CONFIG_PM
15651c6a0718SPierre Ossman 
1566b8c86fc5SPierre Ossman int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
15671c6a0718SPierre Ossman {
1568b8c86fc5SPierre Ossman 	int ret;
15691c6a0718SPierre Ossman 
15707260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
15717260cf5eSAnton Vorontsov 
1572b8c86fc5SPierre Ossman 	ret = mmc_suspend_host(host->mmc, state);
15731c6a0718SPierre Ossman 	if (ret)
15741c6a0718SPierre Ossman 		return ret;
15751c6a0718SPierre Ossman 
1576b8c86fc5SPierre Ossman 	free_irq(host->irq, host);
1577b8c86fc5SPierre Ossman 
1578b8c86fc5SPierre Ossman 	return 0;
1579b8c86fc5SPierre Ossman }
1580b8c86fc5SPierre Ossman 
1581b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host);
1582b8c86fc5SPierre Ossman 
1583b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host)
1584b8c86fc5SPierre Ossman {
1585b8c86fc5SPierre Ossman 	int ret;
1586b8c86fc5SPierre Ossman 
1587b8c86fc5SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
1588b8c86fc5SPierre Ossman 		if (host->ops->enable_dma)
1589b8c86fc5SPierre Ossman 			host->ops->enable_dma(host);
1590b8c86fc5SPierre Ossman 	}
1591b8c86fc5SPierre Ossman 
1592b8c86fc5SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1593b8c86fc5SPierre Ossman 			  mmc_hostname(host->mmc), host);
15941c6a0718SPierre Ossman 	if (ret)
15951c6a0718SPierre Ossman 		return ret;
1596b8c86fc5SPierre Ossman 
1597b8c86fc5SPierre Ossman 	sdhci_init(host);
15981c6a0718SPierre Ossman 	mmiowb();
1599b8c86fc5SPierre Ossman 
1600b8c86fc5SPierre Ossman 	ret = mmc_resume_host(host->mmc);
16011c6a0718SPierre Ossman 	if (ret)
16021c6a0718SPierre Ossman 		return ret;
16031c6a0718SPierre Ossman 
16047260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
16057260cf5eSAnton Vorontsov 
16061c6a0718SPierre Ossman 	return 0;
16071c6a0718SPierre Ossman }
16081c6a0718SPierre Ossman 
1609b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host);
16101c6a0718SPierre Ossman 
16111c6a0718SPierre Ossman #endif /* CONFIG_PM */
16121c6a0718SPierre Ossman 
16131c6a0718SPierre Ossman /*****************************************************************************\
16141c6a0718SPierre Ossman  *                                                                           *
1615b8c86fc5SPierre Ossman  * Device allocation/registration                                            *
16161c6a0718SPierre Ossman  *                                                                           *
16171c6a0718SPierre Ossman \*****************************************************************************/
16181c6a0718SPierre Ossman 
1619b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev,
1620b8c86fc5SPierre Ossman 	size_t priv_size)
16211c6a0718SPierre Ossman {
16221c6a0718SPierre Ossman 	struct mmc_host *mmc;
16231c6a0718SPierre Ossman 	struct sdhci_host *host;
16241c6a0718SPierre Ossman 
1625b8c86fc5SPierre Ossman 	WARN_ON(dev == NULL);
16261c6a0718SPierre Ossman 
1627b8c86fc5SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
16281c6a0718SPierre Ossman 	if (!mmc)
1629b8c86fc5SPierre Ossman 		return ERR_PTR(-ENOMEM);
16301c6a0718SPierre Ossman 
16311c6a0718SPierre Ossman 	host = mmc_priv(mmc);
16321c6a0718SPierre Ossman 	host->mmc = mmc;
16331c6a0718SPierre Ossman 
1634b8c86fc5SPierre Ossman 	return host;
16351c6a0718SPierre Ossman }
16361c6a0718SPierre Ossman 
1637b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host);
1638b8c86fc5SPierre Ossman 
1639b8c86fc5SPierre Ossman int sdhci_add_host(struct sdhci_host *host)
1640b8c86fc5SPierre Ossman {
1641b8c86fc5SPierre Ossman 	struct mmc_host *mmc;
1642b8c86fc5SPierre Ossman 	unsigned int caps;
1643b8c86fc5SPierre Ossman 	int ret;
1644b8c86fc5SPierre Ossman 
1645b8c86fc5SPierre Ossman 	WARN_ON(host == NULL);
1646b8c86fc5SPierre Ossman 	if (host == NULL)
1647b8c86fc5SPierre Ossman 		return -EINVAL;
1648b8c86fc5SPierre Ossman 
1649b8c86fc5SPierre Ossman 	mmc = host->mmc;
1650b8c86fc5SPierre Ossman 
1651b8c86fc5SPierre Ossman 	if (debug_quirks)
1652b8c86fc5SPierre Ossman 		host->quirks = debug_quirks;
1653b8c86fc5SPierre Ossman 
16541c6a0718SPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
16551c6a0718SPierre Ossman 
16564e4141a5SAnton Vorontsov 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
16572134a922SPierre Ossman 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
16582134a922SPierre Ossman 				>> SDHCI_SPEC_VER_SHIFT;
16592134a922SPierre Ossman 	if (host->version > SDHCI_SPEC_200) {
16601c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unknown controller version (%d). "
1661b69c9058SPierre Ossman 			"You may experience problems.\n", mmc_hostname(mmc),
16622134a922SPierre Ossman 			host->version);
16631c6a0718SPierre Ossman 	}
16641c6a0718SPierre Ossman 
16654e4141a5SAnton Vorontsov 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
16661c6a0718SPierre Ossman 
1667b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
16681c6a0718SPierre Ossman 		host->flags |= SDHCI_USE_DMA;
16691c6a0718SPierre Ossman 	else if (!(caps & SDHCI_CAN_DO_DMA))
16701c6a0718SPierre Ossman 		DBG("Controller doesn't have DMA capability\n");
16711c6a0718SPierre Ossman 	else
16721c6a0718SPierre Ossman 		host->flags |= SDHCI_USE_DMA;
16731c6a0718SPierre Ossman 
1674b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
16757c168e3dSFeng Tang 		(host->flags & SDHCI_USE_DMA)) {
1676cee687ceSRolf Eike Beer 		DBG("Disabling DMA as it is marked broken\n");
16777c168e3dSFeng Tang 		host->flags &= ~SDHCI_USE_DMA;
16787c168e3dSFeng Tang 	}
16797c168e3dSFeng Tang 
16801c6a0718SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
16812134a922SPierre Ossman 		if ((host->version >= SDHCI_SPEC_200) &&
16822134a922SPierre Ossman 				(caps & SDHCI_CAN_DO_ADMA2))
16832134a922SPierre Ossman 			host->flags |= SDHCI_USE_ADMA;
16842134a922SPierre Ossman 	}
16852134a922SPierre Ossman 
16862134a922SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
16872134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)) {
16882134a922SPierre Ossman 		DBG("Disabling ADMA as it is marked broken\n");
16892134a922SPierre Ossman 		host->flags &= ~SDHCI_USE_ADMA;
16902134a922SPierre Ossman 	}
16912134a922SPierre Ossman 
16922134a922SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
1693b8c86fc5SPierre Ossman 		if (host->ops->enable_dma) {
1694b8c86fc5SPierre Ossman 			if (host->ops->enable_dma(host)) {
1695b8c86fc5SPierre Ossman 				printk(KERN_WARNING "%s: No suitable DMA "
1696b8c86fc5SPierre Ossman 					"available. Falling back to PIO.\n",
1697b8c86fc5SPierre Ossman 					mmc_hostname(mmc));
16982134a922SPierre Ossman 				host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
16991c6a0718SPierre Ossman 			}
17001c6a0718SPierre Ossman 		}
1701b8c86fc5SPierre Ossman 	}
17021c6a0718SPierre Ossman 
17032134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA) {
17042134a922SPierre Ossman 		/*
17052134a922SPierre Ossman 		 * We need to allocate descriptors for all sg entries
17062134a922SPierre Ossman 		 * (128) and potentially one alignment transfer for
17072134a922SPierre Ossman 		 * each of those entries.
17082134a922SPierre Ossman 		 */
17092134a922SPierre Ossman 		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
17102134a922SPierre Ossman 		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
17112134a922SPierre Ossman 		if (!host->adma_desc || !host->align_buffer) {
17122134a922SPierre Ossman 			kfree(host->adma_desc);
17132134a922SPierre Ossman 			kfree(host->align_buffer);
17142134a922SPierre Ossman 			printk(KERN_WARNING "%s: Unable to allocate ADMA "
17152134a922SPierre Ossman 				"buffers. Falling back to standard DMA.\n",
17162134a922SPierre Ossman 				mmc_hostname(mmc));
17172134a922SPierre Ossman 			host->flags &= ~SDHCI_USE_ADMA;
17182134a922SPierre Ossman 		}
17192134a922SPierre Ossman 	}
17202134a922SPierre Ossman 
17217659150cSPierre Ossman 	/*
17227659150cSPierre Ossman 	 * If we use DMA, then it's up to the caller to set the DMA
17237659150cSPierre Ossman 	 * mask, but PIO does not need the hw shim so we set a new
17247659150cSPierre Ossman 	 * mask here in that case.
17257659150cSPierre Ossman 	 */
17267659150cSPierre Ossman 	if (!(host->flags & SDHCI_USE_DMA)) {
17277659150cSPierre Ossman 		host->dma_mask = DMA_BIT_MASK(64);
17287659150cSPierre Ossman 		mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
17297659150cSPierre Ossman 	}
17301c6a0718SPierre Ossman 
17311c6a0718SPierre Ossman 	host->max_clk =
17321c6a0718SPierre Ossman 		(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
17334240ff0aSBen Dooks 	host->max_clk *= 1000000;
17341c6a0718SPierre Ossman 	if (host->max_clk == 0) {
17354240ff0aSBen Dooks 		if (!host->ops->get_max_clock) {
17364240ff0aSBen Dooks 			printk(KERN_ERR
17374240ff0aSBen Dooks 			       "%s: Hardware doesn't specify base clock "
1738b69c9058SPierre Ossman 			       "frequency.\n", mmc_hostname(mmc));
1739b8c86fc5SPierre Ossman 			return -ENODEV;
17401c6a0718SPierre Ossman 		}
17414240ff0aSBen Dooks 		host->max_clk = host->ops->get_max_clock(host);
17424240ff0aSBen Dooks 	}
17431c6a0718SPierre Ossman 
17441c6a0718SPierre Ossman 	host->timeout_clk =
17451c6a0718SPierre Ossman 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
17461c6a0718SPierre Ossman 	if (host->timeout_clk == 0) {
17474240ff0aSBen Dooks 		if (!host->ops->get_timeout_clock) {
17484240ff0aSBen Dooks 			printk(KERN_ERR
17494240ff0aSBen Dooks 			       "%s: Hardware doesn't specify timeout clock "
1750b69c9058SPierre Ossman 			       "frequency.\n", mmc_hostname(mmc));
1751b8c86fc5SPierre Ossman 			return -ENODEV;
17521c6a0718SPierre Ossman 		}
17534240ff0aSBen Dooks 		host->timeout_clk = host->ops->get_timeout_clock(host);
17544240ff0aSBen Dooks 	}
17551c6a0718SPierre Ossman 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
17561c6a0718SPierre Ossman 		host->timeout_clk *= 1000;
17571c6a0718SPierre Ossman 
17581c6a0718SPierre Ossman 	/*
17591c6a0718SPierre Ossman 	 * Set host parameters.
17601c6a0718SPierre Ossman 	 */
17611c6a0718SPierre Ossman 	mmc->ops = &sdhci_ops;
17621c6a0718SPierre Ossman 	mmc->f_min = host->max_clk / 256;
17631c6a0718SPierre Ossman 	mmc->f_max = host->max_clk;
17645fe23c7fSAnton Vorontsov 	mmc->caps = MMC_CAP_SDIO_IRQ;
17655fe23c7fSAnton Vorontsov 
17665fe23c7fSAnton Vorontsov 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
17675fe23c7fSAnton Vorontsov 		mmc->caps |= MMC_CAP_4_BIT_DATA;
17681c6a0718SPierre Ossman 
176986a6a874SPierre Ossman 	if (caps & SDHCI_CAN_DO_HISPD)
17701c6a0718SPierre Ossman 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
17711c6a0718SPierre Ossman 
177268d1fb7eSAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
177368d1fb7eSAnton Vorontsov 		mmc->caps |= MMC_CAP_NEEDS_POLL;
177468d1fb7eSAnton Vorontsov 
17751c6a0718SPierre Ossman 	mmc->ocr_avail = 0;
17761c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_330)
17771c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
17781c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_300)
17791c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
17801c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_180)
178155556da0SPhilip Langdale 		mmc->ocr_avail |= MMC_VDD_165_195;
17821c6a0718SPierre Ossman 
17831c6a0718SPierre Ossman 	if (mmc->ocr_avail == 0) {
17841c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Hardware doesn't report any "
1785b69c9058SPierre Ossman 			"support voltages.\n", mmc_hostname(mmc));
1786b8c86fc5SPierre Ossman 		return -ENODEV;
17871c6a0718SPierre Ossman 	}
17881c6a0718SPierre Ossman 
17891c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
17901c6a0718SPierre Ossman 
17911c6a0718SPierre Ossman 	/*
17922134a922SPierre Ossman 	 * Maximum number of segments. Depends on if the hardware
17932134a922SPierre Ossman 	 * can do scatter/gather or not.
17941c6a0718SPierre Ossman 	 */
17952134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
17962134a922SPierre Ossman 		mmc->max_hw_segs = 128;
17972134a922SPierre Ossman 	else if (host->flags & SDHCI_USE_DMA)
17981c6a0718SPierre Ossman 		mmc->max_hw_segs = 1;
17992134a922SPierre Ossman 	else /* PIO */
18002134a922SPierre Ossman 		mmc->max_hw_segs = 128;
18012134a922SPierre Ossman 	mmc->max_phys_segs = 128;
18021c6a0718SPierre Ossman 
18031c6a0718SPierre Ossman 	/*
18041c6a0718SPierre Ossman 	 * Maximum number of sectors in one transfer. Limited by DMA boundary
18051c6a0718SPierre Ossman 	 * size (512KiB).
18061c6a0718SPierre Ossman 	 */
18071c6a0718SPierre Ossman 	mmc->max_req_size = 524288;
18081c6a0718SPierre Ossman 
18091c6a0718SPierre Ossman 	/*
18101c6a0718SPierre Ossman 	 * Maximum segment size. Could be one segment with the maximum number
18112134a922SPierre Ossman 	 * of bytes. When doing hardware scatter/gather, each entry cannot
18122134a922SPierre Ossman 	 * be larger than 64 KiB though.
18131c6a0718SPierre Ossman 	 */
18142134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
18152134a922SPierre Ossman 		mmc->max_seg_size = 65536;
18162134a922SPierre Ossman 	else
18171c6a0718SPierre Ossman 		mmc->max_seg_size = mmc->max_req_size;
18181c6a0718SPierre Ossman 
18191c6a0718SPierre Ossman 	/*
18201c6a0718SPierre Ossman 	 * Maximum block size. This varies from controller to controller and
18211c6a0718SPierre Ossman 	 * is specified in the capabilities register.
18221c6a0718SPierre Ossman 	 */
18230633f654SAnton Vorontsov 	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
18240633f654SAnton Vorontsov 		mmc->max_blk_size = 2;
18250633f654SAnton Vorontsov 	} else {
18260633f654SAnton Vorontsov 		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
18270633f654SAnton Vorontsov 				SDHCI_MAX_BLOCK_SHIFT;
18281c6a0718SPierre Ossman 		if (mmc->max_blk_size >= 3) {
1829b69c9058SPierre Ossman 			printk(KERN_WARNING "%s: Invalid maximum block size, "
1830b69c9058SPierre Ossman 				"assuming 512 bytes\n", mmc_hostname(mmc));
18310633f654SAnton Vorontsov 			mmc->max_blk_size = 0;
18320633f654SAnton Vorontsov 		}
18330633f654SAnton Vorontsov 	}
18340633f654SAnton Vorontsov 
18351c6a0718SPierre Ossman 	mmc->max_blk_size = 512 << mmc->max_blk_size;
18361c6a0718SPierre Ossman 
18371c6a0718SPierre Ossman 	/*
18381c6a0718SPierre Ossman 	 * Maximum block count.
18391c6a0718SPierre Ossman 	 */
18401388eefdSBen Dooks 	mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
18411c6a0718SPierre Ossman 
18421c6a0718SPierre Ossman 	/*
18431c6a0718SPierre Ossman 	 * Init tasklets.
18441c6a0718SPierre Ossman 	 */
18451c6a0718SPierre Ossman 	tasklet_init(&host->card_tasklet,
18461c6a0718SPierre Ossman 		sdhci_tasklet_card, (unsigned long)host);
18471c6a0718SPierre Ossman 	tasklet_init(&host->finish_tasklet,
18481c6a0718SPierre Ossman 		sdhci_tasklet_finish, (unsigned long)host);
18491c6a0718SPierre Ossman 
18501c6a0718SPierre Ossman 	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
18511c6a0718SPierre Ossman 
18521c6a0718SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1853b69c9058SPierre Ossman 		mmc_hostname(mmc), host);
18541c6a0718SPierre Ossman 	if (ret)
18551c6a0718SPierre Ossman 		goto untasklet;
18561c6a0718SPierre Ossman 
18571c6a0718SPierre Ossman 	sdhci_init(host);
18581c6a0718SPierre Ossman 
18591c6a0718SPierre Ossman #ifdef CONFIG_MMC_DEBUG
18601c6a0718SPierre Ossman 	sdhci_dumpregs(host);
18611c6a0718SPierre Ossman #endif
18621c6a0718SPierre Ossman 
1863f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
18645dbace0cSHelmut Schaa 	snprintf(host->led_name, sizeof(host->led_name),
18655dbace0cSHelmut Schaa 		"%s::", mmc_hostname(mmc));
18665dbace0cSHelmut Schaa 	host->led.name = host->led_name;
18672f730fecSPierre Ossman 	host->led.brightness = LED_OFF;
18682f730fecSPierre Ossman 	host->led.default_trigger = mmc_hostname(mmc);
18692f730fecSPierre Ossman 	host->led.brightness_set = sdhci_led_control;
18702f730fecSPierre Ossman 
1871b8c86fc5SPierre Ossman 	ret = led_classdev_register(mmc_dev(mmc), &host->led);
18722f730fecSPierre Ossman 	if (ret)
18732f730fecSPierre Ossman 		goto reset;
18742f730fecSPierre Ossman #endif
18752f730fecSPierre Ossman 
18761c6a0718SPierre Ossman 	mmiowb();
18771c6a0718SPierre Ossman 
18781c6a0718SPierre Ossman 	mmc_add_host(mmc);
18791c6a0718SPierre Ossman 
18802134a922SPierre Ossman 	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
1881d1b26863SKay Sievers 		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
18822134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)?"A":"",
18831c6a0718SPierre Ossman 		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
18841c6a0718SPierre Ossman 
18857260cf5eSAnton Vorontsov 	sdhci_enable_card_detection(host);
18867260cf5eSAnton Vorontsov 
18871c6a0718SPierre Ossman 	return 0;
18881c6a0718SPierre Ossman 
1889f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
18902f730fecSPierre Ossman reset:
18912f730fecSPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
18922f730fecSPierre Ossman 	free_irq(host->irq, host);
18932f730fecSPierre Ossman #endif
18941c6a0718SPierre Ossman untasklet:
18951c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
18961c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
18971c6a0718SPierre Ossman 
18981c6a0718SPierre Ossman 	return ret;
18991c6a0718SPierre Ossman }
19001c6a0718SPierre Ossman 
1901b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host);
1902b8c86fc5SPierre Ossman 
19031e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead)
19041c6a0718SPierre Ossman {
19051e72859eSPierre Ossman 	unsigned long flags;
19061e72859eSPierre Ossman 
19071e72859eSPierre Ossman 	if (dead) {
19081e72859eSPierre Ossman 		spin_lock_irqsave(&host->lock, flags);
19091e72859eSPierre Ossman 
19101e72859eSPierre Ossman 		host->flags |= SDHCI_DEVICE_DEAD;
19111e72859eSPierre Ossman 
19121e72859eSPierre Ossman 		if (host->mrq) {
19131e72859eSPierre Ossman 			printk(KERN_ERR "%s: Controller removed during "
19141e72859eSPierre Ossman 				" transfer!\n", mmc_hostname(host->mmc));
19151e72859eSPierre Ossman 
19161e72859eSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
19171e72859eSPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
19181e72859eSPierre Ossman 		}
19191e72859eSPierre Ossman 
19201e72859eSPierre Ossman 		spin_unlock_irqrestore(&host->lock, flags);
19211e72859eSPierre Ossman 	}
19221e72859eSPierre Ossman 
19237260cf5eSAnton Vorontsov 	sdhci_disable_card_detection(host);
19247260cf5eSAnton Vorontsov 
1925b8c86fc5SPierre Ossman 	mmc_remove_host(host->mmc);
19261c6a0718SPierre Ossman 
1927f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS
19282f730fecSPierre Ossman 	led_classdev_unregister(&host->led);
19292f730fecSPierre Ossman #endif
19302f730fecSPierre Ossman 
19311e72859eSPierre Ossman 	if (!dead)
19321c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_ALL);
19331c6a0718SPierre Ossman 
19341c6a0718SPierre Ossman 	free_irq(host->irq, host);
19351c6a0718SPierre Ossman 
19361c6a0718SPierre Ossman 	del_timer_sync(&host->timer);
19371c6a0718SPierre Ossman 
19381c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
19391c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
19402134a922SPierre Ossman 
19412134a922SPierre Ossman 	kfree(host->adma_desc);
19422134a922SPierre Ossman 	kfree(host->align_buffer);
19432134a922SPierre Ossman 
19442134a922SPierre Ossman 	host->adma_desc = NULL;
19452134a922SPierre Ossman 	host->align_buffer = NULL;
19461c6a0718SPierre Ossman }
19471c6a0718SPierre Ossman 
1948b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host);
1949b8c86fc5SPierre Ossman 
1950b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host)
19511c6a0718SPierre Ossman {
1952b8c86fc5SPierre Ossman 	mmc_free_host(host->mmc);
19531c6a0718SPierre Ossman }
19541c6a0718SPierre Ossman 
1955b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host);
19561c6a0718SPierre Ossman 
19571c6a0718SPierre Ossman /*****************************************************************************\
19581c6a0718SPierre Ossman  *                                                                           *
19591c6a0718SPierre Ossman  * Driver init/exit                                                          *
19601c6a0718SPierre Ossman  *                                                                           *
19611c6a0718SPierre Ossman \*****************************************************************************/
19621c6a0718SPierre Ossman 
19631c6a0718SPierre Ossman static int __init sdhci_drv_init(void)
19641c6a0718SPierre Ossman {
19651c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME
19661c6a0718SPierre Ossman 		": Secure Digital Host Controller Interface driver\n");
19671c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
19681c6a0718SPierre Ossman 
1969b8c86fc5SPierre Ossman 	return 0;
19701c6a0718SPierre Ossman }
19711c6a0718SPierre Ossman 
19721c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void)
19731c6a0718SPierre Ossman {
19741c6a0718SPierre Ossman }
19751c6a0718SPierre Ossman 
19761c6a0718SPierre Ossman module_init(sdhci_drv_init);
19771c6a0718SPierre Ossman module_exit(sdhci_drv_exit);
19781c6a0718SPierre Ossman 
19791c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444);
19801c6a0718SPierre Ossman 
198132710e8fSPierre Ossman MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
1982b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
19831c6a0718SPierre Ossman MODULE_LICENSE("GPL");
19841c6a0718SPierre Ossman 
19851c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
1986