Lines Matching refs:host
86 static inline void pxamci_init_ocr(struct pxamci_host *host) in pxamci_init_ocr() argument
89 host->vcc = regulator_get_optional(mmc_dev(host->mmc), "vmmc"); in pxamci_init_ocr()
91 if (IS_ERR(host->vcc)) in pxamci_init_ocr()
92 host->vcc = NULL; in pxamci_init_ocr()
94 host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); in pxamci_init_ocr()
95 if (host->pdata && host->pdata->ocr_mask) in pxamci_init_ocr()
96 dev_warn(mmc_dev(host->mmc), in pxamci_init_ocr()
100 if (host->vcc == NULL) { in pxamci_init_ocr()
102 host->mmc->ocr_avail = host->pdata ? in pxamci_init_ocr()
103 host->pdata->ocr_mask : in pxamci_init_ocr()
108 static inline int pxamci_set_power(struct pxamci_host *host, in pxamci_set_power() argument
114 if (host->vcc) { in pxamci_set_power()
118 ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); in pxamci_set_power()
122 ret = mmc_regulator_set_ocr(host->mmc, host->vcc, 0); in pxamci_set_power()
127 if (!host->vcc && host->pdata && in pxamci_set_power()
128 gpio_is_valid(host->pdata->gpio_power)) { in pxamci_set_power()
129 on = ((1 << vdd) & host->pdata->ocr_mask); in pxamci_set_power()
130 gpio_set_value(host->pdata->gpio_power, in pxamci_set_power()
131 !!on ^ host->pdata->gpio_power_invert); in pxamci_set_power()
133 if (!host->vcc && host->pdata && host->pdata->setpower) in pxamci_set_power()
134 return host->pdata->setpower(mmc_dev(host->mmc), vdd); in pxamci_set_power()
139 static void pxamci_stop_clock(struct pxamci_host *host) in pxamci_stop_clock() argument
141 if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { in pxamci_stop_clock()
145 writel(STOP_CLOCK, host->base + MMC_STRPCL); in pxamci_stop_clock()
148 v = readl(host->base + MMC_STAT); in pxamci_stop_clock()
155 dev_err(mmc_dev(host->mmc), "unable to stop clock\n"); in pxamci_stop_clock()
159 static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask) in pxamci_enable_irq() argument
163 spin_lock_irqsave(&host->lock, flags); in pxamci_enable_irq()
164 host->imask &= ~mask; in pxamci_enable_irq()
165 writel(host->imask, host->base + MMC_I_MASK); in pxamci_enable_irq()
166 spin_unlock_irqrestore(&host->lock, flags); in pxamci_enable_irq()
169 static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) in pxamci_disable_irq() argument
173 spin_lock_irqsave(&host->lock, flags); in pxamci_disable_irq()
174 host->imask |= mask; in pxamci_disable_irq()
175 writel(host->imask, host->base + MMC_I_MASK); in pxamci_disable_irq()
176 spin_unlock_irqrestore(&host->lock, flags); in pxamci_disable_irq()
181 static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) in pxamci_setup_data() argument
192 host->data = data; in pxamci_setup_data()
197 writel(nob, host->base + MMC_NOB); in pxamci_setup_data()
198 writel(data->blksz, host->base + MMC_BLKLEN); in pxamci_setup_data()
200 clks = (unsigned long long)data->timeout_ns * host->clkrate; in pxamci_setup_data()
202 timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); in pxamci_setup_data()
203 writel((timeout + 255) / 256, host->base + MMC_RDTO); in pxamci_setup_data()
208 config.src_addr = host->res->start + MMC_RXFIFO; in pxamci_setup_data()
209 config.dst_addr = host->res->start + MMC_TXFIFO; in pxamci_setup_data()
214 host->dma_dir = DMA_FROM_DEVICE; in pxamci_setup_data()
216 chan = host->dma_chan_rx; in pxamci_setup_data()
218 host->dma_dir = DMA_TO_DEVICE; in pxamci_setup_data()
220 chan = host->dma_chan_tx; in pxamci_setup_data()
227 dev_err(mmc_dev(host->mmc), "dma slave config failed\n"); in pxamci_setup_data()
231 host->dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, in pxamci_setup_data()
232 host->dma_dir); in pxamci_setup_data()
234 tx = dmaengine_prep_slave_sg(chan, data->sg, host->dma_len, direction, in pxamci_setup_data()
237 dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n"); in pxamci_setup_data()
243 tx->callback_param = host; in pxamci_setup_data()
246 host->dma_cookie = dmaengine_submit(tx); in pxamci_setup_data()
258 static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) in pxamci_start_cmd() argument
260 WARN_ON(host->cmd != NULL); in pxamci_start_cmd()
261 host->cmd = cmd; in pxamci_start_cmd()
281 writel(cmd->opcode, host->base + MMC_CMD); in pxamci_start_cmd()
282 writel(cmd->arg >> 16, host->base + MMC_ARGH); in pxamci_start_cmd()
283 writel(cmd->arg & 0xffff, host->base + MMC_ARGL); in pxamci_start_cmd()
284 writel(cmdat, host->base + MMC_CMDAT); in pxamci_start_cmd()
285 writel(host->clkrt, host->base + MMC_CLKRT); in pxamci_start_cmd()
287 writel(START_CLOCK, host->base + MMC_STRPCL); in pxamci_start_cmd()
289 pxamci_enable_irq(host, END_CMD_RES); in pxamci_start_cmd()
292 static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) in pxamci_finish_request() argument
294 host->mrq = NULL; in pxamci_finish_request()
295 host->cmd = NULL; in pxamci_finish_request()
296 host->data = NULL; in pxamci_finish_request()
297 mmc_request_done(host->mmc, mrq); in pxamci_finish_request()
300 static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) in pxamci_cmd_done() argument
302 struct mmc_command *cmd = host->cmd; in pxamci_cmd_done()
309 host->cmd = NULL; in pxamci_cmd_done()
315 v = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
317 u32 w1 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
318 u32 w2 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
339 pxamci_disable_irq(host, END_CMD_RES); in pxamci_cmd_done()
340 if (host->data && !cmd->error) { in pxamci_cmd_done()
341 pxamci_enable_irq(host, DATA_TRAN_DONE); in pxamci_cmd_done()
346 if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) in pxamci_cmd_done()
347 dma_async_issue_pending(host->dma_chan_tx); in pxamci_cmd_done()
349 pxamci_finish_request(host, host->mrq); in pxamci_cmd_done()
355 static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) in pxamci_data_done() argument
357 struct mmc_data *data = host->data; in pxamci_data_done()
364 chan = host->dma_chan_rx; in pxamci_data_done()
366 chan = host->dma_chan_tx; in pxamci_data_done()
368 data->sg, data->sg_len, host->dma_dir); in pxamci_data_done()
386 pxamci_disable_irq(host, DATA_TRAN_DONE); in pxamci_data_done()
388 host->data = NULL; in pxamci_data_done()
389 if (host->mrq->stop) { in pxamci_data_done()
390 pxamci_stop_clock(host); in pxamci_data_done()
391 pxamci_start_cmd(host, host->mrq->stop, host->cmdat); in pxamci_data_done()
393 pxamci_finish_request(host, host->mrq); in pxamci_data_done()
401 struct pxamci_host *host = devid; in pxamci_irq() local
405 ireg = readl(host->base + MMC_I_REG) & ~readl(host->base + MMC_I_MASK); in pxamci_irq()
408 unsigned stat = readl(host->base + MMC_STAT); in pxamci_irq()
413 handled |= pxamci_cmd_done(host, stat); in pxamci_irq()
415 handled |= pxamci_data_done(host, stat); in pxamci_irq()
417 mmc_signal_sdio_irq(host->mmc); in pxamci_irq()
427 struct pxamci_host *host = mmc_priv(mmc); in pxamci_request() local
430 WARN_ON(host->mrq != NULL); in pxamci_request()
432 host->mrq = mrq; in pxamci_request()
434 pxamci_stop_clock(host); in pxamci_request()
436 cmdat = host->cmdat; in pxamci_request()
437 host->cmdat &= ~CMDAT_INIT; in pxamci_request()
440 pxamci_setup_data(host, mrq->data); in pxamci_request()
451 pxamci_start_cmd(host, mrq->cmd, cmdat); in pxamci_request()
456 struct pxamci_host *host = mmc_priv(mmc); in pxamci_get_ro() local
458 if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro)) in pxamci_get_ro()
460 if (host->pdata && host->pdata->get_ro) in pxamci_get_ro()
461 return !!host->pdata->get_ro(mmc_dev(mmc)); in pxamci_get_ro()
471 struct pxamci_host *host = mmc_priv(mmc); in pxamci_set_ios() local
474 unsigned long rate = host->clkrate; in pxamci_set_ios()
477 if (host->clkrt == CLKRT_OFF) in pxamci_set_ios()
478 clk_prepare_enable(host->clk); in pxamci_set_ios()
482 host->clkrt = 7; in pxamci_set_ios()
495 host->clkrt = fls(clk) - 1; in pxamci_set_ios()
502 pxamci_stop_clock(host); in pxamci_set_ios()
503 if (host->clkrt != CLKRT_OFF) { in pxamci_set_ios()
504 host->clkrt = CLKRT_OFF; in pxamci_set_ios()
505 clk_disable_unprepare(host->clk); in pxamci_set_ios()
509 if (host->power_mode != ios->power_mode) { in pxamci_set_ios()
512 host->power_mode = ios->power_mode; in pxamci_set_ios()
514 ret = pxamci_set_power(host, ios->power_mode, ios->vdd); in pxamci_set_ios()
527 host->cmdat |= CMDAT_INIT; in pxamci_set_ios()
531 host->cmdat |= CMDAT_SD_4DAT; in pxamci_set_ios()
533 host->cmdat &= ~CMDAT_SD_4DAT; in pxamci_set_ios()
536 host->clkrt, host->cmdat); in pxamci_set_ios()
539 static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable) in pxamci_enable_sdio_irq() argument
541 struct pxamci_host *pxa_host = mmc_priv(host); in pxamci_enable_sdio_irq()
559 struct pxamci_host *host = param; in pxamci_dma_irq() local
565 spin_lock_irqsave(&host->lock, flags); in pxamci_dma_irq()
567 if (!host->data) in pxamci_dma_irq()
570 if (host->data->flags & MMC_DATA_READ) in pxamci_dma_irq()
571 chan = host->dma_chan_rx; in pxamci_dma_irq()
573 chan = host->dma_chan_tx; in pxamci_dma_irq()
575 status = dmaengine_tx_status(chan, host->dma_cookie, &state); in pxamci_dma_irq()
578 writel(BUF_PART_FULL, host->base + MMC_PRTBUF); in pxamci_dma_irq()
580 pr_err("%s: DMA error on %s channel\n", mmc_hostname(host->mmc), in pxamci_dma_irq()
581 host->data->flags & MMC_DATA_READ ? "rx" : "tx"); in pxamci_dma_irq()
582 host->data->error = -EIO; in pxamci_dma_irq()
583 pxamci_data_done(host, 0); in pxamci_dma_irq()
587 spin_unlock_irqrestore(&host->lock, flags); in pxamci_dma_irq()
592 struct pxamci_host *host = mmc_priv(devid); in pxamci_detect_irq() local
594 mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms)); in pxamci_detect_irq()
645 struct pxamci_host *host = NULL; in pxamci_probe() local
693 host = mmc_priv(mmc); in pxamci_probe()
694 host->mmc = mmc; in pxamci_probe()
695 host->pdata = pdev->dev.platform_data; in pxamci_probe()
696 host->clkrt = CLKRT_OFF; in pxamci_probe()
698 host->clk = clk_get(&pdev->dev, NULL); in pxamci_probe()
699 if (IS_ERR(host->clk)) { in pxamci_probe()
700 ret = PTR_ERR(host->clk); in pxamci_probe()
701 host->clk = NULL; in pxamci_probe()
705 host->clkrate = clk_get_rate(host->clk); in pxamci_probe()
710 mmc->f_min = (host->clkrate + 63) / 64; in pxamci_probe()
711 mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate; in pxamci_probe()
713 pxamci_init_ocr(host); in pxamci_probe()
716 host->cmdat = 0; in pxamci_probe()
719 host->cmdat |= CMDAT_SDIO_INT_EN; in pxamci_probe()
725 spin_lock_init(&host->lock); in pxamci_probe()
726 host->res = r; in pxamci_probe()
727 host->irq = irq; in pxamci_probe()
728 host->imask = MMC_I_MASK_ALL; in pxamci_probe()
730 host->base = ioremap(r->start, SZ_4K); in pxamci_probe()
731 if (!host->base) { in pxamci_probe()
740 pxamci_stop_clock(host); in pxamci_probe()
741 writel(0, host->base + MMC_SPI); in pxamci_probe()
742 writel(64, host->base + MMC_RESTO); in pxamci_probe()
743 writel(host->imask, host->base + MMC_I_MASK); in pxamci_probe()
745 ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host); in pxamci_probe()
767 host->dma_chan_rx = in pxamci_probe()
770 if (host->dma_chan_rx == NULL) { in pxamci_probe()
776 host->dma_chan_tx = in pxamci_probe()
779 if (host->dma_chan_tx == NULL) { in pxamci_probe()
785 if (host->pdata) { in pxamci_probe()
786 gpio_cd = host->pdata->gpio_card_detect; in pxamci_probe()
787 gpio_ro = host->pdata->gpio_card_ro; in pxamci_probe()
788 gpio_power = host->pdata->gpio_power; in pxamci_probe()
799 host->pdata->gpio_power_invert); in pxamci_probe()
807 mmc->caps2 |= host->pdata->gpio_card_ro_invert ? in pxamci_probe()
818 if (host->pdata && host->pdata->init) in pxamci_probe()
819 host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc); in pxamci_probe()
821 if (gpio_is_valid(gpio_power) && host->pdata->setpower) in pxamci_probe()
823 if (gpio_is_valid(gpio_ro) && host->pdata->get_ro) in pxamci_probe()
831 if (host) { in pxamci_probe()
832 if (host->dma_chan_rx) in pxamci_probe()
833 dma_release_channel(host->dma_chan_rx); in pxamci_probe()
834 if (host->dma_chan_tx) in pxamci_probe()
835 dma_release_channel(host->dma_chan_tx); in pxamci_probe()
836 if (host->base) in pxamci_probe()
837 iounmap(host->base); in pxamci_probe()
838 if (host->clk) in pxamci_probe()
839 clk_put(host->clk); in pxamci_probe()
853 struct pxamci_host *host = mmc_priv(mmc); in pxamci_remove() local
857 if (host->pdata) { in pxamci_remove()
858 gpio_cd = host->pdata->gpio_card_detect; in pxamci_remove()
859 gpio_ro = host->pdata->gpio_card_ro; in pxamci_remove()
860 gpio_power = host->pdata->gpio_power; in pxamci_remove()
862 if (host->vcc) in pxamci_remove()
863 regulator_put(host->vcc); in pxamci_remove()
865 if (host->pdata && host->pdata->exit) in pxamci_remove()
866 host->pdata->exit(&pdev->dev, mmc); in pxamci_remove()
868 pxamci_stop_clock(host); in pxamci_remove()
871 host->base + MMC_I_MASK); in pxamci_remove()
873 free_irq(host->irq, host); in pxamci_remove()
874 dmaengine_terminate_all(host->dma_chan_rx); in pxamci_remove()
875 dmaengine_terminate_all(host->dma_chan_tx); in pxamci_remove()
876 dma_release_channel(host->dma_chan_rx); in pxamci_remove()
877 dma_release_channel(host->dma_chan_tx); in pxamci_remove()
878 iounmap(host->base); in pxamci_remove()
880 clk_put(host->clk); in pxamci_remove()
882 release_resource(host->res); in pxamci_remove()