• Home
  • Raw
  • Download

Lines Matching refs:host

77 static int pxamci_init_ocr(struct pxamci_host *host)  in pxamci_init_ocr()  argument
79 struct mmc_host *mmc = host->mmc; in pxamci_init_ocr()
88 mmc->ocr_avail = host->pdata ? in pxamci_init_ocr()
89 host->pdata->ocr_mask : in pxamci_init_ocr()
96 static inline int pxamci_set_power(struct pxamci_host *host, in pxamci_set_power() argument
100 struct mmc_host *mmc = host->mmc; in pxamci_set_power()
106 if (host->power) { in pxamci_set_power()
107 bool on = !!((1 << vdd) & host->pdata->ocr_mask); in pxamci_set_power()
108 gpiod_set_value(host->power, on); in pxamci_set_power()
111 if (host->pdata && host->pdata->setpower) in pxamci_set_power()
112 return host->pdata->setpower(mmc_dev(host->mmc), vdd); in pxamci_set_power()
117 static void pxamci_stop_clock(struct pxamci_host *host) in pxamci_stop_clock() argument
119 if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { in pxamci_stop_clock()
123 writel(STOP_CLOCK, host->base + MMC_STRPCL); in pxamci_stop_clock()
126 v = readl(host->base + MMC_STAT); in pxamci_stop_clock()
133 dev_err(mmc_dev(host->mmc), "unable to stop clock\n"); in pxamci_stop_clock()
137 static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask) in pxamci_enable_irq() argument
141 spin_lock_irqsave(&host->lock, flags); in pxamci_enable_irq()
142 host->imask &= ~mask; in pxamci_enable_irq()
143 writel(host->imask, host->base + MMC_I_MASK); in pxamci_enable_irq()
144 spin_unlock_irqrestore(&host->lock, flags); in pxamci_enable_irq()
147 static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) in pxamci_disable_irq() argument
151 spin_lock_irqsave(&host->lock, flags); in pxamci_disable_irq()
152 host->imask |= mask; in pxamci_disable_irq()
153 writel(host->imask, host->base + MMC_I_MASK); in pxamci_disable_irq()
154 spin_unlock_irqrestore(&host->lock, flags); in pxamci_disable_irq()
159 static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) in pxamci_setup_data() argument
170 host->data = data; in pxamci_setup_data()
172 writel(nob, host->base + MMC_NOB); in pxamci_setup_data()
173 writel(data->blksz, host->base + MMC_BLKLEN); in pxamci_setup_data()
175 clks = (unsigned long long)data->timeout_ns * host->clkrate; in pxamci_setup_data()
177 timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); in pxamci_setup_data()
178 writel((timeout + 255) / 256, host->base + MMC_RDTO); in pxamci_setup_data()
183 config.src_addr = host->res->start + MMC_RXFIFO; in pxamci_setup_data()
184 config.dst_addr = host->res->start + MMC_TXFIFO; in pxamci_setup_data()
189 host->dma_dir = DMA_FROM_DEVICE; in pxamci_setup_data()
191 chan = host->dma_chan_rx; in pxamci_setup_data()
193 host->dma_dir = DMA_TO_DEVICE; in pxamci_setup_data()
195 chan = host->dma_chan_tx; in pxamci_setup_data()
202 dev_err(mmc_dev(host->mmc), "dma slave config failed\n"); in pxamci_setup_data()
206 host->dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, in pxamci_setup_data()
207 host->dma_dir); in pxamci_setup_data()
209 tx = dmaengine_prep_slave_sg(chan, data->sg, host->dma_len, direction, in pxamci_setup_data()
212 dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n"); in pxamci_setup_data()
218 tx->callback_param = host; in pxamci_setup_data()
221 host->dma_cookie = dmaengine_submit(tx); in pxamci_setup_data()
233 static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) in pxamci_start_cmd() argument
235 WARN_ON(host->cmd != NULL); in pxamci_start_cmd()
236 host->cmd = cmd; in pxamci_start_cmd()
256 writel(cmd->opcode, host->base + MMC_CMD); in pxamci_start_cmd()
257 writel(cmd->arg >> 16, host->base + MMC_ARGH); in pxamci_start_cmd()
258 writel(cmd->arg & 0xffff, host->base + MMC_ARGL); in pxamci_start_cmd()
259 writel(cmdat, host->base + MMC_CMDAT); in pxamci_start_cmd()
260 writel(host->clkrt, host->base + MMC_CLKRT); in pxamci_start_cmd()
262 writel(START_CLOCK, host->base + MMC_STRPCL); in pxamci_start_cmd()
264 pxamci_enable_irq(host, END_CMD_RES); in pxamci_start_cmd()
267 static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) in pxamci_finish_request() argument
269 host->mrq = NULL; in pxamci_finish_request()
270 host->cmd = NULL; in pxamci_finish_request()
271 host->data = NULL; in pxamci_finish_request()
272 mmc_request_done(host->mmc, mrq); in pxamci_finish_request()
275 static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) in pxamci_cmd_done() argument
277 struct mmc_command *cmd = host->cmd; in pxamci_cmd_done()
284 host->cmd = NULL; in pxamci_cmd_done()
290 v = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
292 u32 w1 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
293 u32 w2 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
314 pxamci_disable_irq(host, END_CMD_RES); in pxamci_cmd_done()
315 if (host->data && !cmd->error) { in pxamci_cmd_done()
316 pxamci_enable_irq(host, DATA_TRAN_DONE); in pxamci_cmd_done()
321 if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) in pxamci_cmd_done()
322 dma_async_issue_pending(host->dma_chan_tx); in pxamci_cmd_done()
324 pxamci_finish_request(host, host->mrq); in pxamci_cmd_done()
330 static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) in pxamci_data_done() argument
332 struct mmc_data *data = host->data; in pxamci_data_done()
339 chan = host->dma_chan_rx; in pxamci_data_done()
341 chan = host->dma_chan_tx; in pxamci_data_done()
343 data->sg, data->sg_len, host->dma_dir); in pxamci_data_done()
361 pxamci_disable_irq(host, DATA_TRAN_DONE); in pxamci_data_done()
363 host->data = NULL; in pxamci_data_done()
364 if (host->mrq->stop) { in pxamci_data_done()
365 pxamci_stop_clock(host); in pxamci_data_done()
366 pxamci_start_cmd(host, host->mrq->stop, host->cmdat); in pxamci_data_done()
368 pxamci_finish_request(host, host->mrq); in pxamci_data_done()
376 struct pxamci_host *host = devid; in pxamci_irq() local
380 ireg = readl(host->base + MMC_I_REG) & ~readl(host->base + MMC_I_MASK); in pxamci_irq()
383 unsigned stat = readl(host->base + MMC_STAT); in pxamci_irq()
388 handled |= pxamci_cmd_done(host, stat); in pxamci_irq()
390 handled |= pxamci_data_done(host, stat); in pxamci_irq()
392 mmc_signal_sdio_irq(host->mmc); in pxamci_irq()
402 struct pxamci_host *host = mmc_priv(mmc); in pxamci_request() local
405 WARN_ON(host->mrq != NULL); in pxamci_request()
407 host->mrq = mrq; in pxamci_request()
409 pxamci_stop_clock(host); in pxamci_request()
411 cmdat = host->cmdat; in pxamci_request()
412 host->cmdat &= ~CMDAT_INIT; in pxamci_request()
415 pxamci_setup_data(host, mrq->data); in pxamci_request()
423 pxamci_start_cmd(host, mrq->cmd, cmdat); in pxamci_request()
428 struct pxamci_host *host = mmc_priv(mmc); in pxamci_get_ro() local
430 if (host->use_ro_gpio) in pxamci_get_ro()
432 if (host->pdata && host->pdata->get_ro) in pxamci_get_ro()
433 return !!host->pdata->get_ro(mmc_dev(mmc)); in pxamci_get_ro()
443 struct pxamci_host *host = mmc_priv(mmc); in pxamci_set_ios() local
446 unsigned long rate = host->clkrate; in pxamci_set_ios()
449 if (host->clkrt == CLKRT_OFF) in pxamci_set_ios()
450 clk_prepare_enable(host->clk); in pxamci_set_ios()
454 host->clkrt = 7; in pxamci_set_ios()
467 host->clkrt = fls(clk) - 1; in pxamci_set_ios()
474 pxamci_stop_clock(host); in pxamci_set_ios()
475 if (host->clkrt != CLKRT_OFF) { in pxamci_set_ios()
476 host->clkrt = CLKRT_OFF; in pxamci_set_ios()
477 clk_disable_unprepare(host->clk); in pxamci_set_ios()
481 if (host->power_mode != ios->power_mode) { in pxamci_set_ios()
484 host->power_mode = ios->power_mode; in pxamci_set_ios()
486 ret = pxamci_set_power(host, ios->power_mode, ios->vdd); in pxamci_set_ios()
499 host->cmdat |= CMDAT_INIT; in pxamci_set_ios()
503 host->cmdat |= CMDAT_SD_4DAT; in pxamci_set_ios()
505 host->cmdat &= ~CMDAT_SD_4DAT; in pxamci_set_ios()
508 host->clkrt, host->cmdat); in pxamci_set_ios()
511 static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable) in pxamci_enable_sdio_irq() argument
513 struct pxamci_host *pxa_host = mmc_priv(host); in pxamci_enable_sdio_irq()
531 struct pxamci_host *host = param; in pxamci_dma_irq() local
537 spin_lock_irqsave(&host->lock, flags); in pxamci_dma_irq()
539 if (!host->data) in pxamci_dma_irq()
542 if (host->data->flags & MMC_DATA_READ) in pxamci_dma_irq()
543 chan = host->dma_chan_rx; in pxamci_dma_irq()
545 chan = host->dma_chan_tx; in pxamci_dma_irq()
547 status = dmaengine_tx_status(chan, host->dma_cookie, &state); in pxamci_dma_irq()
550 writel(BUF_PART_FULL, host->base + MMC_PRTBUF); in pxamci_dma_irq()
552 pr_err("%s: DMA error on %s channel\n", mmc_hostname(host->mmc), in pxamci_dma_irq()
553 host->data->flags & MMC_DATA_READ ? "rx" : "tx"); in pxamci_dma_irq()
554 host->data->error = -EIO; in pxamci_dma_irq()
555 pxamci_data_done(host, 0); in pxamci_dma_irq()
559 spin_unlock_irqrestore(&host->lock, flags); in pxamci_dma_irq()
564 struct pxamci_host *host = mmc_priv(devid); in pxamci_detect_irq() local
566 mmc_detect_change(devid, msecs_to_jiffies(host->detect_delay_ms)); in pxamci_detect_irq()
582 struct pxamci_host *host = mmc_priv(mmc); in pxamci_of_init() local
591 host->detect_delay_ms = tmp; in pxamci_of_init()
610 struct pxamci_host *host = NULL; in pxamci_probe() local
653 host = mmc_priv(mmc); in pxamci_probe()
654 host->mmc = mmc; in pxamci_probe()
655 host->pdata = pdev->dev.platform_data; in pxamci_probe()
656 host->clkrt = CLKRT_OFF; in pxamci_probe()
658 host->clk = devm_clk_get(dev, NULL); in pxamci_probe()
659 if (IS_ERR(host->clk)) { in pxamci_probe()
660 ret = PTR_ERR(host->clk); in pxamci_probe()
661 host->clk = NULL; in pxamci_probe()
665 host->clkrate = clk_get_rate(host->clk); in pxamci_probe()
670 mmc->f_min = (host->clkrate + 63) / 64; in pxamci_probe()
671 mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate; in pxamci_probe()
673 ret = pxamci_init_ocr(host); in pxamci_probe()
678 host->cmdat = 0; in pxamci_probe()
681 host->cmdat |= CMDAT_SDIO_INT_EN; in pxamci_probe()
687 spin_lock_init(&host->lock); in pxamci_probe()
688 host->res = r; in pxamci_probe()
689 host->imask = MMC_I_MASK_ALL; in pxamci_probe()
691 host->base = devm_ioremap_resource(dev, r); in pxamci_probe()
692 if (IS_ERR(host->base)) { in pxamci_probe()
693 ret = PTR_ERR(host->base); in pxamci_probe()
701 pxamci_stop_clock(host); in pxamci_probe()
702 writel(0, host->base + MMC_SPI); in pxamci_probe()
703 writel(64, host->base + MMC_RESTO); in pxamci_probe()
704 writel(host->imask, host->base + MMC_I_MASK); in pxamci_probe()
707 DRIVER_NAME, host); in pxamci_probe()
713 host->dma_chan_rx = dma_request_chan(dev, "rx"); in pxamci_probe()
714 if (IS_ERR(host->dma_chan_rx)) { in pxamci_probe()
716 ret = PTR_ERR(host->dma_chan_rx); in pxamci_probe()
717 host->dma_chan_rx = NULL; in pxamci_probe()
721 host->dma_chan_tx = dma_request_chan(dev, "tx"); in pxamci_probe()
722 if (IS_ERR(host->dma_chan_tx)) { in pxamci_probe()
724 ret = PTR_ERR(host->dma_chan_tx); in pxamci_probe()
725 host->dma_chan_tx = NULL; in pxamci_probe()
729 if (host->pdata) { in pxamci_probe()
730 host->detect_delay_ms = host->pdata->detect_delay_ms; in pxamci_probe()
732 host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); in pxamci_probe()
733 if (IS_ERR(host->power)) { in pxamci_probe()
734 ret = PTR_ERR(host->power); in pxamci_probe()
746 if (!host->pdata->gpio_card_ro_invert) in pxamci_probe()
755 host->use_ro_gpio = true; in pxamci_probe()
757 if (host->pdata->init) in pxamci_probe()
758 host->pdata->init(dev, pxamci_detect_irq, mmc); in pxamci_probe()
760 if (host->power && host->pdata->setpower) in pxamci_probe()
762 if (host->use_ro_gpio && host->pdata->get_ro) in pxamci_probe()
768 if (host->pdata && host->pdata->exit) in pxamci_probe()
769 host->pdata->exit(dev, mmc); in pxamci_probe()
776 if (host) { in pxamci_probe()
777 if (host->dma_chan_rx) in pxamci_probe()
778 dma_release_channel(host->dma_chan_rx); in pxamci_probe()
779 if (host->dma_chan_tx) in pxamci_probe()
780 dma_release_channel(host->dma_chan_tx); in pxamci_probe()
792 struct pxamci_host *host = mmc_priv(mmc); in pxamci_remove() local
796 if (host->pdata && host->pdata->exit) in pxamci_remove()
797 host->pdata->exit(&pdev->dev, mmc); in pxamci_remove()
799 pxamci_stop_clock(host); in pxamci_remove()
802 host->base + MMC_I_MASK); in pxamci_remove()
804 dmaengine_terminate_all(host->dma_chan_rx); in pxamci_remove()
805 dmaengine_terminate_all(host->dma_chan_tx); in pxamci_remove()
806 dma_release_channel(host->dma_chan_rx); in pxamci_remove()
807 dma_release_channel(host->dma_chan_tx); in pxamci_remove()