diff options
Diffstat (limited to 'drivers/spi/spi_imx.c')
-rw-r--r-- | drivers/spi/spi_imx.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 89c22efedfb0..1893f1e96dc4 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -44,6 +44,9 @@ | |||
44 | #define MXC_CSPIINT 0x0c | 44 | #define MXC_CSPIINT 0x0c |
45 | #define MXC_RESET 0x1c | 45 | #define MXC_RESET 0x1c |
46 | 46 | ||
47 | #define MX3_CSPISTAT 0x14 | ||
48 | #define MX3_CSPISTAT_RR (1 << 3) | ||
49 | |||
47 | /* generic defines to abstract from the different register layouts */ | 50 | /* generic defines to abstract from the different register layouts */ |
48 | #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ | 51 | #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ |
49 | #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ | 52 | #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ |
@@ -205,7 +208,7 @@ static int mx31_config(struct spi_imx_data *spi_imx, | |||
205 | 208 | ||
206 | if (cpu_is_mx31()) | 209 | if (cpu_is_mx31()) |
207 | reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; | 210 | reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; |
208 | else if (cpu_is_mx35()) { | 211 | else if (cpu_is_mx25() || cpu_is_mx35()) { |
209 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; | 212 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; |
210 | reg |= MX31_CSPICTRL_SSCTL; | 213 | reg |= MX31_CSPICTRL_SSCTL; |
211 | } | 214 | } |
@@ -219,7 +222,7 @@ static int mx31_config(struct spi_imx_data *spi_imx, | |||
219 | if (config->cs < 0) { | 222 | if (config->cs < 0) { |
220 | if (cpu_is_mx31()) | 223 | if (cpu_is_mx31()) |
221 | reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; | 224 | reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; |
222 | else if (cpu_is_mx35()) | 225 | else if (cpu_is_mx25() || cpu_is_mx35()) |
223 | reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; | 226 | reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; |
224 | } | 227 | } |
225 | 228 | ||
@@ -481,7 +484,7 @@ static void spi_imx_cleanup(struct spi_device *spi) | |||
481 | { | 484 | { |
482 | } | 485 | } |
483 | 486 | ||
484 | static int __init spi_imx_probe(struct platform_device *pdev) | 487 | static int __devinit spi_imx_probe(struct platform_device *pdev) |
485 | { | 488 | { |
486 | struct spi_imx_master *mxc_platform_info; | 489 | struct spi_imx_master *mxc_platform_info; |
487 | struct spi_master *master; | 490 | struct spi_master *master; |
@@ -489,7 +492,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
489 | struct resource *res; | 492 | struct resource *res; |
490 | int i, ret; | 493 | int i, ret; |
491 | 494 | ||
492 | mxc_platform_info = (struct spi_imx_master *)pdev->dev.platform_data; | 495 | mxc_platform_info = dev_get_platdata(&pdev->dev); |
493 | if (!mxc_platform_info) { | 496 | if (!mxc_platform_info) { |
494 | dev_err(&pdev->dev, "can't get the platform data\n"); | 497 | dev_err(&pdev->dev, "can't get the platform data\n"); |
495 | return -EINVAL; | 498 | return -EINVAL; |
@@ -513,11 +516,12 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
513 | continue; | 516 | continue; |
514 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); | 517 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); |
515 | if (ret) { | 518 | if (ret) { |
516 | i--; | 519 | while (i > 0) { |
517 | while (i > 0) | 520 | i--; |
518 | if (spi_imx->chipselect[i] >= 0) | 521 | if (spi_imx->chipselect[i] >= 0) |
519 | gpio_free(spi_imx->chipselect[i--]); | 522 | gpio_free(spi_imx->chipselect[i]); |
520 | dev_err(&pdev->dev, "can't get cs gpios"); | 523 | } |
524 | dev_err(&pdev->dev, "can't get cs gpios\n"); | ||
521 | goto out_master_put; | 525 | goto out_master_put; |
522 | } | 526 | } |
523 | } | 527 | } |
@@ -551,7 +555,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
551 | } | 555 | } |
552 | 556 | ||
553 | spi_imx->irq = platform_get_irq(pdev, 0); | 557 | spi_imx->irq = platform_get_irq(pdev, 0); |
554 | if (!spi_imx->irq) { | 558 | if (spi_imx->irq <= 0) { |
555 | ret = -EINVAL; | 559 | ret = -EINVAL; |
556 | goto out_iounmap; | 560 | goto out_iounmap; |
557 | } | 561 | } |
@@ -562,7 +566,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
562 | goto out_iounmap; | 566 | goto out_iounmap; |
563 | } | 567 | } |
564 | 568 | ||
565 | if (cpu_is_mx31() || cpu_is_mx35()) { | 569 | if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) { |
566 | spi_imx->intctrl = mx31_intctrl; | 570 | spi_imx->intctrl = mx31_intctrl; |
567 | spi_imx->config = mx31_config; | 571 | spi_imx->config = mx31_config; |
568 | spi_imx->trigger = mx31_trigger; | 572 | spi_imx->trigger = mx31_trigger; |
@@ -590,9 +594,14 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
590 | clk_enable(spi_imx->clk); | 594 | clk_enable(spi_imx->clk); |
591 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk); | 595 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk); |
592 | 596 | ||
593 | if (!cpu_is_mx31() || !cpu_is_mx35()) | 597 | if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) |
594 | writel(1, spi_imx->base + MXC_RESET); | 598 | writel(1, spi_imx->base + MXC_RESET); |
595 | 599 | ||
600 | /* drain receive buffer */ | ||
601 | if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) | ||
602 | while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) | ||
603 | readl(spi_imx->base + MXC_CSPIRXDATA); | ||
604 | |||
596 | spi_imx->intctrl(spi_imx, 0); | 605 | spi_imx->intctrl(spi_imx, 0); |
597 | 606 | ||
598 | ret = spi_bitbang_start(&spi_imx->bitbang); | 607 | ret = spi_bitbang_start(&spi_imx->bitbang); |
@@ -625,7 +634,7 @@ out_master_put: | |||
625 | return ret; | 634 | return ret; |
626 | } | 635 | } |
627 | 636 | ||
628 | static int __exit spi_imx_remove(struct platform_device *pdev) | 637 | static int __devexit spi_imx_remove(struct platform_device *pdev) |
629 | { | 638 | { |
630 | struct spi_master *master = platform_get_drvdata(pdev); | 639 | struct spi_master *master = platform_get_drvdata(pdev); |
631 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 640 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -659,7 +668,7 @@ static struct platform_driver spi_imx_driver = { | |||
659 | .owner = THIS_MODULE, | 668 | .owner = THIS_MODULE, |
660 | }, | 669 | }, |
661 | .probe = spi_imx_probe, | 670 | .probe = spi_imx_probe, |
662 | .remove = __exit_p(spi_imx_remove), | 671 | .remove = __devexit_p(spi_imx_remove), |
663 | }; | 672 | }; |
664 | 673 | ||
665 | static int __init spi_imx_init(void) | 674 | static int __init spi_imx_init(void) |