diff options
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 107 | ||||
-rw-r--r-- | include/linux/spi/mxs-spi.h | 8 |
2 files changed, 67 insertions, 48 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index e80c2b6b2d7c..7b85e035a4cb 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -62,23 +62,20 @@ | |||
62 | #define MXS_MMC_DETECT_TIMEOUT (HZ/2) | 62 | #define MXS_MMC_DETECT_TIMEOUT (HZ/2) |
63 | 63 | ||
64 | struct mxs_mmc_host { | 64 | struct mxs_mmc_host { |
65 | struct mxs_ssp ssp; | ||
66 | |||
65 | struct mmc_host *mmc; | 67 | struct mmc_host *mmc; |
66 | struct mmc_request *mrq; | 68 | struct mmc_request *mrq; |
67 | struct mmc_command *cmd; | 69 | struct mmc_command *cmd; |
68 | struct mmc_data *data; | 70 | struct mmc_data *data; |
69 | 71 | ||
70 | void __iomem *base; | ||
71 | int dma_channel; | 72 | int dma_channel; |
72 | struct clk *clk; | ||
73 | unsigned int clk_rate; | ||
74 | |||
75 | struct dma_chan *dmach; | 73 | struct dma_chan *dmach; |
76 | struct mxs_dma_data dma_data; | 74 | struct mxs_dma_data dma_data; |
77 | unsigned int dma_dir; | 75 | unsigned int dma_dir; |
78 | enum dma_transfer_direction slave_dirn; | 76 | enum dma_transfer_direction slave_dirn; |
79 | u32 ssp_pio_words[SSP_PIO_NUM]; | 77 | u32 ssp_pio_words[SSP_PIO_NUM]; |
80 | 78 | ||
81 | enum mxs_ssp_id devid; | ||
82 | unsigned char bus_width; | 79 | unsigned char bus_width; |
83 | spinlock_t lock; | 80 | spinlock_t lock; |
84 | int sdio_irq_en; | 81 | int sdio_irq_en; |
@@ -105,16 +102,18 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc) | |||
105 | static int mxs_mmc_get_cd(struct mmc_host *mmc) | 102 | static int mxs_mmc_get_cd(struct mmc_host *mmc) |
106 | { | 103 | { |
107 | struct mxs_mmc_host *host = mmc_priv(mmc); | 104 | struct mxs_mmc_host *host = mmc_priv(mmc); |
105 | struct mxs_ssp *ssp = &host->ssp; | ||
108 | 106 | ||
109 | return !(readl(host->base + HW_SSP_STATUS(host)) & | 107 | return !(readl(ssp->base + HW_SSP_STATUS(ssp)) & |
110 | BM_SSP_STATUS_CARD_DETECT); | 108 | BM_SSP_STATUS_CARD_DETECT); |
111 | } | 109 | } |
112 | 110 | ||
113 | static void mxs_mmc_reset(struct mxs_mmc_host *host) | 111 | static void mxs_mmc_reset(struct mxs_mmc_host *host) |
114 | { | 112 | { |
113 | struct mxs_ssp *ssp = &host->ssp; | ||
115 | u32 ctrl0, ctrl1; | 114 | u32 ctrl0, ctrl1; |
116 | 115 | ||
117 | stmp_reset_block(host->base); | 116 | stmp_reset_block(ssp->base); |
118 | 117 | ||
119 | ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; | 118 | ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; |
120 | ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | | 119 | ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | |
@@ -130,15 +129,15 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host) | |||
130 | writel(BF_SSP(0xffff, TIMING_TIMEOUT) | | 129 | writel(BF_SSP(0xffff, TIMING_TIMEOUT) | |
131 | BF_SSP(2, TIMING_CLOCK_DIVIDE) | | 130 | BF_SSP(2, TIMING_CLOCK_DIVIDE) | |
132 | BF_SSP(0, TIMING_CLOCK_RATE), | 131 | BF_SSP(0, TIMING_CLOCK_RATE), |
133 | host->base + HW_SSP_TIMING(host)); | 132 | ssp->base + HW_SSP_TIMING(ssp)); |
134 | 133 | ||
135 | if (host->sdio_irq_en) { | 134 | if (host->sdio_irq_en) { |
136 | ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; | 135 | ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; |
137 | ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN; | 136 | ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN; |
138 | } | 137 | } |
139 | 138 | ||
140 | writel(ctrl0, host->base + HW_SSP_CTRL0); | 139 | writel(ctrl0, ssp->base + HW_SSP_CTRL0); |
141 | writel(ctrl1, host->base + HW_SSP_CTRL1(host)); | 140 | writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp)); |
142 | } | 141 | } |
143 | 142 | ||
144 | static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, | 143 | static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, |
@@ -149,15 +148,16 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) | |||
149 | struct mmc_command *cmd = host->cmd; | 148 | struct mmc_command *cmd = host->cmd; |
150 | struct mmc_data *data = host->data; | 149 | struct mmc_data *data = host->data; |
151 | struct mmc_request *mrq = host->mrq; | 150 | struct mmc_request *mrq = host->mrq; |
151 | struct mxs_ssp *ssp = &host->ssp; | ||
152 | 152 | ||
153 | if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { | 153 | if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { |
154 | if (mmc_resp_type(cmd) & MMC_RSP_136) { | 154 | if (mmc_resp_type(cmd) & MMC_RSP_136) { |
155 | cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host)); | 155 | cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); |
156 | cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host)); | 156 | cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp)); |
157 | cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host)); | 157 | cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp)); |
158 | cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host)); | 158 | cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp)); |
159 | } else { | 159 | } else { |
160 | cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host)); | 160 | cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); |
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
@@ -196,13 +196,14 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
196 | struct mxs_mmc_host *host = dev_id; | 196 | struct mxs_mmc_host *host = dev_id; |
197 | struct mmc_command *cmd = host->cmd; | 197 | struct mmc_command *cmd = host->cmd; |
198 | struct mmc_data *data = host->data; | 198 | struct mmc_data *data = host->data; |
199 | struct mxs_ssp *ssp = &host->ssp; | ||
199 | u32 stat; | 200 | u32 stat; |
200 | 201 | ||
201 | spin_lock(&host->lock); | 202 | spin_lock(&host->lock); |
202 | 203 | ||
203 | stat = readl(host->base + HW_SSP_CTRL1(host)); | 204 | stat = readl(ssp->base + HW_SSP_CTRL1(ssp)); |
204 | writel(stat & MXS_MMC_IRQ_BITS, | 205 | writel(stat & MXS_MMC_IRQ_BITS, |
205 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 206 | ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR); |
206 | 207 | ||
207 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) | 208 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) |
208 | mmc_signal_sdio_irq(host->mmc); | 209 | mmc_signal_sdio_irq(host->mmc); |
@@ -366,6 +367,8 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
366 | unsigned int data_size = 0, log2_blksz; | 367 | unsigned int data_size = 0, log2_blksz; |
367 | unsigned int blocks = data->blocks; | 368 | unsigned int blocks = data->blocks; |
368 | 369 | ||
370 | struct mxs_ssp *ssp = &host->ssp; | ||
371 | |||
369 | u32 ignore_crc, get_resp, long_resp, read; | 372 | u32 ignore_crc, get_resp, long_resp, read; |
370 | u32 ctrl0, cmd0, cmd1, val; | 373 | u32 ctrl0, cmd0, cmd1, val; |
371 | 374 | ||
@@ -408,15 +411,15 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
408 | blocks = 1; | 411 | blocks = 1; |
409 | 412 | ||
410 | /* xfer count, block size and count need to be set differently */ | 413 | /* xfer count, block size and count need to be set differently */ |
411 | if (ssp_is_old(host)) { | 414 | if (ssp_is_old(ssp)) { |
412 | ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); | 415 | ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); |
413 | cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | | 416 | cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | |
414 | BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); | 417 | BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); |
415 | } else { | 418 | } else { |
416 | writel(data_size, host->base + HW_SSP_XFER_SIZE); | 419 | writel(data_size, ssp->base + HW_SSP_XFER_SIZE); |
417 | writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) | | 420 | writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) | |
418 | BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT), | 421 | BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT), |
419 | host->base + HW_SSP_BLOCK_SIZE); | 422 | ssp->base + HW_SSP_BLOCK_SIZE); |
420 | } | 423 | } |
421 | 424 | ||
422 | if ((cmd->opcode == MMC_STOP_TRANSMISSION) || | 425 | if ((cmd->opcode == MMC_STOP_TRANSMISSION) || |
@@ -431,11 +434,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
431 | } | 434 | } |
432 | 435 | ||
433 | /* set the timeout count */ | 436 | /* set the timeout count */ |
434 | timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); | 437 | timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns); |
435 | val = readl(host->base + HW_SSP_TIMING(host)); | 438 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); |
436 | val &= ~(BM_SSP_TIMING_TIMEOUT); | 439 | val &= ~(BM_SSP_TIMING_TIMEOUT); |
437 | val |= BF_SSP(timeout, TIMING_TIMEOUT); | 440 | val |= BF_SSP(timeout, TIMING_TIMEOUT); |
438 | writel(val, host->base + HW_SSP_TIMING(host)); | 441 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); |
439 | 442 | ||
440 | /* pio */ | 443 | /* pio */ |
441 | host->ssp_pio_words[0] = ctrl0; | 444 | host->ssp_pio_words[0] = ctrl0; |
@@ -500,11 +503,12 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
500 | 503 | ||
501 | static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) | 504 | static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) |
502 | { | 505 | { |
506 | struct mxs_ssp *ssp = &host->ssp; | ||
503 | unsigned int ssp_clk, ssp_sck; | 507 | unsigned int ssp_clk, ssp_sck; |
504 | u32 clock_divide, clock_rate; | 508 | u32 clock_divide, clock_rate; |
505 | u32 val; | 509 | u32 val; |
506 | 510 | ||
507 | ssp_clk = clk_get_rate(host->clk); | 511 | ssp_clk = clk_get_rate(ssp->clk); |
508 | 512 | ||
509 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { | 513 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { |
510 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); | 514 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); |
@@ -521,13 +525,13 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) | |||
521 | 525 | ||
522 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); | 526 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); |
523 | 527 | ||
524 | val = readl(host->base + HW_SSP_TIMING(host)); | 528 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); |
525 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); | 529 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); |
526 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); | 530 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); |
527 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); | 531 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); |
528 | writel(val, host->base + HW_SSP_TIMING(host)); | 532 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); |
529 | 533 | ||
530 | host->clk_rate = ssp_sck; | 534 | ssp->clk_rate = ssp_sck; |
531 | 535 | ||
532 | dev_dbg(mmc_dev(host->mmc), | 536 | dev_dbg(mmc_dev(host->mmc), |
533 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", | 537 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", |
@@ -552,6 +556,7 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
552 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | 556 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) |
553 | { | 557 | { |
554 | struct mxs_mmc_host *host = mmc_priv(mmc); | 558 | struct mxs_mmc_host *host = mmc_priv(mmc); |
559 | struct mxs_ssp *ssp = &host->ssp; | ||
555 | unsigned long flags; | 560 | unsigned long flags; |
556 | 561 | ||
557 | spin_lock_irqsave(&host->lock, flags); | 562 | spin_lock_irqsave(&host->lock, flags); |
@@ -560,19 +565,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
560 | 565 | ||
561 | if (enable) { | 566 | if (enable) { |
562 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 567 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
563 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | 568 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); |
564 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 569 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
565 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); | 570 | ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET); |
566 | 571 | ||
567 | if (readl(host->base + HW_SSP_STATUS(host)) & | 572 | if (readl(ssp->base + HW_SSP_STATUS(ssp)) & |
568 | BM_SSP_STATUS_SDIO_IRQ) | 573 | BM_SSP_STATUS_SDIO_IRQ) |
569 | mmc_signal_sdio_irq(host->mmc); | 574 | mmc_signal_sdio_irq(host->mmc); |
570 | 575 | ||
571 | } else { | 576 | } else { |
572 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 577 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
573 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | 578 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
574 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 579 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
575 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 580 | ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR); |
576 | } | 581 | } |
577 | 582 | ||
578 | spin_unlock_irqrestore(&host->lock, flags); | 583 | spin_unlock_irqrestore(&host->lock, flags); |
@@ -635,6 +640,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
635 | dma_cap_mask_t mask; | 640 | dma_cap_mask_t mask; |
636 | struct regulator *reg_vmmc; | 641 | struct regulator *reg_vmmc; |
637 | enum of_gpio_flags flags; | 642 | enum of_gpio_flags flags; |
643 | struct mxs_ssp *ssp; | ||
638 | 644 | ||
639 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 645 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
640 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 646 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -648,14 +654,16 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
648 | return -ENOMEM; | 654 | return -ENOMEM; |
649 | 655 | ||
650 | host = mmc_priv(mmc); | 656 | host = mmc_priv(mmc); |
651 | host->base = devm_request_and_ioremap(&pdev->dev, iores); | 657 | ssp = &host->ssp; |
652 | if (!host->base) { | 658 | ssp->dev = &pdev->dev; |
659 | ssp->base = devm_request_and_ioremap(&pdev->dev, iores); | ||
660 | if (!ssp->base) { | ||
653 | ret = -EADDRNOTAVAIL; | 661 | ret = -EADDRNOTAVAIL; |
654 | goto out_mmc_free; | 662 | goto out_mmc_free; |
655 | } | 663 | } |
656 | 664 | ||
657 | if (np) { | 665 | if (np) { |
658 | host->devid = (enum mxs_ssp_id) of_id->data; | 666 | ssp->devid = (enum mxs_ssp_id) of_id->data; |
659 | /* | 667 | /* |
660 | * TODO: This is a temporary solution and should be changed | 668 | * TODO: This is a temporary solution and should be changed |
661 | * to use generic DMA binding later when the helpers get in. | 669 | * to use generic DMA binding later when the helpers get in. |
@@ -668,7 +676,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
668 | goto out_mmc_free; | 676 | goto out_mmc_free; |
669 | } | 677 | } |
670 | } else { | 678 | } else { |
671 | host->devid = pdev->id_entry->driver_data; | 679 | ssp->devid = pdev->id_entry->driver_data; |
672 | host->dma_channel = dmares->start; | 680 | host->dma_channel = dmares->start; |
673 | } | 681 | } |
674 | 682 | ||
@@ -691,12 +699,12 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
691 | goto out_mmc_free; | 699 | goto out_mmc_free; |
692 | } | 700 | } |
693 | 701 | ||
694 | host->clk = clk_get(&pdev->dev, NULL); | 702 | ssp->clk = clk_get(&pdev->dev, NULL); |
695 | if (IS_ERR(host->clk)) { | 703 | if (IS_ERR(ssp->clk)) { |
696 | ret = PTR_ERR(host->clk); | 704 | ret = PTR_ERR(ssp->clk); |
697 | goto out_mmc_free; | 705 | goto out_mmc_free; |
698 | } | 706 | } |
699 | clk_prepare_enable(host->clk); | 707 | clk_prepare_enable(ssp->clk); |
700 | 708 | ||
701 | mxs_mmc_reset(host); | 709 | mxs_mmc_reset(host); |
702 | 710 | ||
@@ -741,8 +749,8 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
741 | 749 | ||
742 | mmc->max_segs = 52; | 750 | mmc->max_segs = 52; |
743 | mmc->max_blk_size = 1 << 0xf; | 751 | mmc->max_blk_size = 1 << 0xf; |
744 | mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff; | 752 | mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; |
745 | mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff; | 753 | mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; |
746 | mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); | 754 | mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); |
747 | 755 | ||
748 | platform_set_drvdata(pdev, mmc); | 756 | platform_set_drvdata(pdev, mmc); |
@@ -766,8 +774,8 @@ out_free_dma: | |||
766 | if (host->dmach) | 774 | if (host->dmach) |
767 | dma_release_channel(host->dmach); | 775 | dma_release_channel(host->dmach); |
768 | out_clk_put: | 776 | out_clk_put: |
769 | clk_disable_unprepare(host->clk); | 777 | clk_disable_unprepare(ssp->clk); |
770 | clk_put(host->clk); | 778 | clk_put(ssp->clk); |
771 | out_mmc_free: | 779 | out_mmc_free: |
772 | mmc_free_host(mmc); | 780 | mmc_free_host(mmc); |
773 | return ret; | 781 | return ret; |
@@ -777,6 +785,7 @@ static int mxs_mmc_remove(struct platform_device *pdev) | |||
777 | { | 785 | { |
778 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 786 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
779 | struct mxs_mmc_host *host = mmc_priv(mmc); | 787 | struct mxs_mmc_host *host = mmc_priv(mmc); |
788 | struct mxs_ssp *ssp = &host->ssp; | ||
780 | 789 | ||
781 | mmc_remove_host(mmc); | 790 | mmc_remove_host(mmc); |
782 | 791 | ||
@@ -785,8 +794,8 @@ static int mxs_mmc_remove(struct platform_device *pdev) | |||
785 | if (host->dmach) | 794 | if (host->dmach) |
786 | dma_release_channel(host->dmach); | 795 | dma_release_channel(host->dmach); |
787 | 796 | ||
788 | clk_disable_unprepare(host->clk); | 797 | clk_disable_unprepare(ssp->clk); |
789 | clk_put(host->clk); | 798 | clk_put(ssp->clk); |
790 | 799 | ||
791 | mmc_free_host(mmc); | 800 | mmc_free_host(mmc); |
792 | 801 | ||
@@ -798,11 +807,12 @@ static int mxs_mmc_suspend(struct device *dev) | |||
798 | { | 807 | { |
799 | struct mmc_host *mmc = dev_get_drvdata(dev); | 808 | struct mmc_host *mmc = dev_get_drvdata(dev); |
800 | struct mxs_mmc_host *host = mmc_priv(mmc); | 809 | struct mxs_mmc_host *host = mmc_priv(mmc); |
810 | struct mxs_ssp *ssp = &host->ssp; | ||
801 | int ret = 0; | 811 | int ret = 0; |
802 | 812 | ||
803 | ret = mmc_suspend_host(mmc); | 813 | ret = mmc_suspend_host(mmc); |
804 | 814 | ||
805 | clk_disable_unprepare(host->clk); | 815 | clk_disable_unprepare(ssp->clk); |
806 | 816 | ||
807 | return ret; | 817 | return ret; |
808 | } | 818 | } |
@@ -811,9 +821,10 @@ static int mxs_mmc_resume(struct device *dev) | |||
811 | { | 821 | { |
812 | struct mmc_host *mmc = dev_get_drvdata(dev); | 822 | struct mmc_host *mmc = dev_get_drvdata(dev); |
813 | struct mxs_mmc_host *host = mmc_priv(mmc); | 823 | struct mxs_mmc_host *host = mmc_priv(mmc); |
824 | struct mxs_ssp *ssp = &host->ssp; | ||
814 | int ret = 0; | 825 | int ret = 0; |
815 | 826 | ||
816 | clk_prepare_enable(host->clk); | 827 | clk_prepare_enable(ssp->clk); |
817 | 828 | ||
818 | ret = mmc_resume_host(mmc); | 829 | ret = mmc_resume_host(mmc); |
819 | 830 | ||
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h index 7dfa1d7d1a78..475f69fb896f 100644 --- a/include/linux/spi/mxs-spi.h +++ b/include/linux/spi/mxs-spi.h | |||
@@ -128,4 +128,12 @@ enum mxs_ssp_id { | |||
128 | IMX28_SSP, | 128 | IMX28_SSP, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | struct mxs_ssp { | ||
132 | struct device *dev; | ||
133 | void __iomem *base; | ||
134 | struct clk *clk; | ||
135 | unsigned int clk_rate; | ||
136 | enum mxs_ssp_id devid; | ||
137 | }; | ||
138 | |||
131 | #endif /* __LINUX_SPI_MXS_SPI_H__ */ | 139 | #endif /* __LINUX_SPI_MXS_SPI_H__ */ |