^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PCMCIA 16-bit resource management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * The initial developer of the original code is David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1999 David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2004-2010 Dominik Brodowski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <pcmcia/ss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "cs_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Access speed for IO windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) module_param(io_speed, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int pcmcia_validate_mem(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (s->resource_ops->validate_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return s->resource_ops->validate_mem(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* if there is no callback, we can assume that everything is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int low, struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (s->resource_ops->find_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return s->resource_ops->find_mem(base, num, align, low, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * release_io_space() - release IO ports allocated with alloc_io_space()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @s: pcmcia socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @res: resource to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void release_io_space(struct pcmcia_socket *s, struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) resource_size_t num = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) dev_dbg(&s->dev, "release_io_space for %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if ((s->io[i].res->start <= res->start) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) (s->io[i].res->end >= res->end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) s->io[i].InUse -= num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (res->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) res->start = res->end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) res->flags = IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Free the window if no one else is using it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (s->io[i].InUse == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) release_resource(s->io[i].res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) kfree(s->io[i].res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) s->io[i].res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * alloc_io_space() - allocate IO ports for use by a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @s: pcmcia socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @res: resource to allocate (begin: begin, end: size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @lines: number of IO lines decoded by the PCMCIA card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Special stuff for managing IO windows, because they are scarce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int base = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned int num = res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) res->flags |= IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) res, lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) align = base ? (lines ? 1<<lines : 0) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (align && (align < num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dev_dbg(&s->dev, "odd IO request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) while (align && (align < num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) align <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (base & ~(align-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_dbg(&s->dev, "odd IO request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) &res->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) res->start = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) res->end = res->start + num - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (res->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ret = request_resource(res->parent, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dev_warn(&s->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "request_resource %pR failed: %d\n", res, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) res->parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) release_io_space(s, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * pcmcia_access_config() - read or write card configuration registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * pcmcia_access_config() reads and writes configuration registers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * attribute memory. Memory window 0 is reserved for this and the tuple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * reading services. Drivers must use pcmcia_read_config_byte() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * pcmcia_write_config_byte().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int pcmcia_access_config(struct pcmcia_device *p_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) off_t where, u8 *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int (*accessf) (struct pcmcia_socket *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int attr, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int len, void *ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct pcmcia_socket *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (!(c->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dev_dbg(&p_dev->dev, "Configuration isn't locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) addr = (p_dev->config_base + where) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = accessf(s, 1, addr, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * pcmcia_read_config_byte() - read a byte from a card configuration register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * pcmcia_read_config_byte() reads a byte from a configuration register in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * attribute memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return pcmcia_access_config(p_dev, where, val, pcmcia_read_cis_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EXPORT_SYMBOL(pcmcia_read_config_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * pcmcia_write_config_byte() - write a byte to a card configuration register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * pcmcia_write_config_byte() writes a byte to a configuration register in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * attribute memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EXPORT_SYMBOL(pcmcia_write_config_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * pcmcia_map_mem_page() - modify iomem window to point to a different offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * @res: iomem resource already enabled by pcmcia_request_window()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @offset: card_offset to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * pcmcia_map_mem_page() modifies what can be read and written by accessing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * an iomem range previously enabled by pcmcia_request_window(), by setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * the card_offset value to @offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (w >= MAX_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) s->win[w].card_start = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = s->ops->set_mem_map(s, &s->win[w]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dev_warn(&p_dev->dev, "failed to set_mem_map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) EXPORT_SYMBOL(pcmcia_map_mem_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * pcmcia_fixup_iowidth() - reduce io width to 8bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * IO width to 8bit after having called pcmcia_enable_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * previously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pccard_io_map io_off = { 0, 0, 0, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) pccard_io_map io_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!(s->state & SOCKET_PRESENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) !(p_dev->function_config->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) io_on.speed = io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) io_off.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) io_on.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) io_on.start = s->io[i].res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) io_on.stop = s->io[i].res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) s->ops->set_io_map(s, &io_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) msleep(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) s->ops->set_io_map(s, &io_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) EXPORT_SYMBOL(pcmcia_fixup_iowidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * pcmcia_fixup_vpp() - set Vpp to a new voltage level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * @new_vpp: new Vpp voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * a new voltage level between calls to pcmcia_enable_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * and pcmcia_disable_device().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!(s->state & SOCKET_PRESENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) !(p_dev->function_config->state & CONFIG_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) s->socket.Vpp = new_vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (s->ops->set_socket(s, &s->socket)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) dev_warn(&p_dev->dev, "Unable to set VPP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) p_dev->vpp = new_vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) EXPORT_SYMBOL(pcmcia_fixup_vpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * pcmcia_release_configuration() - physically disable a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * pcmcia_release_configuration() is the 1:1 counterpart to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * pcmcia_enable_device(): If a PCMCIA device is no longer used by any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * driver, the Vpp voltage is set to 0, IRQs will no longer be generated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * and I/O ranges will be disabled. As pcmcia_release_io() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * pcmcia_release_window() still need to be called, device drivers are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * expected to call pcmcia_disable_device() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int pcmcia_release_configuration(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pccard_io_map io = { 0, 0, 0, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (p_dev->_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) p_dev->_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (--(s->lock_count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) s->socket.Vpp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) s->socket.io_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) s->ops->set_socket(s, &s->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) c->state &= ~CONFIG_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (c->state & CONFIG_IO_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) for (i = 0; i < MAX_IO_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!s->io[i].res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) s->io[i].Config--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (s->io[i].Config != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) io.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) s->ops->set_io_map(s, &io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * pcmcia_release_io() - release I/O allocated by a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * pcmcia_release_io() releases the I/O ranges allocated by a PCMCIA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * device. This may be invoked some time after a card ejection has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * already dumped the actual socket configuration, so if the client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * "stale", we don't bother checking the port ranges against the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * current socket values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int pcmcia_release_io(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!p_dev->_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) release_io_space(s, &c->io[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (c->io[1].end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) release_io_space(s, &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) p_dev->_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) c->state &= ~CONFIG_IO_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) } /* pcmcia_release_io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * pcmcia_release_window() - release reserved iomem for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @p_dev: pcmcia device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @res: iomem resource to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * pcmcia_release_window() releases &struct resource *res which was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * previously reserved by calling pcmcia_request_window().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pccard_mem_map *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (w >= MAX_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) win = &s->win[w];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_dbg(&p_dev->dev, "not releasing unknown window\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Shut down memory window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) win->flags &= ~MAP_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) s->ops->set_mem_map(s, win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) s->state &= ~SOCKET_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Release system memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (win->res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) release_resource(win->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) kfree(win->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) win->res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) res->start = res->end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) res->flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) p_dev->_win &= ~CLIENT_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) } /* pcmcia_release_window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) EXPORT_SYMBOL(pcmcia_release_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * pcmcia_enable_device() - set up and activate a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * pcmcia_enable_device() physically enables a PCMCIA device. It parses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * the flags passed to in @flags and stored in @p_dev->flags and sets up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * the Vpp voltage, enables the speaker line, I/O ports and store proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * values to configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int pcmcia_enable_device(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) unsigned int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) config_t *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pccard_io_map iomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unsigned char status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unsigned char ext_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned char option = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) unsigned int flags = p_dev->config_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!(s->state & SOCKET_PRESENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) dev_dbg(&p_dev->dev, "Configuration is locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Do power control. We don't allow changes in Vcc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) s->socket.Vpp = p_dev->vpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (s->ops->set_socket(s, &s->socket)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) dev_warn(&p_dev->dev, "Unable to set socket state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* Pick memory or I/O card, DMA mode, interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (p_dev->_io || flags & CONF_ENABLE_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) flags |= CONF_ENABLE_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (flags & CONF_ENABLE_IOCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) s->socket.flags |= SS_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (flags & CONF_ENABLE_ZVCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) s->socket.flags |= SS_ZVCARD | SS_IOCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (flags & CONF_ENABLE_SPKR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) s->socket.flags |= SS_SPKR_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) status = CCSR_AUDIO_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!(p_dev->config_regs & PRESENT_STATUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) dev_warn(&p_dev->dev, "speaker requested, but "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) "PRESENT_STATUS not set!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (flags & CONF_ENABLE_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) s->socket.io_irq = s->pcmcia_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) s->socket.io_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (flags & CONF_ENABLE_ESR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) p_dev->config_regs |= PRESENT_EXT_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ext_status = ESR_REQ_ATTN_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) s->ops->set_socket(s, &s->socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) s->lock_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dev_dbg(&p_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) "enable_device: V %d, flags %x, base %x, regs %x, idx %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) p_dev->vpp, flags, p_dev->config_base, p_dev->config_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) p_dev->config_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Set up CIS configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) base = p_dev->config_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (p_dev->config_regs & PRESENT_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u16 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_dbg(&p_dev->dev, "clearing CISREG_SCR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (p_dev->config_regs & PRESENT_PIN_REPLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) u16 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dev_dbg(&p_dev->dev, "clearing CISREG_PRR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (p_dev->config_regs & PRESENT_OPTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (s->functions == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) option = p_dev->config_index & COR_CONFIG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) option = p_dev->config_index & COR_MFC_CONFIG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) option |= COR_FUNC_ENA|COR_IREQ_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (p_dev->config_regs & PRESENT_IOBASE_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) option |= COR_ADDR_DECODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if ((flags & CONF_ENABLE_IRQ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) !(flags & CONF_ENABLE_PULSE_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) option |= COR_LEVEL_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) msleep(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (p_dev->config_regs & PRESENT_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (p_dev->config_regs & PRESENT_EXT_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) &ext_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (p_dev->config_regs & PRESENT_IOBASE_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 b = c->io[0].start & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) b = (c->io[0].start >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (p_dev->config_regs & PRESENT_IOSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* Configure I/O windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (c->state & CONFIG_IO_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) iomap.speed = io_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) for (i = 0; i < MAX_IO_WIN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (s->io[i].res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) iomap.map = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) iomap.flags = MAP_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case IO_DATA_PATH_WIDTH_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) iomap.flags |= MAP_16BIT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case IO_DATA_PATH_WIDTH_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) iomap.flags |= MAP_AUTOSZ; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) iomap.start = s->io[i].res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) iomap.stop = s->io[i].res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) s->ops->set_io_map(s, &iomap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) s->io[i].Config++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) c->state |= CONFIG_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) p_dev->_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } /* pcmcia_enable_device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) EXPORT_SYMBOL(pcmcia_enable_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * pcmcia_request_io() attempts to reserve the IO port ranges specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * "start" value is the requested start of the IO port resource; "end"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * reflects the number of ports requested. The number of IO lines requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * is specified in &struct pcmcia_device @p_dev->io_lines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int pcmcia_request_io(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) config_t *c = p_dev->function_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) &c->io[0], &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!(s->state & SOCKET_PRESENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (c->state & CONFIG_LOCKED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) dev_dbg(&p_dev->dev, "Configuration is locked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (c->state & CONFIG_IO_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dev_dbg(&p_dev->dev, "IO already configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ret = alloc_io_space(s, &c->io[0], p_dev->io_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (c->io[1].end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct resource tmp = c->io[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* release the previously allocated resource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) release_io_space(s, &c->io[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* but preserve the settings, for they worked... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) c->io[0].end = resource_size(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) c->io[0].start = tmp.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) c->io[0].flags = tmp.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) c->io[1].start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) c->state |= CONFIG_IO_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) p_dev->_io = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) &c->io[0], &c->io[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) } /* pcmcia_request_io */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) EXPORT_SYMBOL(pcmcia_request_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * @handler: IRQ handler to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * pcmcia_request_irq() is a wrapper around request_irq() which allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * the PCMCIA core to clean up the registration in pcmcia_disable_device().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * Drivers are free to use request_irq() directly, but then they need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * call free_irq() themselfves, too. Also, only %IRQF_SHARED capable IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * handlers are allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) irq_handler_t handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!p_dev->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) p_dev->devname, p_dev->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) p_dev->_irq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) EXPORT_SYMBOL(pcmcia_request_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #ifdef CONFIG_PCMCIA_PROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* mask of IRQs already reserved by other cards, we should avoid using them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static u8 pcmcia_used_irq[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static irqreturn_t test_action(int cpl, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * @p_dev - the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * locking note: must be called with ops_mutex locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) unsigned int try, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) u32 mask = s->irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) for (try = 0; try < 64; try++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) irq = try % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (irq > NR_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* marked as available by driver, not blocked by userspace? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!((mask >> irq) & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /* avoid an IRQ which is already used by another PCMCIA card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if ((try < 32) && pcmcia_used_irq[irq])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* register the correct driver, if possible, to check whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * registering a dummy handle works, i.e. if the IRQ isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * marked as used by the kernel resource management core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret = request_irq(irq, test_action, type, p_dev->devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) free_irq(irq, p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) p_dev->irq = s->pcmcia_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) pcmcia_used_irq[irq]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) void pcmcia_cleanup_irq(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) pcmcia_used_irq[s->pcmcia_irq]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) s->pcmcia_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) #else /* CONFIG_PCMCIA_PROBE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) void pcmcia_cleanup_irq(struct pcmcia_socket *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) s->pcmcia_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) #endif /* CONFIG_PCMCIA_PROBE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * pcmcia_setup_irq() - determine IRQ to be used for device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * @p_dev - the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * locking note: must be called with ops_mutex locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int pcmcia_setup_irq(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (p_dev->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* already assigned? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (s->pcmcia_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) p_dev->irq = s->pcmcia_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* prefer an exclusive ISA irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!pcmcia_setup_isa_irq(p_dev, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* but accept a shared ISA irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* but use the PCI irq otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (s->pci_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) p_dev->irq = s->pcmcia_irq = s->pci_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * @res: &struct resource pointing to p_dev->resource[2..5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * @speed: access speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * pcmcia_request_window() attepts to reserve an iomem ranges specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * &struct resource @res pointing to one of the entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * &struct pcmcia_device @p_dev->resource[2..5]. The "start" value is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * requested start of the IO mem resource; "end" reflects the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) unsigned int speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct pcmcia_socket *s = p_dev->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pccard_mem_map *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u_long align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dev_dbg(&p_dev->dev, "request_window %pR %d\n", res, speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!(s->state & SOCKET_PRESENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dev_dbg(&p_dev->dev, "No card present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* Window size defaults to smallest available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (res->end == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) res->end = s->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (res->end & (s->map_size-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) dev_dbg(&p_dev->dev, "invalid map size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if ((res->start && (s->features & SS_CAP_STATIC_MAP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) (res->start & (align-1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dev_dbg(&p_dev->dev, "invalid base address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (res->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* Allocate system memory window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mutex_lock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) for (w = 0; w < MAX_WIN; w++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!(s->state & SOCKET_WIN_REQ(w)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (w == MAX_WIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dev_dbg(&p_dev->dev, "all windows are used already\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) win = &s->win[w];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!(s->features & SS_CAP_STATIC_MAP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) win->res = pcmcia_find_mem_region(res->start, res->end, align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 0, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!win->res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) dev_dbg(&p_dev->dev, "allocating mem region failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) p_dev->_win |= CLIENT_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* Configure the socket controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) win->map = w+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) win->flags = res->flags & WIN_FLAGS_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) win->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) win->card_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (s->ops->set_mem_map(s, win) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) s->state |= SOCKET_WIN_REQ(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* Return window handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (s->features & SS_CAP_STATIC_MAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) res->start = win->static_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) res->start = win->res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* convert to new-style resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) res->end += res->start - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) res->flags &= ~WIN_FLAGS_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) res->flags |= (win->map << 2) | IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) res->parent = win->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (win->res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) request_resource(&iomem_resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) mutex_unlock(&s->ops_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) } /* pcmcia_request_window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) EXPORT_SYMBOL(pcmcia_request_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * pcmcia_disable_device() - disable and clean up a PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * @p_dev: the associated PCMCIA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * pcmcia_disable_device() is the driver-callable counterpart to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * pcmcia_enable_device(): If a PCMCIA device is no longer used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * drivers are expected to clean up and disable the device by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * this function. Any I/O ranges (iomem and ioports) will be released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * the Vpp voltage will be set to 0, and IRQs will no longer be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * generated -- at least if there is no other card function (of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * multifunction devices) being used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) void pcmcia_disable_device(struct pcmcia_device *p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) dev_dbg(&p_dev->dev, "disabling device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) for (i = 0; i < MAX_WIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct resource *res = p_dev->resource[MAX_IO_WIN + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (res->flags & WIN_FLAGS_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) pcmcia_release_window(p_dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) pcmcia_release_configuration(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) pcmcia_release_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (p_dev->_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) free_irq(p_dev->irq, p_dev->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) p_dev->_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) EXPORT_SYMBOL(pcmcia_disable_device);