/* soc_common_pcmcia_sock_init() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * * (Re-)Initialise the socket, turning on status interrupts * and PCMCIA bus. This must wait for power to stabilise * so that the card status signals report correctly. * * Returns: 0 */ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); debug(skt, 2, "initializing socket\n"); skt->ops->socket_init(skt); return 0; }
/* * Implements the get_status() operation for the in-kernel PCMCIA * service (formerly SS_GetStatus in Card Services). Essentially just * fills in bits in `status' according to internal driver state or * the value of the voltage detect chipselect register. * * As a debugging note, during card startup, the PCMCIA core issues * three set_socket() commands in a row the first with RESET deasserted, * the second with RESET asserted, and the last with RESET deasserted * again. Following the third set_socket(), a get_status() command will * be issued. The kernel is looking for the SS_READY flag (see * setup_socket(), reset_socket(), and unreset_socket() in cs.c). * * Returns: 0 */ static int soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); skt->status = soc_common_pcmcia_skt_state(skt); *status = skt->status; return 0; }
/* * soc_common_pcmcia_suspend() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * * Remove power on the socket, disable IRQs from the card. * Turn off status interrupts, and disable the PCMCIA bus. * * Returns: 0 */ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); debug(skt, 2, "suspending socket\n"); skt->ops->socket_suspend(skt); return 0; }
/* * Implements the get_socket() operation for the in-kernel PCMCIA * service (formerly SS_GetSocket in Card Services). Not a very * exciting routine. * * Returns: 0 */ static int soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); debug(skt, 2, "\n"); *state = skt->cs_state; return 0; }
/* * soc_common_pcmcia_suspend() * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * * Remove power on the socket, disable IRQs from the card. * Turn off status interrupts, and disable the PCMCIA bus. * * Returns: 0 */ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); int ret; debug(skt, 2, "suspending socket\n"); ret = soc_common_pcmcia_config_skt(skt, &dead_socket); if (ret == 0) skt->ops->socket_suspend(skt); return ret; }
/* * Implements the set_mem_map() operation for the in-kernel PCMCIA * service (formerly SS_SetMemMap in Card Services). We configure * the map speed as requested, but override the address ranges * supplied by Card Services. * * Returns: 0 on success, -1 on error */ static int soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); struct resource *res; unsigned short speed = map->speed; debug(skt, 2, "map %u speed %u card_start %08x\n", map->map, map->speed, map->card_start); debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", (map->flags==0)?"<NONE>":"", (map->flags&MAP_ACTIVE)?"ACTIVE ":"", (map->flags&MAP_16BIT)?"16BIT ":"", (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", (map->flags&MAP_0WS)?"0WS ":"", (map->flags&MAP_WRPROT)?"WRPROT ":"", (map->flags&MAP_ATTRIB)?"ATTRIB ":"", (map->flags&MAP_USE_WAIT)?"USE_WAIT ":""); if (map->map >= MAX_WIN) return -EINVAL; if (map->flags & MAP_ACTIVE) { if (speed == 0) speed = 300; } else { speed = 0; } if (map->flags & MAP_ATTRIB) { res = &skt->res_attr; skt->spd_attr[map->map] = speed; skt->spd_mem[map->map] = 0; } else { res = &skt->res_mem; skt->spd_attr[map->map] = 0; skt->spd_mem[map->map] = speed; } skt->ops->set_timing(skt); map->sys_stop -= map->sys_start; map->sys_stop += res->start + map->card_start; map->sys_start = res->start + map->card_start; return 0; }
static int soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); unsigned short speed = map->speed; debug(skt, 2, "map %u speed %u start 0x%08llx stop 0x%08llx\n", map->map, map->speed, (unsigned long long)map->start, (unsigned long long)map->stop); debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", (map->flags==0)?"<NONE>":"", (map->flags&MAP_ACTIVE)?"ACTIVE ":"", (map->flags&MAP_16BIT)?"16BIT ":"", (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", (map->flags&MAP_0WS)?"0WS ":"", (map->flags&MAP_WRPROT)?"WRPROT ":"", (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"", (map->flags&MAP_PREFETCH)?"PREFETCH ":""); if (map->map >= MAX_IO_WIN) { printk(KERN_ERR "%s(): map (%d) out of range\n", __func__, map->map); return -1; } if (map->flags & MAP_ACTIVE) { if (speed == 0) speed = SOC_PCMCIA_IO_ACCESS; } else { speed = 0; } skt->spd_io[map->map] = speed; skt->ops->set_timing(skt); if (map->stop == 1) map->stop = PAGE_SIZE-1; map->stop -= map->start; map->stop += skt->socket.io_offset; map->start = skt->socket.io_offset; return 0; }
/* * Implements the set_socket() operation for the in-kernel PCMCIA * service (formerly SS_SetSocket in Card Services). We more or * less punt all of this work and let the kernel handle the details * of power configuration, reset, &c. We also record the value of * `state' in order to regurgitate it to the PCMCIA core later. */ static int soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) { struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n", (state->csc_mask==0)?"<NONE> ":"", (state->csc_mask&SS_DETECT)?"DETECT ":"", (state->csc_mask&SS_READY)?"READY ":"", (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", (state->csc_mask&SS_BATWARN)?"BATWARN ":"", (state->csc_mask&SS_STSCHG)?"STSCHG ":"", (state->flags==0)?"<NONE> ":"", (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", (state->flags&SS_IOCARD)?"IOCARD ":"", (state->flags&SS_RESET)?"RESET ":"", (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"", state->Vcc, state->Vpp, state->io_irq); return soc_common_pcmcia_config_skt(skt, state); }