core.c revision e01587a794fa2ee14d3559a7d919af7e386a03e4
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> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/card.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mmc/host.h> 32da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/mmc.h> 33da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include <linux/mmc/sd.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 35aaac1b470bd0dccb30912356617069dc6199cc80Pierre Ossman#include "core.h" 36ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman#include "bus.h" 37ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman#include "host.h" 38e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman#include "sdio_bus.h" 39da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman 40da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include "mmc_ops.h" 41da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman#include "sd_ops.h" 425c4e6f1301649d5b29dd0f70e6da83e728ab5ca5Pierre Ossman#include "sdio_ops.h" 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic struct workqueue_struct *workqueue; 45ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 46ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman/* 47af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * Enabling software CRCs on the data blocks can be a significant (30%) 48af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * performance cost, and for other reasons may not always be desired. 49af51715079e7fb6b290e1881d63d815dc4de5011David Brownell * So we allow it it to be disabled. 50af51715079e7fb6b290e1881d63d815dc4de5011David Brownell */ 5190ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool use_spi_crc = 1; 52af51715079e7fb6b290e1881d63d815dc4de5011David Brownellmodule_param(use_spi_crc, bool, 0); 53af51715079e7fb6b290e1881d63d815dc4de5011David Brownell 54af51715079e7fb6b290e1881d63d815dc4de5011David Brownell/* 55bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * We normally treat cards as removed during suspend if they are not 56bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * known to be on a non-removable bus, to avoid the risk of writing 57bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * back data to a different card after resume. Allow this to be 58bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings * overridden if necessary. 59bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings */ 60bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#ifdef CONFIG_MMC_UNSAFE_RESUME 6190ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool mmc_assume_removable; 62bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#else 6390ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool mmc_assume_removable = 1; 64bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings#endif 6571d7d3d190fe77588269a8febf93cd739bd91eb3Matt FlemingEXPORT_SYMBOL(mmc_assume_removable); 66bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchingsmodule_param_named(removable, mmc_assume_removable, bool, 0644); 67bd68e0838fe85794b06892054772fa013a8d1986Ben HutchingsMODULE_PARM_DESC( 68bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings removable, 69bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings "MMC/SD cards are removable and may be removed during suspend"); 70bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings 71bd68e0838fe85794b06892054772fa013a8d1986Ben Hutchings/* 72ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman * Internal function. Schedule delayed work in the MMC work queue. 73ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman */ 74ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic int mmc_schedule_delayed_work(struct delayed_work *work, 75ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman unsigned long delay) 76ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 77ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return queue_delayed_work(workqueue, work, delay); 78ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 79ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 80ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman/* 81ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman * Internal function. Flush all scheduled work from the MMC work queue. 82ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman */ 83ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic void mmc_flush_scheduled_work(void) 84ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 85ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman flush_workqueue(workqueue); 86ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 87ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 881b676f70c108cda90cf9d114d16c677584400efcPer Forlin#ifdef CONFIG_FAIL_MMC_REQUEST 891b676f70c108cda90cf9d114d16c677584400efcPer Forlin 901b676f70c108cda90cf9d114d16c677584400efcPer Forlin/* 911b676f70c108cda90cf9d114d16c677584400efcPer Forlin * Internal function. Inject random data errors. 921b676f70c108cda90cf9d114d16c677584400efcPer Forlin * If mmc_data is NULL no errors are injected. 931b676f70c108cda90cf9d114d16c677584400efcPer Forlin */ 941b676f70c108cda90cf9d114d16c677584400efcPer Forlinstatic void mmc_should_fail_request(struct mmc_host *host, 951b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_request *mrq) 961b676f70c108cda90cf9d114d16c677584400efcPer Forlin{ 971b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_command *cmd = mrq->cmd; 981b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_data *data = mrq->data; 991b676f70c108cda90cf9d114d16c677584400efcPer Forlin static const int data_errors[] = { 1001b676f70c108cda90cf9d114d16c677584400efcPer Forlin -ETIMEDOUT, 1011b676f70c108cda90cf9d114d16c677584400efcPer Forlin -EILSEQ, 1021b676f70c108cda90cf9d114d16c677584400efcPer Forlin -EIO, 1031b676f70c108cda90cf9d114d16c677584400efcPer Forlin }; 1041b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1051b676f70c108cda90cf9d114d16c677584400efcPer Forlin if (!data) 1061b676f70c108cda90cf9d114d16c677584400efcPer Forlin return; 1071b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1081b676f70c108cda90cf9d114d16c677584400efcPer Forlin if (cmd->error || data->error || 1091b676f70c108cda90cf9d114d16c677584400efcPer Forlin !should_fail(&host->fail_mmc_request, data->blksz * data->blocks)) 1101b676f70c108cda90cf9d114d16c677584400efcPer Forlin return; 1111b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1121b676f70c108cda90cf9d114d16c677584400efcPer Forlin data->error = data_errors[random32() % ARRAY_SIZE(data_errors)]; 1131b676f70c108cda90cf9d114d16c677584400efcPer Forlin data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9; 1141b676f70c108cda90cf9d114d16c677584400efcPer Forlin} 1151b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1161b676f70c108cda90cf9d114d16c677584400efcPer Forlin#else /* CONFIG_FAIL_MMC_REQUEST */ 1171b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1181b676f70c108cda90cf9d114d16c677584400efcPer Forlinstatic inline void mmc_should_fail_request(struct mmc_host *host, 1191b676f70c108cda90cf9d114d16c677584400efcPer Forlin struct mmc_request *mrq) 1201b676f70c108cda90cf9d114d16c677584400efcPer Forlin{ 1211b676f70c108cda90cf9d114d16c677584400efcPer Forlin} 1221b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1231b676f70c108cda90cf9d114d16c677584400efcPer Forlin#endif /* CONFIG_FAIL_MMC_REQUEST */ 1241b676f70c108cda90cf9d114d16c677584400efcPer Forlin 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 126fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * mmc_request_done - finish processing an MMC request 127fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * @host: MMC host which completed request 128fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * @mrq: MMC request which request 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MMC drivers should call this function when they have completed 131fe10c6abea8bc83291a13e0580b3e4c355710b09Russell King * their processing of a request. 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mmc_command *cmd = mrq->cmd; 136920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King int err = cmd->error; 137920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 138af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (err && cmd->retries && mmc_host_is_spi(host)) { 139af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) 140af51715079e7fb6b290e1881d63d815dc4de5011David Brownell cmd->retries = 0; 141af51715079e7fb6b290e1881d63d815dc4de5011David Brownell } 142af51715079e7fb6b290e1881d63d815dc4de5011David Brownell 143d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (err && cmd->retries && !mmc_card_removed(host->card)) { 14408a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter /* 14508a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter * Request starter must handle retries - see 14608a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter * mmc_wait_for_req_done(). 14708a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter */ 14808a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter if (mrq->done) 14908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter mrq->done(mrq); 150e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } else { 1511b676f70c108cda90cf9d114d16c677584400efcPer Forlin mmc_should_fail_request(host, mrq); 1521b676f70c108cda90cf9d114d16c677584400efcPer Forlin 153af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman led_trigger_event(host->led, LED_OFF); 154af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman 155e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", 156e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), cmd->opcode, err, 157e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman cmd->resp[0], cmd->resp[1], 158e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman cmd->resp[2], cmd->resp[3]); 159e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 160e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->data) { 161e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: %d bytes transferred: %d\n", 162e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), 163e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->bytes_xfered, mrq->data->error); 164e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 165e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 166e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->stop) { 167e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: (CMD%u): %d: %08x %08x %08x %08x\n", 168e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->stop->opcode, 169e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->error, 170e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->resp[0], mrq->stop->resp[1], 171e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->resp[2], mrq->stop->resp[3]); 172e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 173e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 174e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->done) 175e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->done(mrq); 17604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 17708c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg mmc_host_clk_release(host); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_request_done); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 183393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic void 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmmc_start_request(struct mmc_host *host, struct mmc_request *mrq) 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 186976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#ifdef CONFIG_MMC_DEBUG 187976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman unsigned int i, sz; 188a84756c5735f28bf000617f18734a9e94426386aPierre Ossman struct scatterlist *sg; 189976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#endif 190976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman 1917b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung if (mrq->sbc) { 1927b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", 1937b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung mmc_hostname(host), mrq->sbc->opcode, 1947b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung mrq->sbc->arg, mrq->sbc->flags); 1957b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung } 1967b2fd4f23f72c13a78c0892d330dde305ef2fb80Jaehoon Chung 197920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King pr_debug("%s: starting CMD%u arg %08x flags %08x\n", 198920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_hostname(host), mrq->cmd->opcode, 199920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mrq->cmd->arg, mrq->cmd->flags); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->data) { 202e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: blksz %d blocks %d flags %08x " 203e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman "tsac %d ms nsac %d\n", 204e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->data->blksz, 205e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->blocks, mrq->data->flags, 206ce252edd869ba1fee6a9a6f83e20f349d4c4d669Pierre Ossman mrq->data->timeout_ns / 1000000, 207e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->data->timeout_clks); 208e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 209e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 210e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman if (mrq->stop) { 211e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman pr_debug("%s: CMD%u arg %08x flags %08x\n", 212e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mmc_hostname(host), mrq->stop->opcode, 213e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman mrq->stop->arg, mrq->stop->flags); 214e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman } 215e4d217087458914a6d5d9fd034d7237e6530c619Pierre Ossman 216f22ee4edf63e7480511112d9965c71e07be3f8b7Pierre Ossman WARN_ON(!host->claimed); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->error = 0; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->mrq = mrq; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mrq->data) { 221fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman BUG_ON(mrq->data->blksz > host->max_blk_size); 22255db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman BUG_ON(mrq->data->blocks > host->max_blk_count); 22355db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman BUG_ON(mrq->data->blocks * mrq->data->blksz > 22455db890a838c7b37256241b1fc53d6344aa79cc0Pierre Ossman host->max_req_size); 225fe4a3c7a20f14d86022a8132adbf6ddb98e7197cPierre Ossman 226976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#ifdef CONFIG_MMC_DEBUG 227976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman sz = 0; 228a84756c5735f28bf000617f18734a9e94426386aPierre Ossman for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) 229a84756c5735f28bf000617f18734a9e94426386aPierre Ossman sz += sg->length; 230976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); 231976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman#endif 232976d9276c826d6b35e4a2478fd4978dbd63bdd6fPierre Ossman 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->cmd->data = mrq->data; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->error = 0; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->mrq = mrq; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mrq->stop) { 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->data->stop = mrq->stop; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->stop->error = 0; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq->stop->mrq = mrq; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24208c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg mmc_host_clk_hold(host); 24366c036e0142fed2484d58a2d3c7a4d21ba32b6a6Pierre Tardy led_trigger_event(host->led, LED_FULL); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ops->request(host, mrq); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_wait_done(struct mmc_request *mrq) 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 249aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin complete(&mrq->completion); 250aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 251aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 252956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hanssonstatic int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) 253aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 254aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin init_completion(&mrq->completion); 255aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mrq->done = mmc_wait_done; 256d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (mmc_card_removed(host->card)) { 257d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mrq->cmd->error = -ENOMEDIUM; 258d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter complete(&mrq->completion); 259956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson return -ENOMEDIUM; 260d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter } 261aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_start_request(host, mrq); 262956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson return 0; 263aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 264aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 265aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_wait_for_req_done(struct mmc_host *host, 266aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_request *mrq) 267aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 26808a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter struct mmc_command *cmd; 26908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27008a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter while (1) { 27108a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter wait_for_completion(&mrq->completion); 27208a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27308a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd = mrq->cmd; 274d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (!cmd->error || !cmd->retries || 275d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mmc_card_removed(host->card)) 27608a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter break; 27708a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter 27808a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter pr_debug("%s: req failed (CMD%u): %d, retrying...\n", 27908a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter mmc_hostname(host), cmd->opcode, cmd->error); 28008a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd->retries--; 28108a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter cmd->error = 0; 28208a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter host->ops->request(host, mrq); 28308a7e1dfaa63bf5132b5b7231fcf9a33473c78f5Adrian Hunter } 284aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 285aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 286aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 287aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_pre_req - Prepare for a new request 288aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to prepare command 289aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @mrq: MMC request to prepare for 290aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @is_first_req: true if there is no previous started request 291aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * that may run in parellel to this call, otherwise false 292aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 293aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_pre_req() is called in prior to mmc_start_req() to let 294aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * host prepare for the new request. Preparation of a request may be 295aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * performed while another request is running on the host. 296aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 297aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, 298aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin bool is_first_req) 299aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 3002c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->pre_req) { 3012c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 302aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin host->ops->pre_req(host, mrq, is_first_req); 3032c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 3042c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 305aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 306aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 307aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 308aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_post_req - Post process a completed request 309aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to post process command 310aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @mrq: MMC request to post process for 311aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @err: Error, if non zero, clean up any resources made in pre_req 312aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 313aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Let the host post process a completed request. Post processing of 314aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * a request may be performed while another reuqest is running. 315aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 316aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstatic void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, 317aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin int err) 318aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 3192c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->post_req) { 3202c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 321aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin host->ops->post_req(host, mrq, err); 3222c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 3232c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman/** 327aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * mmc_start_req - start a non-blocking request 328aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @host: MMC host to start command 329aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @areq: async request to start 330aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * @error: out parameter returns 0 for success, otherwise non zero 331aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 332aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Start a new MMC custom command request for a host. 333aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * If there is on ongoing async request wait for completion 334aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * of that request and start the new one and return. 335aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Does not wait for the new request to complete. 336aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * 337aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Returns the completed request, NULL in case of none completed. 338aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * Wait for the an ongoing request (previoulsy started) to complete and 339aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * return the completed request. If there is no ongoing request, NULL 340aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin * is returned without waiting. NULL is not an error condition. 341aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin */ 342aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlinstruct mmc_async_req *mmc_start_req(struct mmc_host *host, 343aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_async_req *areq, int *error) 344aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin{ 345aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin int err = 0; 346956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson int start_err = 0; 347aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin struct mmc_async_req *data = host->areq; 348aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 349aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin /* Prepare a new request */ 350aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (areq) 351aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_pre_req(host, areq->mrq, !host->areq); 352aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 353aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (host->areq) { 354aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_wait_for_req_done(host, host->areq->mrq); 355aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin err = host->areq->err_check(host->card, host->areq); 356aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin } 357aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 358956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if (!err && areq) 359956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson start_err = __mmc_start_req(host, areq->mrq); 360aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 361aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (host->areq) 362aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_post_req(host, host->areq->mrq, 0); 363aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 364956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson /* Cancel a prepared request if it was not started. */ 365956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if ((err || start_err) && areq) 366956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson mmc_post_req(host, areq->mrq, -EINVAL); 367956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson 368956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson if (err) 369956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson host->areq = NULL; 370956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson else 371956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson host->areq = areq; 372956d9fd5eb3cbb322440844ed341145707bd71f8Ulf Hansson 373aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin if (error) 374aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin *error = err; 375aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin return data; 376aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin} 377aa8b683a7d392271ed349c6ab9f36b8c313794b7Per ForlinEXPORT_SYMBOL(mmc_start_req); 378aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin 379aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin/** 38067a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * mmc_wait_for_req - start a request and wait for completion 38167a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * @host: MMC host to start command 38267a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * @mrq: MMC request to start 38367a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * 38467a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * Start a new MMC custom command request for a host, and wait 38567a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * for the command to complete. Does not attempt to parse the 38667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * response. 38767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman */ 38867a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossmanvoid mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 390aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin __mmc_start_req(host, mrq); 391aa8b683a7d392271ed349c6ab9f36b8c313794b7Per Forlin mmc_wait_for_req_done(host, mrq); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_wait_for_req); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 396eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * mmc_interrupt_hpi - Issue for High priority Interrupt 397eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * @card: the MMC card associated with the HPI transfer 398eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * 399eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * Issued High Priority Interrupt, and check for card status 400eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * util out-of prg-state. 401eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 402eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chungint mmc_interrupt_hpi(struct mmc_card *card) 403eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung{ 404eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung int err; 405eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung u32 status; 406eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 407eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung BUG_ON(!card); 408eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 409eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (!card->ext_csd.hpi_en) { 410eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host)); 411eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung return 1; 412eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } 413eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 414eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_claim_host(card->host); 415eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_status(card, &status); 416eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) { 417eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_err("%s: Get card status fail\n", mmc_hostname(card->host)); 418eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung goto out; 419eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } 420eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 421eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung /* 422eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * If the card status is in PRG-state, we can send the HPI command. 423eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 424eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (R1_CURRENT_STATE(status) == R1_STATE_PRG) { 425eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung do { 426eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung /* 427eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * We don't know when the HPI command will finish 428eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * processing, so we need to resend HPI until out 429eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * of prg-state, and keep checking the card status 430eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * with SEND_STATUS. If a timeout error occurs when 431eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * sending the HPI command, we are already out of 432eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung * prg-state. 433eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung */ 434eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_hpi_cmd(card, &status); 435eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) 436eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_debug("%s: abort HPI (%d error)\n", 437eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_hostname(card->host), err); 438eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 439eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung err = mmc_send_status(card, &status); 440eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung if (err) 441eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung break; 442eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); 443eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung } else 444eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung pr_debug("%s: Left prg-state\n", mmc_hostname(card->host)); 445eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 446eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chungout: 447eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung mmc_release_host(card->host); 448eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung return err; 449eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung} 450eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon ChungEXPORT_SYMBOL(mmc_interrupt_hpi); 451eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung 452eb0d8f135b6730d6d0324a064664d121334290e7Jaehoon Chung/** 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_wait_for_cmd - start a command and wait for completion 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: MMC host to start command 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @cmd: MMC command to start 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @retries: maximum number of retries 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Start a new MMC command for a host, and wait for the command 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to complete. Return any error that occurred while the command 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * was executing. Do not attempt to parse the response. 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 464ad5fd97288655b5628052c1fa906419417c86100Venkatraman S struct mmc_request mrq = {NULL}; 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 466d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(cmd->resp, 0, sizeof(cmd->resp)); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->retries = retries; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mrq.cmd = cmd; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->data = NULL; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mmc_wait_for_req(host, &mrq); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cmd->error; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_wait_for_cmd); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481335eadf2ef6a1122a720aea98e758e5d431da87dPierre Ossman/** 482d773d7255199a6c8934e197756f54a1115dd127bRussell King * mmc_set_data_timeout - set the timeout for a data command 483d773d7255199a6c8934e197756f54a1115dd127bRussell King * @data: data phase for command 484d773d7255199a6c8934e197756f54a1115dd127bRussell King * @card: the MMC card associated with the data transfer 48567a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * 48667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * Computes the data timeout parameters according to the 48767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * correct algorithm given the card type. 488d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 489b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossmanvoid mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) 490d773d7255199a6c8934e197756f54a1115dd127bRussell King{ 491d773d7255199a6c8934e197756f54a1115dd127bRussell King unsigned int mult; 492d773d7255199a6c8934e197756f54a1115dd127bRussell King 493d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 494e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman * SDIO cards only define an upper 1 s limit on access. 495e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman */ 496e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman if (mmc_card_sdio(card)) { 497e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman data->timeout_ns = 1000000000; 498e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman data->timeout_clks = 0; 499e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman return; 500e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman } 501e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman 502e6f918bf39773d712ab5b457bff54ade3bda0cb1Pierre Ossman /* 503d773d7255199a6c8934e197756f54a1115dd127bRussell King * SD cards use a 100 multiplier rather than 10 504d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 505d773d7255199a6c8934e197756f54a1115dd127bRussell King mult = mmc_card_sd(card) ? 100 : 10; 506d773d7255199a6c8934e197756f54a1115dd127bRussell King 507d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 508d773d7255199a6c8934e197756f54a1115dd127bRussell King * Scale up the multiplier (and therefore the timeout) by 509d773d7255199a6c8934e197756f54a1115dd127bRussell King * the r2w factor for writes. 510d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 511b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman if (data->flags & MMC_DATA_WRITE) 512d773d7255199a6c8934e197756f54a1115dd127bRussell King mult <<= card->csd.r2w_factor; 513d773d7255199a6c8934e197756f54a1115dd127bRussell King 514d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_ns = card->csd.tacc_ns * mult; 515d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_clks = card->csd.tacc_clks * mult; 516d773d7255199a6c8934e197756f54a1115dd127bRussell King 517d773d7255199a6c8934e197756f54a1115dd127bRussell King /* 518d773d7255199a6c8934e197756f54a1115dd127bRussell King * SD cards also have an upper limit on the timeout. 519d773d7255199a6c8934e197756f54a1115dd127bRussell King */ 520d773d7255199a6c8934e197756f54a1115dd127bRussell King if (mmc_card_sd(card)) { 521d773d7255199a6c8934e197756f54a1115dd127bRussell King unsigned int timeout_us, limit_us; 522d773d7255199a6c8934e197756f54a1115dd127bRussell King 523d773d7255199a6c8934e197756f54a1115dd127bRussell King timeout_us = data->timeout_ns / 1000; 524e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij if (mmc_host_clk_rate(card->host)) 525e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij timeout_us += data->timeout_clks * 1000 / 526e9b86841b372de01ae865080118e29159d8b7c39Linus Walleij (mmc_host_clk_rate(card->host) / 1000); 527d773d7255199a6c8934e197756f54a1115dd127bRussell King 528b146d26a61e0feab2f12a98ae83fd352830899c0Pierre Ossman if (data->flags & MMC_DATA_WRITE) 529493890e75d98810a3470b4aae23be628ee5e9667Pierre Ossman /* 5303bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * The MMC spec "It is strongly recommended 5313bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * for hosts to implement more than 500ms 5323bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * timeout value even if the card indicates 5333bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * the 250ms maximum busy length." Even the 5343bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * previous value of 300ms is known to be 5353bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley * insufficient for some cards. 536493890e75d98810a3470b4aae23be628ee5e9667Pierre Ossman */ 5373bdc9ba892d6a294d16e9e6e0c4041926aa3d58cPaul Walmsley limit_us = 3000000; 538d773d7255199a6c8934e197756f54a1115dd127bRussell King else 539d773d7255199a6c8934e197756f54a1115dd127bRussell King limit_us = 100000; 540d773d7255199a6c8934e197756f54a1115dd127bRussell King 541fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale /* 542fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale * SDHC cards always use these fixed values. 543fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale */ 544fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale if (timeout_us > limit_us || mmc_card_blockaddr(card)) { 545d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_ns = limit_us * 1000; 546d773d7255199a6c8934e197756f54a1115dd127bRussell King data->timeout_clks = 0; 547d773d7255199a6c8934e197756f54a1115dd127bRussell King } 548d773d7255199a6c8934e197756f54a1115dd127bRussell King } 5496de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK 5506de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK /* 5516de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * Some cards require longer data read timeout than indicated in CSD. 5526de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * Address this by setting the read timeout to a "reasonably high" 5536de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * value. For the cards tested, 300ms has proven enough. If necessary, 5546de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK * this value can be increased if other problematic cards require this. 5556de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK */ 5566de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { 5576de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK data->timeout_ns = 300000000; 5586de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK data->timeout_clks = 0; 5596de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK } 5606de5fc9cf7de334912de4cfd2d06eb2d744d2afeStefan Nilsson XK 561c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees /* 562c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * Some cards need very high timeouts if driven in SPI mode. 563c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * The worst observed timeout was 900ms after writing a 564c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * continuous stream of data until the internal logic 565c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees * overflowed. 566c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees */ 567c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (mmc_host_is_spi(card->host)) { 568c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->flags & MMC_DATA_WRITE) { 569c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->timeout_ns < 1000000000) 570c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees data->timeout_ns = 1000000000; /* 1s */ 571c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } else { 572c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees if (data->timeout_ns < 100000000) 573c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees data->timeout_ns = 100000000; /* 100ms */ 574c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } 575c0c88871574ccb4ee53dde1bbb678931b38ed47bWolfgang Muees } 576d773d7255199a6c8934e197756f54a1115dd127bRussell King} 577d773d7255199a6c8934e197756f54a1115dd127bRussell KingEXPORT_SYMBOL(mmc_set_data_timeout); 578d773d7255199a6c8934e197756f54a1115dd127bRussell King 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 580ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * mmc_align_data_size - pads a transfer size to a more optimal value 581ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * @card: the MMC card associated with the data transfer 582ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * @sz: original transfer size 583ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 584ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Pads the original data size with a number of extra bytes in 585ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * order to avoid controller bugs and/or performance hits 586ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * (e.g. some controllers revert to PIO for certain sizes). 587ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 588ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Returns the improved size, which might be unmodified. 589ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * 590ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * Note that this function is only relevant when issuing a 591ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * single scatter gather entry. 592ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman */ 593ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossmanunsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) 594ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman{ 595ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman /* 596ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * FIXME: We don't have a system for the controller to tell 597ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * the core about its problems yet, so for now we just 32-bit 598ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman * align the size. 599ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman */ 600ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman sz = ((sz + 3) / 4) * 4; 601ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman 602ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman return sz; 603ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman} 604ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre OssmanEXPORT_SYMBOL(mmc_align_data_size); 605ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman 606ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15Pierre Ossman/** 6072342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * __mmc_claim_host - exclusively claim a host 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host to claim 6092342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * @abort: whether or not the operation should be aborted 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6112342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * Claim a host for a set of operations. If @abort is non null and 6122342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * dereference a non-zero value then this will return prematurely with 6132342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * that non-zero value without acquiring the lock. Returns zero 6142342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre * with the lock held otherwise. 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6162342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitreint __mmc_claim_host(struct mmc_host *host, atomic_t *abort) 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DECLARE_WAITQUEUE(wait, current); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 6202342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre int stop; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 622cf795bfb3ad4e2f8f6bb346aa8edb8272d4c70a2Pierre Ossman might_sleep(); 623cf795bfb3ad4e2f8f6bb346aa8edb8272d4c70a2Pierre Ossman 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_wait_queue(&host->wq, &wait); 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&host->lock, flags); 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 6282342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre stop = abort ? atomic_read(abort) : 0; 629319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (stop || !host->claimed || host->claimer == current) 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&host->lock, flags); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule(); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&host->lock, flags); 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_RUNNING); 636319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (!stop) { 6372342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre host->claimed = 1; 638319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = current; 639319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claim_cnt += 1; 640319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } else 6412342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre wake_up(&host->wq); 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&host->lock, flags); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_wait_queue(&host->wq, &wait); 644907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->enable && !stop && host->claim_cnt == 1) 645907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->enable(host); 6462342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas Pitre return stop; 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6492342f3323c9a76367a1d7f9a35525ee3cb3911dfNicolas PitreEXPORT_SYMBOL(__mmc_claim_host); 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter/** 652319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * mmc_try_claim_host - try exclusively to claim a host 653319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * @host: mmc host to claim 654319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * 655319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter * Returns %1 if the host is claimed, %0 otherwise. 656319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter */ 657319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunterint mmc_try_claim_host(struct mmc_host *host) 6588ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter{ 6598ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter int claimed_host = 0; 6608ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter unsigned long flags; 6618ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 6628ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_lock_irqsave(&host->lock, flags); 663319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (!host->claimed || host->claimer == current) { 6648ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter host->claimed = 1; 665319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = current; 666319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claim_cnt += 1; 6678ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter claimed_host = 1; 6688ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter } 6698ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 670907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->enable && claimed_host && host->claim_cnt == 1) 671907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->enable(host); 6728ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter return claimed_host; 6738ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter} 674319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian HunterEXPORT_SYMBOL(mmc_try_claim_host); 6758ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 676ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson/** 677907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * mmc_release_host - release a host 678ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson * @host: mmc host to release 679ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson * 680907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * Release a MMC host, allowing others to claim the host 681907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter * for their operations. 682ab1efd271704416c9e6e9cb4e5f58e7e4c4260e6Ulf Hansson */ 683907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Huntervoid mmc_release_host(struct mmc_host *host) 6848ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter{ 6858ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter unsigned long flags; 6868ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter 687907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter WARN_ON(!host->claimed); 688907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter 689907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter if (host->ops->disable && host->claim_cnt == 1) 690907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter host->ops->disable(host); 691907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter 6928ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter spin_lock_irqsave(&host->lock, flags); 693319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter if (--host->claim_cnt) { 694319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter /* Release for nested claim */ 695319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter spin_unlock_irqrestore(&host->lock, flags); 696319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } else { 697319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimed = 0; 698319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter host->claimer = NULL; 699319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter spin_unlock_irqrestore(&host->lock, flags); 700319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter wake_up(&host->wq); 701319a3f1429c91147058ac26c5f5bac8ec1730bc6Adrian Hunter } 7028ea926b22e2d13238e4d65d8f61c48fe424e6f4fAdrian Hunter} 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_release_host); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7057ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 7067ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Internal function that does the actual ios call to the host driver, 7077ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * optionally printing some debug output. 7087ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 709920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell Kingstatic inline void mmc_set_ios(struct mmc_host *host) 710920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King{ 711920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King struct mmc_ios *ios = &host->ios; 712920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 713cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " 714cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman "width %u timing %u\n", 715920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_hostname(host), ios->clock, ios->bus_mode, 716920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King ios->power_mode, ios->chip_select, ios->vdd, 717cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman ios->bus_width, ios->timing); 718fba68bd2dab1ac99af3c5a963ec9581cfa9f1725Philip Langdale 71904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (ios->clock > 0) 72004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_set_ungated(host); 721920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King host->ops->set_ios(host, ios); 722920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King} 723920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King 7247ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 7257ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Control chip select pin on a host. 7267ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 727da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossmanvoid mmc_set_chip_select(struct mmc_host *host, int mode) 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 729778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 730da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman host->ios.chip_select = mode; 731da7fbe58d2d347e95af699ddf04d885be6362bbePierre Ossman mmc_set_ios(host); 732778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7367ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Sets the host clock to the highest possible frequency that 7377ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * is below "hz". 7387ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 739778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerbergstatic void __mmc_set_clock(struct mmc_host *host, unsigned int hz) 7407ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman{ 7417ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman WARN_ON(hz < host->f_min); 7427ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 7437ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (hz > host->f_max) 7447ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman hz = host->f_max; 7457ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 7467ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.clock = hz; 7477ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 7487ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman} 7497ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 750778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerbergvoid mmc_set_clock(struct mmc_host *host, unsigned int hz) 751778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg{ 752778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 753778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg __mmc_set_clock(host, hz); 754778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 755778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg} 756778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 75704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#ifdef CONFIG_MMC_CLKGATE 75804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 75904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * This gates the clock by setting it to 0 Hz. 76004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 76104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_gate_clock(struct mmc_host *host) 76204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 76304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 76404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 76504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 76604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_old = host->ios.clock; 76704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->ios.clock = 0; 76804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_gated = true; 76904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 77004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_set_ios(host); 77104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 77204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 77304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 77404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * This restores the clock from gating by using the cached 77504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * clock value. 77604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 77704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_ungate_clock(struct mmc_host *host) 77804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 77904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 78004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * We should previously have gated the clock, so the clock shall 78104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * be 0 here! The clock may however be 0 during initialization, 78204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * when some request operations are performed before setting 78304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * the frequency. When ungate is requested in that situation 78404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * we just ignore the call. 78504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 78604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (host->clk_old) { 78704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij BUG_ON(host->ios.clock); 78804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* This call will also set host->clk_gated to false */ 789778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg __mmc_set_clock(host, host->clk_old); 79004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 79104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 79204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 79304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_set_ungated(struct mmc_host *host) 79404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 79504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 79604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 79704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 79804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * We've been given a new frequency while the clock is gated, 79904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * so make sure we regard this as ungating it. 80004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 80104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 80204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_gated = false; 80304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 80404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 80504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 80604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#else 80704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijvoid mmc_set_ungated(struct mmc_host *host) 80804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 80904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 81004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#endif 81104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 8127ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 8137ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Change the bus mode (open drain/push-pull) of a host. 8147ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 8157ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) 8167ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman{ 817778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 8187ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.bus_mode = mode; 8197ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 820778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 8217ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman} 8227ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 8237ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 8240f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter * Change data bus width of a host. 8250f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter */ 8260f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Huntervoid mmc_set_bus_width(struct mmc_host *host, unsigned int width) 8270f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter{ 828778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 8294c4cb171054230c2e58ed6574d7faa1871c75bbePhilip Rakity host->ios.bus_width = width; 8304c4cb171054230c2e58ed6574d7faa1871c75bbePhilip Rakity mmc_set_ios(host); 831778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 8320f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter} 8330f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 83486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov/** 83586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number 83686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd: voltage (mV) 83786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @low_bits: prefer low bits in boundary cases 83886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 83986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function returns the OCR bit number according to the provided @vdd 84086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * value. If conversion is not possible a negative errno value returned. 84186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 84286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Depending on the @low_bits flag the function prefers low or high OCR bits 84386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * on boundary voltages. For example, 84486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); 84586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); 84686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 84786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). 84886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov */ 84986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsovstatic int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) 85086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov{ 85186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov const int max_bit = ilog2(MMC_VDD_35_36); 85286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov int bit; 85386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 85486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd < 1650 || vdd > 3600) 85586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return -EINVAL; 85686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 85786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd >= 1650 && vdd <= 1950) 85886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return ilog2(MMC_VDD_165_195); 85986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 86086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (low_bits) 86186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd -= 1; 86286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 86386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Base 2000 mV, step 100 mV, bit's base 8. */ 86486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov bit = (vdd - 2000) / 100 + 8; 86586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (bit > max_bit) 86686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return max_bit; 86786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return bit; 86886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov} 86986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 87086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov/** 87186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask 87286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd_min: minimum voltage value (mV) 87386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * @vdd_max: maximum voltage value (mV) 87486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 87586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function returns the OCR mask bits according to the provided @vdd_min 87686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * and @vdd_max values. If conversion is not possible the function returns 0. 87786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * 87886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * Notes wrt boundary cases: 87986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * This function sets the OCR bits for all boundary voltages, for example 88086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | 88186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov * MMC_VDD_34_35 mask. 88286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov */ 88386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsovu32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) 88486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov{ 88586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov u32 mask = 0; 88686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 88786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_max < vdd_min) 88886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 88986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 89086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Prefer high bits for the boundary vdd_max values. */ 89186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); 89286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_max < 0) 89386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 89486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 89586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Prefer low bits for the boundary vdd_min values. */ 89686e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); 89786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov if (vdd_min < 0) 89886e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return 0; 89986e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 90086e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov /* Fill the mask, from max bit to min bit. */ 90186e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov while (vdd_max >= vdd_min) 90286e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov mask |= 1 << vdd_max--; 90386e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 90486e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov return mask; 90586e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov} 90686e8286a0e48663e1e86a5884b30a6d05de2993aAnton VorontsovEXPORT_SYMBOL(mmc_vddrange_to_ocrmask); 90786e8286a0e48663e1e86a5884b30a6d05de2993aAnton Vorontsov 9085c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell#ifdef CONFIG_REGULATOR 9095c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9105c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell/** 9115c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * mmc_regulator_get_ocrmask - return mask of supported voltages 9125c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * @supply: regulator to use 9135c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9145c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * This returns either a negative errno, or a mask of voltages that 9155c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * can be provided to MMC/SD/SDIO devices using the specified voltage 9165c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * regulator. This would normally be called before registering the 9175c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * MMC host adapter. 9185c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9195c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownellint mmc_regulator_get_ocrmask(struct regulator *supply) 9205c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell{ 9215c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int result = 0; 9225c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int count; 9235c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int i; 9245c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9255c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell count = regulator_count_voltages(supply); 9265c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (count < 0) 9275c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return count; 9285c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9295c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell for (i = 0; i < count; i++) { 9305c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int vdd_uV; 9315c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int vdd_mV; 9325c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9335c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell vdd_uV = regulator_list_voltage(supply, i); 9345c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (vdd_uV <= 0) 9355c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell continue; 9365c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9375c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell vdd_mV = vdd_uV / 1000; 9385c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); 9395c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 9405c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9415c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return result; 9425c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell} 9435c13941acc513669c7d07b28789c3f9ba66ddddfDavid BrownellEXPORT_SYMBOL(mmc_regulator_get_ocrmask); 9445c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9455c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell/** 9465c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * mmc_regulator_set_ocr - set regulator to match host->ios voltage 94799fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij * @mmc: the host to regulate 9485c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * @supply: regulator to use 94999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) 9505c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9515c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * Returns zero on success, else negative errno. 9525c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * 9535c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * MMC host drivers may use this to enable or disable a regulator using 9545c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * a particular supply voltage. This would normally be called from the 9555c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * set_ios() method. 9565c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 95799fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleijint mmc_regulator_set_ocr(struct mmc_host *mmc, 95899fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij struct regulator *supply, 95999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij unsigned short vdd_bit) 9605c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell{ 9615c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int result = 0; 9625c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int min_uV, max_uV; 9635c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9645c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (vdd_bit) { 9655c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int tmp; 9665c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell int voltage; 9675c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9685c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell /* REVISIT mmc_vddrange_to_ocrmask() may have set some 9695c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * bits this regulator doesn't quite support ... don't 9705c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * be too picky, most cards and regulators are OK with 9715c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * a 0.1V range goof (it's a small error percentage). 9725c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9735c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell tmp = vdd_bit - ilog2(MMC_VDD_165_195); 9745c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (tmp == 0) { 9755c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell min_uV = 1650 * 1000; 9765c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell max_uV = 1950 * 1000; 9775c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } else { 9785c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell min_uV = 1900 * 1000 + tmp * 100 * 1000; 9795c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell max_uV = min_uV + 100 * 1000; 9805c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 9815c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 9825c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell /* avoid needless changes to this voltage; the regulator 9835c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell * might not allow this operation 9845c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell */ 9855c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell voltage = regulator_get_voltage(supply); 9866e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung 9876e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE) 9886e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung min_uV = max_uV = voltage; 9896e8201f57c9359c9c5dc8f9805c15a4392492a10Jaehoon Chung 9905c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell if (voltage < 0) 9915c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = voltage; 9925c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell else if (voltage < min_uV || voltage > max_uV) 9935c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_set_voltage(supply, min_uV, max_uV); 9945c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell else 9955c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = 0; 9965c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 99799fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result == 0 && !mmc->regulator_enabled) { 9985c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_enable(supply); 99999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (!result) 100099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij mmc->regulator_enabled = true; 100199fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij } 100299fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij } else if (mmc->regulator_enabled) { 10035c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell result = regulator_disable(supply); 100499fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result == 0) 100599fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij mmc->regulator_enabled = false; 10065c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell } 10075c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 100899fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij if (result) 100999fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij dev_err(mmc_dev(mmc), 101099fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij "could not set regulator OCR (%d)\n", result); 10115c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell return result; 10125c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell} 10135c13941acc513669c7d07b28789c3f9ba66ddddfDavid BrownellEXPORT_SYMBOL(mmc_regulator_set_ocr); 10145c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 101599fc5131018cbdc3cf42ce09fb394a4e8b053c74Linus Walleij#endif /* CONFIG_REGULATOR */ 10165c13941acc513669c7d07b28789c3f9ba66ddddfDavid Brownell 10177ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Mask off any voltages we don't support and select 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the lowest voltage 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10217ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanu32 mmc_select_voltage(struct mmc_host *host, u32 ocr) 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int bit; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ocr &= host->ocr_avail; 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit = ffs(ocr); 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bit) { 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bit -= 1; 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 103163ef731aa6a81e286de78dcc92241d123424ed39Timo Teras ocr &= 3 << bit; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1033778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = bit; 1035920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 1036778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1038f6e10b865c3ea56bdaa8c6ecfee313b997900dbbDavid Brownell pr_warning("%s: host doesn't support card's voltages\n", 1039f6e10b865c3ea56bdaa8c6ecfee313b997900dbbDavid Brownell mmc_hostname(host)); 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ocr = 0; 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ocr; 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1046261bbd463a091b939770255d559bbc89b1bad568Philip Rakityint mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11) 1047f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath{ 1048f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath struct mmc_command cmd = {0}; 1049f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath int err = 0; 1050f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1051f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath BUG_ON(!host); 1052f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1053f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath /* 1054f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath * Send CMD11 only if the request is to switch the card to 1055f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath * 1.8V signalling. 1056f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath */ 1057261bbd463a091b939770255d559bbc89b1bad568Philip Rakity if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) { 1058f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.opcode = SD_SWITCH_VOLTAGE; 1059f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.arg = 0; 1060f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1061f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1062f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath err = mmc_wait_for_cmd(host, &cmd, 0); 1063f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath if (err) 1064f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return err; 1065f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1066f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) 1067f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return -EIO; 1068f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath } 1069f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1070f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath host->ios.signal_voltage = signal_voltage; 1071f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 10722c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma if (host->ops->start_signal_voltage_switch) { 10732c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_hold(host); 1074f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath err = host->ops->start_signal_voltage_switch(host, &host->ios); 10752c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma mmc_host_clk_release(host); 10762c4967f741e87cdd63de7271b97807041dccbf3bSujit Reddy Thumma } 1077f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 1078f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath return err; 1079f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath} 1080f2119df6b764609af4baceb68caf1e848c1c8aa7Arindam Nath 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10827ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Select timing parameters for host. 1083b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman */ 10847ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_set_timing(struct mmc_host *host, unsigned int timing) 1085b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman{ 1086778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 10877ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->ios.timing = timing; 10887ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_set_ios(host); 1089778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 1090b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman} 1091b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 1092b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman/* 1093d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath * Select appropriate driver type for host. 1094d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath */ 1095d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nathvoid mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) 1096d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath{ 1097778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1098d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath host->ios.drv_type = drv_type; 1099d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath mmc_set_ios(host); 1100778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 1101d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath} 1102d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath 1103a80f16276388a177199204aa5b60f328d4464110Girish K Sstatic void mmc_poweroff_notify(struct mmc_host *host) 1104a80f16276388a177199204aa5b60f328d4464110Girish K S{ 1105a80f16276388a177199204aa5b60f328d4464110Girish K S struct mmc_card *card; 1106a80f16276388a177199204aa5b60f328d4464110Girish K S unsigned int timeout; 1107a80f16276388a177199204aa5b60f328d4464110Girish K S unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION; 1108a80f16276388a177199204aa5b60f328d4464110Girish K S int err = 0; 1109a80f16276388a177199204aa5b60f328d4464110Girish K S 1110a80f16276388a177199204aa5b60f328d4464110Girish K S card = host->card; 11113e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_claim_host(host); 1112a80f16276388a177199204aa5b60f328d4464110Girish K S 1113a80f16276388a177199204aa5b60f328d4464110Girish K S /* 1114a80f16276388a177199204aa5b60f328d4464110Girish K S * Send power notify command only if card 1115a80f16276388a177199204aa5b60f328d4464110Girish K S * is mmc and notify state is powered ON 1116a80f16276388a177199204aa5b60f328d4464110Girish K S */ 1117a80f16276388a177199204aa5b60f328d4464110Girish K S if (card && mmc_card_mmc(card) && 1118a80f16276388a177199204aa5b60f328d4464110Girish K S (card->poweroff_notify_state == MMC_POWERED_ON)) { 1119a80f16276388a177199204aa5b60f328d4464110Girish K S 1120a80f16276388a177199204aa5b60f328d4464110Girish K S if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { 1121a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type = EXT_CSD_POWER_OFF_SHORT; 1122a80f16276388a177199204aa5b60f328d4464110Girish K S timeout = card->ext_csd.generic_cmd6_time; 1123a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_POWEROFF_SHORT; 1124a80f16276388a177199204aa5b60f328d4464110Girish K S } else { 1125a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type = EXT_CSD_POWER_OFF_LONG; 1126a80f16276388a177199204aa5b60f328d4464110Girish K S timeout = card->ext_csd.power_off_longtime; 1127a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_POWEROFF_LONG; 1128a80f16276388a177199204aa5b60f328d4464110Girish K S } 1129a80f16276388a177199204aa5b60f328d4464110Girish K S 1130a80f16276388a177199204aa5b60f328d4464110Girish K S err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1131a80f16276388a177199204aa5b60f328d4464110Girish K S EXT_CSD_POWER_OFF_NOTIFICATION, 1132a80f16276388a177199204aa5b60f328d4464110Girish K S notify_type, timeout); 1133a80f16276388a177199204aa5b60f328d4464110Girish K S 1134a80f16276388a177199204aa5b60f328d4464110Girish K S if (err && err != -EBADMSG) 1135a80f16276388a177199204aa5b60f328d4464110Girish K S pr_err("Device failed to respond within %d poweroff " 1136a80f16276388a177199204aa5b60f328d4464110Girish K S "time. Forcefully powering down the device\n", 1137a80f16276388a177199204aa5b60f328d4464110Girish K S timeout); 1138a80f16276388a177199204aa5b60f328d4464110Girish K S 1139a80f16276388a177199204aa5b60f328d4464110Girish K S /* Set the card state to no notification after the poweroff */ 1140a80f16276388a177199204aa5b60f328d4464110Girish K S card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; 1141a80f16276388a177199204aa5b60f328d4464110Girish K S } 11423e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_release_host(host); 1143a80f16276388a177199204aa5b60f328d4464110Girish K S} 1144a80f16276388a177199204aa5b60f328d4464110Girish K S 1145d6d50a15a2897d4133d536dd4343b5cf21163db3Arindam Nath/* 114645f8245b972e360c19aec9032e2a2033b8ac3719Russell King * Apply power to the MMC stack. This is a two-stage process. 114745f8245b972e360c19aec9032e2a2033b8ac3719Russell King * First, we enable power to the card without the clock running. 114845f8245b972e360c19aec9032e2a2033b8ac3719Russell King * We then wait a bit for the power to stabilise. Finally, 114945f8245b972e360c19aec9032e2a2033b8ac3719Russell King * enable the bus drivers and clock to the card. 115045f8245b972e360c19aec9032e2a2033b8ac3719Russell King * 115145f8245b972e360c19aec9032e2a2033b8ac3719Russell King * We must _NOT_ enable the clock prior to power stablising. 115245f8245b972e360c19aec9032e2a2033b8ac3719Russell King * 115345f8245b972e360c19aec9032e2a2033b8ac3719Russell King * If a host does all the power sequencing itself, ignore the 115445f8245b972e360c19aec9032e2a2033b8ac3719Russell King * initial MMC_POWER_UP stage. 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mmc_power_up(struct mmc_host *host) 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1158500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao int bit; 1159500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao 1160778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1161778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1162500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao /* If ocr is set, we use it */ 1163500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao if (host->ocr) 1164500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao bit = ffs(host->ocr) - 1; 1165500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao else 1166500f35648e5ebd04be00f974738a9db959a892b8Balaji Rao bit = fls(host->ocr_avail) - 1; 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = bit; 116944669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK if (mmc_host_is_spi(host)) 1170af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_HIGH; 117144669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK else 1172af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_DONTCARE; 117344669034815a7ad263542ac605c581a10b22d146Stefan Nilsson XK host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_UP; 1175f218278a456b3c272b480443c89004c3d2a49f18Pierre Ossman host->ios.bus_width = MMC_BUS_WIDTH_1; 1176cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman host->ios.timing = MMC_TIMING_LEGACY; 1177920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1179f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman /* 1180f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * This delay should be sufficient to allow the power supply 1181f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * to reach the minimum voltage. 1182f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman */ 118379bccc5aefb4e64e651abe04f78c3e6bf8acd6f0José M. Fernández mmc_delay(10); 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 118588ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch host->ios.clock = host->f_init; 11868dfd0374be84793360db7fff2e635d2cd3bbcb21Sascha Hauer 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_ON; 1188920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1190f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman /* 1191f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * This delay must be at least 74 clock sizes, or 1 ms, or the 1192f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman * time required to reach a stable voltage. 1193f9996aee36921e8f1d499de1b2ea380855cf6d97Pierre Ossman */ 119479bccc5aefb4e64e651abe04f78c3e6bf8acd6f0José M. Fernández mmc_delay(10); 1195778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1196778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11997f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hanssonvoid mmc_power_off(struct mmc_host *host) 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12013e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S int err = 0; 1202778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_hold(host); 1203778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.clock = 0; 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.vdd = 0; 1206b33d46c398fd071dccd0815f33620924684860cdUlf Hansson 12073e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S /* 12083e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * For eMMC 4.5 device send AWAKE command before 12093e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * POWER_OFF_NOTIFY command, because in sleep state 12103e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S * eMMC 4.5 devices respond to only RESET and AWAKE cmd 12113e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S */ 12123e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S if (host->card && mmc_card_is_sleep(host->card) && 12133e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S host->bus_ops->resume) { 12143e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S err = host->bus_ops->resume(host); 12153e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S 12163e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S if (!err) 12173e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_poweroff_notify(host); 12183e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S else 12193e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S pr_warning("%s: error %d during resume " 12203e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S "(continue with poweroff sequence)\n", 12213e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S mmc_hostname(host), err); 12223e73c36b4dc224529d0b0c0d5d69c0dacd793c42Girish K S } 1223bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S 1224b33d46c398fd071dccd0815f33620924684860cdUlf Hansson /* 1225b33d46c398fd071dccd0815f33620924684860cdUlf Hansson * Reset ocr mask to be the highest possible voltage supported for 1226b33d46c398fd071dccd0815f33620924684860cdUlf Hansson * this mmc host. This value will be used at next power up. 1227b33d46c398fd071dccd0815f33620924684860cdUlf Hansson */ 1228b33d46c398fd071dccd0815f33620924684860cdUlf Hansson host->ocr = 1 << (fls(host->ocr_avail) - 1); 1229b33d46c398fd071dccd0815f33620924684860cdUlf Hansson 1230af51715079e7fb6b290e1881d63d815dc4de5011David Brownell if (!mmc_host_is_spi(host)) { 1231af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 1232af51715079e7fb6b290e1881d63d815dc4de5011David Brownell host->ios.chip_select = MMC_CS_DONTCARE; 1233af51715079e7fb6b290e1881d63d815dc4de5011David Brownell } 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->ios.power_mode = MMC_POWER_OFF; 1235f218278a456b3c272b480443c89004c3d2a49f18Pierre Ossman host->ios.bus_width = MMC_BUS_WIDTH_1; 1236cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman host->ios.timing = MMC_TIMING_LEGACY; 1237920e70c5c603ada05dd480ca0ccc0ae12a5fdc39Russell King mmc_set_ios(host); 1238778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg 1239041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake /* 1240041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * Some configurations, such as the 802.11 SDIO card in the OLPC 1241041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * XO-1.5, require a short delay after poweroff before the card 1242041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake * can be successfully turned on again. 1243041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake */ 1244041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake mmc_delay(1); 1245041beb1d531f538bf62377e2ca2b4ecbaa479d75Daniel Drake 1246778e277cb82411c9002ca28ccbd216c4d9eb9158Mika Westerberg mmc_host_clk_release(host); 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1250393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Cleanup when the last reference to the bus operator is dropped. 1251393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1252261172fd1b23769bc7632047e2cb826c9b8b1a50Adrian Bunkstatic void __mmc_release_bus(struct mmc_host *host) 1253393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1254393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(!host); 1255393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(host->bus_refs); 1256393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk BUG_ON(!host->bus_dead); 1257393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1258393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_ops = NULL; 1259393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1260393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1261393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 1262393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Increase reference count of bus operator 1263393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1264393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic inline void mmc_bus_get(struct mmc_host *host) 1265393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1266393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk unsigned long flags; 1267393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1268393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_lock_irqsave(&host->lock, flags); 1269393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_refs++; 1270393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_unlock_irqrestore(&host->lock, flags); 1271393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1272393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1273393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 1274393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * Decrease reference count of bus operator and free it if 1275393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk * it is the last reference. 1276393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk */ 1277393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunkstatic inline void mmc_bus_put(struct mmc_host *host) 1278393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk{ 1279393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk unsigned long flags; 1280393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1281393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_lock_irqsave(&host->lock, flags); 1282393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk host->bus_refs--; 1283393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk if ((host->bus_refs == 0) && host->bus_ops) 1284393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk __mmc_release_bus(host); 1285393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk spin_unlock_irqrestore(&host->lock, flags); 1286393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk} 1287393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk 1288393618510d5349e07d71dc28fb6fc49baf0d96a0Adrian Bunk/* 12897ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * Assign a mmc bus handler to a host. Only one bus handler may control a 12907ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman * host at any given time. 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12927ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12947ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman unsigned long flags; 1295e45a1bd20fa5b920901879e85cdf5eda21f78d7cPhilip Langdale 12967ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!host); 12977ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!ops); 1298b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman 1299d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 1300bce40a36de574376f41f1ff3c4d212a7da2a3c90Philip Langdale 13017ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_lock_irqsave(&host->lock, flags); 1302bce40a36de574376f41f1ff3c4d212a7da2a3c90Philip Langdale 13037ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->bus_ops); 13047ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->bus_refs); 1305b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13067ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_ops = ops; 13077ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_refs = 1; 13087ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_dead = 0; 1309b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13107ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_unlock_irqrestore(&host->lock, flags); 1311b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman} 1312b57c43ad81602589afca3948a5a7121e40026e17Pierre Ossman 13137ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman/* 13147f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson * Remove the current bus handler from a host. 13157ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman */ 13167ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossmanvoid mmc_detach_bus(struct mmc_host *host) 13177ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman{ 13187ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman unsigned long flags; 13197ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13207ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(!host); 13217ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 1322d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->claimed); 1323d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(!host->bus_ops); 1324cd9277c011a99769fa371521b460ed57f6d280b1Pierre Ossman 13257ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_lock_irqsave(&host->lock, flags); 13267ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13277ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_dead = 1; 13287ccd266e676a3f0c6f8f897f58b684cac3dd1650Pierre Ossman 13297ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman spin_unlock_irqrestore(&host->lock, flags); 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13317ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_detect_change - process change of state on a MMC socket 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: host which changed state. 13378dc003359cc3996abad9e53a7b2280b272610283Richard Purdie * @delay: optional delay to wait before detection (jiffies) 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 133967a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * MMC drivers should call this when they detect a card has been 134067a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * inserted or removed. The MMC layer will confirm that any 134167a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * present card is still functional, and initialize any newly 134267a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * inserted. 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13448dc003359cc3996abad9e53a7b2280b272610283Richard Purdievoid mmc_detect_change(struct mmc_host *host, unsigned long delay) 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13463b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#ifdef CONFIG_MMC_DEBUG 13471efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman unsigned long flags; 134801f41ec7b36e14da18a4e162ef697ae358f36e37Andrew Morton spin_lock_irqsave(&host->lock, flags); 1349d84075c8aed771d47d7ac6e96b098559da361c25Pierre Ossman WARN_ON(host->removed); 135001f41ec7b36e14da18a4e162ef697ae358f36e37Andrew Morton spin_unlock_irqrestore(&host->lock, flags); 13513b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#endif 1352d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 1; 1353c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells mmc_schedule_delayed_work(&host->detect, delay); 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_detect_change); 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1358dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Huntervoid mmc_init_erase(struct mmc_card *card) 1359dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1360dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int sz; 1361dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1362dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (is_power_of_2(card->erase_size)) 1363dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = ffs(card->erase_size) - 1; 1364dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1365dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = 0; 1366dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1367dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1368dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * It is possible to erase an arbitrarily large area of an SD or MMC 1369dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * card. That is not desirable because it can take a long time 1370dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * (minutes) potentially delaying more important I/O, and also the 1371dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * timeout calculations become increasingly hugely over-estimated. 1372dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Consequently, 'pref_erase' is defined as a guide to limit erases 1373dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * to that size and alignment. 1374dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1375dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * For SD cards that define Allocation Unit size, limit erases to one 1376dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Allocation Unit at a time. For MMC cards that define High Capacity 1377dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Erase Size, whether it is switched on or not, limit to that size. 1378dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Otherwise just have a stab at a good value. For modern cards it 1379dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * will end up being 4MiB. Note that if the value is too small, it 1380dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * can end up taking longer to erase. 1381dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1382dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card) && card->ssr.au) { 1383dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->ssr.au; 1384dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->erase_shift = ffs(card->ssr.au) - 1; 1385dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else if (card->ext_csd.hc_erase_size) { 1386dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->ext_csd.hc_erase_size; 1387dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1388dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter sz = (card->csd.capacity << (card->csd.read_blkbits - 9)) >> 11; 1389dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (sz < 128) 1390dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 512 * 1024 / 512; 1391dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (sz < 512) 1392dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 1024 * 1024 / 512; 1393dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (sz < 1024) 1394dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 2 * 1024 * 1024 / 512; 1395dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1396dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = 4 * 1024 * 1024 / 512; 1397dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->pref_erase < card->erase_size) 1398dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase = card->erase_size; 1399dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else { 1400dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter sz = card->pref_erase % card->erase_size; 1401dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (sz) 1402dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter card->pref_erase += card->erase_size - sz; 1403dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1404dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1405dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1406dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1407eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, 1408eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, unsigned int qty) 1409dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1410dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int erase_timeout; 1411dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1412dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ext_csd.erase_group_def & 1) { 1413dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* High Capacity Erase Group Size uses HC timeouts */ 1414dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_TRIM_ARG) 1415dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = card->ext_csd.trim_timeout; 1416dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1417dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = card->ext_csd.hc_erase_timeout; 1418dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1419dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* CSD Erase Group Size uses write timeout */ 1420dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int mult = (10 << card->csd.r2w_factor); 1421dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int timeout_clks = card->csd.tacc_clks * mult; 1422dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int timeout_us; 1423dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1424dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */ 1425dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->csd.tacc_ns < 1000000) 1426dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us = (card->csd.tacc_ns * mult) / 1000; 1427dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1428dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us = (card->csd.tacc_ns / 1000) * mult; 1429dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1430dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1431dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * ios.clock is only a target. The real clock rate might be 1432dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * less but not that much less, so fudge it by multiplying by 2. 1433dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1434dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_clks <<= 1; 1435dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter timeout_us += (timeout_clks * 1000) / 14364cf8c6dd2e261da94b87c4deadcc136ab022b6acAdrian Hunter (mmc_host_clk_rate(card->host) / 1000); 1437dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1438dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = timeout_us / 1000; 1439dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1440dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1441dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Theoretically, the calculation could underflow so round up 1442dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * to 1ms in that case. 1443dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1444dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!erase_timeout) 1445dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = 1; 1446dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1447dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1448dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Multiplier for secure operations */ 1449dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg & MMC_SECURE_ARGS) { 1450dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_SECURE_ERASE_ARG) 1451dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= card->ext_csd.sec_erase_mult; 1452dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1453dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= card->ext_csd.sec_trim_mult; 1454dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1455dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1456dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout *= qty; 1457dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1458dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1459dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Ensure at least a 1 second timeout for SPI as per 1460dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 'mmc_set_data_timeout()' 1461dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1462dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_host_is_spi(card->host) && erase_timeout < 1000) 1463dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter erase_timeout = 1000; 1464dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1465eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return erase_timeout; 1466dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1467dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1468eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_sd_erase_timeout(struct mmc_card *card, 1469eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, 1470eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int qty) 1471dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1472eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int erase_timeout; 1473eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin 1474dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ssr.erase_timeout) { 1475dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Erase timeout specified in SD Status Register (SSR) */ 1476eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = card->ssr.erase_timeout * qty + 1477eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin card->ssr.erase_offset; 1478dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } else { 1479dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1480dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Erase timeout not specified in SD Status Register (SSR) so 1481dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * use 250ms per write block. 1482dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1483eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = 250 * qty; 1484dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1485dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1486dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Must not be less than 1 second */ 1487eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin if (erase_timeout < 1000) 1488eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin erase_timeout = 1000; 1489eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin 1490eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return erase_timeout; 1491dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1492dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1493eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentinstatic unsigned int mmc_erase_timeout(struct mmc_card *card, 1494eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int arg, 1495eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin unsigned int qty) 1496dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1497dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1498eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return mmc_sd_erase_timeout(card, arg, qty); 1499dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1500eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin return mmc_mmc_erase_timeout(card, arg, qty); 1501dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1502dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1503dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterstatic int mmc_do_erase(struct mmc_card *card, unsigned int from, 1504dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int to, unsigned int arg) 1505dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 15061278dba167f01bb3c6626d16450d31129d041087Chris Ball struct mmc_command cmd = {0}; 1507dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int qty = 0; 1508dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter int err; 1509dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1510dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 1511dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * qty is used to calculate the erase timeout which depends on how many 1512dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * erase groups (or allocation units in SD terminology) are affected. 1513dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * We count erasing part of an erase group as one erase group. 1514dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * For SD, the allocation units are always a power of 2. For MMC, the 1515dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * erase group size is almost certainly also power of 2, but it does not 1516dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * seem to insist on that in the JEDEC standard, so we fall back to 1517dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * division in that case. SD may not specify an allocation unit size, 1518dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * in which case the timeout is based on the number of write blocks. 1519dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1520dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Note that the timeout for secure trim 2 will only be correct if the 1521dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * number of erase groups specified is the same as the total of all 1522dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * preceding secure trim 1 commands. Since the power may have been 1523dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * lost since the secure trim 1 commands occurred, it is generally 1524dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * impossible to calculate the secure trim 2 timeout correctly. 1525dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1526dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->erase_shift) 1527dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += ((to >> card->erase_shift) - 1528dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (from >> card->erase_shift)) + 1; 1529dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else if (mmc_card_sd(card)) 1530dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += to - from + 1; 1531dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1532dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter qty += ((to / card->erase_size) - 1533dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (from / card->erase_size)) + 1; 1534dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1535dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!mmc_card_blockaddr(card)) { 1536dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter from <<= 9; 1537dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to <<= 9; 1538dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1539dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1540dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1541dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = SD_ERASE_WR_BLK_START; 1542dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1543dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE_GROUP_START; 1544dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = from; 1545dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 1546dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1547dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1548a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: group start error %d, " 1549dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter "status %#x\n", err, cmd.resp[0]); 155067716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter err = -EIO; 1551dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1552dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1553dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1554dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1555dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card)) 1556dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = SD_ERASE_WR_BLK_END; 1557dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1558dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE_GROUP_END; 1559dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = to; 1560dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 1561dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1562dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1563a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: group end error %d, status %#x\n", 1564dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 156567716327eec7e9d573e7cb2d806545d6f7c1a38dAdrian Hunter err = -EIO; 1566dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1567dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1568dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1569dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1570dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_ERASE; 1571dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = arg; 1572dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; 1573eaa02f751ff4f8abfc2e55a15c20a5a274244418Andrei Warkentin cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty); 1574dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1575dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err) { 1576a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("mmc_erase: erase error %d, status %#x\n", 1577dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 1578dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = -EIO; 1579dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1580dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1581dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1582dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_host_is_spi(card->host)) 1583dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1584dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1585dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter do { 1586dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter memset(&cmd, 0, sizeof(struct mmc_command)); 1587dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.opcode = MMC_SEND_STATUS; 1588dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.arg = card->rca << 16; 1589dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 1590dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* Do not retry else we can't see errors */ 1591dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1592dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (err || (cmd.resp[0] & 0xFDF92000)) { 1593a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_err("error %d requesting status %#x\n", 1594dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err, cmd.resp[0]); 1595dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter err = -EIO; 1596dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter goto out; 1597dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1598dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || 15997435bb7950ba8a3cbfa6d0c01e92588562533a3fJaehoon Chung R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG); 1600dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterout: 1601dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return err; 1602dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1603dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1604dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter/** 1605dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * mmc_erase - erase sectors. 1606dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @card: card to erase 1607dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @from: first sector to erase 1608dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @nr: number of sectors to erase 1609dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) 1610dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * 1611dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter * Caller must claim host before calling this function. 1612dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter */ 1613dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, 1614dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int arg) 1615dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1616dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int rem, to = from + nr; 1617dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1618dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!(card->host->caps & MMC_CAP_ERASE) || 1619dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->csd.cmdclass & CCC_ERASE)) 1620dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1621dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1622dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!card->erase_size) 1623dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1624dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1625dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (mmc_card_sd(card) && arg != MMC_ERASE_ARG) 1626dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1627dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1628dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((arg & MMC_SECURE_ARGS) && 1629dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) 1630dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1631dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1632dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((arg & MMC_TRIM_ARGS) && 1633dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) 1634dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EOPNOTSUPP; 1635dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1636dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_SECURE_ERASE_ARG) { 1637dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (from % card->erase_size || nr % card->erase_size) 1638dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EINVAL; 1639dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1640dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1641dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (arg == MMC_ERASE_ARG) { 1642dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = from % card->erase_size; 1643dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (rem) { 1644dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = card->erase_size - rem; 1645dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter from += rem; 1646dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (nr > rem) 1647dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter nr -= rem; 1648dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter else 1649dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1650dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1651dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter rem = nr % card->erase_size; 1652dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (rem) 1653dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter nr -= rem; 1654dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter } 1655dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1656dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (nr == 0) 1657dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1658dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1659dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to = from + nr; 1660dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1661dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (to <= from) 1662dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return -EINVAL; 1663dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1664dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter /* 'from' and 'to' are inclusive */ 1665dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter to -= 1; 1666dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1667dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return mmc_do_erase(card, from, to, arg); 1668dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1669dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_erase); 1670dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1671dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_erase(struct mmc_card *card) 1672dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1673dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if ((card->host->caps & MMC_CAP_ERASE) && 1674dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter (card->csd.cmdclass & CCC_ERASE) && card->erase_size) 1675dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1676dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1677dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1678dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_erase); 1679dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1680dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_trim(struct mmc_card *card) 1681dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1682dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) 1683dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1684b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park if (mmc_can_discard(card)) 1685b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park return 1; 1686dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1687dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1688dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_trim); 1689dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1690b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Parkint mmc_can_discard(struct mmc_card *card) 1691b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park{ 1692b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park /* 1693b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park * As there's no way to detect the discard support bit at v4.5 1694b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park * use the s/w feature support filed. 1695b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park */ 1696b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE) 1697b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park return 1; 1698b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park return 0; 1699b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park} 1700b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin ParkEXPORT_SYMBOL(mmc_can_discard); 1701b3bf915308ca2b50f3beec6cc824083870f0f4b5Kyungmin Park 1702d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Parkint mmc_can_sanitize(struct mmc_card *card) 1703d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park{ 1704d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) 1705d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park return 1; 1706d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park return 0; 1707d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park} 1708d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin ParkEXPORT_SYMBOL(mmc_can_sanitize); 1709d9ddd62943ee07a75d0428ffcf52f1a747a28c39Kyungmin Park 1710dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_can_secure_erase_trim(struct mmc_card *card) 1711dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1712dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN) 1713dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1714dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1715dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1716dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_can_secure_erase_trim); 1717dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter 1718dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunterint mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, 1719dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter unsigned int nr) 1720dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter{ 1721dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (!card->erase_size) 1722dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1723dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter if (from % card->erase_size || nr % card->erase_size) 1724dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 0; 1725dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter return 1; 1726dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian Hunter} 1727dfe86cba7676d58db8de7e623f5e72f1b0d3ca35Adrian HunterEXPORT_SYMBOL(mmc_erase_group_aligned); 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1729e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunterstatic unsigned int mmc_do_calc_max_discard(struct mmc_card *card, 1730e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int arg) 1731e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter{ 1732e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter struct mmc_host *host = card->host; 1733e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int max_discard, x, y, qty = 0, max_qty, timeout; 1734e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int last_timeout = 0; 1735e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1736e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (card->erase_shift) 1737e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX >> card->erase_shift; 1738e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else if (mmc_card_sd(card)) 1739e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX; 1740e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else 1741e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_qty = UINT_MAX / card->erase_size; 1742e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1743e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* Find the largest qty with an OK timeout */ 1744e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter do { 1745e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter y = 0; 1746e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { 1747e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter timeout = mmc_erase_timeout(card, arg, qty + x); 1748e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (timeout > host->max_discard_to) 1749e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter break; 1750e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (timeout < last_timeout) 1751e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter break; 1752e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter last_timeout = timeout; 1753e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter y = x; 1754e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } 1755e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter qty += y; 1756e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } while (y); 1757e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1758e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (!qty) 1759e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return 0; 1760e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1761e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (qty == 1) 1762e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return 1; 1763e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1764e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* Convert qty to sectors */ 1765e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (card->erase_shift) 1766e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = --qty << card->erase_shift; 1767e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else if (mmc_card_sd(card)) 1768e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = qty; 1769e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter else 1770e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = --qty * card->erase_size; 1771e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1772e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return max_discard; 1773e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter} 1774e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1775e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunterunsigned int mmc_calc_max_discard(struct mmc_card *card) 1776e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter{ 1777e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter struct mmc_host *host = card->host; 1778e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter unsigned int max_discard, max_trim; 1779e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1780e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (!host->max_discard_to) 1781e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return UINT_MAX; 1782e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1783e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter /* 1784e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * Without erase_group_def set, MMC erase timeout depends on clock 1785e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * frequence which can change. In that case, the best choice is 1786e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter * just the preferred erase size. 1787e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter */ 1788e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1)) 1789e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return card->pref_erase; 1790e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 1791e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG); 1792e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (mmc_can_trim(card)) { 1793e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG); 1794e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter if (max_trim < max_discard) 1795e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = max_trim; 1796e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } else if (max_discard < card->erase_size) { 1797e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter max_discard = 0; 1798e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter } 1799e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n", 1800e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter mmc_hostname(host), max_discard, host->max_discard_to); 1801e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter return max_discard; 1802e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter} 1803e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian HunterEXPORT_SYMBOL(mmc_calc_max_discard); 1804e056a1b5b67b4e4bfad00bf143ab14f634777705Adrian Hunter 18050f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunterint mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) 18060f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter{ 18071278dba167f01bb3c6626d16450d31129d041087Chris Ball struct mmc_command cmd = {0}; 18080f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 18090f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) 18100f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter return 0; 18110f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 18120f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.opcode = MMC_SET_BLOCKLEN; 18130f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.arg = blocklen; 18140f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; 18150f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter return mmc_wait_for_cmd(card->host, &cmd, 5); 18160f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter} 18170f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian HunterEXPORT_SYMBOL(mmc_set_blocklen); 18180f8d8ea64ec7c77ca5beb59534d386fe0235961aAdrian Hunter 1819b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterstatic void mmc_hw_reset_for_init(struct mmc_host *host) 1820b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1821b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) 1822b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return; 1823b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_hold(host); 1824b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ops->hw_reset(host); 1825b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1826b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1827b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1828b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_can_reset(struct mmc_card *card) 1829b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1830b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter u8 rst_n_function; 1831b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1832b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_card_mmc(card)) 1833b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 0; 1834b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter rst_n_function = card->ext_csd.rst_n_function; 1835b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) 1836b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 0; 1837b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return 1; 1838b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1839b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_can_reset); 1840b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1841b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterstatic int mmc_do_hw_reset(struct mmc_host *host, int check) 1842b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1843b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter struct mmc_card *card = host->card; 1844b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1845b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!host->bus_ops->power_restore) 1846b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1847b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1848b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) 1849b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1850b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1851b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!card) 1852b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EINVAL; 1853b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1854b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_can_reset(card)) 1855b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -EOPNOTSUPP; 1856b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1857b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_hold(host); 1858b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_set_clock(host, host->f_init); 1859b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1860b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ops->hw_reset(host); 1861b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1862b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter /* If the reset has happened, then a status command will fail */ 1863b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (check) { 1864b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter struct mmc_command cmd = {0}; 1865b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter int err; 1866b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1867b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.opcode = MMC_SEND_STATUS; 1868b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!mmc_host_is_spi(card->host)) 1869b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.arg = card->rca << 16; 1870b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; 1871b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter err = mmc_wait_for_cmd(card->host, &cmd, 0); 1872b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (!err) { 1873b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1874b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return -ENOSYS; 1875b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1876b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1877b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1878b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_DDR); 1879b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter if (mmc_host_is_spi(host)) { 1880b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.chip_select = MMC_CS_HIGH; 1881b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 1882b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } else { 1883b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.chip_select = MMC_CS_DONTCARE; 1884b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 1885b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter } 1886b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.bus_width = MMC_BUS_WIDTH_1; 1887b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter host->ios.timing = MMC_TIMING_LEGACY; 1888b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_set_ios(host); 1889b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1890b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_host_clk_release(host); 1891b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1892b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return host->bus_ops->power_restore(host); 1893b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1894b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1895b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_hw_reset(struct mmc_host *host) 1896b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1897b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return mmc_do_hw_reset(host, 0); 1898b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1899b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_hw_reset); 1900b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1901b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunterint mmc_hw_reset_check(struct mmc_host *host) 1902b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter{ 1903b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter return mmc_do_hw_reset(host, 1); 1904b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter} 1905b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian HunterEXPORT_SYMBOL(mmc_hw_reset_check); 1906b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1907807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Rossstatic int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) 1908807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross{ 1909807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross host->f_init = freq; 1910807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1911807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross#ifdef CONFIG_MMC_DEBUG 1912807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross pr_info("%s: %s: trying to init card at %u Hz\n", 1913807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_hostname(host), __func__, host->f_init); 1914807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross#endif 1915807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_power_up(host); 19162f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity 19172f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity /* 1918b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter * Some eMMCs (with VCCQ always on) may not be reset after power up, so 1919b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter * do a hardware reset if possible. 1920b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter */ 1921b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter mmc_hw_reset_for_init(host); 1922b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter 1923e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson /* Initialization should be done at 3.3 V I/O voltage. */ 1924e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); 1925e7747475b61fdc2a4a412475a9d64d8c309916e3Ulf Hansson 1926b2499518b5ad7e28bb3ed348fd3f370eeb1e36c0Adrian Hunter /* 19272f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * sdio_reset sends CMD52 to reset card. Since we do not know 19282f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * if the card is being re-initialized, just send it. CMD52 19292f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity * should be ignored by SD/eMMC cards. 19302f94e55ae5ddad83e661002985d2ea11b6d51d3dPhilip Rakity */ 1931807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross sdio_reset(host); 1932807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_go_idle(host); 1933807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1934807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_send_if_cond(host, host->ocr_avail); 1935807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1936807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross /* Order's important: probe SDIO, then SD, then MMC */ 1937807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_sdio(host)) 1938807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1939807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_sd(host)) 1940807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1941807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_attach_mmc(host)) 1942807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return 0; 1943807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1944807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_power_off(host); 1945807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross return -EIO; 1946807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross} 1947807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 1948d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunterint _mmc_detect_card_removed(struct mmc_host *host) 1949d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter{ 1950d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter int ret; 1951d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1952d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive) 1953d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return 0; 1954d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1955d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (!host->card || mmc_card_removed(host->card)) 1956d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return 1; 1957d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1958d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter ret = host->bus_ops->alive(host); 1959d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter if (ret) { 1960d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter mmc_card_set_removed(host->card); 1961d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter pr_debug("%s: card remove detected\n", mmc_hostname(host)); 1962d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter } 1963d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1964d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter return ret; 1965d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter} 1966d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1967d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunterint mmc_detect_card_removed(struct mmc_host *host) 1968d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter{ 1969d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter struct mmc_card *card = host->card; 1970f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson int ret; 1971d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1972d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter WARN_ON(!host->claimed); 1973f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson 1974f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!card) 1975f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return 1; 1976f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson 1977f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson ret = mmc_card_removed(card); 1978d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter /* 1979d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter * The card will be considered unchanged unless we have been asked to 1980d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter * detect a change or host requires polling to provide card detection. 1981d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter */ 1982f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && 1983f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) 1984f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return ret; 1985d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1986d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 0; 1987f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (!ret) { 1988f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson ret = _mmc_detect_card_removed(host); 1989f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { 1990f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson /* 1991f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson * Schedule a detect work as soon as possible to let a 1992f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson * rescan handle the card removal. 1993f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson */ 1994f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson cancel_delayed_work(&host->detect); 1995f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson mmc_detect_change(host, 0); 1996f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson } 1997f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson } 1998d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 1999f0cc9cf99326926fd76f77645c48d16d647802ebUlf Hansson return ret; 2000d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter} 2001d30495048892980e5d453328d1cc9343b3f7e917Adrian HunterEXPORT_SYMBOL(mmc_detect_card_removed); 2002d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2003b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_rescan(struct work_struct *work) 20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2005807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; 2006c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct mmc_host *host = 2007c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct mmc_host, detect.work); 200888ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch int i; 20094c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 2010807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (host->rescan_disable) 20114c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky return; 20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20137ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 2014b855885e3b60cf6f9452848712a62517b94583ebPierre Ossman 201530201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen /* 201630201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen * if there is a _removable_ card registered, check whether it is 201730201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen * still present 201830201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen */ 201930201e7f3ac639fe98fcd25d40346b65dde9ecbaOhad Ben-Cohen if (host->bus_ops && host->bus_ops->detect && !host->bus_dead 2020bad3babace2ee4d1763b4016a662a5c660ab92e9Ohad Ben-Cohen && !(host->caps & MMC_CAP_NONREMOVABLE)) 202194d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer host->bus_ops->detect(host); 202294d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer 2023d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter host->detect_change = 0; 2024d30495048892980e5d453328d1cc9343b3f7e917Adrian Hunter 2025c584179828b268152f5ff82dab529a2c095b09acChris Ball /* 2026c584179828b268152f5ff82dab529a2c095b09acChris Ball * Let mmc_bus_put() free the bus/bus_ops if we've found that 2027c584179828b268152f5ff82dab529a2c095b09acChris Ball * the card is no longer present. 2028c584179828b268152f5ff82dab529a2c095b09acChris Ball */ 202994d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_put(host); 203094d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_get(host); 203194d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer 203294d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer /* if there still is a card present, stop here */ 203394d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer if (host->bus_ops != NULL) { 20347ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 203594d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer goto out; 203694d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer } 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 203894d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer /* 203994d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer * Only we can add a new handler, so it's safe to 204094d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer * release the lock here. 204194d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer */ 204294d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer mmc_bus_put(host); 20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 204494d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer if (host->ops->get_cd && host->ops->get_cd(host) == 0) 204594d89efb2c347a82a08a61dbac8565b1087c3259Jorg Schummer goto out; 20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2047807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_claim_host(host); 204888ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch for (i = 0; i < ARRAY_SIZE(freqs); i++) { 2049807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) 2050807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross break; 205106b2233a20bf25c8ee57b7c6e13f528309ac6edcJaehoon Chung if (freqs[i] <= host->f_min) 2052807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross break; 205388ae8b866488031b0e2fc05a27440fefec5e6927Hein Tibosch } 2054807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross mmc_release_host(host); 2055807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross 2056807e8e40673d9628fa7dcdd14423424b4ee5f43bAndy Ross out: 205728f52482b41edc88cdf575aa6ed414c6e116ce10Anton Vorontsov if (host->caps & MMC_CAP_NEEDS_POLL) 205828f52482b41edc88cdf575aa6ed414c6e116ce10Anton Vorontsov mmc_schedule_delayed_work(&host->detect, HZ); 20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_start_host(struct mmc_host *host) 20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2063b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_power_off(host); 2064b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_detect_change(host, 0); 20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2067b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_stop_host(struct mmc_host *host) 20681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 20693b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#ifdef CONFIG_MMC_DEBUG 20701efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman unsigned long flags; 20711efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman spin_lock_irqsave(&host->lock, flags); 20723b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman host->removed = 1; 20731efd48b3ae8f89a1d04f1e36be96764d7bf43ae9Pierre Ossman spin_unlock_irqrestore(&host->lock, flags); 20743b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman#endif 20753b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman 2076d9bcbf343ec63e1104b5276195888ee06b4d086fGuennadi Liakhovetski cancel_delayed_work_sync(&host->detect); 20773b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman mmc_flush_scheduled_work(); 20783b91e5507cddaca53bccf1524ff11a0ac5c85531Pierre Ossman 2079da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre /* clear pm flags now and let card drivers set them as needed */ 2080da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre host->pm_flags = 0; 2081da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre 20827ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 20837ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops && !host->bus_dead) { 20840db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski /* Calling bus_ops->remove() with a claimed host can deadlock */ 20857ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops->remove) 20867ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman host->bus_ops->remove(host); 20877ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 20887ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_claim_host(host); 20897ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_detach_bus(host); 20907f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson mmc_power_off(host); 20917ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_release_host(host); 209253509f0fe28e049e772897aa8fa1f5183b6823a2Denis Karpov mmc_bus_put(host); 209353509f0fe28e049e772897aa8fa1f5183b6823a2Denis Karpov return; 20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20957ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 20967ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 20977ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman BUG_ON(host->card); 20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mmc_power_off(host); 21001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 210212ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohenint mmc_power_save_host(struct mmc_host *host) 2103eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter{ 210412ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen int ret = 0; 210512ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 2106bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#ifdef CONFIG_MMC_DEBUG 2107bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake pr_info("%s: %s: powering down\n", mmc_hostname(host), __func__); 2108bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#endif 2109bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake 2110eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_get(host); 2111eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2112eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { 2113eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 211412ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return -EINVAL; 2115eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter } 2116eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2117eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (host->bus_ops->power_save) 211812ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen ret = host->bus_ops->power_save(host); 2119eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2120eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 2121eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2122eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_power_off(host); 212312ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 212412ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return ret; 2125eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter} 2126eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian HunterEXPORT_SYMBOL(mmc_power_save_host); 2127eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 212812ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohenint mmc_power_restore_host(struct mmc_host *host) 2129eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter{ 213012ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen int ret; 213112ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 2132bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#ifdef CONFIG_MMC_DEBUG 2133bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake pr_info("%s: %s: powering up\n", mmc_hostname(host), __func__); 2134bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake#endif 2135bb9cab941c7139304899fa7922f3069bb2097f4eDaniel Drake 2136eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_get(host); 2137eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2138eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { 2139eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 214012ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return -EINVAL; 2141eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter } 2142eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2143eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_power_up(host); 214412ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen ret = host->bus_ops->power_restore(host); 2145eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2146eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter mmc_bus_put(host); 214712ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen 214812ae637f081a7a05144af65802a7b492b9162660Ohad Ben-Cohen return ret; 2149eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter} 2150eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian HunterEXPORT_SYMBOL(mmc_power_restore_host); 2151eae1aeeed852aae37621b82a9e7f6c05096a18fdAdrian Hunter 2152b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_awake(struct mmc_host *host) 2153b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2154b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen int err = -ENOSYS; 2155b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2156aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) 2157aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson return 0; 2158aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson 2159b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_get(host); 2160b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2161b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) 2162b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen err = host->bus_ops->awake(host); 2163b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2164b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_put(host); 2165b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2166b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return err; 2167b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2168b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_awake); 2169b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2170b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_sleep(struct mmc_host *host) 2171b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2172b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen int err = -ENOSYS; 2173b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2174aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) 2175aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson return 0; 2176aa9df4fb2adcc73d36fa41e23059519be770aaa5Ulf Hansson 2177b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_get(host); 2178b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2179c99872a16fa7642987f30c750dc166674b0d8060Kyungmin Park if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) 2180b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen err = host->bus_ops->sleep(host); 2181b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2182b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen mmc_bus_put(host); 2183b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2184b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return err; 2185b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2186b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_sleep); 2187b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2188b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinenint mmc_card_can_sleep(struct mmc_host *host) 2189b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen{ 2190b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen struct mmc_card *card = host->card; 2191b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2192b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3) 2193b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return 1; 2194b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen return 0; 2195b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen} 2196b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko LavinenEXPORT_SYMBOL(mmc_card_can_sleep); 2197b1ebe38456f7fe61a88af2844361e763ac6ea5aeJarkko Lavinen 2198881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon/* 2199881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Flush the cache to the non-volatile storage. 2200881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon */ 2201881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonint mmc_flush_cache(struct mmc_card *card) 2202881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon{ 2203881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon struct mmc_host *host = card->host; 2204881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon int err = 0; 2205881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2206881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (!(host->caps2 & MMC_CAP2_CACHE_CTRL)) 2207881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2208881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2209881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (mmc_card_mmc(card) && 2210881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_size > 0) && 2211881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_ctrl & 1)) { 2212881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 2213881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon EXT_CSD_FLUSH_CACHE, 1, 0); 2214881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (err) 2215881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon pr_err("%s: cache flush error %d\n", 2216881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon mmc_hostname(card->host), err); 2217881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon } 2218881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2219881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2220881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon} 2221881d1c25f765938a95def5afe39486ce39f9fc96Seungwon JeonEXPORT_SYMBOL(mmc_flush_cache); 2222881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2223881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon/* 2224881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Turn the cache ON/OFF. 2225881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * Turning the cache OFF shall trigger flushing of the data 2226881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon * to the non-volatile storage. 2227881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon */ 2228881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonint mmc_cache_ctrl(struct mmc_host *host, u8 enable) 2229881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon{ 2230881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon struct mmc_card *card = host->card; 22318bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon unsigned int timeout; 2232881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon int err = 0; 2233881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2234881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || 2235881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon mmc_card_is_removable(host)) 2236881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2237881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2238881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (card && mmc_card_mmc(card) && 2239881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon (card->ext_csd.cache_size > 0)) { 2240881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon enable = !!enable; 2241881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 22428bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon if (card->ext_csd.cache_ctrl ^ enable) { 22438bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon timeout = enable ? card->ext_csd.generic_cmd6_time : 0; 2244881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 22458bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon EXT_CSD_CACHE_CTRL, enable, timeout); 22468bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon if (err) 22478bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon pr_err("%s: cache %s error %d\n", 22488bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon mmc_hostname(card->host), 22498bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon enable ? "on" : "off", 22508bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon err); 22518bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon else 22528bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon card->ext_csd.cache_ctrl = enable; 22538bc0678b845531221ba2ea6efe34db66e587705bSeungwon Jeon } 2254881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon } 2255881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 2256881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon return err; 2257881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon} 2258881d1c25f765938a95def5afe39486ce39f9fc96Seungwon JeonEXPORT_SYMBOL(mmc_cache_ctrl); 2259881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon 22601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PM 22611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_suspend_host - suspend a host 22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host 22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 22661a13f8fa76c880be41d6b1e6a2b44404bcbfdf9eMatt Flemingint mmc_suspend_host(struct mmc_host *host) 22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 226895cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre int err = 0; 226995cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre 22707de427d088a967d2173739e21e744921d5496a8bJorg Schummer cancel_delayed_work(&host->detect); 2271b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman mmc_flush_scheduled_work(); 227217e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon if (mmc_try_claim_host(host)) { 227317e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon err = mmc_cache_ctrl(host, 0); 2274907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter mmc_release_host(host); 227517e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon } else { 227617e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon err = -EBUSY; 227717e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon } 227817e9ff559a7dbb7a6df332007d2ffcd3e7d83fbaSeungwon Jeon 2279881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon if (err) 2280881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeon goto out; 2281b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman 22827ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_get(host); 22837ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman if (host->bus_ops && !host->bus_dead) { 2284b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson 2285b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson /* 2286b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson * A long response time is not acceptable for device drivers 2287b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson * when doing suspend. Prevent mmc_claim_host in the suspend 2288b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson * sequence, to potentially wait "forever" by trying to 2289b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson * pre-claim the host. 2290b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson */ 2291b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson if (mmc_try_claim_host(host)) { 2292a80f16276388a177199204aa5b60f328d4464110Girish K S if (host->bus_ops->suspend) { 2293b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson err = host->bus_ops->suspend(host); 2294a80f16276388a177199204aa5b60f328d4464110Girish K S } 2295907d2e7cc7ebba4ab398422a7f0435e1802be65bAdrian Hunter mmc_release_host(host); 229649df78074963c97e25debc3c67b72f059111607dSujit Reddy Thumma 2297b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson if (err == -ENOSYS || !host->bus_ops->resume) { 2298b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson /* 2299b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson * We simply "remove" the card in this case. 23000db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski * It will be redetected on resume. (Calling 23010db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski * bus_ops->remove() with a claimed host can 23020db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski * deadlock.) 2303b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson */ 2304b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson if (host->bus_ops->remove) 2305b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson host->bus_ops->remove(host); 2306b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson mmc_claim_host(host); 2307b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson mmc_detach_bus(host); 2308b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson mmc_power_off(host); 2309b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson mmc_release_host(host); 2310b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson host->pm_flags = 0; 2311b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson err = 0; 2312b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson } 2313b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson } else { 2314b6ad726e3fe69e1ff3c3b2ad272ba3e4c376cd6aUlf Hansson err = -EBUSY; 23151c8cf9c997a4a6b36e907c7ede5f048aeaab1644Ohad Ben-Cohen } 2316b5af25bee2de2f6cd1ac74ba737cbc4f3d303e5dPierre Ossman } 23177ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman mmc_bus_put(host); 23187ea239d9e6d6993469a6a8ca83ff23834dfc3fcePierre Ossman 2319a5e9425d2010978c5f85986cc70a9fa0c0d5b912Ohad Ben-Cohen if (!err && !mmc_card_keep_power(host)) 232095cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre mmc_power_off(host); 23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2322881d1c25f765938a95def5afe39486ce39f9fc96Seungwon Jeonout: 232395cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre return err; 23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_suspend_host); 23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mmc_resume_host - resume a previously suspended host 23301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @host: mmc host 23311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mmc_resume_host(struct mmc_host *host) 23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 233495cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre int err = 0; 233595cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre 23366abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman mmc_bus_get(host); 23376abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman if (host->bus_ops && !host->bus_dead) { 2338a5e9425d2010978c5f85986cc70a9fa0c0d5b912Ohad Ben-Cohen if (!mmc_card_keep_power(host)) { 2339da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre mmc_power_up(host); 2340da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre mmc_select_voltage(host, host->ocr); 2341e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen /* 2342e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * Tell runtime PM core we just powered up the card, 2343e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * since it still believes the card is powered off. 2344e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * Note that currently runtime PM is only enabled 2345e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen * for SDIO cards that are MMC_CAP_POWER_OFF_CARD 2346e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen */ 2347e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen if (mmc_card_sdio(host->card) && 2348e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen (host->caps & MMC_CAP_POWER_OFF_CARD)) { 2349e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_disable(&host->card->dev); 2350e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_set_active(&host->card->dev); 2351e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen pm_runtime_enable(&host->card->dev); 2352e594573d790bd7e269f05955d316b88f7be0c14aOhad Ben-Cohen } 2353da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6Nicolas Pitre } 23546abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman BUG_ON(!host->bus_ops->resume); 235595cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre err = host->bus_ops->resume(host); 235695cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre if (err) { 2357a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993Girish K S pr_warning("%s: error %d during resume " 235895cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre "(card was removed?)\n", 235995cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre mmc_hostname(host), err); 236095cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre err = 0; 236195cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre } 23626abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman } 2363a8e6df7343cf67c9104955da0de70075a6ee1dfdEliad Peller host->pm_flags &= ~MMC_PM_KEEP_POWER; 23646abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman mmc_bus_put(host); 23656abaa0c9fec563538f2a28a682af8c89bb9b125cPierre Ossman 236695cdfb72b9bc568803f395c266152c71b034b461Nicolas Pitre return err; 23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mmc_resume_host); 23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23704c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky/* Do the card removal on suspend if card is assumed removeable 23714c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky * Do that in pm notifier while userspace isn't yet frozen, so we will be able 23724c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky to sync the card. 23734c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky*/ 23744c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitskyint mmc_pm_notify(struct notifier_block *notify_block, 23754c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky unsigned long mode, void *unused) 23764c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky{ 23774c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky struct mmc_host *host = container_of( 23784c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky notify_block, struct mmc_host, pm_notify); 23794c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky unsigned long flags; 23804c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23814c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23824c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky switch (mode) { 23834c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_HIBERNATION_PREPARE: 23844c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_SUSPEND_PREPARE: 23854c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23864c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_lock_irqsave(&host->lock, flags); 23874c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->rescan_disable = 1; 2388bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT; 23894c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_unlock_irqrestore(&host->lock, flags); 23904c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky cancel_delayed_work_sync(&host->detect); 23914c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23924c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky if (!host->bus_ops || host->bus_ops->suspend) 23934c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky break; 23944c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23950db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski /* Calling bus_ops->remove() with a claimed host can deadlock */ 23964c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky if (host->bus_ops->remove) 23974c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->bus_ops->remove(host); 23984c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 23990db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022Guennadi Liakhovetski mmc_claim_host(host); 24004c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_detach_bus(host); 24017f7e4129c23f0419257184dff6fec89d2d5a8964Ulf Hansson mmc_power_off(host); 24024c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_release_host(host); 24034c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->pm_flags = 0; 24044c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky break; 24054c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24064c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_POST_SUSPEND: 24074c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky case PM_POST_HIBERNATION: 2408274476f8fe0b6ac9bac542cc39de12c3dd0f43f6Takashi Iwai case PM_POST_RESTORE: 24094c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24104c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_lock_irqsave(&host->lock, flags); 24114c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->rescan_disable = 0; 2412bec8726abc72bf30d2743a722aa37cd69e7a0580Girish K S host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG; 24134c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky spin_unlock_irqrestore(&host->lock, flags); 24144c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky mmc_detect_change(host, 0); 24154c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24164c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky } 24174c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky 24184c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky return 0; 24194c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky} 24201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 24211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2422e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat#ifdef CONFIG_MMC_EMBEDDED_SDIO 2423e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehatvoid mmc_set_embedded_sdio_data(struct mmc_host *host, 2424e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_cis *cis, 2425e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_cccr *cccr, 2426e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat struct sdio_embedded_func *funcs, 2427e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat int num_funcs) 2428e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat{ 2429e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.cis = cis; 2430e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.cccr = cccr; 2431e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.funcs = funcs; 2432e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat host->embedded_sdio_data.num_funcs = num_funcs; 2433e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat} 2434e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat 2435e01587a794fa2ee14d3559a7d919af7e386a03e4San MehatEXPORT_SYMBOL(mmc_set_embedded_sdio_data); 2436e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat#endif 2437e01587a794fa2ee14d3559a7d919af7e386a03e4San Mehat 2438ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic int __init mmc_init(void) 2439ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 2440ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman int ret; 2441ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 24420d9ee5b2e9aac981fa063339daf04320eac610d1Tejun Heo workqueue = alloc_ordered_workqueue("kmmcd", 0); 2443ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman if (!workqueue) 2444ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return -ENOMEM; 2445ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 2446ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman ret = mmc_register_bus(); 2447e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2448e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto destroy_workqueue; 2449e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2450e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman ret = mmc_register_host_class(); 2451e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2452e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto unregister_bus; 2453e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2454e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman ret = sdio_register_bus(); 2455e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman if (ret) 2456e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman goto unregister_host_class; 2457e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2458e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman return 0; 2459e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2460e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanunregister_host_class: 2461e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman mmc_unregister_host_class(); 2462e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmanunregister_bus: 2463e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman mmc_unregister_bus(); 2464e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossmandestroy_workqueue: 2465e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman destroy_workqueue(workqueue); 2466e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman 2467ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman return ret; 2468ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 2469ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 2470ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanstatic void __exit mmc_exit(void) 2471ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman{ 2472e29a7d73f4277eb92aa64e17017dea33460828efPierre Ossman sdio_unregister_bus(); 2473ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman mmc_unregister_host_class(); 2474ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman mmc_unregister_bus(); 2475ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman destroy_workqueue(workqueue); 2476ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman} 2477ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 247826074962e8f547b96614dbe248748ba2a1996ca3Nicolas Pitresubsys_initcall(mmc_init); 2479ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossmanmodule_exit(mmc_exit); 2480ffce2e7e7060c949ccd703dacc9b3dd81b377373Pierre Ossman 24811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2482