From ad68bb9f7a3cd47396635a5e3895215af57579da Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 3 Nov 2010 16:29:35 +0100 Subject: ARM: pxa: Access SMEMC via virtual addresses This is important because on PXA3xx, the physical mapping of SMEMC registers differs from the one on PXA2xx. In order to get PCMCIA working on both PXA2xx and PXA320, the PCMCIA driver was adjusted accordingly as well. Also, various places in the kernel had to be patched to use __raw_read/__raw_write. Signed-off-by: Marek Vasut Acked-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_base.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index ae07b4d..55a7d0b 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -116,37 +117,49 @@ static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz, static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) { - MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock) + uint32_t val; + + val = ((pxa2xx_mcxx_setup(speed, clock) & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | ((pxa2xx_mcxx_asst(speed, clock) & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); + __raw_writel(val, MCMEM(sock)); + return 0; } static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) { - MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock) + uint32_t val; + + val = ((pxa2xx_mcxx_setup(speed, clock) & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | ((pxa2xx_mcxx_asst(speed, clock) & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); + __raw_writel(val, MCIO(sock)); + return 0; } static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) { - MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock) + uint32_t val; + + val = ((pxa2xx_mcxx_setup(speed, clock) & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | ((pxa2xx_mcxx_asst(speed, clock) & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); + __raw_writel(val, MCATT(sock)); + return 0; } @@ -205,19 +218,18 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, static void pxa2xx_configure_sockets(struct device *dev) { struct pcmcia_low_level *ops = dev->platform_data; - /* * We have at least one socket, so set MECR:CIT * (Card Is There) */ - MECR |= MECR_CIT; + uint32_t mecr = MECR_CIT; /* Set MECR:NOS (Number Of Sockets) */ if ((ops->first + ops->nr) > 1 || machine_is_viper() || machine_is_arcom_zeus()) - MECR |= MECR_NOS; - else - MECR &= ~MECR_NOS; + mecr |= MECR_NOS; + + __raw_writel(mecr, MECR); } static const char *skt_names[] = { -- cgit v1.1 From 2a125dd56b3a853701063fe8a678ad7603e385fd Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 22 Nov 2010 22:48:49 +0800 Subject: ARM: pxa: remove get_memclk_frequency_10khz() Introduce 'struct clk' for memory and remove get_memclk_frequency_10khz(). Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_base.c | 17 ++++++++++++++--- drivers/pcmcia/soc_common.h | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 55a7d0b..3c01774 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -179,8 +179,8 @@ static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int cl static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) { - unsigned int clk = get_memclk_frequency_10khz(); - return pxa2xx_pcmcia_set_mcxx(skt, clk); + unsigned long clk = clk_get_rate(skt->clk); + return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000); } #ifdef CONFIG_CPU_FREQ @@ -282,24 +282,33 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) struct pcmcia_low_level *ops; struct skt_dev_info *sinfo; struct soc_pcmcia_socket *skt; + struct clk *clk; ops = (struct pcmcia_low_level *)dev->dev.platform_data; if (!ops) return -ENODEV; + clk = clk_get(&dev->dev, NULL); + if (!clk) + return -ENODEV; + pxa2xx_drv_pcmcia_ops(ops); sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); - if (!sinfo) + if (!sinfo) { + clk_put(clk); return -ENOMEM; + } sinfo->nskt = ops->nr; + sinfo->clk = clk; /* Initialize processor specific parameters */ for (i = 0; i < ops->nr; i++) { skt = &sinfo->skt[i]; skt->nr = ops->first + i; + skt->clk = clk; skt->ops = ops; skt->socket.owner = ops->owner; skt->socket.dev.parent = &dev->dev; @@ -314,6 +323,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) while (--i >= 0) soc_pcmcia_remove_one(&sinfo->skt[i]); kfree(sinfo); + clk_put(clk); } else { pxa2xx_configure_sockets(&dev->dev); dev_set_drvdata(&dev->dev, sinfo); @@ -332,6 +342,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) for (i = 0; i < sinfo->nskt; i++) soc_pcmcia_remove_one(&sinfo->skt[i]); + clk_put(sinfo->clk); kfree(sinfo); return 0; } diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index bbcd538..9daa736 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -10,6 +10,7 @@ #define _ASM_ARCH_PCMCIA /* include the world */ +#include #include #include #include @@ -29,6 +30,7 @@ struct soc_pcmcia_socket { * Info from low level handler */ unsigned int nr; + struct clk *clk; /* * Core PCMCIA state @@ -56,6 +58,7 @@ struct soc_pcmcia_socket { struct skt_dev_info { int nskt; + struct clk *clk; struct soc_pcmcia_socket skt[0]; }; -- cgit v1.1 From a4257af5b0c5479bb81597579841e9daaeccd7f6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 3 Nov 2010 16:26:42 +0100 Subject: ARM: pxa: Add pxa320 PCMCIA check On PXA320, there's only one PCMCIA slot available. Check for cases where the user would want to register multiple. Also, rework failpath. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_base.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 3c01774..3755e7c 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -285,8 +285,16 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) struct clk *clk; ops = (struct pcmcia_low_level *)dev->dev.platform_data; - if (!ops) - return -ENODEV; + if (!ops) { + ret = -ENODEV; + goto err0; + } + + if (cpu_is_pxa320() && ops->nr > 1) { + dev_err(&dev->dev, "pxa320 supports only one pcmcia slot"); + ret = -EINVAL; + goto err0; + } clk = clk_get(&dev->dev, NULL); if (!clk) @@ -316,7 +324,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) ret = pxa2xx_drv_pcmcia_add_one(skt); if (ret) - break; + goto err1; } if (ret) { @@ -329,6 +337,13 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) dev_set_drvdata(&dev->dev, sinfo); } + return 0; + +err1: + while (--i >= 0) + soc_pcmcia_remove_one(&sinfo->skt[i]); + kfree(sinfo); +err0: return ret; } -- cgit v1.1 From 960c0acaabf603e39b121ae5c0580aaca6f8aa7b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 11 Aug 2010 03:32:53 +0200 Subject: ARM: pxa: Toradex Colibri PXA270 CF support This driver also contains structures to eventually support PXA320. This is planned to be added in a later patch. Signed-off-by: Marek Vasut Acked-by: Daniel Mack Signed-off-by: Eric Miao --- drivers/pcmcia/Kconfig | 2 +- drivers/pcmcia/Makefile | 1 + drivers/pcmcia/pxa2xx_colibri.c | 214 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 drivers/pcmcia/pxa2xx_colibri.c (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index c80a7a6..e9acf03 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -215,7 +215,7 @@ config PCMCIA_PXA2XX depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ - || MACH_VPAC270 || MACH_BALLOON3) + || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI) select PCMCIA_SOC_COMMON help Say Y here to include support for the PXA2xx PCMCIA controller diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 8d9386a..2fee7ef 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -70,6 +70,7 @@ pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o +pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c new file mode 100644 index 0000000..4ed876c --- /dev/null +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -0,0 +1,214 @@ +/* + * linux/drivers/pcmcia/pxa2xx_colibri.c + * + * Driver for Toradex Colibri PXA270 CF socket + * + * Copyright (C) 2010 Marek Vasut + * + * 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 "soc_common.h" + +#define COLIBRI270_RESET_GPIO 53 +#define COLIBRI270_PPEN_GPIO 107 +#define COLIBRI270_BVD1_GPIO 83 +#define COLIBRI270_BVD2_GPIO 82 +#define COLIBRI270_DETECT_GPIO 84 +#define COLIBRI270_READY_GPIO 1 + +static struct { + int reset_gpio; + int ppen_gpio; + int bvd1_gpio; + int bvd2_gpio; + int detect_gpio; + int ready_gpio; +} colibri_pcmcia_gpio; + +static struct pcmcia_irqs colibri_irqs[] = { + { + .sock = 0, + .str = "PCMCIA CD" + }, +}; + +static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret; + + ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT"); + if (ret) + goto err1; + ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio); + if (ret) + goto err2; + + ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY"); + if (ret) + goto err2; + ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio); + if (ret) + goto err3; + + ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1"); + if (ret) + goto err3; + ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio); + if (ret) + goto err4; + + ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); + if (ret) + goto err4; + ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio); + if (ret) + goto err5; + + ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN"); + if (ret) + goto err5; + ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0); + if (ret) + goto err6; + + ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET"); + if (ret) + goto err6; + ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1); + if (ret) + goto err7; + + colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio); + skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio); + + return soc_pcmcia_request_irqs(skt, colibri_irqs, + ARRAY_SIZE(colibri_irqs)); + +err7: + gpio_free(colibri_pcmcia_gpio.detect_gpio); +err6: + gpio_free(colibri_pcmcia_gpio.ready_gpio); +err5: + gpio_free(colibri_pcmcia_gpio.bvd1_gpio); +err4: + gpio_free(colibri_pcmcia_gpio.bvd2_gpio); +err3: + gpio_free(colibri_pcmcia_gpio.reset_gpio); +err2: + gpio_free(colibri_pcmcia_gpio.ppen_gpio); +err1: + return ret; +} + +static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + gpio_free(colibri_pcmcia_gpio.detect_gpio); + gpio_free(colibri_pcmcia_gpio.ready_gpio); + gpio_free(colibri_pcmcia_gpio.bvd1_gpio); + gpio_free(colibri_pcmcia_gpio.bvd2_gpio); + gpio_free(colibri_pcmcia_gpio.reset_gpio); + gpio_free(colibri_pcmcia_gpio.ppen_gpio); +} + +static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + + state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); + state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); + state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); + state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); + state->wrprot = 0; + state->vs_3v = 1; + state->vs_Xv = 0; +} + +static int +colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + gpio_set_value(colibri_pcmcia_gpio.ppen_gpio, + !(state->Vcc == 33 && state->Vpp < 50)); + gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET); + return 0; +} + +static void colibri_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void colibri_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level colibri_pcmcia_ops = { + .owner = THIS_MODULE, + + .first = 0, + .nr = 1, + + .hw_init = colibri_pcmcia_hw_init, + .hw_shutdown = colibri_pcmcia_hw_shutdown, + + .socket_state = colibri_pcmcia_socket_state, + .configure_socket = colibri_pcmcia_configure_socket, + + .socket_init = colibri_pcmcia_socket_init, + .socket_suspend = colibri_pcmcia_socket_suspend, +}; + +static struct platform_device *colibri_pcmcia_device; + +static int __init colibri_pcmcia_init(void) +{ + int ret; + + colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); + if (!colibri_pcmcia_device) + return -ENOMEM; + + /* Colibri PXA270 */ + if (machine_is_colibri()) { + colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; + colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; + colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; + colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; + colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; + colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; + } + + ret = platform_device_add_data(colibri_pcmcia_device, + &colibri_pcmcia_ops, sizeof(colibri_pcmcia_ops)); + + if (!ret) + ret = platform_device_add(colibri_pcmcia_device); + + if (ret) + platform_device_put(colibri_pcmcia_device); + + return ret; +} + +static void __exit colibri_pcmcia_exit(void) +{ + platform_device_unregister(colibri_pcmcia_device); +} + +module_init(colibri_pcmcia_init); +module_exit(colibri_pcmcia_exit); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270"); +MODULE_ALIAS("platform:pxa2xx-pcmcia"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From fd62999bad9fc3b176ef6bc9d2a71be940efd908 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 11 Aug 2010 05:04:53 +0200 Subject: ARM: pxa: Colibri PXA320 PCMCIA driver Signed-off-by: Marek Vasut Acked-by: Daniel Mack Signed-off-by: Eric Miao --- drivers/pcmcia/Kconfig | 3 ++- drivers/pcmcia/Makefile | 1 + drivers/pcmcia/pxa2xx_colibri.c | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index e9acf03..de886f3 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -215,7 +215,8 @@ config PCMCIA_PXA2XX depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ - || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI) + || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ + || MACH_COLIBRI320) select PCMCIA_SOC_COMMON help Say Y here to include support for the PXA2xx PCMCIA controller diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 2fee7ef..9a44a90 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -71,6 +71,7 @@ pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o +pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index 4ed876c..c3f7219 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -27,6 +27,13 @@ #define COLIBRI270_DETECT_GPIO 84 #define COLIBRI270_READY_GPIO 1 +#define COLIBRI320_RESET_GPIO 77 +#define COLIBRI320_PPEN_GPIO 57 +#define COLIBRI320_BVD1_GPIO 53 +#define COLIBRI320_BVD2_GPIO 79 +#define COLIBRI320_DETECT_GPIO 81 +#define COLIBRI320_READY_GPIO 29 + static struct { int reset_gpio; int ppen_gpio; @@ -186,6 +193,14 @@ static int __init colibri_pcmcia_init(void) colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; + /* Colibri PXA320 */ + } else if (machine_is_colibri320()) { + colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; + colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; + colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; + colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; + colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; + colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; } ret = platform_device_add_data(colibri_pcmcia_device, @@ -209,6 +224,6 @@ module_init(colibri_pcmcia_init); module_exit(colibri_pcmcia_exit); MODULE_AUTHOR("Marek Vasut "); -MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270"); +MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270/PXA320"); MODULE_ALIAS("platform:pxa2xx-pcmcia"); MODULE_LICENSE("GPL"); -- cgit v1.1 From 1b9169d8a0fe2b41fbbb8d152c8108190865f3cf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 19 Oct 2010 16:19:32 +0200 Subject: ARM: pxa: Update Balloon3 for new FPGA firmware The new FPGA firmware in Balloon3 uses different methods to control it's bus control lines. In the new version, there are separate registers to set/clear bus control lines. This patch updates affected places. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_balloon3.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index dbbdd00..453c54c 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c @@ -39,12 +39,10 @@ static struct pcmcia_irqs irqs[] = { static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { uint16_t ver; - int ret; - static void __iomem *fpga_ver; ver = __raw_readw(BALLOON3_FPGA_VER); - if (ver > 0x0201) - pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " + if (ver < 0x4f08) + pr_warn("The FPGA code, version 0x%04x, is too old. " "PCMCIA/CF support might be broken in this version!", ver); @@ -97,8 +95,9 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { - __raw_writew((state->flags & SS_RESET) ? BALLOON3_CF_RESET : 0, - BALLOON3_CF_CONTROL_REG); + __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG | + ((state->flags & SS_RESET) ? + BALLOON3_FPGA_SETnCLR : 0)); return 0; } -- cgit v1.1