コード例 #1
0
static int process_sdio_pending_irqs(struct mmc_host *host)
{
	struct mmc_card *card = host->card;
	int i, ret, count;
	unsigned char pending;
	struct sdio_func *func;

	/*
	 * Optimization, if there is only 1 function interrupt registered
	 * and we know an IRQ was signaled then call irq handler directly.
	 * Otherwise do the full probe.
	 */
	func = card->sdio_single_irq;
	if (func && host->sdio_irq_pending) {
		func->irq_handler(func);
		return 1;
	}

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	if (pending && mmc_card_broken_irq_polling(card) &&
	    !(host->caps & MMC_CAP_SDIO_IRQ)) {
		unsigned char dummy;

		/* A fake interrupt could be created when we poll SDIO_CCCR_INTx
		 * register with a Marvell SD8797 card. A dummy CMD52 read to
		 * function 0 register 0xff can avoid this.
		 */
		(void)mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy);
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
			func = card->sdio_func[i - 1];
			if (!func) {
				pr_warn("%s: pending IRQ for non-existent function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				func->irq_handler(func);
				count++;
			} else {
				pr_warn("%s: pending IRQ with no handler\n",
					sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #2
0
ファイル: mmc_block.c プロジェクト: Antonio-Zhou/Linux-2.6.11
static int mmc_blk_probe(struct mmc_card *card)
{
	struct mmc_blk_data *md;
	int err;

	if (card->csd.cmdclass & ~0x1ff)
		return -ENODEV;

	if (card->csd.read_blkbits < 9) {
		printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
			mmc_card_id(card), 1 << card->csd.read_blkbits);
		return -ENODEV;
	}

	md = mmc_blk_alloc(card);
	if (IS_ERR(md))
		return PTR_ERR(md);

	err = mmc_blk_set_blksize(md, card);
	if (err)
		goto out;

	printk(KERN_INFO "%s: %s %s %dKiB\n",
		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
		(card->csd.capacity << card->csd.read_blkbits) / 1024);

	mmc_set_drvdata(card, md);
	add_disk(md->disk);
	return 0;

 out:
	mmc_blk_put(md);

	return err;
}
コード例 #3
0
static int process_sdio_pending_irqs(struct mmc_card *card)
{
	int i, ret, count;
	unsigned char pending;
	unsigned char reg;
#if 0
#endif

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
	if (ret) {
		printk(KERN_ERR "%s: error %d reading SDIO_CCCR_IENx\n",
				mmc_card_id(card), ret);
		return ret;
	}

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
		        struct sdio_func *func = card->sdio_func[i - 1];
			if (!(reg & 0x1)) {
				pr_err("%s: Master interrupt is disabled but still "
					"we have pending interrupt, bug in h/w??\n", __func__);
				return -EINVAL;
			}

			if (!func) {
				printk(KERN_WARNING "%s: pending IRQ for "
					"non-existent function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				if ((reg & (1 << func->num))) {
					func->irq_handler(func);
					count++;
				} else {
					pr_err("%s: Interrupt ocurred even when IEx "
						"bit is not set, bug in h/w??\n", mmc_card_id(card));
					ret = -EINVAL;
				}
			} else {
				printk(KERN_WARNING "%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #4
0
static int process_sdio_pending_irqs(struct mmc_host *host)
{
	struct mmc_card *card = host->card;
	int i, ret, count;
	unsigned char pending;
	struct sdio_func *func;

	if ((!host->sdio_irq_pending) && (host->caps & MMC_CAP_SDIO_IRQ))
		return 0;

	/*
	 * Optimization, if there is only 1 function interrupt registered
	 * and we know an IRQ was signaled then call irq handler directly.
	 * Otherwise do the full probe.
	 */
	func = card->sdio_single_irq;
	if (func && host->sdio_irq_pending) {
		func->irq_handler(func);
		if (func->func_status == func_suspended)
			host->break_suspend = 1;
		return 1;
	}

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
			func = card->sdio_func[i - 1];
			if (!func) {
				pr_warning("%s: pending IRQ for "
					"non-existent function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				if (func->func_status == func_suspended)
					host->break_suspend = 1;
				func->irq_handler(func);
				count++;
			} else {
				pr_warning("%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #5
0
static int process_sdio_pending_irqs(struct mmc_card *card)
{
	int i, ret, count;
	unsigned char pending;

	if(card->disabled){
		printk(KERN_DEBUG "%s: irq arrive after controller is "
			"disabled, defer it.\n", mmc_card_id(card));
		card->pending_interrupt = 1;
		return 0;
	}

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
			struct sdio_func *func = card->sdio_func[i - 1];
			if (!func) {
				printk(KERN_WARNING "%s: pending IRQ for "
					"non-existant function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				if (func->suspended) {
					card->pending_interrupt = 1;
					printk(KERN_WARNING "%s: IRQ that arrives in suspend"
							" mode.\n",
						sdio_func_id(func));
				}
				func->irq_handler(func);
				count++;
			} else {
				printk(KERN_WARNING "%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #6
0
static int process_sdio_pending_irqs(struct mmc_card *card)
{
	int i, ret, count;
	unsigned char pending;
	struct sdio_func *func;

	/*
	 * Optimization, if there is only 1 function interrupt registered
	 * call irq handler directly
	 */
	func = card->sdio_single_irq;
	if (func) {
		func->irq_handler(func);
		return 1;
	}

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
			func = card->sdio_func[i - 1];
			if (!func) {
				pr_warning("%s: pending IRQ for "
					"non-existent function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				func->irq_handler(func);
				count++;
			} else {
				pr_warning("%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #7
0
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");
}
コード例 #8
0
ファイル: mmc_block.c プロジェクト: maliyu/SOM2416
static int mmc_blk_probe(struct mmc_card *card)
{
	struct mmc_blk_data *md;
	int err;

	/*
	 * Check that the card supports the command class(es) we need.
	 */
	if (!(card->csd.cmdclass & CCC_BLOCK_READ))
		return -ENODEV;

	md = mmc_blk_alloc(card);
	if (IS_ERR(md))
		return PTR_ERR(md);

	err = mmc_blk_set_blksize(md, card);
	if (err)
		goto out;

	printk(KERN_INFO "%s: %s %s %lluKiB %s\n",
		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
		(unsigned long long)(get_capacity(md->disk) >> 1),
		md->read_only ? "(ro)" : "");

	mmc_set_drvdata(card, md);
	add_disk(md->disk);
	return 0;

 out:
	mmc_blk_put(md);

	return err;
}
コード例 #9
0
static int process_sdio_pending_irqs(struct mmc_card *card)
{
	int i, ret, count;
	unsigned char pending;

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		sdio_debug = 1;
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
			struct sdio_func *func = card->sdio_func[i - 1];
			if (!func) {
				printk(KERN_WARNING "%s: pending IRQ for "
					"non-existant function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
				if (sdio_debug) {
					printk(KERN_DEBUG "%s: pending irq for func%d\n",
				       mmc_card_id(card), i);
				}
				func->irq_handler(func);
				count++;
			} else {
				printk(KERN_WARNING "%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}
	if (sdio_debug) {
		printk(KERN_DEBUG "%s: pending irq 0x%x\n",
	       mmc_card_id(card), pending);
		sdio_debug = 0;
	}

	if (count)
		return count;

	return ret;
}
コード例 #10
0
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;

	if (mmc_card_mmc(card))
		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_fops))
			goto err;

	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 6) &&
	    (card->host->caps2 & MMC_CAP2_PACKED_WR))
		if (!debugfs_create_file("wr_pack_stats", S_IRUSR, root, card,
					 &mmc_dbg_wr_pack_stats_fops))
			goto err;

	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) &&
	    card->ext_csd.bkops_en)
		if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card,
					 &mmc_dbg_bkops_stats_fops))
			goto err;

//ASUS_BSP +++ Gavin_Chang "mmc cmd statistics"
	if (mmc_card_mmc(card))
		if (!debugfs_create_file("cmd_stats", S_IRUSR, root, card,
					 &mmc_dbg_cmd_stats_fops))
			goto err;
//ASUS_BSP --- Gavin_Chang "mmc cmd statistics"

	return;

err:
	debugfs_remove_recursive(root);
	card->debugfs_root = NULL;
	dev_err(&card->dev, "failed to initialize debugfs\n");
}
コード例 #11
0
static int mmc_blk_probe(struct mmc_card *card)
{
	struct mmc_blk_data *md;
	int err;

	/*
	 * Check that the card supports the command class(es) we need.
	 */
	if (!(card->csd.cmdclass & CCC_BLOCK_READ))
		return -ENODEV;

	if (card->csd.read_blkbits < 9) {
		printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
			mmc_card_id(card), 1 << card->csd.read_blkbits);
		return -ENODEV;
	}

	md = mmc_blk_alloc(card);
	if (IS_ERR(md))
		return PTR_ERR(md);

	err = mmc_blk_set_blksize(md, card);
	if (err)
		goto out;

	printk(KERN_INFO "%s: %s %s %luKiB %s\n",
		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
		get_capacity(md->disk) >> 1, mmc_blk_readonly(card)?"(ro)":"");

	mmc_set_drvdata(card, md);
	add_disk(md->disk);
	return 0;

 out:
	mmc_blk_put(md);

	return err;
}
コード例 #12
0
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))
		
		return;
	if (!root)
		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;

	if (mmc_card_mmc(card))
		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_fops))
			goto err;

	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 6) &&
	    (card->host->caps2 & MMC_CAP2_PACKED_WR))
		if (!debugfs_create_file("wr_pack_stats", S_IRUSR, root, card,
					 &mmc_dbg_wr_pack_stats_fops))
			goto err;

	if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) &&
	    card->ext_csd.bkops_en)
		if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card,
					 &mmc_dbg_bkops_stats_fops))
			goto err;

	return;

