core.c 18.5 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 *  linux/drivers/mmc/core/core.c
L
Linus Torvalds 已提交
3 4
 *
 *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.
P
Pierre Ossman 已提交
5
 *  SD support Copyright (C) 2004 Ian Molton, All Rights Reserved.
6
 *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
7
 *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/pagemap.h>
#include <linux/err.h>
P
Pierre Ossman 已提交
21
#include <linux/leds.h>
P
Pierre Ossman 已提交
22
#include <linux/scatterlist.h>
L
Linus Torvalds 已提交
23 24 25

#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
P
Pierre Ossman 已提交
26 27
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
L
Linus Torvalds 已提交
28

29
#include "core.h"
30 31
#include "bus.h"
#include "host.h"
P
Pierre Ossman 已提交
32
#include "sdio_bus.h"
P
Pierre Ossman 已提交
33 34 35

#include "mmc_ops.h"
#include "sd_ops.h"
P
Pierre Ossman 已提交
36
#include "sdio_ops.h"
L
Linus Torvalds 已提交
37

38 39
static struct workqueue_struct *workqueue;

D
David Brownell 已提交
40 41 42 43 44 45 46 47
/*
 * Enabling software CRCs on the data blocks can be a significant (30%)
 * performance cost, and for other reasons may not always be desired.
 * So we allow it it to be disabled.
 */
int use_spi_crc = 1;
module_param(use_spi_crc, bool, 0);

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
/*
 * Internal function. Schedule delayed work in the MMC work queue.
 */
static int mmc_schedule_delayed_work(struct delayed_work *work,
				     unsigned long delay)
{
	return queue_delayed_work(workqueue, work, delay);
}

/*
 * Internal function. Flush all scheduled work from the MMC work queue.
 */
static void mmc_flush_scheduled_work(void)
{
	flush_workqueue(workqueue);
}

L
Linus Torvalds 已提交
65
/**
66 67 68
 *	mmc_request_done - finish processing an MMC request
 *	@host: MMC host which completed request
 *	@mrq: MMC request which request
L
Linus Torvalds 已提交
69 70
 *
 *	MMC drivers should call this function when they have completed
71
 *	their processing of a request.
L
Linus Torvalds 已提交
72 73 74 75
 */
void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
{
	struct mmc_command *cmd = mrq->cmd;
76 77
	int err = cmd->error;

D
David Brownell 已提交
78 79 80 81 82
	if (err && cmd->retries && mmc_host_is_spi(host)) {
		if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
			cmd->retries = 0;
	}

L
Linus Torvalds 已提交
83
	if (err && cmd->retries) {
84 85 86
		pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
			mmc_hostname(host), cmd->opcode, err);

L
Linus Torvalds 已提交
87 88 89
		cmd->retries--;
		cmd->error = 0;
		host->ops->request(host, mrq);
90
	} else {
P
Pierre Ossman 已提交
91 92
		led_trigger_event(host->led, LED_OFF);

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
		pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
			mmc_hostname(host), cmd->opcode, err,
			cmd->resp[0], cmd->resp[1],
			cmd->resp[2], cmd->resp[3]);

		if (mrq->data) {
			pr_debug("%s:     %d bytes transferred: %d\n",
				mmc_hostname(host),
				mrq->data->bytes_xfered, mrq->data->error);
		}

		if (mrq->stop) {
			pr_debug("%s:     (CMD%u): %d: %08x %08x %08x %08x\n",
				mmc_hostname(host), mrq->stop->opcode,
				mrq->stop->error,
				mrq->stop->resp[0], mrq->stop->resp[1],
				mrq->stop->resp[2], mrq->stop->resp[3]);
		}

		if (mrq->done)
			mrq->done(mrq);
L
Linus Torvalds 已提交
114 115 116 117 118
	}
}

EXPORT_SYMBOL(mmc_request_done);

119
static void
L
Linus Torvalds 已提交
120 121
mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{
P
Pierre Ossman 已提交
122 123 124 125
#ifdef CONFIG_MMC_DEBUG
	unsigned int i, sz;
#endif

126 127 128
	pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
		 mmc_hostname(host), mrq->cmd->opcode,
		 mrq->cmd->arg, mrq->cmd->flags);
L
Linus Torvalds 已提交
129

