static int __devinit ak98_mci_probe(struct platform_device *pdev) { struct ak98_mci_platform_data *plat = pdev->dev.platform_data; struct ak98_mci_host *host; struct mmc_host *mmc; struct resource *res; int irq; int ret; /* must have platform data */ if (!plat) { ret = -EINVAL; goto out; } PK("%s\n", __func__); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); PK("res: %x, %u", res->start, resource_size(res)); res = request_mem_region(res->start, resource_size(res), DRIVER_NAME); if (!res) { ret = -EBUSY; goto out; } PK("res: %x, %u\n", res->start, resource_size(res)); mmc = mmc_alloc_host(sizeof(struct ak98_mci_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto out; } host = mmc_priv(mmc); host->mmc = mmc; host->gpio_wp = -ENOSYS; host->gpio_cd = -ENOSYS; ak98_mci_reset(); host->clk = clk_get(&pdev->dev, "mci_clk"); 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->asic_clkrate = ak98_get_asic_clk(); host->base = ioremap(res->start, resource_size(res)); if (!host->base) { ret = -ENOMEM; goto clk_disable; } PK("asic_clkrate: %luhz,host->base=0x%x\n", host->asic_clkrate,host->base); mmc->ops = &ak98_mci_ops; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; /* * set the transmit mode to four data line mode, if not set, * default is one data line mode. */ mmc->caps = MMC_CAP_4_BIT_DATA; #if 0 mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; #endif // mmc->caps |= MMC_CAP_NEEDS_POLL; mmc->f_min = host->asic_clkrate / (255+1 + 255+1); mmc->f_max = host->asic_clkrate / (0+1 + 0+1); mmc->f_max = mmc->f_max < fmax ? mmc->f_max : fmax; /* * 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 = 65536; /* * 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; #if 0 /* * Block size can be up to 2048 bytes, but must be a power of two. */ mmc->max_blk_size = 2048; #else /* as l2 fifo limit to 512 bytes */ mmc->max_blk_size = 512; #endif /* * No limit on the number of blocks transferred. */ mmc->max_blk_count = mmc->max_req_size; spin_lock_init(&host->lock); #ifdef CONFIG_MTD_NAND_AK98 down(&nand_lock); #endif ak98_group_pin_config(); // writel(SDIO_INTR_CTR_ENABLE, host->base + AK98SDIOINTRCTR); writel(MCI_ENABLE|MCI_FAIL_TRIGGER, host->base + AK98MCICLOCK); PK("%s: MCICLOCK: 0x%08x\n", __func__, readl(host->base + AK98MCICLOCK)); #ifdef CONFIG_MTD_NAND_AK98 up(&nand_lock); #endif writel(0, host->base + AK98MCIMASK); PK("request irq %i\n", irq); ret = request_irq(irq, ak98_mci_irq, IRQF_DISABLED, DRIVER_NAME " (cmd)", host); if (ret) goto unmap; host->irq_mci = irq; /* * if card detected pin or write protect pin has * been config, then config the pins. */ if(plat->gpio_cd >= 0) { host->gpio_cd = plat->gpio_cd; ak98_gpio_cfgpin(host->gpio_cd, AK98_GPIO_DIR_INPUT); ak98_gpio_pulldown(host->gpio_cd,AK98_PULLDOWN_DISABLE); } if(plat->gpio_wp >= 0) { host->gpio_wp = plat->gpio_wp; ak98_gpio_cfgpin(host->gpio_wp, AK98_GPIO_DIR_INPUT); ak98_gpio_pullup(host->gpio_wp, AK98_PULLUP_ENABLE); ak98_gpio_pulldown(host->gpio_wp,AK98_PULLDOWN_DISABLE); } setup_timer(&host->detect_timer, ak98_mci_detect_change, (unsigned long)host); irq = ak98_gpio_to_irq(host->gpio_cd); ret = request_irq(irq, ak98_mci_card_detect_irq, IRQF_DISABLED, DRIVER_NAME " cd", host); printk("request gpio irq ret = %d, irq=%d", ret, irq); if (ret) goto irq_free; host->irq_cd = irq; host->irq_cd_type = IRQ_TYPE_LEVEL_LOW; platform_set_drvdata(pdev, mmc); ret = ak98mci_cpufreq_register(host); if (ret) { goto irq_free; } ret = mmc_add_host(mmc); if (ret) { goto cpufreq_free; } PK(KERN_INFO "%s: ak98MCI at 0x%016llx irq %d\n", mmc_hostname(mmc), (unsigned long long)res->start, host->irq_mci); return 0; cpufreq_free: PK("ERR cpufreq_free\n"); ak98mci_cpufreq_deregister(host); irq_free: PK("ERR irq_free\n"); free_irq(host->irq_mci, host); unmap: PK("ERR unmap\n"); iounmap(host->base); clk_disable: PK("ERR clk_disable\n"); clk_disable(host->clk); clk_free: PK("ERR clk_free\n"); clk_put(host->clk); host_free: PK("ERR host_free\n"); mmc_free_host(mmc); out: PK("ERR out\n"); return ret; }
static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) { struct s3cmci_host *host; struct mmc_host *mmc; int ret; mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto probe_out; } host = mmc_priv(mmc); host->mmc = mmc; host->pdev = pdev; host->is2440 = is2440; host->pdata = pdev->dev.platform_data; if (!host->pdata) { pdev->dev.platform_data = &s3cmci_def_pdata; host->pdata = &s3cmci_def_pdata; } spin_lock_init(&host->complete_lock); tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); if (is2440) { host->sdiimsk = S3C2440_SDIIMSK; host->sdidata = S3C2440_SDIDATA; host->clk_div = 1; } else { host->sdiimsk = S3C2410_SDIIMSK; host->sdidata = S3C2410_SDIDATA; host->clk_div = 2; } host->dodma = 0; host->complete_what = COMPLETION_NONE; host->pio_active = XFER_NONE; host->dma = S3CMCI_DMA; host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!host->mem) { dev_err(&pdev->dev, "failed to get io memory region resouce.\n"); ret = -ENOENT; goto probe_free_host; } host->mem = request_mem_region(host->mem->start, RESSIZE(host->mem), pdev->name); if (!host->mem) { dev_err(&pdev->dev, "failed to request io memory region.\n"); ret = -ENOENT; goto probe_free_host; } host->base = ioremap(host->mem->start, RESSIZE(host->mem)); if (host->base == 0) { dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); ret = -EINVAL; goto probe_free_mem_region; } host->irq = platform_get_irq(pdev, 0); if (host->irq == 0) { dev_err(&pdev->dev, "failed to get interrupt resouce.\n"); ret = -EINVAL; goto probe_iounmap; } if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) { dev_err(&pdev->dev, "failed to request mci interrupt.\n"); ret = -ENOENT; goto probe_iounmap; } /* We get spurious interrupts even when we have set the IMSK * register to ignore everything, so use disable_irq() to make * ensure we don't lock the system with un-serviceable requests. */ disable_irq(host->irq); host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); if (host->irq_cd >= 0) { if (request_irq(host->irq_cd, s3cmci_irq_cd, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRIVER_NAME, host)) { dev_err(&pdev->dev, "can't get card detect irq.\n"); ret = -ENOENT; goto probe_free_irq; } } else { dev_warn(&pdev->dev, "host detect has no irq available\n"); s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_INPUT); } if (host->pdata->gpio_wprotect) s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect, S3C2410_GPIO_INPUT); if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) { dev_err(&pdev->dev, "unable to get DMA channel.\n"); ret = -EBUSY; goto probe_free_irq_cd; } host->clk = clk_get(&pdev->dev, "sdi"); if (IS_ERR(host->clk)) { dev_err(&pdev->dev, "failed to find clock source.\n"); ret = PTR_ERR(host->clk); host->clk = NULL; goto probe_free_host; } ret = clk_enable(host->clk); if (ret) { dev_err(&pdev->dev, "failed to enable clock source.\n"); goto clk_free; } host->clk_rate = clk_get_rate(host->clk); mmc->ops = &s3cmci_ops; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->caps = MMC_CAP_4_BIT_DATA; mmc->f_min = host->clk_rate / (host->clk_div * 256); mmc->f_max = host->clk_rate / host->clk_div; if (host->pdata->ocr_avail) mmc->ocr_avail = host->pdata->ocr_avail; mmc->max_blk_count = 4095; mmc->max_blk_size = 4095; mmc->max_req_size = 4095 * 512; mmc->max_seg_size = mmc->max_req_size; mmc->max_phys_segs = 128; mmc->max_hw_segs = 128; dbg(host, dbg_debug, "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n", (host->is2440?"2440":""), host->base, host->irq, host->irq_cd, host->dma); ret = mmc_add_host(mmc); if (ret) { dev_err(&pdev->dev, "failed to add mmc host.\n"); goto free_dmabuf; } platform_set_drvdata(pdev, mmc); dev_info(&pdev->dev, "initialisation done.\n"); return 0; free_dmabuf: clk_disable(host->clk); clk_free: clk_put(host->clk); probe_free_irq_cd: if (host->irq_cd >= 0) free_irq(host->irq_cd, host); probe_free_irq: free_irq(host->irq, host); probe_iounmap: iounmap(host->base); probe_free_mem_region: release_mem_region(host->mem->start, RESSIZE(host->mem)); probe_free_host: mmc_free_host(mmc); probe_out: return ret; }
static int sh_mmcif_probe(struct platform_device *pdev) { int ret = 0, irq[2]; struct mmc_host *mmc; struct sh_mmcif_host *host; struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; struct resource *res; void __iomem *reg; const char *name; irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq(pdev, 1); if (irq[0] < 0) { dev_err(&pdev->dev, "Get irq error\n"); return -ENXIO; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev); if (!mmc) return -ENOMEM; ret = mmc_of_parse(mmc); if (ret < 0) goto err_host; host = mmc_priv(mmc); host->mmc = mmc; host->addr = reg; host->timeout = msecs_to_jiffies(10000); host->ccs_enable = !pd || !pd->ccs_unsupported; host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; host->pd = pdev; spin_lock_init(&host->lock); mmc->ops = &sh_mmcif_ops; sh_mmcif_init_ocr(host); mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY; if (pd && pd->caps) mmc->caps |= pd->caps; mmc->max_segs = 32; mmc->max_blk_size = 512; mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs; mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size; mmc->max_seg_size = mmc->max_req_size; platform_set_drvdata(pdev, host); pm_runtime_enable(&pdev->dev); host->power = false; host->hclk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->hclk)) { ret = PTR_ERR(host->hclk); dev_err(&pdev->dev, "cannot get clock: %d\n", ret); goto err_pm; } ret = sh_mmcif_clk_update(host); if (ret < 0) goto err_pm; ret = pm_runtime_resume(&pdev->dev); if (ret < 0) goto err_clk; INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); sh_mmcif_sync_reset(host); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); name = irq[1] < 0 ? dev_name(&pdev->dev) : "sh_mmc:error"; ret = devm_request_threaded_irq(&pdev->dev, irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, name, host); if (ret) { dev_err(&pdev->dev, "request_irq error (%s)\n", name); goto err_clk; } if (irq[1] >= 0) { ret = devm_request_threaded_irq(&pdev->dev, irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); if (ret) { dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); goto err_clk; } } if (pd && pd->use_cd_gpio) { ret = mmc_gpio_request_cd(mmc, pd->cd_gpio, 0); if (ret < 0) goto err_clk; } mutex_init(&host->thread_lock); ret = mmc_add_host(mmc); if (ret < 0) goto err_clk; dev_pm_qos_expose_latency_limit(&pdev->dev, 100); dev_info(&pdev->dev, "Chip version 0x%04x, clock rate %luMHz\n", sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0xffff, clk_get_rate(host->hclk) / 1000000UL); clk_disable_unprepare(host->hclk); return ret; err_clk: clk_disable_unprepare(host->hclk); err_pm: pm_runtime_disable(&pdev->dev); err_host: mmc_free_host(mmc); return ret; }
static int __devinit sh_mmcif_probe(struct platform_device *pdev) { int ret = 0, irq[2]; struct mmc_host *mmc; struct sh_mmcif_host *host; struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; struct resource *res; void __iomem *reg; char clk_name[8]; irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq(pdev, 1); if (irq[0] < 0 || irq[1] < 0) { dev_err(&pdev->dev, "Get irq error\n"); return -ENXIO; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "platform_get_resource error.\n"); return -ENXIO; } reg = ioremap(res->start, resource_size(res)); if (!reg) { dev_err(&pdev->dev, "ioremap error.\n"); return -ENOMEM; } mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto ealloch; } host = mmc_priv(mmc); host->mmc = mmc; host->addr = reg; host->timeout = 1000; host->pd = pdev; spin_lock_init(&host->lock); mmc->ops = &sh_mmcif_ops; sh_mmcif_init_ocr(host); mmc->caps = MMC_CAP_MMC_HIGHSPEED; if (pd && pd->caps) mmc->caps |= pd->caps; mmc->max_segs = 32; mmc->max_blk_size = 512; mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs; mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size; mmc->max_seg_size = mmc->max_req_size; platform_set_drvdata(pdev, host); pm_runtime_enable(&pdev->dev); host->power = false; snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id); host->hclk = clk_get(&pdev->dev, clk_name); if (IS_ERR(host->hclk)) { ret = PTR_ERR(host->hclk); dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret); goto eclkget; } ret = sh_mmcif_clk_update(host); if (ret < 0) goto eclkupdate; ret = pm_runtime_resume(&pdev->dev); if (ret < 0) goto eresume; INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); sh_mmcif_sync_reset(host); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host); if (ret) { dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); goto ereqirq0; } ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); if (ret) { dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); goto ereqirq1; } if (pd && pd->use_cd_gpio) { ret = mmc_gpio_request_cd(mmc, pd->cd_gpio); if (ret < 0) goto erqcd; } clk_disable(host->hclk); ret = mmc_add_host(mmc); if (ret < 0) goto emmcaddh; dev_pm_qos_expose_latency_limit(&pdev->dev, 100); dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); dev_dbg(&pdev->dev, "chip ver H'%04x\n", sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); return ret; emmcaddh: if (pd && pd->use_cd_gpio) mmc_gpio_free_cd(mmc); erqcd: free_irq(irq[1], host); ereqirq1: free_irq(irq[0], host); ereqirq0: pm_runtime_suspend(&pdev->dev); eresume: clk_disable(host->hclk); eclkupdate: clk_put(host->hclk); eclkget: pm_runtime_disable(&pdev->dev); mmc_free_host(mmc); ealloch: iounmap(reg); return ret; }
/* * Probe for the device */ static int __init at91_mci_probe(struct platform_device *pdev) { struct mmc_host *mmc; struct at91mci_host *host; struct resource *res; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENXIO; if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) return -EBUSY; mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; dev_dbg(&pdev->dev, "couldn't allocate mmc host\n"); goto fail6; } mmc->ops = &at91_mci_ops; mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->caps = 0; mmc->max_blk_size = MCI_MAXBLKSIZE; mmc->max_blk_count = MCI_BLKATONCE; mmc->max_req_size = MCI_BUFSIZE; mmc->max_segs = MCI_BLKATONCE; mmc->max_seg_size = MCI_BUFSIZE; host = mmc_priv(mmc); host->mmc = mmc; host->bus_mode = 0; host->board = pdev->dev.platform_data; if (host->board->wire4) { if (at91mci_is_mci1rev2xx()) mmc->caps |= MMC_CAP_4_BIT_DATA; else dev_warn(&pdev->dev, "4 wire bus mode not supported" " - using 1 wire\n"); } host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE, &host->physical_address, GFP_KERNEL); if (!host->buffer) { ret = -ENOMEM; dev_err(&pdev->dev, "Can't allocate transmit buffer\n"); goto fail5; } /* Add SDIO capability when available */ if (at91mci_is_mci1rev2xx()) { /* at91mci MCI1 rev2xx sdio interrupt erratum */ if (host->board->wire4 || !host->board->slot_b) mmc->caps |= MMC_CAP_SDIO_IRQ; } /* * Reserve GPIOs ... board init code makes sure these pins are set * up as GPIOs with the right direction (input, except for vcc) */ if (host->board->det_pin) { ret = gpio_request(host->board->det_pin, "mmc_detect"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); goto fail4b; } } if (host->board->wp_pin) { ret = gpio_request(host->board->wp_pin, "mmc_wp"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); goto fail4; } } if (host->board->vcc_pin) { ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); goto fail3; } } /* * Get Clock */ host->mci_clk = clk_get(&pdev->dev, "mci_clk"); if (IS_ERR(host->mci_clk)) { ret = -ENODEV; dev_dbg(&pdev->dev, "no mci_clk?\n"); goto fail2; } /* * Map I/O region */ host->baseaddr = ioremap(res->start, resource_size(res)); if (!host->baseaddr) { ret = -ENOMEM; goto fail1; } /* * Reset hardware */ clk_enable(host->mci_clk); /* Enable the peripheral clock */ at91_mci_disable(host); at91_mci_enable(host); /* * Allocate the MCI interrupt */ host->irq = platform_get_irq(pdev, 0); ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, mmc_hostname(mmc), host); if (ret) { dev_dbg(&pdev->dev, "request MCI interrupt failed\n"); goto fail0; } setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); platform_set_drvdata(pdev, mmc); /* * Add host to MMC layer */ if (host->board->det_pin) { host->present = !gpio_get_value(host->board->det_pin); } else host->present = -1; mmc_add_host(mmc); /* * monitor card insertion/removal if we can */ if (host->board->det_pin) { ret = request_irq(gpio_to_irq(host->board->det_pin), at91_mmc_det_irq, 0, mmc_hostname(mmc), host); if (ret) dev_warn(&pdev->dev, "request MMC detect irq failed\n"); else device_init_wakeup(&pdev->dev, 1); } pr_debug("Added MCI driver\n"); return 0; fail0: clk_disable(host->mci_clk); iounmap(host->baseaddr); fail1: clk_put(host->mci_clk); fail2: if (host->board->vcc_pin) gpio_free(host->board->vcc_pin); fail3: if (host->board->wp_pin) gpio_free(host->board->wp_pin); fail4: if (host->board->det_pin) gpio_free(host->board->det_pin); fail4b: if (host->buffer) dma_free_coherent(&pdev->dev, MCI_BUFSIZE, host->buffer, host->physical_address); fail5: mmc_free_host(mmc); fail6: release_mem_region(res->start, resource_size(res)); dev_err(&pdev->dev, "probe failed, err %d\n", ret); return ret; }
static int csb536pc_mmc_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct mmc_host *mmc; struct csb536pc_mmc_host *host = NULL; struct resource *r; int ret; // int irq; _cp; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { return -ENXIO; } // irq = platform_get_irq(pdev, 0); // if (irq == NO_IRQ) { // return -ENXIO; // } // _cp; // r = request_mem_region(r->start, SZ_4K, DRIVER_NAME); // if (r == NULL) { // return -EBUSY; // } _cp; mmc = mmc_alloc_host(sizeof(struct csb536pc_mmc_host), dev); if (mmc == NULL ) { ret = -ENOMEM; goto out; } _cp; mmc->ops = &csb536pc_mmc_ops; // mmc->f_min = CLOCKRATE_MIN; // mmc->f_max = CLOCKRATE_MAX; /* * Let's not deal with SG for now. */ _cp; mmc->max_phys_segs = NR_SG; _cp; mmc->max_seg_size = PAGE_SIZE; _cp; host = mmc_priv(mmc); host->mmc = mmc; host->dma = -1; host->pdata = pdev->dev.platform_data; // mmc->ocr_avail = host->pdata ? // host->pdata->ocr_mask : // MMC_VDD_32_33|MMC_VDD_33_34; // host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); // if (!host->sg_cpu) { // ret = -ENOMEM; // goto out; // } spin_lock_init(&host->lock); // host->res = r; // host->irq = irq; // host->imask = MMC_I_MASK_ALL; host->base = ioremap(r->start, SZ_4K); if (host->base == NULL) { ret = -ENOMEM; goto out; } #if 0 /* Configure GPIO for SPI and MMC */ imx_gpio_mode(14 | GPIO_PORTC | GPIO_PF); /* SCLK */ imx_gpio_mode(15 | GPIO_PORTC | GPIO_PF); /* *SS */ imx_gpio_mode(16 | GPIO_PORTC | GPIO_PF); /* MISO */ imx_gpio_mode(17 | GPIO_PORTC | GPIO_PF); /* MOSI */ imx_gpio_mode(14 | GPIO_PORTB | GPIO_OUT); /* SD_VEN */ /* Disable the SD voltage regulator */ DR(1) &= ~(1 << 14) SSP1_CTRL_REG = ( SSP_RATE_DIV256 | /* PCLK2 = SYSCLK/4 = 24MHz. 24MHZ/125KHz = 192 */ SSP_MODE_MASTER | SSP_SS_POL_LOW | SSP_ENABLE | SSP_PHA0 | SSP_POL0 | SSP_WS(8)); #endif /* * Ensure that the host controller is shut down, and setup * with our defaults. */ // csb536pc_mmc_stop_clock(host); // writel(0, host->base + MMC_SPI); // writel(64, host->base + MMC_RESTO); // writel(host->imask, host->base + MMC_I_MASK); // host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW, // csb536pc_mmc_dma_irq, host); // if (host->dma < 0) { // ret = -EBUSY; // goto out; // } // ret = request_irq(host->irq, csb536pc_mmc_irq, 0, DRIVER_NAME, host); // if (ret) // goto out; dev_set_drvdata(dev, mmc); // if (host->pdata && host->pdata->init) // host->pdata->init(dev, csb536pc_mmc_detect_irq, mmc); mmc_add_host(mmc); return 0; out: if (host) { // if (host->dma >= 0) // pxa_free_dma(host->dma); if (host->base) iounmap(host->base); // if (host->sg_cpu) // dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); } if (mmc) mmc_free_host(mmc); release_resource(r); return ret; }
static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; int r; mmc = mmc_alloc_host(sizeof(struct mmc_omap_slot), host->dev); if (mmc == NULL) return -ENOMEM; slot = mmc_priv(mmc); slot->host = host; slot->mmc = mmc; slot->id = id; slot->pdata = &host->pdata->slots[id]; host->slots[id] = slot; mmc->caps = 0; if (host->pdata->slots[id].wires >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->ops = &mmc_omap_ops; mmc->f_min = 400000; if (cpu_class_is_omap2()) mmc->f_max = 48000000; else mmc->f_max = 24000000; if (host->pdata->max_freq) mmc->f_max = min(host->pdata->max_freq, mmc->f_max); mmc->ocr_avail = slot->pdata->ocr_mask; /* Use scatterlist DMA to reduce per-transfer costs. * NOTE max_seg_size assumption that small blocks aren't * normally used (except e.g. for reading SD registers). */ mmc->max_segs = 32; mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */ mmc->max_blk_count = 2048; /* NBLK is 11 bits (+1) */ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; r = mmc_add_host(mmc); if (r < 0) goto err_remove_host; if (slot->pdata->name != NULL) { r = device_create_file(&mmc->class_dev, &dev_attr_slot_name); if (r < 0) goto err_remove_host; } if (slot->pdata->get_cover_state != NULL) { r = device_create_file(&mmc->class_dev, &dev_attr_cover_switch); if (r < 0) goto err_remove_slot_name; setup_timer(&slot->cover_timer, mmc_omap_cover_timer, (unsigned long)slot); tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, (unsigned long)slot); tasklet_schedule(&slot->cover_tasklet); } return 0; err_remove_slot_name: if (slot->pdata->name != NULL) device_remove_file(&mmc->class_dev, &dev_attr_slot_name); err_remove_host: mmc_remove_host(mmc); mmc_free_host(mmc); return r; }
static int s3c_sdi_probe(struct device *dev) { struct platform_device* pdev = to_platform_device(dev); struct mmc_host *mmc; struct s3c_sdi_host *host; int ret; #ifdef CONFIG_S3C2443_EVT1 /* EXTINT0 S3C2443 EVT1 workaround */ u32 tmp; #endif mmc = mmc_alloc_host(sizeof(struct s3c_sdi_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto probe_out; } host = mmc_priv(mmc); spin_lock_init(&host->complete_lock); host->complete_what = COMPLETION_NONE; host->mmc = mmc; #if CONFIG_MACH_TOMTOMGO host->irq_cd = IO_GetInterruptNumber(CD_SD); mmc->removable = 1; #elif CONFIG_ARCH_S3C2460 host->irq_cd = IRQ_EINT3; #elif defined(CONFIG_MACH_SMDK2443) host->irq_cd = IRQ_EINT1; #elif defined(CONFIG_ARCH_MDIRAC3) host->subchannel =S3C_DMA3_SDMMC; // host->irq_cd = IRQ_EINT7; #elif defined CONFIG_ARCH_S3C2412 host->irq_cd = IRQ_EINT18; #endif host->dma = S3C_SDI_DMA; host->mem = platform_get_resource(pdev, IORESOURCE_MEM ,0); if (!host->mem) { printk("failed to get io memory region resource.\n"); ret = -ENOENT; goto probe_free_host; } host->mem = request_mem_region(host->mem->start, RESSIZE(host->mem), pdev->name); if (!host->mem) { printk("failed to request io memory region.\n"); ret = -ENOENT; goto probe_free_host; } /* if there is an error here, check your SoC dependent code. * You must have iotable that contains SDI in it. * by scsuh. */ host->base = S3C24XX_VA_SDI; host->irq = platform_get_irq(pdev, 0); if (host->irq == 0) { printk("failed to get interrupt resouce.\n"); ret = -EINVAL; goto release_memory; } if (request_irq(host->irq, s3c_sdi_irq, 0, DRIVER_NAME, host)) { printk("failed to request sdi interrupt.\n"); ret = -ENOENT; goto release_memory; } #if defined(CONFIG_MACH_SMDK2443) #ifdef CONFIG_S3C2443_EVT1 /* EXTINT0 S3C2443 EVT1 workaround */ tmp = __raw_readl(S3C_EXTINT0); s3c_swap_4bit(tmp); __raw_writel(tmp | (1<<7), S3C_EXTINT0); #endif s3c_gpio_cfgpin(S3C_GPF1, S3C_GPF1_EINT1); #elif defined(CONFIG_ARCH_S3C2460) s3c_gpio_cfgpin(S3C_GPJ3, S3C_GPJ3_EXT_INT3); #elif defined CONFIG_ARCH_S3C2412 s3c_gpio_cfgpin(S3C_GPG10, S3C_GPG10_EINT18); #elif defined CONFIG_ARCH_MDIRAC3 ; #endif #ifdef CONFIG_ARCH_MDIRAC3 if (s3c_dma_request(host->dma,host->subchannel, &s3c_sdi_dma_client,NULL)) { printk("unable to get DMA channel.\n" ); ret = -EBUSY; goto probe_free_irq_cd; } #else INIT_WORK( &host->irq_cd_wq, s3c24xx_irq_cd_handler, mmc ); set_irq_type(host->irq_cd, IRQT_BOTHEDGE); if (host->irq_cd > 0) { if (request_irq(host->irq_cd, s3c_sdi_irq_cd, SA_INTERRUPT, DRIVER_NAME, host)) { printk("failed to request card detect interrupt.\n" ); ret = -ENOENT; goto probe_free_irq; } } if (s3c_dma_request(S3C_SDI_DMA, &s3c_sdi_dma_client, NULL)) { printk("unable to get DMA channel.\n" ); ret = -EBUSY; goto probe_free_irq_cd; } #endif host->clk = clk_get(&pdev->dev, "sdi"); if (IS_ERR(host->clk)) { printk("failed to find clock source.\n"); ret = PTR_ERR(host->clk); host->clk = NULL; goto probe_free_host; } if ((ret = clk_enable(host->clk))) { printk("failed to enable clock source.\n"); goto clk_free; } mmc->ops = &s3c_sdi_ops; mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; mmc->f_min = clk_get_rate(host->clk) / 512; /* you must make sure that our sdmmc block can support * up to 25MHz. by scsuh */ mmc->f_max = 25 * MHZ; mmc->caps = MMC_CAP_4_BIT_DATA; /* * 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; /* * Both block size and block count use 12 bit registers. */ mmc->max_blk_size = 4095; mmc->max_blk_count = 4095; printk(KERN_INFO PFX "probe: mapped sdi_base=%p irq=%u irq_cd=%u dma=%u.\n", host->base, host->irq, host->irq_cd, host->dma); platform_set_drvdata(pdev, mmc); init_timer(&host->timer); host->timer.data = (unsigned long)host; host->timer.function = s3c_sdi_check_status; host->timer.expires = jiffies + HZ; host->ena_2410_workaround=(IO_GetCpuType( ) == GOCPU_S3C2410); if ((ret = mmc_add_host(mmc))) { printk(KERN_INFO PFX "failed to add mmc host.\n"); goto free_dmabuf; } /* Do CPUFREQ registration. */ #if defined CONFIG_CPU_FREQ && defined CONFIG_S3C24XX_DFS_CPUFREQ host->freq_transition.notifier_call = s3c24xxsdi_freq_transition; host->freq_transition.priority = CPUFREQ_ORDER_S3C24XX_SDCARD_PRIO; host->freq_policy.notifier_call = s3c24xxsdi_freq_policy; cpufreq_register_notifier(&host->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); cpufreq_register_notifier(&host->freq_policy, CPUFREQ_POLICY_NOTIFIER); #endif printk(KERN_INFO PFX "initialization done.\n"); return 0; free_dmabuf: clk_disable(host->clk); clk_free: clk_put(host->clk); probe_free_irq_cd: #ifndef CONFIG_ARCH_MDIRAC3 free_irq(host->irq_cd, host); #endif probe_free_irq: free_irq(host->irq, host); release_memory: release_mem_region(host->mem->start, RESSIZE(host->mem)); probe_free_host: mmc_free_host(mmc); probe_out: return ret; }
static int mxs_mmc_probe(struct platform_device *pdev) { const struct of_device_id *of_id = of_match_device(mxs_mmc_dt_ids, &pdev->dev); struct device_node *np = pdev->dev.of_node; struct mxs_mmc_host *host; struct mmc_host *mmc; struct resource *iores; int ret = 0, irq_err; struct regulator *reg_vmmc; struct mxs_ssp *ssp; irq_err = platform_get_irq(pdev, 0); if (irq_err < 0) return irq_err; mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); if (!mmc) return -ENOMEM; host = mmc_priv(mmc); ssp = &host->ssp; ssp->dev = &pdev->dev; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); ssp->base = devm_ioremap_resource(&pdev->dev, iores); if (IS_ERR(ssp->base)) { ret = PTR_ERR(ssp->base); goto out_mmc_free; } ssp->devid = (enum mxs_ssp_id) of_id->data; host->mmc = mmc; host->sdio_irq_en = 0; reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc"); if (!IS_ERR(reg_vmmc)) { ret = regulator_enable(reg_vmmc); if (ret) { dev_err(&pdev->dev, "Failed to enable vmmc regulator: %d\n", ret); goto out_mmc_free; } } ssp->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssp->clk)) { ret = PTR_ERR(ssp->clk); goto out_mmc_free; } ret = clk_prepare_enable(ssp->clk); if (ret) goto out_mmc_free; ret = mxs_mmc_reset(host); if (ret) { dev_err(&pdev->dev, "Failed to reset mmc: %d\n", ret); goto out_clk_disable; } ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx"); if (!ssp->dmach) { dev_err(mmc_dev(host->mmc), "%s: failed to request dma\n", __func__); ret = -ENODEV; goto out_clk_disable; } /* set mmc core parameters */ mmc->ops = &mxs_mmc_ops; mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; host->broken_cd = of_property_read_bool(np, "broken-cd"); mmc->f_min = 400000; mmc->f_max = 288000000; ret = mmc_of_parse(mmc); if (ret) goto out_clk_disable; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->max_segs = 52; mmc->max_blk_size = 1 << 0xf; mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev); platform_set_drvdata(pdev, mmc); ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, dev_name(&pdev->dev), host); if (ret) goto out_free_dma; spin_lock_init(&host->lock); ret = mmc_add_host(mmc); if (ret) goto out_free_dma; dev_info(mmc_dev(host->mmc), "initialized\n"); return 0; out_free_dma: dma_release_channel(ssp->dmach); out_clk_disable: clk_disable_unprepare(ssp->clk); out_mmc_free: mmc_free_host(mmc); return ret; }