提交 24613ff9 编写于 作者: L Linus Torvalds

Merge branch 'pcmcia' of git://git.linaro.org/people/rmk/linux-arm

Pull #3 ARM updates from Russell King:
 "This adds gpio support to soc_common, allowing an amount of code to be
  deleted from each PCMCIA socket driver for the PXA/SA11x0 SoCs."

* 'pcmcia' of git://git.linaro.org/people/rmk/linux-arm:
  PCMCIA: sa1111: rename sa1111 socket drivers to have sa1111_ prefix.
  PCMCIA: make lubbock socket driver part of sa1111_cs
  PCMCIA: add Kconfig control for building sa11xx_base.c
  PCMCIA: sa1111: jornada720: no need to disable IRQs around sa1111_set_io
  PCMCIA: sa1111: pass along sa1111_pcmcia_configure_socket() failure code
  PCMCIA: soc_common: remove explicit wrprot initialization in socket drivers
  PCMCIA: soc_common: remove soc_pcmcia_*_irqs functions
  PCMCIA: sa11x0: h3600: convert to use new irq/gpio management
  PCMCIA: sa11x0: simpad: convert to use new irq/gpio management
  PCMCIA: sa11x0: shannon: convert to use new irq/gpio management
  PCMCIA: sa11x0: nanoengine: convert reset handling to use GPIO subsystem
  PCMCIA: sa11x0: nanoengine: convert to use new irq/gpio management
  PCMCIA: sa11x0: cerf: convert reset handling to use GPIO subsystem
  PCMCIA: sa11x0: cerf: convert to use new irq/gpio management
  PCMCIA: sa11x0: assabet: convert to use new irq/gpio management
  PCMCIA: sa1111: use new per-socket irq/gpio infrastructure
  PCMCIA: pxa: convert PXA socket drivers to use new irq/gpio management
  PCMCIA: soc_common: add GPIO support for card status signals
  PCMCIA: soc_common: move common initialization into soc_common