130 131 132 133 134
	if (mrq->data) {
		pr_debug("%s:     blksz %d blocks %d flags %08x "
			"tsac %d ms nsac %d\n",
			mmc_hostname(host), mrq->data->blksz,
			mrq->data->blocks, mrq->data->flags,
135
			mrq->data->timeout_ns / 1000000,
136 137 138 139 140 141 142 143 144
			mrq->data->timeout_clks);
	}

	if (mrq->stop) {
		pr_debug("%s:     CMD%u arg %08x flags %08x\n",
			 mmc_hostname(host), mrq->stop->opcode,
			 mrq->stop->arg, mrq->stop->flags);
	}

P
Pierre Ossman 已提交
145
	WARN_ON(!host->claimed);
L
Linus Torvalds 已提交
146

P
Pierre Ossman 已提交
147 148
	led_trigger_event(host->led, LED_FULL);

L
Linus Torvalds 已提交
149 150 151
	mrq->cmd->error = 0;
	mrq->cmd->mrq = mrq;
	if (mrq->data) {
152
		BUG_ON(mrq->data->blksz > host->max_blk_size);
153 154 155
		BUG_ON(mrq->data->blocks > host->max_blk_count);
		BUG_ON(mrq->data->blocks * mrq->data->blksz >
			host->max_req_size);
156

P
Pierre Ossman 已提交
157 158 159 160 161 162 163
#ifdef CONFIG_MMC_DEBUG
		sz = 0;
		for (i = 0;i < mrq->data->sg_len;i++)
			sz += mrq->data->sg[i].length;
		BUG_ON(sz != mrq->data->blocks * mrq->data->blksz);
#endif

L
Linus Torvalds 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
		mrq->cmd->data = mrq->data;
		mrq->data->error = 0;
		mrq->data->mrq = mrq;
		if (mrq->stop) {
			mrq->data->stop = mrq->stop;
			mrq->stop->error = 0;
			mrq->stop->mrq = mrq;
		}
	}
	host->ops->request(host, mrq);
}

static void mmc_wait_done(struct mmc_request *mrq)
{
	complete(mrq->done_data);
}

P
Pierre Ossman 已提交
181 182 183 184 185 186 187 188 189 190
/**
 *	mmc_wait_for_req - start a request and wait for completion
 *	@host: MMC host to start command
 *	@mrq: MMC request to start
 *
 *	Start a new MMC custom command request for a host, and wait
 *	for the command to complete. Does not attempt to parse the
 *	response.
 */
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
L
Linus Torvalds 已提交
191
{
192
	DECLARE_COMPLETION_ONSTACK(complete);
L
Linus Torvalds 已提交
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

	mrq->done_data = &complete;
	mrq->done = mmc_wait_done;

	mmc_start_request(host, mrq);

	wait_for_completion(&complete);
}

EXPORT_SYMBOL(mmc_wait_for_req);

/**
 *	mmc_wait_for_cmd - start a command and wait for completion
 *	@host: MMC host to start command
 *	@cmd: MMC command to start
 *	@retries: maximum number of retries
 *
 *	Start a new MMC command for a host, and wait for the command
 *	to complete.  Return any error that occurred while the command
 *	was executing.  Do not attempt to parse the response.
 */
int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
{
	struct mmc_request mrq;

P
Pierre Ossman 已提交
218
	WARN_ON(!host->claimed);
L
Linus Torvalds 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

	memset(&mrq, 0, sizeof(struct mmc_request));

	memset(cmd->resp, 0, sizeof(cmd->resp));
	cmd->retries = retries;

	mrq.cmd = cmd;
	cmd->data = NULL;

	mmc_wait_for_req(host, &mrq);

	return cmd->error;
}

EXPORT_SYMBOL(mmc_wait_for_cmd);

235 236 237 238
/**
 *	mmc_set_data_timeout - set the timeout for a data command
 *	@data: data phase for command
 *	@card: the MMC card associated with the data transfer
P
Pierre Ossman 已提交
239 240 241
 *
 *	Computes the data timeout parameters according to the
 *	correct algorithm given the card type.
242
 */
243
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
244 245 246
{
	unsigned int mult;

247 248 249 250 251 252 253 254 255
	/*
	 * SDIO cards only define an upper 1 s limit on access.
	 */
	if (mmc_card_sdio(card)) {
		data->timeout_ns = 1000000000;
		data->timeout_clks = 0;
		return;
	}

256 257 258 259 260 261 262 263 264
	/*
	 * SD cards use a 100 multiplier rather than 10
	 */
	mult = mmc_card_sd(card) ? 100 : 10;

	/*
	 * Scale up the multiplier (and therefore the timeout) by
	 * the r2w factor for writes.
	 */
265
	if (data->flags & MMC_DATA_WRITE)
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
		mult <<= card->csd.r2w_factor;

	data->timeout_ns = card->csd.tacc_ns * mult;
	data->timeout_clks = card->csd.tacc_clks * mult;

	/*
	 * SD cards also have an upper limit on the timeout.
	 */
	if (mmc_card_sd(card)) {
		unsigned int timeout_us, limit_us;

		timeout_us = data->timeout_ns / 1000;
		timeout_us += data->timeout_clks * 1000 /
			(card->host->ios.clock / 1000);

281
		if (data->flags & MMC_DATA_WRITE)
282 283 284 285
			limit_us = 250000;
		else
			limit_us = 100000;

286 287 288 289
		/*
		 * SDHC cards always use these fixed values.
		 */
		if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
290 291 292 293 294 295 296
			data->timeout_ns = limit_us * 1000;
			data->timeout_clks = 0;
		}
	}
}
EXPORT_SYMBOL(mmc_set_data_timeout);

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
/**
 *	mmc_align_data_size - pads a transfer size to a more optimal value
 *	@card: the MMC card associated with the data transfer
 *	@sz: original transfer size
 *
 *	Pads the original data size with a number of extra bytes in
 *	order to avoid controller bugs and/or performance hits
 *	(e.g. some controllers revert to PIO for certain sizes).
 *
 *	Returns the improved size, which might be unmodified.
 *
 *	Note that this function is only relevant when issuing a
 *	single scatter gather entry.
 */
unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
{
	/*
	 * FIXME: We don't have a system for the controller to tell
	 * the core about its problems yet, so for now we just 32-bit
	 * align the size.
	 */
	sz = ((sz + 3) / 4) * 4;

	return sz;
}
EXPORT_SYMBOL(mmc_align_data_size);

L
Linus Torvalds 已提交
324
/**
325
 *	__mmc_claim_host - exclusively claim a host
L
Linus Torvalds 已提交
326
 *	@host: mmc host to claim
327
 *	@abort: whether or not the operation should be aborted
L
Linus Torvalds 已提交
328
 *
329 330 331 332
 *	Claim a host for a set of operations.  If @abort is non null and
 *	dereference a non-zero value then this will return prematurely with
 *	that non-zero value without acquiring the lock.  Returns zero
 *	with the lock held otherwise.
L
Linus Torvalds 已提交
333
 */
334
int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
L
Linus Torvalds 已提交
335 336 337
{
	DECLARE_WAITQUEUE(wait, current);
	unsigned long flags;
338
	int stop;
L
Linus Torvalds 已提交
339

340 341
	might_sleep();

L
Linus Torvalds 已提交
342 343 344 345
	add_wait_queue(&host->wq, &wait);
	spin_lock_irqsave(&host->lock, flags);
	while (1) {
		set_current_state(TASK_UNINTERRUPTIBLE);
346 347
		stop = abort ? atomic_read(abort) : 0;
		if (stop || !host->claimed)
L
Linus Torvalds 已提交
348 349 350 351 352 353
			break;
		spin_unlock_irqrestore(&host->lock, flags);
		schedule();
		spin_lock_irqsave(&host->lock, flags);
	}
	set_current_state(TASK_RUNNING);
354 355 356 357
	if (!stop)
		host->claimed = 1;
	else
		wake_up(&host->wq);
L
Linus Torvalds 已提交
358 359
	spin_unlock_irqrestore(&host->lock, flags);
	remove_wait_queue(&host->wq, &wait);
360
	return stop;
L
Linus Torvalds 已提交
361 362
}

363
EXPORT_SYMBOL(__mmc_claim_host);
L
Linus Torvalds 已提交
364 365 366 367 368 369 370 371 372 373 374 375

/**
 *	mmc_release_host - release a host
 *	@host: mmc host to release
 *
 *	Release a MMC host, allowing others to claim the host
 *	for their operations.
 */
void mmc_release_host(struct mmc_host *host)
{
	unsigned long flags;

P
Pierre Ossman 已提交
376
	WARN_ON(!host->claimed);
L
Linus Torvalds 已提交
377 378

	spin_lock_irqsave(&host->lock, flags);
P
Pierre Ossman 已提交
379
	host->claimed = 0;
L
Linus Torvalds 已提交
380 381 382 383 384 385 386
	spin_unlock_irqrestore(&host->lock, flags);

	wake_up(&host->wq);
}

EXPORT_SYMBOL(mmc_release_host);

P
Pierre Ossman 已提交
387 388 389 390
/*
 * Internal function that does the actual ios call to the host driver,
 * optionally printing some debug output.
 */
391 392 393 394
static inline void mmc_set_ios(struct mmc_host *host)
{
	struct mmc_ios *ios = &host->ios;

395 396
	pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "
		"width %u timing %u\n",
397 398
		 mmc_hostname(host), ios->clock, ios->bus_mode,
		 ios->power_mode, ios->chip_select, ios->vdd,
399
		 ios->bus_width, ios->timing);
400

401 402 403
	host->ops->set_ios(host, ios);
}

P
Pierre Ossman 已提交
404 405 406
/*
 * Control chip select pin on a host.
 */
P
Pierre Ossman 已提交
407
void mmc_set_chip_select(struct mmc_host *host, int mode)
L
Linus Torvalds 已提交
408
{
P
Pierre Ossman 已提交
409 410
	host->ios.chip_select = mode;
	mmc_set_ios(host);
L
Linus Torvalds 已提交
411 412
}

P
Pierre Ossman 已提交
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
/*
 * Sets the host clock to the highest possible frequency that
 * is below "hz".
 */
void mmc_set_clock(struct mmc_host *host, unsigned int hz)
{
	WARN_ON(hz < host->f_min);

	if (hz > host->f_max)
		hz = host->f_max;

	host->ios.clock = hz;
	mmc_set_ios(host);
}

/*
 * Change the bus mode (open drain/push-pull) of a host.
 */
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
{
	host->ios.bus_mode = mode;
	mmc_set_ios(host);
}

/*
 * Change data bus width of a host.
 */
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
	host->ios.bus_width = width;
	mmc_set_ios(host);
}

L
Linus Torvalds 已提交
446 447 448 449
/*
 * Mask off any voltages we don't support and select
 * the lowest voltage
 */
P
Pierre Ossman 已提交
450
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
L
Linus Torvalds 已提交
451 452 453 454 455 456 457 458 459
{
	int bit;

	ocr &= host->ocr_avail;

	bit = ffs(ocr);
	if (bit) {
		bit -= 1;

460
		ocr &= 3 << bit;
L
Linus Torvalds 已提交
461 462

		host->ios.vdd = bit;
463
		mmc_set_ios(host);
L
Linus Torvalds 已提交
464 465 466 467 468 469 470
	} else {
		ocr = 0;
	}

	return ocr;
}

P
Pierre Ossman 已提交
471
/*
P
Pierre Ossman 已提交
472
 * Select timing parameters for host.
P
Pierre Ossman 已提交
473
 */
P
Pierre Ossman 已提交
474
void mmc_set_timing(struct mmc_host *host, unsigned int timing)
P
Pierre Ossman 已提交
475
{
P
Pierre Ossman 已提交
476 477
	host->ios.timing = timing;
	mmc_set_ios(host);
P
Pierre Ossman 已提交
478 479
}

L
Linus Torvalds 已提交
480
/*
481 482 483 484 485 486 487 488 489
 * Apply power to the MMC stack.  This is a two-stage process.
 * First, we enable power to the card without the clock running.
 * We then wait a bit for the power to stabilise.  Finally,
 * enable the bus drivers and clock to the card.
 *
 * We must _NOT_ enable the clock prior to power stablising.
 *
 * If a host does all the power sequencing itself, ignore the
 * initial MMC_POWER_UP stage.
L
Linus Torvalds 已提交
490 491 492 493 494 495
 */