err:
	debugfs_remove_recursive(root);
	card->debugfs_root = NULL;
	dev_err(&card->dev, "failed to initialize debugfs\n");
}
コード例 #13
0
void mmc_add_card_debugfs(struct mmc_card *card)
{
	struct mmc_host	*host = card->host;
	struct dentry	*root = NULL;
	struct dentry   *sdxc_root = NULL;

	if (!host->debugfs_root)
		return;

        sdxc_root = debugfs_create_dir("sdxc_root", host->debugfs_root);
        if (IS_ERR(sdxc_root))
            return;
        if (!sdxc_root)
            goto err;

	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_sdxc = sdxc_root;
	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;

	if (mmc_card_mmc(card))
		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_fops))
			goto err;

	if (mmc_card_sd(card))
		if (!debugfs_create_file("sdxc", S_IRUSR, sdxc_root, card,
					&mmc_sdxc_fops))
			goto err;

#ifdef CONFIG_HW_MMC_TEST
    if (mmc_card_mmc(card))
        if (!debugfs_create_file("card_addr", S_IRUSR, root, card,
                    &mmc_dbg_card_addr_fops))
            goto err;

    if (mmc_card_mmc(card))
        if (!debugfs_create_file("test_st", S_IRUSR, root, card,
                    &mmc_dbg_test_st_fops))
            goto err;
