patch-2.4.19 linux-2.4.19/drivers/pcmcia/sa1100_cerf.c
Next file: linux-2.4.19/drivers/pcmcia/sa1100_flexanet.c
Previous file: linux-2.4.19/drivers/pcmcia/sa1100_badge4.c
Back to the patch index
Back to the overall index
- Lines: 220
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/pcmcia/sa1100_cerf.c
- Orig date:
Thu Oct 25 13:53:48 2001
diff -urN linux-2.4.18/drivers/pcmcia/sa1100_cerf.c linux-2.4.19/drivers/pcmcia/sa1100_cerf.c
@@ -10,40 +10,55 @@
#include <asm/hardware.h>
#include <asm/irq.h>
-#include <asm/arch/pcmcia.h>
+#include "sa1100_generic.h"
+#ifdef CONFIG_SA1100_CERF_CPLD
+#define CERF_SOCKET 0
+#else
+#define CERF_SOCKET 1
+#endif
-static int cerf_pcmcia_init(struct pcmcia_init *init){
- int irq, res;
+static struct irqs {
+ int irq;
+ unsigned int gpio;
+ const char *str;
+} irqs[] = {
+ { IRQ_GPIO_CF_CD, GPIO_CF_CD, "CF_CD" },
+ { IRQ_GPIO_CF_BVD2, GPIO_CF_BVD2, "CF_BVD2" },
+ { IRQ_GPIO_CF_BVD1, GPIO_CF_BVD1, "CF_BVD1" }
+};
- GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
- GPDR |= (GPIO_CF_RESET);
+static int cerf_pcmcia_init(struct pcmcia_init *init)
+{
+ int i, res;
- set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
- irq = IRQ_GPIO_CF_CD;
- res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
- if( res < 0 ) goto irq_err;
- irq = IRQ_GPIO_CF_BVD2;
- res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
- if( res < 0 ) goto irq_err;
- irq = IRQ_GPIO_CF_BVD1;
- res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
- if( res < 0 ) goto irq_err;
+ for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+ set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
+ res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+ irqs[i].str, NULL);
+ if (res)
+ goto irq_err;
+ }
return 2;
-irq_err:
- printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+ irq_err:
+ printk(KERN_ERR "%s: Request for IRQ%d failed\n", __FUNCTION__, irqs[i].irq);
+
+ while (i--)
+ free_irq(irqs[i].irq, NULL);
+
return -1;
}
static int cerf_pcmcia_shutdown(void)
{
- free_irq( IRQ_GPIO_CF_CD, NULL );
- free_irq( IRQ_GPIO_CF_BVD2, NULL );
- free_irq( IRQ_GPIO_CF_BVD1, NULL );
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(irqs); i++)
+ free_irq(irqs[i].irq, NULL);
return 0;
}
@@ -51,31 +66,18 @@
static int cerf_pcmcia_socket_state(struct pcmcia_state_array
*state_array){
unsigned long levels;
-#ifdef CONFIG_SA1100_CERF_CPLD
- int i = 0;
-#else
- int i = 1;
-#endif
+ int i = CERF_SOCKET;
if(state_array->size<2) return -1;
- memset(state_array->state, 0,
- (state_array->size)*sizeof(struct pcmcia_state));
-
levels=GPLR;
state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
-
state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
-
state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
-
state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
-
state_array->state[i].wrprot=0;
-
state_array->state[i].vs_3v=1;
-
state_array->state[i].vs_Xv=0;
return 1;
@@ -85,11 +87,7 @@
if(info->sock>1) return -1;
-#ifdef CONFIG_SA1100_CERF_CPLD
- if(info->sock==0)
-#else
- if(info->sock==1)
-#endif
+ if (info->sock == CERF_SOCKET)
info->irq=IRQ_GPIO_CF_IRQ;
return 0;
@@ -98,20 +96,12 @@
static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
*configure)
{
- unsigned long flags;
-
if(configure->sock>1)
return -1;
-#ifdef CONFIG_SA1100_CERF_CPLD
- if(configure->sock==1)
-#else
- if(configure->sock==0)
-#endif
+ if (configure->sock != CERF_SOCKET)
return 0;
- save_flags_cli(flags);
-
switch(configure->vcc){
case 0:
break;
@@ -119,43 +109,62 @@
case 50:
case 33:
#ifdef CONFIG_SA1100_CERF_CPLD
- GPDR |= GPIO_PWR_SHUTDOWN;
- GPCR |= GPIO_PWR_SHUTDOWN;
+ GPCR = GPIO_PWR_SHUTDOWN;
#endif
break;
default:
printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
configure->vcc);
- restore_flags(flags);
return -1;
}
if(configure->reset)
{
#ifdef CONFIG_SA1100_CERF_CPLD
- GPDR |= GPIO_CF_RESET;
- GPSR |= GPIO_CF_RESET;
+ GPSR = GPIO_CF_RESET;
#endif
}
else
{
#ifdef CONFIG_SA1100_CERF_CPLD
- GPDR |= GPIO_CF_RESET;
- GPCR |= GPIO_CF_RESET;
+ GPCR = GPIO_CF_RESET;
#endif
}
- restore_flags(flags);
+ return 0;
+}
+
+static int cerf_pcmcia_socket_init(int sock)
+{
+ int i;
+
+ if (sock == CERF_SOCKET)
+ for (i = 0; i < ARRAY_SIZE(irqs); i++)
+ set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
+
+ return 0;
+}
+
+static int cerf_pcmcia_socket_suspend(int sock)
+{
+ int i;
+
+ if (sock == CERF_SOCKET)
+ for (i = 0; i < ARRAY_SIZE(irqs); i++)
+ set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
return 0;
}
struct pcmcia_low_level cerf_pcmcia_ops = {
- cerf_pcmcia_init,
- cerf_pcmcia_shutdown,
- cerf_pcmcia_socket_state,
- cerf_pcmcia_get_irq_info,
- cerf_pcmcia_configure_socket
+ init: cerf_pcmcia_init,
+ shutdown: cerf_pcmcia_shutdown,
+ socket_state: cerf_pcmcia_socket_state,
+ get_irq_info: cerf_pcmcia_get_irq_info,
+ configure_socket: cerf_pcmcia_configure_socket,
+
+ socket_init: cerf_pcmcia_socket_init,
+ socket_suspend: cerf_pcmcia_socket_suspend,
};
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)