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