static void mmc_power_up(struct mmc_host *host)
{
	int bit = fls(host->ocr_avail) - 1;

	host->ios.vdd = bit;
D
David Brownell 已提交
496 497 498 499 500 501 502
	if (mmc_host_is_spi(host)) {
		host->ios.chip_select = MMC_CS_HIGH;
		host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
	} else {
		host->ios.chip_select = MMC_CS_DONTCARE;
		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
	}
L
Linus Torvalds 已提交
503
	host->ios.power_mode = MMC_POWER_UP;
P
Pierre Ossman 已提交
504
	host->ios.bus_width = MMC_BUS_WIDTH_1;
505
	host->ios.timing = MMC_TIMING_LEGACY;
506
	mmc_set_ios(host);
L
Linus Torvalds 已提交
507

P
Pierre Ossman 已提交
508 509 510 511 512
	/*
	 * This delay should be sufficient to allow the power supply
	 * to reach the minimum voltage.
	 */
	mmc_delay(2);
L
Linus Torvalds 已提交
513 514 515

	host->ios.clock = host->f_min;
	host->ios.power_mode = MMC_POWER_ON;
516
	mmc_set_ios(host);
L
Linus Torvalds 已提交
517

P
Pierre Ossman 已提交
518 519 520 521
	/*
	 * This delay must be at least 74 clock sizes, or 1 ms, or the
	 * time required to reach a stable voltage.
	 */
L
Linus Torvalds 已提交
522 523 524 525 526 527 528
	mmc_delay(2);
}

static void mmc_power_off(struct mmc_host *host)
{
	host->ios.clock = 0;
	host->ios.vdd = 0;
D
David Brownell 已提交
529 530 531 532
	if (!mmc_host_is_spi(host)) {
		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
		host->ios.chip_select = MMC_CS_DONTCARE;
	}
L
Linus Torvalds 已提交
533
	host->ios.power_mode = MMC_POWER_OFF;
P
Pierre Ossman 已提交
534
	host->ios.bus_width = MMC_BUS_WIDTH_1;
535
	host->ios.timing = MMC_TIMING_LEGACY;
536
	mmc_set_ios(host);
L
Linus Torvalds 已提交
537 538
}

539 540 541
/*
 * Cleanup when the last reference to the bus operator is dropped.
 */
542
static void __mmc_release_bus(struct mmc_host *host)
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
{
	BUG_ON(!host);
	BUG_ON(host->bus_refs);
	BUG_ON(!host->bus_dead);

	host->bus_ops = NULL;
}

/*
 * Increase reference count of bus operator
 */
static inline void mmc_bus_get(struct mmc_host *host)
{
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
	host->bus_refs++;
	spin_unlock_irqrestore(&host->lock, flags);
}

/*
 * Decrease reference count of bus operator and free it if
 * it is the last reference.
 */
static inline void mmc_bus_put(struct mmc_host *host)
{
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
	host->bus_refs--;
	if ((host->bus_refs == 0) && host->bus_ops)
		__mmc_release_bus(host);
	spin_unlock_irqrestore(&host->lock, flags);
}

L
Linus Torvalds 已提交
578
/*
P
Pierre Ossman 已提交
579 580
 * Assign a mmc bus handler to a host. Only one bus handler may control a
 * host at any given time.
L
Linus Torvalds 已提交
581
 */
P
Pierre Ossman 已提交
582
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)
L
Linus Torvalds 已提交
583
{
P
Pierre Ossman 已提交
584
	unsigned long flags;
585

P
Pierre Ossman 已提交
586 587
	BUG_ON(!host);
	BUG_ON(!ops);
P
Pierre Ossman 已提交
588

P
Pierre Ossman 已提交
589
	WARN_ON(!host->claimed);
590

P
Pierre Ossman 已提交
591
	spin_lock_irqsave(&host->lock, flags);
592

P
Pierre Ossman 已提交
593 594
	BUG_ON(host->bus_ops);
	BUG_ON(host->bus_refs);
P
Pierre Ossman 已提交
595

P
Pierre Ossman 已提交
596 597 598
	host->bus_ops = ops;
	host->bus_refs = 1;
	host->bus_dead = 0;
P
Pierre Ossman 已提交
599

P
Pierre Ossman 已提交
600
	spin_unlock_irqrestore(&host->lock, flags);
P
Pierre Ossman 已提交
601 602
}

P
Pierre Ossman 已提交
603 604 605 606 607
/*
 * Remove the current bus handler from a host. Assumes that there are
 * no interesting cards left, so the bus is powered down.
 */
