xref: /openbmc/linux/drivers/mmc/host/sdhci.c (revision 4a3cba32)
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 
331c6a0718SPierre Ossman static unsigned int debug_quirks = 0;
341c6a0718SPierre Ossman 
351c6a0718SPierre Ossman static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
361c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *);
371c6a0718SPierre Ossman 
381c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
391c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *);
401c6a0718SPierre Ossman 
411c6a0718SPierre Ossman static void sdhci_dumpregs(struct sdhci_host *host)
421c6a0718SPierre Ossman {
431c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
441c6a0718SPierre Ossman 
451c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
461c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_DMA_ADDRESS),
471c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_HOST_VERSION));
481c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
491c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_BLOCK_SIZE),
501c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_BLOCK_COUNT));
511c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
521c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_ARGUMENT),
531c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_TRANSFER_MODE));
541c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
551c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_PRESENT_STATE),
561c6a0718SPierre Ossman 		readb(host->ioaddr + SDHCI_HOST_CONTROL));
571c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
581c6a0718SPierre Ossman 		readb(host->ioaddr + SDHCI_POWER_CONTROL),
591c6a0718SPierre Ossman 		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
601c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
612df3b71bSNicolas Pitre 		readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
621c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
631c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
641c6a0718SPierre Ossman 		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
651c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_INT_STATUS));
661c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
671c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_INT_ENABLE),
681c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
691c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
701c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_ACMD12_ERR),
711c6a0718SPierre Ossman 		readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
721c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
731c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_CAPABILITIES),
741c6a0718SPierre Ossman 		readl(host->ioaddr + SDHCI_MAX_CURRENT));
751c6a0718SPierre Ossman 
761c6a0718SPierre Ossman 	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
771c6a0718SPierre Ossman }
781c6a0718SPierre Ossman 
791c6a0718SPierre Ossman /*****************************************************************************\
801c6a0718SPierre Ossman  *                                                                           *
811c6a0718SPierre Ossman  * Low level functions                                                       *
821c6a0718SPierre Ossman  *                                                                           *
831c6a0718SPierre Ossman \*****************************************************************************/
841c6a0718SPierre Ossman 
851c6a0718SPierre Ossman static void sdhci_reset(struct sdhci_host *host, u8 mask)
861c6a0718SPierre Ossman {
871c6a0718SPierre Ossman 	unsigned long timeout;
881c6a0718SPierre Ossman 
89b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
901c6a0718SPierre Ossman 		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
911c6a0718SPierre Ossman 			SDHCI_CARD_PRESENT))
921c6a0718SPierre Ossman 			return;
931c6a0718SPierre Ossman 	}
941c6a0718SPierre Ossman 
951c6a0718SPierre Ossman 	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
961c6a0718SPierre Ossman 
971c6a0718SPierre Ossman 	if (mask & SDHCI_RESET_ALL)
981c6a0718SPierre Ossman 		host->clock = 0;
991c6a0718SPierre Ossman 
1001c6a0718SPierre Ossman 	/* Wait max 100 ms */
1011c6a0718SPierre Ossman 	timeout = 100;
1021c6a0718SPierre Ossman 
1031c6a0718SPierre Ossman 	/* hw clears the bit when it's done */
1041c6a0718SPierre Ossman 	while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
1051c6a0718SPierre Ossman 		if (timeout == 0) {
1061c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
1071c6a0718SPierre Ossman 				mmc_hostname(host->mmc), (int)mask);
1081c6a0718SPierre Ossman 			sdhci_dumpregs(host);
1091c6a0718SPierre Ossman 			return;
1101c6a0718SPierre Ossman 		}
1111c6a0718SPierre Ossman 		timeout--;
1121c6a0718SPierre Ossman 		mdelay(1);
1131c6a0718SPierre Ossman 	}
1141c6a0718SPierre Ossman }
1151c6a0718SPierre Ossman 
1161c6a0718SPierre Ossman static void sdhci_init(struct sdhci_host *host)
1171c6a0718SPierre Ossman {
1181c6a0718SPierre Ossman 	u32 intmask;
1191c6a0718SPierre Ossman 
1201c6a0718SPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
1211c6a0718SPierre Ossman 
1221c6a0718SPierre Ossman 	intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
1231c6a0718SPierre Ossman 		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
1241c6a0718SPierre Ossman 		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
1251c6a0718SPierre Ossman 		SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
1261c6a0718SPierre Ossman 		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
1272134a922SPierre Ossman 		SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
1282134a922SPierre Ossman 		SDHCI_INT_ADMA_ERROR;
1291c6a0718SPierre Ossman 
1301c6a0718SPierre Ossman 	writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
1311c6a0718SPierre Ossman 	writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
1321c6a0718SPierre Ossman }
1331c6a0718SPierre Ossman 
1341c6a0718SPierre Ossman static void sdhci_activate_led(struct sdhci_host *host)
1351c6a0718SPierre Ossman {
1361c6a0718SPierre Ossman 	u8 ctrl;
1371c6a0718SPierre Ossman 
1381c6a0718SPierre Ossman 	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
1391c6a0718SPierre Ossman 	ctrl |= SDHCI_CTRL_LED;
1401c6a0718SPierre Ossman 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
1411c6a0718SPierre Ossman }
1421c6a0718SPierre Ossman 
1431c6a0718SPierre Ossman static void sdhci_deactivate_led(struct sdhci_host *host)
1441c6a0718SPierre Ossman {
1451c6a0718SPierre Ossman 	u8 ctrl;
1461c6a0718SPierre Ossman 
1471c6a0718SPierre Ossman 	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
1481c6a0718SPierre Ossman 	ctrl &= ~SDHCI_CTRL_LED;
1491c6a0718SPierre Ossman 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
1501c6a0718SPierre Ossman }
1511c6a0718SPierre Ossman 
1522f730fecSPierre Ossman #ifdef CONFIG_LEDS_CLASS
1532f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led,
1542f730fecSPierre Ossman 	enum led_brightness brightness)
1552f730fecSPierre Ossman {
1562f730fecSPierre Ossman 	struct sdhci_host *host = container_of(led, struct sdhci_host, led);
1572f730fecSPierre Ossman 	unsigned long flags;
1582f730fecSPierre Ossman 
1592f730fecSPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
1602f730fecSPierre Ossman 
1612f730fecSPierre Ossman 	if (brightness == LED_OFF)
1622f730fecSPierre Ossman 		sdhci_deactivate_led(host);
1632f730fecSPierre Ossman 	else
1642f730fecSPierre Ossman 		sdhci_activate_led(host);
1652f730fecSPierre Ossman 
1662f730fecSPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
1672f730fecSPierre Ossman }
1682f730fecSPierre Ossman #endif
1692f730fecSPierre Ossman 
1701c6a0718SPierre Ossman /*****************************************************************************\
1711c6a0718SPierre Ossman  *                                                                           *
1721c6a0718SPierre Ossman  * Core functions                                                            *
1731c6a0718SPierre Ossman  *                                                                           *
1741c6a0718SPierre Ossman \*****************************************************************************/
1751c6a0718SPierre Ossman 
1761c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host)
1771c6a0718SPierre Ossman {
1787659150cSPierre Ossman 	unsigned long flags;
1797659150cSPierre Ossman 	size_t blksize, len, chunk;
1807659150cSPierre Ossman 	u32 scratch;
1817659150cSPierre Ossman 	u8 *buf;
1821c6a0718SPierre Ossman 
1831c6a0718SPierre Ossman 	DBG("PIO reading\n");
1841c6a0718SPierre Ossman 
1851c6a0718SPierre Ossman 	blksize = host->data->blksz;
1867659150cSPierre Ossman 	chunk = 0;
1871c6a0718SPierre Ossman 
1887659150cSPierre Ossman 	local_irq_save(flags);
1891c6a0718SPierre Ossman 
1901c6a0718SPierre Ossman 	while (blksize) {
1917659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
1927659150cSPierre Ossman 			BUG();
1937659150cSPierre Ossman 
1947659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
1957659150cSPierre Ossman 
1967659150cSPierre Ossman 		blksize -= len;
1977659150cSPierre Ossman 		host->sg_miter.consumed = len;
1987659150cSPierre Ossman 
1997659150cSPierre Ossman 		buf = host->sg_miter.addr;
2007659150cSPierre Ossman 
2017659150cSPierre Ossman 		while (len) {
2027659150cSPierre Ossman 			if (chunk == 0) {
2037659150cSPierre Ossman 				scratch = readl(host->ioaddr + SDHCI_BUFFER);
2047659150cSPierre Ossman 				chunk = 4;
2051c6a0718SPierre Ossman 			}
2061c6a0718SPierre Ossman 
2077659150cSPierre Ossman 			*buf = scratch & 0xFF;
2081c6a0718SPierre Ossman 
2097659150cSPierre Ossman 			buf++;
2107659150cSPierre Ossman 			scratch >>= 8;
2117659150cSPierre Ossman 			chunk--;
2127659150cSPierre Ossman 			len--;
2137659150cSPierre Ossman 		}
2141c6a0718SPierre Ossman 	}
2151c6a0718SPierre Ossman 
2167659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
2177659150cSPierre Ossman 
2187659150cSPierre Ossman 	local_irq_restore(flags);
2191c6a0718SPierre Ossman }
2201c6a0718SPierre Ossman 
2211c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host)
2221c6a0718SPierre Ossman {
2237659150cSPierre Ossman 	unsigned long flags;
2247659150cSPierre Ossman 	size_t blksize, len, chunk;
2257659150cSPierre Ossman 	u32 scratch;
2267659150cSPierre Ossman 	u8 *buf;
2271c6a0718SPierre Ossman 
2281c6a0718SPierre Ossman 	DBG("PIO writing\n");
2291c6a0718SPierre Ossman 
2301c6a0718SPierre Ossman 	blksize = host->data->blksz;
2317659150cSPierre Ossman 	chunk = 0;
2327659150cSPierre Ossman 	scratch = 0;
2331c6a0718SPierre Ossman 
2347659150cSPierre Ossman 	local_irq_save(flags);
2351c6a0718SPierre Ossman 
2361c6a0718SPierre Ossman 	while (blksize) {
2377659150cSPierre Ossman 		if (!sg_miter_next(&host->sg_miter))
2387659150cSPierre Ossman 			BUG();
2391c6a0718SPierre Ossman 
2407659150cSPierre Ossman 		len = min(host->sg_miter.length, blksize);
2411c6a0718SPierre Ossman 
2427659150cSPierre Ossman 		blksize -= len;
2437659150cSPierre Ossman 		host->sg_miter.consumed = len;
2447659150cSPierre Ossman 
2457659150cSPierre Ossman 		buf = host->sg_miter.addr;
2467659150cSPierre Ossman 
2477659150cSPierre Ossman 		while (len) {
2487659150cSPierre Ossman 			scratch |= (u32)*buf << (chunk * 8);
2497659150cSPierre Ossman 
2507659150cSPierre Ossman 			buf++;
2517659150cSPierre Ossman 			chunk++;
2527659150cSPierre Ossman 			len--;
2537659150cSPierre Ossman 
2547659150cSPierre Ossman 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
2557659150cSPierre Ossman 				writel(scratch, host->ioaddr + SDHCI_BUFFER);
2567659150cSPierre Ossman 				chunk = 0;
2577659150cSPierre Ossman 				scratch = 0;
2587659150cSPierre Ossman 			}
2597659150cSPierre Ossman 		}
2601c6a0718SPierre Ossman 	}
2611c6a0718SPierre Ossman 
2627659150cSPierre Ossman 	sg_miter_stop(&host->sg_miter);
2631c6a0718SPierre Ossman 
2647659150cSPierre Ossman 	local_irq_restore(flags);
2651c6a0718SPierre Ossman }
2661c6a0718SPierre Ossman 
2671c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host)
2681c6a0718SPierre Ossman {
2691c6a0718SPierre Ossman 	u32 mask;
2701c6a0718SPierre Ossman 
2711c6a0718SPierre Ossman 	BUG_ON(!host->data);
2721c6a0718SPierre Ossman 
2737659150cSPierre Ossman 	if (host->blocks == 0)
2741c6a0718SPierre Ossman 		return;
2751c6a0718SPierre Ossman 
2761c6a0718SPierre Ossman 	if (host->data->flags & MMC_DATA_READ)
2771c6a0718SPierre Ossman 		mask = SDHCI_DATA_AVAILABLE;
2781c6a0718SPierre Ossman 	else
2791c6a0718SPierre Ossman 		mask = SDHCI_SPACE_AVAILABLE;
2801c6a0718SPierre Ossman 
2814a3cba32SPierre Ossman 	/*
2824a3cba32SPierre Ossman 	 * Some controllers (JMicron JMB38x) mess up the buffer bits
2834a3cba32SPierre Ossman 	 * for transfers < 4 bytes. As long as it is just one block,
2844a3cba32SPierre Ossman 	 * we can ignore the bits.
2854a3cba32SPierre Ossman 	 */
2864a3cba32SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
2874a3cba32SPierre Ossman 		(host->data->blocks == 1))
2884a3cba32SPierre Ossman 		mask = ~0;
2894a3cba32SPierre Ossman 
2901c6a0718SPierre Ossman 	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
2911c6a0718SPierre Ossman 		if (host->data->flags & MMC_DATA_READ)
2921c6a0718SPierre Ossman 			sdhci_read_block_pio(host);
2931c6a0718SPierre Ossman 		else
2941c6a0718SPierre Ossman 			sdhci_write_block_pio(host);
2951c6a0718SPierre Ossman 
2967659150cSPierre Ossman 		host->blocks--;
2977659150cSPierre Ossman 		if (host->blocks == 0)
2981c6a0718SPierre Ossman 			break;
2991c6a0718SPierre Ossman 	}
3001c6a0718SPierre Ossman 
3011c6a0718SPierre Ossman 	DBG("PIO transfer complete.\n");
3021c6a0718SPierre Ossman }
3031c6a0718SPierre Ossman 
3042134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
3052134a922SPierre Ossman {
3062134a922SPierre Ossman 	local_irq_save(*flags);
3072134a922SPierre Ossman 	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
3082134a922SPierre Ossman }
3092134a922SPierre Ossman 
3102134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
3112134a922SPierre Ossman {
3122134a922SPierre Ossman 	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
3132134a922SPierre Ossman 	local_irq_restore(*flags);
3142134a922SPierre Ossman }
3152134a922SPierre Ossman 
3168f1934ceSPierre Ossman static int sdhci_adma_table_pre(struct sdhci_host *host,
3172134a922SPierre Ossman 	struct mmc_data *data)
3182134a922SPierre Ossman {
3192134a922SPierre Ossman 	int direction;
3202134a922SPierre Ossman 
3212134a922SPierre Ossman 	u8 *desc;
3222134a922SPierre Ossman 	u8 *align;
3232134a922SPierre Ossman 	dma_addr_t addr;
3242134a922SPierre Ossman 	dma_addr_t align_addr;
3252134a922SPierre Ossman 	int len, offset;
3262134a922SPierre Ossman 
3272134a922SPierre Ossman 	struct scatterlist *sg;
3282134a922SPierre Ossman 	int i;
3292134a922SPierre Ossman 	char *buffer;
3302134a922SPierre Ossman 	unsigned long flags;
3312134a922SPierre Ossman 
3322134a922SPierre Ossman 	/*
3332134a922SPierre Ossman 	 * The spec does not specify endianness of descriptor table.
3342134a922SPierre Ossman 	 * We currently guess that it is LE.
3352134a922SPierre Ossman 	 */
3362134a922SPierre Ossman 
3372134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
3382134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
3392134a922SPierre Ossman 	else
3402134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
3412134a922SPierre Ossman 
3422134a922SPierre Ossman 	/*
3432134a922SPierre Ossman 	 * The ADMA descriptor table is mapped further down as we
3442134a922SPierre Ossman 	 * need to fill it with data first.
3452134a922SPierre Ossman 	 */
3462134a922SPierre Ossman 
3472134a922SPierre Ossman 	host->align_addr = dma_map_single(mmc_dev(host->mmc),
3482134a922SPierre Ossman 		host->align_buffer, 128 * 4, direction);
3498d8bb39bSFUJITA Tomonori 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
3508f1934ceSPierre Ossman 		goto fail;
3512134a922SPierre Ossman 	BUG_ON(host->align_addr & 0x3);
3522134a922SPierre Ossman 
3532134a922SPierre Ossman 	host->sg_count = dma_map_sg(mmc_dev(host->mmc),
3542134a922SPierre Ossman 		data->sg, data->sg_len, direction);
3558f1934ceSPierre Ossman 	if (host->sg_count == 0)
3568f1934ceSPierre Ossman 		goto unmap_align;
3572134a922SPierre Ossman 
3582134a922SPierre Ossman 	desc = host->adma_desc;
3592134a922SPierre Ossman 	align = host->align_buffer;
3602134a922SPierre Ossman 
3612134a922SPierre Ossman 	align_addr = host->align_addr;
3622134a922SPierre Ossman 
3632134a922SPierre Ossman 	for_each_sg(data->sg, sg, host->sg_count, i) {
3642134a922SPierre Ossman 		addr = sg_dma_address(sg);
3652134a922SPierre Ossman 		len = sg_dma_len(sg);
3662134a922SPierre Ossman 
3672134a922SPierre Ossman 		/*
3682134a922SPierre Ossman 		 * The SDHCI specification states that ADMA
3692134a922SPierre Ossman 		 * addresses must be 32-bit aligned. If they
3702134a922SPierre Ossman 		 * aren't, then we use a bounce buffer for
3712134a922SPierre Ossman 		 * the (up to three) bytes that screw up the
3722134a922SPierre Ossman 		 * alignment.
3732134a922SPierre Ossman 		 */
3742134a922SPierre Ossman 		offset = (4 - (addr & 0x3)) & 0x3;
3752134a922SPierre Ossman 		if (offset) {
3762134a922SPierre Ossman 			if (data->flags & MMC_DATA_WRITE) {
3772134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
3786cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
3792134a922SPierre Ossman 				memcpy(align, buffer, offset);
3802134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
3812134a922SPierre Ossman 			}
3822134a922SPierre Ossman 
3832134a922SPierre Ossman 			desc[7] = (align_addr >> 24) & 0xff;
3842134a922SPierre Ossman 			desc[6] = (align_addr >> 16) & 0xff;
3852134a922SPierre Ossman 			desc[5] = (align_addr >> 8) & 0xff;
3862134a922SPierre Ossman 			desc[4] = (align_addr >> 0) & 0xff;
3872134a922SPierre Ossman 
3882134a922SPierre Ossman 			BUG_ON(offset > 65536);
3892134a922SPierre Ossman 
3902134a922SPierre Ossman 			desc[3] = (offset >> 8) & 0xff;
3912134a922SPierre Ossman 			desc[2] = (offset >> 0) & 0xff;
3922134a922SPierre Ossman 
3932134a922SPierre Ossman 			desc[1] = 0x00;
3942134a922SPierre Ossman 			desc[0] = 0x21; /* tran, valid */
3952134a922SPierre Ossman 
3962134a922SPierre Ossman 			align += 4;
3972134a922SPierre Ossman 			align_addr += 4;
3982134a922SPierre Ossman 
3992134a922SPierre Ossman 			desc += 8;
4002134a922SPierre Ossman 
4012134a922SPierre Ossman 			addr += offset;
4022134a922SPierre Ossman 			len -= offset;
4032134a922SPierre Ossman 		}
4042134a922SPierre Ossman 
4052134a922SPierre Ossman 		desc[7] = (addr >> 24) & 0xff;
4062134a922SPierre Ossman 		desc[6] = (addr >> 16) & 0xff;
4072134a922SPierre Ossman 		desc[5] = (addr >> 8) & 0xff;
4082134a922SPierre Ossman 		desc[4] = (addr >> 0) & 0xff;
4092134a922SPierre Ossman 
4102134a922SPierre Ossman 		BUG_ON(len > 65536);
4112134a922SPierre Ossman 
4122134a922SPierre Ossman 		desc[3] = (len >> 8) & 0xff;
4132134a922SPierre Ossman 		desc[2] = (len >> 0) & 0xff;
4142134a922SPierre Ossman 
4152134a922SPierre Ossman 		desc[1] = 0x00;
4162134a922SPierre Ossman 		desc[0] = 0x21; /* tran, valid */
4172134a922SPierre Ossman 
4182134a922SPierre Ossman 		desc += 8;
4192134a922SPierre Ossman 
4202134a922SPierre Ossman 		/*
4212134a922SPierre Ossman 		 * If this triggers then we have a calculation bug
4222134a922SPierre Ossman 		 * somewhere. :/
4232134a922SPierre Ossman 		 */
4242134a922SPierre Ossman 		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
4252134a922SPierre Ossman 	}
4262134a922SPierre Ossman 
4272134a922SPierre Ossman 	/*
4282134a922SPierre Ossman 	 * Add a terminating entry.
4292134a922SPierre Ossman 	 */
4302134a922SPierre Ossman 	desc[7] = 0;
4312134a922SPierre Ossman 	desc[6] = 0;
4322134a922SPierre Ossman 	desc[5] = 0;
4332134a922SPierre Ossman 	desc[4] = 0;
4342134a922SPierre Ossman 
4352134a922SPierre Ossman 	desc[3] = 0;
4362134a922SPierre Ossman 	desc[2] = 0;
4372134a922SPierre Ossman 
4382134a922SPierre Ossman 	desc[1] = 0x00;
4392134a922SPierre Ossman 	desc[0] = 0x03; /* nop, end, valid */
4402134a922SPierre Ossman 
4412134a922SPierre Ossman 	/*
4422134a922SPierre Ossman 	 * Resync align buffer as we might have changed it.
4432134a922SPierre Ossman 	 */
4442134a922SPierre Ossman 	if (data->flags & MMC_DATA_WRITE) {
4452134a922SPierre Ossman 		dma_sync_single_for_device(mmc_dev(host->mmc),
4462134a922SPierre Ossman 			host->align_addr, 128 * 4, direction);
4472134a922SPierre Ossman 	}
4482134a922SPierre Ossman 
4492134a922SPierre Ossman 	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
4502134a922SPierre Ossman 		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
4518d8bb39bSFUJITA Tomonori 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
4528f1934ceSPierre Ossman 		goto unmap_entries;
4532134a922SPierre Ossman 	BUG_ON(host->adma_addr & 0x3);
4548f1934ceSPierre Ossman 
4558f1934ceSPierre Ossman 	return 0;
4568f1934ceSPierre Ossman 
4578f1934ceSPierre Ossman unmap_entries:
4588f1934ceSPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
4598f1934ceSPierre Ossman 		data->sg_len, direction);
4608f1934ceSPierre Ossman unmap_align:
4618f1934ceSPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
4628f1934ceSPierre Ossman 		128 * 4, direction);
4638f1934ceSPierre Ossman fail:
4648f1934ceSPierre Ossman 	return -EINVAL;
4652134a922SPierre Ossman }
4662134a922SPierre Ossman 
4672134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host,
4682134a922SPierre Ossman 	struct mmc_data *data)
4692134a922SPierre Ossman {
4702134a922SPierre Ossman 	int direction;
4712134a922SPierre Ossman 
4722134a922SPierre Ossman 	struct scatterlist *sg;
4732134a922SPierre Ossman 	int i, size;
4742134a922SPierre Ossman 	u8 *align;
4752134a922SPierre Ossman 	char *buffer;
4762134a922SPierre Ossman 	unsigned long flags;
4772134a922SPierre Ossman 
4782134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ)
4792134a922SPierre Ossman 		direction = DMA_FROM_DEVICE;
4802134a922SPierre Ossman 	else
4812134a922SPierre Ossman 		direction = DMA_TO_DEVICE;
4822134a922SPierre Ossman 
4832134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
4842134a922SPierre Ossman 		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
4852134a922SPierre Ossman 
4862134a922SPierre Ossman 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
4872134a922SPierre Ossman 		128 * 4, direction);
4882134a922SPierre Ossman 
4892134a922SPierre Ossman 	if (data->flags & MMC_DATA_READ) {
4902134a922SPierre Ossman 		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
4912134a922SPierre Ossman 			data->sg_len, direction);
4922134a922SPierre Ossman 
4932134a922SPierre Ossman 		align = host->align_buffer;
4942134a922SPierre Ossman 
4952134a922SPierre Ossman 		for_each_sg(data->sg, sg, host->sg_count, i) {
4962134a922SPierre Ossman 			if (sg_dma_address(sg) & 0x3) {
4972134a922SPierre Ossman 				size = 4 - (sg_dma_address(sg) & 0x3);
4982134a922SPierre Ossman 
4992134a922SPierre Ossman 				buffer = sdhci_kmap_atomic(sg, &flags);
5006cefd05fSPierre Ossman 				WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
5012134a922SPierre Ossman 				memcpy(buffer, align, size);
5022134a922SPierre Ossman 				sdhci_kunmap_atomic(buffer, &flags);
5032134a922SPierre Ossman 
5042134a922SPierre Ossman 				align += 4;
5052134a922SPierre Ossman 			}
5062134a922SPierre Ossman 		}
5072134a922SPierre Ossman 	}
5082134a922SPierre Ossman 
5092134a922SPierre Ossman 	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
5102134a922SPierre Ossman 		data->sg_len, direction);
5112134a922SPierre Ossman }
5122134a922SPierre Ossman 
513ee53ab5dSPierre Ossman static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
5141c6a0718SPierre Ossman {
5151c6a0718SPierre Ossman 	u8 count;
5161c6a0718SPierre Ossman 	unsigned target_timeout, current_timeout;
5171c6a0718SPierre Ossman 
518ee53ab5dSPierre Ossman 	/*
519ee53ab5dSPierre Ossman 	 * If the host controller provides us with an incorrect timeout
520ee53ab5dSPierre Ossman 	 * value, just skip the check and use 0xE.  The hardware may take
521ee53ab5dSPierre Ossman 	 * longer to time out, but that's much better than having a too-short
522ee53ab5dSPierre Ossman 	 * timeout value.
523ee53ab5dSPierre Ossman 	 */
524ee53ab5dSPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL))
525ee53ab5dSPierre Ossman 		return 0xE;
526e538fbe8SPierre Ossman 
5271c6a0718SPierre Ossman 	/* timeout in us */
5281c6a0718SPierre Ossman 	target_timeout = data->timeout_ns / 1000 +
5291c6a0718SPierre Ossman 		data->timeout_clks / host->clock;
5301c6a0718SPierre Ossman 
5311c6a0718SPierre Ossman 	/*
5321c6a0718SPierre Ossman 	 * Figure out needed cycles.
5331c6a0718SPierre Ossman 	 * We do this in steps in order to fit inside a 32 bit int.
5341c6a0718SPierre Ossman 	 * The first step is the minimum timeout, which will have a
5351c6a0718SPierre Ossman 	 * minimum resolution of 6 bits:
5361c6a0718SPierre Ossman 	 * (1) 2^13*1000 > 2^22,
5371c6a0718SPierre Ossman 	 * (2) host->timeout_clk < 2^16
5381c6a0718SPierre Ossman 	 *     =>
5391c6a0718SPierre Ossman 	 *     (1) / (2) > 2^6
5401c6a0718SPierre Ossman 	 */
5411c6a0718SPierre Ossman 	count = 0;
5421c6a0718SPierre Ossman 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
5431c6a0718SPierre Ossman 	while (current_timeout < target_timeout) {
5441c6a0718SPierre Ossman 		count++;
5451c6a0718SPierre Ossman 		current_timeout <<= 1;
5461c6a0718SPierre Ossman 		if (count >= 0xF)
5471c6a0718SPierre Ossman 			break;
5481c6a0718SPierre Ossman 	}
5491c6a0718SPierre Ossman 
5501c6a0718SPierre Ossman 	if (count >= 0xF) {
5511c6a0718SPierre Ossman 		printk(KERN_WARNING "%s: Too large timeout requested!\n",
5521c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
5531c6a0718SPierre Ossman 		count = 0xE;
5541c6a0718SPierre Ossman 	}
5551c6a0718SPierre Ossman 
556ee53ab5dSPierre Ossman 	return count;
557ee53ab5dSPierre Ossman }
558ee53ab5dSPierre Ossman 
559ee53ab5dSPierre Ossman static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
560ee53ab5dSPierre Ossman {
561ee53ab5dSPierre Ossman 	u8 count;
5622134a922SPierre Ossman 	u8 ctrl;
5638f1934ceSPierre Ossman 	int ret;
564ee53ab5dSPierre Ossman 
565ee53ab5dSPierre Ossman 	WARN_ON(host->data);
566ee53ab5dSPierre Ossman 
567ee53ab5dSPierre Ossman 	if (data == NULL)
568ee53ab5dSPierre Ossman 		return;
569ee53ab5dSPierre Ossman 
570ee53ab5dSPierre Ossman 	/* Sanity checks */
571ee53ab5dSPierre Ossman 	BUG_ON(data->blksz * data->blocks > 524288);
572ee53ab5dSPierre Ossman 	BUG_ON(data->blksz > host->mmc->max_blk_size);
573ee53ab5dSPierre Ossman 	BUG_ON(data->blocks > 65535);
574ee53ab5dSPierre Ossman 
575ee53ab5dSPierre Ossman 	host->data = data;
576ee53ab5dSPierre Ossman 	host->data_early = 0;
577ee53ab5dSPierre Ossman 
578ee53ab5dSPierre Ossman 	count = sdhci_calc_timeout(host, data);
5791c6a0718SPierre Ossman 	writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
5801c6a0718SPierre Ossman 
581c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_USE_DMA)
582c9fddbc4SPierre Ossman 		host->flags |= SDHCI_REQ_USE_DMA;
583c9fddbc4SPierre Ossman 
5842134a922SPierre Ossman 	/*
5852134a922SPierre Ossman 	 * FIXME: This doesn't account for merging when mapping the
5862134a922SPierre Ossman 	 * scatterlist.
5872134a922SPierre Ossman 	 */
5882134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
5892134a922SPierre Ossman 		int broken, i;
5902134a922SPierre Ossman 		struct scatterlist *sg;
5912134a922SPierre Ossman 
5922134a922SPierre Ossman 		broken = 0;
5932134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
5942134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
5952134a922SPierre Ossman 				broken = 1;
5962134a922SPierre Ossman 		} else {
5972134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
5982134a922SPierre Ossman 				broken = 1;
5992134a922SPierre Ossman 		}
6002134a922SPierre Ossman 
6012134a922SPierre Ossman 		if (unlikely(broken)) {
6022134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
6032134a922SPierre Ossman 				if (sg->length & 0x3) {
6042134a922SPierre Ossman 					DBG("Reverting to PIO because of "
6052134a922SPierre Ossman 						"transfer size (%d)\n",
6062134a922SPierre Ossman 						sg->length);
607c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
6082134a922SPierre Ossman 					break;
6092134a922SPierre Ossman 				}
6102134a922SPierre Ossman 			}
6112134a922SPierre Ossman 		}
612c9fddbc4SPierre Ossman 	}
613c9fddbc4SPierre Ossman 
614c9fddbc4SPierre Ossman 	/*
615c9fddbc4SPierre Ossman 	 * The assumption here being that alignment is the same after
616c9fddbc4SPierre Ossman 	 * translation to device address space.
617c9fddbc4SPierre Ossman 	 */
6182134a922SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
6192134a922SPierre Ossman 		int broken, i;
6202134a922SPierre Ossman 		struct scatterlist *sg;
6212134a922SPierre Ossman 
6222134a922SPierre Ossman 		broken = 0;
6232134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
6242134a922SPierre Ossman 			/*
6252134a922SPierre Ossman 			 * As we use 3 byte chunks to work around
6262134a922SPierre Ossman 			 * alignment problems, we need to check this
6272134a922SPierre Ossman 			 * quirk.
6282134a922SPierre Ossman 			 */
6292134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
6302134a922SPierre Ossman 				broken = 1;
6312134a922SPierre Ossman 		} else {
6322134a922SPierre Ossman 			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
6332134a922SPierre Ossman 				broken = 1;
6342134a922SPierre Ossman 		}
6352134a922SPierre Ossman 
6362134a922SPierre Ossman 		if (unlikely(broken)) {
6372134a922SPierre Ossman 			for_each_sg(data->sg, sg, data->sg_len, i) {
6382134a922SPierre Ossman 				if (sg->offset & 0x3) {
6392134a922SPierre Ossman 					DBG("Reverting to PIO because of "
6402134a922SPierre Ossman 						"bad alignment\n");
641c9fddbc4SPierre Ossman 					host->flags &= ~SDHCI_REQ_USE_DMA;
6422134a922SPierre Ossman 					break;
6432134a922SPierre Ossman 				}
6442134a922SPierre Ossman 			}
6452134a922SPierre Ossman 		}
6462134a922SPierre Ossman 	}
6472134a922SPierre Ossman 
6488f1934ceSPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
6498f1934ceSPierre Ossman 		if (host->flags & SDHCI_USE_ADMA) {
6508f1934ceSPierre Ossman 			ret = sdhci_adma_table_pre(host, data);
6518f1934ceSPierre Ossman 			if (ret) {
6528f1934ceSPierre Ossman 				/*
6538f1934ceSPierre Ossman 				 * This only happens when someone fed
6548f1934ceSPierre Ossman 				 * us an invalid request.
6558f1934ceSPierre Ossman 				 */
6568f1934ceSPierre Ossman 				WARN_ON(1);
6578f1934ceSPierre Ossman 				host->flags &= ~SDHCI_USE_DMA;
6588f1934ceSPierre Ossman 			} else {
6598f1934ceSPierre Ossman 				writel(host->adma_addr,
6608f1934ceSPierre Ossman 					host->ioaddr + SDHCI_ADMA_ADDRESS);
6618f1934ceSPierre Ossman 			}
6628f1934ceSPierre Ossman 		} else {
663c8b3e02eSTomas Winkler 			int sg_cnt;
6648f1934ceSPierre Ossman 
665c8b3e02eSTomas Winkler 			sg_cnt = dma_map_sg(mmc_dev(host->mmc),
6668f1934ceSPierre Ossman 					data->sg, data->sg_len,
6678f1934ceSPierre Ossman 					(data->flags & MMC_DATA_READ) ?
6688f1934ceSPierre Ossman 						DMA_FROM_DEVICE :
6698f1934ceSPierre Ossman 						DMA_TO_DEVICE);
670c8b3e02eSTomas Winkler 			if (sg_cnt == 0) {
6718f1934ceSPierre Ossman 				/*
6728f1934ceSPierre Ossman 				 * This only happens when someone fed
6738f1934ceSPierre Ossman 				 * us an invalid request.
6748f1934ceSPierre Ossman 				 */
6758f1934ceSPierre Ossman 				WARN_ON(1);
6768f1934ceSPierre Ossman 				host->flags &= ~SDHCI_USE_DMA;
6778f1934ceSPierre Ossman 			} else {
678719a61b4SPierre Ossman 				WARN_ON(sg_cnt != 1);
6798f1934ceSPierre Ossman 				writel(sg_dma_address(data->sg),
6808f1934ceSPierre Ossman 					host->ioaddr + SDHCI_DMA_ADDRESS);
6818f1934ceSPierre Ossman 			}
6828f1934ceSPierre Ossman 		}
6838f1934ceSPierre Ossman 	}
6848f1934ceSPierre Ossman 
6852134a922SPierre Ossman 	/*
6862134a922SPierre Ossman 	 * Always adjust the DMA selection as some controllers
6872134a922SPierre Ossman 	 * (e.g. JMicron) can't do PIO properly when the selection
6882134a922SPierre Ossman 	 * is ADMA.
6892134a922SPierre Ossman 	 */
6902134a922SPierre Ossman 	if (host->version >= SDHCI_SPEC_200) {
6912134a922SPierre Ossman 		ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
6922134a922SPierre Ossman 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
6932134a922SPierre Ossman 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
6942134a922SPierre Ossman 			(host->flags & SDHCI_USE_ADMA))
6952134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_ADMA32;
6962134a922SPierre Ossman 		else
6972134a922SPierre Ossman 			ctrl |= SDHCI_CTRL_SDMA;
6982134a922SPierre Ossman 		writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
699c9fddbc4SPierre Ossman 	}
700c9fddbc4SPierre Ossman 
7018f1934ceSPierre Ossman 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
7027659150cSPierre Ossman 		sg_miter_start(&host->sg_miter,
7037659150cSPierre Ossman 			data->sg, data->sg_len, SG_MITER_ATOMIC);
7047659150cSPierre Ossman 		host->blocks = data->blocks;
7051c6a0718SPierre Ossman 	}
7061c6a0718SPierre Ossman 
7071c6a0718SPierre Ossman 	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
7081c6a0718SPierre Ossman 	writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
7091c6a0718SPierre Ossman 		host->ioaddr + SDHCI_BLOCK_SIZE);
7101c6a0718SPierre Ossman 	writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
7111c6a0718SPierre Ossman }
7121c6a0718SPierre Ossman 
7131c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host,
7141c6a0718SPierre Ossman 	struct mmc_data *data)
7151c6a0718SPierre Ossman {
7161c6a0718SPierre Ossman 	u16 mode;
7171c6a0718SPierre Ossman 
7181c6a0718SPierre Ossman 	if (data == NULL)
7191c6a0718SPierre Ossman 		return;
7201c6a0718SPierre Ossman 
721e538fbe8SPierre Ossman 	WARN_ON(!host->data);
722e538fbe8SPierre Ossman 
7231c6a0718SPierre Ossman 	mode = SDHCI_TRNS_BLK_CNT_EN;
7241c6a0718SPierre Ossman 	if (data->blocks > 1)
7251c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_MULTI;
7261c6a0718SPierre Ossman 	if (data->flags & MMC_DATA_READ)
7271c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_READ;
728c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA)
7291c6a0718SPierre Ossman 		mode |= SDHCI_TRNS_DMA;
7301c6a0718SPierre Ossman 
7311c6a0718SPierre Ossman 	writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
7321c6a0718SPierre Ossman }
7331c6a0718SPierre Ossman 
7341c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host)
7351c6a0718SPierre Ossman {
7361c6a0718SPierre Ossman 	struct mmc_data *data;
7371c6a0718SPierre Ossman 
7381c6a0718SPierre Ossman 	BUG_ON(!host->data);
7391c6a0718SPierre Ossman 
7401c6a0718SPierre Ossman 	data = host->data;
7411c6a0718SPierre Ossman 	host->data = NULL;
7421c6a0718SPierre Ossman 
743c9fddbc4SPierre Ossman 	if (host->flags & SDHCI_REQ_USE_DMA) {
7442134a922SPierre Ossman 		if (host->flags & SDHCI_USE_ADMA)
7452134a922SPierre Ossman 			sdhci_adma_table_post(host, data);
7462134a922SPierre Ossman 		else {
7472134a922SPierre Ossman 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
7482134a922SPierre Ossman 				data->sg_len, (data->flags & MMC_DATA_READ) ?
749b8c86fc5SPierre Ossman 					DMA_FROM_DEVICE : DMA_TO_DEVICE);
7501c6a0718SPierre Ossman 		}
7512134a922SPierre Ossman 	}
7521c6a0718SPierre Ossman 
7531c6a0718SPierre Ossman 	/*
754c9b74c5bSPierre Ossman 	 * The specification states that the block count register must
755c9b74c5bSPierre Ossman 	 * be updated, but it does not specify at what point in the
756c9b74c5bSPierre Ossman 	 * data flow. That makes the register entirely useless to read
757c9b74c5bSPierre Ossman 	 * back so we have to assume that nothing made it to the card
758c9b74c5bSPierre Ossman 	 * in the event of an error.
7591c6a0718SPierre Ossman 	 */
760c9b74c5bSPierre Ossman 	if (data->error)
761c9b74c5bSPierre Ossman 		data->bytes_xfered = 0;
7621c6a0718SPierre Ossman 	else
763c9b74c5bSPierre Ossman 		data->bytes_xfered = data->blksz * data->blocks;
7641c6a0718SPierre Ossman 
7651c6a0718SPierre Ossman 	if (data->stop) {
7661c6a0718SPierre Ossman 		/*
7671c6a0718SPierre Ossman 		 * The controller needs a reset of internal state machines
7681c6a0718SPierre Ossman 		 * upon error conditions.
7691c6a0718SPierre Ossman 		 */
77017b0429dSPierre Ossman 		if (data->error) {
7711c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
7721c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
7731c6a0718SPierre Ossman 		}
7741c6a0718SPierre Ossman 
7751c6a0718SPierre Ossman 		sdhci_send_command(host, data->stop);
7761c6a0718SPierre Ossman 	} else
7771c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
7781c6a0718SPierre Ossman }
7791c6a0718SPierre Ossman 
7801c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
7811c6a0718SPierre Ossman {
7821c6a0718SPierre Ossman 	int flags;
7831c6a0718SPierre Ossman 	u32 mask;
7841c6a0718SPierre Ossman 	unsigned long timeout;
7851c6a0718SPierre Ossman 
7861c6a0718SPierre Ossman 	WARN_ON(host->cmd);
7871c6a0718SPierre Ossman 
7881c6a0718SPierre Ossman 	/* Wait max 10 ms */
7891c6a0718SPierre Ossman 	timeout = 10;
7901c6a0718SPierre Ossman 
7911c6a0718SPierre Ossman 	mask = SDHCI_CMD_INHIBIT;
7921c6a0718SPierre Ossman 	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
7931c6a0718SPierre Ossman 		mask |= SDHCI_DATA_INHIBIT;
7941c6a0718SPierre Ossman 
7951c6a0718SPierre Ossman 	/* We shouldn't wait for data inihibit for stop commands, even
7961c6a0718SPierre Ossman 	   though they might use busy signaling */
7971c6a0718SPierre Ossman 	if (host->mrq->data && (cmd == host->mrq->data->stop))
7981c6a0718SPierre Ossman 		mask &= ~SDHCI_DATA_INHIBIT;
7991c6a0718SPierre Ossman 
8001c6a0718SPierre Ossman 	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
8011c6a0718SPierre Ossman 		if (timeout == 0) {
8021c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Controller never released "
8031c6a0718SPierre Ossman 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
8041c6a0718SPierre Ossman 			sdhci_dumpregs(host);
80517b0429dSPierre Ossman 			cmd->error = -EIO;
8061c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
8071c6a0718SPierre Ossman 			return;
8081c6a0718SPierre Ossman 		}
8091c6a0718SPierre Ossman 		timeout--;
8101c6a0718SPierre Ossman 		mdelay(1);
8111c6a0718SPierre Ossman 	}
8121c6a0718SPierre Ossman 
8131c6a0718SPierre Ossman 	mod_timer(&host->timer, jiffies + 10 * HZ);
8141c6a0718SPierre Ossman 
8151c6a0718SPierre Ossman 	host->cmd = cmd;
8161c6a0718SPierre Ossman 
8171c6a0718SPierre Ossman 	sdhci_prepare_data(host, cmd->data);
8181c6a0718SPierre Ossman 
8191c6a0718SPierre Ossman 	writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
8201c6a0718SPierre Ossman 
8211c6a0718SPierre Ossman 	sdhci_set_transfer_mode(host, cmd->data);
8221c6a0718SPierre Ossman 
8231c6a0718SPierre Ossman 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
8241c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unsupported response type!\n",
8251c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
82617b0429dSPierre Ossman 		cmd->error = -EINVAL;
8271c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
8281c6a0718SPierre Ossman 		return;
8291c6a0718SPierre Ossman 	}
8301c6a0718SPierre Ossman 
8311c6a0718SPierre Ossman 	if (!(cmd->flags & MMC_RSP_PRESENT))
8321c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_NONE;
8331c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_136)
8341c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_LONG;
8351c6a0718SPierre Ossman 	else if (cmd->flags & MMC_RSP_BUSY)
8361c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT_BUSY;
8371c6a0718SPierre Ossman 	else
8381c6a0718SPierre Ossman 		flags = SDHCI_CMD_RESP_SHORT;
8391c6a0718SPierre Ossman 
8401c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_CRC)
8411c6a0718SPierre Ossman 		flags |= SDHCI_CMD_CRC;
8421c6a0718SPierre Ossman 	if (cmd->flags & MMC_RSP_OPCODE)
8431c6a0718SPierre Ossman 		flags |= SDHCI_CMD_INDEX;
8441c6a0718SPierre Ossman 	if (cmd->data)
8451c6a0718SPierre Ossman 		flags |= SDHCI_CMD_DATA;
8461c6a0718SPierre Ossman 
8471c6a0718SPierre Ossman 	writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
8481c6a0718SPierre Ossman 		host->ioaddr + SDHCI_COMMAND);
8491c6a0718SPierre Ossman }
8501c6a0718SPierre Ossman 
8511c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host)
8521c6a0718SPierre Ossman {
8531c6a0718SPierre Ossman 	int i;
8541c6a0718SPierre Ossman 
8551c6a0718SPierre Ossman 	BUG_ON(host->cmd == NULL);
8561c6a0718SPierre Ossman 
8571c6a0718SPierre Ossman 	if (host->cmd->flags & MMC_RSP_PRESENT) {
8581c6a0718SPierre Ossman 		if (host->cmd->flags & MMC_RSP_136) {
8591c6a0718SPierre Ossman 			/* CRC is stripped so we need to do some shifting. */
8601c6a0718SPierre Ossman 			for (i = 0;i < 4;i++) {
8611c6a0718SPierre Ossman 				host->cmd->resp[i] = readl(host->ioaddr +
8621c6a0718SPierre Ossman 					SDHCI_RESPONSE + (3-i)*4) << 8;
8631c6a0718SPierre Ossman 				if (i != 3)
8641c6a0718SPierre Ossman 					host->cmd->resp[i] |=
8651c6a0718SPierre Ossman 						readb(host->ioaddr +
8661c6a0718SPierre Ossman 						SDHCI_RESPONSE + (3-i)*4-1);
8671c6a0718SPierre Ossman 			}
8681c6a0718SPierre Ossman 		} else {
8691c6a0718SPierre Ossman 			host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
8701c6a0718SPierre Ossman 		}
8711c6a0718SPierre Ossman 	}
8721c6a0718SPierre Ossman 
87317b0429dSPierre Ossman 	host->cmd->error = 0;
8741c6a0718SPierre Ossman 
875e538fbe8SPierre Ossman 	if (host->data && host->data_early)
876e538fbe8SPierre Ossman 		sdhci_finish_data(host);
877e538fbe8SPierre Ossman 
878e538fbe8SPierre Ossman 	if (!host->cmd->data)
8791c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
8801c6a0718SPierre Ossman 
8811c6a0718SPierre Ossman 	host->cmd = NULL;
8821c6a0718SPierre Ossman }
8831c6a0718SPierre Ossman 
8841c6a0718SPierre Ossman static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
8851c6a0718SPierre Ossman {
8861c6a0718SPierre Ossman 	int div;
8871c6a0718SPierre Ossman 	u16 clk;
8881c6a0718SPierre Ossman 	unsigned long timeout;
8891c6a0718SPierre Ossman 
8901c6a0718SPierre Ossman 	if (clock == host->clock)
8911c6a0718SPierre Ossman 		return;
8921c6a0718SPierre Ossman 
8931c6a0718SPierre Ossman 	writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
8941c6a0718SPierre Ossman 
8951c6a0718SPierre Ossman 	if (clock == 0)
8961c6a0718SPierre Ossman 		goto out;
8971c6a0718SPierre Ossman 
8981c6a0718SPierre Ossman 	for (div = 1;div < 256;div *= 2) {
8991c6a0718SPierre Ossman 		if ((host->max_clk / div) <= clock)
9001c6a0718SPierre Ossman 			break;
9011c6a0718SPierre Ossman 	}
9021c6a0718SPierre Ossman 	div >>= 1;
9031c6a0718SPierre Ossman 
9041c6a0718SPierre Ossman 	clk = div << SDHCI_DIVIDER_SHIFT;
9051c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_INT_EN;
9061c6a0718SPierre Ossman 	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
9071c6a0718SPierre Ossman 
9081c6a0718SPierre Ossman 	/* Wait max 10 ms */
9091c6a0718SPierre Ossman 	timeout = 10;
9101c6a0718SPierre Ossman 	while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
9111c6a0718SPierre Ossman 		& SDHCI_CLOCK_INT_STABLE)) {
9121c6a0718SPierre Ossman 		if (timeout == 0) {
9131c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Internal clock never "
9141c6a0718SPierre Ossman 				"stabilised.\n", mmc_hostname(host->mmc));
9151c6a0718SPierre Ossman 			sdhci_dumpregs(host);
9161c6a0718SPierre Ossman 			return;
9171c6a0718SPierre Ossman 		}
9181c6a0718SPierre Ossman 		timeout--;
9191c6a0718SPierre Ossman 		mdelay(1);
9201c6a0718SPierre Ossman 	}
9211c6a0718SPierre Ossman 
9221c6a0718SPierre Ossman 	clk |= SDHCI_CLOCK_CARD_EN;
9231c6a0718SPierre Ossman 	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
9241c6a0718SPierre Ossman 
9251c6a0718SPierre Ossman out:
9261c6a0718SPierre Ossman 	host->clock = clock;
9271c6a0718SPierre Ossman }
9281c6a0718SPierre Ossman 
9291c6a0718SPierre Ossman static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
9301c6a0718SPierre Ossman {
9311c6a0718SPierre Ossman 	u8 pwr;
9321c6a0718SPierre Ossman 
9331c6a0718SPierre Ossman 	if (host->power == power)
9341c6a0718SPierre Ossman 		return;
9351c6a0718SPierre Ossman 
9361c6a0718SPierre Ossman 	if (power == (unsigned short)-1) {
9371c6a0718SPierre Ossman 		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
9381c6a0718SPierre Ossman 		goto out;
9391c6a0718SPierre Ossman 	}
9401c6a0718SPierre Ossman 
9411c6a0718SPierre Ossman 	/*
9421c6a0718SPierre Ossman 	 * Spec says that we should clear the power reg before setting
9431c6a0718SPierre Ossman 	 * a new value. Some controllers don't seem to like this though.
9441c6a0718SPierre Ossman 	 */
945b8c86fc5SPierre Ossman 	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
9461c6a0718SPierre Ossman 		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
9471c6a0718SPierre Ossman 
9481c6a0718SPierre Ossman 	pwr = SDHCI_POWER_ON;
9491c6a0718SPierre Ossman 
9504be34c99SPhilip Langdale 	switch (1 << power) {
95155556da0SPhilip Langdale 	case MMC_VDD_165_195:
9521c6a0718SPierre Ossman 		pwr |= SDHCI_POWER_180;
9531c6a0718SPierre Ossman 		break;
9544be34c99SPhilip Langdale 	case MMC_VDD_29_30:
9554be34c99SPhilip Langdale 	case MMC_VDD_30_31:
9561c6a0718SPierre Ossman 		pwr |= SDHCI_POWER_300;
9571c6a0718SPierre Ossman 		break;
9584be34c99SPhilip Langdale 	case MMC_VDD_32_33:
9594be34c99SPhilip Langdale 	case MMC_VDD_33_34:
9601c6a0718SPierre Ossman 		pwr |= SDHCI_POWER_330;
9611c6a0718SPierre Ossman 		break;
9621c6a0718SPierre Ossman 	default:
9631c6a0718SPierre Ossman 		BUG();
9641c6a0718SPierre Ossman 	}
9651c6a0718SPierre Ossman 
966e08c1694SAndres Salomon 	/*
967c71f6512SAndres Salomon 	 * At least the Marvell CaFe chip gets confused if we set the voltage
968e08c1694SAndres Salomon 	 * and set turn on power at the same time, so set the voltage first.
969e08c1694SAndres Salomon 	 */
970b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
971e08c1694SAndres Salomon 		writeb(pwr & ~SDHCI_POWER_ON,
972e08c1694SAndres Salomon 				host->ioaddr + SDHCI_POWER_CONTROL);
973e08c1694SAndres Salomon 
9741c6a0718SPierre Ossman 	writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
9751c6a0718SPierre Ossman 
9761c6a0718SPierre Ossman out:
9771c6a0718SPierre Ossman 	host->power = power;
9781c6a0718SPierre Ossman }
9791c6a0718SPierre Ossman 
9801c6a0718SPierre Ossman /*****************************************************************************\
9811c6a0718SPierre Ossman  *                                                                           *
9821c6a0718SPierre Ossman  * MMC callbacks                                                             *
9831c6a0718SPierre Ossman  *                                                                           *
9841c6a0718SPierre Ossman \*****************************************************************************/
9851c6a0718SPierre Ossman 
9861c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
9871c6a0718SPierre Ossman {
9881c6a0718SPierre Ossman 	struct sdhci_host *host;
9891c6a0718SPierre Ossman 	unsigned long flags;
9901c6a0718SPierre Ossman 
9911c6a0718SPierre Ossman 	host = mmc_priv(mmc);
9921c6a0718SPierre Ossman 
9931c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
9941c6a0718SPierre Ossman 
9951c6a0718SPierre Ossman 	WARN_ON(host->mrq != NULL);
9961c6a0718SPierre Ossman 
9972f730fecSPierre Ossman #ifndef CONFIG_LEDS_CLASS
9981c6a0718SPierre Ossman 	sdhci_activate_led(host);
9992f730fecSPierre Ossman #endif
10001c6a0718SPierre Ossman 
10011c6a0718SPierre Ossman 	host->mrq = mrq;
10021c6a0718SPierre Ossman 
10031e72859eSPierre Ossman 	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
10041e72859eSPierre Ossman 		|| (host->flags & SDHCI_DEVICE_DEAD)) {
100517b0429dSPierre Ossman 		host->mrq->cmd->error = -ENOMEDIUM;
10061c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
10071c6a0718SPierre Ossman 	} else
10081c6a0718SPierre Ossman 		sdhci_send_command(host, mrq->cmd);
10091c6a0718SPierre Ossman 
10101c6a0718SPierre Ossman 	mmiowb();
10111c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
10121c6a0718SPierre Ossman }
10131c6a0718SPierre Ossman 
10141c6a0718SPierre Ossman static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
10151c6a0718SPierre Ossman {
10161c6a0718SPierre Ossman 	struct sdhci_host *host;
10171c6a0718SPierre Ossman 	unsigned long flags;
10181c6a0718SPierre Ossman 	u8 ctrl;
10191c6a0718SPierre Ossman 
10201c6a0718SPierre Ossman 	host = mmc_priv(mmc);
10211c6a0718SPierre Ossman 
10221c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
10231c6a0718SPierre Ossman 
10241e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
10251e72859eSPierre Ossman 		goto out;
10261e72859eSPierre Ossman 
10271c6a0718SPierre Ossman 	/*
10281c6a0718SPierre Ossman 	 * Reset the chip on each power off.
10291c6a0718SPierre Ossman 	 * Should clear out any weird states.
10301c6a0718SPierre Ossman 	 */
10311c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF) {
10321c6a0718SPierre Ossman 		writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
10331c6a0718SPierre Ossman 		sdhci_init(host);
10341c6a0718SPierre Ossman 	}
10351c6a0718SPierre Ossman 
10361c6a0718SPierre Ossman 	sdhci_set_clock(host, ios->clock);
10371c6a0718SPierre Ossman 
10381c6a0718SPierre Ossman 	if (ios->power_mode == MMC_POWER_OFF)
10391c6a0718SPierre Ossman 		sdhci_set_power(host, -1);
10401c6a0718SPierre Ossman 	else
10411c6a0718SPierre Ossman 		sdhci_set_power(host, ios->vdd);
10421c6a0718SPierre Ossman 
10431c6a0718SPierre Ossman 	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
10441c6a0718SPierre Ossman 
10451c6a0718SPierre Ossman 	if (ios->bus_width == MMC_BUS_WIDTH_4)
10461c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_4BITBUS;
10471c6a0718SPierre Ossman 	else
10481c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_4BITBUS;
10491c6a0718SPierre Ossman 
10501c6a0718SPierre Ossman 	if (ios->timing == MMC_TIMING_SD_HS)
10511c6a0718SPierre Ossman 		ctrl |= SDHCI_CTRL_HISPD;
10521c6a0718SPierre Ossman 	else
10531c6a0718SPierre Ossman 		ctrl &= ~SDHCI_CTRL_HISPD;
10541c6a0718SPierre Ossman 
10551c6a0718SPierre Ossman 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
10561c6a0718SPierre Ossman 
1057b8352260SLeandro Dorileo 	/*
1058b8352260SLeandro Dorileo 	 * Some (ENE) controllers go apeshit on some ios operation,
1059b8352260SLeandro Dorileo 	 * signalling timeout and CRC errors even on CMD0. Resetting
1060b8352260SLeandro Dorileo 	 * it on each ios seems to solve the problem.
1061b8352260SLeandro Dorileo 	 */
1062b8c86fc5SPierre Ossman 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
1063b8352260SLeandro Dorileo 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
1064b8352260SLeandro Dorileo 
10651e72859eSPierre Ossman out:
10661c6a0718SPierre Ossman 	mmiowb();
10671c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
10681c6a0718SPierre Ossman }
10691c6a0718SPierre Ossman 
10701c6a0718SPierre Ossman static int sdhci_get_ro(struct mmc_host *mmc)
10711c6a0718SPierre Ossman {
10721c6a0718SPierre Ossman 	struct sdhci_host *host;
10731c6a0718SPierre Ossman 	unsigned long flags;
10741c6a0718SPierre Ossman 	int present;
10751c6a0718SPierre Ossman 
10761c6a0718SPierre Ossman 	host = mmc_priv(mmc);
10771c6a0718SPierre Ossman 
10781c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
10791c6a0718SPierre Ossman 
10801e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
10811e72859eSPierre Ossman 		present = 0;
10821e72859eSPierre Ossman 	else
10831c6a0718SPierre Ossman 		present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
10841c6a0718SPierre Ossman 
10851c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
10861c6a0718SPierre Ossman 
10871c6a0718SPierre Ossman 	return !(present & SDHCI_WRITE_PROTECT);
10881c6a0718SPierre Ossman }
10891c6a0718SPierre Ossman 
1090f75979b7SPierre Ossman static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1091f75979b7SPierre Ossman {
1092f75979b7SPierre Ossman 	struct sdhci_host *host;
1093f75979b7SPierre Ossman 	unsigned long flags;
1094f75979b7SPierre Ossman 	u32 ier;
1095f75979b7SPierre Ossman 
1096f75979b7SPierre Ossman 	host = mmc_priv(mmc);
1097f75979b7SPierre Ossman 
1098f75979b7SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
1099f75979b7SPierre Ossman 
11001e72859eSPierre Ossman 	if (host->flags & SDHCI_DEVICE_DEAD)
11011e72859eSPierre Ossman 		goto out;
11021e72859eSPierre Ossman 
1103f75979b7SPierre Ossman 	ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
1104f75979b7SPierre Ossman 
1105f75979b7SPierre Ossman 	ier &= ~SDHCI_INT_CARD_INT;
1106f75979b7SPierre Ossman 	if (enable)
1107f75979b7SPierre Ossman 		ier |= SDHCI_INT_CARD_INT;
1108f75979b7SPierre Ossman 
1109f75979b7SPierre Ossman 	writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
1110f75979b7SPierre Ossman 	writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
1111f75979b7SPierre Ossman 
11121e72859eSPierre Ossman out:
1113f75979b7SPierre Ossman 	mmiowb();
1114f75979b7SPierre Ossman 
1115f75979b7SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
1116f75979b7SPierre Ossman }
1117f75979b7SPierre Ossman 
11181c6a0718SPierre Ossman static const struct mmc_host_ops sdhci_ops = {
11191c6a0718SPierre Ossman 	.request	= sdhci_request,
11201c6a0718SPierre Ossman 	.set_ios	= sdhci_set_ios,
11211c6a0718SPierre Ossman 	.get_ro		= sdhci_get_ro,
1122f75979b7SPierre Ossman 	.enable_sdio_irq = sdhci_enable_sdio_irq,
11231c6a0718SPierre Ossman };
11241c6a0718SPierre Ossman 
11251c6a0718SPierre Ossman /*****************************************************************************\
11261c6a0718SPierre Ossman  *                                                                           *
11271c6a0718SPierre Ossman  * Tasklets                                                                  *
11281c6a0718SPierre Ossman  *                                                                           *
11291c6a0718SPierre Ossman \*****************************************************************************/
11301c6a0718SPierre Ossman 
11311c6a0718SPierre Ossman static void sdhci_tasklet_card(unsigned long param)
11321c6a0718SPierre Ossman {
11331c6a0718SPierre Ossman 	struct sdhci_host *host;
11341c6a0718SPierre Ossman 	unsigned long flags;
11351c6a0718SPierre Ossman 
11361c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
11371c6a0718SPierre Ossman 
11381c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11391c6a0718SPierre Ossman 
11401c6a0718SPierre Ossman 	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
11411c6a0718SPierre Ossman 		if (host->mrq) {
11421c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Card removed during transfer!\n",
11431c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
11441c6a0718SPierre Ossman 			printk(KERN_ERR "%s: Resetting controller.\n",
11451c6a0718SPierre Ossman 				mmc_hostname(host->mmc));
11461c6a0718SPierre Ossman 
11471c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_CMD);
11481c6a0718SPierre Ossman 			sdhci_reset(host, SDHCI_RESET_DATA);
11491c6a0718SPierre Ossman 
115017b0429dSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
11511c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
11521c6a0718SPierre Ossman 		}
11531c6a0718SPierre Ossman 	}
11541c6a0718SPierre Ossman 
11551c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
11561c6a0718SPierre Ossman 
11571c6a0718SPierre Ossman 	mmc_detect_change(host->mmc, msecs_to_jiffies(500));
11581c6a0718SPierre Ossman }
11591c6a0718SPierre Ossman 
11601c6a0718SPierre Ossman static void sdhci_tasklet_finish(unsigned long param)
11611c6a0718SPierre Ossman {
11621c6a0718SPierre Ossman 	struct sdhci_host *host;
11631c6a0718SPierre Ossman 	unsigned long flags;
11641c6a0718SPierre Ossman 	struct mmc_request *mrq;
11651c6a0718SPierre Ossman 
11661c6a0718SPierre Ossman 	host = (struct sdhci_host*)param;
11671c6a0718SPierre Ossman 
11681c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
11691c6a0718SPierre Ossman 
11701c6a0718SPierre Ossman 	del_timer(&host->timer);
11711c6a0718SPierre Ossman 
11721c6a0718SPierre Ossman 	mrq = host->mrq;
11731c6a0718SPierre Ossman 
11741c6a0718SPierre Ossman 	/*
11751c6a0718SPierre Ossman 	 * The controller needs a reset of internal state machines
11761c6a0718SPierre Ossman 	 * upon error conditions.
11771c6a0718SPierre Ossman 	 */
11781e72859eSPierre Ossman 	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
11791e72859eSPierre Ossman 		(mrq->cmd->error ||
118017b0429dSPierre Ossman 		 (mrq->data && (mrq->data->error ||
118184c46a53SPierre Ossman 		  (mrq->data->stop && mrq->data->stop->error))) ||
11821e72859eSPierre Ossman 		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
11831c6a0718SPierre Ossman 
11841c6a0718SPierre Ossman 		/* Some controllers need this kick or reset won't work here */
1185b8c86fc5SPierre Ossman 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
11861c6a0718SPierre Ossman 			unsigned int clock;
11871c6a0718SPierre Ossman 
11881c6a0718SPierre Ossman 			/* This is to force an update */
11891c6a0718SPierre Ossman 			clock = host->clock;
11901c6a0718SPierre Ossman 			host->clock = 0;
11911c6a0718SPierre Ossman 			sdhci_set_clock(host, clock);
11921c6a0718SPierre Ossman 		}
11931c6a0718SPierre Ossman 
11941c6a0718SPierre Ossman 		/* Spec says we should do both at the same time, but Ricoh
11951c6a0718SPierre Ossman 		   controllers do not like that. */
11961c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_CMD);
11971c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_DATA);
11981c6a0718SPierre Ossman 	}
11991c6a0718SPierre Ossman 
12001c6a0718SPierre Ossman 	host->mrq = NULL;
12011c6a0718SPierre Ossman 	host->cmd = NULL;
12021c6a0718SPierre Ossman 	host->data = NULL;
12031c6a0718SPierre Ossman 
12042f730fecSPierre Ossman #ifndef CONFIG_LEDS_CLASS
12051c6a0718SPierre Ossman 	sdhci_deactivate_led(host);
12062f730fecSPierre Ossman #endif
12071c6a0718SPierre Ossman 
12081c6a0718SPierre Ossman 	mmiowb();
12091c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12101c6a0718SPierre Ossman 
12111c6a0718SPierre Ossman 	mmc_request_done(host->mmc, mrq);
12121c6a0718SPierre Ossman }
12131c6a0718SPierre Ossman 
12141c6a0718SPierre Ossman static void sdhci_timeout_timer(unsigned long data)
12151c6a0718SPierre Ossman {
12161c6a0718SPierre Ossman 	struct sdhci_host *host;
12171c6a0718SPierre Ossman 	unsigned long flags;
12181c6a0718SPierre Ossman 
12191c6a0718SPierre Ossman 	host = (struct sdhci_host*)data;
12201c6a0718SPierre Ossman 
12211c6a0718SPierre Ossman 	spin_lock_irqsave(&host->lock, flags);
12221c6a0718SPierre Ossman 
12231c6a0718SPierre Ossman 	if (host->mrq) {
12241c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Timeout waiting for hardware "
12251c6a0718SPierre Ossman 			"interrupt.\n", mmc_hostname(host->mmc));
12261c6a0718SPierre Ossman 		sdhci_dumpregs(host);
12271c6a0718SPierre Ossman 
12281c6a0718SPierre Ossman 		if (host->data) {
122917b0429dSPierre Ossman 			host->data->error = -ETIMEDOUT;
12301c6a0718SPierre Ossman 			sdhci_finish_data(host);
12311c6a0718SPierre Ossman 		} else {
12321c6a0718SPierre Ossman 			if (host->cmd)
123317b0429dSPierre Ossman 				host->cmd->error = -ETIMEDOUT;
12341c6a0718SPierre Ossman 			else
123517b0429dSPierre Ossman 				host->mrq->cmd->error = -ETIMEDOUT;
12361c6a0718SPierre Ossman 
12371c6a0718SPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
12381c6a0718SPierre Ossman 		}
12391c6a0718SPierre Ossman 	}
12401c6a0718SPierre Ossman 
12411c6a0718SPierre Ossman 	mmiowb();
12421c6a0718SPierre Ossman 	spin_unlock_irqrestore(&host->lock, flags);
12431c6a0718SPierre Ossman }
12441c6a0718SPierre Ossman 
12451c6a0718SPierre Ossman /*****************************************************************************\
12461c6a0718SPierre Ossman  *                                                                           *
12471c6a0718SPierre Ossman  * Interrupt handling                                                        *
12481c6a0718SPierre Ossman  *                                                                           *
12491c6a0718SPierre Ossman \*****************************************************************************/
12501c6a0718SPierre Ossman 
12511c6a0718SPierre Ossman static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
12521c6a0718SPierre Ossman {
12531c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
12541c6a0718SPierre Ossman 
12551c6a0718SPierre Ossman 	if (!host->cmd) {
1256b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
1257b67ac3f3SPierre Ossman 			"though no command operation was in progress.\n",
1258b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
12591c6a0718SPierre Ossman 		sdhci_dumpregs(host);
12601c6a0718SPierre Ossman 		return;
12611c6a0718SPierre Ossman 	}
12621c6a0718SPierre Ossman 
12631c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_TIMEOUT)
126417b0429dSPierre Ossman 		host->cmd->error = -ETIMEDOUT;
126517b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
126617b0429dSPierre Ossman 			SDHCI_INT_INDEX))
126717b0429dSPierre Ossman 		host->cmd->error = -EILSEQ;
12681c6a0718SPierre Ossman 
126917b0429dSPierre Ossman 	if (host->cmd->error)
12701c6a0718SPierre Ossman 		tasklet_schedule(&host->finish_tasklet);
127143b58b36SPierre Ossman 	else if (intmask & SDHCI_INT_RESPONSE)
127243b58b36SPierre Ossman 		sdhci_finish_command(host);
12731c6a0718SPierre Ossman }
12741c6a0718SPierre Ossman 
12751c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
12761c6a0718SPierre Ossman {
12771c6a0718SPierre Ossman 	BUG_ON(intmask == 0);
12781c6a0718SPierre Ossman 
12791c6a0718SPierre Ossman 	if (!host->data) {
12801c6a0718SPierre Ossman 		/*
12811c6a0718SPierre Ossman 		 * A data end interrupt is sent together with the response
12821c6a0718SPierre Ossman 		 * for the stop command.
12831c6a0718SPierre Ossman 		 */
12841c6a0718SPierre Ossman 		if (intmask & SDHCI_INT_DATA_END)
12851c6a0718SPierre Ossman 			return;
12861c6a0718SPierre Ossman 
1287b67ac3f3SPierre Ossman 		printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
1288b67ac3f3SPierre Ossman 			"though no data operation was in progress.\n",
1289b67ac3f3SPierre Ossman 			mmc_hostname(host->mmc), (unsigned)intmask);
12901c6a0718SPierre Ossman 		sdhci_dumpregs(host);
12911c6a0718SPierre Ossman 
12921c6a0718SPierre Ossman 		return;
12931c6a0718SPierre Ossman 	}
12941c6a0718SPierre Ossman 
12951c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
129617b0429dSPierre Ossman 		host->data->error = -ETIMEDOUT;
129717b0429dSPierre Ossman 	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
129817b0429dSPierre Ossman 		host->data->error = -EILSEQ;
12992134a922SPierre Ossman 	else if (intmask & SDHCI_INT_ADMA_ERROR)
13002134a922SPierre Ossman 		host->data->error = -EIO;
13011c6a0718SPierre Ossman 
130217b0429dSPierre Ossman 	if (host->data->error)
13031c6a0718SPierre Ossman 		sdhci_finish_data(host);
13041c6a0718SPierre Ossman 	else {
13051c6a0718SPierre Ossman 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
13061c6a0718SPierre Ossman 			sdhci_transfer_pio(host);
13071c6a0718SPierre Ossman 
13086ba736a1SPierre Ossman 		/*
13096ba736a1SPierre Ossman 		 * We currently don't do anything fancy with DMA
13106ba736a1SPierre Ossman 		 * boundaries, but as we can't disable the feature
13116ba736a1SPierre Ossman 		 * we need to at least restart the transfer.
13126ba736a1SPierre Ossman 		 */
13136ba736a1SPierre Ossman 		if (intmask & SDHCI_INT_DMA_END)
13146ba736a1SPierre Ossman 			writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
13156ba736a1SPierre Ossman 				host->ioaddr + SDHCI_DMA_ADDRESS);
13166ba736a1SPierre Ossman 
1317e538fbe8SPierre Ossman 		if (intmask & SDHCI_INT_DATA_END) {
1318e538fbe8SPierre Ossman 			if (host->cmd) {
1319e538fbe8SPierre Ossman 				/*
1320e538fbe8SPierre Ossman 				 * Data managed to finish before the
1321e538fbe8SPierre Ossman 				 * command completed. Make sure we do
1322e538fbe8SPierre Ossman 				 * things in the proper order.
1323e538fbe8SPierre Ossman 				 */
1324e538fbe8SPierre Ossman 				host->data_early = 1;
1325e538fbe8SPierre Ossman 			} else {
13261c6a0718SPierre Ossman 				sdhci_finish_data(host);
13271c6a0718SPierre Ossman 			}
13281c6a0718SPierre Ossman 		}
1329e538fbe8SPierre Ossman 	}
1330e538fbe8SPierre Ossman }
13311c6a0718SPierre Ossman 
13321c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id)
13331c6a0718SPierre Ossman {
13341c6a0718SPierre Ossman 	irqreturn_t result;
13351c6a0718SPierre Ossman 	struct sdhci_host* host = dev_id;
13361c6a0718SPierre Ossman 	u32 intmask;
1337f75979b7SPierre Ossman 	int cardint = 0;
13381c6a0718SPierre Ossman 
13391c6a0718SPierre Ossman 	spin_lock(&host->lock);
13401c6a0718SPierre Ossman 
13411c6a0718SPierre Ossman 	intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
13421c6a0718SPierre Ossman 
13431c6a0718SPierre Ossman 	if (!intmask || intmask == 0xffffffff) {
13441c6a0718SPierre Ossman 		result = IRQ_NONE;
13451c6a0718SPierre Ossman 		goto out;
13461c6a0718SPierre Ossman 	}
13471c6a0718SPierre Ossman 
1348b69c9058SPierre Ossman 	DBG("*** %s got interrupt: 0x%08x\n",
1349b69c9058SPierre Ossman 		mmc_hostname(host->mmc), intmask);
13501c6a0718SPierre Ossman 
13511c6a0718SPierre Ossman 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
13521c6a0718SPierre Ossman 		writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
13531c6a0718SPierre Ossman 			host->ioaddr + SDHCI_INT_STATUS);
13541c6a0718SPierre Ossman 		tasklet_schedule(&host->card_tasklet);
13551c6a0718SPierre Ossman 	}
13561c6a0718SPierre Ossman 
13571c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
13581c6a0718SPierre Ossman 
13591c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_CMD_MASK) {
13601c6a0718SPierre Ossman 		writel(intmask & SDHCI_INT_CMD_MASK,
13611c6a0718SPierre Ossman 			host->ioaddr + SDHCI_INT_STATUS);
13621c6a0718SPierre Ossman 		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
13631c6a0718SPierre Ossman 	}
13641c6a0718SPierre Ossman 
13651c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_DATA_MASK) {
13661c6a0718SPierre Ossman 		writel(intmask & SDHCI_INT_DATA_MASK,
13671c6a0718SPierre Ossman 			host->ioaddr + SDHCI_INT_STATUS);
13681c6a0718SPierre Ossman 		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
13691c6a0718SPierre Ossman 	}
13701c6a0718SPierre Ossman 
13711c6a0718SPierre Ossman 	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
13721c6a0718SPierre Ossman 
1373964f9ce2SPierre Ossman 	intmask &= ~SDHCI_INT_ERROR;
1374964f9ce2SPierre Ossman 
13751c6a0718SPierre Ossman 	if (intmask & SDHCI_INT_BUS_POWER) {
13761c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Card is consuming too much power!\n",
13771c6a0718SPierre Ossman 			mmc_hostname(host->mmc));
13781c6a0718SPierre Ossman 		writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
13791c6a0718SPierre Ossman 	}
13801c6a0718SPierre Ossman 
13819d26a5d3SRolf Eike Beer 	intmask &= ~SDHCI_INT_BUS_POWER;
13821c6a0718SPierre Ossman 
1383f75979b7SPierre Ossman 	if (intmask & SDHCI_INT_CARD_INT)
1384f75979b7SPierre Ossman 		cardint = 1;
1385f75979b7SPierre Ossman 
1386f75979b7SPierre Ossman 	intmask &= ~SDHCI_INT_CARD_INT;
1387f75979b7SPierre Ossman 
13881c6a0718SPierre Ossman 	if (intmask) {
13891c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
13901c6a0718SPierre Ossman 			mmc_hostname(host->mmc), intmask);
13911c6a0718SPierre Ossman 		sdhci_dumpregs(host);
13921c6a0718SPierre Ossman 
13931c6a0718SPierre Ossman 		writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
13941c6a0718SPierre Ossman 	}
13951c6a0718SPierre Ossman 
13961c6a0718SPierre Ossman 	result = IRQ_HANDLED;
13971c6a0718SPierre Ossman 
13981c6a0718SPierre Ossman 	mmiowb();
13991c6a0718SPierre Ossman out:
14001c6a0718SPierre Ossman 	spin_unlock(&host->lock);
14011c6a0718SPierre Ossman 
1402f75979b7SPierre Ossman 	/*
1403f75979b7SPierre Ossman 	 * We have to delay this as it calls back into the driver.
1404f75979b7SPierre Ossman 	 */
1405f75979b7SPierre Ossman 	if (cardint)
1406f75979b7SPierre Ossman 		mmc_signal_sdio_irq(host->mmc);
1407f75979b7SPierre Ossman 
14081c6a0718SPierre Ossman 	return result;
14091c6a0718SPierre Ossman }
14101c6a0718SPierre Ossman 
14111c6a0718SPierre Ossman /*****************************************************************************\
14121c6a0718SPierre Ossman  *                                                                           *
14131c6a0718SPierre Ossman  * Suspend/resume                                                            *
14141c6a0718SPierre Ossman  *                                                                           *
14151c6a0718SPierre Ossman \*****************************************************************************/
14161c6a0718SPierre Ossman 
14171c6a0718SPierre Ossman #ifdef CONFIG_PM
14181c6a0718SPierre Ossman 
1419b8c86fc5SPierre Ossman int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
14201c6a0718SPierre Ossman {
1421b8c86fc5SPierre Ossman 	int ret;
14221c6a0718SPierre Ossman 
1423b8c86fc5SPierre Ossman 	ret = mmc_suspend_host(host->mmc, state);
14241c6a0718SPierre Ossman 	if (ret)
14251c6a0718SPierre Ossman 		return ret;
14261c6a0718SPierre Ossman 
1427b8c86fc5SPierre Ossman 	free_irq(host->irq, host);
1428b8c86fc5SPierre Ossman 
1429b8c86fc5SPierre Ossman 	return 0;
1430b8c86fc5SPierre Ossman }
1431b8c86fc5SPierre Ossman 
1432b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host);
1433b8c86fc5SPierre Ossman 
1434b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host)
1435b8c86fc5SPierre Ossman {
1436b8c86fc5SPierre Ossman 	int ret;
1437b8c86fc5SPierre Ossman 
1438b8c86fc5SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
1439b8c86fc5SPierre Ossman 		if (host->ops->enable_dma)
1440b8c86fc5SPierre Ossman 			host->ops->enable_dma(host);
1441b8c86fc5SPierre Ossman 	}
1442b8c86fc5SPierre Ossman 
1443b8c86fc5SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1444b8c86fc5SPierre Ossman 			  mmc_hostname(host->mmc), host);
14451c6a0718SPierre Ossman 	if (ret)
14461c6a0718SPierre Ossman 		return ret;
1447b8c86fc5SPierre Ossman 
1448b8c86fc5SPierre Ossman 	sdhci_init(host);
14491c6a0718SPierre Ossman 	mmiowb();
1450b8c86fc5SPierre Ossman 
1451b8c86fc5SPierre Ossman 	ret = mmc_resume_host(host->mmc);
14521c6a0718SPierre Ossman 	if (ret)
14531c6a0718SPierre Ossman 		return ret;
14541c6a0718SPierre Ossman 
14551c6a0718SPierre Ossman 	return 0;
14561c6a0718SPierre Ossman }
14571c6a0718SPierre Ossman 
1458b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host);
14591c6a0718SPierre Ossman 
14601c6a0718SPierre Ossman #endif /* CONFIG_PM */
14611c6a0718SPierre Ossman 
14621c6a0718SPierre Ossman /*****************************************************************************\
14631c6a0718SPierre Ossman  *                                                                           *
1464b8c86fc5SPierre Ossman  * Device allocation/registration                                            *
14651c6a0718SPierre Ossman  *                                                                           *
14661c6a0718SPierre Ossman \*****************************************************************************/
14671c6a0718SPierre Ossman 
1468b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev,
1469b8c86fc5SPierre Ossman 	size_t priv_size)
14701c6a0718SPierre Ossman {
14711c6a0718SPierre Ossman 	struct mmc_host *mmc;
14721c6a0718SPierre Ossman 	struct sdhci_host *host;
14731c6a0718SPierre Ossman 
1474b8c86fc5SPierre Ossman 	WARN_ON(dev == NULL);
14751c6a0718SPierre Ossman 
1476b8c86fc5SPierre Ossman 	mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
14771c6a0718SPierre Ossman 	if (!mmc)
1478b8c86fc5SPierre Ossman 		return ERR_PTR(-ENOMEM);
14791c6a0718SPierre Ossman 
14801c6a0718SPierre Ossman 	host = mmc_priv(mmc);
14811c6a0718SPierre Ossman 	host->mmc = mmc;
14821c6a0718SPierre Ossman 
1483b8c86fc5SPierre Ossman 	return host;
14841c6a0718SPierre Ossman }
14851c6a0718SPierre Ossman 
1486b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host);
1487b8c86fc5SPierre Ossman 
1488b8c86fc5SPierre Ossman int sdhci_add_host(struct sdhci_host *host)
1489b8c86fc5SPierre Ossman {
1490b8c86fc5SPierre Ossman 	struct mmc_host *mmc;
1491b8c86fc5SPierre Ossman 	unsigned int caps;
1492b8c86fc5SPierre Ossman 	int ret;
1493b8c86fc5SPierre Ossman 
1494b8c86fc5SPierre Ossman 	WARN_ON(host == NULL);
1495b8c86fc5SPierre Ossman 	if (host == NULL)
1496b8c86fc5SPierre Ossman 		return -EINVAL;
1497b8c86fc5SPierre Ossman 
1498b8c86fc5SPierre Ossman 	mmc = host->mmc;
1499b8c86fc5SPierre Ossman 
1500b8c86fc5SPierre Ossman 	if (debug_quirks)
1501b8c86fc5SPierre Ossman 		host->quirks = debug_quirks;
1502b8c86fc5SPierre Ossman 
15031c6a0718SPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
15041c6a0718SPierre Ossman 
15052134a922SPierre Ossman 	host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
15062134a922SPierre Ossman 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
15072134a922SPierre Ossman 				>> SDHCI_SPEC_VER_SHIFT;
15082134a922SPierre Ossman 	if (host->version > SDHCI_SPEC_200) {
15091c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Unknown controller version (%d). "
1510b69c9058SPierre Ossman 			"You may experience problems.\n", mmc_hostname(mmc),
15112134a922SPierre Ossman 			host->version);
15121c6a0718SPierre Ossman 	}
15131c6a0718SPierre Ossman 
15141c6a0718SPierre Ossman 	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
15151c6a0718SPierre Ossman 
1516b8c86fc5SPierre Ossman 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
15171c6a0718SPierre Ossman 		host->flags |= SDHCI_USE_DMA;
15181c6a0718SPierre Ossman 	else if (!(caps & SDHCI_CAN_DO_DMA))
15191c6a0718SPierre Ossman 		DBG("Controller doesn't have DMA capability\n");
15201c6a0718SPierre Ossman 	else
15211c6a0718SPierre Ossman 		host->flags |= SDHCI_USE_DMA;
15221c6a0718SPierre Ossman 
1523b8c86fc5SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
15247c168e3dSFeng Tang 		(host->flags & SDHCI_USE_DMA)) {
1525cee687ceSRolf Eike Beer 		DBG("Disabling DMA as it is marked broken\n");
15267c168e3dSFeng Tang 		host->flags &= ~SDHCI_USE_DMA;
15277c168e3dSFeng Tang 	}
15287c168e3dSFeng Tang 
15291c6a0718SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
15302134a922SPierre Ossman 		if ((host->version >= SDHCI_SPEC_200) &&
15312134a922SPierre Ossman 				(caps & SDHCI_CAN_DO_ADMA2))
15322134a922SPierre Ossman 			host->flags |= SDHCI_USE_ADMA;
15332134a922SPierre Ossman 	}
15342134a922SPierre Ossman 
15352134a922SPierre Ossman 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
15362134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)) {
15372134a922SPierre Ossman 		DBG("Disabling ADMA as it is marked broken\n");
15382134a922SPierre Ossman 		host->flags &= ~SDHCI_USE_ADMA;
15392134a922SPierre Ossman 	}
15402134a922SPierre Ossman 
15412134a922SPierre Ossman 	if (host->flags & SDHCI_USE_DMA) {
1542b8c86fc5SPierre Ossman 		if (host->ops->enable_dma) {
1543b8c86fc5SPierre Ossman 			if (host->ops->enable_dma(host)) {
1544b8c86fc5SPierre Ossman 				printk(KERN_WARNING "%s: No suitable DMA "
1545b8c86fc5SPierre Ossman 					"available. Falling back to PIO.\n",
1546b8c86fc5SPierre Ossman 					mmc_hostname(mmc));
15472134a922SPierre Ossman 				host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
15481c6a0718SPierre Ossman 			}
15491c6a0718SPierre Ossman 		}
1550b8c86fc5SPierre Ossman 	}
15511c6a0718SPierre Ossman 
15522134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA) {
15532134a922SPierre Ossman 		/*
15542134a922SPierre Ossman 		 * We need to allocate descriptors for all sg entries
15552134a922SPierre Ossman 		 * (128) and potentially one alignment transfer for
15562134a922SPierre Ossman 		 * each of those entries.
15572134a922SPierre Ossman 		 */
15582134a922SPierre Ossman 		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
15592134a922SPierre Ossman 		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
15602134a922SPierre Ossman 		if (!host->adma_desc || !host->align_buffer) {
15612134a922SPierre Ossman 			kfree(host->adma_desc);
15622134a922SPierre Ossman 			kfree(host->align_buffer);
15632134a922SPierre Ossman 			printk(KERN_WARNING "%s: Unable to allocate ADMA "
15642134a922SPierre Ossman 				"buffers. Falling back to standard DMA.\n",
15652134a922SPierre Ossman 				mmc_hostname(mmc));
15662134a922SPierre Ossman 			host->flags &= ~SDHCI_USE_ADMA;
15672134a922SPierre Ossman 		}
15682134a922SPierre Ossman 	}
15692134a922SPierre Ossman 
15707659150cSPierre Ossman 	/*
15717659150cSPierre Ossman 	 * If we use DMA, then it's up to the caller to set the DMA
15727659150cSPierre Ossman 	 * mask, but PIO does not need the hw shim so we set a new
15737659150cSPierre Ossman 	 * mask here in that case.
15747659150cSPierre Ossman 	 */
15757659150cSPierre Ossman 	if (!(host->flags & SDHCI_USE_DMA)) {
15767659150cSPierre Ossman 		host->dma_mask = DMA_BIT_MASK(64);
15777659150cSPierre Ossman 		mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
15787659150cSPierre Ossman 	}
15791c6a0718SPierre Ossman 
15801c6a0718SPierre Ossman 	host->max_clk =
15811c6a0718SPierre Ossman 		(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
15821c6a0718SPierre Ossman 	if (host->max_clk == 0) {
15831c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Hardware doesn't specify base clock "
1584b69c9058SPierre Ossman 			"frequency.\n", mmc_hostname(mmc));
1585b8c86fc5SPierre Ossman 		return -ENODEV;
15861c6a0718SPierre Ossman 	}
15871c6a0718SPierre Ossman 	host->max_clk *= 1000000;
15881c6a0718SPierre Ossman 
15891c6a0718SPierre Ossman 	host->timeout_clk =
15901c6a0718SPierre Ossman 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
15911c6a0718SPierre Ossman 	if (host->timeout_clk == 0) {
15921c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
1593b69c9058SPierre Ossman 			"frequency.\n", mmc_hostname(mmc));
1594b8c86fc5SPierre Ossman 		return -ENODEV;
15951c6a0718SPierre Ossman 	}
15961c6a0718SPierre Ossman 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
15971c6a0718SPierre Ossman 		host->timeout_clk *= 1000;
15981c6a0718SPierre Ossman 
15991c6a0718SPierre Ossman 	/*
16001c6a0718SPierre Ossman 	 * Set host parameters.
16011c6a0718SPierre Ossman 	 */
16021c6a0718SPierre Ossman 	mmc->ops = &sdhci_ops;
16031c6a0718SPierre Ossman 	mmc->f_min = host->max_clk / 256;
16041c6a0718SPierre Ossman 	mmc->f_max = host->max_clk;
1605c9b74c5bSPierre Ossman 	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
16061c6a0718SPierre Ossman 
16071c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_DO_HISPD)
16081c6a0718SPierre Ossman 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
16091c6a0718SPierre Ossman 
16101c6a0718SPierre Ossman 	mmc->ocr_avail = 0;
16111c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_330)
16121c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
16131c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_300)
16141c6a0718SPierre Ossman 		mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
16151c6a0718SPierre Ossman 	if (caps & SDHCI_CAN_VDD_180)
161655556da0SPhilip Langdale 		mmc->ocr_avail |= MMC_VDD_165_195;
16171c6a0718SPierre Ossman 
16181c6a0718SPierre Ossman 	if (mmc->ocr_avail == 0) {
16191c6a0718SPierre Ossman 		printk(KERN_ERR "%s: Hardware doesn't report any "
1620b69c9058SPierre Ossman 			"support voltages.\n", mmc_hostname(mmc));
1621b8c86fc5SPierre Ossman 		return -ENODEV;
16221c6a0718SPierre Ossman 	}
16231c6a0718SPierre Ossman 
16241c6a0718SPierre Ossman 	spin_lock_init(&host->lock);
16251c6a0718SPierre Ossman 
16261c6a0718SPierre Ossman 	/*
16272134a922SPierre Ossman 	 * Maximum number of segments. Depends on if the hardware
16282134a922SPierre Ossman 	 * can do scatter/gather or not.
16291c6a0718SPierre Ossman 	 */
16302134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
16312134a922SPierre Ossman 		mmc->max_hw_segs = 128;
16322134a922SPierre Ossman 	else if (host->flags & SDHCI_USE_DMA)
16331c6a0718SPierre Ossman 		mmc->max_hw_segs = 1;
16342134a922SPierre Ossman 	else /* PIO */
16352134a922SPierre Ossman 		mmc->max_hw_segs = 128;
16362134a922SPierre Ossman 	mmc->max_phys_segs = 128;
16371c6a0718SPierre Ossman 
16381c6a0718SPierre Ossman 	/*
16391c6a0718SPierre Ossman 	 * Maximum number of sectors in one transfer. Limited by DMA boundary
16401c6a0718SPierre Ossman 	 * size (512KiB).
16411c6a0718SPierre Ossman 	 */
16421c6a0718SPierre Ossman 	mmc->max_req_size = 524288;
16431c6a0718SPierre Ossman 
16441c6a0718SPierre Ossman 	/*
16451c6a0718SPierre Ossman 	 * Maximum segment size. Could be one segment with the maximum number
16462134a922SPierre Ossman 	 * of bytes. When doing hardware scatter/gather, each entry cannot
16472134a922SPierre Ossman 	 * be larger than 64 KiB though.
16481c6a0718SPierre Ossman 	 */
16492134a922SPierre Ossman 	if (host->flags & SDHCI_USE_ADMA)
16502134a922SPierre Ossman 		mmc->max_seg_size = 65536;
16512134a922SPierre Ossman 	else
16521c6a0718SPierre Ossman 		mmc->max_seg_size = mmc->max_req_size;
16531c6a0718SPierre Ossman 
16541c6a0718SPierre Ossman 	/*
16551c6a0718SPierre Ossman 	 * Maximum block size. This varies from controller to controller and
16561c6a0718SPierre Ossman 	 * is specified in the capabilities register.
16571c6a0718SPierre Ossman 	 */
16581c6a0718SPierre Ossman 	mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
16591c6a0718SPierre Ossman 	if (mmc->max_blk_size >= 3) {
1660b69c9058SPierre Ossman 		printk(KERN_WARNING "%s: Invalid maximum block size, "
1661b69c9058SPierre Ossman 			"assuming 512 bytes\n", mmc_hostname(mmc));
166203f8590dSDavid Vrabel 		mmc->max_blk_size = 512;
166303f8590dSDavid Vrabel 	} else
16641c6a0718SPierre Ossman 		mmc->max_blk_size = 512 << mmc->max_blk_size;
16651c6a0718SPierre Ossman 
16661c6a0718SPierre Ossman 	/*
16671c6a0718SPierre Ossman 	 * Maximum block count.
16681c6a0718SPierre Ossman 	 */
16691c6a0718SPierre Ossman 	mmc->max_blk_count = 65535;
16701c6a0718SPierre Ossman 
16711c6a0718SPierre Ossman 	/*
16721c6a0718SPierre Ossman 	 * Init tasklets.
16731c6a0718SPierre Ossman 	 */
16741c6a0718SPierre Ossman 	tasklet_init(&host->card_tasklet,
16751c6a0718SPierre Ossman 		sdhci_tasklet_card, (unsigned long)host);
16761c6a0718SPierre Ossman 	tasklet_init(&host->finish_tasklet,
16771c6a0718SPierre Ossman 		sdhci_tasklet_finish, (unsigned long)host);
16781c6a0718SPierre Ossman 
16791c6a0718SPierre Ossman 	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
16801c6a0718SPierre Ossman 
16811c6a0718SPierre Ossman 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1682b69c9058SPierre Ossman 		mmc_hostname(mmc), host);
16831c6a0718SPierre Ossman 	if (ret)
16841c6a0718SPierre Ossman 		goto untasklet;
16851c6a0718SPierre Ossman 
16861c6a0718SPierre Ossman 	sdhci_init(host);
16871c6a0718SPierre Ossman 
16881c6a0718SPierre Ossman #ifdef CONFIG_MMC_DEBUG
16891c6a0718SPierre Ossman 	sdhci_dumpregs(host);
16901c6a0718SPierre Ossman #endif
16911c6a0718SPierre Ossman 
16922f730fecSPierre Ossman #ifdef CONFIG_LEDS_CLASS
16932f730fecSPierre Ossman 	host->led.name = mmc_hostname(mmc);
16942f730fecSPierre Ossman 	host->led.brightness = LED_OFF;
16952f730fecSPierre Ossman 	host->led.default_trigger = mmc_hostname(mmc);
16962f730fecSPierre Ossman 	host->led.brightness_set = sdhci_led_control;
16972f730fecSPierre Ossman 
1698b8c86fc5SPierre Ossman 	ret = led_classdev_register(mmc_dev(mmc), &host->led);
16992f730fecSPierre Ossman 	if (ret)
17002f730fecSPierre Ossman 		goto reset;
17012f730fecSPierre Ossman #endif
17022f730fecSPierre Ossman 
17031c6a0718SPierre Ossman 	mmiowb();
17041c6a0718SPierre Ossman 
17051c6a0718SPierre Ossman 	mmc_add_host(mmc);
17061c6a0718SPierre Ossman 
17072134a922SPierre Ossman 	printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
1708b8c86fc5SPierre Ossman 		mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->bus_id,
17092134a922SPierre Ossman 		(host->flags & SDHCI_USE_ADMA)?"A":"",
17101c6a0718SPierre Ossman 		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
17111c6a0718SPierre Ossman 
17121c6a0718SPierre Ossman 	return 0;
17131c6a0718SPierre Ossman 
17142f730fecSPierre Ossman #ifdef CONFIG_LEDS_CLASS
17152f730fecSPierre Ossman reset:
17162f730fecSPierre Ossman 	sdhci_reset(host, SDHCI_RESET_ALL);
17172f730fecSPierre Ossman 	free_irq(host->irq, host);
17182f730fecSPierre Ossman #endif
17191c6a0718SPierre Ossman untasklet:
17201c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
17211c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
17221c6a0718SPierre Ossman 
17231c6a0718SPierre Ossman 	return ret;
17241c6a0718SPierre Ossman }
17251c6a0718SPierre Ossman 
1726b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host);
1727b8c86fc5SPierre Ossman 
17281e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead)
17291c6a0718SPierre Ossman {
17301e72859eSPierre Ossman 	unsigned long flags;
17311e72859eSPierre Ossman 
17321e72859eSPierre Ossman 	if (dead) {
17331e72859eSPierre Ossman 		spin_lock_irqsave(&host->lock, flags);
17341e72859eSPierre Ossman 
17351e72859eSPierre Ossman 		host->flags |= SDHCI_DEVICE_DEAD;
17361e72859eSPierre Ossman 
17371e72859eSPierre Ossman 		if (host->mrq) {
17381e72859eSPierre Ossman 			printk(KERN_ERR "%s: Controller removed during "
17391e72859eSPierre Ossman 				" transfer!\n", mmc_hostname(host->mmc));
17401e72859eSPierre Ossman 
17411e72859eSPierre Ossman 			host->mrq->cmd->error = -ENOMEDIUM;
17421e72859eSPierre Ossman 			tasklet_schedule(&host->finish_tasklet);
17431e72859eSPierre Ossman 		}
17441e72859eSPierre Ossman 
17451e72859eSPierre Ossman 		spin_unlock_irqrestore(&host->lock, flags);
17461e72859eSPierre Ossman 	}
17471e72859eSPierre Ossman 
1748b8c86fc5SPierre Ossman 	mmc_remove_host(host->mmc);
17491c6a0718SPierre Ossman 
17502f730fecSPierre Ossman #ifdef CONFIG_LEDS_CLASS
17512f730fecSPierre Ossman 	led_classdev_unregister(&host->led);
17522f730fecSPierre Ossman #endif
17532f730fecSPierre Ossman 
17541e72859eSPierre Ossman 	if (!dead)
17551c6a0718SPierre Ossman 		sdhci_reset(host, SDHCI_RESET_ALL);
17561c6a0718SPierre Ossman 
17571c6a0718SPierre Ossman 	free_irq(host->irq, host);
17581c6a0718SPierre Ossman 
17591c6a0718SPierre Ossman 	del_timer_sync(&host->timer);
17601c6a0718SPierre Ossman 
17611c6a0718SPierre Ossman 	tasklet_kill(&host->card_tasklet);
17621c6a0718SPierre Ossman 	tasklet_kill(&host->finish_tasklet);
17632134a922SPierre Ossman 
17642134a922SPierre Ossman 	kfree(host->adma_desc);
17652134a922SPierre Ossman 	kfree(host->align_buffer);
17662134a922SPierre Ossman 
17672134a922SPierre Ossman 	host->adma_desc = NULL;
17682134a922SPierre Ossman 	host->align_buffer = NULL;
17691c6a0718SPierre Ossman }
17701c6a0718SPierre Ossman 
1771b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host);
1772b8c86fc5SPierre Ossman 
1773b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host)
17741c6a0718SPierre Ossman {
1775b8c86fc5SPierre Ossman 	mmc_free_host(host->mmc);
17761c6a0718SPierre Ossman }
17771c6a0718SPierre Ossman 
1778b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host);
17791c6a0718SPierre Ossman 
17801c6a0718SPierre Ossman /*****************************************************************************\
17811c6a0718SPierre Ossman  *                                                                           *
17821c6a0718SPierre Ossman  * Driver init/exit                                                          *
17831c6a0718SPierre Ossman  *                                                                           *
17841c6a0718SPierre Ossman \*****************************************************************************/
17851c6a0718SPierre Ossman 
17861c6a0718SPierre Ossman static int __init sdhci_drv_init(void)
17871c6a0718SPierre Ossman {
17881c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME
17891c6a0718SPierre Ossman 		": Secure Digital Host Controller Interface driver\n");
17901c6a0718SPierre Ossman 	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
17911c6a0718SPierre Ossman 
1792b8c86fc5SPierre Ossman 	return 0;
17931c6a0718SPierre Ossman }
17941c6a0718SPierre Ossman 
17951c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void)
17961c6a0718SPierre Ossman {
17971c6a0718SPierre Ossman }
17981c6a0718SPierre Ossman 
17991c6a0718SPierre Ossman module_init(sdhci_drv_init);
18001c6a0718SPierre Ossman module_exit(sdhci_drv_exit);
18011c6a0718SPierre Ossman 
18021c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444);
18031c6a0718SPierre Ossman 
18041c6a0718SPierre Ossman MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
1805b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
18061c6a0718SPierre Ossman MODULE_LICENSE("GPL");
18071c6a0718SPierre Ossman 
18081c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
1809