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; }
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; }
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, ®); 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; }
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; }
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; }
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; }
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"); }
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; }
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; }
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"); }
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; }
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"); }
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"); }
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)); }
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, ®); 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; }
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"); }