From ce1807b2e527979bd77d8a1a1768a6365f3febb5 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 19 Nov 2009 19:01:42 +0000 Subject: spi/i.mx: drain MXC SPI transfer buffer when probing device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the MX31litekit, the bootloader seems to communicate with the MC13783 PMIC chip before booting Linux. However, it does not flush all the buffers properly after that, which makes the imx-spi driver read bogus data when probing the MC13783. Fix that by draining the SPI receive buffer on startup. Signed-off-by: Daniel Mack Acked-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 89c22efedfb0..1b17f443dee7 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -44,6 +44,9 @@ #define MXC_CSPIINT 0x0c #define MXC_RESET 0x1c +#define MX3_CSPISTAT 0x14 +#define MX3_CSPISTAT_RR (1 << 3) + /* generic defines to abstract from the different register layouts */ #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ @@ -593,6 +596,11 @@ static int __init spi_imx_probe(struct platform_device *pdev) if (!cpu_is_mx31() || !cpu_is_mx35()) writel(1, spi_imx->base + MXC_RESET); + /* drain receive buffer */ + if (cpu_is_mx31() || cpu_is_mx35()) + while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) + readl(spi_imx->base + MXC_CSPIRXDATA); + spi_imx->intctrl(spi_imx, 0); ret = spi_bitbang_start(&spi_imx->bitbang); -- cgit v1.2.3 From bbd050af0e2b7d77bfc959cf76219eb71c3b982a Mon Sep 17 00:00:00 2001 From: John Ogness Date: Tue, 24 Nov 2009 16:53:07 +0000 Subject: spi/i.MX: fix broken error handling for gpio_request i.MX35-provided chipselects are represented using negative numbers. If gpio_request() fails and the previous chipselect was a negative number, the while loop is endless (i is never decremented). Also, the error loop would never call gpio_free on chipselect[0]. And finally, the error message was missing an endline. Signed-off-by: John Ogness Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 1b17f443dee7..8ffa48ce570c 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -516,11 +516,12 @@ static int __init spi_imx_probe(struct platform_device *pdev) continue; ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); if (ret) { - i--; - while (i > 0) + while (i > 0) { + i--; if (spi_imx->chipselect[i] >= 0) - gpio_free(spi_imx->chipselect[i--]); - dev_err(&pdev->dev, "can't get cs gpios"); + gpio_free(spi_imx->chipselect[i]); + } + dev_err(&pdev->dev, "can't get cs gpios\n"); goto out_master_put; } } -- cgit v1.2.3 From 60f675a12c03c65018beaa1d1ede41557aa60e00 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 13 Dec 2009 00:58:13 -0700 Subject: spi-imx: correct check for platform_get_irq failing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platform_get_irq returns -ENXIO if there is no entry. So ensure return value is greater than zero instead of non-zero. Signed-off-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 8ffa48ce570c..c96804f62052 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -555,7 +555,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) } spi_imx->irq = platform_get_irq(pdev, 0); - if (!spi_imx->irq) { + if (spi_imx->irq <= 0) { ret = -EINVAL; goto out_iounmap; } -- cgit v1.2.3 From f30d59c5d34478fe5e07fd9c9e4bda6329684509 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 13 Dec 2009 00:58:29 -0700 Subject: spi-imx: use positive logic to distinguish cpu variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is much safer when support for new variants is added. Signed-off-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index c96804f62052..496bf9ad16e0 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -594,7 +594,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) clk_enable(spi_imx->clk); spi_imx->spi_clk = clk_get_rate(spi_imx->clk); - if (!cpu_is_mx31() || !cpu_is_mx35()) + if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) writel(1, spi_imx->base + MXC_RESET); /* drain receive buffer */ -- cgit v1.2.3 From 87f673e9ca468b98da5677cf43abdd09945f449d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 13 Dec 2009 00:58:41 -0700 Subject: spi-imx: Add mx25 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sascha Hauer Signed-off-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 496bf9ad16e0..4c9b1332b536 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -208,7 +208,7 @@ static int mx31_config(struct spi_imx_data *spi_imx, if (cpu_is_mx31()) reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; - else if (cpu_is_mx35()) { + else if (cpu_is_mx25() || cpu_is_mx35()) { reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; reg |= MX31_CSPICTRL_SSCTL; } @@ -222,7 +222,7 @@ static int mx31_config(struct spi_imx_data *spi_imx, if (config->cs < 0) { if (cpu_is_mx31()) reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; - else if (cpu_is_mx35()) + else if (cpu_is_mx25() || cpu_is_mx35()) reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; } @@ -566,7 +566,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) goto out_iounmap; } - if (cpu_is_mx31() || cpu_is_mx35()) { + if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) { spi_imx->intctrl = mx31_intctrl; spi_imx->config = mx31_config; spi_imx->trigger = mx31_trigger; @@ -598,7 +598,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) writel(1, spi_imx->base + MXC_RESET); /* drain receive buffer */ - if (cpu_is_mx31() || cpu_is_mx35()) + if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) readl(spi_imx->base + MXC_CSPIRXDATA); -- cgit v1.2.3 From 980f3beeb68fd3b383908bac8a017b121df8ee29 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 13 Dec 2009 01:02:09 -0700 Subject: spi-imx: don't access struct device directly but use dev_get_platdata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also there is no casting needed to assign a void pointer. Signed-off-by: Uwe Kleine-König Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 4c9b1332b536..e334747ba2d9 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -492,7 +492,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) struct resource *res; int i, ret; - mxc_platform_info = (struct spi_imx_master *)pdev->dev.platform_data; + mxc_platform_info = dev_get_platdata(&pdev->dev); if (!mxc_platform_info) { dev_err(&pdev->dev, "can't get the platform data\n"); return -EINVAL; -- cgit v1.2.3 From 965346e3b99e2c5f51bd1325ddd0257227000355 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sun, 13 Dec 2009 01:03:12 -0700 Subject: spi: fix probe/remove section markings Probe/remove functions need to be marked as __devinit and __devexit (not __init an __exit) to prevent trying to run code that has been discarded. This patch fixes the spi_imx driver to mark probe and remove correctly. Signed-off-by: Grant Likely --- drivers/spi/spi_imx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/spi/spi_imx.c') diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index e334747ba2d9..1893f1e96dc4 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -484,7 +484,7 @@ static void spi_imx_cleanup(struct spi_device *spi) { } -static int __init spi_imx_probe(struct platform_device *pdev) +static int __devinit spi_imx_probe(struct platform_device *pdev) { struct spi_imx_master *mxc_platform_info; struct spi_master *master; @@ -634,7 +634,7 @@ out_master_put: return ret; } -static int __exit spi_imx_remove(struct platform_device *pdev) +static int __devexit spi_imx_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -668,7 +668,7 @@ static struct platform_driver spi_imx_driver = { .owner = THIS_MODULE, }, .probe = spi_imx_probe, - .remove = __exit_p(spi_imx_remove), + .remove = __devexit_p(spi_imx_remove), }; static int __init spi_imx_init(void) -- cgit v1.2.3