static int mmci_probe(struct amba_device *dev, void *id) { struct mmc_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->clk = clk_get(&dev->dev, "MCLK"); 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->mmc = mmc; host->base = ioremap(dev->res.start, SZ_4K); 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); mmc->ocr_avail = plat->ocr_mask; /* * 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); 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); 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: 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; }
static int mmci_driver_probe(struct vmm_device *dev, const struct vmm_devtree_nodeid *devid) { int rc; u32 sdi; virtual_addr_t base; physical_addr_t basepa; struct mmc_host *mmc; struct mmci_host *host; mmc = mmc_alloc_host(sizeof(struct mmci_host), dev); if (!mmc) { rc = VMM_ENOMEM; goto free_nothing; } host = mmc_priv(mmc); rc = vmm_devtree_regmap(dev->node, &base, 0); if (rc) { goto free_host; } host->base = (struct sdi_registers *)base; rc = vmm_devtree_irq_get(dev->node, &host->irq0, 0); if (rc) { goto free_reg; } if ((rc = vmm_host_irq_register(host->irq0, dev->name, mmci_cmd_irq_handler, mmc))) { goto free_reg; } rc = vmm_devtree_irq_get(dev->node, &host->irq1, 1); if (!rc) { if ((rc = vmm_host_irq_register(host->irq1, dev->name, mmci_pio_irq_handler, mmc))) { goto free_irq0; } host->singleirq = 0; } else { host->singleirq = 1; } /* Retrive matching data */ host->pwr_init = ((const u32 *)devid->data)[0]; host->clkdiv_init = ((const u32 *)devid->data)[1]; host->voltages = ((const u32 *)devid->data)[2]; host->caps = ((const u32 *)devid->data)[3]; host->clock_in = ((const u32 *)devid->data)[4]; host->clock_min = ((const u32 *)devid->data)[5]; host->clock_max = ((const u32 *)devid->data)[6]; host->b_max = ((const u32 *)devid->data)[7]; host->version2 = ((const u32 *)devid->data)[8]; /* Initialize power and clock divider */ vmm_writel(host->pwr_init, &host->base->power); vmm_writel(host->clkdiv_init, &host->base->clock); vmm_udelay(CLK_CHANGE_DELAY); /* Disable interrupts */ sdi = vmm_readl(&host->base->mask0) & ~SDI_MASK0_MASK; vmm_writel(sdi, &host->base->mask0); /* Setup mmc host configuration */ mmc->caps = host->caps; mmc->voltages = host->voltages; mmc->f_min = host->clock_min; mmc->f_max = host->clock_max; mmc->b_max = host->b_max; /* Setup mmc host operations */ mmc->ops.send_cmd = mmci_request; mmc->ops.set_ios = mmci_set_ios; mmc->ops.init_card = mmci_init_card; mmc->ops.get_cd = NULL; mmc->ops.get_wp = NULL; rc = mmc_add_host(mmc); if (rc) { goto free_irq1; } dev->priv = mmc; vmm_devtree_regaddr(dev->node, &basepa, 0); vmm_printf("%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", dev->name, amba_part(dev), amba_manf(dev), amba_rev(dev), (unsigned long long)basepa, host->irq0, host->irq1); return VMM_OK; free_irq1: if (!host->singleirq) { vmm_host_irq_unregister(host->irq1, mmc); } free_irq0: vmm_host_irq_unregister(host->irq0, mmc); free_reg: vmm_devtree_regunmap(dev->node, (virtual_addr_t)host->base, 0); free_host: mmc_free_host(mmc); free_nothing: return rc; }
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; }
static int mmci_probe(struct amba_device *dev, void *id) { struct mmc_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->clk = clk_get(&dev->dev, "MCLK"); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); host->clk = NULL; goto host_free; } ret = clk_use(host->clk); if (ret) goto clk_free; ret = clk_enable(host->clk); if (ret) goto clk_unuse; host->plat = plat; host->mclk = clk_get_rate(host->clk); host->mmc = mmc; host->base = ioremap(dev->res.start, SZ_4K); 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); mmc->ocr_avail = plat->ocr_mask; /* * 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. * Choose 64 (512-byte) sectors as the limit. */ mmc->max_sectors = 64; /* * 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_sectors << 9; spin_lock_init(&host->lock); writel(0, host->base + MMCIMASK0); writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); ret = request_irq(dev->irq[0], mmci_irq, SA_SHIRQ, DRIVER_NAME " (cmd)", host); if (ret) goto unmap; ret = request_irq(dev->irq[1], mmci_pio_irq, SA_SHIRQ, DRIVER_NAME " (pio)", host); if (ret) goto irq0_free; writel(MCI_IRQENABLE, host->base + MMCIMASK0); amba_set_drvdata(dev, mmc); mmc_add_host(mmc); printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", mmc_hostname(mmc), amba_rev(dev), amba_config(dev), 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: iounmap(host->base); clk_disable: clk_disable(host->clk); clk_unuse: clk_unuse(host->clk); clk_free: clk_put(host->clk); host_free: mmc_free_host(mmc); rel_regions: amba_release_regions(dev); out: return ret; }