#endif

	return;

err:
	debugfs_remove_recursive(root);
	debugfs_remove_recursive(sdxc_root);
	card->debugfs_root = NULL;
	card->debugfs_sdxc = NULL;
	dev_err(&card->dev, "failed to initialize debugfs\n");
}
コード例 #14
0
static void mmc_test_run(struct mmc_test_card *test, int testcase)
{
	int i, ret;

	printk(KERN_INFO "%s: Starting tests of card %s...\n",
		mmc_hostname(test->card->host), mmc_card_id(test->card));

	mmc_claim_host(test->card->host);

	for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
		if (testcase && ((i + 1) != testcase))
			continue;

		printk(KERN_INFO "%s: Test case %d. %s...\n",
			mmc_hostname(test->card->host), i + 1,
			mmc_test_cases[i].name);

		if (mmc_test_cases[i].prepare) {
			ret = mmc_test_cases[i].prepare(test);
			if (ret) {
				printk(KERN_INFO "%s: Result: Prepare "
					"stage failed! (%d)\n",
					mmc_hostname(test->card->host),
					ret);
				continue;
			}
		}

		ret = mmc_test_cases[i].run(test);
		switch (ret) {
		case RESULT_OK:
			printk(KERN_INFO "%s: Result: OK\n",
				mmc_hostname(test->card->host));
			break;
		case RESULT_FAIL:
			printk(KERN_INFO "%s: Result: FAILED\n",
				mmc_hostname(test->card->host));
			break;
		case RESULT_UNSUP_HOST:
			printk(KERN_INFO "%s: Result: UNSUPPORTED "
				"(by host)\n",
				mmc_hostname(test->card->host));
			break;
		case RESULT_UNSUP_CARD:
			printk(KERN_INFO "%s: Result: UNSUPPORTED "
				"(by card)\n",
				mmc_hostname(test->card->host));
			break;
		default:
			printk(KERN_INFO "%s: Result: ERROR (%d)\n",
				mmc_hostname(test->card->host), ret);
		}

		if (mmc_test_cases[i].cleanup) {
			ret = mmc_test_cases[i].cleanup(test);
			if (ret) {
				printk(KERN_INFO "%s: Warning: Cleanup "
					"stage failed! (%d)\n",
					mmc_hostname(test->card->host),
					ret);
			}
		}
	}

	mmc_release_host(test->card->host);

	printk(KERN_INFO "%s: Tests completed.\n",
		mmc_hostname(test->card->host));
}
コード例 #15
0
ファイル: sdio_irq.c プロジェクト: CSRedRat/CM-LG-L5_Kernel
static int process_sdio_pending_irqs(struct mmc_card *card)
{
	int i, ret, count;
	unsigned char pending;
	struct sdio_func *func;
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [START]
	unsigned char reg;
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [END]

	/*
	 * Optimization, if there is only 1 function interrupt registered
	 * call irq handler directly
	 */
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [START]
#if 0
	func = card->sdio_single_irq;
	if (func) {
		func->irq_handler(func);
		return 1;
	}
#endif

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
	if (ret) {
		printk(KERN_ERR "%s: error %d reading SDIO_CCCR_IENx\n",
				mmc_card_id(card), ret);
		return ret;
	}
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [END]

	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
	if (ret) {
		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
		       mmc_card_id(card), ret);
		return ret;
	}

	count = 0;
	for (i = 1; i <= 7; i++) {
		if (pending & (1 << i)) {
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [START]
			if (!(reg & 0x1)) {
				pr_err("%s: Master interrupt is disabled but still "
					"we have pending interrupt, bug in h/w??\n", __func__);
				return -EINVAL;
			}
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [END]

			func = card->sdio_func[i - 1];
			if (!func) {
				printk(KERN_WARNING "%s: pending IRQ for "
					"non-existent function\n",
					mmc_card_id(card));
				ret = -EINVAL;
			} else if (func->irq_handler) {
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [START]
				if ((reg & (1 << func->num))) {
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [END]
				func->irq_handler(func);
				count++;
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [START]
				} else {
					pr_err("%s: Interrupt ocurred even when IEx "
						"bit is not set, bug in h/w??\n", mmc_card_id(card));
					ret = -EINVAL;
				}
// 20120317 [email protected][wo0gi] QCT patch : SDIO kernel crash [END]
			} else {
				printk(KERN_WARNING "%s: pending IRQ with no handler\n",
				       sdio_func_id(func));
				ret = -EINVAL;
			}
		}
	}

	if (count)
		return count;

	return ret;
}
コード例 #16
0
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;

	if (mmc_card_mmc(card)) {
		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_fops))
			goto err;
		if (!debugfs_create_file("eol_status", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_eol_fops))
			goto err;
		if (!debugfs_create_file("dhs_type_a", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_life_time_type_a_fops))
			goto err;
		if (!debugfs_create_file("dhs_type_b", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_life_time_type_b_fops))
			goto err;
		if (!debugfs_create_file("emmc_device_type", S_IRUSR, root,
					card, &mmc_dbg_ext_csd_device_type_fops))
			goto err;
		if (!debugfs_create_file("firmware_version", S_IRUSR, root,
					card, &mmc_dbg_ext_csd_fw_v_fops))
			goto err;
		if (!debugfs_create_file("bkops_status", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_bkops_status_fops))
			goto err;
		if (!debugfs_create_file("bkops_support", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_bkops_support_fops))
			goto err;
		if (!debugfs_create_file("poweron_notify", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_pon_notify_fops))
			goto err;
		if (!debugfs_create_file("hpi_support", S_IRUSR, root, card,
					&mmc_dbg_ext_csd_hpi_support_fops))
			goto err;
	}

	if (mmc_card_sd(card))
		if (!debugfs_create_file("speed_class", S_IROTH, root, card,
					&mmc_dbg_card_speed_class_fops))
			goto err;

	return;

err:
	debugfs_remove_recursive(root);
	card->debugfs_root = NULL;
	dev_err(&card->dev, "failed to initialize debugfs\n");
}