11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2aaac1b470bd0dccb30912356617069dc6199cc80Pierre Ossman * linux/drivers/mmc/core/core.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003-2004 Russell King, All Rights Reserved. 55b4fd9aef778e223968dfab1b90f905b3f2bd23dPierre Ossman * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. 6ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. 7bce40a36de574376f41f1ff3c4d212a7da2a3c90Philip Langdale * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License version 2 as 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/completion.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pagemap.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/err.h> 21af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman#include <linux/leds.h> 22b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman#include <linux/scatterlist.h> 2386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov#include <linux/log2.h> 245c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell#include <linux/regulator/consumer.h> 25e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen#include <linux/pm_runtime.h> 2635eb6db11ed9cbf9702ec90a28779a51fe4a21a9Amerigo Wang#include <linux/suspend.h> 271b676f70c108cda90cf9d114d16c677584400efcPer Forlin#include <linux/fault-inject.h> 281b676f70c108cda90cf9d114d16c677584400efcPer Forlin#include <linux/random.h> 2928c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat#include <linux/wakelock.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/card.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/host.h> 33da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/mmc.h> 34da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/sd.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36aaac1b470bd0dccb30912356617069dc6199cc80Pierre Ossman#include "core.h" 37ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman#include "bus.h" 38ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman#include "host.h" 39e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include "sdio_bus.h" 40da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman 41da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include "mmc_ops.h" 42da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include "sd_ops.h" 435c4e6f1301649d5b29dd0f70e6da83e728ab5ca5Pierre Ossman#include "sdio_ops.h" 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic struct workqueue_struct *workqueue; 46ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 47ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman/* 48af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * Enabling software CRCs on the data blocks can be a significant (30%) 49af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * performance cost, and for other reasons may not always be desired. 50af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * So we allow it it to be disabled. 51af51715079e7fb6b290e1881d63d815dc4de5011David Brownell */ 5290ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool use_spi_crc = 1; 53af51715079e7fb6b290e1881d63d815dc4de5011David Brownellmodule_param(use_spi_crc, bool, 0); 54af51715079e7fb6b290e1881d63d815dc4de5011David Brownell 55af51715079e7fb6b290e1881d63d815dc4de5011David Brownell/* 56bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * We normally treat cards as removed during suspend if they are not 57bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * known to be on a non-removable bus, to avoid the risk of writing 58bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * back data to a different card after resume. Allow this to be 59bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * overridden if necessary. 60bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings */ 61bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#ifdef CONFIG_MMC_UNSAFE_RESUME 6290ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool mmc_assume_removable; 63bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#else 6490ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool mmc_assume_removable = 1; 65bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#endif 6671d7d3d190fe77588269a8febf93cd739bd91eb3Matt FlemingEXPORT_SYMBOL(mmc_assume_removable); 67bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchingsmodule_param_named(removable, mmc_assume_removable, bool, 0644); 68bd68e0838fe85794b06892054772fa013a8d1986Ben HutchingsMODULE_PARM_DESC( 69bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings removable, 70bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings "MMC/SD cards are removable and may be removed during suspend"); 71bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings 72bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings/* 73ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman * Internal function. Schedule delayed work in the MMC work queue. 74ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman */ 75ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic int mmc_schedule_delayed_work(struct delayed_work *work, 76ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman unsigned long delay) 77ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 78ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return queue_delayed_work(workqueue, work, delay); 79ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 80ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 81ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman/* 82ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman * Internal function. Flush all scheduled work from the MMC work queue. 83ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman */ 84ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic void mmc_flush_scheduled_work(void) 85ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 86ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman flush_workqueue(workqueue); 87ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 88ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 891b676f70c108cda90cf9d114d16c677584400efcPer Forlin#ifdef CONFIG_FAIL_MMC_REQUEST 901b676f70c108cda90cf9d114d16c677584400efcPer Forlin 911b676f70c108cda90cf9d114d16c677584400efcPer Forlin/* 921b676f70c108cda90cf9d114d16c677584400efcPer Forlin * Internal function. Inject random data errors. 931b676f70c108cda90cf9d114d16c677584400efcPer Forlin * If mmc_data is NULL no errors are injected. 941b676f70c108cda90cf9d114d16c677584400efcPer Forlin */ 951b676f70c108cda90cf9d114d16c677584400efcPer Forlinstatic void mmc_should_fail_request(struct mmc_host *host, 961b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_request *mrq) 971b676f70c108cda90cf9d114d16c677584400efcPer Forlin{ 981b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_command *cmd = mrq->cmd; 991b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_data *data = mrq->data; 1001b676f70c108cda90cf9d114d16c677584400efcPer Forlin static const int data_errors[] = { 1011b676f70c108cda90cf9d114d16c677584400efcPer Forlin -ETIMEDOUT, 1021b676f70c108cda90cf9d114d16c677584400efcPer Forlin -EILSEQ, 1031b676f70c108cda90cf9d114d16c677584400efcPer Forlin -EIO, 1041b676f70c108cda90cf9d114d16c677584400efcPer Forlin }; 1051b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1061b676f70c108cda90cf9d114d16c677584400efcPer Forlin if (!data) 1071b676f70c108cda90cf9d114d16c677584400efcPer Forlin return; 1081b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1091b676f70c108cda90cf9d114d16c677584400efcPer Forlin if (cmd->error || data->error || 1101b676f70c108cda90cf9d114d16c677584400efcPer Forlin !should_fail(&host->fail_mmc_request, data->blksz * data->blocks)) 1111b676f70c108cda90cf9d114d16c677584400efcPer Forlin return; 1121b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1131b676f70c108cda90cf9d114d16c677584400efcPer Forlin data->error = data_errors[random32() % ARRAY_SIZE(data_errors)]; 1141b676f70c108cda90cf9d114d16c677584400efcPer Forlin data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9; 1151b676f70c108cda90cf9d114d16c677584400efcPer Forlin} 1161b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1171b676f70c108cda90cf9d114d16c677584400efcPer Forlin#else /* CONFIG_FAIL_MMC_REQUEST */ 1181b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1191b676f70c108cda90cf9d114d16c677584400efcPer Forlinstatic inline void mmc_should_fail_request(struct mmc_host *host, 1201b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_request *mrq) 1211b676f70c108cda90cf9d114d16c677584400efcPer Forlin{ 1221b676f70c108cda90cf9d114d16c677584400efcPer Forlin} 1231b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1241b676f70c108cda90cf9d114d16c677584400efcPer Forlin#endif /* CONFIG_FAIL_MMC_REQUEST */ 1251b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 127fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * mmc_request_done - finish processing an MMC request 128fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * @host: MMC host which completed request 129fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * @mrq: MMC request which request 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MMC drivers should call this function when they have completed 132fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * their processing of a request. 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mmc_command *cmd = mrq->cmd; 137920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King int err = cmd->error; 138920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 139af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (err && cmd->retries && mmc_host_is_spi(host)) { 140af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) 141af51715079e7fb6b290e1881d63d815dc4de5011David Brownell cmd->retries = 0; 142af51715079e7fb6b290e1881d63d815dc4de5011David Brownell } 143af51715079e7fb6b290e1881d63d815dc4de5011David Brownell 144d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (err && cmd->retries && !mmc_card_removed(host->card)) { 14508a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter /* 14608a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter * Request starter must handle retries - see 14708a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter * mmc_wait_for_req_done(). 14808a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter */ 14908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter if (mrq->done) 15008a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter mrq->done(mrq); 151e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } else { 1521b676f70c108cda90cf9d114d16c677584400efcPer Forlin mmc_should_fail_request(host, mrq); 1531b676f70c108cda90cf9d114d16c677584400efcPer Forlin 154af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman led_trigger_event(host->led, LED_OFF); 155af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman 156e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", 157e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), cmd->opcode, err, 158e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman cmd->resp[0], cmd->resp[1], 159e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman cmd->resp[2], cmd->resp[3]); 160e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 161e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->data) { 162e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: %d bytes transferred: %d\n", 163e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), 164e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->bytes_xfered, mrq->data->error); 165e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 166e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 167e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->stop) { 168e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: (CMD%u): %d: %08x %08x %08x %08x\n", 169e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->stop->opcode, 170e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->error, 171e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->resp[0], mrq->stop->resp[1], 172e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->resp[2], mrq->stop->resp[3]); 173e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 174e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 175e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->done) 176e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->done(mrq); 17704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 17808c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg mmc_host_clk_release(host); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_request_done); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 184393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic void 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmmc_start_request(struct mmc_host *host, struct mmc_request *mrq) 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 187976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#ifdef CONFIG_MMC_DEBUG 188976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman unsigned int i, sz; 189a84756c5735f28bf000617f18734a9e94426386aPierre Ossman struct scatterlist *sg; 190976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#endif 191976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman 1927b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung if (mrq->sbc) { 1937b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", 1947b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung mmc_hostname(host), mrq->sbc->opcode, 1957b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung mrq->sbc->arg, mrq->sbc->flags); 1967b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung } 1977b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung 198920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King pr_debug("%s: starting CMD%u arg %08x flags %08x\n", 199920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_hostname(host), mrq->cmd->opcode, 200920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mrq->cmd->arg, mrq->cmd->flags); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 202e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->data) { 203e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: blksz %d blocks %d flags %08x " 204e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman "tsac %d ms nsac %d\n", 205e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->data->blksz, 206e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->blocks, mrq->data->flags, 207ce252edd869ba1fee6a9a6f83e20f349d4c4d669Pierre Ossman mrq->data->timeout_ns / 1000000, 208e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->timeout_clks); 209e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 210e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 211e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->stop) { 212e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: CMD%u arg %08x flags %08x\n", 213e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->stop->opcode, 214e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->arg, mrq->stop->flags); 215e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 216e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 217f22ee4edf63e7480511112d9965c71e07be3f8b7Pierre Ossman WARN_ON(!host->claimed); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->error = 0; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->mrq = mrq; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mrq->data) { 222fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman BUG_ON(mrq->data->blksz > host->max_blk_size); 22355db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman BUG_ON(mrq->data->blocks > host->max_blk_count); 22455db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman BUG_ON(mrq->data->blocks * mrq->data->blksz > 22555db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman host->max_req_size); 226fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman 227976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#ifdef CONFIG_MMC_DEBUG 228976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman sz = 0; 229a84756c5735f28bf000617f18734a9e94426386aPierre Ossman for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) 230a84756c5735f28bf000617f18734a9e94426386aPierre Ossman sz += sg->length; 231976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); 232976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#endif 233976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->data = mrq->data; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->error = 0; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->mrq = mrq; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mrq->stop) { 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->stop = mrq->stop; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->stop->error = 0; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->stop->mrq = mrq; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24308c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg mmc_host_clk_hold(host); 24466c036e0142fed2484d58a2d3c7a4d21ba32b6a6Pierre Tardy led_trigger_event(host->led, LED_FULL); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ops->request(host, mrq); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_wait_done(struct mmc_request *mrq) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 250aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin complete(&mrq->completion); 251aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 252aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 253956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hanssonstatic int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) 254aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 255aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin init_completion(&mrq->completion); 256aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mrq->done = mmc_wait_done; 257d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (mmc_card_removed(host->card)) { 258d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mrq->cmd->error = -ENOMEDIUM; 259d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter complete(&mrq->completion); 260956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson return -ENOMEDIUM; 261d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter } 262aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_start_request(host, mrq); 263956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson return 0; 264aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 265aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 266aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_wait_for_req_done(struct mmc_host *host, 267aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_request *mrq) 268aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 26908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter struct mmc_command *cmd; 27008a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27108a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter while (1) { 27208a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter wait_for_completion(&mrq->completion); 27308a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27408a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd = mrq->cmd; 275d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (!cmd->error || !cmd->retries || 276d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mmc_card_removed(host->card)) 27708a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter break; 27808a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter pr_debug("%s: req failed (CMD%u): %d, retrying...\n", 28008a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter mmc_hostname(host), cmd->opcode, cmd->error); 28108a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd->retries--; 28208a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd->error = 0; 28308a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter host->ops->request(host, mrq); 28408a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter } 285aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 286aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 287aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 288aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_pre_req - Prepare for a new request 289aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to prepare command 290aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @mrq: MMC request to prepare for 291aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @is_first_req: true if there is no previous started request 292aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * that may run in parellel to this call, otherwise false 293aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 294aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_pre_req() is called in prior to mmc_start_req() to let 295aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * host prepare for the new request. Preparation of a request may be 296aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * performed while another request is running on the host. 297aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 298aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, 299aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin bool is_first_req) 300aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 3012c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->pre_req) { 3022c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 303aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin host->ops->pre_req(host, mrq, is_first_req); 3042c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 3052c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 306aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 307aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 308aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 309aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_post_req - Post process a completed request 310aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to post process command 311aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @mrq: MMC request to post process for 312aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @err: Error, if non zero, clean up any resources made in pre_req 313aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 314aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Let the host post process a completed request. Post processing of 315aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * a request may be performed while another reuqest is running. 316aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 317aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, 318aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin int err) 319aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 3202c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->post_req) { 3212c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 322aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin host->ops->post_req(host, mrq, err); 3232c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 3242c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman/** 328aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_start_req - start a non-blocking request 329aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to start command 330aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @areq: async request to start 331aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @error: out parameter returns 0 for success, otherwise non zero 332aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 333aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Start a new MMC custom command request for a host. 334aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * If there is on ongoing async request wait for completion 335aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * of that request and start the new one and return. 336aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Does not wait for the new request to complete. 337aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 338aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Returns the completed request, NULL in case of none completed. 339aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Wait for the an ongoing request (previoulsy started) to complete and 340aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * return the completed request. If there is no ongoing request, NULL 341aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * is returned without waiting. NULL is not an error condition. 342aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 343aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstruct mmc_async_req *mmc_start_req(struct mmc_host *host, 344aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_async_req *areq, int *error) 345aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 346aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin int err = 0; 347956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson int start_err = 0; 348aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_async_req *data = host->areq; 349aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 350aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin /* Prepare a new request */ 351aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (areq) 352aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_pre_req(host, areq->mrq, !host->areq); 353aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 354aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (host->areq) { 355aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_wait_for_req_done(host, host->areq->mrq); 356aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin err = host->areq->err_check(host->card, host->areq); 357aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin } 358aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 359956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if (!err && areq) 360956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson start_err = __mmc_start_req(host, areq->mrq); 361aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 362aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (host->areq) 363aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_post_req(host, host->areq->mrq, 0); 364aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 365956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson /* Cancel a prepared request if it was not started. */ 366956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if ((err || start_err) && areq) 367956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson mmc_post_req(host, areq->mrq, -EINVAL); 368956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson 369956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if (err) 370956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson host->areq = NULL; 371956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson else 372956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson host->areq = areq; 373956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson 374aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (error) 375aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin *error = err; 376aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin return data; 377aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 378aa8b683a7d392271ed349c6ab9f36b8c313794b7Per ForlinEXPORT_SYMBOL(mmc_start_req); 379aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 380aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 38167a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * mmc_wait_for_req - start a request and wait for completion 38267a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * @host: MMC host to start command 38367a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * @mrq: MMC request to start 38467a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * 38567a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * Start a new MMC custom command request for a host, and wait 38667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * for the command to complete. Does not attempt to parse the 38767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * response. 38867a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman */ 38967a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossmanvoid mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 391aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin __mmc_start_req(host, mrq); 392aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_wait_for_req_done(host, mrq); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_wait_for_req); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 397eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * mmc_interrupt_hpi - Issue for High priority Interrupt 398eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * @card: the MMC card associated with the HPI transfer 399eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * 400eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * Issued High Priority Interrupt, and check for card status 401eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * util out-of prg-state. 402eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 403eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chungint mmc_interrupt_hpi(struct mmc_card *card) 404eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung{ 405eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung int err; 406eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung u32 status; 407eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 408eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung BUG_ON(!card); 409eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 410eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (!card->ext_csd.hpi_en) { 411eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host)); 412eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung return 1; 413eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } 414eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 415eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_claim_host(card->host); 416eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_status(card, &status); 417eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) { 418eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_err("%s: Get card status fail\n", mmc_hostname(card->host)); 419eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung goto out; 420eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } 421eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 422eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung /* 423eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * If the card status is in PRG-state, we can send the HPI command. 424eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 425eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (R1_CURRENT_STATE(status) == R1_STATE_PRG) { 426eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung do { 427eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung /* 428eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * We don't know when the HPI command will finish 429eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * processing, so we need to resend HPI until out 430eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * of prg-state, and keep checking the card status 431eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * with SEND_STATUS. If a timeout error occurs when 432eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * sending the HPI command, we are already out of 433eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * prg-state. 434eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 435eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_hpi_cmd(card, &status); 436eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) 437eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_debug("%s: abort HPI (%d error)\n", 438eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_hostname(card->host), err); 439eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 440eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_status(card, &status); 441eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) 442eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung break; 443eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); 444eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } else 445eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_debug("%s: Left prg-state\n", mmc_hostname(card->host)); 446eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 447eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chungout: 448eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_release_host(card->host); 449eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung return err; 450eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung} 451eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon ChungEXPORT_SYMBOL(mmc_interrupt_hpi); 452eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 453eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung/** 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_wait_for_cmd - start a command and wait for completion 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: MMC host to start command 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @cmd: MMC command to start 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @retries: maximum number of retries 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Start a new MMC command for a host, and wait for the command 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to complete. Return any error that occurred while the command 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * was executing. Do not attempt to parse the response. 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 465ad5fd97288655b5628052c1fa906419417c86100Venkatraman S struct mmc_request mrq = {NULL}; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 467d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(cmd->resp, 0, sizeof(cmd->resp)); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->retries = retries; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq.cmd = cmd; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->data = NULL; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mmc_wait_for_req(host, &mrq); 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cmd->error; 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_wait_for_cmd); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 482335eadf2ef6a1122a720aea98e758e5d431da87dPierre Ossman/** 483d773d7255199a6c8934e197756f54a1115dd127bRussell King * mmc_set_data_timeout - set the timeout for a data command 484d773d7255199a6c8934e197756f54a1115dd127bRussell King * @data: data phase for command 485d773d7255199a6c8934e197756f54a1115dd127bRussell King * @card: the MMC card associated with the data transfer 48667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * 48767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * Computes the data timeout parameters according to the 48867a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * correct algorithm given the card type. 489d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 490b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossmanvoid mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) 491d773d7255199a6c8934e197756f54a1115dd127bRussell King{ 492d773d7255199a6c8934e197756f54a1115dd127bRussell King unsigned int mult; 493d773d7255199a6c8934e197756f54a1115dd127bRussell King 494d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 495e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman * SDIO cards only define an upper 1 s limit on access. 496e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman */ 497e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman if (mmc_card_sdio(card)) { 498e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman data->timeout_ns = 1000000000; 499e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman data->timeout_clks = 0; 500e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman return; 501e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman } 502e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman 503e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman /* 504d773d7255199a6c8934e197756f54a1115dd127bRussell King * SD cards use a 100 multiplier rather than 10 505d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 506d773d7255199a6c8934e197756f54a1115dd127bRussell King mult = mmc_card_sd(card) ? 100 : 10; 507d773d7255199a6c8934e197756f54a1115dd127bRussell King 508d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 509d773d7255199a6c8934e197756f54a1115dd127bRussell King * Scale up the multiplier (and therefore the timeout) by 510d773d7255199a6c8934e197756f54a1115dd127bRussell King * the r2w factor for writes. 511d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 512b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman if (data->flags & MMC_DATA_WRITE) 513d773d7255199a6c8934e197756f54a1115dd127bRussell King mult <<= card->csd.r2w_factor; 514d773d7255199a6c8934e197756f54a1115dd127bRussell King 515d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_ns = card->csd.tacc_ns * mult; 516d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_clks = card->csd.tacc_clks * mult; 517d773d7255199a6c8934e197756f54a1115dd127bRussell King 518d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 519d773d7255199a6c8934e197756f54a1115dd127bRussell King * SD cards also have an upper limit on the timeout. 520d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 521d773d7255199a6c8934e197756f54a1115dd127bRussell King if (mmc_card_sd(card)) { 522d773d7255199a6c8934e197756f54a1115dd127bRussell King unsigned int timeout_us, limit_us; 523d773d7255199a6c8934e197756f54a1115dd127bRussell King 524d773d7255199a6c8934e197756f54a1115dd127bRussell King timeout_us = data->timeout_ns / 1000; 525e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij if (mmc_host_clk_rate(card->host)) 526e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij timeout_us += data->timeout_clks * 1000 / 527e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij (mmc_host_clk_rate(card->host) / 1000); 528d773d7255199a6c8934e197756f54a1115dd127bRussell King 529b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman if (data->flags & MMC_DATA_WRITE) 530493890e75d98810a3470b4aae23be628ee5e9667Pierre Ossman /* 5313bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * The MMC spec "It is strongly recommended 5323bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * for hosts to implement more than 500ms 5333bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * timeout value even if the card indicates 5343bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * the 250ms maximum busy length." Even the 5353bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * previous value of 300ms is known to be 5363bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * insufficient for some cards. 537493890e75d98810a3470b4aae23be628ee5e9667Pierre Ossman */ 5383bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley limit_us = 3000000; 539d773d7255199a6c8934e197756f54a1115dd127bRussell King else 540d773d7255199a6c8934e197756f54a1115dd127bRussell King limit_us = 100000; 541d773d7255199a6c8934e197756f54a1115dd127bRussell King 542fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale /* 543fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale * SDHC cards always use these fixed values. 544fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale */ 545fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale if (timeout_us > limit_us || mmc_card_blockaddr(card)) { 546d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_ns = limit_us * 1000; 547d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_clks = 0; 548d773d7255199a6c8934e197756f54a1115dd127bRussell King } 549d773d7255199a6c8934e197756f54a1115dd127bRussell King } 5506de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK 5516de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK /* 5526de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * Some cards require longer data read timeout than indicated in CSD. 5536de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * Address this by setting the read timeout to a "reasonably high" 5546de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * value. For the cards tested, 300ms has proven enough. If necessary, 5556de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * this value can be increased if other problematic cards require this. 5566de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK */ 5576de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { 5586de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK data->timeout_ns = 300000000; 5596de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK data->timeout_clks = 0; 5606de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK } 5616de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK 562c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees /* 563c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * Some cards need very high timeouts if driven in SPI mode. 564c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * The worst observed timeout was 900ms after writing a 565c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * continuous stream of data until the internal logic 566c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * overflowed. 567c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees */ 568c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (mmc_host_is_spi(card->host)) { 569c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->flags & MMC_DATA_WRITE) { 570c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->timeout_ns < 1000000000) 571c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees data->timeout_ns = 1000000000; /* 1s */ 572c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } else { 573c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->timeout_ns < 100000000) 574c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees data->timeout_ns = 100000000; /* 100ms */ 575c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } 576c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } 577d773d7255199a6c8934e197756f54a1115dd127bRussell King} 578d773d7255199a6c8934e197756f54a1115dd127bRussell KingEXPORT_SYMBOL(mmc_set_data_timeout); 579d773d7255199a6c8934e197756f54a1115dd127bRussell King 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 581ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * mmc_align_data_size - pads a transfer size to a more optimal value 582ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * @card: the MMC card associated with the data transfer 583ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * @sz: original transfer size 584ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 585ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Pads the original data size with a number of extra bytes in 586ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * order to avoid controller bugs and/or performance hits 587ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * (e.g. some controllers revert to PIO for certain sizes). 588ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 589ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Returns the improved size, which might be unmodified. 590ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 591ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Note that this function is only relevant when issuing a 592ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * single scatter gather entry. 593ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman */ 594ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossmanunsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) 595ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman{ 596ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman /* 597ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * FIXME: We don't have a system for the controller to tell 598ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * the core about its problems yet, so for now we just 32-bit 599ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * align the size. 600ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman */ 601ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman sz = ((sz + 3) / 4) * 4; 602ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman 603ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman return sz; 604ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman} 605ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre OssmanEXPORT_SYMBOL(mmc_align_data_size); 606ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman 607ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman/** 6082342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * __mmc_claim_host - exclusively claim a host 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host to claim 6102342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * @abort: whether or not the operation should be aborted 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6122342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * Claim a host for a set of operations. If @abort is non null and 6132342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * dereference a non-zero value then this will return prematurely with 6142342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * that non-zero value without acquiring the lock. Returns zero 6152342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * with the lock held otherwise. 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6172342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitreint __mmc_claim_host(struct mmc_host *host, atomic_t *abort) 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DECLARE_WAITQUEUE(wait, current); 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 6212342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre int stop; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 623cf795bfb3ad4e2f8f6bb346aa8edb8272d4c70a2Pierre Ossman might_sleep(); 624cf795bfb3ad4e2f8f6bb346aa8edb8272d4c70a2Pierre Ossman 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_wait_queue(&host->wq, &wait); 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&host->lock, flags); 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 6292342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre stop = abort ? atomic_read(abort) : 0; 630319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (stop || !host->claimed || host->claimer == current) 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&host->lock, flags); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule(); 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&host->lock, flags); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_RUNNING); 637319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (!stop) { 6382342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre host->claimed = 1; 639319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = current; 640319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claim_cnt += 1; 641319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } else 6422342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre wake_up(&host->wq); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&host->lock, flags); 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_wait_queue(&host->wq, &wait); 645907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->enable && !stop && host->claim_cnt == 1) 646907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->enable(host); 6472342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre return stop; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6502342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas PitreEXPORT_SYMBOL(__mmc_claim_host); 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 652319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter/** 653319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * mmc_try_claim_host - try exclusively to claim a host 654319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * @host: mmc host to claim 655319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * 656319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * Returns %1 if the host is claimed, %0 otherwise. 657319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter */ 658319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunterint mmc_try_claim_host(struct mmc_host *host) 6598ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter{ 6608ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter int claimed_host = 0; 6618ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter unsigned long flags; 6628ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 6638ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_lock_irqsave(&host->lock, flags); 664319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (!host->claimed || host->claimer == current) { 6658ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter host->claimed = 1; 666319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = current; 667319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claim_cnt += 1; 6688ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter claimed_host = 1; 6698ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter } 6708ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 671907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->enable && claimed_host && host->claim_cnt == 1) 672907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->enable(host); 6738ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter return claimed_host; 6748ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter} 675319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian HunterEXPORT_SYMBOL(mmc_try_claim_host); 6768ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 677ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson/** 678907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * mmc_release_host - release a host 679ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson * @host: mmc host to release 680ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson * 681907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * Release a MMC host, allowing others to claim the host 682907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * for their operations. 683ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson */ 684907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Huntervoid mmc_release_host(struct mmc_host *host) 6858ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter{ 6868ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter unsigned long flags; 6878ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 688907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter WARN_ON(!host->claimed); 689907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter 690907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->disable && host->claim_cnt == 1) 691907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->disable(host); 692907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter 6938ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_lock_irqsave(&host->lock, flags); 694319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (--host->claim_cnt) { 695319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter /* Release for nested claim */ 696319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter spin_unlock_irqrestore(&host->lock, flags); 697319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } else { 698319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimed = 0; 699319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = NULL; 700319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter spin_unlock_irqrestore(&host->lock, flags); 701319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter wake_up(&host->wq); 702319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } 7038ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter} 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_release_host); 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7067ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 7077ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Internal function that does the actual ios call to the host driver, 7087ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * optionally printing some debug output. 7097ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 710920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell Kingstatic inline void mmc_set_ios(struct mmc_host *host) 711920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King{ 712920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King struct mmc_ios *ios = &host->ios; 713920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 714cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " 715cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman "width %u timing %u\n", 716920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_hostname(host), ios->clock, ios->bus_mode, 717920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King ios->power_mode, ios->chip_select, ios->vdd, 718cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman ios->bus_width, ios->timing); 719fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale 72004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (ios->clock > 0) 72104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_set_ungated(host); 722920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King host->ops->set_ios(host, ios); 723920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King} 724920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 7257ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 7267ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Control chip select pin on a host. 7277ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 728da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossmanvoid mmc_set_chip_select(struct mmc_host *host, int mode) 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 730778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 731da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman host->ios.chip_select = mode; 732da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman mmc_set_ios(host); 733778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7377ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Sets the host clock to the highest possible frequency that 7387ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * is below "hz". 7397ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 740778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerbergstatic void __mmc_set_clock(struct mmc_host *host, unsigned int hz) 7417ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman{ 7427ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman WARN_ON(hz < host->f_min); 7437ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 7447ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (hz > host->f_max) 7457ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman hz = host->f_max; 7467ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 7477ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.clock = hz; 7487ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 7497ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman} 7507ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 751778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerbergvoid mmc_set_clock(struct mmc_host *host, unsigned int hz) 752778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg{ 753778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 754778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg __mmc_set_clock(host, hz); 755778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 756778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg} 757778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 75804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#ifdef CONFIG_MMC_CLKGATE 75904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 76004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * This gates the clock by setting it to 0 Hz. 76104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 76204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_gate_clock(struct mmc_host *host) 76304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 76404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 76504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 76604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 76704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_old = host->ios.clock; 76804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->ios.clock = 0; 76904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_gated = true; 77004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 77104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_set_ios(host); 77204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 77304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 77404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 77504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * This restores the clock from gating by using the cached 77604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * clock value. 77704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 77804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_ungate_clock(struct mmc_host *host) 77904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 78004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 78104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * We should previously have gated the clock, so the clock shall 78204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * be 0 here! The clock may however be 0 during initialization, 78304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * when some request operations are performed before setting 78404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * the frequency. When ungate is requested in that situation 78504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * we just ignore the call. 78604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 78704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (host->clk_old) { 78804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij BUG_ON(host->ios.clock); 78904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* This call will also set host->clk_gated to false */ 790778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg __mmc_set_clock(host, host->clk_old); 79104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 79204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 79304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 79404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_set_ungated(struct mmc_host *host) 79504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 79604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 79704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 79804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 79904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * We've been given a new frequency while the clock is gated, 80004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * so make sure we regard this as ungating it. 80104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 80204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 80304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_gated = false; 80404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 80504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 80604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 80704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#else 80804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_set_ungated(struct mmc_host *host) 80904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 81004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 81104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#endif 81204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 8137ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 8147ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Change the bus mode (open drain/push-pull) of a host. 8157ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 8167ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) 8177ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman{ 818778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 8197ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.bus_mode = mode; 8207ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 821778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 8227ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman} 8237ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 8247ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 8250f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter * Change data bus width of a host. 8260f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter */ 8270f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Huntervoid mmc_set_bus_width(struct mmc_host *host, unsigned int width) 8280f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter{ 829778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 8304c4cb171054230c2e58ed6574d7faa1871c75bbePhilip Rakity host->ios.bus_width = width; 8314c4cb171054230c2e58ed6574d7faa1871c75bbePhilip Rakity mmc_set_ios(host); 832778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 8330f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter} 8340f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 83586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov/** 83686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number 83786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd: voltage (mV) 83886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @low_bits: prefer low bits in boundary cases 83986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 84086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function returns the OCR bit number according to the provided @vdd 84186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * value. If conversion is not possible a negative errno value returned. 84286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 84386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Depending on the @low_bits flag the function prefers low or high OCR bits 84486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * on boundary voltages. For example, 84586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); 84686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); 84786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 84886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). 84986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov */ 85086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsovstatic int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) 85186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov{ 85286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov const int max_bit = ilog2(MMC_VDD_35_36); 85386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov int bit; 85486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 85586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd < 1650 || vdd > 3600) 85686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return -EINVAL; 85786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 85886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd >= 1650 && vdd <= 1950) 85986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return ilog2(MMC_VDD_165_195); 86086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 86186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (low_bits) 86286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd -= 1; 86386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 86486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Base 2000 mV, step 100 mV, bit's base 8. */ 86586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov bit = (vdd - 2000) / 100 + 8; 86686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (bit > max_bit) 86786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return max_bit; 86886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return bit; 86986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov} 87086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 87186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov/** 87286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask 87386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd_min: minimum voltage value (mV) 87486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd_max: maximum voltage value (mV) 87586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 87686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function returns the OCR mask bits according to the provided @vdd_min 87786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * and @vdd_max values. If conversion is not possible the function returns 0. 87886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 87986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Notes wrt boundary cases: 88086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function sets the OCR bits for all boundary voltages, for example 88186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | 88286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * MMC_VDD_34_35 mask. 88386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov */ 88486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsovu32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) 88586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov{ 88686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov u32 mask = 0; 88786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 88886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_max < vdd_min) 88986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 89086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 89186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Prefer high bits for the boundary vdd_max values. */ 89286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); 89386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_max < 0) 89486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 89586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 89686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Prefer low bits for the boundary vdd_min values. */ 89786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); 89886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_min < 0) 89986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 90086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 90186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Fill the mask, from max bit to min bit. */ 90286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov while (vdd_max >= vdd_min) 90386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov mask |= 1 << vdd_max--; 90486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 90586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return mask; 90686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov} 90786e8286a0e48663e1e86a5884b30a6d05de2993aAnton VorontsovEXPORT_SYMBOL(mmc_vddrange_to_ocrmask); 90886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 9095c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell#ifdef CONFIG_REGULATOR 9105c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9115c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell/** 9125c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * mmc_regulator_get_ocrmask - return mask of supported voltages 9135c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * @supply: regulator to use 9145c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9155c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * This returns either a negative errno, or a mask of voltages that 9165c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * can be provided to MMC/SD/SDIO devices using the specified voltage 9175c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * regulator. This would normally be called before registering the 9185c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * MMC host adapter. 9195c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9205c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownellint mmc_regulator_get_ocrmask(struct regulator *supply) 9215c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell{ 9225c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int result = 0; 9235c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int count; 9245c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int i; 9255c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9265c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell count = regulator_count_voltages(supply); 9275c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (count < 0) 9285c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return count; 9295c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9305c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell for (i = 0; i < count; i++) { 9315c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int vdd_uV; 9325c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int vdd_mV; 9335c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9345c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell vdd_uV = regulator_list_voltage(supply, i); 9355c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (vdd_uV <= 0) 9365c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell continue; 9375c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9385c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell vdd_mV = vdd_uV / 1000; 9395c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); 9405c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 9415c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9425c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return result; 9435c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell} 9445c13941acc513669c7d07b28789c3f9ba66ddddfDavid BrownellEXPORT_SYMBOL(mmc_regulator_get_ocrmask); 9455c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9465c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell/** 9475c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * mmc_regulator_set_ocr - set regulator to match host->ios voltage 94899fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij * @mmc: the host to regulate 9495c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * @supply: regulator to use 95099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) 9515c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9525c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * Returns zero on success, else negative errno. 9535c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9545c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * MMC host drivers may use this to enable or disable a regulator using 9555c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * a particular supply voltage. This would normally be called from the 9565c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * set_ios() method. 9575c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 95899fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleijint mmc_regulator_set_ocr(struct mmc_host *mmc, 95999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij struct regulator *supply, 96099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij unsigned short vdd_bit) 9615c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell{ 9625c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int result = 0; 9635c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int min_uV, max_uV; 9645c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9655c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (vdd_bit) { 9665c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int tmp; 9675c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int voltage; 9685c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9695c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell /* REVISIT mmc_vddrange_to_ocrmask() may have set some 9705c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * bits this regulator doesn't quite support ... don't 9715c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * be too picky, most cards and regulators are OK with 9725c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * a 0.1V range goof (it's a small error percentage). 9735c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9745c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell tmp = vdd_bit - ilog2(MMC_VDD_165_195); 9755c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (tmp == 0) { 9765c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell min_uV = 1650 * 1000; 9775c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell max_uV = 1950 * 1000; 9785c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } else { 9795c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell min_uV = 1900 * 1000 + tmp * 100 * 1000; 9805c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell max_uV = min_uV + 100 * 1000; 9815c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 9825c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9835c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell /* avoid needless changes to this voltage; the regulator 9845c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * might not allow this operation 9855c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9865c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell voltage = regulator_get_voltage(supply); 9876e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung 9886e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE) 9896e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung min_uV = max_uV = voltage; 9906e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung 9915c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (voltage < 0) 9925c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = voltage; 9935c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell else if (voltage < min_uV || voltage > max_uV) 9945c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_set_voltage(supply, min_uV, max_uV); 9955c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell else 9965c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = 0; 9975c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 99899fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result == 0 && !mmc->regulator_enabled) { 9995c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_enable(supply); 100099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (!result) 100199fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij mmc->regulator_enabled = true; 100299fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij } 100399fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij } else if (mmc->regulator_enabled) { 10045c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_disable(supply); 100599fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result == 0) 100699fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij mmc->regulator_enabled = false; 10075c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 10085c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 100999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result) 101099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij dev_err(mmc_dev(mmc), 101199fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij "could not set regulator OCR (%d)\n", result); 10125c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return result; 10135c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell} 10145c13941acc513669c7d07b28789c3f9ba66ddddfDavid BrownellEXPORT_SYMBOL(mmc_regulator_set_ocr); 10155c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 101699fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij#endif /* CONFIG_REGULATOR */ 10175c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 10187ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Mask off any voltages we don't support and select 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the lowest voltage 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10227ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanu32 mmc_select_voltage(struct mmc_host *host, u32 ocr) 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int bit; 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ocr &= host->ocr_avail; 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit = ffs(ocr); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bit) { 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit -= 1; 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 103263ef731aa6a81e286de78dcc92241d123424ed39Timo Teras ocr &= 3 << bit; 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1034778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = bit; 1036920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 1037778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1039f6e10b865c3ea56bdaa8c6ecfee313b997900dbbDavid Brownell pr_warning("%s: host doesn't support card's voltages\n", 1040f6e10b865c3ea56bdaa8c6ecfee313b997900dbbDavid Brownell mmc_hostname(host)); 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ocr = 0; 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ocr; 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1047261bbd463a091b939770255d559bbc89b1bad568Philip Rakityint mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11) 1048f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath{ 1049f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath struct mmc_command cmd = {0}; 1050f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath int err = 0; 1051f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1052f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath BUG_ON(!host); 1053f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1054f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath /* 1055f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath * Send CMD11 only if the request is to switch the card to 1056f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath * 1.8V signalling. 1057f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath */ 1058261bbd463a091b939770255d559bbc89b1bad568Philip Rakity if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) { 1059f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.opcode = SD_SWITCH_VOLTAGE; 1060f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.arg = 0; 1061f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1062f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1063f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath err = mmc_wait_for_cmd(host, &cmd, 0); 1064f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath if (err) 1065f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return err; 1066f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1067f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) 1068f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return -EIO; 1069f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath } 1070f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1071f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath host->ios.signal_voltage = signal_voltage; 1072f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 10732c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->start_signal_voltage_switch) { 10742c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 1075f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath err = host->ops->start_signal_voltage_switch(host, &host->ios); 10762c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 10772c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 1078f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1079f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return err; 1080f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath} 1081f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10837ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Select timing parameters for host. 1084b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman */ 10857ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_set_timing(struct mmc_host *host, unsigned int timing) 1086b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman{ 1087778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 10887ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.timing = timing; 10897ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 1090778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 1091b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman} 1092b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 1093b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman/* 1094d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath * Select appropriate driver type for host. 1095d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath */ 1096d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nathvoid mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) 1097d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath{ 1098778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1099d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath host->ios.drv_type = drv_type; 1100d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath mmc_set_ios(host); 1101778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 1102d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath} 1103d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath 1104a80f16276388a177199204aa5b60f328d4464110Girish K Sstatic void mmc_poweroff_notify(struct mmc_host *host) 1105a80f16276388a177199204aa5b60f328d4464110Girish K S{ 1106a80f16276388a177199204aa5b60f328d4464110Girish K S struct mmc_card *card; 1107a80f16276388a177199204aa5b60f328d4464110Girish K S unsigned int timeout; 1108a80f16276388a177199204aa5b60f328d4464110Girish K S unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION; 1109a80f16276388a177199204aa5b60f328d4464110Girish K S int err = 0; 1110a80f16276388a177199204aa5b60f328d4464110Girish K S 1111a80f16276388a177199204aa5b60f328d4464110Girish K S card = host->card; 11123e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_claim_host(host); 1113a80f16276388a177199204aa5b60f328d4464110Girish K S 1114a80f16276388a177199204aa5b60f328d4464110Girish K S /* 1115a80f16276388a177199204aa5b60f328d4464110Girish K S * Send power notify command only if card 1116a80f16276388a177199204aa5b60f328d4464110Girish K S * is mmc and notify state is powered ON 1117a80f16276388a177199204aa5b60f328d4464110Girish K S */ 1118a80f16276388a177199204aa5b60f328d4464110Girish K S if (card && mmc_card_mmc(card) && 1119a80f16276388a177199204aa5b60f328d4464110Girish K S (card->poweroff_notify_state == MMC_POWERED_ON)) { 1120a80f16276388a177199204aa5b60f328d4464110Girish K S 1121a80f16276388a177199204aa5b60f328d4464110Girish K S if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { 1122a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type = EXT_CSD_POWER_OFF_SHORT; 1123a80f16276388a177199204aa5b60f328d4464110Girish K S timeout = card->ext_csd.generic_cmd6_time; 1124a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_POWEROFF_SHORT; 1125a80f16276388a177199204aa5b60f328d4464110Girish K S } else { 1126a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type = EXT_CSD_POWER_OFF_LONG; 1127a80f16276388a177199204aa5b60f328d4464110Girish K S timeout = card->ext_csd.power_off_longtime; 1128a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_POWEROFF_LONG; 1129a80f16276388a177199204aa5b60f328d4464110Girish K S } 1130a80f16276388a177199204aa5b60f328d4464110Girish K S 1131a80f16276388a177199204aa5b60f328d4464110Girish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1132a80f16276388a177199204aa5b60f328d4464110Girish K S EXT_CSD_POWER_OFF_NOTIFICATION, 1133a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type, timeout); 1134a80f16276388a177199204aa5b60f328d4464110Girish K S 1135a80f16276388a177199204aa5b60f328d4464110Girish K S if (err && err != -EBADMSG) 1136a80f16276388a177199204aa5b60f328d4464110Girish K S pr_err("Device failed to respond within %d poweroff " 1137a80f16276388a177199204aa5b60f328d4464110Girish K S "time. Forcefully powering down the device\n", 1138a80f16276388a177199204aa5b60f328d4464110Girish K S timeout); 1139a80f16276388a177199204aa5b60f328d4464110Girish K S 1140a80f16276388a177199204aa5b60f328d4464110Girish K S /* Set the card state to no notification after the poweroff */ 1141a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; 1142a80f16276388a177199204aa5b60f328d4464110Girish K S } 11433e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_release_host(host); 1144a80f16276388a177199204aa5b60f328d4464110Girish K S} 1145a80f16276388a177199204aa5b60f328d4464110Girish K S 1146d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath/* 114745f8245b972e360c19aec9032e2a2033b8ac3719Russell King * Apply power to the MMC stack. This is a two-stage process. 114845f8245b972e360c19aec9032e2a2033b8ac3719Russell King * First, we enable power to the card without the clock running. 114945f8245b972e360c19aec9032e2a2033b8ac3719Russell King * We then wait a bit for the power to stabilise. Finally, 115045f8245b972e360c19aec9032e2a2033b8ac3719Russell King * enable the bus drivers and clock to the card. 115145f8245b972e360c19aec9032e2a2033b8ac3719Russell King * 115245f8245b972e360c19aec9032e2a2033b8ac3719Russell King * We must _NOT_ enable the clock prior to power stablising. 115345f8245b972e360c19aec9032e2a2033b8ac3719Russell King * 115445f8245b972e360c19aec9032e2a2033b8ac3719Russell King * If a host does all the power sequencing itself, ignore the 115545f8245b972e360c19aec9032e2a2033b8ac3719Russell King * initial MMC_POWER_UP stage. 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_power_up(struct mmc_host *host) 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1159500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao int bit; 1160500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao 1161778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1162778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1163500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao /* If ocr is set, we use it */ 1164500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao if (host->ocr) 1165500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao bit = ffs(host->ocr) - 1; 1166500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao else 1167500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao bit = fls(host->ocr_avail) - 1; 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = bit; 117044669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK if (mmc_host_is_spi(host)) 1171af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_HIGH; 117244669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK else 1173af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_DONTCARE; 117444669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_UP; 1176f218278a456b3c272b480443c89004c3d2a49f18Pierre Ossman host->ios.bus_width = MMC_BUS_WIDTH_1; 1177cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman host->ios.timing = MMC_TIMING_LEGACY; 1178920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1180f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman /* 1181f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * This delay should be sufficient to allow the power supply 1182f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * to reach the minimum voltage. 1183f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman */ 118479bccc5aefb4e64e651abe04f78c3e6bf8acd6f0José M. Fernández mmc_delay(10); 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 118688ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch host->ios.clock = host->f_init; 11878dfd0374be84793360db7fff2e635d2cd3bbcb21Sascha Hauer 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_ON; 1189920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman /* 1192f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * This delay must be at least 74 clock sizes, or 1 ms, or the 1193f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * time required to reach a stable voltage. 1194f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman */ 119579bccc5aefb4e64e651abe04f78c3e6bf8acd6f0José M. Fernández mmc_delay(10); 1196778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1197778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12007f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hanssonvoid mmc_power_off(struct mmc_host *host) 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12023e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S int err = 0; 1203778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1204778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.clock = 0; 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = 0; 1207b33d46c398fd071dccd0815f33620924684860cdUlf Hansson 12083e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S /* 12093e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * For eMMC 4.5 device send AWAKE command before 12103e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * POWER_OFF_NOTIFY command, because in sleep state 12113e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * eMMC 4.5 devices respond to only RESET and AWAKE cmd 12123e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S */ 12133e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S if (host->card && mmc_card_is_sleep(host->card) && 12143e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S host->bus_ops->resume) { 12153e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S err = host->bus_ops->resume(host); 12163e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S 12173e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S if (!err) 12183e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_poweroff_notify(host); 12193e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S else 12203e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S pr_warning("%s: error %d during resume " 12213e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S "(continue with poweroff sequence)\n", 12223e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_hostname(host), err); 12233e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S } 1224bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S 1225b33d46c398fd071dccd0815f33620924684860cdUlf Hansson /* 1226b33d46c398fd071dccd0815f33620924684860cdUlf Hansson * Reset ocr mask to be the highest possible voltage supported for 1227b33d46c398fd071dccd0815f33620924684860cdUlf Hansson * this mmc host. This value will be used at next power up. 1228b33d46c398fd071dccd0815f33620924684860cdUlf Hansson */ 1229b33d46c398fd071dccd0815f33620924684860cdUlf Hansson host->ocr = 1 << (fls(host->ocr_avail) - 1); 1230b33d46c398fd071dccd0815f33620924684860cdUlf Hansson 1231af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (!mmc_host_is_spi(host)) { 1232af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 1233af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_DONTCARE; 1234af51715079e7fb6b290e1881d63d815dc4de5011David Brownell } 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_OFF; 1236f218278a456b3c272b480443c89004c3d2a49f18Pierre Ossman host->ios.bus_width = MMC_BUS_WIDTH_1; 1237cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman host->ios.timing = MMC_TIMING_LEGACY; 1238920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 1239778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1240041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake /* 1241041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * Some configurations, such as the 802.11 SDIO card in the OLPC 1242041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * XO-1.5, require a short delay after poweroff before the card 1243041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * can be successfully turned on again. 1244041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake */ 1245041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake mmc_delay(1); 1246041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake 1247778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1251393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Cleanup when the last reference to the bus operator is dropped. 1252393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1253261172fd1b23769bc7632047e2cb826c9b8b1a50Adrian Bunkstatic void __mmc_release_bus(struct mmc_host *host) 1254393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1255393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(!host); 1256393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(host->bus_refs); 1257393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(!host->bus_dead); 1258393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1259393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_ops = NULL; 1260393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1261393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1262393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 1263393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Increase reference count of bus operator 1264393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1265393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic inline void mmc_bus_get(struct mmc_host *host) 1266393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1267393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk unsigned long flags; 1268393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1269393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_lock_irqsave(&host->lock, flags); 1270393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_refs++; 1271393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_unlock_irqrestore(&host->lock, flags); 1272393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1273393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1274393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 1275393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Decrease reference count of bus operator and free it if 1276393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * it is the last reference. 1277393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1278393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic inline void mmc_bus_put(struct mmc_host *host) 1279393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1280393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk unsigned long flags; 1281393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1282393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_lock_irqsave(&host->lock, flags); 1283393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_refs--; 1284393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk if ((host->bus_refs == 0) && host->bus_ops) 1285393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk __mmc_release_bus(host); 1286393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_unlock_irqrestore(&host->lock, flags); 1287393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1288393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 128941d9d91eeb7288e34a7631b4446b0f642055daa7San Mehatint mmc_resume_bus(struct mmc_host *host) 129041d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat{ 12910eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt unsigned long flags; 12920eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt 129341d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat if (!mmc_bus_needs_resume(host)) 129441d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat return -EINVAL; 129541d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 129641d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat printk("%s: Starting deferred resume\n", mmc_hostname(host)); 12970eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt spin_lock_irqsave(&host->lock, flags); 129841d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; 12990eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt host->rescan_disable = 0; 13000eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt spin_unlock_irqrestore(&host->lock, flags); 13010eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt 130241d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat mmc_bus_get(host); 130341d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat if (host->bus_ops && !host->bus_dead) { 130441d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat mmc_power_up(host); 130541d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat BUG_ON(!host->bus_ops->resume); 130641d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat host->bus_ops->resume(host); 130741d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat } 130841d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 130941d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat if (host->bus_ops->detect && !host->bus_dead) 131041d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat host->bus_ops->detect(host); 131141d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 131241d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat mmc_bus_put(host); 131341d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat printk("%s: Deferred resume completed\n", mmc_hostname(host)); 131441d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat return 0; 131541d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat} 131641d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 131741d9d91eeb7288e34a7631b4446b0f642055daa7San MehatEXPORT_SYMBOL(mmc_resume_bus); 131841d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 1319393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 13207ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Assign a mmc bus handler to a host. Only one bus handler may control a 13217ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * host at any given time. 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13237ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13257ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman unsigned long flags; 1326e45a1bd20fa5b920901879e85cdf5eda21f78d7cPhilip Langdale 13277ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!host); 13287ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!ops); 1329b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman 1330d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 1331bce40a36de574376f41f1ff3c4d212a7da2a3c90Philip Langdale 13327ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_lock_irqsave(&host->lock, flags); 1333bce40a36de574376f41f1ff3c4d212a7da2a3c90Philip Langdale 13347ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->bus_ops); 13357ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->bus_refs); 1336b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13377ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_ops = ops; 13387ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_refs = 1; 13397ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_dead = 0; 1340b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13417ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_unlock_irqrestore(&host->lock, flags); 1342b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman} 1343b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13447ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 13457f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson * Remove the current bus handler from a host. 13467ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 13477ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_detach_bus(struct mmc_host *host) 13487ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman{ 13497ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman unsigned long flags; 13507ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13517ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!host); 13527ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 1353d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 1354d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->bus_ops); 1355cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman 13567ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_lock_irqsave(&host->lock, flags); 13577ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13587ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_dead = 1; 13597ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13607ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_unlock_irqrestore(&host->lock, flags); 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13627ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_detect_change - process change of state on a MMC socket 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: host which changed state. 13688dc003359cc3996abad9e53a7b2280b272610283Richard Purdie * @delay: optional delay to wait before detection (jiffies) 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 137067a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * MMC drivers should call this when they detect a card has been 137167a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * inserted or removed. The MMC layer will confirm that any 137267a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * present card is still functional, and initialize any newly 137367a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * inserted. 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13758dc003359cc3996abad9e53a7b2280b272610283Richard Purdievoid mmc_detect_change(struct mmc_host *host, unsigned long delay) 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13773b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#ifdef CONFIG_MMC_DEBUG 13781efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman unsigned long flags; 137901f41ec7b36e14da18a4e162ef697ae358f36e37Andrew Morton spin_lock_irqsave(&host->lock, flags); 1380d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(host->removed); 138101f41ec7b36e14da18a4e162ef697ae358f36e37Andrew Morton spin_unlock_irqrestore(&host->lock, flags); 13823b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#endif 1383d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 1; 138426d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross 138526d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_lock(&host->detect_wake_lock); 1386c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells mmc_schedule_delayed_work(&host->detect, delay); 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_detect_change); 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Huntervoid mmc_init_erase(struct mmc_card *card) 1392dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1393dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int sz; 1394dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1395dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (is_power_of_2(card->erase_size)) 1396dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = ffs(card->erase_size) - 1; 1397dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1398dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = 0; 1399dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1400dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1401dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * It is possible to erase an arbitrarily large area of an SD or MMC 1402dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * card. That is not desirable because it can take a long time 1403dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * (minutes) potentially delaying more important I/O, and also the 1404dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * timeout calculations become increasingly hugely over-estimated. 1405dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Consequently, 'pref_erase' is defined as a guide to limit erases 1406dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * to that size and alignment. 1407dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1408dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * For SD cards that define Allocation Unit size, limit erases to one 1409dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Allocation Unit at a time. For MMC cards that define High Capacity 1410dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Erase Size, whether it is switched on or not, limit to that size. 1411dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Otherwise just have a stab at a good value. For modern cards it 1412dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * will end up being 4MiB. Note that if the value is too small, it 1413dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * can end up taking longer to erase. 1414dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1415dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card) && card->ssr.au) { 1416dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->ssr.au; 1417dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = ffs(card->ssr.au) - 1; 1418dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else if (card->ext_csd.hc_erase_size) { 1419dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->ext_csd.hc_erase_size; 1420dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1421dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter sz = (card->csd.capacity << (card->csd.read_blkbits - 9)) >> 11; 1422dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (sz < 128) 1423dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 512 * 1024 / 512; 1424dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (sz < 512) 1425dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 1024 * 1024 / 512; 1426dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (sz < 1024) 1427dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 2 * 1024 * 1024 / 512; 1428dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1429dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 4 * 1024 * 1024 / 512; 1430dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->pref_erase < card->erase_size) 1431dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->erase_size; 1432dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else { 1433dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter sz = card->pref_erase % card->erase_size; 1434dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (sz) 1435dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase += card->erase_size - sz; 1436dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1437dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1438dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1439dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1440eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, 1441eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, unsigned int qty) 1442dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1443dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int erase_timeout; 1444dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 14457194efb8f063ee3aa0cb50d9002348887e68ec10Adrian Hunter if (arg == MMC_DISCARD_ARG || 14467194efb8f063ee3aa0cb50d9002348887e68ec10Adrian Hunter (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { 14477194efb8f063ee3aa0cb50d9002348887e68ec10Adrian Hunter erase_timeout = card->ext_csd.trim_timeout; 14487194efb8f063ee3aa0cb50d9002348887e68ec10Adrian Hunter } else if (card->ext_csd.erase_group_def & 1) { 1449dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* High Capacity Erase Group Size uses HC timeouts */ 1450dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_TRIM_ARG) 1451dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = card->ext_csd.trim_timeout; 1452dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1453dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = card->ext_csd.hc_erase_timeout; 1454dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1455dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* CSD Erase Group Size uses write timeout */ 1456dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int mult = (10 << card->csd.r2w_factor); 1457dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int timeout_clks = card->csd.tacc_clks * mult; 1458dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int timeout_us; 1459dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1460dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */ 1461dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->csd.tacc_ns < 1000000) 1462dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us = (card->csd.tacc_ns * mult) / 1000; 1463dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1464dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us = (card->csd.tacc_ns / 1000) * mult; 1465dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1466dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1467dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * ios.clock is only a target. The real clock rate might be 1468dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * less but not that much less, so fudge it by multiplying by 2. 1469dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1470dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_clks <<= 1; 1471dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us += (timeout_clks * 1000) / 14724cf8c6dd2e261da94b87c4deadcc136ab022b6acAdrian Hunter (mmc_host_clk_rate(card->host) / 1000); 1473dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1474dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = timeout_us / 1000; 1475dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1476dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1477dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Theoretically, the calculation could underflow so round up 1478dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * to 1ms in that case. 1479dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1480dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!erase_timeout) 1481dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = 1; 1482dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1483dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1484dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Multiplier for secure operations */ 1485dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg & MMC_SECURE_ARGS) { 1486dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_SECURE_ERASE_ARG) 1487dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= card->ext_csd.sec_erase_mult; 1488dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1489dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= card->ext_csd.sec_trim_mult; 1490dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1491dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1492dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= qty; 1493dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1494dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1495dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Ensure at least a 1 second timeout for SPI as per 1496dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 'mmc_set_data_timeout()' 1497dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1498dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_host_is_spi(card->host) && erase_timeout < 1000) 1499dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = 1000; 1500dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1501eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return erase_timeout; 1502dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1503dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1504eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_sd_erase_timeout(struct mmc_card *card, 1505eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, 1506eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int qty) 1507dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1508eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int erase_timeout; 1509eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin 1510dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ssr.erase_timeout) { 1511dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Erase timeout specified in SD Status Register (SSR) */ 1512eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = card->ssr.erase_timeout * qty + 1513eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin card->ssr.erase_offset; 1514dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1515dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1516dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Erase timeout not specified in SD Status Register (SSR) so 1517dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * use 250ms per write block. 1518dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1519eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = 250 * qty; 1520dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1521dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1522dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Must not be less than 1 second */ 1523eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin if (erase_timeout < 1000) 1524eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = 1000; 1525eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin 1526eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return erase_timeout; 1527dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1528dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1529eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_erase_timeout(struct mmc_card *card, 1530eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, 1531eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int qty) 1532dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1533dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1534eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return mmc_sd_erase_timeout(card, arg, qty); 1535dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1536eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return mmc_mmc_erase_timeout(card, arg, qty); 1537dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1538dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1539dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterstatic int mmc_do_erase(struct mmc_card *card, unsigned int from, 1540dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int to, unsigned int arg) 1541dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 15421278dba167f01bb3c6626d16450d31129d041087Chris Ball struct mmc_command cmd = {0}; 1543dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int qty = 0; 1544dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter int err; 1545dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1546dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1547dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * qty is used to calculate the erase timeout which depends on how many 1548dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * erase groups (or allocation units in SD terminology) are affected. 1549dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * We count erasing part of an erase group as one erase group. 1550dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * For SD, the allocation units are always a power of 2. For MMC, the 1551dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * erase group size is almost certainly also power of 2, but it does not 1552dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * seem to insist on that in the JEDEC standard, so we fall back to 1553dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * division in that case. SD may not specify an allocation unit size, 1554dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * in which case the timeout is based on the number of write blocks. 1555dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1556dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Note that the timeout for secure trim 2 will only be correct if the 1557dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * number of erase groups specified is the same as the total of all 1558dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * preceding secure trim 1 commands. Since the power may have been 1559dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * lost since the secure trim 1 commands occurred, it is generally 1560dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * impossible to calculate the secure trim 2 timeout correctly. 1561dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1562dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->erase_shift) 1563dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += ((to >> card->erase_shift) - 1564dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (from >> card->erase_shift)) + 1; 1565dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (mmc_card_sd(card)) 1566dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += to - from + 1; 1567dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1568dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += ((to / card->erase_size) - 1569dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (from / card->erase_size)) + 1; 1570dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1571dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!mmc_card_blockaddr(card)) { 1572dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter from <<= 9; 1573dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to <<= 9; 1574dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1575dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1576dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1577dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = SD_ERASE_WR_BLK_START; 1578dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1579dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE_GROUP_START; 1580dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = from; 1581dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 1582dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1583dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1584a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: group start error %d, " 1585dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter "status %#x\n", err, cmd.resp[0]); 158667716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter err = -EIO; 1587dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1588dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1589dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1590dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1591dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1592dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = SD_ERASE_WR_BLK_END; 1593dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1594dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE_GROUP_END; 1595dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = to; 1596dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 1597dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1598dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1599a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: group end error %d, status %#x\n", 1600dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 160167716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter err = -EIO; 1602dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1603dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1604dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1605dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1606dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE; 1607dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = arg; 1608dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; 1609eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty); 1610dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1611dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1612a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: erase error %d, status %#x\n", 1613dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 1614dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = -EIO; 1615dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1616dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1617dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1618dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_host_is_spi(card->host)) 1619dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1620dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1621dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter do { 1622dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1623dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_SEND_STATUS; 1624dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = card->rca << 16; 1625dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1626dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Do not retry else we can't see errors */ 1627dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1628dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err || (cmd.resp[0] & 0xFDF92000)) { 1629a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("error %d requesting status %#x\n", 1630dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 1631dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = -EIO; 1632dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1633dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1634dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || 16357435bb7950ba8a3cbfa6d0c01e92588562533a3fJaehoon Chung R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG); 1636dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterout: 1637dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return err; 1638dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1639dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1640dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter/** 1641dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * mmc_erase - erase sectors. 1642dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @card: card to erase 1643dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @from: first sector to erase 1644dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @nr: number of sectors to erase 1645dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) 1646dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1647dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Caller must claim host before calling this function. 1648dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1649dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, 1650dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int arg) 1651dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1652dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int rem, to = from + nr; 1653dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1654dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!(card->host->caps & MMC_CAP_ERASE) || 1655dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->csd.cmdclass & CCC_ERASE)) 1656dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1657dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1658dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!card->erase_size) 1659dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1660dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1661dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card) && arg != MMC_ERASE_ARG) 1662dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1663dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1664dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((arg & MMC_SECURE_ARGS) && 1665dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) 1666dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1667dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1668dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((arg & MMC_TRIM_ARGS) && 1669dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) 1670dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1671dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1672dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_SECURE_ERASE_ARG) { 1673dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (from % card->erase_size || nr % card->erase_size) 1674dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EINVAL; 1675dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1676dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1677dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_ERASE_ARG) { 1678dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = from % card->erase_size; 1679dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (rem) { 1680dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = card->erase_size - rem; 1681dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter from += rem; 1682dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (nr > rem) 1683dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter nr -= rem; 1684dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1685dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1686dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1687dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = nr % card->erase_size; 1688dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (rem) 1689dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter nr -= rem; 1690dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1691dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1692dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (nr == 0) 1693dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1694dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1695dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to = from + nr; 1696dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1697dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (to <= from) 1698dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EINVAL; 1699dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1700dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 'from' and 'to' are inclusive */ 1701dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to -= 1; 1702dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1703dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return mmc_do_erase(card, from, to, arg); 1704dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1705dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_erase); 1706dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1707dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_erase(struct mmc_card *card) 1708dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1709dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((card->host->caps & MMC_CAP_ERASE) && 1710dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (card->csd.cmdclass & CCC_ERASE) && card->erase_size) 1711dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1712dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1713dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1714dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_erase); 1715dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1716dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_trim(struct mmc_card *card) 1717dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1718dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) 1719dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1720dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1721dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1722dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_trim); 1723dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1724b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Parkint mmc_can_discard(struct mmc_card *card) 1725b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park{ 1726b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park /* 1727b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park * As there's no way to detect the discard support bit at v4.5 1728b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park * use the s/w feature support filed. 1729b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park */ 1730b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE) 1731b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park return 1; 1732b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park return 0; 1733b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park} 1734b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin ParkEXPORT_SYMBOL(mmc_can_discard); 1735b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park 1736d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Parkint mmc_can_sanitize(struct mmc_card *card) 1737d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park{ 1738283028122db37621b124f079ca8eae5b64807ad4Adrian Hunter if (!mmc_can_trim(card) && !mmc_can_erase(card)) 1739283028122db37621b124f079ca8eae5b64807ad4Adrian Hunter return 0; 1740d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) 1741d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park return 1; 1742d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park return 0; 1743d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park} 1744d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin ParkEXPORT_SYMBOL(mmc_can_sanitize); 1745d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park 1746dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_secure_erase_trim(struct mmc_card *card) 1747dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1748dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN) 1749dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1750dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1751dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1752dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_secure_erase_trim); 1753dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1754dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, 1755dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int nr) 1756dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1757dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!card->erase_size) 1758dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1759dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (from % card->erase_size || nr % card->erase_size) 1760dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1761dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1762dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1763dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_erase_group_aligned); 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1765e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunterstatic unsigned int mmc_do_calc_max_discard(struct mmc_card *card, 1766e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int arg) 1767e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter{ 1768e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter struct mmc_host *host = card->host; 1769e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int max_discard, x, y, qty = 0, max_qty, timeout; 1770e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int last_timeout = 0; 1771e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1772e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (card->erase_shift) 1773e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX >> card->erase_shift; 1774e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else if (mmc_card_sd(card)) 1775e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX; 1776e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else 1777e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX / card->erase_size; 1778e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1779e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* Find the largest qty with an OK timeout */ 1780e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter do { 1781e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter y = 0; 1782e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { 1783e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter timeout = mmc_erase_timeout(card, arg, qty + x); 1784e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (timeout > host->max_discard_to) 1785e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter break; 1786e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (timeout < last_timeout) 1787e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter break; 1788e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter last_timeout = timeout; 1789e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter y = x; 1790e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } 1791e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter qty += y; 1792e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } while (y); 1793e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1794e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (!qty) 1795e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return 0; 1796e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1797e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (qty == 1) 1798e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return 1; 1799e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1800e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* Convert qty to sectors */ 1801e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (card->erase_shift) 1802e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = --qty << card->erase_shift; 1803e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else if (mmc_card_sd(card)) 1804e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = qty; 1805e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else 1806e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = --qty * card->erase_size; 1807e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1808e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return max_discard; 1809e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter} 1810e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1811e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunterunsigned int mmc_calc_max_discard(struct mmc_card *card) 1812e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter{ 1813e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter struct mmc_host *host = card->host; 1814e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int max_discard, max_trim; 1815e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1816e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (!host->max_discard_to) 1817e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return UINT_MAX; 1818e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1819e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* 1820e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * Without erase_group_def set, MMC erase timeout depends on clock 1821e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * frequence which can change. In that case, the best choice is 1822e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * just the preferred erase size. 1823e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter */ 1824e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1)) 1825e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return card->pref_erase; 1826e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1827e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG); 1828e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (mmc_can_trim(card)) { 1829e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG); 1830e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (max_trim < max_discard) 1831e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = max_trim; 1832e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } else if (max_discard < card->erase_size) { 1833e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = 0; 1834e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } 1835e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n", 1836e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter mmc_hostname(host), max_discard, host->max_discard_to); 1837e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return max_discard; 1838e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter} 1839e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian HunterEXPORT_SYMBOL(mmc_calc_max_discard); 1840e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 18410f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunterint mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) 18420f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter{ 18431278dba167f01bb3c6626d16450d31129d041087Chris Ball struct mmc_command cmd = {0}; 18440f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 18450f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) 18460f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter return 0; 18470f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 18480f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.opcode = MMC_SET_BLOCKLEN; 18490f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.arg = blocklen; 18500f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 18510f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter return mmc_wait_for_cmd(card->host, &cmd, 5); 18520f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter} 18530f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian HunterEXPORT_SYMBOL(mmc_set_blocklen); 18540f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 1855b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterstatic void mmc_hw_reset_for_init(struct mmc_host *host) 1856b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1857b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) 1858b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return; 1859b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_hold(host); 1860b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ops->hw_reset(host); 1861b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1862b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1863b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1864b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_can_reset(struct mmc_card *card) 1865b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1866b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter u8 rst_n_function; 1867b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1868b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_card_mmc(card)) 1869b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 0; 1870b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter rst_n_function = card->ext_csd.rst_n_function; 1871b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) 1872b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 0; 1873b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 1; 1874b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1875b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_can_reset); 1876b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1877b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterstatic int mmc_do_hw_reset(struct mmc_host *host, int check) 1878b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1879b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter struct mmc_card *card = host->card; 1880b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1881b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!host->bus_ops->power_restore) 1882b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1883b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1884b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) 1885b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1886b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1887b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!card) 1888b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EINVAL; 1889b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1890b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_can_reset(card)) 1891b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1892b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1893b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_hold(host); 1894b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_set_clock(host, host->f_init); 1895b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1896b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ops->hw_reset(host); 1897b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1898b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter /* If the reset has happened, then a status command will fail */ 1899b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (check) { 1900b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter struct mmc_command cmd = {0}; 1901b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter int err; 1902b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1903b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.opcode = MMC_SEND_STATUS; 1904b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_host_is_spi(card->host)) 1905b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.arg = card->rca << 16; 1906b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; 1907b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1908b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!err) { 1909b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1910b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -ENOSYS; 1911b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1912b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1913b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1914b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_DDR); 1915b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (mmc_host_is_spi(host)) { 1916b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.chip_select = MMC_CS_HIGH; 1917b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 1918b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } else { 1919b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.chip_select = MMC_CS_DONTCARE; 1920b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 1921b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1922b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_width = MMC_BUS_WIDTH_1; 1923b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.timing = MMC_TIMING_LEGACY; 1924b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_set_ios(host); 1925b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1926b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1927b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1928b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return host->bus_ops->power_restore(host); 1929b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1930b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1931b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_hw_reset(struct mmc_host *host) 1932b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1933b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return mmc_do_hw_reset(host, 0); 1934b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1935b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_hw_reset); 1936b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1937b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_hw_reset_check(struct mmc_host *host) 1938b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1939b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return mmc_do_hw_reset(host, 1); 1940b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1941b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_hw_reset_check); 1942b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1943807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Rossstatic int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) 1944807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross{ 1945807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross host->f_init = freq; 1946807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1947807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross#ifdef CONFIG_MMC_DEBUG 1948807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross pr_info("%s: %s: trying to init card at %u Hz\n", 1949807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_hostname(host), __func__, host->f_init); 1950807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross#endif 1951807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_power_up(host); 19522f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity 19532f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity /* 1954b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter * Some eMMCs (with VCCQ always on) may not be reset after power up, so 1955b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter * do a hardware reset if possible. 1956b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter */ 1957b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_hw_reset_for_init(host); 1958b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1959e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson /* Initialization should be done at 3.3 V I/O voltage. */ 1960e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); 1961e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson 1962b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter /* 19632f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * sdio_reset sends CMD52 to reset card. Since we do not know 19642f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * if the card is being re-initialized, just send it. CMD52 19652f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * should be ignored by SD/eMMC cards. 19662f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity */ 1967807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross sdio_reset(host); 1968807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_go_idle(host); 1969807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1970807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_send_if_cond(host, host->ocr_avail); 1971807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1972807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross /* Order's important: probe SDIO, then SD, then MMC */ 1973807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_sdio(host)) 1974807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1975807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_sd(host)) 1976807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1977807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_mmc(host)) 1978807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1979807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1980807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_power_off(host); 1981807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return -EIO; 1982807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross} 1983807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1984d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunterint _mmc_detect_card_removed(struct mmc_host *host) 1985d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter{ 1986d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter int ret; 1987d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1988d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive) 1989d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return 0; 1990d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1991d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (!host->card || mmc_card_removed(host->card)) 1992d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return 1; 1993d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1994d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter ret = host->bus_ops->alive(host); 1995d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (ret) { 1996d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mmc_card_set_removed(host->card); 1997d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter pr_debug("%s: card remove detected\n", mmc_hostname(host)); 1998d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter } 1999d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2000d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return ret; 2001d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter} 2002d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2003d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunterint mmc_detect_card_removed(struct mmc_host *host) 2004d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter{ 2005d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter struct mmc_card *card = host->card; 2006f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson int ret; 2007d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2008d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter WARN_ON(!host->claimed); 2009f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson 2010f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!card) 2011f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return 1; 2012f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson 2013f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson ret = mmc_card_removed(card); 2014d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter /* 2015d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter * The card will be considered unchanged unless we have been asked to 2016d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter * detect a change or host requires polling to provide card detection. 2017d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter */ 2018f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && 2019f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) 2020f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return ret; 2021d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2022d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 0; 2023f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!ret) { 2024f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson ret = _mmc_detect_card_removed(host); 2025f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { 2026f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson /* 2027f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson * Schedule a detect work as soon as possible to let a 2028f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson * rescan handle the card removal. 2029f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson */ 2030f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson cancel_delayed_work(&host->detect); 2031f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson mmc_detect_change(host, 0); 2032f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson } 2033f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson } 2034d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2035f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return ret; 2036d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter} 2037d30495048892980e5d453328d1cc9343b3f7e917Adrian HunterEXPORT_SYMBOL(mmc_detect_card_removed); 2038d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2039b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_rescan(struct work_struct *work) 20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2041807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; 2042c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct mmc_host *host = 2043c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct mmc_host, detect.work); 204488ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch int i; 204528c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat bool extend_wakelock = false; 20464c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 2047807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (host->rescan_disable) 20484c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky return; 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20507ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 2051b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman 205230201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen /* 205330201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen * if there is a _removable_ card registered, check whether it is 205430201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen * still present 205530201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen */ 205630201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen if (host->bus_ops && host->bus_ops->detect && !host->bus_dead 2057bad3babace2ee4d1763b4016a662a5c660ab92e9Ohad Ben-Cohen && !(host->caps & MMC_CAP_NONREMOVABLE)) 205894d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer host->bus_ops->detect(host); 205994d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer 2060d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 0; 2061d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2062148c57a844082ece502f79ce7dc18f97aed20e54San Mehat /* If the card was removed the bus will be marked 2063148c57a844082ece502f79ce7dc18f97aed20e54San Mehat * as dead - extend the wakelock so userspace 2064148c57a844082ece502f79ce7dc18f97aed20e54San Mehat * can respond */ 2065148c57a844082ece502f79ce7dc18f97aed20e54San Mehat if (host->bus_dead) 2066148c57a844082ece502f79ce7dc18f97aed20e54San Mehat extend_wakelock = 1; 2067148c57a844082ece502f79ce7dc18f97aed20e54San Mehat 2068c584179828b268152f5ff82dab529a2c095b09acChris Ball /* 2069c584179828b268152f5ff82dab529a2c095b09acChris Ball * Let mmc_bus_put() free the bus/bus_ops if we've found that 2070c584179828b268152f5ff82dab529a2c095b09acChris Ball * the card is no longer present. 2071c584179828b268152f5ff82dab529a2c095b09acChris Ball */ 207294d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_put(host); 207394d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_get(host); 207494d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer 207594d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer /* if there still is a card present, stop here */ 207694d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer if (host->bus_ops != NULL) { 20777ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 207894d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer goto out; 207994d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer } 20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 208194d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer /* 208294d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer * Only we can add a new handler, so it's safe to 208394d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer * release the lock here. 208494d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer */ 208594d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_put(host); 20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 208794d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer if (host->ops->get_cd && host->ops->get_cd(host) == 0) 208894d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer goto out; 20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2090807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_claim_host(host); 209188ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch for (i = 0; i < ARRAY_SIZE(freqs); i++) { 209228c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { 209328c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat extend_wakelock = true; 2094807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross break; 209528c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat } 209606b2233a20bf25c8ee57b7c6e13f528309ac6edcJaehoon Chung if (freqs[i] <= host->f_min) 2097807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross break; 209888ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch } 2099807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_release_host(host); 2100807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 2101807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross out: 210228c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat if (extend_wakelock) 210326d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_lock_timeout(&host->detect_wake_lock, HZ / 2); 210428c97583c32bb755bea693a0c822a5c900f1d8eaSan Mehat else 210526d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_unlock(&host->detect_wake_lock); 210626d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross if (host->caps & MMC_CAP_NEEDS_POLL) { 210726d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_lock(&host->detect_wake_lock); 210828f52482b41edc88cdf575aa6ed414c6e116ce10Anton Vorontsov mmc_schedule_delayed_work(&host->detect, HZ); 210926d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross } 21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2112b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_start_host(struct mmc_host *host) 21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2114b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_power_off(host); 2115b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_detect_change(host, 0); 21161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2118b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_stop_host(struct mmc_host *host) 21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21203b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#ifdef CONFIG_MMC_DEBUG 21211efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman unsigned long flags; 21221efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman spin_lock_irqsave(&host->lock, flags); 21233b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman host->removed = 1; 21241efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman spin_unlock_irqrestore(&host->lock, flags); 21253b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#endif 21263b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman 212726d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross if (cancel_delayed_work_sync(&host->detect)) 212826d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_unlock(&host->detect_wake_lock); 21293b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman mmc_flush_scheduled_work(); 21303b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman 2131da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre /* clear pm flags now and let card drivers set them as needed */ 2132da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre host->pm_flags = 0; 2133da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre 21347ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 21357ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops && !host->bus_dead) { 21360db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski /* Calling bus_ops->remove() with a claimed host can deadlock */ 21377ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops->remove) 21387ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_ops->remove(host); 21397ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 21407ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_claim_host(host); 21417ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_detach_bus(host); 21427f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson mmc_power_off(host); 21437ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_release_host(host); 214453509f0fe28e049e772897aa8fa1f5183b6823a2Denis Karpov mmc_bus_put(host); 214553509f0fe28e049e772897aa8fa1f5183b6823a2Denis Karpov return; 21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21477ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 21487ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 21497ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->card); 21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mmc_power_off(host); 21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 215412ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohenint mmc_power_save_host(struct mmc_host *host) 2155eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter{ 215612ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen int ret = 0; 215712ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 2158bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#ifdef CONFIG_MMC_DEBUG 2159bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake pr_info("%s: %s: powering down\n", mmc_hostname(host), __func__); 2160bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#endif 2161bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake 2162eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_get(host); 2163eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2164eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { 2165eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 216612ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return -EINVAL; 2167eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter } 2168eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2169eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (host->bus_ops->power_save) 217012ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen ret = host->bus_ops->power_save(host); 2171eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2172eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 2173eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2174eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_power_off(host); 217512ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 217612ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return ret; 2177eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter} 2178eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian HunterEXPORT_SYMBOL(mmc_power_save_host); 2179eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 218012ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohenint mmc_power_restore_host(struct mmc_host *host) 2181eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter{ 218212ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen int ret; 218312ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 2184bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#ifdef CONFIG_MMC_DEBUG 2185bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake pr_info("%s: %s: powering up\n", mmc_hostname(host), __func__); 2186bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#endif 2187bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake 2188eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_get(host); 2189eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2190eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { 2191eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 219212ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return -EINVAL; 2193eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter } 2194eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2195eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_power_up(host); 219612ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen ret = host->bus_ops->power_restore(host); 2197eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2198eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 219912ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 220012ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return ret; 2201eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter} 2202eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian HunterEXPORT_SYMBOL(mmc_power_restore_host); 2203eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2204b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_awake(struct mmc_host *host) 2205b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2206b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen int err = -ENOSYS; 2207b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2208aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) 2209aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson return 0; 2210aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson 2211b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_get(host); 2212b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2213b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) 2214b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen err = host->bus_ops->awake(host); 2215b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2216b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_put(host); 2217b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2218b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return err; 2219b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2220b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_awake); 2221b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2222b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_sleep(struct mmc_host *host) 2223b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2224b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen int err = -ENOSYS; 2225b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2226aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) 2227aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson return 0; 2228aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson 2229b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_get(host); 2230b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2231c99872a16fa7642987f30c750dc166674b0d8060Kyungmin Park if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) 2232b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen err = host->bus_ops->sleep(host); 2233b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2234b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_put(host); 2235b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2236b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return err; 2237b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2238b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_sleep); 2239b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2240b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_can_sleep(struct mmc_host *host) 2241b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2242b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen struct mmc_card *card = host->card; 2243b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2244b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3) 2245b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return 1; 2246b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return 0; 2247b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2248b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_can_sleep); 2249b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2250881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon/* 2251881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Flush the cache to the non-volatile storage. 2252881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon */ 2253881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonint mmc_flush_cache(struct mmc_card *card) 2254881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon{ 2255881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon struct mmc_host *host = card->host; 2256881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon int err = 0; 2257881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2258881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (!(host->caps2 & MMC_CAP2_CACHE_CTRL)) 2259881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2260881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2261881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (mmc_card_mmc(card) && 2262881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_size > 0) && 2263881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_ctrl & 1)) { 2264881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 2265881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon EXT_CSD_FLUSH_CACHE, 1, 0); 2266881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (err) 2267881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon pr_err("%s: cache flush error %d\n", 2268881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon mmc_hostname(card->host), err); 2269881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon } 2270881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2271881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2272881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon} 2273881d1c25f765938a95def5afe39486ce39f9fc96Seungwon JeonEXPORT_SYMBOL(mmc_flush_cache); 2274881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2275881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon/* 2276881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Turn the cache ON/OFF. 2277881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Turning the cache OFF shall trigger flushing of the data 2278881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * to the non-volatile storage. 2279881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon */ 2280881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonint mmc_cache_ctrl(struct mmc_host *host, u8 enable) 2281881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon{ 2282881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon struct mmc_card *card = host->card; 22838bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon unsigned int timeout; 2284881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon int err = 0; 2285881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2286881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || 2287881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon mmc_card_is_removable(host)) 2288881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2289881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 22907c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_claim_host(host); 2291881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (card && mmc_card_mmc(card) && 2292881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_size > 0)) { 2293881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon enable = !!enable; 2294881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 22958bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon if (card->ext_csd.cache_ctrl ^ enable) { 22968bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon timeout = enable ? card->ext_csd.generic_cmd6_time : 0; 2297881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 22988bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon EXT_CSD_CACHE_CTRL, enable, timeout); 22998bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon if (err) 23008bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon pr_err("%s: cache %s error %d\n", 23018bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon mmc_hostname(card->host), 23028bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon enable ? "on" : "off", 23038bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon err); 23048bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon else 23058bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon card->ext_csd.cache_ctrl = enable; 23068bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon } 2307881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon } 23087c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_release_host(host); 2309881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2310881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2311881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon} 2312881d1c25f765938a95def5afe39486ce39f9fc96Seungwon JeonEXPORT_SYMBOL(mmc_cache_ctrl); 2313881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 23141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM 23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 23171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_suspend_host - suspend a host 23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host 23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 23201a13f8fa76c880be41d6b1e6a2b44404bcbfdf9eMatt Flemingint mmc_suspend_host(struct mmc_host *host) 23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 232295cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre int err = 0; 232395cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre 232441d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat if (mmc_bus_needs_resume(host)) 232541d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat return 0; 232641d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 232726d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross if (cancel_delayed_work(&host->detect)) 232826d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_unlock(&host->detect_wake_lock); 2329b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman mmc_flush_scheduled_work(); 233017e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon 23317c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson err = mmc_cache_ctrl(host, 0); 2332881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (err) 2333881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon goto out; 2334b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman 23357ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 23367ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops && !host->bus_dead) { 2337b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson 23387c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson if (host->bus_ops->suspend) 23397c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson err = host->bus_ops->suspend(host); 234049df78074963c97e25debc3c67b72f059111607dSujit Reddy Thumma 23417c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson if (err == -ENOSYS || !host->bus_ops->resume) { 23427c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson /* 23437c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson * We simply "remove" the card in this case. 23447c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson * It will be redetected on resume. (Calling 23457c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson * bus_ops->remove() with a claimed host can 23467c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson * deadlock.) 23477c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson */ 23487c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson if (host->bus_ops->remove) 23497c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson host->bus_ops->remove(host); 23507c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_claim_host(host); 23517c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_detach_bus(host); 23527c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_power_off(host); 23537c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson mmc_release_host(host); 23547c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson host->pm_flags = 0; 23557c5709194096beea1ab6e6db46768d70a068efb0Ulf Hansson err = 0; 23561c8cf9c997a4a6b36e907c7ede5f048aeaab1644Ohad Ben-Cohen } 2357b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman } 23587ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 23597ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 2360a5e9425d2010978c5f85986cc70a9fa0c0d5b912Ohad Ben-Cohen if (!err && !mmc_card_keep_power(host)) 236195cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre mmc_power_off(host); 23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2363881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonout: 236495cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre return err; 23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_suspend_host); 23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 23701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_resume_host - resume a previously suspended host 23711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host 23721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 23731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mmc_resume_host(struct mmc_host *host) 23741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 237595cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre int err = 0; 237695cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre 23776abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman mmc_bus_get(host); 23780eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt if (mmc_bus_manual_resume(host)) { 237941d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME; 238041d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat mmc_bus_put(host); 238141d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat return 0; 238241d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat } 238341d9d91eeb7288e34a7631b4446b0f642055daa7San Mehat 23846abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman if (host->bus_ops && !host->bus_dead) { 2385a5e9425d2010978c5f85986cc70a9fa0c0d5b912Ohad Ben-Cohen if (!mmc_card_keep_power(host)) { 2386da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre mmc_power_up(host); 2387da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre mmc_select_voltage(host, host->ocr); 2388e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen /* 2389e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * Tell runtime PM core we just powered up the card, 2390e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * since it still believes the card is powered off. 2391e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * Note that currently runtime PM is only enabled 2392e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * for SDIO cards that are MMC_CAP_POWER_OFF_CARD 2393e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen */ 2394e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen if (mmc_card_sdio(host->card) && 2395e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen (host->caps & MMC_CAP_POWER_OFF_CARD)) { 2396e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_disable(&host->card->dev); 2397e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_set_active(&host->card->dev); 2398e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_enable(&host->card->dev); 2399e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen } 2400da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre } 24016abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman BUG_ON(!host->bus_ops->resume); 240295cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre err = host->bus_ops->resume(host); 240395cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre if (err) { 2404a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_warning("%s: error %d during resume " 240595cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre "(card was removed?)\n", 240695cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre mmc_hostname(host), err); 240795cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre err = 0; 240895cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre } 24096abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman } 2410a8e6df7343cf67c9104955da0de70075a6ee1dfdEliad Peller host->pm_flags &= ~MMC_PM_KEEP_POWER; 24116abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman mmc_bus_put(host); 24126abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman 241395cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre return err; 24141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_resume_host); 24161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24174c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky/* Do the card removal on suspend if card is assumed removeable 24184c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky * Do that in pm notifier while userspace isn't yet frozen, so we will be able 24194c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky to sync the card. 24204c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky*/ 24214c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitskyint mmc_pm_notify(struct notifier_block *notify_block, 24224c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky unsigned long mode, void *unused) 24234c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky{ 24244c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky struct mmc_host *host = container_of( 24254c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky notify_block, struct mmc_host, pm_notify); 24264c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky unsigned long flags; 24274c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24284c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24294c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky switch (mode) { 24304c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_HIBERNATION_PREPARE: 24314c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_SUSPEND_PREPARE: 24324c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24334c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_lock_irqsave(&host->lock, flags); 24340eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt if (mmc_bus_needs_resume(host)) { 24350eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt spin_unlock_irqrestore(&host->lock, flags); 24360eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt break; 24370eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt } 24384c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->rescan_disable = 1; 2439bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT; 24404c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_unlock_irqrestore(&host->lock, flags); 244126d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross if (cancel_delayed_work_sync(&host->detect)) 244226d2321b3fdcca2c1b7b062ad4a726ca961416d5Colin Cross wake_unlock(&host->detect_wake_lock); 24434c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24444c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky if (!host->bus_ops || host->bus_ops->suspend) 24454c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky break; 24464c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24470db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski /* Calling bus_ops->remove() with a claimed host can deadlock */ 24484c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky if (host->bus_ops->remove) 24494c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->bus_ops->remove(host); 24504c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24510db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski mmc_claim_host(host); 24524c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_detach_bus(host); 24537f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson mmc_power_off(host); 24544c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_release_host(host); 24554c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->pm_flags = 0; 24564c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky break; 24574c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24584c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_POST_SUSPEND: 24594c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_POST_HIBERNATION: 2460274476f8fe0b6ac9bac542cc39de12c3dd0f43f6Takashi Iwai case PM_POST_RESTORE: 24614c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24624c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_lock_irqsave(&host->lock, flags); 24630eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt if (mmc_bus_manual_resume(host)) { 24640eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt spin_unlock_irqrestore(&host->lock, flags); 24650eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt break; 24660eb9a8f9d0c6ac5b4c29ba9f1c198b44c8ebb4c1Dmitry Shmidt } 24674c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->rescan_disable = 0; 2468bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG; 24694c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_unlock_irqrestore(&host->lock, flags); 24704c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_detect_change(host, 0); 24714c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24724c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky } 24734c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24744c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky return 0; 24754c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky} 24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2478e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat#ifdef CONFIG_MMC_EMBEDDED_SDIO 2479e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehatvoid mmc_set_embedded_sdio_data(struct mmc_host *host, 2480e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_cis *cis, 2481e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_cccr *cccr, 2482e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_embedded_func *funcs, 2483e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat int num_funcs) 2484e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat{ 2485e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.cis = cis; 2486e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.cccr = cccr; 2487e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.funcs = funcs; 2488e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.num_funcs = num_funcs; 2489e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat} 2490e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat 2491e01587a794fa2ee14d3559a7d919af7e386a03e4San MehatEXPORT_SYMBOL(mmc_set_embedded_sdio_data); 2492e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat#endif 2493e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat 2494ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic int __init mmc_init(void) 2495ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 2496ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman int ret; 2497ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 24980d9ee5b2e9aac981fa063339daf04320eac610d1Tejun Heo workqueue = alloc_ordered_workqueue("kmmcd", 0); 2499ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman if (!workqueue) 2500ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return -ENOMEM; 2501ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 2502ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman ret = mmc_register_bus(); 2503e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2504e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto destroy_workqueue; 2505e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2506e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman ret = mmc_register_host_class(); 2507e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2508e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto unregister_bus; 2509e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2510e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman ret = sdio_register_bus(); 2511e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2512e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto unregister_host_class; 2513e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2514e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return 0; 2515e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2516e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanunregister_host_class: 2517e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman mmc_unregister_host_class(); 2518e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanunregister_bus: 2519e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman mmc_unregister_bus(); 2520e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmandestroy_workqueue: 2521e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman destroy_workqueue(workqueue); 2522e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2523ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return ret; 2524ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 2525ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 2526ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic void __exit mmc_exit(void) 2527ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 2528e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman sdio_unregister_bus(); 2529ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman mmc_unregister_host_class(); 2530ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman mmc_unregister_bus(); 2531ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman destroy_workqueue(workqueue); 2532ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 2533ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 253426074962e8f547b96614dbe248748ba2a1996ca3Nicolas Pitresubsys_initcall(mmc_init); 2535ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanmodule_exit(mmc_exit); 2536ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 25371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2538