From e3bd9ec5d8bfc90f9e1bd995677829e57a404061 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:39 +0000 Subject: [ARM] S3C24XX: Move mci.h to arch/arm/plat-s3c24xx/include/plat Move mci.h to new position in arch/arm/plat-s3c24xx/include/plat ready to clean out old include directories. Signed-off-by: Ben Dooks --- drivers/mmc/host/s3cmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 3b2085b5776..fcc98a4cce3 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "s3cmci.h" -- cgit v1.2.3-70-g09d2 From e0d8b13ae1e3ea747620580b6f777992148de182 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 11 Nov 2008 17:52:32 +0000 Subject: [ARM] pxa: don't pass a consumer clock name for devices with unique clocks Where devices only have one consumer, passing a consumer clock ID has no real benefit. Remove it. Signed-off-by: Russell King --- arch/arm/mach-pxa/pwm.c | 2 +- arch/arm/mach-pxa/ssp.c | 2 +- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/input/keyboard/pxa27x_keypad.c | 2 +- drivers/media/video/pxa_camera.c | 2 +- drivers/mmc/host/pxamci.c | 2 +- drivers/mtd/nand/pxa3xx_nand.c | 2 +- drivers/serial/pxa.c | 2 +- drivers/usb/gadget/pxa25x_udc.c | 2 +- drivers/usb/gadget/pxa27x_udc.c | 2 +- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/video/pxafb.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/mmc') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index 74e2ead8cee..3ca7ffc6904 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -173,7 +173,7 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev, return ERR_PTR(-ENOMEM); } - pwm->clk = clk_get(&pdev->dev, "PWMCLK"); + pwm->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(pwm->clk)) { ret = PTR_ERR(pwm->clk); goto err_free; diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 2c31ec72568..6f42004db3e 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -356,7 +356,7 @@ static int __devinit ssp_probe(struct platform_device *pdev, int type) } ssp->pdev = pdev; - ssp->clk = clk_get(&pdev->dev, "SSPCLK"); + ssp->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(ssp->clk)) { ret = PTR_ERR(ssp->clk); goto err_free; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 906f9b9d715..587f5b2380d 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1016,7 +1016,7 @@ static int i2c_pxa_probe(struct platform_device *dev) snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", i2c->adap.nr); - i2c->clk = clk_get(&dev->dev, "I2CCLK"); + i2c->clk = clk_get(&dev->dev, NULL); if (IS_ERR(i2c->clk)) { ret = PTR_ERR(i2c->clk); goto eclk; diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 6d30c6d334c..0d2fc64a5e1 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -475,7 +475,7 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) goto failed_free_mem; } - keypad->clk = clk_get(&pdev->dev, "KBDCLK"); + keypad->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); error = PTR_ERR(keypad->clk); diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index eb6be580292..6586f0b1336 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -1071,7 +1071,7 @@ static int pxa_camera_probe(struct platform_device *pdev) goto exit; } - pcdev->clk = clk_get(&pdev->dev, "CAMCLK"); + pcdev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(pcdev->clk)) { err = PTR_ERR(pcdev->clk); goto exit_kfree; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index ebfaa996093..a1700a80e2f 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -533,7 +533,7 @@ static int pxamci_probe(struct platform_device *pdev) host->pdata = pdev->dev.platform_data; host->clkrt = CLKRT_OFF; - host->clk = clk_get(&pdev->dev, "MMCCLK"); + host->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); host->clk = NULL; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index c0fa9c9edf0..61c922a8356 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1079,7 +1079,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) this = &info->nand_chip; mtd->priv = info; - info->clk = clk_get(&pdev->dev, "NANDCLK"); + info->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed to get nand clock\n"); ret = PTR_ERR(info->clk); diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index abc00be5543..8ea314bc00c 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -766,7 +766,7 @@ static int serial_pxa_probe(struct platform_device *dev) if (!sport) return -ENOMEM; - sport->clk = clk_get(&dev->dev, "UARTCLK"); + sport->clk = clk_get(&dev->dev, NULL); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); goto err_free; diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index da6e93c201d..a4790f3c7cd 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2145,7 +2145,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; - dev->clk = clk_get(&pdev->dev, "UDCCLK"); + dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { retval = PTR_ERR(dev->clk); goto err_clk; diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index caa37c95802..944e4ff641d 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2226,7 +2226,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) udc->dev = &pdev->dev; udc->mach = pdev->dev.platform_data; - udc->clk = clk_get(&pdev->dev, "UDCCLK"); + udc->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(udc->clk)) { retval = PTR_ERR(udc->clk); goto err_clk; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e294d430733..e44dc2cbca2 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -296,7 +296,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device return -ENXIO; } - usb_clk = clk_get(&pdev->dev, "USBCLK"); + usb_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(usb_clk)) return PTR_ERR(usb_clk); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index cc59c52e110..0bc2c5a127b 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1429,7 +1429,7 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) memset(fbi, 0, sizeof(struct pxafb_info)); fbi->dev = dev; - fbi->clk = clk_get(dev, "LCDCLK"); + fbi->clk = clk_get(dev, NULL); if (IS_ERR(fbi->clk)) { kfree(fbi); return NULL; -- cgit v1.2.3-70-g09d2 From 05678a96de2e97fdfd4b817478840ad6a02ea1d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 28 Nov 2008 16:04:54 +0000 Subject: [ARM] pxa: avoid polluting the kernel's namespace Avoid unnecessarily pollution of the kernel's namespace by avoiding mach/hardware.h. Include this header file where necessary. Signed-off-by: Russell King --- arch/arm/mach-pxa/ezx.c | 1 + arch/arm/mach-pxa/include/mach/io.h | 2 -- arch/arm/mach-pxa/smemc.c | 2 ++ arch/arm/mach-pxa/time.c | 1 + drivers/mmc/host/pxamci.c | 3 ++- drivers/net/irda/pxaficp_ir.c | 1 + drivers/net/smc91x.h | 1 + 7 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/mmc') diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index cc3d850cc0b..83c56d3abac 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 600fd4f7660..38cb2123e9b 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -6,8 +6,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include - #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index ad346addc02..d6f6904132a 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -8,6 +8,8 @@ #include #include +#include + #define SMEMC_PHYS_BASE (0x4A000000) #define SMEMC_PHYS_SIZE (0x90) diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index f8a9a62959e..ef4ddf9d504 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index a1700a80e2f..e9b0159de52 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -26,11 +26,12 @@ #include #include #include +#include #include -#include #include +#include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index c5b02b66f75..50b839da140 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -24,6 +24,7 @@ #include #include +#include #include #define IrSR_RXPL_NEG_IS_ZERO (1<<4) diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index a07cc9351c6..22576e0a6d1 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -528,6 +528,7 @@ struct smc_local { */ #include #include +#include #include #ifdef SMC_insl -- cgit v1.2.3-70-g09d2 From dcea83adc666061864b82c96e059dffe7268b512 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 29 Nov 2008 11:40:28 +0000 Subject: [ARM] Hide ISA DMA API when ISA_DMA_API is unset When ISA_DMA_API is unset, we're not implementing the ISA DMA API, so there's no point in publishing the prototypes via asm/dma.h, nor including the machine dependent parts of that API. This allows us to remove a lot of mach/dma.h files which don't contain any useful code. Unfortunately though, some platforms put their own private non-ISA definitions into mach/dma.h, so we leave these behind and fix the appropriate #include statments. Signed-off-by: Russell King --- arch/arm/include/asm/dma.h | 23 ++++++++++++++++------- arch/arm/mach-aaec2000/include/mach/dma.h | 9 --------- arch/arm/mach-at91/include/mach/dma.h | 19 ------------------- arch/arm/mach-clps711x/include/mach/dma.h | 19 ------------------- arch/arm/mach-davinci/include/mach/dma.h | 10 ---------- arch/arm/mach-ebsa110/include/mach/dma.h | 11 ----------- arch/arm/mach-ep93xx/include/mach/dma.h | 3 --- arch/arm/mach-imx/dma.c | 7 ++++--- arch/arm/mach-imx/include/mach/imx-dma.h | 12 ++++++++---- arch/arm/mach-integrator/include/mach/dma.h | 19 ------------------- arch/arm/mach-iop13xx/include/mach/dma.h | 3 --- arch/arm/mach-iop32x/include/mach/dma.h | 9 --------- arch/arm/mach-iop33x/include/mach/dma.h | 9 --------- arch/arm/mach-ixp2000/include/mach/dma.h | 9 --------- arch/arm/mach-ixp23xx/include/mach/dma.h | 3 --- arch/arm/mach-ixp4xx/include/mach/dma.h | 10 ---------- arch/arm/mach-kirkwood/include/mach/dma.h | 1 - arch/arm/mach-ks8695/include/mach/dma.h | 17 ----------------- arch/arm/mach-l7200/include/mach/dma.h | 16 ---------------- arch/arm/mach-loki/include/mach/dma.h | 1 - arch/arm/mach-mv78xx0/include/mach/dma.h | 1 - arch/arm/mach-netx/include/mach/dma.h | 20 -------------------- arch/arm/mach-ns9xxx/include/mach/dma.h | 14 -------------- arch/arm/mach-orion5x/include/mach/dma.h | 1 - arch/arm/mach-pnx4008/dma.c | 3 +-- arch/arm/mach-pxa/dma.c | 2 +- arch/arm/mach-realview/include/mach/dma.h | 20 -------------------- arch/arm/mach-s3c2410/dma.c | 1 - arch/arm/mach-s3c2410/include/mach/dma.h | 18 +++++++++--------- arch/arm/mach-s3c2412/dma.c | 1 - arch/arm/mach-s3c2440/dma.c | 1 - arch/arm/mach-s3c2443/dma.c | 1 - arch/arm/mach-sa1100/collie_pm.c | 2 +- arch/arm/mach-sa1100/dma.c | 2 +- arch/arm/mach-versatile/include/mach/dma.h | 20 -------------------- arch/arm/plat-mxc/dma-mx1-mx2.c | 2 +- arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h | 2 +- arch/arm/plat-mxc/include/mach/dma.h | 14 -------------- arch/arm/plat-omap/dma.c | 2 +- arch/arm/plat-s3c24xx/dma.c | 17 ++++++++--------- drivers/mfd/mcp-core.c | 2 +- drivers/mfd/mcp-sa11x0.c | 2 +- drivers/mfd/ucb1x00-assabet.c | 2 +- drivers/mfd/ucb1x00-core.c | 2 +- drivers/mfd/ucb1x00-ts.c | 2 +- drivers/mmc/host/pxamci.c | 2 +- drivers/net/irda/pxaficp_ir.c | 2 +- drivers/net/smc91x.h | 2 +- drivers/spi/pxa2xx_spi.c | 2 +- 49 files changed, 61 insertions(+), 311 deletions(-) delete mode 100644 arch/arm/mach-aaec2000/include/mach/dma.h delete mode 100644 arch/arm/mach-at91/include/mach/dma.h delete mode 100644 arch/arm/mach-clps711x/include/mach/dma.h delete mode 100644 arch/arm/mach-davinci/include/mach/dma.h delete mode 100644 arch/arm/mach-ebsa110/include/mach/dma.h delete mode 100644 arch/arm/mach-ep93xx/include/mach/dma.h delete mode 100644 arch/arm/mach-integrator/include/mach/dma.h delete mode 100644 arch/arm/mach-iop13xx/include/mach/dma.h delete mode 100644 arch/arm/mach-iop32x/include/mach/dma.h delete mode 100644 arch/arm/mach-iop33x/include/mach/dma.h delete mode 100644 arch/arm/mach-ixp2000/include/mach/dma.h delete mode 100644 arch/arm/mach-ixp23xx/include/mach/dma.h delete mode 100644 arch/arm/mach-ixp4xx/include/mach/dma.h delete mode 100644 arch/arm/mach-kirkwood/include/mach/dma.h delete mode 100644 arch/arm/mach-ks8695/include/mach/dma.h delete mode 100644 arch/arm/mach-l7200/include/mach/dma.h delete mode 100644 arch/arm/mach-loki/include/mach/dma.h delete mode 100644 arch/arm/mach-mv78xx0/include/mach/dma.h delete mode 100644 arch/arm/mach-netx/include/mach/dma.h delete mode 100644 arch/arm/mach-ns9xxx/include/mach/dma.h delete mode 100644 arch/arm/mach-orion5x/include/mach/dma.h delete mode 100644 arch/arm/mach-realview/include/mach/dma.h delete mode 100644 arch/arm/mach-versatile/include/mach/dma.h delete mode 100644 arch/arm/plat-mxc/include/mach/dma.h (limited to 'drivers/mmc') diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 6a4d44a5b45..06419980dde 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -1,13 +1,7 @@ #ifndef __ASM_ARM_DMA_H #define __ASM_ARM_DMA_H -typedef unsigned int dmach_t; - -#include #include -#include -#include -#include /* * This is the maximum virtual address which can be DMA'd from. @@ -16,6 +10,19 @@ typedef unsigned int dmach_t; #define MAX_DMA_ADDRESS 0xffffffff #endif +#ifdef CONFIG_ISA_DMA_API +/* + * This is used to support drivers written for the x86 ISA DMA API. + * It should not be re-used except for that purpose. + */ +#include +#include +#include + +typedef unsigned int dmach_t; + +#include + /* * DMA modes */ @@ -141,4 +148,6 @@ extern int isa_dma_bridge_buggy; #define isa_dma_bridge_buggy (0) #endif -#endif /* _ARM_DMA_H */ +#endif /* CONFIG_ISA_DMA_API */ + +#endif /* __ASM_ARM_DMA_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/dma.h b/arch/arm/mach-aaec2000/include/mach/dma.h deleted file mode 100644 index 2da846c72fe..00000000000 --- a/arch/arm/mach-aaec2000/include/mach/dma.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-aaec2000/include/mach/dma.h - * - * Copyright (c) 2005 Nicolas Bellido Y Ortega - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ diff --git a/arch/arm/mach-at91/include/mach/dma.h b/arch/arm/mach-at91/include/mach/dma.h deleted file mode 100644 index e4f90c17761..00000000000 --- a/arch/arm/mach-at91/include/mach/dma.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/dma.h - * - * Copyright (C) 2003 SAN People - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/mach-clps711x/include/mach/dma.h b/arch/arm/mach-clps711x/include/mach/dma.h deleted file mode 100644 index 0d620e86953..00000000000 --- a/arch/arm/mach-clps711x/include/mach/dma.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/dma.h - * - * Copyright (C) 1997,1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/mach-davinci/include/mach/dma.h b/arch/arm/mach-davinci/include/mach/dma.h deleted file mode 100644 index cdf6ec9d46f..00000000000 --- a/arch/arm/mach-davinci/include/mach/dma.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * DaVinci DMA definitions - * - * Author: Kevin Hilman, MontaVista Software, Inc. - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ diff --git a/arch/arm/mach-ebsa110/include/mach/dma.h b/arch/arm/mach-ebsa110/include/mach/dma.h deleted file mode 100644 index 780a04c8bbe..00000000000 --- a/arch/arm/mach-ebsa110/include/mach/dma.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/arm/mach-ebsa110/include/mach/dma.h - * - * Copyright (C) 1997,1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * EBSA110 DMA definitions - */ diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h deleted file mode 100644 index d0fa9656e92..00000000000 --- a/arch/arm/mach-ep93xx/include/mach/dma.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/dma.h - */ diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c index c10810c936b..1536583eece 100644 --- a/arch/arm/mach-imx/dma.c +++ b/arch/arm/mach-imx/dma.c @@ -28,10 +28,11 @@ #include #include +#include #include #include #include -#include +#include #include struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS]; @@ -138,7 +139,7 @@ imx_dma_setup_sg_base(imx_dmach_t dma_ch, int imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address, unsigned int dma_length, unsigned int dev_addr, - dmamode_t dmamode) + unsigned int dmamode) { struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; @@ -223,7 +224,7 @@ imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address, int imx_dma_setup_sg(imx_dmach_t dma_ch, struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, - unsigned int dev_addr, dmamode_t dmamode) + unsigned int dev_addr, unsigned int dmamode) { int res; struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; diff --git a/arch/arm/mach-imx/include/mach/imx-dma.h b/arch/arm/mach-imx/include/mach/imx-dma.h index 44d89c35539..bbe54df7f0d 100644 --- a/arch/arm/mach-imx/include/mach/imx-dma.h +++ b/arch/arm/mach-imx/include/mach/imx-dma.h @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #ifndef __ASM_ARCH_IMX_DMA_H #define __ASM_ARCH_IMX_DMA_H @@ -48,7 +48,7 @@ struct imx_dma_channel { void (*irq_handler) (int, void *); void (*err_handler) (int, void *, int errcode); void *data; - dmamode_t dma_mode; + unsigned int dma_mode; struct scatterlist *sg; unsigned int sgbc; unsigned int sgcount; @@ -66,14 +66,18 @@ extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS]; /* The type to distinguish channel numbers parameter from ordinal int type */ typedef int imx_dmach_t; +#define DMA_MODE_READ 0 +#define DMA_MODE_WRITE 1 +#define DMA_MODE_MASK 1 + int imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address, - unsigned int dma_length, unsigned int dev_addr, dmamode_t dmamode); + unsigned int dma_length, unsigned int dev_addr, unsigned int dmamode); int imx_dma_setup_sg(imx_dmach_t dma_ch, struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, - unsigned int dev_addr, dmamode_t dmamode); + unsigned int dev_addr, unsigned int dmamode); int imx_dma_setup_handlers(imx_dmach_t dma_ch, diff --git a/arch/arm/mach-integrator/include/mach/dma.h b/arch/arm/mach-integrator/include/mach/dma.h deleted file mode 100644 index fbebe85a2db..00000000000 --- a/arch/arm/mach-integrator/include/mach/dma.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-integrator/include/mach/dma.h - * - * Copyright (C) 1997,1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/mach-iop13xx/include/mach/dma.h b/arch/arm/mach-iop13xx/include/mach/dma.h deleted file mode 100644 index d79846fbb39..00000000000 --- a/arch/arm/mach-iop13xx/include/mach/dma.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef _IOP13XX_DMA_H -#define _IOP13XX_DMA_H -#endif diff --git a/arch/arm/mach-iop32x/include/mach/dma.h b/arch/arm/mach-iop32x/include/mach/dma.h deleted file mode 100644 index f8bd817f205..00000000000 --- a/arch/arm/mach-iop32x/include/mach/dma.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-iop32x/include/mach/dma.h - * - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ diff --git a/arch/arm/mach-iop33x/include/mach/dma.h b/arch/arm/mach-iop33x/include/mach/dma.h deleted file mode 100644 index d8b42232931..00000000000 --- a/arch/arm/mach-iop33x/include/mach/dma.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-iop33x/include/mach/dma.h - * - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ diff --git a/arch/arm/mach-ixp2000/include/mach/dma.h b/arch/arm/mach-ixp2000/include/mach/dma.h deleted file mode 100644 index 26063d60f62..00000000000 --- a/arch/arm/mach-ixp2000/include/mach/dma.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-ixp2000/include/mach/dma.h - * - * Copyright (C) 2002 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ diff --git a/arch/arm/mach-ixp23xx/include/mach/dma.h b/arch/arm/mach-ixp23xx/include/mach/dma.h deleted file mode 100644 index 8886544b93f..00000000000 --- a/arch/arm/mach-ixp23xx/include/mach/dma.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/include/mach/dma.h - */ diff --git a/arch/arm/mach-ixp4xx/include/mach/dma.h b/arch/arm/mach-ixp4xx/include/mach/dma.h deleted file mode 100644 index 5b7e1a98e98..00000000000 --- a/arch/arm/mach-ixp4xx/include/mach/dma.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/dma.h - * - * Copyright (C) 2001-2004 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ diff --git a/arch/arm/mach-kirkwood/include/mach/dma.h b/arch/arm/mach-kirkwood/include/mach/dma.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-ks8695/include/mach/dma.h b/arch/arm/mach-ks8695/include/mach/dma.h deleted file mode 100644 index 56120628008..00000000000 --- a/arch/arm/mach-ks8695/include/mach/dma.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-ks8695/include/mach/dma.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/mach-l7200/include/mach/dma.h b/arch/arm/mach-l7200/include/mach/dma.h deleted file mode 100644 index 07731f2cccf..00000000000 --- a/arch/arm/mach-l7200/include/mach/dma.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-l7200/include/mach/dma.h - * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) - * - * Changelog: - * 08-29-2000 SJH Created - */ -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -/* DMA is not yet implemented! It should be the same as acorn, copy over.. */ - -#define DMA_S0 0 - -#endif /* _ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-loki/include/mach/dma.h b/arch/arm/mach-loki/include/mach/dma.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/arm/mach-loki/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-mv78xx0/include/mach/dma.h b/arch/arm/mach-mv78xx0/include/mach/dma.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/arm/mach-mv78xx0/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-netx/include/mach/dma.h b/arch/arm/mach-netx/include/mach/dma.h deleted file mode 100644 index c0ac3d98a7b..00000000000 --- a/arch/arm/mach-netx/include/mach/dma.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-netx/include/mach/dma.h - * - * Copyright (C) 2005 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MAX_DMA_CHANNELS 0 diff --git a/arch/arm/mach-ns9xxx/include/mach/dma.h b/arch/arm/mach-ns9xxx/include/mach/dma.h deleted file mode 100644 index 3f50d8c9e5c..00000000000 --- a/arch/arm/mach-ns9xxx/include/mach/dma.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/arm/mach-ns9xxx/include/mach/dma.h - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -#endif /* ifndef __ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-orion5x/include/mach/dma.h b/arch/arm/mach-orion5x/include/mach/dma.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/arm/mach-orion5x/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c index ac2f70eddb9..425f7188505 100644 --- a/arch/arm/mach-pnx4008/dma.c +++ b/arch/arm/mach-pnx4008/dma.c @@ -25,9 +25,8 @@ #include #include -#include +#include #include -#include #include static struct dma_channel { diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c index c0be17e0ab8..b1514fb20d3 100644 --- a/arch/arm/mach-pxa/dma.c +++ b/arch/arm/mach-pxa/dma.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include diff --git a/arch/arm/mach-realview/include/mach/dma.h b/arch/arm/mach-realview/include/mach/dma.h deleted file mode 100644 index f1a5a1a1095..00000000000 --- a/arch/arm/mach-realview/include/mach/dma.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/dma.h - * - * Copyright (C) 2003 ARM Limited. - * Copyright (C) 1997,1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 7d914a470b6..17d4674ecb4 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 7cbea7b82b5..13358ce2128 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -249,7 +249,7 @@ typedef unsigned long dma_device_t; * request a dma channel exclusivley */ -extern int s3c2410_dma_request(dmach_t channel, +extern int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *, void *dev); @@ -258,14 +258,14 @@ extern int s3c2410_dma_request(dmach_t channel, * change the state of the dma channel */ -extern int s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op); +extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); /* s3c2410_dma_setflags * * set the channel's flags to a given state */ -extern int s3c2410_dma_setflags(dmach_t channel, +extern int s3c2410_dma_setflags(unsigned int channel, unsigned int flags); /* s3c2410_dma_free @@ -273,7 +273,7 @@ extern int s3c2410_dma_setflags(dmach_t channel, * free the dma channel (will also abort any outstanding operations) */ -extern int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *); +extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); /* s3c2410_dma_enqueue * @@ -282,7 +282,7 @@ extern int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *); * drained before the buffer is given to the DMA system. */ -extern int s3c2410_dma_enqueue(dmach_t channel, void *id, +extern int s3c2410_dma_enqueue(unsigned int channel, void *id, dma_addr_t data, int size); /* s3c2410_dma_config @@ -290,7 +290,7 @@ extern int s3c2410_dma_enqueue(dmach_t channel, void *id, * configure the dma channel */ -extern int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon); +extern int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon); /* s3c2410_dma_devconfig * @@ -305,11 +305,11 @@ extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, * get the position that the dma transfer is currently at */ -extern int s3c2410_dma_getposition(dmach_t channel, +extern int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dest); -extern int s3c2410_dma_set_opfn(dmach_t, s3c2410_dma_opfn_t rtn); -extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); +extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); +extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); /* DMA Register definitions */ diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index ba0591e71f3..b5e6a35321d 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index 32303f6a832..f33baad69d0 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c2440/dma.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c index f73ccb25ff9..2a685ce22ee 100644 --- a/arch/arm/mach-s3c2443/dma.c +++ b/arch/arm/mach-s3c2443/dma.c @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/collie_pm.c b/arch/arm/mach-sa1100/collie_pm.c index b1161fc8060..947883a483d 100644 --- a/arch/arm/mach-sa1100/collie_pm.c +++ b/arch/arm/mach-sa1100/collie_pm.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c index f990a3e8584..3f445ffd99f 100644 --- a/arch/arm/mach-sa1100/dma.c +++ b/arch/arm/mach-sa1100/dma.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #undef DEBUG diff --git a/arch/arm/mach-versatile/include/mach/dma.h b/arch/arm/mach-versatile/include/mach/dma.h deleted file mode 100644 index 0aabf12c883..00000000000 --- a/arch/arm/mach-versatile/include/mach/dma.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/dma.h - * - * Copyright (C) 2003 ARM Limited. - * Copyright (C) 1997,1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c index b296f19fd89..21427434444 100644 --- a/arch/arm/plat-mxc/dma-mx1-mx2.c +++ b/arch/arm/plat-mxc/dma-mx1-mx2.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #define DMA_DCR 0x00 /* Control Register */ diff --git a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h index e85fd946116..6cc6f0c8cb2 100644 --- a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h +++ b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h @@ -22,7 +22,7 @@ * MA 02110-1301, USA. */ -#include +#include #ifndef __ASM_ARCH_MXC_DMA_H #define __ASM_ARCH_MXC_DMA_H diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h deleted file mode 100644 index c822d569a05..00000000000 --- a/arch/arm/plat-mxc/include/mach/dma.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_MXC_DMA_H__ -#define __ASM_ARCH_MXC_DMA_H__ - -#endif diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 50f8b4ad9a0..7686b9fa53f 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 1baf941d193..63bb22b973e 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -31,9 +31,8 @@ #include #include #include -#include +#include -#include #include #include @@ -804,7 +803,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); * allowed to go through. */ -int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) +int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); unsigned long flags; @@ -995,7 +994,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) } int -s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) +s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); @@ -1043,7 +1042,7 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); * dcon: base value of the DCONx register */ -int s3c2410_dma_config(dmach_t channel, +int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon) { @@ -1092,7 +1091,7 @@ int s3c2410_dma_config(dmach_t channel, EXPORT_SYMBOL(s3c2410_dma_config); -int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) +int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); @@ -1113,7 +1112,7 @@ EXPORT_SYMBOL(s3c2410_dma_setflags); * irq? */ -int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) +int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); @@ -1129,7 +1128,7 @@ int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) EXPORT_SYMBOL(s3c2410_dma_set_opfn); -int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) +int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); @@ -1219,7 +1218,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); * returns the current transfer points for the dma source and destination */ -int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) +int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) { struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index b4ed57e0272..6063dc2b52e 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "mcp.h" diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 28380b20bc7..62b32dabf62 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index 61aeaf79640..86fed4870f9 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include "ucb1x00.h" diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index a316f1b7593..6860c924f36 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include "ucb1x00.h" diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 44762ca86a8..61b7d3eb9a2 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index e9b0159de52..f88cc740635 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -28,9 +28,9 @@ #include #include -#include #include +#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 50b839da140..37424f01ebe 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 22576e0a6d1..37e2cb4f4f8 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -527,7 +527,7 @@ struct smc_local { * as RX which can overrun memory and lose packets. */ #include -#include +#include #include #include diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index cf12f2d84be..6104f461a3c 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -32,8 +32,8 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From ee569c43e340202fb0ba427c57b77568a32b9a3a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 30 Nov 2008 17:38:14 +0000 Subject: [ARM] amba drivers: don't pass a consumer clock name for devices with unique clocks Where devices only have one consumer, passing a consumer clock ID has no real benefit, and it only encourages wrong implementations of the clk API. Remove it. Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 2 +- drivers/serial/amba-pl010.c | 2 +- drivers/serial/amba-pl011.c | 2 +- drivers/video/amba-clcd.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 2fadf323c69..1bcbdd6763a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -500,7 +500,7 @@ static int mmci_probe(struct amba_device *dev, void *id) } host = mmc_priv(mmc); - host->clk = clk_get(&dev->dev, "MCLK"); + host->clk = clk_get(&dev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); host->clk = NULL; diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 71562689116..e3a5ad5ef1d 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -692,7 +692,7 @@ static int pl010_probe(struct amba_device *dev, void *id) goto free; } - uap->clk = clk_get(&dev->dev, "UARTCLK"); + uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk); goto unmap; diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index b7180046f8d..8b2b9700f3e 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -756,7 +756,7 @@ static int pl011_probe(struct amba_device *dev, void *id) goto free; } - uap->clk = clk_get(&dev->dev, "UARTCLK"); + uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk); goto unmap; diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index a7a1c891bfa..c818174b40d 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c @@ -343,7 +343,7 @@ static int clcdfb_register(struct clcd_fb *fb) { int ret; - fb->clk = clk_get(&fb->dev->dev, "CLCDCLK"); + fb->clk = clk_get(&fb->dev->dev, NULL); if (IS_ERR(fb->clk)) { ret = PTR_ERR(fb->clk); goto out; -- cgit v1.2.3-70-g09d2 From d88746652b4d133284d1fdd05b5e999e8f44c998 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 10 Dec 2008 17:37:16 -0800 Subject: omap mmc: Add better MMC low-level init This will simplify the MMC low-level init, and make it more flexible to add support for a newer MMC controller in the following patches. The patch rearranges platform data and gets rid of slot vs controller confusion in the old data structures. Also fix device id numbering in the clock code. Some code snippets are based on an earlier patch by Russell King . Cc: Pierre Ossman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-h2-mmc.c | 63 +++++++- arch/arm/mach-omap1/board-h2.c | 15 ++ arch/arm/mach-omap1/board-h3-mmc.c | 50 ++++++- arch/arm/mach-omap1/board-innovator.c | 50 ++++++- arch/arm/mach-omap1/board-nokia770.c | 74 ++++++++-- arch/arm/mach-omap1/board-sx1-mmc.c | 31 ++-- arch/arm/mach-omap1/clock.h | 3 +- arch/arm/mach-omap1/devices.c | 90 ++++++++++++ arch/arm/mach-omap2/clock24xx.h | 9 +- arch/arm/mach-omap2/clock34xx.h | 10 +- arch/arm/mach-omap2/devices.c | 83 +++++++++++ arch/arm/plat-omap/devices.c | 225 +++++------------------------ arch/arm/plat-omap/include/mach/board-h2.h | 6 +- arch/arm/plat-omap/include/mach/board.h | 22 --- arch/arm/plat-omap/include/mach/mmc.h | 74 +++++++++- drivers/mmc/host/omap.c | 7 +- 16 files changed, 529 insertions(+), 283 deletions(-) (limited to 'drivers/mmc') diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c index 504ae881360..409fa56d0a8 100644 --- a/arch/arm/mach-omap1/board-h2-mmc.c +++ b/arch/arm/mach-omap1/board-h2-mmc.c @@ -12,13 +12,74 @@ * published by the Free Software Foundation. */ +#include + +#include + #include #include +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static int mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + if (power_on) + gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1); + else + gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0); + + return 0; +} + +static int mmc_late_init(struct device *dev) +{ + int ret; + + ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power"); + if (ret < 0) + return ret; + + gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0); + + return ret; +} + +static void mmc_shutdown(struct device *dev) +{ + gpio_free(H2_TPS_GPIO_MMC_PWR_EN); +} + +/* + * H2 could use the following functions tested: + * - mmc_get_cover_state that uses OMAP_MPUIO(1) + * - mmc_get_wp that uses OMAP_MPUIO(3) + */ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots = 1, + .init = mmc_late_init, + .shutdown = mmc_shutdown, + .dma_mask = 0xffffffff, + .slots[0] = { + .set_power = mmc_set_power, + .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | + MMC_VDD_32_33 | MMC_VDD_33_34, + .name = "mmcblk", + }, +}; + +static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; + void __init h2_mmc_init(void) { + mmc_data[0] = &mmc1_data; + omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC); } -void h2_mmc_slot_cover_handler(void *arg, int state) +#else + +void __init h2_mmc_init(void) { } + +#endif diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 125d8e21dce..b240c5f861d 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -345,10 +345,25 @@ static void __init h2_init_smc91x(void) } } +static int tps_setup(struct i2c_client *client, void *context) +{ + tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | + TPS_LDO1_ENABLE | TPS_VLDO1_3_0V); + + return 0; +} + +static struct tps65010_board tps_board = { + .base = H2_TPS_GPIO_BASE, + .outmask = 0x0f, + .setup = tps_setup, +}; + static struct i2c_board_info __initdata h2_i2c_board_info[] = { { I2C_BOARD_INFO("tps65010", 0x48), .irq = OMAP_GPIO_IRQ(58), + .platform_data = &tps_board, }, { I2C_BOARD_INFO("isp1301_omap", 0x2d), .irq = OMAP_GPIO_IRQ(2), diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c index 0baba1c4d12..fdfe793d56f 100644 --- a/arch/arm/mach-omap1/board-h3-mmc.c +++ b/arch/arm/mach-omap1/board-h3-mmc.c @@ -12,13 +12,61 @@ * published by the Free Software Foundation. */ +#include + +#include + #include #include +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static int mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + if (power_on) + gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1); + else + gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0); + + return 0; +} + +/* + * H3 could use the following functions tested: + * - mmc_get_cover_state that uses OMAP_MPUIO(1) + * - mmc_get_wp that maybe uses OMAP_MPUIO(3) + */ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots = 1, + .dma_mask = 0xffffffff, + .slots[0] = { + .set_power = mmc_set_power, + .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | + MMC_VDD_32_33 | MMC_VDD_33_34, + .name = "mmcblk", + }, +}; + +static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; + void __init h3_mmc_init(void) { + int ret; + + ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power"); + if (ret < 0) + return; + gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0); + + mmc_data[0] = &mmc1_data; + omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC); } -void h3_mmc_slot_cover_handler(void *arg, int state) +#else + +void __init h3_mmc_init(void) { } + +#endif diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index a21e365a7a8..8ffb06fc0f0 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -39,6 +39,7 @@ #include #include #include +#include static int innovator_keymap[] = { KEY(0, 0, KEY_F1), @@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = { }; #endif -static struct omap_mmc_config innovator_mmc_config __initdata = { - .mmc [0] = { - .enabled = 1, - .wire4 = 1, - .wp_pin = OMAP_MPUIO(3), - .power_pin = -1, /* FPGA F3 UIO42 */ - .switch_pin = -1, /* FPGA F4 UIO43 */ +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static int mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + if (power_on) + fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), + OMAP1510_FPGA_POWER); + else + fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), + OMAP1510_FPGA_POWER); + + return 0; +} + +/* + * Innovator could use the following functions tested: + * - mmc_get_wp that uses OMAP_MPUIO(3) + * - mmc_get_cover_state that uses FPGA F4 UIO43 + */ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots = 1, + .slots[0] = { + .set_power = mmc_set_power, + .wire4 = 1, + .name = "mmcblk", }, }; +static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; + +void __init innovator_mmc_init(void) +{ + mmc_data[0] = &mmc1_data; + omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC); +} + +#else +static inline void innovator_mmc_init(void) +{ +} +#endif + static struct omap_uart_config innovator_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; @@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = { static struct omap_board_config_kernel innovator_config[] = { { OMAP_TAG_USB, NULL }, { OMAP_TAG_LCD, NULL }, - { OMAP_TAG_MMC, &innovator_mmc_config }, { OMAP_TAG_UART, &innovator_uart_config }, }; @@ -412,6 +445,7 @@ static void __init innovator_init(void) omap_board_config_size = ARRAY_SIZE(innovator_config); omap_serial_init(); omap_register_i2c_bus(1, 100, NULL, 0); + innovator_mmc_init(); } static void __init innovator_map_io(void) diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index b26782471e5..4970c402a59 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -35,6 +35,7 @@ #include #include #include +#include #define ADS7846_PENDOWN_GPIO 15 @@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = { .pins[0] = 6, }; -static struct omap_mmc_config nokia770_mmc_config __initdata = { - .mmc[0] = { - .enabled = 0, - .wire4 = 0, - .wp_pin = -1, - .power_pin = -1, - .switch_pin = -1, - }, - .mmc[1] = { - .enabled = 0, - .wire4 = 0, - .wp_pin = -1, - .power_pin = -1, - .switch_pin = -1, +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +#define NOKIA770_GPIO_MMC_POWER 41 +#define NOKIA770_GPIO_MMC_SWITCH 23 + +static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + if (power_on) + gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1); + else + gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0); + + return 0; +} + +static int nokia770_mmc_get_cover_state(struct device *dev, int slot) +{ + return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH); +} + +static struct omap_mmc_platform_data nokia770_mmc2_data = { + .nr_slots = 1, + .dma_mask = 0xffffffff, + .slots[0] = { + .set_power = nokia770_mmc_set_power, + .get_cover_state = nokia770_mmc_get_cover_state, + .name = "mmcblk", }, }; +static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC]; + +static void __init nokia770_mmc_init(void) +{ + int ret; + + ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power"); + if (ret < 0) + return; + gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0); + + ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover"); + if (ret < 0) { + gpio_free(NOKIA770_GPIO_MMC_POWER); + return; + } + gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH); + + /* Only the second MMC controller is used */ + nokia770_mmc_data[1] = &nokia770_mmc2_data; + omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC); +} + +#else +static inline void nokia770_mmc_init(void) +{ +} +#endif + static struct omap_board_config_kernel nokia770_config[] __initdata = { { OMAP_TAG_USB, NULL }, - { OMAP_TAG_MMC, &nokia770_mmc_config }, }; #if defined(CONFIG_OMAP_DSP) @@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void) omap_dsp_init(); ads7846_dev_init(); mipid_dev_init(); + nokia770_mmc_init(); } static void __init omap_nokia770_map_io(void) diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c index 0ece109aee4..66a4d7d5255 100644 --- a/arch/arm/mach-omap1/board-sx1-mmc.c +++ b/arch/arm/mach-omap1/board-sx1-mmc.c @@ -12,30 +12,20 @@ * published by the Free Software Foundation. */ +#include + #include #include #include -#ifdef CONFIG_MMC_OMAP -static int slot_cover_open; -static struct device *mmc_device; +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) -static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, +static int mmc_set_power(struct device *dev, int slot, int power_on, int vdd) { int err; u8 dat = 0; -#ifdef CONFIG_MMC_DEBUG - dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, - power_on ? "on" : "off", vdd); -#endif - - if (slot != 0) { - dev_err(dev, "No such slot %d\n", slot + 1); - return -ENODEV; - } - err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); if (err < 0) return err; @@ -48,19 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); } -static struct omap_mmc_platform_data sx1_mmc_data = { +/* Cover switch is at OMAP_MPUIO(3) */ +static struct omap_mmc_platform_data mmc1_data = { .nr_slots = 1, .slots[0] = { - .set_power = sx1_mmc_set_power, + .set_power = mmc_set_power, .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | MMC_VDD_32_33 | MMC_VDD_33_34, .name = "mmcblk", }, }; +static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC]; + void __init sx1_mmc_init(void) { - omap_set_mmc_info(1, &sx1_mmc_data); + mmc_data[0] = &mmc1_data; + omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC); } #else @@ -69,7 +63,4 @@ void __init sx1_mmc_init(void) { } -void sx1_mmc_slot_cover_handler(void *arg, int state) -{ -} #endif diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 5635b511ab6..c1dcdf18d8d 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -705,7 +705,6 @@ static struct clk bclk_16xx = { static struct clk mmc1_ck = { .name = "mmc_ck", - .id = 1, /* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate = 48000000, @@ -720,7 +719,7 @@ static struct clk mmc1_ck = { static struct clk mmc2_ck = { .name = "mmc_ck", - .id = 2, + .id = 1, /* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate = 48000000, diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index e382b438c64..024dab13d4b 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -22,6 +22,7 @@ #include #include #include +#include /*-------------------------------------------------------------------------*/ @@ -99,6 +100,95 @@ static inline void omap_init_mbox(void) static inline void omap_init_mbox(void) { } #endif +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller, + int controller_nr) +{ + if (controller_nr == 0) { + omap_cfg_reg(MMC_CMD); + omap_cfg_reg(MMC_CLK); + omap_cfg_reg(MMC_DAT0); + if (cpu_is_omap1710()) { + omap_cfg_reg(M15_1710_MMC_CLKI); + omap_cfg_reg(P19_1710_MMC_CMDDIR); + omap_cfg_reg(P20_1710_MMC_DATDIR0); + } + if (mmc_controller->slots[0].wire4) { + omap_cfg_reg(MMC_DAT1); + /* NOTE: DAT2 can be on W10 (here) or M15 */ + if (!mmc_controller->slots[0].nomux) + omap_cfg_reg(MMC_DAT2); + omap_cfg_reg(MMC_DAT3); + } + } + + /* Block 2 is on newer chips, and has many pinout options */ + if (cpu_is_omap16xx() && controller_nr == 1) { + if (!mmc_controller->slots[1].nomux) { + omap_cfg_reg(Y8_1610_MMC2_CMD); + omap_cfg_reg(Y10_1610_MMC2_CLK); + omap_cfg_reg(R18_1610_MMC2_CLKIN); + omap_cfg_reg(W8_1610_MMC2_DAT0); + if (mmc_controller->slots[1].wire4) { + omap_cfg_reg(V8_1610_MMC2_DAT1); + omap_cfg_reg(W15_1610_MMC2_DAT2); + omap_cfg_reg(R10_1610_MMC2_DAT3); + } + + /* These are needed for the level shifter */ + omap_cfg_reg(V9_1610_MMC2_CMDDIR); + omap_cfg_reg(V5_1610_MMC2_DATDIR0); + omap_cfg_reg(W19_1610_MMC2_DATDIR1); + } + + /* Feedback clock must be set on OMAP-1710 MMC2 */ + if (cpu_is_omap1710()) + omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), + MOD_CONF_CTRL_1); + } +} + +void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers) +{ + int i; + + for (i = 0; i < nr_controllers; i++) { + unsigned long base, size; + unsigned int irq = 0; + + if (!mmc_data[i]) + continue; + + omap1_mmc_mux(mmc_data[i], i); + + switch (i) { + case 0: + base = OMAP1_MMC1_BASE; + irq = INT_MMC; + break; + case 1: + if (!cpu_is_omap16xx()) + return; + base = OMAP1_MMC2_BASE; + irq = INT_1610_MMC2; + break; + default: + continue; + } + size = OMAP1_MMC_SIZE; + + omap_mmc_add(i, base, size, irq, mmc_data[i]); + }; +} + +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_OMAP_STI) #define OMAP1_STI_BASE 0xfffea000 diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 242a19d86cc..ff6cd14d254 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h @@ -2522,7 +2522,6 @@ static struct clk usbhs_ick = { static struct clk mmchs1_ick = { .name = "mmchs_ick", - .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .clkdm_name = "core_l4_clkdm", @@ -2533,7 +2532,6 @@ static struct clk mmchs1_ick = { static struct clk mmchs1_fck = { .name = "mmchs_fck", - .id = 1, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, .clkdm_name = "core_l3_clkdm", @@ -2544,7 +2542,7 @@ static struct clk mmchs1_fck = { static struct clk mmchs2_ick = { .name = "mmchs_ick", - .id = 2, + .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .clkdm_name = "core_l4_clkdm", @@ -2555,7 +2553,7 @@ static struct clk mmchs2_ick = { static struct clk mmchs2_fck = { .name = "mmchs_fck", - .id = 2, + .id = 1, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), @@ -2595,7 +2593,6 @@ static struct clk mdm_intc_ick = { static struct clk mmchsdb1_fck = { .name = "mmchsdb_fck", - .id = 1, .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP243X, .clkdm_name = "core_l4_clkdm", @@ -2606,7 +2603,7 @@ static struct clk mmchsdb1_fck = { static struct clk mmchsdb2_fck = { .name = "mmchsdb_fck", - .id = 2, + .id = 1, .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP243X, .clkdm_name = "core_l4_clkdm", diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 7217a0824ec..a826094d89b 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -1374,7 +1374,7 @@ static struct clk core_96m_fck = { static struct clk mmchs3_fck = { .name = "mmchs_fck", - .id = 3, + .id = 2, .parent = &core_96m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, @@ -1385,7 +1385,7 @@ static struct clk mmchs3_fck = { static struct clk mmchs2_fck = { .name = "mmchs_fck", - .id = 2, + .id = 1, .parent = &core_96m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MMC2_SHIFT, @@ -1406,7 +1406,6 @@ static struct clk mspro_fck = { static struct clk mmchs1_fck = { .name = "mmchs_fck", - .id = 1, .parent = &core_96m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MMC1_SHIFT, @@ -1722,7 +1721,7 @@ static struct clk usbtll_ick = { static struct clk mmchs3_ick = { .name = "mmchs_ick", - .id = 3, + .id = 2, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, @@ -1774,7 +1773,7 @@ static struct clk des2_ick = { static struct clk mmchs2_ick = { .name = "mmchs_ick", - .id = 2, + .id = 1, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC2_SHIFT, @@ -1785,7 +1784,6 @@ static struct clk mmchs2_ick = { static struct clk mmchs1_ick = { .name = "mmchs_ick", - .id = 1, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC1_SHIFT, diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 90af2ac469a..8ccdfcf2942 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -24,6 +24,7 @@ #include #include #include +#include #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) #define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) @@ -295,6 +296,88 @@ static void omap_init_sha1_md5(void) static inline void omap_init_sha1_md5(void) { } #endif +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) + +static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, + int controller_nr) +{ + if (cpu_is_omap2420() && controller_nr == 0) { + omap_cfg_reg(H18_24XX_MMC_CMD); + omap_cfg_reg(H15_24XX_MMC_CLKI); + omap_cfg_reg(G19_24XX_MMC_CLKO); + omap_cfg_reg(F20_24XX_MMC_DAT0); + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); + omap_cfg_reg(G18_24XX_MMC_CMD_DIR); + if (mmc_controller->slots[0].wire4) { + omap_cfg_reg(H14_24XX_MMC_DAT1); + omap_cfg_reg(E19_24XX_MMC_DAT2); + omap_cfg_reg(D19_24XX_MMC_DAT3); + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); + } + + /* + * Use internal loop-back in MMC/SDIO Module Input Clock + * selection + */ + if (mmc_controller->slots[0].internal_clock) { + u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + v |= (1 << 24); + omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); + } + } +} + +void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers) +{ + int i; + + for (i = 0; i < nr_controllers; i++) { + unsigned long base, size; + unsigned int irq = 0; + + if (!mmc_data[i]) + continue; + + omap2_mmc_mux(mmc_data[i], i); + + switch (i) { + case 0: + base = OMAP2_MMC1_BASE; + irq = INT_24XX_MMC_IRQ; + break; + case 1: + base = OMAP2_MMC2_BASE; + irq = INT_24XX_MMC2_IRQ; + break; + case 2: + if (!cpu_is_omap34xx()) + return; + base = OMAP3_MMC3_BASE; + irq = INT_34XX_MMC3_IRQ; + break; + default: + continue; + } + + if (cpu_is_omap2420()) + size = OMAP2420_MMC_SIZE; + else + size = HSMMC_SIZE; + + omap_mmc_add(i, base, size, irq, mmc_data[i]); + }; +} + +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) #define OMAP_HDQ_BASE 0x480B2000 diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 0cb2b22388e..ac15c23fd5d 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -192,202 +192,48 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) -#define OMAP_MMC1_BASE 0x4809c000 -#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc) -#define OMAP_MMC1_INT INT_24XX_MMC_IRQ +#define OMAP_MMC_NR_RES 2 -#define OMAP_MMC2_BASE 0x480b4000 -#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc) -#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ - -#else - -#define OMAP_MMC1_BASE 0xfffb7800 -#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f) -#define OMAP_MMC1_INT INT_MMC - -#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ -#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f) -#define OMAP_MMC2_INT INT_1610_MMC2 - -#endif - -static struct omap_mmc_platform_data mmc1_data; - -static u64 mmc1_dmamask = 0xffffffff; - -static struct resource mmc1_resources[] = { - { - .start = OMAP_MMC1_BASE, - .end = OMAP_MMC1_END, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP_MMC1_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device mmc_omap_device1 = { - .name = "mmci-omap", - .id = 1, - .dev = { - .dma_mask = &mmc1_dmamask, - .platform_data = &mmc1_data, - }, - .num_resources = ARRAY_SIZE(mmc1_resources), - .resource = mmc1_resources, -}; - -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ - defined(CONFIG_ARCH_OMAP34XX) - -static struct omap_mmc_platform_data mmc2_data; - -static u64 mmc2_dmamask = 0xffffffff; - -static struct resource mmc2_resources[] = { - { - .start = OMAP_MMC2_BASE, - .end = OMAP_MMC2_END, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP_MMC2_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device mmc_omap_device2 = { - .name = "mmci-omap", - .id = 2, - .dev = { - .dma_mask = &mmc2_dmamask, - .platform_data = &mmc2_data, - }, - .num_resources = ARRAY_SIZE(mmc2_resources), - .resource = mmc2_resources, -}; -#endif - -static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf) -{ - if (cpu_is_omap2430() || cpu_is_omap34xx()) - return; - - if (mmc_conf->mmc[0].enabled) { - if (cpu_is_omap24xx()) { - omap_cfg_reg(H18_24XX_MMC_CMD); - omap_cfg_reg(H15_24XX_MMC_CLKI); - omap_cfg_reg(G19_24XX_MMC_CLKO); - omap_cfg_reg(F20_24XX_MMC_DAT0); - omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); - omap_cfg_reg(G18_24XX_MMC_CMD_DIR); - } else { - omap_cfg_reg(MMC_CMD); - omap_cfg_reg(MMC_CLK); - omap_cfg_reg(MMC_DAT0); - if (cpu_is_omap1710()) { - omap_cfg_reg(M15_1710_MMC_CLKI); - omap_cfg_reg(P19_1710_MMC_CMDDIR); - omap_cfg_reg(P20_1710_MMC_DATDIR0); - } - } - if (mmc_conf->mmc[0].wire4) { - if (cpu_is_omap24xx()) { - omap_cfg_reg(H14_24XX_MMC_DAT1); - omap_cfg_reg(E19_24XX_MMC_DAT2); - omap_cfg_reg(D19_24XX_MMC_DAT3); - omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); - omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); - omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); - } else { - omap_cfg_reg(MMC_DAT1); - /* NOTE: DAT2 can be on W10 (here) or M15 */ - if (!mmc_conf->mmc[0].nomux) - omap_cfg_reg(MMC_DAT2); - omap_cfg_reg(MMC_DAT3); - } - } - } - -#ifdef CONFIG_ARCH_OMAP16XX - /* block 2 is on newer chips, and has many pinout options */ - if (mmc_conf->mmc[1].enabled) { - if (!mmc_conf->mmc[1].nomux) { - omap_cfg_reg(Y8_1610_MMC2_CMD); - omap_cfg_reg(Y10_1610_MMC2_CLK); - omap_cfg_reg(R18_1610_MMC2_CLKIN); - omap_cfg_reg(W8_1610_MMC2_DAT0); - if (mmc_conf->mmc[1].wire4) { - omap_cfg_reg(V8_1610_MMC2_DAT1); - omap_cfg_reg(W15_1610_MMC2_DAT2); - omap_cfg_reg(R10_1610_MMC2_DAT3); - } - - /* These are needed for the level shifter */ - omap_cfg_reg(V9_1610_MMC2_CMDDIR); - omap_cfg_reg(V5_1610_MMC2_DATDIR0); - omap_cfg_reg(W19_1610_MMC2_DATDIR1); - } - - /* Feedback clock must be set on OMAP-1710 MMC2 */ - if (cpu_is_omap1710()) - omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), - MOD_CONF_CTRL_1); - } -#endif -} - -static void __init omap_init_mmc(void) +/* + * Register MMC devices. Called from mach-omap1 and mach-omap2 device init. + */ +int __init omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data) { - const struct omap_mmc_config *mmc_conf; - - /* NOTE: assumes MMC was never (wrongly) enabled */ - mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); - if (!mmc_conf) - return; - - omap_init_mmc_conf(mmc_conf); - - if (mmc_conf->mmc[0].enabled) { - mmc1_data.conf = mmc_conf->mmc[0]; - (void) platform_device_register(&mmc_omap_device1); - } - -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ - defined(CONFIG_ARCH_OMAP34XX) - if (mmc_conf->mmc[1].enabled) { - mmc2_data.conf = mmc_conf->mmc[1]; - (void) platform_device_register(&mmc_omap_device2); - } -#endif -} + struct platform_device *pdev; + struct resource res[OMAP_MMC_NR_RES]; + int ret; + + pdev = platform_device_alloc("mmci-omap", id); + if (!pdev) + return -ENOMEM; + + memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource)); + res[0].start = base; + res[0].end = base + size - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = res[1].end = irq; + res[1].flags = IORESOURCE_IRQ; + + ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); + if (ret == 0) + ret = platform_device_add_data(pdev, data, sizeof(*data)); + if (ret) + goto fail; + + ret = platform_device_add(pdev); + if (ret) + goto fail; + return 0; -void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) -{ - switch (host) { - case 1: - mmc1_data = *info; - break; -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ - defined(CONFIG_ARCH_OMAP34XX) - case 2: - mmc2_data = *info; - break; -#endif - default: - BUG(); - } +fail: + platform_device_put(pdev); + return ret; } -#else -static inline void omap_init_mmc(void) {} -void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {} #endif /*-------------------------------------------------------------------------*/ @@ -532,7 +378,6 @@ static int __init omap_init_devices(void) */ omap_init_dsp(); omap_init_kp(); - omap_init_mmc(); omap_init_uwire(); omap_init_wdt(); omap_init_rng(); diff --git a/arch/arm/plat-omap/include/mach/board-h2.h b/arch/arm/plat-omap/include/mach/board-h2.h index 2a050e9be65..15531c8dc0e 100644 --- a/arch/arm/plat-omap/include/mach/board-h2.h +++ b/arch/arm/plat-omap/include/mach/board-h2.h @@ -29,13 +29,13 @@ #ifndef __ASM_ARCH_OMAP_H2_H #define __ASM_ARCH_OMAP_H2_H -/* Placeholder for H2 specific defines */ - /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ #define OMAP1610_ETHR_START 0x04000300 +#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) +# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3) + extern void h2_mmc_init(void); -extern void h2_mmc_slot_cover_handler(void *arg, int state); #endif /* __ASM_ARCH_OMAP_H2_H */ diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h index c23c12ccb35..9466772fc7c 100644 --- a/arch/arm/plat-omap/include/mach/board.h +++ b/arch/arm/plat-omap/include/mach/board.h @@ -16,7 +16,6 @@ /* Different peripheral ids */ #define OMAP_TAG_CLOCK 0x4f01 -#define OMAP_TAG_MMC 0x4f02 #define OMAP_TAG_SERIAL_CONSOLE 0x4f03 #define OMAP_TAG_USB 0x4f04 #define OMAP_TAG_LCD 0x4f05 @@ -35,27 +34,6 @@ struct omap_clock_config { u8 system_clock_type; }; -struct omap_mmc_conf { - unsigned enabled:1; - /* nomux means "standard" muxing is wrong on this board, and that - * board-specific code handled it before common init logic. - */ - unsigned nomux:1; - /* switch pin can be for card detect (default) or card cover */ - unsigned cover:1; - /* 4 wire signaling is optional, and is only used for SD/SDIO */ - unsigned wire4:1; - /* use the internal clock */ - unsigned internal_clock:1; - s16 power_pin; - s16 switch_pin; - s16 wp_pin; -}; - -struct omap_mmc_config { - struct omap_mmc_conf mmc[2]; -}; - struct omap_serial_console_config { u8 console_uart; u32 console_speed; diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index fc15d13058f..0c2ef3b8956 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h @@ -17,12 +17,28 @@ #include +#define OMAP15XX_NR_MMC 1 +#define OMAP16XX_NR_MMC 2 +#define OMAP1_MMC_SIZE 0x080 +#define OMAP1_MMC1_BASE 0xfffb7800 +#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */ + +#define OMAP24XX_NR_MMC 2 +#define OMAP34XX_NR_MMC 3 +#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE +#define HSMMC_SIZE 0x200 +#define OMAP2_MMC1_BASE 0x4809c000 +#define OMAP2_MMC2_BASE 0x480b4000 +#define OMAP3_MMC3_BASE 0x480ad000 +#define HSMMC3 (1 << 2) +#define HSMMC2 (1 << 1) +#define HSMMC1 (1 << 0) + #define OMAP_MMC_MAX_SLOTS 2 struct omap_mmc_platform_data { - struct omap_mmc_conf conf; - /* number of slots on board */ + /* number of slots per controller */ unsigned nr_slots:2; /* set if your board has components or wiring that limits the @@ -41,7 +57,27 @@ struct omap_mmc_platform_data { int (*suspend)(struct device *dev, int slot); int (*resume)(struct device *dev, int slot); + u64 dma_mask; + struct omap_mmc_slot_data { + + /* + * nomux means "standard" muxing is wrong on this board, and + * that board-specific code handled it before common init logic. + */ + unsigned nomux:1; + + /* switch pin can be for card detect (default) or card cover */ + unsigned cover:1; + + /* 4 wire signaling is optional, and is only used for SD/SDIO */ + unsigned wire4:1; + + /* use the internal clock */ + unsigned internal_clock:1; + s16 power_pin; + s16 switch_pin; + int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); int (* set_power)(struct device *dev, int slot, int power_on, int vdd); int (* get_ro)(struct device *dev, int slot); @@ -49,8 +85,8 @@ struct omap_mmc_platform_data { /* return MMC cover switch state, can be NULL if not supported. * * possible return values: - * 0 - open - * 1 - closed + * 0 - closed + * 1 - open */ int (* get_cover_state)(struct device *dev, int slot); @@ -66,9 +102,35 @@ struct omap_mmc_platform_data { } slots[OMAP_MMC_MAX_SLOTS]; }; -extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info); - /* called from board-specific card detection service routine */ extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) +void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers); +void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers); +void hsmmc_init(int controller_mask); +int omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data); +#else +static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers) +{ +} +static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers) +{ +} +static inline void hsmmc_init(int controller_mask) +{ +} +static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, + unsigned int irq, struct omap_mmc_platform_data *data) +{ + return 0; +} + +#endif #endif diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 1b9fc3c6b87..c6544d2d072 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1015,7 +1015,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data } if (is_read) { - if (host->id == 1) { + if (host->id == 0) { sync_dev = OMAP_DMA_MMC_RX; dma_dev_name = "MMC1 read"; } else { @@ -1023,7 +1023,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data dma_dev_name = "MMC2 read"; } } else { - if (host->id == 1) { + if (host->id == 0) { sync_dev = OMAP_DMA_MMC_TX; dma_dev_name = "MMC1 write"; } else { @@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) host->slots[id] = slot; mmc->caps = 0; - if (host->pdata->conf.wire4) + if (host->pdata->slots[id].wire4) mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->ops = &mmc_omap_ops; @@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev) host->irq = irq; host->use_dma = 1; + host->dev->dma_mask = &pdata->dma_mask; host->dma_ch = -1; host->irq = irq; -- cgit v1.2.3-70-g09d2 From 90c62bf08f5823faa097271f3346a9142769b9ac Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 10 Dec 2008 17:37:17 -0800 Subject: omap mmc: Add low-level initialization for hsmmc controller Add low-level initialization for hsmmc controller. Merged into this patch patch are various improvments and board support by Grazvydas Ignotas and David Brownell. Also change wire4 to be wires, as some newer controllers support 8 data lines. Cc: Pierre Ossman Signed-off-by: Grazvydas Ignotas Signed-off-by: David Brownell Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/devices.c | 4 +- arch/arm/mach-omap2/Makefile | 15 +- arch/arm/mach-omap2/board-2430sdp.c | 48 ++++ arch/arm/mach-omap2/board-ldp.c | 40 ++- arch/arm/mach-omap2/board-omap3beagle.c | 90 +++++++ arch/arm/mach-omap2/board-omap3pandora.c | 32 +++ arch/arm/mach-omap2/board-overo.c | 43 ++++ arch/arm/mach-omap2/devices.c | 3 +- arch/arm/mach-omap2/mmc-twl4030.c | 408 ++++++++++++++++++++++++++++++ arch/arm/mach-omap2/mmc-twl4030.h | 29 +++ arch/arm/plat-omap/include/mach/control.h | 17 ++ arch/arm/plat-omap/include/mach/mmc.h | 16 +- drivers/mmc/host/omap.c | 2 +- 14 files changed, 730 insertions(+), 19 deletions(-) create mode 100644 arch/arm/mach-omap2/mmc-twl4030.c create mode 100644 arch/arm/mach-omap2/mmc-twl4030.h (limited to 'drivers/mmc') diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 8ffb06fc0f0..af2fb907008 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -385,7 +385,7 @@ static struct omap_mmc_platform_data mmc1_data = { .nr_slots = 1, .slots[0] = { .set_power = mmc_set_power, - .wire4 = 1, + .wires = 4, .name = "mmcblk", }, }; diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 024dab13d4b..77382d8b6b2 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -116,7 +116,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_cfg_reg(P19_1710_MMC_CMDDIR); omap_cfg_reg(P20_1710_MMC_DATDIR0); } - if (mmc_controller->slots[0].wire4) { + if (mmc_controller->slots[0].wires == 4) { omap_cfg_reg(MMC_DAT1); /* NOTE: DAT2 can be on W10 (here) or M15 */ if (!mmc_controller->slots[0].nomux) @@ -132,7 +132,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_cfg_reg(Y10_1610_MMC2_CLK); omap_cfg_reg(R18_1610_MMC2_CLKIN); omap_cfg_reg(W8_1610_MMC2_DAT0); - if (mmc_controller->slots[1].wire4) { + if (mmc_controller->slots[1].wires == 4) { omap_cfg_reg(V8_1610_MMC2_DAT1); omap_cfg_reg(W15_1610_MMC2_DAT2); omap_cfg_reg(R10_1610_MMC2_DAT3); diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f12c43e4932..bbd12bc10fd 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -27,10 +27,15 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o +obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ + mmc-twl4030.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o -obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o -obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o -obj-$(CONFIG_MACH_OVERO) += board-overo.o -obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o +obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OVERO) += board-overo.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ + mmc-twl4030.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 6748de6e19a..83fa37211d7 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include +#include "mmc-twl4030.h" #define SDP2430_FLASH_CS 0 #define SDP2430_SMC91X_CS 5 @@ -197,12 +199,58 @@ static struct omap_board_config_kernel sdp2430_config[] = { {OMAP_TAG_UART, &sdp2430_uart_config}, }; + +static struct twl4030_gpio_platform_data sdp2430_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, +}; + +static struct twl4030_platform_data sdp2430_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .gpio = &sdp2430_gpio_data, +}; + +static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_24XX_SYS_NIRQ, + .platform_data = &sdp2430_twldata, + }, +}; + +static int __init omap2430_i2c_init(void) +{ + omap_register_i2c_bus(1, 400, NULL, 0); + omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo, + ARRAY_SIZE(sdp2430_i2c_boardinfo)); + return 0; +} + +static struct twl4030_hsmmc_info mmc[] __initdata = { + { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .ext_clock = 1, + }, + {} /* Terminator */ +}; + static void __init omap_2430sdp_init(void) { + omap2430_i2c_init(); + platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); omap_board_config = sdp2430_config; omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap_serial_init(); + twl4030_mmc_init(mmc); } static void __init omap_2430sdp_map_io(void) diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 43c7ac4b7f8..aa6972781e4 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,8 @@ #include #include +#include "mmc-twl4030.h" + #define SDP3430_SMC91X_CS 3 static struct resource ldp_smc911x_resources[] = { @@ -109,14 +112,48 @@ static struct omap_board_config_kernel ldp_config[] __initdata = { { OMAP_TAG_UART, &ldp_uart_config }, }; +static struct twl4030_gpio_platform_data ldp_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, +}; + +static struct twl4030_platform_data ldp_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .gpio = &ldp_gpio_data, +}; + +static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &ldp_twldata, + }, +}; + static int __init omap_i2c_init(void) { - omap_register_i2c_bus(1, 2600, NULL, 0); + omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo, + ARRAY_SIZE(ldp_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); return 0; } +static struct twl4030_hsmmc_info mmc[] __initdata = { + { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + {} /* Terminator */ +}; + static void __init omap_ldp_init(void) { omap_i2c_init(); @@ -124,6 +161,7 @@ static void __init omap_ldp_init(void) omap_board_config = ldp_config; omap_board_config_size = ARRAY_SIZE(ldp_config); omap_serial_init(); + twl4030_mmc_init(mmc); } static void __init omap_ldp_map_io(void) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index baa79674e9d..9e5ada01b5f 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -38,7 +38,9 @@ #include #include #include +#include +#include "mmc-twl4030.h" #define GPMC_CS0_BASE 0x60 #define GPMC_CS_SIZE 0x30 @@ -103,6 +105,78 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; +static struct twl4030_hsmmc_info mmc[] = { + { + .mmc = 1, + .wires = 8, + .gpio_wp = 29, + }, + {} /* Terminator */ +}; + +static struct gpio_led gpio_leds[]; + +static int beagle_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + + gpio_request(gpio + 1, "EHCI_nOC"); + gpio_direction_input(gpio + 1); + + /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ + gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + + return 0; +} + +static struct twl4030_gpio_platform_data beagle_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .pullups = BIT(1), + .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) + | BIT(15) | BIT(16) | BIT(17), + .setup = beagle_twl_gpio_setup, +}; + +static struct twl4030_platform_data beagle_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .gpio = &beagle_gpio_data, +}; + +static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &beagle_twldata, + }, +}; + +static int __init omap3_beagle_i2c_init(void) +{ + omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, + ARRAY_SIZE(beagle_i2c_boardinfo)); +#ifdef CONFIG_I2C2_OMAP_BEAGLE + omap_register_i2c_bus(2, 400, NULL, 0); +#endif + omap_register_i2c_bus(3, 400, NULL, 0); + return 0; +} + static void __init omap3_beagle_init_irq(void) { omap2_init_common_hw(); @@ -130,6 +204,11 @@ static struct gpio_led gpio_leds[] = { .default_trigger = "mmc0", .gpio = 149, }, + { + .name = "beagleboard::pmu_stat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + }, }; static struct gpio_led_platform_data gpio_led_info = { @@ -218,11 +297,22 @@ static void __init omap3beagle_flash_init(void) static void __init omap3_beagle_init(void) { + omap3_beagle_i2c_init(); platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); omap_board_config = omap3_beagle_config; omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); omap_serial_init(); + + omap_cfg_reg(AH8_34XX_GPIO29); + mmc[0].gpio_cd = gpio + 0; + twl4030_mmc_init(mmc); + + omap_cfg_reg(J25_34XX_GPIO170); + gpio_request(170, "DVI_nPD"); + /* REVISIT leave DVI powered down until it's needed ... */ + gpio_direction_output(170, true); + omap3beagle_flash_init(); } diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 7236c7be05b..b3196107afd 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -35,16 +35,48 @@ #include #include +#include "mmc-twl4030.h" + #define OMAP3_PANDORA_TS_GPIO 94 +static struct twl4030_hsmmc_info omap3pandora_mmc[] = { + { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = 126, + .ext_clock = 0, + }, + { + .mmc = 2, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = 127, + .ext_clock = 1, + }, + {} /* Terminator */ +}; + static struct omap_uart_config omap3pandora_uart_config __initdata = { .enabled_uarts = (1 << 2), /* UART3 */ }; +static int omap3pandora_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ + omap3pandora_mmc[0].gpio_cd = gpio + 0; + omap3pandora_mmc[1].gpio_cd = gpio + 1; + twl4030_mmc_init(omap3pandora_mmc); + + return 0; +} + static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, + .setup = omap3pandora_twl_gpio_setup, }; static struct twl4030_usb_data omap3pandora_usb_data = { diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index e09aa59a399..82b3dc557c9 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,8 @@ #include #include +#include "mmc-twl4030.h" + #define NAND_BLOCK_SIZE SZ_128K #define GPMC_CS0_BASE 0x60 #define GPMC_CS_SIZE 0x30 @@ -139,8 +142,31 @@ static struct omap_uart_config overo_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; +static struct twl4030_gpio_platform_data overo_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, +}; + +static struct twl4030_platform_data overo_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + .gpio = &overo_gpio_data, +}; + +static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &overo_twldata, + }, +}; + static int __init overo_i2c_init(void) { + omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo, + ARRAY_SIZE(overo_i2c_boardinfo)); /* i2c2 pins are used for gpio */ omap_register_i2c_bus(3, 400, NULL, 0); return 0; @@ -171,6 +197,22 @@ static struct platform_device *overo_devices[] __initdata = { &overo_lcd_device, }; +static struct twl4030_hsmmc_info mmc[] __initdata = { + { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + { + .mmc = 2, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + {} /* Terminator */ +}; + static void __init overo_init(void) { overo_i2c_init(); @@ -178,6 +220,7 @@ static void __init overo_init(void) omap_board_config = overo_config; omap_board_config_size = ARRAY_SIZE(overo_config); omap_serial_init(); + twl4030_mmc_init(mmc); overo_flash_init(); if ((gpio_request(OVERO_GPIO_W2W_NRESET, diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 8ccdfcf2942..6e03272b052 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -311,7 +312,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_cfg_reg(F20_24XX_MMC_DAT0); omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); omap_cfg_reg(G18_24XX_MMC_CMD_DIR); - if (mmc_controller->slots[0].wire4) { + if (mmc_controller->slots[0].wires == 4) { omap_cfg_reg(H14_24XX_MMC_DAT1); omap_cfg_reg(E19_24XX_MMC_DAT2); omap_cfg_reg(D19_24XX_MMC_DAT3); diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c new file mode 100644 index 00000000000..437f52073f6 --- /dev/null +++ b/arch/arm/mach-omap2/mmc-twl4030.c @@ -0,0 +1,408 @@ +/* + * linux/arch/arm/mach-omap2/mmc-twl4030.c + * + * Copyright (C) 2007-2008 Texas Instruments + * Copyright (C) 2008 Nokia Corporation + * Author: Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "mmc-twl4030.h" + +#if defined(CONFIG_TWL4030_CORE) && \ + (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) + +#define LDO_CLR 0x00 +#define VSEL_S2_CLR 0x40 + +#define VMMC1_DEV_GRP 0x27 +#define VMMC1_CLR 0x00 +#define VMMC1_315V 0x03 +#define VMMC1_300V 0x02 +#define VMMC1_285V 0x01 +#define VMMC1_185V 0x00 +#define VMMC1_DEDICATED 0x2A + +#define VMMC2_DEV_GRP 0x2B +#define VMMC2_CLR 0x40 +#define VMMC2_315V 0x0c +#define VMMC2_300V 0x0b +#define VMMC2_285V 0x0a +#define VMMC2_260V 0x08 +#define VMMC2_185V 0x06 +#define VMMC2_DEDICATED 0x2E + +#define VMMC_DEV_GRP_P1 0x20 + +static u16 control_pbias_offset; +static u16 control_devconf1_offset; + +#define HSMMC_NAME_LEN 9 + +static struct twl_mmc_controller { + struct omap_mmc_platform_data *mmc; + u8 twl_vmmc_dev_grp; + u8 twl_mmc_dedicated; + char name[HSMMC_NAME_LEN]; +} hsmmc[] = { + { + .twl_vmmc_dev_grp = VMMC1_DEV_GRP, + .twl_mmc_dedicated = VMMC1_DEDICATED, + }, + { + .twl_vmmc_dev_grp = VMMC2_DEV_GRP, + .twl_mmc_dedicated = VMMC2_DEDICATED, + }, +}; + +static int twl_mmc_card_detect(int irq) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { + struct omap_mmc_platform_data *mmc; + + mmc = hsmmc[i].mmc; + if (!mmc) + continue; + if (irq != mmc->slots[0].card_detect_irq) + continue; + + /* NOTE: assumes card detect signal is active-low */ + return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); + } + return -ENOSYS; +} + +static int twl_mmc_get_ro(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + /* NOTE: assumes write protect signal is active-high */ + return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); +} + +/* + * MMC Slot Initialization. + */ +static int twl_mmc_late_init(struct device *dev) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + int ret = 0; + int i; + + ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); + if (ret) + goto done; + ret = gpio_direction_input(mmc->slots[0].switch_pin); + if (ret) + goto err; + + for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { + if (hsmmc[i].name == mmc->slots[0].name) { + hsmmc[i].mmc = mmc; + break; + } + } + + return 0; + +err: + gpio_free(mmc->slots[0].switch_pin); +done: + mmc->slots[0].card_detect_irq = 0; + mmc->slots[0].card_detect = NULL; + + dev_err(dev, "err %d configuring card detect\n", ret); + return ret; +} + +static void twl_mmc_cleanup(struct device *dev) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + gpio_free(mmc->slots[0].switch_pin); +} + +#ifdef CONFIG_PM + +static int twl_mmc_suspend(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + disable_irq(mmc->slots[0].card_detect_irq); + return 0; +} + +static int twl_mmc_resume(struct device *dev, int slot) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + enable_irq(mmc->slots[0].card_detect_irq); + return 0; +} + +#else +#define twl_mmc_suspend NULL +#define twl_mmc_resume NULL +#endif + +/* + * Sets the MMC voltage in twl4030 + */ +static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd) +{ + int ret; + u8 vmmc, dev_grp_val; + + switch (1 << vdd) { + case MMC_VDD_35_36: + case MMC_VDD_34_35: + case MMC_VDD_33_34: + case MMC_VDD_32_33: + case MMC_VDD_31_32: + case MMC_VDD_30_31: + if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) + vmmc = VMMC1_315V; + else + vmmc = VMMC2_315V; + break; + case MMC_VDD_29_30: + if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) + vmmc = VMMC1_315V; + else + vmmc = VMMC2_300V; + break; + case MMC_VDD_27_28: + case MMC_VDD_26_27: + if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) + vmmc = VMMC1_285V; + else + vmmc = VMMC2_285V; + break; + case MMC_VDD_25_26: + case MMC_VDD_24_25: + case MMC_VDD_23_24: + case MMC_VDD_22_23: + case MMC_VDD_21_22: + case MMC_VDD_20_21: + if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) + vmmc = VMMC1_285V; + else + vmmc = VMMC2_260V; + break; + case MMC_VDD_165_195: + if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) + vmmc = VMMC1_185V; + else + vmmc = VMMC2_185V; + break; + default: + vmmc = 0; + break; + } + + if (vmmc) + dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */ + else + dev_grp_val = LDO_CLR; /* Power down */ + + ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, + dev_grp_val, c->twl_vmmc_dev_grp); + if (ret) + return ret; + + ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, + vmmc, c->twl_mmc_dedicated); + + return ret; +} + +static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + u32 reg; + int ret = 0; + struct twl_mmc_controller *c = &hsmmc[0]; + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (power_on) { + if (cpu_is_omap2430()) { + reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); + if ((1 << vdd) >= MMC_VDD_30_31) + reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; + else + reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; + omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); + } + + if (mmc->slots[0].internal_clock) { + reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + reg |= OMAP2_MMCSDIO1ADPCLKISEL; + omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); + } + + reg = omap_ctrl_readl(control_pbias_offset); + reg |= OMAP2_PBIASSPEEDCTRL0; + reg &= ~OMAP2_PBIASLITEPWRDNZ0; + omap_ctrl_writel(reg, control_pbias_offset); + + ret = twl_mmc_set_voltage(c, vdd); + + /* 100ms delay required for PBIAS configuration */ + msleep(100); + reg = omap_ctrl_readl(control_pbias_offset); + reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); + if ((1 << vdd) <= MMC_VDD_165_195) + reg &= ~OMAP2_PBIASLITEVMODE0; + else + reg |= OMAP2_PBIASLITEVMODE0; + omap_ctrl_writel(reg, control_pbias_offset); + } else { + reg = omap_ctrl_readl(control_pbias_offset); + reg &= ~OMAP2_PBIASLITEPWRDNZ0; + omap_ctrl_writel(reg, control_pbias_offset); + + ret = twl_mmc_set_voltage(c, 0); + + /* 100ms delay required for PBIAS configuration */ + msleep(100); + reg = omap_ctrl_readl(control_pbias_offset); + reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | + OMAP2_PBIASLITEVMODE0); + omap_ctrl_writel(reg, control_pbias_offset); + } + + return ret; +} + +static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd) +{ + int ret; + struct twl_mmc_controller *c = &hsmmc[1]; + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (power_on) { + if (mmc->slots[0].internal_clock) { + u32 reg; + + reg = omap_ctrl_readl(control_devconf1_offset); + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, control_devconf1_offset); + } + ret = twl_mmc_set_voltage(c, vdd); + } else { + ret = twl_mmc_set_voltage(c, 0); + } + + return ret; +} + +static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; + +void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) +{ + struct twl4030_hsmmc_info *c; + int nr_hsmmc = ARRAY_SIZE(hsmmc_data); + + if (cpu_is_omap2430()) { + control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; + nr_hsmmc = 2; + } else { + control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; + } + + for (c = controllers; c->mmc; c++) { + struct twl_mmc_controller *twl = hsmmc + c->mmc - 1; + struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; + + if (!c->mmc || c->mmc > nr_hsmmc) { + pr_debug("MMC%d: no such controller\n", c->mmc); + continue; + } + if (mmc) { + pr_debug("MMC%d: already configured\n", c->mmc); + continue; + } + + mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); + if (!mmc) { + pr_err("Cannot allocate memory for mmc device!\n"); + return; + } + + sprintf(twl->name, "mmc%islot%i", c->mmc, 1); + mmc->slots[0].name = twl->name; + mmc->nr_slots = 1; + mmc->slots[0].ocr_mask = MMC_VDD_165_195 | + MMC_VDD_26_27 | MMC_VDD_27_28 | + MMC_VDD_29_30 | + MMC_VDD_30_31 | MMC_VDD_31_32; + mmc->slots[0].wires = c->wires; + mmc->slots[0].internal_clock = !c->ext_clock; + mmc->dma_mask = 0xffffffff; + + /* note: twl4030 card detect GPIOs normally switch VMMCx ... */ + if (gpio_is_valid(c->gpio_cd)) { + mmc->init = twl_mmc_late_init; + mmc->cleanup = twl_mmc_cleanup; + mmc->suspend = twl_mmc_suspend; + mmc->resume = twl_mmc_resume; + + mmc->slots[0].switch_pin = c->gpio_cd; + mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); + mmc->slots[0].card_detect = twl_mmc_card_detect; + } else + mmc->slots[0].switch_pin = -EINVAL; + + /* write protect normally uses an OMAP gpio */ + if (gpio_is_valid(c->gpio_wp)) { + gpio_request(c->gpio_wp, "mmc_wp"); + gpio_direction_input(c->gpio_wp); + + mmc->slots[0].gpio_wp = c->gpio_wp; + mmc->slots[0].get_ro = twl_mmc_get_ro; + } else + mmc->slots[0].gpio_wp = -EINVAL; + + /* NOTE: we assume OMAP's MMC1 and MMC2 use + * the TWL4030's VMMC1 and VMMC2, respectively; + * and that OMAP's MMC3 isn't used. + */ + + switch (c->mmc) { + case 1: + mmc->slots[0].set_power = twl_mmc1_set_power; + break; + case 2: + mmc->slots[0].set_power = twl_mmc2_set_power; + break; + default: + pr_err("MMC%d configuration not supported!\n", c->mmc); + continue; + } + hsmmc_data[c->mmc - 1] = mmc; + } + + omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); +} + +#endif diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h new file mode 100644 index 00000000000..e1c8076400c --- /dev/null +++ b/arch/arm/mach-omap2/mmc-twl4030.h @@ -0,0 +1,29 @@ +/* + * MMC definitions for OMAP2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +struct twl4030_hsmmc_info { + u8 mmc; /* controller 1/2/3 */ + u8 wires; /* 1/4/8 wires */ + int gpio_cd; /* or -EINVAL */ + int gpio_wp; /* or -EINVAL */ + int ext_clock:1; /* use external pin for input clock */ +}; + +#if defined(CONFIG_TWL4030_CORE) && \ + (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ + defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) + +void twl4030_mmc_init(struct twl4030_hsmmc_info *); + +#else + +static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info) +{ +} + +#endif diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h index dc988676057..269147f3836 100644 --- a/arch/arm/plat-omap/include/mach/control.h +++ b/arch/arm/plat-omap/include/mach/control.h @@ -74,6 +74,7 @@ #define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) #define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) +#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230) /* 24xx-only CONTROL_GENERAL register offsets */ #define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000) @@ -140,6 +141,7 @@ #define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0) #define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) /* @@ -154,11 +156,14 @@ * and the security mode (secure, non-secure, don't care) */ /* CONTROL_DEVCONF0 bits */ +#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */ #define OMAP24XX_USBSTANDBYCTRL (1 << 15) #define OMAP2_MCBSP2_CLKS_MASK (1 << 6) #define OMAP2_MCBSP1_CLKS_MASK (1 << 2) /* CONTROL_DEVCONF1 bits */ +#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31) +#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */ #define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */ #define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */ #define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */ @@ -172,6 +177,18 @@ #define OMAP2_SYSBOOT_1_MASK (1 << 1) #define OMAP2_SYSBOOT_0_MASK (1 << 0) +/* CONTROL_PBIAS_LITE bits */ +#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15) +#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11) +#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10) +#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9) +#define OMAP343X_PBIASLITEVMODE1 (1 << 8) +#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7) +#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3) +#define OMAP2_PBIASSPEEDCTRL0 (1 << 2) +#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) +#define OMAP2_PBIASLITEVMODE0 (1 << 0) + #ifndef __ASSEMBLY__ #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) extern void __iomem *omap_ctrl_base_get(void); diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index 0c2ef3b8956..031250f0280 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h @@ -61,6 +61,11 @@ struct omap_mmc_platform_data { struct omap_mmc_slot_data { + /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC; + * 8 wire signaling is also optional, and is used with HSMMC + */ + u8 wires; + /* * nomux means "standard" muxing is wrong on this board, and * that board-specific code handled it before common init logic. @@ -70,13 +75,12 @@ struct omap_mmc_platform_data { /* switch pin can be for card detect (default) or card cover */ unsigned cover:1; - /* 4 wire signaling is optional, and is only used for SD/SDIO */ - unsigned wire4:1; - /* use the internal clock */ unsigned internal_clock:1; s16 power_pin; - s16 switch_pin; + + int switch_pin; /* gpio (card detect) */ + int gpio_wp; /* gpio (write protect) */ int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); int (* set_power)(struct device *dev, int slot, int power_on, int vdd); @@ -111,7 +115,6 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers); -void hsmmc_init(int controller_mask); int omap_mmc_add(int id, unsigned long base, unsigned long size, unsigned int irq, struct omap_mmc_platform_data *data); #else @@ -123,9 +126,6 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) { } -static inline void hsmmc_init(int controller_mask) -{ -} static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, unsigned int irq, struct omap_mmc_platform_data *data) { diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index c6544d2d072..67d7b7fef08 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) host->slots[id] = slot; mmc->caps = 0; - if (host->pdata->slots[id].wire4) + if (host->pdata->slots[id].wires >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->ops = &mmc_omap_ops; -- cgit v1.2.3-70-g09d2 From 4b7c0e4cae35b49380ad69e668324d4d70b7fd4c Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 10 Oct 2008 12:05:03 +0200 Subject: imxmmc: Checkpatch cleanup This cleans up the warnings issued by the checkpatch script and remove the file history from the header Signed-off-by: Marc Kleine-Budde Signed-off-by: Sascha Hauer --- drivers/mmc/host/imxmmc.c | 301 ++++++++++++++++++++++------------------------ 1 file changed, 141 insertions(+), 160 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 2f0fcdb869b..02e9dd3e22d 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -10,20 +10,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * 2005-04-17 Pavel Pisa - * Changed to conform redesigned i.MX scatter gather DMA interface - * - * 2005-11-04 Pavel Pisa - * Updated for 2.6.14 kernel - * - * 2005-12-13 Jay Monkman - * Found and corrected problems in the write path - * - * 2005-12-30 Pavel Pisa - * The event handling rewritten right way in softirq. - * Added many ugly hacks and delays to overcome SDHC - * deficiencies - * */ #include @@ -37,9 +23,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -50,8 +36,8 @@ #define DRIVER_NAME "imx-mmc" #define IMXMCI_INT_MASK_DEFAULT (INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | \ - INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \ - INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO) + INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \ + INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO) struct imxmci_host { struct mmc_host *mmc; @@ -74,7 +60,7 @@ struct imxmci_host { struct tasklet_struct tasklet; unsigned int status_reg; unsigned long pending_events; - /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */ + /* Next two fields are there for CPU driven transfers to overcome SDHC deficiencies */ u16 *data_ptr; unsigned int data_cnt; atomic_t stuck_timeout; @@ -115,13 +101,13 @@ static void imxmci_stop_clock(struct imxmci_host *host) { int i = 0; MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK; - while(i < 0x1000) { - if(!(i & 0x7f)) + while (i < 0x1000) { + if (!(i & 0x7f)) MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK; - if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) { + if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) { /* Check twice before cut */ - if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) + if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) return; } @@ -150,13 +136,13 @@ static int imxmci_start_clock(struct imxmci_host *host) do { unsigned int delay = delay_limit; - while(delay--){ - if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) + while (delay--) { + if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) /* Check twice before cut */ - if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) + if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) return 0; - if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) + if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) return 0; } @@ -167,11 +153,11 @@ static int imxmci_start_clock(struct imxmci_host *host) * IRQ or schedule delays this function execution and the clocks has * been already stopped by other means (response processing, SDHC HW) */ - if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) + if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; local_irq_restore(flags); - } while(++trials<256); + } while (++trials < 256); dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); @@ -198,13 +184,14 @@ static void imxmci_softreset(void) } static int imxmci_busy_wait_for_status(struct imxmci_host *host, - unsigned int *pstat, unsigned int stat_mask, - int timeout, const char *where) + unsigned int *pstat, unsigned int stat_mask, + int timeout, const char *where) { - int loops=0; - while(!(*pstat & stat_mask)) { - loops+=2; - if(loops >= timeout) { + int loops = 0; + + while (!(*pstat & stat_mask)) { + loops += 2; + if (loops >= timeout) { dev_dbg(mmc_dev(host->mmc), "busy wait timeout in %s, STATUS = 0x%x (0x%x)\n", where, *pstat, stat_mask); return -1; @@ -212,13 +199,13 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, udelay(2); *pstat |= MMC_STATUS; } - if(!loops) + if (!loops) return 0; /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */ - if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000)) + if (!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock >= 8000000)) dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", - loops, where, *pstat, stat_mask); + loops, where, *pstat, stat_mask); return loops; } @@ -259,7 +246,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) } /* Convert back to virtual address */ - host->data_ptr = (u16*)sg_virt(data->sg); + host->data_ptr = (u16 *)sg_virt(data->sg); host->data_cnt = 0; clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events); @@ -271,10 +258,10 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) { host->dma_dir = DMA_FROM_DEVICE; host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, host->dma_dir); + data->sg_len, host->dma_dir); imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ); + host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ); /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/ CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN; @@ -282,10 +269,10 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) host->dma_dir = DMA_TO_DEVICE; host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, host->dma_dir); + data->sg_len, host->dma_dir); imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE); + host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE); /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/ CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN; @@ -293,12 +280,12 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) #if 1 /* This code is there only for consistency checking and can be disabled in future */ host->dma_size = 0; - for(i=0; idma_nents; i++) - host->dma_size+=data->sg[i].length; + for (i = 0; i < host->dma_nents; i++) + host->dma_size += data->sg[i].length; if (datasz > host->dma_size) { dev_err(mmc_dev(host->mmc), "imxmci_setup_data datasz 0x%x > 0x%x dm_size\n", - datasz, host->dma_size); + datasz, host->dma_size); } #endif @@ -306,7 +293,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) wmb(); - if(host->actual_bus_width == MMC_BUS_WIDTH_4) + if (host->actual_bus_width == MMC_BUS_WIDTH_4) BLR(host->dma) = 0; /* burst 64 byte read / 64 bytes write */ else BLR(host->dma) = 16; /* burst 16 byte read / 16 bytes write */ @@ -317,9 +304,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events); /* start DMA engine for read, write is delayed after initial response */ - if (host->dma_dir == DMA_FROM_DEVICE) { + if (host->dma_dir == DMA_FROM_DEVICE) imx_dma_enable(host->dma); - } } static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat) @@ -351,10 +337,10 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, break; } - if ( test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events) ) + if (test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events)) cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */ - if ( host->actual_bus_width == MMC_BUS_WIDTH_4 ) + if (host->actual_bus_width == MMC_BUS_WIDTH_4) cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; MMC_CMD = cmd->opcode; @@ -368,12 +354,12 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, imask = IMXMCI_INT_MASK_DEFAULT; imask &= ~INT_MASK_END_CMD_RES; - if ( cmdat & CMD_DAT_CONT_DATA_ENABLE ) { - /*imask &= ~INT_MASK_BUF_READY;*/ + if (cmdat & CMD_DAT_CONT_DATA_ENABLE) { + /* imask &= ~INT_MASK_BUF_READY; */ imask &= ~INT_MASK_DATA_TRAN; - if ( cmdat & CMD_DAT_CONT_WRITE ) + if (cmdat & CMD_DAT_CONT_WRITE) imask &= ~INT_MASK_WRITE_OP_DONE; - if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) + if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) imask &= ~INT_MASK_BUF_READY; } @@ -395,14 +381,14 @@ static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request * spin_lock_irqsave(&host->lock, flags); host->pending_events &= ~(IMXMCI_PEND_WAIT_RESP_m | IMXMCI_PEND_DMA_END_m | - IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); + IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); host->imask = IMXMCI_INT_MASK_DEFAULT; MMC_INT_MASK = host->imask; spin_unlock_irqrestore(&host->lock, flags); - if(req && req->cmd) + if (req && req->cmd) host->prev_cmd_code = req->cmd->opcode; host->req = NULL; @@ -416,17 +402,17 @@ static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat) struct mmc_data *data = host->data; int data_error; - if(test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)){ + if (test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { imx_dma_disable(host->dma); dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, host->dma_dir); } - if ( stat & STATUS_ERR_MASK ) { - dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat); - if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR)) + if (stat & STATUS_ERR_MASK) { + dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", stat); + if (stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR)) data->error = -EILSEQ; - else if(stat & STATUS_TIME_OUT_READ) + else if (stat & STATUS_TIME_OUT_READ) data->error = -ETIMEDOUT; else data->error = -EIO; @@ -445,7 +431,7 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) { struct mmc_command *cmd = host->cmd; int i; - u32 a,b,c; + u32 a, b, c; struct mmc_data *data = host->data; if (!cmd) @@ -461,18 +447,18 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) cmd->error = -EILSEQ; } - if(cmd->flags & MMC_RSP_PRESENT) { - if(cmd->flags & MMC_RSP_136) { + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) { for (i = 0; i < 4; i++) { - u32 a = MMC_RES_FIFO & 0xffff; - u32 b = MMC_RES_FIFO & 0xffff; - cmd->resp[i] = a<<16 | b; + u32 d = MMC_RES_FIFO & 0xffff; + u32 e = MMC_RES_FIFO & 0xffff; + cmd->resp[i] = d << 16 | e; } } else { a = MMC_RES_FIFO & 0xffff; b = MMC_RES_FIFO & 0xffff; c = MMC_RES_FIFO & 0xffff; - cmd->resp[0] = a<<24 | b<<8 | c>>8; + cmd->resp[0] = a << 24 | b << 8 | c >> 8; } } @@ -485,35 +471,33 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) /* Wait for FIFO to be empty before starting DMA write */ stat = MMC_STATUS; - if(imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FE, - 40, "imxmci_cmd_done DMA WR") < 0) { + if (imxmci_busy_wait_for_status(host, &stat, + STATUS_APPL_BUFF_FE, + 40, "imxmci_cmd_done DMA WR") < 0) { cmd->error = -EIO; imxmci_finish_data(host, stat); - if(host->req) + if (host->req) imxmci_finish_request(host, host->req); dev_warn(mmc_dev(host->mmc), "STATUS = 0x%04x\n", - stat); + stat); return 0; } - if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { + if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) imx_dma_enable(host->dma); - } } } else { struct mmc_request *req; imxmci_stop_clock(host); req = host->req; - if(data) + if (data) imxmci_finish_data(host, stat); - if( req ) { + if (req) imxmci_finish_request(host, req); - } else { + else dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n"); - } } return 1; @@ -535,11 +519,10 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) } else { struct mmc_request *req; req = host->req; - if( req ) { + if (req) imxmci_finish_request(host, req); - } else { + else dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n"); - } } return 1; @@ -552,7 +535,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) int trans_done = 0; unsigned int stat = *pstat; - if(host->actual_bus_width != MMC_BUS_WIDTH_4) + if (host->actual_bus_width != MMC_BUS_WIDTH_4) burst_len = 16; else burst_len = 64; @@ -563,27 +546,27 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) udelay(20); /* required for clocks < 8MHz*/ - if(host->dma_dir == DMA_FROM_DEVICE) { + if (host->dma_dir == DMA_FROM_DEVICE) { imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE | - STATUS_TIME_OUT_READ, - 50, "imxmci_cpu_driven_data read"); + STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE | + STATUS_TIME_OUT_READ, + 50, "imxmci_cpu_driven_data read"); - while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) && - !(stat & STATUS_TIME_OUT_READ) && - (host->data_cnt < 512)) { + while ((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) && + !(stat & STATUS_TIME_OUT_READ) && + (host->data_cnt < 512)) { udelay(20); /* required for clocks < 8MHz*/ - for(i = burst_len; i>=2 ; i-=2) { + for (i = burst_len; i >= 2 ; i -= 2) { u16 data; data = MMC_BUFFER_ACCESS; udelay(10); /* required for clocks < 8MHz*/ - if(host->data_cnt+2 <= host->dma_size) { + if (host->data_cnt+2 <= host->dma_size) { *(host->data_ptr++) = data; } else { - if(host->data_cnt < host->dma_size) - *(u8*)(host->data_ptr) = data; + if (host->data_cnt < host->dma_size) + *(u8 *)(host->data_ptr) = data; } host->data_cnt += 2; } @@ -594,13 +577,13 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) host->data_cnt, burst_len, stat); } - if((stat & STATUS_DATA_TRANS_DONE) && (host->data_cnt >= 512)) + if ((stat & STATUS_DATA_TRANS_DONE) && (host->data_cnt >= 512)) trans_done = 1; - if(host->dma_size & 0x1ff) + if (host->dma_size & 0x1ff) stat &= ~STATUS_CRC_READ_ERR; - if(stat & STATUS_TIME_OUT_READ) { + if (stat & STATUS_TIME_OUT_READ) { dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read timeout STATUS = 0x%x\n", stat); trans_done = -1; @@ -608,12 +591,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) } else { imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FE, - 20, "imxmci_cpu_driven_data write"); + STATUS_APPL_BUFF_FE, + 20, "imxmci_cpu_driven_data write"); - while((stat & STATUS_APPL_BUFF_FE) && - (host->data_cnt < host->dma_size)) { - if(burst_len >= host->dma_size - host->data_cnt) { + while ((stat & STATUS_APPL_BUFF_FE) && + (host->data_cnt < host->dma_size)) { + if (burst_len >= host->dma_size - host->data_cnt) { burst_len = host->dma_size - host->data_cnt; host->data_cnt = host->dma_size; trans_done = 1; @@ -621,7 +604,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) host->data_cnt += burst_len; } - for(i = burst_len; i>0 ; i-=2) + for (i = burst_len; i > 0 ; i -= 2) MMC_BUFFER_ACCESS = *(host->data_ptr++); stat = MMC_STATUS; @@ -671,7 +654,7 @@ static void imxmci_tasklet_fnc(unsigned long data) unsigned int data_dir_mask = 0; /* STATUS_WR_CRC_ERROR_CODE_MASK */ int timeout = 0; - if(atomic_read(&host->stuck_timeout) > 4) { + if (atomic_read(&host->stuck_timeout) > 4) { char *what; timeout = 1; stat = MMC_STATUS; @@ -683,7 +666,7 @@ static void imxmci_tasklet_fnc(unsigned long data) what = "RESP"; else if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) - if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events)) + if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events)) what = "DATA"; else what = "DMA"; @@ -691,18 +674,18 @@ static void imxmci_tasklet_fnc(unsigned long data) what = "???"; dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", - what, stat, MMC_INT_MASK); + what, stat, MMC_INT_MASK); dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", - MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma)); + MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma)); dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n", - host->cmd?host->cmd->opcode:0, host->prev_cmd_code, 1<actual_bus_width, host->dma_size); + host->cmd?host->cmd->opcode:0, host->prev_cmd_code, 1 << host->actual_bus_width, host->dma_size); } - if(!host->present || timeout) + if (!host->present || timeout) host->status_reg = STATUS_TIME_OUT_RESP | STATUS_TIME_OUT_READ | - STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR; + STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR; - if(test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { + if (test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); stat = MMC_STATUS; @@ -713,63 +696,62 @@ static void imxmci_tasklet_fnc(unsigned long data) */ stat |= host->status_reg; - if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) + if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) stat &= ~STATUS_CRC_READ_ERR; - if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { + if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { imxmci_busy_wait_for_status(host, &stat, - STATUS_END_CMD_RESP | STATUS_ERR_MASK, - 20, "imxmci_tasklet_fnc resp (ERRATUM #4)"); + STATUS_END_CMD_RESP | STATUS_ERR_MASK, + 20, "imxmci_tasklet_fnc resp (ERRATUM #4)"); } - if(stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) { - if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) + if (stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) { + if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) imxmci_cmd_done(host, stat); - if(host->data && (stat & STATUS_ERR_MASK)) + if (host->data && (stat & STATUS_ERR_MASK)) imxmci_data_done(host, stat); } - if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { + if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { stat |= MMC_STATUS; - if(imxmci_cpu_driven_data(host, &stat)){ - if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) + if (imxmci_cpu_driven_data(host, &stat)) { + if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) imxmci_cmd_done(host, stat); atomic_clear_mask(IMXMCI_PEND_IRQ_m|IMXMCI_PEND_CPU_DATA_m, - &host->pending_events); + &host->pending_events); imxmci_data_done(host, stat); } } } - if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && - !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { + if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && + !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { stat = MMC_STATUS; /* Same as above */ stat |= host->status_reg; - if(host->dma_dir == DMA_TO_DEVICE) { + if (host->dma_dir == DMA_TO_DEVICE) data_dir_mask = STATUS_WRITE_OP_DONE; - } else { + else data_dir_mask = STATUS_DATA_TRANS_DONE; - } - if(stat & data_dir_mask) { + if (stat & data_dir_mask) { clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); imxmci_data_done(host, stat); } } - if(test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) { + if (test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) { - if(host->cmd) + if (host->cmd) imxmci_cmd_done(host, STATUS_TIME_OUT_RESP); - if(host->data) + if (host->data) imxmci_data_done(host, STATUS_TIME_OUT_READ | STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR); - if(host->req) + if (host->req) imxmci_finish_request(host, host->req); mmc_detect_change(host->mmc, msecs_to_jiffies(100)); @@ -796,9 +778,8 @@ static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req) if (req->data->flags & MMC_DATA_WRITE) cmdat |= CMD_DAT_CONT_WRITE; - if (req->data->flags & MMC_DATA_STREAM) { + if (req->data->flags & MMC_DATA_STREAM) cmdat |= CMD_DAT_CONT_STREAM_BLOCK; - } } imxmci_start_cmd(host, req->cmd, cmdat); @@ -811,36 +792,36 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct imxmci_host *host = mmc_priv(mmc); int prescaler; - if( ios->bus_width==MMC_BUS_WIDTH_4 ) { + if (ios->bus_width == MMC_BUS_WIDTH_4) { host->actual_bus_width = MMC_BUS_WIDTH_4; imx_gpio_mode(PB11_PF_SD_DAT3); - }else{ + } else { host->actual_bus_width = MMC_BUS_WIDTH_1; imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11); } - if ( host->power_mode != ios->power_mode ) { + if (host->power_mode != ios->power_mode) { switch (ios->power_mode) { case MMC_POWER_OFF: - break; + break; case MMC_POWER_UP: set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events); - break; + break; case MMC_POWER_ON: - break; + break; } host->power_mode = ios->power_mode; } - if ( ios->clock ) { + if (ios->clock) { unsigned int clk; /* The prescaler is 5 for PERCLK2 equal to 96MHz * then 96MHz / 5 = 19.2 MHz */ clk = clk_get_rate(host->clk); - prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE; - switch(prescaler) { + prescaler = (clk + (CLK_RATE * 7) / 8) / CLK_RATE; + switch (prescaler) { case 0: case 1: prescaler = 0; break; @@ -858,22 +839,22 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) dev_dbg(mmc_dev(host->mmc), "PERCLK2 %d MHz -> prescaler %d\n", clk, prescaler); - for(clk=0; clk<8; clk++) { + for (clk = 0; clk < 8; clk++) { int x; - x = CLK_RATE / (1<clock) + x = CLK_RATE / (1 << clk); + if (x <= ios->clock) break; } MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */ imxmci_stop_clock(host); - MMC_CLK_RATE = (prescaler<<3) | clk; + MMC_CLK_RATE = (prescaler << 3) | clk; /* * Under my understanding, clock should not be started there, because it would * initiate SDHC sequencer and send last or random command into card */ - /*imxmci_start_clock(host);*/ + /* imxmci_start_clock(host); */ dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); } else { @@ -915,10 +896,10 @@ static void imxmci_check_status(unsigned long data) tasklet_schedule(&host->tasklet); } - if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) || - test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { + if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) || + test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) { atomic_inc(&host->stuck_timeout); - if(atomic_read(&host->stuck_timeout) > 4) + if (atomic_read(&host->stuck_timeout) > 4) tasklet_schedule(&host->tasklet); } else { atomic_set(&host->stuck_timeout, 0); @@ -995,9 +976,9 @@ static int imxmci_probe(struct platform_device *pdev) imxmci_softreset(); - if ( MMC_REV_NO != 0x390 ) { + if (MMC_REV_NO != 0x390) { dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", - MMC_REV_NO); + MMC_REV_NO); goto out; } @@ -1012,7 +993,7 @@ static int imxmci_probe(struct platform_device *pdev) ret = -EBUSY; goto out; } - host->dma_allocated=1; + host->dma_allocated = 1; imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host); tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host); @@ -1032,7 +1013,7 @@ static int imxmci_probe(struct platform_device *pdev) host->timer.data = (unsigned long)host; host->timer.function = imxmci_check_status; add_timer(&host->timer); - mod_timer(&host->timer, jiffies + (HZ>>1)); + mod_timer(&host->timer, jiffies + (HZ >> 1)); platform_set_drvdata(pdev, mmc); @@ -1042,9 +1023,9 @@ static int imxmci_probe(struct platform_device *pdev) out: if (host) { - if(host->dma_allocated){ + if (host->dma_allocated) { imx_dma_free(host->dma); - host->dma_allocated=0; + host->dma_allocated = 0; } if (host->clk) { clk_disable(host->clk); @@ -1072,9 +1053,9 @@ static int imxmci_remove(struct platform_device *pdev) mmc_remove_host(mmc); free_irq(host->irq, host); - if(host->dma_allocated){ + if (host->dma_allocated) { imx_dma_free(host->dma); - host->dma_allocated=0; + host->dma_allocated = 0; } tasklet_kill(&host->tasklet); @@ -1109,7 +1090,7 @@ static int imxmci_resume(struct platform_device *dev) if (mmc) { host = mmc_priv(mmc); - if(host) + if (host) set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events); ret = mmc_resume_host(mmc); } -- cgit v1.2.3-70-g09d2 From 2507b0a33343552d2177b75dc35fe7073349b773 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 10 Oct 2008 12:05:03 +0200 Subject: imxmmc: Remove unused variables This removes clkrt and cmdat from struct imxmci_host, they are unused. Signed-off-by: Marc Kleine-Budde Signed-off-by: Sascha Hauer --- drivers/mmc/host/imxmmc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 02e9dd3e22d..5c921b33b10 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -45,8 +45,6 @@ struct imxmci_host { struct resource *res; int irq; imx_dmach_t dma; - unsigned int clkrt; - unsigned int cmdat; volatile unsigned int imask; unsigned int power_mode; unsigned int present; -- cgit v1.2.3-70-g09d2 From df25f9da9fcc12193208e8da135c930924cd56c5 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 10 Oct 2008 12:05:03 +0200 Subject: imxmmc: use readl/writel Use readl/writel instead of direct pointer deref. Signed-off-by: Marc Kleine-Budde Signed-off-by: Sascha Hauer --- drivers/mmc/host/imxmmc.c | 190 ++++++++++++++++++++++++++++------------------ drivers/mmc/host/imxmmc.h | 37 +++++---- 2 files changed, 134 insertions(+), 93 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 5c921b33b10..eb29b1d933a 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -43,6 +43,7 @@ struct imxmci_host { struct mmc_host *mmc; spinlock_t lock; struct resource *res; + void __iomem *base; int irq; imx_dmach_t dma; volatile unsigned int imask; @@ -98,14 +99,22 @@ struct imxmci_host { static void imxmci_stop_clock(struct imxmci_host *host) { int i = 0; - MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK; + u16 reg; + + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg & ~STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); while (i < 0x1000) { - if (!(i & 0x7f)) - MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK; + if (!(i & 0x7f)) { + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg | STR_STP_CLK_STOP_CLK, + host->base + MMC_REG_STR_STP_CLK); + } - if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) { + reg = readw(host->base + MMC_REG_STATUS); + if (!(reg & STATUS_CARD_BUS_CLK_RUN)) { /* Check twice before cut */ - if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) + reg = readw(host->base + MMC_REG_STATUS); + if (!(reg & STATUS_CARD_BUS_CLK_RUN)) return; } @@ -119,8 +128,10 @@ static int imxmci_start_clock(struct imxmci_host *host) unsigned int trials = 0; unsigned int delay_limit = 128; unsigned long flags; + u16 reg; - MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg & ~STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK); clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); @@ -129,15 +140,18 @@ static int imxmci_start_clock(struct imxmci_host *host) * then 6 delay loops, but during card detection (low clockrate) * it takes up to 5000 delay loops and sometimes fails for the first time */ - MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg | STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); do { unsigned int delay = delay_limit; while (delay--) { - if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) + reg = readw(host->base + MMC_REG_STATUS); + if (reg & STATUS_CARD_BUS_CLK_RUN) /* Check twice before cut */ - if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) + reg = readw(host->base + MMC_REG_STATUS); + if (reg & STATUS_CARD_BUS_CLK_RUN) return 0; if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) @@ -151,8 +165,11 @@ static int imxmci_start_clock(struct imxmci_host *host) * IRQ or schedule delays this function execution and the clocks has * been already stopped by other means (response processing, SDHC HW) */ - if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) - MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; + if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) { + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg | STR_STP_CLK_START_CLK, + host->base + MMC_REG_STR_STP_CLK); + } local_irq_restore(flags); } while (++trials < 256); @@ -162,23 +179,20 @@ static int imxmci_start_clock(struct imxmci_host *host) return -1; } -static void imxmci_softreset(void) +static void imxmci_softreset(struct imxmci_host *host) { + int i; + /* reset sequence */ - MMC_STR_STP_CLK = 0x8; - MMC_STR_STP_CLK = 0xD; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - MMC_STR_STP_CLK = 0x5; - - MMC_RES_TO = 0xff; - MMC_BLK_LEN = 512; - MMC_NOB = 1; + writew(0x08, host->base + MMC_REG_STR_STP_CLK); + writew(0x0D, host->base + MMC_REG_STR_STP_CLK); + + for (i = 0; i < 8; i++) + writew(0x05, host->base + MMC_REG_STR_STP_CLK); + + writew(0xff, host->base + MMC_REG_RES_TO); + writew(512, host->base + MMC_REG_BLK_LEN); + writew(1, host->base + MMC_REG_NOB); } static int imxmci_busy_wait_for_status(struct imxmci_host *host, @@ -195,7 +209,7 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, return -1; } udelay(2); - *pstat |= MMC_STATUS; + *pstat |= readw(host->base + MMC_REG_STATUS); } if (!loops) return 0; @@ -220,8 +234,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) host->data = data; data->bytes_xfered = 0; - MMC_NOB = nob; - MMC_BLK_LEN = blksz; + writew(nob, host->base + MMC_REG_NOB); + writew(blksz, host->base + MMC_REG_BLK_LEN); /* * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise. @@ -237,8 +251,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) host->dma_dir = DMA_FROM_DEVICE; /* Hack to enable read SCR */ - MMC_NOB = 1; - MMC_BLK_LEN = 512; + writew(1, host->base + MMC_REG_NOB); + writew(512, host->base + MMC_REG_BLK_LEN); } else { host->dma_dir = DMA_TO_DEVICE; } @@ -259,7 +273,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) data->sg_len, host->dma_dir); imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ); + host->res->start + MMC_REG_BUFFER_ACCESS, + DMA_MODE_READ); /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/ CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN; @@ -270,7 +285,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) data->sg_len, host->dma_dir); imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, - host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE); + host->res->start + MMC_REG_BUFFER_ACCESS, + DMA_MODE_WRITE); /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/ CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN; @@ -341,10 +357,10 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, if (host->actual_bus_width == MMC_BUS_WIDTH_4) cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; - MMC_CMD = cmd->opcode; - MMC_ARGH = cmd->arg >> 16; - MMC_ARGL = cmd->arg & 0xffff; - MMC_CMD_DAT_CONT = cmdat; + writew(cmd->opcode, host->base + MMC_REG_CMD); + writew(cmd->arg >> 16, host->base + MMC_REG_ARGH); + writew(cmd->arg & 0xffff, host->base + MMC_REG_ARGL); + writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT); atomic_set(&host->stuck_timeout, 0); set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events); @@ -363,7 +379,7 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, spin_lock_irqsave(&host->lock, flags); host->imask = imask; - MMC_INT_MASK = host->imask; + writew(host->imask, host->base + MMC_REG_INT_MASK); spin_unlock_irqrestore(&host->lock, flags); dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n", @@ -382,7 +398,7 @@ static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request * IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); host->imask = IMXMCI_INT_MASK_DEFAULT; - MMC_INT_MASK = host->imask; + writew(host->imask, host->base + MMC_REG_INT_MASK); spin_unlock_irqrestore(&host->lock, flags); @@ -448,14 +464,14 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { for (i = 0; i < 4; i++) { - u32 d = MMC_RES_FIFO & 0xffff; - u32 e = MMC_RES_FIFO & 0xffff; - cmd->resp[i] = d << 16 | e; + a = readw(host->base + MMC_REG_RES_FIFO); + b = readw(host->base + MMC_REG_RES_FIFO); + cmd->resp[i] = a << 16 | b; } } else { - a = MMC_RES_FIFO & 0xffff; - b = MMC_RES_FIFO & 0xffff; - c = MMC_RES_FIFO & 0xffff; + a = readw(host->base + MMC_REG_RES_FIFO); + b = readw(host->base + MMC_REG_RES_FIFO); + c = readw(host->base + MMC_REG_RES_FIFO); cmd->resp[0] = a << 24 | b << 8 | c >> 8; } } @@ -468,7 +484,7 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) /* Wait for FIFO to be empty before starting DMA write */ - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); if (imxmci_busy_wait_for_status(host, &stat, STATUS_APPL_BUFF_FE, 40, "imxmci_cmd_done DMA WR") < 0) { @@ -558,7 +574,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) for (i = burst_len; i >= 2 ; i -= 2) { u16 data; - data = MMC_BUFFER_ACCESS; + data = readw(host->base + MMC_REG_BUFFER_ACCESS); udelay(10); /* required for clocks < 8MHz*/ if (host->data_cnt+2 <= host->dma_size) { *(host->data_ptr++) = data; @@ -569,7 +585,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) host->data_cnt += 2; } - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read %d burst %d STATUS = 0x%x\n", host->data_cnt, burst_len, stat); @@ -603,9 +619,9 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) } for (i = burst_len; i > 0 ; i -= 2) - MMC_BUFFER_ACCESS = *(host->data_ptr++); + writew(*(host->data_ptr++), host->base + MMC_REG_BUFFER_ACCESS); - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n", burst_len, stat); @@ -620,7 +636,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) static void imxmci_dma_irq(int dma, void *devid) { struct imxmci_host *host = devid; - uint32_t stat = MMC_STATUS; + u32 stat = readw(host->base + MMC_REG_STATUS); atomic_set(&host->stuck_timeout, 0); host->status_reg = stat; @@ -631,10 +647,11 @@ static void imxmci_dma_irq(int dma, void *devid) static irqreturn_t imxmci_irq(int irq, void *devid) { struct imxmci_host *host = devid; - uint32_t stat = MMC_STATUS; + u32 stat = readw(host->base + MMC_REG_STATUS); int handled = 1; - MMC_INT_MASK = host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT; + writew(host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT, + host->base + MMC_REG_INT_MASK); atomic_set(&host->stuck_timeout, 0); host->status_reg = stat; @@ -655,7 +672,7 @@ static void imxmci_tasklet_fnc(unsigned long data) if (atomic_read(&host->stuck_timeout) > 4) { char *what; timeout = 1; - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); host->status_reg = stat; if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) @@ -671,12 +688,20 @@ static void imxmci_tasklet_fnc(unsigned long data) else what = "???"; - dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", - what, stat, MMC_INT_MASK); - dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", - MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma)); + dev_err(mmc_dev(host->mmc), + "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", + what, stat, + readw(host->base + MMC_REG_INT_MASK)); + dev_err(mmc_dev(host->mmc), + "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", + readw(host->base + MMC_REG_CMD_DAT_CONT), + readw(host->base + MMC_REG_BLK_LEN), + readw(host->base + MMC_REG_NOB), + CCR(host->dma)); dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n", - host->cmd?host->cmd->opcode:0, host->prev_cmd_code, 1 << host->actual_bus_width, host->dma_size); + host->cmd ? host->cmd->opcode : 0, + host->prev_cmd_code, + 1 << host->actual_bus_width, host->dma_size); } if (!host->present || timeout) @@ -686,7 +711,7 @@ static void imxmci_tasklet_fnc(unsigned long data) if (test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); /* * This is not required in theory, but there is chance to miss some flag * which clears automatically by mask write, FreeScale original code keeps @@ -711,7 +736,7 @@ static void imxmci_tasklet_fnc(unsigned long data) } if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { - stat |= MMC_STATUS; + stat |= readw(host->base + MMC_REG_STATUS); if (imxmci_cpu_driven_data(host, &stat)) { if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) imxmci_cmd_done(host, stat); @@ -725,7 +750,7 @@ static void imxmci_tasklet_fnc(unsigned long data) if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { - stat = MMC_STATUS; + stat = readw(host->base + MMC_REG_STATUS); /* Same as above */ stat |= host->status_reg; @@ -813,6 +838,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->clock) { unsigned int clk; + u16 reg; /* The prescaler is 5 for PERCLK2 equal to 96MHz * then 96MHz / 5 = 19.2 MHz @@ -844,17 +870,22 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; } - MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */ + /* enable controller */ + reg = readw(host->base + MMC_REG_STR_STP_CLK); + writew(reg | STR_STP_CLK_ENABLE, + host->base + MMC_REG_STR_STP_CLK); imxmci_stop_clock(host); - MMC_CLK_RATE = (prescaler << 3) | clk; + writew((prescaler << 3) | clk, host->base + MMC_REG_CLK_RATE); /* * Under my understanding, clock should not be started there, because it would * initiate SDHC sequencer and send last or random command into card */ /* imxmci_start_clock(host); */ - dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); + dev_dbg(mmc_dev(host->mmc), + "MMC_CLK_RATE: 0x%08x\n", + readw(host->base + MMC_REG_CLK_RATE)); } else { imxmci_stop_clock(host); } @@ -913,6 +944,7 @@ static int imxmci_probe(struct platform_device *pdev) struct imxmci_host *host = NULL; struct resource *r; int ret = 0, irq; + u16 rev_no; printk(KERN_INFO "i.MX mmc driver\n"); @@ -921,7 +953,8 @@ static int imxmci_probe(struct platform_device *pdev) if (!r || irq < 0) return -ENXIO; - if (!request_mem_region(r->start, 0x100, pdev->name)) + r = request_mem_region(r->start, resource_size(r), pdev->name); + if (!r) return -EBUSY; mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); @@ -945,6 +978,12 @@ static int imxmci_probe(struct platform_device *pdev) mmc->max_blk_count = 65535; host = mmc_priv(mmc); + host->base = ioremap(r->start, resource_size(r)); + if (!host->base) { + ret = -ENOMEM; + goto out; + } + host->mmc = mmc; host->dma_allocated = 0; host->pdata = pdev->dev.platform_data; @@ -972,18 +1011,20 @@ static int imxmci_probe(struct platform_device *pdev) imx_gpio_mode(PB12_PF_SD_CLK); imx_gpio_mode(PB13_PF_SD_CMD); - imxmci_softreset(); + imxmci_softreset(host); - if (MMC_REV_NO != 0x390) { + rev_no = readw(host->base + MMC_REG_REV_NO); + if (rev_no != 0x390) { dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", - MMC_REV_NO); + readw(host->base + MMC_REG_REV_NO)); goto out; } - MMC_READ_TO = 0x2db4; /* recommended in data sheet */ + /* recommended in data sheet */ + writew(0x2db4, host->base + MMC_REG_READ_TO); host->imask = IMXMCI_INT_MASK_DEFAULT; - MMC_INT_MASK = host->imask; + writew(host->imask, host->base + MMC_REG_INT_MASK); host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); if(host->dma < 0) { @@ -1029,10 +1070,12 @@ out: clk_disable(host->clk); clk_put(host->clk); } + if (host->base) + iounmap(host->base); } if (mmc) mmc_free_host(mmc); - release_mem_region(r->start, 0x100); + release_mem_region(r->start, resource_size(r)); return ret; } @@ -1051,6 +1094,7 @@ static int imxmci_remove(struct platform_device *pdev) mmc_remove_host(mmc); free_irq(host->irq, host); + iounmap(host->base); if (host->dma_allocated) { imx_dma_free(host->dma); host->dma_allocated = 0; @@ -1061,7 +1105,7 @@ static int imxmci_remove(struct platform_device *pdev) clk_disable(host->clk); clk_put(host->clk); - release_mem_region(host->res->start, 0x100); + release_mem_region(host->res->start, resource_size(host->res)); mmc_free_host(mmc); } diff --git a/drivers/mmc/host/imxmmc.h b/drivers/mmc/host/imxmmc.h index e5339e334db..09d5d4ee3a7 100644 --- a/drivers/mmc/host/imxmmc.h +++ b/drivers/mmc/host/imxmmc.h @@ -1,24 +1,21 @@ +#define MMC_REG_STR_STP_CLK 0x00 +#define MMC_REG_STATUS 0x04 +#define MMC_REG_CLK_RATE 0x08 +#define MMC_REG_CMD_DAT_CONT 0x0C +#define MMC_REG_RES_TO 0x10 +#define MMC_REG_READ_TO 0x14 +#define MMC_REG_BLK_LEN 0x18 +#define MMC_REG_NOB 0x1C +#define MMC_REG_REV_NO 0x20 +#define MMC_REG_INT_MASK 0x24 +#define MMC_REG_CMD 0x28 +#define MMC_REG_ARGH 0x2C +#define MMC_REG_ARGL 0x30 +#define MMC_REG_RES_FIFO 0x34 +#define MMC_REG_BUFFER_ACCESS 0x38 -# define __REG16(x) (*((volatile u16 *)IO_ADDRESS(x))) - -#define MMC_STR_STP_CLK __REG16(IMX_MMC_BASE + 0x00) -#define MMC_STATUS __REG16(IMX_MMC_BASE + 0x04) -#define MMC_CLK_RATE __REG16(IMX_MMC_BASE + 0x08) -#define MMC_CMD_DAT_CONT __REG16(IMX_MMC_BASE + 0x0C) -#define MMC_RES_TO __REG16(IMX_MMC_BASE + 0x10) -#define MMC_READ_TO __REG16(IMX_MMC_BASE + 0x14) -#define MMC_BLK_LEN __REG16(IMX_MMC_BASE + 0x18) -#define MMC_NOB __REG16(IMX_MMC_BASE + 0x1C) -#define MMC_REV_NO __REG16(IMX_MMC_BASE + 0x20) -#define MMC_INT_MASK __REG16(IMX_MMC_BASE + 0x24) -#define MMC_CMD __REG16(IMX_MMC_BASE + 0x28) -#define MMC_ARGH __REG16(IMX_MMC_BASE + 0x2C) -#define MMC_ARGL __REG16(IMX_MMC_BASE + 0x30) -#define MMC_RES_FIFO __REG16(IMX_MMC_BASE + 0x34) -#define MMC_BUFFER_ACCESS __REG16(IMX_MMC_BASE + 0x38) -#define MMC_BUFFER_ACCESS_OFS 0x38 - - +#define STR_STP_CLK_IPG_CLK_GATE_DIS (1<<15) +#define STR_STP_CLK_IPG_PERCLK_GATE_DIS (1<<14) #define STR_STP_CLK_ENDIAN (1<<5) #define STR_STP_CLK_RESET (1<<3) #define STR_STP_CLK_ENABLE (1<<2) -- cgit v1.2.3-70-g09d2 From 092f82edbe96d0a08e1d10436927e89fa101fe0d Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 28 Sep 2008 16:15:56 -0700 Subject: pci: use pci_ioremap_bar() in drivers/mmc Use the new pci_ioremap_bar() function in drivers/mmc. pci_ioremap_bar() just takes a pci device and a bar number, with the goal of making it really hard to get wrong, while also having a central place to stick sanity checks. Signed-off-by: Arjan van de Ven Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 9bd7026b002..f07255cb17e 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -545,7 +545,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( } addr = pci_resource_start(pdev, bar); - host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar)); + host->ioaddr = pci_ioremap_bar(pdev, bar); if (!host->ioaddr) { dev_err(&pdev->dev, "failed to remap registers\n"); goto release; -- cgit v1.2.3-70-g09d2 From b7a03210b7b381e06f71751cb9addfae7704489c Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 22 Oct 2008 17:09:00 -0700 Subject: mmc: trivial annotation of 'blocks' sg_init_one is reading a be32, annotate as such. Signed-off-by: Harvey Harrison Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3d067c35185..903c8aae54b 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -145,7 +145,7 @@ struct mmc_blk_request { static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; - u32 blocks; + __be32 blocks; struct mmc_request mrq; struct mmc_command cmd; @@ -204,9 +204,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) if (cmd.error || data.error) return (u32)-1; - blocks = ntohl(blocks); - - return blocks; + return ntohl(blocks); } static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) -- cgit v1.2.3-70-g09d2 From 35ff8554d12ecc80a46ea0d9bce34fe28733ff38 Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Sat, 22 Nov 2008 19:29:29 +0100 Subject: sdhci: activate led support also when module CONFIG_LEDS_CLASS is defined only if led-class is built-in, otherwise when it is a module the option is called CONFIG_LEDS_CLASS_MODULE. Led support should also be activated in this case. Signed-off-by: Eric Piel Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 12 ++++++------ drivers/mmc/host/sdhci.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4d010a984be..3b1b54f9b0f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -149,7 +149,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host) writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); } -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) static void sdhci_led_control(struct led_classdev *led, enum led_brightness brightness) { @@ -994,7 +994,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host->mrq != NULL); -#ifndef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) sdhci_activate_led(host); #endif @@ -1201,7 +1201,7 @@ static void sdhci_tasklet_finish(unsigned long param) host->cmd = NULL; host->data = NULL; -#ifndef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) sdhci_deactivate_led(host); #endif @@ -1717,7 +1717,7 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_dumpregs(host); #endif -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) host->led.name = mmc_hostname(mmc); host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); @@ -1739,7 +1739,7 @@ int sdhci_add_host(struct sdhci_host *host) return 0; -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) reset: sdhci_reset(host, SDHCI_RESET_ALL); free_irq(host->irq, host); @@ -1775,7 +1775,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) mmc_remove_host(host->mmc); -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) led_classdev_unregister(&host->led); #endif diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 31f4b1528e7..3efba236394 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -220,7 +220,7 @@ struct sdhci_host { struct mmc_host *mmc; /* MMC structure */ u64 dma_mask; /* custom DMA mask */ -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) struct led_classdev led; /* LED control */ #endif -- cgit v1.2.3-70-g09d2 From b30f8af3358b5c66be223e3a9f3d11b3d02b4a8f Mon Sep 17 00:00:00 2001 From: Jarkko Lavinen Date: Mon, 17 Nov 2008 14:35:21 +0200 Subject: mmc: Add 8-bit bus width support Signed-off-by: Jarkko Lavinen Signed-off-by: Pierre Ossman --- drivers/mmc/core/mmc.c | 18 ++++++++++++++---- include/linux/mmc/host.h | 2 ++ 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index fdd7c760be8..c232d11a7ed 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -434,13 +434,24 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && - (host->caps & MMC_CAP_4_BIT_DATA)) { + (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { + unsigned ext_csd_bit, bus_width; + + if (host->caps & MMC_CAP_8_BIT_DATA) { + ext_csd_bit = EXT_CSD_BUS_WIDTH_8; + bus_width = MMC_BUS_WIDTH_8; + } else { + ext_csd_bit = EXT_CSD_BUS_WIDTH_4; + bus_width = MMC_BUS_WIDTH_4; + } + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); + EXT_CSD_BUS_WIDTH, ext_csd_bit); + if (err) goto free_card; - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + mmc_set_bus_width(card->host, bus_width); } if (!oldcard) @@ -624,4 +635,3 @@ err: return err; } - diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f842f234e44..4e457256bd3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -41,6 +41,7 @@ struct mmc_ios { #define MMC_BUS_WIDTH_1 0 #define MMC_BUS_WIDTH_4 2 +#define MMC_BUS_WIDTH_8 3 unsigned char timing; /* timing specification used */ @@ -116,6 +117,7 @@ struct mmc_host { #define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ +#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ -- cgit v1.2.3-70-g09d2 From 0527a60c2b6bd7ab20e82cc5e488659e20eaaacd Mon Sep 17 00:00:00 2001 From: "philipl@overt.org" Date: Sun, 30 Nov 2008 20:27:50 -0500 Subject: ricoh_mmc: Handle newer models of Ricoh controllers The latest generation of laptops are shipping with a newer model of Ricoh chip where the firewire controller is the primary PCI function but a cardbus controller is also present. The existing code assumes that if a cardbus controller is, present, then it must be the one to manipulate - but the real rule is that you manipulate PCI function 0. This patch adds an additional constraint that the target must be function 0. Signed-off-by: Philip Langdale Signed-off-by: Pierre Ossman --- drivers/mmc/host/ricoh_mmc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c index a16d7609e4e..be9e7b32b34 100644 --- a/drivers/mmc/host/ricoh_mmc.c +++ b/drivers/mmc/host/ricoh_mmc.c @@ -11,9 +11,10 @@ /* * This is a conceptually ridiculous driver, but it is required by the way - * the Ricoh multi-function R5C832 works. This chip implements firewire - * and four different memory card controllers. Two of those controllers are - * an SDHCI controller and a proprietary MMC controller. The linux SDHCI + * the Ricoh multi-function chips (R5CXXX) work. These chips implement + * the four main memory card controllers (SD, MMC, MS, xD) and one or both + * of cardbus or firewire. It happens that they implement SD and MMC + * support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller. @@ -21,8 +22,10 @@ * a detection event occurs immediately, even if the MMC card is already * in the reader. * - * The relevant registers live on the firewire function, so this is unavoidably - * ugly. Such is life. + * It seems to be the case that the relevant PCI registers to deactivate the + * MMC controller live on PCI function 0, which might be the cardbus controller + * or the firewire controller, depending on the particular chip in question. As + * such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include @@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n"); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From 86e8286a0e48663e1e86a5884b30a6d05de2993a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 26 Nov 2008 22:54:17 +0300 Subject: mmc: Add mmc_vddrange_to_ocrmask() helper function This function sets the OCR mask bits according to provided voltage ranges. Will be used by the mmc_spi OpenFirmware bindings. Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman --- drivers/mmc/core/core.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/core.h | 2 ++ 2 files changed, 77 insertions(+) (limited to 'drivers/mmc') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f7284b905eb..5f288aeeb72 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -448,6 +449,80 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) mmc_set_ios(host); } +/** + * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number + * @vdd: voltage (mV) + * @low_bits: prefer low bits in boundary cases + * + * This function returns the OCR bit number according to the provided @vdd + * value. If conversion is not possible a negative errno value returned. + * + * Depending on the @low_bits flag the function prefers low or high OCR bits + * on boundary voltages. For example, + * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); + * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); + * + * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). + */ +static int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) +{ + const int max_bit = ilog2(MMC_VDD_35_36); + int bit; + + if (vdd < 1650 || vdd > 3600) + return -EINVAL; + + if (vdd >= 1650 && vdd <= 1950) + return ilog2(MMC_VDD_165_195); + + if (low_bits) + vdd -= 1; + + /* Base 2000 mV, step 100 mV, bit's base 8. */ + bit = (vdd - 2000) / 100 + 8; + if (bit > max_bit) + return max_bit; + return bit; +} + +/** + * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask + * @vdd_min: minimum voltage value (mV) + * @vdd_max: maximum voltage value (mV) + * + * This function returns the OCR mask bits according to the provided @vdd_min + * and @vdd_max values. If conversion is not possible the function returns 0. + * + * Notes wrt boundary cases: + * This function sets the OCR bits for all boundary voltages, for example + * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | + * MMC_VDD_34_35 mask. + */ +u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) +{ + u32 mask = 0; + + if (vdd_max < vdd_min) + return 0; + + /* Prefer high bits for the boundary vdd_max values. */ + vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); + if (vdd_max < 0) + return 0; + + /* Prefer low bits for the boundary vdd_min values. */ + vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); + if (vdd_min < 0) + return 0; + + /* Fill the mask, from max bit to min bit. */ + while (vdd_max >= vdd_min) + mask |= 1 << vdd_max--; + + return mask; +} +EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); + /* * Mask off any voltages we don't support and select * the lowest voltage diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 143cebf0586..7ac8b500d55 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -151,4 +151,6 @@ static inline void mmc_claim_host(struct mmc_host *host) __mmc_claim_host(host, NULL); } +extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); + #endif -- cgit v1.2.3-70-g09d2 From 504f191f25b1671802246bac06c9f59f94f0b7de Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 16 Oct 2008 12:55:25 +0300 Subject: mmc_block: print better error messages Add command response and card status to error messages. Signed-off-by: Adrian Hunter Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 903c8aae54b..cc9b3abf4a3 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -207,6 +207,23 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) return ntohl(blocks); } +static u32 get_card_status(struct mmc_card *card, struct request *req) +{ + struct mmc_command cmd; + int err; + + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + if (!mmc_host_is_spi(card->host)) + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + printk(KERN_ERR "%s: error %d sending status comand", + req->rq_disk->disk_name, err); + return cmd.resp[0]; +} + static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq->data; @@ -218,7 +235,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) do { struct mmc_command cmd; - u32 readcmd, writecmd; + u32 readcmd, writecmd, status = 0; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; @@ -273,19 +290,32 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * until later as we need to wait for the card to leave * programming mode even when things go wrong. */ + if (brq.cmd.error || brq.data.error || brq.stop.error) + status = get_card_status(card, req); + if (brq.cmd.error) { - printk(KERN_ERR "%s: error %d sending read/write command\n", - req->rq_disk->disk_name, brq.cmd.error); + printk(KERN_ERR "%s: error %d sending read/write " + "command, response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.cmd.error, + brq.cmd.resp[0], status); } if (brq.data.error) { - printk(KERN_ERR "%s: error %d transferring data\n", - req->rq_disk->disk_name, brq.data.error); + if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) + /* 'Stop' response contains card status */ + status = brq.mrq.stop->resp[0]; + printk(KERN_ERR "%s: error %d transferring data," + " sector %u, nr %u, card status %#x\n", + req->rq_disk->disk_name, brq.data.error, + (unsigned)req->sector, + (unsigned)req->nr_sectors, status); } if (brq.stop.error) { - printk(KERN_ERR "%s: error %d sending stop command\n", - req->rq_disk->disk_name, brq.stop.error); + printk(KERN_ERR "%s: error %d sending stop command, " + "response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.stop.error, + brq.stop.resp[0], status); } if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { -- cgit v1.2.3-70-g09d2 From ca4f10563929b932ed8970fda41a7f99385e4b0b Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 13 Dec 2008 21:21:33 +0100 Subject: mmc: balanc pci_iomap with pci_iounmap balance pci_iomap with pci_iounmap, not iounmap Signed-off-by: Roel Kluin Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdricoh_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 1df44d966bd..d4748a8e0de 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -463,7 +463,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev, err: if (iobase) - iounmap(iobase); + pci_iounmap(pci_dev, iobase); if (mmc) mmc_free_host(mmc); -- cgit v1.2.3-70-g09d2 From f9134319c81c6c56e0ddf38e7adac2492b243d9b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 21 Dec 2008 17:01:48 +0100 Subject: sdhci: handle built-in sdhci with modular leds class As reported by Randy Dunlap, having sdhci built-in and LEDs class as a module resulted in undefined symbols. Change the code to handle that case properly (by not having LEDs class support in sdhci). Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3b1b54f9b0f..6b2d1f99af6 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -30,6 +30,11 @@ #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) +#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ + defined(CONFIG_MMC_SDHCI_MODULE)) +#define SDHCI_USE_LEDS_CLASS +#endif + static unsigned int debug_quirks = 0; static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); @@ -149,7 +154,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host) writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); } -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifdef SDHCI_USE_LEDS_CLASS static void sdhci_led_control(struct led_classdev *led, enum led_brightness brightness) { @@ -994,7 +999,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host->mrq != NULL); -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifndef SDHCI_USE_LEDS_CLASS sdhci_activate_led(host); #endif @@ -1201,7 +1206,7 @@ static void sdhci_tasklet_finish(unsigned long param) host->cmd = NULL; host->data = NULL; -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifndef SDHCI_USE_LEDS_CLASS sdhci_deactivate_led(host); #endif @@ -1717,7 +1722,7 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_dumpregs(host); #endif -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifdef SDHCI_USE_LEDS_CLASS host->led.name = mmc_hostname(mmc); host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); @@ -1739,7 +1744,7 @@ int sdhci_add_host(struct sdhci_host *host) return 0; -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifdef SDHCI_USE_LEDS_CLASS reset: sdhci_reset(host, SDHCI_RESET_ALL); free_irq(host->irq, host); @@ -1775,7 +1780,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) mmc_remove_host(host->mmc); -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#ifdef SDHCI_USE_LEDS_CLASS led_classdev_unregister(&host->led); #endif -- cgit v1.2.3-70-g09d2 From a0d045cac9bcb3e9a9796d596415f7ffb64852e2 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 16 Dec 2008 16:13:09 +0100 Subject: drivers/mmc: Move a dereference below a NULL test In each case, if the NULL test is necessary, then the dereference should be moved below the NULL test. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ type T; expression E; identifier i,fld; statement S; @@ - T i = E->fld; + T i; ... when != E when != i if (E == NULL) S + i = E->fld; // Signed-off-by: Julia Lawall Signed-off-by: Pierre Ossman --- drivers/mmc/host/tmio_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 95430b81ec1..6a7a6190483 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -224,7 +224,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) { void __iomem *ctl = host->ctl; struct mmc_data *data = host->data; - struct mmc_command *stop = data->stop; + struct mmc_command *stop; host->data = NULL; @@ -232,6 +232,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) pr_debug("Spurious data end IRQ\n"); return; } + stop = data->stop; /* FIXME - return correct transfer count on errors */ if (!data->error) -- cgit v1.2.3-70-g09d2 From 6a79e391df295bd7c2aa1309ea5031f361c197fd Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 31 Dec 2008 18:21:17 +0100 Subject: mmc_block: ensure all sectors that do not have errors are read If a card encounters an ECC error while reading a sector it will timeout. Instead of reporting the entire I/O request as having an error, redo the I/O one sector at a time so that all readable sectors are provided to the upper layers. Signed-off-by: Adrian Hunter Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 76 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index cc9b3abf4a3..45b1f430685 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -229,7 +229,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request brq; - int ret = 1; + int ret = 1, disable_multi = 0; mmc_claim_host(card->host); @@ -251,6 +251,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; brq.data.blocks = req->nr_sectors; + /* + * After a read error, we redo the request one sector at a time + * in order to accurately determine which sectors can be read + * successfully. + */ + if (disable_multi && brq.data.blocks > 1) + brq.data.blocks = 1; + if (brq.data.blocks > 1) { /* SPI multiblock writes terminate using a special * token, not a STOP_TRANSMISSION request. @@ -279,6 +287,25 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.sg = mq->sg; brq.data.sg_len = mmc_queue_map_sg(mq); + /* + * Adjust the sg list so it is the same size as the + * request. + */ + if (brq.data.blocks != req->nr_sectors) { + int i, data_size = brq.data.blocks << 9; + struct scatterlist *sg; + + for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { + data_size -= sg->length; + if (data_size <= 0) { + sg->length += data_size; + i++; + break; + } + } + brq.data.sg_len = i; + } + mmc_queue_bounce_pre(mq); mmc_wait_for_req(card->host, &brq.mrq); @@ -290,8 +317,16 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * until later as we need to wait for the card to leave * programming mode even when things go wrong. */ - if (brq.cmd.error || brq.data.error || brq.stop.error) + if (brq.cmd.error || brq.data.error || brq.stop.error) { + if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { + /* Redo read one sector at a time */ + printk(KERN_WARNING "%s: retrying using single " + "block read\n", req->rq_disk->disk_name); + disable_multi = 1; + continue; + } status = get_card_status(card, req); + } if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write " @@ -348,8 +383,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) #endif } - if (brq.cmd.error || brq.data.error || brq.stop.error) + if (brq.cmd.error || brq.stop.error || brq.data.error) { + if (rq_data_dir(req) == READ) { + /* + * After an error, we redo I/O one sector at a + * time, so we only reach here after trying to + * read a single sector. + */ + spin_lock_irq(&md->lock); + ret = __blk_end_request(req, -EIO, brq.data.blksz); + spin_unlock_irq(&md->lock); + continue; + } goto cmd_err; + } /* * A block was successfully transferred. @@ -371,25 +418,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * If the card is not SD, we can still ok written sectors * as reported by the controller (which might be less than * the real number of written sectors, but never more). - * - * For reads we just fail the entire chunk as that should - * be safe in all cases. */ - if (rq_data_dir(req) != READ) { - if (mmc_card_sd(card)) { - u32 blocks; + if (mmc_card_sd(card)) { + u32 blocks; - blocks = mmc_sd_num_wr_blocks(card); - if (blocks != (u32)-1) { - spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, blocks << 9); - spin_unlock_irq(&md->lock); - } - } else { + blocks = mmc_sd_num_wr_blocks(card); + if (blocks != (u32)-1) { spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, brq.data.bytes_xfered); + ret = __blk_end_request(req, 0, blocks << 9); spin_unlock_irq(&md->lock); } + } else { + spin_lock_irq(&md->lock); + ret = __blk_end_request(req, 0, brq.data.bytes_xfered); + spin_unlock_irq(&md->lock); } mmc_release_host(card->host); -- cgit v1.2.3-70-g09d2 From c00a46abd4d45a67ff62f4ff6d4f839dff38b877 Mon Sep 17 00:00:00 2001 From: Vernon Sauder Date: Mon, 29 Dec 2008 19:21:28 -0500 Subject: pxamci: fix dma_unmap_sg length dma_unmap_sg should be given the same length as dma_map_sg, not the value returned from dma_map_sg Signed-off-by: Vernon Sauder Signed-off-by: Pierre Ossman --- drivers/mmc/host/pxamci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index f88cc740635..3c5483b75da 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) return 0; DCSR(host->dma) = 0; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); if (stat & STAT_READ_TIME_OUT) -- cgit v1.2.3-70-g09d2 From 9c43df57910bbba540a6cb5c9132302a9ea5f41a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 30 Dec 2008 18:15:28 +0300 Subject: mmc_spi: Add support for OpenFirmware bindings The support is implemented via platform data accessors, new module (of_mmc_spi) will be created automatically when the driver compiles on OpenFirmware platforms. Link-time dependency will load the module automatically. Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman --- drivers/mmc/host/Makefile | 3 + drivers/mmc/host/mmc_spi.c | 4 +- drivers/mmc/host/of_mmc_spi.c | 149 ++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/mmc_spi.h | 15 ++++- 4 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/of_mmc_spi.c (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c794cc5ce44..f4853288bbb 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -19,6 +19,9 @@ obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o +ifeq ($(CONFIG_OF),y) +obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o +endif obj-$(CONFIG_MMC_S3C) += s3cmci.o obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index ad00e163231..87e211df68a 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1285,7 +1285,7 @@ static int mmc_spi_probe(struct spi_device *spi) /* Platform data is used to hook up things like card sensing * and power switching gpios. */ - host->pdata = spi->dev.platform_data; + host->pdata = mmc_spi_get_pdata(spi); if (host->pdata) mmc->ocr_avail = host->pdata->ocr_mask; if (!mmc->ocr_avail) { @@ -1368,6 +1368,7 @@ fail_glue_init: fail_nobuf1: mmc_free_host(mmc); + mmc_spi_put_pdata(spi); dev_set_drvdata(&spi->dev, NULL); nomem: @@ -1402,6 +1403,7 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) spi->max_speed_hz = mmc->f_max; mmc_free_host(mmc); + mmc_spi_put_pdata(spi); dev_set_drvdata(&spi->dev, NULL); } return 0; diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c new file mode 100644 index 00000000000..fb2921f8099 --- /dev/null +++ b/drivers/mmc/host/of_mmc_spi.c @@ -0,0 +1,149 @@ +/* + * OpenFirmware bindings for the MMC-over-SPI driver + * + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + CD_GPIO = 0, + WP_GPIO, + NUM_GPIOS, +}; + +struct of_mmc_spi { + int gpios[NUM_GPIOS]; + bool alow_gpios[NUM_GPIOS]; + struct mmc_spi_platform_data pdata; +}; + +static struct of_mmc_spi *to_of_mmc_spi(struct device *dev) +{ + return container_of(dev->platform_data, struct of_mmc_spi, pdata); +} + +static int of_mmc_spi_read_gpio(struct device *dev, int gpio_num) +{ + struct of_mmc_spi *oms = to_of_mmc_spi(dev); + bool active_low = oms->alow_gpios[gpio_num]; + bool value = gpio_get_value(oms->gpios[gpio_num]); + + return active_low ^ value; +} + +static int of_mmc_spi_get_cd(struct device *dev) +{ + return of_mmc_spi_read_gpio(dev, CD_GPIO); +} + +static int of_mmc_spi_get_ro(struct device *dev) +{ + return of_mmc_spi_read_gpio(dev, WP_GPIO); +} + +struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct of_mmc_spi *oms; + const u32 *voltage_ranges; + int num_ranges; + int i; + int ret = -EINVAL; + + if (dev->platform_data || !np) + return dev->platform_data; + + oms = kzalloc(sizeof(*oms), GFP_KERNEL); + if (!oms) + return NULL; + + voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); + num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; + if (!voltage_ranges || !num_ranges) { + dev_err(dev, "OF: voltage-ranges unspecified\n"); + goto err_ocr; + } + + for (i = 0; i < num_ranges; i++) { + const int j = i * 2; + u32 mask; + + mask = mmc_vddrange_to_ocrmask(voltage_ranges[j], + voltage_ranges[j + 1]); + if (!mask) { + ret = -EINVAL; + dev_err(dev, "OF: voltage-range #%d is invalid\n", i); + goto err_ocr; + } + oms->pdata.ocr_mask |= mask; + } + + for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { + enum of_gpio_flags gpio_flags; + + oms->gpios[i] = of_get_gpio_flags(np, i, &gpio_flags); + if (!gpio_is_valid(oms->gpios[i])) + continue; + + ret = gpio_request(oms->gpios[i], dev->bus_id); + if (ret < 0) { + oms->gpios[i] = -EINVAL; + continue; + } + + if (gpio_flags & OF_GPIO_ACTIVE_LOW) + oms->alow_gpios[i] = true; + } + + if (gpio_is_valid(oms->gpios[CD_GPIO])) + oms->pdata.get_cd = of_mmc_spi_get_cd; + if (gpio_is_valid(oms->gpios[WP_GPIO])) + oms->pdata.get_ro = of_mmc_spi_get_ro; + + /* We don't support interrupts yet, let's poll. */ + oms->pdata.caps |= MMC_CAP_NEEDS_POLL; + + dev->platform_data = &oms->pdata; + return dev->platform_data; +err_ocr: + kfree(oms); + return NULL; +} +EXPORT_SYMBOL(mmc_spi_get_pdata); + +void mmc_spi_put_pdata(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct of_mmc_spi *oms = to_of_mmc_spi(dev); + int i; + + if (!dev->platform_data || !np) + return; + + for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { + if (gpio_is_valid(oms->gpios[i])) + gpio_free(oms->gpios[i]); + } + kfree(oms); + dev->platform_data = NULL; +} +EXPORT_SYMBOL(mmc_spi_put_pdata); diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h index a3626aedaec..0f4eb165f25 100644 --- a/include/linux/spi/mmc_spi.h +++ b/include/linux/spi/mmc_spi.h @@ -1,9 +1,10 @@ #ifndef __LINUX_SPI_MMC_SPI_H #define __LINUX_SPI_MMC_SPI_H +#include +#include #include -struct device; struct mmc_host; /* Put this in platform_data of a device being used to manage an MMC/SD @@ -41,4 +42,16 @@ struct mmc_spi_platform_data { void (*setpower)(struct device *, unsigned int maskval); }; +#ifdef CONFIG_OF +extern struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi); +extern void mmc_spi_put_pdata(struct spi_device *spi); +#else +static inline struct mmc_spi_platform_data * +mmc_spi_get_pdata(struct spi_device *spi) +{ + return spi->dev.platform_data; +} +static inline void mmc_spi_put_pdata(struct spi_device *spi) {} +#endif /* CONFIG_OF */ + #endif /* __LINUX_SPI_MMC_SPI_H */ -- cgit v1.2.3-70-g09d2 From f6e10b865c3ea56bdaa8c6ecfee313b997900dbb Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 31 Dec 2008 09:50:30 -0800 Subject: mmc: warn about voltage mismatches Get rid of a silent failure mode when the MMC/SD host doesn't support the voltages needed to operate a given card, by adding a warning. A 3.3V host and a 3.0V card, for example, no longer need to mysteriously just not work at all. This isn't the best diagnostic; ideally it would also tell what voltage the card and host support (and not just by dumping the bitmasks). Signed-off-by: David Brownell Signed-off-by: Pierre Ossman --- drivers/mmc/core/core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mmc') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5f288aeeb72..df6ce4a06cf 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -542,6 +542,8 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) host->ios.vdd = bit; mmc_set_ios(host); } else { + pr_warning("%s: host doesn't support card's voltages\n", + mmc_hostname(host)); ocr = 0; } -- cgit v1.2.3-70-g09d2