aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/block.c83
-rw-r--r--drivers/mmc/card/mmc_test.c28
-rw-r--r--drivers/mmc/card/queue.c16
3 files changed, 65 insertions, 62 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1fa4c80ff886..4409d79ed650 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -78,13 +78,16 @@ static int perdev_minors = CONFIG_MMC_BLOCK_MINORS;
/*
* We've only got one major, so number of mmcblk devices is
- * limited to 256 / number of minors per device.
+ * limited to (1 << 20) / number of minors per device. It is also
+ * currently limited by the size of the static bitmaps below.
*/
static int max_devices;
-/* 256 minors, so at most 256 separate devices */
-static DECLARE_BITMAP(dev_use, 256);
-static DECLARE_BITMAP(name_use, 256);
+#define MAX_DEVICES 256
+
+/* TODO: Replace these with struct ida */
+static DECLARE_BITMAP(dev_use, MAX_DEVICES);
+static DECLARE_BITMAP(name_use, MAX_DEVICES);
/*
* There is one mmc_blk_data per slot.
@@ -112,7 +115,7 @@ struct mmc_blk_data {
/*
* Only set in main mmc_blk_data associated
- * with mmc_card with mmc_set_drvdata, and keeps
+ * with mmc_card with dev_set_drvdata, and keeps
* track of the current selected device partition.
*/
unsigned int part_curr;
@@ -260,7 +263,7 @@ static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
int ret;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
- ret = snprintf(buf, PAGE_SIZE, "%d",
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
get_disk_ro(dev_to_disk(dev)) ^
md->read_only);
mmc_blk_put(md);
@@ -642,7 +645,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
struct mmc_blk_data *md)
{
int ret;
- struct mmc_blk_data *main_md = mmc_get_drvdata(card);
+ struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev);
if (main_md->part_curr == md->part_type)
return 0;
@@ -1004,7 +1007,8 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
err = mmc_hw_reset(host);
/* Ensure we switch back to the correct partition */
if (err != -EOPNOTSUPP) {
- struct mmc_blk_data *main_md = mmc_get_drvdata(host->card);
+ struct mmc_blk_data *main_md =
+ dev_get_drvdata(&host->card->dev);
int part_err;
main_md->part_curr = main_md->part_type;
@@ -1308,19 +1312,11 @@ static int mmc_blk_packed_err_check(struct mmc_card *card,
}
if (status & R1_EXCEPTION_EVENT) {
- ext_csd = kzalloc(512, GFP_KERNEL);
- if (!ext_csd) {
- pr_err("%s: unable to allocate buffer for ext_csd\n",
- req->rq_disk->disk_name);
- return -ENOMEM;
- }
-
- err = mmc_send_ext_csd(card, ext_csd);
+ err = mmc_get_ext_csd(card, &ext_csd);
if (err) {
pr_err("%s: error %d sending ext_csd\n",
req->rq_disk->disk_name, err);
- check = MMC_BLK_ABORT;
- goto free;
+ return MMC_BLK_ABORT;
}
if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] &
@@ -1338,7 +1334,6 @@ static int mmc_blk_packed_err_check(struct mmc_card *card,
req->rq_disk->disk_name, packed->nr_entries,
packed->blocks, packed->idx_failure);
}
-free:
kfree(ext_csd);
}
@@ -2093,7 +2088,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
/*
* !subname implies we are creating main mmc_blk_data that will be
- * associated with mmc_card with mmc_set_drvdata. Due to device
+ * associated with mmc_card with dev_set_drvdata. Due to device
* partitions, devidx will not coincide with a per-physical card
* index anymore so we keep track of a name index.
*/
@@ -2425,8 +2420,9 @@ static const struct mmc_fixup blk_fixups[] =
END_FIXUP
};
-static int mmc_blk_probe(struct mmc_card *card)
+static int mmc_blk_probe(struct device *dev)
{
+ struct mmc_card *card = mmc_dev_to_card(dev);
struct mmc_blk_data *md, *part_md;
char cap_str[10];
@@ -2451,7 +2447,7 @@ static int mmc_blk_probe(struct mmc_card *card)
if (mmc_blk_alloc_parts(card, md))
goto out;
- mmc_set_drvdata(card, md);
+ dev_set_drvdata(dev, md);
if (mmc_add_disk(md))
goto out;
@@ -2481,9 +2477,10 @@ static int mmc_blk_probe(struct mmc_card *card)
return 0;
}
-static void mmc_blk_remove(struct mmc_card *card)
+static int mmc_blk_remove(struct device *dev)
{
- struct mmc_blk_data *md = mmc_get_drvdata(card);
+ struct mmc_card *card = mmc_dev_to_card(dev);
+ struct mmc_blk_data *md = dev_get_drvdata(dev);
mmc_blk_remove_parts(card, md);
pm_runtime_get_sync(&card->dev);
@@ -2494,13 +2491,15 @@ static void mmc_blk_remove(struct mmc_card *card)
pm_runtime_disable(&card->dev);
pm_runtime_put_noidle(&card->dev);
mmc_blk_remove_req(md);
- mmc_set_drvdata(card, NULL);
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
}
-static int _mmc_blk_suspend(struct mmc_card *card)
+static int _mmc_blk_suspend(struct device *dev)
{
struct mmc_blk_data *part_md;
- struct mmc_blk_data *md = mmc_get_drvdata(card);
+ struct mmc_blk_data *md = dev_get_drvdata(dev);
if (md) {
mmc_queue_suspend(&md->queue);
@@ -2511,21 +2510,21 @@ static int _mmc_blk_suspend(struct mmc_card *card)
return 0;
}
-static void mmc_blk_shutdown(struct mmc_card *card)
+static void mmc_blk_shutdown(struct device *dev)
{
- _mmc_blk_suspend(card);
+ _mmc_blk_suspend(dev);
}
-#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card)
+#ifdef CONFIG_PM_SLEEP
+static int mmc_blk_suspend(struct device *dev)
{
- return _mmc_blk_suspend(card);
+ return _mmc_blk_suspend(dev);
}
-static int mmc_blk_resume(struct mmc_card *card)
+static int mmc_blk_resume(struct device *dev)
{
struct mmc_blk_data *part_md;
- struct mmc_blk_data *md = mmc_get_drvdata(card);
+ struct mmc_blk_data *md = dev_get_drvdata(dev);
if (md) {
/*
@@ -2540,19 +2539,15 @@ static int mmc_blk_resume(struct mmc_card *card)
}
return 0;
}
-#else
-#define mmc_blk_suspend NULL
-#define mmc_blk_resume NULL
#endif
-static struct mmc_driver mmc_driver = {
- .drv = {
- .name = "mmcblk",
- },
+static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume);
+
+static struct device_driver mmc_driver = {
+ .name = "mmcblk",
+ .pm = &mmc_blk_pm_ops,
.probe = mmc_blk_probe,
.remove = mmc_blk_remove,
- .suspend = mmc_blk_suspend,
- .resume = mmc_blk_resume,
.shutdown = mmc_blk_shutdown,
};
@@ -2563,7 +2558,7 @@ static int __init mmc_blk_init(void)
if (perdev_minors != CONFIG_MMC_BLOCK_MINORS)
pr_info("mmcblk: using %d minors per device\n", perdev_minors);
- max_devices = 256 / perdev_minors;
+ max_devices = min(MAX_DEVICES, (1 << MINORBITS) / perdev_minors);
res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
if (res)
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 0c0fc52d42c5..0a7430f94d29 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -14,6 +14,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/slab.h>
+#include <linux/device.h>
#include <linux/scatterlist.h>
#include <linux/swap.h> /* For nr_free_buffer_pages() */
@@ -32,6 +33,8 @@
#define BUFFER_ORDER 2
#define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER)
+#define TEST_ALIGN_END 8
+
/*
* Limit the test area size to the maximum MMC HC erase group size. Note that
* the maximum SD allocation unit size is just 4MiB.
@@ -1174,7 +1177,7 @@ static int mmc_test_align_write(struct mmc_test_card *test)
int ret, i;
struct scatterlist sg;
- for (i = 1;i < 4;i++) {
+ for (i = 1; i < TEST_ALIGN_END; i++) {
sg_init_one(&sg, test->buffer + i, 512);
ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
if (ret)
@@ -1189,7 +1192,7 @@ static int mmc_test_align_read(struct mmc_test_card *test)
int ret, i;
struct scatterlist sg;
- for (i = 1;i < 4;i++) {
+ for (i = 1; i < TEST_ALIGN_END; i++) {
sg_init_one(&sg, test->buffer + i, 512);
ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
if (ret)
@@ -1216,7 +1219,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test)
if (size < 1024)
return RESULT_UNSUP_HOST;
- for (i = 1;i < 4;i++) {
+ for (i = 1; i < TEST_ALIGN_END; i++) {
sg_init_one(&sg, test->buffer + i, size);
ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
if (ret)
@@ -1243,7 +1246,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test)
if (size < 1024)
return RESULT_UNSUP_HOST;
- for (i = 1;i < 4;i++) {
+ for (i = 1; i < TEST_ALIGN_END; i++) {
sg_init_one(&sg, test->buffer + i, size);
ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
if (ret)
@@ -2997,8 +3000,9 @@ err:
return ret;
}
-static int mmc_test_probe(struct mmc_card *card)
+static int mmc_test_probe(struct device *dev)
{
+ struct mmc_card *card = mmc_dev_to_card(dev);
int ret;
if (!mmc_card_mmc(card) && !mmc_card_sd(card))
@@ -3013,20 +3017,22 @@ static int mmc_test_probe(struct mmc_card *card)
return 0;
}
-static void mmc_test_remove(struct mmc_card *card)
+static int mmc_test_remove(struct device *dev)
{
+ struct mmc_card *card = mmc_dev_to_card(dev);
+
mmc_test_free_result(card);
mmc_test_free_dbgfs_file(card);
+
+ return 0;
}
-static void mmc_test_shutdown(struct mmc_card *card)
+static void mmc_test_shutdown(struct device *dev)
{
}
-static struct mmc_driver mmc_driver = {
- .drv = {
- .name = "mmc_test",
- },
+static struct device_driver mmc_driver = {
+ .name = "mmc_test",
.probe = mmc_test_probe,
.remove = mmc_test_remove,
.shutdown = mmc_test_shutdown,
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index cfa6110632c3..236d194c2883 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -232,13 +232,15 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
if (!mqrq_cur->bounce_buf) {
pr_warn("%s: unable to allocate bounce cur buffer\n",
mmc_card_name(card));
- }
- mqrq_prev->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
- if (!mqrq_prev->bounce_buf) {
- pr_warn("%s: unable to allocate bounce prev buffer\n",
- mmc_card_name(card));
- kfree(mqrq_cur->bounce_buf);
- mqrq_cur->bounce_buf = NULL;
+ } else {
+ mqrq_prev->bounce_buf =
+ kmalloc(bouncesz, GFP_KERNEL);
+ if (!mqrq_prev->bounce_buf) {
+ pr_warn("%s: unable to allocate bounce prev buffer\n",
+ mmc_card_name(card));
+ kfree(mqrq_cur->bounce_buf);
+ mqrq_cur->bounce_buf = NULL;
+ }
}
}