diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-09 09:26:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-09 09:26:36 -0700 |
commit | 7886e8aa7ff59198271ac650878eb247627a8b9a (patch) | |
tree | ac6f337a50d43db95e489517296247f10a6d10b9 /drivers/pcmcia | |
parent | 4a1e00524cbdd38567e36f9c54a0444deebd864a (diff) | |
parent | 64b2f129c38713a059e1299662fc68fc6bf6f0a6 (diff) | |
download | blackbird-op-linux-7886e8aa7ff59198271ac650878eb247627a8b9a.tar.gz blackbird-op-linux-7886e8aa7ff59198271ac650878eb247627a8b9a.zip |
Merge branch 'for-linus-sa1100' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM SA1100 updates from Russell King:
"We have support for arbitary MMIO registers providing platform GPIOs,
which allows us to abstract some of the SA11x0 CF support.
This set of updates makes that change"
* 'for-linus-sa1100' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: sa1100/simpad: switch simpad CF to use gpiod APIs
ARM: sa1100/shannon: convert to generic CF sockets
ARM: sa1100/nanoengine: convert to generic CF sockets
ARM: sa1100/h3xxx: switch h3xxx PCMCIA to use gpiod APIs
ARM: sa1100/cerf: convert to generic CF sockets
ARM: sa1100/assabet: convert to generic CF sockets
ARM: sa1100: provide infrastructure to support generic CF sockets
pcmcia: sa1100: provide generic CF support
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/Makefile | 4 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_assabet.c | 100 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_cerf.c | 86 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_generic.c | 115 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_generic.h | 4 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_h3600.c | 16 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_nanoengine.c | 133 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_shannon.c | 104 | ||||
-rw-r--r-- | drivers/pcmcia/sa1100_simpad.c | 12 |
9 files changed, 108 insertions, 466 deletions
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index f1f89ddb1bfd..28502bd159e0 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -43,13 +43,9 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o sa1100_cs-y += sa1100_generic.o -sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o -sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o -sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o -sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c deleted file mode 100644 index 78ad2bba76db..000000000000 --- a/drivers/pcmcia/sa1100_assabet.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * drivers/pcmcia/sa1100_assabet.c - * - * PCMCIA implementation routines for Assabet - * - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/gpio.h> - -#include <asm/mach-types.h> -#include <mach/assabet.h> - -#include "sa1100_generic.h" - -static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -{ - skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; - skt->stat[SOC_STAT_CD].name = "CF CD"; - skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; - skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; - skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; - skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; - skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; - skt->stat[SOC_STAT_RDY].name = "CF RDY"; - - return 0; -} - -static int -assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) -{ - unsigned int mask; - - switch (state->Vcc) { - case 0: - mask = 0; - break; - - case 50: - printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", - __func__); - - case 33: /* Can only apply 3.3V to the CF slot. */ - mask = ASSABET_BCR_CF_PWR; - break; - - default: - printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, - state->Vcc); - return -1; - } - - /* Silently ignore Vpp, speaker enable. */ - - if (state->flags & SS_RESET) - mask |= ASSABET_BCR_CF_RST; - if (!(state->flags & SS_OUTPUT_ENA)) - mask |= ASSABET_BCR_CF_BUS_OFF; - - ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | - ASSABET_BCR_CF_BUS_OFF, mask); - - return 0; -} - -/* - * Disable card status IRQs on suspend. - */ -static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - /* - * Tristate the CF bus signals. Also assert CF - * reset as per user guide page 4-11. - */ - ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); -} - -static struct pcmcia_low_level assabet_pcmcia_ops = { - .owner = THIS_MODULE, - .hw_init = assabet_pcmcia_hw_init, - .socket_state = soc_common_cf_socket_state, - .configure_socket = assabet_pcmcia_configure_socket, - .socket_suspend = assabet_pcmcia_socket_suspend, -}; - -int pcmcia_assabet_init(struct device *dev) -{ - int ret = -ENODEV; - - if (machine_is_assabet() && !machine_has_neponset()) - ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1); - - return ret; -} diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c deleted file mode 100644 index 2a54081d161d..000000000000 --- a/drivers/pcmcia/sa1100_cerf.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * drivers/pcmcia/sa1100_cerf.c - * - * PCMCIA implementation routines for CerfBoard - * Based off the Assabet. - * - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/gpio.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/irq.h> -#include <mach/cerf.h> -#include "sa1100_generic.h" - -#define CERF_SOCKET 1 - -static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -{ - int ret; - - ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET"); - if (ret) - return ret; - - skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD; - skt->stat[SOC_STAT_CD].name = "CF_CD"; - skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1; - skt->stat[SOC_STAT_BVD1].name = "CF_BVD1"; - skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2; - skt->stat[SOC_STAT_BVD2].name = "CF_BVD2"; - skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ; - skt->stat[SOC_STAT_RDY].name = "CF_IRQ"; - - return 0; -} - -static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - gpio_free(CERF_GPIO_CF_RESET); -} - -static int -cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, - const socket_state_t *state) -{ - switch (state->Vcc) { - case 0: - case 50: - case 33: - break; - - default: - printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); - return -1; - } - - gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET)); - - return 0; -} - -static struct pcmcia_low_level cerf_pcmcia_ops = { - .owner = THIS_MODULE, - .hw_init = cerf_pcmcia_hw_init, - .hw_shutdown = cerf_pcmcia_hw_shutdown, - .socket_state = soc_common_cf_socket_state, - .configure_socket = cerf_pcmcia_configure_socket, -}; - -int pcmcia_cerf_init(struct device *dev) -{ - int ret = -ENODEV; - - if (machine_is_cerf()) - ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1); - - return ret; -} diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 66acdc85727c..47b060c57418 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -31,7 +31,9 @@ ======================================================================*/ #include <linux/module.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/platform_device.h> @@ -41,24 +43,64 @@ #include "sa1100_generic.h" +static const char *sa11x0_cf_gpio_names[] = { + [SOC_STAT_CD] = "detect", + [SOC_STAT_BVD1] = "bvd1", + [SOC_STAT_BVD2] = "bvd2", + [SOC_STAT_RDY] = "ready", +}; + +static int sa11x0_cf_hw_init(struct soc_pcmcia_socket *skt) +{ + struct device *dev = skt->socket.dev.parent; + int i; + + skt->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(skt->gpio_reset)) + return PTR_ERR(skt->gpio_reset); + + skt->gpio_bus_enable = devm_gpiod_get_optional(dev, "bus-enable", + GPIOD_OUT_HIGH); + if (IS_ERR(skt->gpio_bus_enable)) + return PTR_ERR(skt->gpio_bus_enable); + + skt->vcc.reg = devm_regulator_get_optional(dev, "vcc"); + if (IS_ERR(skt->vcc.reg)) + return PTR_ERR(skt->vcc.reg); + + if (!skt->vcc.reg) + dev_warn(dev, + "no Vcc regulator provided, ignoring Vcc controls\n"); + + for (i = 0; i < ARRAY_SIZE(sa11x0_cf_gpio_names); i++) { + skt->stat[i].name = sa11x0_cf_gpio_names[i]; + skt->stat[i].desc = devm_gpiod_get_optional(dev, + sa11x0_cf_gpio_names[i], GPIOD_IN); + if (IS_ERR(skt->stat[i].desc)) + return PTR_ERR(skt->stat[i].desc); + } + return 0; +} + +static int sa11x0_cf_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc); +} + +static struct pcmcia_low_level sa11x0_cf_ops = { + .owner = THIS_MODULE, + .hw_init = sa11x0_cf_hw_init, + .socket_state = soc_common_cf_socket_state, + .configure_socket = sa11x0_cf_configure_socket, +}; + int __init pcmcia_collie_init(struct device *dev); -static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { -#ifdef CONFIG_SA1100_ASSABET - pcmcia_assabet_init, -#endif -#ifdef CONFIG_SA1100_CERF - pcmcia_cerf_init, -#endif +static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = { #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) pcmcia_h3600_init, #endif -#ifdef CONFIG_SA1100_NANOENGINE - pcmcia_nanoengine_init, -#endif -#ifdef CONFIG_SA1100_SHANNON - pcmcia_shannon_init, -#endif #ifdef CONFIG_SA1100_SIMPAD pcmcia_simpad_init, #endif @@ -67,15 +109,15 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { #endif }; -static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) +static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev) { int i, ret = -ENODEV; /* * Initialise any "on-board" PCMCIA sockets. */ - for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { - ret = sa11x0_pcmcia_hw_init[i](&dev->dev); + for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) { + ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev); if (ret == 0) break; } @@ -83,7 +125,7 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) return ret; } -static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) +static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev) { struct skt_dev_info *sinfo = platform_get_drvdata(dev); int i; @@ -96,6 +138,45 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) return 0; } +static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev) +{ + struct soc_pcmcia_socket *skt; + struct device *dev = &pdev->dev; + + if (pdev->id == -1) + return sa11x0_drv_pcmcia_legacy_probe(pdev); + + skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL); + if (!skt) + return -ENOMEM; + + platform_set_drvdata(pdev, skt); + + skt->nr = pdev->id; + skt->clk = devm_clk_get(dev, NULL); + if (IS_ERR(skt->clk)) + return PTR_ERR(skt->clk); + + sa11xx_drv_pcmcia_ops(&sa11x0_cf_ops); + soc_pcmcia_init_one(skt, &sa11x0_cf_ops, dev); + + return sa11xx_drv_pcmcia_add_one(skt); +} + +static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) +{ + struct soc_pcmcia_socket *skt; + + if (dev->id == -1) + return sa11x0_drv_pcmcia_legacy_remove(dev); + + skt = platform_get_drvdata(dev); + + soc_pcmcia_remove_one(skt); + + return 0; +} + static struct platform_driver sa11x0_pcmcia_driver = { .driver = { .name = "sa11x0-pcmcia", diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h index a5f1f1dd63cb..7b7cdcd20187 100644 --- a/drivers/pcmcia/sa1100_generic.h +++ b/drivers/pcmcia/sa1100_generic.h @@ -6,18 +6,14 @@ * Declaration for all machine specific init/exit functions. */ extern int pcmcia_adsbitsy_init(struct device *); -extern int pcmcia_assabet_init(struct device *); extern int pcmcia_badge4_init(struct device *); -extern int pcmcia_cerf_init(struct device *); extern int pcmcia_flexanet_init(struct device *); extern int pcmcia_freebird_init(struct device *); extern int pcmcia_gcplus_init(struct device *); extern int pcmcia_graphicsmaster_init(struct device *); extern int pcmcia_h3600_init(struct device *); -extern int pcmcia_nanoengine_init(struct device *); extern int pcmcia_pangolin_init(struct device *); extern int pcmcia_pfs168_init(struct device *); -extern int pcmcia_shannon_init(struct device *); extern int pcmcia_simpad_init(struct device *); extern int pcmcia_stork_init(struct device *); extern int pcmcia_system3_init(struct device *); diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index aebf9a66fdde..a91222bc3824 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c @@ -24,13 +24,15 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int err; + skt->stat[SOC_STAT_CD].name = skt->nr ? "pcmcia1-detect" : "pcmcia0-detect"; + skt->stat[SOC_STAT_RDY].name = skt->nr ? "pcmcia1-ready" : "pcmcia0-ready"; + + err = soc_pcmcia_request_gpiods(skt); + if (err) + return err; + switch (skt->nr) { case 0: - skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0; - skt->stat[SOC_STAT_CD].name = "PCMCIA CD0"; - skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0; - skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0"; - err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); if (err) goto err01; @@ -57,10 +59,6 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) goto err06; break; case 1: - skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1; - skt->stat[SOC_STAT_CD].name = "PCMCIA CD1"; - skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1; - skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1"; break; } return 0; diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c deleted file mode 100644 index 35c30ff41e81..000000000000 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * drivers/pcmcia/sa1100_nanoengine.c - * - * PCMCIA implementation routines for BSI nanoEngine. - * - * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine - * board you should carefully read this: - * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/ - * - * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> - * - * Based on original work for kernel 2.4 by - * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br> - * - * 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/device.h> -#include <linux/errno.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/signal.h> - -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <mach/hardware.h> -#include <mach/nanoengine.h> - -#include "sa1100_generic.h" - -struct nanoengine_pins { - unsigned output_pins; - unsigned clear_outputs; - int gpio_rst; - int gpio_cd; - int gpio_rdy; -}; - -static struct nanoengine_pins nano_skts[] = { - { - .gpio_rst = GPIO_PC_RESET0, - .gpio_cd = GPIO_PC_CD0, - .gpio_rdy = GPIO_PC_READY0, - }, { - .gpio_rst = GPIO_PC_RESET1, - .gpio_cd = GPIO_PC_CD1, - .gpio_rdy = GPIO_PC_READY1, - } -}; - -unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); - -static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -{ - unsigned i = skt->nr; - int ret; - - if (i >= num_nano_pcmcia_sockets) - return -ENXIO; - - ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW, - i ? "PC RST1" : "PC RST0"); - if (ret) - return ret; - - skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; - skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; - skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy; - skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0"; - - return 0; -} - -static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - gpio_free(nano_skts[skt->nr].gpio_rst); -} - -static int nanoengine_pcmcia_configure_socket( - struct soc_pcmcia_socket *skt, const socket_state_t *state) -{ - unsigned i = skt->nr; - - if (i >= num_nano_pcmcia_sockets) - return -ENXIO; - - gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET)); - - return 0; -} - -static void nanoengine_pcmcia_socket_state( - struct soc_pcmcia_socket *skt, struct pcmcia_state *state) -{ - unsigned i = skt->nr; - - if (i >= num_nano_pcmcia_sockets) - return; - - state->bvd1 = 1; - state->bvd2 = 1; - state->vs_3v = 1; /* Can only apply 3.3V */ - state->vs_Xv = 0; -} - -static struct pcmcia_low_level nanoengine_pcmcia_ops = { - .owner = THIS_MODULE, - - .hw_init = nanoengine_pcmcia_hw_init, - .hw_shutdown = nanoengine_pcmcia_hw_shutdown, - - .configure_socket = nanoengine_pcmcia_configure_socket, - .socket_state = nanoengine_pcmcia_socket_state, -}; - -int pcmcia_nanoengine_init(struct device *dev) -{ - int ret = -ENODEV; - - if (machine_is_nanoengine()) - ret = sa11xx_drv_pcmcia_probe( - dev, &nanoengine_pcmcia_ops, 0, 2); - - return ret; -} - diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c deleted file mode 100644 index 0e52a575986e..000000000000 --- a/drivers/pcmcia/sa1100_shannon.c +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * drivers/pcmcia/sa1100_shannon.c - * - * PCMCIA implementation routines for Shannon - * - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <mach/shannon.h> -#include <asm/irq.h> -#include "sa1100_generic.h" - -static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -{ - /* All those are inputs */ - GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) | - GPIO_GPIO(SHANNON_GPIO_EJECT_1) | - GPIO_GPIO(SHANNON_GPIO_RDY_0) | - GPIO_GPIO(SHANNON_GPIO_RDY_1)); - - if (skt->nr == 0) { - skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0; - skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0"; - skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0; - skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0"; - } else { - skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1; - skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1"; - skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1; - skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1"; - } - - return 0; -} - -static void -shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, - struct pcmcia_state *state) -{ - switch (skt->nr) { - case 0: - state->bvd1 = 1; - state->bvd2 = 1; - state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ - state->vs_Xv = 0; - break; - - case 1: - state->bvd1 = 1; - state->bvd2 = 1; - state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ - state->vs_Xv = 0; - break; - } -} - -static int -shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, - const socket_state_t *state) -{ - switch (state->Vcc) { - case 0: /* power off */ - printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__); - break; - case 50: - printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__); - case 33: - break; - default: - printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); - return -1; - } - - printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__); - - /* Silently ignore Vpp, output enable, speaker enable. */ - - return 0; -} - -static struct pcmcia_low_level shannon_pcmcia_ops = { - .owner = THIS_MODULE, - .hw_init = shannon_pcmcia_hw_init, - .socket_state = shannon_pcmcia_socket_state, - .configure_socket = shannon_pcmcia_configure_socket, -}; - -int pcmcia_shannon_init(struct device *dev) -{ - int ret = -ENODEV; - - if (machine_is_shannon()) - ret = sa11xx_drv_pcmcia_probe(dev, &shannon_pcmcia_ops, 0, 2); - - return ret; -} diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index 7ce65bb23a8e..e235ee14eaa6 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c @@ -12,7 +12,6 @@ #include <mach/hardware.h> #include <asm/mach-types.h> -#include <asm/irq.h> #include <mach/simpad.h> #include "sa1100_generic.h" @@ -21,12 +20,10 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); - skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD; - skt->stat[SOC_STAT_CD].name = "CF_CD"; - skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ; - skt->stat[SOC_STAT_RDY].name = "CF_RDY"; + skt->stat[SOC_STAT_CD].name = "cf-detect"; + skt->stat[SOC_STAT_RDY].name = "cf-ready"; - return 0; + return soc_pcmcia_request_gpiods(skt); } static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) @@ -42,9 +39,6 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, { long cs3reg = simpad_get_cs3_ro(); - /* the detect signal is inverted - fix that up here */ - state->detect = !state->detect; - state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ |