summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/arm/xscale/pxa2x0_pcic.c222
-rw-r--r--sys/arch/arm/xscale/pxapcicvar.h12
2 files changed, 131 insertions, 103 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_pcic.c b/sys/arch/arm/xscale/pxa2x0_pcic.c
index c59496f3750..cab860786f8 100644
--- a/sys/arch/arm/xscale/pxa2x0_pcic.c
+++ b/sys/arch/arm/xscale/pxa2x0_pcic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_pcic.c,v 1.1 2004/12/30 23:48:17 drahn Exp $ */
+/* $OpenBSD: pxa2x0_pcic.c,v 1.2 2005/01/04 05:37:43 drahn Exp $ */
/*
* Copyright (c) Dale Rahn <drahn@openbsd.org>
*
@@ -312,61 +312,38 @@ pxapcic_set_power(struct pxapcic_socket *so, int arg)
int
pxapcic_match(struct device *parent, void *v, void *aux)
{
- return (1);
+ return (0);
}
void
pxapcic_event_thread(void *arg)
{
- struct pxapcic_softc *sc = arg;
+ struct pxapcic_socket *sock = arg;
u_int16_t csr;
int present;
- while (sc->sc_shutdown == 0) {
+ while (sock->sc->sc_shutdown == 0) {
/* sleep .25s to avoid chatterling interrupts */
- (void) tsleep((caddr_t)sc, PWAIT,
+ (void) tsleep((caddr_t)sock, PWAIT,
"pxapcicss", hz/4);
- csr = bus_space_read_2(sc->sc_iot, sc->sc_scooph,
+ csr = bus_space_read_2(sock->sc->sc_iot, sock->scooph,
SCOOP_REG_CSR);
- present = sc->sc_socket[0].flags & PXAPCIC_FLAG_CARDP;
+ present = sock->flags & PXAPCIC_FLAG_CARDP;
if (((csr & SCP_CSR_MISSING) == 0) == (present == 1))
continue; /* state unchanged */
-
-#if 0
- printf("pxapcic_event_thread\n");
-
- printf("SCOOP_CSR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CSR));
- printf("SCOOP_CDR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CDR));
- printf("SCOOP_CPR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CPR));
- printf("SCOOP_CCR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CCR));
- printf("SCOOP_MCR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_MCR));
- printf("SCOOP_IMR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR));
- printf("SCOOP_IRR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IRR));
-#endif
-
/* XXX Do both? */
- pxapcic_event_process(&sc->sc_socket[0]);
-#if NUM_CF_CARDS > 1
- pxapcic_event_process(&sc->sc_socket[1]);
-#endif
+ pxapcic_event_process(sock);
}
- sc->sc_event_thread = NULL;
+ sock->event_thread = NULL;
/* In case parent is waiting for us to exit. */
- wakeup(sc);
+ wakeup(sock->sc);
kthread_exit(0);
}
@@ -404,25 +381,25 @@ pxapcic_event_process_st(void *v)
pxapcic_event_process(h);
}
void
-pxapcic_event_process(h)
- struct pxapcic_socket *h;
+pxapcic_event_process(sock)
+ struct pxapcic_socket *sock;
{
- struct pxapcic_softc *sc = h->sc;
+ struct pxapcic_softc *sc = sock->sc;
u_int16_t csr;
- csr = bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CSR);
+ csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR);
switch (csr & SCP_CSR_MISSING) {
case 0: /* PRESENT */
- //DPRINTF(("%s: insertion event\n", h->sc->dv_xname));
- if (!(h->flags & PXAPCIC_FLAG_CARDP))
- pxapcic_attach_card(h);
+ //DPRINTF(("%s: insertion event\n", sock->sc->dv_xname));
+ if (!(sock->flags & PXAPCIC_FLAG_CARDP))
+ pxapcic_attach_card(sock);
break;
case SCP_CSR_MISSING:
- //DPRINTF(("%s: removal event\n", h->sc->dv_xname));
- if ((h->flags & PXAPCIC_FLAG_CARDP))
- pxapcic_detach_card(h, DETACH_FORCE);
+ //DPRINTF(("%s: removal event\n", sock->sc->dv_xname));
+ if ((sock->flags & PXAPCIC_FLAG_CARDP))
+ pxapcic_detach_card(sock, DETACH_FORCE);
break;
}
}
@@ -430,27 +407,32 @@ pxapcic_event_process(h)
void
pxapcic_create_event_thread(void *arg)
{
- struct pxapcic_softc *sc = arg;
+ struct pxapcic_socket *sock = arg;
+ struct pxapcic_softc *sc = sock->sc;
u_int16_t csr;
- csr = bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CSR);
+ csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR);
+ printf("%s%d: create event, csr %d\n", sc->sc_dev.dv_xname,
+ sock->socket, csr);
/* if there's a card there, then attach it */
switch (csr & SCP_CSR_MISSING) {
case 0: /* PRESENT */
- pxapcic_attach_card(&sc->sc_socket[0]);
+ pxapcic_attach_card(sock);
break;
default:
;
}
- if (kthread_create(pxapcic_event_thread, sc, &sc->sc_event_thread,
- sc->sc_dev.dv_xname, "0")) {
+ if (kthread_create(pxapcic_event_thread, sock, &sock->event_thread,
+ sc->sc_dev.dv_xname, sock->socket ? "1" : "0")) {
printf("%s: unable to create event thread for %s\n",
- sc->sc_dev.dv_xname, "0");
+ sc->sc_dev.dv_xname, sock->socket ? "1" : "0");
}
+ /*
config_pending_decr();
+ */
}
int
@@ -476,63 +458,75 @@ pxapcic_attach(struct device *parent, struct device *self, void *aux)
struct pxapcic_softc *sc = (struct pxapcic_softc *)self;
struct pxaip_attach_args *pxa = aux;
struct pxapcic_socket *so;
+ bus_space_tag_t iot;
+ bus_space_handle_t scooph;
int i;
int error;
- bus_addr_t pa = 0x10800000;
+ bus_addr_t pa;
bus_size_t size = 0x100;
sc->sc_iot = pxa->pxa_iot;
-/*
- pxa->pxa_addr;
- pxa->pxa_size = 0x20;
-*/
sc->sc_shutdown = 0;
-
- /* scoop? */
- error = bus_space_map(sc->sc_iot, pa, size, 0, &sc->sc_scooph);
-
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR,
- 0x00c0);
-
-
-#if 0
- printf("SCOOP_CSR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CSR));
- printf("SCOOP_CDR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CDR));
- printf("SCOOP_CPR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CPR));
- printf("SCOOP_CCR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CCR));
- printf("SCOOP_MCR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_MCR));
- printf("SCOOP_IMR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR));
- printf("SCOOP_IRR 0x%04x\n",
- bus_space_read_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IRR));
-#endif
-
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_MCR, 0x0100);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CDR, 0x0000);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CPR, 0x0000);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR, 0x0000);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IRM, 0x00ff);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_ISR, 0x0000);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR, 0x0000);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_CPR,
- SCP_CPR_PWR|SCP_CPR_3V);
-
printf("\n");
for(i = 0; i < NUM_CF_CARDS; i++) {
+ iot = sc->sc_iot;
so = &sc->sc_socket[i];
so->sc = sc;
so->socket = i;
so->flags = 0;
+ /* scoop? */
+ if (so->socket == 0)
+ pa = 0x10800000;
+ else if (so->socket == 1)
+ pa = 0x14800000;
+ else {
+ printf ("%s: invalid CF slot %d\n", sc->sc_dev.dv_xname,
+ i);
+ continue;
+ }
+ error = bus_space_map(iot, pa, size, 0, &scooph);
+ if (error) {
+ printf ("%s%d:failed to map memory %x for scoop\n",
+ sc->sc_dev.dv_xname, i, pa);
+ continue;
+ }
+ so->scooph = scooph;
+
+ {
+ u_int16_t val;
+ /* probe */
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_IMR);
+ printf("scoop%d: IMR %x\n", i, val);
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_MCR);
+ printf("scoop%d: MCR %x\n", i, val);
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_CDR);
+ printf("scoop%d: CDR %x\n", i, val);
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_CPR);
+ printf("scoop%d: CPR %x\n", i, val);
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_IRM);
+ printf("scoop%d: IRM %x\n", i, val);
+ val = bus_space_read_2(iot, scooph, SCOOP_REG_ISR);
+ printf("scoop%d: ISR %x\n", i, val);
+ }
+
+ bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x00c0);
+
/* setup */
+ bus_space_write_2(iot, scooph, SCOOP_REG_MCR, 0x0100);
+ bus_space_write_2(iot, scooph, SCOOP_REG_CDR, 0x0000);
+ bus_space_write_2(iot, scooph, SCOOP_REG_CPR, 0x0000);
+ bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x0000);
+ bus_space_write_2(iot, scooph, SCOOP_REG_IRM, 0x00ff);
+ bus_space_write_2(iot, scooph, SCOOP_REG_ISR, 0x0000);
+ bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x0000);
+
+ bus_space_write_2(iot, scooph, SCOOP_REG_CPR,
+ SCP_CPR_PWR|SCP_CPR_3V);
+
paa.paa_busname = "pcmcia";
paa.pct = (pcmcia_chipset_tag_t) &pxapcic_pcmcia_functions;
@@ -544,23 +538,57 @@ pxapcic_attach(struct device *parent, struct device *self, void *aux)
pxapcic_submatch);
}
+#if 0
+ /* XXX 860 */
+ so = &sc->sc_socket[0];
pxa2x0_gpio_set_function(14, GPIO_IN);
pxa2x0_gpio_set_function(17, GPIO_IN);
-
sc->sc_irq = pxa2x0_gpio_intr_establish(14 /*???*/, IST_EDGE_FALLING,
- IPL_BIO /* XXX */, pxapcic_intr_detect, sc, sc->sc_dev.dv_xname);
-
+ IPL_BIO /* XXX */, pxapcic_intr_detect, so, sc->sc_dev.dv_xname);
+ sc->sc_socket[0].irqpin = 17; /* GPIO pin for interrupt */
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_IMR, 0x00ce);
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_MCR, 0x0111);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_IMR, 0x00ce);
- bus_space_write_2(sc->sc_iot, sc->sc_scooph, SCOOP_REG_MCR, 0x0111);
+ config_pending_incr();
+ kthread_create_deferred(pxapcic_create_event_thread, so);
+#else
+
+ /* XXX c3000 */
+ so = &sc->sc_socket[0];
+ pxa2x0_gpio_set_function(105, GPIO_IN); /* GPIO_CF_IRQ */
+ pxa2x0_gpio_set_function(106, GPIO_IN); /* GPIO_CF2_IRQ */
+ pxa2x0_gpio_set_function(94, GPIO_IN); /* GPIO_CF_CD */
+ pxa2x0_gpio_set_function(93, GPIO_IN); /* GPIO_CF2_CD */
+ sc->sc_socket[0].irq = pxa2x0_gpio_intr_establish(94 /*???*/,
+ IST_EDGE_FALLING, IPL_BIO /* XXX */, pxapcic_intr_detect,
+ so, sc->sc_dev.dv_xname);
+ sc->sc_socket[0].irqpin = 105; /* GPIO pin for interrupt */
- sc->sc_gpio = 17; /* GPIO pin for interrupt */
-
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_IMR, 0x00ce);
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_MCR, 0x0111);
+
+ /*
config_pending_incr();
- kthread_create_deferred(pxapcic_create_event_thread, sc);
+ */
+ kthread_create_deferred(pxapcic_create_event_thread, so);
+
+ so = &sc->sc_socket[1];
+ sc->sc_socket[1].irq = pxa2x0_gpio_intr_establish(93 /*???*/,
+ IST_EDGE_FALLING, IPL_BIO /* XXX */, pxapcic_intr_detect,
+ so, sc->sc_dev.dv_xname);
+ sc->sc_socket[1].irqpin = 106; /* GPIO pin for interrupt */
+
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_IMR, 0x00ce);
+ bus_space_write_2(sc->sc_iot, so->scooph, SCOOP_REG_MCR, 0x0111);
+
+ /*
+ config_pending_incr();
+ */
+ kthread_create_deferred(pxapcic_create_event_thread, so);
+#endif
}
diff --git a/sys/arch/arm/xscale/pxapcicvar.h b/sys/arch/arm/xscale/pxapcicvar.h
index f282001ab32..acd1076a9c9 100644
--- a/sys/arch/arm/xscale/pxapcicvar.h
+++ b/sys/arch/arm/xscale/pxapcicvar.h
@@ -1,15 +1,17 @@
-/* $OpenBSD: pxapcicvar.h,v 1.2 2005/01/02 19:52:37 drahn Exp $ */
+/* $OpenBSD: pxapcicvar.h,v 1.3 2005/01/04 05:37:43 drahn Exp $ */
struct pxapcic_socket {
struct pxapcic_softc *sc;
int socket; /* socket number */
struct device *pcmcia;
- /*
- struct pxapcic_tag *pcictag;
- */
+ struct proc *event_thread;
+
+ bus_space_handle_t scooph;
int flags;
int power_capability;
+ int irqpin;
+ void *irq;
void *pcictag_cookie; /* opaque data for pcictag functions */
};
@@ -38,9 +40,7 @@ struct pxapcic_softc {
struct pxapcic_socket sc_socket[2];
bus_space_tag_t sc_iot;
- bus_space_handle_t sc_scooph;
- struct proc *sc_event_thread;
void *sc_irq;
int sc_gpio;
int sc_shutdown;