if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio) return;
irq = gpiod_to_irq(ctx->cd_gpio);
/* * Even if gpiod_to_irq() returns a valid IRQ number, the platform might * still prefer to poll, e.g., because that IRQ number is already used * by another unit and cannot be shared. */ if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) irq = -EINVAL;
if (irq >= 0) { ret = devm_request_threaded_irq(&host->class_dev, irq, NULL, mmc_gpio_cd_irqt, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ctx->cd_label, host); if (ret < 0) irq = ret; }
host->slot.cd_irq = irq;
if (irq < 0) host->caps |= MMC_CAP_NEEDS_POLL; }
中断处理是mmc_gpio_cd_irqt:
staticirqreturn_tmmc_gpio_cd_irqt(int irq, void *dev_id) { /* Schedule a card detection after a debounce timeout */ structmmc_host *host = dev_id;
/* * Firstly check card presence from cd-gpio. The return could * be one of the following possibilities: * negative: cd-gpio is not available * zero: cd-gpio is used, and card is removed * one: cd-gpio is used, and card is present */ present = mmc_gpio_get_cd(host->mmc); if (present < 0) { /* If polling, assume that the card is always present. */ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else present = sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT; }