]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 27 Jul 2008 03:27:31 +0000 (20:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 27 Jul 2008 03:27:31 +0000 (20:27 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
  atmel-mci: debugfs support
  mmc: Add per-card debugfs support
  mmc: Export internal host state through debugfs
  imxmmc: fix crash when no platform data is provided
  imxmmc: fix platform resources
  imxmmc: remove DEBUG definition
  mmc_spi: put signals to low power off fix

drivers/mmc/core/Makefile
drivers/mmc/core/bus.c
drivers/mmc/core/core.h
drivers/mmc/core/debugfs.c [new file with mode: 0644]
drivers/mmc/core/host.c
drivers/mmc/host/atmel-mci-regs.h
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/imxmmc.c
drivers/mmc/host/mmc_spi.c
include/linux/mmc/card.h
include/linux/mmc/host.h

index 19a1a254a0c5f81d8e0a36815caf4b870b6497cc..889e5f898f6f99485c6b031aee41f5a6ff86d0aa 100644 (file)
@@ -12,3 +12,4 @@ mmc_core-y                    := core.o bus.o host.o \
                                   sdio.o sdio_ops.o sdio_bus.o \
                                   sdio_cis.o sdio_io.o sdio_irq.o
 
+mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
index fd95b18e988b3c33496c309f41dcc38356a82c47..0d9b2d6f9ebfba638b2bba41a0a0f6d28c922cc6 100644 (file)
@@ -252,6 +252,10 @@ int mmc_add_card(struct mmc_card *card)
        if (ret)
                return ret;
 
+#ifdef CONFIG_DEBUG_FS
+       mmc_add_card_debugfs(card);
+#endif
+
        mmc_card_set_present(card);
 
        return 0;
@@ -263,6 +267,10 @@ int mmc_add_card(struct mmc_card *card)
  */
 void mmc_remove_card(struct mmc_card *card)
 {
+#ifdef CONFIG_DEBUG_FS
+       mmc_remove_card_debugfs(card);
+#endif
+
        if (mmc_card_present(card)) {
                if (mmc_host_is_spi(card->host)) {
                        printk(KERN_INFO "%s: SPI card removed\n",
index cdb332b7dedc87340ef5ff0aacedc71f8b4fe931..c819effa1032c5ccebf896dff58d78f6e7ca13d5 100644 (file)
@@ -52,5 +52,12 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
 
 extern int use_spi_crc;
 
+/* Debugfs information for hosts and cards */
+void mmc_add_host_debugfs(struct mmc_host *host);
+void mmc_remove_host_debugfs(struct mmc_host *host);
+
+void mmc_add_card_debugfs(struct mmc_card *card);
+void mmc_remove_card_debugfs(struct mmc_card *card);
+
 #endif
 
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
new file mode 100644 (file)
index 0000000..1237bb4
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Debugfs support for hosts and cards
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/stat.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include "core.h"
+#include "mmc_ops.h"
+
+/* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */
+static int mmc_ios_show(struct seq_file *s, void *data)
+{
+       static const char *vdd_str[] = {
+               [8]     = "2.0",
+               [9]     = "2.1",
+               [10]    = "2.2",
+               [11]    = "2.3",
+               [12]    = "2.4",
+               [13]    = "2.5",
+               [14]    = "2.6",
+               [15]    = "2.7",
+               [16]    = "2.8",
+               [17]    = "2.9",
+               [18]    = "3.0",
+               [19]    = "3.1",
+               [20]    = "3.2",
+               [21]    = "3.3",
+               [22]    = "3.4",
+               [23]    = "3.5",
+               [24]    = "3.6",
+       };
+       struct mmc_host *host = s->private;
+       struct mmc_ios  *ios = &host->ios;
+       const char *str;
+
+       seq_printf(s, "clock:\t\t%u Hz\n", ios->clock);
+       seq_printf(s, "vdd:\t\t%u ", ios->vdd);
+       if ((1 << ios->vdd) & MMC_VDD_165_195)
+               seq_printf(s, "(1.65 - 1.95 V)\n");
+       else if (ios->vdd < (ARRAY_SIZE(vdd_str) - 1)
+                       && vdd_str[ios->vdd] && vdd_str[ios->vdd + 1])
+               seq_printf(s, "(%s ~ %s V)\n", vdd_str[ios->vdd],
+                               vdd_str[ios->vdd + 1]);
+       else
+               seq_printf(s, "(invalid)\n");
+
+       switch (ios->bus_mode) {
+       case MMC_BUSMODE_OPENDRAIN:
+               str = "open drain";
+               break;
+       case MMC_BUSMODE_PUSHPULL:
+               str = "push-pull";
+               break;
+       default:
+               str = "invalid";
+               break;
+       }
+       seq_printf(s, "bus mode:\t%u (%s)\n", ios->bus_mode, str);
+
+       switch (ios->chip_select) {
+       case MMC_CS_DONTCARE:
+               str = "don't care";
+               break;
+       case MMC_CS_HIGH:
+               str = "active high";
+               break;
+       case MMC_CS_LOW:
+               str = "active low";
+               break;
+       default:
+               str = "invalid";
+               break;
+       }
+       seq_printf(s, "chip select:\t%u (%s)\n", ios->chip_select, str);
+
+       switch (ios->power_mode) {
+       case MMC_POWER_OFF:
+               str = "off";
+               break;
+       case MMC_POWER_UP:
+               str = "up";
+               break;
+       case MMC_POWER_ON:
+               str = "on";
+               break;
+       default:
+               str = "invalid";
+               break;
+       }
+       seq_printf(s, "power mode:\t%u (%s)\n", ios->power_mode, str);
+       seq_printf(s, "bus width:\t%u (%u bits)\n",
+                       ios->bus_width, 1 << ios->bus_width);
+
+       switch (ios->timing) {
+       case MMC_TIMING_LEGACY:
+               str = "legacy";
+               break;
+       case MMC_TIMING_MMC_HS:
+               str = "mmc high-speed";
+               break;
+       case MMC_TIMING_SD_HS:
+               str = "sd high-speed";
+               break;
+       default:
+               str = "invalid";
+               break;
+       }
+       seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str);
+
+       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,
+};
+
+void mmc_add_host_debugfs(struct mmc_host *host)
+{
+       struct dentry *root;
+
+       root = debugfs_create_dir(mmc_hostname(host), NULL);
+       if (IS_ERR(root))
+               /* Don't complain -- debugfs just isn't enabled */
+               return;
+       if (!root)
+               /* Complain -- debugfs is enabled, but it failed to
+                * create the directory. */
+               goto err_root;
+
+       host->debugfs_root = root;
+
+       if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops))
+               goto err_ios;
+
+       return;
+
+err_ios:
+       debugfs_remove_recursive(root);
+       host->debugfs_root = NULL;
+err_root:
+       dev_err(&host->class_dev, "failed to initialize debugfs\n");
+}
+
+void mmc_remove_host_debugfs(struct mmc_host *host)
+{
+       debugfs_remove_recursive(host->debugfs_root);
+}
+
+static int mmc_dbg_card_status_get(void *data, u64 *val)
+{
+       struct mmc_card *card = data;
+       u32             status;
+       int             ret;
+
+       mmc_claim_host(card->host);
+
+       ret = mmc_send_status(data, &status);
+       if (!ret)
+               *val = status;
+
+       mmc_release_host(card->host);
+
+       return ret;
+}
+DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
+               NULL, "%08llx\n");
+
+void mmc_add_card_debugfs(struct mmc_card *card)
+{
+       struct mmc_host *host = card->host;
+       struct dentry   *root;
+
+       if (!host->debugfs_root)
+               return;
+
+       root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root);
+       if (IS_ERR(root))
+               /* Don't complain -- debugfs just isn't enabled */
+               return;
+       if (!root)
+               /* Complain -- debugfs is enabled, but it failed to
+                * create the directory. */
+               goto err;
+
+       card->debugfs_root = root;
+
+       if (!debugfs_create_x32("state", S_IRUSR, root, &card->state))
+               goto err;
+
+       if (mmc_card_mmc(card) || mmc_card_sd(card))
+               if (!debugfs_create_file("status", S_IRUSR, root, card,
+                                       &mmc_dbg_card_status_fops))
+                       goto err;
+
+       return;
+
+err:
+       debugfs_remove_recursive(root);
+       card->debugfs_root = NULL;
+       dev_err(&card->dev, "failed to initialize debugfs\n");
+}
+
+void mmc_remove_card_debugfs(struct mmc_card *card)
+{
+       debugfs_remove_recursive(card->debugfs_root);
+}
index 1d795c5379b548f5869b83d7aabf05848a6d27b1..6da80fd4d974669223ac2caf54576f6521c52083 100644 (file)
@@ -127,6 +127,10 @@ int mmc_add_host(struct mmc_host *host)
        if (err)
                return err;
 
+#ifdef CONFIG_DEBUG_FS
+       mmc_add_host_debugfs(host);
+#endif
+
        mmc_start_host(host);
 
        return 0;
@@ -146,6 +150,10 @@ void mmc_remove_host(struct mmc_host *host)
 {
        mmc_stop_host(host);
 
+#ifdef CONFIG_DEBUG_FS
+       mmc_remove_host_debugfs(host);
+#endif
+
        device_del(&host->class_dev);
 
        led_trigger_unregister_simple(host->led);
index a9a5657706c6de2b22b3a92f0086eaa043df8b4b..26bd80e650317397545b4c62d0393f7d429c6e36 100644 (file)
@@ -82,6 +82,8 @@
 # define MCI_OVRE              (  1 <<  30)    /* RX Overrun Error */
 # define MCI_UNRE              (  1 <<  31)    /* TX Underrun Error */
 
+#define MCI_REGS_SIZE          0x100
+
 /* Register access macros */
 #define mci_readl(port,reg)                            \
        __raw_readl((port)->regs + MCI_##reg)
index cce873c5a149528f7d65fb3c5891a71bb5cdb502..b68381f7bfdd504e3f786675be6930626eb33ed2 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/blkdev.h>
 #include <linux/clk.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -16,6 +17,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/seq_file.h>
+#include <linux/stat.h>
 
 #include <linux/mmc/host.h>
 
@@ -88,6 +91,188 @@ struct atmel_mci {
 #define atmci_clear_pending(host, event)                       \
        clear_bit(event, &host->pending_events)
 
+/*
+ * The debugfs stuff below is mostly optimized away when
+ * CONFIG_DEBUG_FS is not set.
+ */
+static int atmci_req_show(struct seq_file *s, void *v)
+{
+       struct atmel_mci        *host = s->private;
+       struct mmc_request      *mrq = host->mrq;
+       struct mmc_command      *cmd;
+       struct mmc_command      *stop;
+       struct mmc_data         *data;
+
+       /* Make sure we get a consistent snapshot */
+       spin_lock_irq(&host->mmc->lock);
+
+       if (mrq) {
+               cmd = mrq->cmd;
+               data = mrq->data;
+               stop = mrq->stop;
+
+               if (cmd)
+                       seq_printf(s,
+                               "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
+                               cmd->opcode, cmd->arg, cmd->flags,
+                               cmd->resp[0], cmd->resp[1], cmd->resp[2],
+                               cmd->resp[2], cmd->error);
+               if (data)
+                       seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
+                               data->bytes_xfered, data->blocks,
+                               data->blksz, data->flags, data->error);
+               if (stop)
+                       seq_printf(s,
+                               "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
+                               stop->opcode, stop->arg, stop->flags,
+                               stop->resp[0], stop->resp[1], stop->resp[2],
+                               stop->resp[2], stop->error);
+       }
+
+       spin_unlock_irq(&host->mmc->lock);
+
+       return 0;
+}
+
+static int atmci_req_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, atmci_req_show, inode->i_private);
+}
+
+static const struct file_operations atmci_req_fops = {
+       .owner          = THIS_MODULE,
+       .open           = atmci_req_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void atmci_show_status_reg(struct seq_file *s,
+               const char *regname, u32 value)
+{
+       static const char       *sr_bit[] = {
+               [0]     = "CMDRDY",
+               [1]     = "RXRDY",
+               [2]     = "TXRDY",
+               [3]     = "BLKE",
+               [4]     = "DTIP",
+               [5]     = "NOTBUSY",
+               [8]     = "SDIOIRQA",
+               [9]     = "SDIOIRQB",
+               [16]    = "RINDE",
+               [17]    = "RDIRE",
+               [18]    = "RCRCE",
+               [19]    = "RENDE",
+               [20]    = "RTOE",
+               [21]    = "DCRCE",
+               [22]    = "DTOE",
+               [30]    = "OVRE",
+               [31]    = "UNRE",
+       };
+       unsigned int            i;
+
+       seq_printf(s, "%s:\t0x%08x", regname, value);
+       for (i = 0; i < ARRAY_SIZE(sr_bit); i++) {
+               if (value & (1 << i)) {
+                       if (sr_bit[i])
+                               seq_printf(s, " %s", sr_bit[i]);
+                       else
+                               seq_puts(s, " UNKNOWN");
+               }
+       }
+       seq_putc(s, '\n');
+}
+
+static int atmci_regs_show(struct seq_file *s, void *v)
+{
+       struct atmel_mci        *host = s->private;
+       u32                     *buf;
+
+       buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Grab a more or less consistent snapshot */
+       spin_lock_irq(&host->mmc->lock);
+       memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
+       spin_unlock_irq(&host->mmc->lock);
+
+       seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
+                       buf[MCI_MR / 4],
+                       buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "",
+                       buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "",
+                       buf[MCI_MR / 4] & 0xff);
+       seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]);
+       seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]);
+       seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]);
+       seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n",
+                       buf[MCI_BLKR / 4],
+                       buf[MCI_BLKR / 4] & 0xffff,
+                       (buf[MCI_BLKR / 4] >> 16) & 0xffff);
+
+       /* Don't read RSPR and RDR; it will consume the data there */
+
+       atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
+       atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
+
+       return 0;
+}
+
+static int atmci_regs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, atmci_regs_show, inode->i_private);
+}
+
+static const struct file_operations atmci_regs_fops = {
+       .owner          = THIS_MODULE,
+       .open           = atmci_regs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void atmci_init_debugfs(struct atmel_mci *host)
+{
+       struct mmc_host *mmc;
+       struct dentry   *root;
+       struct dentry   *node;
+       struct resource *res;
+
+       mmc = host->mmc;
+       root = mmc->debugfs_root;
+       if (!root)
+               return;
+
+       node = debugfs_create_file("regs", S_IRUSR, root, host,
+                       &atmci_regs_fops);
+       if (IS_ERR(node))
+               return;
+       if (!node)
+               goto err;
+
+       res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
+       node->d_inode->i_size = res->end - res->start + 1;
+
+       node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops);
+       if (!node)
+               goto err;
+
+       node = debugfs_create_x32("pending_events", S_IRUSR, root,
+                                    (u32 *)&host->pending_events);
+       if (!node)
+               goto err;
+
+       node = debugfs_create_x32("completed_events", S_IRUSR, root,
+                                    (u32 *)&host->completed_events);
+       if (!node)
+               goto err;
+
+       return;
+
+err:
+       dev_err(&host->pdev->dev,
+               "failed to initialize debugfs for controller\n");
+}
 
 static void atmci_enable(struct atmel_mci *host)
 {
@@ -905,6 +1090,8 @@ static int __init atmci_probe(struct platform_device *pdev)
                        "Atmel MCI controller at 0x%08lx irq %d\n",
                        host->mapbase, irq);
 
