Lines Matching full:host

24 #include <linux/mmc/host.h>
72 static inline void alcor_rmw8(struct alcor_sdmmc_host *host, unsigned int addr, in alcor_rmw8() argument
75 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_rmw8()
87 static inline void alcor_mask_sd_irqs(struct alcor_sdmmc_host *host) in alcor_mask_sd_irqs() argument
89 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_mask_sd_irqs()
94 static inline void alcor_unmask_sd_irqs(struct alcor_sdmmc_host *host) in alcor_unmask_sd_irqs() argument
96 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_unmask_sd_irqs()
104 static void alcor_reset(struct alcor_sdmmc_host *host, u8 val) in alcor_reset() argument
106 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_reset()
116 dev_err(host->dev, "%s: timeout\n", __func__); in alcor_reset()
122 static void alcor_data_set_dma(struct alcor_sdmmc_host *host) in alcor_data_set_dma() argument
124 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_data_set_dma()
127 if (!host->sg_count) in alcor_data_set_dma()
130 if (!host->sg) { in alcor_data_set_dma()
131 dev_err(host->dev, "have blocks, but no SG\n"); in alcor_data_set_dma()
135 if (!sg_dma_len(host->sg)) { in alcor_data_set_dma()
136 dev_err(host->dev, "DMA SG len == 0\n"); in alcor_data_set_dma()
141 addr = (u32)sg_dma_address(host->sg); in alcor_data_set_dma()
144 host->sg = sg_next(host->sg); in alcor_data_set_dma()
145 host->sg_count--; in alcor_data_set_dma()
148 static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host) in alcor_trigger_data_transfer() argument
150 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_trigger_data_transfer()
151 struct mmc_data *data = host->data; in alcor_trigger_data_transfer()
166 alcor_data_set_dma(host); in alcor_trigger_data_transfer()
168 host->dma_on = 1; in alcor_trigger_data_transfer()
185 static void alcor_trf_block_pio(struct alcor_sdmmc_host *host, bool read) in alcor_trf_block_pio() argument
187 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_trf_block_pio()
191 if (!host->blocks) in alcor_trf_block_pio()
194 if (host->dma_on) { in alcor_trf_block_pio()
195 dev_err(host->dev, "configured DMA but got PIO request.\n"); in alcor_trf_block_pio()
199 if (!!(host->data->flags & MMC_DATA_READ) != read) { in alcor_trf_block_pio()
200 dev_err(host->dev, "got unexpected direction %i != %i\n", in alcor_trf_block_pio()
201 !!(host->data->flags & MMC_DATA_READ), read); in alcor_trf_block_pio()
204 if (!sg_miter_next(&host->sg_miter)) in alcor_trf_block_pio()
207 blksize = host->data->blksz; in alcor_trf_block_pio()
208 len = min(host->sg_miter.length, blksize); in alcor_trf_block_pio()
210 dev_dbg(host->dev, "PIO, %s block size: 0x%zx\n", in alcor_trf_block_pio()
213 host->sg_miter.consumed = len; in alcor_trf_block_pio()
214 host->blocks--; in alcor_trf_block_pio()
216 buf = host->sg_miter.addr; in alcor_trf_block_pio()
223 sg_miter_stop(&host->sg_miter); in alcor_trf_block_pio()
226 static void alcor_prepare_sg_miter(struct alcor_sdmmc_host *host) in alcor_prepare_sg_miter() argument
229 struct mmc_data *data = host->data; in alcor_prepare_sg_miter()
235 sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); in alcor_prepare_sg_miter()
238 static void alcor_prepare_data(struct alcor_sdmmc_host *host, in alcor_prepare_data() argument
241 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_prepare_data()
248 host->data = data; in alcor_prepare_data()
249 host->data->bytes_xfered = 0; in alcor_prepare_data()
250 host->blocks = data->blocks; in alcor_prepare_data()
251 host->sg = data->sg; in alcor_prepare_data()
252 host->sg_count = data->sg_count; in alcor_prepare_data()
253 dev_dbg(host->dev, "prepare DATA: sg %i, blocks: %i\n", in alcor_prepare_data()
254 host->sg_count, host->blocks); in alcor_prepare_data()
257 alcor_prepare_sg_miter(host); in alcor_prepare_data()
262 static void alcor_send_cmd(struct alcor_sdmmc_host *host, in alcor_send_cmd() argument
265 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_send_cmd()
269 host->cmd = cmd; in alcor_send_cmd()
270 alcor_prepare_data(host, cmd); in alcor_send_cmd()
272 dev_dbg(host->dev, "send CMD. opcode: 0x%02x, arg; 0x%08x\n", in alcor_send_cmd()
294 dev_err(host->dev, "%s: cmd->flag (0x%02x) is not valid\n", in alcor_send_cmd()
295 mmc_hostname(mmc_from_priv(host)), mmc_resp_type(cmd)); in alcor_send_cmd()
305 schedule_delayed_work(&host->timeout_work, in alcor_send_cmd()
309 dev_dbg(host->dev, "xfer ctrl: 0x%02x; timeout: %lu\n", ctrl, timeout); in alcor_send_cmd()
314 static void alcor_request_complete(struct alcor_sdmmc_host *host, in alcor_request_complete() argument
323 if (!host->mrq) in alcor_request_complete()
327 cancel_delayed_work(&host->timeout_work); in alcor_request_complete()
329 mrq = host->mrq; in alcor_request_complete()
331 host->mrq = NULL; in alcor_request_complete()
332 host->cmd = NULL; in alcor_request_complete()
333 host->data = NULL; in alcor_request_complete()
334 host->dma_on = 0; in alcor_request_complete()
336 mmc_request_done(mmc_from_priv(host), mrq); in alcor_request_complete()
339 static void alcor_finish_data(struct alcor_sdmmc_host *host) in alcor_finish_data() argument
343 data = host->data; in alcor_finish_data()
344 host->data = NULL; in alcor_finish_data()
345 host->dma_on = 0; in alcor_finish_data()
366 !host->mrq->sbc)) { in alcor_finish_data()
373 alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA); in alcor_finish_data()
375 alcor_unmask_sd_irqs(host); in alcor_finish_data()
376 alcor_send_cmd(host, data->stop, false); in alcor_finish_data()
380 alcor_request_complete(host, 1); in alcor_finish_data()
383 static void alcor_err_irq(struct alcor_sdmmc_host *host, u32 intmask) in alcor_err_irq() argument
385 dev_dbg(host->dev, "ERR IRQ %x\n", intmask); in alcor_err_irq()
387 if (host->cmd) { in alcor_err_irq()
389 host->cmd->error = -ETIMEDOUT; in alcor_err_irq()
391 host->cmd->error = -EILSEQ; in alcor_err_irq()
394 if (host->data) { in alcor_err_irq()
396 host->data->error = -ETIMEDOUT; in alcor_err_irq()
398 host->data->error = -EILSEQ; in alcor_err_irq()
400 host->data->bytes_xfered = 0; in alcor_err_irq()
403 alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA); in alcor_err_irq()
404 alcor_request_complete(host, 1); in alcor_err_irq()
407 static int alcor_cmd_irq_done(struct alcor_sdmmc_host *host, u32 intmask) in alcor_cmd_irq_done() argument
409 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_cmd_irq_done()
419 if (!host->cmd) in alcor_cmd_irq_done()
422 if (host->cmd->flags & MMC_RSP_PRESENT) { in alcor_cmd_irq_done()
423 struct mmc_command *cmd = host->cmd; in alcor_cmd_irq_done()
426 dev_dbg(host->dev, "RSP0: 0x%04x\n", cmd->resp[0]); in alcor_cmd_irq_done()
427 if (host->cmd->flags & MMC_RSP_136) { in alcor_cmd_irq_done()
434 dev_dbg(host->dev, "RSP1,2,3: 0x%04x 0x%04x 0x%04x\n", in alcor_cmd_irq_done()
440 host->cmd->error = 0; in alcor_cmd_irq_done()
443 if (!host->data) in alcor_cmd_irq_done()
446 alcor_trigger_data_transfer(host); in alcor_cmd_irq_done()
447 host->cmd = NULL; in alcor_cmd_irq_done()
451 static void alcor_cmd_irq_thread(struct alcor_sdmmc_host *host, u32 intmask) in alcor_cmd_irq_thread() argument
458 if (!host->cmd && intmask & AU6601_INT_CMD_END) { in alcor_cmd_irq_thread()
459 …dev_dbg(host->dev, "Got command interrupt 0x%08x even though no command operation was in progress.… in alcor_cmd_irq_thread()
464 if (!host->data) in alcor_cmd_irq_thread()
465 alcor_request_complete(host, 1); in alcor_cmd_irq_thread()
467 alcor_trigger_data_transfer(host); in alcor_cmd_irq_thread()
468 host->cmd = NULL; in alcor_cmd_irq_thread()
471 static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask) in alcor_data_irq_done() argument
484 if (!host->data && intmask == AU6601_INT_DATA_END) in alcor_data_irq_done()
488 if (!host->data) in alcor_data_irq_done()
497 alcor_trf_block_pio(host, true); in alcor_data_irq_done()
500 alcor_trf_block_pio(host, false); in alcor_data_irq_done()
503 if (!host->sg_count) in alcor_data_irq_done()
506 alcor_data_set_dma(host); in alcor_data_irq_done()
509 dev_err(host->dev, "Got READ_BUF_RDY and WRITE_BUF_RDY at same time\n"); in alcor_data_irq_done()
514 if (!host->dma_on && host->blocks) { in alcor_data_irq_done()
515 alcor_trigger_data_transfer(host); in alcor_data_irq_done()
525 static void alcor_data_irq_thread(struct alcor_sdmmc_host *host, u32 intmask) in alcor_data_irq_thread() argument
532 if (!host->data) { in alcor_data_irq_thread()
533 dev_dbg(host->dev, "Got data interrupt 0x%08x even though no data operation was in progress.\n", in alcor_data_irq_thread()
535 alcor_reset(host, AU6601_RESET_DATA); in alcor_data_irq_thread()
539 if (alcor_data_irq_done(host, intmask)) in alcor_data_irq_thread()
542 if ((intmask & AU6601_INT_DATA_END) || !host->blocks || in alcor_data_irq_thread()
543 (host->dma_on && !host->sg_count)) in alcor_data_irq_thread()
544 alcor_finish_data(host); in alcor_data_irq_thread()
547 static void alcor_cd_irq(struct alcor_sdmmc_host *host, u32 intmask) in alcor_cd_irq() argument
549 dev_dbg(host->dev, "card %s\n", in alcor_cd_irq()
552 if (host->mrq) { in alcor_cd_irq()
553 dev_dbg(host->dev, "cancel all pending tasks.\n"); in alcor_cd_irq()
555 if (host->data) in alcor_cd_irq()
556 host->data->error = -ENOMEDIUM; in alcor_cd_irq()
558 if (host->cmd) in alcor_cd_irq()
559 host->cmd->error = -ENOMEDIUM; in alcor_cd_irq()
561 host->mrq->cmd->error = -ENOMEDIUM; in alcor_cd_irq()
563 alcor_request_complete(host, 1); in alcor_cd_irq()
566 mmc_detect_change(mmc_from_priv(host), msecs_to_jiffies(1)); in alcor_cd_irq()
571 struct alcor_sdmmc_host *host = d; in alcor_irq_thread() local
575 mutex_lock(&host->cmd_mutex); in alcor_irq_thread()
577 intmask = host->irq_status_sd; in alcor_irq_thread()
581 dev_dbg(host->dev, "unexpected IRQ: 0x%04x\n", intmask); in alcor_irq_thread()
589 alcor_err_irq(host, tmp); in alcor_irq_thread()
591 alcor_cmd_irq_thread(host, tmp); in alcor_irq_thread()
592 alcor_data_irq_thread(host, tmp); in alcor_irq_thread()
598 alcor_cd_irq(host, intmask); in alcor_irq_thread()
603 dev_warn(host->dev, in alcor_irq_thread()
609 dev_dbg(host->dev, "got not handled IRQ: 0x%04x\n", intmask); in alcor_irq_thread()
612 mutex_unlock(&host->cmd_mutex); in alcor_irq_thread()
613 alcor_unmask_sd_irqs(host); in alcor_irq_thread()
620 struct alcor_sdmmc_host *host = d; in alcor_irq() local
621 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_irq()
636 cmd_done = alcor_cmd_irq_done(host, tmp); in alcor_irq()
637 data_done = alcor_data_irq_done(host, tmp); in alcor_irq()
645 host->irq_status_sd = status; in alcor_irq()
647 alcor_mask_sd_irqs(host); in alcor_irq()
652 static void alcor_set_clock(struct alcor_sdmmc_host *host, unsigned int clock) in alcor_set_clock() argument
654 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_set_clock()
685 dev_dbg(host->dev, "set freq %d cal freq %d, use div %d, mod %x\n", in alcor_set_clock()
694 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_set_timing() local
697 alcor_rmw8(host, AU6601_CLK_DELAY, in alcor_set_timing()
700 alcor_rmw8(host, AU6601_CLK_DELAY, in alcor_set_timing()
707 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_set_bus_width() local
708 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_set_bus_width()
716 dev_err(host->dev, "Unknown BUS mode\n"); in alcor_set_bus_width()
722 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_card_busy() local
723 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_card_busy()
734 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_get_cd() local
735 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_get_cd()
746 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_get_ro() local
747 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_get_ro()
758 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_request() local
760 mutex_lock(&host->cmd_mutex); in alcor_request()
762 host->mrq = mrq; in alcor_request()
766 alcor_send_cmd(host, mrq->cmd, true); in alcor_request()
769 alcor_request_complete(host, 1); in alcor_request()
772 mutex_unlock(&host->cmd_mutex); in alcor_request()
778 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_pre_req() local
817 sg_len = dma_map_sg(host->dev, data->sg, data->sg_len, in alcor_pre_req()
829 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_post_req() local
836 dma_unmap_sg(host->dev, in alcor_post_req()
847 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_set_power_mode() local
848 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_set_power_mode()
852 alcor_set_clock(host, ios->clock); in alcor_set_power_mode()
880 alcor_set_clock(host, ios->clock); in alcor_set_power_mode()
887 alcor_set_clock(host, ios->clock); in alcor_set_power_mode()
902 dev_err(host->dev, "Unknown power parameter\n"); in alcor_set_power_mode()
908 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_set_ios() local
910 mutex_lock(&host->cmd_mutex); in alcor_set_ios()
912 dev_dbg(host->dev, "set ios. bus width: %x, power mode: %x\n", in alcor_set_ios()
915 if (ios->power_mode != host->cur_power_mode) { in alcor_set_ios()
917 host->cur_power_mode = ios->power_mode; in alcor_set_ios()
921 alcor_set_clock(host, ios->clock); in alcor_set_ios()
924 mutex_unlock(&host->cmd_mutex); in alcor_set_ios()
930 struct alcor_sdmmc_host *host = mmc_priv(mmc); in alcor_signal_voltage_switch() local
932 mutex_lock(&host->cmd_mutex); in alcor_signal_voltage_switch()
936 alcor_rmw8(host, AU6601_OPT, AU6601_OPT_SD_18V, 0); in alcor_signal_voltage_switch()
939 alcor_rmw8(host, AU6601_OPT, 0, AU6601_OPT_SD_18V); in alcor_signal_voltage_switch()
946 mutex_unlock(&host->cmd_mutex); in alcor_signal_voltage_switch()
964 struct alcor_sdmmc_host *host = container_of(d, struct alcor_sdmmc_host, in alcor_timeout_timer() local
966 mutex_lock(&host->cmd_mutex); in alcor_timeout_timer()
968 dev_dbg(host->dev, "triggered timeout\n"); in alcor_timeout_timer()
969 if (host->mrq) { in alcor_timeout_timer()
970 dev_err(host->dev, "Timeout waiting for hardware interrupt.\n"); in alcor_timeout_timer()
972 if (host->data) { in alcor_timeout_timer()
973 host->data->error = -ETIMEDOUT; in alcor_timeout_timer()
975 if (host->cmd) in alcor_timeout_timer()
976 host->cmd->error = -ETIMEDOUT; in alcor_timeout_timer()
978 host->mrq->cmd->error = -ETIMEDOUT; in alcor_timeout_timer()
981 alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA); in alcor_timeout_timer()
982 alcor_request_complete(host, 0); in alcor_timeout_timer()
985 mutex_unlock(&host->cmd_mutex); in alcor_timeout_timer()
988 static void alcor_hw_init(struct alcor_sdmmc_host *host) in alcor_hw_init() argument
990 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_hw_init()
999 alcor_reset(host, AU6601_RESET_CMD); in alcor_hw_init()
1009 alcor_reset(host, AU6601_RESET_DATA); in alcor_hw_init()
1030 alcor_unmask_sd_irqs(host); in alcor_hw_init()
1033 static void alcor_hw_uninit(struct alcor_sdmmc_host *host) in alcor_hw_uninit() argument
1035 struct alcor_pci_priv *priv = host->alcor_pci; in alcor_hw_uninit()
1037 alcor_mask_sd_irqs(host); in alcor_hw_uninit()
1038 alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA); in alcor_hw_uninit()
1048 static void alcor_init_mmc(struct alcor_sdmmc_host *host) in alcor_init_mmc() argument
1050 struct mmc_host *mmc = mmc_from_priv(host); in alcor_init_mmc()
1076 dma_set_max_seg_size(host->dev, mmc->max_seg_size); in alcor_init_mmc()
1083 struct alcor_sdmmc_host *host; in alcor_pci_sdmmc_drv_probe() local
1086 mmc = mmc_alloc_host(sizeof(*host), &pdev->dev); in alcor_pci_sdmmc_drv_probe()
1092 host = mmc_priv(mmc); in alcor_pci_sdmmc_drv_probe()
1093 host->dev = &pdev->dev; in alcor_pci_sdmmc_drv_probe()
1094 host->cur_power_mode = MMC_POWER_UNDEFINED; in alcor_pci_sdmmc_drv_probe()
1095 host->alcor_pci = priv; in alcor_pci_sdmmc_drv_probe()
1103 DRV_NAME_ALCOR_PCI_SDMMC, host); in alcor_pci_sdmmc_drv_probe()
1110 mutex_init(&host->cmd_mutex); in alcor_pci_sdmmc_drv_probe()
1111 INIT_DELAYED_WORK(&host->timeout_work, alcor_timeout_timer); in alcor_pci_sdmmc_drv_probe()
1113 alcor_init_mmc(host); in alcor_pci_sdmmc_drv_probe()
1114 alcor_hw_init(host); in alcor_pci_sdmmc_drv_probe()
1116 dev_set_drvdata(&pdev->dev, host); in alcor_pci_sdmmc_drv_probe()
1130 struct alcor_sdmmc_host *host = dev_get_drvdata(&pdev->dev); in alcor_pci_sdmmc_drv_remove() local
1131 struct mmc_host *mmc = mmc_from_priv(host); in alcor_pci_sdmmc_drv_remove()
1133 if (cancel_delayed_work_sync(&host->timeout_work)) in alcor_pci_sdmmc_drv_remove()
1134 alcor_request_complete(host, 0); in alcor_pci_sdmmc_drv_remove()
1136 alcor_hw_uninit(host); in alcor_pci_sdmmc_drv_remove()
1144 struct alcor_sdmmc_host *host = dev_get_drvdata(dev); in alcor_pci_sdmmc_suspend() local
1146 if (cancel_delayed_work_sync(&host->timeout_work)) in alcor_pci_sdmmc_suspend()
1147 alcor_request_complete(host, 0); in alcor_pci_sdmmc_suspend()
1149 alcor_hw_uninit(host); in alcor_pci_sdmmc_suspend()
1156 struct alcor_sdmmc_host *host = dev_get_drvdata(dev); in alcor_pci_sdmmc_resume() local
1158 alcor_hw_init(host); in alcor_pci_sdmmc_resume()
1189 MODULE_DESCRIPTION("PCI driver for Alcor Micro AU6601 Secure Digital Host Controller Interface");