...@@ -174,7 +174,6 @@ enum balloon3_features { ...@@ -174,7 +174,6 @@ enum balloon3_features {
#define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ) #define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ)
#define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ) #define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ)
#define BALLOON3_S0_CD_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD)
#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) #define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16)
......
...@@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); ...@@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
#define ASSABET_BSR_RAD_RI (1 << 31) #define ASSABET_BSR_RAD_RI (1 << 31)
/* GPIOs for which the generic definition doesn't say much */ /* GPIOs (bitmasks) for which the generic definition doesn't say much */
#define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */ #define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */
#define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */ #define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */
#define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */ #define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */
#define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */
#define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */
#define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */
#define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */ #define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */
#define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */
#define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */ #define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */
#define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */ #define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */
#define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21 /* These are gpiolib GPIO numbers, not bitmasks */
#define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22 #define ASSABET_GPIO_CF_IRQ 21 /* CF IRQ */
#define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24 #define ASSABET_GPIO_CF_CD 22 /* CF CD */
#define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25 #define ASSABET_GPIO_CF_BVD2 24 /* CF BVD / IOSPKR */
#define ASSABET_GPIO_CF_BVD1 25 /* CF BVD / IOSTSCHG */
#endif #endif
...@@ -14,15 +14,10 @@ ...@@ -14,15 +14,10 @@
#define CERF_ETH_IO 0xf0000000 #define CERF_ETH_IO 0xf0000000
#define CERF_ETH_IRQ IRQ_GPIO26 #define CERF_ETH_IRQ IRQ_GPIO26
#define CERF_GPIO_CF_BVD2 GPIO_GPIO (19) #define CERF_GPIO_CF_BVD2 19
#define CERF_GPIO_CF_BVD1 GPIO_GPIO (20) #define CERF_GPIO_CF_BVD1 20
#define CERF_GPIO_CF_RESET GPIO_GPIO (21) #define CERF_GPIO_CF_RESET 21
#define CERF_GPIO_CF_IRQ GPIO_GPIO (22) #define CERF_GPIO_CF_IRQ 22
#define CERF_GPIO_CF_CD GPIO_GPIO (23) #define CERF_GPIO_CF_CD 23
#define CERF_IRQ_GPIO_CF_BVD2 IRQ_GPIO19
#define CERF_IRQ_GPIO_CF_BVD1 IRQ_GPIO20
#define CERF_IRQ_GPIO_CF_IRQ IRQ_GPIO22
#define CERF_IRQ_GPIO_CF_CD IRQ_GPIO23
#endif // _INCLUDE_CERF_H_ #endif // _INCLUDE_CERF_H_
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
#include <mach/irqs.h> #include <mach/irqs.h>
#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ #define GPIO_PC_READY0 11 /* ready for socket 0 (active high)*/
#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ #define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */
#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ #define GPIO_PC_CD0 13 /* detect for socket 0 (active low) */
#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */ #define GPIO_PC_CD1 14 /* detect for socket 1 (active low) */
#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ #define GPIO_PC_RESET0 15 /* reset socket 0 */
#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ #define GPIO_PC_RESET1 16 /* reset socket 1 */
#define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0 #define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0
#define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 #define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11
......
...@@ -23,14 +23,10 @@ ...@@ -23,14 +23,10 @@
#define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */ #define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */
#define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */ #define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */
/* XXX GPIO 23 unaccounted for */ /* XXX GPIO 23 unaccounted for */
#define SHANNON_GPIO_EJECT_0 GPIO_GPIO (24) /* in */ #define SHANNON_GPIO_EJECT_0 24 /* in */
#define SHANNON_IRQ_GPIO_EJECT_0 IRQ_GPIO24 #define SHANNON_GPIO_EJECT_1 25 /* in */
#define SHANNON_GPIO_EJECT_1 GPIO_GPIO (25) /* in */ #define SHANNON_GPIO_RDY_0 26 /* in */
#define SHANNON_IRQ_GPIO_EJECT_1 IRQ_GPIO25 #define SHANNON_GPIO_RDY_1 27 /* in */
#define SHANNON_GPIO_RDY_0 GPIO_GPIO (26) /* in */
#define SHANNON_IRQ_GPIO_RDY_0 IRQ_GPIO26
#define SHANNON_GPIO_RDY_1 GPIO_GPIO (27) /* in */
#define SHANNON_IRQ_GPIO_RDY_1 IRQ_GPIO27
/* MCP UCB codec GPIO pins... */ /* MCP UCB codec GPIO pins... */
......
...@@ -39,10 +39,8 @@ ...@@ -39,10 +39,8 @@
/*--- PCMCIA ---*/ /*--- PCMCIA ---*/
#define GPIO_CF_CD GPIO_GPIO24 #define GPIO_CF_CD 24
#define GPIO_CF_IRQ GPIO_GPIO1 #define GPIO_CF_IRQ 1
#define IRQ_GPIO_CF_IRQ IRQ_GPIO1
#define IRQ_GPIO_CF_CD IRQ_GPIO24
/*--- SmartCard ---*/ /*--- SmartCard ---*/
#define GPIO_SMART_CARD GPIO_GPIO10 #define GPIO_SMART_CARD GPIO_GPIO10
......
...@@ -183,10 +183,14 @@ config PCMCIA_BCM63XX ...@@ -183,10 +183,14 @@ config PCMCIA_BCM63XX
config PCMCIA_SOC_COMMON config PCMCIA_SOC_COMMON
tristate tristate
config PCMCIA_SA11XX_BASE
tristate
config PCMCIA_SA1100 config PCMCIA_SA1100
tristate "SA1100 support" tristate "SA1100 support"
depends on ARM && ARCH_SA1100 && PCMCIA depends on ARM && ARCH_SA1100 && PCMCIA
select PCMCIA_SOC_COMMON select PCMCIA_SOC_COMMON
select PCMCIA_SA11XX_BASE
help help
Say Y here to include support for SA11x0-based PCMCIA or CF Say Y here to include support for SA11x0-based PCMCIA or CF
sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
...@@ -196,8 +200,9 @@ config PCMCIA_SA1100 ...@@ -196,8 +200,9 @@ config PCMCIA_SA1100
config PCMCIA_SA1111 config PCMCIA_SA1111
tristate "SA1111 support" tristate "SA1111 support"
depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA depends on ARM && SA1111 && PCMCIA
select PCMCIA_SOC_COMMON select PCMCIA_SOC_COMMON
select PCMCIA_SA11XX_BASE if ARCH_SA1100
help help
Say Y here to include support for SA1111-based PCMCIA or CF Say Y here to include support for SA1111-based PCMCIA or CF
sockets, found on the Jornada 720, Graphicsmaster and other sockets, found on the Jornada 720, Graphicsmaster and other
...@@ -213,6 +218,7 @@ config PCMCIA_PXA2XX ...@@ -213,6 +218,7 @@ config PCMCIA_PXA2XX
|| ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
|| MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
|| MACH_COLIBRI320) || MACH_COLIBRI320)
select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
select PCMCIA_SOC_COMMON select PCMCIA_SOC_COMMON
help help
Say Y here to include support for the PXA2xx PCMCIA controller Say Y here to include support for the PXA2xx PCMCIA controller
......
...@@ -25,8 +25,9 @@ obj-$(CONFIG_I82092) += i82092.o ...@@ -25,8 +25,9 @@ obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
...@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o ...@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
sa1111_cs-y += sa1111_generic.o sa1111_cs-y += sa1111_generic.o
sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o
sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1111_badge4.o
sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o
sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o
sa1100_cs-y += sa1100_generic.o sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
...@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o ...@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
......
...@@ -29,15 +29,6 @@ ...@@ -29,15 +29,6 @@
#include "soc_common.h" #include "soc_common.h"
/*
* These are a list of interrupt sources that provokes a polled
* check of status
*/
static struct pcmcia_irqs irqs[] = {
{ 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" },
{ 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" },
};
static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
uint16_t ver; uint16_t ver;
...@@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
ver); ver);
skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ; skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD;
} skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ;
skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) return 0;
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
} }
static unsigned long balloon3_pcmcia_status[2] = { static unsigned long balloon3_pcmcia_status[2] = {
...@@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
disable_irq(BALLOON3_BP_NSTSCHG_IRQ); disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
} }
state->detect = !gpio_get_value(BALLOON3_GPIO_S0_CD);
state->ready = !!(status & BALLOON3_CF_nIRQ); state->ready = !!(status & BALLOON3_CF_nIRQ);
state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1); state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1);
state->bvd2 = 0; /* not available */ state->bvd2 = 0; /* not available */
state->vs_3v = 1; /* Always true its a CF card */ state->vs_3v = 1; /* Always true its a CF card */
state->vs_Xv = 0; /* not available */ state->vs_Xv = 0; /* not available */
state->wrprot = 0; /* not available */
} }
static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
...@@ -106,7 +95,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -106,7 +95,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static struct pcmcia_low_level balloon3_pcmcia_ops = { static struct pcmcia_low_level balloon3_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = balloon3_pcmcia_hw_init, .hw_init = balloon3_pcmcia_hw_init,
.hw_shutdown = balloon3_pcmcia_hw_shutdown,
.socket_state = balloon3_pcmcia_socket_state, .socket_state = balloon3_pcmcia_socket_state,
.configure_socket = balloon3_pcmcia_configure_socket, .configure_socket = balloon3_pcmcia_configure_socket,
.first = 0, .first = 0,
......
...@@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) ...@@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
skt->nr = ops->first + i; skt->nr = ops->first + i;
skt->clk = clk; skt->clk = clk;
skt->ops = ops; soc_pcmcia_init_one(skt, ops, &dev->dev);
skt->socket.owner = ops->owner;
skt->socket.dev.parent = &dev->dev;
skt->socket.pci_irq = NO_IRQ;
ret = pxa2xx_drv_pcmcia_add_one(skt); ret = pxa2xx_drv_pcmcia_add_one(skt);
if (ret) if (ret)
......
...@@ -25,17 +25,6 @@ ...@@ -25,17 +25,6 @@
#define GPIO_PCMCIA_S1_RDYINT (8) #define GPIO_PCMCIA_S1_RDYINT (8)
#define GPIO_PCMCIA_RESET (9) #define GPIO_PCMCIA_RESET (9)
#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
#define PCMCIA_S1_CD_VALID gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID)
#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
#define PCMCIA_S1_RDYINT gpio_to_irq(GPIO_PCMCIA_S1_RDYINT)
static struct pcmcia_irqs irqs[] = {
{ .sock = 0, .str = "PCMCIA0 CD" },
{ .sock = 1, .str = "PCMCIA1 CD" },
};
static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
...@@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
return ret; return ret;
gpio_direction_output(GPIO_PCMCIA_RESET, 0); gpio_direction_output(GPIO_PCMCIA_RESET, 0);
skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; if (skt->nr == 0) {
irqs[0].irq = PCMCIA_S0_CD_VALID; skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
irqs[1].irq = PCMCIA_S1_CD_VALID; skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
if (!ret) skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
gpio_free(GPIO_PCMCIA_RESET); } else {
skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
}
return ret; return 0;
} }
static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
gpio_free(GPIO_PCMCIA_RESET); gpio_free(GPIO_PCMCIA_RESET);
} }
...@@ -63,16 +56,8 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) ...@@ -63,16 +56,8 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
state->detect = !gpio_get_value(cd);
state->ready = !!gpio_get_value(rdy);
state->bvd1 = 1;
state->bvd2 = 1;
state->vs_3v = 0; state->vs_3v = 0;
state->vs_Xv = 0; state->vs_Xv = 0;
state->wrprot = 0; /* not available */
} }
......
...@@ -22,14 +22,6 @@ ...@@ -22,14 +22,6 @@
#define GPIO_PCMCIA_S0_RDYINT (82) #define GPIO_PCMCIA_S0_RDYINT (82)
#define GPIO_PCMCIA_RESET (53) #define GPIO_PCMCIA_RESET (53)
#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
static struct pcmcia_irqs irqs[] = {
{ .sock = 0, .str = "PCMCIA0 CD" },
};
static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
...@@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
return ret; return ret;
gpio_direction_output(GPIO_PCMCIA_RESET, 0); gpio_direction_output(GPIO_PCMCIA_RESET, 0);
skt->socket.pci_irq = PCMCIA_S0_RDYINT; skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
irqs[0].irq = PCMCIA_S0_CD_VALID; skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
if (!ret) skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
gpio_free(GPIO_PCMCIA_RESET);
return ret; return ret;
} }
static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
gpio_free(GPIO_PCMCIA_RESET); gpio_free(GPIO_PCMCIA_RESET);
} }
...@@ -56,13 +46,8 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) ...@@ -56,13 +46,8 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
state->ready = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
state->bvd1 = 1;
state->bvd2 = 1;
state->vs_3v = 0; state->vs_3v = 0;
state->vs_Xv = 0; state->vs_Xv = 0;
state->wrprot = 0; /* not available */
} }
......
...@@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = { ...@@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = {
{ 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" },
}; };
static struct pcmcia_irqs colibri_irqs[] = {
{
.sock = 0,
.str = "PCMCIA CD"
},
};
static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
...@@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
if (ret) if (ret)
goto err1; goto err1;
colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
ARRAY_SIZE(colibri_irqs));
if (ret)
goto err2;
return ret;
err2:
gpio_free_array(colibri_pcmcia_gpios,
ARRAY_SIZE(colibri_pcmcia_gpios));
err1: err1:
return ret; return ret;
} }
...@@ -100,7 +84,6 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -100,7 +84,6 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
......
...@@ -23,53 +23,27 @@ ...@@ -23,53 +23,27 @@
#include "soc_common.h" #include "soc_common.h"
static struct pcmcia_irqs cd_irqs[] = {
{
.sock = 0,
.str = "CF card detect"
},
{
.sock = 1,
.str = "Wifi switch"
},
};
static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
if (skt->nr == 0) if (skt->nr == 0) {
skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0); skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
else skt->stat[SOC_STAT_CD].name = "CF card detect";
skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1); skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
skt->stat[SOC_STAT_RDY].name = "CF ready";
cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0); } else {
cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1); skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
skt->stat[SOC_STAT_CD].name = "Wifi switch";
return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
} skt->stat[SOC_STAT_RDY].name = "Wifi ready";
}
/* return 0;
* Release all resources.
*/
static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1);
} }
static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
if (skt->nr == 0) {
state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1;
state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0;
} else {
state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1;
state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0;
}
state->vs_3v = 1; state->vs_3v = 1;
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
...@@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return 0; return 0;
} }
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
}
/*
* Disable card status IRQs on suspend.
*/
static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
}
static struct pcmcia_low_level e740_pcmcia_ops = { static struct pcmcia_low_level e740_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = e740_pcmcia_hw_init, .hw_init = e740_pcmcia_hw_init,
.hw_shutdown = e740_pcmcia_hw_shutdown,
.socket_state = e740_pcmcia_socket_state, .socket_state = e740_pcmcia_socket_state,
.configure_socket = e740_pcmcia_configure_socket, .configure_socket = e740_pcmcia_configure_socket,
.socket_init = e740_pcmcia_socket_init,
.socket_suspend = e740_pcmcia_socket_suspend,
.nr = 2, .nr = 2,
}; };
......
...@@ -30,27 +30,26 @@ ...@@ -30,27 +30,26 @@
#include "soc_common.h" #include "soc_common.h"
static struct pcmcia_irqs irqs[] = {
{ 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" },
{ 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" },
{ 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" },
{ 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" },
};
static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
/* /*
* Setup default state of GPIO outputs * Setup default state of GPIO outputs
* before we enable them as outputs. * before we enable them as outputs.
*/ */
if (skt->nr == 0) {
skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; skt->socket.pci_irq = MAINSTONE_S0_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
} skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
{ } else {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->socket.pci_irq = MAINSTONE_S1_IRQ;
skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
}
return 0;
} }
static unsigned long mst_pcmcia_status[2]; static unsigned long mst_pcmcia_status[2];
...@@ -84,7 +83,6 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -84,7 +83,6 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0; state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1; state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1;
state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1; state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1;
state->wrprot = 0; /* not available */
} }
static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
...@@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static struct pcmcia_low_level mst_pcmcia_ops __initdata = { static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = mst_pcmcia_hw_init, .hw_init = mst_pcmcia_hw_init,
.hw_shutdown = mst_pcmcia_hw_shutdown,
.socket_state = mst_pcmcia_socket_state, .socket_state = mst_pcmcia_socket_state,
.configure_socket = mst_pcmcia_configure_socket, .configure_socket = mst_pcmcia_configure_socket,
.nr = 2, .nr = 2,
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
static struct gpio palmld_pcmcia_gpios[] = { static struct gpio palmld_pcmcia_gpios[] = {
{ GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" },
{ GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
{ GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
}; };
static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
...@@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
ret = gpio_request_array(palmld_pcmcia_gpios, ret = gpio_request_array(palmld_pcmcia_gpios,
ARRAY_SIZE(palmld_pcmcia_gpios)); ARRAY_SIZE(palmld_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY); skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
return ret; return ret;
} }
...@@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = 1; /* always inserted */ state->detect = 1; /* always inserted */
state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
......
...@@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = { ...@@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = {
{ GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
{ GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
{ GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
{ GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
{ GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" },
}; };
...@@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
ret = gpio_request_array(palmtc_pcmcia_gpios, ret = gpio_request_array(palmtc_pcmcia_gpios,
ARRAY_SIZE(palmtc_pcmcia_gpios)); ARRAY_SIZE(palmtc_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY); skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
return ret; return ret;
} }
...@@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = 1; /* always inserted */ state->detect = 1; /* always inserted */
state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
......
...@@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = { ...@@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = {
{ GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
{ GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
{ GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
{ GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
}; };
static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
...@@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
ret = gpio_request_array(palmtx_pcmcia_gpios, ret = gpio_request_array(palmtx_pcmcia_gpios,
ARRAY_SIZE(palmtx_pcmcia_gpios)); ARRAY_SIZE(palmtx_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY;
skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
return ret; return ret;
} }
...@@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = 1; /* always inserted */ state->detect = 1; /* always inserted */
state->ready = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY);
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
......
...@@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) ...@@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret;
/* Register interrupts */
if (SCOOP_DEV[skt->nr].cd_irq >= 0) { if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq; skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq;
skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str;
cd_irq.sock = skt->nr;
cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
if (ret) {
printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
return ret;
}
} }
skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
...@@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
return 0; return 0;
} }
static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr;
cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
soc_pcmcia_free_irqs(skt, &cd_irq, 1);
}
}
static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
...@@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) ...@@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = sharpsl_pcmcia_hw_init, .hw_init = sharpsl_pcmcia_hw_init,
.hw_shutdown = sharpsl_pcmcia_hw_shutdown,
.socket_state = sharpsl_pcmcia_socket_state, .socket_state = sharpsl_pcmcia_socket_state,
.configure_socket = sharpsl_pcmcia_configure_socket, .configure_socket = sharpsl_pcmcia_configure_socket,
.socket_init = sharpsl_pcmcia_socket_init, .socket_init = sharpsl_pcmcia_socket_init,
......
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
#define SG2_S0_GPIO_DETECT 53 #define SG2_S0_GPIO_DETECT 53
#define SG2_S0_GPIO_READY 81 #define SG2_S0_GPIO_READY 81
static struct pcmcia_irqs irqs[] = {
{.sock = 0, .str = "PCMCIA0 CD" },
};
static struct gpio sg2_pcmcia_gpios[] = { static struct gpio sg2_pcmcia_gpios[] = {
{ SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" }, { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
{ SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
...@@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = { ...@@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = {
static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY); skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT); skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
} return 0;
static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
} }
static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT);
state->ready = !!gpio_get_value(SG2_S0_GPIO_READY);
state->bvd1 = 0; /* not available - battery detect on card */ state->bvd1 = 0; /* not available - battery detect on card */
state->bvd2 = 0; /* not available */ state->bvd2 = 0; /* not available */
state->vs_3v = 1; /* not available - voltage detect for card */ state->vs_3v = 1; /* not available - voltage detect for card */
state->vs_Xv = 0; /* not available */ state->vs_Xv = 0; /* not available */
state->wrprot = 0; /* not available - write protect */
} }
static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
...@@ -94,24 +83,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -94,24 +83,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return 0; return 0;
} }
static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = sg2_pcmcia_hw_init, .hw_init = sg2_pcmcia_hw_init,
.hw_shutdown = sg2_pcmcia_hw_shutdown,
.socket_state = sg2_pcmcia_socket_state, .socket_state = sg2_pcmcia_socket_state,
.configure_socket = sg2_pcmcia_configure_socket, .configure_socket = sg2_pcmcia_configure_socket,
.socket_init = sg2_pcmcia_socket_init,
.socket_suspend = sg2_pcmcia_socket_suspend,
.nr = 1, .nr = 1,
}; };
......
...@@ -29,32 +29,17 @@ ...@@ -29,32 +29,17 @@
extern void board_pcmcia_power(int power); extern void board_pcmcia_power(int power);
static struct pcmcia_irqs irqs[] = {
{ .sock = 0, .str = "cs0_cd" }
/* on other baseboards we can have more inputs */
};
static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret, i;
/* we dont have voltage/card/ready detection /* we dont have voltage/card/ready detection
* so we dont need interrupts for it * so we dont need interrupts for it
*/ */
switch (skt->nr) { switch (skt->nr) {
case 0: case 0:
if (gpio_request(GPIO_PRDY, "cf_irq") < 0) { skt->stat[SOC_STAT_CD].gpio = GPIO_PCD;
pr_err("%s: sock %d unable to request gpio %d\n", __func__, skt->stat[SOC_STAT_CD].name = "cs0_cd";
skt->nr, GPIO_PRDY); skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY;
return -EBUSY; skt->stat[SOC_STAT_RDY].name = "cs0_rdy";
}
if (gpio_direction_input(GPIO_PRDY) < 0) {
pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
skt->nr, GPIO_PRDY);
gpio_free(GPIO_PRDY);
return -EINVAL;
}
skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY);
irqs[0].irq = gpio_to_irq(GPIO_PCD);
break; break;
default: default:
break; break;
...@@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
/* release the reset of this card */ /* release the reset of this card */
pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
/* supplementory irqs for the socket */ return 0;
for (i = 0; i < ARRAY_SIZE(irqs); i++) {
if (irqs[i].sock != skt->nr)
continue;
if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) {
pr_err("%s: sock %d unable to request gpio %d\n",
__func__, skt->nr, irq_to_gpio(irqs[i].irq));
ret = -EBUSY;
goto error;
}
if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) {
pr_err("%s: sock %d unable to set input gpio %d\n",
__func__, skt->nr, irq_to_gpio(irqs[i].irq));
ret = -EINVAL;
goto error;
}
}
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
error:
for (; i >= 0; i--) {
gpio_free(irq_to_gpio(irqs[i].irq));
}
return (ret);
}
static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
int i;
/* free allocated gpio's */
gpio_free(GPIO_PRDY);
for (i = 0; i < ARRAY_SIZE(irqs); i++)
gpio_free(irq_to_gpio(irqs[i].irq));
} }
static unsigned long trizeps_pcmcia_status[2]; static unsigned long trizeps_pcmcia_status[2];
...@@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
switch (skt->nr) { switch (skt->nr) {
case 0: case 0:
/* just fill in fix states */ /* just fill in fix states */
state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0;
state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0; state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0;
state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0; state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0;
state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1; state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1;
state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1; state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1;
state->wrprot = 0; /* not available */
break; break;
#ifndef CONFIG_MACH_TRIZEPS_CONXS #ifndef CONFIG_MACH_TRIZEPS_CONXS
...@@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
state->bvd2 = 0; state->bvd2 = 0;
state->vs_3v = 0; state->vs_3v = 0;
state->vs_Xv = 0; state->vs_Xv = 0;
state->wrprot = 0;
break; break;
#endif #endif
...@@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) ...@@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static struct pcmcia_low_level trizeps_pcmcia_ops = { static struct pcmcia_low_level trizeps_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = trizeps_pcmcia_hw_init, .hw_init = trizeps_pcmcia_hw_init,
.hw_shutdown = trizeps_pcmcia_hw_shutdown,
.socket_state = trizeps_pcmcia_socket_state, .socket_state = trizeps_pcmcia_socket_state,
.configure_socket = trizeps_pcmcia_configure_socket, .configure_socket = trizeps_pcmcia_configure_socket,
.socket_init = trizeps_pcmcia_socket_init, .socket_init = trizeps_pcmcia_socket_init,
......
...@@ -32,13 +32,6 @@ ...@@ -32,13 +32,6 @@
static struct platform_device *arcom_pcmcia_dev; static struct platform_device *arcom_pcmcia_dev;
static struct pcmcia_irqs irqs[] = {
{
.sock = 0,
.str = "PCMCIA_CD",
},
};
static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
{ {
return arcom_pcmcia_dev->dev.platform_data; return arcom_pcmcia_dev->dev.platform_data;
...@@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
unsigned long flags; unsigned long flags;
skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio); skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio;
irqs[0].irq = gpio_to_irq(pdata->cd_gpio); skt->stat[SOC_STAT_CD].name = "PCMCIA_CD";
skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio;
if (gpio_request(pdata->cd_gpio, "CF detect")) skt->stat[SOC_STAT_RDY].name = "CF ready";
goto err_request_cd;
if (gpio_request(pdata->rdy_gpio, "CF ready"))
goto err_request_rdy;
if (gpio_request(pdata->pwr_gpio, "CF power")) if (gpio_request(pdata->pwr_gpio, "CF power"))
goto err_request_pwr; goto err_request_pwr;
local_irq_save(flags); local_irq_save(flags);
if (gpio_direction_output(pdata->pwr_gpio, 0) || if (gpio_direction_output(pdata->pwr_gpio, 0)) {
gpio_direction_input(pdata->cd_gpio) ||
gpio_direction_input(pdata->rdy_gpio)) {
local_irq_restore(flags); local_irq_restore(flags);
goto err_dir; goto err_dir;
} }
local_irq_restore(flags); local_irq_restore(flags);
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); return 0;
err_dir: err_dir:
gpio_free(pdata->pwr_gpio); gpio_free(pdata->pwr_gpio);
err_request_pwr: err_request_pwr:
gpio_free(pdata->rdy_gpio);
err_request_rdy:
gpio_free(pdata->cd_gpio);
err_request_cd:
dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n"); dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
return -1; return -1;
} }
...@@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) ...@@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
gpio_free(pdata->pwr_gpio); gpio_free(pdata->pwr_gpio);
gpio_free(pdata->rdy_gpio);
gpio_free(pdata->cd_gpio);
} }
static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
state->detect = !gpio_get_value(pdata->cd_gpio);
state->ready = !!gpio_get_value(pdata->rdy_gpio);
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1; /* Can only apply 3.3V */ state->vs_3v = 1; /* Can only apply 3.3V */
state->vs_Xv = 0; state->vs_Xv = 0;
} }
......
...@@ -23,29 +23,14 @@ ...@@ -23,29 +23,14 @@
#include "soc_common.h" #include "soc_common.h"
static struct gpio vpac270_pcmcia_gpios[] = { static struct gpio vpac270_pcmcia_gpios[] = {
{ GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" },
{ GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" },
{ GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" },
{ GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" },
}; };
static struct gpio vpac270_cf_gpios[] = { static struct gpio vpac270_cf_gpios[] = {
{ GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" },
{ GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" },
{ GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" },
}; };
static struct pcmcia_irqs cd_irqs[] = {
{
.sock = 0,
.str = "PCMCIA CD"
},
{
.sock = 1,
.str = "CF CD"
},
};
static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
...@@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
ret = gpio_request_array(vpac270_pcmcia_gpios, ret = gpio_request_array(vpac270_pcmcia_gpios,
ARRAY_SIZE(vpac270_pcmcia_gpios)); ARRAY_SIZE(vpac270_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
if (!ret) skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
} else { } else {
ret = gpio_request_array(vpac270_cf_gpios, ret = gpio_request_array(vpac270_cf_gpios,
ARRAY_SIZE(vpac270_cf_gpios)); ARRAY_SIZE(vpac270_cf_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); skt->stat[SOC_STAT_CD].name = "CF CD";
skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
if (!ret) skt->stat[SOC_STAT_RDY].name = "CF Ready";
ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
} }
return ret; return ret;
...@@ -86,16 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) ...@@ -86,16 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
if (skt->nr == 0) {
state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
} else {
state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
}
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
...@@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return 0; return 0;
} }
static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
}
static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
}
static struct pcmcia_low_level vpac270_pcmcia_ops = { static struct pcmcia_low_level vpac270_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = { ...@@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = {
.socket_state = vpac270_pcmcia_socket_state, .socket_state = vpac270_pcmcia_socket_state,
.configure_socket = vpac270_pcmcia_configure_socket, .configure_socket = vpac270_pcmcia_configure_socket,
.socket_init = vpac270_pcmcia_socket_init,
.socket_suspend = vpac270_pcmcia_socket_suspend,
}; };
static struct platform_device *vpac270_pcmcia_device; static struct platform_device *vpac270_pcmcia_device;
......
...@@ -10,46 +10,30 @@ ...@@ -10,46 +10,30 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/signal.h>
#include <mach/assabet.h> #include <mach/assabet.h>
#include "sa1100_generic.h" #include "sa1100_generic.h"
static struct pcmcia_irqs irqs[] = {
{ 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" },
{ 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" },
{ 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" },
};
static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
skt->stat[SOC_STAT_CD].name = "CF CD";
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 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;
* Release all resources.
*/
static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
} }
static void static void
assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{ {
unsigned long levels = GPLR;
state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
state->wrprot = 0; /* Not available on Assabet. */
state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */
state->vs_Xv = 0; state->vs_Xv = 0;
} }
...@@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat ...@@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat
return -1; return -1;
} }
/* Silently ignore Vpp, output enable, speaker enable. */ /* Silently ignore Vpp, speaker enable. */
if (state->flags & SS_RESET) if (state->flags & SS_RESET)
mask |= ASSABET_BCR_CF_RST; 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, mask); ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
ASSABET_BCR_CF_BUS_OFF, mask);
return 0; return 0;
} }
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
/*
* Enable CF bus
*/
ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/* /*
* Disable card status IRQs on suspend. * Disable card status IRQs on suspend.
*/ */
static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* /*
* Tristate the CF bus signals. Also assert CF * Tristate the CF bus signals. Also assert CF
* reset as per user guide page 4-11. * reset as per user guide page 4-11.
...@@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) ...@@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static struct pcmcia_low_level assabet_pcmcia_ops = { static struct pcmcia_low_level assabet_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = assabet_pcmcia_hw_init, .hw_init = assabet_pcmcia_hw_init,
.hw_shutdown = assabet_pcmcia_hw_shutdown,
.socket_state = assabet_pcmcia_socket_state, .socket_state = assabet_pcmcia_socket_state,
.configure_socket = assabet_pcmcia_configure_socket, .configure_socket = assabet_pcmcia_configure_socket,
.socket_init = assabet_pcmcia_socket_init,
.socket_suspend = assabet_pcmcia_socket_suspend, .socket_suspend = assabet_pcmcia_socket_suspend,
}; };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -19,34 +20,34 @@ ...@@ -19,34 +20,34 @@
#define CERF_SOCKET 1 #define CERF_SOCKET 1
static struct pcmcia_irqs irqs[] = {
{ CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" },
{ CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" },
{ CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" }
};
static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; 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 soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); return 0;
} }
static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); gpio_free(CERF_GPIO_CF_RESET);
} }
static void static void
cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{ {
unsigned long levels = GPLR;
state->detect = (levels & CERF_GPIO_CF_CD) ?0:1;
state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0;
state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0;
state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0;
state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
} }
...@@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return -1; return -1;
} }
if (state->flags & SS_RESET) { gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
GPSR = CERF_GPIO_CF_RESET;
} else {
GPCR = CERF_GPIO_CF_RESET;
}
return 0; return 0;
} }
static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level cerf_pcmcia_ops = { static struct pcmcia_low_level cerf_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = cerf_pcmcia_hw_init, .hw_init = cerf_pcmcia_hw_init,
.hw_shutdown = cerf_pcmcia_hw_shutdown, .hw_shutdown = cerf_pcmcia_hw_shutdown,
.socket_state = cerf_pcmcia_socket_state, .socket_state = cerf_pcmcia_socket_state,
.configure_socket = cerf_pcmcia_configure_socket, .configure_socket = cerf_pcmcia_configure_socket,
.socket_init = cerf_pcmcia_socket_init,
.socket_suspend = cerf_pcmcia_socket_suspend,
}; };
int __devinit pcmcia_cerf_init(struct device *dev) int __devinit pcmcia_cerf_init(struct device *dev)
......
...@@ -19,36 +19,20 @@ ...@@ -19,36 +19,20 @@
#include "sa1100_generic.h" #include "sa1100_generic.h"
static struct pcmcia_irqs irqs[] = {
{ .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
{ .sock = 1, .str = "PCMCIA CD1" }
};
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int err; int err;
switch (skt->nr) { switch (skt->nr) {
case 0: case 0:
err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
if (err) skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
goto err00; skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
if (err)
goto err01;
skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
if (err)
goto err01;
err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
if (err)
goto err02;
irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
if (err) if (err)
goto err02; goto err01;
err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
if (err) if (err)
goto err03; goto err03;
...@@ -68,32 +52,14 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -68,32 +52,14 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
if (err) if (err)
goto err05; goto err05;
err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
if (err)
goto err06;
err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
if (err) if (err)
goto err06; goto err06;
break; break;
case 1: case 1:
err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
if (err) skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
goto err10; skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
if (err)
goto err11;
skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
if (err)
goto err11;
err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
if (err)
goto err12;
irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
if (err)
goto err12;
break; break;
} }
return 0; return 0;
...@@ -102,19 +68,12 @@ err06: gpio_free(H3XXX_EGPIO_CARD_RESET); ...@@ -102,19 +68,12 @@ err06: gpio_free(H3XXX_EGPIO_CARD_RESET);
err05: gpio_free(H3XXX_EGPIO_OPT_RESET); err05: gpio_free(H3XXX_EGPIO_OPT_RESET);
err04: gpio_free(H3XXX_EGPIO_OPT_ON); err04: gpio_free(H3XXX_EGPIO_OPT_ON);
err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
err00: return err; return err;
err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
err10: return err;
} }
static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
switch (skt->nr) { switch (skt->nr) {
case 0: case 0:
/* Disable CF bus: */ /* Disable CF bus: */
...@@ -126,12 +85,8 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) ...@@ -126,12 +85,8 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
gpio_free(H3XXX_EGPIO_OPT_RESET); gpio_free(H3XXX_EGPIO_OPT_RESET);
gpio_free(H3XXX_EGPIO_OPT_ON); gpio_free(H3XXX_EGPIO_OPT_ON);
gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
gpio_free(H3XXX_GPIO_PCMCIA_CD0);
gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
break; break;
case 1: case 1:
gpio_free(H3XXX_GPIO_PCMCIA_CD1);
gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
break; break;
} }
} }
...@@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) ...@@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
static void static void
h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{ {
switch (skt->nr) { state->bvd1 = 0;
case 0: state->bvd2 = 0;
state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); state->vs_3v = 0;
state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); state->vs_Xv = 0;
state->bvd1 = 0;
state->bvd2 = 0;
state->wrprot = 0; /* Not available on H3600. */
state->vs_3v = 0;
state->vs_Xv = 0;
break;
case 1:
state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
state->bvd1 = 0;
state->bvd2 = 0;
state->wrprot = 0; /* Not available on H3600. */
state->vs_3v = 0;
state->vs_Xv = 0;
break;
}
} }
static int static int
...@@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt) ...@@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
msleep(10); msleep(10);
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
} }
static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* /*
* FIXME: This doesn't fit well. We don't have the mechanism in * FIXME: This doesn't fit well. We don't have the mechanism in
* the generic PCMCIA layer to deal with the idea of two sockets * the generic PCMCIA layer to deal with the idea of two sockets
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -34,43 +35,23 @@ ...@@ -34,43 +35,23 @@
#include "sa1100_generic.h" #include "sa1100_generic.h"
static struct pcmcia_irqs irqs_skt0[] = {
/* socket, IRQ, name */
{ 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
};
static struct pcmcia_irqs irqs_skt1[] = {
/* socket, IRQ, name */
{ 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
};
struct nanoengine_pins { struct nanoengine_pins {
unsigned input_pins;
unsigned output_pins; unsigned output_pins;
unsigned clear_outputs; unsigned clear_outputs;
unsigned transition_pins; int gpio_rst;
unsigned pci_irq; int gpio_cd;
struct pcmcia_irqs *pcmcia_irqs; int gpio_rdy;
unsigned pcmcia_irqs_size;
}; };
static struct nanoengine_pins nano_skts[] = { static struct nanoengine_pins nano_skts[] = {
{ {
.input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, .gpio_rst = GPIO_PC_RESET0,
.output_pins = GPIO_PC_RESET0, .gpio_cd = GPIO_PC_CD0,
.clear_outputs = GPIO_PC_RESET0, .gpio_rdy = GPIO_PC_READY0,
.transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0,
.pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0,
.pcmcia_irqs = irqs_skt0,
.pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0)
}, { }, {
.input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, .gpio_rst = GPIO_PC_RESET1,
.output_pins = GPIO_PC_RESET1, .gpio_cd = GPIO_PC_CD1,
.clear_outputs = GPIO_PC_RESET1, .gpio_rdy = GPIO_PC_READY1,
.transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1,
.pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1,
.pcmcia_irqs = irqs_skt1,
.pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1)
} }
}; };
...@@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); ...@@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
unsigned i = skt->nr; unsigned i = skt->nr;
int ret;
if (i >= num_nano_pcmcia_sockets) if (i >= num_nano_pcmcia_sockets)
return -ENXIO; return -ENXIO;
GPDR &= ~nano_skts[i].input_pins; ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
GPDR |= nano_skts[i].output_pins; i ? "PC RST1" : "PC RST0");
GPCR = nano_skts[i].clear_outputs; if (ret)
irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); return ret;
skt->socket.pci_irq = nano_skts[i].pci_irq;
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 soc_pcmcia_request_irqs(skt, return 0;
nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
} }
/*
* Release all resources.
*/
static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
unsigned i = skt->nr; gpio_free(nano_skts[skt->nr].gpio_rst);
if (i >= num_nano_pcmcia_sockets)
return;
soc_pcmcia_free_irqs(skt,
nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
} }
static int nanoengine_pcmcia_configure_socket( static int nanoengine_pcmcia_configure_socket(
struct soc_pcmcia_socket *skt, const socket_state_t *state) struct soc_pcmcia_socket *skt, const socket_state_t *state)
{ {
unsigned reset;
unsigned i = skt->nr; unsigned i = skt->nr;
if (i >= num_nano_pcmcia_sockets) if (i >= num_nano_pcmcia_sockets)
return -ENXIO; return -ENXIO;
switch (i) { gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
case 0:
reset = GPIO_PC_RESET0;
break;
case 1:
reset = GPIO_PC_RESET1;
break;
default:
return -ENXIO;
}
if (state->flags & SS_RESET)
GPSR = reset;
else
GPCR = reset;
return 0; return 0;
} }
...@@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket( ...@@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket(
static void nanoengine_pcmcia_socket_state( static void nanoengine_pcmcia_socket_state(
struct soc_pcmcia_socket *skt, struct pcmcia_state *state) struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{ {
unsigned long levels = GPLR;
unsigned i = skt->nr; unsigned i = skt->nr;
if (i >= num_nano_pcmcia_sockets) if (i >= num_nano_pcmcia_sockets)
return; return;
memset(state, 0, sizeof(struct pcmcia_state));
switch (i) {
case 0:
state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
break;
case 1:
state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
break;
default:
return;
}
state->bvd1 = 1; state->bvd1 = 1;
state->bvd2 = 1; state->bvd2 = 1;
state->wrprot = 0; /* Not available */
state->vs_3v = 1; /* Can only apply 3.3V */ state->vs_3v = 1; /* Can only apply 3.3V */
state->vs_Xv = 0; state->vs_Xv = 0;
} }
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
unsigned i = skt->nr;
if (i >= num_nano_pcmcia_sockets)
return;
soc_pcmcia_enable_irqs(skt,
nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
}
/*
* Disable card status IRQs on suspend.
*/
static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
unsigned i = skt->nr;
if (i >= num_nano_pcmcia_sockets)
return;
soc_pcmcia_disable_irqs(skt,
nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
}
static struct pcmcia_low_level nanoengine_pcmcia_ops = { static struct pcmcia_low_level nanoengine_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = { ...@@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = {
.configure_socket = nanoengine_pcmcia_configure_socket, .configure_socket = nanoengine_pcmcia_configure_socket,
.socket_state = nanoengine_pcmcia_socket_state, .socket_state = nanoengine_pcmcia_socket_state,
.socket_init = nanoengine_pcmcia_socket_init,
.socket_suspend = nanoengine_pcmcia_socket_suspend,
}; };
int pcmcia_nanoengine_init(struct device *dev) int pcmcia_nanoengine_init(struct device *dev)
......
...@@ -15,40 +15,35 @@ ...@@ -15,40 +15,35 @@
#include <asm/irq.h> #include <asm/irq.h>
#include "sa1100_generic.h" #include "sa1100_generic.h"
static struct pcmcia_irqs irqs[] = {
{ 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" },
{ 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" },
};
static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
/* All those are inputs */ /* All those are inputs */
GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | GPIO_GPIO(SHANNON_GPIO_RDY_0) |
SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); GPIO_GPIO(SHANNON_GPIO_RDY_1));
skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; if (skt->nr == 0) {
skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 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";
}
static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) return 0;
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
} }
static void static void
shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
unsigned long levels = GPLR;
switch (skt->nr) { switch (skt->nr) {
case 0: case 0:
state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
state->wrprot = 0; /* Not available on Shannon. */
state->bvd1 = 1; state->bvd1 = 1;
state->bvd2 = 1; state->bvd2 = 1;
state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */
...@@ -56,9 +51,6 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -56,9 +51,6 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
break; break;
case 1: case 1:
state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
state->wrprot = 0; /* Not available on Shannon. */
state->bvd1 = 1; state->bvd1 = 1;
state->bvd2 = 1; state->bvd2 = 1;
state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */
...@@ -92,25 +84,11 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -92,25 +84,11 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return 0; return 0;
} }
static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level shannon_pcmcia_ops = { static struct pcmcia_low_level shannon_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hw_init = shannon_pcmcia_hw_init, .hw_init = shannon_pcmcia_hw_init,
.hw_shutdown = shannon_pcmcia_hw_shutdown,
.socket_state = shannon_pcmcia_socket_state, .socket_state = shannon_pcmcia_socket_state,
.configure_socket = shannon_pcmcia_configure_socket, .configure_socket = shannon_pcmcia_configure_socket,
.socket_init = shannon_pcmcia_socket_init,
.socket_suspend = shannon_pcmcia_socket_suspend,
}; };
int __devinit pcmcia_shannon_init(struct device *dev) int __devinit pcmcia_shannon_init(struct device *dev)
......
...@@ -15,24 +15,21 @@ ...@@ -15,24 +15,21 @@
#include <mach/simpad.h> #include <mach/simpad.h>
#include "sa1100_generic.h" #include "sa1100_generic.h"
static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
};
static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; 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";
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); return 0;
} }
static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */ /* Disable CF bus: */
/*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/ /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
simpad_clear_cs3_bit(PCMCIA_RESET); simpad_clear_cs3_bit(PCMCIA_RESET);
...@@ -42,14 +39,13 @@ static void ...@@ -42,14 +39,13 @@ static void
simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
unsigned long levels = GPLR;
long cs3reg = simpad_get_cs3_ro(); long cs3reg = simpad_get_cs3_ro();
state->detect=((levels & GPIO_CF_CD)==0)?1:0; /* the detect signal is inverted - fix that up here */
state->ready=(levels & GPIO_CF_IRQ)?1:0; state->detect = !state->detect;
state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
state->wrprot=0; /* Not available on Simpad. */
if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) == if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
(PCMCIA_VS1|PCMCIA_VS2)) { (PCMCIA_VS1|PCMCIA_VS2)) {
...@@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
return 0; return 0;
} }
static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{ {
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
simpad_set_cs3_bit(PCMCIA_RESET); simpad_set_cs3_bit(PCMCIA_RESET);
} }
...@@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = { ...@@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
.hw_shutdown = simpad_pcmcia_hw_shutdown, .hw_shutdown = simpad_pcmcia_hw_shutdown,
.socket_state = simpad_pcmcia_socket_state, .socket_state = simpad_pcmcia_socket_state,
.configure_socket = simpad_pcmcia_configure_socket, .configure_socket = simpad_pcmcia_configure_socket,
.socket_init = simpad_pcmcia_socket_init,
.socket_suspend = simpad_pcmcia_socket_suspend, .socket_suspend = simpad_pcmcia_socket_suspend,
}; };
......
...@@ -122,13 +122,12 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state ...@@ -122,13 +122,12 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
local_irq_restore(flags); local_irq_restore(flags);
} }
return 0; return ret;
} }
static struct pcmcia_low_level badge4_pcmcia_ops = { static struct pcmcia_low_level badge4_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.configure_socket = badge4_pcmcia_configure_socket, .configure_socket = badge4_pcmcia_configure_socket,
.socket_init = sa1111_pcmcia_socket_init,
.first = 0, .first = 0,
.nr = 2, .nr = 2,
}; };
......
...@@ -29,23 +29,6 @@ ...@@ -29,23 +29,6 @@
#define IDX_IRQ_S1_CD_VALID (4) #define IDX_IRQ_S1_CD_VALID (4)
#define IDX_IRQ_S1_BVD1_STSCHG (5) #define IDX_IRQ_S1_BVD1_STSCHG (5)
static struct pcmcia_irqs irqs[] = {
{ 0, NO_IRQ, "SA1111 PCMCIA card detect" },
{ 0, NO_IRQ, "SA1111 PCMCIA BVD1" },
{ 1, NO_IRQ, "SA1111 CF card detect" },
{ 1, NO_IRQ, "SA1111 CF BVD1" },
};
static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{ {
struct sa1111_pcmcia_socket *s = to_skt(skt); struct sa1111_pcmcia_socket *s = to_skt(skt);
...@@ -114,26 +97,13 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s ...@@ -114,26 +97,13 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
return 0; return 0;
} }
void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
int (*add)(struct soc_pcmcia_socket *)) int (*add)(struct soc_pcmcia_socket *))
{ {
struct sa1111_pcmcia_socket *s; struct sa1111_pcmcia_socket *s;
int i, ret = 0; int i, ret = 0;
ops->hw_init = sa1111_pcmcia_hw_init;
ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
ops->socket_state = sa1111_pcmcia_socket_state; ops->socket_state = sa1111_pcmcia_socket_state;
ops->socket_suspend = sa1111_pcmcia_socket_suspend;
for (i = 0; i < ops->nr; i++) { for (i = 0; i < ops->nr; i++) {
s = kzalloc(sizeof(*s), GFP_KERNEL); s = kzalloc(sizeof(*s), GFP_KERNEL);
...@@ -141,13 +111,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, ...@@ -141,13 +111,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
return -ENOMEM; return -ENOMEM;
s->soc.nr = ops->first + i; s->soc.nr = ops->first + i;
s->soc.ops = ops; soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
s->soc.socket.owner = ops->owner;
s->soc.socket.dev.parent = &dev->dev;
s->soc.socket.pci_irq = s->soc.nr ?
dev->irq[IDX_IRQ_S0_READY_NINT] :
dev->irq[IDX_IRQ_S1_READY_NINT];
s->dev = dev; s->dev = dev;
if (s->soc.nr) {
s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT];
s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect";
s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1";
} else {
s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT];
s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect";
s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1";
}
ret = add(&s->soc); ret = add(&s->soc);
if (ret == 0) { if (ret == 0) {
...@@ -172,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev) ...@@ -172,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev)
base = dev->mapbase; base = dev->mapbase;
/* Initialize PCMCIA IRQs */
irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
/* /*
* Initialise the suspend state. * Initialise the suspend state.
*/ */
......
...@@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, ...@@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
extern int pcmcia_badge4_init(struct device *); extern int pcmcia_badge4_init(struct device *);
extern int pcmcia_jornada720_init(struct device *); extern int pcmcia_jornada720_init(struct device *);
......
...@@ -78,13 +78,8 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s ...@@ -78,13 +78,8 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
} }
ret = sa1111_pcmcia_configure_socket(skt, state); ret = sa1111_pcmcia_configure_socket(skt, state);
if (ret == 0) { if (ret == 0)
unsigned long flags;
local_irq_save(flags);
sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
local_irq_restore(flags);
}
return ret; return ret;
} }
...@@ -92,7 +87,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s ...@@ -92,7 +87,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
static struct pcmcia_low_level jornada720_pcmcia_ops = { static struct pcmcia_low_level jornada720_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.configure_socket = jornada720_pcmcia_configure_socket, .configure_socket = jornada720_pcmcia_configure_socket,
.socket_init = sa1111_pcmcia_socket_init,
.first = 0, .first = 0,
.nr = 2, .nr = 2,
}; };
......
...@@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static struct pcmcia_low_level lubbock_pcmcia_ops = { static struct pcmcia_low_level lubbock_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.configure_socket = lubbock_pcmcia_configure_socket, .configure_socket = lubbock_pcmcia_configure_socket,
.socket_init = sa1111_pcmcia_socket_init,
.first = 0, .first = 0,
.nr = 2, .nr = 2,
}; };
......
...@@ -103,21 +103,12 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta ...@@ -103,21 +103,12 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
} }
return 0; return ret;
}
static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
if (skt->nr == 0)
NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
sa1111_pcmcia_socket_init(skt);
} }
static struct pcmcia_low_level neponset_pcmcia_ops = { static struct pcmcia_low_level neponset_pcmcia_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.configure_socket = neponset_pcmcia_configure_socket, .configure_socket = neponset_pcmcia_configure_socket,
.socket_init = neponset_pcmcia_socket_init,
.first = 0, .first = 0,
.nr = 2, .nr = 2,
}; };
......
...@@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, ...@@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
skt = &sinfo->skt[i]; skt = &sinfo->skt[i];
skt->nr = first + i; skt->nr = first + i;
skt->ops = ops; soc_pcmcia_init_one(skt, ops, dev);
skt->socket.owner = ops->owner;
skt->socket.dev.parent = dev;
skt->socket.pci_irq = NO_IRQ;
ret = sa11xx_drv_pcmcia_add_one(skt); ret = sa11xx_drv_pcmcia_add_one(skt);
if (ret) if (ret)
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -49,6 +50,8 @@ ...@@ -49,6 +50,8 @@
#include "soc_common.h" #include "soc_common.h"
static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev);
#ifdef CONFIG_PCMCIA_DEBUG #ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug; static int pc_debug;
...@@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, ...@@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
} }
EXPORT_SYMBOL(soc_common_pcmcia_get_timing); EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
unsigned int nr)
{
unsigned int i;
for (i = 0; i < nr; i++) {
if (skt->stat[i].irq)
free_irq(skt->stat[i].irq, skt);
if (gpio_is_valid(skt->stat[i].gpio))
gpio_free(skt->stat[i].gpio);
}
if (skt->ops->hw_shutdown)
skt->ops->hw_shutdown(skt);
}
static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
__soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
}
static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret = 0, i;
if (skt->ops->hw_init) {
ret = skt->ops->hw_init(skt);
if (ret)
return ret;
}
for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
if (gpio_is_valid(skt->stat[i].gpio)) {
int irq;
ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
skt->stat[i].name);
if (ret) {
__soc_pcmcia_hw_shutdown(skt, i);
return ret;
}
irq = gpio_to_irq(skt->stat[i].gpio);
if (i == SOC_STAT_RDY)
skt->socket.pci_irq = irq;
else
skt->stat[i].irq = irq;
}
if (skt->stat[i].irq) {
ret = request_irq(skt->stat[i].irq,
soc_common_pcmcia_interrupt,
IRQF_TRIGGER_NONE,
skt->stat[i].name, skt);
if (ret) {
if (gpio_is_valid(skt->stat[i].gpio))
gpio_free(skt->stat[i].gpio);
__soc_pcmcia_hw_shutdown(skt, i);
return ret;
}
}
}
return ret;
}
static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt)
{
int i;
for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
if (skt->stat[i].irq) {
irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING);
irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH);
}
}
static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
{
int i;
for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
if (skt->stat[i].irq)
irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
}
static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
{ {
struct pcmcia_state state; struct pcmcia_state state;
...@@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) ...@@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
memset(&state, 0, sizeof(struct pcmcia_state)); memset(&state, 0, sizeof(struct pcmcia_state));
/* Make battery voltage state report 'good' */
state.bvd1 = 1;
state.bvd2 = 1;
/* CD is active low by default */
if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
/* RDY and BVD are active high by default */
if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
skt->ops->socket_state(skt, &state); skt->ops->socket_state(skt, &state);
stat = state.detect ? SS_DETECT : 0; stat = state.detect ? SS_DETECT : 0;
...@@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) ...@@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
debug(skt, 2, "initializing socket\n"); debug(skt, 2, "initializing socket\n");
if (skt->ops->socket_init) if (skt->ops->socket_init)
skt->ops->socket_init(skt); skt->ops->socket_init(skt);
soc_pcmcia_hw_enable(skt);
return 0; return 0;
} }
...@@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) ...@@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
debug(skt, 2, "suspending socket\n"); debug(skt, 2, "suspending socket\n");
soc_pcmcia_hw_disable(skt);
if (skt->ops->socket_suspend) if (skt->ops->socket_suspend)
skt->ops->socket_suspend(skt); skt->ops->socket_suspend(skt);
...@@ -526,69 +634,6 @@ static struct pccard_operations soc_common_pcmcia_operations = { ...@@ -526,69 +634,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
}; };
int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
struct pcmcia_irqs *irqs, int nr)
{
int i, res = 0;
for (i = 0; i < nr; i++) {
if (irqs[i].sock != skt->nr)
continue;
res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
IRQF_DISABLED, irqs[i].str, skt);
if (res)
break;
irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
}
if (res) {
printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
irqs[i].irq, res);
while (i--)
if (irqs[i].sock == skt->nr)
free_irq(irqs[i].irq, skt);
}
return res;
}
EXPORT_SYMBOL(soc_pcmcia_request_irqs);
void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
struct pcmcia_irqs *irqs, int nr)
{
int i;
for (i = 0; i < nr; i++)
if (irqs[i].sock == skt->nr)
free_irq(irqs[i].irq, skt);
}
EXPORT_SYMBOL(soc_pcmcia_free_irqs);
void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
struct pcmcia_irqs *irqs, int nr)
{
int i;
for (i = 0; i < nr; i++)
if (irqs[i].sock == skt->nr)
irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
}
EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
struct pcmcia_irqs *irqs, int nr)
{
int i;
for (i = 0; i < nr; i++)
if (irqs[i].sock == skt->nr) {
irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
}
}
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
static LIST_HEAD(soc_pcmcia_sockets); static LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock); static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
...@@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister); ...@@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister);
#endif #endif
void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
struct pcmcia_low_level *ops, struct device *dev)
{
int i;
skt->ops = ops;
skt->socket.owner = ops->owner;
skt->socket.dev.parent = dev;
skt->socket.pci_irq = NO_IRQ;
for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
skt->stat[i].gpio = -EINVAL;
}
EXPORT_SYMBOL(soc_pcmcia_init_one);
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
{ {
mutex_lock(&soc_pcmcia_sockets_lock); mutex_lock(&soc_pcmcia_sockets_lock);
...@@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) ...@@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
skt->ops->hw_shutdown(skt); soc_pcmcia_hw_shutdown(skt);
/* should not be required; violates some lowlevel drivers */
soc_common_pcmcia_config_skt(skt, &dead_socket); soc_common_pcmcia_config_skt(skt, &dead_socket);
list_del(&skt->node); list_del(&skt->node);
...@@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) ...@@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
*/ */
skt->ops->set_timing(skt); skt->ops->set_timing(skt);
ret = skt->ops->hw_init(skt); ret = soc_pcmcia_hw_init(skt);
if (ret) if (ret)
goto out_err_6; goto out_err_6;
...@@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) ...@@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
out_err_7: out_err_7:
skt->ops->hw_shutdown(skt); soc_pcmcia_hw_shutdown(skt);
out_err_6: out_err_6:
list_del(&skt->node); list_del(&skt->node);
mutex_unlock(&soc_pcmcia_sockets_lock); mutex_unlock(&soc_pcmcia_sockets_lock);
......
...@@ -50,6 +50,16 @@ struct soc_pcmcia_socket { ...@@ -50,6 +50,16 @@ struct soc_pcmcia_socket {
struct resource res_attr; struct resource res_attr;
void __iomem *virt_io; void __iomem *virt_io;
struct {
int gpio;
unsigned int irq;
const char *name;
} stat[4];
#define SOC_STAT_CD 0 /* Card detect */
#define SOC_STAT_BVD1 1 /* BATDEAD / IOSTSCHG */
#define SOC_STAT_BVD2 2 /* BATWARN / IOSPKR */
#define SOC_STAT_RDY 3 /* Ready / Interrupt */
unsigned int irq_state; unsigned int irq_state;
struct timer_list poll_timer; struct timer_list poll_timer;
...@@ -115,25 +125,16 @@ struct pcmcia_low_level { ...@@ -115,25 +125,16 @@ struct pcmcia_low_level {
}; };
struct pcmcia_irqs {
int sock;
int irq;
const char *str;
};
struct soc_pcmcia_timing { struct soc_pcmcia_timing {
unsigned short io; unsigned short io;
unsigned short mem; unsigned short mem;
unsigned short attr; unsigned short attr;
}; };
extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
struct pcmcia_low_level *ops, struct device *dev);
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册