+       atmci_init_debugfs(host);
+
        return 0;
 
 err_request_irq:
@@ -923,6 +1110,8 @@ static int __exit atmci_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (host) {
+               /* Debugfs stuff is cleaned up by mmc core */
+
                if (host->detect_pin >= 0) {
                        int pin = host->detect_pin;
 
index 5e880c0f13495105105efee78d1eadcebdfa4a29..f61406da65d2c953e31896395209ce76428990cc 100644 (file)
  *
  */
 
-#ifdef CONFIG_MMC_DEBUG
-#define DEBUG
-#else
-#undef  DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -907,31 +901,12 @@ static const struct mmc_host_ops imxmci_ops = {
        .get_ro         = imxmci_get_ro,
 };
 
-static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
-{
-       int i;
-
-       for (i = 0; i < dev->num_resources; i++)
-               if (dev->resource[i].flags == mask && nr-- == 0)
-                       return &dev->resource[i];
-       return NULL;
-}
-
-static int platform_device_irq(struct platform_device *dev, int nr)
-{
-       int i;
-
-       for (i = 0; i < dev->num_resources; i++)
-               if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)
-                       return dev->resource[i].start;
-       return NO_IRQ;
-}
-
 static void imxmci_check_status(unsigned long data)
 {
        struct imxmci_host *host = (struct imxmci_host *)data;
 
-       if( host->pdata->card_present(mmc_dev(host->mmc)) != host->present ) {
+       if (host->pdata && host->pdata->card_present &&
+           host->pdata->card_present(mmc_dev(host->mmc)) != host->present) {
                host->present ^= 1;
                dev_info(mmc_dev(host->mmc), "card %s\n",
                      host->present ? "inserted" : "removed");
@@ -962,13 +937,12 @@ static int imxmci_probe(struct platform_device *pdev)
 
        printk(KERN_INFO "i.MX mmc driver\n");
 
-       r = platform_device_resource(pdev, IORESOURCE_MEM, 0);
-       irq = platform_device_irq(pdev, 0);
-       if (!r || irq == NO_IRQ)
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       irq = platform_get_irq(pdev, 0);
+       if (!r || irq < 0)
                return -ENXIO;
 
-       r = request_mem_region(r->start, 0x100, "IMXMCI");
-       if (!r)
+       if (!request_mem_region(r->start, 0x100, pdev->name))
                return -EBUSY;
 
        mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev);
@@ -995,6 +969,8 @@ static int imxmci_probe(struct platform_device *pdev)
        host->mmc = mmc;
        host->dma_allocated = 0;
        host->pdata = pdev->dev.platform_data;
+       if (!host->pdata)
+               dev_warn(&pdev->dev, "No platform data provided!\n");
 
        spin_lock_init(&host->lock);
        host->res = r;
@@ -1047,7 +1023,11 @@ static int imxmci_probe(struct platform_device *pdev)
        if (ret)
                goto out;
 
-       host->present = host->pdata->card_present(mmc_dev(mmc));
+       if (host->pdata && host->pdata->card_present)
+               host->present = host->pdata->card_present(mmc_dev(mmc));
+       else    /* if there is no way to detect assume that card is present */
+               host->present = 1;
+
        init_timer(&host->timer);
        host->timer.data = (unsigned long)host;
        host->timer.function = imxmci_check_status;
@@ -1073,7 +1053,7 @@ out:
        }
        if (mmc)
                mmc_free_host(mmc);
-       release_resource(r);
+       release_mem_region(r->start, 0x100);
        return ret;
 }
 
@@ -1102,7 +1082,7 @@ static int imxmci_remove(struct platform_device *pdev)
                clk_disable(host->clk);
                clk_put(host->clk);
 
-               release_resource(host->res);
+               release_mem_region(host->res->start, 0x100);
 
                mmc_free_host(mmc);
        }
index 41cc63360e43d357db2d5d42a06cf55b0abd47b3..7503b81374e0783690df20afbc88da0b02a75e85 100644 (file)
@@ -1076,6 +1076,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                 */
                if (canpower && ios->power_mode == MMC_POWER_OFF) {
                        int mres;
+                       u8 nullbyte = 0;
 
                        host->spi->mode &= ~(SPI_CPOL|SPI_CPHA);
                        mres = spi_setup(host->spi);
@@ -1083,7 +1084,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                                dev_dbg(&host->spi->dev,
                                        "switch to SPI mode 0 failed\n");
 
-                       if (spi_w8r8(host->spi, 0x00) < 0)
+                       if (spi_write(host->spi, &nullbyte, 1) < 0)
                                dev_dbg(&host->spi->dev,
                                        "put spi signals to low failed\n");
 
index 0d508ac17d6452b5a35429fd38704c8de2c13de4..ee6e822d59947312d3bc464508e9f38ff1686e91 100644 (file)
@@ -111,6 +111,8 @@ struct mmc_card {
        unsigned                num_info;       /* number of info strings */
        const char              **info;         /* info strings */
        struct sdio_func_tuple  *tuples;        /* unknown common tuples */
+
+       struct dentry           *debugfs_root;
 };
 
 #define mmc_card_mmc(c)                ((c)->type == MMC_TYPE_MMC)
index 10a2080086ca9e6402eec37178bd8dea384f3f92..9c288c9098783cfc3ef1b4d6357081b7d3f44849 100644 (file)
@@ -157,6 +157,8 @@ struct mmc_host {
        struct led_trigger      *led;           /* activity led */
 #endif
 
+       struct dentry           *debugfs_root;
+
        unsigned long           private[0] ____cacheline_aligned;
 };