void mmc_detach_bus(struct mmc_host *host)
608
{
P
Pierre Ossman 已提交
609
	unsigned long flags;
610

P
Pierre Ossman 已提交
611
	BUG_ON(!host);
612

P
Pierre Ossman 已提交
613 614
	WARN_ON(!host->claimed);
	WARN_ON(!host->bus_ops);
615

P
Pierre Ossman 已提交
616
	spin_lock_irqsave(&host->lock, flags);
617

P
Pierre Ossman 已提交
618
	host->bus_dead = 1;
619

P
Pierre Ossman 已提交
620
	spin_unlock_irqrestore(&host->lock, flags);
L
Linus Torvalds 已提交
621

P
Pierre Ossman 已提交
622
	mmc_power_off(host);
L
Linus Torvalds 已提交
623

P
Pierre Ossman 已提交
624
	mmc_bus_put(host);
L
Linus Torvalds 已提交
625 626 627 628 629
}

/**
 *	mmc_detect_change - process change of state on a MMC socket
 *	@host: host which changed state.
630
 *	@delay: optional delay to wait before detection (jiffies)
L
Linus Torvalds 已提交
631
 *
P
Pierre Ossman 已提交
632 633 634 635
 *	MMC drivers should call this when they detect a card has been
 *	inserted or removed. The MMC layer will confirm that any
 *	present card is still functional, and initialize any newly
 *	inserted.
L
Linus Torvalds 已提交
636
 */
637
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
L
Linus Torvalds 已提交
638
{
639
#ifdef CONFIG_MMC_DEBUG
640
	unsigned long flags;
A
Andrew Morton 已提交
641
	spin_lock_irqsave(&host->lock, flags);
P
Pierre Ossman 已提交
642
	WARN_ON(host->removed);
A
Andrew Morton 已提交
643
	spin_unlock_irqrestore(&host->lock, flags);
644 645
#endif

D
David Howells 已提交
646
	mmc_schedule_delayed_work(&host->detect, delay);
L
Linus Torvalds 已提交
647 648 649 650 651
}

EXPORT_SYMBOL(mmc_detect_change);


652
void mmc_rescan(struct work_struct *work)
L
Linus Torvalds 已提交
653
{
D
David Howells 已提交
654 655
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
P
Pierre Ossman 已提交
656 657
	u32 ocr;
	int err;
L
Linus Torvalds 已提交
658

P
Pierre Ossman 已提交
659
	mmc_bus_get(host);
P
Pierre Ossman 已提交
660

P
Pierre Ossman 已提交
661
	if (host->bus_ops == NULL) {
L
Linus Torvalds 已提交
662
		/*
P
Pierre Ossman 已提交
663 664
		 * Only we can add a new handler, so it's safe to
		 * release the lock here.
L
Linus Torvalds 已提交
665
		 */
P
Pierre Ossman 已提交
666
		mmc_bus_put(host);
L
Linus Torvalds 已提交
667

668 669 670
		if (host->ops->get_cd && host->ops->get_cd(host) == 0)
			goto out;

P
Pierre Ossman 已提交
671
		mmc_claim_host(host);
L
Linus Torvalds 已提交
672

P
Pierre Ossman 已提交
673 674
		mmc_power_up(host);
		mmc_go_idle(host);
L
Linus Torvalds 已提交
675

P
Pierre Ossman 已提交
676
		mmc_send_if_cond(host, host->ocr_avail);
L
Linus Torvalds 已提交
677

P
Pierre Ossman 已提交
678 679 680 681 682 683 684
		/*
		 * First we search for SDIO...
		 */
		err = mmc_send_io_op_cond(host, 0, &ocr);
		if (!err) {
			if (mmc_attach_sdio(host, ocr))
				mmc_power_off(host);
685
			goto out;
P
Pierre Ossman 已提交
686 687 688 689 690
		}

		/*
		 * ...then normal SD...
		 */
P
Pierre Ossman 已提交
691
		err = mmc_send_app_op_cond(host, 0, &ocr);
P
Pierre Ossman 已提交
692
		if (!err) {
P
Pierre Ossman 已提交
693 694
			if (mmc_attach_sd(host, ocr))
				mmc_power_off(host);
695
			goto out;
P
Pierre Ossman 已提交
696 697 698 699 700 701 702 703
		}

		/*
		 * ...and finally MMC.
		 */
		err = mmc_send_op_cond(host, 0, &ocr);
		if (!err) {
			if (mmc_attach_mmc(host, ocr))
P
Pierre Ossman 已提交
704
				mmc_power_off(host);
705
			goto out;
P
Pierre Ossman 已提交
706
		}
P
Pierre Ossman 已提交
707 708 709

		mmc_release_host(host);
		mmc_power_off(host);
P
Pierre Ossman 已提交
710 711 712 713 714 715
	} else {
		if (host->bus_ops->detect && !host->bus_dead)
			host->bus_ops->detect(host);

		mmc_bus_put(host);
	}
716 717 718
out:
	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
L
Linus Torvalds 已提交
719 720
}

