summaryrefslogtreecommitdiff
path: root/drivers/mmc/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/Kconfig1
-rw-r--r--drivers/mmc/core/block.c250
-rw-r--r--drivers/mmc/core/mmc.c106
-rw-r--r--drivers/mmc/core/mmc_ops.h14
-rw-r--r--drivers/mmc/core/regulator.c8
-rw-r--r--drivers/mmc/core/sd.c133
-rw-r--r--drivers/mmc/core/sd_ops.c3
7 files changed, 373 insertions, 142 deletions
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index bf4e29ef023c..14d2ecbb04d3 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -37,6 +37,7 @@ config PWRSEQ_SIMPLE
config MMC_BLOCK
tristate "MMC block device driver"
depends on BLOCK
+ depends on RPMB || !RPMB
imply IOSCHED_BFQ
default y
help
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 2c9963248fcb..f58bea534004 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -33,6 +33,7 @@
#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
+#include <linux/string.h>
#include <linux/string_helpers.h>
#include <linux/delay.h>
#include <linux/capability.h>
@@ -40,6 +41,7 @@
#include <linux/pm_runtime.h>
#include <linux/idr.h>
#include <linux/debugfs.h>
+#include <linux/rpmb.h>
#include <linux/mmc/ioctl.h>
#include <linux/mmc/card.h>
@@ -76,6 +78,48 @@ MODULE_ALIAS("mmc:block");
#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
#define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8)
+/**
+ * struct rpmb_frame - rpmb frame as defined by eMMC 5.1 (JESD84-B51)
+ *
+ * @stuff : stuff bytes
+ * @key_mac : The authentication key or the message authentication
+ * code (MAC) depending on the request/response type.
+ * The MAC will be delivered in the last (or the only)
+ * block of data.
+ * @data : Data to be written or read by signed access.
+ * @nonce : Random number generated by the host for the requests
+ * and copied to the response by the RPMB engine.
+ * @write_counter: Counter value for the total amount of the successful
+ * authenticated data write requests made by the host.
+ * @addr : Address of the data to be programmed to or read
+ * from the RPMB. Address is the serial number of
+ * the accessed block (half sector 256B).
+ * @block_count : Number of blocks (half sectors, 256B) requested to be
+ * read/programmed.
+ * @result : Includes information about the status of the write counter
+ * (valid, expired) and result of the access made to the RPMB.
+ * @req_resp : Defines the type of request and response to/from the memory.
+ *
+ * The stuff bytes and big-endian properties are modeled to fit to the spec.
+ */
+struct rpmb_frame {
+ u8 stuff[196];
+ u8 key_mac[32];
+ u8 data[256];
+ u8 nonce[16];
+ __be32 write_counter;
+ __be16 addr;
+ __be16 block_count;
+ __be16 result;
+ __be16 req_resp;
+} __packed;
+
+#define RPMB_PROGRAM_KEY 0x1 /* Program RPMB Authentication Key */
+#define RPMB_GET_WRITE_COUNTER 0x2 /* Read RPMB write counter */
+#define RPMB_WRITE_DATA 0x3 /* Write data to RPMB partition */
+#define RPMB_READ_DATA 0x4 /* Read data from RPMB partition */
+#define RPMB_RESULT_READ 0x5 /* Read result request (Internal) */
+
static DEFINE_MUTEX(block_mutex);
/*
@@ -155,6 +199,7 @@ static const struct bus_type mmc_rpmb_bus_type = {
* @id: unique device ID number
* @part_index: partition index (0 on first)
* @md: parent MMC block device
+ * @rdev: registered RPMB device
* @node: list item, so we can put this device on a list
*/
struct mmc_rpmb_data {
@@ -163,6 +208,7 @@ struct mmc_rpmb_data {
int id;
unsigned int part_index;
struct mmc_blk_data *md;
+ struct rpmb_dev *rdev;
struct list_head node;
};
@@ -307,10 +353,10 @@ static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
- char *end;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
- unsigned long set = simple_strtoul(buf, &end, 0);
- if (end == buf) {
+ unsigned long set;
+
+ if (kstrtoul(buf, 0, &set)) {
ret = -EINVAL;
goto out;
}
@@ -2484,7 +2530,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
return ERR_PTR(devidx);
}
- md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
+ md = kzalloc(sizeof(*md), GFP_KERNEL);
if (!md) {
ret = -ENOMEM;
goto out;
@@ -2670,7 +2716,6 @@ static int mmc_rpmb_chrdev_open(struct inode *inode, struct file *filp)
get_device(&rpmb->dev);
filp->private_data = rpmb;
- mmc_blk_get(rpmb->md->disk);
return nonseekable_open(inode, filp);
}
@@ -2680,7 +2725,6 @@ static int mmc_rpmb_chrdev_release(struct inode *inode, struct file *filp)
struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev,
struct mmc_rpmb_data, chrdev);
- mmc_blk_put(rpmb->md);
put_device(&rpmb->dev);
return 0;
@@ -2701,10 +2745,165 @@ static void mmc_blk_rpmb_device_release(struct device *dev)
{
struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev);
+ rpmb_dev_unregister(rpmb->rdev);
+ mmc_blk_put(rpmb->md);
ida_free(&mmc_rpmb_ida, rpmb->id);
kfree(rpmb);
}
+static void free_idata(struct mmc_blk_ioc_data **idata, unsigned int cmd_count)
+{
+ unsigned int n;
+
+ for (n = 0; n < cmd_count; n++)
+ kfree(idata[n]);
+ kfree(idata);
+}
+
+static struct mmc_blk_ioc_data **alloc_idata(struct mmc_rpmb_data *rpmb,
+ unsigned int cmd_count)
+{
+ struct mmc_blk_ioc_data **idata;
+ unsigned int n;
+
+ idata = kcalloc(cmd_count, sizeof(*idata), GFP_KERNEL);
+ if (!idata)
+ return NULL;
+
+ for (n = 0; n < cmd_count; n++) {
+ idata[n] = kcalloc(1, sizeof(**idata), GFP_KERNEL);
+ if (!idata[n]) {
+ free_idata(idata, n);
+ return NULL;
+ }
+ idata[n]->rpmb = rpmb;
+ }
+
+ return idata;
+}
+
+static void set_idata(struct mmc_blk_ioc_data *idata, u32 opcode,
+ int write_flag, u8 *buf, unsigned int buf_bytes)
+{
+ /*
+ * The size of an RPMB frame must match what's expected by the
+ * hardware.
+ */
+ BUILD_BUG_ON(sizeof(struct rpmb_frame) != 512);
+
+ idata->ic.opcode = opcode;
+ idata->ic.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+ idata->ic.write_flag = write_flag;
+ idata->ic.blksz = sizeof(struct rpmb_frame);
+ idata->ic.blocks = buf_bytes / idata->ic.blksz;
+ idata->buf = buf;
+ idata->buf_bytes = buf_bytes;
+}
+
+static int mmc_route_rpmb_frames(struct device *dev, u8 *req,
+ unsigned int req_len, u8 *resp,
+ unsigned int resp_len)
+{
+ struct rpmb_frame *frm = (struct rpmb_frame *)req;
+ struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev);
+ struct mmc_blk_data *md = rpmb->md;
+ struct mmc_blk_ioc_data **idata;
+ struct mmc_queue_req *mq_rq;
+ unsigned int cmd_count;
+ struct request *rq;
+ u16 req_type;
+ bool write;
+ int ret;
+
+ if (IS_ERR(md->queue.card))
+ return PTR_ERR(md->queue.card);
+
+ if (req_len < sizeof(*frm))
+ return -EINVAL;
+
+ req_type = be16_to_cpu(frm->req_resp);
+ switch (req_type) {
+ case RPMB_PROGRAM_KEY:
+ if (req_len != sizeof(struct rpmb_frame) ||
+ resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ write = true;
+ break;
+ case RPMB_GET_WRITE_COUNTER:
+ if (req_len != sizeof(struct rpmb_frame) ||
+ resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ write = false;
+ break;
+ case RPMB_WRITE_DATA:
+ if (req_len % sizeof(struct rpmb_frame) ||
+ resp_len != sizeof(struct rpmb_frame))
+ return -EINVAL;
+ write = true;
+ break;
+ case RPMB_READ_DATA:
+ if (req_len != sizeof(struct rpmb_frame) ||
+ resp_len % sizeof(struct rpmb_frame))
+ return -EINVAL;
+ write = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (write)
+ cmd_count = 3;
+ else
+ cmd_count = 2;
+
+ idata = alloc_idata(rpmb, cmd_count);
+ if (!idata)
+ return -ENOMEM;
+
+ if (write) {
+ struct rpmb_frame *frm = (struct rpmb_frame *)resp;
+
+ /* Send write request frame(s) */
+ set_idata(idata[0], MMC_WRITE_MULTIPLE_BLOCK,
+ 1 | MMC_CMD23_ARG_REL_WR, req, req_len);
+
+ /* Send result request frame */
+ memset(frm, 0, sizeof(*frm));
+ frm->req_resp = cpu_to_be16(RPMB_RESULT_READ);
+ set_idata(idata[1], MMC_WRITE_MULTIPLE_BLOCK, 1, resp,
+ resp_len);
+
+ /* Read response frame */
+ set_idata(idata[2], MMC_READ_MULTIPLE_BLOCK, 0, resp, resp_len);
+ } else {
+ /* Send write request frame(s) */
+ set_idata(idata[0], MMC_WRITE_MULTIPLE_BLOCK, 1, req, req_len);
+
+ /* Read response frame */
+ set_idata(idata[1], MMC_READ_MULTIPLE_BLOCK, 0, resp, resp_len);
+ }
+
+ rq = blk_mq_alloc_request(md->queue.queue, REQ_OP_DRV_OUT, 0);
+ if (IS_ERR(rq)) {
+ ret = PTR_ERR(rq);
+ goto out;
+ }
+
+ mq_rq = req_to_mmc_queue_req(rq);
+ mq_rq->drv_op = MMC_DRV_OP_IOCTL_RPMB;
+ mq_rq->drv_op_result = -EIO;
+ mq_rq->drv_op_data = idata;
+ mq_rq->ioc_count = cmd_count;
+ blk_execute_rq(rq, false);
+ ret = req_to_mmc_queue_req(rq)->drv_op_result;
+
+ blk_mq_free_request(rq);
+
+out:
+ free_idata(idata, cmd_count);
+ return ret;
+}
+
static int mmc_blk_alloc_rpmb_part(struct mmc_card *card,
struct mmc_blk_data *md,
unsigned int part_index,
@@ -2739,6 +2938,7 @@ static int mmc_blk_alloc_rpmb_part(struct mmc_card *card,
rpmb->dev.release = mmc_blk_rpmb_device_release;
device_initialize(&rpmb->dev);
dev_set_drvdata(&rpmb->dev, rpmb);
+ mmc_blk_get(md->disk);
rpmb->md = md;
cdev_init(&rpmb->chrdev, &mmc_rpmb_fileops);
@@ -3000,6 +3200,42 @@ static void mmc_blk_remove_debugfs(struct mmc_card *card,
#endif /* CONFIG_DEBUG_FS */
+static void mmc_blk_rpmb_add(struct mmc_card *card)
+{
+ struct mmc_blk_data *md = dev_get_drvdata(&card->dev);
+ struct mmc_rpmb_data *rpmb;
+ struct rpmb_dev *rdev;
+ unsigned int n;
+ u32 cid[4];
+ struct rpmb_descr descr = {
+ .type = RPMB_TYPE_EMMC,
+ .route_frames = mmc_route_rpmb_frames,
+ .reliable_wr_count = card->ext_csd.enhanced_rpmb_supported ?
+ 2 : 32,
+ .capacity = card->ext_csd.raw_rpmb_size_mult,
+ .dev_id = (void *)cid,
+ .dev_id_len = sizeof(cid),
+ };
+
+ /*
+ * Provice CID as an octet array. The CID needs to be interpreted
+ * when used as input to derive the RPMB key since some fields
+ * will change due to firmware updates.
+ */
+ for (n = 0; n < 4; n++)
+ cid[n] = be32_to_cpu((__force __be32)card->raw_cid[n]);
+
+ list_for_each_entry(rpmb, &md->rpmbs, node) {
+ rdev = rpmb_dev_register(&rpmb->dev, &descr);
+ if (IS_ERR(rdev)) {
+ pr_warn("%s: could not register RPMB device\n",
+ dev_name(&rpmb->dev));
+ continue;
+ }
+ rpmb->rdev = rdev;
+ }
+}
+
static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md;
@@ -3045,6 +3281,8 @@ static int mmc_blk_probe(struct mmc_card *card)
pm_runtime_enable(&card->dev);
}
+ mmc_blk_rpmb_add(card);
+
return 0;
out:
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 5b2f7c285461..6a23be214543 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -51,20 +51,6 @@ static const unsigned int taac_mant[] = {
35, 40, 45, 50, 55, 60, 70, 80,
};
-#define UNSTUFF_BITS(resp,start,size) \
- ({ \
- const int __size = size; \
- const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
- const int __off = 3 - ((start) / 32); \
- const int __shft = (start) & 31; \
- u32 __res; \
- \
- __res = resp[__off] >> __shft; \
- if (__size + __shft > 32) \
- __res |= resp[__off-1] << ((32 - __shft) % 32); \
- __res & __mask; \
- })
-
/*
* Given the decoded CSD structure, decode the raw CID to our CID structure.
*/
@@ -85,36 +71,36 @@ static int mmc_decode_cid(struct mmc_card *card)
switch (card->csd.mmca_vsn) {
case 0: /* MMC v1.0 - v1.2 */
case 1: /* MMC v1.4 */
- card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
- card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
- card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
- card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
- card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
- card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
- card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
- card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
- card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
- card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
- card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
- card->cid.month = UNSTUFF_BITS(resp, 12, 4);
- card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
+ card->cid.manfid = unstuff_bits(resp, 104, 24);
+ card->cid.prod_name[0] = unstuff_bits(resp, 96, 8);
+ card->cid.prod_name[1] = unstuff_bits(resp, 88, 8);
+ card->cid.prod_name[2] = unstuff_bits(resp, 80, 8);
+ card->cid.prod_name[3] = unstuff_bits(resp, 72, 8);
+ card->cid.prod_name[4] = unstuff_bits(resp, 64, 8);
+ card->cid.prod_name[5] = unstuff_bits(resp, 56, 8);
+ card->cid.prod_name[6] = unstuff_bits(resp, 48, 8);
+ card->cid.hwrev = unstuff_bits(resp, 44, 4);
+ card->cid.fwrev = unstuff_bits(resp, 40, 4);
+ card->cid.serial = unstuff_bits(resp, 16, 24);
+ card->cid.month = unstuff_bits(resp, 12, 4);
+ card->cid.year = unstuff_bits(resp, 8, 4) + 1997;
break;
case 2: /* MMC v2.0 - v2.2 */
case 3: /* MMC v3.1 - v3.3 */
case 4: /* MMC v4 */
- card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
- card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
- card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
- card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
- card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
- card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
- card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
- card->cid.prv = UNSTUFF_BITS(resp, 48, 8);
- card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
- card->cid.month = UNSTUFF_BITS(resp, 12, 4);
- card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
+ card->cid.manfid = unstuff_bits(resp, 120, 8);
+ card->cid.oemid = unstuff_bits(resp, 104, 16);
+ card->cid.prod_name[0] = unstuff_bits(resp, 96, 8);
+ card->cid.prod_name[1] = unstuff_bits(resp, 88, 8);
+ card->cid.prod_name[2] = unstuff_bits(resp, 80, 8);
+ card->cid.prod_name[3] = unstuff_bits(resp, 72, 8);
+ card->cid.prod_name[4] = unstuff_bits(resp, 64, 8);
+ card->cid.prod_name[5] = unstuff_bits(resp, 56, 8);
+ card->cid.prv = unstuff_bits(resp, 48, 8);
+ card->cid.serial = unstuff_bits(resp, 16, 32);
+ card->cid.month = unstuff_bits(resp, 12, 4);
+ card->cid.year = unstuff_bits(resp, 8, 4) + 1997;
break;
default:
@@ -161,43 +147,43 @@ static int mmc_decode_csd(struct mmc_card *card)
* v1.2 has extra information in bits 15, 11 and 10.
* We also support eMMC v4.4 & v4.41.
*/
- csd->structure = UNSTUFF_BITS(resp, 126, 2);
+ csd->structure = unstuff_bits(resp, 126, 2);
if (csd->structure == 0) {
pr_err("%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd->structure);
return -EINVAL;
}
- csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
- m = UNSTUFF_BITS(resp, 115, 4);
- e = UNSTUFF_BITS(resp, 112, 3);
+ csd->mmca_vsn = unstuff_bits(resp, 122, 4);
+ m = unstuff_bits(resp, 115, 4);
+ e = unstuff_bits(resp, 112, 3);
csd->taac_ns = (taac_exp[e] * taac_mant[m] + 9) / 10;
- csd->taac_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
+ csd->taac_clks = unstuff_bits(resp, 104, 8) * 100;
- m = UNSTUFF_BITS(resp, 99, 4);
- e = UNSTUFF_BITS(resp, 96, 3);
+ m = unstuff_bits(resp, 99, 4);
+ e = unstuff_bits(resp, 96, 3);
csd->max_dtr = tran_exp[e] * tran_mant[m];
- csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+ csd->cmdclass = unstuff_bits(resp, 84, 12);
- e = UNSTUFF_BITS(resp, 47, 3);
- m = UNSTUFF_BITS(resp, 62, 12);
+ e = unstuff_bits(resp, 47, 3);
+ m = unstuff_bits(resp, 62, 12);
csd->capacity = (1 + m) << (e + 2);
- csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
- csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
- csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
- csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
- csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1);
- csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
- csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
- csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+ csd->read_blkbits = unstuff_bits(resp, 80, 4);
+ csd->read_partial = unstuff_bits(resp, 79, 1);
+ csd->write_misalign = unstuff_bits(resp, 78, 1);
+ csd->read_misalign = unstuff_bits(resp, 77, 1);
+ csd->dsr_imp = unstuff_bits(resp, 76, 1);
+ csd->r2w_factor = unstuff_bits(resp, 26, 3);
+ csd->write_blkbits = unstuff_bits(resp, 22, 4);
+ csd->write_partial = unstuff_bits(resp, 21, 1);
if (csd->write_blkbits >= 9) {
- a = UNSTUFF_BITS(resp, 42, 5);
- b = UNSTUFF_BITS(resp, 37, 5);
+ a = unstuff_bits(resp, 42, 5);
+ b = unstuff_bits(resp, 37, 5);
csd->erase_size = (a + 1) * (b + 1);
csd->erase_size <<= csd->write_blkbits - 9;
- csd->wp_grp_size = UNSTUFF_BITS(resp, 32, 5);
+ csd->wp_grp_size = unstuff_bits(resp, 32, 5);
}
return 0;
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 92d4194c7893..06017110e1b0 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -56,5 +56,19 @@ int mmc_cmdq_enable(struct mmc_card *card);
int mmc_cmdq_disable(struct mmc_card *card);
int mmc_sanitize(struct mmc_card *card, unsigned int timeout_ms);
+static inline u32 unstuff_bits(const u32 *resp, int start, int size)
+{
+ const int __size = size;
+ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;
+ const int __off = 3 - (start / 32);
+ const int __shft = start & 31;
+ u32 __res = resp[__off] >> __shft;
+
+ if (__size + __shft > 32)
+ __res |= resp[__off - 1] << ((32 - __shft) % 32);
+
+ return __res & __mask;
+}
+
#endif
diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c
index 005247a49e51..01747ab1024e 100644
--- a/drivers/mmc/core/regulator.c
+++ b/drivers/mmc/core/regulator.c
@@ -255,7 +255,9 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)
if (IS_ERR(mmc->supply.vmmc)) {
if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "vmmc regulator not available\n");
+
dev_dbg(dev, "No vmmc regulator found\n");
} else {
ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
@@ -267,7 +269,9 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)
if (IS_ERR(mmc->supply.vqmmc)) {
if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "vqmmc regulator not available\n");
+
dev_dbg(dev, "No vqmmc regulator found\n");
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index ee37ad14e79e..12fe282bea77 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -56,20 +56,6 @@ static const unsigned int sd_au_size[] = {
SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512,
};
-#define UNSTUFF_BITS(resp,start,size) \
- ({ \
- const int __size = size; \
- const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
- const int __off = 3 - ((start) / 32); \
- const int __shft = (start) & 31; \
- u32 __res; \
- \
- __res = resp[__off] >> __shft; \
- if (__size + __shft > 32) \
- __res |= resp[__off-1] << ((32 - __shft) % 32); \
- __res & __mask; \
- })
-
#define SD_POWEROFF_NOTIFY_TIMEOUT_MS 1000
#define SD_WRITE_EXTR_SINGLE_TIMEOUT_MS 1000
@@ -95,18 +81,18 @@ void mmc_decode_cid(struct mmc_card *card)
* SD doesn't currently have a version field so we will
* have to assume we can parse this.
*/
- card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
- card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
- card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
- card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
- card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
- card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
- card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4);
- card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4);
- card->cid.serial = UNSTUFF_BITS(resp, 24, 32);
- card->cid.year = UNSTUFF_BITS(resp, 12, 8);
- card->cid.month = UNSTUFF_BITS(resp, 8, 4);
+ card->cid.manfid = unstuff_bits(resp, 120, 8);
+ card->cid.oemid = unstuff_bits(resp, 104, 16);
+ card->cid.prod_name[0] = unstuff_bits(resp, 96, 8);
+ card->cid.prod_name[1] = unstuff_bits(resp, 88, 8);
+ card->cid.prod_name[2] = unstuff_bits(resp, 80, 8);
+ card->cid.prod_name[3] = unstuff_bits(resp, 72, 8);
+ card->cid.prod_name[4] = unstuff_bits(resp, 64, 8);
+ card->cid.hwrev = unstuff_bits(resp, 60, 4);
+ card->cid.fwrev = unstuff_bits(resp, 56, 4);
+ card->cid.serial = unstuff_bits(resp, 24, 32);
+ card->cid.year = unstuff_bits(resp, 12, 8);
+ card->cid.month = unstuff_bits(resp, 8, 4);
card->cid.year += 2000; /* SD cards year offset */
}
@@ -120,41 +106,41 @@ static int mmc_decode_csd(struct mmc_card *card)
unsigned int e, m, csd_struct;
u32 *resp = card->raw_csd;
- csd_struct = UNSTUFF_BITS(resp, 126, 2);
+ csd_struct = unstuff_bits(resp, 126, 2);
switch (csd_struct) {
case 0:
- m = UNSTUFF_BITS(resp, 115, 4);
- e = UNSTUFF_BITS(resp, 112, 3);
+ m = unstuff_bits(resp, 115, 4);
+ e = unstuff_bits(resp, 112, 3);
csd->taac_ns = (taac_exp[e] * taac_mant[m] + 9) / 10;
- csd->taac_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
+ csd->taac_clks = unstuff_bits(resp, 104, 8) * 100;
- m = UNSTUFF_BITS(resp, 99, 4);
- e = UNSTUFF_BITS(resp, 96, 3);
+ m = unstuff_bits(resp, 99, 4);
+ e = unstuff_bits(resp, 96, 3);
csd->max_dtr = tran_exp[e] * tran_mant[m];
- csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
+ csd->cmdclass = unstuff_bits(resp, 84, 12);
- e = UNSTUFF_BITS(resp, 47, 3);
- m = UNSTUFF_BITS(resp, 62, 12);
+ e = unstuff_bits(resp, 47, 3);
+ m = unstuff_bits(resp, 62, 12);
csd->capacity = (1 + m) << (e + 2);
- csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
- csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
- csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
- csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
- csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1);
- csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
- csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
- csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+ csd->read_blkbits = unstuff_bits(resp, 80, 4);
+ csd->read_partial = unstuff_bits(resp, 79, 1);
+ csd->write_misalign = unstuff_bits(resp, 78, 1);
+ csd->read_misalign = unstuff_bits(resp, 77, 1);
+ csd->dsr_imp = unstuff_bits(resp, 76, 1);
+ csd->r2w_factor = unstuff_bits(resp, 26, 3);
+ csd->write_blkbits = unstuff_bits(resp, 22, 4);
+ csd->write_partial = unstuff_bits(resp, 21, 1);
- if (UNSTUFF_BITS(resp, 46, 1)) {
+ if (unstuff_bits(resp, 46, 1)) {
csd->erase_size = 1;
} else if (csd->write_blkbits >= 9) {
- csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1;
+ csd->erase_size = unstuff_bits(resp, 39, 7) + 1;
csd->erase_size <<= csd->write_blkbits - 9;
}
- if (UNSTUFF_BITS(resp, 13, 1))
+ if (unstuff_bits(resp, 13, 1))
mmc_card_set_readonly(card);
break;
case 1:
@@ -169,17 +155,17 @@ static int mmc_decode_csd(struct mmc_card *card)
csd->taac_ns = 0; /* Unused */
csd->taac_clks = 0; /* Unused */
- m = UNSTUFF_BITS(resp, 99, 4);
- e = UNSTUFF_BITS(resp, 96, 3);
+ m = unstuff_bits(resp, 99, 4);
+ e = unstuff_bits(resp, 96, 3);
csd->max_dtr = tran_exp[e] * tran_mant[m];
- csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
- csd->c_size = UNSTUFF_BITS(resp, 48, 22);
+ csd->cmdclass = unstuff_bits(resp, 84, 12);
+ csd->c_size = unstuff_bits(resp, 48, 22);
/* SDXC cards have a minimum C_SIZE of 0x00FFFF */
if (csd->c_size >= 0xFFFF)
mmc_card_set_ext_capacity(card);
- m = UNSTUFF_BITS(resp, 48, 22);
+ m = unstuff_bits(resp, 48, 22);
csd->capacity = (1 + m) << 10;
csd->read_blkbits = 9;
@@ -191,7 +177,7 @@ static int mmc_decode_csd(struct mmc_card *card)
csd->write_partial = 0;
csd->erase_size = 1;
- if (UNSTUFF_BITS(resp, 13, 1))
+ if (unstuff_bits(resp, 13, 1))
mmc_card_set_readonly(card);
break;
default:
@@ -217,33 +203,33 @@ static int mmc_decode_scr(struct mmc_card *card)
resp[3] = card->raw_scr[1];
resp[2] = card->raw_scr[0];
- scr_struct = UNSTUFF_BITS(resp, 60, 4);
+ scr_struct = unstuff_bits(resp, 60, 4);
if (scr_struct != 0) {
pr_err("%s: unrecognised SCR structure version %d\n",
mmc_hostname(card->host), scr_struct);
return -EINVAL;
}
- scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
- scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
+ scr->sda_vsn = unstuff_bits(resp, 56, 4);
+ scr->bus_widths = unstuff_bits(resp, 48, 4);
if (scr->sda_vsn == SCR_SPEC_VER_2)
/* Check if Physical Layer Spec v3.0 is supported */
- scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
+ scr->sda_spec3 = unstuff_bits(resp, 47, 1);
if (scr->sda_spec3) {
- scr->sda_spec4 = UNSTUFF_BITS(resp, 42, 1);
- scr->sda_specx = UNSTUFF_BITS(resp, 38, 4);
+ scr->sda_spec4 = unstuff_bits(resp, 42, 1);
+ scr->sda_specx = unstuff_bits(resp, 38, 4);
}
- if (UNSTUFF_BITS(resp, 55, 1))
+ if (unstuff_bits(resp, 55, 1))
card->erased_byte = 0xFF;
else
card->erased_byte = 0x0;
if (scr->sda_spec4)
- scr->cmds = UNSTUFF_BITS(resp, 32, 4);
+ scr->cmds = unstuff_bits(resp, 32, 4);
else if (scr->sda_spec3)
- scr->cmds = UNSTUFF_BITS(resp, 32, 2);
+ scr->cmds = unstuff_bits(resp, 32, 2);
/* SD Spec says: any SD Card shall set at least bits 0 and 2 */
if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) ||
@@ -289,17 +275,17 @@ static int mmc_read_ssr(struct mmc_card *card)
kfree(raw_ssr);
/*
- * UNSTUFF_BITS only works with four u32s so we have to offset the
+ * unstuff_bits only works with four u32s so we have to offset the
* bitfield positions accordingly.
*/
- au = UNSTUFF_BITS(card->raw_ssr, 428 - 384, 4);
+ au = unstuff_bits(card->raw_ssr, 428 - 384, 4);
if (au) {
if (au <= 9 || card->scr.sda_spec3) {
card->ssr.au = sd_au_size[au];
- es = UNSTUFF_BITS(card->raw_ssr, 408 - 384, 16);
- et = UNSTUFF_BITS(card->raw_ssr, 402 - 384, 6);
+ es = unstuff_bits(card->raw_ssr, 408 - 384, 16);
+ et = unstuff_bits(card->raw_ssr, 402 - 384, 6);
if (es && et) {
- eo = UNSTUFF_BITS(card->raw_ssr, 400 - 384, 2);
+ eo = unstuff_bits(card->raw_ssr, 400 - 384, 2);
card->ssr.erase_timeout = (et * 1000) / es;
card->ssr.erase_offset = eo * 1000;
}
@@ -313,7 +299,7 @@ static int mmc_read_ssr(struct mmc_card *card)
* starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set
*/
resp[3] = card->raw_ssr[6];
- discard_support = UNSTUFF_BITS(resp, 313 - 288, 1);
+ discard_support = unstuff_bits(resp, 313 - 288, 1);
card->erase_arg = (card->scr.sda_specx && discard_support) ?
SD_DISCARD_ARG : SD_ERASE_ARG;
@@ -346,7 +332,7 @@ static int mmc_read_switch(struct mmc_card *card)
* The argument does not matter, as the support bits do not
* change with the arguments.
*/
- err = mmc_sd_switch(card, 0, 0, 0, status);
+ err = mmc_sd_switch(card, SD_SWITCH_CHECK, 0, 0, status);
if (err) {
/*
* If the host or the card can't do the switch,
@@ -402,7 +388,8 @@ int mmc_sd_switch_hs(struct mmc_card *card)
if (!status)
return -ENOMEM;
- err = mmc_sd_switch(card, 1, 0, HIGH_SPEED_BUS_SPEED, status);
+ err = mmc_sd_switch(card, SD_SWITCH_SET, 0,
+ HIGH_SPEED_BUS_SPEED, status);
if (err)
goto out;
@@ -434,7 +421,8 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
card_drv_type, &drv_type);
if (drive_strength) {
- err = mmc_sd_switch(card, 1, 2, drive_strength, status);
+ err = mmc_sd_switch(card, SD_SWITCH_SET, 2,
+ drive_strength, status);
if (err)
return err;
if ((status[15] & 0xF) != drive_strength) {
@@ -514,7 +502,7 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
return 0;
}
- err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status);
+ err = mmc_sd_switch(card, SD_SWITCH_SET, 0, card->sd_bus_speed, status);
if (err)
return err;
@@ -605,7 +593,8 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
current_limit = SD_SET_CURRENT_LIMIT_200;
if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
- err = mmc_sd_switch(card, 1, 3, current_limit, status);
+ err = mmc_sd_switch(card, SD_SWITCH_SET, 3,
+ current_limit, status);
if (err)
return err;
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 8b9b34286ef3..f93c392040ae 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -336,14 +336,13 @@ int mmc_app_send_scr(struct mmc_card *card)
return 0;
}
-int mmc_sd_switch(struct mmc_card *card, int mode, int group,
+int mmc_sd_switch(struct mmc_card *card, bool mode, int group,
u8 value, u8 *resp)
{
u32 cmd_args;
/* NOTE: caller guarantees resp is heap-allocated */
- mode = !!mode;
value &= 0xF;
cmd_args = mode << 31 | 0x00FFFFFF;
cmd_args &= ~(0xF << (group * 4));