summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUri Yanai <uri.yanai@sandisk.com>2016-08-14 11:46:36 +0300
committerUlf Hansson <ulf.hansson@linaro.org>2016-09-26 21:31:09 +0200
commit5275a652d296711aaf7f2f4173c8db153e5777c3 (patch)
tree1a3b3c42261e76dcbafb4ba118e4e94a531c36bc /drivers/mmc
parentd51c50525f0a4c6b58fdd493a933017c62d98731 (diff)
downloadlinux-5275a652d296711aaf7f2f4173c8db153e5777c3.tar.gz
linux-5275a652d296711aaf7f2f4173c8db153e5777c3.tar.bz2
linux-5275a652d296711aaf7f2f4173c8db153e5777c3.zip
mmc: sd: Export SD Status via “ssr” device attribute
The SD Status register contains several important fields related to the SD Card proprietary features. Those fields may be used by user space applications for vendor specific usage. None of those fields are exported today by the driver to user space. In this patch, we are reading the SD Status register and exporting (using MMC_DEV_ATTR) the SD Status register to the user space. Signed-off-by: Uri Yanai <uri.yanai@sandisk.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sd.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 0123936241b0..73c762a28dfe 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -223,8 +223,7 @@ static int mmc_decode_scr(struct mmc_card *card)
static int mmc_read_ssr(struct mmc_card *card)
{
unsigned int au, es, et, eo;
- int err, i;
- u32 *ssr;
+ int i;
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
pr_warn("%s: card lacks mandatory SD Status function\n",
@@ -232,33 +231,27 @@ static int mmc_read_ssr(struct mmc_card *card)
return 0;
}
- ssr = kmalloc(64, GFP_KERNEL);
- if (!ssr)
- return -ENOMEM;
-
- err = mmc_app_sd_status(card, ssr);
- if (err) {
+ if (mmc_app_sd_status(card, card->raw_ssr)) {
pr_warn("%s: problem reading SD Status register\n",
mmc_hostname(card->host));
- err = 0;
- goto out;
+ return 0;
}
for (i = 0; i < 16; i++)
- ssr[i] = be32_to_cpu(ssr[i]);
+ card->raw_ssr[i] = be32_to_cpu(card->raw_ssr[i]);
/*
* UNSTUFF_BITS only works with four u32s so we have to offset the
* bitfield positions accordingly.
*/
- au = UNSTUFF_BITS(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(ssr, 408 - 384, 16);
- et = UNSTUFF_BITS(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(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;
}
@@ -267,9 +260,8 @@ static int mmc_read_ssr(struct mmc_card *card)
mmc_hostname(card->host));
}
}
-out:
- kfree(ssr);
- return err;
+
+ return 0;
}
/*
@@ -666,6 +658,14 @@ MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
card->raw_csd[2], card->raw_csd[3]);
MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
+MMC_DEV_ATTR(ssr,
+ "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x\n",
+ card->raw_ssr[0], card->raw_ssr[1], card->raw_ssr[2],
+ card->raw_ssr[3], card->raw_ssr[4], card->raw_ssr[5],
+ card->raw_ssr[6], card->raw_ssr[7], card->raw_ssr[8],
+ card->raw_ssr[9], card->raw_ssr[10], card->raw_ssr[11],
+ card->raw_ssr[12], card->raw_ssr[13], card->raw_ssr[14],
+ card->raw_ssr[15]);
MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9);
MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9);
@@ -698,6 +698,7 @@ static struct attribute *sd_std_attrs[] = {
&dev_attr_cid.attr,
&dev_attr_csd.attr,
&dev_attr_scr.attr,
+ &dev_attr_ssr.attr,
&dev_attr_date.attr,
&dev_attr_erase_size.attr,
&dev_attr_preferred_erase_size.attr,