721
void mmc_start_host(struct mmc_host *host)
L
Linus Torvalds 已提交
722
{
723 724
	mmc_power_off(host);
	mmc_detect_change(host, 0);
L
Linus Torvalds 已提交
725 726
}

727
void mmc_stop_host(struct mmc_host *host)
L
Linus Torvalds 已提交
728
{
729
#ifdef CONFIG_MMC_DEBUG
730 731
	unsigned long flags;
	spin_lock_irqsave(&host->lock, flags);
732
	host->removed = 1;
733
	spin_unlock_irqrestore(&host->lock, flags);
734 735 736 737
#endif

	mmc_flush_scheduled_work();

P
Pierre Ossman 已提交
738 739 740 741 742 743 744 745
	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->remove)
			host->bus_ops->remove(host);

		mmc_claim_host(host);
		mmc_detach_bus(host);
		mmc_release_host(host);
L
Linus Torvalds 已提交
746
	}
P
Pierre Ossman 已提交
747 748 749
	mmc_bus_put(host);

	BUG_ON(host->card);
L
Linus Torvalds 已提交
750 751 752 753 754 755 756 757 758 759 760

	mmc_power_off(host);
}

#ifdef CONFIG_PM

/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 *	@state: suspend mode (PM_SUSPEND_xxx)
 */
761
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
L
Linus Torvalds 已提交
762
{
P
Pierre Ossman 已提交
763 764
	mmc_flush_scheduled_work();

P
Pierre Ossman 已提交
765 766
	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
767 768 769 770 771 772 773 774 775 776
		if (host->bus_ops->suspend)
			host->bus_ops->suspend(host);
		if (!host->bus_ops->resume) {
			if (host->bus_ops->remove)
				host->bus_ops->remove(host);

			mmc_claim_host(host);
			mmc_detach_bus(host);
			mmc_release_host(host);
		}
P
Pierre Ossman 已提交
777
	}
P
Pierre Ossman 已提交
778 779
	mmc_bus_put(host);

L
Linus Torvalds 已提交
780 781 782 783 784 785 786 787 788 789 790 791 792
	mmc_power_off(host);

	return 0;
}

EXPORT_SYMBOL(mmc_suspend_host);

/**
 *	mmc_resume_host - resume a previously suspended host
 *	@host: mmc host
 */
int mmc_resume_host(struct mmc_host *host)
{
793 794 795 796 797 798 799 800 801 802 803 804 805
	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		mmc_power_up(host);
		BUG_ON(!host->bus_ops->resume);
		host->bus_ops->resume(host);
	}
	mmc_bus_put(host);

	/*
	 * We add a slight delay here so that resume can progress
	 * in parallel.
	 */
	mmc_detect_change(host, 1);
L
Linus Torvalds 已提交
806 807 808 809 810 811 812 813

	return 0;
}

EXPORT_SYMBOL(mmc_resume_host);

#endif

814 815 816 817 818 819 820 821 822
static int __init mmc_init(void)
{
	int ret;

	workqueue = create_singlethread_workqueue("kmmcd");
	if (!workqueue)
		return -ENOMEM;

	ret = mmc_register_bus();
P
Pierre Ossman 已提交
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
	if (ret)
		goto destroy_workqueue;

	ret = mmc_register_host_class();
	if (ret)
		goto unregister_bus;

	ret = sdio_register_bus();
	if (ret)
		goto unregister_host_class;

	return 0;

unregister_host_class:
	mmc_unregister_host_class();
unregister_bus:
	mmc_unregister_bus();
destroy_workqueue:
	destroy_workqueue(workqueue);

843 844 845 846 847
	return ret;
}

static void __exit mmc_exit(void)
{
P
Pierre Ossman 已提交
848
	sdio_unregister_bus();
849 850 851 852 853
	mmc_unregister_host_class();
	mmc_unregister_bus();
	destroy_workqueue(workqueue);
}

854
subsys_initcall(mmc_init);
855 856
module_exit(mmc_exit);

L
Linus Torvalds 已提交
857
MODULE_LICENSE("GPL");