diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:37:40 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:37:40 -0700 | 
| commit | 24613ff927500513eae7e84bb6fc6c3ef268e452 (patch) | |
| tree | ef26480a8f123a12690c0f226870cf69dc6ffb55 /drivers/pcmcia | |
| parent | 0d19eac12031680dc5f5402921fb0c388e42f619 (diff) | |
| parent | ff80aa57cc9946d3dafe65119d576b3d11304303 (diff) | |
| download | linux-24613ff927500513eae7e84bb6fc6c3ef268e452.tar.bz2 | |
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
Diffstat (limited to 'drivers/pcmcia')
32 files changed, 348 insertions, 856 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index f9e3fb3a285b..bba3ab2066ee 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -183,10 +183,14 @@ config PCMCIA_BCM63XX  config PCMCIA_SOC_COMMON  	tristate +config PCMCIA_SA11XX_BASE +	tristate +  config PCMCIA_SA1100  	tristate "SA1100 support"  	depends on ARM && ARCH_SA1100 && PCMCIA  	select PCMCIA_SOC_COMMON +	select PCMCIA_SA11XX_BASE  	help  	  Say Y here to include support for SA11x0-based PCMCIA or CF  	  sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ @@ -196,8 +200,9 @@ config PCMCIA_SA1100  config PCMCIA_SA1111  	tristate "SA1111 support" -	depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA +	depends on ARM && SA1111 && PCMCIA  	select PCMCIA_SOC_COMMON +	select PCMCIA_SA11XX_BASE if ARCH_SA1100  	help  	  Say Y  here to include support for SA1111-based PCMCIA or CF  	  sockets, found on the Jornada 720, Graphicsmaster and other @@ -213,6 +218,7 @@ config PCMCIA_PXA2XX  		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \  		    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \  		    || MACH_COLIBRI320) +	select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111  	select PCMCIA_SOC_COMMON  	help  	  Say Y here to include support for the PXA2xx PCMCIA controller diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index ec543a4ff2e4..47525de6a631 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -25,8 +25,9 @@ obj-$(CONFIG_I82092)				+= i82092.o  obj-$(CONFIG_TCIC)				+= tcic.o  obj-$(CONFIG_PCMCIA_M8XX)			+= m8xx_pcmcia.o  obj-$(CONFIG_PCMCIA_SOC_COMMON)			+= soc_common.o -obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_base.o sa1100_cs.o -obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_base.o sa1111_cs.o +obj-$(CONFIG_PCMCIA_SA11XX_BASE)		+= sa11xx_base.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_CFC)				+= m32r_cfc.o  obj-$(CONFIG_PCMCIA_BCM63XX)			+= bcm63xx_pcmcia.o @@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o  obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o  sa1111_cs-y					+= sa1111_generic.o -sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1100_neponset.o -sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1100_badge4.o -sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1100_jornada720.o +sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1111_neponset.o +sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1111_badge4.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-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.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_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-obj-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock_cs.o  pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o  pxa2xx-obj-$(CONFIG_PXA_SHARPSL)		+= pxa2xx_sharpsl.o  pxa2xx-obj-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x2xx_cs.o diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index 22a75e610f12..2ef576c5b69d 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c @@ -29,15 +29,6 @@  #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)  {  	uint16_t ver; @@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  			ver);  	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) -{ -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	return 0;  }  static unsigned long balloon3_pcmcia_status[2] = { @@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  			disable_irq(BALLOON3_BP_NSTSCHG_IRQ);  	} -	state->detect	= !gpio_get_value(BALLOON3_GPIO_S0_CD);  	state->ready	= !!(status & BALLOON3_CF_nIRQ);  	state->bvd1	= !!(status & BALLOON3_CF_nSTSCHG_BVD1);  	state->bvd2	= 0;	/* not available */  	state->vs_3v	= 1;	/* Always true its a CF card */  	state->vs_Xv	= 0;	/* not available */ -	state->wrprot	= 0;	/* not available */  }  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 = {  	.owner			= THIS_MODULE,  	.hw_init		= balloon3_pcmcia_hw_init, -	.hw_shutdown		= balloon3_pcmcia_hw_shutdown,  	.socket_state		= balloon3_pcmcia_socket_state,  	.configure_socket	= balloon3_pcmcia_configure_socket,  	.first			= 0, diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 64d433ec4fc6..66a54222bbf4 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)  		skt->nr = ops->first + i;  		skt->clk = clk; -		skt->ops = ops; -		skt->socket.owner = ops->owner; -		skt->socket.dev.parent = &dev->dev; -		skt->socket.pci_irq = NO_IRQ; +		soc_pcmcia_init_one(skt, ops, &dev->dev);  		ret = pxa2xx_drv_pcmcia_add_one(skt);  		if (ret) diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c index 31ab6ddf52c9..da40908b29dd 100644 --- a/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/drivers/pcmcia/pxa2xx_cm_x255.c @@ -25,17 +25,6 @@  #define GPIO_PCMCIA_S1_RDYINT	(8)  #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)  {  	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); @@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  		return ret;  	gpio_direction_output(GPIO_PCMCIA_RESET, 0); -	skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; -	irqs[0].irq = PCMCIA_S0_CD_VALID; -	irqs[1].irq = PCMCIA_S1_CD_VALID; -	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -	if (!ret) -		gpio_free(GPIO_PCMCIA_RESET); +	if (skt->nr == 0) { +		skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; +		skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; +	} 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)  { -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));  	gpio_free(GPIO_PCMCIA_RESET);  } @@ -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,  				       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_Xv  = 0; -	state->wrprot = 0;  /* not available */  } diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 3dc7621a0767..f59223f2307d 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -22,14 +22,6 @@  #define GPIO_PCMCIA_S0_RDYINT	(82)  #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)  {  	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); @@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  		return ret;  	gpio_direction_output(GPIO_PCMCIA_RESET, 0); -	skt->socket.pci_irq = PCMCIA_S0_RDYINT; -	irqs[0].irq = PCMCIA_S0_CD_VALID; -	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -	if (!ret) -		gpio_free(GPIO_PCMCIA_RESET); +	skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; +	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; +	skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; +	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";  	return ret;  }  static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)  { -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));  	gpio_free(GPIO_PCMCIA_RESET);  } @@ -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,  				       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_Xv  = 0; -	state->wrprot = 0;  /* not available */  } diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c6dec572a05d..4dee7b2a8032 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = {  	{ 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)  {  	int ret; @@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	if (ret)  		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->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:  	return ret;  } @@ -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->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);  	state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); -	state->wrprot = 0;  	state->vs_3v  = 1;  	state->vs_Xv  = 0;  } diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c index 17cd2ce7428f..8751a323b448 100644 --- a/drivers/pcmcia/pxa2xx_e740.c +++ b/drivers/pcmcia/pxa2xx_e740.c @@ -23,53 +23,27 @@  #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)  { -	if (skt->nr == 0) -		skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0); -	else -		skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1); - -	cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0); -	cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1); - -	return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); -} +	if (skt->nr == 0) { +		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0; +		skt->stat[SOC_STAT_CD].name = "CF card detect"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0; +		skt->stat[SOC_STAT_RDY].name = "CF ready"; +	} else { +		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1; +		skt->stat[SOC_STAT_CD].name = "Wifi switch"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1; +		skt->stat[SOC_STAT_RDY].name = "Wifi ready"; +	} -/* - * Release all resources. - */ -static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ -	soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1); +	return 0;  }  static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  					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->bvd1   = 1; -	state->bvd2   = 1; -	state->wrprot = 0;  	state->vs_Xv  = 0;  } @@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  	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 = {  	.owner            = THIS_MODULE,  	.hw_init          = e740_pcmcia_hw_init, -	.hw_shutdown      = e740_pcmcia_hw_shutdown,  	.socket_state     = e740_pcmcia_socket_state,  	.configure_socket = e740_pcmcia_configure_socket, -	.socket_init      = e740_pcmcia_socket_init, -	.socket_suspend   = e740_pcmcia_socket_suspend,  	.nr               = 2,  }; diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index aded706c0b9f..7e32e25cdcb2 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -30,27 +30,26 @@  #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)  {  	/*  	 * Setup default state of GPIO outputs  	 * before we enable them as outputs.  	 */ - -	skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; -	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	if (skt->nr == 0) { +		skt->socket.pci_irq = MAINSTONE_S0_IRQ; +		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; +		skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; +	} else { +		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]; @@ -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->vs_3v  = (status & MST_PCMCIA_nVS1) ? 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, @@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  static struct pcmcia_low_level mst_pcmcia_ops __initdata = {  	.owner			= THIS_MODULE,  	.hw_init		= mst_pcmcia_hw_init, -	.hw_shutdown		= mst_pcmcia_hw_shutdown,  	.socket_state		= mst_pcmcia_socket_state,  	.configure_socket	= mst_pcmcia_configure_socket,  	.nr			= 2, diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6a8e011a8c13..ed7d4dbc39fa 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c @@ -23,7 +23,6 @@  static struct gpio palmld_pcmcia_gpios[] = {  	{ GPIO_NR_PALMLD_PCMCIA_POWER,	GPIOF_INIT_LOW,	"PCMCIA Power" },  	{ 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) @@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	ret = gpio_request_array(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;  } @@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  					struct pcmcia_state *state)  {  	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_Xv  = 0;  } diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 9e38de769ba3..81225a7a8cbb 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c @@ -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_POWER3,	GPIOF_INIT_LOW,	"PCMCIA Power 3" },  	{ 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" },  }; @@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	ret = gpio_request_array(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;  } @@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  					struct pcmcia_state *state)  {  	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_Xv  = 0;  } diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index 80645a688ee3..069b6bbcf319 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c @@ -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_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },  	{ 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) @@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	ret = gpio_request_array(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;  } @@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  					struct pcmcia_state *state)  {  	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_Xv  = 0;  } diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 69ae2fd22400..b066273b6b4f 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -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)  { -	int ret; - -	/* Register interrupts */  	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; -		ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); - -		if (ret) { -			printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); -			return ret; -		} +		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;  	}  	skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; @@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	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,  				    struct pcmcia_state *state)  { @@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)  static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {  	.owner                  = THIS_MODULE,  	.hw_init                = sharpsl_pcmcia_hw_init, -	.hw_shutdown            = sharpsl_pcmcia_hw_shutdown,  	.socket_state           = sharpsl_pcmcia_socket_state,  	.configure_socket       = sharpsl_pcmcia_configure_socket,  	.socket_init            = sharpsl_pcmcia_socket_init, diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c index 6c2366b74a35..1d73c4401fdd 100644 --- a/drivers/pcmcia/pxa2xx_stargate2.c +++ b/drivers/pcmcia/pxa2xx_stargate2.c @@ -33,10 +33,6 @@  #define SG2_S0_GPIO_DETECT	53  #define SG2_S0_GPIO_READY	81 -static struct pcmcia_irqs irqs[] = { -	{.sock = 0, .str = "PCMCIA0 CD" }, -}; -  static struct gpio sg2_pcmcia_gpios[] = {  	{ SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },  	{ SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, @@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = {  static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  { -	skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY); -	irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT); - -	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT; +	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; +	skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY; +	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; +	return 0;  }  static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  				    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->bvd2   = 0; /* not available */  	state->vs_3v  = 1; /* not available - voltage detect for card */  	state->vs_Xv  = 0; /* not available */ -	state->wrprot = 0; /* not available - write protect */  }  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;  } -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 = {  	.owner			= THIS_MODULE,  	.hw_init		= sg2_pcmcia_hw_init, -	.hw_shutdown		= sg2_pcmcia_hw_shutdown,  	.socket_state		= sg2_pcmcia_socket_state,  	.configure_socket	= sg2_pcmcia_configure_socket, -	.socket_init		= sg2_pcmcia_socket_init, -	.socket_suspend		= sg2_pcmcia_socket_suspend,  	.nr			= 1,  }; diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index 7c33f898135a..d326ba1fa1ce 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c @@ -29,32 +29,17 @@  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)  { -	int ret, i;  	/* we dont have voltage/card/ready detection  	 * so we dont need interrupts for it  	 */  	switch (skt->nr) {  	case 0: -		if (gpio_request(GPIO_PRDY, "cf_irq") < 0) { -			pr_err("%s: sock %d unable to request gpio %d\n", __func__, -				skt->nr, GPIO_PRDY); -			return -EBUSY; -		} -		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); +		skt->stat[SOC_STAT_CD].gpio = GPIO_PCD; +		skt->stat[SOC_STAT_CD].name = "cs0_cd"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY; +		skt->stat[SOC_STAT_RDY].name = "cs0_rdy";  		break;  	default:  		break; @@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	/* release the reset of this card */  	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); -	/* supplementory irqs for the socket */ -	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)); +	return 0;  }  static unsigned long trizeps_pcmcia_status[2]; @@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  	switch (skt->nr) {  	case 0:  		/* 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->bvd2   = (status & ConXS_CFSR_BVD2) ? 1 : 0;  		state->vs_3v  = (status & ConXS_CFSR_VS1) ? 0 : 1;  		state->vs_Xv  = (status & ConXS_CFSR_VS2) ? 0 : 1; -		state->wrprot = 0;	/* not available */  		break;  #ifndef CONFIG_MACH_TRIZEPS_CONXS @@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  		state->bvd2   = 0;  		state->vs_3v  = 0;  		state->vs_Xv  = 0; -		state->wrprot = 0;  		break;  #endif @@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)  static struct pcmcia_low_level trizeps_pcmcia_ops = {  	.owner			= THIS_MODULE,  	.hw_init		= trizeps_pcmcia_hw_init, -	.hw_shutdown		= trizeps_pcmcia_hw_shutdown,  	.socket_state		= trizeps_pcmcia_socket_state,  	.configure_socket	= trizeps_pcmcia_configure_socket,  	.socket_init		= trizeps_pcmcia_socket_init, diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index 1064b1c2869d..adfae4987a42 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c @@ -32,13 +32,6 @@  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)  {  	return arcom_pcmcia_dev->dev.platform_data; @@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();  	unsigned long flags; -	skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio); -	irqs[0].irq = gpio_to_irq(pdata->cd_gpio); - -	if (gpio_request(pdata->cd_gpio, "CF detect")) -		goto err_request_cd; - -	if (gpio_request(pdata->rdy_gpio, "CF ready")) -		goto err_request_rdy; +	skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio; +	skt->stat[SOC_STAT_CD].name = "PCMCIA_CD"; +	skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio; +	skt->stat[SOC_STAT_RDY].name = "CF ready";  	if (gpio_request(pdata->pwr_gpio, "CF power"))  		goto err_request_pwr;  	local_irq_save(flags); -	if (gpio_direction_output(pdata->pwr_gpio, 0) || -	    gpio_direction_input(pdata->cd_gpio) || -	    gpio_direction_input(pdata->rdy_gpio)) { +	if (gpio_direction_output(pdata->pwr_gpio, 0)) {  		local_irq_restore(flags);  		goto err_dir;  	}  	local_irq_restore(flags); -	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	return 0;  err_dir:  	gpio_free(pdata->pwr_gpio);  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");  	return -1;  } @@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)  {  	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->rdy_gpio); -	gpio_free(pdata->cd_gpio);  }  static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  				      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_Xv  = 0;  } diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 61b17d235dbe..a47dcd24a26a 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -23,29 +23,14 @@  #include "soc_common.h"  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" },  	{ GPIO11_VPAC270_PCMCIA_RESET,	GPIOF_INIT_LOW,	"PCMCIA Reset" },  };  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" },  }; -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)  {  	int ret; @@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  		ret = gpio_request_array(vpac270_pcmcia_gpios,  				ARRAY_SIZE(vpac270_pcmcia_gpios)); -		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); -		cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); - -		if (!ret) -			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); +		skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD; +		skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";  	} else {  		ret = gpio_request_array(vpac270_cf_gpios,  				ARRAY_SIZE(vpac270_cf_gpios)); -		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); -		cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); - -		if (!ret) -			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); +		skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD; +		skt->stat[SOC_STAT_CD].name = "CF CD"; +		skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY; +		skt->stat[SOC_STAT_RDY].name = "CF Ready";  	}  	return ret; @@ -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,  					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_Xv  = 0;  } @@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  	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 = {  	.owner			= THIS_MODULE, @@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = {  	.socket_state		= vpac270_pcmcia_socket_state,  	.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; diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c index f1e882272ab0..ba8557eea618 100644 --- a/drivers/pcmcia/sa1100_assabet.c +++ b/drivers/pcmcia/sa1100_assabet.c @@ -10,46 +10,30 @@  #include <linux/interrupt.h>  #include <linux/device.h>  #include <linux/init.h> +#include <linux/gpio.h> -#include <mach/hardware.h>  #include <asm/mach-types.h> -#include <asm/irq.h> -#include <asm/signal.h>  #include <mach/assabet.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)  { -	skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; - -	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} +	skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; +	skt->stat[SOC_STAT_CD].name = "CF CD"; +	skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; +	skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; +	skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; +	skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; +	skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; +	skt->stat[SOC_STAT_RDY].name = "CF RDY"; -/* - * Release all resources. - */ -static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	return 0;  }  static void  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_Xv  = 0;  } @@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat  		return -1;  	} -	/* Silently ignore Vpp, output enable, speaker enable. */ +	/* Silently ignore Vpp, speaker enable. */  	if (state->flags & SS_RESET)  		mask |= ASSABET_BCR_CF_RST; +	if (!(state->flags & SS_OUTPUT_ENA)) +		mask |= ASSABET_BCR_CF_BUS_OFF; -	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); +	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | +			ASSABET_BCR_CF_BUS_OFF, mask);  	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.   */  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  	 * reset as per user guide page 4-11. @@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)  static struct pcmcia_low_level assabet_pcmcia_ops = {   	.owner			= THIS_MODULE, -  	.hw_init		= assabet_pcmcia_hw_init, -	.hw_shutdown		= assabet_pcmcia_hw_shutdown, -  	.socket_state		= assabet_pcmcia_socket_state,  	.configure_socket	= assabet_pcmcia_configure_socket, - -	.socket_init		= assabet_pcmcia_socket_init,  	.socket_suspend		= assabet_pcmcia_socket_suspend,  }; diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 30560df8c76b..c59c44921a3a 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -10,6 +10,7 @@  #include <linux/device.h>  #include <linux/init.h>  #include <linux/delay.h> +#include <linux/gpio.h>  #include <mach/hardware.h>  #include <asm/mach-types.h> @@ -19,34 +20,34 @@  #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)  { -	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)  { -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	gpio_free(CERF_GPIO_CF_RESET);  }  static void  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_Xv	= 0;  } @@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  		return -1;  	} -	if (state->flags & SS_RESET) { -		GPSR = CERF_GPIO_CF_RESET; -	} else { -		GPCR = CERF_GPIO_CF_RESET; -	} +	gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));  	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 = {   	.owner			= THIS_MODULE,  	.hw_init		= cerf_pcmcia_hw_init,  	.hw_shutdown		= cerf_pcmcia_hw_shutdown,  	.socket_state		= cerf_pcmcia_socket_state,  	.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) diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index edf8f0028898..d9c7337b909c 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c @@ -19,36 +19,20 @@  #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)  {  	int err;  	switch (skt->nr) {  	case 0: -		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); -		if (err) -			goto err00; -		err = gpio_direction_input(H3XXX_GPIO_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); +		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0; +		skt->stat[SOC_STAT_CD].name = "PCMCIA CD0"; +		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";  		err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");  		if (err) -			goto err02; +			goto err01;  		err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);  		if (err)  			goto err03; @@ -70,30 +54,12 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  		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) -			goto err06;  		break;  	case 1: -		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); -		if (err) -			goto err10; -		err = gpio_direction_input(H3XXX_GPIO_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; +		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1; +		skt->stat[SOC_STAT_CD].name = "PCMCIA CD1"; +		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";  		break;  	}  	return 0; @@ -102,19 +68,12 @@ err06:	gpio_free(H3XXX_EGPIO_CARD_RESET);  err05:	gpio_free(H3XXX_EGPIO_OPT_RESET);  err04:	gpio_free(H3XXX_EGPIO_OPT_ON);  err03:	gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); -err02:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);  err01:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); -err00:	return err; - -err12:	gpio_free(H3XXX_GPIO_PCMCIA_CD0); -err11:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); -err10:	return err; +	return err;  }  static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)  { -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); -    	switch (skt->nr) {  	case 0:  		/* Disable CF bus: */ @@ -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_ON);  		gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); -		gpio_free(H3XXX_GPIO_PCMCIA_CD0); -		gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);  		break;  	case 1: -		gpio_free(H3XXX_GPIO_PCMCIA_CD1); -		gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);  		break;  	}  } @@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)  static void  h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)  { -	switch (skt->nr) { -	case 0: -		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); -		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); -		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; -	} +	state->bvd1 = 0; +	state->bvd2 = 0; +	state->vs_3v = 0; +	state->vs_Xv = 0;  }  static int @@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)  	gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);  	msleep(10); - -	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));  }  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  	 * the generic PCMCIA layer to deal with the idea of two sockets diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c index 93b9c9ba57c3..35c30ff41e81 100644 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ b/drivers/pcmcia/sa1100_nanoengine.c @@ -19,6 +19,7 @@   */  #include <linux/device.h>  #include <linux/errno.h> +#include <linux/gpio.h>  #include <linux/interrupt.h>  #include <linux/irq.h>  #include <linux/init.h> @@ -34,43 +35,23 @@  #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 { -	unsigned input_pins;  	unsigned output_pins;  	unsigned clear_outputs; -	unsigned transition_pins; -	unsigned pci_irq; -	struct pcmcia_irqs *pcmcia_irqs; -	unsigned pcmcia_irqs_size; +	int gpio_rst; +	int gpio_cd; +	int gpio_rdy;  };  static struct nanoengine_pins nano_skts[] = {  	{ -		.input_pins		= GPIO_PC_READY0 | GPIO_PC_CD0, -		.output_pins		= GPIO_PC_RESET0, -		.clear_outputs		= GPIO_PC_RESET0, -		.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) +		.gpio_rst		= GPIO_PC_RESET0, +		.gpio_cd		= GPIO_PC_CD0, +		.gpio_rdy		= GPIO_PC_READY0,  	}, { -		.input_pins		= GPIO_PC_READY1 | GPIO_PC_CD1, -		.output_pins		= GPIO_PC_RESET1, -		.clear_outputs		= GPIO_PC_RESET1, -		.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) +		.gpio_rst		= GPIO_PC_RESET1, +		.gpio_cd		= GPIO_PC_CD1, +		.gpio_rdy		= GPIO_PC_READY1,  	}  }; @@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);  static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)  {  	unsigned i = skt->nr; +	int ret;  	if (i >= num_nano_pcmcia_sockets)  		return -ENXIO; -	GPDR &= ~nano_skts[i].input_pins; -	GPDR |= nano_skts[i].output_pins; -	GPCR = nano_skts[i].clear_outputs; -	irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); -	skt->socket.pci_irq = nano_skts[i].pci_irq; +	ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW, +		i ? "PC RST1" : "PC RST0"); +	if (ret) +		return ret; + +	skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; +	skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; +	skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy; +	skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0"; -	return soc_pcmcia_request_irqs(skt, -		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); +	return 0;  } -/* - * Release all resources. - */  static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)  { -	unsigned i = skt->nr; - -	if (i >= num_nano_pcmcia_sockets) -		return; - -	soc_pcmcia_free_irqs(skt, -		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); +	gpio_free(nano_skts[skt->nr].gpio_rst);  }  static int nanoengine_pcmcia_configure_socket(  	struct soc_pcmcia_socket *skt, const socket_state_t *state)  { -	unsigned reset;  	unsigned i = skt->nr;  	if (i >= num_nano_pcmcia_sockets)  		return -ENXIO; -	switch (i) { -	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; +	gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));  	return 0;  } @@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket(  static void nanoengine_pcmcia_socket_state(  	struct soc_pcmcia_socket *skt, struct pcmcia_state *state)  { -	unsigned long levels = GPLR;  	unsigned i = skt->nr;  	if (i >= num_nano_pcmcia_sockets)  		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->bvd2 = 1; -	state->wrprot = 0; /* Not available */  	state->vs_3v = 1; /* Can only apply 3.3V */  	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 = {  	.owner			= THIS_MODULE, @@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = {  	.configure_socket	= nanoengine_pcmcia_configure_socket,  	.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) diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c index 7ff1b43540b8..decb34730bcf 100644 --- a/drivers/pcmcia/sa1100_shannon.c +++ b/drivers/pcmcia/sa1100_shannon.c @@ -15,40 +15,35 @@  #include <asm/irq.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)  {  	/* All those are inputs */ -	GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |  -		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); -	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |  -		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); - -	skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; - -	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} +	GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) | +		  GPIO_GPIO(SHANNON_GPIO_EJECT_1) | +		  GPIO_GPIO(SHANNON_GPIO_RDY_0) | +		  GPIO_GPIO(SHANNON_GPIO_RDY_1)); + +	if (skt->nr == 0) { +		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0; +		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0"; +		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0"; +	} else { +		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1; +		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1"; +		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1; +		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1"; +	} -static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); +	return 0;  }  static void  shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  			    struct pcmcia_state *state)  { -	unsigned long levels = GPLR; -  	switch (skt->nr) {  	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->bvd2   = 1;   		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,  		break;  	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->bvd2   = 1;   		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,  	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 = {  	.owner			= THIS_MODULE,  	.hw_init		= shannon_pcmcia_hw_init, -	.hw_shutdown		= shannon_pcmcia_hw_shutdown,  	.socket_state		= shannon_pcmcia_socket_state,  	.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) diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index 0fac9658b020..8647b17c449e 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c @@ -15,24 +15,21 @@  #include <mach/simpad.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)  {  	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)  { -	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); -  	/* Disable CF bus: */  	/*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/  	simpad_clear_cs3_bit(PCMCIA_RESET); @@ -42,14 +39,13 @@ static void  simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,  			   struct pcmcia_state *state)  { -	unsigned long levels = GPLR;  	long cs3reg = simpad_get_cs3_ro(); -	state->detect=((levels & GPIO_CF_CD)==0)?1:0; -	state->ready=(levels & GPIO_CF_IRQ)?1:0; +	/* the detect signal is inverted - fix that up here */ +	state->detect = !state->detect; +  	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */  	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ -	state->wrprot=0; /* Not available on Simpad. */  	if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==  			(PCMCIA_VS1|PCMCIA_VS2)) { @@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  	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)  { -	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));  	simpad_set_cs3_bit(PCMCIA_RESET);  } @@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {  	.hw_shutdown		= simpad_pcmcia_hw_shutdown,  	.socket_state		= simpad_pcmcia_socket_state,  	.configure_socket	= simpad_pcmcia_configure_socket, -	.socket_init		= simpad_pcmcia_socket_init,  	.socket_suspend		= simpad_pcmcia_socket_suspend,  }; diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1111_badge4.c index 1ce53f493bef..4d206f4dd67b 100644 --- a/drivers/pcmcia/sa1100_badge4.c +++ b/drivers/pcmcia/sa1111_badge4.c @@ -122,13 +122,12 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state  		local_irq_restore(flags);  	} -	return 0; +	return ret;  }  static struct pcmcia_low_level badge4_pcmcia_ops = {  	.owner			= THIS_MODULE,  	.configure_socket	= badge4_pcmcia_configure_socket, -	.socket_init		= sa1111_pcmcia_socket_init,  	.first			= 0,  	.nr			= 2,  }; diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 27f2fe3b7fb4..ef5848f65241 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -29,23 +29,6 @@  #define IDX_IRQ_S1_CD_VALID	(4)  #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)  {  	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  	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 (*add)(struct soc_pcmcia_socket *))  {  	struct sa1111_pcmcia_socket *s;  	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_suspend = sa1111_pcmcia_socket_suspend;  	for (i = 0; i < ops->nr; i++) {  		s = kzalloc(sizeof(*s), GFP_KERNEL); @@ -141,13 +111,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,  			return -ENOMEM;  		s->soc.nr = ops->first + i; -		s->soc.ops = ops; -		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]; +		soc_pcmcia_init_one(&s->soc, ops, &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);  		if (ret == 0) { @@ -172,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev)  	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.  	 */ diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index 02dc8577cdaf..f6376e34a7e4 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h @@ -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 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_jornada720_init(struct device *); diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c index 6bcabee6bde4..69428d1f5ae1 100644 --- a/drivers/pcmcia/sa1100_jornada720.c +++ b/drivers/pcmcia/sa1111_jornada720.c @@ -78,13 +78,8 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s  	}  	ret = sa1111_pcmcia_configure_socket(skt, state); -	if (ret == 0) { -		unsigned long flags; - -		local_irq_save(flags); +	if (ret == 0)  		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); -		local_irq_restore(flags); -	}  	return ret;  } @@ -92,7 +87,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s  static struct pcmcia_low_level jornada720_pcmcia_ops = {  	.owner			= THIS_MODULE,  	.configure_socket	= jornada720_pcmcia_configure_socket, -	.socket_init		= sa1111_pcmcia_socket_init,  	.first			= 0,  	.nr			= 2,  }; diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c index c21888eebb58..c5caf5790451 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/sa1111_lubbock.c @@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,  static struct pcmcia_low_level lubbock_pcmcia_ops = {  	.owner			= THIS_MODULE,  	.configure_socket	= lubbock_pcmcia_configure_socket, -	.socket_init		= sa1111_pcmcia_socket_init,  	.first			= 0,  	.nr			= 2,  }; diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1111_neponset.c index c95639b5f2a0..50f297d850e7 100644 --- a/drivers/pcmcia/sa1100_neponset.c +++ b/drivers/pcmcia/sa1111_neponset.c @@ -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);  	} -	return 0; -} - -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); +	return ret;  }  static struct pcmcia_low_level neponset_pcmcia_ops = {  	.owner			= THIS_MODULE,  	.configure_socket	= neponset_pcmcia_configure_socket, -	.socket_init		= neponset_pcmcia_socket_init,  	.first			= 0,  	.nr			= 2,  }; diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 0c62fe31a40e..a3ee89a6dd0e 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,  		skt = &sinfo->skt[i];  		skt->nr = first + i; -		skt->ops = ops; -		skt->socket.owner = ops->owner; -		skt->socket.dev.parent = dev; -		skt->socket.pci_irq = NO_IRQ; +		soc_pcmcia_init_one(skt, ops, dev);  		ret = sa11xx_drv_pcmcia_add_one(skt);  		if (ret) diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index a0a9c2aa8d78..e0433f571962 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -32,6 +32,7 @@  #include <linux/cpufreq.h> +#include <linux/gpio.h>  #include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h> @@ -49,6 +50,8 @@  #include "soc_common.h" +static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev); +  #ifdef CONFIG_PCMCIA_DEBUG  static int pc_debug; @@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,  }  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)  {  	struct pcmcia_state state; @@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)  	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);  	stat = state.detect  ? SS_DETECT : 0; @@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)  	debug(skt, 2, "initializing socket\n");  	if (skt->ops->socket_init)  		skt->ops->socket_init(skt); +	soc_pcmcia_hw_enable(skt);  	return 0;  } @@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)  	debug(skt, 2, "suspending socket\n"); +	soc_pcmcia_hw_disable(skt);  	if (skt->ops->socket_suspend)  		skt->ops->socket_suspend(skt); @@ -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 DEFINE_MUTEX(soc_pcmcia_sockets_lock); @@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister);  #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)  {  	mutex_lock(&soc_pcmcia_sockets_lock); @@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)  	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);  	list_del(&skt->node); @@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)  	 */  	skt->ops->set_timing(skt); -	ret = skt->ops->hw_init(skt); +	ret = soc_pcmcia_hw_init(skt);  	if (ret)  		goto out_err_6; @@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)  	pcmcia_unregister_socket(&skt->socket);   out_err_7: -	skt->ops->hw_shutdown(skt); +	soc_pcmcia_hw_shutdown(skt);   out_err_6:  	list_del(&skt->node);  	mutex_unlock(&soc_pcmcia_sockets_lock); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 9daa73615c8b..e6fcbea5b682 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -50,6 +50,16 @@ struct soc_pcmcia_socket {  	struct resource		res_attr;  	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;  	struct timer_list	poll_timer; @@ -115,25 +125,16 @@ struct pcmcia_low_level {  }; -struct pcmcia_irqs { -	int sock; -	int irq; -	const char *str; -}; -  struct soc_pcmcia_timing {  	unsigned short io;  	unsigned short mem;  	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 *); - +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);  int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);  |