/* Set hwif for S3C2410/S3C2440, by www.100ask.net */ static void __init ide_s3c24xx_init(void) { int i; unsigned int oldval_bwscon; /* 用来保存BWSCON寄存器的值 */ unsigned long mapaddr0; unsigned long mapaddr1; unsigned long baseaddr[] = IDE_ARM_IOs; hw_regs_t hw; /* 设置BANK1/2: 总线宽度为16 */ oldval_bwscon = readl(S3C2410_BWSCON); writel((oldval_bwscon & ~((3<<4)|(3<<8))) \ | S3C2410_BWSCON_DW1_16 | S3C2410_BWSCON_WS1 | S3C2410_BWSCON_DW2_16 | S3C2410_BWSCON_WS2, S3C2410_BWSCON); /* 设置BANK1/2的时间参数 */ writel((S3C2410_BANKCON_Tacs4 | S3C2410_BANKCON_Tcos4 | S3C2410_BANKCON_Tacc14 | S3C2410_BANKCON_Tcoh4 | S3C2410_BANKCON_Tcah4 | S3C2410_BANKCON_Tacp6 | S3C2410_BANKCON_PMCnorm), S3C2410_BANKCON1); writel((S3C2410_BANKCON_Tacs4 | S3C2410_BANKCON_Tcos4 | S3C2410_BANKCON_Tacc14 | S3C2410_BANKCON_Tcoh4 | S3C2410_BANKCON_Tcah4 | S3C2410_BANKCON_Tacp6 | S3C2410_BANKCON_PMCnorm), S3C2410_BANKCON2); /* * 设置IDE接口的地址, ADDR3~1接到IDE接口的A02~00 * 注意:没有使用ADDR0,所以下面确定地址时,都左移1位 */ mapaddr0 = (unsigned long)ioremap(baseaddr[0], 16); mapaddr1 = (unsigned long)ioremap(baseaddr[1], 16); memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) hw.io_ports[i] = mapaddr0 + (i<<1); hw.io_ports[IDE_CONTROL_OFFSET] = mapaddr1 + (6<<1); /* 设置中断引脚 */ hw.irq = s3c2410_gpio_getirq(IDE_ARM_IRQPIN); s3c2410_gpio_cfgpin(IDE_ARM_IRQPIN, S3C2410_GPIO_IRQ); set_irq_type(hw.irq, IRQF_TRIGGER_RISING); /* 注册IDE接口 */ ide_register_hw(&hw, 1, NULL); }
static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) { unsigned long irqstate; unsigned long pinstate; int irq = s3c2410_gpio_getirq(pin); if (irqoffs < 4) irqstate = s3c_irqwake_intmask & (1L<<irqoffs); else irqstate = s3c_irqwake_eintmask & (1L<<irqoffs); pinstate = s3c2410_gpio_getcfg(pin); if (!irqstate) { if (pinstate == S3C2410_GPIO_IRQ) S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); } else { if (pinstate == S3C2410_GPIO_IRQ) { S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); } } }
static int s3cmci_probe(struct platform_device *pdev, int is2440) { struct mmc_host *mmc; struct s3cmci_host *host; 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->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->is2440 = 1; host->sdiimsk = S3C2440_SDIIMSK; host->sdidata = S3C2440_SDIDATA; host->clk_div = 1; } else { host->is2440 = 0; 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->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); 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; } disable_irq(host->irq); printk("======>>>> card detect [ %d ]\n", host->pdata->gpio_detect); s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); set_irq_type(host->irq_cd, IRQT_BOTHEDGE); // set_irq_type(host->irq_cd, IRQT_LOW); if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { dev_err(&pdev->dev, "failed to request card detect interrupt.\n"); ret = -ENOENT; goto probe_free_irq; } 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)) { 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; } if ((ret = clk_enable(host->clk))) { 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 = host->pdata->ocr_avail; 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; 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); if ((ret = mmc_add_host(mmc))) { 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: 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 __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; }