diff options
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/block.c | 18 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 5 | ||||
-rw-r--r-- | drivers/mmc/core/debugfs.c | 19 | ||||
-rw-r--r-- | drivers/mmc/core/host.h | 3 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/queue.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 20 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 9 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 4 | ||||
-rw-r--r-- | drivers/mmc/core/slot-gpio.c | 23 |
10 files changed, 57 insertions, 54 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 2cfb963d9f37..9e923cd1d80e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -376,22 +376,15 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( return idata; } - idata->buf = kmalloc(idata->buf_bytes, GFP_KERNEL); - if (!idata->buf) { - err = -ENOMEM; + idata->buf = memdup_user((void __user *)(unsigned long) + idata->ic.data_ptr, idata->buf_bytes); + if (IS_ERR(idata->buf)) { + err = PTR_ERR(idata->buf); goto idata_err; } - if (copy_from_user(idata->buf, (void __user *)(unsigned long) - idata->ic.data_ptr, idata->buf_bytes)) { - err = -EFAULT; - goto copy_err; - } - return idata; -copy_err: - kfree(idata->buf); idata_err: kfree(idata); out: @@ -2666,7 +2659,6 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md) * from being accepted. */ card = md->queue.card; - mmc_cleanup_queue(&md->queue); if (md->disk->flags & GENHD_FL_UP) { device_remove_file(disk_to_dev(md->disk), &md->force_ro); if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && @@ -2676,6 +2668,7 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md) del_gendisk(md->disk); } + mmc_cleanup_queue(&md->queue); mmc_blk_put(md); } } @@ -3087,6 +3080,7 @@ static void __exit mmc_blk_exit(void) mmc_unregister_driver(&mmc_driver); unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES); + bus_unregister(&mmc_rpmb_bus_type); } module_init(mmc_blk_init); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c0ba6d8823b7..121ce50b6d5e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2369,7 +2369,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card) return card->pref_erase; max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG); - if (mmc_can_trim(card)) { + if (max_discard && mmc_can_trim(card)) { max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG); if (max_trim < max_discard) max_discard = max_trim; @@ -2655,8 +2655,7 @@ void mmc_start_host(struct mmc_host *host) void mmc_stop_host(struct mmc_host *host) { if (host->slot.cd_irq >= 0) { - if (host->slot.cd_wake_enabled) - disable_irq_wake(host->slot.cd_irq); + mmc_gpio_set_cd_wake(host, false); disable_irq(host->slot.cd_irq); } diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 0f4a7d7b2626..d2275c5a2311 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -196,18 +196,7 @@ static int mmc_ios_show(struct seq_file *s, void *data) return 0; } - -static int mmc_ios_open(struct inode *inode, struct file *file) -{ - return single_open(file, mmc_ios_show, inode->i_private); -} - -static const struct file_operations mmc_ios_fops = { - .open = mmc_ios_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(mmc_ios); static int mmc_clock_opt_get(void *data, u64 *val) { @@ -254,6 +243,12 @@ void mmc_add_host_debugfs(struct mmc_host *host) if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops)) goto err_node; + if (!debugfs_create_x32("caps", S_IRUSR, root, &host->caps)) + goto err_node; + + if (!debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2)) + goto err_node; + if (!debugfs_create_file("clock", S_IRUSR | S_IWUSR, root, host, &mmc_clock_fops)) goto err_node; diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 06ec19b5bf9f..4805438c02ff 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -56,7 +56,8 @@ static inline int mmc_host_uhs(struct mmc_host *host) return host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | - MMC_CAP_UHS_DDR50); + MMC_CAP_UHS_DDR50) && + host->caps & MMC_CAP_4_BIT_DATA; } static inline bool mmc_card_hs200(struct mmc_card *card) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 208a762b87ef..6f8ebd6caa4c 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -792,6 +792,7 @@ MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr); +MMC_DEV_ATTR(rca, "0x%04x\n", card->rca); MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en); static ssize_t mmc_fwrev_show(struct device *dev, @@ -848,6 +849,7 @@ static struct attribute *mmc_std_attrs[] = { &dev_attr_raw_rpmb_size_mult.attr, &dev_attr_rel_sectors.attr, &dev_attr_ocr.attr, + &dev_attr_rca.attr, &dev_attr_dsr.attr, &dev_attr_cmdq_en.attr, NULL, diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 421fab7250ac..56e9a803db21 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -185,14 +185,14 @@ static void mmc_queue_setup_discard(struct request_queue *q, if (!max_discard) return; - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); + blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); blk_queue_max_discard_sectors(q, max_discard); q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity = 0; if (mmc_can_secure_erase_trim(card)) - queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); + blk_queue_flag_set(QUEUE_FLAG_SECERASE, q); } /** @@ -356,8 +356,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; - queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); - queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue); + blk_queue_flag_set(QUEUE_FLAG_NONROT, mq->queue); + blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, mq->queue); if (mmc_can_erase(card)) mmc_queue_setup_discard(mq->queue, card); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 62b84dd8f9fe..baf3d5da4ccb 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -291,8 +291,6 @@ static int mmc_read_switch(struct mmc_card *card) return 0; } - err = -EIO; - status = kmalloc(64, GFP_KERNEL); if (!status) return -ENOMEM; @@ -582,9 +580,6 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) int err; u8 *status; - if (!card->scr.sda_spec3) - return 0; - if (!(card->csd.cmdclass & CCC_SWITCH)) return 0; @@ -593,14 +588,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) return -ENOMEM; /* Set 4-bit bus width */ - if ((card->host->caps & MMC_CAP_4_BIT_DATA) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); - if (err) - goto out; + err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); + if (err) + goto out; - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); - } + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); /* * Select the bus speed mode depending on host @@ -676,6 +668,7 @@ MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr); +MMC_DEV_ATTR(rca, "0x%04x\n", card->rca); static ssize_t mmc_dsr_show(struct device *dev, @@ -709,6 +702,7 @@ static struct attribute *sd_std_attrs[] = { &dev_attr_oemid.attr, &dev_attr_serial.attr, &dev_attr_ocr.attr, + &dev_attr_rca.attr, &dev_attr_dsr.attr, NULL, }; @@ -1033,7 +1027,7 @@ retry: } /* Initialization sequence for UHS-I cards */ - if (rocr & SD_ROCR_S18A) { + if (rocr & SD_ROCR_S18A && mmc_host_uhs(host)) { err = mmc_sd_init_uhs_card(card); if (err) goto free_card; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index cc43687ca241..c599a628a387 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -518,11 +518,10 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card) if (!card->scr.sda_spec3) return 0; - /* - * Switch to wider bus (if supported). - */ - if (card->host->caps & MMC_CAP_4_BIT_DATA) - err = sdio_enable_4bit_bus(card); + /* Switch to wider bus */ + err = sdio_enable_4bit_bus(card); + if (err) + goto out; /* Set the driver strength for the card */ sdio_select_driver_type(card); diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index 7a2eaf8410a3..7ca7b99413f0 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -277,8 +277,8 @@ static void sdio_single_irq_set(struct mmc_card *card) * * Claim and activate the IRQ for the given SDIO function. The provided * handler will be called when that IRQ is asserted. The host is always - * claimed already when the handler is called so the handler must not - * call sdio_claim_host() nor sdio_release_host(). + * claimed already when the handler is called so the handler should not + * call sdio_claim_host() or sdio_release_host(). */ int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler) { diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 3698b0576009..31f7dbb15668 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c @@ -149,11 +149,30 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host) if (irq < 0) host->caps |= MMC_CAP_NEEDS_POLL; - else if ((host->caps & MMC_CAP_CD_WAKE) && !enable_irq_wake(irq)) - host->slot.cd_wake_enabled = true; } EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); +int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on) +{ + int ret = 0; + + if (!(host->caps & MMC_CAP_CD_WAKE) || + host->slot.cd_irq < 0 || + on == host->slot.cd_wake_enabled) + return 0; + + if (on) { + ret = enable_irq_wake(host->slot.cd_irq); + host->slot.cd_wake_enabled = !ret; + } else { + disable_irq_wake(host->slot.cd_irq); + host->slot.cd_wake_enabled = false; + } + + return ret; +} +EXPORT_SYMBOL(mmc_gpio_set_cd_wake); + /* Register an alternate interrupt service routine for * the card-detect GPIO. */ |