Home | History | Annotate | Line # | Download | only in imx
imx_pcic.c revision 1.2.2.1
      1  1.2.2.1  wrstuden /*	$Id: imx_pcic.c,v 1.2.2.1 2008/09/18 04:33:21 wrstuden Exp $	*/
      2      1.2      matt 
      3      1.2      matt /*
      4      1.2      matt  * IMX CF interface to pcic/pcmcia
      5      1.2      matt  * derived from pxa2x0_pcic
      6      1.2      matt  * Sun Apr  1 21:42:37 PDT 2007
      7      1.2      matt  */
      8      1.2      matt 
      9  1.2.2.1  wrstuden /*	$NetBSD: imx_pcic.c,v 1.2.2.1 2008/09/18 04:33:21 wrstuden Exp $	*/
     10      1.2      matt /*	$OpenBSD: pxa2x0_pcic.c,v 1.17 2005/12/14 15:08:51 uwe Exp $	*/
     11      1.2      matt 
     12      1.2      matt /*
     13      1.2      matt  * Copyright (c) 2005 Dale Rahn <drahn (at) openbsd.org>
     14      1.2      matt  *
     15      1.2      matt  * Permission to use, copy, modify, and distribute this software for any
     16      1.2      matt  * purpose with or without fee is hereby granted, provided that the above
     17      1.2      matt  * copyright notice and this permission notice appear in all copies.
     18      1.2      matt  *
     19      1.2      matt  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     20      1.2      matt  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     21      1.2      matt  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     22      1.2      matt  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     23      1.2      matt  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     24      1.2      matt  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     25      1.2      matt  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     26      1.2      matt  */
     27      1.2      matt 
     28      1.2      matt #include <sys/cdefs.h>
     29  1.2.2.1  wrstuden __KERNEL_RCSID(0, "$Id: imx_pcic.c,v 1.2.2.1 2008/09/18 04:33:21 wrstuden Exp $");
     30      1.2      matt 
     31      1.2      matt #include <sys/param.h>
     32      1.2      matt #include <sys/systm.h>
     33      1.2      matt #include <sys/device.h>
     34      1.2      matt #include <sys/kernel.h>
     35      1.2      matt #include <sys/kthread.h>
     36      1.2      matt #include <sys/malloc.h>
     37      1.2      matt 
     38      1.2      matt #include <uvm/uvm.h>
     39      1.2      matt 
     40      1.2      matt #include <machine/bus.h>
     41      1.2      matt #include <machine/intr.h>
     42      1.2      matt 
     43      1.2      matt #include <dev/pcmcia/pcmciareg.h>
     44      1.2      matt #include <dev/pcmcia/pcmciavar.h>
     45      1.2      matt #include <dev/pcmcia/pcmciachip.h>
     46      1.2      matt 
     47      1.2      matt #ifdef NOTYET
     48      1.2      matt #include <arm/imx/imx_gpio.h>
     49      1.2      matt #endif
     50      1.2      matt #include <arm/imx/imx_pcic.h>
     51      1.2      matt 
     52      1.2      matt static int	imx_pcic_print(void *, const char *);
     53      1.2      matt 
     54      1.2      matt static void	imx_pcic_event_thread(void *);
     55      1.2      matt #ifdef NOTYET
     56      1.2      matt static void	imx_pcic_event_process(struct imx_pcic_socket *);
     57      1.2      matt static void	imx_pcic_attach_card(struct imx_pcic_socket *);
     58      1.2      matt #endif
     59      1.2      matt #ifdef NOTYET
     60      1.2      matt static void	imx_pcic_detach_card(struct imx_pcic_socket *, int);
     61      1.2      matt #endif
     62      1.2      matt 
     63      1.2      matt static int	imx_pcic_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
     64      1.2      matt 		    struct pcmcia_mem_handle *);
     65      1.2      matt static void	imx_pcic_mem_free(pcmcia_chipset_handle_t,
     66      1.2      matt 		    struct pcmcia_mem_handle *);
     67      1.2      matt static int	imx_pcic_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
     68      1.2      matt 		   bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
     69      1.2      matt static void	imx_pcic_mem_unmap(pcmcia_chipset_handle_t, int);
     70      1.2      matt 
     71      1.2      matt static int	imx_pcic_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
     72      1.2      matt 		    bus_size_t, bus_size_t, struct pcmcia_io_handle *);
     73      1.2      matt static void	imx_pcic_io_free(pcmcia_chipset_handle_t,
     74      1.2      matt 		    struct pcmcia_io_handle *);
     75      1.2      matt static int	imx_pcic_io_map(pcmcia_chipset_handle_t, int,
     76      1.2      matt 		    bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *);
     77      1.2      matt static void	imx_pcic_io_unmap(pcmcia_chipset_handle_t, int);
     78      1.2      matt 
     79      1.2      matt static void	*imx_pcic_intr_establish(pcmcia_chipset_handle_t,
     80      1.2      matt 		    struct pcmcia_function *, int, int (*)(void *), void *);
     81      1.2      matt static void	imx_pcic_intr_disestablish(pcmcia_chipset_handle_t, void *);
     82      1.2      matt 
     83      1.2      matt static void	imx_pcic_socket_enable(pcmcia_chipset_handle_t);
     84      1.2      matt static void	imx_pcic_socket_disable(pcmcia_chipset_handle_t);
     85      1.2      matt static void	imx_pcic_socket_settype(pcmcia_chipset_handle_t, int);
     86      1.2      matt 
     87      1.2      matt /*
     88      1.2      matt  * PCMCIA chipset methods
     89      1.2      matt  */
     90      1.2      matt static struct pcmcia_chip_functions imx_pcic_pcmcia_functions = {
     91      1.2      matt 	imx_pcic_mem_alloc,
     92      1.2      matt 	imx_pcic_mem_free,
     93      1.2      matt 	imx_pcic_mem_map,
     94      1.2      matt 	imx_pcic_mem_unmap,
     95      1.2      matt 
     96      1.2      matt 	imx_pcic_io_alloc,
     97      1.2      matt 	imx_pcic_io_free,
     98      1.2      matt 	imx_pcic_io_map,
     99      1.2      matt 	imx_pcic_io_unmap,
    100      1.2      matt 
    101      1.2      matt 	imx_pcic_intr_establish,
    102      1.2      matt 	imx_pcic_intr_disestablish,
    103      1.2      matt 
    104      1.2      matt 	imx_pcic_socket_enable,
    105      1.2      matt 	imx_pcic_socket_disable,
    106      1.2      matt 	imx_pcic_socket_settype,
    107      1.2      matt };
    108      1.2      matt 
    109      1.2      matt #define IMX_MEMCTL_BASE	0x08000000		/* XXX */
    110      1.2      matt #define IMX_MEMCTL_SIZE	0x00000010		/* XXX */
    111      1.2      matt #define IMX_PCIC_SOCKET_BASE	0x08009000		/* XXX */
    112      1.2      matt #define IMX_PCIC_SOCKET_OFFSET	0x00000000		/* XXX */
    113      1.2      matt #define	IMX_PCIC_ATTR_OFFSET	0x00000800		/* XXX 5912 */
    114      1.2      matt #define	IMX_PCIC_COMMON_OFFSET	0x00000000		/* XXX 5912 */
    115      1.2      matt 
    116      1.2      matt 
    117      1.2      matt 
    118      1.2      matt /*
    119      1.2      matt  * PCMCIA Helpers
    120      1.2      matt  */
    121      1.2      matt static int
    122      1.2      matt imx_pcic_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size,
    123      1.2      matt     struct pcmcia_mem_handle *pmh)
    124      1.2      matt {
    125      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    126      1.2      matt 
    127      1.2      matt 	/* All we need is the bus space tag */
    128      1.2      matt 	memset(pmh, 0, sizeof(*pmh));
    129      1.2      matt 	pmh->memt = so->sc->sc_iot;
    130      1.2      matt 
    131      1.2      matt 	return 0;
    132      1.2      matt }
    133      1.2      matt 
    134      1.2      matt static void
    135      1.2      matt imx_pcic_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pmh)
    136      1.2      matt {
    137      1.2      matt 
    138      1.2      matt 	/* Nothing to do */
    139      1.2      matt }
    140      1.2      matt 
    141      1.2      matt static int
    142      1.2      matt imx_pcic_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr,
    143      1.2      matt     bus_size_t size, struct pcmcia_mem_handle *pmh, bus_size_t *offsetp,
    144      1.2      matt     int *windowp)
    145      1.2      matt {
    146      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    147      1.2      matt 	int error;
    148      1.2      matt 	bus_addr_t pa;
    149      1.2      matt 
    150  1.2.2.1  wrstuden printf("%s: card_addr %lx\n", __func__, card_addr);
    151      1.2      matt 	pa = trunc_page(card_addr);
    152      1.2      matt 	*offsetp = card_addr - pa;
    153  1.2.2.1  wrstuden printf("%s: offset %lx\n", __func__, *offsetp);
    154      1.2      matt 	size = round_page(card_addr + size) - pa;
    155      1.2      matt 	pmh->realsize = size;
    156      1.2      matt 
    157      1.2      matt 	pa += IMX_PCIC_SOCKET_BASE;
    158      1.2      matt 	pa += IMX_PCIC_SOCKET_OFFSET * so->socket;
    159  1.2.2.1  wrstuden printf("%s: pa %lx\n", __func__, pa);
    160  1.2.2.1  wrstuden printf("%s: kind %x\n", __func__, kind);
    161      1.2      matt 
    162      1.2      matt 	switch (kind & ~PCMCIA_WIDTH_MEM_MASK) {
    163      1.2      matt 	case PCMCIA_MEM_ATTR:
    164      1.2      matt 		pa += IMX_PCIC_ATTR_OFFSET;
    165      1.2      matt 		break;
    166      1.2      matt 	case PCMCIA_MEM_COMMON:
    167      1.2      matt 		pa += IMX_PCIC_COMMON_OFFSET;
    168      1.2      matt 		break;
    169      1.2      matt 	default:
    170      1.2      matt 		panic("imx_pcic_mem_map: bogus kind");
    171      1.2      matt 	}
    172      1.2      matt 
    173  1.2.2.1  wrstuden printf("%s: pa %lx\n", __func__, pa);
    174      1.2      matt Debugger();
    175      1.2      matt 	error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pmh->memh);
    176      1.2      matt 	if (error)
    177      1.2      matt 		return error;
    178      1.2      matt 
    179      1.2      matt 	*windowp = (int)pmh->memh;
    180      1.2      matt 	return 0;
    181      1.2      matt }
    182      1.2      matt 
    183      1.2      matt static void
    184      1.2      matt imx_pcic_mem_unmap(pcmcia_chipset_handle_t pch, int window)
    185      1.2      matt {
    186      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    187      1.2      matt 
    188      1.2      matt 	bus_space_unmap(so->sc->sc_iot, (bus_addr_t)window, 4096); /* XXX */
    189      1.2      matt }
    190      1.2      matt 
    191      1.2      matt static int
    192      1.2      matt imx_pcic_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start,
    193      1.2      matt     bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pih)
    194      1.2      matt {
    195      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    196      1.2      matt 	bus_addr_t pa;
    197      1.2      matt 	int error;
    198      1.2      matt 
    199      1.2      matt 	memset(pih, 0, sizeof(*pih));
    200      1.2      matt 	pih->iot = so->sc->sc_iot;
    201      1.2      matt 	pih->addr = start;
    202      1.2      matt 	pih->size = size;
    203      1.2      matt 
    204      1.2      matt 	pa = pih->addr;
    205      1.2      matt 	pa += IMX_PCIC_SOCKET_BASE;
    206      1.2      matt 	pa += IMX_PCIC_SOCKET_OFFSET * so->socket;
    207      1.2      matt 
    208      1.2      matt 	/* XXX Are we ignoring alignment constraints? */
    209      1.2      matt 	error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pih->ioh);
    210      1.2      matt 
    211      1.2      matt 	return error;
    212      1.2      matt }
    213      1.2      matt 
    214      1.2      matt static void
    215      1.2      matt imx_pcic_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pih)
    216      1.2      matt {
    217      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    218      1.2      matt 
    219      1.2      matt 	bus_space_unmap(so->sc->sc_iot, pih->ioh, pih->size);
    220      1.2      matt }
    221      1.2      matt 
    222      1.2      matt static int
    223      1.2      matt imx_pcic_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset,
    224      1.2      matt     bus_size_t size, struct pcmcia_io_handle *pih, int *windowp)
    225      1.2      matt {
    226      1.2      matt 
    227      1.2      matt 	return 0;
    228      1.2      matt }
    229      1.2      matt 
    230      1.2      matt static void
    231      1.2      matt imx_pcic_io_unmap(pcmcia_chipset_handle_t pch, int window)
    232      1.2      matt {
    233      1.2      matt 
    234      1.2      matt 	/* Nothing to do */
    235      1.2      matt }
    236      1.2      matt 
    237      1.2      matt static void *
    238      1.2      matt imx_pcic_intr_establish(pcmcia_chipset_handle_t pch,
    239      1.2      matt     struct pcmcia_function *pf, int ipl, int (*fct)(void *), void *arg)
    240      1.2      matt {
    241      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    242      1.2      matt 	/* XXX need to check if something should be done here */
    243      1.2      matt 
    244      1.2      matt 	return (*so->pcictag->intr_establish)(so, ipl, fct, arg);
    245      1.2      matt }
    246      1.2      matt 
    247      1.2      matt static void
    248      1.2      matt imx_pcic_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih)
    249      1.2      matt {
    250      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    251      1.2      matt 
    252      1.2      matt 	(*so->pcictag->intr_disestablish)(so, ih);
    253      1.2      matt }
    254      1.2      matt 
    255      1.2      matt static void
    256      1.2      matt imx_pcic_socket_enable(pcmcia_chipset_handle_t pch)
    257      1.2      matt {
    258      1.2      matt #ifdef NOTYET
    259      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    260      1.2      matt 	int i;
    261      1.2      matt 
    262      1.2      matt 	/* Power down the card and socket before setting the voltage. */
    263      1.2      matt 	(*so->pcictag->write)(so, IMX_PCIC_CARD_POWER, IMX_PCIC_POWER_OFF);
    264      1.2      matt 	(*so->pcictag->set_power)(so, IMX_PCIC_POWER_OFF);
    265      1.2      matt 
    266      1.2      matt 	/*
    267      1.2      matt 	 * Wait 300ms until power fails (Tpf).  Then, wait 100ms since
    268      1.2      matt 	 * we are changing Vcc (Toff).
    269      1.2      matt 	 */
    270      1.2      matt 	delay((300 + 100) * 1000);
    271      1.2      matt 
    272      1.2      matt 	/* Power up the socket and card at appropriate voltage. */
    273      1.2      matt 	if (so->power_capability & IMX_PCIC_POWER_5V) {
    274      1.2      matt 		(*so->pcictag->set_power)(so, IMX_PCIC_POWER_5V);
    275      1.2      matt 		(*so->pcictag->write)(so, IMX_PCIC_CARD_POWER,
    276      1.2      matt 		    IMX_PCIC_POWER_5V);
    277      1.2      matt 	} else {
    278      1.2      matt 		(*so->pcictag->set_power)(so, IMX_PCIC_POWER_3V);
    279      1.2      matt 		(*so->pcictag->write)(so, IMX_PCIC_CARD_POWER,
    280      1.2      matt 		    IMX_PCIC_POWER_3V);
    281      1.2      matt 	}
    282      1.2      matt 
    283      1.2      matt 	/*
    284      1.2      matt 	 * Wait 100ms until power raise (Tpr) and 20ms to become
    285      1.2      matt 	 * stable (Tsu(Vcc)).
    286      1.2      matt 	 *
    287      1.2      matt 	 * Some machines require some more time to be settled
    288      1.2      matt 	 * (another 200ms is added here).
    289      1.2      matt 	 */
    290      1.2      matt 	delay((100 + 20 + 200) * 1000);
    291      1.2      matt 
    292      1.2      matt 	/* Hold RESET at least 10us. */
    293      1.2      matt 	(*so->pcictag->write)(so, IMX_PCIC_CARD_RESET, 1);
    294      1.2      matt 	delay(10);
    295      1.2      matt 	/* XXX wrong, but lets TE-CF100 cards work for some reason. */
    296      1.2      matt 	delay(3000);
    297      1.2      matt 	(*so->pcictag->write)(so, IMX_PCIC_CARD_RESET, 0);
    298      1.2      matt 
    299      1.2      matt 	/* Wait 20ms as per PC Card standard (r2.01) section 4.3.6. */
    300      1.2      matt 	delay(20 * 1000);
    301      1.2      matt 
    302      1.2      matt 	/* Wait for the card to become ready. */
    303      1.2      matt 	for (i = 0; i < 10000; i++) {
    304      1.2      matt 		if ((*so->pcictag->read)(so, IMX_PCIC_CARD_READY))
    305      1.2      matt 			break;
    306      1.2      matt 		delay(500);
    307      1.2      matt 	}
    308      1.2      matt #else
    309  1.2.2.1  wrstuden printf("%s: (stubbed)\n", __func__);
    310      1.2      matt #endif	/* NOTYET */
    311      1.2      matt }
    312      1.2      matt 
    313      1.2      matt static void
    314      1.2      matt imx_pcic_socket_disable(pcmcia_chipset_handle_t pch)
    315      1.2      matt {
    316      1.2      matt #ifdef NOTYET
    317      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)pch;
    318      1.2      matt 
    319      1.2      matt #ifdef PCICDEBUG
    320      1.2      matt 	printf("imx_pcic_socket_disable: socket %d\n", so->socket);
    321      1.2      matt #endif
    322      1.2      matt 
    323      1.2      matt 	/* Power down the card and socket. */
    324      1.2      matt 	(*so->pcictag->write)(so, IMX_PCIC_CARD_POWER, IMX_PCIC_POWER_OFF);
    325      1.2      matt 	(*so->pcictag->set_power)(so, IMX_PCIC_POWER_OFF);
    326      1.2      matt #endif	/* NOTYET */
    327      1.2      matt }
    328      1.2      matt 
    329      1.2      matt static void
    330      1.2      matt imx_pcic_socket_settype(pcmcia_chipset_handle_t pch, int type)
    331      1.2      matt {
    332      1.2      matt 
    333      1.2      matt #ifdef PCICDEBUG
    334      1.2      matt 	printf("imx_pcic_socket_settype: type=%d",type);
    335      1.2      matt 
    336      1.2      matt 	switch (type) {
    337      1.2      matt 	case PCMCIA_IFTYPE_MEMORY:
    338      1.2      matt 		printf("(Memory)\n");
    339      1.2      matt 		break;
    340      1.2      matt 	case PCMCIA_IFTYPE_IO:
    341      1.2      matt 		printf("(I/O)\n");
    342      1.2      matt 		break;
    343      1.2      matt 	default:
    344      1.2      matt 		printf("(unknown)\n");
    345      1.2      matt 		break;
    346      1.2      matt 	}
    347      1.2      matt #endif
    348      1.2      matt }
    349      1.2      matt 
    350      1.2      matt /*
    351      1.2      matt  * Attachment and initialization
    352      1.2      matt  */
    353      1.2      matt static int
    354      1.2      matt imx_pcic_print(void *aux, const char *name)
    355      1.2      matt {
    356      1.2      matt 
    357      1.2      matt 	return UNCONF;
    358      1.2      matt }
    359      1.2      matt 
    360      1.2      matt void
    361      1.2      matt imx_pcic_attach_common(struct imx_pcic_softc *sc,
    362      1.2      matt     void (*socket_setup_hook)(struct imx_pcic_socket *))
    363      1.2      matt {
    364      1.2      matt 	struct pcmciabus_attach_args paa;
    365      1.2      matt 	struct imx_pcic_socket *so;
    366      1.2      matt 	int s[IMX_PCIC_NSLOT];
    367      1.2      matt 	int i;
    368      1.2      matt 
    369      1.2      matt 	printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots < 2 ? "" : "s");
    370      1.2      matt 
    371      1.2      matt 	if (sc->sc_nslots == 0) {
    372      1.2      matt 		aprint_error("%s: can't attach\n", sc->sc_dev.dv_xname);
    373      1.2      matt 		return;
    374      1.2      matt 	}
    375      1.2      matt 
    376      1.2      matt 	if (bus_space_map(sc->sc_iot, IMX_MEMCTL_BASE, IMX_MEMCTL_SIZE,
    377      1.2      matt 	    0, &sc->sc_memctl_ioh)) {
    378      1.2      matt 		aprint_error("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname);
    379      1.2      matt 		return;
    380      1.2      matt 	}
    381      1.2      matt 
    382      1.2      matt #if 0
    383      1.2      matt 	/* Clear CIT (card present) and set NOS correctly. */
    384      1.2      matt 	bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR,
    385      1.2      matt 	    (sc->sc_nslots == 2) ? MECR_NOS : 0);
    386      1.2      matt #endif
    387      1.2      matt 
    388      1.2      matt 	if (sc->sc_flags & PPF_REVERSE_ORDER) {
    389      1.2      matt 		for (i = 0; i < sc->sc_nslots; i++) {
    390      1.2      matt 			s[i] = sc->sc_nslots - 1 - i;
    391      1.2      matt 		}
    392      1.2      matt 	} else {
    393      1.2      matt 		for (i = 0; i < sc->sc_nslots; i++) {
    394      1.2      matt 			s[i] = i;
    395      1.2      matt 		}
    396      1.2      matt 	}
    397      1.2      matt 
    398      1.2      matt 	for (i = 0; i < sc->sc_nslots; i++) {
    399      1.2      matt 		so = &sc->sc_socket[s[i]];
    400      1.2      matt 		so->sc = sc;
    401      1.2      matt 		so->socket = s[i];
    402      1.2      matt 		so->flags = 0;
    403      1.2      matt 
    404      1.2      matt 		(*socket_setup_hook)(so);
    405      1.2      matt 
    406      1.2      matt 		paa.paa_busname = "pcmcia";
    407      1.2      matt 		paa.pct = (pcmcia_chipset_tag_t)&imx_pcic_pcmcia_functions;
    408      1.2      matt 		paa.pch = (pcmcia_chipset_handle_t)so;
    409  1.2.2.1  wrstuden printf("%s: sc_pa %lx\n", __func__, sc->sc_pa);
    410      1.2      matt 		paa.iobase = sc->sc_pa;
    411      1.2      matt 		paa.iosize = 0x2000;
    412      1.2      matt 
    413      1.2      matt 		so->pcmcia = config_found_ia(&sc->sc_dev, "pcmciabus", &paa,
    414      1.2      matt 		    imx_pcic_print);
    415      1.2      matt 
    416      1.2      matt #ifdef NOTYET
    417      1.2      matt 		imx_gpio_set_direction(sc->sc_irqpin[s[i]], GPIO_IN);
    418      1.2      matt 		imx_gpio_set_direction(sc->sc_irqcfpin[s[i]], GPIO_IN);
    419      1.2      matt 
    420      1.2      matt 		/* Card slot interrupt */
    421      1.2      matt 		so->irq = imx_gpio_intr_establish(sc->sc_irqcfpin[s[i]],
    422      1.2      matt 		    IST_EDGE_BOTH, IPL_BIO /* XXX */, "pcic",
    423      1.2      matt 		    imx_pcic_intr, so);
    424      1.2      matt 
    425      1.2      matt 		/* GPIO pin for interrupt */
    426      1.2      matt 		so->irqpin = sc->sc_irqpin[s[i]];
    427      1.2      matt #else
    428      1.2      matt 		so->irqpin = sc->sc_irqpin[s[i]];
    429  1.2.2.1  wrstuden printf("%s: slot %d, irqpin %d\n",  __func__, s[i], sc->sc_irqpin[s[i]]);
    430      1.2      matt #endif	/* NOTYET */
    431      1.2      matt 
    432      1.2      matt 		if (kthread_create(PRI_NONE, 0, NULL,
    433      1.2      matt 		    imx_pcic_event_thread, so, &so->event_thread,
    434      1.2      matt 		    "%s,%d", sc->sc_dev.dv_xname, so->socket) != 0) {
    435      1.2      matt 			printf("%s: unable to create event thread for %d\n",
    436      1.2      matt 				sc->sc_dev.dv_xname, so->socket);
    437      1.2      matt 		}
    438      1.2      matt 	}
    439      1.2      matt }
    440      1.2      matt 
    441      1.2      matt /*
    442      1.2      matt  * Card slot interrupt handling
    443      1.2      matt  */
    444      1.2      matt int
    445      1.2      matt imx_pcic_intr(void *arg)
    446      1.2      matt {
    447      1.2      matt 	struct imx_pcic_socket *so = (struct imx_pcic_socket *)arg;
    448      1.2      matt 
    449      1.2      matt 	(*so->pcictag->clear_intr)(so);
    450      1.2      matt         wakeup(so);
    451      1.2      matt 
    452      1.2      matt         return 1;
    453      1.2      matt }
    454      1.2      matt 
    455      1.2      matt static void
    456      1.2      matt imx_pcic_event_thread(void *arg)
    457      1.2      matt {
    458      1.2      matt #ifdef NOTYET
    459      1.2      matt 	struct imx_pcic_socket *sock = (struct imx_pcic_socket *)arg;
    460      1.2      matt 	u_int cs;
    461      1.2      matt 	int present;
    462      1.2      matt 
    463      1.2      matt 	while (sock->sc->sc_shutdown == 0) {
    464      1.2      matt 		(void) tsleep(sock, PWAIT, "imx_pcicev", 0);
    465      1.2      matt 
    466      1.2      matt 		/* sleep .25s to avoid chattering interrupts */
    467      1.2      matt 		(void) tsleep((void *)sock, PWAIT, "imx_pcicss", hz/4);
    468      1.2      matt 
    469      1.2      matt 		cs = (*sock->pcictag->read)(sock, IMX_PCIC_CARD_STATUS);
    470      1.2      matt 		present = sock->flags & IMX_PCIC_FLAG_CARDP;
    471      1.2      matt 		if ((cs == IMX_PCIC_CARD_VALID) == (present == 1)) {
    472      1.2      matt 			continue;	/* state unchanged */
    473      1.2      matt 		}
    474      1.2      matt 
    475      1.2      matt 		/* XXX Do both? */
    476      1.2      matt 		imx_pcic_event_process(sock);
    477      1.2      matt 	}
    478      1.2      matt 	sock->event_thread = NULL;
    479      1.2      matt 
    480      1.2      matt 	/* In case parent is waiting for us to exit. */
    481      1.2      matt 	wakeup(sock->sc);
    482      1.2      matt 	kthread_exit(0);
    483      1.2      matt #endif	/* NOTYET */
    484      1.2      matt }
    485      1.2      matt 
    486      1.2      matt #ifdef NOTYET
    487      1.2      matt static void
    488      1.2      matt imx_pcic_event_process(struct imx_pcic_socket *sock)
    489      1.2      matt {
    490      1.2      matt 	u_int cs;
    491      1.2      matt 
    492      1.2      matt 	cs = (*sock->pcictag->read)(sock, IMX_PCIC_CARD_STATUS);
    493      1.2      matt 	if (cs == IMX_PCIC_CARD_VALID) {
    494      1.2      matt 		if (!(sock->flags & IMX_PCIC_FLAG_CARDP)) {
    495      1.2      matt 			imx_pcic_attach_card(sock);
    496      1.2      matt 		}
    497      1.2      matt 	} else {
    498      1.2      matt 		if ((sock->flags & IMX_PCIC_FLAG_CARDP)) {
    499      1.2      matt 			imx_pcic_detach_card(sock, DETACH_FORCE);
    500      1.2      matt 		}
    501      1.2      matt 	}
    502      1.2      matt }
    503      1.2      matt 
    504      1.2      matt static void
    505      1.2      matt imx_pcic_attach_card(struct imx_pcic_socket *h)
    506      1.2      matt {
    507      1.2      matt 
    508      1.2      matt 	if (h->flags & IMX_PCIC_FLAG_CARDP)
    509      1.2      matt 		panic("pcic_attach_card: already attached");
    510      1.2      matt 	h->flags |= IMX_PCIC_FLAG_CARDP;
    511      1.2      matt 
    512      1.2      matt 
    513      1.2      matt 	/* call the MI attach function */
    514      1.2      matt 	pcmcia_card_attach(h->pcmcia);
    515      1.2      matt }
    516      1.2      matt #endif	/* NOTYET */
    517      1.2      matt 
    518      1.2      matt #ifdef NOTYET
    519      1.2      matt static void
    520      1.2      matt imx_pcic_detach_card(struct imx_pcic_socket *h, int flags)
    521      1.2      matt {
    522      1.2      matt 	struct imx_pcic_softc *sc = h->sc;
    523      1.2      matt 	int i;
    524      1.2      matt 
    525      1.2      matt 	if (h->flags & IMX_PCIC_FLAG_CARDP) {
    526      1.2      matt 		h->flags &= ~IMX_PCIC_FLAG_CARDP;
    527      1.2      matt 
    528      1.2      matt 		/* call the MI detach function */
    529      1.2      matt 		pcmcia_card_detach(h->pcmcia, flags);
    530      1.2      matt 	}
    531      1.2      matt 
    532      1.2      matt 	/* Clear CIT if no other card is present. */
    533      1.2      matt 	for (i = 0; i < sc->sc_nslots; i++) {
    534      1.2      matt 		if (sc->sc_socket[i].flags & IMX_PCIC_FLAG_CARDP) {
    535      1.2      matt 			return;
    536      1.2      matt 		}
    537      1.2      matt 	}
    538      1.2      matt }
    539      1.2      matt #endif	/* NOTYET */
    540