static int ext_cd_init(void (*notify_func) (struct platform_device *, int state), void *data) { struct platform_device *pdev = data; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct sdhci_host *host = platform_get_drvdata(pdev); int err, cd_irq, ext_cd_gpio; int status; /* Catch wake lock when card is inserted or removed */ wake_lock_init(&cd_wake_lock, WAKE_LOCK_SUSPEND, "sd_card_detect"); #ifdef CONFIG_REGULATOR host->vmmc = regulator_get(&pdev->dev, "v_mmc"); if (IS_ERR(host->vmmc)) host->vmmc = NULL; else mmc_regulator_get_ocrmask(host->vmmc); #else printk(KERN_ERR "Cannot find the power supply for SD\n"); #endif cd_irq = gpio_to_irq(pdata->ext_cd_gpio); ext_cd_gpio = pdata->ext_cd_gpio; /* * setup GPIO for saarc MMC controller */ err = gpio_request(ext_cd_gpio, "mmc card detect"); if (err) { printk(KERN_ERR "gpio_request err =%d\n", err); goto err_request_cd; } gpio_direction_input(ext_cd_gpio); err = request_threaded_irq(cd_irq, NULL, sdhci_pxa_cd_irq_thread, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC card detect", pdev); if (err) { printk(KERN_ERR "%s: MMC/SD/SDIO: " "can't request card detect IRQ\n", __func__); goto err_request_irq; } status = ext_cd_val(pdata->ext_cd_gpio,pdata->ext_cd_gpio_invert); notify_func(pdev, status); return 0; err_request_irq: gpio_free(ext_cd_gpio); err_request_cd: return -1; }
static inline void pxamci_init_ocr(struct pxamci_host *host) { #ifdef CONFIG_REGULATOR host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); if (IS_ERR(host->vcc)) host->vcc = NULL; else { host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); if (host->pdata && host->pdata->ocr_mask) dev_warn(mmc_dev(host->mmc), "ocr_mask/setpower will not be used\n"); } #endif if (host->vcc == NULL) { /* fall-back to platform data */ host->mmc->ocr_avail = host->pdata ? host->pdata->ocr_mask : MMC_VDD_32_33 | MMC_VDD_33_34; } }
static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) { struct mmci_platform_data *plat = dev->dev.platform_data; struct mmci_host *host; struct mmc_host *mmc; int ret; /* must have platform data */ if (!plat) { ret = -EINVAL; goto out; } ret = amba_request_regions(dev, DRIVER_NAME); if (ret) goto out; mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); if (!mmc) { ret = -ENOMEM; goto rel_regions; } host = mmc_priv(mmc); host->mmc = mmc; host->gpio_wp = -ENOSYS; host->gpio_cd = -ENOSYS; host->hw_designer = amba_manf(dev); host->hw_revision = amba_rev(dev); DBG(host, "designer ID = 0x%02x\n", host->hw_designer); DBG(host, "revision = 0x%01x\n", host->hw_revision); host->clk = clk_get(&dev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); host->clk = NULL; goto host_free; } ret = clk_enable(host->clk); if (ret) goto clk_free; host->plat = plat; host->mclk = clk_get_rate(host->clk); /* * According to the spec, mclk is max 100 MHz, * so we try to adjust the clock down to this, * (if possible). */ if (host->mclk > 100000000) { ret = clk_set_rate(host->clk, 100000000); if (ret < 0) goto clk_disable; host->mclk = clk_get_rate(host->clk); DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); } host->base = ioremap(dev->res.start, resource_size(&dev->res)); if (!host->base) { ret = -ENOMEM; goto clk_disable; } mmc->ops = &mmci_ops; mmc->f_min = (host->mclk + 511) / 512; mmc->f_max = min(host->mclk, fmax); #ifdef CONFIG_REGULATOR /* If we're using the regulator framework, try to fetch a regulator */ host->vcc = regulator_get(&dev->dev, "vmmc"); if (IS_ERR(host->vcc)) host->vcc = NULL; else { int mask = mmc_regulator_get_ocrmask(host->vcc); if (mask < 0) dev_err(&dev->dev, "error getting OCR mask (%d)\n", mask); else { host->mmc->ocr_avail = (u32) mask; if (plat->ocr_mask) dev_warn(&dev->dev, "Provided ocr_mask/setpower will not be used " "(using regulator instead)\n"); } } #endif /* Fall back to platform data if no regulator is found */ if (host->vcc == NULL) mmc->ocr_avail = plat->ocr_mask; mmc->caps = plat->capabilities; /* * We can do SGIO */ mmc->max_hw_segs = 16; mmc->max_phys_segs = NR_SG; /* * Since we only have a 16-bit data length register, we must * ensure that we don't exceed 2^16-1 bytes in a single request. */ mmc->max_req_size = 65535; /* * Set the maximum segment size. Since we aren't doing DMA * (yet) we are only limited by the data length register. */ mmc->max_seg_size = mmc->max_req_size; /* * Block size can be up to 2048 bytes, but must be a power of two. */ mmc->max_blk_size = 2048; /* * No limit on the number of blocks transferred. */ mmc->max_blk_count = mmc->max_req_size; spin_lock_init(&host->lock); writel(0, host->base + MMCIMASK0); writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) ret = gpio_direction_input(plat->gpio_cd); if (ret == 0) host->gpio_cd = plat->gpio_cd; else if (ret != -ENOSYS) goto err_gpio_cd; } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) ret = gpio_direction_input(plat->gpio_wp); if (ret == 0) host->gpio_wp = plat->gpio_wp; else if (ret != -ENOSYS) goto err_gpio_wp; } ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); if (ret) goto unmap; ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host); if (ret) goto irq0_free; writel(MCI_IRQENABLE, host->base + MMCIMASK0); amba_set_drvdata(dev, mmc); host->oldstat = mmci_get_cd(host->mmc); mmc_add_host(mmc); printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", mmc_hostname(mmc), amba_rev(dev), amba_config(dev), (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); init_timer(&host->timer); host->timer.data = (unsigned long)host; host->timer.function = mmci_check_status; host->timer.expires = jiffies + HZ; add_timer(&host->timer); return 0; irq0_free: free_irq(dev->irq[0], host); unmap: if (host->gpio_wp != -ENOSYS) gpio_free(host->gpio_wp); err_gpio_wp: if (host->gpio_cd != -ENOSYS) gpio_free(host->gpio_cd); err_gpio_cd: iounmap(host->base); clk_disable: clk_disable(host->clk); clk_free: clk_put(host->clk); host_free: mmc_free_host(mmc); rel_regions: amba_release_regions(dev); out: return ret; }
/* * MMC Slot Initialization. */ static int twl_mmc_late_init(struct device *dev) { struct omap_mmc_platform_data *mmc = dev->platform_data; int ret = 0; int i; /* MMC/SD/SDIO doesn't require a card detect switch */ if (!cpu_is_omap44xx()) { if (gpio_is_valid(mmc->slots[0].switch_pin)) { ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); if (ret) goto done; ret = gpio_direction_input(mmc->slots[0].switch_pin); if (ret) goto err; } } /* require at least main regulator */ for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { if (hsmmc[i].name == mmc->slots[0].name) { struct regulator *reg; hsmmc[i].mmc = mmc; reg = regulator_get(dev, "vmmc"); if (IS_ERR(reg)) { dev_dbg(dev, "vmmc regulator missing\n"); /* HACK: until fixed.c regulator is usable, * we don't require a main regulator * for MMC2 or MMC3 */ if (i != 0) break; ret = PTR_ERR(reg); hsmmc[i].vcc = NULL; goto err; } hsmmc[i].vcc = reg; mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg); /* allow an aux regulator */ reg = regulator_get(dev, "vmmc_aux"); hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg; /* UGLY HACK: workaround regulator framework bugs. * When the bootloader leaves a supply active, it's * initialized with zero usecount ... and we can't * disable it without first enabling it. Until the * framework is fixed, we need a workaround like this * (which is safe for MMC, but not in general). */ if (regulator_is_enabled(hsmmc[i].vcc) > 0) { regulator_enable(hsmmc[i].vcc); regulator_disable(hsmmc[i].vcc); } if (hsmmc[i].vcc_aux) { if (regulator_is_enabled(reg) > 0) { regulator_enable(reg); regulator_disable(reg); } } if (cpu_is_omap44xx()) { if (twl_class_is_6030()) { twl6030_interrupt_unmask (TWL6030_MMCDETECT_INT_MASK, REG_INT_MSK_LINE_B); twl6030_interrupt_unmask (TWL6030_MMCDETECT_INT_MASK, REG_INT_MSK_STS_B); } /* Configure Phoenix for MMC1 Card detect */ if (i == 0) { twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x04, PHOENIX_MMC_CTRL); twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x11, PHOENIX_CFG_INPUT_PUPD3); } } break; } } return 0; err: gpio_free(mmc->slots[0].switch_pin); done: mmc->slots[0].card_detect_irq = 0; mmc->slots[0].card_detect = NULL; dev_err(dev, "err %d configuring card detect\n", ret); return ret; }