12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 25c4e6f13SPierre Ossman /* 35c4e6f13SPierre Ossman * linux/drivers/mmc/sdio.c 45c4e6f13SPierre Ossman * 55c4e6f13SPierre Ossman * Copyright 2006-2007 Pierre Ossman 65c4e6f13SPierre Ossman */ 75c4e6f13SPierre Ossman 85c4e6f13SPierre Ossman #include <linux/err.h> 981968561SOhad Ben-Cohen #include <linux/pm_runtime.h> 105c4e6f13SPierre Ossman 115c4e6f13SPierre Ossman #include <linux/mmc/host.h> 125c4e6f13SPierre Ossman #include <linux/mmc/card.h> 13a4924c71SGirish K S #include <linux/mmc/mmc.h> 1435c66c19SPierre Ossman #include <linux/mmc/sdio.h> 15e29a7d73SPierre Ossman #include <linux/mmc/sdio_func.h> 16eab40687SOhad Ben-Cohen #include <linux/mmc/sdio_ids.h> 175c4e6f13SPierre Ossman 185c4e6f13SPierre Ossman #include "core.h" 194facdde1SUlf Hansson #include "card.h" 205857b29bSUlf Hansson #include "host.h" 215c4e6f13SPierre Ossman #include "bus.h" 2228fc64afSShawn Lin #include "quirks.h" 2371578a1eSMichal Miroslaw #include "sd.h" 24e29a7d73SPierre Ossman #include "sdio_bus.h" 255c4e6f13SPierre Ossman #include "mmc_ops.h" 265c4e6f13SPierre Ossman #include "sd_ops.h" 275c4e6f13SPierre Ossman #include "sdio_ops.h" 28b7261261SNicolas Pitre #include "sdio_cis.h" 295c4e6f13SPierre Ossman 30254e1754SPali Rohár MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor); 31254e1754SPali Rohár MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device); 32254e1754SPali Rohár MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr); 33254e1754SPali Rohár MMC_DEV_ATTR(rca, "0x%04x\n", card->rca); 34254e1754SPali Rohár 35254e1754SPali Rohár static struct attribute *sdio_std_attrs[] = { 36254e1754SPali Rohár &dev_attr_vendor.attr, 37254e1754SPali Rohár &dev_attr_device.attr, 38254e1754SPali Rohár &dev_attr_ocr.attr, 39254e1754SPali Rohár &dev_attr_rca.attr, 40254e1754SPali Rohár NULL, 41254e1754SPali Rohár }; 42254e1754SPali Rohár ATTRIBUTE_GROUPS(sdio_std); 43254e1754SPali Rohár 44254e1754SPali Rohár static struct device_type sdio_type = { 45254e1754SPali Rohár .groups = sdio_std_groups, 46254e1754SPali Rohár }; 47254e1754SPali Rohár 480597007fSPierre Ossman static int sdio_read_fbr(struct sdio_func *func) 490597007fSPierre Ossman { 500597007fSPierre Ossman int ret; 510597007fSPierre Ossman unsigned char data; 520597007fSPierre Ossman 53eab40687SOhad Ben-Cohen if (mmc_card_nonstd_func_interface(func->card)) { 54eab40687SOhad Ben-Cohen func->class = SDIO_CLASS_NONE; 55eab40687SOhad Ben-Cohen return 0; 56eab40687SOhad Ben-Cohen } 57eab40687SOhad Ben-Cohen 580597007fSPierre Ossman ret = mmc_io_rw_direct(func->card, 0, 0, 597616ee95SDavid Vrabel SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); 600597007fSPierre Ossman if (ret) 610597007fSPierre Ossman goto out; 620597007fSPierre Ossman 630597007fSPierre Ossman data &= 0x0f; 640597007fSPierre Ossman 650597007fSPierre Ossman if (data == 0x0f) { 660597007fSPierre Ossman ret = mmc_io_rw_direct(func->card, 0, 0, 677616ee95SDavid Vrabel SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); 680597007fSPierre Ossman if (ret) 690597007fSPierre Ossman goto out; 700597007fSPierre Ossman } 710597007fSPierre Ossman 720597007fSPierre Ossman func->class = data; 730597007fSPierre Ossman 740597007fSPierre Ossman out: 750597007fSPierre Ossman return ret; 760597007fSPierre Ossman } 770597007fSPierre Ossman 78e29a7d73SPierre Ossman static int sdio_init_func(struct mmc_card *card, unsigned int fn) 79e29a7d73SPierre Ossman { 800597007fSPierre Ossman int ret; 81e29a7d73SPierre Ossman struct sdio_func *func; 82e29a7d73SPierre Ossman 835df0e823SShawn Lin if (WARN_ON(fn > SDIO_MAX_FUNCS)) 845df0e823SShawn Lin return -EINVAL; 85e29a7d73SPierre Ossman 86e29a7d73SPierre Ossman func = sdio_alloc_func(card); 87e29a7d73SPierre Ossman if (IS_ERR(func)) 88e29a7d73SPierre Ossman return PTR_ERR(func); 89e29a7d73SPierre Ossman 90e29a7d73SPierre Ossman func->num = fn; 91e29a7d73SPierre Ossman 926f51be3dSGrazvydas Ignotas if (!(card->quirks & MMC_QUIRK_NONSTD_SDIO)) { 930597007fSPierre Ossman ret = sdio_read_fbr(func); 940597007fSPierre Ossman if (ret) 950597007fSPierre Ossman goto fail; 960597007fSPierre Ossman 971a632f8cSPierre Ossman ret = sdio_read_func_cis(func); 98b7261261SNicolas Pitre if (ret) 99b7261261SNicolas Pitre goto fail; 1006f51be3dSGrazvydas Ignotas } else { 1016f51be3dSGrazvydas Ignotas func->vendor = func->card->cis.vendor; 1026f51be3dSGrazvydas Ignotas func->device = func->card->cis.device; 1036f51be3dSGrazvydas Ignotas func->max_blksize = func->card->cis.blksize; 1046f51be3dSGrazvydas Ignotas } 105b7261261SNicolas Pitre 106e29a7d73SPierre Ossman card->sdio_func[fn - 1] = func; 107e29a7d73SPierre Ossman 108e29a7d73SPierre Ossman return 0; 1090597007fSPierre Ossman 1100597007fSPierre Ossman fail: 1110597007fSPierre Ossman /* 1120597007fSPierre Ossman * It is okay to remove the function here even though we hold 1130597007fSPierre Ossman * the host lock as we haven't registered the device yet. 1140597007fSPierre Ossman */ 1150597007fSPierre Ossman sdio_remove_func(func); 1160597007fSPierre Ossman return ret; 117e29a7d73SPierre Ossman } 118e29a7d73SPierre Ossman 1192d0d68f5SPhilip Rakity static int sdio_read_cccr(struct mmc_card *card, u32 ocr) 12035c66c19SPierre Ossman { 12135c66c19SPierre Ossman int ret; 12235c66c19SPierre Ossman int cccr_vsn; 1232d0d68f5SPhilip Rakity int uhs = ocr & R4_18V_PRESENT; 12435c66c19SPierre Ossman unsigned char data; 125a303c531SPhilip Rakity unsigned char speed; 12635c66c19SPierre Ossman 12735c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data); 12835c66c19SPierre Ossman if (ret) 12935c66c19SPierre Ossman goto out; 13035c66c19SPierre Ossman 13135c66c19SPierre Ossman cccr_vsn = data & 0x0f; 13235c66c19SPierre Ossman 133b4625dabSBing Zhao if (cccr_vsn > SDIO_CCCR_REV_3_00) { 134a3c76eb9SGirish K S pr_err("%s: unrecognised CCCR structure version %d\n", 13535c66c19SPierre Ossman mmc_hostname(card->host), cccr_vsn); 13635c66c19SPierre Ossman return -EINVAL; 13735c66c19SPierre Ossman } 13835c66c19SPierre Ossman 13935c66c19SPierre Ossman card->cccr.sdio_vsn = (data & 0xf0) >> 4; 14035c66c19SPierre Ossman 14135c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data); 14235c66c19SPierre Ossman if (ret) 14335c66c19SPierre Ossman goto out; 14435c66c19SPierre Ossman 14535c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_SMB) 14635c66c19SPierre Ossman card->cccr.multi_block = 1; 14735c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_LSC) 14835c66c19SPierre Ossman card->cccr.low_speed = 1; 14935c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_4BLS) 15035c66c19SPierre Ossman card->cccr.wide_bus = 1; 15135c66c19SPierre Ossman 15235c66c19SPierre Ossman if (cccr_vsn >= SDIO_CCCR_REV_1_10) { 15335c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data); 15435c66c19SPierre Ossman if (ret) 15535c66c19SPierre Ossman goto out; 15635c66c19SPierre Ossman 15735c66c19SPierre Ossman if (data & SDIO_POWER_SMPC) 15835c66c19SPierre Ossman card->cccr.high_power = 1; 15935c66c19SPierre Ossman } 16035c66c19SPierre Ossman 16135c66c19SPierre Ossman if (cccr_vsn >= SDIO_CCCR_REV_1_20) { 162a303c531SPhilip Rakity ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 16335c66c19SPierre Ossman if (ret) 16435c66c19SPierre Ossman goto out; 16535c66c19SPierre Ossman 166a303c531SPhilip Rakity card->scr.sda_spec3 = 0; 167a303c531SPhilip Rakity card->sw_caps.sd3_bus_mode = 0; 168a303c531SPhilip Rakity card->sw_caps.sd3_drv_type = 0; 1692d0d68f5SPhilip Rakity if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) { 170a303c531SPhilip Rakity card->scr.sda_spec3 = 1; 171a303c531SPhilip Rakity ret = mmc_io_rw_direct(card, 0, 0, 172a303c531SPhilip Rakity SDIO_CCCR_UHS, 0, &data); 173a303c531SPhilip Rakity if (ret) 174a303c531SPhilip Rakity goto out; 175a303c531SPhilip Rakity 17641875e38SSujit Reddy Thumma if (mmc_host_uhs(card->host)) { 177a303c531SPhilip Rakity if (data & SDIO_UHS_DDR50) 178a303c531SPhilip Rakity card->sw_caps.sd3_bus_mode 179*e8151555SHaibo Chen |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50 180*e8151555SHaibo Chen | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; 181a303c531SPhilip Rakity 182a303c531SPhilip Rakity if (data & SDIO_UHS_SDR50) 183a303c531SPhilip Rakity card->sw_caps.sd3_bus_mode 184*e8151555SHaibo Chen |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 185*e8151555SHaibo Chen | SD_MODE_UHS_SDR12; 186a303c531SPhilip Rakity 187a303c531SPhilip Rakity if (data & SDIO_UHS_SDR104) 188a303c531SPhilip Rakity card->sw_caps.sd3_bus_mode 189*e8151555SHaibo Chen |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50 190*e8151555SHaibo Chen | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; 191a303c531SPhilip Rakity } 192a303c531SPhilip Rakity 193a303c531SPhilip Rakity ret = mmc_io_rw_direct(card, 0, 0, 194a303c531SPhilip Rakity SDIO_CCCR_DRIVE_STRENGTH, 0, &data); 195a303c531SPhilip Rakity if (ret) 196a303c531SPhilip Rakity goto out; 197a303c531SPhilip Rakity 198a303c531SPhilip Rakity if (data & SDIO_DRIVE_SDTA) 199a303c531SPhilip Rakity card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A; 200a303c531SPhilip Rakity if (data & SDIO_DRIVE_SDTC) 201a303c531SPhilip Rakity card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C; 202a303c531SPhilip Rakity if (data & SDIO_DRIVE_SDTD) 203a303c531SPhilip Rakity card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D; 204a303c531SPhilip Rakity } 205a303c531SPhilip Rakity 206a303c531SPhilip Rakity /* if no uhs mode ensure we check for high speed */ 207a303c531SPhilip Rakity if (!card->sw_caps.sd3_bus_mode) { 208a303c531SPhilip Rakity if (speed & SDIO_SPEED_SHS) { 20935c66c19SPierre Ossman card->cccr.high_speed = 1; 210a303c531SPhilip Rakity card->sw_caps.hs_max_dtr = 50000000; 211a303c531SPhilip Rakity } else { 212a303c531SPhilip Rakity card->cccr.high_speed = 0; 213a303c531SPhilip Rakity card->sw_caps.hs_max_dtr = 25000000; 214a303c531SPhilip Rakity } 215a303c531SPhilip Rakity } 21635c66c19SPierre Ossman } 21735c66c19SPierre Ossman 21835c66c19SPierre Ossman out: 21935c66c19SPierre Ossman return ret; 22035c66c19SPierre Ossman } 22135c66c19SPierre Ossman 2224ff6471cSPierre Ossman static int sdio_enable_wide(struct mmc_card *card) 2234ff6471cSPierre Ossman { 2244ff6471cSPierre Ossman int ret; 2254ff6471cSPierre Ossman u8 ctrl; 2264ff6471cSPierre Ossman 2274ff6471cSPierre Ossman if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) 2284ff6471cSPierre Ossman return 0; 2294ff6471cSPierre Ossman 2304ff6471cSPierre Ossman if (card->cccr.low_speed && !card->cccr.wide_bus) 2314ff6471cSPierre Ossman return 0; 2324ff6471cSPierre Ossman 2334ff6471cSPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 2344ff6471cSPierre Ossman if (ret) 2354ff6471cSPierre Ossman return ret; 2364ff6471cSPierre Ossman 2372a0fe914SYong Ding if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) 2386606110dSJoe Perches pr_warn("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", 2392a0fe914SYong Ding mmc_hostname(card->host), ctrl); 2402a0fe914SYong Ding 2412a0fe914SYong Ding /* set as 4-bit bus width */ 2422a0fe914SYong Ding ctrl &= ~SDIO_BUS_WIDTH_MASK; 2434ff6471cSPierre Ossman ctrl |= SDIO_BUS_WIDTH_4BIT; 2444ff6471cSPierre Ossman 2454ff6471cSPierre Ossman ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 2464ff6471cSPierre Ossman if (ret) 2474ff6471cSPierre Ossman return ret; 2484ff6471cSPierre Ossman 2497310ece8SMichal Miroslaw return 1; 2504ff6471cSPierre Ossman } 2514ff6471cSPierre Ossman 2525c4e6f13SPierre Ossman /* 253006ebd5dSOhad Ben-Cohen * If desired, disconnect the pull-up resistor on CD/DAT[3] (pin 1) 254006ebd5dSOhad Ben-Cohen * of the card. This may be required on certain setups of boards, 255006ebd5dSOhad Ben-Cohen * controllers and embedded sdio device which do not need the card's 256006ebd5dSOhad Ben-Cohen * pull-up. As a result, card detection is disabled and power is saved. 257006ebd5dSOhad Ben-Cohen */ 258006ebd5dSOhad Ben-Cohen static int sdio_disable_cd(struct mmc_card *card) 259006ebd5dSOhad Ben-Cohen { 260006ebd5dSOhad Ben-Cohen int ret; 261006ebd5dSOhad Ben-Cohen u8 ctrl; 262006ebd5dSOhad Ben-Cohen 2632059a02dSOhad Ben-Cohen if (!mmc_card_disable_cd(card)) 264006ebd5dSOhad Ben-Cohen return 0; 265006ebd5dSOhad Ben-Cohen 266006ebd5dSOhad Ben-Cohen ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 267006ebd5dSOhad Ben-Cohen if (ret) 268006ebd5dSOhad Ben-Cohen return ret; 269006ebd5dSOhad Ben-Cohen 270006ebd5dSOhad Ben-Cohen ctrl |= SDIO_BUS_CD_DISABLE; 271006ebd5dSOhad Ben-Cohen 272006ebd5dSOhad Ben-Cohen return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 273006ebd5dSOhad Ben-Cohen } 274006ebd5dSOhad Ben-Cohen 275006ebd5dSOhad Ben-Cohen /* 2766b5eda36SDaniel Drake * Devices that remain active during a system suspend are 2776b5eda36SDaniel Drake * put back into 1-bit mode. 2786b5eda36SDaniel Drake */ 2796b5eda36SDaniel Drake static int sdio_disable_wide(struct mmc_card *card) 2806b5eda36SDaniel Drake { 2816b5eda36SDaniel Drake int ret; 2826b5eda36SDaniel Drake u8 ctrl; 2836b5eda36SDaniel Drake 2846b5eda36SDaniel Drake if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) 2856b5eda36SDaniel Drake return 0; 2866b5eda36SDaniel Drake 2876b5eda36SDaniel Drake if (card->cccr.low_speed && !card->cccr.wide_bus) 2886b5eda36SDaniel Drake return 0; 2896b5eda36SDaniel Drake 2906b5eda36SDaniel Drake ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 2916b5eda36SDaniel Drake if (ret) 2926b5eda36SDaniel Drake return ret; 2936b5eda36SDaniel Drake 2946b5eda36SDaniel Drake if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) 2956b5eda36SDaniel Drake return 0; 2966b5eda36SDaniel Drake 2976b5eda36SDaniel Drake ctrl &= ~SDIO_BUS_WIDTH_4BIT; 2986b5eda36SDaniel Drake ctrl |= SDIO_BUS_ASYNC_INT; 2996b5eda36SDaniel Drake 3006b5eda36SDaniel Drake ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 3016b5eda36SDaniel Drake if (ret) 3026b5eda36SDaniel Drake return ret; 3036b5eda36SDaniel Drake 3046b5eda36SDaniel Drake mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); 3056b5eda36SDaniel Drake 3066b5eda36SDaniel Drake return 0; 3076b5eda36SDaniel Drake } 3086b5eda36SDaniel Drake 30940e6c479SYue Hu static int sdio_disable_4bit_bus(struct mmc_card *card) 31040e6c479SYue Hu { 31140e6c479SYue Hu int err; 31240e6c479SYue Hu 31340e6c479SYue Hu if (card->type == MMC_TYPE_SDIO) 31440e6c479SYue Hu goto out; 31540e6c479SYue Hu 31640e6c479SYue Hu if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) 31740e6c479SYue Hu return 0; 31840e6c479SYue Hu 31940e6c479SYue Hu if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) 32040e6c479SYue Hu return 0; 32140e6c479SYue Hu 32240e6c479SYue Hu err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); 32340e6c479SYue Hu if (err) 32440e6c479SYue Hu return err; 32540e6c479SYue Hu 32640e6c479SYue Hu out: 32740e6c479SYue Hu return sdio_disable_wide(card); 32840e6c479SYue Hu } 32940e6c479SYue Hu 3307310ece8SMichal Miroslaw 3317310ece8SMichal Miroslaw static int sdio_enable_4bit_bus(struct mmc_card *card) 3327310ece8SMichal Miroslaw { 3337310ece8SMichal Miroslaw int err; 3347310ece8SMichal Miroslaw 3357310ece8SMichal Miroslaw err = sdio_enable_wide(card); 3367310ece8SMichal Miroslaw if (err <= 0) 3377310ece8SMichal Miroslaw return err; 338ec97863cSYue Hu if (card->type == MMC_TYPE_SDIO) 339ec97863cSYue Hu goto out; 340ec97863cSYue Hu 341ec97863cSYue Hu if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) { 342ec97863cSYue Hu err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); 343ec97863cSYue Hu if (err) { 344ec97863cSYue Hu sdio_disable_wide(card); 345ec97863cSYue Hu return err; 346ec97863cSYue Hu } 347ec97863cSYue Hu } 348ec97863cSYue Hu out: 349ec97863cSYue Hu mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); 350ec97863cSYue Hu 351ec97863cSYue Hu return 0; 3527310ece8SMichal Miroslaw } 3537310ece8SMichal Miroslaw 3547310ece8SMichal Miroslaw 3556b5eda36SDaniel Drake /* 356d16f5770SPierre Ossman * Test if the card supports high-speed mode and, if so, switch to it. 357d16f5770SPierre Ossman */ 3587310ece8SMichal Miroslaw static int mmc_sdio_switch_hs(struct mmc_card *card, int enable) 359d16f5770SPierre Ossman { 360d16f5770SPierre Ossman int ret; 361d16f5770SPierre Ossman u8 speed; 362d16f5770SPierre Ossman 363d16f5770SPierre Ossman if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) 364d16f5770SPierre Ossman return 0; 365d16f5770SPierre Ossman 366d16f5770SPierre Ossman if (!card->cccr.high_speed) 367d16f5770SPierre Ossman return 0; 368d16f5770SPierre Ossman 369d16f5770SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 370d16f5770SPierre Ossman if (ret) 371d16f5770SPierre Ossman return ret; 372d16f5770SPierre Ossman 3737310ece8SMichal Miroslaw if (enable) 374d16f5770SPierre Ossman speed |= SDIO_SPEED_EHS; 3757310ece8SMichal Miroslaw else 3767310ece8SMichal Miroslaw speed &= ~SDIO_SPEED_EHS; 377d16f5770SPierre Ossman 378d16f5770SPierre Ossman ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); 379d16f5770SPierre Ossman if (ret) 380d16f5770SPierre Ossman return ret; 381d16f5770SPierre Ossman 38271578a1eSMichal Miroslaw return 1; 38371578a1eSMichal Miroslaw } 384d16f5770SPierre Ossman 3857310ece8SMichal Miroslaw /* 3867310ece8SMichal Miroslaw * Enable SDIO/combo card's high-speed mode. Return 0/1 if [not]supported. 3877310ece8SMichal Miroslaw */ 3887310ece8SMichal Miroslaw static int sdio_enable_hs(struct mmc_card *card) 3897310ece8SMichal Miroslaw { 3907310ece8SMichal Miroslaw int ret; 3917310ece8SMichal Miroslaw 3927310ece8SMichal Miroslaw ret = mmc_sdio_switch_hs(card, true); 3937310ece8SMichal Miroslaw if (ret <= 0 || card->type == MMC_TYPE_SDIO) 3947310ece8SMichal Miroslaw return ret; 3957310ece8SMichal Miroslaw 3967310ece8SMichal Miroslaw ret = mmc_sd_switch_hs(card); 3977310ece8SMichal Miroslaw if (ret <= 0) 3987310ece8SMichal Miroslaw mmc_sdio_switch_hs(card, false); 3997310ece8SMichal Miroslaw 4007310ece8SMichal Miroslaw return ret; 4017310ece8SMichal Miroslaw } 4027310ece8SMichal Miroslaw 40371578a1eSMichal Miroslaw static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) 40471578a1eSMichal Miroslaw { 40571578a1eSMichal Miroslaw unsigned max_dtr; 40671578a1eSMichal Miroslaw 407cdc99179SSeungwon Jeon if (mmc_card_hs(card)) { 40871578a1eSMichal Miroslaw /* 40971578a1eSMichal Miroslaw * The SDIO specification doesn't mention how 41071578a1eSMichal Miroslaw * the CIS transfer speed register relates to 41171578a1eSMichal Miroslaw * high-speed, but it seems that 50 MHz is 41271578a1eSMichal Miroslaw * mandatory. 41371578a1eSMichal Miroslaw */ 41471578a1eSMichal Miroslaw max_dtr = 50000000; 41571578a1eSMichal Miroslaw } else { 41671578a1eSMichal Miroslaw max_dtr = card->cis.max_dtr; 41771578a1eSMichal Miroslaw } 41871578a1eSMichal Miroslaw 4197310ece8SMichal Miroslaw if (card->type == MMC_TYPE_SD_COMBO) 4207310ece8SMichal Miroslaw max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); 4217310ece8SMichal Miroslaw 42271578a1eSMichal Miroslaw return max_dtr; 423d16f5770SPierre Ossman } 424d16f5770SPierre Ossman 425a303c531SPhilip Rakity static unsigned char host_drive_to_sdio_drive(int host_strength) 426a303c531SPhilip Rakity { 427a303c531SPhilip Rakity switch (host_strength) { 428a303c531SPhilip Rakity case MMC_SET_DRIVER_TYPE_A: 429a303c531SPhilip Rakity return SDIO_DTSx_SET_TYPE_A; 430a303c531SPhilip Rakity case MMC_SET_DRIVER_TYPE_B: 431a303c531SPhilip Rakity return SDIO_DTSx_SET_TYPE_B; 432a303c531SPhilip Rakity case MMC_SET_DRIVER_TYPE_C: 433a303c531SPhilip Rakity return SDIO_DTSx_SET_TYPE_C; 434a303c531SPhilip Rakity case MMC_SET_DRIVER_TYPE_D: 435a303c531SPhilip Rakity return SDIO_DTSx_SET_TYPE_D; 436a303c531SPhilip Rakity default: 437a303c531SPhilip Rakity return SDIO_DTSx_SET_TYPE_B; 438a303c531SPhilip Rakity } 439a303c531SPhilip Rakity } 440a303c531SPhilip Rakity 441a303c531SPhilip Rakity static void sdio_select_driver_type(struct mmc_card *card) 442a303c531SPhilip Rakity { 443fa021cefSAdrian Hunter int card_drv_type, drive_strength, drv_type; 444a303c531SPhilip Rakity unsigned char card_strength; 445a303c531SPhilip Rakity int err; 446a303c531SPhilip Rakity 4473853a042SAdrian Hunter card->drive_strength = 0; 4483853a042SAdrian Hunter 449fa021cefSAdrian Hunter card_drv_type = card->sw_caps.sd3_drv_type | SD_DRIVER_TYPE_B; 450a303c531SPhilip Rakity 451e23350b3SAdrian Hunter drive_strength = mmc_select_drive_strength(card, 452a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr, 453e23350b3SAdrian Hunter card_drv_type, &drv_type); 454a303c531SPhilip Rakity 455b4f30a17SAdrian Hunter if (drive_strength) { 456a303c531SPhilip Rakity /* if error just use default for drive strength B */ 457a303c531SPhilip Rakity err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, 458a303c531SPhilip Rakity &card_strength); 459a303c531SPhilip Rakity if (err) 460a303c531SPhilip Rakity return; 461a303c531SPhilip Rakity 462a303c531SPhilip Rakity card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT); 463a303c531SPhilip Rakity card_strength |= host_drive_to_sdio_drive(drive_strength); 464a303c531SPhilip Rakity 465b4f30a17SAdrian Hunter /* if error default to drive strength B */ 466a303c531SPhilip Rakity err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH, 467a303c531SPhilip Rakity card_strength, NULL); 468b4f30a17SAdrian Hunter if (err) 469b4f30a17SAdrian Hunter return; 4703853a042SAdrian Hunter card->drive_strength = drive_strength; 471b4f30a17SAdrian Hunter } 472a303c531SPhilip Rakity 473b4f30a17SAdrian Hunter if (drv_type) 474b4f30a17SAdrian Hunter mmc_set_driver_type(card->host, drv_type); 475a303c531SPhilip Rakity } 476a303c531SPhilip Rakity 477a303c531SPhilip Rakity 478a303c531SPhilip Rakity static int sdio_set_bus_speed_mode(struct mmc_card *card) 479a303c531SPhilip Rakity { 480a303c531SPhilip Rakity unsigned int bus_speed, timing; 481a303c531SPhilip Rakity int err; 482a303c531SPhilip Rakity unsigned char speed; 483ebc5a1bfSharish_kandiga@mentor.com unsigned int max_rate; 484a303c531SPhilip Rakity 485a303c531SPhilip Rakity /* 486a303c531SPhilip Rakity * If the host doesn't support any of the UHS-I modes, fallback on 487a303c531SPhilip Rakity * default speed. 488a303c531SPhilip Rakity */ 48941875e38SSujit Reddy Thumma if (!mmc_host_uhs(card->host)) 490a303c531SPhilip Rakity return 0; 491a303c531SPhilip Rakity 492a303c531SPhilip Rakity bus_speed = SDIO_SPEED_SDR12; 493a303c531SPhilip Rakity timing = MMC_TIMING_UHS_SDR12; 494a303c531SPhilip Rakity if ((card->host->caps & MMC_CAP_UHS_SDR104) && 495a303c531SPhilip Rakity (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { 496a303c531SPhilip Rakity bus_speed = SDIO_SPEED_SDR104; 497a303c531SPhilip Rakity timing = MMC_TIMING_UHS_SDR104; 498a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; 49977e2ff08SSubhash Jadavani card->sd_bus_speed = UHS_SDR104_BUS_SPEED; 500a303c531SPhilip Rakity } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && 501a303c531SPhilip Rakity (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { 502a303c531SPhilip Rakity bus_speed = SDIO_SPEED_DDR50; 503a303c531SPhilip Rakity timing = MMC_TIMING_UHS_DDR50; 504a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; 50577e2ff08SSubhash Jadavani card->sd_bus_speed = UHS_DDR50_BUS_SPEED; 506a303c531SPhilip Rakity } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | 507a303c531SPhilip Rakity MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & 508a303c531SPhilip Rakity SD_MODE_UHS_SDR50)) { 509a303c531SPhilip Rakity bus_speed = SDIO_SPEED_SDR50; 510a303c531SPhilip Rakity timing = MMC_TIMING_UHS_SDR50; 511a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; 51277e2ff08SSubhash Jadavani card->sd_bus_speed = UHS_SDR50_BUS_SPEED; 513a303c531SPhilip Rakity } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | 514a303c531SPhilip Rakity MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && 515a303c531SPhilip Rakity (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { 516a303c531SPhilip Rakity bus_speed = SDIO_SPEED_SDR25; 517a303c531SPhilip Rakity timing = MMC_TIMING_UHS_SDR25; 518a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; 51977e2ff08SSubhash Jadavani card->sd_bus_speed = UHS_SDR25_BUS_SPEED; 520a303c531SPhilip Rakity } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | 521a303c531SPhilip Rakity MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | 522a303c531SPhilip Rakity MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & 523a303c531SPhilip Rakity SD_MODE_UHS_SDR12)) { 524a303c531SPhilip Rakity bus_speed = SDIO_SPEED_SDR12; 525a303c531SPhilip Rakity timing = MMC_TIMING_UHS_SDR12; 526a303c531SPhilip Rakity card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; 52777e2ff08SSubhash Jadavani card->sd_bus_speed = UHS_SDR12_BUS_SPEED; 528a303c531SPhilip Rakity } 529a303c531SPhilip Rakity 530a303c531SPhilip Rakity err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 531a303c531SPhilip Rakity if (err) 532a303c531SPhilip Rakity return err; 533a303c531SPhilip Rakity 534a303c531SPhilip Rakity speed &= ~SDIO_SPEED_BSS_MASK; 535a303c531SPhilip Rakity speed |= bus_speed; 536a303c531SPhilip Rakity err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); 537a303c531SPhilip Rakity if (err) 538a303c531SPhilip Rakity return err; 539a303c531SPhilip Rakity 540ebc5a1bfSharish_kandiga@mentor.com max_rate = min_not_zero(card->quirk_max_rate, 541ebc5a1bfSharish_kandiga@mentor.com card->sw_caps.uhs_max_dtr); 542ebc5a1bfSharish_kandiga@mentor.com 543a303c531SPhilip Rakity mmc_set_timing(card->host, timing); 544ebc5a1bfSharish_kandiga@mentor.com mmc_set_clock(card->host, max_rate); 545a303c531SPhilip Rakity 546a303c531SPhilip Rakity return 0; 547a303c531SPhilip Rakity } 548a303c531SPhilip Rakity 549a303c531SPhilip Rakity /* 550a303c531SPhilip Rakity * UHS-I specific initialization procedure 551a303c531SPhilip Rakity */ 552a303c531SPhilip Rakity static int mmc_sdio_init_uhs_card(struct mmc_card *card) 553a303c531SPhilip Rakity { 554a303c531SPhilip Rakity int err; 555a303c531SPhilip Rakity 556a303c531SPhilip Rakity if (!card->scr.sda_spec3) 557a303c531SPhilip Rakity return 0; 558a303c531SPhilip Rakity 5591e178270SShawn Lin /* Switch to wider bus */ 560a303c531SPhilip Rakity err = sdio_enable_4bit_bus(card); 5611e178270SShawn Lin if (err) 5621e178270SShawn Lin goto out; 563a303c531SPhilip Rakity 564a303c531SPhilip Rakity /* Set the driver strength for the card */ 565a303c531SPhilip Rakity sdio_select_driver_type(card); 566a303c531SPhilip Rakity 567a303c531SPhilip Rakity /* Set bus speed mode of the card */ 568a303c531SPhilip Rakity err = sdio_set_bus_speed_mode(card); 569a303c531SPhilip Rakity if (err) 570a303c531SPhilip Rakity goto out; 571a303c531SPhilip Rakity 572810e08eeSFredrik Soderstedt /* 573810e08eeSFredrik Soderstedt * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and 574810e08eeSFredrik Soderstedt * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. 575810e08eeSFredrik Soderstedt */ 57663e415c6SAdrian Hunter if (!mmc_host_is_spi(card->host) && 577e10c3219SCarlo Caione ((card->host->ios.timing == MMC_TIMING_UHS_SDR50) || 578e10c3219SCarlo Caione (card->host->ios.timing == MMC_TIMING_UHS_SDR104))) 57963e415c6SAdrian Hunter err = mmc_execute_tuning(card); 580a303c531SPhilip Rakity out: 581a303c531SPhilip Rakity return err; 582a303c531SPhilip Rakity } 583a303c531SPhilip Rakity 5841dc5a615SUlf Hansson static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr, 5850eb51a58SShawn Lin struct mmc_card *card) 5860eb51a58SShawn Lin { 5871dc5a615SUlf Hansson if (card) 5881dc5a615SUlf Hansson mmc_remove_card(card); 5891dc5a615SUlf Hansson 5901dc5a615SUlf Hansson /* 5911dc5a615SUlf Hansson * Reset the card by performing the same steps that are taken by 5921dc5a615SUlf Hansson * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. 5931dc5a615SUlf Hansson * 5941dc5a615SUlf Hansson * sdio_reset() is technically not needed. Having just powered up the 5951dc5a615SUlf Hansson * hardware, it should already be in reset state. However, some 5961dc5a615SUlf Hansson * platforms (such as SD8686 on OLPC) do not instantly cut power, 5971dc5a615SUlf Hansson * meaning that a reset is required when restoring power soon after 5981dc5a615SUlf Hansson * powering off. It is harmless in other cases. 5991dc5a615SUlf Hansson * 6001dc5a615SUlf Hansson * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, 6011dc5a615SUlf Hansson * is not necessary for non-removable cards. However, it is required 6021dc5a615SUlf Hansson * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and 6031dc5a615SUlf Hansson * harmless in other situations. 6041dc5a615SUlf Hansson * 6051dc5a615SUlf Hansson */ 6061dc5a615SUlf Hansson 6070eb51a58SShawn Lin sdio_reset(host); 6080eb51a58SShawn Lin mmc_go_idle(host); 609fa1e3191SUlf Hansson mmc_send_if_cond(host, ocr); 6101dc5a615SUlf Hansson return mmc_send_io_op_cond(host, 0, NULL); 6110eb51a58SShawn Lin } 6120eb51a58SShawn Lin 613d16f5770SPierre Ossman /* 61417d33e14SNicolas Pitre * Handle the detection and initialisation of a card. 61517d33e14SNicolas Pitre * 61617d33e14SNicolas Pitre * In the case of a resume, "oldcard" will contain the card 61717d33e14SNicolas Pitre * we're trying to reinitialise. 61817d33e14SNicolas Pitre */ 61917d33e14SNicolas Pitre static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, 6204aaaf3abSUlf Hansson struct mmc_card *oldcard) 62117d33e14SNicolas Pitre { 62217d33e14SNicolas Pitre struct mmc_card *card; 62317d33e14SNicolas Pitre int err; 6240797e5f1SJohan Rudholm int retries = 10; 625db4a0d05SUlf Hansson u32 rocr = 0; 62669041150SUlf Hansson u32 ocr_card = ocr; 62717d33e14SNicolas Pitre 62817d33e14SNicolas Pitre WARN_ON(!host->claimed); 62917d33e14SNicolas Pitre 630db4a0d05SUlf Hansson /* to query card if 1.8V signalling is supported */ 631db4a0d05SUlf Hansson if (mmc_host_uhs(host)) 632db4a0d05SUlf Hansson ocr |= R4_18V_PRESENT; 633db4a0d05SUlf Hansson 6340797e5f1SJohan Rudholm try_again: 6350797e5f1SJohan Rudholm if (!retries) { 6366606110dSJoe Perches pr_warn("%s: Skipping voltage switch\n", mmc_hostname(host)); 6370797e5f1SJohan Rudholm ocr &= ~R4_18V_PRESENT; 6380797e5f1SJohan Rudholm } 6390797e5f1SJohan Rudholm 64017d33e14SNicolas Pitre /* 64117d33e14SNicolas Pitre * Inform the card of the voltage 64217d33e14SNicolas Pitre */ 643db4a0d05SUlf Hansson err = mmc_send_io_op_cond(host, ocr, &rocr); 64417d33e14SNicolas Pitre if (err) 645a94a59f4SUlf Hansson return err; 64617d33e14SNicolas Pitre 64717d33e14SNicolas Pitre /* 64817d33e14SNicolas Pitre * For SPI, enable CRC as appropriate. 64917d33e14SNicolas Pitre */ 65017d33e14SNicolas Pitre if (mmc_host_is_spi(host)) { 65117d33e14SNicolas Pitre err = mmc_spi_set_crc(host, use_spi_crc); 65217d33e14SNicolas Pitre if (err) 653a94a59f4SUlf Hansson return err; 65417d33e14SNicolas Pitre } 65517d33e14SNicolas Pitre 65617d33e14SNicolas Pitre /* 65717d33e14SNicolas Pitre * Allocate card structure. 65817d33e14SNicolas Pitre */ 659254e1754SPali Rohár card = mmc_alloc_card(host, &sdio_type); 660a94a59f4SUlf Hansson if (IS_ERR(card)) 661a94a59f4SUlf Hansson return PTR_ERR(card); 66217d33e14SNicolas Pitre 663db4a0d05SUlf Hansson if ((rocr & R4_MEMORY_PRESENT) && 664db4a0d05SUlf Hansson mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) { 6657310ece8SMichal Miroslaw card->type = MMC_TYPE_SD_COMBO; 6667310ece8SMichal Miroslaw 6677310ece8SMichal Miroslaw if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || 6687310ece8SMichal Miroslaw memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) { 669a94a59f4SUlf Hansson err = -ENOENT; 670a94a59f4SUlf Hansson goto mismatch; 6717310ece8SMichal Miroslaw } 6727310ece8SMichal Miroslaw } else { 67317d33e14SNicolas Pitre card->type = MMC_TYPE_SDIO; 67417d33e14SNicolas Pitre 6757310ece8SMichal Miroslaw if (oldcard && oldcard->type != MMC_TYPE_SDIO) { 676a94a59f4SUlf Hansson err = -ENOENT; 677a94a59f4SUlf Hansson goto mismatch; 6787310ece8SMichal Miroslaw } 6797310ece8SMichal Miroslaw } 6807310ece8SMichal Miroslaw 68117d33e14SNicolas Pitre /* 6823fcb027dSDaniel Mack * Call the optional HC's init_card function to handle quirks. 6833fcb027dSDaniel Mack */ 6843fcb027dSDaniel Mack if (host->ops->init_card) 6853fcb027dSDaniel Mack host->ops->init_card(host, card); 6863fcb027dSDaniel Mack 6873fcb027dSDaniel Mack /* 688a303c531SPhilip Rakity * If the host and card support UHS-I mode request the card 689a303c531SPhilip Rakity * to switch to 1.8V signaling level. No 1.8v signalling if 6907122bbb0SMasanari Iida * UHS mode is not enabled to maintain compatibility and some 691a303c531SPhilip Rakity * systems that claim 1.8v signalling in fact do not support 6925fc3d80eSShawn Lin * it. Per SDIO spec v3, section 3.1.2, if the voltage is already 6935fc3d80eSShawn Lin * 1.8v, the card sets S18A to 0 in the R4 response. So it will 6945fc3d80eSShawn Lin * fails to check rocr & R4_18V_PRESENT, but we still need to 6955fc3d80eSShawn Lin * try to init uhs card. sdio_read_cccr will take over this task 6965fc3d80eSShawn Lin * to make sure which speed mode should work. 697a303c531SPhilip Rakity */ 6984aaaf3abSUlf Hansson if (rocr & ocr & R4_18V_PRESENT) { 6992ed573b6SUlf Hansson err = mmc_set_uhs_voltage(host, ocr_card); 7000797e5f1SJohan Rudholm if (err == -EAGAIN) { 7011dc5a615SUlf Hansson mmc_sdio_pre_init(host, ocr_card, card); 7020797e5f1SJohan Rudholm retries--; 7030797e5f1SJohan Rudholm goto try_again; 7040797e5f1SJohan Rudholm } else if (err) { 705a303c531SPhilip Rakity ocr &= ~R4_18V_PRESENT; 706a303c531SPhilip Rakity } 707a303c531SPhilip Rakity } 708a303c531SPhilip Rakity 709a303c531SPhilip Rakity /* 71017d33e14SNicolas Pitre * For native busses: set card RCA and quit open drain mode. 71117d33e14SNicolas Pitre */ 7124aaaf3abSUlf Hansson if (!mmc_host_is_spi(host)) { 71317d33e14SNicolas Pitre err = mmc_send_relative_addr(host, &card->rca); 71417d33e14SNicolas Pitre if (err) 71517d33e14SNicolas Pitre goto remove; 71617d33e14SNicolas Pitre 7170aab3995SStefan Nilsson XK /* 7180aab3995SStefan Nilsson XK * Update oldcard with the new RCA received from the SDIO 7190aab3995SStefan Nilsson XK * device -- we're doing this so that it's updated in the 7200aab3995SStefan Nilsson XK * "card" struct when oldcard overwrites that later. 7210aab3995SStefan Nilsson XK */ 7220aab3995SStefan Nilsson XK if (oldcard) 7230aab3995SStefan Nilsson XK oldcard->rca = card->rca; 72417d33e14SNicolas Pitre } 72517d33e14SNicolas Pitre 72617d33e14SNicolas Pitre /* 7277310ece8SMichal Miroslaw * Read CSD, before selecting the card 7287310ece8SMichal Miroslaw */ 7297310ece8SMichal Miroslaw if (!oldcard && card->type == MMC_TYPE_SD_COMBO) { 7307310ece8SMichal Miroslaw err = mmc_sd_get_csd(host, card); 7317310ece8SMichal Miroslaw if (err) 732a94a59f4SUlf Hansson goto remove; 7337310ece8SMichal Miroslaw 7347310ece8SMichal Miroslaw mmc_decode_cid(card); 7357310ece8SMichal Miroslaw } 7367310ece8SMichal Miroslaw 7377310ece8SMichal Miroslaw /* 73817d33e14SNicolas Pitre * Select card, as all following commands rely on that. 73917d33e14SNicolas Pitre */ 7404aaaf3abSUlf Hansson if (!mmc_host_is_spi(host)) { 74117d33e14SNicolas Pitre err = mmc_select_card(card); 74217d33e14SNicolas Pitre if (err) 74317d33e14SNicolas Pitre goto remove; 74417d33e14SNicolas Pitre } 74517d33e14SNicolas Pitre 7466f51be3dSGrazvydas Ignotas if (card->quirks & MMC_QUIRK_NONSTD_SDIO) { 7476f51be3dSGrazvydas Ignotas /* 7486f51be3dSGrazvydas Ignotas * This is non-standard SDIO device, meaning it doesn't 7496f51be3dSGrazvydas Ignotas * have any CIA (Common I/O area) registers present. 7506f51be3dSGrazvydas Ignotas * It's host's responsibility to fill cccr and cis 7516f51be3dSGrazvydas Ignotas * structures in init_card(). 7526f51be3dSGrazvydas Ignotas */ 7536f51be3dSGrazvydas Ignotas mmc_set_clock(host, card->cis.max_dtr); 7546f51be3dSGrazvydas Ignotas 7556f51be3dSGrazvydas Ignotas if (card->cccr.high_speed) { 7566f51be3dSGrazvydas Ignotas mmc_set_timing(card->host, MMC_TIMING_SD_HS); 7576f51be3dSGrazvydas Ignotas } 7586f51be3dSGrazvydas Ignotas 759a94a59f4SUlf Hansson if (oldcard) 760a94a59f4SUlf Hansson mmc_remove_card(card); 761a94a59f4SUlf Hansson else 762a94a59f4SUlf Hansson host->card = card; 763a94a59f4SUlf Hansson 764a94a59f4SUlf Hansson return 0; 7656f51be3dSGrazvydas Ignotas } 7666f51be3dSGrazvydas Ignotas 76717d33e14SNicolas Pitre /* 7685fc3d80eSShawn Lin * Read the common registers. Note that we should try to 7695fc3d80eSShawn Lin * validate whether UHS would work or not. 77017d33e14SNicolas Pitre */ 7712d0d68f5SPhilip Rakity err = sdio_read_cccr(card, ocr); 7725fc3d80eSShawn Lin if (err) { 7731dc5a615SUlf Hansson mmc_sdio_pre_init(host, ocr_card, card); 7745fc3d80eSShawn Lin if (ocr & R4_18V_PRESENT) { 7755fc3d80eSShawn Lin /* Retry init sequence, but without R4_18V_PRESENT. */ 7765fc3d80eSShawn Lin retries = 0; 7775fc3d80eSShawn Lin goto try_again; 7785fc3d80eSShawn Lin } 779f04086c2SUlf Hansson return err; 7805fc3d80eSShawn Lin } 78117d33e14SNicolas Pitre 78217d33e14SNicolas Pitre /* 78317d33e14SNicolas Pitre * Read the common CIS tuples. 78417d33e14SNicolas Pitre */ 78517d33e14SNicolas Pitre err = sdio_read_common_cis(card); 78617d33e14SNicolas Pitre if (err) 78717d33e14SNicolas Pitre goto remove; 78817d33e14SNicolas Pitre 78917d33e14SNicolas Pitre if (oldcard) { 790a94a59f4SUlf Hansson if (card->cis.vendor == oldcard->cis.vendor && 791a94a59f4SUlf Hansson card->cis.device == oldcard->cis.device) { 79217d33e14SNicolas Pitre mmc_remove_card(card); 79317d33e14SNicolas Pitre card = oldcard; 794a94a59f4SUlf Hansson } else { 795a94a59f4SUlf Hansson err = -ENOENT; 796a94a59f4SUlf Hansson goto mismatch; 797a94a59f4SUlf Hansson } 79817d33e14SNicolas Pitre } 79969041150SUlf Hansson card->ocr = ocr_card; 8001144c1e4SShawn Lin mmc_fixup_device(card, sdio_fixup_methods); 80117d33e14SNicolas Pitre 8027310ece8SMichal Miroslaw if (card->type == MMC_TYPE_SD_COMBO) { 8037310ece8SMichal Miroslaw err = mmc_sd_setup_card(host, card, oldcard != NULL); 8047310ece8SMichal Miroslaw /* handle as SDIO-only card if memory init failed */ 8057310ece8SMichal Miroslaw if (err) { 8067310ece8SMichal Miroslaw mmc_go_idle(host); 8077310ece8SMichal Miroslaw if (mmc_host_is_spi(host)) 8087310ece8SMichal Miroslaw /* should not fail, as it worked previously */ 8097310ece8SMichal Miroslaw mmc_spi_set_crc(host, use_spi_crc); 8107310ece8SMichal Miroslaw card->type = MMC_TYPE_SDIO; 8117310ece8SMichal Miroslaw } else 8127310ece8SMichal Miroslaw card->dev.type = &sd_type; 8137310ece8SMichal Miroslaw } 8147310ece8SMichal Miroslaw 8157310ece8SMichal Miroslaw /* 8167310ece8SMichal Miroslaw * If needed, disconnect card detection pull-up resistor. 8177310ece8SMichal Miroslaw */ 8187310ece8SMichal Miroslaw err = sdio_disable_cd(card); 8197310ece8SMichal Miroslaw if (err) 8207310ece8SMichal Miroslaw goto remove; 8217310ece8SMichal Miroslaw 822a303c531SPhilip Rakity /* Initialization sequence for UHS-I cards */ 823a303c531SPhilip Rakity /* Only if card supports 1.8v and UHS signaling */ 824a303c531SPhilip Rakity if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) { 825a303c531SPhilip Rakity err = mmc_sdio_init_uhs_card(card); 826a303c531SPhilip Rakity if (err) 827a303c531SPhilip Rakity goto remove; 828a303c531SPhilip Rakity } else { 82917d33e14SNicolas Pitre /* 83017d33e14SNicolas Pitre * Switch to high-speed (if supported). 83117d33e14SNicolas Pitre */ 83217d33e14SNicolas Pitre err = sdio_enable_hs(card); 83371578a1eSMichal Miroslaw if (err > 0) 834cdc99179SSeungwon Jeon mmc_set_timing(card->host, MMC_TIMING_SD_HS); 83571578a1eSMichal Miroslaw else if (err) 83617d33e14SNicolas Pitre goto remove; 83717d33e14SNicolas Pitre 83817d33e14SNicolas Pitre /* 83917d33e14SNicolas Pitre * Change to the card's maximum speed. 84017d33e14SNicolas Pitre */ 84171578a1eSMichal Miroslaw mmc_set_clock(host, mmc_sdio_get_max_clock(card)); 84217d33e14SNicolas Pitre 84317d33e14SNicolas Pitre /* 84417d33e14SNicolas Pitre * Switch to wider bus (if supported). 84517d33e14SNicolas Pitre */ 8467310ece8SMichal Miroslaw err = sdio_enable_4bit_bus(card); 847303dbedcSNeilBrown if (err) 84817d33e14SNicolas Pitre goto remove; 849a303c531SPhilip Rakity } 850247cfe53SKyle Roeschley 851247cfe53SKyle Roeschley if (host->caps2 & MMC_CAP2_AVOID_3_3V && 852247cfe53SKyle Roeschley host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { 853247cfe53SKyle Roeschley pr_err("%s: Host failed to negotiate down from 3.3V\n", 854247cfe53SKyle Roeschley mmc_hostname(host)); 855247cfe53SKyle Roeschley err = -EINVAL; 856247cfe53SKyle Roeschley goto remove; 857247cfe53SKyle Roeschley } 858a94a59f4SUlf Hansson 85917d33e14SNicolas Pitre host->card = card; 86017d33e14SNicolas Pitre return 0; 86117d33e14SNicolas Pitre 862a94a59f4SUlf Hansson mismatch: 863a94a59f4SUlf Hansson pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host)); 86417d33e14SNicolas Pitre remove: 865a94a59f4SUlf Hansson if (oldcard != card) 86617d33e14SNicolas Pitre mmc_remove_card(card); 86717d33e14SNicolas Pitre return err; 86817d33e14SNicolas Pitre } 86917d33e14SNicolas Pitre 8703c30e739SUlf Hansson static int mmc_sdio_reinit_card(struct mmc_host *host) 871fb09f44eSUlf Hansson { 872fb09f44eSUlf Hansson int ret; 873fb09f44eSUlf Hansson 8741dc5a615SUlf Hansson ret = mmc_sdio_pre_init(host, host->card->ocr, NULL); 875fb09f44eSUlf Hansson if (ret) 876fb09f44eSUlf Hansson return ret; 877fb09f44eSUlf Hansson 8784aaaf3abSUlf Hansson return mmc_sdio_init_card(host, host->card->ocr, host->card); 879fb09f44eSUlf Hansson } 880fb09f44eSUlf Hansson 88117d33e14SNicolas Pitre /* 8825c4e6f13SPierre Ossman * Host is being removed. Free up the current card. 8835c4e6f13SPierre Ossman */ 8845c4e6f13SPierre Ossman static void mmc_sdio_remove(struct mmc_host *host) 8855c4e6f13SPierre Ossman { 886e29a7d73SPierre Ossman int i; 887e29a7d73SPierre Ossman 888e29a7d73SPierre Ossman for (i = 0;i < host->card->sdio_funcs;i++) { 889e29a7d73SPierre Ossman if (host->card->sdio_func[i]) { 890e29a7d73SPierre Ossman sdio_remove_func(host->card->sdio_func[i]); 891e29a7d73SPierre Ossman host->card->sdio_func[i] = NULL; 892e29a7d73SPierre Ossman } 893e29a7d73SPierre Ossman } 894e29a7d73SPierre Ossman 8955c4e6f13SPierre Ossman mmc_remove_card(host->card); 8965c4e6f13SPierre Ossman host->card = NULL; 8975c4e6f13SPierre Ossman } 8985c4e6f13SPierre Ossman 8995c4e6f13SPierre Ossman /* 900d3049504SAdrian Hunter * Card detection - card is alive. 901d3049504SAdrian Hunter */ 902d3049504SAdrian Hunter static int mmc_sdio_alive(struct mmc_host *host) 903d3049504SAdrian Hunter { 904d3049504SAdrian Hunter return mmc_select_card(host->card); 905d3049504SAdrian Hunter } 906d3049504SAdrian Hunter 907d3049504SAdrian Hunter /* 9085c4e6f13SPierre Ossman * Card detection callback from host. 9095c4e6f13SPierre Ossman */ 9105c4e6f13SPierre Ossman static void mmc_sdio_detect(struct mmc_host *host) 9115c4e6f13SPierre Ossman { 9125c4e6f13SPierre Ossman int err; 9135c4e6f13SPierre Ossman 91487973ba2SOhad Ben-Cohen /* Make sure card is powered before detecting it */ 915ed919b01SOhad Ben-Cohen if (host->caps & MMC_CAP_POWER_OFF_CARD) { 91687973ba2SOhad Ben-Cohen err = pm_runtime_get_sync(&host->card->dev); 9173bffb800SLi Fei if (err < 0) { 9183bffb800SLi Fei pm_runtime_put_noidle(&host->card->dev); 91987973ba2SOhad Ben-Cohen goto out; 920ed919b01SOhad Ben-Cohen } 9213bffb800SLi Fei } 92287973ba2SOhad Ben-Cohen 9235c4e6f13SPierre Ossman mmc_claim_host(host); 9245c4e6f13SPierre Ossman 9255c4e6f13SPierre Ossman /* 9265c4e6f13SPierre Ossman * Just check if our card has been removed. 9275c4e6f13SPierre Ossman */ 928d3049504SAdrian Hunter err = _mmc_detect_card_removed(host); 9295c4e6f13SPierre Ossman 9305c4e6f13SPierre Ossman mmc_release_host(host); 9315c4e6f13SPierre Ossman 9324d0812c3SOhad Ben-Cohen /* 9334d0812c3SOhad Ben-Cohen * Tell PM core it's OK to power off the card now. 9344d0812c3SOhad Ben-Cohen * 9354d0812c3SOhad Ben-Cohen * The _sync variant is used in order to ensure that the card 9364d0812c3SOhad Ben-Cohen * is left powered off in case an error occurred, and the card 9374d0812c3SOhad Ben-Cohen * is going to be removed. 9384d0812c3SOhad Ben-Cohen * 9394d0812c3SOhad Ben-Cohen * Since there is no specific reason to believe a new user 9404d0812c3SOhad Ben-Cohen * is about to show up at this point, the _sync variant is 9414d0812c3SOhad Ben-Cohen * desirable anyway. 9424d0812c3SOhad Ben-Cohen */ 943ed919b01SOhad Ben-Cohen if (host->caps & MMC_CAP_POWER_OFF_CARD) 9444d0812c3SOhad Ben-Cohen pm_runtime_put_sync(&host->card->dev); 9454d0812c3SOhad Ben-Cohen 94687973ba2SOhad Ben-Cohen out: 9475c4e6f13SPierre Ossman if (err) { 9485c4e6f13SPierre Ossman mmc_sdio_remove(host); 9495c4e6f13SPierre Ossman 9505c4e6f13SPierre Ossman mmc_claim_host(host); 9515c4e6f13SPierre Ossman mmc_detach_bus(host); 9527f7e4129SUlf Hansson mmc_power_off(host); 9535c4e6f13SPierre Ossman mmc_release_host(host); 9545c4e6f13SPierre Ossman } 9555c4e6f13SPierre Ossman } 9565c4e6f13SPierre Ossman 95717d33e14SNicolas Pitre /* 958810caddbSUlf Hansson * SDIO pre_suspend. We need to suspend all functions separately. 95917d33e14SNicolas Pitre * Therefore all registered functions must have drivers with suspend 96017d33e14SNicolas Pitre * and resume methods. Failing that we simply remove the whole card. 96117d33e14SNicolas Pitre */ 962810caddbSUlf Hansson static int mmc_sdio_pre_suspend(struct mmc_host *host) 96317d33e14SNicolas Pitre { 96495cdfb72SNicolas Pitre int i, err = 0; 96517d33e14SNicolas Pitre 96617d33e14SNicolas Pitre for (i = 0; i < host->card->sdio_funcs; i++) { 96717d33e14SNicolas Pitre struct sdio_func *func = host->card->sdio_func[i]; 96817d33e14SNicolas Pitre if (func && sdio_func_present(func) && func->dev.driver) { 96917d33e14SNicolas Pitre const struct dev_pm_ops *pmops = func->dev.driver->pm; 97017d33e14SNicolas Pitre if (!pmops || !pmops->suspend || !pmops->resume) { 97195cdfb72SNicolas Pitre /* force removal of entire card in that case */ 97295cdfb72SNicolas Pitre err = -ENOSYS; 973810caddbSUlf Hansson break; 974810caddbSUlf Hansson } 975810caddbSUlf Hansson } 976810caddbSUlf Hansson } 977810caddbSUlf Hansson 978810caddbSUlf Hansson return err; 979810caddbSUlf Hansson } 980810caddbSUlf Hansson 981810caddbSUlf Hansson /* 982810caddbSUlf Hansson * SDIO suspend. Suspend all functions separately. 983810caddbSUlf Hansson */ 984810caddbSUlf Hansson static int mmc_sdio_suspend(struct mmc_host *host) 985810caddbSUlf Hansson { 986c5d3e8faSUlf Hansson WARN_ON(host->sdio_irqs && !mmc_card_keep_power(host)); 987c5d3e8faSUlf Hansson 98883293386SUlf Hansson /* Prevent processing of SDIO IRQs in suspended state. */ 98983293386SUlf Hansson mmc_card_set_suspended(host->card); 99083293386SUlf Hansson cancel_delayed_work_sync(&host->sdio_irq_work); 99183293386SUlf Hansson 9926b5eda36SDaniel Drake mmc_claim_host(host); 9938d1ffc8cSUlf Hansson 9948d1ffc8cSUlf Hansson if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) 99540e6c479SYue Hu sdio_disable_4bit_bus(host->card); 9966b5eda36SDaniel Drake 99779d5a65aSAdrian Hunter if (!mmc_card_keep_power(host)) { 99874590263SUlf Hansson mmc_power_off(host); 99979d5a65aSAdrian Hunter } else if (host->retune_period) { 100079d5a65aSAdrian Hunter mmc_retune_timer_stop(host); 100179d5a65aSAdrian Hunter mmc_retune_needed(host); 100279d5a65aSAdrian Hunter } 100374590263SUlf Hansson 10048d1ffc8cSUlf Hansson mmc_release_host(host); 10058d1ffc8cSUlf Hansson 1006573185ccSUlf Hansson return 0; 100795cdfb72SNicolas Pitre } 100895cdfb72SNicolas Pitre 100995cdfb72SNicolas Pitre static int mmc_sdio_resume(struct mmc_host *host) 101095cdfb72SNicolas Pitre { 1011573185ccSUlf Hansson int err = 0; 101295cdfb72SNicolas Pitre 101395cdfb72SNicolas Pitre /* Basic card reinitialization. */ 101495cdfb72SNicolas Pitre mmc_claim_host(host); 1015080bc977SOhad Ben-Cohen 10166ebc581cSUlf Hansson /* 10176ebc581cSUlf Hansson * Restore power and reinitialize the card when needed. Note that a 10186ebc581cSUlf Hansson * removable card is checked from a detect work later on in the resume 10196ebc581cSUlf Hansson * process. 10206ebc581cSUlf Hansson */ 102174590263SUlf Hansson if (!mmc_card_keep_power(host)) { 102269041150SUlf Hansson mmc_power_up(host, host->card->ocr); 102374590263SUlf Hansson /* 102474590263SUlf Hansson * Tell runtime PM core we just powered up the card, 102574590263SUlf Hansson * since it still believes the card is powered off. 102674590263SUlf Hansson * Note that currently runtime PM is only enabled 102774590263SUlf Hansson * for SDIO cards that are MMC_CAP_POWER_OFF_CARD 102874590263SUlf Hansson */ 102974590263SUlf Hansson if (host->caps & MMC_CAP_POWER_OFF_CARD) { 103074590263SUlf Hansson pm_runtime_disable(&host->card->dev); 103174590263SUlf Hansson pm_runtime_set_active(&host->card->dev); 103274590263SUlf Hansson pm_runtime_enable(&host->card->dev); 103374590263SUlf Hansson } 10343c30e739SUlf Hansson err = mmc_sdio_reinit_card(host); 10356ebc581cSUlf Hansson } else if (mmc_card_wake_sdio_irq(host)) { 1036080bc977SOhad Ben-Cohen /* We may have switched to 1-bit mode during suspend */ 1037080bc977SOhad Ben-Cohen err = sdio_enable_4bit_bus(host->card); 1038080bc977SOhad Ben-Cohen } 1039080bc977SOhad Ben-Cohen 104083293386SUlf Hansson if (err) 104183293386SUlf Hansson goto out; 104283293386SUlf Hansson 104383293386SUlf Hansson /* Allow SDIO IRQs to be processed again. */ 104483293386SUlf Hansson mmc_card_clr_suspended(host->card); 104583293386SUlf Hansson 104683293386SUlf Hansson if (host->sdio_irqs) { 10479eadcc05SUlf Hansson if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) 1048bbbc4c4dSNicolas Pitre wake_up_process(host->sdio_irq_thread); 10499eadcc05SUlf Hansson else if (host->caps & MMC_CAP_SDIO_IRQ) 105051133850SUlf Hansson queue_delayed_work(system_wq, &host->sdio_irq_work, 0); 1051dea67c4eSFu Zhonghui } 1052dea67c4eSFu Zhonghui 105383293386SUlf Hansson out: 105495cdfb72SNicolas Pitre mmc_release_host(host); 105595cdfb72SNicolas Pitre 105674590263SUlf Hansson host->pm_flags &= ~MMC_PM_KEEP_POWER; 105795cdfb72SNicolas Pitre return err; 105817d33e14SNicolas Pitre } 10595c4e6f13SPierre Ossman 106012d01d0bSUlf Hansson static int mmc_sdio_runtime_suspend(struct mmc_host *host) 106112d01d0bSUlf Hansson { 106212d01d0bSUlf Hansson /* No references to the card, cut the power to it. */ 10638d1ffc8cSUlf Hansson mmc_claim_host(host); 106412d01d0bSUlf Hansson mmc_power_off(host); 10658d1ffc8cSUlf Hansson mmc_release_host(host); 10668d1ffc8cSUlf Hansson 106712d01d0bSUlf Hansson return 0; 106812d01d0bSUlf Hansson } 106912d01d0bSUlf Hansson 107012d01d0bSUlf Hansson static int mmc_sdio_runtime_resume(struct mmc_host *host) 107112d01d0bSUlf Hansson { 10728d1ffc8cSUlf Hansson int ret; 10738d1ffc8cSUlf Hansson 107412d01d0bSUlf Hansson /* Restore power and re-initialize. */ 10758d1ffc8cSUlf Hansson mmc_claim_host(host); 107669041150SUlf Hansson mmc_power_up(host, host->card->ocr); 10773c30e739SUlf Hansson ret = mmc_sdio_reinit_card(host); 10788d1ffc8cSUlf Hansson mmc_release_host(host); 10798d1ffc8cSUlf Hansson 10808d1ffc8cSUlf Hansson return ret; 108112d01d0bSUlf Hansson } 108212d01d0bSUlf Hansson 10832ac55d5eSUlf Hansson /* 10842ac55d5eSUlf Hansson * SDIO HW reset 10852ac55d5eSUlf Hansson * 10862ac55d5eSUlf Hansson * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW 10872ac55d5eSUlf Hansson * reset was asynchronously scheduled, else a negative error code. 10882ac55d5eSUlf Hansson */ 10893a3db603SUlf Hansson static int mmc_sdio_hw_reset(struct mmc_host *host) 10901fb654fdSAndreas Fenkart { 10912ac55d5eSUlf Hansson struct mmc_card *card = host->card; 10922ac55d5eSUlf Hansson 10932ac55d5eSUlf Hansson /* 10942ac55d5eSUlf Hansson * In case the card is shared among multiple func drivers, reset the 10952ac55d5eSUlf Hansson * card through a rescan work. In this way it will be removed and 10962ac55d5eSUlf Hansson * re-detected, thus all func drivers becomes informed about it. 10972ac55d5eSUlf Hansson */ 10982ac55d5eSUlf Hansson if (atomic_read(&card->sdio_funcs_probed) > 1) { 10992ac55d5eSUlf Hansson if (mmc_card_removed(card)) 11002ac55d5eSUlf Hansson return 1; 11012ac55d5eSUlf Hansson host->rescan_entered = 0; 11022ac55d5eSUlf Hansson mmc_card_set_removed(card); 11032ac55d5eSUlf Hansson _mmc_detect_change(host, 0, false); 11042ac55d5eSUlf Hansson return 1; 11052ac55d5eSUlf Hansson } 11062ac55d5eSUlf Hansson 11072ac55d5eSUlf Hansson /* 11082ac55d5eSUlf Hansson * A single func driver has been probed, then let's skip the heavy 11092ac55d5eSUlf Hansson * hotplug dance above and execute the reset immediately. 11102ac55d5eSUlf Hansson */ 11112ac55d5eSUlf Hansson mmc_power_cycle(host, card->ocr); 11123c30e739SUlf Hansson return mmc_sdio_reinit_card(host); 11131fb654fdSAndreas Fenkart } 11141fb654fdSAndreas Fenkart 11157405df4cSUlf Hansson static int mmc_sdio_sw_reset(struct mmc_host *host) 11167405df4cSUlf Hansson { 11177405df4cSUlf Hansson mmc_set_clock(host, host->f_init); 11187405df4cSUlf Hansson sdio_reset(host); 11197405df4cSUlf Hansson mmc_go_idle(host); 11207405df4cSUlf Hansson 11217405df4cSUlf Hansson mmc_set_initial_state(host); 11227405df4cSUlf Hansson mmc_set_initial_signal_voltage(host); 11237405df4cSUlf Hansson 11243c30e739SUlf Hansson return mmc_sdio_reinit_card(host); 11257405df4cSUlf Hansson } 11267405df4cSUlf Hansson 11275c4e6f13SPierre Ossman static const struct mmc_bus_ops mmc_sdio_ops = { 11285c4e6f13SPierre Ossman .remove = mmc_sdio_remove, 11295c4e6f13SPierre Ossman .detect = mmc_sdio_detect, 1130810caddbSUlf Hansson .pre_suspend = mmc_sdio_pre_suspend, 113117d33e14SNicolas Pitre .suspend = mmc_sdio_suspend, 113217d33e14SNicolas Pitre .resume = mmc_sdio_resume, 113312d01d0bSUlf Hansson .runtime_suspend = mmc_sdio_runtime_suspend, 113412d01d0bSUlf Hansson .runtime_resume = mmc_sdio_runtime_resume, 1135d3049504SAdrian Hunter .alive = mmc_sdio_alive, 11363a3db603SUlf Hansson .hw_reset = mmc_sdio_hw_reset, 11377405df4cSUlf Hansson .sw_reset = mmc_sdio_sw_reset, 11385c4e6f13SPierre Ossman }; 11395c4e6f13SPierre Ossman 11405c4e6f13SPierre Ossman 11415c4e6f13SPierre Ossman /* 11425c4e6f13SPierre Ossman * Starting point for SDIO card init. 11435c4e6f13SPierre Ossman */ 1144807e8e40SAndy Ross int mmc_attach_sdio(struct mmc_host *host) 11455c4e6f13SPierre Ossman { 1146807e8e40SAndy Ross int err, i, funcs; 114769041150SUlf Hansson u32 ocr, rocr; 11485c4e6f13SPierre Ossman struct mmc_card *card; 11495c4e6f13SPierre Ossman 1150d84075c8SPierre Ossman WARN_ON(!host->claimed); 11515c4e6f13SPierre Ossman 1152807e8e40SAndy Ross err = mmc_send_io_op_cond(host, 0, &ocr); 1153807e8e40SAndy Ross if (err) 1154807e8e40SAndy Ross return err; 1155807e8e40SAndy Ross 11565c4e6f13SPierre Ossman mmc_attach_bus(host, &mmc_sdio_ops); 11578f230f45STakashi Iwai if (host->ocr_avail_sdio) 11588f230f45STakashi Iwai host->ocr_avail = host->ocr_avail_sdio; 11595c4e6f13SPierre Ossman 11605c4e6f13SPierre Ossman 116169041150SUlf Hansson rocr = mmc_select_voltage(host, ocr); 11625c4e6f13SPierre Ossman 11635c4e6f13SPierre Ossman /* 11645c4e6f13SPierre Ossman * Can we support the voltage(s) of the card(s)? 11655c4e6f13SPierre Ossman */ 116669041150SUlf Hansson if (!rocr) { 11675c4e6f13SPierre Ossman err = -EINVAL; 11685c4e6f13SPierre Ossman goto err; 11695c4e6f13SPierre Ossman } 11705c4e6f13SPierre Ossman 11715c4e6f13SPierre Ossman /* 117217d33e14SNicolas Pitre * Detect and init the card. 11735c4e6f13SPierre Ossman */ 11744aaaf3abSUlf Hansson err = mmc_sdio_init_card(host, rocr, NULL); 11755c4e6f13SPierre Ossman if (err) 11765c4e6f13SPierre Ossman goto err; 1177ec2ed700SUlf Hansson 117817d33e14SNicolas Pitre card = host->card; 1179af517150SDavid Brownell 1180af517150SDavid Brownell /* 1181ed919b01SOhad Ben-Cohen * Enable runtime PM only if supported by host+card+board 1182ed919b01SOhad Ben-Cohen */ 1183ed919b01SOhad Ben-Cohen if (host->caps & MMC_CAP_POWER_OFF_CARD) { 1184ed919b01SOhad Ben-Cohen /* 11854760257cSAdrian Hunter * Do not allow runtime suspend until after SDIO function 11864760257cSAdrian Hunter * devices are added. 11874760257cSAdrian Hunter */ 11884760257cSAdrian Hunter pm_runtime_get_noresume(&card->dev); 11894760257cSAdrian Hunter 11904760257cSAdrian Hunter /* 119181968561SOhad Ben-Cohen * Let runtime PM core know our card is active 119281968561SOhad Ben-Cohen */ 119381968561SOhad Ben-Cohen err = pm_runtime_set_active(&card->dev); 119481968561SOhad Ben-Cohen if (err) 119581968561SOhad Ben-Cohen goto remove; 119681968561SOhad Ben-Cohen 119781968561SOhad Ben-Cohen /* 119881968561SOhad Ben-Cohen * Enable runtime PM for this card 119981968561SOhad Ben-Cohen */ 120081968561SOhad Ben-Cohen pm_runtime_enable(&card->dev); 1201ed919b01SOhad Ben-Cohen } 120281968561SOhad Ben-Cohen 120381968561SOhad Ben-Cohen /* 12045c4e6f13SPierre Ossman * The number of functions on the card is encoded inside 12055c4e6f13SPierre Ossman * the ocr. 12065c4e6f13SPierre Ossman */ 1207e8812793SMatt Fleming funcs = (ocr & 0x70000000) >> 28; 1208e8812793SMatt Fleming card->sdio_funcs = 0; 12094ff6471cSPierre Ossman 12104ff6471cSPierre Ossman /* 1211e29a7d73SPierre Ossman * Initialize (but don't add) all present functions. 1212e29a7d73SPierre Ossman */ 1213e8812793SMatt Fleming for (i = 0; i < funcs; i++, card->sdio_funcs++) { 1214e29a7d73SPierre Ossman err = sdio_init_func(host->card, i + 1); 1215e29a7d73SPierre Ossman if (err) 1216e29a7d73SPierre Ossman goto remove; 121740bba0c1SOhad Ben-Cohen 121840bba0c1SOhad Ben-Cohen /* 1219ed919b01SOhad Ben-Cohen * Enable Runtime PM for this func (if supported) 122040bba0c1SOhad Ben-Cohen */ 1221ed919b01SOhad Ben-Cohen if (host->caps & MMC_CAP_POWER_OFF_CARD) 122240bba0c1SOhad Ben-Cohen pm_runtime_enable(&card->sdio_func[i]->dev); 1223e29a7d73SPierre Ossman } 12245c4e6f13SPierre Ossman 1225e29a7d73SPierre Ossman /* 1226e29a7d73SPierre Ossman * First add the card to the driver model... 1227e29a7d73SPierre Ossman */ 1228807e8e40SAndy Ross mmc_release_host(host); 12295c4e6f13SPierre Ossman err = mmc_add_card(host->card); 12305c4e6f13SPierre Ossman if (err) 1231e29a7d73SPierre Ossman goto remove_added; 1232e29a7d73SPierre Ossman 1233e29a7d73SPierre Ossman /* 1234e29a7d73SPierre Ossman * ...then the SDIO functions. 1235e29a7d73SPierre Ossman */ 1236e29a7d73SPierre Ossman for (i = 0;i < funcs;i++) { 1237e29a7d73SPierre Ossman err = sdio_add_func(host->card->sdio_func[i]); 1238e29a7d73SPierre Ossman if (err) 1239e29a7d73SPierre Ossman goto remove_added; 1240e29a7d73SPierre Ossman } 12415c4e6f13SPierre Ossman 12424760257cSAdrian Hunter if (host->caps & MMC_CAP_POWER_OFF_CARD) 12434760257cSAdrian Hunter pm_runtime_put(&card->dev); 12444760257cSAdrian Hunter 124534497913SDmitry Shmidt mmc_claim_host(host); 12465c4e6f13SPierre Ossman return 0; 12475c4e6f13SPierre Ossman 1248e29a7d73SPierre Ossman 1249e29a7d73SPierre Ossman remove: 1250807e8e40SAndy Ross mmc_release_host(host); 125182e7edc2SAdrian Hunter remove_added: 125282e7edc2SAdrian Hunter /* 125382e7edc2SAdrian Hunter * The devices are being deleted so it is not necessary to disable 12544760257cSAdrian Hunter * runtime PM. Similarly we also don't pm_runtime_put() the SDIO card 12554760257cSAdrian Hunter * because it needs to be active to remove any function devices that 12564760257cSAdrian Hunter * were probed, and after that it gets deleted. 125782e7edc2SAdrian Hunter */ 1258e29a7d73SPierre Ossman mmc_sdio_remove(host); 1259807e8e40SAndy Ross mmc_claim_host(host); 12605c4e6f13SPierre Ossman err: 12615c4e6f13SPierre Ossman mmc_detach_bus(host); 12625c4e6f13SPierre Ossman 1263a3c76eb9SGirish K S pr_err("%s: error %d whilst initialising SDIO card\n", 12645c4e6f13SPierre Ossman mmc_hostname(host), err); 12655c4e6f13SPierre Ossman 12665c4e6f13SPierre Ossman return err; 12675c4e6f13SPierre Ossman } 12685c4e6f13SPierre Ossman 1269