Lines Matching refs:host

165 static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host)  in jz4740_mmc_release_dma_channels()  argument
167 if (!host->use_dma) in jz4740_mmc_release_dma_channels()
170 dma_release_channel(host->dma_tx); in jz4740_mmc_release_dma_channels()
171 dma_release_channel(host->dma_rx); in jz4740_mmc_release_dma_channels()
174 static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) in jz4740_mmc_acquire_dma_channels() argument
181 host->dma_tx = dma_request_channel(mask, NULL, host); in jz4740_mmc_acquire_dma_channels()
182 if (!host->dma_tx) { in jz4740_mmc_acquire_dma_channels()
183 dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); in jz4740_mmc_acquire_dma_channels()
187 host->dma_rx = dma_request_channel(mask, NULL, host); in jz4740_mmc_acquire_dma_channels()
188 if (!host->dma_rx) { in jz4740_mmc_acquire_dma_channels()
189 dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n"); in jz4740_mmc_acquire_dma_channels()
194 host->next_data.cookie = 1; in jz4740_mmc_acquire_dma_channels()
199 dma_release_channel(host->dma_tx); in jz4740_mmc_acquire_dma_channels()
208 static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host, in jz4740_mmc_get_dma_chan() argument
211 return (data->flags & MMC_DATA_READ) ? host->dma_rx : host->dma_tx; in jz4740_mmc_get_dma_chan()
214 static void jz4740_mmc_dma_unmap(struct jz4740_mmc_host *host, in jz4740_mmc_dma_unmap() argument
217 struct dma_chan *chan = jz4740_mmc_get_dma_chan(host, data); in jz4740_mmc_dma_unmap()
224 static int jz4740_mmc_prepare_dma_data(struct jz4740_mmc_host *host, in jz4740_mmc_prepare_dma_data() argument
229 struct jz4740_mmc_host_next *next_data = &host->next_data; in jz4740_mmc_prepare_dma_data()
234 data->host_cookie != host->next_data.cookie) { in jz4740_mmc_prepare_dma_data()
235 dev_warn(mmc_dev(host->mmc), in jz4740_mmc_prepare_dma_data()
239 host->next_data.cookie); in jz4740_mmc_prepare_dma_data()
244 if (next || data->host_cookie != host->next_data.cookie) { in jz4740_mmc_prepare_dma_data()
256 dev_err(mmc_dev(host->mmc), in jz4740_mmc_prepare_dma_data()
265 host->sg_len = sg_len; in jz4740_mmc_prepare_dma_data()
270 static int jz4740_mmc_start_dma_transfer(struct jz4740_mmc_host *host, in jz4740_mmc_start_dma_transfer() argument
285 conf.dst_addr = host->mem_res->start + JZ_REG_MMC_TXFIFO; in jz4740_mmc_start_dma_transfer()
287 chan = host->dma_tx; in jz4740_mmc_start_dma_transfer()
290 conf.src_addr = host->mem_res->start + JZ_REG_MMC_RXFIFO; in jz4740_mmc_start_dma_transfer()
292 chan = host->dma_rx; in jz4740_mmc_start_dma_transfer()
295 ret = jz4740_mmc_prepare_dma_data(host, data, NULL, chan); in jz4740_mmc_start_dma_transfer()
302 host->sg_len, in jz4740_mmc_start_dma_transfer()
306 dev_err(mmc_dev(host->mmc), in jz4740_mmc_start_dma_transfer()
318 jz4740_mmc_dma_unmap(host, data); in jz4740_mmc_start_dma_transfer()
326 struct jz4740_mmc_host *host = mmc_priv(mmc); in jz4740_mmc_pre_request() local
328 struct jz4740_mmc_host_next *next_data = &host->next_data; in jz4740_mmc_pre_request()
332 if (host->use_dma) { in jz4740_mmc_pre_request()
333 struct dma_chan *chan = jz4740_mmc_get_dma_chan(host, data); in jz4740_mmc_pre_request()
335 if (jz4740_mmc_prepare_dma_data(host, data, next_data, chan)) in jz4740_mmc_pre_request()
344 struct jz4740_mmc_host *host = mmc_priv(mmc); in jz4740_mmc_post_request() local
347 if (host->use_dma && data->host_cookie) { in jz4740_mmc_post_request()
348 jz4740_mmc_dma_unmap(host, data); in jz4740_mmc_post_request()
353 struct dma_chan *chan = jz4740_mmc_get_dma_chan(host, data); in jz4740_mmc_post_request()
361 static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host, in jz4740_mmc_set_irq_enabled() argument
366 spin_lock_irqsave(&host->lock, flags); in jz4740_mmc_set_irq_enabled()
368 host->irq_mask &= ~irq; in jz4740_mmc_set_irq_enabled()
370 host->irq_mask |= irq; in jz4740_mmc_set_irq_enabled()
371 spin_unlock_irqrestore(&host->lock, flags); in jz4740_mmc_set_irq_enabled()
373 writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); in jz4740_mmc_set_irq_enabled()
376 static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host, in jz4740_mmc_clock_enable() argument
384 writew(val, host->base + JZ_REG_MMC_STRPCL); in jz4740_mmc_clock_enable()
387 static void jz4740_mmc_clock_disable(struct jz4740_mmc_host *host) in jz4740_mmc_clock_disable() argument
392 writew(JZ_MMC_STRPCL_CLOCK_STOP, host->base + JZ_REG_MMC_STRPCL); in jz4740_mmc_clock_disable()
394 status = readl(host->base + JZ_REG_MMC_STATUS); in jz4740_mmc_clock_disable()
398 static void jz4740_mmc_reset(struct jz4740_mmc_host *host) in jz4740_mmc_reset() argument
403 writew(JZ_MMC_STRPCL_RESET, host->base + JZ_REG_MMC_STRPCL); in jz4740_mmc_reset()
406 status = readl(host->base + JZ_REG_MMC_STATUS); in jz4740_mmc_reset()
410 static void jz4740_mmc_request_done(struct jz4740_mmc_host *host) in jz4740_mmc_request_done() argument
414 req = host->req; in jz4740_mmc_request_done()
415 host->req = NULL; in jz4740_mmc_request_done()
417 mmc_request_done(host->mmc, req); in jz4740_mmc_request_done()
420 static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host, in jz4740_mmc_poll_irq() argument
427 status = readw(host->base + JZ_REG_MMC_IREG); in jz4740_mmc_poll_irq()
431 set_bit(0, &host->waiting); in jz4740_mmc_poll_irq()
432 mod_timer(&host->timeout_timer, jiffies + 5*HZ); in jz4740_mmc_poll_irq()
433 jz4740_mmc_set_irq_enabled(host, irq, true); in jz4740_mmc_poll_irq()
440 static void jz4740_mmc_transfer_check_state(struct jz4740_mmc_host *host, in jz4740_mmc_transfer_check_state() argument
445 status = readl(host->base + JZ_REG_MMC_STATUS); in jz4740_mmc_transfer_check_state()
448 host->req->cmd->error = -ETIMEDOUT; in jz4740_mmc_transfer_check_state()
451 host->req->cmd->error = -EIO; in jz4740_mmc_transfer_check_state()
456 host->req->cmd->error = -ETIMEDOUT; in jz4740_mmc_transfer_check_state()
459 host->req->cmd->error = -EIO; in jz4740_mmc_transfer_check_state()
465 static bool jz4740_mmc_write_data(struct jz4740_mmc_host *host, in jz4740_mmc_write_data() argument
468 struct sg_mapping_iter *miter = &host->miter; in jz4740_mmc_write_data()
469 void __iomem *fifo_addr = host->base + JZ_REG_MMC_TXFIFO; in jz4740_mmc_write_data()
480 timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ); in jz4740_mmc_write_data()
496 timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_TXFIFO_WR_REQ); in jz4740_mmc_write_data()
520 static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host, in jz4740_mmc_read_data() argument
523 struct sg_mapping_iter *miter = &host->miter; in jz4740_mmc_read_data()
524 void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; in jz4740_mmc_read_data()
537 timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ); in jz4740_mmc_read_data()
555 timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_RXFIFO_RD_REQ); in jz4740_mmc_read_data()
579 status = readl(host->base + JZ_REG_MMC_STATUS); in jz4740_mmc_read_data()
582 status = readl(host->base + JZ_REG_MMC_STATUS); in jz4740_mmc_read_data()
597 struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)data; in jz4740_mmc_timeout() local
599 if (!test_and_clear_bit(0, &host->waiting)) in jz4740_mmc_timeout()
602 jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, false); in jz4740_mmc_timeout()
604 host->req->cmd->error = -ETIMEDOUT; in jz4740_mmc_timeout()
605 jz4740_mmc_request_done(host); in jz4740_mmc_timeout()
608 static void jz4740_mmc_read_response(struct jz4740_mmc_host *host, in jz4740_mmc_read_response() argument
613 void __iomem *fifo_addr = host->base + JZ_REG_MMC_RESP_FIFO; in jz4740_mmc_read_response()
631 static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, in jz4740_mmc_send_command() argument
634 uint32_t cmdat = host->cmdat; in jz4740_mmc_send_command()
636 host->cmdat &= ~JZ_MMC_CMDAT_INIT; in jz4740_mmc_send_command()
637 jz4740_mmc_clock_disable(host); in jz4740_mmc_send_command()
639 host->cmd = cmd; in jz4740_mmc_send_command()
665 if (host->use_dma) in jz4740_mmc_send_command()
668 writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); in jz4740_mmc_send_command()
669 writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); in jz4740_mmc_send_command()
672 writeb(cmd->opcode, host->base + JZ_REG_MMC_CMD); in jz4740_mmc_send_command()
673 writel(cmd->arg, host->base + JZ_REG_MMC_ARG); in jz4740_mmc_send_command()
674 writel(cmdat, host->base + JZ_REG_MMC_CMDAT); in jz4740_mmc_send_command()
676 jz4740_mmc_clock_enable(host, 1); in jz4740_mmc_send_command()
679 static void jz_mmc_prepare_data_transfer(struct jz4740_mmc_host *host) in jz_mmc_prepare_data_transfer() argument
681 struct mmc_command *cmd = host->req->cmd; in jz_mmc_prepare_data_transfer()
690 sg_miter_start(&host->miter, data->sg, data->sg_len, direction); in jz_mmc_prepare_data_transfer()
696 struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid; in jz_mmc_irq_worker() local
697 struct mmc_command *cmd = host->req->cmd; in jz_mmc_irq_worker()
698 struct mmc_request *req = host->req; in jz_mmc_irq_worker()
703 host->state = JZ4740_MMC_STATE_DONE; in jz_mmc_irq_worker()
705 switch (host->state) { in jz_mmc_irq_worker()
708 jz4740_mmc_read_response(host, cmd); in jz_mmc_irq_worker()
713 jz_mmc_prepare_data_transfer(host); in jz_mmc_irq_worker()
716 if (host->use_dma) { in jz_mmc_irq_worker()
723 timeout = jz4740_mmc_start_dma_transfer(host, data); in jz_mmc_irq_worker()
731 timeout = jz4740_mmc_read_data(host, data); in jz_mmc_irq_worker()
733 timeout = jz4740_mmc_write_data(host, data); in jz_mmc_irq_worker()
736 host->state = JZ4740_MMC_STATE_TRANSFER_DATA; in jz_mmc_irq_worker()
740 jz4740_mmc_transfer_check_state(host, data); in jz_mmc_irq_worker()
742 timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_DATA_TRAN_DONE); in jz_mmc_irq_worker()
744 host->state = JZ4740_MMC_STATE_SEND_STOP; in jz_mmc_irq_worker()
747 writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG); in jz_mmc_irq_worker()
753 jz4740_mmc_send_command(host, req->stop); in jz_mmc_irq_worker()
756 timeout = jz4740_mmc_poll_irq(host, in jz_mmc_irq_worker()
759 host->state = JZ4740_MMC_STATE_DONE; in jz_mmc_irq_worker()
768 jz4740_mmc_request_done(host); in jz_mmc_irq_worker()
775 struct jz4740_mmc_host *host = devid; in jz_mmc_irq() local
776 struct mmc_command *cmd = host->cmd; in jz_mmc_irq()
779 irq_reg = readw(host->base + JZ_REG_MMC_IREG); in jz_mmc_irq()
782 irq_reg &= ~host->irq_mask; in jz_mmc_irq()
788 writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG); in jz_mmc_irq()
791 writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG); in jz_mmc_irq()
792 mmc_signal_sdio_irq(host->mmc); in jz_mmc_irq()
796 if (host->req && cmd && irq_reg) { in jz_mmc_irq()
797 if (test_and_clear_bit(0, &host->waiting)) { in jz_mmc_irq()
798 del_timer(&host->timeout_timer); in jz_mmc_irq()
800 status = readl(host->base + JZ_REG_MMC_STATUS); in jz_mmc_irq()
813 jz4740_mmc_set_irq_enabled(host, irq_reg, false); in jz_mmc_irq()
814 writew(irq_reg, host->base + JZ_REG_MMC_IREG); in jz_mmc_irq()
823 static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) in jz4740_mmc_set_clock_rate() argument
828 jz4740_mmc_clock_disable(host); in jz4740_mmc_set_clock_rate()
829 clk_set_rate(host->clk, JZ_MMC_CLK_RATE); in jz4740_mmc_set_clock_rate()
831 real_rate = clk_get_rate(host->clk); in jz4740_mmc_set_clock_rate()
838 writew(div, host->base + JZ_REG_MMC_CLKRT); in jz4740_mmc_set_clock_rate()
844 struct jz4740_mmc_host *host = mmc_priv(mmc); in jz4740_mmc_request() local
846 host->req = req; in jz4740_mmc_request()
848 writew(0xffff, host->base + JZ_REG_MMC_IREG); in jz4740_mmc_request()
850 writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG); in jz4740_mmc_request()
851 jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true); in jz4740_mmc_request()
853 host->state = JZ4740_MMC_STATE_READ_RESPONSE; in jz4740_mmc_request()
854 set_bit(0, &host->waiting); in jz4740_mmc_request()
855 mod_timer(&host->timeout_timer, jiffies + 5*HZ); in jz4740_mmc_request()
856 jz4740_mmc_send_command(host, req->cmd); in jz4740_mmc_request()
861 struct jz4740_mmc_host *host = mmc_priv(mmc); in jz4740_mmc_set_ios() local
863 jz4740_mmc_set_clock_rate(host, ios->clock); in jz4740_mmc_set_ios()
867 jz4740_mmc_reset(host); in jz4740_mmc_set_ios()
868 if (gpio_is_valid(host->pdata->gpio_power)) in jz4740_mmc_set_ios()
869 gpio_set_value(host->pdata->gpio_power, in jz4740_mmc_set_ios()
870 !host->pdata->power_active_low); in jz4740_mmc_set_ios()
871 host->cmdat |= JZ_MMC_CMDAT_INIT; in jz4740_mmc_set_ios()
872 clk_prepare_enable(host->clk); in jz4740_mmc_set_ios()
877 if (gpio_is_valid(host->pdata->gpio_power)) in jz4740_mmc_set_ios()
878 gpio_set_value(host->pdata->gpio_power, in jz4740_mmc_set_ios()
879 host->pdata->power_active_low); in jz4740_mmc_set_ios()
880 clk_disable_unprepare(host->clk); in jz4740_mmc_set_ios()
886 host->cmdat &= ~JZ_MMC_CMDAT_BUS_WIDTH_4BIT; in jz4740_mmc_set_ios()
889 host->cmdat |= JZ_MMC_CMDAT_BUS_WIDTH_4BIT; in jz4740_mmc_set_ios()
898 struct jz4740_mmc_host *host = mmc_priv(mmc); in jz4740_mmc_enable_sdio_irq() local
899 jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); in jz4740_mmc_enable_sdio_irq()
984 static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host) in jz4740_mmc_num_pins() argument
987 if (host->pdata && host->pdata->data_1bit) in jz4740_mmc_num_pins()
997 struct jz4740_mmc_host *host; in jz4740_mmc_probe() local
1008 host = mmc_priv(mmc); in jz4740_mmc_probe()
1009 host->pdata = pdata; in jz4740_mmc_probe()
1011 host->irq = platform_get_irq(pdev, 0); in jz4740_mmc_probe()
1012 if (host->irq < 0) { in jz4740_mmc_probe()
1013 ret = host->irq; in jz4740_mmc_probe()
1018 host->clk = devm_clk_get(&pdev->dev, "mmc"); in jz4740_mmc_probe()
1019 if (IS_ERR(host->clk)) { in jz4740_mmc_probe()
1020 ret = PTR_ERR(host->clk); in jz4740_mmc_probe()
1025 host->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); in jz4740_mmc_probe()
1026 host->base = devm_ioremap_resource(&pdev->dev, host->mem_res); in jz4740_mmc_probe()
1027 if (IS_ERR(host->base)) { in jz4740_mmc_probe()
1028 ret = PTR_ERR(host->base); in jz4740_mmc_probe()
1033 ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); in jz4740_mmc_probe()
1057 host->mmc = mmc; in jz4740_mmc_probe()
1058 host->pdev = pdev; in jz4740_mmc_probe()
1059 spin_lock_init(&host->lock); in jz4740_mmc_probe()
1060 host->irq_mask = 0xffff; in jz4740_mmc_probe()
1062 ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0, in jz4740_mmc_probe()
1063 dev_name(&pdev->dev), host); in jz4740_mmc_probe()
1069 jz4740_mmc_reset(host); in jz4740_mmc_probe()
1070 jz4740_mmc_clock_disable(host); in jz4740_mmc_probe()
1071 setup_timer(&host->timeout_timer, jz4740_mmc_timeout, in jz4740_mmc_probe()
1072 (unsigned long)host); in jz4740_mmc_probe()
1074 set_timer_slack(&host->timeout_timer, HZ); in jz4740_mmc_probe()
1076 host->use_dma = true; in jz4740_mmc_probe()
1077 if (host->use_dma && jz4740_mmc_acquire_dma_channels(host) != 0) in jz4740_mmc_probe()
1078 host->use_dma = false; in jz4740_mmc_probe()
1080 platform_set_drvdata(pdev, host); in jz4740_mmc_probe()
1090 host->use_dma ? "DMA" : "PIO", in jz4740_mmc_probe()
1096 free_irq(host->irq, host); in jz4740_mmc_probe()
1100 if (host->use_dma) in jz4740_mmc_probe()
1101 jz4740_mmc_release_dma_channels(host); in jz4740_mmc_probe()
1102 jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); in jz4740_mmc_probe()
1111 struct jz4740_mmc_host *host = platform_get_drvdata(pdev); in jz4740_mmc_remove() local
1113 del_timer_sync(&host->timeout_timer); in jz4740_mmc_remove()
1114 jz4740_mmc_set_irq_enabled(host, 0xff, false); in jz4740_mmc_remove()
1115 jz4740_mmc_reset(host); in jz4740_mmc_remove()
1117 mmc_remove_host(host->mmc); in jz4740_mmc_remove()
1119 free_irq(host->irq, host); in jz4740_mmc_remove()
1122 jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); in jz4740_mmc_remove()
1124 if (host->use_dma) in jz4740_mmc_remove()
1125 jz4740_mmc_release_dma_channels(host); in jz4740_mmc_remove()
1127 mmc_free_host(host->mmc); in jz4740_mmc_remove()
1136 struct jz4740_mmc_host *host = dev_get_drvdata(dev); in jz4740_mmc_suspend() local
1138 jz_gpio_bulk_suspend(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); in jz4740_mmc_suspend()
1145 struct jz4740_mmc_host *host = dev_get_drvdata(dev); in jz4740_mmc_resume() local
1147 jz_gpio_bulk_resume(jz4740_mmc_pins, jz4740_mmc_num_pins(host)); in jz4740_mmc_resume()