diff options
Diffstat (limited to 'target/linux/pxa/patches/005-verdex_pcmcia_support.patch')
-rw-r--r-- | target/linux/pxa/patches/005-verdex_pcmcia_support.patch | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/target/linux/pxa/patches/005-verdex_pcmcia_support.patch b/target/linux/pxa/patches/005-verdex_pcmcia_support.patch new file mode 100644 index 0000000000..ca50022c67 --- /dev/null +++ b/target/linux/pxa/patches/005-verdex_pcmcia_support.patch @@ -0,0 +1,234 @@ +From 76a102bd5c9d792db19c6c72eafdecea0311a0c9 Mon Sep 17 00:00:00 2001 +From: Craig Hughes <craig@gumstix.com> +Date: Fri, 30 Oct 2009 14:16:27 -0400 +Subject: [PATCH] [ARM] pxa: Gumstix Verdex PCMCIA support + +Needed for the Libertas CS wireless device. + +Signed-off-by: Bobby Powers <bobbypowers@gmail.com> +--- + drivers/pcmcia/Kconfig | 3 +- + drivers/pcmcia/Makefile | 3 + + drivers/pcmcia/pxa2xx_gumstix.c | 194 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 199 insertions(+), 1 deletions(-) + create mode 100644 drivers/pcmcia/pxa2xx_gumstix.c + +--- a/drivers/pcmcia/Kconfig ++++ b/drivers/pcmcia/Kconfig +@@ -221,7 +221,8 @@ config PCMCIA_PXA2XX + depends on ARM && ARCH_PXA && PCMCIA + depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ + || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ +- || ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2) ++ || ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2 \ ++ || ARCH_GUMSTIX) + help + Say Y here to include support for the PXA2xx PCMCIA controller + +--- a/drivers/pcmcia/Makefile ++++ b/drivers/pcmcia/Makefile +@@ -77,4 +77,7 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa + pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o + pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o + ++pxa2xx-obj-$(CONFIG_MACH_GUMSTIX_VERDEX) += pxa2xx_cs.o ++pxa2xx_cs-objs := pxa2xx_gumstix.o ++ + obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y) +--- /dev/null ++++ b/drivers/pcmcia/pxa2xx_gumstix.c +@@ -0,0 +1,194 @@ ++/* ++ * linux/drivers/pcmcia/pxa2xx_gumstix.c ++ * ++ * Gumstix PCMCIA specific routines. Based on Mainstone ++ * ++ * Copyright 2004, Craig Hughes <craig@gumstix.com> ++ * ++ * 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 <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/gpio.h> ++ ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++ ++#include <pcmcia/ss.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_GUMSTIX_VERDEX ++#include <mach/pxa27x.h> ++#else ++#include <mach/pxa27x.h> ++#endif ++ ++#include <asm/io.h> ++#include <mach/gpio.h> ++#include <mach/gumstix.h> ++#include "soc_common.h" ++ ++#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) ++ ++static struct pcmcia_irqs gumstix_pcmcia_irqs0[] = { ++ { 0, GUMSTIX_S0_nCD_IRQ, "CF0 nCD" }, ++ { 0, GUMSTIX_S0_nSTSCHG_IRQ, "CF0 nSTSCHG" }, ++}; ++ ++static struct pcmcia_irqs gumstix_pcmcia_irqs1[] = { ++ { 1, GUMSTIX_S1_nCD_IRQ, "CF1 nCD" }, ++ { 1, GUMSTIX_S1_nSTSCHG_IRQ, "CF1 nSTSCHG" }, ++}; ++ ++ ++static int net_cf_vx_mode = 0; ++ ++static int gumstix_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ++{ ++/* Note: The verdex_pcmcia_pin_config is moved to gumstix_verdex.c in order to use mfp_pxa2xx_config ++ for board-specific pin configuration instead of the old deprecated pxa_gpio_mode function. Thus, ++ only the IRQ init is still needed to be done here. */ ++ skt->irq = (skt->nr == 0) ? ((net_cf_vx_mode == 0) ? GUMSTIX_S0_PRDY_nBSY_IRQ : GUMSTIX_S0_PRDY_nBSY_OLD_IRQ) : GUMSTIX_S1_PRDY_nBSY_IRQ; ++ ++ return (skt->nr == 0) ? soc_pcmcia_request_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0)) : ++ soc_pcmcia_request_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1)); ++} ++ ++static void gumstix_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) ++{ ++ if(skt->nr == 0) ++ { ++ soc_pcmcia_free_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0)); ++ } else { ++ soc_pcmcia_free_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1)); ++ } ++ ++ if (net_cf_vx_mode) { ++ gpio_free(GPIO_GUMSTIX_CF_OLD_RESET); ++ } else { ++ gpio_free(GPIO_GUMSTIX_CF_RESET); ++ } ++ ++} ++ ++static void gumstix_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ++ struct pcmcia_state *state) ++{ ++ unsigned int cd, prdy_nbsy, nbvd1; ++ if(skt->nr == 0) ++ { ++ cd = GPIO_GUMSTIX_nCD_0; ++ if(net_cf_vx_mode) ++ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_0_OLD; ++ else ++ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_0; ++ nbvd1 = GPIO_GUMSTIX_nBVD1_0; ++ } else { ++ cd = GPIO_GUMSTIX_nCD_1; ++ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_1; ++ nbvd1 = GPIO_GUMSTIX_nBVD1_1; ++ } ++ state->detect = !(GPLR(cd) & GPIO_bit(cd)); ++ state->ready = !!(GPLR(prdy_nbsy) & GPIO_bit(prdy_nbsy)); ++ state->bvd1 = !!(GPLR(nbvd1) & GPIO_bit(nbvd1)); ++ state->bvd2 = 1; ++ state->vs_3v = 0; ++ state->vs_Xv = 0; ++ state->wrprot = 0; ++} ++ ++static int gumstix_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ++ const socket_state_t *state) ++{ ++ return 0; ++} ++ ++static void gumstix_pcmcia_socket_init(struct soc_pcmcia_socket *skt) ++{ ++ if(skt->nr) { ++ soc_pcmcia_enable_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0)); ++ } else { ++ soc_pcmcia_enable_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1)); ++ } ++} ++ ++static void gumstix_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) ++{ ++ if(skt->nr) { ++ soc_pcmcia_disable_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0)); ++ } else { ++ soc_pcmcia_disable_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1)); ++ } ++} ++ ++static struct pcmcia_low_level gumstix_pcmcia_ops = { ++ .owner = THIS_MODULE, ++ .hw_init = gumstix_pcmcia_hw_init, ++ .hw_shutdown = gumstix_pcmcia_hw_shutdown, ++ .socket_state = gumstix_pcmcia_socket_state, ++ .configure_socket = gumstix_pcmcia_configure_socket, ++ .socket_init = gumstix_pcmcia_socket_init, ++ .socket_suspend = gumstix_pcmcia_socket_suspend, ++ .nr = 2, ++}; ++ ++static struct platform_device *gumstix_pcmcia_device; ++ ++extern int __init gumstix_get_cf_cards(void); ++ ++#ifdef CONFIG_MACH_GUMSTIX_VERDEX ++extern int __init gumstix_check_if_netCF_vx(void); ++#endif ++ ++static int __init gumstix_pcmcia_init(void) ++{ ++ int ret; ++ ++#ifdef CONFIG_MACH_GUMSTIX_VERDEX ++ net_cf_vx_mode = gumstix_check_if_netCF_vx(); ++#endif ++ ++ gumstix_pcmcia_ops.nr = gumstix_get_cf_cards(); ++ ++ gumstix_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); ++ if (!gumstix_pcmcia_device) ++ return -ENOMEM; ++ ++ ret = platform_device_add_data(gumstix_pcmcia_device, &gumstix_pcmcia_ops, ++ sizeof(gumstix_pcmcia_ops)); ++ ++ if (ret == 0) { ++ printk(KERN_INFO "Registering gumstix PCMCIA interface.\n"); ++ ret = platform_device_add(gumstix_pcmcia_device); ++ } ++ ++ if (ret) ++ platform_device_put(gumstix_pcmcia_device); ++ ++ return ret; ++} ++ ++static void __exit gumstix_pcmcia_exit(void) ++{ ++ /* ++ * This call is supposed to free our gumstix_pcmcia_device. ++ * Unfortunately platform_device don't have a free method, and ++ * we can't assume it's free of any reference at this point so we ++ * can't free it either. ++ */ ++ platform_device_unregister(gumstix_pcmcia_device); ++} ++ ++fs_initcall(gumstix_pcmcia_init); ++module_exit(gumstix_pcmcia_exit); ++ ++MODULE_LICENSE("GPL"); |